Integrate dns resolving (#615)
* integrate dns * give hostname to transport dial * add hostname test * switched to websock master * Add dnsaddr dial test w multiple transports
This commit is contained in:
parent
e787fc35a6
commit
c92125a1a4
|
@ -16,7 +16,7 @@ requires "nim >= 1.2.0",
|
||||||
"metrics",
|
"metrics",
|
||||||
"secp256k1",
|
"secp256k1",
|
||||||
"stew#head",
|
"stew#head",
|
||||||
"https://github.com/status-im/nim-websock"
|
"websock"
|
||||||
|
|
||||||
proc runTest(filename: string, verify: bool = true, sign: bool = true,
|
proc runTest(filename: string, verify: bool = true, sign: bool = true,
|
||||||
moreoptions: string = "") =
|
moreoptions: string = "") =
|
||||||
|
|
|
@ -20,6 +20,7 @@ import dial,
|
||||||
connmanager,
|
connmanager,
|
||||||
stream/connection,
|
stream/connection,
|
||||||
transports/transport,
|
transports/transport,
|
||||||
|
nameresolving/nameresolver,
|
||||||
errors
|
errors
|
||||||
|
|
||||||
export dial, errors
|
export dial, errors
|
||||||
|
@ -41,6 +42,7 @@ type
|
||||||
connManager: ConnManager
|
connManager: ConnManager
|
||||||
dialLock: Table[PeerID, AsyncLock]
|
dialLock: Table[PeerID, AsyncLock]
|
||||||
transports: seq[Transport]
|
transports: seq[Transport]
|
||||||
|
nameResolver: NameResolver
|
||||||
|
|
||||||
proc dialAndUpgrade(
|
proc dialAndUpgrade(
|
||||||
self: Dialer,
|
self: Dialer,
|
||||||
|
@ -49,58 +51,63 @@ proc dialAndUpgrade(
|
||||||
Future[Connection] {.async.} =
|
Future[Connection] {.async.} =
|
||||||
debug "Dialing peer", peerId
|
debug "Dialing peer", peerId
|
||||||
|
|
||||||
# Avoid "cannot be captured as it would violate memory safety" errors in Nim-1.4.x.
|
for address in addrs: # for each address
|
||||||
var
|
let
|
||||||
transport: Transport
|
hostname = address.getHostname()
|
||||||
address: MultiAddress
|
resolvedAddresses =
|
||||||
|
if isNil(self.nameResolver): @[address]
|
||||||
|
else: await self.nameResolver.resolveMAddress(address)
|
||||||
|
|
||||||
for t in self.transports: # for each transport
|
for a in resolvedAddresses: # for each resolved address
|
||||||
transport = t
|
for transport in self.transports: # for each transport
|
||||||
for a in addrs: # for each address
|
if transport.handles(a): # check if it can dial it
|
||||||
address = a
|
trace "Dialing address", address = $a, peerId, hostname
|
||||||
if t.handles(a): # check if it can dial it
|
let dialed = try:
|
||||||
trace "Dialing address", address = $a, peerId
|
libp2p_total_dial_attempts.inc()
|
||||||
let dialed = try:
|
# await a connection slot when the total
|
||||||
libp2p_total_dial_attempts.inc()
|
# connection count is equal to `maxConns`
|
||||||
# await a connection slot when the total
|
#
|
||||||
# connection count is equal to `maxConns`
|
# Need to copy to avoid "cannot be captured" errors in Nim-1.4.x.
|
||||||
await self.connManager.trackOutgoingConn(
|
let
|
||||||
() => transport.dial(address)
|
transportCopy = transport
|
||||||
)
|
addressCopy = a
|
||||||
except TooManyConnectionsError as exc:
|
await self.connManager.trackOutgoingConn(
|
||||||
trace "Connection limit reached!"
|
() => transportCopy.dial(hostname, addressCopy)
|
||||||
raise exc
|
)
|
||||||
except CancelledError as exc:
|
except TooManyConnectionsError as exc:
|
||||||
debug "Dialing canceled", msg = exc.msg, peerId
|
trace "Connection limit reached!"
|
||||||
raise exc
|
raise exc
|
||||||
except CatchableError as exc:
|
except CancelledError as exc:
|
||||||
debug "Dialing failed", msg = exc.msg, peerId
|
debug "Dialing canceled", msg = exc.msg, peerId
|
||||||
libp2p_failed_dials.inc()
|
raise exc
|
||||||
continue # Try the next address
|
except CatchableError as exc:
|
||||||
|
debug "Dialing failed", msg = exc.msg, peerId
|
||||||
|
libp2p_failed_dials.inc()
|
||||||
|
continue # Try the next address
|
||||||
|
|
||||||
# make sure to assign the peer to the connection
|
# make sure to assign the peer to the connection
|
||||||
dialed.peerId = peerId
|
dialed.peerId = peerId
|
||||||
|
|
||||||
# also keep track of the connection's bottom unsafe transport direction
|
# also keep track of the connection's bottom unsafe transport direction
|
||||||
# required by gossipsub scoring
|
# required by gossipsub scoring
|
||||||
dialed.transportDir = Direction.Out
|
dialed.transportDir = Direction.Out
|
||||||
|
|
||||||
libp2p_successful_dials.inc()
|
libp2p_successful_dials.inc()
|
||||||
|
|
||||||
let conn = try:
|
let conn = try:
|
||||||
await transport.upgradeOutgoing(dialed)
|
await transport.upgradeOutgoing(dialed)
|
||||||
except CatchableError as exc:
|
except CatchableError as exc:
|
||||||
# If we failed to establish the connection through one transport,
|
# If we failed to establish the connection through one transport,
|
||||||
# we won't succeeded through another - no use in trying again
|
# we won't succeeded through another - no use in trying again
|
||||||
await dialed.close()
|
await dialed.close()
|
||||||
debug "Upgrade failed", msg = exc.msg, peerId
|
debug "Upgrade failed", msg = exc.msg, peerId
|
||||||
if exc isnot CancelledError:
|
if exc isnot CancelledError:
|
||||||
libp2p_failed_upgrades_outgoing.inc()
|
libp2p_failed_upgrades_outgoing.inc()
|
||||||
raise exc
|
raise exc
|
||||||
|
|
||||||
doAssert not isNil(conn), "connection died after upgradeOutgoing"
|
doAssert not isNil(conn), "connection died after upgradeOutgoing"
|
||||||
debug "Dial successful", conn, peerId = conn.peerId
|
debug "Dial successful", conn, peerId = conn.peerId
|
||||||
return conn
|
return conn
|
||||||
|
|
||||||
proc internalConnect(
|
proc internalConnect(
|
||||||
self: Dialer,
|
self: Dialer,
|
||||||
|
@ -234,9 +241,11 @@ proc new*(
|
||||||
localPeerId: PeerId,
|
localPeerId: PeerId,
|
||||||
connManager: ConnManager,
|
connManager: ConnManager,
|
||||||
transports: seq[Transport],
|
transports: seq[Transport],
|
||||||
ms: MultistreamSelect): Dialer =
|
ms: MultistreamSelect,
|
||||||
|
nameResolver: NameResolver = nil): Dialer =
|
||||||
|
|
||||||
T(localPeerId: localPeerId,
|
T(localPeerId: localPeerId,
|
||||||
connManager: connManager,
|
connManager: connManager,
|
||||||
transports: transports,
|
transports: transports,
|
||||||
ms: ms)
|
ms: ms,
|
||||||
|
nameResolver: nameResolver)
|
||||||
|
|
|
@ -40,12 +40,10 @@ method resolveIp*(
|
||||||
|
|
||||||
doAssert(false, "Not implemented!")
|
doAssert(false, "Not implemented!")
|
||||||
|
|
||||||
proc getHostname(ma: MultiAddress): string =
|
proc getHostname*(ma: MultiAddress): string =
|
||||||
var dnsbuf = newSeq[byte](256)
|
let firstPart = ($ma[0].get()).split('/')
|
||||||
|
if firstPart.len > 1: firstPart[2]
|
||||||
let dnsLen = ma[0].get().protoArgument(dnsbuf).get()
|
else: ""
|
||||||
dnsbuf.setLen(dnsLen)
|
|
||||||
return string.fromBytes(dnsbuf)
|
|
||||||
|
|
||||||
proc resolveDnsAddress(
|
proc resolveDnsAddress(
|
||||||
self: NameResolver,
|
self: NameResolver,
|
||||||
|
@ -122,27 +120,26 @@ proc resolveDnsAddr(
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
proc resolveMAddresses*(
|
proc resolveMAddress*(
|
||||||
self: NameResolver,
|
self: NameResolver,
|
||||||
addrs: seq[MultiAddress]): Future[seq[MultiAddress]] {.async.} =
|
address: MultiAddress): Future[seq[MultiAddress]] {.async.} =
|
||||||
var res = initOrderedSet[MultiAddress]()
|
var res = initOrderedSet[MultiAddress]()
|
||||||
|
|
||||||
for address in addrs:
|
if not DNS.matchPartial(address):
|
||||||
if not DNS.matchPartial(address):
|
res.incl(address)
|
||||||
res.incl(address)
|
else:
|
||||||
else:
|
let code = address[0].get().protoCode().get()
|
||||||
let code = address[0].get().protoCode().get()
|
let seq = case code:
|
||||||
let seq = case code:
|
of multiCodec("dns"):
|
||||||
of multiCodec("dns"):
|
await self.resolveDnsAddress(address)
|
||||||
await self.resolveDnsAddress(address)
|
of multiCodec("dns4"):
|
||||||
of multiCodec("dns4"):
|
await self.resolveDnsAddress(address, Domain.AF_INET)
|
||||||
await self.resolveDnsAddress(address, Domain.AF_INET)
|
of multiCodec("dns6"):
|
||||||
of multiCodec("dns6"):
|
await self.resolveDnsAddress(address, Domain.AF_INET6)
|
||||||
await self.resolveDnsAddress(address, Domain.AF_INET6)
|
of multiCodec("dnsaddr"):
|
||||||
of multiCodec("dnsaddr"):
|
await self.resolveDnsAddr(address)
|
||||||
await self.resolveDnsAddr(address)
|
else:
|
||||||
else:
|
@[address]
|
||||||
@[address]
|
for ad in seq:
|
||||||
for ad in seq:
|
res.incl(ad)
|
||||||
res.incl(ad)
|
|
||||||
return res.toSeq
|
return res.toSeq
|
||||||
|
|
|
@ -273,7 +273,7 @@ proc newSwitch*(peerInfo: PeerInfo,
|
||||||
transports: transports,
|
transports: transports,
|
||||||
connManager: connManager,
|
connManager: connManager,
|
||||||
peerStore: PeerStore.new(),
|
peerStore: PeerStore.new(),
|
||||||
dialer: Dialer.new(peerInfo.peerId, connManager, transports, ms),
|
dialer: Dialer.new(peerInfo.peerId, connManager, transports, ms, nameResolver),
|
||||||
nameResolver: nameResolver)
|
nameResolver: nameResolver)
|
||||||
|
|
||||||
switch.connManager.peerStore = switch.peerStore
|
switch.connManager.peerStore = switch.peerStore
|
||||||
|
|
|
@ -199,6 +199,7 @@ method accept*(self: TcpTransport): Future[Connection] {.async, gcsafe.} =
|
||||||
|
|
||||||
method dial*(
|
method dial*(
|
||||||
self: TcpTransport,
|
self: TcpTransport,
|
||||||
|
hostname: string,
|
||||||
address: MultiAddress): Future[Connection] {.async, gcsafe.} =
|
address: MultiAddress): Future[Connection] {.async, gcsafe.} =
|
||||||
## dial a peer
|
## dial a peer
|
||||||
##
|
##
|
||||||
|
|
|
@ -60,12 +60,18 @@ method accept*(self: Transport): Future[Connection]
|
||||||
|
|
||||||
method dial*(
|
method dial*(
|
||||||
self: Transport,
|
self: Transport,
|
||||||
|
hostname: string,
|
||||||
address: MultiAddress): Future[Connection] {.base, gcsafe.} =
|
address: MultiAddress): Future[Connection] {.base, gcsafe.} =
|
||||||
## dial a peer
|
## dial a peer
|
||||||
##
|
##
|
||||||
|
|
||||||
doAssert(false, "Not implemented!")
|
doAssert(false, "Not implemented!")
|
||||||
|
|
||||||
|
proc dial*(
|
||||||
|
self: Transport,
|
||||||
|
address: MultiAddress): Future[Connection] {.gcsafe.} =
|
||||||
|
self.dial("", address)
|
||||||
|
|
||||||
method upgradeIncoming*(
|
method upgradeIncoming*(
|
||||||
self: Transport,
|
self: Transport,
|
||||||
conn: Connection): Future[void] {.base, gcsafe.} =
|
conn: Connection): Future[void] {.base, gcsafe.} =
|
||||||
|
|
|
@ -207,6 +207,7 @@ method accept*(self: WsTransport): Future[Connection] {.async, gcsafe.} =
|
||||||
|
|
||||||
method dial*(
|
method dial*(
|
||||||
self: WsTransport,
|
self: WsTransport,
|
||||||
|
hostname: string,
|
||||||
address: MultiAddress): Future[Connection] {.async, gcsafe.} =
|
address: MultiAddress): Future[Connection] {.async, gcsafe.} =
|
||||||
## dial a peer
|
## dial a peer
|
||||||
##
|
##
|
||||||
|
@ -219,6 +220,7 @@ method dial*(
|
||||||
address.initTAddress().tryGet(),
|
address.initTAddress().tryGet(),
|
||||||
"",
|
"",
|
||||||
secure = secure,
|
secure = secure,
|
||||||
|
hostName = hostname,
|
||||||
flags = self.tlsFlags)
|
flags = self.tlsFlags)
|
||||||
|
|
||||||
return await self.connHandler(transp, Direction.Out)
|
return await self.connHandler(transp, Direction.Out)
|
||||||
|
|
|
@ -59,7 +59,7 @@ suite "Name resolving":
|
||||||
var resolver {.threadvar.}: MockResolver
|
var resolver {.threadvar.}: MockResolver
|
||||||
|
|
||||||
proc testOne(input: string, output: seq[Multiaddress]): bool =
|
proc testOne(input: string, output: seq[Multiaddress]): bool =
|
||||||
let resolved = waitFor resolver.resolveMAddresses(@[Multiaddress.init(input).tryGet()])
|
let resolved = waitFor resolver.resolveMAddress(Multiaddress.init(input).tryGet())
|
||||||
if resolved != output:
|
if resolved != output:
|
||||||
echo "Expected ", output
|
echo "Expected ", output
|
||||||
echo "Got ", resolved
|
echo "Got ", resolved
|
||||||
|
@ -90,18 +90,6 @@ suite "Name resolving":
|
||||||
|
|
||||||
check testOne("/ip6/::1/tcp/0", "/ip6/::1/tcp/0")
|
check testOne("/ip6/::1/tcp/0", "/ip6/::1/tcp/0")
|
||||||
|
|
||||||
asyncTest "test multiple resolve":
|
|
||||||
resolver.ipResponses[("localhost", false)] = @["127.0.0.1"]
|
|
||||||
resolver.ipResponses[("localhost", true)] = @["::1"]
|
|
||||||
|
|
||||||
let resolved = waitFor resolver.resolveMAddresses(@[
|
|
||||||
Multiaddress.init("/dns/localhost/udp/0").tryGet(),
|
|
||||||
Multiaddress.init("/dns4/localhost/udp/0").tryGet(),
|
|
||||||
Multiaddress.init("/dns6/localhost/udp/0").tryGet(),
|
|
||||||
])
|
|
||||||
|
|
||||||
check resolved == @[Multiaddress.init("/ip4/127.0.0.1/udp/0").tryGet(), Multiaddress.init("/ip6/::1/udp/0").tryGet()]
|
|
||||||
|
|
||||||
asyncTest "dnsaddr recursive test":
|
asyncTest "dnsaddr recursive test":
|
||||||
resolver.txtResponses["_dnsaddr.bootstrap.libp2p.io"] = @[
|
resolver.txtResponses["_dnsaddr.bootstrap.libp2p.io"] = @[
|
||||||
"dnsaddr=/dnsaddr/sjc-1.bootstrap.libp2p.io/tcp/4001/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
|
"dnsaddr=/dnsaddr/sjc-1.bootstrap.libp2p.io/tcp/4001/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
|
||||||
|
|
|
@ -21,7 +21,8 @@ import ../libp2p/[errors,
|
||||||
nameresolving/nameresolver,
|
nameresolving/nameresolver,
|
||||||
nameresolving/mockresolver,
|
nameresolving/mockresolver,
|
||||||
stream/chronosstream,
|
stream/chronosstream,
|
||||||
transports/tcptransport]
|
transports/tcptransport,
|
||||||
|
transports/wstransport]
|
||||||
import ./helpers
|
import ./helpers
|
||||||
|
|
||||||
const
|
const
|
||||||
|
@ -463,7 +464,7 @@ suite "Switch":
|
||||||
|
|
||||||
let switch1 = newStandardSwitch()
|
let switch1 = newStandardSwitch()
|
||||||
|
|
||||||
let rng = newRng()
|
let rng = crypto.newRng()
|
||||||
# use same private keys to emulate two connection from same peer
|
# use same private keys to emulate two connection from same peer
|
||||||
let privKey = PrivateKey.random(rng[]).tryGet()
|
let privKey = PrivateKey.random(rng[]).tryGet()
|
||||||
let switch2 = newStandardSwitch(
|
let switch2 = newStandardSwitch(
|
||||||
|
@ -530,7 +531,7 @@ suite "Switch":
|
||||||
asyncTest "e2e should allow dropping peer from connection events":
|
asyncTest "e2e should allow dropping peer from connection events":
|
||||||
var awaiters: seq[Future[void]]
|
var awaiters: seq[Future[void]]
|
||||||
|
|
||||||
let rng = newRng()
|
let rng = crypto.newRng()
|
||||||
# use same private keys to emulate two connection from same peer
|
# use same private keys to emulate two connection from same peer
|
||||||
let
|
let
|
||||||
privateKey = PrivateKey.random(rng[]).tryGet()
|
privateKey = PrivateKey.random(rng[]).tryGet()
|
||||||
|
@ -573,7 +574,7 @@ suite "Switch":
|
||||||
asyncTest "e2e should allow dropping multiple connections for peer from connection events":
|
asyncTest "e2e should allow dropping multiple connections for peer from connection events":
|
||||||
var awaiters: seq[Future[void]]
|
var awaiters: seq[Future[void]]
|
||||||
|
|
||||||
let rng = newRng()
|
let rng = crypto.newRng()
|
||||||
# use same private keys to emulate two connection from same peer
|
# use same private keys to emulate two connection from same peer
|
||||||
let
|
let
|
||||||
privateKey = PrivateKey.random(rng[]).tryGet()
|
privateKey = PrivateKey.random(rng[]).tryGet()
|
||||||
|
@ -901,5 +902,79 @@ suite "Switch":
|
||||||
switch1.peerStore.addressBook.get(switch2.peerInfo.peerId) == switch2.peerInfo.addrs.toHashSet()
|
switch1.peerStore.addressBook.get(switch2.peerInfo.peerId) == switch2.peerInfo.addrs.toHashSet()
|
||||||
switch2.peerStore.addressBook.get(switch1.peerInfo.peerId) == switch1.peerInfo.addrs.toHashSet()
|
switch2.peerStore.addressBook.get(switch1.peerInfo.peerId) == switch1.peerInfo.addrs.toHashSet()
|
||||||
|
|
||||||
switch1.peerStore.addressBook.get(switch2.peerInfo.peerId) == switch2.peerInfo.addrs.toHashSet()
|
switch1.peerStore.protoBook.get(switch2.peerInfo.peerId) == switch2.peerInfo.protocols.toHashSet()
|
||||||
switch2.peerStore.addressBook.get(switch1.peerInfo.peerId) == switch1.peerInfo.addrs.toHashSet()
|
switch2.peerStore.protoBook.get(switch1.peerInfo.peerId) == switch1.peerInfo.protocols.toHashSet()
|
||||||
|
|
||||||
|
asyncTest "e2e dial dns4 address":
|
||||||
|
var awaiters: seq[Future[void]]
|
||||||
|
let resolver = MockResolver.new()
|
||||||
|
resolver.ipResponses[("localhost", false)] = @["127.0.0.1"]
|
||||||
|
resolver.ipResponses[("localhost", true)] = @["::1"]
|
||||||
|
|
||||||
|
let
|
||||||
|
srcSwitch = newStandardSwitch(nameResolver = resolver)
|
||||||
|
destSwitch = newStandardSwitch()
|
||||||
|
|
||||||
|
awaiters.add(await destSwitch.start())
|
||||||
|
awaiters.add(await srcSwitch.start())
|
||||||
|
await allFuturesThrowing(awaiters)
|
||||||
|
|
||||||
|
let testAddr = MultiAddress.init("/dns4/localhost/").tryGet() &
|
||||||
|
destSwitch.peerInfo.addrs[0][1].tryGet()
|
||||||
|
|
||||||
|
await srcSwitch.connect(destSwitch.peerInfo.peerId, @[testAddr])
|
||||||
|
check srcSwitch.isConnected(destSwitch.peerInfo.peerId)
|
||||||
|
|
||||||
|
await destSwitch.stop()
|
||||||
|
await srcSwitch.stop()
|
||||||
|
|
||||||
|
asyncTest "e2e dial dnsaddr with multiple transports":
|
||||||
|
var awaiters: seq[Future[void]]
|
||||||
|
let resolver = MockResolver.new()
|
||||||
|
|
||||||
|
let
|
||||||
|
wsAddress = MultiAddress.init("/ip4/127.0.0.1/tcp/0/ws").tryGet()
|
||||||
|
tcpAddress = MultiAddress.init("/ip4/127.0.0.1/tcp/0").tryGet()
|
||||||
|
|
||||||
|
srcTcpSwitch = newStandardSwitch(nameResolver = resolver)
|
||||||
|
srcWsSwitch =
|
||||||
|
SwitchBuilder.new()
|
||||||
|
.withAddress(wsAddress)
|
||||||
|
.withRng(crypto.newRng())
|
||||||
|
.withMplex()
|
||||||
|
.withTransport(proc (upgr: Upgrade): Transport = WsTransport.new(upgr))
|
||||||
|
.withNameResolver(resolver)
|
||||||
|
.withNoise()
|
||||||
|
.build()
|
||||||
|
|
||||||
|
destSwitch =
|
||||||
|
SwitchBuilder.new()
|
||||||
|
.withAddresses(@[tcpAddress, wsAddress])
|
||||||
|
.withRng(crypto.newRng())
|
||||||
|
.withMplex()
|
||||||
|
.withTransport(proc (upgr: Upgrade): Transport = WsTransport.new(upgr))
|
||||||
|
.withTcpTransport()
|
||||||
|
.withNoise()
|
||||||
|
.build()
|
||||||
|
|
||||||
|
awaiters.add(await destSwitch.start())
|
||||||
|
awaiters.add(await srcTcpSwitch.start())
|
||||||
|
awaiters.add(await srcWsSwitch.start())
|
||||||
|
await allFuturesThrowing(awaiters)
|
||||||
|
|
||||||
|
resolver.txtResponses["_dnsaddr.test.io"] = @[
|
||||||
|
"dnsaddr=/ip4/127.0.0.1" & $destSwitch.peerInfo.addrs[1][1].tryGet() & "/ws",
|
||||||
|
"dnsaddr=/ip4/127.0.0.1" & $destSwitch.peerInfo.addrs[0][1].tryGet()
|
||||||
|
]
|
||||||
|
|
||||||
|
let testAddr = MultiAddress.init("/dnsaddr/test.io/").tryGet()
|
||||||
|
|
||||||
|
await srcTcpSwitch.connect(destSwitch.peerInfo.peerId, @[testAddr])
|
||||||
|
check srcTcpSwitch.isConnected(destSwitch.peerInfo.peerId)
|
||||||
|
|
||||||
|
await srcWsSwitch.connect(destSwitch.peerInfo.peerId, @[testAddr])
|
||||||
|
check srcWsSwitch.isConnected(destSwitch.peerInfo.peerId)
|
||||||
|
|
||||||
|
await destSwitch.stop()
|
||||||
|
await srcWsSwitch.stop()
|
||||||
|
await srcTcpSwitch.stop()
|
||||||
|
|
|
@ -15,56 +15,39 @@ import ./helpers, ./commontransport
|
||||||
const
|
const
|
||||||
SecureKey* = """
|
SecureKey* = """
|
||||||
-----BEGIN PRIVATE KEY-----
|
-----BEGIN PRIVATE KEY-----
|
||||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCdNv0SX02aeZ4/
|
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAP0yH7F7FtGunC91
|
||||||
Yc+p/Kwd5UVOHlpmK7/TVC/kcjFbdoUuKNn8pnX/fyhgSKpUYut+te7YRiZhqlaL
|
IPkU+u8B4gdxiwYW0J3PrixtB1Xz3e4dfjwQqhIJlG6BxQ4myCxmSPjxP/eOOYp+
|
||||||
EZKjfy8GBZwXZnJCevFkTvGTTebXXExLIsLGfJqKeLAdFCQkX8wV3jV1DT5JLV+D
|
8/+A9nikbnc7H3OV8fNJhsSmPu8j8W2FsNVJzJnUQaE2yimrFR8NnvQ4MKvMBSgb
|
||||||
5+HWaiiBr38gsl4ZbfyedTF40JvzokCmcdlx9bpzX1j/b84L/zSwUyyEcgp5G28F
|
lHTLbP1aAFp+K6KPPE7pkRMUdlqFAgMBAAECgYBl0eli4yALFI/kmdK3uBMtWHGA
|
||||||
Jh5TnxAeDHJpOVjr8XMb/xoNqiDF6NwF96hvOZC14mZ1TxxW5bUzXprsy0l52pmh
|
Es4YlcYxIFpnrTS9AQPnhN7F4uGxvT5+rhsDlN780+lWixXxRLWpF2KiBkeW8ayT
|
||||||
dN3Crz11+t2h519hRKHxT6/l5pTx/+dApXiP6hMV04CQJNnas3NyRxTDR9dNel+3
|
kPeWvpSy6z+4LXw633ZLfCO1r6brpqSXNWxA0q7IgzYQEfMpnkaQrE3PVP5xkmTT
|
||||||
+wD7/PRTAgMBAAECggEBAJuXPEbegxMKog7gYoE9S6oaqchySc0sJyCjBPL2ANsg
|
k159ev138J23VfNgRQJBAP768qHOCnplKIe69SVUWlsQ5nnnybDBMq2YVATbombz
|
||||||
JRZV38cnh0hhNDh2MfxqGd7Bd6wbYQjvZ88iiRm+WW+ARcby4MnimtxHNNYwFvG0
|
KD57iufzBgND1clIEEuC6PK2C5gzTk4HZQioJ/juOFcCQQD+NVlb1HLoK7rHXZFO
|
||||||
qt0BffqqftfkMYfV0x8coAJUdFtvy+DoQstsxhlJ3uTaJtrZLD/GlmjMWzXSX0Vy
|
Tg3O+bwRZdo67J4pt//ijF7tLlZU/q6Kp9wHrXe1yhRV+Tow0BzBVHkc5eUM0/n7
|
||||||
FXiLDO7/LoSjsjaf4e4aLofIyLJS3H1T+5cr/d2mdpRzkeWkxShODsK4cRLOlZ5I
|
cOqDAkAedrECb/GEig17mfSsDxX0h2Jh8jWArrR1VRvEsNEIZ8jJHk2MRNbVEQe7
|
||||||
pz4Wm2770DTbiYph8ixl/CnmYn6T7V0F5VYujALknipUBeQY4e/A9vrQ/pvqJV+W
|
0qZPv0ZBqUpdVtPmMq/5hs2vyhZlAkEA1cZ1fCUf8KD9tLS6AnjfYeRgRN07dXwQ
|
||||||
JjFUne6Rxg/lJjh8vNJp2bK1ZbzpwmZLaZIoEz8t/qECgYEAzvCCA48uQPaurSQ3
|
0hKbTKAxIBJspZN7orzg60/0sNrc2SP6zJvm4qowI54tTelhexMNEwJBAOZz72xn
|
||||||
cvHDhcVwYmEaH8MW8aIW/5l8XJK60GsUHPFhEsfD/ObI5PJJ9aOqgabpRHkvD4ZY
|
EFUXKYQBbetiejnBBzFYmdA/QKmZ7kbQfDBOwG9wDPFmvnNSvSZws/bP1zcM95rq
|
||||||
a8QJBxCy6UeogUeKvGks8VQ34SZXLimmgrL9Mlljv0v9PloEkVYbztYyX4GVO0ov
|
NABr5ec1FxuJa/8=
|
||||||
3oH+hKO+/MclzNDyeXZx3Vv4K+UCgYEAwnyb7tqp7fRqm/8EymIZV5pa0p6h609p
|
|
||||||
EhCBi9ii6d/ewEjsBhs7bPDBO4PO9ylvOvryYZH1hVbQja2anOCBjO8dAHRHWM86
|
|
||||||
964TFriywBQkYxp6dsB8nUjLBDza2xAM3m+OGi9/ATuhEAe5sXp/fZL3tkfSaOXI
|
|
||||||
A7Gzro+kS9cCgYEAtKScSfEeBlWQa9H2mV9UN5z/mtF61YkeqTW+b8cTGVh4vWEL
|
|
||||||
wKww+gzqGAV6Duk2CLijKeSDMmO64gl7fC83VjSMiTklbhz+jbQeKFhFI0Sty71N
|
|
||||||
/j+y6NXBTgdOfLRl0lzhj2/JrzdWBtie6tR9UloCaXSKmb04PTFY+kvDWsUCgYBR
|
|
||||||
krJUnKJpi/qrM2tu93Zpp/QwIxkG+We4i/PKFDNApQVo4S0d4o4qQ1DJBZ/pSxe8
|
|
||||||
RUUkZ3PzWVZgFlCjPAcadbBUYHEMbt7sw7Z98ToIFmqspo53AIVD8yQzwtKIz1KW
|
|
||||||
eXPAx+sdOUV008ivCBIxOVNswPMfzED4S7Bxpw3iQQKBgGJhct2nBsgu0l2/wzh9
|
|
||||||
tpKbalW1RllgptNQzjuBEZMTvPF0L+7BE09/exKtt4N9s3yAzi8o6Qo7RHX5djVc
|
|
||||||
SNgafV4jj7jt2Ilh6KOy9dshtLoEkS1NmiqfVe2go2auXZdyGm+I2yzKWdKGDO0J
|
|
||||||
diTtYf1sA0PgNXdSyDC03TZl
|
|
||||||
-----END PRIVATE KEY-----
|
-----END PRIVATE KEY-----
|
||||||
"""
|
"""
|
||||||
|
|
||||||
SecureCert* = """
|
SecureCert* = """
|
||||||
-----BEGIN CERTIFICATE-----
|
-----BEGIN CERTIFICATE-----
|
||||||
MIIDazCCAlOgAwIBAgIUe9fr78Dz9PedQ5Sq0uluMWQhX9wwDQYJKoZIhvcNAQEL
|
MIICjDCCAfWgAwIBAgIURjeiJmkNbBVktqXvnXh44DKx364wDQYJKoZIhvcNAQEL
|
||||||
BQAwRTELMAkGA1UEBhMCSU4xEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
|
BQAwVzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
|
||||||
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTAzMTcwOTMzMzZaFw0zMTAz
|
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEQMA4GA1UEAwwHd3MudGVzdDAgFw0y
|
||||||
MTUwOTMzMzZaMEUxCzAJBgNVBAYTAklOMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
|
MTA5MTQxMTU2NTZaGA8yMDgyMDgzMDExNTY1NlowVzELMAkGA1UEBhMCQVUxEzAR
|
||||||
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
|
BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5
|
||||||
AQUAA4IBDwAwggEKAoIBAQCdNv0SX02aeZ4/Yc+p/Kwd5UVOHlpmK7/TVC/kcjFb
|
IEx0ZDEQMA4GA1UEAwwHd3MudGVzdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
|
||||||
doUuKNn8pnX/fyhgSKpUYut+te7YRiZhqlaLEZKjfy8GBZwXZnJCevFkTvGTTebX
|
gYEA/TIfsXsW0a6cL3Ug+RT67wHiB3GLBhbQnc+uLG0HVfPd7h1+PBCqEgmUboHF
|
||||||
XExLIsLGfJqKeLAdFCQkX8wV3jV1DT5JLV+D5+HWaiiBr38gsl4ZbfyedTF40Jvz
|
DibILGZI+PE/9445in7z/4D2eKRudzsfc5Xx80mGxKY+7yPxbYWw1UnMmdRBoTbK
|
||||||
okCmcdlx9bpzX1j/b84L/zSwUyyEcgp5G28FJh5TnxAeDHJpOVjr8XMb/xoNqiDF
|
KasVHw2e9Dgwq8wFKBuUdMts/VoAWn4roo88TumRExR2WoUCAwEAAaNTMFEwHQYD
|
||||||
6NwF96hvOZC14mZ1TxxW5bUzXprsy0l52pmhdN3Crz11+t2h519hRKHxT6/l5pTx
|
VR0OBBYEFHaV2ief8/Que1wxcZ8ACfdW7NUNMB8GA1UdIwQYMBaAFHaV2ief8/Qu
|
||||||
/+dApXiP6hMV04CQJNnas3NyRxTDR9dNel+3+wD7/PRTAgMBAAGjUzBRMB0GA1Ud
|
e1wxcZ8ACfdW7NUNMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADgYEA
|
||||||
DgQWBBRkSY1AkGUpVNxG5fYocfgFODtQmTAfBgNVHSMEGDAWgBRkSY1AkGUpVNxG
|
XvDtaDLShrjS9huhRVoEdUtoBdhonmFpV3HXqRs7NdTuUWooXiph9a66GVSIfUCR
|
||||||
5fYocfgFODtQmTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBt
|
iEaNOKF6OM0n7GLSDIrBeIWAxL9Ra/dFFwCxl+9wxg8yyzEJDBkAhXkrfp2b4Sx6
|
||||||
D71VH7F8GOQXITFXCrHwEq1Fx3ScuSnL04NJrXw/e9huzLVQOchAYp/EIn4x2utN
|
wdK6xU2VOAxI0GUzwzjcyNl7RDFA3ayFaGl+9+oppWM=
|
||||||
S31dt94wvi/IysOVbR1LatYNF5kKgGj2Wc6DH0PswBMk8R1G8QMeCz+hCjf1VDHe
|
|
||||||
AAW1x2q20rJAvUrT6cRBQqeiMzQj0OaJbvfnd2hu0/d0DFkcuGVgBa2zlbG5rbdU
|
|
||||||
Jnq7MQfSaZHd0uBgiKkS+Zw6XaYfWfByCAGSnUqRdOChiJ2stFVLvu+9oQ+PJjJt
|
|
||||||
Er1u9bKTUyeuYpqXr2BP9dqphwu8R4NFVUg6DIRpMFMsybaL7KAd4hD22RXCvc0m
|
|
||||||
uLu7KODi+eW62MHqs4N2
|
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -86,3 +69,30 @@ suite "WebSocket transport":
|
||||||
TLSCertificate.init(SecureCert),
|
TLSCertificate.init(SecureCert),
|
||||||
{TLSFlags.NoVerifyHost, TLSFlags.NoVerifyServerName}),
|
{TLSFlags.NoVerifyHost, TLSFlags.NoVerifyServerName}),
|
||||||
"/ip4/0.0.0.0/tcp/0/wss")
|
"/ip4/0.0.0.0/tcp/0/wss")
|
||||||
|
|
||||||
|
asyncTest "Hostname verification":
|
||||||
|
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0/wss").tryGet()
|
||||||
|
let transport1 = WsTransport.new(Upgrade(), TLSPrivateKey.init(SecureKey), TLSCertificate.init(SecureCert), {TLSFlags.NoVerifyHost})
|
||||||
|
|
||||||
|
await transport1.start(ma)
|
||||||
|
proc acceptHandler() {.async, gcsafe.} =
|
||||||
|
while true:
|
||||||
|
let conn = await transport1.accept()
|
||||||
|
if not isNil(conn):
|
||||||
|
await conn.close()
|
||||||
|
|
||||||
|
let handlerWait = acceptHandler()
|
||||||
|
|
||||||
|
# ws.test is in certificate
|
||||||
|
let conn = await transport1.dial("ws.test", transport1.ma)
|
||||||
|
|
||||||
|
await conn.close()
|
||||||
|
|
||||||
|
try:
|
||||||
|
let conn = await transport1.dial("ws.wronghostname", transport1.ma)
|
||||||
|
check false
|
||||||
|
except CatchableError as exc:
|
||||||
|
check true
|
||||||
|
|
||||||
|
await handlerWait.cancelAndWait()
|
||||||
|
await transport1.stop()
|
||||||
|
|
Loading…
Reference in New Issue