mirror of
https://github.com/logos-storage/logos-storage-nim.git
synced 2026-03-19 18:53:12 +00:00
chore: making it compile
This commit is contained in:
parent
a816201f50
commit
56a1b664b5
@ -10,7 +10,6 @@
|
||||
|
||||
import std/[options, os, strutils, times, net, atomics]
|
||||
|
||||
import pkg/stew/objects
|
||||
import pkg/nat_traversal/[miniupnpc, natpmp]
|
||||
import pkg/json_serialization/std/net
|
||||
import pkg/results
|
||||
@ -40,6 +39,9 @@ type PortMappingStrategy* = enum
|
||||
type MappingPort* = ref object of RootObj
|
||||
value*: Port
|
||||
|
||||
proc `$`(p: MappingPort): string =
|
||||
$(p.value)
|
||||
|
||||
type TcpPort* = ref object of MappingPort
|
||||
type UdpPort* = ref object of MappingPort
|
||||
|
||||
@ -49,7 +51,7 @@ proc newTcpMappingPort*(value: Port): TcpPort =
|
||||
proc newUdpMappingPort*(value: Port): UdpPort =
|
||||
UdpPort(value: value)
|
||||
|
||||
type PortMapping = tuple[internalPort: MappingPort, externalPort: Option[MappingPort]]
|
||||
type PortMapping* = tuple[internalPort: MappingPort, externalPort: Option[MappingPort]]
|
||||
type RenewelThreadArgs =
|
||||
tuple[strategy: PortMappingStrategy, portMapping: seq[PortMapping]]
|
||||
|
||||
@ -150,7 +152,7 @@ proc upnpPortMapping(
|
||||
|
||||
if pmres.isErr:
|
||||
error "UPnP port mapping", msg = pmres.error
|
||||
return failure(pmres.error)
|
||||
return failure($pmres.error)
|
||||
|
||||
# let's check it
|
||||
let cres = upnp.getSpecificPortMapping(
|
||||
@ -175,22 +177,23 @@ proc npmpPortMapping(
|
||||
internalPort = internalPort.value
|
||||
protocol = protocol
|
||||
|
||||
without extPort =?
|
||||
npmp.addPortMapping(
|
||||
eport = externalPort.value,
|
||||
iport = internalPort.value,
|
||||
protocol = protocol,
|
||||
lifetime = Pmp_LIFETIME,
|
||||
), err:
|
||||
error "NAT-PMP port mapping error", msg = err.msg
|
||||
return failure(err.msg)
|
||||
let extPortRes = npmp.addPortMapping(
|
||||
eport = externalPort.value.cushort,
|
||||
iport = internalPort.value.cushort,
|
||||
protocol = protocol,
|
||||
lifetime = Pmp_LIFETIME,
|
||||
)
|
||||
|
||||
if extPortRes.isErr:
|
||||
error "NAT-PMP port mapping error", msg = extPortRes.error()
|
||||
return failure(extPortRes.error())
|
||||
|
||||
info "NAT-PMP: added port mapping"
|
||||
|
||||
if internalPort is TcpPort:
|
||||
return success(newTcpMappingPort(extPort))
|
||||
return success(MappingPort(newTcpMappingPort(Port(extPortRes.value))))
|
||||
else:
|
||||
return success(newUdpMappingPort(extPort))
|
||||
return success(MappingPort(newUdpMappingPort(Port(extPortRes.value))))
|
||||
|
||||
## Create port mapping that will try to utilize the same port number
|
||||
## of the internal port for the external port mapping.
|
||||
@ -217,118 +220,6 @@ proc doPortMapping(
|
||||
|
||||
return failure("No active startegy")
|
||||
|
||||
## Gets external IP provided by the port mapping protocols
|
||||
## Port mapping needs to be succesfully started first using `startPortMapping()`
|
||||
proc getExternalIP*(): ?IpAddress =
|
||||
if upnp == nil and npmp == nil:
|
||||
warn "No available port-mapping protocol"
|
||||
return IpAddress.none
|
||||
|
||||
if upnp != nil:
|
||||
let ires = upnp.externalIPAddress
|
||||
if ires.isOk():
|
||||
info "Got externa IP address: " & ires.value, ip = ires.value
|
||||
return parseIpAddress(ires.value).some
|
||||
else:
|
||||
debug "Getting external IP address using UPnP failed",
|
||||
msg = ires.error, protocol = "upnp"
|
||||
|
||||
if npmp != nil:
|
||||
let nires = npmp.externalIPAddress()
|
||||
if nires.isErr:
|
||||
debug "Getting external IP address using NAT-PMP failed", msg = nires.error
|
||||
else:
|
||||
try:
|
||||
info "Got externa IP address: " & $(nires.value),
|
||||
ip =$ (nires.value), protocol = "npmp"
|
||||
return parseIpAddress($(nires.value)).some
|
||||
except ValueError as e:
|
||||
error "parseIpAddress() exception", err = e.msg
|
||||
|
||||
return IpAddress.none
|
||||
|
||||
proc startPortMapping*(
|
||||
strategy: PortMappingStrategy, internalPorts: seq[MappingPort]
|
||||
): ?!seq[PortMapping] =
|
||||
if strategy == PortMappingStrategy.None:
|
||||
return failure("No port mapping strategy requested")
|
||||
|
||||
if internalPorts.len == 0:
|
||||
return failure("No internal ports to be mapped were supplied")
|
||||
|
||||
strategy = initProtocols(strategy)
|
||||
if strategy == PortMappingStrategy.None:
|
||||
return failure("No available port mapping protocols on the network")
|
||||
|
||||
portMapping = newSeqOfCap[PortMappings](internalPorts.len)
|
||||
|
||||
for port in internalPorts:
|
||||
without mappedPort =? doPortMapping(port), err:
|
||||
warn "Failed to map port", port = port.value, msg = err.msg
|
||||
portMapping.add((internalPort: port, externalPort: MappingPort.none))
|
||||
|
||||
portMapping.add((internalPort: port, externalPort: mappedPort.some))
|
||||
|
||||
startRenewalThread(strategy)
|
||||
|
||||
return success(externalPorts)
|
||||
|
||||
proc stopPortMapping*() =
|
||||
if upnp == nil or npmp == nil:
|
||||
debug "Port mapping is not running, nothing to stop"
|
||||
return
|
||||
|
||||
info "Stopping port mapping renewal threads"
|
||||
try:
|
||||
portMappingExiting.store(true)
|
||||
renewalThread.join()
|
||||
except CatchableError as exc:
|
||||
warn "Failed to stop port mapping renewal thread", exc = exc.msg
|
||||
|
||||
for mapping in portMapping:
|
||||
if upnp != nil:
|
||||
let protocol =
|
||||
if (internalPort is TcpPort): UPNPProtocol.TCP else: UPNPProtocol.UDP
|
||||
|
||||
if err =?
|
||||
upnp.deletePortMapping(
|
||||
externalPort = $(mapping.externalPort.value), protocol = protocol
|
||||
).errorOption:
|
||||
error "UPnP port mapping deletion error", msg = err.msg
|
||||
else:
|
||||
debug "UPnP: deleted port mapping",
|
||||
externalPort = mapping.externalPort,
|
||||
internalPort = mapping.internalPort,
|
||||
protocol = protocol
|
||||
|
||||
if npnp != nil:
|
||||
let protocol =
|
||||
if (internalPort is TcpPort): NatPmpProtocol.TCP else: NatPmpProtocol.UDP
|
||||
|
||||
if err =?
|
||||
npmp.deletePortMapping(
|
||||
eport = mapping.externalPort.value,
|
||||
iport = mapping.internalPort.value,
|
||||
protocol = protocol,
|
||||
).errorOption:
|
||||
error "NAT-PMP port mapping deletion error", msg = err.msg
|
||||
else:
|
||||
debug "NAT-PMP: deleted port mapping",
|
||||
externalPort = mapping.externalPort,
|
||||
internalPort = mapping.internalPort,
|
||||
protocol = protocol
|
||||
|
||||
proc startRenewalThread(
|
||||
strategy: PortMappingStrategy,
|
||||
internalPorts: seq[MappingPort],
|
||||
externalPorts: seq[?MappingPort],
|
||||
) =
|
||||
try:
|
||||
renewalThread = Thread[RenewelThreadArgs]()
|
||||
renewalThread.createThread(renewPortMapping, (strategy, portMapping))
|
||||
except CatchableError as exc:
|
||||
warn "Failed to create NAT port mapping renewal thread", exc = exc.msg
|
||||
|
||||
proc renewPortMapping(args: RenewelThreadArgs) {.thread, raises: [ValueError].} =
|
||||
ignoreSignalsInThread()
|
||||
let
|
||||
@ -361,3 +252,121 @@ proc renewPortMapping(args: RenewelThreadArgs) {.thread, raises: [ValueError].}
|
||||
lastUpdate = now()
|
||||
|
||||
sleep(sleepDuration)
|
||||
|
||||
proc startRenewalThread(strategy: PortMappingStrategy) =
|
||||
try:
|
||||
renewalThread = Thread[RenewelThreadArgs]()
|
||||
renewalThread.createThread(renewPortMapping, (strategy, mappings))
|
||||
except CatchableError as exc:
|
||||
warn "Failed to create NAT port mapping renewal thread", exc = exc.msg
|
||||
|
||||
## Gets external IP provided by the port mapping protocols
|
||||
## Port mapping needs to be succesfully started first using `startPortMapping()`
|
||||
proc getExternalIP*(): ?IpAddress =
|
||||
if upnp == nil and npmp == nil:
|
||||
warn "No available port-mapping protocol"
|
||||
return IpAddress.none
|
||||
|
||||
if upnp != nil:
|
||||
let ires = upnp.externalIPAddress
|
||||
if ires.isOk():
|
||||
info "Got externa IP address", ip = ires.value
|
||||
try:
|
||||
return parseIpAddress(ires.value).some
|
||||
except ValueError as e:
|
||||
error "Failed to parse IP address", err = e.msg
|
||||
else:
|
||||
debug "Getting external IP address using UPnP failed",
|
||||
msg = ires.error, protocol = "upnp"
|
||||
|
||||
if npmp != nil:
|
||||
let nires = npmp.externalIPAddress()
|
||||
if nires.isErr:
|
||||
debug "Getting external IP address using NAT-PMP failed", msg = nires.error
|
||||
else:
|
||||
try:
|
||||
info "Got externa IP address", ip = $(nires.value), protocol = "npmp"
|
||||
return parseIpAddress($(nires.value)).some
|
||||
except ValueError as e:
|
||||
error "Failed to parse IP address", err = e.msg
|
||||
|
||||
return IpAddress.none
|
||||
|
||||
proc startPortMapping*(
|
||||
strategy: var PortMappingStrategy, internalPorts: seq[MappingPort]
|
||||
): ?!seq[PortMapping] =
|
||||
if strategy == PortMappingStrategy.None:
|
||||
return failure("No port mapping strategy requested")
|
||||
|
||||
if internalPorts.len == 0:
|
||||
return failure("No internal ports to be mapped were supplied")
|
||||
|
||||
strategy = initProtocols(strategy)
|
||||
if strategy == PortMappingStrategy.None:
|
||||
return failure("No available port mapping protocols on the network")
|
||||
|
||||
if mappings.len > 0:
|
||||
return failure("Port mapping was already started! Stop first before re-starting.")
|
||||
|
||||
mappings = newSeqOfCap[PortMapping](internalPorts.len)
|
||||
|
||||
for port in internalPorts:
|
||||
without mappedPort =? doPortMapping(port), err:
|
||||
warn "Failed to map port", port = port, msg = err.msg
|
||||
mappings.add((internalPort: port, externalPort: MappingPort.none))
|
||||
|
||||
mappings.add((internalPort: port, externalPort: mappedPort.some))
|
||||
|
||||
startRenewalThread(strategy)
|
||||
|
||||
return success(mappings)
|
||||
|
||||
proc stopPortMapping*() =
|
||||
if upnp == nil or npmp == nil:
|
||||
debug "Port mapping is not running, nothing to stop"
|
||||
return
|
||||
|
||||
info "Stopping port mapping renewal threads"
|
||||
try:
|
||||
portMappingExiting.store(true)
|
||||
renewalThread.joinThread()
|
||||
except CatchableError as exc:
|
||||
warn "Failed to stop port mapping renewal thread", exc = exc.msg
|
||||
|
||||
for mapping in mappings:
|
||||
if mapping.externalPort.isNone:
|
||||
continue
|
||||
|
||||
if upnp != nil:
|
||||
let protocol =
|
||||
if (mapping.internalPort is TcpPort): UPNPProtocol.TCP else: UPNPProtocol.UDP
|
||||
|
||||
if err =?
|
||||
upnp.deletePortMapping(
|
||||
externalPort = $((!mapping.externalPort).value), protocol = protocol
|
||||
).errorOption:
|
||||
error "UPnP port mapping deletion error", msg = err
|
||||
else:
|
||||
debug "UPnP: deleted port mapping",
|
||||
externalPort = !mapping.externalPort,
|
||||
internalPort = mapping.internalPort,
|
||||
protocol = protocol
|
||||
|
||||
if npmp != nil:
|
||||
let protocol =
|
||||
if (mapping.internalPort is TcpPort): NatPmpProtocol.TCP else: NatPmpProtocol.UDP
|
||||
|
||||
if err =?
|
||||
npmp.deletePortMapping(
|
||||
eport = (!mapping.externalPort).value.cushort,
|
||||
iport = mapping.internalPort.value.cushort,
|
||||
protocol = protocol,
|
||||
).errorOption:
|
||||
error "NAT-PMP port mapping deletion error", msg = err
|
||||
else:
|
||||
debug "NAT-PMP: deleted port mapping",
|
||||
externalPort = !mapping.externalPort,
|
||||
internalPort = mapping.internalPort,
|
||||
protocol = protocol
|
||||
|
||||
mappings = @[]
|
||||
|
||||
@ -10,6 +10,7 @@ import pkg/libp2p/protocols/connectivity/autonat/service
|
||||
|
||||
import ../rng as random
|
||||
import ./port_mapping
|
||||
import ./utils
|
||||
|
||||
const AutonatCheckInterval = Opt.some(chronos.seconds(30))
|
||||
|
||||
@ -34,11 +35,53 @@ proc new*(
|
||||
): T =
|
||||
return T(portMappingStrategy: portMappingStrategy)
|
||||
|
||||
proc startPortMapping(self: ReachabilityManager): bool =
|
||||
if not self.started:
|
||||
warn "ReachabilityManager is not started, yet we are trying to map ports already!"
|
||||
return false
|
||||
|
||||
try:
|
||||
let announceRecords = (!self.getAnnounceRecords)()
|
||||
let discoveryRecords = (!self.getDiscoveryRecords)()
|
||||
let portsToBeMapped =
|
||||
(announceRecords & discoveryRecords).mapIt(getAddressAndPort(it)).mapIt(it.port)
|
||||
|
||||
without mappedPorts =? startPortMapping(self.portMappingStrategy, portsToBeMapped),
|
||||
err:
|
||||
warn "Could not start port mapping", msg = err.msg
|
||||
return false
|
||||
|
||||
if mappedPorts.any(
|
||||
proc(x: PortMapping): bool =
|
||||
isNone(x.externalPort)
|
||||
):
|
||||
warn "Some ports were not mapped - not using port mapping then"
|
||||
return false
|
||||
|
||||
info "Started port mapping"
|
||||
|
||||
let announceMappedRecords = zip(
|
||||
announceRecords, mappedPorts[0 .. announceRecords.len - 1]
|
||||
)
|
||||
.mapIt(getMultiAddr(getAddressAndPort(it[0]).ip, !it[1].externalPort))
|
||||
(!self.updateAnnounceRecords)(announceMappedRecords)
|
||||
|
||||
let discoveryMappedRecords = zip(
|
||||
discoveryRecords, mappedPorts[announceRecords.len .. ^1]
|
||||
)
|
||||
.mapIt(getMultiAddr(getAddressAndPort(it[0]).ip, !it[1].externalPort))
|
||||
(!self.updateDiscoveryRecords)(discoveryMappedRecords)
|
||||
|
||||
return true
|
||||
except ValueError as exc:
|
||||
error "Error while starting port mapping", msg = exc.msg
|
||||
return false
|
||||
|
||||
proc getReachabilityHandler(manager: ReachabilityManager): StatusAndConfidenceHandler =
|
||||
let statusAndConfidenceHandler = proc(
|
||||
networkReachability: NetworkReachability, confidenceOpt: Opt[float]
|
||||
): Future[void] {.gcsafe, async: (raises: [CancelledError]).} =
|
||||
if not started:
|
||||
): Future[void] {.async: (raises: [CancelledError]).} =
|
||||
if not manager.started:
|
||||
warn "ReachabilityManager was not started, but we are already getting reachability updates! Ignoring..."
|
||||
return
|
||||
|
||||
@ -56,7 +99,7 @@ proc getReachabilityHandler(manager: ReachabilityManager): StatusAndConfidenceHa
|
||||
|
||||
manager.networkReachability = networkReachability
|
||||
|
||||
if networkReachability == NetworkReachability.Unreachable:
|
||||
if networkReachability == NetworkReachability.NotReachable:
|
||||
# Lets first start to expose port using port mapping protocols like NAT-PMP or UPnP
|
||||
if manager.startPortMapping():
|
||||
return # We exposed ports so we should be good!
|
||||
@ -65,45 +108,6 @@ proc getReachabilityHandler(manager: ReachabilityManager): StatusAndConfidenceHa
|
||||
|
||||
return statusAndConfidenceHandler
|
||||
|
||||
proc startPortMapping(self: ReachabilityManager): bool =
|
||||
try:
|
||||
let announceRecords = self.getAnnounceRecords()
|
||||
let discoveryRecords = self.getDiscoveryRecords()
|
||||
let portsToBeMapped =
|
||||
(announceRecords & discoveryRecords).mapIt(getAddressAndPort(it)).mapIt(it.port)
|
||||
|
||||
without mappedPorts =? startPortMapping(
|
||||
manager.portMappingStrategy, portsToBeMapped
|
||||
), err:
|
||||
warn "Could not start port mapping", msg = err
|
||||
return false
|
||||
|
||||
if mappedPorts.any(
|
||||
proc(x: ?MappingPort): bool =
|
||||
isNone(x)
|
||||
):
|
||||
warn "Some ports were not mapped - not using port mapping then"
|
||||
return false
|
||||
|
||||
info "Started port mapping"
|
||||
|
||||
let announceMappedRecords = zip(
|
||||
announceRecords, mappedPorts[0 .. announceRecords.len - 1]
|
||||
)
|
||||
.mapIt(getMultiAddr(getAddressAndPort(it[0]).ip, it[1].value))
|
||||
self.updateAnnounceRecords(announceMappedRecords)
|
||||
|
||||
let discoveryMappedRecords = zip(
|
||||
discoveryRecords, mappedPorts[announceRecords.len, ^1]
|
||||
)
|
||||
.mapIt(getMultiAddr(getAddressAndPort(it[0]).ip, it[1].value))
|
||||
self.updateDiscoveryRecords(discoveryMappedRecords)
|
||||
|
||||
return true
|
||||
except ValueError as exc:
|
||||
error "Error while starting port mapping", msg = exc.msg
|
||||
return false
|
||||
|
||||
proc start*(
|
||||
self: ReachabilityManager, switch: Switch, bootNodes: seq[SignedPeerRecord]
|
||||
): Future[void] {.async: (raises: [CancelledError]).} =
|
||||
|
||||
@ -7,13 +7,11 @@
|
||||
## This file may not be copied, modified, or distributed except according to
|
||||
## those terms.
|
||||
|
||||
import std/strutils
|
||||
import std/options
|
||||
import std/net
|
||||
|
||||
import pkg/libp2p
|
||||
import pkg/questionable
|
||||
import pkg/questionable/results
|
||||
import pkg/stew/endians2
|
||||
|
||||
import ./port_mapping
|
||||
|
||||
@ -62,7 +60,7 @@ proc getAddressAndPort*(
|
||||
|
||||
proc getMultiAddr*(ip: IpAddress, port: MappingPort): MultiAddress =
|
||||
let ipFamily = if ip.family == IpAddressFamily.IPv4: "/ip4/" else: "/ip6/"
|
||||
let portType = if (internalPort is TcpPort): "/tcp/" else: "/udp/"
|
||||
let portType = if (port is TcpPort): "/tcp/" else: "/udp/"
|
||||
return MultiAddress.init(ipFamily & $ip & portType & $(port.value)).expect(
|
||||
"valid multiaddr"
|
||||
)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user