1use std::{
2 mem::MaybeUninit,
3 net::{SocketAddr, ToSocketAddrs},
4 time::{Duration, SystemTime, UNIX_EPOCH},
5};
6
7use socket2::{Domain, Protocol, SockAddr, Socket, Type};
8
9use crate::common::{adress::Adress, packets::Packets, FromRawSock, IntoRawSock, RawSock};
10
11use super::TConnection;
12
13pub struct Response<T, R> {
14 pub connection: T,
15 pub packets: Packets,
16 pub fn_has: fn(&T, &Packets) -> bool,
17 pub fn_get: fn(T, Packets) -> R,
18}
19
20impl<T, R> Response<T, R> {
21 pub fn has(&self) -> bool {
22 (self.fn_has)(&self.connection, &self.packets)
23 }
24
25 pub fn get(self) -> R {
26 while !self.has() {
27 std::thread::sleep(Duration::from_millis(0));
28 }
29 (self.fn_get)(self.connection, self.packets)
30 }
31}
32
33pub enum RequestStage {
34 NewRequest(NewRequest),
35 NewRequestResponse(NewRequestResponse),
36 NewRequestFinal(NewRequestFinal),
37 ConnectOn(ConnectOn),
38}
39
40pub struct NewRequest {
41 pub connection: Box<dyn TConnection>,
42 pub from: Adress,
43 pub secret: String,
44}
45
46impl NewRequest {
47 pub fn accept(self, accept: bool) -> Response<Box<dyn TConnection>, NewRequestFinal> {
48 self.connection.request_response(&self.from, accept)
49 }
50}
51
52pub struct NewRequestResponse {
53 pub connection: Box<dyn TConnection>,
54 pub from: Adress,
55 pub accept: bool,
56 pub secret: String,
57}
58
59impl NewRequestResponse {
60 pub fn add_port(&self, port: u16) {
61 self.connection.add_port(port)
62 }
63
64 pub fn accept(
66 self,
67 accept: bool,
68 time_offset: Option<u128>,
69 ) -> Response<Box<dyn TConnection>, ConnectOn> {
70 self.connection
71 .request_final(&self.from, accept, time_offset)
72 }
73}
74
75pub struct NewRequestFinal {
76 pub connection: Box<dyn TConnection>,
77 pub from: Adress,
78 pub accept: bool,
79}
80
81impl NewRequestFinal {
82 pub fn add_port(&self, port: u16) {
83 self.connection.add_port(port)
84 }
85}
86
87pub struct ConnectOn {
88 pub connection: Box<dyn TConnection + Send>,
89 pub adress: Adress,
90 pub to: String,
91 pub port: u16,
92 pub time: u128,
93}
94
95impl std::fmt::Debug for ConnectOn {
96 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97 f.debug_struct("ConnectOn")
98 .field("adress", &self.adress)
99 .field("to", &self.to)
100 .field("port", &self.port)
101 .field("time", &self.time)
102 .finish()
103 }
104}
105
106#[derive(Debug)]
107pub enum ConnectOnError {
108 CannotBind,
109 CannotSetNonBlocking,
110 TimoutIsLesTheResend,
111 StageOneFailed,
112 StageTwoFailed,
113}
114
115#[derive(Debug)]
116pub struct Conn {
117 my_adress: SocketAddr,
118 addr: SocketAddr,
119 port: u16,
120 fd: RawSock,
121 pub socket: Socket,
122 pub had_upnp: bool,
123}
124
125impl Conn {
126 pub fn fd(&self) -> RawSock {
127 self.fd
128 }
129
130 pub fn addr(&self) -> SocketAddr {
131 self.addr
132 }
133
134 pub fn my_addr(&self) -> SocketAddr {
135 self.my_adress
136 }
137
138 pub fn port(&self) -> u16 {
139 self.port
140 }
141
142 pub fn socket(&self) -> &Socket {
143 &self.socket
144 }
145
146 pub fn mut_socket(&mut self) -> &mut Socket {
147 &mut self.socket
148 }
149}
150
151impl std::ops::Deref for Conn {
152 type Target = Socket;
153
154 fn deref(&self) -> &Self::Target {
155 &self.socket
156 }
157}
158
159impl std::ops::DerefMut for Conn {
160 fn deref_mut(&mut self) -> &mut Self::Target {
161 &mut self.socket
162 }
163}
164
165impl Drop for Conn {
166 fn drop(&mut self) {
167 if self.had_upnp {
168 if let Ok(upnp_gateway) = igd::search_gateway(igd::SearchOptions::default()) {
169 if let SocketAddr::V4(_) = self.my_adress {
170 let _ = upnp_gateway.remove_port(igd::PortMappingProtocol::UDP, self.port);
171 }
172 }
173 }
174 }
175}
176
177impl ConnectOn {
178 pub fn connect(
180 self,
181 timeout: Duration,
182 resend: Duration,
183 nonblocking: bool,
184 ) -> Result<Conn, ConnectOnError> {
185 if timeout < resend {
186 return Err(ConnectOnError::TimoutIsLesTheResend);
187 }
188
189 let local_adress = local_ip_address::local_ip().unwrap();
190 let addr = self.to.to_socket_addrs().unwrap().next().unwrap();
191 let my_addr = format!("{}:{}", local_adress, self.port)
192 .to_socket_addrs()
193 .unwrap()
194 .next()
195 .unwrap();
196
197 let sock_my_addr = SockAddr::from(my_addr);
198 let sock_addr = SockAddr::from(addr);
199
200 println!("SockAddr: {}", sock_addr.as_socket().unwrap());
201
202 let socket = Socket::new(
203 Domain::for_address(addr),
204 Type::DGRAM,
205 Some(Protocol::from(0)),
206 )
207 .unwrap();
208 let fd = socket.into_raw();
209 let mut conn = Conn {
210 my_adress: my_addr,
211 addr,
212 fd,
213 port: self.port,
214 socket: Socket::from_raw(fd),
215 had_upnp: false,
216 };
217 let Ok(_) = conn.bind(&sock_my_addr) else{return Err(ConnectOnError::CannotBind)};
218 let Ok(_) = conn.set_nonblocking(nonblocking) else {return Err(ConnectOnError::CannotSetNonBlocking)};
219 let _ = conn.set_read_timeout(Some(resend));
220 let _ = conn.set_write_timeout(Some(resend));
221
222 'try_to_port_forword: {
223 let mut n = natpmp::Natpmp::new().unwrap();
224 n.send_port_mapping_request(natpmp::Protocol::UDP, self.port, self.port, 30)
225 .unwrap();
226
227 loop {
228 match n.read_response_or_retry() {
229 Ok(ok) => match ok {
230 natpmp::Response::UDP(res) => {
231 println!(
232 "PMP Open: public: {}, private: {}, lifetime: {:?}",
233 res.public_port(),
234 res.private_port(),
235 res.lifetime()
236 );
237 break 'try_to_port_forword;
238 }
239 _ => {
240 println!("PMP Failed: {:?}", ok);
241 break;
242 }
243 },
244 Err(err) => {
245 std::thread::sleep(Duration::from_millis(500));
246 match err {
247 natpmp::Error::NATPMP_TRYAGAIN => {}
248 _ => {
249 println!("PMP Error: {:?}", err);
250 break;
251 }
252 }
253 }
254 }
255 }
256
257 if let Ok(upnp_gateway) = igd::search_gateway(igd::SearchOptions::default()) {
258 if let SocketAddr::V4(ip) = my_addr {
259 let res = upnp_gateway.add_port(
260 igd::PortMappingProtocol::UDP,
261 self.port,
262 ip,
263 30,
264 "RelayMan",
265 );
266
267 match res {
268 Ok(_) => {
269 println!("UPNP Open port: {} for: {}", self.port, my_addr);
270 conn.had_upnp = true;
271 break 'try_to_port_forword;
272 }
273 Err(err) => println!("UPNP Error: {:?}", err),
274 }
275 }
276 } else {
277 println!("No UPNP gateway");
278 }
279 }
280
281 while SystemTime::now()
282 .duration_since(UNIX_EPOCH)
283 .unwrap()
284 .as_nanos()
285 < self.time
286 {}
287
288 println!("Start");
289
290 let time = SystemTime::now();
291 let mut time_send = time;
292
293 let mut buffer = [MaybeUninit::new(0); 4];
294 let message = [1, 4, 21, 6];
295
296 let _ = conn.send_to(&message, &sock_addr);
299
300 loop {
301 if time.elapsed().unwrap() > timeout {
302 return Err(ConnectOnError::StageOneFailed);
303 }
304
305 if let Ok((len, from)) = conn.recv_from(&mut buffer) {
306 if from.as_socket().unwrap() == sock_addr.as_socket().unwrap()
307 && unsafe { std::mem::transmute::<&[MaybeUninit<u8>], &[u8]>(&buffer[0..len]) }
308 == message
309 {
310 conn.connect(&sock_addr).unwrap();
311 println!("First stage succesful!");
312 break;
313 }
314 }
315
316 if time_send.elapsed().unwrap() > resend {
317 time_send = SystemTime::now();
318 let _ = conn.send_to(&message, &sock_addr);
319 }
320 }
321
322 let message = [21, 20, 20, 21];
323 let time = SystemTime::now();
324 let mut time_send = time;
325 let _ = conn.send(&message);
326
327 loop {
328 if time.elapsed().unwrap() > timeout {
329 return Err(ConnectOnError::StageTwoFailed);
330 }
331
332 if let Ok(len) = conn.recv(&mut buffer) {
333 let buffer =
334 unsafe { std::mem::transmute::<&[MaybeUninit<u8>], &[u8]>(&buffer[0..len]) };
335 if buffer == message {
336 break;
337 }
338 }
339
340 if time_send.elapsed().unwrap() > resend {
341 time_send = SystemTime::now();
342 let _ = conn.send(&message);
343 }
344 }
345
346 Ok(conn)
347 }
348}
349
350pub struct SearchResponse {
351 pub adresses: Vec<Adress>,
352}