diff --git a/src/libstd/net_ip.rs b/src/libstd/net_ip.rs index cf5323c498b..5d78fb19bab 100644 --- a/src/libstd/net_ip.rs +++ b/src/libstd/net_ip.rs @@ -10,8 +10,10 @@ use addrinfo = uv::ll::addrinfo; use uv_getaddrinfo_t = uv::ll::uv_getaddrinfo_t; use uv_ip4_addr = uv::ll::ip4_addr; use uv_ip4_name = uv::ll::ip4_name; +use uv_ip4_port = uv::ll::ip4_port; use uv_ip6_addr = uv::ll::ip6_addr; use uv_ip6_name = uv::ll::ip6_name; +use uv_ip6_port = uv::ll::ip6_port; use uv_getaddrinfo = uv::ll::getaddrinfo; use uv_freeaddrinfo = uv::ll::freeaddrinfo; use create_uv_getaddrinfo_t = uv::ll::getaddrinfo_t; @@ -33,11 +35,11 @@ type ParseAddrErr = { }; /** - * Convert a `ip_addr` to a str + * Convert a `IpAddr` to a str * * # Arguments * - * * ip - a `std::net::ip::ip_addr` + * * ip - a `std::net::ip::IpAddr` */ pub fn format_addr(ip: &IpAddr) -> ~str { match *ip { @@ -58,6 +60,23 @@ pub fn format_addr(ip: &IpAddr) -> ~str { } } +/** + * Get the associated port + * + * # Arguments + * * ip - a `std::net::ip::IpAddr` + */ +pub fn get_port(ip: &IpAddr) -> uint { + match *ip { + Ipv4(ref addr) => unsafe { + uv_ip4_port(addr) + }, + Ipv6(ref addr) => unsafe { + uv_ip6_port(addr) + } + } +} + /// Represents errors returned from `net::ip::get_addr()` enum IpGetAddrErr { GetAddrUnknownError diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs index db5c1328e62..94293c3aa41 100644 --- a/src/libstd/net_tcp.rs +++ b/src/libstd/net_tcp.rs @@ -746,6 +746,22 @@ impl TcpSocket { -> future::Future> { write_future(&self, raw_write_data) } + pub fn getpeername() -> ip::IpAddr { + unsafe { + let addr = uv::ll::ip4_addr("", 0); + uv::ll::tcp_getpeername(self.socket_data.stream_handle_ptr, + ptr::addr_of(&addr)); + ip::Ipv4(move addr) + } + } + pub fn getpeername6() -> ip::IpAddr { + unsafe { + let addr = uv::ll::ip6_addr("", 0); + uv::ll::tcp_getpeername6(self.socket_data.stream_handle_ptr, + ptr::addr_of(&addr)); + ip::Ipv6(move addr) + } + } } /// Implementation of `io::reader` trait for a buffered `net::tcp::tcp_socket` diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs index b4b04a1a714..c12682fcc92 100644 --- a/src/libstd/uv_ll.rs +++ b/src/libstd/uv_ll.rs @@ -590,6 +590,8 @@ extern mod rustrt { -> libc::c_int; fn rust_uv_ip6_name(src: *sockaddr_in6, dst: *u8, size: libc::size_t) -> libc::c_int; + fn rust_uv_ip4_port(src: *sockaddr_in) -> libc::c_uint; + fn rust_uv_ip6_port(src: *sockaddr_in6) -> libc::c_uint; // FIXME ref #2064 fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t, @@ -606,6 +608,10 @@ extern mod rustrt { // FIXME ref #2064 fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, ++addr: *sockaddr_in6) -> libc::c_int; + fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, + ++name: *sockaddr_in) -> libc::c_int; + fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, + ++name: *sockaddr_in6) ->libc::c_int; fn rust_uv_listen(stream: *libc::c_void, backlog: libc::c_int, cb: *u8) -> libc::c_int; fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void) @@ -736,6 +742,16 @@ pub unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t, addr_ptr); } +pub unsafe fn tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, + name: *sockaddr_in) -> libc::c_int { + return rustrt::rust_uv_tcp_getpeername(tcp_handle_ptr, name); +} + +pub unsafe fn tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, + name: *sockaddr_in6) ->libc::c_int { + return rustrt::rust_uv_tcp_getpeername6(tcp_handle_ptr, name); +} + pub unsafe fn listen(stream: *T, backlog: libc::c_int, cb: *u8) -> libc::c_int { return rustrt::rust_uv_listen(stream as *libc::c_void, backlog, cb); @@ -857,6 +873,12 @@ pub unsafe fn ip6_name(src: &sockaddr_in6) -> ~str { } } } +pub unsafe fn ip4_port(src: &sockaddr_in) -> uint { + rustrt::rust_uv_ip4_port(to_unsafe_ptr(src)) as uint +} +pub unsafe fn ip6_port(src: &sockaddr_in6) -> uint { + rustrt::rust_uv_ip6_port(to_unsafe_ptr(src)) as uint +} pub unsafe fn timer_init(loop_ptr: *libc::c_void, timer_ptr: *uv_timer_t) -> libc::c_int { diff --git a/src/rt/rust_uv.cpp b/src/rt/rust_uv.cpp index 706e8ff4380..c34fd166bae 100644 --- a/src/rt/rust_uv.cpp +++ b/src/rt/rust_uv.cpp @@ -269,6 +269,20 @@ rust_uv_tcp_bind6 return uv_tcp_bind6(tcp_server, addr); } +extern "C" int +rust_uv_tcp_getpeername +(uv_tcp_t* handle, sockaddr_in* name) { + int namelen = sizeof(sockaddr_in); + return uv_tcp_getpeername(handle, (sockaddr*)name, &namelen); +} + +extern "C" int +rust_uv_tcp_getpeername6 +(uv_tcp_t* handle, sockaddr_in6* name) { + int namelen = sizeof(sockaddr_in6); + return uv_tcp_getpeername(handle, (sockaddr*)name, &namelen); +} + extern "C" int rust_uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) { @@ -480,6 +494,14 @@ rust_uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size) { int result = uv_ip6_name(src, dst, size); return result; } +extern "C" unsigned int +rust_uv_ip4_port(struct sockaddr_in* src) { + return ntohs(src->sin_port); +} +extern "C" unsigned int +rust_uv_ip6_port(struct sockaddr_in6* src) { + return ntohs(src->sin6_port); +} extern "C" uintptr_t* rust_uv_get_kernel_global_chan_ptr() {