Changed TransportAddress API.
Introduced resolveTAddress(). Added TransportAddress tests.
This commit is contained in:
parent
6985626e1c
commit
960b675d62
|
@ -30,6 +30,10 @@ task test, "Run all tests":
|
|||
exec "nim c -r tests/testsignal"
|
||||
exec "nim c -r -d:release tests/testsignal"
|
||||
|
||||
exec "nim c -r -d:useSysAssert -d:useGcAssert tests/testaddress"
|
||||
exec "nim c -r tests/testaddress"
|
||||
exec "nim c -r -d:release tests/testaddress"
|
||||
|
||||
exec "nim c -r -d:useSysAssert -d:useGcAssert tests/testdatagram"
|
||||
exec "nim c -r tests/testdatagram"
|
||||
exec "nim c -r -d:release tests/testdatagram"
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
# Apache License, version 2.0, (LICENSE-APACHEv2)
|
||||
# MIT license (LICENSE-MIT)
|
||||
|
||||
import net, strutils
|
||||
import net, nativesockets, strutils
|
||||
import ../asyncloop, ../asyncsync
|
||||
|
||||
const
|
||||
|
@ -102,7 +102,7 @@ proc `$`*(address: TransportAddress): string =
|
|||
result.add(":")
|
||||
result.add($int(address.port))
|
||||
|
||||
proc strAddress*(address: string): TransportAddress =
|
||||
proc initTAddress*(address: string): TransportAddress =
|
||||
## Parses string representation of ``address``.
|
||||
##
|
||||
## IPv4 transport address format is ``a.b.c.d:port``.
|
||||
|
@ -110,13 +110,65 @@ proc strAddress*(address: string): TransportAddress =
|
|||
var parts = address.rsplit(":", maxsplit = 1)
|
||||
doAssert(len(parts) == 2, "Format is <address>:<port>!")
|
||||
let port = parseInt(parts[1])
|
||||
doAssert(port > 0 and port < 65536, "Illegal port number!")
|
||||
doAssert(port >= 0 and port < 65536, "Illegal port number!")
|
||||
result.port = Port(port)
|
||||
if parts[0][0] == '[' and parts[0][^1] == ']':
|
||||
result.address = parseIpAddress(parts[0][1..^2])
|
||||
else:
|
||||
result.address = parseIpAddress(parts[0])
|
||||
|
||||
proc initTAddress*(address: string, port: Port): TransportAddress =
|
||||
## Initialize ``TransportAddress`` with IP address ``address`` and
|
||||
## port number ``port``.
|
||||
result.address = parseIpAddress(address)
|
||||
result.port = port
|
||||
|
||||
proc initTAddress*(address: string, port: int): TransportAddress =
|
||||
## Initialize ``TransportAddress`` with IP address ``address`` and
|
||||
## port number ``port``.
|
||||
result.address = parseIpAddress(address)
|
||||
result.port = Port(Port(port and 0xFFFF))
|
||||
|
||||
proc resolveTAddress*(address: string,
|
||||
family = IpAddressFamily.IPv4): seq[TransportAddress] =
|
||||
## Resolve string representation of ``address``.
|
||||
##
|
||||
## Supported formats are:
|
||||
## IPv4 numeric address ``a.b.c.d:port``
|
||||
## IPv6 numeric address ``[::]:port``
|
||||
## Hostname address ``hostname:port``
|
||||
##
|
||||
## If hostname address is detected, then network address translation via DNS
|
||||
## will be performed.
|
||||
var
|
||||
ta: TransportAddress
|
||||
ap: Port
|
||||
result = newSeq[TransportAddress]()
|
||||
var parts = address.rsplit(":", maxsplit = 1)
|
||||
doAssert(len(parts) == 2, "Format is <address>:<port>!")
|
||||
let port = parseInt(parts[1])
|
||||
doAssert(port >= 0 and port < 65536, "Illegal port number!")
|
||||
if parts[0][0] == '[' and parts[0][^1] == ']':
|
||||
ta = TransportAddress(address: parseIpAddress(parts[0][1..^2]),
|
||||
port: Port(port))
|
||||
result.add(ta)
|
||||
else:
|
||||
if isIpAddress(parts[0]):
|
||||
ta = TransportAddress(address: parseIpAddress(parts[0]),
|
||||
port: Port(port))
|
||||
result.add(ta)
|
||||
else:
|
||||
var domain = if family == IpAddressFamily.IPv4: Domain(AF_INET) else:
|
||||
Domain(AF_INET6)
|
||||
var aiList = getAddrInfo(parts[0], Port(port), domain)
|
||||
var it = aiList
|
||||
while it != nil:
|
||||
fromSockAddr(cast[ptr Sockaddr_storage](it.ai_addr)[],
|
||||
SockLen(it.ai_addrlen), ta.address, ta.port)
|
||||
result.add(ta)
|
||||
it = it.ai_next
|
||||
freeAddrInfo(aiList)
|
||||
|
||||
template checkClosed*(t: untyped) =
|
||||
if (ReadClosed in (t).state) or (WriteClosed in (t).state):
|
||||
raise newException(TransportError, "Transport is already closed!")
|
||||
|
@ -133,3 +185,6 @@ when defined(windows):
|
|||
const ERROR_SUCCESS* = 0
|
||||
proc cancelIo*(hFile: HANDLE): WINBOOL
|
||||
{.stdcall, dynlib: "kernel32", importc: "CancelIo".}
|
||||
|
||||
when isMainModule:
|
||||
echo $resolveTAddress("localhost:443", IpAddressFamily.IPv6)
|
|
@ -36,6 +36,11 @@ else:
|
|||
writer: Future[void] # Writer vector completion Future
|
||||
|
||||
type
|
||||
DatagramServer* = ref object of RootRef
|
||||
## Datagram server object
|
||||
transport*: DatagramTransport ## Datagram transport
|
||||
status*: ServerStatus ## Current server status
|
||||
|
||||
DatagramCallback* = proc(transp: DatagramTransport,
|
||||
pbytes: pointer,
|
||||
nbytes: int,
|
||||
|
@ -558,11 +563,6 @@ proc sendTo*(transp: DatagramTransport, pbytes: pointer, nbytes: int,
|
|||
if WriteError in transp.state:
|
||||
raise transp.getError()
|
||||
|
||||
type
|
||||
DatagramServer* = ref object of RootRef
|
||||
transport*: DatagramTransport
|
||||
status*: ServerStatus
|
||||
|
||||
proc createDatagramServer*(host: TransportAddress,
|
||||
cbproc: DatagramCallback,
|
||||
flags: set[ServerFlags] = {},
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
# Asyncdispatch2 Test Suite
|
||||
# (c) Copyright 2018
|
||||
# Status Research & Development GmbH
|
||||
#
|
||||
# Licensed under either of
|
||||
# Apache License, version 2.0, (LICENSE-APACHEv2)
|
||||
# MIT license (LICENSE-MIT)
|
||||
|
||||
import strutils, unittest
|
||||
import ../asyncdispatch2
|
||||
|
||||
when isMainModule:
|
||||
suite "TransportAddress test suite":
|
||||
test "initTAddress(string)":
|
||||
check $initTAddress("0.0.0.0:0") == "0.0.0.0:0"
|
||||
check $initTAddress("255.255.255.255:65535") == "255.255.255.255:65535"
|
||||
check $initTAddress("[::]:0") == "[::]:0"
|
||||
check $initTAddress("[FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF]:65535") ==
|
||||
"[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535"
|
||||
test "initTAddress(string, Port)":
|
||||
check $initTAddress("0.0.0.0", Port(0)) == "0.0.0.0:0"
|
||||
check $initTAddress("255.255.255.255", Port(65535)) ==
|
||||
"255.255.255.255:65535"
|
||||
check $initTAddress("::", Port(0)) == "[::]:0"
|
||||
check $initTAddress("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF",
|
||||
Port(65535)) ==
|
||||
"[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535"
|
||||
test "initTAddress(string, int)":
|
||||
check $initTAddress("0.0.0.0", 0) == "0.0.0.0:0"
|
||||
check $initTAddress("255.255.255.255", 65535) ==
|
||||
"255.255.255.255:65535"
|
||||
check $initTAddress("::", 0) == "[::]:0"
|
||||
check $initTAddress("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", 65535) ==
|
||||
"[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535"
|
||||
test "resolveTAddress(string)":
|
||||
var numeric = [
|
||||
"0.0.0.0:0",
|
||||
"255.0.0.255:54321",
|
||||
"128.128.128.128:12345",
|
||||
"255.255.255.255:65535",
|
||||
"[::]:0",
|
||||
"[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535",
|
||||
"[aaaa:bbbb:cccc:dddd:eeee:ffff::1111]:12345",
|
||||
"[aaaa:bbbb:cccc:dddd:eeee:ffff::]:12345",
|
||||
"[a:b:c:d:e:f::]:12345",
|
||||
"[2222:3333:4444:5555:6666:7777:8888:9999]:56789"
|
||||
]
|
||||
var hostnames = [
|
||||
"www.google.com:443",
|
||||
"www.github.com:443"
|
||||
]
|
||||
for item in numeric:
|
||||
var taseq = resolveTAddress(item)
|
||||
check len(taseq) == 1
|
||||
check $taseq[0] == item
|
||||
|
||||
for item in hostnames:
|
||||
var taseq = resolveTAddress(item)
|
||||
check len(taseq) >= 1
|
|
@ -46,7 +46,7 @@ proc client2(transp: DatagramTransport, pbytes: pointer, nbytes: int,
|
|||
if counterPtr[] == TestsCount:
|
||||
transp.close()
|
||||
else:
|
||||
var ta = strAddress("127.0.0.1:33336")
|
||||
var ta = initTAddress("127.0.0.1:33336")
|
||||
var req = "REQUEST" & $counterPtr[]
|
||||
await transp.sendTo(addr req[0], len(req), ta)
|
||||
else:
|
||||
|
@ -119,7 +119,7 @@ proc client5(transp: DatagramTransport, pbytes: pointer, nbytes: int,
|
|||
if counterPtr[] == MessagesCount:
|
||||
transp.close()
|
||||
else:
|
||||
var ta = strAddress("127.0.0.1:33337")
|
||||
var ta = initTAddress("127.0.0.1:33337")
|
||||
var req = "REQUEST" & $counterPtr[]
|
||||
await transp.sendTo(addr req[0], len(req), ta)
|
||||
else:
|
||||
|
@ -133,7 +133,7 @@ proc client5(transp: DatagramTransport, pbytes: pointer, nbytes: int,
|
|||
transp.close()
|
||||
|
||||
proc test1(): Future[int] {.async.} =
|
||||
var ta = strAddress("127.0.0.1:33336")
|
||||
var ta = initTAddress("127.0.0.1:33336")
|
||||
var counter = 0
|
||||
var dgram1 = newDatagramTransport(client1, udata = addr counter, local = ta)
|
||||
var dgram2 = newDatagramTransport(client2, udata = addr counter)
|
||||
|
@ -144,7 +144,7 @@ proc test1(): Future[int] {.async.} =
|
|||
result = counter
|
||||
|
||||
proc test2(): Future[int] {.async.} =
|
||||
var ta = strAddress("127.0.0.1:33337")
|
||||
var ta = initTAddress("127.0.0.1:33337")
|
||||
var counter = 0
|
||||
var dgram1 = newDatagramTransport(client1, udata = addr counter, local = ta)
|
||||
var dgram2 = newDatagramTransport(client3, udata = addr counter, remote = ta)
|
||||
|
@ -166,7 +166,7 @@ proc waitAll(futs: seq[Future[void]]): Future[void] =
|
|||
return retFuture
|
||||
|
||||
proc test3(bounded: bool): Future[int] {.async.} =
|
||||
var ta = strAddress("127.0.0.1:33337")
|
||||
var ta = initTAddress("127.0.0.1:33337")
|
||||
var counter = 0
|
||||
var dgram1 = newDatagramTransport(client1, udata = addr counter, local = ta)
|
||||
var clients = newSeq[Future[void]](ClientsCount)
|
||||
|
@ -265,7 +265,7 @@ proc serveDatagramClient(transp: DatagramTransport,
|
|||
await transp.sendTo(addr answer[0], len(answer), raddr)
|
||||
|
||||
proc test4(): Future[int] {.async.} =
|
||||
var ta = strAddress("127.0.0.1:31346")
|
||||
var ta = initTAddress("127.0.0.1:31346")
|
||||
var counter = 0
|
||||
var server = createDatagramServer(ta, serveDatagramClient, {ReuseAddr})
|
||||
server.start()
|
||||
|
|
|
@ -244,7 +244,7 @@ proc swarmManager4(address: TransportAddress): Future[int] {.async.} =
|
|||
result += res
|
||||
|
||||
proc test1(): Future[int] {.async.} =
|
||||
var ta = strAddress("127.0.0.1:31344")
|
||||
var ta = initTAddress("127.0.0.1:31344")
|
||||
var server = createStreamServer(ta, serveClient1, {ReuseAddr})
|
||||
server.start()
|
||||
result = await swarmManager1(ta)
|
||||
|
@ -252,7 +252,7 @@ proc test1(): Future[int] {.async.} =
|
|||
server.close()
|
||||
|
||||
proc test2(): Future[int] {.async.} =
|
||||
var ta = strAddress("127.0.0.1:31345")
|
||||
var ta = initTAddress("127.0.0.1:31345")
|
||||
var counter = 0
|
||||
var server = createStreamServer(ta, serveClient2, {ReuseAddr})
|
||||
server.start()
|
||||
|
@ -261,7 +261,7 @@ proc test2(): Future[int] {.async.} =
|
|||
server.close()
|
||||
|
||||
proc test3(): Future[int] {.async.} =
|
||||
var ta = strAddress("127.0.0.1:31346")
|
||||
var ta = initTAddress("127.0.0.1:31346")
|
||||
var counter = 0
|
||||
var server = createStreamServer(ta, serveClient3, {ReuseAddr})
|
||||
server.start()
|
||||
|
@ -270,7 +270,7 @@ proc test3(): Future[int] {.async.} =
|
|||
server.close()
|
||||
|
||||
proc test4(): Future[int] {.async.} =
|
||||
var ta = strAddress("127.0.0.1:31347")
|
||||
var ta = initTAddress("127.0.0.1:31347")
|
||||
var counter = 0
|
||||
var server = createStreamServer(ta, serveClient4, {ReuseAddr})
|
||||
server.start()
|
||||
|
|
Loading…
Reference in New Issue