Skip to content

Commit

Permalink
Sockets: fix return value of getpeername/getsockname (#34986)
Browse files Browse the repository at this point in the history
  • Loading branch information
Keno authored Mar 4, 2020
1 parent fed29f8 commit 598209d
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 32 deletions.
10 changes: 4 additions & 6 deletions src/jl_uv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}

Expand All @@ -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;
Expand All @@ -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;
}

Expand Down
44 changes: 20 additions & 24 deletions stdlib/Sockets/src/Sockets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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 <sys/socket.h>
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 <sys/socket.h>
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
Expand Down
14 changes: 12 additions & 2 deletions stdlib/Sockets/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 598209d

Please sign in to comment.