Skip to main content

tunneler_core/
server.rs

1//! This contains all the logic needed for running the Server-Side of this
2//!
3//! # Structure
4//! ## Server
5//! The Server itself is the overarching "Manager"/"Handler" for all how it all
6//! works together. It is therefore also responsible for accepting the Client-
7//! Connections and creating their appropriate Forwarders or adding a Client
8//! to a new Forwarder.
9//!
10//! ## Forwarder
11//! A Forwarder is responsible for accepting the connections from actual
12//! Users and forwarding them to a given Client and managing their Data
13//! exchange for the entire lifetime of the connection
14
15use crate::{handshake, metrics, metrics::Metrics};
16
17use rand::Rng;
18use std::collections::BTreeMap;
19use std::sync::Arc;
20use tokio::net::TcpListener;
21
22mod tcpforwarder;
23use tcpforwarder::{Client, ClientManager};
24mod ports;
25mod user;
26
27pub use ports::Strategy;
28use tcpforwarder::TCPForwarder;
29
30/// Holds all information needed to creating and running
31/// a single Tunneler-Server
32#[derive(Debug, PartialEq)]
33pub struct Server<M> {
34    listen_port: u32,
35    port_strategy: Strategy,
36    key: Vec<u8>,
37    metrics: Arc<M>,
38}
39
40impl Server<metrics::Empty> {
41    /// Creates a new Server-Instance from the given Data
42    ///
43    /// Params:
44    /// * listen_port: The Port clients will connect to
45    /// * port_strategy: The Strategy to determine if a port a client wants to use is valid
46    /// * key: The Key/Password clients need to connect to the server
47    pub fn new(listen_port: u32, port_strategy: Strategy, key: Vec<u8>) -> Self {
48        Self::new_metrics(listen_port, port_strategy, key, metrics::Empty::new())
49    }
50}
51
52impl<M> Server<M>
53where
54    M: Metrics,
55{
56    /// Creates a new Server-Instance from the given Data
57    ///
58    /// Params:
59    /// * listen_port: The Port clients will connect to
60    /// * port_strategy: The Strategy to determine if a port a client wants to use is valid
61    /// * key: The Key/Password clients need to connect to the server
62    /// * p_metrics: The Metrics-Collector to use
63    pub fn new_metrics(
64        listen_port: u32,
65        port_strategy: Strategy,
66        key: Vec<u8>,
67        p_metrics: M,
68    ) -> Self {
69        Self {
70            listen_port,
71            port_strategy,
72            key,
73            metrics: Arc::new(p_metrics),
74        }
75    }
76
77    /// Actually starts the Server and starts listening for incoming Connections from
78    /// both users and clients.
79    ///
80    /// # Behaviour
81    /// This function is not expected to return as all the connections will be handled
82    /// internally or by other parts of the System, so this one can keep accepting new
83    /// ones
84    pub async fn listen(self) -> Result<(), ()> {
85        info!("Starting...");
86
87        let listen_bind_addr = format!("0.0.0.0:{}", self.listen_port);
88        let client_listener = match TcpListener::bind(&listen_bind_addr).await {
89            Ok(l) => l,
90            Err(e) => {
91                error!("Binding to Address('{}'): {:?}", listen_bind_addr, e);
92                return Err(());
93            }
94        };
95
96        info!("Listening for Clients on: {}", listen_bind_addr);
97
98        let mut ports: BTreeMap<u16, Arc<ClientManager>> = BTreeMap::new();
99
100        // Accept new Clients
101        loop {
102            // Get Client
103            let mut client_socket = match client_listener.accept().await {
104                Ok((socket, _)) => socket,
105                Err(e) => {
106                    error!("Accepting client-connection: {}", e);
107                    continue;
108                }
109            };
110
111            let conf = match handshake::server::perform(&mut client_socket, &self.key, |port| {
112                self.port_strategy.contains_port(port)
113            })
114            .await
115            {
116                Ok(p) => p,
117                Err(e) => {
118                    error!("Validating Client-Connection: {:?}", e);
119                    continue;
120                }
121            };
122
123            let clients = match ports.get(&conf.port()) {
124                Some(c) => c.clone(),
125                None => {
126                    // Create new Client-List for the Port and start a Forwarder for
127                    // the Port as well
128                    let tmp = Arc::new(ClientManager::new());
129                    let fwd = match TCPForwarder::new(conf.port(), tmp.clone()).await {
130                        Ok(f) => f,
131                        Err(e) => {
132                            error!("Binding Forwader: {:?}", e);
133                            continue;
134                        }
135                    };
136                    tokio::task::spawn(fwd.start());
137
138                    ports.insert(conf.port(), tmp.clone());
139                    tmp
140                }
141            };
142
143            let c_id: u32 = rand::thread_rng().gen();
144
145            info!("Accepted client: {}", c_id);
146
147            let (rx, tx) = client_socket.into_split();
148
149            let (queue_tx, queue_rx) = tokio::sync::mpsc::unbounded_channel();
150
151            let client = Client::new(c_id, clients.clone(), queue_tx);
152
153            tokio::task::spawn(Client::sender(c_id, tx, queue_rx, clients.clone()));
154            tokio::task::spawn(Client::receiver(
155                c_id,
156                rx,
157                client.get_user_cons(),
158                clients.clone(),
159            ));
160
161            clients.add(client);
162        }
163    }
164}
165
166#[cfg(test)]
167mod tests {
168    use super::*;
169
170    #[test]
171    fn new_server() {
172        assert_eq!(
173            Server {
174                listen_port: 8080,
175                port_strategy: Strategy::Single(12),
176                key: vec![2, 3, 1],
177                metrics: Arc::new(metrics::Empty::new()),
178            },
179            Server::new(8080, Strategy::Single(12), vec![2, 3, 1])
180        );
181    }
182}