1use std::{
2 sync::Arc,
3 net::SocketAddr,
4 io,
5 collections::{HashMap, VecDeque, HashSet}
6};
7use tokio::{net::UdpSocket, sync::mpsc::{Sender, self}};
8
9
10use chrono::Utc;
11use parking_lot::Mutex;
12use rand::Rng;
13use sock_send::SockSend;
14use types::{
15 AckUdpDatagram,
16 AckUdpDatagramOutStatus,
17 AckUdpDatagramOutStatusEnum,
18 AckUdpPacket
19};
20
21mod types;
22mod sock_send;
23mod methods;
24
25pub struct AckUdp {
26 pub sock: Arc<UdpSocket>,
27
28 pub ready_to_read_datagrams: Arc<Mutex<VecDeque<(SocketAddr, Vec<u8>)>>>,
29 pub pending_in_datagrams: Arc<Mutex<HashMap<[u8; 5], AckUdpDatagram>>>,
30 pub pending_out_datagrams: Arc<Mutex<HashMap<[u8; 5], AckUdpDatagram>>>,
31
32 pub out_datagrams_status_links: Arc<Mutex<HashMap<[u8; 5], Arc<Mutex<AckUdpDatagramOutStatus>>>>>,
33
34 pub kill_listener_channel_sender: Sender<()>,
35 pub kill_income_checker_channel_sender: Sender<()>,
36 pub kill_outcome_checker_listener_channel_sender: Sender<()>,
37 pub kill_incoming_queue_channel_sender: Sender<()>,
38
39 pub incoming_queue: Arc<Mutex<VecDeque<(SocketAddr, Vec<u8>)>>>
40}
41
42impl AckUdp {
43 pub async fn new(address: SocketAddr) -> io::Result<AckUdp> {
44 let sock = Arc::new(UdpSocket::bind(address).await?);
45
46 let (listener_sender, listener_receiver) = mpsc::channel(1);
47 let (income_checker_sender, income_checker_receiver) = mpsc::channel(1);
48 let (outcome_checker_sender, outcome_checker_receiver) = mpsc::channel(1);
49 let (incoming_queue_sender, incoming_queue_receiver) = mpsc::channel(1);
50
51 let instance = AckUdp {
52 sock: sock.clone(),
53 ready_to_read_datagrams: Arc::new(Mutex::new(VecDeque::new())),
54 pending_in_datagrams: Arc::new(Mutex::new(HashMap::new())),
55 pending_out_datagrams: Arc::new(Mutex::new(HashMap::new())),
56 out_datagrams_status_links: Arc::new(Mutex::new(HashMap::new())),
57 kill_listener_channel_sender: listener_sender,
58 kill_income_checker_channel_sender: income_checker_sender,
59 kill_outcome_checker_listener_channel_sender: outcome_checker_sender,
60 kill_incoming_queue_channel_sender: incoming_queue_sender,
61 incoming_queue: Arc::new(Mutex::new(VecDeque::new()))
62 };
63
64 tokio::spawn(AckUdp::check_dropped_income(
66 income_checker_receiver,
67 instance.pending_in_datagrams.clone())
68 );
69
70 tokio::spawn(AckUdp::check_dropped_outcome(
72 outcome_checker_receiver,
73 instance.pending_out_datagrams.clone(),
74 instance.sock.clone(),
75 instance.out_datagrams_status_links.clone()
76 ));
77
78 tokio::spawn(AckUdp::listen_packets(listener_receiver, instance.sock.clone(), instance.incoming_queue.clone()));
80
81 tokio::spawn(AckUdp::process_packets(
83 incoming_queue_receiver,
84 instance.incoming_queue.clone(),
85 instance.sock.clone(),
86 instance.ready_to_read_datagrams.clone(),
87 instance.pending_in_datagrams.clone(),
88 instance.pending_out_datagrams.clone(),
89 instance.out_datagrams_status_links.clone()
90 ));
91
92 Ok(instance)
93 }
94
95 pub fn recv(&mut self) -> Option<(SocketAddr, Vec<u8>)> {
96 self.ready_to_read_datagrams.lock().pop_front()
97 }
98
99 pub fn send(&mut self, buf: &[u8], address: SocketAddr ) -> io::Result<Arc<Mutex<AckUdpDatagramOutStatus>>> {
100 let datagram_id = rand::thread_rng().gen::<[u8; 5]>();
101 let status = Arc::new(Mutex::new(AckUdpDatagramOutStatus(AckUdpDatagramOutStatusEnum::Pending)));
102 if buf.len() > 400 {
103 let segments_count = {
104 let a = buf.len() as f64 / 400 as f64;
105 a.ceil() as u32
106 };
107
108 let segments = Arc::new(Mutex::new(HashMap::new()));
109
110 let datagram = AckUdpDatagram {
111 id: datagram_id,
112 address,
113 segments_count: segments_count,
114 segments: segments.clone(),
115 segments_got: Arc::new(Mutex::new(vec![])),
116 segments_acks: Arc::new(Mutex::new(HashSet::new())),
117 last_active: Utc::now(),
118 checks_failure_count: 0
119 };
120
121 self.pending_out_datagrams.lock().insert(datagram_id, datagram.clone());
122 self.out_datagrams_status_links.lock().insert(datagram_id, status.clone());
123
124 let buffer_length = buf.len();
125 for index in 0..segments_count {
126 let start = 400 * index as usize;
127 let end = {
128 let v = start + 400;
129 if v > buffer_length {
130 buffer_length
131 }
132 else {
133 v
134 }
135 };
136 let payload = &buf[start..end];
137 let packet = AckUdpPacket {
138 datagram_id,
139 seg_index: index,
140 total_segments: segments_count,
141 ack: 0,
142 payload_size: payload.len() as u16,
143 payload: payload.to_vec()
144 };
145 segments.lock().insert(index, packet.clone());
146
147 let packet_bytes: Vec<u8> = packet.into();
148 self.sock.sock_send(packet_bytes, address);
149 }
150
151 let mut sent_datagram = self.pending_out_datagrams.lock().get(&datagram_id).unwrap().clone();
152 sent_datagram.last_active = Utc::now();
153 self.pending_out_datagrams.lock().insert(datagram_id, sent_datagram);
154
155 return Ok(status.clone());
156 }
157 else {
158 let packet = AckUdpPacket {
159 datagram_id,
160 seg_index: 0,
161 total_segments: 1,
162 ack: 0,
163 payload_size: buf.len() as u16,
164 payload: buf.to_vec()
165 };
166
167 let segments= Arc::new(Mutex::new(HashMap::new()));
168 segments.lock().insert(0, packet.clone());
169
170 let datagram = AckUdpDatagram {
171 id: datagram_id,
172 address,
173 segments_count: 1,
174 segments,
175 segments_got: Arc::new(Mutex::new(vec![])),
176 segments_acks: Arc::new(Mutex::new(HashSet::new())),
177 last_active: Utc::now(),
178 checks_failure_count: 0
179 };
180
181 self.pending_out_datagrams.lock().insert(datagram_id, datagram);
182 self.out_datagrams_status_links.lock().insert(datagram_id, status.clone());
183
184 let packet_bytes: Vec<u8> = packet.into();
185 self.sock.sock_send(packet_bytes, address);
186
187 Ok(status.clone())
188 }
189 }
190}