From 61e741cf714020107c6cda12793351fa5b8c7782 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Thu, 25 Jul 2013 02:33:43 -0400 Subject: libstd: Implement {peer, socket}_name for new rt tcp & udp. --- src/rt/rust_uv.cpp | 60 ++++++++++++++++++++---------------------------------- 1 file changed, 22 insertions(+), 38 deletions(-) (limited to 'src/rt/rust_uv.cpp') diff --git a/src/rt/rust_uv.cpp b/src/rt/rust_uv.cpp index 95e38a9903c..a7f5db9dc5f 100644 --- a/src/rt/rust_uv.cpp +++ b/src/rt/rust_uv.cpp @@ -282,29 +282,19 @@ rust_uv_tcp_bind6 extern "C" int rust_uv_tcp_getpeername -(uv_tcp_t* handle, sockaddr_in* name) { +(uv_tcp_t* handle, sockaddr_storage* name) { + // sockaddr_storage is big enough to hold either + // sockaddr_in or sockaddr_in6 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_tcp_getsockname -(uv_tcp_t* handle, sockaddr_in* name) { - int namelen = sizeof(sockaddr_in); - return uv_tcp_getsockname(handle, (sockaddr*)name, &namelen); -} - -extern "C" int -rust_uv_tcp_getsockname6 -(uv_tcp_t* handle, sockaddr_in6* name) { - int namelen = sizeof(sockaddr_in6); +(uv_tcp_t* handle, sockaddr_storage* name) { + // sockaddr_storage is big enough to hold either + // sockaddr_in or sockaddr_in6 + int namelen = sizeof(sockaddr_storage); return uv_tcp_getsockname(handle, (sockaddr*)name, &namelen); } @@ -370,15 +360,10 @@ rust_uv_get_udp_handle_from_send_req(uv_udp_send_t* send_req) { extern "C" int rust_uv_udp_getsockname -(uv_udp_t* handle, sockaddr_in* name) { - int namelen = sizeof(sockaddr_in); - return uv_udp_getsockname(handle, (sockaddr*)name, &namelen); -} - -extern "C" int -rust_uv_udp_getsockname6 -(uv_udp_t* handle, sockaddr_in6* name) { - int namelen = sizeof(sockaddr_in6); +(uv_udp_t* handle, sockaddr_storage* name) { + // sockaddr_storage is big enough to hold either + // sockaddr_in or sockaddr_in6 + int namelen = sizeof(sockaddr_storage); return uv_udp_getsockname(handle, (sockaddr*)name, &namelen); } @@ -609,6 +594,17 @@ rust_uv_ip6_addrp(const char* ip, int port) { return addrp; } +extern "C" struct sockaddr_storage * +rust_uv_malloc_sockaddr_storage() { + struct sockaddr_storage *ss = (sockaddr_storage *)malloc(sizeof(struct sockaddr_storage)); + return ss; +} + +extern "C" void +rust_uv_free_sockaddr_storage(struct sockaddr_storage *ss) { + free(ss); +} + extern "C" void rust_uv_free_ip4_addr(sockaddr_in *addrp) { free(addrp); @@ -669,18 +665,6 @@ rust_uv_is_ipv6_sockaddr(sockaddr* addr) { return addr->sa_family == AF_INET6; } -extern "C" sockaddr_in* -rust_uv_sockaddr_as_sockaddr_in(sockaddr* addr) { -// return (sockaddr_in*)addr->sa_data; - return (sockaddr_in*)addr; -} - -extern "C" sockaddr_in6* -rust_uv_sockaddr_as_sockaddr_in6(sockaddr* addr) { - //return (sockaddr_in6*)addr->sa_data; - return (sockaddr_in6*)addr; -} - extern "C" bool rust_uv_is_ipv4_addrinfo(addrinfo* input) { return input->ai_family == AF_INET; -- cgit 1.4.1-3-g733a5 From 037bf3757cf54e38544c494657ac88bc002b945c Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Thu, 25 Jul 2013 22:21:46 -0400 Subject: libstd: Implement some missing udp methods. --- src/libstd/rt/rtio.rs | 16 +++---- src/libstd/rt/uv/uvio.rs | 121 +++++++++++++++++++++++++++++++++++++++++++---- src/libstd/rt/uv/uvll.rs | 16 +++++-- src/rt/rust_uv.cpp | 6 +++ src/rt/rustrt.def.in | 1 + 5 files changed, 139 insertions(+), 21 deletions(-) (limited to 'src/rt/rust_uv.cpp') diff --git a/src/libstd/rt/rtio.rs b/src/libstd/rt/rtio.rs index 728ee4ba035..d293d46e012 100644 --- a/src/libstd/rt/rtio.rs +++ b/src/libstd/rt/rtio.rs @@ -74,17 +74,17 @@ pub trait RtioUdpSocket : RtioSocket { fn recvfrom(&mut self, buf: &mut [u8]) -> Result<(uint, IpAddr), IoError>; fn sendto(&mut self, buf: &[u8], dst: IpAddr) -> Result<(), IoError>; - fn join_multicast(&mut self, multi: IpAddr); - fn leave_multicast(&mut self, multi: IpAddr); + fn join_multicast(&mut self, multi: IpAddr) -> Result<(), IoError>; + fn leave_multicast(&mut self, multi: IpAddr) -> Result<(), IoError>; - fn loop_multicast_locally(&mut self); - fn dont_loop_multicast_locally(&mut self); + fn loop_multicast_locally(&mut self) -> Result<(), IoError>; + fn dont_loop_multicast_locally(&mut self) -> Result<(), IoError>; - fn multicast_time_to_live(&mut self, ttl: int); - fn time_to_live(&mut self, ttl: int); + fn multicast_time_to_live(&mut self, ttl: int) -> Result<(), IoError>; + fn time_to_live(&mut self, ttl: int) -> Result<(), IoError>; - fn hear_broadcasts(&mut self); - fn ignore_broadcasts(&mut self); + fn hear_broadcasts(&mut self) -> Result<(), IoError>; + fn ignore_broadcasts(&mut self) -> Result<(), IoError>; } pub trait RtioTimer { diff --git a/src/libstd/rt/uv/uvio.rs b/src/libstd/rt/uv/uvio.rs index 203248c4483..fc4a668bdf6 100644 --- a/src/libstd/rt/uv/uvio.rs +++ b/src/libstd/rt/uv/uvio.rs @@ -16,8 +16,9 @@ use cast; use cast::transmute; use clone::Clone; use libc::{c_int, c_uint, c_void}; +use ptr; use rt::io::IoError; -use rt::io::net::ip::IpAddr; +use rt::io::net::ip::{IpAddr, Ipv4, Ipv6}; use rt::uv::*; use rt::uv::idle::IdleWatcher; use rt::uv::net::{UvIpv4, UvIpv6}; @@ -26,6 +27,7 @@ use rt::sched::Scheduler; use rt::io::{standard_error, OtherIoError}; use rt::tube::Tube; use rt::local::Local; +use str::StrSlice; use unstable::sync::{Exclusive, exclusive}; #[cfg(test)] use container::Container; @@ -657,18 +659,117 @@ impl RtioUdpSocket for UvUdpSocket { return result_cell.take(); } - // XXX implement - fn join_multicast(&mut self, _multi: IpAddr) { fail!(); } - fn leave_multicast(&mut self, _multi: IpAddr) { fail!(); } + fn join_multicast(&mut self, multi: IpAddr) -> Result<(), IoError> { + let ip_str = match multi { + Ipv4(x1, x2, x3, x4, _) => + fmt!("%u.%u.%u.%u", x1 as uint, x2 as uint, x3 as uint, x4 as uint), + Ipv6(x1, x2, x3, x4, x5, x6, x7, x8, _) => + fmt!("%x:%x:%x:%x:%x:%x:%x:%x", + x1 as uint, x2 as uint, x3 as uint, x4 as uint, + x5 as uint, x6 as uint, x7 as uint, x8 as uint), + }; + + let r = unsafe { + do ip_str.as_c_str |m_addr| { + uvll::udp_set_membership(self.native_handle(), m_addr, + ptr::null(), uvll::UV_JOIN_GROUP) + } + }; + + match status_to_maybe_uv_error(**self, r) { + Some(err) => Err(uv_error_to_io_error(err)), + None => Ok(()) + } + } + + fn leave_multicast(&mut self, multi: IpAddr) -> Result<(), IoError> { + let ip_str = match multi { + Ipv4(x1, x2, x3, x4, _) => + fmt!("%u.%u.%u.%u", x1 as uint, x2 as uint, x3 as uint, x4 as uint), + Ipv6(x1, x2, x3, x4, x5, x6, x7, x8, _) => + fmt!("%x:%x:%x:%x:%x:%x:%x:%x", + x1 as uint, x2 as uint, x3 as uint, x4 as uint, + x5 as uint, x6 as uint, x7 as uint, x8 as uint), + }; + + let r = unsafe { + do ip_str.as_c_str |m_addr| { + uvll::udp_set_membership(self.native_handle(), m_addr, + ptr::null(), uvll::UV_LEAVE_GROUP) + } + }; + + match status_to_maybe_uv_error(**self, r) { + Some(err) => Err(uv_error_to_io_error(err)), + None => Ok(()) + } + } + + fn loop_multicast_locally(&mut self) -> Result<(), IoError> { + let r = unsafe { + uvll::udp_set_multicast_loop(self.native_handle(), 1 as c_int) + }; + + match status_to_maybe_uv_error(**self, r) { + Some(err) => Err(uv_error_to_io_error(err)), + None => Ok(()) + } + } + + fn dont_loop_multicast_locally(&mut self) -> Result<(), IoError> { + let r = unsafe { + uvll::udp_set_multicast_loop(self.native_handle(), 0 as c_int) + }; + + match status_to_maybe_uv_error(**self, r) { + Some(err) => Err(uv_error_to_io_error(err)), + None => Ok(()) + } + } - fn loop_multicast_locally(&mut self) { fail!(); } - fn dont_loop_multicast_locally(&mut self) { fail!(); } + fn multicast_time_to_live(&mut self, ttl: int) -> Result<(), IoError> { + let r = unsafe { + uvll::udp_set_multicast_ttl(self.native_handle(), ttl as c_int) + }; - fn multicast_time_to_live(&mut self, _ttl: int) { fail!(); } - fn time_to_live(&mut self, _ttl: int) { fail!(); } + match status_to_maybe_uv_error(**self, r) { + Some(err) => Err(uv_error_to_io_error(err)), + None => Ok(()) + } + } - fn hear_broadcasts(&mut self) { fail!(); } - fn ignore_broadcasts(&mut self) { fail!(); } + fn time_to_live(&mut self, ttl: int) -> Result<(), IoError> { + let r = unsafe { + uvll::udp_set_ttl(self.native_handle(), ttl as c_int) + }; + + match status_to_maybe_uv_error(**self, r) { + Some(err) => Err(uv_error_to_io_error(err)), + None => Ok(()) + } + } + + fn hear_broadcasts(&mut self) -> Result<(), IoError> { + let r = unsafe { + uvll::udp_set_broadcast(self.native_handle(), 1 as c_int) + }; + + match status_to_maybe_uv_error(**self, r) { + Some(err) => Err(uv_error_to_io_error(err)), + None => Ok(()) + } + } + + fn ignore_broadcasts(&mut self) -> Result<(), IoError> { + let r = unsafe { + uvll::udp_set_broadcast(self.native_handle(), 0 as c_int) + }; + + match status_to_maybe_uv_error(**self, r) { + Some(err) => Err(uv_error_to_io_error(err)), + None => Ok(()) + } + } } pub struct UvTimer(timer::TimerWatcher); diff --git a/src/libstd/rt/uv/uvll.rs b/src/libstd/rt/uv/uvll.rs index 72d96e59c36..07264839c35 100644 --- a/src/libstd/rt/uv/uvll.rs +++ b/src/libstd/rt/uv/uvll.rs @@ -78,7 +78,6 @@ pub type sockaddr = c_void; pub type sockaddr_in = c_void; pub type sockaddr_in6 = c_void; pub type sockaddr_storage = c_void; -pub type uv_membership = c_void; #[deriving(Eq)] pub enum uv_handle_type { @@ -117,6 +116,12 @@ pub enum uv_req_type { UV_REQ_TYPE_MAX } +#[deriving(Eq)] +pub enum uv_membership { + UV_LEAVE_GROUP, + UV_JOIN_GROUP +} + pub unsafe fn malloc_handle(handle: uv_handle_type) -> *c_void { assert!(handle != UV_UNKNOWN_HANDLE && handle != UV_HANDLE_TYPE_MAX); let size = rust_uv_handle_size(handle as uint); @@ -240,7 +245,7 @@ pub unsafe fn udp_get_sockname(handle: *uv_udp_t, name: *sockaddr_storage) -> c_ pub unsafe fn udp_set_membership(handle: *uv_udp_t, multicast_addr: *c_char, interface_addr: *c_char, membership: uv_membership) -> c_int { - return rust_uv_udp_set_membership(handle, multicast_addr, interface_addr, membership); + return rust_uv_udp_set_membership(handle, multicast_addr, interface_addr, membership as c_int); } pub unsafe fn udp_set_multicast_loop(handle: *uv_udp_t, on: c_int) -> c_int { @@ -251,6 +256,10 @@ pub unsafe fn udp_set_multicast_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int { return rust_uv_udp_set_multicast_ttl(handle, ttl); } +pub unsafe fn udp_set_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int { + return rust_uv_udp_set_ttl(handle, ttl); +} + pub unsafe fn udp_set_broadcast(handle: *uv_udp_t, on: c_int) -> c_int { return rust_uv_udp_set_broadcast(handle, on); } @@ -527,9 +536,10 @@ extern { fn rust_uv_get_udp_handle_from_send_req(req: *uv_udp_send_t) -> *uv_udp_t; fn rust_uv_udp_getsockname(handle: *uv_udp_t, name: *sockaddr_storage) -> c_int; fn rust_uv_udp_set_membership(handle: *uv_udp_t, multicast_addr: *c_char, - interface_addr: *c_char, membership: uv_membership) -> c_int; + interface_addr: *c_char, membership: c_int) -> c_int; fn rust_uv_udp_set_multicast_loop(handle: *uv_udp_t, on: c_int) -> c_int; fn rust_uv_udp_set_multicast_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int; + fn rust_uv_udp_set_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int; fn rust_uv_udp_set_broadcast(handle: *uv_udp_t, on: c_int) -> c_int; fn rust_uv_is_ipv4_sockaddr(addr: *sockaddr) -> c_int; diff --git a/src/rt/rust_uv.cpp b/src/rt/rust_uv.cpp index a7f5db9dc5f..19162b8df6b 100644 --- a/src/rt/rust_uv.cpp +++ b/src/rt/rust_uv.cpp @@ -385,6 +385,12 @@ rust_uv_udp_set_multicast_ttl return uv_udp_set_multicast_ttl(handle, ttl); } +extern "C" int +rust_uv_udp_set_ttl +(uv_udp_t* handle, int ttl) { + return uv_udp_set_ttl(handle, ttl); +} + extern "C" int rust_uv_udp_set_broadcast (uv_udp_t* handle, int on) { diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 804f448d261..fc7796ef66c 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -121,6 +121,7 @@ rust_uv_udp_getsockname rust_uv_udp_set_membership rust_uv_udp_set_multicast_loop rust_uv_udp_set_multicast_ttl +rust_uv_udp_set_ttl rust_uv_udp_set_broadcast rust_uv_is_ipv4_sockaddr rust_uv_is_ipv6_sockaddr -- cgit 1.4.1-3-g733a5