Merge pull request #79 from status-im/dgramanyaddr
Fix Windows datagram's AnyAddress issue.
This commit is contained in:
commit
fe1b1a6983
|
@ -1,5 +1,5 @@
|
|||
packageName = "chronos"
|
||||
version = "2.3.5"
|
||||
version = "2.3.6"
|
||||
author = "Status Research & Development GmbH"
|
||||
description = "Chronos"
|
||||
license = "Apache License 2.0 or MIT"
|
||||
|
|
|
@ -448,6 +448,21 @@ proc resolveTAddress*(address: string, port: Port,
|
|||
elif family == IpAddressFamily.IPv6:
|
||||
result = resolveTAddress(address, port, AddressFamily.IPv6)
|
||||
|
||||
proc windowsAnyAddressFix*(a: TransportAddress): TransportAddress {.inline.} =
|
||||
## BSD Sockets on *nix systems are able to perform connections to
|
||||
## `0.0.0.0` or `::0` which are equal to `127.0.0.1` or `::1`.
|
||||
when defined(windows):
|
||||
if (a.family == AddressFamily.IPv4 and
|
||||
a.address_v4 == AnyAddress.address_v4):
|
||||
result = initTAddress("127.0.0.1", a.port)
|
||||
elif (a.family == AddressFamily.IPv6 and
|
||||
a.address_v6 == AnyAddress6.address_v6):
|
||||
result = initTAddress("::1", a.port)
|
||||
else:
|
||||
result = a
|
||||
else:
|
||||
result = a
|
||||
|
||||
template checkClosed*(t: untyped) =
|
||||
if (ReadClosed in (t).state) or (WriteClosed in (t).state):
|
||||
raise newException(TransportError, "Transport is already closed!")
|
||||
|
|
|
@ -165,7 +165,8 @@ when defined(windows):
|
|||
transp.setWriterWSABuffer(vector)
|
||||
var ret: cint
|
||||
if vector.kind == WithAddress:
|
||||
toSAddr(vector.address, transp.waddr, transp.walen)
|
||||
var fixedAddress = windowsAnyAddressFix(vector.address)
|
||||
toSAddr(fixedAddress, transp.waddr, transp.walen)
|
||||
ret = WSASendTo(fd, addr transp.wwsabuf, DWORD(1), addr bytesCount,
|
||||
DWORD(0), cast[ptr SockAddr](addr transp.waddr),
|
||||
cint(transp.walen),
|
||||
|
@ -359,16 +360,17 @@ when defined(windows):
|
|||
raiseTransportOsError(err)
|
||||
|
||||
if remote.port != Port(0):
|
||||
var fixedAddress = windowsAnyAddressFix(remote)
|
||||
var saddr: Sockaddr_storage
|
||||
var slen: SockLen
|
||||
toSAddr(remote, saddr, slen)
|
||||
toSAddr(fixedAddress, saddr, slen)
|
||||
if connect(SocketHandle(localSock), cast[ptr SockAddr](addr saddr),
|
||||
slen) != 0:
|
||||
let err = osLastError()
|
||||
if sock == asyncInvalidSocket:
|
||||
closeSocket(localSock)
|
||||
raiseTransportOsError(err)
|
||||
result.remote = remote
|
||||
result.remote = fixedAddress
|
||||
|
||||
result.fd = localSock
|
||||
result.function = cbproc
|
||||
|
|
|
@ -685,18 +685,8 @@ when defined(windows):
|
|||
sock: AsyncFD
|
||||
povl: RefCustomOverlapped
|
||||
proto: Protocol
|
||||
raddress: TransportAddress
|
||||
|
||||
## BSD Sockets on *nix systems are able to perform connections to
|
||||
## `0.0.0.0` or `::0` which are equal to `127.0.0.1` or `::1`.
|
||||
if (address.family == AddressFamily.IPv4 and
|
||||
address.address_v4 == AnyAddress.address_v4):
|
||||
raddress = initTAddress("127.0.0.1", address.port)
|
||||
elif (address.family == AddressFamily.IPv6 and
|
||||
address.address_v6 == AnyAddress6.address_v6):
|
||||
raddress = initTAddress("::1", address.port)
|
||||
else:
|
||||
raddress = address
|
||||
var raddress = windowsAnyAddressFix(address)
|
||||
|
||||
toSAddr(raddress, saddr, slen)
|
||||
proto = Protocol.IPPROTO_TCP
|
||||
|
|
|
@ -483,6 +483,55 @@ suite "Datagram Transport test suite":
|
|||
await wait(dgram1.join(), 5.seconds)
|
||||
result = res
|
||||
|
||||
proc testAnyAddress(): Future[int] {.async.} =
|
||||
var expectStr = "ANYADDRESS MESSAGE"
|
||||
var expectSeq = cast[seq[byte]](expectStr)
|
||||
let ta = initTAddress("0.0.0.0:0")
|
||||
var res = 0
|
||||
var event = newAsyncEvent()
|
||||
|
||||
proc clientMark1(transp: DatagramTransport,
|
||||
raddr: TransportAddress): Future[void] {.async.} =
|
||||
var bmsg = transp.getMessage()
|
||||
var smsg = cast[string](bmsg)
|
||||
if smsg == expectStr:
|
||||
inc(res)
|
||||
event.fire()
|
||||
|
||||
proc clientMark2(transp: DatagramTransport,
|
||||
raddr: TransportAddress): Future[void] {.async.} =
|
||||
discard
|
||||
|
||||
var dgram1 = newDatagramTransport(clientMark1, local = ta)
|
||||
let la = dgram1.localAddress()
|
||||
var dgram2 = newDatagramTransport(clientMark2)
|
||||
var dgram3 = newDatagramTransport(clientMark2,
|
||||
remote = la)
|
||||
await dgram2.sendTo(la, addr expectStr[0], len(expectStr))
|
||||
await event.wait()
|
||||
event.clear()
|
||||
await dgram2.sendTo(la, expectStr)
|
||||
await event.wait()
|
||||
event.clear()
|
||||
await dgram2.sendTo(la, expectSeq)
|
||||
await event.wait()
|
||||
event.clear()
|
||||
await dgram3.send(addr expectStr[0], len(expectStr))
|
||||
await event.wait()
|
||||
event.clear()
|
||||
await dgram3.send(expectStr)
|
||||
await event.wait()
|
||||
event.clear()
|
||||
await dgram3.send(expectSeq)
|
||||
await event.wait()
|
||||
event.clear()
|
||||
|
||||
await dgram1.closeWait()
|
||||
await dgram2.closeWait()
|
||||
await dgram3.closeWait()
|
||||
|
||||
result = res
|
||||
|
||||
test "close(transport) test":
|
||||
check waitFor(testTransportClose()) == true
|
||||
test m1:
|
||||
|
@ -505,5 +554,7 @@ suite "Datagram Transport test suite":
|
|||
check waitFor(testConnReset()) == true
|
||||
test "Broadcast test":
|
||||
check waitFor(testBroadcast()) == 1
|
||||
test "0.0.0.0/::0 (INADDR_ANY) test":
|
||||
check waitFor(testAnyAddress()) == 6
|
||||
test "Transports leak test":
|
||||
check getTracker("datagram.transport").isLeaked() == false
|
||||
|
|
Loading…
Reference in New Issue