mirror of
https://github.com/vacp2p/nim-libp2p-experimental.git
synced 2025-02-04 14:23:58 +00:00
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:
|
if relayPid notin self.relayAddresses or self.relayAddresses[relayPid] != relayedAddr:
|
||||||
self.relayAddresses[relayPid] = relayedAddr
|
self.relayAddresses[relayPid] = relayedAddr
|
||||||
await switch.peerInfo.update()
|
await switch.peerInfo.update()
|
||||||
|
debug "Updated relay addresses", relayPid, relayedAddr
|
||||||
if not self.onReservation.isNil():
|
if not self.onReservation.isNil():
|
||||||
self.onReservation(concat(toSeq(self.relayAddresses.values)))
|
self.onReservation(concat(toSeq(self.relayAddresses.values)))
|
||||||
await sleepAsync chronos.seconds(ttl - 30)
|
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)
|
return T(autonatService: autonatService, autoRelayService: autoRelayService, isPublicIPAddrProc: isPublicIPAddrProc)
|
||||||
|
|
||||||
proc tryStartingDirectConn(self: HPService, switch: Switch, peerId: PeerId): Future[bool] {.async.} =
|
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
|
await sleepAsync(500.milliseconds) # wait for AddressBook to be populated
|
||||||
for address in switch.peerStore[AddressBook][peerId]:
|
for address in switch.peerStore[AddressBook][peerId]:
|
||||||
try:
|
try:
|
||||||
let ta = initTAddress(address)
|
if DNS.matchPartial(address):
|
||||||
if ta.isOk() and self.isPublicIPAddrProc(ta.get()):
|
return await tryConnect(address)
|
||||||
await switch.connect(peerId, @[address], true, false)
|
else:
|
||||||
debug "Direct connection created."
|
let ta = initTAddress(address)
|
||||||
return true
|
if ta.isOk() and self.isPublicIPAddrProc(ta.get()):
|
||||||
|
return await tryConnect(address)
|
||||||
except CatchableError as err:
|
except CatchableError as err:
|
||||||
debug "Failed to create direct connection.", err = err.msg
|
debug "Failed to create direct connection.", err = err.msg
|
||||||
continue
|
continue
|
||||||
|
@ -339,7 +339,7 @@ proc start*(s: Switch) {.async, gcsafe, public.} =
|
|||||||
warn "Switch has already been started"
|
warn "Switch has already been started"
|
||||||
return
|
return
|
||||||
|
|
||||||
trace "starting switch for peer", peerInfo = s.peerInfo
|
debug "starting switch for peer", peerInfo = s.peerInfo
|
||||||
var startFuts: seq[Future[void]]
|
var startFuts: seq[Future[void]]
|
||||||
for t in s.transports:
|
for t in s.transports:
|
||||||
let addrs = s.peerInfo.listenAddrs.filterIt(
|
let addrs = s.peerInfo.listenAddrs.filterIt(
|
||||||
|
@ -26,12 +26,15 @@ import ../libp2p/[builders,
|
|||||||
import ../libp2p/protocols/connectivity/relay/[relay, client]
|
import ../libp2p/protocols/connectivity/relay/[relay, client]
|
||||||
import ../libp2p/protocols/connectivity/autonat/[service]
|
import ../libp2p/protocols/connectivity/autonat/[service]
|
||||||
import ../libp2p/wire
|
import ../libp2p/wire
|
||||||
|
import ../libp2p/nameresolving/nameresolver
|
||||||
|
import ../libp2p/nameresolving/mockresolver
|
||||||
|
|
||||||
import stubs/autonatclientstub
|
import stubs/autonatclientstub
|
||||||
|
|
||||||
proc isPublicAddrIPAddrMock(ta: TransportAddress): bool =
|
proc isPublicAddrIPAddrMock(ta: TransportAddress): bool =
|
||||||
return true
|
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()
|
var builder = SwitchBuilder.new()
|
||||||
.withRng(newRng())
|
.withRng(newRng())
|
||||||
.withAddresses(@[ MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet() ])
|
.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:
|
if r != nil:
|
||||||
builder = builder.withCircuitRelay(r)
|
builder = builder.withCircuitRelay(r)
|
||||||
|
|
||||||
|
if nameResolver != nil:
|
||||||
|
builder = builder.withNameResolver(nameResolver)
|
||||||
|
|
||||||
return builder.build()
|
return builder.build()
|
||||||
|
|
||||||
proc buildRelayMA(switchRelay: Switch, switchClient: Switch): MultiAddress =
|
proc buildRelayMA(switchRelay: Switch, switchClient: Switch): MultiAddress =
|
||||||
@ -90,6 +96,51 @@ suite "Hole Punching":
|
|||||||
await allFuturesThrowing(
|
await allFuturesThrowing(
|
||||||
privatePeerSwitch.stop(), publicPeerSwitch.stop(), switchRelay.stop())
|
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.},
|
proc holePunchingTest(connectStub: proc (): Future[void] {.async.},
|
||||||
isPublicIPAddrProc: IsPublicIPAddrProc,
|
isPublicIPAddrProc: IsPublicIPAddrProc,
|
||||||
answer: Answer) {.async.} =
|
answer: Answer) {.async.} =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user