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"
|
packageName = "chronos"
|
||||||
version = "2.3.5"
|
version = "2.3.6"
|
||||||
author = "Status Research & Development GmbH"
|
author = "Status Research & Development GmbH"
|
||||||
description = "Chronos"
|
description = "Chronos"
|
||||||
license = "Apache License 2.0 or MIT"
|
license = "Apache License 2.0 or MIT"
|
||||||
|
|
|
@ -448,6 +448,21 @@ proc resolveTAddress*(address: string, port: Port,
|
||||||
elif family == IpAddressFamily.IPv6:
|
elif family == IpAddressFamily.IPv6:
|
||||||
result = resolveTAddress(address, port, AddressFamily.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) =
|
template checkClosed*(t: untyped) =
|
||||||
if (ReadClosed in (t).state) or (WriteClosed in (t).state):
|
if (ReadClosed in (t).state) or (WriteClosed in (t).state):
|
||||||
raise newException(TransportError, "Transport is already closed!")
|
raise newException(TransportError, "Transport is already closed!")
|
||||||
|
|
|
@ -165,7 +165,8 @@ when defined(windows):
|
||||||
transp.setWriterWSABuffer(vector)
|
transp.setWriterWSABuffer(vector)
|
||||||
var ret: cint
|
var ret: cint
|
||||||
if vector.kind == WithAddress:
|
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,
|
ret = WSASendTo(fd, addr transp.wwsabuf, DWORD(1), addr bytesCount,
|
||||||
DWORD(0), cast[ptr SockAddr](addr transp.waddr),
|
DWORD(0), cast[ptr SockAddr](addr transp.waddr),
|
||||||
cint(transp.walen),
|
cint(transp.walen),
|
||||||
|
@ -359,16 +360,17 @@ when defined(windows):
|
||||||
raiseTransportOsError(err)
|
raiseTransportOsError(err)
|
||||||
|
|
||||||
if remote.port != Port(0):
|
if remote.port != Port(0):
|
||||||
|
var fixedAddress = windowsAnyAddressFix(remote)
|
||||||
var saddr: Sockaddr_storage
|
var saddr: Sockaddr_storage
|
||||||
var slen: SockLen
|
var slen: SockLen
|
||||||
toSAddr(remote, saddr, slen)
|
toSAddr(fixedAddress, saddr, slen)
|
||||||
if connect(SocketHandle(localSock), cast[ptr SockAddr](addr saddr),
|
if connect(SocketHandle(localSock), cast[ptr SockAddr](addr saddr),
|
||||||
slen) != 0:
|
slen) != 0:
|
||||||
let err = osLastError()
|
let err = osLastError()
|
||||||
if sock == asyncInvalidSocket:
|
if sock == asyncInvalidSocket:
|
||||||
closeSocket(localSock)
|
closeSocket(localSock)
|
||||||
raiseTransportOsError(err)
|
raiseTransportOsError(err)
|
||||||
result.remote = remote
|
result.remote = fixedAddress
|
||||||
|
|
||||||
result.fd = localSock
|
result.fd = localSock
|
||||||
result.function = cbproc
|
result.function = cbproc
|
||||||
|
|
|
@ -685,18 +685,8 @@ when defined(windows):
|
||||||
sock: AsyncFD
|
sock: AsyncFD
|
||||||
povl: RefCustomOverlapped
|
povl: RefCustomOverlapped
|
||||||
proto: Protocol
|
proto: Protocol
|
||||||
raddress: TransportAddress
|
|
||||||
|
|
||||||
## BSD Sockets on *nix systems are able to perform connections to
|
var raddress = windowsAnyAddressFix(address)
|
||||||
## `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
|
|
||||||
|
|
||||||
toSAddr(raddress, saddr, slen)
|
toSAddr(raddress, saddr, slen)
|
||||||
proto = Protocol.IPPROTO_TCP
|
proto = Protocol.IPPROTO_TCP
|
||||||
|
|
|
@ -483,6 +483,55 @@ suite "Datagram Transport test suite":
|
||||||
await wait(dgram1.join(), 5.seconds)
|
await wait(dgram1.join(), 5.seconds)
|
||||||
result = res
|
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":
|
test "close(transport) test":
|
||||||
check waitFor(testTransportClose()) == true
|
check waitFor(testTransportClose()) == true
|
||||||
test m1:
|
test m1:
|
||||||
|
@ -505,5 +554,7 @@ suite "Datagram Transport test suite":
|
||||||
check waitFor(testConnReset()) == true
|
check waitFor(testConnReset()) == true
|
||||||
test "Broadcast test":
|
test "Broadcast test":
|
||||||
check waitFor(testBroadcast()) == 1
|
check waitFor(testBroadcast()) == 1
|
||||||
|
test "0.0.0.0/::0 (INADDR_ANY) test":
|
||||||
|
check waitFor(testAnyAddress()) == 6
|
||||||
test "Transports leak test":
|
test "Transports leak test":
|
||||||
check getTracker("datagram.transport").isLeaked() == false
|
check getTracker("datagram.transport").isLeaked() == false
|
||||||
|
|
Loading…
Reference in New Issue