auto merge of #8243 : stepancheg/rust/ipv, r=brson
multicast functions now take IpAddr (without port), because they dont't need port. Uv* types renamed: * UvIpAddr -> UvSocketAddr * UvIpv4 -> UvIpv4SocketAddr * UvIpv6 -> UvIpv6SocketAddr "Socket address" is a common name for (ip-address, port) pair (e.g. in sockaddr_in struct). P. S. Are there any backward compatibility concerns? What is std::rt module, is it a part of public API?
This commit is contained in:
commit
22f9ce4df6
@ -15,19 +15,19 @@ type Port = u16;
|
||||
|
||||
#[deriving(Eq, TotalEq)]
|
||||
pub enum IpAddr {
|
||||
Ipv4(u8, u8, u8, u8, Port),
|
||||
Ipv6(u16, u16, u16, u16, u16, u16, u16, u16, Port)
|
||||
Ipv4Addr(u8, u8, u8, u8),
|
||||
Ipv6Addr(u16, u16, u16, u16, u16, u16, u16, u16)
|
||||
}
|
||||
|
||||
impl ToStr for IpAddr {
|
||||
fn to_str(&self) -> ~str {
|
||||
match *self {
|
||||
Ipv4(a, b, c, d, p) =>
|
||||
fmt!("%u.%u.%u.%u:%u",
|
||||
a as uint, b as uint, c as uint, d as uint, p as uint),
|
||||
Ipv4Addr(a, b, c, d) =>
|
||||
fmt!("%u.%u.%u.%u",
|
||||
a as uint, b as uint, c as uint, d as uint),
|
||||
|
||||
// Ipv4 Compatible address
|
||||
Ipv6(0, 0, 0, 0, 0, 0, g, h, p) => {
|
||||
Ipv6Addr(0, 0, 0, 0, 0, 0, g, h) => {
|
||||
let a = fmt!("%04x", g as uint);
|
||||
let b = FromStrRadix::from_str_radix(a.slice(2, 4), 16).unwrap();
|
||||
let a = FromStrRadix::from_str_radix(a.slice(0, 2), 16).unwrap();
|
||||
@ -35,11 +35,11 @@ impl ToStr for IpAddr {
|
||||
let d = FromStrRadix::from_str_radix(c.slice(2, 4), 16).unwrap();
|
||||
let c = FromStrRadix::from_str_radix(c.slice(0, 2), 16).unwrap();
|
||||
|
||||
fmt!("[::%u.%u.%u.%u]:%u", a, b, c, d, p as uint)
|
||||
fmt!("::%u.%u.%u.%u", a, b, c, d)
|
||||
}
|
||||
|
||||
// Ipv4-Mapped address
|
||||
Ipv6(0, 0, 0, 0, 0, 1, g, h, p) => {
|
||||
Ipv6Addr(0, 0, 0, 0, 0, 1, g, h) => {
|
||||
let a = fmt!("%04x", g as uint);
|
||||
let b = FromStrRadix::from_str_radix(a.slice(2, 4), 16).unwrap();
|
||||
let a = FromStrRadix::from_str_radix(a.slice(0, 2), 16).unwrap();
|
||||
@ -47,13 +47,29 @@ impl ToStr for IpAddr {
|
||||
let d = FromStrRadix::from_str_radix(c.slice(2, 4), 16).unwrap();
|
||||
let c = FromStrRadix::from_str_radix(c.slice(0, 2), 16).unwrap();
|
||||
|
||||
fmt!("[::FFFF:%u.%u.%u.%u]:%u", a, b, c, d, p as uint)
|
||||
fmt!("::FFFF:%u.%u.%u.%u", a, b, c, d)
|
||||
}
|
||||
|
||||
Ipv6(a, b, c, d, e, f, g, h, p) =>
|
||||
fmt!("[%x:%x:%x:%x:%x:%x:%x:%x]:%u",
|
||||
Ipv6Addr(a, b, c, d, e, f, g, h) =>
|
||||
fmt!("%x:%x:%x:%x:%x:%x:%x:%x",
|
||||
a as uint, b as uint, c as uint, d as uint,
|
||||
e as uint, f as uint, g as uint, h as uint, p as uint)
|
||||
e as uint, f as uint, g as uint, h as uint)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Eq, TotalEq)]
|
||||
pub struct SocketAddr {
|
||||
ip: IpAddr,
|
||||
port: Port,
|
||||
}
|
||||
|
||||
|
||||
impl ToStr for SocketAddr {
|
||||
fn to_str(&self) -> ~str {
|
||||
match self.ip {
|
||||
Ipv4Addr(*) => fmt!("%s:%u", self.ip.to_str(), self.port as uint),
|
||||
Ipv6Addr(*) => fmt!("[%s]:%u", self.ip.to_str(), self.port as uint),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
use option::{Option, Some, None};
|
||||
use result::{Ok, Err};
|
||||
use rt::io::net::ip::IpAddr;
|
||||
use rt::io::net::ip::SocketAddr;
|
||||
use rt::io::{Reader, Writer, Listener};
|
||||
use rt::io::{io_error, read_error, EndOfFile};
|
||||
use rt::rtio::{IoFactory, IoFactoryObject,
|
||||
@ -26,7 +26,7 @@ impl TcpStream {
|
||||
TcpStream(s)
|
||||
}
|
||||
|
||||
pub fn connect(addr: IpAddr) -> Option<TcpStream> {
|
||||
pub fn connect(addr: SocketAddr) -> Option<TcpStream> {
|
||||
let stream = unsafe {
|
||||
rtdebug!("borrowing io to connect");
|
||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
||||
@ -44,7 +44,7 @@ impl TcpStream {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn peer_name(&mut self) -> Option<IpAddr> {
|
||||
pub fn peer_name(&mut self) -> Option<SocketAddr> {
|
||||
match (**self).peer_name() {
|
||||
Ok(pn) => Some(pn),
|
||||
Err(ioerr) => {
|
||||
@ -55,7 +55,7 @@ impl TcpStream {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn socket_name(&mut self) -> Option<IpAddr> {
|
||||
pub fn socket_name(&mut self) -> Option<SocketAddr> {
|
||||
match (**self).socket_name() {
|
||||
Ok(sn) => Some(sn),
|
||||
Err(ioerr) => {
|
||||
@ -100,7 +100,7 @@ impl Writer for TcpStream {
|
||||
pub struct TcpListener(~RtioTcpListenerObject);
|
||||
|
||||
impl TcpListener {
|
||||
pub fn bind(addr: IpAddr) -> Option<TcpListener> {
|
||||
pub fn bind(addr: SocketAddr) -> Option<TcpListener> {
|
||||
let listener = unsafe {
|
||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
||||
(*io).tcp_bind(addr)
|
||||
@ -114,7 +114,7 @@ impl TcpListener {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn socket_name(&mut self) -> Option<IpAddr> {
|
||||
pub fn socket_name(&mut self) -> Option<SocketAddr> {
|
||||
match (**self).socket_name() {
|
||||
Ok(sn) => Some(sn),
|
||||
Err(ioerr) => {
|
||||
@ -145,7 +145,7 @@ mod test {
|
||||
use super::*;
|
||||
use cell::Cell;
|
||||
use rt::test::*;
|
||||
use rt::io::net::ip::Ipv4;
|
||||
use rt::io::net::ip::{Ipv4Addr, SocketAddr};
|
||||
use rt::io::*;
|
||||
use prelude::*;
|
||||
|
||||
@ -157,7 +157,7 @@ mod test {
|
||||
assert!(e.kind == PermissionDenied);
|
||||
called = true;
|
||||
}).inside {
|
||||
let addr = Ipv4(0, 0, 0, 0, 1);
|
||||
let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
|
||||
let listener = TcpListener::bind(addr);
|
||||
assert!(listener.is_none());
|
||||
}
|
||||
@ -173,7 +173,7 @@ mod test {
|
||||
assert!(e.kind == ConnectionRefused);
|
||||
called = true;
|
||||
}).inside {
|
||||
let addr = Ipv4(0, 0, 0, 0, 1);
|
||||
let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
|
||||
let stream = TcpStream::connect(addr);
|
||||
assert!(stream.is_none());
|
||||
}
|
||||
@ -437,7 +437,7 @@ mod test {
|
||||
|
||||
connect(0, addr);
|
||||
|
||||
fn connect(i: int, addr: IpAddr) {
|
||||
fn connect(i: int, addr: SocketAddr) {
|
||||
if i == MAX { return }
|
||||
|
||||
do spawntask {
|
||||
@ -476,7 +476,7 @@ mod test {
|
||||
|
||||
connect(0, addr);
|
||||
|
||||
fn connect(i: int, addr: IpAddr) {
|
||||
fn connect(i: int, addr: SocketAddr) {
|
||||
if i == MAX { return }
|
||||
|
||||
do spawntask {
|
||||
@ -515,7 +515,7 @@ mod test {
|
||||
|
||||
connect(0, addr);
|
||||
|
||||
fn connect(i: int, addr: IpAddr) {
|
||||
fn connect(i: int, addr: SocketAddr) {
|
||||
if i == MAX { return }
|
||||
|
||||
do spawntask_later {
|
||||
@ -553,7 +553,7 @@ mod test {
|
||||
|
||||
connect(0, addr);
|
||||
|
||||
fn connect(i: int, addr: IpAddr) {
|
||||
fn connect(i: int, addr: SocketAddr) {
|
||||
if i == MAX { return }
|
||||
|
||||
do spawntask_later {
|
||||
@ -569,7 +569,7 @@ mod test {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn socket_name(addr: IpAddr) {
|
||||
fn socket_name(addr: SocketAddr) {
|
||||
do run_in_newsched_task {
|
||||
do spawntask {
|
||||
let listener = TcpListener::bind(addr);
|
||||
@ -588,7 +588,7 @@ mod test {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn peer_name(addr: IpAddr) {
|
||||
fn peer_name(addr: SocketAddr) {
|
||||
do run_in_newsched_task {
|
||||
do spawntask {
|
||||
let mut listener = TcpListener::bind(addr);
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
use option::{Option, Some, None};
|
||||
use result::{Ok, Err};
|
||||
use rt::io::net::ip::IpAddr;
|
||||
use rt::io::net::ip::SocketAddr;
|
||||
use rt::io::{Reader, Writer};
|
||||
use rt::io::{io_error, read_error, EndOfFile};
|
||||
use rt::rtio::{RtioSocket, RtioUdpSocketObject, RtioUdpSocket, IoFactory, IoFactoryObject};
|
||||
@ -19,7 +19,7 @@ use rt::local::Local;
|
||||
pub struct UdpSocket(~RtioUdpSocketObject);
|
||||
|
||||
impl UdpSocket {
|
||||
pub fn bind(addr: IpAddr) -> Option<UdpSocket> {
|
||||
pub fn bind(addr: SocketAddr) -> Option<UdpSocket> {
|
||||
let socket = unsafe { (*Local::unsafe_borrow::<IoFactoryObject>()).udp_bind(addr) };
|
||||
match socket {
|
||||
Ok(s) => Some(UdpSocket(s)),
|
||||
@ -30,7 +30,7 @@ impl UdpSocket {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn recvfrom(&mut self, buf: &mut [u8]) -> Option<(uint, IpAddr)> {
|
||||
pub fn recvfrom(&mut self, buf: &mut [u8]) -> Option<(uint, SocketAddr)> {
|
||||
match (**self).recvfrom(buf) {
|
||||
Ok((nread, src)) => Some((nread, src)),
|
||||
Err(ioerr) => {
|
||||
@ -43,18 +43,18 @@ impl UdpSocket {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sendto(&mut self, buf: &[u8], dst: IpAddr) {
|
||||
pub fn sendto(&mut self, buf: &[u8], dst: SocketAddr) {
|
||||
match (**self).sendto(buf, dst) {
|
||||
Ok(_) => (),
|
||||
Err(ioerr) => io_error::cond.raise(ioerr),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn connect(self, other: IpAddr) -> UdpStream {
|
||||
pub fn connect(self, other: SocketAddr) -> UdpStream {
|
||||
UdpStream { socket: self, connectedTo: other }
|
||||
}
|
||||
|
||||
pub fn socket_name(&mut self) -> Option<IpAddr> {
|
||||
pub fn socket_name(&mut self) -> Option<SocketAddr> {
|
||||
match (***self).socket_name() {
|
||||
Ok(sn) => Some(sn),
|
||||
Err(ioerr) => {
|
||||
@ -68,7 +68,7 @@ impl UdpSocket {
|
||||
|
||||
pub struct UdpStream {
|
||||
socket: UdpSocket,
|
||||
connectedTo: IpAddr
|
||||
connectedTo: SocketAddr
|
||||
}
|
||||
|
||||
impl UdpStream {
|
||||
@ -106,7 +106,7 @@ impl Writer for UdpStream {
|
||||
mod test {
|
||||
use super::*;
|
||||
use rt::test::*;
|
||||
use rt::io::net::ip::Ipv4;
|
||||
use rt::io::net::ip::{Ipv4Addr, SocketAddr};
|
||||
use rt::io::*;
|
||||
use option::{Some, None};
|
||||
|
||||
@ -118,7 +118,7 @@ mod test {
|
||||
assert!(e.kind == PermissionDenied);
|
||||
called = true;
|
||||
}).inside {
|
||||
let addr = Ipv4(0, 0, 0, 0, 1);
|
||||
let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
|
||||
let socket = UdpSocket::bind(addr);
|
||||
assert!(socket.is_none());
|
||||
}
|
||||
@ -265,7 +265,7 @@ mod test {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn socket_name(addr: IpAddr) {
|
||||
fn socket_name(addr: SocketAddr) {
|
||||
do run_in_newsched_task {
|
||||
do spawntask {
|
||||
let server = UdpSocket::bind(addr);
|
||||
|
@ -12,7 +12,7 @@ use option::*;
|
||||
use result::*;
|
||||
|
||||
use rt::io::IoError;
|
||||
use super::io::net::ip::IpAddr;
|
||||
use super::io::net::ip::{IpAddr, SocketAddr};
|
||||
use rt::uv::uvio;
|
||||
|
||||
// XXX: ~object doesn't work currently so these are some placeholder
|
||||
@ -44,9 +44,9 @@ pub trait RemoteCallback {
|
||||
}
|
||||
|
||||
pub trait IoFactory {
|
||||
fn tcp_connect(&mut self, addr: IpAddr) -> Result<~RtioTcpStreamObject, IoError>;
|
||||
fn tcp_bind(&mut self, addr: IpAddr) -> Result<~RtioTcpListenerObject, IoError>;
|
||||
fn udp_bind(&mut self, addr: IpAddr) -> Result<~RtioUdpSocketObject, IoError>;
|
||||
fn tcp_connect(&mut self, addr: SocketAddr) -> Result<~RtioTcpStreamObject, IoError>;
|
||||
fn tcp_bind(&mut self, addr: SocketAddr) -> Result<~RtioTcpListenerObject, IoError>;
|
||||
fn udp_bind(&mut self, addr: SocketAddr) -> Result<~RtioUdpSocketObject, IoError>;
|
||||
fn timer_init(&mut self) -> Result<~RtioTimerObject, IoError>;
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ pub trait RtioTcpListener : RtioSocket {
|
||||
pub trait RtioTcpStream : RtioSocket {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError>;
|
||||
fn write(&mut self, buf: &[u8]) -> Result<(), IoError>;
|
||||
fn peer_name(&mut self) -> Result<IpAddr, IoError>;
|
||||
fn peer_name(&mut self) -> Result<SocketAddr, IoError>;
|
||||
fn control_congestion(&mut self) -> Result<(), IoError>;
|
||||
fn nodelay(&mut self) -> Result<(), IoError>;
|
||||
fn keepalive(&mut self, delay_in_seconds: uint) -> Result<(), IoError>;
|
||||
@ -67,12 +67,12 @@ pub trait RtioTcpStream : RtioSocket {
|
||||
}
|
||||
|
||||
pub trait RtioSocket {
|
||||
fn socket_name(&mut self) -> Result<IpAddr, IoError>;
|
||||
fn socket_name(&mut self) -> Result<SocketAddr, IoError>;
|
||||
}
|
||||
|
||||
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 recvfrom(&mut self, buf: &mut [u8]) -> Result<(uint, SocketAddr), IoError>;
|
||||
fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> Result<(), IoError>;
|
||||
|
||||
fn join_multicast(&mut self, multi: IpAddr) -> Result<(), IoError>;
|
||||
fn leave_multicast(&mut self, multi: IpAddr) -> Result<(), IoError>;
|
||||
|
@ -16,7 +16,7 @@ use clone::Clone;
|
||||
use container::Container;
|
||||
use iterator::{Iterator, range};
|
||||
use vec::{OwnedVector, MutableVector};
|
||||
use super::io::net::ip::{IpAddr, Ipv4, Ipv6};
|
||||
use super::io::net::ip::{SocketAddr, Ipv4Addr, Ipv6Addr};
|
||||
use rt::sched::Scheduler;
|
||||
use unstable::run_in_bare_thread;
|
||||
use rt::thread::Thread;
|
||||
@ -306,13 +306,13 @@ pub fn next_test_port() -> u16 {
|
||||
}
|
||||
|
||||
/// Get a unique IPv4 localhost:port pair starting at 9600
|
||||
pub fn next_test_ip4() -> IpAddr {
|
||||
Ipv4(127, 0, 0, 1, next_test_port())
|
||||
pub fn next_test_ip4() -> SocketAddr {
|
||||
SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: next_test_port() }
|
||||
}
|
||||
|
||||
/// Get a unique IPv6 localhost:port pair starting at 9600
|
||||
pub fn next_test_ip6() -> IpAddr {
|
||||
Ipv6(0, 0, 0, 0, 0, 0, 0, 1, next_test_port())
|
||||
pub fn next_test_ip6() -> SocketAddr {
|
||||
SocketAddr { ip: Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1), port: next_test_port() }
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -47,7 +47,7 @@ use libc::{c_void, c_int, size_t, malloc, free};
|
||||
use cast::transmute;
|
||||
use ptr::null;
|
||||
use unstable::finally::Finally;
|
||||
use rt::io::net::ip::IpAddr;
|
||||
use rt::io::net::ip::SocketAddr;
|
||||
|
||||
use rt::io::IoError;
|
||||
|
||||
@ -128,7 +128,7 @@ pub type ConnectionCallback = ~fn(StreamWatcher, Option<UvError>);
|
||||
pub type FsCallback = ~fn(FsRequest, Option<UvError>);
|
||||
pub type TimerCallback = ~fn(TimerWatcher, Option<UvError>);
|
||||
pub type AsyncCallback = ~fn(AsyncWatcher, Option<UvError>);
|
||||
pub type UdpReceiveCallback = ~fn(UdpWatcher, int, Buf, IpAddr, uint, Option<UvError>);
|
||||
pub type UdpReceiveCallback = ~fn(UdpWatcher, int, Buf, SocketAddr, uint, Option<UvError>);
|
||||
pub type UdpSendCallback = ~fn(UdpWatcher, Option<UvError>);
|
||||
|
||||
|
||||
|
@ -15,56 +15,45 @@ use rt::uv::uvll::*;
|
||||
use rt::uv::{AllocCallback, ConnectionCallback, ReadCallback, UdpReceiveCallback, UdpSendCallback};
|
||||
use rt::uv::{Loop, Watcher, Request, UvError, Buf, NativeHandle, NullCallback,
|
||||
status_to_maybe_uv_error};
|
||||
use rt::io::net::ip::{IpAddr, Ipv4, Ipv6};
|
||||
use rt::io::net::ip::{SocketAddr, Ipv4Addr, Ipv6Addr};
|
||||
use rt::uv::last_uv_error;
|
||||
use vec;
|
||||
use str;
|
||||
use from_str::{FromStr};
|
||||
use num;
|
||||
|
||||
pub enum UvIpAddr {
|
||||
UvIpv4(*sockaddr_in),
|
||||
UvIpv6(*sockaddr_in6),
|
||||
pub enum UvSocketAddr {
|
||||
UvIpv4SocketAddr(*sockaddr_in),
|
||||
UvIpv6SocketAddr(*sockaddr_in6),
|
||||
}
|
||||
|
||||
fn sockaddr_to_UvIpAddr(addr: *uvll::sockaddr) -> UvIpAddr {
|
||||
fn sockaddr_to_UvSocketAddr(addr: *uvll::sockaddr) -> UvSocketAddr {
|
||||
unsafe {
|
||||
assert!((is_ip4_addr(addr) || is_ip6_addr(addr)));
|
||||
assert!(!(is_ip4_addr(addr) && is_ip6_addr(addr)));
|
||||
match addr {
|
||||
_ if is_ip4_addr(addr) => UvIpv4(addr as *uvll::sockaddr_in),
|
||||
_ if is_ip6_addr(addr) => UvIpv6(addr as *uvll::sockaddr_in6),
|
||||
_ if is_ip4_addr(addr) => UvIpv4SocketAddr(addr as *uvll::sockaddr_in),
|
||||
_ if is_ip6_addr(addr) => UvIpv6SocketAddr(addr as *uvll::sockaddr_in6),
|
||||
_ => fail!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn ip_as_uv_ip<T>(addr: IpAddr, f: &fn(UvIpAddr) -> T) -> T {
|
||||
let malloc = match addr {
|
||||
Ipv4(*) => malloc_ip4_addr,
|
||||
Ipv6(*) => malloc_ip6_addr,
|
||||
fn socket_addr_as_uv_socket_addr<T>(addr: SocketAddr, f: &fn(UvSocketAddr) -> T) -> T {
|
||||
let malloc = match addr.ip {
|
||||
Ipv4Addr(*) => malloc_ip4_addr,
|
||||
Ipv6Addr(*) => malloc_ip6_addr,
|
||||
};
|
||||
let wrap = match addr {
|
||||
Ipv4(*) => UvIpv4,
|
||||
Ipv6(*) => UvIpv6,
|
||||
let wrap = match addr.ip {
|
||||
Ipv4Addr(*) => UvIpv4SocketAddr,
|
||||
Ipv6Addr(*) => UvIpv6SocketAddr,
|
||||
};
|
||||
let ip_str = match addr {
|
||||
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 port = match addr {
|
||||
Ipv4(_, _, _, _, p) | Ipv6(_, _, _, _, _, _, _, _, p) => p as int
|
||||
};
|
||||
let free = match addr {
|
||||
Ipv4(*) => free_ip4_addr,
|
||||
Ipv6(*) => free_ip6_addr,
|
||||
let free = match addr.ip {
|
||||
Ipv4Addr(*) => free_ip4_addr,
|
||||
Ipv6Addr(*) => free_ip6_addr,
|
||||
};
|
||||
|
||||
let addr = unsafe { malloc(ip_str, port) };
|
||||
let addr = unsafe { malloc(addr.ip.to_str(), addr.port as int) };
|
||||
do (|| {
|
||||
f(wrap(addr))
|
||||
}).finally {
|
||||
@ -72,39 +61,43 @@ fn ip_as_uv_ip<T>(addr: IpAddr, f: &fn(UvIpAddr) -> T) -> T {
|
||||
}
|
||||
}
|
||||
|
||||
fn uv_ip_as_ip<T>(addr: UvIpAddr, f: &fn(IpAddr) -> T) -> T {
|
||||
fn uv_socket_addr_as_socket_addr<T>(addr: UvSocketAddr, f: &fn(SocketAddr) -> T) -> T {
|
||||
let ip_size = match addr {
|
||||
UvIpv4(*) => 4/*groups of*/ * 3/*digits separated by*/ + 3/*periods*/,
|
||||
UvIpv6(*) => 8/*groups of*/ * 4/*hex digits separated by*/ + 7 /*colons*/,
|
||||
UvIpv4SocketAddr(*) => 4/*groups of*/ * 3/*digits separated by*/ + 3/*periods*/,
|
||||
UvIpv6SocketAddr(*) => 8/*groups of*/ * 4/*hex digits separated by*/ + 7 /*colons*/,
|
||||
};
|
||||
let ip_name = {
|
||||
let buf = vec::from_elem(ip_size + 1 /*null terminated*/, 0u8);
|
||||
unsafe {
|
||||
let buf_ptr = vec::raw::to_ptr(buf);
|
||||
match addr {
|
||||
UvIpv4(addr) => uvll::ip4_name(addr, vec::raw::to_ptr(buf), ip_size as size_t),
|
||||
UvIpv6(addr) => uvll::ip6_name(addr, vec::raw::to_ptr(buf), ip_size as size_t),
|
||||
UvIpv4SocketAddr(addr) => uvll::ip4_name(addr, buf_ptr, ip_size as size_t),
|
||||
UvIpv6SocketAddr(addr) => uvll::ip6_name(addr, buf_ptr, ip_size as size_t),
|
||||
}
|
||||
};
|
||||
buf
|
||||
};
|
||||
let ip_port = unsafe {
|
||||
let port = match addr {
|
||||
UvIpv4(addr) => uvll::ip4_port(addr),
|
||||
UvIpv6(addr) => uvll::ip6_port(addr),
|
||||
UvIpv4SocketAddr(addr) => uvll::ip4_port(addr),
|
||||
UvIpv6SocketAddr(addr) => uvll::ip6_port(addr),
|
||||
};
|
||||
port as u16
|
||||
};
|
||||
let ip_str = str::from_bytes_slice(ip_name).trim_right_chars(&'\x00');
|
||||
let ip = match addr {
|
||||
UvIpv4(*) => {
|
||||
UvIpv4SocketAddr(*) => {
|
||||
let ip: ~[u8] =
|
||||
ip_str.split_iter('.')
|
||||
.transform(|s: &str| -> u8 { FromStr::from_str(s).unwrap() })
|
||||
.collect();
|
||||
assert_eq!(ip.len(), 4);
|
||||
Ipv4(ip[0], ip[1], ip[2], ip[3], ip_port)
|
||||
SocketAddr {
|
||||
ip: Ipv4Addr(ip[0], ip[1], ip[2], ip[3]),
|
||||
port: ip_port
|
||||
}
|
||||
},
|
||||
UvIpv6(*) => {
|
||||
UvIpv6SocketAddr(*) => {
|
||||
let ip: ~[u16] = {
|
||||
let expand_shorthand_and_convert = |s: &str| -> ~[~[u16]] {
|
||||
let convert_each_segment = |s: &str| -> ~[u16] {
|
||||
@ -154,7 +147,10 @@ fn uv_ip_as_ip<T>(addr: UvIpAddr, f: &fn(IpAddr) -> T) -> T {
|
||||
}
|
||||
};
|
||||
assert_eq!(ip.len(), 8);
|
||||
Ipv6(ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7], ip_port)
|
||||
SocketAddr {
|
||||
ip: Ipv6Addr(ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7]),
|
||||
port: ip_port
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@ -162,9 +158,9 @@ fn uv_ip_as_ip<T>(addr: UvIpAddr, f: &fn(IpAddr) -> T) -> T {
|
||||
f(ip)
|
||||
}
|
||||
|
||||
pub fn uv_ip_to_ip(addr: UvIpAddr) -> IpAddr {
|
||||
pub fn uv_socket_addr_to_socket_addr(addr: UvSocketAddr) -> SocketAddr {
|
||||
use util;
|
||||
uv_ip_as_ip(addr, util::id)
|
||||
uv_socket_addr_as_socket_addr(addr, util::id)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -172,7 +168,7 @@ pub fn uv_ip_to_ip(addr: UvIpAddr) -> IpAddr {
|
||||
fn test_ip4_conversion() {
|
||||
use rt;
|
||||
let ip4 = rt::test::next_test_ip4();
|
||||
assert_eq!(ip4, ip_as_uv_ip(ip4, uv_ip_to_ip));
|
||||
assert_eq!(ip4, socket_addr_as_uv_socket_addr(ip4, uv_socket_addr_to_socket_addr));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -180,7 +176,7 @@ fn test_ip4_conversion() {
|
||||
fn test_ip6_conversion() {
|
||||
use rt;
|
||||
let ip6 = rt::test::next_test_ip6();
|
||||
assert_eq!(ip6, ip_as_uv_ip(ip6, uv_ip_to_ip));
|
||||
assert_eq!(ip6, socket_addr_as_uv_socket_addr(ip6, uv_socket_addr_to_socket_addr));
|
||||
}
|
||||
|
||||
// uv_stream_t is the parent class of uv_tcp_t, uv_pipe_t, uv_tty_t
|
||||
@ -293,12 +289,12 @@ impl TcpWatcher {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bind(&mut self, address: IpAddr) -> Result<(), UvError> {
|
||||
do ip_as_uv_ip(address) |addr| {
|
||||
pub fn bind(&mut self, address: SocketAddr) -> Result<(), UvError> {
|
||||
do socket_addr_as_uv_socket_addr(address) |addr| {
|
||||
let result = unsafe {
|
||||
match addr {
|
||||
UvIpv4(addr) => uvll::tcp_bind(self.native_handle(), addr),
|
||||
UvIpv6(addr) => uvll::tcp_bind6(self.native_handle(), addr),
|
||||
UvIpv4SocketAddr(addr) => uvll::tcp_bind(self.native_handle(), addr),
|
||||
UvIpv6SocketAddr(addr) => uvll::tcp_bind6(self.native_handle(), addr),
|
||||
}
|
||||
};
|
||||
match result {
|
||||
@ -308,18 +304,18 @@ impl TcpWatcher {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn connect(&mut self, address: IpAddr, cb: ConnectionCallback) {
|
||||
pub fn connect(&mut self, address: SocketAddr, cb: ConnectionCallback) {
|
||||
unsafe {
|
||||
assert!(self.get_watcher_data().connect_cb.is_none());
|
||||
self.get_watcher_data().connect_cb = Some(cb);
|
||||
|
||||
let connect_handle = ConnectRequest::new().native_handle();
|
||||
rtdebug!("connect_t: %x", connect_handle as uint);
|
||||
do ip_as_uv_ip(address) |addr| {
|
||||
do socket_addr_as_uv_socket_addr(address) |addr| {
|
||||
let result = match addr {
|
||||
UvIpv4(addr) => uvll::tcp_connect(connect_handle,
|
||||
UvIpv4SocketAddr(addr) => uvll::tcp_connect(connect_handle,
|
||||
self.native_handle(), addr, connect_cb),
|
||||
UvIpv6(addr) => uvll::tcp_connect6(connect_handle,
|
||||
UvIpv6SocketAddr(addr) => uvll::tcp_connect6(connect_handle,
|
||||
self.native_handle(), addr, connect_cb),
|
||||
};
|
||||
assert_eq!(0, result);
|
||||
@ -388,12 +384,12 @@ impl UdpWatcher {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bind(&mut self, address: IpAddr) -> Result<(), UvError> {
|
||||
do ip_as_uv_ip(address) |addr| {
|
||||
pub fn bind(&mut self, address: SocketAddr) -> Result<(), UvError> {
|
||||
do socket_addr_as_uv_socket_addr(address) |addr| {
|
||||
let result = unsafe {
|
||||
match addr {
|
||||
UvIpv4(addr) => uvll::udp_bind(self.native_handle(), addr, 0u32),
|
||||
UvIpv6(addr) => uvll::udp_bind6(self.native_handle(), addr, 0u32),
|
||||
UvIpv4SocketAddr(addr) => uvll::udp_bind(self.native_handle(), addr, 0u32),
|
||||
UvIpv6SocketAddr(addr) => uvll::udp_bind6(self.native_handle(), addr, 0u32),
|
||||
}
|
||||
};
|
||||
match result {
|
||||
@ -432,7 +428,7 @@ impl UdpWatcher {
|
||||
let mut udp_watcher: UdpWatcher = NativeHandle::from_native_handle(handle);
|
||||
let cb = udp_watcher.get_watcher_data().udp_recv_cb.get_ref();
|
||||
let status = status_to_maybe_uv_error(udp_watcher, nread as c_int);
|
||||
let addr = uv_ip_to_ip(sockaddr_to_UvIpAddr(addr));
|
||||
let addr = uv_socket_addr_to_socket_addr(sockaddr_to_UvSocketAddr(addr));
|
||||
(*cb)(udp_watcher, nread as int, buf, addr, flags as uint, status);
|
||||
}
|
||||
}
|
||||
@ -441,7 +437,7 @@ impl UdpWatcher {
|
||||
unsafe { uvll::udp_recv_stop(self.native_handle()); }
|
||||
}
|
||||
|
||||
pub fn send(&mut self, buf: Buf, address: IpAddr, cb: UdpSendCallback) {
|
||||
pub fn send(&mut self, buf: Buf, address: SocketAddr, cb: UdpSendCallback) {
|
||||
{
|
||||
let data = self.get_watcher_data();
|
||||
assert!(data.udp_send_cb.is_none());
|
||||
@ -449,12 +445,12 @@ impl UdpWatcher {
|
||||
}
|
||||
|
||||
let req = UdpSendRequest::new();
|
||||
do ip_as_uv_ip(address) |addr| {
|
||||
do socket_addr_as_uv_socket_addr(address) |addr| {
|
||||
let result = unsafe {
|
||||
match addr {
|
||||
UvIpv4(addr) => uvll::udp_send(req.native_handle(),
|
||||
UvIpv4SocketAddr(addr) => uvll::udp_send(req.native_handle(),
|
||||
self.native_handle(), [buf], addr, send_cb),
|
||||
UvIpv6(addr) => uvll::udp_send6(req.native_handle(),
|
||||
UvIpv6SocketAddr(addr) => uvll::udp_send6(req.native_handle(),
|
||||
self.native_handle(), [buf], addr, send_cb),
|
||||
}
|
||||
};
|
||||
|
@ -18,10 +18,10 @@ use clone::Clone;
|
||||
use libc::{c_int, c_uint, c_void};
|
||||
use ptr;
|
||||
use rt::io::IoError;
|
||||
use rt::io::net::ip::{IpAddr, Ipv4, Ipv6};
|
||||
use rt::io::net::ip::{SocketAddr, IpAddr};
|
||||
use rt::uv::*;
|
||||
use rt::uv::idle::IdleWatcher;
|
||||
use rt::uv::net::{UvIpv4, UvIpv6};
|
||||
use rt::uv::net::{UvIpv4SocketAddr, UvIpv6SocketAddr};
|
||||
use rt::rtio::*;
|
||||
use rt::sched::Scheduler;
|
||||
use rt::io::{standard_error, OtherIoError};
|
||||
@ -44,7 +44,7 @@ enum SocketNameKind {
|
||||
}
|
||||
|
||||
fn socket_name<T, U: Watcher + NativeHandle<*T>>(sk: SocketNameKind,
|
||||
handle: U) -> Result<IpAddr, IoError> {
|
||||
handle: U) -> Result<SocketAddr, IoError> {
|
||||
|
||||
let getsockname = match sk {
|
||||
TcpPeer => uvll::rust_uv_tcp_getpeername,
|
||||
@ -67,9 +67,9 @@ fn socket_name<T, U: Watcher + NativeHandle<*T>>(sk: SocketNameKind,
|
||||
|
||||
let addr = unsafe {
|
||||
if uvll::is_ip6_addr(r_addr as *uvll::sockaddr) {
|
||||
net::uv_ip_to_ip(UvIpv6(r_addr as *uvll::sockaddr_in6))
|
||||
net::uv_socket_addr_to_socket_addr(UvIpv6SocketAddr(r_addr as *uvll::sockaddr_in6))
|
||||
} else {
|
||||
net::uv_ip_to_ip(UvIpv4(r_addr as *uvll::sockaddr_in))
|
||||
net::uv_socket_addr_to_socket_addr(UvIpv4SocketAddr(r_addr as *uvll::sockaddr_in))
|
||||
}
|
||||
};
|
||||
|
||||
@ -244,7 +244,7 @@ impl IoFactory for UvIoFactory {
|
||||
// Connect to an address and return a new stream
|
||||
// NB: This blocks the task waiting on the connection.
|
||||
// It would probably be better to return a future
|
||||
fn tcp_connect(&mut self, addr: IpAddr) -> Result<~RtioTcpStreamObject, IoError> {
|
||||
fn tcp_connect(&mut self, addr: SocketAddr) -> Result<~RtioTcpStreamObject, IoError> {
|
||||
// Create a cell in the task to hold the result. We will fill
|
||||
// the cell before resuming the task.
|
||||
let result_cell = Cell::new_empty();
|
||||
@ -291,7 +291,7 @@ impl IoFactory for UvIoFactory {
|
||||
return result_cell.take();
|
||||
}
|
||||
|
||||
fn tcp_bind(&mut self, addr: IpAddr) -> Result<~RtioTcpListenerObject, IoError> {
|
||||
fn tcp_bind(&mut self, addr: SocketAddr) -> Result<~RtioTcpListenerObject, IoError> {
|
||||
let mut watcher = TcpWatcher::new(self.uv_loop());
|
||||
match watcher.bind(addr) {
|
||||
Ok(_) => Ok(~UvTcpListener::new(watcher)),
|
||||
@ -309,7 +309,7 @@ impl IoFactory for UvIoFactory {
|
||||
}
|
||||
}
|
||||
|
||||
fn udp_bind(&mut self, addr: IpAddr) -> Result<~RtioUdpSocketObject, IoError> {
|
||||
fn udp_bind(&mut self, addr: SocketAddr) -> Result<~RtioUdpSocketObject, IoError> {
|
||||
let mut watcher = UdpWatcher::new(self.uv_loop());
|
||||
match watcher.bind(addr) {
|
||||
Ok(_) => Ok(~UvUdpSocket(watcher)),
|
||||
@ -365,7 +365,7 @@ impl Drop for UvTcpListener {
|
||||
}
|
||||
|
||||
impl RtioSocket for UvTcpListener {
|
||||
fn socket_name(&mut self) -> Result<IpAddr, IoError> {
|
||||
fn socket_name(&mut self) -> Result<SocketAddr, IoError> {
|
||||
socket_name(Tcp, self.watcher)
|
||||
}
|
||||
}
|
||||
@ -445,7 +445,7 @@ impl Drop for UvTcpStream {
|
||||
}
|
||||
|
||||
impl RtioSocket for UvTcpStream {
|
||||
fn socket_name(&mut self) -> Result<IpAddr, IoError> {
|
||||
fn socket_name(&mut self) -> Result<SocketAddr, IoError> {
|
||||
socket_name(Tcp, **self)
|
||||
}
|
||||
}
|
||||
@ -519,7 +519,7 @@ impl RtioTcpStream for UvTcpStream {
|
||||
return result_cell.take();
|
||||
}
|
||||
|
||||
fn peer_name(&mut self) -> Result<IpAddr, IoError> {
|
||||
fn peer_name(&mut self) -> Result<SocketAddr, IoError> {
|
||||
socket_name(TcpPeer, **self)
|
||||
}
|
||||
|
||||
@ -586,15 +586,15 @@ impl Drop for UvUdpSocket {
|
||||
}
|
||||
|
||||
impl RtioSocket for UvUdpSocket {
|
||||
fn socket_name(&mut self) -> Result<IpAddr, IoError> {
|
||||
fn socket_name(&mut self) -> Result<SocketAddr, IoError> {
|
||||
socket_name(Udp, **self)
|
||||
}
|
||||
}
|
||||
|
||||
impl RtioUdpSocket for UvUdpSocket {
|
||||
fn recvfrom(&mut self, buf: &mut [u8]) -> Result<(uint, IpAddr), IoError> {
|
||||
fn recvfrom(&mut self, buf: &mut [u8]) -> Result<(uint, SocketAddr), IoError> {
|
||||
let result_cell = Cell::new_empty();
|
||||
let result_cell_ptr: *Cell<Result<(uint, IpAddr), IoError>> = &result_cell;
|
||||
let result_cell_ptr: *Cell<Result<(uint, SocketAddr), IoError>> = &result_cell;
|
||||
|
||||
let scheduler = Local::take::<Scheduler>();
|
||||
let buf_ptr: *&mut [u8] = &buf;
|
||||
@ -626,7 +626,7 @@ impl RtioUdpSocket for UvUdpSocket {
|
||||
return result_cell.take();
|
||||
}
|
||||
|
||||
fn sendto(&mut self, buf: &[u8], dst: IpAddr) -> Result<(), IoError> {
|
||||
fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> Result<(), IoError> {
|
||||
let result_cell = Cell::new_empty();
|
||||
let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell;
|
||||
let scheduler = Local::take::<Scheduler>();
|
||||
@ -653,17 +653,8 @@ impl RtioUdpSocket for UvUdpSocket {
|
||||
}
|
||||
|
||||
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| {
|
||||
do multi.to_str().as_c_str |m_addr| {
|
||||
uvll::udp_set_membership(self.native_handle(), m_addr,
|
||||
ptr::null(), uvll::UV_JOIN_GROUP)
|
||||
}
|
||||
@ -676,17 +667,8 @@ impl RtioUdpSocket for UvUdpSocket {
|
||||
}
|
||||
|
||||
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| {
|
||||
do multi.to_str().as_c_str |m_addr| {
|
||||
uvll::udp_set_membership(self.native_handle(), m_addr,
|
||||
ptr::null(), uvll::UV_LEAVE_GROUP)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user