libc: clean up socket option handling

This commit is contained in:
Mark Poliakov 2025-01-12 15:03:19 +02:00
parent 945c490fa7
commit 8454fec183
3 changed files with 41 additions and 25 deletions

View File

@ -6,7 +6,7 @@ use crate::{
util::PointerExt,
};
use super::sys_socket::{sa_family_t, socklen_t, SocketAddrExt};
use super::sys_socket::{sa_family_t, socklen_t, SocketAddrExt, SOL_SOCKOPT_IPV6, SOL_SOCKOPT_TCP};
pub type in_port_t = u16;
pub type in_addr_t = u32;
@ -57,13 +57,15 @@ pub const INADDR_BROADCAST: in_addr_t = 0xFFFFFFFF;
pub const INET_ADDRSTRLEN: usize = 16;
pub const INET6_ADDRSTRLEN: usize = 46;
pub const IPV6_JOIN_GROUP: c_int = 6001;
pub const IPV6_LEAVE_GROUP: c_int = 6002;
pub const IPV6_MULTICAST_HOPS: c_int = 6003;
pub const IPV6_MULTICAST_IF: c_int = 6004;
pub const IPV6_MULTICAST_LOOP: c_int = 6005;
pub const IPV6_UNICAST_HOPS: c_int = 6006;
pub const IPV6_V6ONLY: c_int = 6007;
pub const IPV6_JOIN_GROUP: c_int = 1 | SOL_SOCKOPT_IPV6;
pub const IPV6_LEAVE_GROUP: c_int = 2 | SOL_SOCKOPT_IPV6;
pub const IPV6_MULTICAST_HOPS: c_int = 3 | SOL_SOCKOPT_IPV6;
pub const IPV6_MULTICAST_IF: c_int = 4 | SOL_SOCKOPT_IPV6;
pub const IPV6_MULTICAST_LOOP: c_int = 5 | SOL_SOCKOPT_IPV6;
pub const IPV6_UNICAST_HOPS: c_int = 6 | SOL_SOCKOPT_IPV6;
pub const IPV6_V6ONLY: c_int = 7 | SOL_SOCKOPT_IPV6;
pub const TCP_NODELAY: c_int = 1 | SOL_SOCKOPT_TCP;
impl in_addr {
pub fn to_rust(&self) -> Ipv4Addr {

View File

@ -56,24 +56,27 @@ pub const SOCK_SEQPACKET: c_int = 3;
pub const SOCK_STREAM: c_int = 4;
// setsockopt() parameters
pub const SOL_SOCKET: c_int = 1;
pub const SOL_SOCKET: c_int = 1 << 24;
pub const SOL_SOCKOPT_TCP: c_int = 2 << 24;
pub const SOL_SOCKOPT_IPV4: c_int = 4 << 24;
pub const SOL_SOCKOPT_IPV6: c_int = 6 << 24;
pub const SO_ACCEPTCONN: c_int = 1;
pub const SO_BROADCAST: c_int = 2;
pub const SO_DEBUG: c_int = 3;
pub const SO_DONTROUTE: c_int = 4;
pub const SO_ERROR: c_int = 5;
pub const SO_KEEPALIVE: c_int = 6;
pub const SO_LINGER: c_int = 7;
pub const SO_OOBINLINE: c_int = 8;
pub const SO_RCVBUF: c_int = 9;
pub const SO_RCVLOWAT: c_int = 10;
pub const SO_RCVTIMEO: c_int = 11;
pub const SO_REUSEADDR: c_int = 12;
pub const SO_SNDBUF: c_int = 13;
pub const SO_SNDLOWAT: c_int = 14;
pub const SO_SNDTIMEO: c_int = 15;
pub const SO_TYPE: c_int = 16;
pub const SO_ACCEPTCONN: c_int = 1 | SOL_SOCKET;
pub const SO_BROADCAST: c_int = 2 | SOL_SOCKET;
pub const SO_DEBUG: c_int = 3 | SOL_SOCKET;
pub const SO_DONTROUTE: c_int = 4 | SOL_SOCKET;
pub const SO_ERROR: c_int = 5 | SOL_SOCKET;
pub const SO_KEEPALIVE: c_int = 6 | SOL_SOCKET;
pub const SO_LINGER: c_int = 7 | SOL_SOCKET;
pub const SO_OOBINLINE: c_int = 8 | SOL_SOCKET;
pub const SO_RCVBUF: c_int = 9 | SOL_SOCKET;
pub const SO_RCVLOWAT: c_int = 10 | SOL_SOCKET;
pub const SO_RCVTIMEO: c_int = 11 | SOL_SOCKET;
pub const SO_REUSEADDR: c_int = 12 | SOL_SOCKET;
pub const SO_SNDBUF: c_int = 13 | SOL_SOCKET;
pub const SO_SNDLOWAT: c_int = 14 | SOL_SOCKET;
pub const SO_SNDTIMEO: c_int = 15 | SOL_SOCKET;
pub const SO_TYPE: c_int = 16 | SOL_SOCKET;
pub const SOMAXCONN: usize = 64;

View File

@ -9,6 +9,7 @@ use crate::{
error::{self, CIntZeroResult, CResult, OptionExt, ResultExt, TryFromExt},
headers::{
errno::Errno,
netinet_in::{IPPROTO_TCP, TCP_NODELAY},
sys_socket::{SocketAddrExt, SOL_SOCKET, SO_BROADCAST, SO_RCVTIMEO, SO_SNDTIMEO},
sys_time::timeval,
},
@ -60,6 +61,12 @@ unsafe extern "C" fn getsockopt(
value.write(broadcast as c_int);
size_of::<c_int>()
}
(IPPROTO_TCP, TCP_NODELAY) => {
let broadcast = rt::get_socket_option!(fd, options::NoDelay).e_map_err(Errno::from)?;
let value = value.cast::<c_int>();
value.write(broadcast as c_int);
size_of::<c_int>()
}
_ => {
yggdrasil_rt::debug_trace!("Unhandled getsockopt({level}, {name}, {space})");
error::errno = Errno::EINVAL;
@ -100,6 +107,10 @@ unsafe extern "C" fn setsockopt(
let value = *value.cast::<c_int>() != 0;
rt::set_socket_option::<options::Broadcast>(fd, &value).e_map_err(Errno::from)?;
}
(IPPROTO_TCP, TCP_NODELAY) if size == size_of::<c_int>() => {
let value = *value.cast::<c_int>() != 0;
rt::set_socket_option::<options::NoDelay>(fd, &value).e_map_err(Errno::from)?;
}
_ => {
yggdrasil_rt::debug_trace!("Unhandled setsockopt({level}, {name}, {size})");
error::errno = Errno::EINVAL;