mirror of https://github.com/vacp2p/nim-libp2p.git
Handle dns addrs in HP service (#890)
This commit is contained in:
parent
a1eb53b181
commit
7d6bc545e0
|
@ -53,6 +53,7 @@ proc reserveAndUpdate(self: AutoRelayService, relayPid: PeerId, switch: Switch)
|
|||
if relayPid notin self.relayAddresses or self.relayAddresses[relayPid] != relayedAddr:
|
||||
self.relayAddresses[relayPid] = relayedAddr
|
||||
await switch.peerInfo.update()
|
||||
debug "Updated relay addresses", relayPid, relayedAddr
|
||||
if not self.onReservation.isNil():
|
||||
self.onReservation(concat(toSeq(self.relayAddresses.values)))
|
||||
await sleepAsync chronos.seconds(ttl - 30)
|
||||
|
|
|
@ -43,14 +43,21 @@ proc new*(T: typedesc[HPService], autonatService: AutonatService, autoRelayServi
|
|||
return T(autonatService: autonatService, autoRelayService: autoRelayService, isPublicIPAddrProc: isPublicIPAddrProc)
|
||||
|
||||
proc tryStartingDirectConn(self: HPService, switch: Switch, peerId: PeerId): Future[bool] {.async.} =
|
||||
proc tryConnect(address: MultiAddress): Future[bool] {.async.} =
|
||||
debug "Trying to create direct connection", peerId, address
|
||||
await switch.connect(peerId, @[address], true, false)
|
||||
debug "Direct connection created."
|
||||
return true
|
||||
|
||||
await sleepAsync(500.milliseconds) # wait for AddressBook to be populated
|
||||
for address in switch.peerStore[AddressBook][peerId]:
|
||||
try:
|
||||
let ta = initTAddress(address)
|
||||
if ta.isOk() and self.isPublicIPAddrProc(ta.get()):
|
||||
await switch.connect(peerId, @[address], true, false)
|
||||
debug "Direct connection created."
|
||||
return true
|
||||
if DNS.matchPartial(address):
|
||||
return await tryConnect(address)
|
||||
else:
|
||||
let ta = initTAddress(address)
|
||||
if ta.isOk() and self.isPublicIPAddrProc(ta.get()):
|
||||
return await tryConnect(address)
|
||||
except CatchableError as err:
|
||||
debug "Failed to create direct connection.", err = err.msg
|
||||
continue
|
||||
|
|
|
@ -339,7 +339,7 @@ proc start*(s: Switch) {.async, gcsafe, public.} =
|
|||
warn "Switch has already been started"
|
||||
return
|
||||
|
||||
trace "starting switch for peer", peerInfo = s.peerInfo
|
||||
debug "starting switch for peer", peerInfo = s.peerInfo
|
||||
var startFuts: seq[Future[void]]
|
||||
for t in s.transports:
|
||||
let addrs = s.peerInfo.listenAddrs.filterIt(
|
||||
|
|
|
@ -26,12 +26,15 @@ import ../libp2p/[builders,
|
|||
import ../libp2p/protocols/connectivity/relay/[relay, client]
|
||||
import ../libp2p/protocols/connectivity/autonat/[service]
|
||||
import ../libp2p/wire
|
||||
import ../libp2p/nameresolving/nameresolver
|
||||
import ../libp2p/nameresolving/mockresolver
|
||||
|
||||
import stubs/autonatclientstub
|
||||
|
||||
proc isPublicAddrIPAddrMock(ta: TransportAddress): bool =
|
||||
return true
|
||||
|
||||
proc createSwitch(r: Relay = nil, hpService: Service = nil): Switch {.raises: [LPError, Defect].} =
|
||||
proc createSwitch(r: Relay = nil, hpService: Service = nil, nameResolver: NameResolver = nil): Switch {.raises: [LPError, Defect].} =
|
||||
var builder = SwitchBuilder.new()
|
||||
.withRng(newRng())
|
||||
.withAddresses(@[ MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet() ])
|
||||
|
@ -46,6 +49,9 @@ proc createSwitch(r: Relay = nil, hpService: Service = nil): Switch {.raises: [L
|
|||
if r != nil:
|
||||
builder = builder.withCircuitRelay(r)
|
||||
|
||||
if nameResolver != nil:
|
||||
builder = builder.withNameResolver(nameResolver)
|
||||
|
||||
return builder.build()
|
||||
|
||||
proc buildRelayMA(switchRelay: Switch, switchClient: Switch): MultiAddress =
|
||||
|
@ -90,6 +96,51 @@ suite "Hole Punching":
|
|||
await allFuturesThrowing(
|
||||
privatePeerSwitch.stop(), publicPeerSwitch.stop(), switchRelay.stop())
|
||||
|
||||
asyncTest "Direct connection must work when peer address is public and dns is used":
|
||||
|
||||
let autonatClientStub = AutonatClientStub.new(expectedDials = 1)
|
||||
autonatClientStub.answer = NotReachable
|
||||
let autonatService = AutonatService.new(autonatClientStub, newRng(), maxQueueSize = 1)
|
||||
|
||||
let relayClient = RelayClient.new()
|
||||
let privatePeerRelayAddr = newFuture[seq[MultiAddress]]()
|
||||
|
||||
|
||||
let resolver = MockResolver.new()
|
||||
resolver.ipResponses[("localhost", false)] = @["127.0.0.1"]
|
||||
resolver.ipResponses[("localhost", true)] = @["::1"]
|
||||
|
||||
let publicPeerSwitch = createSwitch(RelayClient.new(), nameResolver = resolver)
|
||||
|
||||
proc addressMapper(listenAddrs: seq[MultiAddress]): Future[seq[MultiAddress]] {.gcsafe, async.} =
|
||||
return @[MultiAddress.init("/dns4/localhost/").tryGet() & listenAddrs[0][1].tryGet()]
|
||||
publicPeerSwitch.peerInfo.addressMappers.add(addressMapper)
|
||||
await publicPeerSwitch.peerInfo.update()
|
||||
|
||||
proc checkMA(address: seq[MultiAddress]) =
|
||||
if not privatePeerRelayAddr.completed():
|
||||
privatePeerRelayAddr.complete(address)
|
||||
|
||||
let autoRelayService = AutoRelayService.new(1, relayClient, checkMA, newRng())
|
||||
|
||||
let hpservice = HPService.new(autonatService, autoRelayService, isPublicAddrIPAddrMock)
|
||||
|
||||
let privatePeerSwitch = createSwitch(relayClient, hpservice, nameResolver = resolver)
|
||||
let switchRelay = createSwitch(Relay.new())
|
||||
|
||||
await allFutures(switchRelay.start(), privatePeerSwitch.start(), publicPeerSwitch.start())
|
||||
|
||||
await privatePeerSwitch.connect(switchRelay.peerInfo.peerId, switchRelay.peerInfo.addrs)
|
||||
|
||||
await publicPeerSwitch.connect(privatePeerSwitch.peerInfo.peerId, (await privatePeerRelayAddr))
|
||||
|
||||
checkExpiring:
|
||||
privatePeerSwitch.connManager.connCount(publicPeerSwitch.peerInfo.peerId) == 1 and
|
||||
not isRelayed(privatePeerSwitch.connManager.selectMuxer(publicPeerSwitch.peerInfo.peerId).connection)
|
||||
|
||||
await allFuturesThrowing(
|
||||
privatePeerSwitch.stop(), publicPeerSwitch.stop(), switchRelay.stop())
|
||||
|
||||
proc holePunchingTest(connectStub: proc (): Future[void] {.async.},
|
||||
isPublicIPAddrProc: IsPublicIPAddrProc,
|
||||
answer: Answer) {.async.} =
|
||||
|
|
Loading…
Reference in New Issue