1use std::collections::HashMap;
2use std::{net::SocketAddr, sync::Arc};
3use tokio::net::UdpSocket;
4use tokio::sync::mpsc::channel;
5use tokio::sync::mpsc::{Receiver, Sender};
6use tokio::sync::{Mutex, Notify, watch};
7
8use crate::error::{RaknetError, Result};
9use crate::packet::*;
10use crate::utils::*;
11use crate::{raknet_log_debug, raknet_log_error, socket::*};
12
13const SERVER_NAME: &str = "Rust Raknet Server";
14const MAX_CONNECTION: u32 = 99999;
15
16struct SessionSender {
17 sender: Sender<Vec<u8>>,
18 close: Arc<tokio::sync::Semaphore>,
19 guid: u64,
20 mtu: u16,
21}
22
23struct SessionDispatchCache {
27 entries: Vec<Option<CachedSession>>,
28}
29
30struct CachedSession {
31 address: SocketAddr,
32 sender: Sender<Vec<u8>>,
33 close: Arc<tokio::sync::Semaphore>,
34}
35
36impl Default for SessionDispatchCache {
37 fn default() -> Self {
38 Self {
39 entries: std::iter::repeat_with(|| None).take(Self::LIMIT).collect(),
40 }
41 }
42}
43
44impl SessionDispatchCache {
45 const LIMIT: usize = 4096;
46
47 fn slot(address: &SocketAddr) -> usize {
48 usize::from(address.port()) % Self::LIMIT
49 }
50
51 fn sender(&self, address: &SocketAddr) -> Option<&Sender<Vec<u8>>> {
52 self.entries[Self::slot(address)]
53 .as_ref()
54 .filter(|entry| {
55 entry.address == *address && !entry.close.is_closed() && !entry.sender.is_closed()
56 })
57 .map(|entry| &entry.sender)
58 }
59
60 fn remember(&mut self, address: SocketAddr, session: &SessionSender) {
61 self.entries[Self::slot(&address)] = Some(CachedSession {
62 address,
63 sender: session.sender.clone(),
64 close: session.close.clone(),
65 });
66 }
67
68 fn forget(&mut self, address: &SocketAddr) {
69 let slot = &mut self.entries[Self::slot(address)];
70 if slot.as_ref().is_some_and(|entry| entry.address == *address) {
71 *slot = None;
72 }
73 }
74
75 fn prune(&mut self) {
76 for slot in &mut self.entries {
77 if slot
78 .as_ref()
79 .is_some_and(|entry| entry.close.is_closed() || entry.sender.is_closed())
80 {
81 *slot = None;
82 }
83 }
84 }
85}
86
87pub struct RaknetListener {
89 motd: String,
90 shards: Vec<Self>,
91 socket: Option<Arc<UdpSocket>>,
92 guid: u64,
93 listened: bool,
94 maximum_mtu: u16,
95 connection_receiver: Receiver<RaknetSocket>,
96 connection_sender: Sender<RaknetSocket>,
97 sessions: Arc<Mutex<HashMap<SocketAddr, SessionSender>>>,
98 close_notifier: Arc<tokio::sync::Semaphore>,
99 all_session_closed_notifier: Arc<Notify>,
100 version_map: Arc<Mutex<HashMap<SocketAddr, u8>>>,
101 motd_receiver: watch::Receiver<String>,
102 motd_sender: watch::Sender<String>,
103}
104
105impl RaknetListener {
106 pub async fn bind(sockaddr: &SocketAddr) -> Result<Self> {
110 let socket =
111 std::net::UdpSocket::bind(sockaddr).map_err(|_| RaknetError::BindAddressError)?;
112 if let Err(error) = socket2::SockRef::from(&socket).set_recv_buffer_size(2 * 1024 * 1024) {
115 raknet_log_debug!("could not enlarge the listener receive buffer: {error}");
116 }
117 Self::from_std(socket).await
118 }
119
120 pub async fn bind_with_maximum_mtu(sockaddr: &SocketAddr, maximum_mtu: u16) -> Result<Self> {
126 if !(61..=RAKNET_MAX_MTU).contains(&maximum_mtu) {
127 return Err(RaknetError::PacketSizeExceedMTU);
128 }
129 let mut listener = Self::bind(sockaddr).await?;
130 listener.maximum_mtu = maximum_mtu;
131 Ok(listener)
132 }
133
134 #[cfg(target_os = "linux")]
142 pub async fn bind_with_socket_shards(
143 sockaddr: &SocketAddr,
144 count: std::num::NonZeroUsize,
145 ) -> Result<Self> {
146 if count.get() == 1 {
147 return Self::bind(sockaddr).await;
148 }
149 if count.get() > 64 {
150 return Err(RaknetError::SocketError);
151 }
152 fn bind_socket(address: &SocketAddr) -> Result<std::net::UdpSocket> {
153 let socket = socket2::Socket::new(
154 socket2::Domain::for_address(*address),
155 socket2::Type::DGRAM,
156 Some(socket2::Protocol::UDP),
157 )
158 .map_err(|_| RaknetError::BindAddressError)?;
159 socket
160 .set_reuse_port(true)
161 .map_err(|_| RaknetError::SocketError)?;
162 socket
163 .set_recv_buffer_size(2 * 1024 * 1024)
164 .map_err(|_| RaknetError::SocketError)?;
165 socket
166 .bind(&(*address).into())
167 .map_err(|_| RaknetError::BindAddressError)?;
168 Ok(socket.into())
169 }
170 let mut listener = Self::from_std(bind_socket(sockaddr)?).await?;
171 let address = listener.local_addr()?;
172 for _ in 1..count.get() {
173 let mut shard = Self::from_std(bind_socket(&address)?).await?;
174 shard.guid = listener.guid;
175 shard.connection_sender = listener.connection_sender.clone();
176 shard.motd_sender = listener.motd_sender.clone();
177 shard.motd_receiver = listener.motd_receiver.clone();
178 listener.shards.push(shard);
179 }
180 Ok(listener)
181 }
182
183 pub async fn bind_with_receive_buffer_size(
189 sockaddr: &SocketAddr,
190 size: std::num::NonZeroUsize,
191 ) -> Result<Self> {
192 if size.get() > i32::MAX as usize {
193 return Err(RaknetError::SocketError);
194 }
195 let socket =
196 std::net::UdpSocket::bind(sockaddr).map_err(|_| RaknetError::BindAddressError)?;
197 socket2::SockRef::from(&socket)
198 .set_recv_buffer_size(size.get())
199 .map_err(|_| RaknetError::SocketError)?;
200 Self::from_std(socket).await
201 }
202
203 pub fn with_accept_backlog(mut self, backlog: std::num::NonZeroUsize) -> Self {
211 assert!(
212 !self.listened,
213 "configure the accept backlog before listening"
214 );
215 let (sender, receiver) = channel(backlog.get());
216 for shard in &mut self.shards {
217 shard.connection_sender = sender.clone();
218 }
219 self.connection_sender = sender;
220 self.connection_receiver = receiver;
221 self
222 }
223
224 pub async fn from_std(socket: std::net::UdpSocket) -> Result<Self> {
226 socket
227 .set_nonblocking(true)
228 .map_err(|_| RaknetError::SetRaknetRawSocketError)?;
229 let socket =
230 UdpSocket::from_std(socket).map_err(|_| RaknetError::SetRaknetRawSocketError)?;
231 Self::from_udp_socket(socket).await
232 }
233
234 async fn from_udp_socket(socket: UdpSocket) -> Result<Self> {
235 let (connection_sender, connection_receiver) = channel::<RaknetSocket>(128);
236 let (motd_sender, motd_receiver) = watch::channel(String::new());
237 let listener = Self {
238 motd: String::new(),
239 shards: Vec::new(),
240 socket: Some(Arc::new(socket)),
241 guid: rand::random(),
242 listened: false,
243 maximum_mtu: RAKNET_CLIENT_MTU,
244 connection_receiver,
245 connection_sender,
246 sessions: Arc::new(Mutex::new(HashMap::new())),
247 close_notifier: Arc::new(tokio::sync::Semaphore::new(0)),
248 all_session_closed_notifier: Arc::new(Notify::new()),
249 version_map: Arc::new(Mutex::new(HashMap::new())),
250 motd_receiver,
251 motd_sender,
252 };
253
254 Ok(listener)
255 }
256
257 async fn start_session_collect(
258 &self,
259 socket: &Arc<UdpSocket>,
260 sessions: &Arc<Mutex<HashMap<SocketAddr, SessionSender>>>,
261 mut collect_receiver: Receiver<SocketAddr>,
262 ) {
263 let sessions = sessions.clone();
264 let version_map = self.version_map.clone();
265 let socket = socket.clone();
266 let close_notifier = self.close_notifier.clone();
267 let all_session_closed_notifier = self.all_session_closed_notifier.clone();
268 tokio::spawn(async move {
269 loop {
270 let addr: SocketAddr;
271
272 tokio::select! {
273 a = collect_receiver.recv() => {
274 match a {
275 Some(p) => { addr = p },
276 None => {
277 raknet_log_debug!("session collector closed");
278 break;
279 },
280 };
281 },
282 _ = close_notifier.acquire() => {
283 raknet_log_debug!("session collector received close notification");
284 break;
285 }
286 }
287
288 let mut sessions = sessions.lock().await;
289 if sessions
292 .get(&addr)
293 .is_some_and(|session| session.close.is_closed())
294 {
295 match socket.send_to(&[PacketID::Disconnect.to_u8()], addr).await {
296 Ok(_) => {}
297 Err(e) => {
298 raknet_log_error!("udp socket send_to error : {}", e);
299 }
300 };
301 sessions.remove(&addr);
302 version_map.lock().await.remove(&addr);
303 raknet_log_debug!("collect socket : {}", addr);
304 }
305 }
306
307 let mut sessions = sessions.lock().await;
308
309 for (addr, session) in sessions.iter() {
310 session.close.close();
311
312 match socket.send_to(&[PacketID::Disconnect.to_u8()], addr).await {
313 Ok(_) => {}
314 Err(e) => {
315 raknet_log_error!("udp socket send_to error : {}", e);
316 }
317 };
318 }
319
320 while !sessions.is_empty() {
321 let addr = match collect_receiver.recv().await {
322 Some(p) => p,
323 None => {
324 raknet_log_error!(
325 "failed to clean up sessions; some connections may still be open"
326 );
327 break;
328 }
329 };
330
331 if sessions.contains_key(&addr) {
332 match socket.send_to(&[PacketID::Disconnect.to_u8()], addr).await {
333 Ok(_) => {}
334 Err(e) => {
335 raknet_log_error!("udp socket send_to error : {}", e);
336 }
337 };
338 sessions.remove(&addr);
339 version_map.lock().await.remove(&addr);
340 raknet_log_debug!("collect socket : {}", addr);
341 }
342 }
343
344 sessions.clear();
345 version_map.lock().await.clear();
346 all_session_closed_notifier.notify_one();
347
348 raknet_log_debug!("session collect closed");
349 });
350 }
351
352 pub async fn listen(&mut self) {
356 if self.close_notifier.is_closed() || self.listened {
357 return;
358 }
359 for shard in &mut self.shards {
360 shard.motd = self.motd.clone();
363 }
364 self.listen_single().await;
365 for shard in &mut self.shards {
366 shard.motd = self.motd.clone();
367 shard.listen_single().await;
368 }
369 }
370
371 async fn listen_single(&mut self) {
372 if self.close_notifier.is_closed() || self.listened {
373 return;
374 }
375
376 let Some(socket) = self.socket.as_ref().cloned() else {
377 return;
378 };
379 let local_addr = match socket.local_addr() {
380 Ok(address) => address,
381 Err(error) => {
382 raknet_log_error!("failed to query listener address: {error}");
383 return;
384 }
385 };
386
387 if self.motd.is_empty() {
388 let _ = self
389 .set_motd(
390 SERVER_NAME,
391 MAX_CONNECTION,
392 "486",
393 "1.18.11",
394 "Survival",
395 local_addr.port(),
396 )
397 .await;
398 }
399
400 let guid = self.guid;
401 let maximum_mtu = self.maximum_mtu;
402 let sessions = self.sessions.clone();
403 let connection_sender = self.connection_sender.clone();
404
405 self.listened = true;
406
407 let (collect_sender, collect_receiver) = channel::<SocketAddr>(10);
408 let collect_sender = Arc::new(Mutex::new(collect_sender));
409 self.start_session_collect(&socket, &sessions, collect_receiver)
410 .await;
411
412 let close_notify = self.close_notifier.clone();
413 let version_map = self.version_map.clone();
414 let mut motd_receiver = self.motd_receiver.clone();
415
416 tokio::spawn(async move {
417 let mut buf = [0u8; 2048];
418 let mut pending_versions = HashMap::<SocketAddr, (u8, std::time::Instant)>::new();
419 let mut dispatch_cache = SessionDispatchCache::default();
420 let mut cleanup = tokio::time::interval(std::time::Duration::from_secs(30));
421
422 raknet_log_debug!("start listen worker : {}", local_addr);
423
424 loop {
425 let size: usize;
426 let addr: SocketAddr;
427
428 tokio::select! {
429 a = socket.recv_from(&mut buf) => {
430 match a {
431 Ok(p) => {
432 size = p.0;
433 addr = p.1;
434 },
435 Err(e) => {
436 raknet_log_debug!("server recv_from error {}" , e);
437 break;
438 },
439 };
440 },
441 _ = cleanup.tick() => {
442 pending_versions.retain(|_, (_, time)| time.elapsed().as_secs() < 60);
443 dispatch_cache.prune();
444 continue;
445 },
446 changed = motd_receiver.changed() => {
447 if changed.is_err() {
448 break;
449 }
450 let _ = motd_receiver.borrow_and_update();
451 continue;
452 },
453 _ = close_notify.acquire() => {
454 raknet_log_debug!("listen close notified");
455 break;
456 }
457 }
458
459 if size == 0 {
460 continue;
461 }
462
463 let cur_status = match PacketID::from(buf[0]) {
464 Ok(p) => p,
465 Err(e) => {
466 raknet_log_debug!("parse packetid faild : {:?}", e);
467 continue;
468 }
469 };
470
471 match cur_status {
472 PacketID::UnconnectedPing1 => {
473 let _ping = match read_packet_ping(&buf[..size]) {
474 Ok(p) => p,
475 Err(_) => continue,
476 };
477
478 let packet = crate::packet::PacketUnconnectedPong {
479 time: cur_timestamp_millis(),
480 guid,
481 motd: motd_receiver.borrow_and_update().clone(),
482 };
483
484 let pong = match write_packet_pong(&packet) {
485 Ok(p) => p,
486 Err(_) => continue,
487 };
488
489 match socket.send_to(&pong, addr).await {
490 Ok(_) => {}
491 Err(e) => {
492 raknet_log_error!("udp socket send_to error : {}", e);
493 }
494 };
495 continue;
496 }
497 PacketID::UnconnectedPing2 => {
498 match read_packet_ping(&buf[..size]) {
499 Ok(p) => p,
500 Err(_) => continue,
501 };
502
503 let packet = crate::packet::PacketUnconnectedPong {
504 time: cur_timestamp_millis(),
505 guid,
506 motd: motd_receiver.borrow_and_update().clone(),
507 };
508
509 let pong = match write_packet_pong(&packet) {
510 Ok(p) => p,
511 Err(_) => continue,
512 };
513
514 match socket.send_to(&pong, addr).await {
515 Ok(_) => {}
516 Err(e) => {
517 raknet_log_error!("udp socket send_to error : {}", e);
518 }
519 };
520 continue;
521 }
522 PacketID::OpenConnectionRequest1 => {
523 let req = match read_packet_connection_open_request_1(&buf[..size]) {
524 Ok(p) => p,
525 Err(_) => continue,
526 };
527
528 if !RAKNET_PROTOCOL_VERSION_LIST
529 .as_slice()
530 .contains(&req.protocol_version)
531 {
532 let packet = crate::packet::IncompatibleProtocolVersion {
533 server_protocol: RAKNET_PROTOCOL_VERSION,
534 server_guid: guid,
535 };
536 let buf = match write_packet_incompatible_protocol_version(&packet) {
537 Ok(buf) => buf,
538 Err(error) => {
539 raknet_log_error!("failed to encode protocol error: {error}");
540 continue;
541 }
542 };
543
544 match socket.send_to(&buf, addr).await {
545 Ok(_) => {}
546 Err(e) => {
547 raknet_log_error!("udp socket send_to error : {}", e);
548 }
549 };
550 continue;
551 }
552 if pending_versions.len() >= 4096 && !pending_versions.contains_key(&addr) {
553 continue;
554 }
555 pending_versions
556 .insert(addr, (req.protocol_version, std::time::Instant::now()));
557
558 let packet = crate::packet::OpenConnectionReply1 {
559 guid,
560 use_encryption: 0x00,
562 mtu_size: req.mtu_size.min(maximum_mtu),
563 };
564
565 let reply = match write_packet_connection_open_reply_1(&packet) {
566 Ok(p) => p,
567 Err(_) => continue,
568 };
569
570 match socket.send_to(&reply, addr).await {
571 Ok(_) => {}
572 Err(e) => {
573 raknet_log_error!("udp socket send_to error : {}", e);
574 }
575 };
576 continue;
577 }
578 PacketID::OpenConnectionRequest2 => {
579 dispatch_cache.forget(&addr);
580 let req = match read_packet_connection_open_request_2(&buf[..size]) {
581 Ok(p) => p,
582 Err(_) => continue,
583 };
584
585 if !(61..=maximum_mtu).contains(&req.mtu) {
586 continue;
587 }
588 let existing = sessions
589 .lock()
590 .await
591 .get(&addr)
592 .map(|session| (session.guid, session.mtu));
593 if let Some((client_guid, mtu)) = existing {
594 let reply = if client_guid == req.guid {
597 write_packet_connection_open_reply_2(&OpenConnectionReply2 {
598 guid,
599 address: addr,
600 mtu,
601 encryption_enabled: 0,
602 })
603 } else {
604 write_packet_already_connected(&AlreadyConnected { guid })
605 };
606 if let Ok(reply) = reply {
607 let _ = socket.send_to(&reply, addr).await;
608 }
609 continue;
610 }
611
612 let accept_slot = match connection_sender.try_reserve() {
615 Ok(slot) => slot,
616 Err(tokio::sync::mpsc::error::TrySendError::Full(_)) => continue,
617 Err(tokio::sync::mpsc::error::TrySendError::Closed(_)) => break,
618 };
619
620 let packet = crate::packet::OpenConnectionReply2 {
621 guid,
622 address: addr,
623 mtu: req.mtu,
624 encryption_enabled: 0x00,
625 };
626
627 let reply = match write_packet_connection_open_reply_2(&packet) {
628 Ok(p) => p,
629 Err(_) => continue,
630 };
631
632 if let Err(e) = socket.send_to(&reply, addr).await {
633 raknet_log_error!("udp socket send_to error : {}", e);
634 continue;
635 }
636
637 let (sender, receiver) = channel::<Vec<u8>>(128);
639 let raknet_version = pending_versions
640 .remove(&addr)
641 .filter(|(_, time)| time.elapsed().as_secs() < 60)
642 .map(|(version, _)| version)
643 .unwrap_or(RAKNET_PROTOCOL_VERSION);
644 version_map.lock().await.insert(addr, raknet_version);
645
646 let raknet_socket = RaknetSocket::from(
647 &addr,
648 &socket,
649 receiver,
650 req.mtu,
651 collect_sender.clone(),
652 raknet_version,
653 )
654 .await;
655
656 sessions.lock().await.insert(
657 addr,
658 SessionSender {
659 sender,
660 close: raknet_socket.close_signal(),
661 guid: req.guid,
662 mtu: req.mtu,
663 },
664 );
665
666 raknet_log_debug!("accept connection : {}", addr);
667 accept_slot.send(raknet_socket);
668 }
669 PacketID::Disconnect => {
670 dispatch_cache.forget(&addr);
671 let session_sender = sessions
672 .lock()
673 .await
674 .remove(&addr)
675 .map(|session| session.close);
676 if let Some(session_sender) = session_sender {
677 session_sender.close();
678 version_map.lock().await.remove(&addr);
679 }
680 }
681 _ => {
682 let result = if let Some(sender) = dispatch_cache.sender(&addr) {
683 tokio::task::consume_budget().await;
687 Some(sender.try_send(buf[..size].to_vec()))
688 } else {
689 dispatch_cache.forget(&addr);
690 let sessions = sessions.lock().await;
691 sessions.get(&addr).map(|session| {
692 let result = session.sender.try_send(buf[..size].to_vec());
693 dispatch_cache.remember(addr, session);
694 result
695 })
696 };
697 match result {
698 Some(Ok(())) | None => {}
699 Some(Err(tokio::sync::mpsc::error::TrySendError::Full(_))) => {
700 raknet_log_debug!("session receive queue full for {}", addr);
701 }
702 Some(Err(tokio::sync::mpsc::error::TrySendError::Closed(_))) => {
703 dispatch_cache.forget(&addr);
704 sessions.lock().await.remove(&addr);
705 version_map.lock().await.remove(&addr);
706 }
707 }
708 }
709 }
710 }
711 raknet_log_debug!("listen worker closed");
712 });
713 }
714
715 pub async fn accept(&mut self) -> Result<RaknetSocket> {
726 if !self.listened {
727 Err(RaknetError::NotListen)
728 } else {
729 tokio::select! {
730 a = self.connection_receiver.recv() => {
731 match a {
732 Some(p) => Ok(p),
733 None => {
734 Err(RaknetError::NotListen)
735 },
736 }
737 },
738 _ = self.close_notifier.acquire() => {
739 raknet_log_debug!("accept close notified");
740 Err(RaknetError::NotListen)
741 }
742 }
743 }
744 }
745
746 pub fn get_guid(&self) -> u64 {
748 self.guid
749 }
750
751 pub async fn set_motd(
761 &mut self,
762 server_name: &str,
763 max_connection: u32,
764 mc_protocol_version: &str,
765 mc_version: &str,
766 game_type: &str,
767 port: u16,
768 ) -> Result<()> {
769 let motd = format!(
770 "MCPE;{};{};{};0;{};{};Bedrock level;{};1;{};",
771 server_name,
772 mc_protocol_version,
773 mc_version,
774 max_connection,
775 self.guid,
776 game_type,
777 port
778 );
779
780 self.motd = motd.clone();
781 self.motd_sender.send_replace(motd);
782 Ok(())
783 }
784
785 pub async fn get_motd(&self) -> String {
793 self.motd.clone()
794 }
795
796 pub fn local_addr(&self) -> Result<SocketAddr> {
804 self.socket
805 .as_ref()
806 .ok_or(RaknetError::ConnectionClosed)?
807 .local_addr()
808 .map_err(|_| RaknetError::SocketError)
809 }
810
811 pub async fn close(&mut self) -> Result<()> {
819 self.close_notifier.close();
822 for shard in &self.shards {
823 shard.close_notifier.close();
824 }
825 self.close_single().await?;
826 for shard in &mut self.shards {
827 shard.close_single().await?;
828 }
829 Ok(())
830 }
831
832 async fn close_single(&mut self) -> Result<()> {
833 if self.socket.is_none() {
834 return Ok(());
835 }
836 self.close_notifier.close();
837 if self.listened {
838 self.all_session_closed_notifier.notified().await;
839 }
840 if let Some(socket) = self.socket.as_ref() {
841 while Arc::strong_count(socket) != 1 {
842 tokio::task::yield_now().await;
843 }
844 }
845 self.socket = None;
846 self.listened = false;
847 Ok(())
848 }
849
850 pub async fn set_full_motd(&mut self, motd: String) -> Result<()> {
858 self.motd = motd.clone();
859 self.motd_sender.send_replace(motd);
860 Ok(())
861 }
862
863 pub async fn get_peer_raknet_version(&self, peer: &SocketAddr) -> Result<u8> {
864 if let Some(version) = self.version_map.lock().await.get(peer).copied() {
865 return Ok(version);
866 }
867 for shard in &self.shards {
868 if let Some(version) = shard.version_map.lock().await.get(peer).copied() {
869 return Ok(version);
870 }
871 }
872 Ok(RAKNET_PROTOCOL_VERSION)
873 }
874}
875
876impl Drop for RaknetListener {
877 fn drop(&mut self) {
878 self.close_notifier.close();
879 }
880}
881
882#[tokio::test]
883async fn supplied_udp_socket_keeps_its_receive_buffer_configuration() {
884 let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
885 socket2::SockRef::from(&socket)
886 .set_recv_buffer_size(8192)
887 .unwrap();
888 let before = socket2::SockRef::from(&socket).recv_buffer_size().unwrap();
889 let listener = RaknetListener::from_std(socket).await.unwrap();
890 let socket = listener.socket.as_ref().unwrap();
891 assert_eq!(
892 socket2::SockRef::from(socket.as_ref())
893 .recv_buffer_size()
894 .unwrap(),
895 before
896 );
897}
898
899#[tokio::test]
900async fn custom_receive_buffer_binds_and_rejects_unrepresentable_sizes() {
901 let address = "127.0.0.1:0".parse().unwrap();
902 let listener = RaknetListener::bind_with_receive_buffer_size(
903 &address,
904 std::num::NonZeroUsize::new(8192).unwrap(),
905 )
906 .await
907 .unwrap();
908 assert_ne!(listener.local_addr().unwrap().port(), 0);
909 assert!(matches!(
910 RaknetListener::bind_with_receive_buffer_size(
911 &address,
912 std::num::NonZeroUsize::new(usize::MAX).unwrap(),
913 )
914 .await,
915 Err(RaknetError::SocketError)
916 ));
917}
918
919#[cfg(all(test, target_os = "linux"))]
920mod shard_tests {
921 use super::*;
922 use crate::arq::Reliability;
923 use std::{num::NonZeroUsize, time::Duration};
924 use tokio::{task::JoinSet, time::timeout};
925
926 #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
927 async fn shards_share_discovery_backlog_versions_and_close_all_sessions() {
928 timeout(Duration::from_secs(10), async {
929 let mut listener = RaknetListener::bind_with_socket_shards(
930 &"127.0.0.1:0".parse().unwrap(),
931 NonZeroUsize::new(4).unwrap(),
932 )
933 .await
934 .unwrap()
935 .with_accept_backlog(NonZeroUsize::new(64).unwrap());
936 let address = listener.local_addr().unwrap();
937 let guid = listener.get_guid();
938 listener
939 .set_full_motd("shared discovery".into())
940 .await
941 .unwrap();
942 listener.listen().await;
943 listener
944 .set_full_motd("updated discovery".into())
945 .await
946 .unwrap();
947 for _ in 0..32 {
948 let socket = UdpSocket::bind("127.0.0.1:0").await.unwrap();
949 let packet =
950 write_packet_ping(&PacketUnconnectedPing { time: 1, guid: 2 }).unwrap();
951 socket.send_to(&packet, address).await.unwrap();
952 let mut buffer = [0; 2048];
953 let (size, _) = socket.recv_from(&mut buffer).await.unwrap();
954 let pong = read_packet_pong(&buffer[..size]).unwrap();
955 assert_eq!(pong.guid, guid);
956 assert_eq!(pong.motd, "updated discovery");
957 }
958 let mut tasks = JoinSet::new();
959 for index in 0..32 {
960 tasks.spawn(async move {
961 let version = if index % 2 == 0 { 10 } else { 11 };
962 RaknetSocket::connect_with_version(&address, version)
963 .await
964 .unwrap()
965 });
966 }
967 let mut servers = Vec::new();
968 for _ in 0..32 {
969 let server = listener.accept().await.unwrap();
970 assert_eq!(
971 listener
972 .get_peer_raknet_version(&server.peer_addr().unwrap())
973 .await
974 .unwrap(),
975 server.raknet_version().unwrap()
976 );
977 servers.push(server);
978 }
979 let mut clients = Vec::new();
980 while let Some(client) = tasks.join_next().await {
981 clients.push(client.unwrap());
982 }
983 let mut occupied = usize::from(!listener.sessions.lock().await.is_empty());
984 for shard in &listener.shards {
985 occupied += usize::from(!shard.sessions.lock().await.is_empty());
986 }
987 assert!(occupied > 1, "flows did not reach multiple sockets");
988 for server in &servers {
989 server
990 .send(&[0xfe, 42], Reliability::ReliableOrdered)
991 .await
992 .unwrap();
993 }
994 for client in &clients {
995 assert_eq!(client.recv().await.unwrap(), vec![0xfe, 42]);
996 }
997 listener.close().await.unwrap();
998 listener.close().await.unwrap();
999 assert!(listener.sessions.lock().await.is_empty());
1000 assert!(listener.socket.is_none());
1001 for shard in &listener.shards {
1002 assert!(shard.sessions.lock().await.is_empty());
1003 assert!(shard.socket.is_none());
1004 }
1005 for client in clients {
1006 assert!(client.recv().await.is_err());
1007 }
1008 })
1009 .await
1010 .expect("sharded listener stalled");
1011 }
1012
1013 #[tokio::test]
1014 async fn shard_count_is_bounded_and_one_uses_the_normal_listener() {
1015 let address = "127.0.0.1:0".parse().unwrap();
1016 assert!(
1017 RaknetListener::bind_with_socket_shards(&address, NonZeroUsize::new(65).unwrap(),)
1018 .await
1019 .is_err()
1020 );
1021 let mut listener = RaknetListener::bind_with_socket_shards(&address, NonZeroUsize::MIN)
1022 .await
1023 .unwrap();
1024 assert!(listener.shards.is_empty());
1025 listener.close().await.unwrap();
1026 }
1027}
1028
1029#[cfg(test)]
1030mod dispatch_cache_tests {
1031 use super::*;
1032
1033 fn session() -> (SessionSender, Receiver<Vec<u8>>) {
1034 let (sender, receiver) = channel(2);
1035 (
1036 SessionSender {
1037 sender,
1038 close: Arc::new(tokio::sync::Semaphore::new(0)),
1039 guid: 1,
1040 mtu: 1400,
1041 },
1042 receiver,
1043 )
1044 }
1045
1046 #[test]
1047 fn cache_rejects_closed_sessions_and_replaces_reused_addresses() {
1048 let address = "127.0.0.1:19132".parse().unwrap();
1049 let (first, _first_receiver) = session();
1050 let (second, second_receiver) = session();
1051 let mut cache = SessionDispatchCache::default();
1052 cache.remember(address, &first);
1053 assert!(cache.sender(&address).unwrap().same_channel(&first.sender));
1054 first.close.close();
1055 assert!(cache.sender(&address).is_none());
1056 cache.remember(address, &second);
1057 assert!(cache.sender(&address).unwrap().same_channel(&second.sender));
1058 drop(second_receiver);
1059 assert!(cache.sender(&address).is_none());
1060 cache.prune();
1061 assert!(cache.entries.iter().all(Option::is_none));
1062 }
1063
1064 #[tokio::test]
1065 async fn late_collection_does_not_remove_a_replacement_peer() {
1066 tokio::time::timeout(std::time::Duration::from_secs(2), async {
1067 let mut listener = RaknetListener::bind(&"127.0.0.1:0".parse().unwrap())
1068 .await
1069 .unwrap();
1070 let peer_socket = UdpSocket::bind("127.0.0.1:0").await.unwrap();
1071 let marker_socket = UdpSocket::bind("127.0.0.1:0").await.unwrap();
1072 let peer = peer_socket.local_addr().unwrap();
1073 let marker = marker_socket.local_addr().unwrap();
1074 let (replacement, _replacement_receiver) = session();
1075 let close = replacement.close.clone();
1076 let (old_marker, _marker_receiver) = session();
1077 old_marker.close.close();
1078 listener.sessions.lock().await.insert(peer, replacement);
1079 listener.sessions.lock().await.insert(marker, old_marker);
1080 listener.version_map.lock().await.insert(peer, 11);
1081 let (collect_sender, collect_receiver) = channel(2);
1082 listener
1083 .start_session_collect(
1084 listener.socket.as_ref().unwrap(),
1085 &listener.sessions,
1086 collect_receiver,
1087 )
1088 .await;
1089 collect_sender.send(peer).await.unwrap();
1090 collect_sender.send(marker).await.unwrap();
1092 while listener.sessions.lock().await.contains_key(&marker) {
1093 tokio::task::yield_now().await;
1094 }
1095 assert!(listener.sessions.lock().await.contains_key(&peer));
1096 assert_eq!(listener.version_map.lock().await.get(&peer), Some(&11));
1097 let mut packet = [0; 32];
1098 assert_eq!(
1099 peer_socket.try_recv_from(&mut packet).unwrap_err().kind(),
1100 std::io::ErrorKind::WouldBlock
1101 );
1102 close.close();
1103 collect_sender.send(peer).await.unwrap();
1104 while listener.sessions.lock().await.contains_key(&peer) {
1105 tokio::task::yield_now().await;
1106 }
1107 let (length, _) = peer_socket.recv_from(&mut packet).await.unwrap();
1108 assert_eq!(&packet[..length], &[PacketID::Disconnect.to_u8()]);
1109 drop(collect_sender);
1110 listener.close().await.unwrap();
1111 })
1112 .await
1113 .expect("session collection stalled");
1114 }
1115
1116 #[test]
1117 fn collisions_never_dispatch_to_or_forget_another_peer() {
1118 let (first, _first_receiver) = session();
1119 let (second, _second_receiver) = session();
1120 let first_address = SocketAddr::from(([127, 0, 0, 1], 19132));
1121 let second_address = SocketAddr::from(([127, 0, 0, 2], 19132));
1122 let third_address = "[::1]:19132".parse().unwrap();
1123 let mut cache = SessionDispatchCache::default();
1124 cache.remember(first_address, &first);
1125 cache.remember(second_address, &second);
1126 assert!(cache.sender(&first_address).is_none());
1127 assert!(cache.sender(&third_address).is_none());
1128 assert!(
1129 cache
1130 .sender(&second_address)
1131 .unwrap()
1132 .same_channel(&second.sender)
1133 );
1134 cache.forget(&first_address);
1135 assert!(cache.sender(&second_address).is_some());
1136 cache.remember(third_address, &first);
1137 assert!(cache.sender(&second_address).is_none());
1138 assert!(
1139 cache
1140 .sender(&third_address)
1141 .unwrap()
1142 .same_channel(&first.sender)
1143 );
1144 for port in 1..=u16::MAX {
1145 cache.remember(SocketAddr::from(([127, 0, 0, 1], port)), &first);
1146 }
1147 assert_eq!(cache.entries.len(), SessionDispatchCache::LIMIT);
1148 assert_eq!(
1149 cache.entries.iter().filter(|entry| entry.is_some()).count(),
1150 SessionDispatchCache::LIMIT
1151 );
1152 }
1153}