Skip to content

Commit

Permalink
register tailscale+udp network for HTTP3
Browse files Browse the repository at this point in the history
Updates #33

Signed-off-by: Will Norris <will@tailscale.com>
  • Loading branch information
willnorris committed Jun 2, 2024
1 parent a24e950 commit 0ab0d8e
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 5 deletions.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
github.com/caddyserver/caddy/v2 v2.8.4
github.com/google/go-cmp v0.6.0
go.uber.org/zap v1.27.0
tailscale.com v1.67.0-pre.0.20240510224123-fc1ae97e1037
tailscale.com v1.67.0-pre.0.20240602160856-30bd3ffdd3e8
)

require (
Expand Down Expand Up @@ -110,6 +110,7 @@ require (
github.com/pierrec/lz4/v4 v4.1.21 // indirect
github.com/pires/go-proxyproto v0.7.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus-community/pro-bing v0.4.0 // indirect
github.com/prometheus/client_golang v1.19.1 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.48.0 // indirect
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/prometheus-community/pro-bing v0.4.0 h1:YMbv+i08gQz97OZZBwLyvmmQEEzyfyrrjEaAchdy3R4=
github.com/prometheus-community/pro-bing v0.4.0/go.mod h1:b7wRYZtCcPmt4Sz319BykUU241rWLe1VFXyiyWK/dH4=
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
Expand Down Expand Up @@ -748,5 +750,5 @@ nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q=
nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c=
software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k=
software.sslmate.com/src/go-pkcs12 v0.4.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI=
tailscale.com v1.67.0-pre.0.20240510224123-fc1ae97e1037 h1:ZrUO++qvsCa1jRyg5QI2mrEY3/LgEg4UETvYwgFAIYw=
tailscale.com v1.67.0-pre.0.20240510224123-fc1ae97e1037/go.mod h1:99BIV4U3UPw36Sva04xK2ZsEpVRUkY9jCdEDSAhaNGM=
tailscale.com v1.67.0-pre.0.20240602160856-30bd3ffdd3e8 h1:XnIXLknCk4pIgFA/3iddz9D9nN7UiC4FTRIOmQ/+nRI=
tailscale.com v1.67.0-pre.0.20240602160856-30bd3ffdd3e8/go.mod h1:fI1Vx71PB5JSJv93FKNSmdD0X5QnBuGllLk67AmeNRo=
46 changes: 44 additions & 2 deletions module.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,26 @@ import (
"crypto/tls"
"fmt"
"net"
"net/netip"
"os"
"path/filepath"
"strconv"
"strings"

"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
"go.uber.org/zap"
"tailscale.com/tsnet"
)

func init() {
caddy.RegisterNetwork("tailscale", getPlainListener)
caddy.RegisterNetwork("tailscale", getTCPListener)
caddy.RegisterNetwork("tailscale+tls", getTLSListener)
caddy.RegisterNetwork("tailscale+udp", getUDPListener)
caddyhttp.RegisterNetworkHTTP3("tailscale", "tailscale+udp")
}

func getPlainListener(c context.Context, _ string, addr string, _ net.ListenConfig) (any, error) {
func getTCPListener(c context.Context, _ string, addr string, _ net.ListenConfig) (any, error) {
ctx, ok := c.(caddy.Context)
if !ok {
return nil, fmt.Errorf("context is not a caddy.Context: %T", c)
Expand Down Expand Up @@ -78,6 +83,43 @@ func getTLSListener(c context.Context, _ string, addr string, _ net.ListenConfig
return ln, nil
}

func getUDPListener(c context.Context, _ string, addr string, _ net.ListenConfig) (any, error) {
ctx, ok := c.(caddy.Context)
if !ok {
return nil, fmt.Errorf("context is not a caddy.Context: %T", c)
}

network, host, port, err := caddy.SplitNetworkAddress(addr)
if err != nil {
return nil, err
}

s, err := getNode(ctx, host)
if err != nil {
return nil, err
}

st, err := s.Up(context.Background())
if err != nil {
return nil, err
}

if network == "" {
network = "udp4"

}
var ap netip.AddrPort
for _, ip := range st.TailscaleIPs {
// TODO(will): watch for Tailscale IP changes and update listener
if (network == "udp4" && ip.Is4()) || (network == "udp6" && ip.Is6()) {
p, _ := strconv.Atoi(port)
ap = netip.AddrPortFrom(ip, uint16(p))
break
}
}
return s.Server.ListenPacket(network, ap.String())
}

// nodes are the Tailscale nodes that have been configured and started.
// Node configuration comes from the global Tailscale Caddy app.
// When nodes are no longer in used (e.g. all listeners have been closed), they are shutdown.
Expand Down

0 comments on commit 0ab0d8e

Please sign in to comment.