]> git.lizzy.rs Git - mt_rudp.git/blob - src/common.rs
797ccd1501fb205b11b1541d564aa5d943ad4da5
[mt_rudp.git] / src / common.rs
1 use super::*;
2 use async_trait::async_trait;
3 use delegate::delegate;
4 use num_enum::TryFromPrimitive;
5 use std::{io, sync::Arc};
6 use tokio::sync::mpsc;
7
8 pub const PROTO_ID: u32 = 0x4f457403;
9 pub const UDP_PKT_SIZE: usize = 512;
10 pub const NUM_CHANS: usize = 3;
11 pub const REL_BUFFER: usize = 0x8000;
12 pub const INIT_SEQNUM: u16 = 65500;
13 pub const TIMEOUT: u64 = 30;
14 pub const PING_TIMEOUT: u64 = 5;
15
16 #[async_trait]
17 pub trait UdpSender: Send + Sync + 'static {
18     async fn send(&self, data: &[u8]) -> io::Result<()>;
19 }
20
21 #[async_trait]
22 pub trait UdpReceiver: Send + Sync + 'static {
23     async fn recv(&self) -> io::Result<Vec<u8>>;
24 }
25
26 #[derive(Debug, Copy, Clone, PartialEq)]
27 #[repr(u16)]
28 pub enum PeerID {
29     Nil = 0,
30     Srv,
31     CltMin,
32 }
33
34 #[derive(Debug, Copy, Clone, PartialEq, TryFromPrimitive)]
35 #[repr(u8)]
36 pub enum PktType {
37     Ctl = 0,
38     Orig,
39     Split,
40     Rel,
41 }
42
43 #[derive(Debug, Copy, Clone, PartialEq, TryFromPrimitive)]
44 #[repr(u8)]
45 pub enum CtlType {
46     Ack = 0,
47     SetPeerID,
48     Ping,
49     Disco,
50 }
51
52 #[derive(Debug)]
53 pub struct Pkt<T> {
54     pub unrel: bool,
55     pub chan: u8,
56     pub data: T,
57 }
58
59 pub type InPkt = Result<Pkt<Vec<u8>>, error::Error>;
60
61 #[derive(Debug)]
62 pub struct RudpReceiver<S: UdpSender> {
63     pub(crate) share: Arc<RudpShare<S>>,
64     pub(crate) pkt_rx: mpsc::UnboundedReceiver<InPkt>,
65 }
66
67 #[derive(Debug)]
68 pub struct RudpSender<S: UdpSender> {
69     pub(crate) share: Arc<RudpShare<S>>,
70 }
71
72 macro_rules! impl_share {
73     ($T:ident) => {
74         impl<S: UdpSender> $T<S> {
75             pub async fn peer_id(&self) -> u16 {
76                 self.share.id
77             }
78
79             pub async fn is_server(&self) -> bool {
80                 self.share.id == PeerID::Srv as u16
81             }
82
83             pub async fn close(self) {
84                 self.share.close_tx.send(true).ok();
85
86                 let mut tasks = self.share.tasks.lock().await;
87                 while let Some(res) = tasks.join_next().await {
88                     res.ok(); // TODO: handle error (?)
89                 }
90             }
91         }
92     };
93 }
94
95 impl_share!(RudpReceiver);
96 impl_share!(RudpSender);
97
98 impl<S: UdpSender> RudpReceiver<S> {
99     delegate! {
100         to self.pkt_rx {
101             pub async fn recv(&mut self) -> Option<InPkt>;
102         }
103     }
104 }