torrust_tracker/servers/udp/server/
receiver.rs1use std::cell::RefCell;
2use std::net::SocketAddr;
3use std::pin::Pin;
4use std::sync::Arc;
5use std::task::{Context, Poll};
6
7use futures::Stream;
8
9use super::bound_socket::BoundSocket;
10use super::RawRequest;
11use crate::shared::bit_torrent::tracker::udp::MAX_PACKET_SIZE;
12
13pub struct Receiver {
14 pub socket: Arc<BoundSocket>,
15 data: RefCell<[u8; MAX_PACKET_SIZE]>,
16}
17
18impl Receiver {
19 #[must_use]
20 pub fn new(bound_socket: Arc<BoundSocket>) -> Self {
21 Receiver {
22 socket: bound_socket,
23 data: RefCell::new([0; MAX_PACKET_SIZE]),
24 }
25 }
26
27 pub fn bound_socket_address(&self) -> SocketAddr {
28 self.socket.address()
29 }
30}
31
32impl Stream for Receiver {
33 type Item = std::io::Result<RawRequest>;
34
35 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
36 let mut buf = *self.data.borrow_mut();
37 let mut buf = tokio::io::ReadBuf::new(&mut buf);
38
39 let Poll::Ready(ready) = self.socket.poll_recv_from(cx, &mut buf) else {
40 return Poll::Pending;
41 };
42
43 let res = match ready {
44 Ok(from) => {
45 let payload = buf.filled().to_vec();
46 let request = RawRequest { payload, from };
47 Some(Ok(request))
48 }
49 Err(err) => Some(Err(err)),
50 };
51
52 Poll::Ready(res)
53 }
54}