From 603010f8c9d9655bb0fa3f91dc0bd1b76d3a0bd3 Mon Sep 17 00:00:00 2001 From: rockcavera Date: Mon, 4 May 2020 06:54:08 -0300 Subject: [PATCH] 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() --- lib/pure/net.nim | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/lib/pure/net.nim b/lib/pure/net.nim index fad6e897d6..10589ac122 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -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.