1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use futures::{ready, Future};
use std::{
io,
net::SocketAddr,
task::{Context, Poll},
};
use tokio::{io::ReadBuf, net::UdpSocket};
use crate::GenTransport;
pub type Transport = GenTransport<Provider>;
pub struct Provider {
socket: UdpSocket,
socket_recv_buffer: Vec<u8>,
next_packet_out: Option<(Vec<u8>, SocketAddr)>,
}
impl super::Provider for Provider {
type IfWatcher = if_watch::tokio::IfWatcher;
fn from_socket(socket: std::net::UdpSocket) -> std::io::Result<Self> {
let socket = UdpSocket::from_std(socket)?;
Ok(Provider {
socket,
socket_recv_buffer: vec![0; super::RECEIVE_BUFFER_SIZE],
next_packet_out: None,
})
}
fn poll_send_flush(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
let (data, addr) = match self.next_packet_out.as_ref() {
Some(pending) => pending,
None => return Poll::Ready(Ok(())),
};
match self.socket.poll_send_to(cx, data.as_slice(), *addr) {
Poll::Ready(result) => {
self.next_packet_out = None;
Poll::Ready(result.map(|_| ()))
}
Poll::Pending => Poll::Pending,
}
}
fn poll_recv_from(&mut self, cx: &mut Context<'_>) -> Poll<io::Result<(Vec<u8>, SocketAddr)>> {
let Self {
socket,
socket_recv_buffer,
..
} = self;
let mut read_buf = ReadBuf::new(socket_recv_buffer.as_mut_slice());
let packet_src = ready!(socket.poll_recv_from(cx, &mut read_buf)?);
let bytes = read_buf.filled().to_vec();
Poll::Ready(Ok((bytes, packet_src)))
}
fn start_send(&mut self, data: Vec<u8>, addr: SocketAddr) {
self.next_packet_out = Some((data, addr));
}
fn spawn(future: impl Future<Output = ()> + Send + 'static) {
tokio::spawn(future);
}
fn new_if_watcher() -> io::Result<Self::IfWatcher> {
if_watch::tokio::IfWatcher::new()
}
fn poll_if_event(
watcher: &mut Self::IfWatcher,
cx: &mut Context<'_>,
) -> Poll<io::Result<if_watch::IfEvent>> {
watcher.poll_if_event(cx)
}
}