1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
use self::exchange_msg::ExchangeMsg;
use {Interface, NatError, NatState};
use config::TCP_RENDEZVOUS_PORT;
use mio::{Poll, PollOpt, Ready, Token};
use mio::tcp::TcpListener;
use net2::TcpBuilder;
use std::any::Any;
use std::cell::RefCell;
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use std::rc::Rc;
use tcp::{Socket, TcpEchoReq, TcpEchoResp};

mod exchange_msg;

const LISTENER_BACKLOG: i32 = 100;

/// TCP Rendezvous server.
///
/// This is intended to be kept running on some publicly reachable endpoint so that peers can
/// obtain their rendezvous information. The information provided back to the peer is encrypted
/// with peer-supplied asymmetric key. Certain router and firewalls scan the packet and if they
/// find an IP address belonging to their pool that they use to do the NAT mapping/translation,
/// they take it as a STUN attempt or similar and mangle the information or even discard it.
/// Encrypting makes sure no such thing happens.
pub struct TcpRendezvousServer {
    token: Token,
    listener: TcpListener,
}

impl TcpRendezvousServer {
    /// Boot the TCP Rendezvous server. This should normally be called only once.
    pub fn start(ifc: &mut Interface, poll: &Poll) -> ::Res<Token> {
        let listener = {
            let port = ifc.config()
                .tcp_rendezvous_port
                .unwrap_or(TCP_RENDEZVOUS_PORT);
            let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), port));
            let builder = TcpBuilder::new_v4()?;
            let _ = builder.bind(addr)?;
            let l = builder.listen(LISTENER_BACKLOG)?;
            TcpListener::from_listener(l, &addr)?
        };

        let token = ifc.new_token();

        poll.register(&listener,
                      token,
                      Ready::readable() | Ready::error() | Ready::hup(),
                      PollOpt::edge())?;

        let server = Rc::new(RefCell::new(TcpRendezvousServer {
                                              token: token,
                                              listener: listener,
                                          }));

        if ifc.insert_state(token, server.clone()).is_err() {
            warn!("Unable to start TcpRendezvousServer!");
            server.borrow_mut().terminate(ifc, poll);
            Err(NatError::TcpRendezvousServerStartFailed)
        } else {
            Ok(token)
        }
    }

    fn accept(&mut self, ifc: &mut Interface, poll: &Poll) {
        loop {
            match self.listener.accept() {
                Ok((socket, peer)) => {
                    if let Err(e) = ExchangeMsg::start(ifc, poll, peer, Socket::wrap(socket)) {
                        debug!("Error accepting direct connection: {:?}", e);
                    }
                }
                Err(e) => {
                    debug!("Failed to accept new socket: {:?}", e);
                    return;
                }
            }
        }
    }
}

impl NatState for TcpRendezvousServer {
    fn ready(&mut self, ifc: &mut Interface, poll: &Poll, event: Ready) {
        if event.is_error() || event.is_hup() {
            let e = match self.listener.take_error() {
                Ok(err) => err.map_or(NatError::Unknown, NatError::from),
                Err(e) => From::from(e),
            };
            warn!("Error in TcpRendezvousServer readiness: {:?}", e);
            self.terminate(ifc, poll)
        } else if event.is_readable() {
            self.accept(ifc, poll)
        } else {
            trace!("Ignoring unknown event kind: {:?}", event);
        }
    }

    fn terminate(&mut self, ifc: &mut Interface, poll: &Poll) {
        let _ = ifc.remove_state(self.token);
        let _ = poll.deregister(&self.listener);
    }

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