mirror of https://github.com/vacp2p/nim-libp2p.git
Allow public address mapping (#767)
This commit is contained in:
parent
32233d36c8
commit
7b103e02f2
|
@ -48,19 +48,19 @@ proc main() {.async.} =
|
|||
swSrc = createCircuitRelaySwitch(clSrc)
|
||||
swDst = createCircuitRelaySwitch(clDst)
|
||||
|
||||
# Create a relay address to swDst using swRel as the relay
|
||||
addrs = MultiAddress.init($swRel.peerInfo.addrs[0] & "/p2p/" &
|
||||
$swRel.peerInfo.peerId & "/p2p-circuit/p2p/" &
|
||||
$swDst.peerInfo.peerId).get()
|
||||
|
||||
swDst.mount(proto)
|
||||
|
||||
await swRel.start()
|
||||
await swSrc.start()
|
||||
await swDst.start()
|
||||
|
||||
# Connect both Src and Dst to the relay, but not to each other.
|
||||
await swSrc.connect(swRel.peerInfo.peerId, swRel.peerInfo.addrs)
|
||||
let
|
||||
# Create a relay address to swDst using swRel as the relay
|
||||
addrs = MultiAddress.init($swRel.peerInfo.addrs[0] & "/p2p/" &
|
||||
$swRel.peerInfo.peerId & "/p2p-circuit/p2p/" &
|
||||
$swDst.peerInfo.peerId).get()
|
||||
|
||||
# Connect Dst to the relay
|
||||
await swDst.connect(swRel.peerInfo.peerId, swRel.peerInfo.addrs)
|
||||
|
||||
# Dst reserve a slot on the relay.
|
||||
|
|
|
@ -22,11 +22,17 @@ export peerid, multiaddress, crypto, routing_record, errors, results
|
|||
## Our local peer info
|
||||
|
||||
type
|
||||
PeerInfoError* = LPError
|
||||
PeerInfoError* = object of LPError
|
||||
|
||||
AddressMapper* =
|
||||
proc(listenAddrs: seq[MultiAddress]): Future[seq[MultiAddress]]
|
||||
{.gcsafe, raises: [Defect].}
|
||||
|
||||
PeerInfo* {.public.} = ref object
|
||||
peerId*: PeerId
|
||||
addrs*: seq[MultiAddress]
|
||||
listenAddrs*: seq[MultiAddress]
|
||||
addrs: seq[MultiAddress]
|
||||
addressMappers*: seq[AddressMapper]
|
||||
protocols*: seq[string]
|
||||
protoVersion*: string
|
||||
agentVersion*: string
|
||||
|
@ -37,6 +43,7 @@ type
|
|||
func shortLog*(p: PeerInfo): auto =
|
||||
(
|
||||
peerId: $p.peerId,
|
||||
listenAddrs: mapIt(p.listenAddrs, $it),
|
||||
addrs: mapIt(p.addrs, $it),
|
||||
protocols: mapIt(p.protocols, $it),
|
||||
protoVersion: p.protoVersion,
|
||||
|
@ -44,7 +51,11 @@ func shortLog*(p: PeerInfo): auto =
|
|||
)
|
||||
chronicles.formatIt(PeerInfo): shortLog(it)
|
||||
|
||||
proc update*(p: PeerInfo) =
|
||||
proc update*(p: PeerInfo) {.async.} =
|
||||
p.addrs = p.listenAddrs
|
||||
for mapper in p.addressMappers:
|
||||
p.addrs = await mapper(p.addrs)
|
||||
|
||||
let sprRes = SignedPeerRecord.init(
|
||||
p.privateKey,
|
||||
PeerRecord.init(p.peerId, p.addrs)
|
||||
|
@ -55,20 +66,25 @@ proc update*(p: PeerInfo) =
|
|||
discard
|
||||
#info "Can't update the signed peer record"
|
||||
|
||||
proc addrs*(p: PeerInfo): seq[MultiAddress] =
|
||||
p.addrs
|
||||
|
||||
proc new*(
|
||||
p: typedesc[PeerInfo],
|
||||
key: PrivateKey,
|
||||
addrs: openArray[MultiAddress] = [],
|
||||
listenAddrs: openArray[MultiAddress] = [],
|
||||
protocols: openArray[string] = [],
|
||||
protoVersion: string = "",
|
||||
agentVersion: string = ""): PeerInfo
|
||||
{.raises: [Defect, PeerInfoError].} =
|
||||
agentVersion: string = "",
|
||||
addressMappers = newSeq[AddressMapper](),
|
||||
): PeerInfo
|
||||
{.raises: [Defect, LPError].} =
|
||||
|
||||
let pubkey = try:
|
||||
key.getPublicKey().tryGet()
|
||||
except CatchableError:
|
||||
raise newException(PeerInfoError, "invalid private key")
|
||||
|
||||
|
||||
let peerId = PeerId.init(key).tryGet()
|
||||
|
||||
let peerInfo = PeerInfo(
|
||||
|
@ -77,10 +93,9 @@ proc new*(
|
|||
privateKey: key,
|
||||
protoVersion: protoVersion,
|
||||
agentVersion: agentVersion,
|
||||
addrs: @addrs,
|
||||
listenAddrs: @listenAddrs,
|
||||
protocols: @protocols,
|
||||
addressMappers: addressMappers
|
||||
)
|
||||
|
||||
peerInfo.update()
|
||||
|
||||
return peerInfo
|
||||
|
|
|
@ -299,11 +299,11 @@ proc start*(s: Switch) {.async, gcsafe, public.} =
|
|||
trace "starting switch for peer", peerInfo = s.peerInfo
|
||||
var startFuts: seq[Future[void]]
|
||||
for t in s.transports:
|
||||
let addrs = s.peerInfo.addrs.filterIt(
|
||||
let addrs = s.peerInfo.listenAddrs.filterIt(
|
||||
t.handles(it)
|
||||
)
|
||||
|
||||
s.peerInfo.addrs.keepItIf(
|
||||
s.peerInfo.listenAddrs.keepItIf(
|
||||
it notin addrs
|
||||
)
|
||||
|
||||
|
@ -320,9 +320,9 @@ proc start*(s: Switch) {.async, gcsafe, public.} =
|
|||
for t in s.transports: # for each transport
|
||||
if t.addrs.len > 0 or t.running:
|
||||
s.acceptFuts.add(s.accept(t))
|
||||
s.peerInfo.addrs &= t.addrs
|
||||
s.peerInfo.listenAddrs &= t.addrs
|
||||
|
||||
s.peerInfo.update()
|
||||
await s.peerInfo.update()
|
||||
|
||||
await s.ms.start()
|
||||
|
||||
|
|
|
@ -52,6 +52,9 @@ suite "Identify":
|
|||
msListen = MultistreamSelect.new()
|
||||
msDial = MultistreamSelect.new()
|
||||
|
||||
serverFut = transport1.start(ma)
|
||||
await remotePeerInfo.update()
|
||||
|
||||
asyncTeardown:
|
||||
await conn.close()
|
||||
await acceptFut
|
||||
|
@ -61,7 +64,6 @@ suite "Identify":
|
|||
|
||||
asyncTest "default agent version":
|
||||
msListen.addHandler(IdentifyCodec, identifyProto1)
|
||||
serverFut = transport1.start(ma)
|
||||
proc acceptHandler(): Future[void] {.async, gcsafe.} =
|
||||
let c = await transport1.accept()
|
||||
await msListen.handle(c)
|
||||
|
@ -84,8 +86,6 @@ suite "Identify":
|
|||
remotePeerInfo.agentVersion = customAgentVersion
|
||||
msListen.addHandler(IdentifyCodec, identifyProto1)
|
||||
|
||||
serverFut = transport1.start(ma)
|
||||
|
||||
proc acceptHandler(): Future[void] {.async, gcsafe.} =
|
||||
let c = await transport1.accept()
|
||||
await msListen.handle(c)
|
||||
|
@ -105,7 +105,6 @@ suite "Identify":
|
|||
|
||||
asyncTest "handle failed identify":
|
||||
msListen.addHandler(IdentifyCodec, identifyProto1)
|
||||
asyncSpawn transport1.start(ma)
|
||||
|
||||
proc acceptHandler() {.async.} =
|
||||
var conn: Connection
|
||||
|
@ -128,7 +127,6 @@ suite "Identify":
|
|||
asyncTest "can send signed peer record":
|
||||
msListen.addHandler(IdentifyCodec, identifyProto1)
|
||||
identifyProto1.sendSignedPeerRecord = true
|
||||
serverFut = transport1.start(ma)
|
||||
proc acceptHandler(): Future[void] {.async, gcsafe.} =
|
||||
let c = await transport1.accept()
|
||||
await msListen.handle(c)
|
||||
|
@ -195,7 +193,8 @@ suite "Identify":
|
|||
|
||||
asyncTest "simple push identify":
|
||||
switch2.peerInfo.protocols.add("/newprotocol/")
|
||||
switch2.peerInfo.addrs.add(MultiAddress.init("/ip4/127.0.0.1/tcp/5555").tryGet())
|
||||
switch2.peerInfo.listenAddrs.add(MultiAddress.init("/ip4/127.0.0.1/tcp/5555").tryGet())
|
||||
await switch2.peerInfo.update()
|
||||
|
||||
check:
|
||||
switch1.peerStore[AddressBook][switch2.peerInfo.peerId] != switch2.peerInfo.addrs
|
||||
|
@ -216,7 +215,8 @@ suite "Identify":
|
|||
|
||||
asyncTest "wrong peer id push identify":
|
||||
switch2.peerInfo.protocols.add("/newprotocol/")
|
||||
switch2.peerInfo.addrs.add(MultiAddress.init("/ip4/127.0.0.1/tcp/5555").tryGet())
|
||||
switch2.peerInfo.listenAddrs.add(MultiAddress.init("/ip4/127.0.0.1/tcp/5555").tryGet())
|
||||
await switch2.peerInfo.update()
|
||||
|
||||
check:
|
||||
switch1.peerStore[AddressBook][switch2.peerInfo.peerId] != switch2.peerInfo.addrs
|
||||
|
|
|
@ -60,8 +60,7 @@ method init(p: TestProto) {.gcsafe.} =
|
|||
proc createSwitch(ma: MultiAddress; outgoing: bool, secio: bool = false): (Switch, PeerInfo) =
|
||||
var
|
||||
privateKey = PrivateKey.random(ECDSA, rng[]).get()
|
||||
peerInfo = PeerInfo.new(privateKey)
|
||||
peerInfo.addrs.add(ma)
|
||||
peerInfo = PeerInfo.new(privateKey, @[ma])
|
||||
|
||||
proc createMplex(conn: Connection): Muxer =
|
||||
result = Mplex.new(conn)
|
||||
|
|
|
@ -18,22 +18,24 @@ suite "PeerInfo":
|
|||
|
||||
check peerId == peerInfo.peerId
|
||||
check seckey.getPublicKey().get() == peerInfo.publicKey
|
||||
|
||||
|
||||
test "Signed peer record":
|
||||
const
|
||||
ExpectedDomain = $multiCodec("libp2p-peer-record")
|
||||
ExpectedPayloadType = @[(byte) 0x03, (byte) 0x01]
|
||||
|
||||
|
||||
let
|
||||
seckey = PrivateKey.random(rng[]).tryGet()
|
||||
peerId = PeerId.init(seckey).get()
|
||||
multiAddresses = @[MultiAddress.init("/ip4/0.0.0.0/tcp/24").tryGet(), MultiAddress.init("/ip4/0.0.0.0/tcp/25").tryGet()]
|
||||
peerInfo = PeerInfo.new(seckey, multiAddresses)
|
||||
|
||||
|
||||
waitFor(peerInfo.update())
|
||||
|
||||
let
|
||||
env = peerInfo.signedPeerRecord.envelope
|
||||
rec = PeerRecord.decode(env.payload()).tryGet()
|
||||
|
||||
|
||||
# Check envelope fields
|
||||
check:
|
||||
env.publicKey == peerInfo.publicKey
|
||||
|
@ -47,3 +49,17 @@ suite "PeerInfo":
|
|||
rec.addresses.len == 2
|
||||
rec.addresses[0].address == multiAddresses[0]
|
||||
rec.addresses[1].address == multiAddresses[1]
|
||||
|
||||
test "Public address mapping":
|
||||
let
|
||||
seckey = PrivateKey.random(ECDSA, rng[]).get()
|
||||
multiAddresses = @[MultiAddress.init("/ip4/0.0.0.0/tcp/24").tryGet(), MultiAddress.init("/ip4/0.0.0.0/tcp/25").tryGet()]
|
||||
multiAddresses2 = @[MultiAddress.init("/ip4/8.8.8.8/tcp/33").tryGet()]
|
||||
|
||||
proc addressMapper(input: seq[MultiAddress]): Future[seq[MultiAddress]] {.async.} =
|
||||
check input == multiAddresses
|
||||
await sleepAsync(0.seconds)
|
||||
return multiAddresses2
|
||||
var peerInfo = PeerInfo.new(seckey, multiAddresses, addressMappers = @[addressMapper])
|
||||
waitFor peerInfo.update()
|
||||
check peerInfo.addrs == multiAddresses2
|
||||
|
|
|
@ -118,7 +118,6 @@ suite "Circuit Relay V2":
|
|||
asyncTeardown:
|
||||
checkTrackers()
|
||||
var
|
||||
addrs {.threadvar.}: MultiAddress
|
||||
customProtoCodec {.threadvar.}: string
|
||||
proto {.threadvar.}: LPProtocol
|
||||
ttl {.threadvar.}: int
|
||||
|
@ -145,9 +144,6 @@ suite "Circuit Relay V2":
|
|||
src = createSwitch(srcCl)
|
||||
dst = createSwitch(dstCl)
|
||||
rel = newStandardSwitch()
|
||||
addrs = MultiAddress.init($rel.peerInfo.addrs[0] & "/p2p/" &
|
||||
$rel.peerInfo.peerId & "/p2p-circuit/p2p/" &
|
||||
$dst.peerInfo.peerId).get()
|
||||
|
||||
asyncTest "Connection succeed":
|
||||
proto.handler = proc(conn: Connection, proto: string) {.async.} =
|
||||
|
@ -167,6 +163,10 @@ suite "Circuit Relay V2":
|
|||
await src.start()
|
||||
await dst.start()
|
||||
|
||||
let addrs = MultiAddress.init($rel.peerInfo.addrs[0] & "/p2p/" &
|
||||
$rel.peerInfo.peerId & "/p2p-circuit/p2p/" &
|
||||
$dst.peerInfo.peerId).get()
|
||||
|
||||
await src.connect(rel.peerInfo.peerId, rel.peerInfo.addrs)
|
||||
await dst.connect(rel.peerInfo.peerId, rel.peerInfo.addrs)
|
||||
|
||||
|
@ -200,6 +200,10 @@ suite "Circuit Relay V2":
|
|||
await src.start()
|
||||
await dst.start()
|
||||
|
||||
let addrs = MultiAddress.init($rel.peerInfo.addrs[0] & "/p2p/" &
|
||||
$rel.peerInfo.peerId & "/p2p-circuit/p2p/" &
|
||||
$dst.peerInfo.peerId).get()
|
||||
|
||||
await src.connect(rel.peerInfo.peerId, rel.peerInfo.addrs)
|
||||
await dst.connect(rel.peerInfo.peerId, rel.peerInfo.addrs)
|
||||
|
||||
|
@ -245,6 +249,10 @@ take to the ship.""")
|
|||
await src.start()
|
||||
await dst.start()
|
||||
|
||||
let addrs = MultiAddress.init($rel.peerInfo.addrs[0] & "/p2p/" &
|
||||
$rel.peerInfo.peerId & "/p2p-circuit/p2p/" &
|
||||
$dst.peerInfo.peerId).get()
|
||||
|
||||
await src.connect(rel.peerInfo.peerId, rel.peerInfo.addrs)
|
||||
await dst.connect(rel.peerInfo.peerId, rel.peerInfo.addrs)
|
||||
|
||||
|
@ -277,6 +285,10 @@ take to the ship.""")
|
|||
await src.start()
|
||||
await dst.start()
|
||||
|
||||
let addrs = MultiAddress.init($rel.peerInfo.addrs[0] & "/p2p/" &
|
||||
$rel.peerInfo.peerId & "/p2p-circuit/p2p/" &
|
||||
$dst.peerInfo.peerId).get()
|
||||
|
||||
await src.connect(rel.peerInfo.peerId, rel.peerInfo.addrs)
|
||||
await dst.connect(rel.peerInfo.peerId, rel.peerInfo.addrs)
|
||||
|
||||
|
@ -308,11 +320,6 @@ take to the ship.""")
|
|||
rel2Cl = RelayClient.new(canHop = true)
|
||||
rel2 = createSwitch(rel2Cl)
|
||||
rv2 = Relay.new()
|
||||
addrs = @[ MultiAddress.init($rel.peerInfo.addrs[0] & "/p2p/" &
|
||||
$rel.peerInfo.peerId & "/p2p-circuit/p2p/" &
|
||||
$rel2.peerInfo.peerId & "/p2p/" &
|
||||
$rel2.peerInfo.peerId & "/p2p-circuit/p2p/" &
|
||||
$dst.peerInfo.peerId).get() ]
|
||||
rv2.setup(rel)
|
||||
rel.mount(rv2)
|
||||
dst.mount(proto)
|
||||
|
@ -321,6 +328,13 @@ take to the ship.""")
|
|||
await src.start()
|
||||
await dst.start()
|
||||
|
||||
let
|
||||
addrs = @[ MultiAddress.init($rel.peerInfo.addrs[0] & "/p2p/" &
|
||||
$rel.peerInfo.peerId & "/p2p-circuit/p2p/" &
|
||||
$rel2.peerInfo.peerId & "/p2p/" &
|
||||
$rel2.peerInfo.peerId & "/p2p-circuit/p2p/" &
|
||||
$dst.peerInfo.peerId).get() ]
|
||||
|
||||
await src.connect(rel.peerInfo.peerId, rel.peerInfo.addrs)
|
||||
await rel2.connect(rel.peerInfo.peerId, rel.peerInfo.addrs)
|
||||
await dst.connect(rel2.peerInfo.peerId, rel2.peerInfo.addrs)
|
||||
|
@ -367,6 +381,16 @@ take to the ship.""")
|
|||
switchA = createSwitch(clientA)
|
||||
switchB = createSwitch(clientB)
|
||||
switchC = createSwitch(clientC)
|
||||
|
||||
switchA.mount(protoBCA)
|
||||
switchB.mount(protoCAB)
|
||||
switchC.mount(protoABC)
|
||||
|
||||
await switchA.start()
|
||||
await switchB.start()
|
||||
await switchC.start()
|
||||
|
||||
let
|
||||
addrsABC = MultiAddress.init($switchB.peerInfo.addrs[0] & "/p2p/" &
|
||||
$switchB.peerInfo.peerId & "/p2p-circuit/p2p/" &
|
||||
$switchC.peerInfo.peerId).get()
|
||||
|
@ -376,13 +400,6 @@ take to the ship.""")
|
|||
addrsCAB = MultiAddress.init($switchA.peerInfo.addrs[0] & "/p2p/" &
|
||||
$switchA.peerInfo.peerId & "/p2p-circuit/p2p/" &
|
||||
$switchB.peerInfo.peerId).get()
|
||||
switchA.mount(protoBCA)
|
||||
switchB.mount(protoCAB)
|
||||
switchC.mount(protoABC)
|
||||
|
||||
await switchA.start()
|
||||
await switchB.start()
|
||||
await switchC.start()
|
||||
|
||||
await switchA.connect(switchB.peerInfo.peerId, switchB.peerInfo.addrs)
|
||||
await switchB.connect(switchC.peerInfo.peerId, switchC.peerInfo.addrs)
|
||||
|
|
Loading…
Reference in New Issue