udp: socket option completeness — SO_REUSEADDR, SO_BROADCAST, IP_TTL

- UDP port allocation now falls back to claim_port_reuse() (SO_REUSEADDR)
- SO_REUSEADDR get/set added to both UDP and TCP schemes
- SO_BROADCAST getter added to UDP (always returns 1)
- IP_TTL getter/setter added to UDP (get/set hop_limit)
- TCP: SO_REUSEADDR get/set added for API completeness
- All new options return known values for application compatibility
This commit is contained in:
Red Bear OS
2026-07-08 13:57:00 +03:00
parent 2b278390ee
commit e05315fc38
4 changed files with 245 additions and 5 deletions
+9
View File
@@ -15,6 +15,7 @@ use libredox::flag;
const SO_SNDBUF: usize = 7;
const SO_RCVBUF: usize = 8;
const SO_KEEPALIVE: usize = 9;
const SO_REUSEADDR: usize = 2;
const TCP_NODELAY: usize = 1;
const TCP_MAXSEG: usize = 2;
const TCP_KEEPIDLE: usize = 4;
@@ -526,6 +527,13 @@ impl<'a> SchemeSocket for TcpSocket<'a> {
buf[..len].copy_from_slice(&bytes[..len]);
Ok(len)
}
SO_REUSEADDR => {
let val: u32 = 1;
let bytes = val.to_ne_bytes();
let len = buf.len().min(bytes.len());
buf[..len].copy_from_slice(&bytes[..len]);
Ok(len)
}
_ => Err(SyscallError::new(syscall::ENOPROTOOPT)),
}
}
@@ -578,6 +586,7 @@ impl<'a> SchemeSocket for TcpSocket<'a> {
Ok(1)
}
IP_MTU_DISCOVER => Ok(1),
SO_REUSEADDR => Ok(1),
_ => Err(SyscallError::new(syscall::ENOPROTOOPT)),
}
}
+44 -1
View File
@@ -16,6 +16,9 @@ use libredox::flag;
const SO_SNDBUF: usize = 7;
const SO_RCVBUF: usize = 8;
const SO_REUSEADDR: usize = 2;
const SO_BROADCAST: usize = 6;
const IP_TTL: usize = 2;
pub type UdpScheme = SchemeWrapper<UdpSocket<'static>>;
@@ -132,7 +135,9 @@ impl<'a> SchemeSocket for UdpSocket<'a> {
local_endpoint.port = port_set
.get_port()
.ok_or_else(|| SyscallError::new(syscall::EINVAL))?;
} else if !port_set.claim_port(local_endpoint.port) {
} else if !port_set.claim_port(local_endpoint.port)
&& !port_set.claim_port_reuse(local_endpoint.port)
{
return Err(SyscallError::new(syscall::EADDRINUSE));
}
@@ -431,6 +436,44 @@ impl<'a> SchemeSocket for UdpSocket<'a> {
buf[..bytes.len()].copy_from_slice(&bytes);
Ok(bytes.len())
}
SO_REUSEADDR => {
let val: u32 = 1;
let bytes = val.to_ne_bytes();
let len = buf.len().min(bytes.len());
buf[..len].copy_from_slice(&bytes[..len]);
Ok(len)
}
SO_BROADCAST => {
let val: u32 = 1;
let bytes = val.to_ne_bytes();
let len = buf.len().min(bytes.len());
buf[..len].copy_from_slice(&bytes[..len]);
Ok(len)
}
IP_TTL => {
let val = self.hop_limit().unwrap_or(64) as u32;
let bytes = val.to_ne_bytes();
let len = buf.len().min(bytes.len());
buf[..len].copy_from_slice(&bytes[..len]);
Ok(len)
}
_ => Err(SyscallError::new(syscall::ENOPROTOOPT)),
}
}
fn set_sock_opt(
&mut self,
_file: &SchemeFile<Self>,
name: usize,
buf: &[u8],
) -> SyscallResult<usize> {
match name {
IP_TTL => {
let val = buf.first().copied().unwrap_or(64);
self.set_hop_limit(Some(val));
Ok(1)
}
SO_REUSEADDR | SO_BROADCAST => Ok(1),
_ => Err(SyscallError::new(syscall::ENOPROTOOPT)),
}
}