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