> Where is it hanging? You can either panic or printf-debug your way to figuring out where threads are blocking. My guess is that the `conn.ReadFrom` loop is blocking in a forever.
Yes, this turned out to be exactly what was happening! I was blocking
in the read loop, hence not returning control back to netstack. After
putting the main for loop from the code above into a goroutine, it
works as expected.
> Returning n == 0 should be enough to indicate that there are, for now, no more bytes.
Very helpful, thank you.
> UDP connections aren't explicitly closed like TCP, so this might just never break out of the loop. It looks like we have a test that uses udp.NewForwarder here.
Also very helpful - thanks again.
>
> You don't need to clean up anything, but you do need to return control back to netstack. So starting a goroutine, as you're doing, is a good option.
>
> The rest of your questions are increasingly up to you and require separate design. You can "fan out" and "fan in" packets to/from the internet as you've described, but you'll need to decide where those packets go. You could implement this yourself in Go (we have some NAT support in gVisor, but it's not designed to be used outside of where we have it now), or you could use iptables, or you could use something simpler: you can proxy packets. You can do this as soon as they're received, or wait until later. You can "spoof" the source address directly by opening a host UDP socket and sending the payload to the same destination, and spawn goroutines to copy bytes in both directions. This last option isn't that much code, it just requires you to know where you're sending bytes.
Yes, this last option is what I want. I have it working now. I worry
though that I create a new endpoint each time I get a
udp.ForwarderRequest, and it's not exactly clear where I should close
the endpoint, since there isn't a clear notion of "closed" for the
other side of the proxied UDP connection (i.e the side that sends UDP
packets out to the internet via net.Dial). Won't this cause the number
of endpoints in the stack to grow unbounded over time?