about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLuqman Aden <me@luqman.ca>2013-07-25 22:21:46 -0400
committerLuqman Aden <me@luqman.ca>2013-07-25 22:21:46 -0400
commit037bf3757cf54e38544c494657ac88bc002b945c (patch)
tree13c2b954f06bbdc2a0149fe7df0c0dc2247d5a0d
parenta5c6b85091e171c9ec85bad68774aece81af74fa (diff)
downloadrust-037bf3757cf54e38544c494657ac88bc002b945c.tar.gz
rust-037bf3757cf54e38544c494657ac88bc002b945c.zip
libstd: Implement some missing udp methods.
-rw-r--r--src/libstd/rt/rtio.rs16
-rw-r--r--src/libstd/rt/uv/uvio.rs121
-rw-r--r--src/libstd/rt/uv/uvll.rs16
-rw-r--r--src/rt/rust_uv.cpp6
-rw-r--r--src/rt/rustrt.def.in1
5 files changed, 139 insertions, 21 deletions
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
@@ -386,6 +386,12 @@ rust_uv_udp_set_multicast_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) {
     return uv_udp_set_broadcast(handle, 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