p2p 0.6.0

NAT Traversal for P2P communication
use common::event_loop::{Core, CoreState};
use common::types::PeerId;
use mio::net::TcpListener;
use mio::{Poll, PollOpt, Ready, Token};
use p2p::Interface;
use socket_collection::TcpSock;
use sodium::crypto::box_;
use std::any::Any;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::io::ErrorKind;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::rc::Rc;
use std::time::Duration;
use Peer;

pub struct Overlay {
    token: Token,
    l: TcpListener,
    peers: Rc<RefCell<BTreeMap<PeerId, Token>>>,
}

impl Overlay {
    pub fn start(core: &mut Core, poll: &Poll, overlay_port: u16) {
        let local_ep = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), overlay_port);
        let l = unwrap!(TcpListener::bind(&local_ep));

        let token = core.new_token();

        unwrap!(poll.register(
            &l,
            token,
            Ready::readable() | Ready::error() | Ready::hup(),
            PollOpt::edge(),
        ));

        let state = Self {
            token,
            l,
            peers: Rc::new(RefCell::new(Default::default())),
        };

        if core
            .insert_peer_state(token, Rc::new(RefCell::new(state)))
            .is_err()
        {
            panic!("Could not start Overlay !");
        }
    }

    fn accept(&self, core: &mut Core, poll: &Poll) {
        loop {
            match self.l.accept() {
                Ok((socket, _)) => {
                    unwrap!(socket.set_keepalive(Some(Duration::from_secs(10))));
                    let peers = Rc::downgrade(&self.peers);
                    Peer::start(core, poll, TcpSock::wrap(socket), peers);
                }
                Err(e) => {
                    if e.kind() != ErrorKind::WouldBlock && e.kind() != ErrorKind::Interrupted {
                        warn!("Failed to accept new socket: {:?}", e);
                    }
                    break;
                }
            }
        }
    }
}

impl CoreState for Overlay {
    fn ready(&mut self, core: &mut Core, poll: &Poll, kind: Ready) {
        if kind.is_error() || kind.is_hup() {
            warn!("Overlay errored out");
            self.terminate(core, poll);
        } else if kind.is_readable() {
            self.accept(core, poll);
        }
    }

    fn terminate(&mut self, core: &mut Core, poll: &Poll) {
        let _ = poll.deregister(&self.l);
        let _ = core.remove_peer_state(self.token);
    }

    fn as_any(&mut self) -> &mut Any {
        self
    }
}