Commit 3a92b2c4 authored by Romeo Disca's avatar Romeo Disca Committed by Jeremy Soller

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
parent a2a534f1
......@@ -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))
......
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<IcmpSocket<'static, 'static>>;
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::<IcmpSocket>(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> {
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment