Skip to main content

rust_raknet/
server.rs

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
23// The authoritative session map handles handshakes and shutdown. This bounded,
24// direct-mapped cache avoids hashing the common dispatch path. A slot collision
25// is only a cache miss: the complete peer address is always checked.
26struct 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
87/// A RakNet UDP server that accepts incoming connections.
88pub 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    /// Bind a RakNet listener to the specified UDP address.
107    ///
108    /// Call [`listen`](Self::listen) before accepting connections.
109    pub async fn bind(sockaddr: &SocketAddr) -> Result<Self> {
110        let socket =
111            std::net::UdpSocket::bind(sockaddr).map_err(|_| RaknetError::BindAddressError)?;
112        // A shared listener receives bursts from every connection. This changes
113        // only this socket; the OS may clamp the requested receive buffer.
114        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    /// Bind a listener with an explicit maximum nominal MTU in bytes.
121    ///
122    /// The maximum must be between 61 and 1,492 bytes. Offline negotiation
123    /// chooses the smaller of this limit and the client's request. Ordinary
124    /// listeners retain their 1,400-byte maximum.
125    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    /// Bind a fixed group of UDP receive sockets on Linux.
135    ///
136    /// All shards use the same address, server GUID, MOTD and accept backlog.
137    /// Linux `SO_REUSEPORT` distributes peer flows across the fixed group. Create
138    /// every shard before listening and retain the group for the listener's lifetime.
139    /// The count must be at most 64; one shard uses the ordinary binding path.
140    /// This changes only these sockets and does not alter system network limits.
141    #[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    /// Bind with a requested per-socket UDP receive buffer size.
184    ///
185    /// The OS may clamp the size to its existing limits. No system limits are
186    /// changed. Unlike [`bind`](Self::bind), a failed buffer request returns an error.
187    /// [`from_std`](Self::from_std) preserves the supplied socket's buffer settings.
188    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    /// Sets the number of connections that may wait for [`accept`](Self::accept).
204    ///
205    /// The default backlog is 128. When it is full, new offline handshakes wait
206    /// for a retried request instead of allocating and immediately closing a session.
207    ///
208    /// # Panics
209    /// Panics if called after [`listen`](Self::listen).
210    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    /// Creates a listener from a standard UDP socket.
225    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                // A late collector message from an old peer must not remove
290                // a replacement connection that reused the same address.
291                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    /// Start receiving connection requests.
353    ///
354    /// Call this before [`accept`](Self::accept). Repeated calls have no effect.
355    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            // Only the parent owns discovery metadata. Prevent a shard from
361            // replacing the shared MOTD with its default during startup.
362            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                            // Encryption is not negotiated by this implementation.
561                            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                            // A lost offline reply causes Request2 retransmission.
595                            // Replay the negotiated response without creating a session.
596                            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                        // Reserve acceptance before acknowledging the offline handshake.
613                        // A full backlog must not create a session only to disconnect it.
614                        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                        // Cover the 64-datagram flight window plus control traffic.
638                        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                            // Preserve the cooperative budget consumed by the map
684                            // lock on the uncached path. A busy UDP listener must
685                            // still give protocol and application tasks time to run.
686                            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    /// Wait for and accept the next incoming RakNet connection.
716    ///
717    /// Call [`listen`](Self::listen) first.
718    ///
719    /// # Example
720    /// ```ignore
721    /// let mut listener = RaknetListener::bind("127.0.0.1:19132".parse().unwrap()).await.unwrap();
722    /// listener.listen().await;
723    /// let mut socket = listener.accept().await.unwrap();
724    /// ```
725    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    /// Get the GUID, a random number that uniquely identifies the listener instance.
747    pub fn get_guid(&self) -> u64 {
748        self.guid
749    }
750
751    /// Set the server-list MOTD returned in unconnected pong packets.
752    ///
753    /// Future ping responses use the updated value.
754    ///
755    /// # Example
756    /// ```ignore
757    /// let mut listener = RaknetListener::bind("127.0.0.1:19132".parse().unwrap()).await.unwrap();
758    /// listener.set_motd("Bedrock Server", 20, "protocol", "version", "Survival", 19132).await?;
759    /// ```
760    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    /// Return the MOTD sent in unconnected pong packets.
786    ///
787    /// # Example
788    /// ```ignore
789    /// let listener = RaknetListener::bind("127.0.0.1:19132".parse().unwrap()).await.unwrap();
790    /// let motd = listener.get_motd().await;
791    /// ```
792    pub async fn get_motd(&self) -> String {
793        self.motd.clone()
794    }
795
796    /// Return the local UDP address used by this listener.
797    ///
798    /// # Example
799    /// ```ignore
800    /// let mut socket = RaknetListener::bind("127.0.0.1:19132".parse().unwrap()).await.unwrap();
801    /// assert_eq!(socket.local_addr().unwrap().ip(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
802    /// ```
803    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    /// Close the listener and all active connections.
812    ///
813    /// # Example
814    /// ```ignore
815    /// let mut socket = RaknetListener::bind("127.0.0.1:19132".parse().unwrap()).await.unwrap();
816    /// socket.close().await;
817    /// ```
818    pub async fn close(&mut self) -> Result<()> {
819        // Signal the whole group before releasing any socket. Active flows must
820        // never be remapped onto a shard that is still accepting new sessions.
821        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    /// Set the full MOTD string used by future unconnected pong responses.
851    ///
852    /// # Example
853    /// ```ignore
854    /// let mut listener = RaknetListener::bind("127.0.0.1:19132".parse().unwrap()).await.unwrap();
855    /// listener.set_full_motd(String::from("motd")).await.unwrap();
856    /// ```
857    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            // The marker makes it observable that the earlier notification was processed.
1091            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}