Skip to main content

netget/server/openvpn/
session.rs

1//! One peer's OpenVPN control channel: reliability layer, TLS session and the
2//! key-method-2 exchange that runs inside it.
3//!
4//! # Why this is separate from [`super::peer`]
5//!
6//! `Peer` is cloneable transport bookkeeping — addresses, counters, the
7//! admission decision — and several call sites take a snapshot of it. A
8//! `rustls::ServerConnection` cannot be cloned and must never be snapshotted:
9//! two copies of a TLS session are two divergent record streams. So the
10//! non-cloneable half lives here, in a table whose only access is a closure that
11//! borrows it mutably.
12//!
13//! # Locking
14//!
15//! [`SessionManager`] hands out `&mut ControlSession` inside a synchronous
16//! closure and nothing else, so the lock is never held across an `await`. Every
17//! method here returns the bytes to transmit rather than transmitting them: the
18//! socket write happens in `mod.rs` after the guard has been dropped.
19
20use super::keymethod::{self, ClientKeyMethod2};
21use super::packet::{ControlFrame, Opcode};
22use super::reliable::{fragment, ReliableReceiver, ReliableSender};
23use super::tls_channel;
24use crate::server::connection::ConnectionId;
25use crate::utils::clock::Instant;
26use anyhow::{Context, Result};
27use std::collections::HashMap;
28use std::io::{Read, Write};
29use std::net::SocketAddr;
30use std::sync::Arc;
31use tokio::sync::Mutex;
32
33/// Most control-channel plaintext held while waiting for the rest of a message.
34///
35/// The control channel is a byte stream, so a message can span TLS records and
36/// several `P_CONTROL_V1` packets and a prefix has to be buffered. Nothing else
37/// bounds that buffer: a peer that completes the TLS handshake - which needs no
38/// client certificate, so anyone can - could then stream indefinitely and this
39/// server would hold every byte, because after the key exchange the buffer is only
40/// drained at a NUL and a stream without one never drains.
41///
42/// A key-method-2 message is ~200 bytes and its longest field is capped at 4 KiB
43/// by `keymethod::MAX_STRING_LEN`; the control messages that follow it
44/// (`PUSH_REQUEST`, `RESTART`, ...) are a couple of dozen bytes. 64 KiB is far more
45/// than any of them and small enough that a hundred peers cannot matter.
46const MAX_PLAINTEXT_BUFFER: usize = 64 * 1024;
47
48/// Something that happened on a peer's control channel and that the server loop
49/// has to act on outside the session lock.
50#[derive(Debug)]
51pub enum SessionEvent {
52    /// The TLS handshake completed.
53    TlsEstablished { version: String, cipher: String },
54    /// The client sent its key material, options and credentials.
55    ClientKeyExchange(Box<ClientKeyMethod2>),
56    /// A NUL-terminated control message after the key exchange, e.g.
57    /// `PUSH_REQUEST`.
58    ControlMessage(String),
59    /// The TLS session cannot continue. The session is finished; any alert
60    /// rustls produced is still transmitted.
61    TlsFailed(String),
62}
63
64/// The control channel of one peer.
65pub struct ControlSession {
66    pub connection_id: ConnectionId,
67    pub client_session_id: u64,
68    pub server_session_id: u64,
69    pub key_id: u8,
70
71    send: ReliableSender,
72    recv: ReliableReceiver,
73
74    tls: Option<rustls::ServerConnection>,
75    /// Set once, so "handshake done" is reported exactly once.
76    tls_reported: bool,
77    tls_dead: bool,
78
79    /// Control-channel plaintext read out of TLS and not yet consumed. The
80    /// control channel is a byte stream, so a message can span TLS records and
81    /// therefore several `P_CONTROL_V1` packets.
82    plaintext: Vec<u8>,
83    key_exchange_seen: bool,
84    /// Whether this server has written its own key-method-2 answer.
85    pub answered_key_exchange: bool,
86
87    pub bytes_sent: u64,
88    pub bytes_received: u64,
89}
90
91impl ControlSession {
92    /// Start a session and queue the `P_CONTROL_HARD_RESET_SERVER_V2` that
93    /// answers the client's reset.
94    ///
95    /// The reply goes through the reliability layer like any other control
96    /// packet, so it is retransmitted until the client acknowledges it instead
97    /// of relying on the client's own reset retransmissions to trigger a
98    /// re-send.
99    pub fn new(
100        connection_id: ConnectionId,
101        client_session_id: u64,
102        server_session_id: u64,
103        key_id: u8,
104        client_reset_packet_id: u32,
105        tls_config: Arc<rustls::ServerConfig>,
106    ) -> Result<Self> {
107        let tls = rustls::ServerConnection::new(tls_config)
108            .context("Failed to create the OpenVPN control-channel TLS session")?;
109
110        let mut send = ReliableSender::new();
111        send.queue(
112            Opcode::ControlHardResetServerV2,
113            vec![client_reset_packet_id],
114            Vec::new(),
115        );
116
117        Ok(ControlSession {
118            connection_id,
119            client_session_id,
120            server_session_id,
121            key_id,
122            send,
123            recv: ReliableReceiver::new(client_reset_packet_id.saturating_add(1)),
124            tls: Some(tls),
125            tls_reported: false,
126            tls_dead: false,
127            plaintext: Vec::new(),
128            key_exchange_seen: false,
129            answered_key_exchange: false,
130            bytes_sent: 0,
131            bytes_received: 0,
132        })
133    }
134
135    /// The client retransmitted its reset, so it never saw our reply. Put
136    /// everything in flight back on the wire.
137    pub fn on_client_reset_retransmit(&mut self) {
138        self.send.mark_all_due();
139    }
140
141    /// Process a `P_ACK_V1` from the peer.
142    pub fn on_ack_frame(&mut self, frame: &ControlFrame) {
143        self.send.on_ack(&frame.ack_packet_ids);
144    }
145
146    /// Process a `P_CONTROL_V1` (or any control frame carrying a packet id).
147    pub fn on_control_frame(&mut self, frame: ControlFrame) -> Vec<SessionEvent> {
148        self.send.on_ack(&frame.ack_packet_ids);
149        self.bytes_received = self
150            .bytes_received
151            .saturating_add(frame.payload.len() as u64);
152
153        let packet_id = match frame.packet_id {
154            Some(id) => id,
155            None => return Vec::new(),
156        };
157
158        let mut events = Vec::new();
159        for payload in self.recv.accept(packet_id, frame.payload) {
160            if payload.is_empty() {
161                // A control packet with no payload exists only to carry ACKs.
162                continue;
163            }
164            events.extend(self.feed_tls(&payload));
165        }
166        events
167    }
168
169    /// Push one control payload into the TLS session and harvest whatever it
170    /// produced.
171    fn feed_tls(&mut self, payload: &[u8]) -> Vec<SessionEvent> {
172        if self.tls_dead {
173            return Vec::new();
174        }
175        let tls = match self.tls.as_mut() {
176            Some(t) => t,
177            None => return Vec::new(),
178        };
179
180        let mut cursor = std::io::Cursor::new(payload);
181        while (cursor.position() as usize) < payload.len() {
182            match tls.read_tls(&mut cursor) {
183                Ok(0) => break,
184                Ok(_) => {}
185                Err(e) => {
186                    self.tls_dead = true;
187                    return vec![SessionEvent::TlsFailed(format!(
188                        "TLS record could not be buffered: {}",
189                        e
190                    ))];
191                }
192            }
193            if let Err(e) = tls.process_new_packets() {
194                // rustls has queued an alert describing the failure; leave the
195                // connection in place so `drain_datagrams` can still send it,
196                // but feed it nothing further.
197                self.tls_dead = true;
198                return vec![SessionEvent::TlsFailed(e.to_string())];
199            }
200        }
201
202        let mut events = Vec::new();
203
204        if !self.tls_reported && !tls.is_handshaking() {
205            self.tls_reported = true;
206            events.push(SessionEvent::TlsEstablished {
207                version: tls_channel::protocol_version_name(tls),
208                cipher: tls_channel::cipher_suite_name(tls),
209            });
210        }
211
212        // Drain application data. `WouldBlock` is rustls saying "nothing more
213        // right now", which is the normal exit, not a failure.
214        let mut chunk = [0u8; 4096];
215        loop {
216            match tls.reader().read(&mut chunk) {
217                Ok(0) => break,
218                Ok(n) => self.plaintext.extend_from_slice(&chunk[..n]),
219                Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
220                Err(e) => {
221                    self.tls_dead = true;
222                    events.push(SessionEvent::TlsFailed(format!(
223                        "control-channel plaintext read failed: {}",
224                        e
225                    )));
226                    return events;
227                }
228            }
229        }
230
231        events.extend(self.consume_plaintext());
232
233        // `consume_plaintext` has taken everything it could parse; whatever is left is an
234        // incomplete message. Past this size it is not one.
235        if self.plaintext.len() > MAX_PLAINTEXT_BUFFER {
236            self.tls_dead = true;
237            let held = self.plaintext.len();
238            self.plaintext.clear();
239            events.push(SessionEvent::TlsFailed(format!(
240                "peer sent {held} bytes of control-channel data without a complete message                  (limit {MAX_PLAINTEXT_BUFFER}); dropping the session rather than buffering                  without bound"
241            )));
242        }
243
244        events
245    }
246
247    /// Turn accumulated control-channel plaintext into events.
248    ///
249    /// The first message is always key method 2; everything after it is a
250    /// NUL-terminated ASCII control message (`PUSH_REQUEST`, `AUTH_FAILED`,
251    /// `RESTART`, …).
252    fn consume_plaintext(&mut self) -> Vec<SessionEvent> {
253        let mut events = Vec::new();
254        loop {
255            if !self.key_exchange_seen {
256                match keymethod::parse_client_key_method_2(&self.plaintext) {
257                    Ok(Some((msg, consumed))) => {
258                        self.plaintext.drain(..consumed);
259                        self.key_exchange_seen = true;
260                        events.push(SessionEvent::ClientKeyExchange(Box::new(msg)));
261                    }
262                    Ok(None) => break,
263                    Err(e) => {
264                        self.tls_dead = true;
265                        self.plaintext.clear();
266                        events.push(SessionEvent::TlsFailed(e.to_string()));
267                        break;
268                    }
269                }
270            } else if let Some(pos) = self.plaintext.iter().position(|b| *b == 0) {
271                let msg = String::from_utf8_lossy(&self.plaintext[..pos]).into_owned();
272                self.plaintext.drain(..=pos);
273                events.push(SessionEvent::ControlMessage(msg));
274            } else {
275                break;
276            }
277        }
278        events
279    }
280
281    /// Write the server's key-method-2 answer into the TLS session.
282    ///
283    /// The key material is fresh random bytes. Nothing is derived from it: the
284    /// data channel that would consume it does not exist, and inventing keys
285    /// nothing can use would be worse than not having them.
286    pub fn write_key_method_2_answer(&mut self, client_options: &str) -> Result<String> {
287        let tls = self
288            .tls
289            .as_mut()
290            .context("no TLS session on this control channel")?;
291
292        let random1: [u8; 32] = rand::random();
293        let random2: [u8; 32] = rand::random();
294        let options = keymethod::server_options_from_client(client_options);
295        let message = keymethod::build_server_key_method_2(&random1, &random2, &options);
296
297        tls.writer()
298            .write_all(&message)
299            .context("Failed to queue the key-method-2 answer on the control channel")?;
300        self.answered_key_exchange = true;
301        Ok(options)
302    }
303
304    /// Everything this session wants to put on the wire right now.
305    ///
306    /// Pending acknowledgements go first: a peer that is retransmitting needs to
307    /// hear that we have its packets before it needs anything we have to say.
308    pub fn drain_datagrams(&mut self, now: Instant) -> Vec<Vec<u8>> {
309        self.queue_tls_records();
310
311        let mut out = Vec::new();
312
313        while self.recv.has_pending_acks() {
314            let acks = self.recv.take_acks();
315            if acks.is_empty() {
316                break;
317            }
318            out.push(self.serialize(Opcode::AckV1, &acks, None, &[]));
319        }
320
321        for packet in self.send.take_due(now) {
322            out.push(self.serialize(
323                packet.opcode,
324                &packet.acks,
325                Some(packet.packet_id),
326                &packet.payload,
327            ));
328        }
329
330        self.bytes_sent = self
331            .bytes_sent
332            .saturating_add(out.iter().map(|d| d.len() as u64).sum::<u64>());
333        out
334    }
335
336    /// Move any TLS records rustls has produced into the reliability layer,
337    /// fragmented to fit a single `P_CONTROL_V1`.
338    fn queue_tls_records(&mut self) {
339        let tls = match self.tls.as_mut() {
340            Some(t) => t,
341            None => return,
342        };
343        if !tls.wants_write() {
344            return;
345        }
346
347        let mut records = Vec::new();
348        while tls.wants_write() {
349            match tls.write_tls(&mut records) {
350                Ok(0) => break,
351                Ok(_) => {}
352                // The sink is a `Vec`, which cannot fail; treat anything else as
353                // the session being over rather than looping forever.
354                Err(_) => break,
355            }
356        }
357
358        for chunk in fragment(&records) {
359            self.send.queue(Opcode::ControlV1, Vec::new(), chunk);
360        }
361    }
362
363    fn serialize(
364        &self,
365        opcode: Opcode,
366        acks: &[u32],
367        packet_id: Option<u32>,
368        payload: &[u8],
369    ) -> Vec<u8> {
370        ControlFrame {
371            opcode,
372            key_id: self.key_id,
373            session_id: self.server_session_id,
374            ack_packet_ids: acks.to_vec(),
375            // The peer session id is on the wire only when the ACK array is
376            // non-empty; `ControlFrame::serialize` enforces the same rule.
377            remote_session_id: if acks.is_empty() {
378                None
379            } else {
380                Some(self.client_session_id)
381            },
382            packet_id,
383            payload: payload.to_vec(),
384        }
385        .serialize()
386        .to_vec()
387    }
388
389    /// True once a control packet has been retransmitted to exhaustion: the peer
390    /// has stopped listening.
391    pub fn is_dead(&self) -> bool {
392        self.send.is_exhausted()
393    }
394}
395
396/// The control sessions of every peer this server is answering.
397pub struct SessionManager {
398    sessions: Mutex<HashMap<SocketAddr, ControlSession>>,
399}
400
401impl SessionManager {
402    pub fn new() -> Self {
403        SessionManager {
404            sessions: Mutex::new(HashMap::new()),
405        }
406    }
407
408    pub async fn insert(&self, addr: SocketAddr, session: ControlSession) {
409        self.sessions.lock().await.insert(addr, session);
410    }
411
412    pub async fn remove(&self, addr: &SocketAddr) -> bool {
413        self.sessions.lock().await.remove(addr).is_some()
414    }
415
416    /// Borrow one session for the duration of a **synchronous** closure.
417    ///
418    /// The closure cannot await, which is the point: the guard is dropped before
419    /// the caller touches the socket or the LLM.
420    pub async fn with<F, T>(&self, addr: &SocketAddr, f: F) -> Option<T>
421    where
422        F: FnOnce(&mut ControlSession) -> T,
423    {
424        self.sessions.lock().await.get_mut(addr).map(f)
425    }
426
427    /// Collect the datagrams every session wants to send, and the addresses of
428    /// sessions that have given up on their peer.
429    pub async fn drain_all(&self, now: Instant) -> (Vec<(SocketAddr, Vec<u8>)>, Vec<SocketAddr>) {
430        let mut out = Vec::new();
431        let mut dead = Vec::new();
432        let mut guard = self.sessions.lock().await;
433        for (addr, session) in guard.iter_mut() {
434            if session.is_dead() {
435                dead.push(*addr);
436                continue;
437            }
438            for datagram in session.drain_datagrams(now) {
439                out.push((*addr, datagram));
440            }
441        }
442        (out, dead)
443    }
444}
445
446impl Default for SessionManager {
447    fn default() -> Self {
448        Self::new()
449    }
450}