Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transport hole punching #873

Merged
merged 51 commits into from
Apr 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
2033712
[skip ci] Start of upgrade refacto
Menduist Nov 22, 2022
df97314
kinda working
Menduist Nov 23, 2022
1ab9cc9
remove upgraded system
Menduist Nov 23, 2022
8b76889
re-add custom matcher
Menduist Nov 23, 2022
b954dad
Simplify connManager
Menduist Nov 23, 2022
c0316e3
fix
Menduist Nov 23, 2022
12ac83f
fix tests
Menduist Nov 24, 2022
7ad1ea8
try fix test
Menduist Nov 25, 2022
263b9e8
Fix GossipSub race condition
Menduist Nov 25, 2022
7b98af6
fix more race conditions
Menduist Nov 25, 2022
99bc8ee
Fix GossipSub race condition
Menduist Nov 25, 2022
6992d81
Merge remote-tracking branch 'origin/unstable' into upgraderefacto
Menduist Jan 2, 2023
a6cec9f
Better fix
Menduist Jan 2, 2023
696a5b4
Merge branch 'fixgossiprace' into upgraderefacto
Menduist Jan 2, 2023
92a425c
Fix typo
Menduist Jan 3, 2023
95fb447
Merge branch 'fixgossiprace' into upgraderefacto
Menduist Jan 3, 2023
7a74dd3
fix ci
Menduist Jan 3, 2023
5510ef7
Merge remote-tracking branch 'origin/unstable' into upgraderefacto
Menduist Jan 10, 2023
281a15a
Merge remote-tracking branch 'origin/unstable' into upgraderefacto
Menduist Jan 24, 2023
6acf4b4
Merge remote-tracking branch 'origin/unstable' into upgraderefacto
Menduist Jan 25, 2023
c279e5a
Fix pubsub
Menduist Jan 25, 2023
5c6fe92
fix short agent
Menduist Jan 30, 2023
5dc290b
Update libp2p/multistream.nim
Menduist Jan 30, 2023
c5f2dbd
Merge remote-tracking branch 'origin/unstable' into upgraderefacto
Menduist Feb 21, 2023
de06b46
Add getWrapped to YamuxChannel
Menduist Feb 21, 2023
2ab82c0
Merge remote-tracking branch 'origin/upgraderefacto' into upgraderefacto
Menduist Feb 21, 2023
685966c
fix autonat
Menduist Feb 21, 2023
8618c85
Merge branch 'unstable' into upgraderefacto
diegomrsantos Feb 22, 2023
b07e66b
Merge remote-tracking branch 'origin/unstable' into upgraderefacto
Menduist Mar 2, 2023
c9cc2bc
Trigger events before identify
Menduist Mar 2, 2023
1fee13c
ObservedMAManager
diegomrsantos Mar 2, 2023
19de3d7
improvements
diegomrsantos Mar 3, 2023
7627325
replace the heap by a seq
diegomrsantos Mar 3, 2023
92bfd83
Move manager to identify
diegomrsantos Mar 6, 2023
4fc7b6d
Simplify api
diegomrsantos Mar 6, 2023
22d6c05
Improvements after code review
diegomrsantos Mar 8, 2023
aee8dcf
Merge branch 'unstable' into observed-addr-manager
diegomrsantos Mar 8, 2023
7cb27cc
More fixes
diegomrsantos Mar 8, 2023
c462503
move procs here for reuse
diegomrsantos Mar 10, 2023
e6908d0
improve naming
diegomrsantos Mar 10, 2023
a378b2d
remove proc
diegomrsantos Mar 10, 2023
f4b34f2
Add an AddressMapper to the AutoRelayService
diegomrsantos Mar 13, 2023
e1c4c9e
Remove AddressMapper when AutonatService stops
diegomrsantos Mar 14, 2023
a38cd88
Bind to local addr when behind a NAT
diegomrsantos Mar 7, 2023
2289e82
Use ReusePort when starting
diegomrsantos Mar 8, 2023
21d9835
Merge branch 'unstable' into transport-hole-punching
diegomrsantos Mar 24, 2023
113d4af
update chronos
diegomrsantos Mar 27, 2023
d72e110
use SocketFlags
diegomrsantos Mar 27, 2023
8988e68
remove duplicate ports check
diegomrsantos Mar 27, 2023
34f5f0d
Make Unknown the NetworkReachability default value
diegomrsantos Mar 27, 2023
f579c12
update chronos
diegomrsantos Apr 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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@#ab5a8c2e0f6941fe3debd61dff0293790079d1b0
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
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
Unknown, NotReachable, Reachable

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

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

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

proc new*(
Expand Down
21 changes: 15 additions & 6 deletions libp2p/transports/tcptransport.nim
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,15 @@ type
servers*: seq[StreamServer]
clients: array[Direction, seq[StreamTransport]]
flags: set[ServerFlags]
clientFlags: set[TransportFlags]
clientFlags: set[SocketFlags]
acceptFuts: seq[Future[StreamTransport]]

TcpTransportTracker* = ref object of TrackerBase
opened*: uint64
closed*: uint64

TcpTransportError* = object of transport.TransportError

proc setupTcpTransportTracker(): TcpTransportTracker {.gcsafe, raises: [Defect].}

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

return transport

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

self.flags.incl(ServerFlags.ReusePort)
let server = createStreamServer(
ma = ma,
flags = self.flags,
Expand Down Expand Up @@ -263,8 +267,13 @@ method dial*(
##

trace "Dialing remote peer", address = $address
let transp =
if self.networkReachability == NetworkReachability.NotReachable and self.addrs.len > 0:
self.clientFlags.incl(SocketFlags.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
7 changes: 5 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[SocketFlags]),
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,9 @@ proc connect*(
let transportAddress = initTAddress(ma).tryGet()

compilesOr:
return connect(transportAddress, bufferSize, child, flags)
return connect(transportAddress, bufferSize, child,
if localAddress.isSome(): initTAddress(localAddress.get()).tryGet() else : TransportAddress(),
flags)
do:
# support for older chronos versions
return connect(transportAddress, bufferSize, child)
Expand Down
39 changes: 39 additions & 0 deletions tests/testtcptransport.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import ../libp2p/[stream/connection,
transports/tcptransport,
upgrademngrs/upgrade,
multiaddress,
multicodec,
errors,
wire]

Expand Down Expand Up @@ -125,6 +126,44 @@ suite "TCP transport":
server.close()
await server.join()

asyncTest "Starting with duplicate but zero ports addresses must NOT fail":
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet(),
MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]

let transport: TcpTransport = TcpTransport.new(upgrade = Upgrade())

await transport.start(ma)
await transport.stop()

asyncTest "Bind to listening port when not reachable":
let ma = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
let transport: TcpTransport = TcpTransport.new(upgrade = Upgrade())
await transport.start(ma)

let ma2 = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
let transport2: TcpTransport = TcpTransport.new(upgrade = Upgrade())
await transport2.start(ma2)

let ma3 = @[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
let transport3: TcpTransport = TcpTransport.new(upgrade = Upgrade())
await transport3.start(ma3)

let listeningPort = transport.addrs[0][multiCodec("tcp")].get()

let conn = await transport.dial(transport2.addrs[0])
let acceptedConn = await transport2.accept()
let acceptedPort = acceptedConn.observedAddr.get()[multiCodec("tcp")].get()
check listeningPort != acceptedPort

transport.networkReachability = NetworkReachability.NotReachable

let conn2 = await transport.dial(transport3.addrs[0])
let acceptedConn2 = await transport3.accept()
let acceptedPort2 = acceptedConn2.observedAddr.get()[multiCodec("tcp")].get()
check listeningPort == acceptedPort2

await allFutures(transport.stop(), transport2.stop(), transport3.stop())

proc transProvider(): Transport = TcpTransport.new(upgrade = Upgrade())

commonTransportTest(
Expand Down