tsnet: add UDP support to Server.Listen

No ListenPacket support yet, but Listen with a udp network type fit
easier into netstack's model to start.

Then added an example of using it to cmd/sniproxy with a little udp
:53 handler.

No tests in tsnet yet because we don't have support for dialing over
UDP in tsnet yet. When that's done, a new test can test both sides.

Updates #5871
Updates #1748

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2023-03-05 20:13:36 +00:00
committed by Brad Fitzpatrick
parent 9ff51ca17f
commit 0f4359116e
3 changed files with 130 additions and 16 deletions

View File

@@ -18,6 +18,7 @@ import (
"tailscale.com/client/tailscale"
"tailscale.com/net/netutil"
"tailscale.com/tsnet"
"tailscale.com/types/nettype"
)
var ports = flag.String("ports", "443", "comma-separated list of ports to proxy")
@@ -45,6 +46,13 @@ func main() {
log.Printf("Serving on port %v ...", portStr)
go s.serve(ln)
}
ln, err := s.ts.Listen("udp", ":53")
if err != nil {
log.Fatal(err)
}
go s.serveDNS(ln)
select {}
}
@@ -63,6 +71,25 @@ func (s *server) serve(ln net.Listener) {
}
}
func (s *server) serveDNS(ln net.Listener) {
for {
c, err := ln.Accept()
if err != nil {
log.Fatal(err)
}
go s.serveDNSConn(c.(nettype.ConnPacketConn))
}
}
func (s *server) serveDNSConn(c nettype.ConnPacketConn) {
defer c.Close()
c.SetReadDeadline(time.Now().Add(5 * time.Second))
buf := make([]byte, 1500)
n, err := c.Read(buf)
log.Printf("got DNS packet: %q, %v", buf[:n], err)
// TODO: rest of the owl
}
func (s *server) serveConn(c net.Conn) {
addrPortStr := c.LocalAddr().String()
_, port, err := net.SplitHostPort(addrPortStr)