@@ -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