mirror of https://github.com/dswd/vpncloud.git
types in extra module
This commit is contained in:
parent
fe036ded5f
commit
a559a10155
112
src/cloud.rs
112
src/cloud.rs
|
@ -1,9 +1,9 @@
|
||||||
use std::net::{SocketAddr, ToSocketAddrs, Ipv4Addr, Ipv6Addr};
|
use std::net::{SocketAddr, ToSocketAddrs};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::hash::Hasher;
|
use std::hash::Hasher;
|
||||||
use std::net::UdpSocket;
|
use std::net::UdpSocket;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::{fmt, ptr};
|
use std::fmt;
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
@ -11,117 +11,11 @@ use std::str::FromStr;
|
||||||
use time::{Duration, SteadyTime, precise_time_ns};
|
use time::{Duration, SteadyTime, precise_time_ns};
|
||||||
use epoll;
|
use epoll;
|
||||||
|
|
||||||
|
use super::types::{Table, Protocol, VirtualInterface, Range, Error, NetworkId, Behavior};
|
||||||
use super::device::{TunDevice, TapDevice};
|
use super::device::{TunDevice, TapDevice};
|
||||||
use super::udpmessage::{encode, decode, Options, Message};
|
use super::udpmessage::{encode, decode, Options, Message};
|
||||||
use super::ethernet::{Frame, MacTable};
|
use super::ethernet::{Frame, MacTable};
|
||||||
use super::ip::{InternetProtocol, RoutingTable};
|
use super::ip::{InternetProtocol, RoutingTable};
|
||||||
use super::util::as_bytes;
|
|
||||||
|
|
||||||
|
|
||||||
pub type NetworkId = u64;
|
|
||||||
|
|
||||||
#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
|
|
||||||
pub struct Address(pub Vec<u8>);
|
|
||||||
|
|
||||||
impl fmt::Debug for Address {
|
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
||||||
match self.0.len() {
|
|
||||||
4 => write!(formatter, "{}.{}.{}.{}", self.0[0], self.0[1], self.0[2], self.0[3]),
|
|
||||||
6 => write!(formatter, "{:x}:{:x}:{:x}:{:x}:{:x}:{:x}",
|
|
||||||
self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5]),
|
|
||||||
16 => write!(formatter, "{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}",
|
|
||||||
self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5], self.0[6], self.0[7],
|
|
||||||
self.0[8], self.0[9], self.0[10], self.0[11], self.0[12], self.0[13], self.0[14], self.0[15]
|
|
||||||
),
|
|
||||||
_ => self.0.fmt(formatter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for Address {
|
|
||||||
type Err=Error;
|
|
||||||
|
|
||||||
fn from_str(text: &str) -> Result<Self, Self::Err> {
|
|
||||||
if let Ok(addr) = Ipv4Addr::from_str(text) {
|
|
||||||
let ip = addr.octets();
|
|
||||||
let mut res = Vec::with_capacity(4);
|
|
||||||
unsafe {
|
|
||||||
res.set_len(4);
|
|
||||||
ptr::copy_nonoverlapping(ip.as_ptr(), res.as_mut_ptr(), ip.len());
|
|
||||||
}
|
|
||||||
return Ok(Address(res));
|
|
||||||
}
|
|
||||||
if let Ok(addr) = Ipv6Addr::from_str(text) {
|
|
||||||
let mut segments = addr.segments();
|
|
||||||
for i in 0..8 {
|
|
||||||
segments[i] = segments[i].to_be();
|
|
||||||
}
|
|
||||||
let bytes = unsafe { as_bytes(&segments) };
|
|
||||||
let mut res = Vec::with_capacity(16);
|
|
||||||
unsafe {
|
|
||||||
res.set_len(16);
|
|
||||||
ptr::copy_nonoverlapping(bytes.as_ptr(), res.as_mut_ptr(), bytes.len());
|
|
||||||
}
|
|
||||||
return Ok(Address(res));
|
|
||||||
}
|
|
||||||
//FIXME: implement for mac addresses
|
|
||||||
return Err(Error::ParseError("Failed to parse address"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
|
|
||||||
pub struct Range {
|
|
||||||
pub base: Address,
|
|
||||||
pub prefix_len: u8
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for Range {
|
|
||||||
type Err=Error;
|
|
||||||
|
|
||||||
fn from_str(text: &str) -> Result<Self, Self::Err> {
|
|
||||||
let pos = match text.find("/") {
|
|
||||||
Some(pos) => pos,
|
|
||||||
None => return Err(Error::ParseError("Invalid range format"))
|
|
||||||
};
|
|
||||||
let prefix_len = try!(u8::from_str(&text[pos+1..])
|
|
||||||
.map_err(|_| Error::ParseError("Failed to parse prefix length")));
|
|
||||||
let base = try!(Address::from_str(&text[..pos]));
|
|
||||||
Ok(Range{base: base, prefix_len: prefix_len})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(RustcDecodable, Debug)]
|
|
||||||
pub enum Behavior {
|
|
||||||
Normal, Hub, Switch, Router
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Table {
|
|
||||||
fn learn(&mut self, Address, Option<u8>, SocketAddr);
|
|
||||||
fn lookup(&self, &Address) -> Option<SocketAddr>;
|
|
||||||
fn housekeep(&mut self);
|
|
||||||
fn remove_all(&mut self, SocketAddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Protocol: Sized {
|
|
||||||
fn parse(&[u8]) -> Result<(Address, Address), Error>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait VirtualInterface: AsRawFd {
|
|
||||||
fn read(&mut self, &mut [u8]) -> Result<usize, Error>;
|
|
||||||
fn write(&mut self, &[u8]) -> Result<(), Error>;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Error {
|
|
||||||
ParseError(&'static str),
|
|
||||||
WrongNetwork(Option<NetworkId>),
|
|
||||||
SocketError(&'static str),
|
|
||||||
TunTapDevError(&'static str),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct PeerList {
|
struct PeerList {
|
||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::io::{Result as IoResult, Error as IoError, Read, Write};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
use super::cloud::{Error, VirtualInterface};
|
use super::types::{Error, VirtualInterface};
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
fn setup_tap_device(fd: i32, ifname: *mut u8) -> i32;
|
fn setup_tap_device(fd: i32, ifname: *mut u8) -> i32;
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::ptr;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use super::cloud::{Error, Table, Protocol, Address};
|
use super::types::{Error, Table, Protocol, Address};
|
||||||
|
|
||||||
use time::{Duration, SteadyTime};
|
use time::{Duration, SteadyTime};
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::net::SocketAddr;
|
||||||
use std::collections::{hash_map, HashMap};
|
use std::collections::{hash_map, HashMap};
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
|
||||||
use super::cloud::{Protocol, Error, Table, Address};
|
use super::types::{Protocol, Error, Table, Address};
|
||||||
use super::util::to_vec;
|
use super::util::to_vec;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
|
|
@ -5,6 +5,7 @@ extern crate rustc_serialize;
|
||||||
extern crate epoll;
|
extern crate epoll;
|
||||||
|
|
||||||
mod util;
|
mod util;
|
||||||
|
mod types;
|
||||||
mod udpmessage;
|
mod udpmessage;
|
||||||
mod ethernet;
|
mod ethernet;
|
||||||
mod ip;
|
mod ip;
|
||||||
|
@ -16,7 +17,8 @@ use docopt::Docopt;
|
||||||
|
|
||||||
use std::hash::{Hash, SipHasher, Hasher};
|
use std::hash::{Hash, SipHasher, Hasher};
|
||||||
|
|
||||||
use cloud::{Error, TapCloud, TunCloud, Behavior};
|
use types::{Error, Behavior};
|
||||||
|
use cloud::{TapCloud, TunCloud};
|
||||||
|
|
||||||
|
|
||||||
//TODO: hub behavior
|
//TODO: hub behavior
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
use std::net::{SocketAddr, Ipv4Addr, Ipv6Addr};
|
||||||
|
use std::hash::Hasher;
|
||||||
|
use std::{fmt, ptr};
|
||||||
|
use std::os::unix::io::AsRawFd;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use super::util::as_bytes;
|
||||||
|
|
||||||
|
pub type NetworkId = u64;
|
||||||
|
|
||||||
|
#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
|
||||||
|
pub struct Address(pub Vec<u8>);
|
||||||
|
|
||||||
|
impl fmt::Debug for Address {
|
||||||
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
|
match self.0.len() {
|
||||||
|
4 => write!(formatter, "{}.{}.{}.{}", self.0[0], self.0[1], self.0[2], self.0[3]),
|
||||||
|
6 => write!(formatter, "{:x}:{:x}:{:x}:{:x}:{:x}:{:x}",
|
||||||
|
self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5]),
|
||||||
|
16 => write!(formatter, "{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}",
|
||||||
|
self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5], self.0[6], self.0[7],
|
||||||
|
self.0[8], self.0[9], self.0[10], self.0[11], self.0[12], self.0[13], self.0[14], self.0[15]
|
||||||
|
),
|
||||||
|
_ => self.0.fmt(formatter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Address {
|
||||||
|
type Err=Error;
|
||||||
|
|
||||||
|
fn from_str(text: &str) -> Result<Self, Self::Err> {
|
||||||
|
if let Ok(addr) = Ipv4Addr::from_str(text) {
|
||||||
|
let ip = addr.octets();
|
||||||
|
let mut res = Vec::with_capacity(4);
|
||||||
|
unsafe {
|
||||||
|
res.set_len(4);
|
||||||
|
ptr::copy_nonoverlapping(ip.as_ptr(), res.as_mut_ptr(), ip.len());
|
||||||
|
}
|
||||||
|
return Ok(Address(res));
|
||||||
|
}
|
||||||
|
if let Ok(addr) = Ipv6Addr::from_str(text) {
|
||||||
|
let mut segments = addr.segments();
|
||||||
|
for i in 0..8 {
|
||||||
|
segments[i] = segments[i].to_be();
|
||||||
|
}
|
||||||
|
let bytes = unsafe { as_bytes(&segments) };
|
||||||
|
let mut res = Vec::with_capacity(16);
|
||||||
|
unsafe {
|
||||||
|
res.set_len(16);
|
||||||
|
ptr::copy_nonoverlapping(bytes.as_ptr(), res.as_mut_ptr(), bytes.len());
|
||||||
|
}
|
||||||
|
return Ok(Address(res));
|
||||||
|
}
|
||||||
|
//FIXME: implement for mac addresses
|
||||||
|
return Err(Error::ParseError("Failed to parse address"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
|
||||||
|
pub struct Range {
|
||||||
|
pub base: Address,
|
||||||
|
pub prefix_len: u8
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Range {
|
||||||
|
type Err=Error;
|
||||||
|
|
||||||
|
fn from_str(text: &str) -> Result<Self, Self::Err> {
|
||||||
|
let pos = match text.find("/") {
|
||||||
|
Some(pos) => pos,
|
||||||
|
None => return Err(Error::ParseError("Invalid range format"))
|
||||||
|
};
|
||||||
|
let prefix_len = try!(u8::from_str(&text[pos+1..])
|
||||||
|
.map_err(|_| Error::ParseError("Failed to parse prefix length")));
|
||||||
|
let base = try!(Address::from_str(&text[..pos]));
|
||||||
|
Ok(Range{base: base, prefix_len: prefix_len})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(RustcDecodable, Debug)]
|
||||||
|
pub enum Behavior {
|
||||||
|
Normal, Hub, Switch, Router
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Table {
|
||||||
|
fn learn(&mut self, Address, Option<u8>, SocketAddr);
|
||||||
|
fn lookup(&self, &Address) -> Option<SocketAddr>;
|
||||||
|
fn housekeep(&mut self);
|
||||||
|
fn remove_all(&mut self, SocketAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Protocol: Sized {
|
||||||
|
fn parse(&[u8]) -> Result<(Address, Address), Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait VirtualInterface: AsRawFd {
|
||||||
|
fn read(&mut self, &mut [u8]) -> Result<usize, Error>;
|
||||||
|
fn write(&mut self, &[u8]) -> Result<(), Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
ParseError(&'static str),
|
||||||
|
WrongNetwork(Option<NetworkId>),
|
||||||
|
SocketError(&'static str),
|
||||||
|
TunTapDevError(&'static str),
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ use std::{mem, ptr, fmt};
|
||||||
use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr};
|
use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr};
|
||||||
use std::u16;
|
use std::u16;
|
||||||
|
|
||||||
use super::cloud::{Error, NetworkId, Range, Address};
|
use super::types::{Error, NetworkId, Range, Address};
|
||||||
use super::util::{as_obj, as_bytes, to_vec};
|
use super::util::{as_obj, as_bytes, to_vec};
|
||||||
|
|
||||||
const MAGIC: [u8; 3] = [0x76, 0x70, 0x6e];
|
const MAGIC: [u8; 3] = [0x76, 0x70, 0x6e];
|
||||||
|
|
Loading…
Reference in New Issue