1use std::collections::VecDeque;
4use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, UdpSocket};
5
6use log::{debug, error, info};
7
8use crate::packet::{AllowedPackets, Packet};
9use crate::replay::ReplayProtection;
10use crate::token::{
11 self, CHALLENGE_TOKEN_BYTES, CONNECT_TOKEN_PRIVATE_BYTES, ChallengeToken, PrivateConnectToken,
12};
13use crate::{
14 Error, KEY_BYTES, Key, MAC_BYTES, MAX_CLIENTS, MAX_PACKET_BYTES, MAX_PAYLOAD_BYTES,
15 NUM_DISCONNECT_PACKETS, PACKET_QUEUE_SIZE, PACKET_SEND_RATE, USER_DATA_BYTES, UserData, crypto,
16 socket,
17};
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub enum DisconnectReason {
22 TimedOut,
24 ClientDisconnect,
26 ServerDisconnect,
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32pub enum ServerEvent {
33 ClientConnected {
35 client_index: usize,
37 },
38 ClientDisconnected {
40 client_index: usize,
43 reason: DisconnectReason,
45 },
46}
47
48const MAX_ENCRYPTION_MAPPINGS: usize = MAX_CLIENTS * 4;
51
52struct EncryptionEntry {
57 address: Option<SocketAddr>,
58 timeout_seconds: i32,
59 expire_time: f64,
60 last_access_time: f64,
61 client_index: Option<usize>,
62 send_key: Key,
63 receive_key: Key,
64}
65
66impl EncryptionEntry {
67 fn new() -> Self {
68 Self {
69 address: None,
70 timeout_seconds: 0,
71 expire_time: -1.0,
72 last_access_time: -1000.0,
73 client_index: None,
74 send_key: [0; KEY_BYTES],
75 receive_key: [0; KEY_BYTES],
76 }
77 }
78
79 fn expired(&self, time: f64) -> bool {
80 (self.timeout_seconds > 0 && self.last_access_time + (self.timeout_seconds as f64) < time)
81 || (self.expire_time >= 0.0 && self.expire_time < time)
82 }
83}
84
85struct EncryptionManager {
86 entries: Vec<EncryptionEntry>,
87 num_entries: usize,
89}
90
91impl EncryptionManager {
92 fn new() -> Self {
93 Self {
94 entries: (0..MAX_ENCRYPTION_MAPPINGS).map(|_| EncryptionEntry::new()).collect(),
95 num_entries: 0,
96 }
97 }
98
99 fn reset(&mut self) {
100 debug!("reset encryption manager");
101 *self = Self::new();
102 }
103
104 #[allow(clippy::too_many_arguments)]
105 fn add_encryption_mapping(
106 &mut self,
107 address: SocketAddr,
108 send_key: &Key,
109 receive_key: &Key,
110 time: f64,
111 expire_time: f64,
112 timeout_seconds: i32,
113 ) -> bool {
114 for index in 0..self.num_entries {
115 let entry = &mut self.entries[index];
116 if entry.address == Some(address) && !entry.expired(time) {
117 entry.timeout_seconds = timeout_seconds;
118 entry.expire_time = expire_time;
119 entry.last_access_time = time;
120 entry.send_key = *send_key;
121 entry.receive_key = *receive_key;
122 return true;
123 }
124 }
125
126 for index in 0..MAX_ENCRYPTION_MAPPINGS {
127 let entry = &mut self.entries[index];
128 if entry.address.is_none() || (entry.expired(time) && entry.client_index.is_none()) {
129 *entry = EncryptionEntry {
130 address: Some(address),
131 timeout_seconds,
132 expire_time,
133 last_access_time: time,
134 client_index: None,
135 send_key: *send_key,
136 receive_key: *receive_key,
137 };
138 if index + 1 > self.num_entries {
139 self.num_entries = index + 1;
140 }
141 return true;
142 }
143 }
144
145 false
146 }
147
148 fn remove_encryption_mapping(&mut self, address: SocketAddr, time: f64) -> bool {
149 for index in 0..self.num_entries {
150 if self.entries[index].address != Some(address) {
151 continue;
152 }
153
154 self.entries[index] = EncryptionEntry::new();
155
156 if index + 1 == self.num_entries {
158 let mut last = index;
159 while last > 0 {
160 let entry = &self.entries[last - 1];
161 if !entry.expired(time) || entry.client_index.is_some() {
162 break;
163 }
164 self.entries[last - 1].address = None;
165 last -= 1;
166 }
167 self.num_entries = last;
168 }
169
170 return true;
171 }
172
173 false
174 }
175
176 fn find_encryption_mapping(&mut self, address: SocketAddr, time: f64) -> Option<usize> {
177 for index in 0..self.num_entries {
178 let entry = &mut self.entries[index];
179 if entry.address == Some(address) && !entry.expired(time) {
180 entry.last_access_time = time;
181 return Some(index);
182 }
183 }
184 None
185 }
186
187 fn touch(&mut self, index: usize, address: SocketAddr, time: f64) -> bool {
188 if self.entries[index].address != Some(address) {
189 return false;
190 }
191 self.entries[index].last_access_time = time;
192 true
193 }
194
195 fn set_expire_time(&mut self, index: usize, expire_time: f64) {
196 self.entries[index].expire_time = expire_time;
197 }
198
199 fn set_client_index(&mut self, index: usize, client_index: Option<usize>) {
200 self.entries[index].client_index = client_index;
201 }
202
203 fn send_key(&self, index: usize) -> Key {
204 self.entries[index].send_key
205 }
206
207 fn receive_key(&self, index: usize) -> Key {
208 self.entries[index].receive_key
209 }
210
211 fn timeout(&self, index: usize) -> i32 {
212 self.entries[index].timeout_seconds
213 }
214}
215
216const MAX_CONNECT_TOKEN_ENTRIES: usize = MAX_CLIENTS * 8;
219
220struct ConnectTokenEntry {
223 time: f64,
224 mac: [u8; MAC_BYTES],
225 address: Option<SocketAddr>,
226}
227
228fn reset_connect_token_entries(entries: &mut Vec<ConnectTokenEntry>) {
229 entries.clear();
230 entries.extend((0..MAX_CONNECT_TOKEN_ENTRIES).map(|_| ConnectTokenEntry {
231 time: -1000.0,
232 mac: [0; MAC_BYTES],
233 address: None,
234 }));
235}
236
237fn find_or_add_connect_token_entry(
240 entries: &mut [ConnectTokenEntry],
241 address: SocketAddr,
242 mac: &[u8; MAC_BYTES],
243 time: f64,
244) -> bool {
245 let mut matching_index = None;
248 let mut oldest_index = 0;
249 let mut oldest_time = f64::MAX;
250
251 for (index, entry) in entries.iter().enumerate() {
252 if &entry.mac == mac {
253 matching_index = Some(index);
254 }
255 if entry.time < oldest_time {
256 oldest_time = entry.time;
257 oldest_index = index;
258 }
259 }
260
261 match matching_index {
262 None => {
264 entries[oldest_index] = ConnectTokenEntry { time, mac: *mac, address: Some(address) };
265 true
266 }
267 Some(index) => entries[index].address == Some(address),
269 }
270}
271
272struct ClientSlot {
275 connected: bool,
276 confirmed: bool,
277 client_id: u64,
278 timeout_seconds: i32,
279 encryption_index: Option<usize>,
280 address: Option<SocketAddr>,
281 sequence: u64,
282 last_packet_send_time: f64,
283 last_packet_receive_time: f64,
284 user_data: UserData,
285 replay_protection: ReplayProtection,
286 packet_queue: VecDeque<(Vec<u8>, u64)>,
287}
288
289impl ClientSlot {
290 fn new() -> Self {
291 Self {
292 connected: false,
293 confirmed: false,
294 client_id: 0,
295 timeout_seconds: 0,
296 encryption_index: None,
297 address: None,
298 sequence: 0,
299 last_packet_send_time: 0.0,
300 last_packet_receive_time: 0.0,
301 user_data: [0; USER_DATA_BYTES],
302 replay_protection: ReplayProtection::new(),
303 packet_queue: VecDeque::new(),
304 }
305 }
306}
307
308pub struct Server {
315 protocol_id: u64,
316 private_key: Key,
317 socket: UdpSocket,
318 public_address: SocketAddr,
319 time: f64,
320 running: bool,
321 max_clients: usize,
322 num_connected_clients: usize,
323 global_sequence: u64,
324 challenge_sequence: u64,
325 challenge_key: Key,
326 clients: Vec<ClientSlot>,
327 connect_token_entries: Vec<ConnectTokenEntry>,
328 encryption_manager: EncryptionManager,
329 events: VecDeque<ServerEvent>,
330}
331
332impl Server {
333 pub fn new(
342 public_address: SocketAddr,
343 protocol_id: u64,
344 private_key: &Key,
345 time: f64,
346 ) -> Result<Self, Error> {
347 let bind_address: SocketAddr = match public_address {
348 SocketAddr::V4(_) => (Ipv4Addr::UNSPECIFIED, public_address.port()).into(),
349 SocketAddr::V6(_) => (Ipv6Addr::UNSPECIFIED, public_address.port()).into(),
350 };
351 let socket = socket::create_socket(bind_address)?;
352
353 let mut public_address = public_address;
354 if public_address.port() == 0 {
355 public_address.set_port(socket.local_addr()?.port());
356 }
357
358 info!("server listening on {public_address}");
359
360 let mut connect_token_entries = Vec::new();
361 reset_connect_token_entries(&mut connect_token_entries);
362
363 Ok(Self {
364 protocol_id,
365 private_key: *private_key,
366 socket,
367 public_address,
368 time,
369 running: false,
370 max_clients: 0,
371 num_connected_clients: 0,
372 global_sequence: 1 << 63,
373 challenge_sequence: 0,
374 challenge_key: [0; KEY_BYTES],
375 clients: Vec::new(),
376 connect_token_entries,
377 encryption_manager: EncryptionManager::new(),
378 events: VecDeque::new(),
379 })
380 }
381
382 pub fn start(&mut self, max_clients: usize) -> Result<(), Error> {
385 if max_clients == 0 || max_clients > MAX_CLIENTS {
386 return Err(Error::InvalidMaxClients(max_clients));
387 }
388
389 if self.running {
390 self.stop();
391 }
392
393 info!("server started with {max_clients} client slots");
394
395 self.running = true;
396 self.max_clients = max_clients;
397 self.num_connected_clients = 0;
398 self.challenge_sequence = 0;
399 self.challenge_key = crypto::generate_key();
400 self.global_sequence = 1 << 63;
405 self.clients = (0..max_clients).map(|_| ClientSlot::new()).collect();
406
407 Ok(())
408 }
409
410 pub fn stop(&mut self) {
412 if !self.running {
413 return;
414 }
415
416 self.disconnect_all_clients();
417
418 self.running = false;
419 self.max_clients = 0;
420 self.num_connected_clients = 0;
421 self.global_sequence = 1 << 63;
422 self.challenge_sequence = 0;
423 self.challenge_key = [0; KEY_BYTES];
424 self.clients.clear();
425
426 reset_connect_token_entries(&mut self.connect_token_entries);
427 self.encryption_manager.reset();
428
429 info!("server stopped");
430 }
431
432 pub fn update(&mut self, time: f64) {
435 self.time = time;
436 self.receive_packets();
437 self.send_packets();
438 self.check_for_timeouts();
439 }
440
441 pub fn next_event(&mut self) -> Option<ServerEvent> {
443 self.events.pop_front()
444 }
445
446 pub fn send_packet(&mut self, client_index: usize, payload: &[u8]) -> Result<(), Error> {
449 if payload.is_empty() || payload.len() > MAX_PAYLOAD_BYTES {
450 return Err(Error::InvalidPayloadSize(payload.len()));
451 }
452
453 if !self.running
454 || client_index >= self.max_clients
455 || !self.clients[client_index].connected
456 {
457 return Ok(());
458 }
459
460 if !self.clients[client_index].confirmed {
463 let keep_alive = Packet::KeepAlive {
464 client_index: client_index as u32,
465 max_clients: self.max_clients as u32,
466 };
467 self.send_client_packet(&keep_alive, client_index);
468 }
469
470 self.send_client_packet(&Packet::Payload(payload.to_vec()), client_index);
471
472 Ok(())
473 }
474
475 pub fn receive_packet(&mut self, client_index: usize) -> Option<(Vec<u8>, u64)> {
478 if !self.running || client_index >= self.max_clients {
479 return None;
480 }
481 self.clients[client_index].packet_queue.pop_front()
482 }
483
484 pub fn disconnect_client(&mut self, client_index: usize) {
487 if !self.running
488 || client_index >= self.max_clients
489 || !self.clients[client_index].connected
490 {
491 return;
492 }
493 self.disconnect_client_internal(client_index, true, DisconnectReason::ServerDisconnect);
494 }
495
496 pub fn disconnect_all_clients(&mut self) {
498 if !self.running {
499 return;
500 }
501 for client_index in 0..self.max_clients {
502 if self.clients[client_index].connected {
503 self.disconnect_client_internal(
504 client_index,
505 true,
506 DisconnectReason::ServerDisconnect,
507 );
508 }
509 }
510 }
511
512 pub fn running(&self) -> bool {
514 self.running
515 }
516
517 pub fn max_clients(&self) -> usize {
519 self.max_clients
520 }
521
522 pub fn num_connected_clients(&self) -> usize {
524 self.num_connected_clients
525 }
526
527 pub fn client_connected(&self, client_index: usize) -> bool {
529 self.running && client_index < self.max_clients && self.clients[client_index].connected
530 }
531
532 pub fn client_id(&self, client_index: usize) -> u64 {
534 if !self.client_connected(client_index) {
535 return 0;
536 }
537 self.clients[client_index].client_id
538 }
539
540 pub fn client_address(&self, client_index: usize) -> Option<SocketAddr> {
542 if !self.client_connected(client_index) {
543 return None;
544 }
545 self.clients[client_index].address
546 }
547
548 pub fn client_user_data(&self, client_index: usize) -> Option<&UserData> {
550 if !self.client_connected(client_index) {
551 return None;
552 }
553 Some(&self.clients[client_index].user_data)
554 }
555
556 pub fn next_packet_sequence(&self, client_index: usize) -> u64 {
559 if !self.client_connected(client_index) {
560 return 0;
561 }
562 self.clients[client_index].sequence
563 }
564
565 pub fn port(&self) -> u16 {
567 self.public_address.port()
568 }
569
570 pub fn address(&self) -> SocketAddr {
572 self.public_address
573 }
574
575 fn find_client_index_by_address(&self, address: SocketAddr) -> Option<usize> {
578 self.clients[..self.max_clients]
579 .iter()
580 .position(|client| client.connected && client.address == Some(address))
581 }
582
583 fn find_client_index_by_id(&self, client_id: u64) -> Option<usize> {
584 self.clients[..self.max_clients]
585 .iter()
586 .position(|client| client.connected && client.client_id == client_id)
587 }
588
589 fn find_free_client_index(&self) -> Option<usize> {
590 self.clients[..self.max_clients].iter().position(|client| !client.connected)
591 }
592
593 fn receive_packets(&mut self) {
594 let current_timestamp = token::unix_timestamp();
595 let mut packet_data = [0u8; MAX_PACKET_BYTES];
596 while let Some((packet_bytes, from)) =
597 socket::receive_packet(&self.socket, &mut packet_data)
598 {
599 self.read_and_process_packet(from, &mut packet_data[..packet_bytes], current_timestamp);
600 }
601 }
602
603 fn read_and_process_packet(
604 &mut self,
605 from: SocketAddr,
606 packet_data: &mut [u8],
607 current_timestamp: u64,
608 ) {
609 if !self.running || packet_data.len() <= 1 {
610 return;
611 }
612
613 let client_index = self.find_client_index_by_address(from);
614 let encryption_index = match client_index {
615 Some(client_index) => self.clients[client_index].encryption_index,
616 None => self.encryption_manager.find_encryption_mapping(from, self.time),
617 };
618
619 let read_packet_key = encryption_index
620 .map(|encryption_index| self.encryption_manager.receive_key(encryption_index));
621
622 if read_packet_key.is_none() && packet_data[0] != 0 {
623 debug!(
624 "server could not process packet because no encryption mapping exists for {from}"
625 );
626 return;
627 }
628
629 let protocol_id = self.protocol_id;
630 let private_key = self.private_key;
631 let replay_protection =
632 client_index.map(|client_index| &mut self.clients[client_index].replay_protection);
633
634 let Some((packet, sequence)) = crate::packet::read_packet(
635 packet_data,
636 read_packet_key.as_ref(),
637 protocol_id,
638 current_timestamp,
639 Some(&private_key),
640 AllowedPackets::SERVER,
641 replay_protection,
642 ) else {
643 return;
644 };
645
646 self.process_packet(from, packet, sequence, encryption_index, client_index);
647 }
648
649 fn process_packet(
650 &mut self,
651 from: SocketAddr,
652 packet: Packet,
653 sequence: u64,
654 encryption_index: Option<usize>,
655 client_index: Option<usize>,
656 ) {
657 match packet {
658 Packet::Request { private_data, .. } => {
659 debug!("server received connection request from {from}");
660 self.process_connection_request(from, &private_data);
661 }
662
663 Packet::Response { challenge_token_sequence, challenge_token_data } => {
664 debug!("server received connection response from {from}");
665 self.process_connection_response(
666 from,
667 challenge_token_sequence,
668 challenge_token_data,
669 encryption_index,
670 );
671 }
672
673 Packet::KeepAlive { .. } => {
674 if let Some(client_index) = client_index {
675 debug!(
676 "server received connection keep alive packet from client {client_index}"
677 );
678 self.touch_client(client_index);
679 }
680 }
681
682 Packet::Payload(payload) => {
683 if let Some(client_index) = client_index {
684 debug!("server received connection payload packet from client {client_index}");
685 self.touch_client(client_index);
686 let queue = &mut self.clients[client_index].packet_queue;
687 if queue.len() < PACKET_QUEUE_SIZE {
688 queue.push_back((payload, sequence));
689 }
690 }
691 }
692
693 Packet::Disconnect => {
694 if let Some(client_index) = client_index {
695 debug!("server received disconnect packet from client {client_index}");
696 self.disconnect_client_internal(
697 client_index,
698 false,
699 DisconnectReason::ClientDisconnect,
700 );
701 }
702 }
703
704 Packet::Denied | Packet::Challenge { .. } => unreachable!(),
705 }
706 }
707
708 fn touch_client(&mut self, client_index: usize) {
710 let client = &mut self.clients[client_index];
711 client.last_packet_receive_time = self.time;
712 if !client.confirmed {
713 debug!("server confirmed connection with client {client_index}");
714 client.confirmed = true;
715 }
716 }
717
718 fn process_connection_request(
722 &mut self,
723 from: SocketAddr,
724 private_data: &[u8; CONNECT_TOKEN_PRIVATE_BYTES],
725 ) {
726 let Ok(private_token) = PrivateConnectToken::read(&private_data[..]) else {
727 debug!("server ignored connection request. failed to read connect token");
728 return;
729 };
730
731 if !private_token.server_addresses.contains(&self.public_address) {
732 debug!(
733 "server ignored connection request. server address not in connect token whitelist"
734 );
735 return;
736 }
737
738 if self.find_client_index_by_address(from).is_some() {
739 debug!(
740 "server ignored connection request. a client with this address is already connected"
741 );
742 return;
743 }
744
745 if self.find_client_index_by_id(private_token.client_id).is_some() {
746 debug!("server ignored connection request. a client with this id is already connected");
747 return;
748 }
749
750 let mac: [u8; MAC_BYTES] =
751 private_data[CONNECT_TOKEN_PRIVATE_BYTES - MAC_BYTES..].try_into().unwrap();
752 if !find_or_add_connect_token_entry(&mut self.connect_token_entries, from, &mac, self.time)
753 {
754 debug!("server ignored connection request. connect token has already been used");
755 return;
756 }
757
758 if self.num_connected_clients == self.max_clients {
759 debug!("server denied connection request. server is full");
760 self.send_global_packet(&Packet::Denied, from, &private_token.server_to_client_key);
761 return;
762 }
763
764 let expire_time = if private_token.timeout_seconds >= 0 {
765 self.time + private_token.timeout_seconds as f64
766 } else {
767 -1.0
768 };
769
770 if !self.encryption_manager.add_encryption_mapping(
771 from,
772 &private_token.server_to_client_key,
773 &private_token.client_to_server_key,
774 self.time,
775 expire_time,
776 private_token.timeout_seconds,
777 ) {
778 debug!("server ignored connection request. failed to add encryption mapping");
779 return;
780 }
781
782 let challenge_token = ChallengeToken {
783 client_id: private_token.client_id,
784 user_data: private_token.user_data,
785 };
786 let mut challenge_token_data = [0u8; CHALLENGE_TOKEN_BYTES];
787 challenge_token.write(&mut challenge_token_data);
788 if token::encrypt_challenge_token(
789 &mut challenge_token_data,
790 self.challenge_sequence,
791 &self.challenge_key,
792 )
793 .is_err()
794 {
795 debug!("server ignored connection request. failed to encrypt challenge token");
796 return;
797 }
798
799 let challenge_packet = Packet::Challenge {
800 challenge_token_sequence: self.challenge_sequence,
801 challenge_token_data,
802 };
803 self.challenge_sequence += 1;
804
805 debug!("server sent connection challenge packet");
806 self.send_global_packet(&challenge_packet, from, &private_token.server_to_client_key);
807 }
808
809 fn process_connection_response(
810 &mut self,
811 from: SocketAddr,
812 challenge_token_sequence: u64,
813 mut challenge_token_data: [u8; CHALLENGE_TOKEN_BYTES],
814 encryption_index: Option<usize>,
815 ) {
816 if token::decrypt_challenge_token(
817 &mut challenge_token_data,
818 challenge_token_sequence,
819 &self.challenge_key,
820 )
821 .is_err()
822 {
823 debug!("server ignored connection response. failed to decrypt challenge token");
824 return;
825 }
826
827 let challenge_token = ChallengeToken::read(&challenge_token_data);
828
829 let Some(encryption_index) = encryption_index else {
830 debug!("server ignored connection response. no packet send key");
831 return;
832 };
833
834 if self.find_client_index_by_address(from).is_some() {
835 debug!(
836 "server ignored connection response. a client with this address is already connected"
837 );
838 return;
839 }
840
841 if self.find_client_index_by_id(challenge_token.client_id).is_some() {
842 debug!(
843 "server ignored connection response. a client with this id is already connected"
844 );
845 return;
846 }
847
848 if self.num_connected_clients == self.max_clients {
849 debug!("server denied connection response. server is full");
850 let send_key = self.encryption_manager.send_key(encryption_index);
851 self.send_global_packet(&Packet::Denied, from, &send_key);
852 return;
853 }
854
855 let client_index = self.find_free_client_index().expect("server is not full");
856 let timeout_seconds = self.encryption_manager.timeout(encryption_index);
857 self.connect_client(
858 client_index,
859 from,
860 challenge_token.client_id,
861 encryption_index,
862 timeout_seconds,
863 &challenge_token.user_data,
864 );
865 }
866
867 #[allow(clippy::too_many_arguments)]
868 fn connect_client(
869 &mut self,
870 client_index: usize,
871 address: SocketAddr,
872 client_id: u64,
873 encryption_index: usize,
874 timeout_seconds: i32,
875 user_data: &UserData,
876 ) {
877 self.num_connected_clients += 1;
878 debug_assert!(self.num_connected_clients <= self.max_clients);
879
880 self.encryption_manager.set_expire_time(encryption_index, -1.0);
883 self.encryption_manager.set_client_index(encryption_index, Some(client_index));
884
885 let client = &mut self.clients[client_index];
886 debug_assert!(!client.connected);
887 client.connected = true;
888 client.confirmed = false;
889 client.client_id = client_id;
890 client.timeout_seconds = timeout_seconds;
891 client.encryption_index = Some(encryption_index);
892 client.address = Some(address);
893 client.sequence = 0;
894 client.last_packet_send_time = self.time;
895 client.last_packet_receive_time = self.time;
896 client.user_data = *user_data;
897
898 info!("server accepted client {address} {client_id:016x} in slot {client_index}");
899
900 let packet = Packet::KeepAlive {
901 client_index: client_index as u32,
902 max_clients: self.max_clients as u32,
903 };
904 self.send_client_packet(&packet, client_index);
905
906 self.events.push_back(ServerEvent::ClientConnected { client_index });
907 }
908
909 fn disconnect_client_internal(
910 &mut self,
911 client_index: usize,
912 send_disconnect_packets: bool,
913 reason: DisconnectReason,
914 ) {
915 debug_assert!(self.running);
916 debug_assert!(self.clients[client_index].connected);
917
918 info!("server disconnected client {client_index}");
919
920 self.events.push_back(ServerEvent::ClientDisconnected { client_index, reason });
921
922 if send_disconnect_packets {
923 debug!("server sent disconnect packets to client {client_index}");
924 for _ in 0..NUM_DISCONNECT_PACKETS {
925 self.send_client_packet(&Packet::Disconnect, client_index);
926 }
927 }
928
929 self.clients[client_index].replay_protection.reset();
930
931 if let Some(encryption_index) = self.clients[client_index].encryption_index {
932 self.encryption_manager.set_client_index(encryption_index, None);
933 }
934 if let Some(address) = self.clients[client_index].address {
935 self.encryption_manager.remove_encryption_mapping(address, self.time);
936 }
937
938 self.clients[client_index] = ClientSlot::new();
939 self.num_connected_clients -= 1;
940 }
941
942 fn send_global_packet(&mut self, packet: &Packet, to: SocketAddr, packet_key: &Key) {
945 let mut packet_data = [0u8; MAX_PACKET_BYTES];
946 let Ok(packet_bytes) = crate::packet::write_packet(
947 packet,
948 &mut packet_data,
949 self.global_sequence,
950 packet_key,
951 self.protocol_id,
952 ) else {
953 return;
954 };
955 let _ = self.socket.send_to(&packet_data[..packet_bytes], to);
956 self.global_sequence += 1;
957 }
958
959 fn send_client_packet(&mut self, packet: &Packet, client_index: usize) {
960 let client = &self.clients[client_index];
961 debug_assert!(client.connected);
962 let (Some(encryption_index), Some(address)) = (client.encryption_index, client.address)
963 else {
964 return;
965 };
966
967 if !self.encryption_manager.touch(encryption_index, address, self.time) {
968 error!("encryption mapping is out of date for client {client_index}");
969 return;
970 }
971
972 let packet_key = self.encryption_manager.send_key(encryption_index);
973
974 let mut packet_data = [0u8; MAX_PACKET_BYTES];
975 let Ok(packet_bytes) = crate::packet::write_packet(
976 packet,
977 &mut packet_data,
978 self.clients[client_index].sequence,
979 &packet_key,
980 self.protocol_id,
981 ) else {
982 return;
983 };
984 let _ = self.socket.send_to(&packet_data[..packet_bytes], address);
985
986 let client = &mut self.clients[client_index];
987 client.sequence += 1;
988 client.last_packet_send_time = self.time;
989 }
990
991 fn send_packets(&mut self) {
992 if !self.running {
993 return;
994 }
995
996 for client_index in 0..self.max_clients {
997 let client = &self.clients[client_index];
998 if client.connected
999 && client.last_packet_send_time + 1.0 / PACKET_SEND_RATE <= self.time
1000 {
1001 debug!("server sent connection keep alive packet to client {client_index}");
1002 let packet = Packet::KeepAlive {
1003 client_index: client_index as u32,
1004 max_clients: self.max_clients as u32,
1005 };
1006 self.send_client_packet(&packet, client_index);
1007 }
1008 }
1009 }
1010
1011 fn check_for_timeouts(&mut self) {
1012 if !self.running {
1013 return;
1014 }
1015
1016 for client_index in 0..self.max_clients {
1017 let client = &self.clients[client_index];
1018 if client.connected
1019 && client.timeout_seconds > 0
1020 && client.last_packet_receive_time + client.timeout_seconds as f64 <= self.time
1021 {
1022 info!("server timed out client {client_index}");
1023 self.disconnect_client_internal(client_index, false, DisconnectReason::TimedOut);
1024 }
1025 }
1026 }
1027}
1028
1029impl Drop for Server {
1030 fn drop(&mut self) {
1031 self.stop();
1032 }
1033}
1034
1035#[cfg(test)]
1036mod tests {
1037 use super::*;
1038
1039 fn test_address(port: u16) -> SocketAddr {
1040 format!("127.0.0.1:{port}").parse().unwrap()
1041 }
1042
1043 #[test]
1044 fn encryption_manager_add_find_remove() {
1045 let mut manager = EncryptionManager::new();
1046 let time = 100.0;
1047
1048 let send_key = crypto::generate_key();
1049 let receive_key = crypto::generate_key();
1050
1051 for port in 0..5u16 {
1052 assert!(manager.add_encryption_mapping(
1053 test_address(40000 + port),
1054 &send_key,
1055 &receive_key,
1056 time,
1057 time + 5.0,
1058 5,
1059 ));
1060 }
1061
1062 for port in 0..5u16 {
1063 let index = manager.find_encryption_mapping(test_address(40000 + port), time).unwrap();
1064 assert_eq!(manager.send_key(index), send_key);
1065 assert_eq!(manager.receive_key(index), receive_key);
1066 }
1067 assert!(manager.find_encryption_mapping(test_address(50000), time).is_none());
1068
1069 assert!(manager.remove_encryption_mapping(test_address(40002), time));
1070 assert!(manager.find_encryption_mapping(test_address(40002), time).is_none());
1071 assert!(!manager.remove_encryption_mapping(test_address(40002), time));
1072
1073 assert!(manager.find_encryption_mapping(test_address(40000), time + 10.0).is_none());
1075 }
1076
1077 #[test]
1078 fn encryption_manager_expire_time() {
1079 let mut manager = EncryptionManager::new();
1080 let send_key = crypto::generate_key();
1081 let receive_key = crypto::generate_key();
1082
1083 assert!(manager.add_encryption_mapping(
1085 test_address(40000),
1086 &send_key,
1087 &receive_key,
1088 100.0,
1089 105.0,
1090 -1,
1091 ));
1092 assert!(manager.find_encryption_mapping(test_address(40000), 104.0).is_some());
1093 assert!(manager.find_encryption_mapping(test_address(40000), 106.0).is_none());
1094 }
1095
1096 #[test]
1097 fn connect_token_entries_reject_reuse_from_different_address() {
1098 let mut entries = Vec::new();
1099 reset_connect_token_entries(&mut entries);
1100
1101 let mac = [0x42u8; MAC_BYTES];
1102
1103 assert!(find_or_add_connect_token_entry(&mut entries, test_address(40000), &mac, 0.0));
1105 assert!(find_or_add_connect_token_entry(&mut entries, test_address(40000), &mac, 1.0));
1107 assert!(!find_or_add_connect_token_entry(&mut entries, test_address(40001), &mac, 2.0));
1109 }
1110}