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
commit 603010f8c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

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