Skip to content

Commit 503a780

Browse files
committed
Partially revert "Suppress ICMP error replies […]", still allow reception by other sockets.
This reverts commit f56666a. Adds another test case.
1 parent e6a6b16 commit 503a780

File tree

1 file changed

+110
-22
lines changed

1 file changed

+110
-22
lines changed

src/iface/ethernet.rs

Lines changed: 110 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -876,21 +876,20 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> {
876876
let ip_payload = ipv6_packet.payload();
877877

878878
#[cfg(feature = "socket-raw")]
879-
{
880-
if self.raw_socket_filter(sockets, &ipv6_repr.into(), ip_payload) {
881-
return Ok(Packet::None);
882-
}
883-
}
879+
let handled_by_raw_socket = self.raw_socket_filter(sockets, &ipv6_repr.into(), ip_payload);
880+
#[cfg(not(feature = "socket-raw"))]
881+
let handled_by_raw_socket = false;
884882

885-
self.process_nxt_hdr(sockets, timestamp, ipv6_repr, ipv6_repr.next_header, ip_payload)
883+
self.process_nxt_hdr(sockets, timestamp, ipv6_repr, ipv6_repr.next_header,
884+
handled_by_raw_socket, ip_payload)
886885
}
887886

888887
/// Given the next header value forward the payload onto the correct process
889888
/// function.
890889
#[cfg(feature = "proto-ipv6")]
891890
fn process_nxt_hdr<'frame>
892891
(&mut self, sockets: &mut SocketSet, timestamp: Instant, ipv6_repr: Ipv6Repr,
893-
nxt_hdr: IpProtocol, ip_payload: &'frame [u8])
892+
nxt_hdr: IpProtocol, handled_by_raw_socket: bool, ip_payload: &'frame [u8])
894893
-> Result<Packet<'frame>>
895894
{
896895
match nxt_hdr {
@@ -899,14 +898,18 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> {
899898

900899
#[cfg(feature = "socket-udp")]
901900
IpProtocol::Udp =>
902-
self.process_udp(sockets, ipv6_repr.into(), ip_payload),
901+
self.process_udp(sockets, ipv6_repr.into(), handled_by_raw_socket, ip_payload),
903902

904903
#[cfg(feature = "socket-tcp")]
905904
IpProtocol::Tcp =>
906905
self.process_tcp(sockets, timestamp, ipv6_repr.into(), ip_payload),
907906

908907
IpProtocol::HopByHop =>
909-
self.process_hopbyhop(sockets, timestamp, ipv6_repr, ip_payload),
908+
self.process_hopbyhop(sockets, timestamp, ipv6_repr, handled_by_raw_socket, ip_payload),
909+
910+
#[cfg(feature = "socket-raw")]
911+
_ if handled_by_raw_socket =>
912+
Ok(Packet::None),
910913

911914
_ => {
912915
// Send back as much of the original payload as we can.
@@ -970,10 +973,6 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> {
970973
}
971974

972975
match ipv4_repr.protocol {
973-
#[cfg(feature = "socket-raw")]
974-
_ if handled_by_raw_socket =>
975-
Ok(Packet::None),
976-
977976
IpProtocol::Icmp =>
978977
self.process_icmpv4(sockets, ip_repr, ip_payload),
979978

@@ -983,12 +982,16 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> {
983982

984983
#[cfg(feature = "socket-udp")]
985984
IpProtocol::Udp =>
986-
self.process_udp(sockets, ip_repr, ip_payload),
985+
self.process_udp(sockets, ip_repr, handled_by_raw_socket, ip_payload),
987986

988987
#[cfg(feature = "socket-tcp")]
989988
IpProtocol::Tcp =>
990989
self.process_tcp(sockets, timestamp, ip_repr, ip_payload),
991990

991+
#[cfg(feature = "socket-raw")]
992+
_ if handled_by_raw_socket =>
993+
Ok(Packet::None),
994+
992995
_ => {
993996
// Send back as much of the original payload as we can.
994997
let payload_len = icmp_reply_payload_len(ip_payload.len(), IPV4_MIN_MTU,
@@ -1170,7 +1173,8 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> {
11701173

11711174
#[cfg(feature = "proto-ipv6")]
11721175
fn process_hopbyhop<'frame>(&mut self, sockets: &mut SocketSet, timestamp: Instant,
1173-
ipv6_repr: Ipv6Repr, ip_payload: &'frame [u8]) -> Result<Packet<'frame>>
1176+
ipv6_repr: Ipv6Repr, handled_by_raw_socket: bool,
1177+
ip_payload: &'frame [u8]) -> Result<Packet<'frame>>
11741178
{
11751179
let hbh_pkt = Ipv6HopByHopHeader::new_checked(ip_payload)?;
11761180
let hbh_repr = Ipv6HopByHopRepr::parse(&hbh_pkt)?;
@@ -1195,7 +1199,7 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> {
11951199
}
11961200
}
11971201
self.process_nxt_hdr(sockets, timestamp, ipv6_repr, hbh_repr.next_header,
1198-
&ip_payload[hbh_repr.buffer_len()..])
1202+
handled_by_raw_socket, &ip_payload[hbh_repr.buffer_len()..])
11991203
}
12001204

12011205
#[cfg(feature = "proto-ipv4")]
@@ -1314,7 +1318,7 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> {
13141318

13151319
#[cfg(feature = "socket-udp")]
13161320
fn process_udp<'frame>(&self, sockets: &mut SocketSet,
1317-
ip_repr: IpRepr, ip_payload: &'frame [u8]) ->
1321+
ip_repr: IpRepr, handled_by_raw_socket: bool, ip_payload: &'frame [u8]) ->
13181322
Result<Packet<'frame>>
13191323
{
13201324
let (src_addr, dst_addr) = (ip_repr.src_addr(), ip_repr.dst_addr());
@@ -1336,6 +1340,12 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> {
13361340
// The packet wasn't handled by a socket, send an ICMP port unreachable packet.
13371341
match ip_repr {
13381342
#[cfg(feature = "proto-ipv4")]
1343+
IpRepr::Ipv4(_) if handled_by_raw_socket =>
1344+
Ok(Packet::None),
1345+
#[cfg(feature = "proto-ipv6")]
1346+
IpRepr::Ipv6(_) if handled_by_raw_socket =>
1347+
Ok(Packet::None),
1348+
#[cfg(feature = "proto-ipv4")]
13391349
IpRepr::Ipv4(ipv4_repr) => {
13401350
let payload_len = icmp_reply_payload_len(ip_payload.len(), IPV4_MIN_MTU,
13411351
ipv4_repr.buffer_len());
@@ -1957,7 +1967,7 @@ mod test {
19571967

19581968
// Ensure that the unknown protocol triggers an error response.
19591969
// And we correctly handle no payload.
1960-
assert_eq!(iface.inner.process_udp(&mut socket_set, ip_repr, data),
1970+
assert_eq!(iface.inner.process_udp(&mut socket_set, ip_repr, false, data),
19611971
Ok(expected_repr));
19621972

19631973
let ip_repr = IpRepr::Ipv4(Ipv4Repr {
@@ -1977,7 +1987,7 @@ mod test {
19771987
// ICMP error response when the destination address is a
19781988
// broadcast address and no socket is bound to the port.
19791989
assert_eq!(iface.inner.process_udp(&mut socket_set, ip_repr,
1980-
packet_broadcast.into_inner()), Ok(Packet::None));
1990+
false, packet_broadcast.into_inner()), Ok(Packet::None));
19811991
}
19821992

19831993
#[test]
@@ -2040,7 +2050,7 @@ mod test {
20402050
&ChecksumCapabilities::default());
20412051

20422052
// Packet should be handled by bound UDP socket
2043-
assert_eq!(iface.inner.process_udp(&mut socket_set, ip_repr, packet.into_inner()),
2053+
assert_eq!(iface.inner.process_udp(&mut socket_set, ip_repr, false, packet.into_inner()),
20442054
Ok(Packet::None));
20452055

20462056
{
@@ -2198,10 +2208,10 @@ mod test {
21982208
assert_eq!(expected_ip_repr.buffer_len() + expected_icmp_repr.buffer_len(), MIN_MTU);
21992209
// The expected packet and the generated packet are equal
22002210
#[cfg(all(feature = "proto-ipv4", not(feature = "proto-ipv6")))]
2201-
assert_eq!(iface.inner.process_udp(&mut socket_set, ip_repr.into(), payload),
2211+
assert_eq!(iface.inner.process_udp(&mut socket_set, ip_repr.into(), false, payload),
22022212
Ok(Packet::Icmpv4((expected_ip_repr, expected_icmp_repr))));
22032213
#[cfg(feature = "proto-ipv6")]
2204-
assert_eq!(iface.inner.process_udp(&mut socket_set, ip_repr.into(), payload),
2214+
assert_eq!(iface.inner.process_udp(&mut socket_set, ip_repr.into(), false, payload),
22052215
Ok(Packet::Icmpv6((expected_ip_repr, expected_icmp_repr))));
22062216
}
22072217

@@ -2645,4 +2655,82 @@ mod test {
26452655
assert_eq!(iface.inner.process_ipv4(&mut socket_set, Instant::from_millis(0), &frame),
26462656
Ok(Packet::None));
26472657
}
2658+
2659+
#[test]
2660+
#[cfg(all(feature = "proto-ipv4", feature = "socket-raw", feature = "socket-udp"))]
2661+
fn test_raw_socket_with_udp_socket() {
2662+
use socket::{UdpSocket, UdpSocketBuffer, UdpPacketMetadata,
2663+
RawSocket, RawSocketBuffer, RawPacketMetadata};
2664+
use wire::{IpVersion, IpEndpoint, Ipv4Packet, UdpPacket, UdpRepr};
2665+
2666+
static UDP_PAYLOAD: [u8; 5] = [0x48, 0x65, 0x6c, 0x6c, 0x6f];
2667+
2668+
let (mut iface, mut socket_set) = create_loopback();
2669+
2670+
let udp_rx_buffer = UdpSocketBuffer::new(vec![UdpPacketMetadata::EMPTY], vec![0; 15]);
2671+
let udp_tx_buffer = UdpSocketBuffer::new(vec![UdpPacketMetadata::EMPTY], vec![0; 15]);
2672+
let udp_socket = UdpSocket::new(udp_rx_buffer, udp_tx_buffer);
2673+
let udp_socket_handle = socket_set.add(udp_socket);
2674+
{
2675+
// Bind the socket to port 68
2676+
let mut socket = socket_set.get::<UdpSocket>(udp_socket_handle);
2677+
assert_eq!(socket.bind(68), Ok(()));
2678+
assert!(!socket.can_recv());
2679+
assert!(socket.can_send());
2680+
}
2681+
2682+
let packets = 1;
2683+
let raw_rx_buffer = RawSocketBuffer::new(vec![RawPacketMetadata::EMPTY; packets], vec![0; 48 * 1]);
2684+
let raw_tx_buffer = RawSocketBuffer::new(vec![RawPacketMetadata::EMPTY; packets], vec![0; 48 * packets]);
2685+
let raw_socket = RawSocket::new(IpVersion::Ipv4, IpProtocol::Udp, raw_rx_buffer, raw_tx_buffer);
2686+
socket_set.add(raw_socket);
2687+
2688+
let src_addr = Ipv4Address([127, 0, 0, 2]);
2689+
let dst_addr = Ipv4Address([127, 0, 0, 1]);
2690+
2691+
let udp_repr = UdpRepr {
2692+
src_port: 67,
2693+
dst_port: 68,
2694+
payload: &UDP_PAYLOAD
2695+
};
2696+
let mut bytes = vec![0xff; udp_repr.buffer_len()];
2697+
let mut packet = UdpPacket::new_unchecked(&mut bytes[..]);
2698+
udp_repr.emit(&mut packet, &src_addr.into(), &dst_addr.into(), &ChecksumCapabilities::default());
2699+
let ipv4_repr = Ipv4Repr {
2700+
src_addr: src_addr,
2701+
dst_addr: dst_addr,
2702+
protocol: IpProtocol::Udp,
2703+
hop_limit: 64,
2704+
payload_len: udp_repr.buffer_len()
2705+
};
2706+
2707+
// Emit to ethernet frame
2708+
let mut eth_bytes = vec![0u8;
2709+
EthernetFrame::<&[u8]>::header_len() +
2710+
ipv4_repr.buffer_len() + udp_repr.buffer_len()
2711+
];
2712+
let frame = {
2713+
let mut frame = EthernetFrame::new_unchecked(&mut eth_bytes);
2714+
ipv4_repr.emit(
2715+
&mut Ipv4Packet::new_unchecked(frame.payload_mut()),
2716+
&ChecksumCapabilities::default());
2717+
udp_repr.emit(
2718+
&mut UdpPacket::new_unchecked(
2719+
&mut frame.payload_mut()[ipv4_repr.buffer_len()..]),
2720+
&src_addr.into(),
2721+
&dst_addr.into(),
2722+
&ChecksumCapabilities::default());
2723+
EthernetFrame::new_unchecked(&*frame.into_inner())
2724+
};
2725+
2726+
assert_eq!(iface.inner.process_ipv4(&mut socket_set, Instant::from_millis(0), &frame),
2727+
Ok(Packet::None));
2728+
2729+
{
2730+
// Make sure the UDP socket can still receive in presence of a Raw socket that handles UDP
2731+
let mut socket = socket_set.get::<UdpSocket>(udp_socket_handle);
2732+
assert!(socket.can_recv());
2733+
assert_eq!(socket.recv(), Ok((&UDP_PAYLOAD[..], IpEndpoint::new(src_addr.into(), 67))));
2734+
}
2735+
}
26482736
}

0 commit comments

Comments
 (0)