move Port -> uint16 conversions to a wrapper proc
This commit is contained in:
parent
e814df7a67
commit
81a39f32c1
|
@ -9,7 +9,7 @@ const RandomPortCount = 10000
|
|||
proc min(a, b: uint16): uint16 =
|
||||
min(a.int32, b.int32).uint16
|
||||
|
||||
proc toUint16(p: Port): uint16 = uint16(p)
|
||||
proc toUInt16(p: Port): uint16 = uint16(p)
|
||||
|
||||
proc toPort(u: uint16): Port = Port(u)
|
||||
|
||||
|
@ -31,31 +31,29 @@ proc subtractOffset(port: uint16, offset: uint16, minValue = 1024'u16,
|
|||
return maxValue - offset + distanceToMinValue + 1
|
||||
return port - offset
|
||||
|
||||
proc predictPortRange*(localPort: Port, probedPorts: seq[Port]): seq[Port] =
|
||||
proc predictPortRange*(localPort: uint16, probedPorts: seq[uint16]): seq[uint16] =
|
||||
if probedPorts.len == 0:
|
||||
# No probed ports, so our only guess can be that the NAT is a cone-type NAT
|
||||
# and the port mapping preserves the local Port.
|
||||
return @[localPort]
|
||||
let localPortUint = localPort.uint16
|
||||
let probedPortsUint = probedPorts.map(toUint16)
|
||||
if probedPorts.len == 1:
|
||||
# Only one server was used for probing, so we cannot know if the NAT is
|
||||
# symmetric or not. We are trying the probed port (assuming cone-type NAT)
|
||||
# and the next port in a progressive sequence if applicable (assuming
|
||||
# symmetric NAT with progressive port mapping).
|
||||
result.add(probedPorts[0])
|
||||
if probedPortsUint[0] > localPortUint:
|
||||
let offset = probedPortsUint[0] - localPortUint
|
||||
result.add(Port(probedPortsUint[0].addOffset(offset)))
|
||||
elif probedPortsUint[0] < localPortUint:
|
||||
let offset = localPortUint - probedPortsUint[0]
|
||||
result.add(Port(probedPortsUint[0].subtractOffset(offset)))
|
||||
if probedPorts[0] > localPort:
|
||||
let offset = probedPorts[0] - localPort
|
||||
result.add(probedPorts[0].addOffset(offset))
|
||||
elif probedPorts[0] < localPort:
|
||||
let offset = localPort - probedPorts[0]
|
||||
result.add(probedPorts[0].subtractOffset(offset))
|
||||
return
|
||||
let deduplicatedPorts = probedPortsUint.deduplicate()
|
||||
let deduplicatedPorts = probedPorts.deduplicate()
|
||||
if deduplicatedPorts.len() == 1:
|
||||
# It looks like the NAT is a cone-type NAT.
|
||||
return deduplicatedPorts.map(toPort)
|
||||
let probedPortsSorted = probedPortsUint.sorted()
|
||||
return deduplicatedPorts
|
||||
let probedPortsSorted = probedPorts.sorted()
|
||||
let minPort = probedPortsSorted[probedPortsSorted.minIndex()]
|
||||
let maxPort = probedPortsSorted[probedPortsSorted.maxIndex()]
|
||||
var minDistance = uint16.high()
|
||||
|
@ -66,21 +64,21 @@ proc predictPortRange*(localPort: Port, probedPorts: seq[Port]): seq[Port] =
|
|||
minDistance = min(minDistance, distance)
|
||||
maxDistance = max(maxDistance, distance)
|
||||
if maxDistance < 10:
|
||||
if probedPortsUint.isSorted(Ascending):
|
||||
if probedPorts.isSorted(Ascending):
|
||||
# assume symmetric NAT with positive-progressive port mapping
|
||||
if minDistance == maxDistance:
|
||||
return @[Port(maxPort.addOffset(maxDistance))]
|
||||
return @[maxPort.addOffset(maxDistance)]
|
||||
else:
|
||||
for i in countup(0'u16, maxDistance):
|
||||
result.add(Port(minPort.addOffset(i)))
|
||||
result.add(minPort.addOffset(i))
|
||||
return
|
||||
if probedPortsUint.isSorted(Descending):
|
||||
if probedPorts.isSorted(Descending):
|
||||
# assume symmetric NAT with negative-progressive port mapping
|
||||
if minDistance == maxDistance:
|
||||
return @[Port(minPort.subtractOffset(maxDistance))]
|
||||
return @[minPort.subtractOffset(maxDistance)]
|
||||
else:
|
||||
for i in countup(0'u16, maxDistance):
|
||||
result.add(Port(maxPort.subtractOffset(i)))
|
||||
result.add(maxPort.subtractOffset(i))
|
||||
return
|
||||
# assume symmetric NAT with random port mapping
|
||||
randomize()
|
||||
|
@ -88,9 +86,12 @@ proc predictPortRange*(localPort: Port, probedPorts: seq[Port]): seq[Port] =
|
|||
maxPort + 1000'u16
|
||||
else:
|
||||
uint16.high - RandomPortCount
|
||||
result = newSeq[Port](RandomPortCount)
|
||||
result = newSeq[uint16](RandomPortCount)
|
||||
for i in 0'u16 .. RandomPortCount - 1'u16:
|
||||
result[i] = Port(first + i)
|
||||
result[i] = first + i
|
||||
|
||||
proc predictPortRange*(localPort: Port, probedPorts: seq[Port]): seq[Port] =
|
||||
predictPortRange(localPort.uint16, probedPorts.map(toUInt16)).map(toPort)
|
||||
|
||||
suite "port prediction tests":
|
||||
test "single port":
|
||||
|
|
Loading…
Reference in New Issue