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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#![no_std]
extern crate alloc;
#[macro_use]
extern crate lazy_static;
mod datagram;
mod history;
mod sender;
mod socket;
use alloc::boxed::Box;
use alloc::collections::btree_map::BTreeMap;
use alloc::sync::Arc;
use datagram::{Datagram, Field};
use history::History;
pub use sender::Cfg;
use sender::Sender;
pub use socket::{Addr, Socket};
use spin::RwLock;
use unmp::net::{self, Id};
use unmp::protocol::{protocols, Protocol};
pub const PROTOCOL_ID: u8 = 1;
pub const PORT_ALL: u8 = 0xFF;
lazy_static! {
static ref INDEX: RwLock<u16> = RwLock::new(0);
static ref LISTENERS: RwLock<BTreeMap<u8, Box<dyn Socket + Send + Sync>>> = RwLock::new(BTreeMap::new());
static ref SENDER: RwLock<Sender> = RwLock::new(Sender::new());
static ref HISTORY: RwLock<History> = RwLock::new(History::new());
}
struct ProtocolEtp {}
impl Protocol for ProtocolEtp {
fn id(&self) -> u8 {
PROTOCOL_ID
}
fn recv(&self, remote: &Id, data: &[u8]) {
let datagram = Datagram::try_from_buf(data);
if let Ok(datagram) = datagram {
if datagram.control < 0x80 {
let mut is_repeat = false;
if datagram.control & (1 << 1) == (1 << 1) {
let mut history = HISTORY.write();
if history.has(remote, datagram.index) {
is_repeat = true;
} else {
history.add(remote, datagram.index);
}
}
if datagram.control & (1 << 0) == (1 << 0) {
let mut res = Datagram::new();
res.set_var(Field::Control, &[0x81 | (is_repeat as u8) << 1]);
res.set_var(
Field::Index,
&[(datagram.index >> 8) as u8, datagram.index as u8],
);
res.set_var(Field::Srcport, &[datagram.dstport]);
res.set_var(Field::Dstport, &[datagram.srcport]);
res.set_var(Field::Body, &[]);
let buf = res.to_buf();
net::send(PROTOCOL_ID, &buf, Some(remote), None);
}
if is_repeat {
return;
}
let addr = Addr(remote.clone(), datagram.srcport);
let listeners = LISTENERS.read();
if let Some(listener) = listeners.get(&PORT_ALL) {
listener.recv_handle(&addr, &datagram.body);
}
if let Some(listener) = listeners.get(&datagram.dstport) {
listener.recv_handle(&addr, &datagram.body);
}
} else {
let mut sender = SENDER.write();
sender.finish(datagram.index);
}
}
}
}
pub fn init() {
let protocol = ProtocolEtp {};
protocols::add_protocol(Arc::new(protocol));
}
pub fn listen(listener: Box<dyn Socket + Send + Sync>) {
let mut listeners = LISTENERS.write();
listeners.insert(listener.port(), listener);
}
pub fn send(port: u8, dst: &Addr, body: &[u8], cfg: Cfg) {
let mut datagram = Datagram::new();
datagram.set_var(Field::Control, &[3]);
let index = {
let mut index = INDEX.write();
*index += 1;
*index
};
datagram.set_var(Field::Index, &[(index >> 8) as u8, index as u8]);
datagram.set_var(Field::Srcport, &[port]);
datagram.set_var(Field::Dstport, &[dst.1]);
datagram.set_var(Field::Body, body);
let buf = datagram.to_buf();
let mut sender = SENDER.write();
(*sender).send(index, buf, dst.0, cfg);
}
pub fn resend() {
let mut sender = SENDER.write();
(*sender).resend();
}