Skip to content

Commit

Permalink
Autonat protocol (#739)
Browse files Browse the repository at this point in the history
  • Loading branch information
lchenut authored Aug 23, 2022
1 parent 124a7a5 commit 2332813
Show file tree
Hide file tree
Showing 8 changed files with 435 additions and 2 deletions.
11 changes: 10 additions & 1 deletion libp2p/builders.nim
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import
switch, peerid, peerinfo, stream/connection, multiaddress,
crypto/crypto, transports/[transport, tcptransport],
muxers/[muxer, mplex/mplex, yamux/yamux],
protocols/[identify, secure/secure, secure/noise],
protocols/[identify, secure/secure, secure/noise, autonat],
protocols/relay/[relay, client, rtransport],
connmanager, upgrademngrs/muxedupgrade,
nameresolving/nameresolver,
Expand Down Expand Up @@ -58,6 +58,7 @@ type
agentVersion: string
nameResolver: NameResolver
peerStoreCapacity: Option[int]
autonat: bool
circuitRelay: Relay

proc new*(T: type[SwitchBuilder]): T {.public.} =
Expand Down Expand Up @@ -185,6 +186,10 @@ proc withNameResolver*(b: SwitchBuilder, nameResolver: NameResolver): SwitchBuil
b.nameResolver = nameResolver
b

proc withAutonat*(b: SwitchBuilder): SwitchBuilder =
b.autonat = true
b

proc withCircuitRelay*(b: SwitchBuilder, r: Relay = Relay.new()): SwitchBuilder =
b.circuitRelay = r
b
Expand Down Expand Up @@ -246,6 +251,10 @@ proc build*(b: SwitchBuilder): Switch
nameResolver = b.nameResolver,
peerStore = peerStore)

if b.autonat:
let autonat = Autonat.new(switch)
switch.mount(autonat)

if not isNil(b.circuitRelay):
if b.circuitRelay of RelayClient:
switch.addTransport(RelayTransport.new(RelayClient(b.circuitRelay), muxedUpgrade))
Expand Down
6 changes: 6 additions & 0 deletions libp2p/dial.nim
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,9 @@ method addTransport*(
self: Dial,
transport: Transport) {.base.} =
doAssert(false, "Not implemented!")

method tryDial*(
self: Dial,
peerId: PeerId,
addrs: seq[MultiAddress]): Future[MultiAddress] {.async, base.} =
doAssert(false, "Not implemented!")
22 changes: 22 additions & 0 deletions libp2p/dialer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import dial,
stream/connection,
transports/transport,
nameresolving/nameresolver,
upgrademngrs/upgrade,
errors

export dial, errors
Expand Down Expand Up @@ -178,6 +179,27 @@ proc negotiateStream(

return conn

method tryDial*(
self: Dialer,
peerId: PeerId,
addrs: seq[MultiAddress]): Future[MultiAddress] {.async.} =
## Create a protocol stream and in order to check
## if a connection is possible.
## Doesn't use the Connection Manager to save it.
##

trace "Check if it can dial", peerId, addrs
try:
let conn = await self.dialAndUpgrade(peerId, addrs)
if conn.isNil():
raise newException(DialFailedError, "No valid multiaddress")
await conn.close()
return conn.observedAddr
except CancelledError as exc:
raise exc
except CatchableError as exc:
raise newException(DialFailedError, exc.msg)

method dial*(
self: Dialer,
peerId: PeerId,
Expand Down
25 changes: 25 additions & 0 deletions libp2p/multiaddress.nim
Original file line number Diff line number Diff line change
Expand Up @@ -590,10 +590,28 @@ proc getPart(ma: MultiAddress, index: int): MaResult[MultiAddress] =
inc(offset)
ok(res)

proc getParts[U, V](ma: MultiAddress, slice: HSlice[U, V]): MaResult[MultiAddress] =
when slice.a is BackwardsIndex or slice.b is BackwardsIndex:
let maLength = ? len(ma)
template normalizeIndex(index): int =
when index is BackwardsIndex: maLength - int(index)
else: int(index)
let
indexStart = normalizeIndex(slice.a)
indexEnd = normalizeIndex(slice.b)
var res: MultiAddress
for i in indexStart..indexEnd:
? res.append(? ma[i])
ok(res)

proc `[]`*(ma: MultiAddress, i: int): MaResult[MultiAddress] {.inline.} =
## Returns part with index ``i`` of MultiAddress ``ma``.
ma.getPart(i)

proc `[]`*(ma: MultiAddress, slice: HSlice): MaResult[MultiAddress] {.inline.} =
## Returns parts with slice ``slice`` of MultiAddress ``ma``.
ma.getParts(slice)

iterator items*(ma: MultiAddress): MaResult[MultiAddress] =
## Iterates over all addresses inside of MultiAddress ``ma``.
var header: uint64
Expand Down Expand Up @@ -630,6 +648,13 @@ iterator items*(ma: MultiAddress): MaResult[MultiAddress] =
res.data.finish()
yield ok(MaResult[MultiAddress], res)

proc len*(ma: MultiAddress): MaResult[int] =
var counter: int
for part in ma:
if part.isErr: return err(part.error)
counter.inc()
ok(counter)

proc contains*(ma: MultiAddress, codec: MultiCodec): MaResult[bool] {.inline.} =
## Returns ``true``, if address with MultiCodec ``codec`` present in
## MultiAddress ``ma``.
Expand Down
Loading

0 comments on commit 2332813

Please sign in to comment.