wasmer_wasix/journal/effector/syscalls/
sock_accept.rs

1use std::net::SocketAddr;
2
3use wasmer_wasix_types::wasi::{Addressfamily, SockProto, Socktype};
4
5use crate::{
6    fs::Kind,
7    net::socket::{InodeSocket, InodeSocketKind, SocketProperties},
8};
9
10use super::*;
11
12impl JournalEffector {
13    pub fn save_sock_accepted(
14        ctx: &mut FunctionEnvMut<'_, WasiEnv>,
15        listen_fd: Fd,
16        fd: Fd,
17        addr: SocketAddr,
18        peer_addr: SocketAddr,
19        fd_flags: Fdflags,
20        nonblocking: bool,
21    ) -> anyhow::Result<()> {
22        Self::save_event(
23            ctx,
24            JournalEntry::SocketAcceptedV1 {
25                listen_fd,
26                fd,
27                local_addr: addr,
28                peer_addr,
29                fd_flags,
30                non_blocking: nonblocking,
31            },
32        )
33    }
34
35    pub fn apply_sock_accepted(
36        ctx: &mut FunctionEnvMut<'_, WasiEnv>,
37        _listen_fd: Fd,
38        fd: Fd,
39        addr: SocketAddr,
40        peer_addr: SocketAddr,
41        fd_flags: Fdflags,
42        nonblocking: bool,
43    ) -> anyhow::Result<()> {
44        let kind = Kind::Socket {
45            socket: InodeSocket::new(InodeSocketKind::RemoteSocket {
46                is_dead: true,
47                local_addr: addr,
48                peer_addr,
49                ttl: 0,
50                multicast_ttl: 0,
51                props: SocketProperties {
52                    family: match peer_addr.is_ipv4() {
53                        true => Addressfamily::Inet4,
54                        false => Addressfamily::Inet6,
55                    },
56                    ty: Socktype::Stream,
57                    pt: SockProto::Tcp,
58                    only_v6: false,
59                    reuse_port: false,
60                    reuse_addr: false,
61                    no_delay: None,
62                    keep_alive: None,
63                    dont_route: None,
64                    send_buf_size: None,
65                    recv_buf_size: None,
66                    write_timeout: None,
67                    read_timeout: None,
68                    accept_timeout: None,
69                    connect_timeout: None,
70                    handler: None,
71                },
72            }),
73        };
74
75        let env = ctx.data();
76        let state = env.state();
77        let inodes = &state.inodes;
78        let inode = state
79            .fs
80            .create_inode_with_default_stat(inodes, kind, false, "socket".into());
81
82        let mut new_flags = Fdflags::empty();
83        if nonblocking {
84            new_flags.set(Fdflags::NONBLOCK, true);
85        }
86
87        let mut new_flags = Fdflags::empty();
88        if fd_flags.contains(Fdflags::NONBLOCK) {
89            new_flags.set(Fdflags::NONBLOCK, true);
90        }
91
92        let rights = Rights::all_socket();
93        let ret = state
94            .fs
95            .with_fd(rights, rights, new_flags, Fdflagsext::empty(), 0, inode, fd);
96        ret.map_err(|err| {
97            anyhow::format_err!(
98                "journal restore error: failed to create remote accepted socket - {err}"
99            )
100        })?;
101
102        Ok(())
103    }
104}