More code

This commit is contained in:
Dennis Schwerdel 2015-11-22 17:28:04 +01:00
parent 0a04c9f1b9
commit 7cbe7c8f71
5 changed files with 75 additions and 14 deletions

View File

@ -10,9 +10,9 @@ use std::marker::PhantomData;
use time::{Duration, SteadyTime, precise_time_ns};
use epoll;
use super::{ethernet, udpmessage};
use super::udpmessage::{Options, Message};
use super::ethernet::{TapDevice, MacTable};
use super::udpmessage::{encode, decode, Options, Message};
use super::ethernet::{Frame, EthAddr, TapDevice, MacTable};
pub type NetworkId = u64;
@ -113,7 +113,8 @@ impl PeerList {
}
}
pub struct EthCloud<A, T: Table<Address=A>, M: InterfaceMessage<Address=A>, I: VirtualInterface> {
pub struct GenericCloud<A, T: Table<Address=A>, M: InterfaceMessage<Address=A>, I: VirtualInterface> {
peers: PeerList,
reconnect_peers: Vec<SocketAddr>,
table: T,
@ -127,13 +128,13 @@ pub struct EthCloud<A, T: Table<Address=A>, M: InterfaceMessage<Address=A>, I: V
_dummy_m: PhantomData<M>,
}
impl<A: fmt::Debug, T: Table<Address=A>, M: InterfaceMessage<Address=A>, I: VirtualInterface> EthCloud<A, T, M, I> {
impl<A: fmt::Debug, T: Table<Address=A>, M: InterfaceMessage<Address=A>, I: VirtualInterface> GenericCloud<A, T, M, I> {
pub fn new(device: I, listen: String, network_id: Option<NetworkId>, table: T, peer_timeout: Duration) -> Self {
let socket = match UdpSocket::bind(&listen as &str) {
Ok(socket) => socket,
_ => panic!("Failed to open socket")
};
EthCloud{
GenericCloud{
peers: PeerList::new(peer_timeout),
reconnect_peers: Vec::new(),
table: table,
@ -152,7 +153,7 @@ impl<A: fmt::Debug, T: Table<Address=A>, M: InterfaceMessage<Address=A>, I: Virt
debug!("Sending {:?} to {}", msg, addr);
let mut options = Options::default();
options.network_id = self.network_id;
let size = udpmessage::encode(&options, msg, &mut self.buffer_out);
let size = encode(&options, msg, &mut self.buffer_out);
match self.socket.send_to(&self.buffer_out[..size], addr) {
Ok(written) if written == size => Ok(()),
Ok(_) => Err(Error::SocketError("Sent out truncated packet")),
@ -281,7 +282,7 @@ impl<A: fmt::Debug, T: Table<Address=A>, M: InterfaceMessage<Address=A>, I: Virt
match &events[i as usize].data {
&0 => match self.socket.recv_from(&mut buffer) {
Ok((size, src)) => {
match udpmessage::decode(&buffer[..size]).and_then(|(options, msg)| self.handle_net_message(src, options, msg)) {
match decode(&buffer[..size]).and_then(|(options, msg)| self.handle_net_message(src, options, msg)) {
Ok(_) => (),
Err(e) => error!("Error: {:?}", e)
}
@ -310,7 +311,8 @@ impl<A: fmt::Debug, T: Table<Address=A>, M: InterfaceMessage<Address=A>, I: Virt
}
}
pub type TapCloud = EthCloud<ethernet::EthAddr, MacTable, ethernet::Frame, ethernet::TapDevice>;
pub type TapCloud = GenericCloud<EthAddr, MacTable, Frame, TapDevice>;
impl TapCloud {
pub fn new_tap_cloud(device: &str, listen: String, network_id: Option<NetworkId>, mac_timeout: Duration, peer_timeout: Duration) -> Self {

View File

@ -4,7 +4,7 @@ use std::collections::HashMap;
use std::os::unix::io::{AsRawFd, RawFd};
use std::io::{Result as IoResult, Error as IoError, Read, Write};
use super::ethcloud::{Error, Table, InterfaceMessage, VirtualInterface};
use super::cloud::{Error, Table, InterfaceMessage, VirtualInterface};
use super::util::{as_bytes, as_obj};
use time::{Duration, SteadyTime};
@ -13,6 +13,7 @@ extern {
fn setup_tap_device(fd: i32, ifname: *mut u8) -> i32;
}
#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Mac(pub [u8; 6]);
@ -31,6 +32,7 @@ pub struct EthAddr {
pub vlan: Option<VlanId>
}
#[derive(PartialEq)]
pub struct Frame {
pub src: EthAddr,
@ -101,6 +103,7 @@ impl InterfaceMessage for Frame {
}
}
pub struct TapDevice {
fd: fs::File,
ifname: String
@ -151,11 +154,13 @@ impl VirtualInterface for TapDevice {
}
}
struct MacTableValue {
address: SocketAddr,
timeout: SteadyTime
}
pub struct MacTable {
table: HashMap<EthAddr, MacTableValue>,
timeout: Duration

View File

@ -1,5 +1,59 @@
use std::net::SocketAddr;
use std::net::{SocketAddr, Ipv4Addr, Ipv6Addr};
use std::collections::{hash_map, HashMap};
use std::fmt;
use super::cloud::{InterfaceMessage, Error};
use super::util::{as_obj, as_bytes};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum IpAddress {
V4(Ipv4Addr),
V6(Ipv6Addr)
}
#[derive(PartialEq)]
pub enum IpHeader {
V4{src: Ipv4Addr, dst: Ipv4Addr},
V6{src: Ipv6Addr, dst: Ipv6Addr}
}
impl fmt::Debug for IpHeader {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match self {
&IpHeader::V4{src, dst} => write!(formatter, "src: {}, dst: {}", src, dst),
&IpHeader::V6{src, dst} => write!(formatter, "src: {}, dst: {}", src, dst)
}
}
}
impl InterfaceMessage for IpHeader {
type Address = IpAddress;
fn src(&self) -> Self::Address {
match self {
&IpHeader::V4{src, dst: _} => IpAddress::V4(src),
&IpHeader::V6{src, dst: _} => IpAddress::V6(src)
}
}
fn dst(&self) -> Self::Address {
match self {
&IpHeader::V4{src: _, dst} => IpAddress::V4(dst),
&IpHeader::V6{src: _, dst} => IpAddress::V6(dst)
}
}
fn encode_to(&self, payload: &[u8], data: &mut [u8]) -> usize {
unimplemented!()
}
fn parse_from(data: &[u8]) -> Result<(Self, &[u8]), Error> {
unimplemented!()
}
}
struct RoutingEntry {
address: SocketAddr,

View File

@ -8,14 +8,14 @@ mod util;
mod udpmessage;
mod ethernet;
mod ip;
mod ethcloud;
mod cloud;
use time::Duration;
use docopt::Docopt;
use std::hash::{Hash, SipHasher, Hasher};
use ethcloud::{Error, TapCloud};
use cloud::{Error, TapCloud};
//TODO: Implement IPv6

View File

@ -2,7 +2,7 @@ use std::{mem, ptr, fmt};
use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr};
use std::u16;
use super::ethcloud::{Error, NetworkId, InterfaceMessage};
use super::cloud::{Error, NetworkId, InterfaceMessage};
use super::ethernet;
use super::util::{as_obj, as_bytes};