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:
@@ -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)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user