google / netstack

IPv4 and IPv6 userland network stack
Apache License 2.0
3.09k stars 279 forks source link

udp.ForwarderRequest.CreateEndpoint doesn't set endpoint.effectiveNetProtos #27

Open neex opened 5 years ago

neex commented 5 years ago

The endpoint returned by udp.ForwarderRequest.CreateEndpoint doesn't have effectiveNetProtos filled (it's nil).

Maybe I'm missing something and I should do some initialization by hand?

There're two things that make me think this is not true:

  1. Endpoints returned by tcp.ForwarderRequest.CreateEndpoint have their effectiveNetProtos set.
  2. A test that uses udp.Forwarder at https://github.com/google/gvisor/blob/master/pkg/tcpip/adapters/gonet/gonet_test.go#L354 doesn't do anything more than CreateEndpoint.

Missing effectiveNetProtos means that such endpoint won't be closed correctly: while stack.RegisterTransportEndpoint is called with hardcoded netProtos in ForwarderRequest.CreateEndpoints, the UnregisterTransportEndpoint in endpoint.Close is called with netprotos == nil.

This means that the code as simple as

...
    var wq waiter.Queue
    f := udp.NewForwarder(s, func(r *udp.ForwarderRequest) {
        if zalupa, err := r.CreateEndpoint(&wq); err == nil {
            log.Printf("Packet received: %v", r.ID())
            zalupa.Close()
        }
    })
    s.SetTransportProtocolHandler(udp.ProtocolNumber, f.HandlePacket)
...

misses new packets if the source port is reused.

hbhasker commented 5 years ago

Do you mind filing this issue on github.com/google/gvisor and maybe send a pull request w/ a test?