Skip to content

Commit

Permalink
Bind to local addr when behind a NAT
Browse files Browse the repository at this point in the history
  • Loading branch information
diegomrsantos committed Mar 10, 2023
1 parent e6908d0 commit 2e74822
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 12 deletions.
2 changes: 1 addition & 1 deletion .pinned
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
bearssl;https://github.com/status-im/nim-bearssl@#acf9645e328bdcab481cfda1c158e07ecd46bd7b
chronicles;https://github.com/status-im/nim-chronicles@#32ac8679680ea699f7dbc046e8e0131cac97d41a
chronos;https://github.com/status-im/nim-chronos@#f7835a192b45c37e97614d865141f21eea8c156e
chronos;https://github.com/status-im/nim-chronos@#0240dd8b8a7fc54676b8d494a9126b5ffbbb4adf
dnsclient;https://github.com/ba0f3/dnsclient.nim@#fcd7443634b950eaea574e5eaa00a628ae029823
faststreams;https://github.com/status-im/nim-faststreams@#814f8927e1f356f39219f37f069b83066bcc893a
httputils;https://github.com/status-im/nim-http-utils@#a85bd52ae0a956983ca6b3267c72961d2ec0245f
Expand Down
5 changes: 5 additions & 0 deletions libp2p/peerstore.nim
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,11 @@ proc getMostObservedIP*(self: PeerStore, ipVersion: IPVersion): Opt[MultiAddress
## Returns the most observed IP address or none if the number of observations are less than minCount.
return self.identify.getMostObservedIP(ipVersion)

proc getMostObservedIPsAndPorts*(self: PeerStore): seq[MultiAddress] =
## Returns the most observed IP4/Port and IP6/Port address or an empty seq if the number of observations
## are less than minCount.
return self.identify.getMostObservedIPsAndPorts()

proc replaceMAIpByMostObserved*(
self: PeerStore,
ma: MultiAddress): Opt[MultiAddress] =
Expand Down
3 changes: 3 additions & 0 deletions libp2p/protocols/connectivity/autonat/core.nim
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ type
dial*: Option[AutonatDial]
response*: Option[AutonatDialResponse]

NetworkReachability* {.pure.} = enum
NotReachable, Reachable, Unknown

proc encode(p: AutonatPeerInfo): ProtoBuffer =
result = initProtoBuffer()
if p.id.isSome():
Expand Down
4 changes: 1 addition & 3 deletions libp2p/protocols/connectivity/autonat/service.nim
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ type
minConfidence: float
dialTimeout: Duration

NetworkReachability* {.pure.} = enum
NotReachable, Reachable, Unknown

StatusAndConfidenceHandler* = proc (networkReachability: NetworkReachability, confidence: Option[float]): Future[void] {.gcsafe, raises: [Defect].}

proc new*(
Expand Down Expand Up @@ -135,6 +132,7 @@ proc askPeer(self: AutonatService, switch: Switch, peerId: PeerId): Future[Netwo
if not isNil(self.statusAndConfidenceHandler):
await self.statusAndConfidenceHandler(self.networkReachability, self.confidence)
await switch.peerInfo.update()
echo switch.peerStore.getMostObservedIPsAndPorts()
return ans

proc askConnectedPeers(self: AutonatService, switch: Switch) {.async.} =
Expand Down
6 changes: 6 additions & 0 deletions libp2p/protocols/identify.nim
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,9 @@ proc push*(p: IdentifyPush, peerInfo: PeerInfo, conn: Connection) {.async, publi
proc getMostObservedIP*(self: Identify, ipVersion: IPVersion): Opt[MultiAddress] =
## Returns the most observed IP address or none if the number of observations are less than minCount.
return self.observedAddrManager.getMostObservedIP(ipVersion)

proc getMostObservedIPsAndPorts*(self: Identify): seq[MultiAddress] =
## Returns the most observed IP4/Port and IP6/Port address or an empty seq if the number of observations
## are less than minCount.
echo self.observedAddrManager
return self.observedAddrManager.getMostObservedIPsAndPorts()
18 changes: 13 additions & 5 deletions libp2p/transports/tcptransport.nim
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type
servers*: seq[StreamServer]
clients: array[Direction, seq[StreamTransport]]
flags: set[ServerFlags]
clientFlags: set[TransportFlags]
clientFlags: set[ClientFlags]
acceptFuts: seq[Future[StreamTransport]]

TcpTransportTracker* = ref object of TrackerBase
Expand Down Expand Up @@ -136,13 +136,14 @@ proc new*(
clientFlags:
if ServerFlags.TcpNoDelay in flags:
compilesOr:
{TransportFlags.TcpNoDelay}
{ClientFlags.TcpNoDelay}
do:
doAssert(false)
default(set[TransportFlags])
else:
default(set[TransportFlags]),
upgrader: upgrade)
default(set[ClientFlags]),
upgrader: upgrade,
networkReachability: NetworkReachability.Unknown)

return transport

Expand All @@ -165,6 +166,8 @@ method start*(
trace "Invalid address detected, skipping!", address = ma
continue

if self.networkReachability == NetworkReachability.NotReachable:
self.flags.incl(ServerFlags.ReusePort)
let server = createStreamServer(
ma = ma,
flags = self.flags,
Expand Down Expand Up @@ -263,8 +266,13 @@ method dial*(
##

trace "Dialing remote peer", address = $address
let transp =
if self.networkReachability == NetworkReachability.NotReachable and self.addrs.len > 0:
self.clientFlags.incl(ClientFlags.ReusePort)
await connect(address, flags = self.clientFlags, localAddress = Opt.some(self.addrs[0]))
else:
await connect(address, flags = self.clientFlags)

let transp = await connect(address, flags = self.clientFlags)
try:
let observedAddr = await getObservedAddr(transp)
return await self.connHandler(transp, Opt.some(observedAddr), Direction.Out)
Expand Down
6 changes: 5 additions & 1 deletion libp2p/transports/transport.nim
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ import ../stream/connection,
../multiaddress,
../multicodec,
../muxers/muxer,
../upgrademngrs/upgrade
../upgrademngrs/upgrade,
../protocols/connectivity/autonat/core

export core.NetworkReachability

logScope:
topics = "libp2p transport"
Expand All @@ -33,6 +36,7 @@ type
addrs*: seq[MultiAddress]
running*: bool
upgrader*: Upgrade
networkReachability*: NetworkReachability

proc newTransportClosedError*(parent: ref Exception = nil): ref LPError =
newException(TransportClosedError,
Expand Down
8 changes: 6 additions & 2 deletions libp2p/wire.nim
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ proc connect*(
ma: MultiAddress,
bufferSize = DefaultStreamBufferSize,
child: StreamTransport = nil,
flags = default(set[TransportFlags])): Future[StreamTransport]
flags = default(set[ClientFlags]),
localAddress: Opt[MultiAddress] = Opt.none(MultiAddress)): Future[StreamTransport]
{.raises: [Defect, LPError, MaInvalidAddress].} =
## Open new connection to remote peer with address ``ma`` and create
## new transport object ``StreamTransport`` for established connection.
Expand All @@ -90,7 +91,10 @@ proc connect*(
let transportAddress = initTAddress(ma).tryGet()

compilesOr:
return connect(transportAddress, bufferSize, child, flags)
if localAddress.isSome():
return connect(transportAddress, flags, bufferSize, child, initTAddress(localAddress.get()).tryGet())
else:
return connect(transportAddress, flags, bufferSize, child)
do:
# support for older chronos versions
return connect(transportAddress, bufferSize, child)
Expand Down

0 comments on commit 2e74822

Please sign in to comment.