Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: smoltcp-rs/smoltcp
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: b971d91315a7
Choose a base ref
...
head repository: smoltcp-rs/smoltcp
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: ffe2de73c18a
Choose a head ref
  • 2 commits
  • 3 files changed
  • 1 contributor

Commits on Jul 24, 2017

  1. Rename RingBuffer::{dequeue_mut→dequeue}, remove RingBuffer::dequeue.

    There's nothing dequeue can do that dequeue_mut cannot.
    whitequark committed Jul 24, 2017
    Copy the full SHA
    f31f724 View commit details
  2. Copy the full SHA
    ffe2de7 View commit details
Showing with 49 additions and 64 deletions.
  1. +47 −49 src/iface/ethernet.rs
  2. +1 −1 src/socket/raw.rs
  3. +1 −14 src/storage/ring_buffer.rs
96 changes: 47 additions & 49 deletions src/iface/ethernet.rs
Original file line number Diff line number Diff line change
@@ -228,23 +228,21 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
Self::process_tcpv4(sockets, timestamp, ipv4_repr, ipv4_packet.payload()),
IpProtocol::Udp =>
Self::process_udpv4(sockets, timestamp, ipv4_repr, ipv4_packet.payload()),
_ if handled_by_raw_socket =>
Ok(Response::Nop),
_ => {
if handled_by_raw_socket {
Ok(Response::Nop)
} else {
let icmp_reply_repr = Icmpv4Repr::DstUnreachable {
reason: Icmpv4DstUnreachable::PortUnreachable,
header: ipv4_repr,
data: &ipv4_packet.payload()[0..8]
};
let ipv4_reply_repr = Ipv4Repr {
src_addr: ipv4_repr.dst_addr,
dst_addr: ipv4_repr.src_addr,
protocol: IpProtocol::Icmp,
payload_len: icmp_reply_repr.buffer_len()
};
Ok(Response::Icmpv4(ipv4_reply_repr, icmp_reply_repr))
}
let icmp_reply_repr = Icmpv4Repr::DstUnreachable {
reason: Icmpv4DstUnreachable::PortUnreachable,
header: ipv4_repr,
data: &ipv4_packet.payload()[0..8]
};
let ipv4_reply_repr = Ipv4Repr {
src_addr: ipv4_repr.dst_addr,
dst_addr: ipv4_repr.src_addr,
protocol: IpProtocol::Icmp,
payload_len: icmp_reply_repr.buffer_len()
};
Ok(Response::Icmpv4(ipv4_reply_repr, icmp_reply_repr))
}
}
}
@@ -281,6 +279,39 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
}
}

fn process_udpv4<'frame>(sockets: &mut SocketSet, timestamp: u64,
ipv4_repr: Ipv4Repr, ip_payload: &'frame [u8]) ->
Result<Response<'frame>, Error> {
let ip_repr = IpRepr::Ipv4(ipv4_repr);

for udp_socket in sockets.iter_mut().filter_map(
<Socket as AsSocket<UdpSocket>>::try_as_socket) {
match udp_socket.process(timestamp, &ip_repr, ip_payload) {
// The packet was valid and handled by socket.
Ok(()) => return Ok(Response::Nop),
// The packet wasn't addressed to the socket.
Err(Error::Rejected) => continue,
// The packet was addressed to the socket but is malformed.
Err(Error::Malformed) => break,
Err(e) => return Err(e)
}
}

//The packet wasn't handled by a socket, send an ICMP port unreachable packet.
let icmp_reply_repr = Icmpv4Repr::DstUnreachable {
reason: Icmpv4DstUnreachable::PortUnreachable,
header: ipv4_repr,
data: &ip_payload[0..8]
};
let ipv4_reply_repr = Ipv4Repr {
src_addr: ipv4_repr.dst_addr,
dst_addr: ipv4_repr.src_addr,
protocol: IpProtocol::Icmp,
payload_len: icmp_reply_repr.buffer_len()
};
Ok(Response::Icmpv4(ipv4_reply_repr, icmp_reply_repr))
}

fn process_tcpv4<'frame>(sockets: &mut SocketSet, timestamp: u64,
ipv4_repr: Ipv4Repr, ip_payload: &'frame [u8]) ->
Result<Response<'frame>, Error> {
@@ -327,39 +358,6 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
Ok(Response::Tcpv4(ipv4_reply_repr, tcp_reply_repr))
}

fn process_udpv4<'frame>(sockets: &mut SocketSet, timestamp: u64,
ipv4_repr: Ipv4Repr, ip_payload: &'frame [u8]) ->
Result<Response<'frame>, Error> {
let ip_repr = IpRepr::Ipv4(ipv4_repr);

for udp_socket in sockets.iter_mut().filter_map(
<Socket as AsSocket<UdpSocket>>::try_as_socket) {
match udp_socket.process(timestamp, &ip_repr, ip_payload) {
// The packet was valid and handled by socket.
Ok(()) => return Ok(Response::Nop),
// The packet wasn't addressed to the socket.
Err(Error::Rejected) => continue,
// The packet was addressed to the socket but is malformed.
Err(Error::Malformed) => break,
Err(e) => return Err(e)
}
}

//The packet wasn't handled by a socket, send an ICMP port unreachable packet.
let icmp_reply_repr = Icmpv4Repr::DstUnreachable {
reason: Icmpv4DstUnreachable::PortUnreachable,
header: ipv4_repr,
data: &ip_payload[0..8]
};
let ipv4_reply_repr = Ipv4Repr {
src_addr: ipv4_repr.dst_addr,
dst_addr: ipv4_repr.src_addr,
protocol: IpProtocol::Icmp,
payload_len: icmp_reply_repr.buffer_len()
};
Ok(Response::Icmpv4(ipv4_reply_repr, icmp_reply_repr))
}

fn send_response(&mut self, timestamp: u64, response: Response) -> Result<(), Error> {
macro_rules! ip_response {
($tx_buffer:ident, $frame:ident, $ip_repr:ident) => ({
2 changes: 1 addition & 1 deletion src/socket/raw.rs
Original file line number Diff line number Diff line change
@@ -176,7 +176,7 @@ impl<'a, 'b> RawSocket<'a, 'b> {
pub(crate) fn dispatch<F, R>(&mut self, _timestamp: u64, _limits: &DeviceLimits,
emit: &mut F) -> Result<R, Error>
where F: FnMut(&IpRepr, &IpPayload) -> Result<R, Error> {
let mut packet_buf = self.tx_buffer.dequeue_mut().map_err(|()| Error::Exhausted)?;
let mut packet_buf = self.tx_buffer.dequeue().map_err(|()| Error::Exhausted)?;
net_trace!("[{}]:{}:{}: sending {} octets",
self.debug_id, self.ip_version, self.ip_protocol,
packet_buf.size);
15 changes: 1 addition & 14 deletions src/storage/ring_buffer.rs
Original file line number Diff line number Diff line change
@@ -59,22 +59,9 @@ impl<'a, T: 'a> RingBuffer<'a, T> {
}
}

/// Dequeue an element from the buffer, and return a pointer to it, or return
/// `Err(())` if the buffer is empty.
pub fn dequeue(&mut self) -> Result<&T, ()> {
if self.empty() {
Err(())
} else {
self.length -= 1;
let result = &self.storage[self.read_at];
self.read_at = self.incr(self.read_at);
Ok(result)
}
}

/// Dequeue an element from the buffer, and return a mutable reference to it, or return
/// `Err(())` if the buffer is empty.
pub fn dequeue_mut(&mut self) -> Result<&mut T, ()> {
pub fn dequeue(&mut self) -> Result<&mut T, ()> {
if self.empty() {
Err(())
} else {