Fixes net.recvFrom to work correctly with IPv6 (#14131)

* added high level sendTo and recvFrom to std/asyncnet; tests were also added.
* add .since annotation, a changelog entry and fixed to standard library style guide.
* fixes net.recvFrom to work correctly with IPv6
* raise if domain is not AF_INET or AF_INET6
* renamed template to adaptRecvFromToDomain()
This commit is contained in:
rockcavera
2020-05-04 06:54:08 -03:00
committed by GitHub
parent f115e40e6a
commit 603010f8c9

View File

@@ -1425,21 +1425,33 @@ proc recvFrom*(socket: Socket, data: var string, length: int,
## so when ``socket`` is buffered the non-buffered implementation will be
## used. Therefore if ``socket`` contains something in its buffer this
## function will make no effort to return it.
template adaptRecvFromToDomain(domain: Domain) =
var addrLen = sizeof(sockAddress).SockLen
result = recvfrom(socket.fd, cstring(data), length.cint, flags.cint,
cast[ptr SockAddr](addr(sockAddress)), addr(addrLen))
if result != -1:
data.setLen(result)
address = getAddrString(cast[ptr SockAddr](addr(sockAddress)))
when domain == AF_INET6:
port = ntohs(sockAddress.sin6_port).Port
else:
port = ntohs(sockAddress.sin_port).Port
else:
raiseOSError(osLastError())
assert(socket.protocol != IPPROTO_TCP, "Cannot `recvFrom` on a TCP socket")
# TODO: Buffered sockets
data.setLen(length)
var sockAddress: Sockaddr_in
var addrLen = sizeof(sockAddress).SockLen
result = recvfrom(socket.fd, cstring(data), length.cint, flags.cint,
cast[ptr SockAddr](addr(sockAddress)), addr(addrLen))
if result != -1:
data.setLen(result)
address = getAddrString(cast[ptr SockAddr](addr(sockAddress)))
port = ntohs(sockAddress.sin_port).Port
case socket.domain
of AF_INET6:
var sockAddress: Sockaddr_in6
adaptRecvFromToDomain(AF_INET6)
of AF_INET:
var sockAddress: Sockaddr_in
adaptRecvFromToDomain(AF_INET)
else:
raiseOSError(osLastError())
raise newException(ValueError, "Unknown socket address family")
proc skip*(socket: Socket, size: int, timeout = -1) =
## Skips ``size`` amount of bytes.