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
16type SessionSender = (i64, Sender<Vec<u8>>);
17
18pub struct RaknetListener {
20 motd: String,
21 socket: Option<Arc<UdpSocket>>,
22 guid: u64,
23 listened: bool,
24 connection_receiver: Receiver<RaknetSocket>,
25 connection_sender: Sender<RaknetSocket>,
26 sessions: Arc<Mutex<HashMap<SocketAddr, SessionSender>>>,
27 close_notifier: Arc<tokio::sync::Semaphore>,
28 all_session_closed_notifier: Arc<Notify>,
29 drop_notifier: Arc<Notify>,
30 version_map: Arc<Mutex<HashMap<String, u8>>>,
31 motd_receiver: watch::Receiver<String>,
32 motd_sender: watch::Sender<String>,
33}
34
35impl RaknetListener {
36 pub async fn bind(sockaddr: &SocketAddr) -> Result<Self> {
40 let socket = UdpSocket::bind(sockaddr)
41 .await
42 .map_err(|_| RaknetError::BindAddressError)?;
43 Self::from_udp_socket(socket).await
44 }
45
46 pub async fn from_std(socket: std::net::UdpSocket) -> Result<Self> {
48 socket
49 .set_nonblocking(true)
50 .map_err(|_| RaknetError::SetRaknetRawSocketError)?;
51 let socket =
52 UdpSocket::from_std(socket).map_err(|_| RaknetError::SetRaknetRawSocketError)?;
53 Self::from_udp_socket(socket).await
54 }
55
56 async fn from_udp_socket(socket: UdpSocket) -> Result<Self> {
57 let (connection_sender, connection_receiver) = channel::<RaknetSocket>(10);
58 let (motd_sender, motd_receiver) = watch::channel(String::new());
59 let listener = Self {
60 motd: String::new(),
61 socket: Some(Arc::new(socket)),
62 guid: rand::random(),
63 listened: false,
64 connection_receiver,
65 connection_sender,
66 sessions: Arc::new(Mutex::new(HashMap::new())),
67 close_notifier: Arc::new(tokio::sync::Semaphore::new(0)),
68 all_session_closed_notifier: Arc::new(Notify::new()),
69 drop_notifier: Arc::new(Notify::new()),
70 version_map: Arc::new(Mutex::new(HashMap::new())),
71 motd_receiver,
72 motd_sender,
73 };
74
75 listener.drop_watcher().await;
76 Ok(listener)
77 }
78
79 async fn start_session_collect(
80 &self,
81 socket: &Arc<UdpSocket>,
82 sessions: &Arc<Mutex<HashMap<SocketAddr, SessionSender>>>,
83 mut collect_receiver: Receiver<SocketAddr>,
84 ) {
85 let sessions = sessions.clone();
86 let socket = socket.clone();
87 let close_notifier = self.close_notifier.clone();
88 let all_session_closed_notifier = self.all_session_closed_notifier.clone();
89 tokio::spawn(async move {
90 loop {
91 let addr: SocketAddr;
92
93 tokio::select! {
94 a = collect_receiver.recv() => {
95 match a {
96 Some(p) => { addr = p },
97 None => {
98 raknet_log_debug!("session collector closed");
99 break;
100 },
101 };
102 },
103 _ = close_notifier.acquire() => {
104 raknet_log_debug!("session collector received close notification");
105 break;
106 }
107 }
108
109 let mut sessions = sessions.lock().await;
110 if sessions.contains_key(&addr) {
111 match socket.send_to(&[PacketID::Disconnect.to_u8()], addr).await {
112 Ok(_) => {}
113 Err(e) => {
114 raknet_log_error!("udp socket send_to error : {}", e);
115 }
116 };
117 sessions.remove(&addr);
118 raknet_log_debug!("collect socket : {}", addr);
119 }
120 }
121
122 let mut sessions = sessions.lock().await;
123
124 for (addr, (_, sender)) in sessions.iter() {
125 let _ = sender.send(vec![PacketID::Disconnect.to_u8()]).await;
126
127 match socket.send_to(&[PacketID::Disconnect.to_u8()], addr).await {
128 Ok(_) => {}
129 Err(e) => {
130 raknet_log_error!("udp socket send_to error : {}", e);
131 }
132 };
133 }
134
135 while !sessions.is_empty() {
136 let addr = match collect_receiver.recv().await {
137 Some(p) => p,
138 None => {
139 raknet_log_error!(
140 "failed to clean up sessions; some connections may still be open"
141 );
142 break;
143 }
144 };
145
146 if sessions.contains_key(&addr) {
147 match socket.send_to(&[PacketID::Disconnect.to_u8()], addr).await {
148 Ok(_) => {}
149 Err(e) => {
150 raknet_log_error!("udp socket send_to error : {}", e);
151 }
152 };
153 sessions.remove(&addr);
154 raknet_log_debug!("collect socket : {}", addr);
155 }
156 }
157
158 sessions.clear();
159 all_session_closed_notifier.notify_one();
160
161 raknet_log_debug!("session collect closed");
162 });
163 }
164
165 pub async fn listen(&mut self) {
169 if self.close_notifier.is_closed() || self.listened {
170 return;
171 }
172
173 let Some(socket) = self.socket.as_ref().cloned() else {
174 return;
175 };
176 let local_addr = match socket.local_addr() {
177 Ok(address) => address,
178 Err(error) => {
179 raknet_log_error!("failed to query listener address: {error}");
180 return;
181 }
182 };
183
184 if self.motd.is_empty() {
185 let _ = self
186 .set_motd(
187 SERVER_NAME,
188 MAX_CONNECTION,
189 "486",
190 "1.18.11",
191 "Survival",
192 local_addr.port(),
193 )
194 .await;
195 }
196
197 let guid = self.guid;
198 let sessions = self.sessions.clone();
199 let connection_sender = self.connection_sender.clone();
200
201 self.listened = true;
202
203 let (collect_sender, collect_receiver) = channel::<SocketAddr>(10);
204 let collect_sender = Arc::new(Mutex::new(collect_sender));
205 self.start_session_collect(&socket, &sessions, collect_receiver)
206 .await;
207
208 let close_notify = self.close_notifier.clone();
209 let version_map = self.version_map.clone();
210 let mut motd_receiver = self.motd_receiver.clone();
211
212 tokio::spawn(async move {
213 let mut buf = [0u8; 2048];
214
215 raknet_log_debug!("start listen worker : {}", local_addr);
216
217 loop {
218 let size: usize;
219 let addr: SocketAddr;
220
221 tokio::select! {
222 a = socket.recv_from(&mut buf) => {
223 match a {
224 Ok(p) => {
225 size = p.0;
226 addr = p.1;
227 },
228 Err(e) => {
229 raknet_log_debug!("server recv_from error {}" , e);
230 break;
231 },
232 };
233 },
234 changed = motd_receiver.changed() => {
235 if changed.is_err() {
236 break;
237 }
238 let _ = motd_receiver.borrow_and_update();
239 continue;
240 },
241 _ = close_notify.acquire() => {
242 raknet_log_debug!("listen close notified");
243 break;
244 }
245 }
246
247 if size == 0 {
248 continue;
249 }
250
251 let new_motd = motd_receiver.borrow_and_update().clone();
252 let cur_status = match PacketID::from(buf[0]) {
253 Ok(p) => p,
254 Err(e) => {
255 raknet_log_debug!("parse packetid faild : {:?}", e);
256 continue;
257 }
258 };
259
260 match cur_status {
261 PacketID::UnconnectedPing1 => {
262 let _ping = match read_packet_ping(&buf[..size]) {
263 Ok(p) => p,
264 Err(_) => continue,
265 };
266
267 let packet = crate::packet::PacketUnconnectedPong {
268 time: cur_timestamp_millis(),
269 guid,
270 motd: new_motd,
271 };
272
273 let pong = match write_packet_pong(&packet) {
274 Ok(p) => p,
275 Err(_) => continue,
276 };
277
278 match socket.send_to(&pong, addr).await {
279 Ok(_) => {}
280 Err(e) => {
281 raknet_log_error!("udp socket send_to error : {}", e);
282 }
283 };
284 continue;
285 }
286 PacketID::UnconnectedPing2 => {
287 match read_packet_ping(&buf[..size]) {
288 Ok(p) => p,
289 Err(_) => continue,
290 };
291
292 let packet = crate::packet::PacketUnconnectedPong {
293 time: cur_timestamp_millis(),
294 guid,
295 motd: new_motd,
296 };
297
298 let pong = match write_packet_pong(&packet) {
299 Ok(p) => p,
300 Err(_) => continue,
301 };
302
303 match socket.send_to(&pong, addr).await {
304 Ok(_) => {}
305 Err(e) => {
306 raknet_log_error!("udp socket send_to error : {}", e);
307 }
308 };
309 continue;
310 }
311 PacketID::OpenConnectionRequest1 => {
312 let req = match read_packet_connection_open_request_1(&buf[..size]) {
313 Ok(p) => p,
314 Err(_) => continue,
315 };
316
317 if !RAKNET_PROTOCOL_VERSION_LIST
318 .as_slice()
319 .contains(&req.protocol_version)
320 {
321 let packet = crate::packet::IncompatibleProtocolVersion {
322 server_protocol: RAKNET_PROTOCOL_VERSION,
323 server_guid: guid,
324 };
325 let buf = match write_packet_incompatible_protocol_version(&packet) {
326 Ok(buf) => buf,
327 Err(error) => {
328 raknet_log_error!("failed to encode protocol error: {error}");
329 continue;
330 }
331 };
332
333 match socket.send_to(&buf, addr).await {
334 Ok(_) => {}
335 Err(e) => {
336 raknet_log_error!("udp socket send_to error : {}", e);
337 }
338 };
339 continue;
340 }
341 {
342 let mut version_map = version_map.lock().await;
343 version_map.insert(addr.to_string(), req.protocol_version);
344 }
345
346 let packet = crate::packet::OpenConnectionReply1 {
347 guid,
348 use_encryption: 0x00,
350 mtu_size: RAKNET_CLIENT_MTU,
351 };
352
353 let reply = match write_packet_connection_open_reply_1(&packet) {
354 Ok(p) => p,
355 Err(_) => continue,
356 };
357
358 match socket.send_to(&reply, addr).await {
359 Ok(_) => {}
360 Err(e) => {
361 raknet_log_error!("udp socket send_to error : {}", e);
362 }
363 };
364 continue;
365 }
366 PacketID::OpenConnectionRequest2 => {
367 let req = match read_packet_connection_open_request_2(&buf[..size]) {
368 Ok(p) => p,
369 Err(_) => continue,
370 };
371
372 let already_connected = { sessions.lock().await.contains_key(&addr) };
373 if already_connected {
374 if let Ok(packet) =
375 write_packet_already_connected(&AlreadyConnected { guid })
376 {
377 let _ = socket.send_to(&packet, addr).await;
378 }
379 continue;
380 }
381
382 let packet = crate::packet::OpenConnectionReply2 {
383 guid,
384 address: addr,
385 mtu: req.mtu,
386 encryption_enabled: 0x00,
387 };
388
389 let reply = match write_packet_connection_open_reply_2(&packet) {
390 Ok(p) => p,
391 Err(_) => continue,
392 };
393
394 if let Err(e) = socket.send_to(&reply, addr).await {
395 raknet_log_error!("udp socket send_to error : {}", e);
396 continue;
397 }
398
399 let (sender, receiver) = channel::<Vec<u8>>(10);
400 let raknet_version = {
401 let version_map = version_map.lock().await;
402 *version_map
403 .get(&addr.to_string())
404 .unwrap_or(&RAKNET_PROTOCOL_VERSION)
405 };
406
407 let raknet_socket = RaknetSocket::from(
408 &addr,
409 &socket,
410 receiver,
411 req.mtu,
412 collect_sender.clone(),
413 raknet_version,
414 )
415 .await;
416
417 sessions
418 .lock()
419 .await
420 .insert(addr, (cur_timestamp_millis(), sender));
421
422 raknet_log_debug!("accept connection : {}", addr);
423 if connection_sender.try_send(raknet_socket).is_err() {
424 sessions.lock().await.remove(&addr);
425 let _ = socket.send_to(&[PacketID::Disconnect.to_u8()], addr).await;
426 raknet_log_debug!(
427 "pending accept queue is full; disconnected {}",
428 addr
429 );
430 }
431 }
432 PacketID::Disconnect => {
433 let session_sender = sessions
434 .lock()
435 .await
436 .remove(&addr)
437 .map(|(_, sender)| sender);
438 if let Some(session_sender) = session_sender {
439 let _ = session_sender.try_send(buf[..size].to_vec());
440 }
441 }
442 _ => {
443 let session_sender = {
444 let mut sessions = sessions.lock().await;
445 sessions.get_mut(&addr).map(|(last_seen, sender)| {
446 *last_seen = cur_timestamp_millis();
447 sender.clone()
448 })
449 };
450
451 if let Some(session_sender) = session_sender {
452 match session_sender.try_send(buf[..size].to_vec()) {
453 Ok(()) => {}
454 Err(tokio::sync::mpsc::error::TrySendError::Full(_)) => {
455 raknet_log_debug!("session receive queue full for {}", addr);
456 }
457 Err(tokio::sync::mpsc::error::TrySendError::Closed(_)) => {
458 sessions.lock().await.remove(&addr);
459 }
460 }
461 }
462 }
463 }
464 }
465 raknet_log_debug!("listen worker closed");
466 });
467 }
468
469 pub async fn accept(&mut self) -> Result<RaknetSocket> {
480 if !self.listened {
481 Err(RaknetError::NotListen)
482 } else {
483 tokio::select! {
484 a = self.connection_receiver.recv() => {
485 match a {
486 Some(p) => Ok(p),
487 None => {
488 Err(RaknetError::NotListen)
489 },
490 }
491 },
492 _ = self.close_notifier.acquire() => {
493 raknet_log_debug!("accept close notified");
494 Err(RaknetError::NotListen)
495 }
496 }
497 }
498 }
499
500 pub fn get_guid(&self) -> u64 {
502 self.guid
503 }
504
505 pub async fn set_motd(
515 &mut self,
516 server_name: &str,
517 max_connection: u32,
518 mc_protocol_version: &str,
519 mc_version: &str,
520 game_type: &str,
521 port: u16,
522 ) -> Result<()> {
523 let motd = format!(
524 "MCPE;{};{};{};0;{};{};Bedrock level;{};1;{};",
525 server_name,
526 mc_protocol_version,
527 mc_version,
528 max_connection,
529 self.guid,
530 game_type,
531 port
532 );
533
534 self.motd = motd.clone();
535 self.motd_sender.send_replace(motd);
536 Ok(())
537 }
538
539 pub async fn get_motd(&self) -> String {
547 self.motd.clone()
548 }
549
550 pub fn local_addr(&self) -> Result<SocketAddr> {
558 self.socket
559 .as_ref()
560 .ok_or(RaknetError::ConnectionClosed)?
561 .local_addr()
562 .map_err(|_| RaknetError::SocketError)
563 }
564
565 pub async fn close(&mut self) -> Result<()> {
573 if self.close_notifier.is_closed() {
574 return Ok(());
575 }
576 self.close_notifier.close();
577 if self.listened {
578 self.all_session_closed_notifier.notified().await;
579 }
580
581 if let Some(socket) = self.socket.as_ref() {
582 while Arc::strong_count(socket) != 1 {
583 tokio::task::yield_now().await;
584 }
585 }
586 self.socket = None;
587 self.listened = false;
588
589 Ok(())
590 }
591
592 pub async fn set_full_motd(&mut self, motd: String) -> Result<()> {
600 self.motd = motd.clone();
601 self.motd_sender.send_replace(motd);
602 Ok(())
603 }
604
605 pub async fn get_peer_raknet_version(&self, peer: &SocketAddr) -> Result<u8> {
606 let version_map = self.version_map.lock().await;
607 let ver = version_map.get(&peer.to_string());
608 Ok(*ver.unwrap_or(&RAKNET_PROTOCOL_VERSION))
609 }
610
611 async fn drop_watcher(&self) {
612 let close_notifier = self.close_notifier.clone();
613 let drop_notifier = self.drop_notifier.clone();
614 tokio::spawn(async move {
615 raknet_log_debug!("listener drop watcher start");
616 drop_notifier.notify_one();
617
618 drop_notifier.notified().await;
619
620 if close_notifier.is_closed() {
621 raknet_log_debug!("close notifier closed");
622 return;
623 }
624
625 close_notifier.close();
626
627 raknet_log_debug!("listener drop watcher closed");
628 });
629
630 self.drop_notifier.notified().await;
631 }
632}
633
634impl Drop for RaknetListener {
635 fn drop(&mut self) {
636 self.drop_notifier.notify_one();
637 }
638}