google / gvisor

Application Kernel for Containers
https://gvisor.dev
Apache License 2.0
15.63k stars 1.29k forks source link

Not Sending 'Destination Unreachable' for UDP Traceroute #703

Closed chunyingw closed 5 years ago

chunyingw commented 5 years ago

Traceroute to the Fuchsia device over a direct connection seems to work on everything except UDP. $ sudo traceroute -6 -T $(fx netaddr --fuchsia) traceroute to fe80::4607:bff:febb:3063%enx44070bbb3062 (fe80::4607:bff:febb:3063%enx44070bbb3062), 30 hops max, 80 byte packets 1 fe80::4607:bff:febb:3063%enx44070bbb3062 (fe80::4607:bff:febb:3063%enx44070bbb3062) 0.319 ms 0.293 ms 0.300 ms $ sudo traceroute -6 -I $(fx netaddr --fuchsia) traceroute to fe80::4607:bff:febb:3063%enx44070bbb3062 (fe80::4607:bff:febb:3063%enx44070bbb3062), 30 hops max, 80 byte packets

$ traceroute -6 $(fx netaddr --fuchsia) traceroute to fe80::4607:bff:febb:3063%enx44070bbb3062 (fe80::4607:bff:febb:3063%enx44070bbb3062), 30 hops max, 80 byte packets 1 2 3 4 5 * .... 30 hops ....

tamird commented 5 years ago

@mrahatm is this your area?

hbhasker commented 5 years ago

I will take a look at this today. I will see if i can reproduce this in runsc and figure out the issue.

hbhasker commented 5 years ago

So I ran a small test with runsc under docker and what I see is the following.

On linux we see a clear ICMP destination unreachable message for UDP probes

09:00:30.364523 IP 192.168.9.1.36847 > 192.168.9.2.domain: 16449 op8 [b2&3=0x4243] [17991a] [17477q] [18505n] [19019au][|domain] 09:00:30.364566 IP 192.168.9.2 > 192.168.9.1: ICMP 192.168.9.2 udp port domain unreachable, length 68 09:00:30.364632 IP 192.168.9.1.51045 > 192.168.9.2.domain: 16449 op8 [b2&3=0x4243] [17991a] [17477q] [18505n] [19019au][|domain] 09:00:30.364641 IP 192.168.9.2 > 192.168.9.1: ICMP 192.168.9.2 udp port domain unreachable, length 68 09:00:30.364692 IP 192.168.9.1.60801 > 192.168.9.2.domain: 16449 op8 [b2&3=0x4243] [17991a] [17477q] [18505n] [19019au][|domain] 09:00:30.364699 IP 192.168.9.2 > 192.168.9.1: ICMP 192.168.9.2 udp port domain unreachable, length 68

On Netstack we do not send it and the reason is the UDP endpoint code to handle unknown destination does exactly nothing.

https://github.com/google/gvisor/blob/master/pkg/tcpip/transport/udp/protocol.go#L72

We should probably just generate an ICMP Destination unreachable message at this point.

hbhasker commented 5 years ago

This is exactly what linux does too here https://github.com/torvalds/linux/blob/master/net/ipv4/udp.c#L2307

hbhasker commented 5 years ago

As per RFC 1122 4.1.3 SPECIFIC ISSUES

     4.1.3.1  Ports

        UDP well-known ports follow the same rules as TCP well-known
        ports; see Section 4.2.2.1 below.

        If a datagram arrives addressed to a UDP port for which
        there is no pending LISTEN call, UDP SHOULD send an ICMP
        Port Unreachable message.

And From section 3.2.2.2 of the same RFC

3.2.2.1 Destination Unreachable: RFC-792

        The following additional codes are hereby defined:

                6 = destination network unknown

Internet Engineering Task Force [Page 39]

RFC1122 INTERNET LAYER October 1989

                7 = destination host unknown

                8 = source host isolated

                9 = communication with destination network
                        administratively prohibited

               10 = communication with destination host
                        administratively prohibited

               11 = network unreachable for type of service

               12 = host unreachable for type of service

        A host SHOULD generate Destination Unreachable messages with
        code:

        2    (Protocol Unreachable), when the designated transport
             protocol is not supported; or

        3    (Port Unreachable), when the designated transport
             protocol (e.g., UDP) is unable to demultiplex the
             datagram but has no protocol mechanism to inform the
             sender.

        A Destination Unreachable message that is received MUST be
        reported to the transport layer.  The transport layer SHOULD
        use the information appropriately; for example, see Sections
        4.1.3.3, 4.2.3.9, and 4.2.4 below.  A transport protocol
        that has its own mechanism for notifying the sender that a
        port is unreachable (e.g., TCP, which sends RST segments)
        MUST nevertheless accept an ICMP Port Unreachable for the
        same purpose.

        A Destination Unreachable message that is received with code
        0 (Net), 1 (Host), or 5 (Bad Source Route) may result from a
        routing transient and MUST therefore be interpreted as only
        a hint, not proof, that the specified destination is
        unreachable [IP:11].  For example, it MUST NOT be used as
        proof of a dead gateway (see Section 3.3.1).
chunyingw commented 5 years ago

That's right, the final destination will return an ICMP "port unreachable" message. But from gVisor code base, it seems it's not processing the incoming UDP packet and no response was sent back. Are you able to try the following command on gVisor. The following result is what I got on Linux. ~$ traceroute -6 2001:4860:4860::8888 traceroute to 2001:4860:4860::8888 (2001:4860:4860::8888), 30 hops max, 80 byte packets 1 us-nyc-9th-core1-irb-275.n.corp.google.com (2620:0:1003:511::2) 0.376 ms 0.315 ms 0.327 ms 2 us-nyc-8510-bb1-ae3-0.n.corp.google.com (2620:0:1003:1077::e) 0.325 ms us-nyc-9th-bb1-ae3-0.n.corp.google.com (2620:0:1003:1077::a) 0.320 ms 0.300 ms 3 us-nyc-9th-br1-ae2-704.n.corp.google.com (2620:0:1003:1077::2) 0.431 ms us-nyc-8510-br1-ae2-705.n.corp.google.com (2620:0:1003:1077::6) 0.896 ms us-nyc-8510-br1-ae1-706.n.corp.google.com (2620:0:1003:1077::4) 0.465 ms 4 pr03-xe-9-0-1-511.lga07.net.google.com (2001:4860:1:1::1133) 0.451 ms pr03-xe-1-3-1-511.lga07.net.google.com (2001:4860:1:1::1135) 0.548 ms pr01-xe-11-2-1-511.lga26.net.google.com (2001:4860:1:1::117b) 0.613 ms 5 cx01-vl100.lga34.net.google.com (2001:4860:0:1126::1) 1.947 ms cx02-vl100.lga34.net.google.com (2001:4860:0:1128::1) 0.850 ms cx01-vl100.lga25.net.google.com (2001:4860:0:1125::1) 2.068 ms 6 sr10-pc51.lga25.net.google.com (2001:4860:0:1::2627) 1.246 ms sr03-pc51.lga25.net.google.com (2001:4860:0:1::1ced) 1.274 ms sr05-pc51.lga25.net.google.com (2001:4860:0:1::1cf5) 1.298 ms 7 dns.google (2001:4860:4860::8888) 1.085 ms 1.088 ms 0.779 ms