vpncloud/src/ip.rs

101 lines
3.1 KiB
Rust
Raw Normal View History

2015-11-22 23:49:58 +00:00
use std::net::SocketAddr;
2015-11-21 15:50:50 +00:00
use std::collections::{hash_map, HashMap};
2015-11-22 21:00:34 +00:00
use std::io::Read;
2015-11-22 18:47:28 +00:00
2015-11-23 00:04:30 +00:00
use super::types::{Protocol, Error, Table, Address};
2015-11-22 23:49:58 +00:00
use super::util::to_vec;
2015-11-22 18:47:28 +00:00
2015-11-22 19:02:02 +00:00
#[allow(dead_code)]
2015-11-23 00:40:47 +00:00
pub struct Packet;
2015-11-22 16:28:04 +00:00
2015-11-23 00:40:47 +00:00
impl Protocol for Packet {
2015-11-22 23:49:58 +00:00
fn parse(data: &[u8]) -> Result<(Address, Address), Error> {
2015-11-22 18:00:56 +00:00
if data.len() < 1 {
return Err(Error::ParseError("Empty header"));
}
let version = data[0] >> 4;
match version {
4 => {
if data.len() < 20 {
return Err(Error::ParseError("Truncated header"));
}
2015-11-22 23:49:58 +00:00
Ok((Address(to_vec(&data[12..16])), Address(to_vec(&data[16..20]))))
2015-11-22 18:00:56 +00:00
},
6 => {
if data.len() < 40 {
return Err(Error::ParseError("Truncated header"));
}
2015-11-22 23:49:58 +00:00
Ok((Address(to_vec(&data[8..24])), Address(to_vec(&data[24..40]))))
2015-11-22 18:00:56 +00:00
},
_ => Err(Error::ParseError("Invalid version"))
}
2015-11-22 16:28:04 +00:00
}
}
2015-11-21 15:50:50 +00:00
struct RoutingEntry {
address: SocketAddr,
bytes: Vec<u8>,
prefix_len: u8
}
pub struct RoutingTable(HashMap<Vec<u8>, Vec<RoutingEntry>>);
impl RoutingTable {
pub fn new() -> Self {
RoutingTable(HashMap::new())
}
2015-11-22 23:49:58 +00:00
}
2015-11-21 15:50:50 +00:00
2015-11-22 23:49:58 +00:00
impl Table for RoutingTable {
fn learn(&mut self, addr: Address, prefix_len: Option<u8>, address: SocketAddr) {
let prefix_len = match prefix_len {
Some(val) => val,
None => addr.0.len() as u8 * 8
};
2015-11-23 10:55:37 +00:00
info!("New routing entry: {:?}/{} => {}", addr, prefix_len, address);
2015-11-21 15:50:50 +00:00
let group_len = (prefix_len as usize / 16) * 2;
2015-11-22 23:49:58 +00:00
let group_bytes: Vec<u8> = addr.0[..group_len].iter().map(|b| *b).collect();
let routing_entry = RoutingEntry{address: address, bytes: addr.0, prefix_len: prefix_len};
2015-11-21 15:50:50 +00:00
match self.0.entry(group_bytes) {
hash_map::Entry::Occupied(mut entry) => entry.get_mut().push(routing_entry),
hash_map::Entry::Vacant(entry) => { entry.insert(vec![routing_entry]); () }
}
}
2015-11-22 23:49:58 +00:00
fn lookup(&self, addr: &Address) -> Option<SocketAddr> {
let len = addr.0.len()/2 * 2;
2015-11-23 10:55:37 +00:00
for i in 0..(len/2)+1 {
2015-11-22 23:49:58 +00:00
if let Some(group) = self.0.get(&addr.0[0..len-2*i]) {
2015-11-21 15:50:50 +00:00
for entry in group {
2015-11-22 23:49:58 +00:00
if entry.bytes.len() != addr.0.len() {
2015-11-21 15:50:50 +00:00
continue;
}
let mut match_len = 0;
2015-11-22 23:49:58 +00:00
for i in 0..addr.0.len() {
let b = addr.0[i] ^ entry.bytes[i];
2015-11-21 15:50:50 +00:00
if b == 0 {
match_len += 8;
} else {
match_len += b.leading_zeros();
break;
}
}
if match_len as u8 >= entry.prefix_len {
return Some(entry.address);
}
}
}
}
None
}
2015-11-22 18:00:56 +00:00
fn housekeep(&mut self) {
//nothing to do
2015-11-22 18:00:56 +00:00
}
2015-11-22 21:00:34 +00:00
fn remove_all(&mut self, _addr: SocketAddr) {
unimplemented!()
}
2015-11-22 18:00:56 +00:00
}