mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-22 12:58:37 +00:00
make hard NAT work
Change-Id: Id7b4195639c7fbff17c5b52e3780a1fdbcefbd31 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
92c3a4ce9a
commit
38aa2687ac
@ -4,6 +4,8 @@ import (
|
|||||||
"math/rand/v2"
|
"math/rand/v2"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"tailscale.com/util/mak"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NATTable is what a NAT implementation is expected to do.
|
// NATTable is what a NAT implementation is expected to do.
|
||||||
@ -101,16 +103,16 @@ func (n *hardNAT) PickOutgoingSrc(src, dst netip.AddrPort, at time.Time) (wanSrc
|
|||||||
// Instead of proper data structures that would be efficient, we instead
|
// Instead of proper data structures that would be efficient, we instead
|
||||||
// just loop a bunch and look for a free port. This project is only used
|
// just loop a bunch and look for a free port. This project is only used
|
||||||
// by tests and doesn't care about performance, this is good enough.
|
// by tests and doesn't care about performance, this is good enough.
|
||||||
port := src.Port() // start with the port the client used? (TODO: does FreeBSD do this? make knob?)
|
|
||||||
for {
|
for {
|
||||||
|
port := rand.N(uint16(32<<10)) + 32<<10 // pick some "ephemeral" port
|
||||||
ki := hardKeyIn{wanPort: port, src: dst}
|
ki := hardKeyIn{wanPort: port, src: dst}
|
||||||
if _, ok := n.in[ki]; ok {
|
if _, ok := n.in[ki]; ok {
|
||||||
// Collision. Try again.
|
// Port already in use.
|
||||||
port = rand.N(uint16(32<<10)) + 32<<10 // pick some "ephemeral" port
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
n.in[ki] = lanAddrAndTime{lanAddr: src, at: at}
|
mak.Set(&n.in, ki, lanAddrAndTime{lanAddr: src, at: at})
|
||||||
n.out[ko] = portMappingAndTime{port: port, at: at}
|
mak.Set(&n.out, ko, portMappingAndTime{port: port, at: at})
|
||||||
|
return netip.AddrPortFrom(n.wanIP, port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,8 +162,8 @@ func (n *easyNAT) PickOutgoingSrc(src, dst netip.AddrPort, at time.Time) (wanSrc
|
|||||||
port := 32<<10 + (start + off)
|
port := 32<<10 + (start + off)
|
||||||
if _, ok := n.in[port]; !ok {
|
if _, ok := n.in[port]; !ok {
|
||||||
// Found a free port.
|
// Found a free port.
|
||||||
n.out[src] = portMappingAndTime{port: port, at: at}
|
mak.Set(&n.out, src, portMappingAndTime{port: port, at: at})
|
||||||
n.in[port] = lanAddrAndTime{lanAddr: src, at: at}
|
mak.Set(&n.in, port, lanAddrAndTime{lanAddr: src, at: at})
|
||||||
return netip.AddrPortFrom(n.wanIP, port)
|
return netip.AddrPortFrom(n.wanIP, port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.nodes[node1.mac] = node1
|
s.nodes[node1.mac] = node1
|
||||||
net1.SetNATTable(&oneToOneNAT{wanIP: net1.wanIP, lanIP: node1.lanIP})
|
net1.SetNATTable(&hardNAT{wanIP: net1.wanIP})
|
||||||
net2 := &network{
|
net2 := &network{
|
||||||
s: s,
|
s: s,
|
||||||
mac: MAC{0x52, 0x54, 0x00, 0x01, 0x01, 0x2},
|
mac: MAC{0x52, 0x54, 0x00, 0x01, 0x01, 0x2},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user