From 598209de2161df196419cb39a2d595c6abf8763b Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Wed, 4 Mar 2020 17:49:52 -0500 Subject: [PATCH] Sockets: fix return value of getpeername/getsockname (#34986) --- src/jl_uv.c | 10 +++----- stdlib/Sockets/src/Sockets.jl | 44 +++++++++++++++------------------ stdlib/Sockets/test/runtests.jl | 14 +++++++++-- 3 files changed, 36 insertions(+), 32 deletions(-) diff --git a/src/jl_uv.c b/src/jl_uv.c index 80a91efc38047..6c945f8f4d7ac 100644 --- a/src/jl_uv.c +++ b/src/jl_uv.c @@ -672,6 +672,8 @@ JL_DLLEXPORT int jl_tcp_getsockname(uv_tcp_t *handle, uint16_t *port, memset(&addr, 0, sizeof(struct sockaddr_storage)); namelen = sizeof addr; int res = uv_tcp_getsockname(handle, (struct sockaddr*)&addr, &namelen); + if (res) + return res; *family = addr.ss_family; if (addr.ss_family == AF_INET) { struct sockaddr_in *addr4 = (struct sockaddr_in*)&addr; @@ -683,9 +685,6 @@ JL_DLLEXPORT int jl_tcp_getsockname(uv_tcp_t *handle, uint16_t *port, *port = addr6->sin6_port; memcpy(host, &(addr6->sin6_addr), 16); } - else { - return -1; - } return res; } @@ -697,6 +696,8 @@ JL_DLLEXPORT int jl_tcp_getpeername(uv_tcp_t *handle, uint16_t *port, memset(&addr, 0, sizeof(struct sockaddr_storage)); namelen = sizeof addr; int res = uv_tcp_getpeername(handle, (struct sockaddr*)&addr, &namelen); + if (res) + return res; *family = addr.ss_family; if (addr.ss_family == AF_INET) { struct sockaddr_in *addr4 = (struct sockaddr_in*)&addr; @@ -708,9 +709,6 @@ JL_DLLEXPORT int jl_tcp_getpeername(uv_tcp_t *handle, uint16_t *port, *port = addr6->sin6_port; memcpy(host, &(addr6->sin6_addr), 16); } - else { - return -1; - } return res; } diff --git a/stdlib/Sockets/src/Sockets.jl b/stdlib/Sockets/src/Sockets.jl index fa4aab7832511..5e87abda233a2 100644 --- a/stdlib/Sockets/src/Sockets.jl +++ b/stdlib/Sockets/src/Sockets.jl @@ -760,32 +760,28 @@ function _sockname(sock, self=true) end iolock_end() uv_error("cannot obtain socket name", r) - if r == 0 - port = ntoh(rport[]) - af_inet6 = @static if Sys.iswindows() # AF_INET6 in - 23 - elseif Sys.isapple() - 30 - elseif Sys.KERNEL ∈ (:FreeBSD, :DragonFly) - 28 - elseif Sys.KERNEL ∈ (:NetBSD, :OpenBSD) - 24 - else - 10 - end + port = ntoh(rport[]) + af_inet6 = @static if Sys.iswindows() # AF_INET6 in + 23 + elseif Sys.isapple() + 30 + elseif Sys.KERNEL ∈ (:FreeBSD, :DragonFly) + 28 + elseif Sys.KERNEL ∈ (:NetBSD, :OpenBSD) + 24 + else + 10 + end - if rfamily[] == 2 # AF_INET - addrv4 = raddress[1:4] - naddr = ntoh(unsafe_load(Ptr{Cuint}(pointer(addrv4)), 1)) - addr = IPv4(naddr) - elseif rfamily[] == af_inet6 - naddr = ntoh(unsafe_load(Ptr{UInt128}(pointer(raddress)), 1)) - addr = IPv6(naddr) - else - error(string("unsupported address family: ", getindex(rfamily))) - end + if rfamily[] == 2 # AF_INET + addrv4 = raddress[1:4] + naddr = ntoh(unsafe_load(Ptr{Cuint}(pointer(addrv4)), 1)) + addr = IPv4(naddr) + elseif rfamily[] == af_inet6 + naddr = ntoh(unsafe_load(Ptr{UInt128}(pointer(raddress)), 1)) + addr = IPv6(naddr) else - error("cannot obtain socket name") + error(string("unsupported address family: ", rfamily[])) end return addr, port end diff --git a/stdlib/Sockets/test/runtests.jl b/stdlib/Sockets/test/runtests.jl index eeb99d0a29cdf..8268e5a6d0b06 100644 --- a/stdlib/Sockets/test/runtests.jl +++ b/stdlib/Sockets/test/runtests.jl @@ -182,6 +182,18 @@ defaultport = rand(2000:4000) end end +@testset "getsockname errors" begin + sock = TCPSocket() + serv = Sockets.TCPServer() + @test_throws MethodError getpeername(serv) + @test_throws Base._UVError("cannot obtain socket name", Base.UV_EBADF) getpeername(sock) + @test_throws Base._UVError("cannot obtain socket name", Base.UV_EBADF) getsockname(serv) + @test_throws Base._UVError("cannot obtain socket name", Base.UV_EBADF) getsockname(sock) + close(sock) + close(serv) +end + + @testset "getnameinfo on some unroutable IP addresses (RFC 5737)" begin @test getnameinfo(ip"192.0.2.1") == "192.0.2.1" @test getnameinfo(ip"198.51.100.1") == "198.51.100.1" @@ -344,8 +356,6 @@ end @test addr == gsn_addr @test port == gsn_port - @test_throws MethodError getpeername(listen_sock) - # connect to it client_sock = connect(addr, port) server_sock = accept(listen_sock)