Add flow PortWithSelectorRange
This commit is contained in:
parent
7c92d5e53e
commit
15b67423c3
2 changed files with 27 additions and 7 deletions
5
flow.go
5
flow.go
|
|
@ -73,6 +73,11 @@ type Port interface {
|
||||||
WritePackets(packets [][]byte) error
|
WritePackets(packets [][]byte) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PortWithSelectorRange interface {
|
||||||
|
Port
|
||||||
|
PortSelectorRange() (start uint16, count uint16)
|
||||||
|
}
|
||||||
|
|
||||||
type Return interface {
|
type Return interface {
|
||||||
ReturnHeadroom() int
|
ReturnHeadroom() int
|
||||||
ReturnPackets(packets [][]byte) [][]byte
|
ReturnPackets(packets [][]byte) [][]byte
|
||||||
|
|
|
||||||
21
flow_nat.go
21
flow_nat.go
|
|
@ -19,6 +19,8 @@ type portNAT struct {
|
||||||
hasher maphash.Hasher[flowKey]
|
hasher maphash.Hasher[flowKey]
|
||||||
shardMask uint32
|
shardMask uint32
|
||||||
shards []natShard
|
shards []natShard
|
||||||
|
selectorStart uint16
|
||||||
|
selectorCount uint16
|
||||||
|
|
||||||
counter uint32
|
counter uint32
|
||||||
pending [][]byte
|
pending [][]byte
|
||||||
|
|
@ -40,6 +42,9 @@ func newPortNAT(port Port) *portNAT {
|
||||||
shardMask: uint32(shardCount - 1),
|
shardMask: uint32(shardCount - 1),
|
||||||
shards: make([]natShard, shardCount),
|
shards: make([]natShard, shardCount),
|
||||||
}
|
}
|
||||||
|
if rangedPort, isRanged := port.(PortWithSelectorRange); isRanged {
|
||||||
|
nat.selectorStart, nat.selectorCount = rangedPort.PortSelectorRange()
|
||||||
|
}
|
||||||
for i := range nat.shards {
|
for i := range nat.shards {
|
||||||
nat.shards[i].flows = make(map[flowKey]*forwardFlow)
|
nat.shards[i].flows = make(map[flowKey]*forwardFlow)
|
||||||
}
|
}
|
||||||
|
|
@ -87,16 +92,26 @@ func (n *portNAT) reverseKeyFor(protocol uint8, portAddress, serverAddress netip
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *portNAT) selectorRange(protocol uint8) (uint16, uint32) {
|
||||||
|
if n.selectorCount == 0 ||
|
||||||
|
protocol == uint8(header.ICMPv4ProtocolNumber) || protocol == uint8(header.ICMPv6ProtocolNumber) {
|
||||||
|
return natSelectorMin, natSelectorMax - natSelectorMin + 1
|
||||||
|
}
|
||||||
|
return n.selectorStart, uint32(n.selectorCount)
|
||||||
|
}
|
||||||
|
|
||||||
func (n *portNAT) allocateSelector(protocol uint8, portAddress, serverAddress netip.Addr, serverPort, clientSelector uint16) (uint16, flowKey, bool) {
|
func (n *portNAT) allocateSelector(protocol uint8, portAddress, serverAddress netip.Addr, serverPort, clientSelector uint16) (uint16, flowKey, bool) {
|
||||||
if clientSelector != 0 {
|
rangeStart, rangeCount := n.selectorRange(protocol)
|
||||||
|
if clientSelector != 0 &&
|
||||||
|
clientSelector >= rangeStart && uint32(clientSelector-rangeStart) < rangeCount {
|
||||||
key := n.reverseKeyFor(protocol, portAddress, serverAddress, serverPort, clientSelector)
|
key := n.reverseKeyFor(protocol, portAddress, serverAddress, serverPort, clientSelector)
|
||||||
if n.lookup(key) == nil {
|
if n.lookup(key) == nil {
|
||||||
return clientSelector, key, true
|
return clientSelector, key, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for range natSelectorMax - natSelectorMin + 1 {
|
for range rangeCount {
|
||||||
n.counter++
|
n.counter++
|
||||||
candidate := uint16(natSelectorMin + n.counter%(natSelectorMax-natSelectorMin+1))
|
candidate := rangeStart + uint16(n.counter%rangeCount)
|
||||||
key := n.reverseKeyFor(protocol, portAddress, serverAddress, serverPort, candidate)
|
key := n.reverseKeyFor(protocol, portAddress, serverAddress, serverPort, candidate)
|
||||||
if n.lookup(key) == nil {
|
if n.lookup(key) == nil {
|
||||||
return candidate, key, true
|
return candidate, key, true
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue