Skip to content

Commit 96343f7

Browse files
authored
Merge branch 'master' into fix-ads-pruning
2 parents 40e6433 + 502a36a commit 96343f7

15 files changed

Lines changed: 226 additions & 35 deletions

File tree

libp2p/builders.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ proc withWsTransport*(
243243
proc withQuicTransport*(b: SwitchBuilder): SwitchBuilder =
244244
b.withTransport(
245245
proc(config: TransportConfig): Transport =
246-
QuicTransport.new(config.upgr, config.privateKey, config.connManager)
246+
QuicTransport.new(config.upgr, config.privateKey, config.rng, config.connManager)
247247
)
248248

249249
proc withMemoryTransport*(b: SwitchBuilder): SwitchBuilder =

libp2p/crypto/rng.nim

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,19 @@ proc randBelow(rng: Rng, max: uint32): int =
113113
if r >= threshold:
114114
return (r mod max).int
115115

116+
proc rand*(rng: Rng, low, high: int): int =
117+
## Return a uniformly random integer in the inclusive range [`low`, `high`].
118+
doAssert low <= high, "random range must not be empty"
119+
120+
let width =
121+
if low >= 0 or high < 0:
122+
uint64(high - low) + 1
123+
else:
124+
uint64(-(low + 1)) + uint64(high) + 2
125+
doAssert width <= uint64(uint32.high), "random range is too large"
126+
127+
low + rng.randBelow(width.uint32)
128+
116129
proc pick*[T](rng: Rng, x: openArray[T], n: int): Opt[seq[T]] =
117130
doAssert n >= 0, "n must be non-negative"
118131
if x.len == 0:

libp2p/dialer.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ proc dialAndUpgrade*(
5656
let dialed =
5757
try:
5858
libp2p_total_dial_attempts.inc()
59-
await transport.dial(hostname, addrs, peerId)
59+
await transport.dial(hostname, addrs, peerId, dir)
6060
except CancelledError as exc:
6161
trace "Dialing canceled", description = exc.msg, peerId
6262
raise exc

libp2p/protocols/connectivity/relay/rtransport.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ method dial*(
107107
hostname: string,
108108
ma: MultiAddress,
109109
peerId: Opt[PeerId] = Opt.none(PeerId),
110+
dir: Direction = Direction.Out,
110111
): Future[RawConn] {.async: (raises: [transport.TransportError, CancelledError]).} =
111112
peerId.withValue(pid):
112113
try:

libp2p/protocols/service_discovery/registrar.nim

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ proc pruneExpiredEntries[K](
107107
bounds.del(k)
108108

109109
proc pruneExpiredAds*(registrar: Registrar, advertExpiry: Duration) =
110-
let now = Moment.now()
110+
#Always use seconds granularity
111+
let now = Moment.init(Moment.now().epochSeconds, Second)
111112

112113
var expiredCount = 0
113114

@@ -162,8 +163,7 @@ proc waitingTime*(
162163
(serviceSim + discoConfig.ipSimCoefficient * ipSim + discoConfig.safetyParam)
163164

164165
# Bound & Quantize W
165-
w = max(0.0, w)
166-
w = min(w, float64(uint32.high))
166+
w = w.clamp(0.0, float64(uint32.high))
167167
w = round(w)
168168

169169
var waitDuration = w.int64.secs
@@ -470,7 +470,8 @@ proc registration*(disco: ServiceDiscovery, peerId: PeerId, inMsg: Message): Mes
470470

471471
return msg
472472

473-
let now = Moment.now()
473+
#Always use seconds granularity
474+
let now = Moment.init(Moment.now().epochSeconds, Second)
474475

475476
let ticketOpt = disco.isValidTicket(regMsg, now).valueOr:
476477
error "invalid ticket", error
@@ -498,6 +499,8 @@ proc registration*(disco: ServiceDiscovery, peerId: PeerId, inMsg: Message): Mes
498499

499500
return msg
500501

502+
tWait = min(disco.discoConfig.advertExpiry, tWait)
503+
501504
disco.registrar.updateLowerBounds(serviceId, ad, tWait, now)
502505

503506
var ticket = Ticket(

libp2p/transports/memorytransport.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ method dial*(
9797
hostname: string,
9898
ma: MultiAddress,
9999
peerId: Opt[PeerId] = Opt.none(PeerId),
100+
dir: Direction = Direction.Out,
100101
): Future[RawConn] {.async: (raises: [transport.TransportError, CancelledError]).} =
101102
try:
102103
let listener = getInstance().dial($ma)

libp2p/transports/quictransport.nim

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import std/[hashes, sets, sequtils]
55
import chronos, chronicles, metrics, results
66
import lsquic
77
import
8+
../crypto/rng,
89
../wire,
910
../connmanager,
1011
../multiaddress,
@@ -25,6 +26,8 @@ export transport
2526
logScope:
2627
topics = "libp2p quictransport"
2728

29+
const QuicHolePunchPacketSize* = 64
30+
2831
type
2932
P2PConnection = connection.Connection
3033
QuicConnection = lsquic.Connection
@@ -353,11 +356,15 @@ proc new*(
353356
_: type QuicTransport,
354357
u: Upgrade,
355358
privateKey: PrivateKey,
359+
rng: Rng,
356360
connManager: ConnManager = nil,
357361
): QuicTransport =
362+
doAssert not rng.isNil, "Rng is nil"
363+
358364
let self = QuicTransport(
359365
upgrader: QuicUpgrade(ms: u.ms, connManager: connManager.toOpt()),
360366
privateKey: privateKey,
367+
rng: rng,
361368
certGenerator: defaultCertGenerator,
362369
)
363370
procCall Transport(self).initialize()
@@ -367,12 +374,16 @@ proc new*(
367374
_: type QuicTransport,
368375
u: Upgrade,
369376
privateKey: PrivateKey,
377+
rng: Rng,
370378
certGenerator: CertGenerator,
371379
connManager: ConnManager = nil,
372380
): QuicTransport =
381+
doAssert not rng.isNil, "Rng is nil"
382+
373383
let self = QuicTransport(
374384
upgrader: QuicUpgrade(ms: u.ms, connManager: connManager.toOpt()),
375385
privateKey: privateKey,
386+
rng: rng,
376387
certGenerator: certGenerator,
377388
)
378389
procCall Transport(self).initialize()
@@ -583,6 +594,7 @@ method dial*(
583594
hostname: string,
584595
address: MultiAddress,
585596
peerId: Opt[PeerId] = Opt.none(PeerId),
597+
dir: Direction = Direction.Out,
586598
): Future[RawConn] {.async: (raises: [transport.TransportError, CancelledError]).} =
587599
let taAddress =
588600
try:
@@ -593,6 +605,23 @@ method dial*(
593605
)
594606

595607
try:
608+
if dir == Direction.In:
609+
let endpoint = self.listenerEndpointFor(taAddress)
610+
if endpoint.isNone():
611+
raise newException(
612+
QuicTransportDialError,
613+
"error in QUIC hole punch: no unique listener for address family",
614+
)
615+
616+
# The Sync sender is the QUIC server. Open its NAT mapping with random
617+
# UDP packets from the listener socket and let the expected inbound
618+
# connection complete the DCUtR attempt.
619+
while true:
620+
let payload = self.rng.generateBytes(QuicHolePunchPacketSize)
621+
await endpoint.get().datagramTransport().sendTo(taAddress, payload)
622+
let delay = self.rng.rand(10, 200)
623+
await sleepAsync(delay.milliseconds)
624+
596625
let endpoint = self.dialEndpointFor(taAddress)
597626
let quicConnection = await endpoint.dial(taAddress)
598627
peerId.withValue(expectedPeerId):
@@ -613,6 +642,8 @@ method dial*(
613642
)
614643
except TransportOsError as e:
615644
raise newException(QuicTransportDialError, "error in quic dial:" & e.msg, e)
645+
except chronos.TransportError as e:
646+
raise newException(QuicTransportDialError, "error in quic dial: " & e.msg, e)
616647
except DialError as e:
617648
raise newException(QuicTransportDialError, "error in quic dial:" & e.msg, e)
618649
except QuicError as e:

libp2p/transports/tcptransport.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ method dial*(
286286
hostname: string,
287287
address: MultiAddress,
288288
peerId: Opt[PeerId] = Opt.none(PeerId),
289+
dir: Direction = Direction.Out,
289290
): Future[RawConn] {.async: (raises: [transport.TransportError, CancelledError]).} =
290291
## dial a peer
291292
if self.stopping:

libp2p/transports/tortransport.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ method dial*(
221221
hostname: string,
222222
address: MultiAddress,
223223
peerId: Opt[PeerId] = Opt.none(PeerId),
224+
dir: Direction = Direction.Out,
224225
): Future[RawConn] {.async: (raises: [transport.TransportError, CancelledError]).} =
225226
## dial a peer
226227
##

libp2p/transports/transport.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ method dial*(
7575
hostname: string,
7676
address: MultiAddress,
7777
peerId: Opt[PeerId] = Opt.none(PeerId),
78+
dir: Direction = Direction.Out,
7879
): Future[RawConn] {.base, gcsafe, async: (raises: [TransportError, CancelledError]).} =
7980
## dial a peer
8081
##

0 commit comments

Comments
 (0)