diff --git a/netstack/src/scheme/tcp.rs b/netstack/src/scheme/tcp.rs index ea72d43a0b..bef9baef71 100644 --- a/netstack/src/scheme/tcp.rs +++ b/netstack/src/scheme/tcp.rs @@ -79,6 +79,7 @@ impl<'a> SchemeSocket for TcpSocket<'a> { let tx_buffer = TcpSocketBuffer::new(tx_packets); let socket = TcpSocket::new(rx_buffer, tx_buffer); + // TODO: claim port with ethernet ip address if local_endpoint.port == 0 { local_endpoint.port = port_set .get_port() @@ -95,6 +96,7 @@ impl<'a> SchemeSocket for TcpSocket<'a> { let local_endpoint_addr = match local_endpoint.addr { Some(addr) if !addr.is_unspecified() => Some(addr), _ => { + // local ip is 0.0.0.0, resolve it let route_table = context.route_table.borrow(); let addr = route_table .lookup_src_addr(&remote_endpoint.addr.expect("Checked in is_specified")); diff --git a/netstack/src/scheme/udp.rs b/netstack/src/scheme/udp.rs index eb9e0d4d93..b414069899 100644 --- a/netstack/src/scheme/udp.rs +++ b/netstack/src/scheme/udp.rs @@ -11,6 +11,7 @@ use super::socket::{Context, DupResult, SchemeFile, SchemeSocket, SocketFile}; use super::{parse_endpoint, SchemeWrapper, Smolnetd, SocketSet}; use crate::port_set::PortSet; use crate::router::Router; +use std::fmt::Write; pub type UdpScheme = SchemeWrapper>; @@ -64,7 +65,7 @@ impl<'a> SchemeSocket for UdpSocket<'a> { path: &str, uid: u32, port_set: &mut Self::SchemeDataT, - _context: &Context, + context: &Context, ) -> SyscallResult<(SocketHandle, Self::DataT)> { let mut parts = path.split('/'); let remote_endpoint = parse_endpoint(parts.next().unwrap_or("")); @@ -84,6 +85,7 @@ impl<'a> SchemeSocket for UdpSocket<'a> { ); let udp_socket = UdpSocket::new(rx_buffer, tx_buffer); + // TODO: claim port with ethernet ip address if local_endpoint.port == 0 { local_endpoint.port = port_set .get_port() @@ -95,6 +97,27 @@ impl<'a> SchemeSocket for UdpSocket<'a> { let socket_handle = socket_set.add(udp_socket); let udp_socket = socket_set.get_mut::(socket_handle); + + if remote_endpoint.is_specified() { + let local_endpoint_addr = match local_endpoint.addr { + Some(addr) if addr.is_unspecified() => Some(addr), + _ => { + // local ip is 0.0.0.0, resolve it + let route_table = context.route_table.borrow(); + let addr = route_table + .lookup_src_addr(&remote_endpoint.addr.expect("Checked in is_specified")); + if matches!(addr, None) { + error!("Opening a TCP connection with a probably invalid source IP as no route have been found for destination: {}", remote_endpoint); + } + addr + } + }; + local_endpoint = IpListenEndpoint { + addr: local_endpoint_addr, + port: local_endpoint.port, + }; + } + udp_socket .bind(local_endpoint) .expect("Can't bind udp socket to local endpoint"); @@ -161,6 +184,10 @@ impl<'a> SchemeSocket for UdpSocket<'a> { ) -> SyscallResult> { let socket_handle = file.socket_handle(); let file = match path { + "listen" => { + // there's no accept() for UDP + return Err(SyscallError::new(syscall::EAFNOSUPPORT)); + } _ => { let remote_endpoint = parse_endpoint(path); if let SchemeFile::Socket(ref udp_handle) = *file { @@ -190,19 +217,36 @@ impl<'a> SchemeSocket for UdpSocket<'a> { } fn fpath(&self, file: &SchemeFile, buf: &mut [u8]) -> SyscallResult { - if let SchemeFile::Socket(ref socket_file) = *file { - let path = format!("udp:{}/{}", socket_file.data, self.endpoint()); - let path = path.as_bytes(); + let unspecified = "0.0.0.0:0"; + let mut path = String::from("/scheme/udp/"); - let mut i = 0; - while i < buf.len() && i < path.len() { - buf[i] = path[i]; - i += 1; + // remote + match file { + SchemeFile::Socket(SocketFile { data: endpoint, .. }) => { + if endpoint.is_specified() { + write!(&mut path, "{}", endpoint).unwrap() + } else { + write!(&mut path, "0.0.0.0:{}", endpoint.port).unwrap() + } } - - Ok(i) - } else { - Err(SyscallError::new(syscall::EBADF)) + _ => path.push_str(unspecified), } + path.push('/'); + // local + let endpoint = self.endpoint(); + if endpoint.is_specified() { + write!(&mut path, "{}", endpoint).unwrap() + } else { + write!(&mut path, "0.0.0.0:{}", endpoint.port).unwrap() + } + let path = path.as_bytes(); + + let mut i = 0; + while i < buf.len() && i < path.len() { + buf[i] = path[i]; + i += 1; + } + + Ok(i) } }