WIP: rebase fork onto upstream/main (v1.103.0) #15

Closed
codinget wants to merge 670 commits from webnet into save/webnet-2026-07-29
2 changed files with 54 additions and 0 deletions
Showing only changes of commit 1b2062f3c1 - Show all commits
+20
View File
@@ -1154,6 +1154,26 @@ func (t *Wrapper) injectedRead(res tunInjectedRead, outBuffs [][]byte, sizes []i
}
invertGSOChecksum(pkt, gso)
// Check if this is a packet for conn25-style app connectors,
// and perform the necessary NAT. The main case that requires
// NAT from netstack toward WireGuard is an SNAT on return traffic
// from the target application on the internet, translating
// the original server's source IP to the TransitIP.
// The hook can also perform DNAT for client-originated traffic,
// translating the destination MagicIP to a TransitIP, and rejects
// MagicIPs that have not been approved for the client.
//
// Normal non-connector traffic is forwarded unmodified.
//
// Cross-tailnet conn25 app connector connections are not supported,
// so at most one of this hook and the following pc.snat should modify the packet.
if t.PreFilterPacketOutboundToWireGuardAppConnectorIntercept != nil {
if r := t.PreFilterPacketOutboundToWireGuardAppConnectorIntercept(p, t); r.IsDrop() {
metricPacketOut.Add(1)
metricPacketOutDrop.Add(1)
return 0, nil
}
}
pc.snat(p)
invertGSOChecksum(pkt, gso)
+34
View File
@@ -28,6 +28,7 @@ import (
"tailscale.com/disco"
"tailscale.com/net/netaddr"
"tailscale.com/net/packet"
"tailscale.com/net/packet/checksum"
"tailscale.com/tstest"
"tailscale.com/tstime/mono"
"tailscale.com/types/ipproto"
@@ -1120,3 +1121,36 @@ func TestInterceptOrdering(t *testing.T) {
t.Errorf("got number of intercepts run in Read(): %d; want: %d", seq, numOutboundIntercepts)
}
}
func TestInjectedReadCallsAppConnectorHook(t *testing.T) {
var called bool
hook := func(p *packet.Parsed, _ *Wrapper) filter.Response {
called = true
checksum.UpdateSrcAddr(p, netip.MustParseAddr("169.254.0.1"))
return filter.Accept
}
bus := eventbustest.NewBus(t)
_, tun := newFakeTUN(t.Logf, bus, false)
tun.PreFilterPacketOutboundToWireGuardAppConnectorIntercept = hook
tun.Start()
defer tun.Close()
if err := tun.InjectOutbound(udp4("145.53.32.10", "100.25.63.57", 80, 12345)); err != nil {
t.Fatalf("InjectOutbound error: %v", err)
}
var buf [MaxPacketSize]byte
sizes := make([]int, 1)
tun.Read([][]byte{buf[:]}, sizes, 0)
if !called {
t.Error("app connector hook was not called in InjectOutbound")
}
wantPkt := udp4("169.254.0.1", "100.25.63.57", 80, 12345)
gotPkt := buf[:sizes[0]]
if !bytes.Equal(wantPkt, gotPkt) {
t.Errorf("packet mismatch\nwant:\t% x\ngot:\t% x", wantPkt, gotPkt)
}
}