wasmer_wasix/syscalls/wasix/
sock_open.rs1use super::*;
2use crate::{net::socket::SocketProperties, syscalls::*};
3
4#[instrument(level = "trace", skip_all, fields(?af, ?ty, ?pt, sock = field::Empty), ret)]
24pub fn sock_open<M: MemorySize>(
25 mut ctx: FunctionEnvMut<'_, WasiEnv>,
26 af: Addressfamily,
27 ty: Socktype,
28 pt: SockProto,
29 ro_sock: WasmPtr<WasiFd, M>,
30) -> Result<Errno, WasiError> {
31 WasiEnv::do_pending_operations(&mut ctx)?;
32
33 match pt {
35 SockProto::Tcp => {
36 if ty != Socktype::Stream {
37 return Ok(Errno::Notsup);
38 }
39 }
40 SockProto::Udp => {
41 if ty != Socktype::Dgram {
42 return Ok(Errno::Notsup);
43 }
44 }
45 _ => {}
46 }
47
48 let fd = wasi_try_ok!(sock_open_internal(&mut ctx, af, ty, pt, None)?);
49
50 #[cfg(feature = "journal")]
51 if ctx.data().enable_journal {
52 JournalEffector::save_sock_open(&mut ctx, af, ty, pt, fd).map_err(|err| {
53 tracing::error!("failed to save sock_open event - {}", err);
54 WasiError::Exit(ExitCode::from(Errno::Fault))
55 })?;
56 }
57
58 let env = ctx.data();
59 let (memory, state, inodes) = unsafe { env.get_memory_and_wasi_state_and_inodes(&ctx, 0) };
60 wasi_try_mem_ok!(ro_sock.write(&memory, fd));
61
62 Ok(Errno::Success)
63}
64
65pub(crate) fn sock_open_internal(
66 ctx: &mut FunctionEnvMut<'_, WasiEnv>,
67 af: Addressfamily,
68 ty: Socktype,
69 pt: SockProto,
70 with_fd: Option<WasiFd>,
71) -> Result<Result<WasiFd, Errno>, WasiError> {
72 let env = ctx.data();
73 let (memory, state, inodes) = unsafe { env.get_memory_and_wasi_state_and_inodes(&ctx, 0) };
74
75 let kind = match ty {
76 Socktype::Stream | Socktype::Dgram => Kind::Socket {
77 socket: InodeSocket::new(InodeSocketKind::PreSocket {
78 props: SocketProperties {
79 family: af,
80 ty,
81 pt,
82 only_v6: false,
83 reuse_port: false,
84 reuse_addr: false,
85 no_delay: None,
86 keep_alive: None,
87 dont_route: None,
88 send_buf_size: None,
89 recv_buf_size: None,
90 write_timeout: None,
91 read_timeout: None,
92 accept_timeout: None,
93 connect_timeout: None,
94 handler: None,
95 },
96 addr: None,
97 }),
98 },
99 _ => return Ok(Err(Errno::Notsup)),
100 };
101
102 let inode =
103 state
104 .fs
105 .create_inode_with_default_stat(inodes, kind, false, "socket".to_string().into());
106 let rights = Rights::all_socket();
107 let fd = wasi_try_ok_ok!(if let Some(fd) = with_fd {
108 state
109 .fs
110 .with_fd(
111 rights,
112 rights,
113 Fdflags::empty(),
114 Fdflagsext::empty(),
115 0,
116 inode,
117 fd,
118 )
119 .map(|_| fd)
120 } else {
121 state.fs.create_fd(
122 rights,
123 rights,
124 Fdflags::empty(),
125 Fdflagsext::empty(),
126 0,
127 inode,
128 )
129 });
130 Span::current().record("sock", fd);
131
132 Ok(Ok(fd))
133}