From 3a92b2c466062751dd9bc8a08ac916f9728e0b6d Mon Sep 17 00:00:00 2001 From: Romeo Disca Date: Mon, 21 May 2018 21:12:24 +0200 Subject: [PATCH] add udp support (#26) * icmp.rs add udp branches to read and write * add write_buf implementation to icmp udp port unreachable * add udp port support --- src/dnsd/scheme.rs | 2 +- src/smolnetd/scheme/icmp.rs | 51 ++++++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/dnsd/scheme.rs b/src/dnsd/scheme.rs index 1bcf69e1f6..b8fe1edf10 100644 --- a/src/dnsd/scheme.rs +++ b/src/dnsd/scheme.rs @@ -165,7 +165,7 @@ impl Domains { let domain = e.remove(); self.requested_timeouts .retain(|&(_, ref d)| d.as_ref() != domain.as_ref()); - if let Entry::Occupied(mut e) = self.domains.entry(domain) { + if let Entry::Occupied(e) = self.domains.entry(domain) { let domain_data = e.remove(); return if let Domain::Requested { waiting_fds, .. } = domain_data { Some(DnsParsingResult::FailFiles(waiting_fds)) diff --git a/src/smolnetd/scheme/icmp.rs b/src/smolnetd/scheme/icmp.rs index cacb9f6605..0e33c21c8c 100644 --- a/src/smolnetd/scheme/icmp.rs +++ b/src/smolnetd/scheme/icmp.rs @@ -1,5 +1,5 @@ use smoltcp::socket::{IcmpEndpoint, IcmpPacketBuffer, IcmpSocket, IcmpSocketBuffer, SocketHandle}; -use smoltcp::wire::{Icmpv4Packet, Icmpv4Repr, IpAddress}; +use smoltcp::wire::{Icmpv4Packet, Icmpv4Repr, IpAddress, IpEndpoint}; use std::mem; use std::str; use syscall::{Error as SyscallError, Result as SyscallResult}; @@ -15,6 +15,7 @@ pub type IcmpScheme = SocketScheme>; enum IcmpSocketType { Echo, + Udp, } pub struct IcmpData { @@ -111,6 +112,38 @@ impl<'a, 'b> SchemeSocket for IcmpSocket<'a, 'b> { }; Ok((handle, socket_data)) } + "udp" => { + let addr = parts + .next() + .ok_or_else(|| syscall::Error::new(syscall::EINVAL))?; + let ip = + IpAddress::from_str(addr).map_err(|_| syscall::Error::new(syscall::EINVAL))?; + + let mut rx_packets = Vec::with_capacity(Smolnetd::SOCKET_BUFFER_SIZE); + let mut tx_packets = Vec::with_capacity(Smolnetd::SOCKET_BUFFER_SIZE); + for _ in 0..Smolnetd::SOCKET_BUFFER_SIZE { + rx_packets.push(IcmpPacketBuffer::new(vec![0; NetworkDevice::MTU])); + } + + let socket = IcmpSocket::new( + IcmpSocketBuffer::new(rx_packets), + IcmpSocketBuffer::new(tx_packets), + ); + let handle = socket_set.add(socket); + let mut icmp_socket = socket_set.get::(handle); + let ident = ident_set + .get_port() + .ok_or_else(|| SyscallError::new(syscall::EINVAL))?; + icmp_socket + .bind(IcmpEndpoint::Udp(IpEndpoint::from(ident))) + .map_err(|_| syscall::Error::new(syscall::EINVAL))?; + let socket_data = IcmpData { + socket_type: IcmpSocketType::Udp, + ident, + ip, + }; + Ok((handle, socket_data)) + } _ => Err(syscall::Error::new(syscall::EINVAL)), } } @@ -152,6 +185,9 @@ impl<'a, 'b> SchemeSocket for IcmpSocket<'a, 'b> { icmp_repr.emit(&mut icmp_packet, &Default::default()); Ok(buf.len()) } + IcmpSocketType::Udp => { + Err(SyscallError::new(syscall::EINVAL)) + } } } else if file.flags & syscall::O_NONBLOCK == syscall::O_NONBLOCK { Ok(0) @@ -214,6 +250,18 @@ impl<'a, 'b> SchemeSocket for IcmpSocket<'a, 'b> { i += 1; } + Ok(i) + } + IcmpSocketType::Udp => { + let path = format!("icmp:udp/{}", socket_file.data.ip); + let path = path.as_bytes(); + + let mut i = 0; + while i < buf.len() && i < path.len() { + buf[i] = path[i]; + i += 1; + } + Ok(i) } } @@ -222,3 +270,4 @@ impl<'a, 'b> SchemeSocket for IcmpSocket<'a, 'b> { } } } +