Skip to content

Commit

Permalink
feat: impliment syscall sys_socketpair
Browse files Browse the repository at this point in the history
  • Loading branch information
Stone749990226 committed Feb 11, 2025
1 parent 154103c commit 512e9d1
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 2 deletions.
33 changes: 33 additions & 0 deletions api/ruxos_posix_api/src/imp/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -940,3 +940,36 @@ pub unsafe fn sys_sendmsg(
Ok(ret)
})
}

/// Creates a pair of Unix domain sockets and stores the file descriptors in `sv`
///
/// This system call only works for UNIX domain sockets (AF_UNIX), which are used for communication
/// between processes on the same machine. It cannot be used for communication over the network (e.g.,
/// using AF_INET or AF_INET6). The created socket pair is anonymous, meaning it does not require
/// a pathname, and is typically used for communication between related processes (e.g., parent-child processes)
pub fn sys_socketpair(domain: c_int, socktype: c_int, protocol: c_int, sv: &mut [c_int]) -> c_int {
info!("sys_socketpair <= domain: {domain}, socktype: {socktype}, protocol: {protocol}, sv pointer: {:#x}", sv.as_ptr() as usize);
syscall_body!(sys_socketpair, {
let (domain, socktype, _protocol) = (domain as u32, socktype as u32, protocol as u32);
let fdflags = flags_to_options((socktype & ctypes::SOCK_CLOEXEC) as c_int, 0);
let socktype = socktype & !ctypes::SOCK_CLOEXEC & !ctypes::SOCK_NONBLOCK;
match domain {
ctypes::AF_UNIX => {
let (sk1, sk2) = match socktype {
ctypes::SOCK_STREAM => {
UnixSocket::create_socket_pair(UnixSocketType::SockStream)?
}
ctypes::SOCK_DGRAM => {
UnixSocket::create_socket_pair(UnixSocketType::SockDgram)?
}
_ => return Err(LinuxError::EAFNOSUPPORT),
};
sv[0] = Socket::Unix(Mutex::new(sk1)).add_to_fd_table(fdflags.clone())?;
sv[1] = Socket::Unix(Mutex::new(sk2)).add_to_fd_table(fdflags)?;
info!("create sv[0] {}, sv[1] {}", sv[0], sv[1]);
Ok(0)
}
_ => return Err(LinuxError::EAFNOSUPPORT),
}
})
}
2 changes: 1 addition & 1 deletion api/ruxos_posix_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pub use imp::mmap::{sys_madvise, sys_mmap, sys_mprotect, sys_mremap, sys_msync,
pub use imp::net::{
sys_accept, sys_bind, sys_connect, sys_freeaddrinfo, sys_getaddrinfo, sys_getpeername,
sys_getsockname, sys_getsockopt, sys_listen, sys_recv, sys_recvfrom, sys_send, sys_sendmsg,
sys_sendto, sys_setsockopt, sys_shutdown, sys_socket,
sys_sendto, sys_setsockopt, sys_shutdown, sys_socket, sys_socketpair,
};
#[cfg(feature = "pipe")]
pub use imp::pipe::{sys_pipe, sys_pipe2};
Expand Down
42 changes: 42 additions & 0 deletions modules/ruxnet/src/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,48 @@ impl UnixSocket {
}
}

/// Creates a pair of Unix domain sockets and establishes their connection based on the specified socket type.
///
/// For `SOCK_STREAM`, the sockets are connected and marked as "connected" in the UNIX_TABLE.
/// For `SOCK_DGRAM`, the sockets are assigned each other's address as their peer address.
///
/// Returns:
///
/// A result containing a tuple of two connected `UnixSocket` instances on success.
/// If the connection setup fails, an error is returned.
pub fn create_socket_pair(_type: UnixSocketType) -> AxResult<(Self, Self)> {
let sk1 = UnixSocket::new(_type);
let sk2 = UnixSocket::new(_type);
let handle1 = sk1.get_sockethandle();
let handle2 = sk2.get_sockethandle();
match _type {
UnixSocketType::SockStream => {
let mut binding = UNIX_TABLE.write();
let mut inner1 = binding.get_mut(handle1).unwrap().lock();
inner1.set_peersocket(handle2);
inner1.set_state(UnixSocketStatus::Connected);
drop(inner1);
let mut inner2 = binding.get_mut(handle2).unwrap().lock();
inner2.set_peersocket(handle1);
inner2.set_state(UnixSocketStatus::Connected);
}
UnixSocketType::SockDgram => {
let addr1 = sk1.check_and_set_addr();
let addr2 = sk2.check_and_set_addr();
let mut binding = UNIX_TABLE.write();
let mut inner1 = binding.get_mut(handle1).unwrap().lock();
inner1.set_peersocket(handle2);
inner1.dgram_connected_addr = Some(addr2);
drop(inner1);
let mut inner2 = binding.get_mut(handle2).unwrap().lock();
inner2.set_peersocket(handle1);
inner2.dgram_connected_addr = Some(addr1);
}
UnixSocketType::SockSeqpacket => todo!(),
}
Ok((sk1, sk2))
}

/// Sets the socket handle.
pub fn set_sockethandle(&mut self, fd: usize) {
self.sockethandle = Some(fd);
Expand Down
7 changes: 7 additions & 0 deletions ulib/ruxmusl/src/aarch64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,13 @@ pub fn syscall(syscall_id: SyscallId, args: [usize; 6]) -> isize {
as _
}
#[cfg(feature = "net")]
SyscallId::SOCKETPAIR => ruxos_posix_api::sys_socketpair(
args[0] as _,
args[1] as _,
args[2] as _,
core::slice::from_raw_parts_mut(args[3] as *mut c_int, 2),
) as _,
#[cfg(feature = "net")]
SyscallId::BIND => ruxos_posix_api::sys_bind(
args[0] as c_int,
args[1] as *const ctypes::sockaddr,
Expand Down
2 changes: 2 additions & 0 deletions ulib/ruxmusl/src/aarch64/syscall_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ pub enum SyscallId {
#[cfg(feature = "net")]
SOCKET = 198,
#[cfg(feature = "net")]
SOCKETPAIR = 199,
#[cfg(feature = "net")]
BIND = 200,
#[cfg(feature = "net")]
LISTEN = 201,
Expand Down
7 changes: 7 additions & 0 deletions ulib/ruxmusl/src/riscv64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,13 @@ pub fn syscall(syscall_id: SyscallId, args: [usize; 6]) -> isize {
as _
}
#[cfg(feature = "net")]
SyscallId::SOCKETPAIR => ruxos_posix_api::sys_socketpair(
args[0] as _,
args[1] as _,
args[2] as _,
core::slice::from_raw_parts_mut(args[3] as *mut c_int, 2),
) as _,
#[cfg(feature = "net")]
SyscallId::BIND => ruxos_posix_api::sys_bind(
args[0] as c_int,
args[1] as *const ctypes::sockaddr,
Expand Down
2 changes: 2 additions & 0 deletions ulib/ruxmusl/src/riscv64/syscall_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ pub enum SyscallId {
#[cfg(feature = "net")]
SOCKET = 198,
#[cfg(feature = "net")]
SOCKETPAIR = 199,
#[cfg(feature = "net")]
BIND = 200,
#[cfg(feature = "net")]
LISTEN = 201,
Expand Down
8 changes: 7 additions & 1 deletion ulib/ruxmusl/src/x86_64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,13 @@ pub fn syscall(syscall_id: SyscallId, args: [usize; 6]) -> isize {
ruxos_posix_api::sys_socket(args[0] as c_int, args[1] as c_int, args[2] as c_int)
as _
}

#[cfg(feature = "net")]
SyscallId::SOCKETPAIR => ruxos_posix_api::sys_socketpair(
args[0] as _,
args[1] as _,
args[2] as _,
core::slice::from_raw_parts_mut(args[3] as *mut c_int, 2),
) as _,
#[cfg(feature = "net")]
SyscallId::CONNECT => ruxos_posix_api::sys_connect(
args[0] as c_int,
Expand Down
3 changes: 3 additions & 0 deletions ulib/ruxmusl/src/x86_64/syscall_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ pub enum SyscallId {
#[cfg(feature = "net")]
GETPEERNAME = 52,

#[cfg(feature = "net")]
SOCKETPAIR = 53,

#[cfg(feature = "net")]
SETSOCKOPT = 54,

Expand Down

0 comments on commit 512e9d1

Please sign in to comment.