1use log::{debug, warn};
2use std::collections::HashMap;
3use std::net::SocketAddr;
4use std::ops::Add;
5use std::time::{Duration, Instant};
6
7use stun::attributes::*;
8use stun::error_code::*;
9use stun::fingerprint::*;
10use stun::integrity::*;
11use stun::message::*;
12use stun::textattrs::*;
13
14use super::permission::*;
15use super::transaction::*;
16use crate::proto;
17
18use crate::client::binding::BindingState;
19use crate::client::{Client, Event, RelayedAddr};
20use shared::error::{Error, Result};
21
22const PERM_REFRESH_INTERVAL: Duration = Duration::from_secs(120);
23const PERM_LIFETIME: Duration = Duration::from_secs(300);
26const MAX_RETRY_ATTEMPTS: u16 = 3;
27const MIN_ALLOC_REFRESH_INTERVAL: Duration = Duration::from_secs(1);
38
39pub(crate) struct RelayState {
41 pub(crate) relayed_addr: RelayedAddr,
42 pub(crate) integrity: MessageIntegrity,
43 pub(crate) nonce: Nonce,
44 pub(crate) lifetime: Duration,
45 perm_map: HashMap<SocketAddr, Permission>,
46 refresh_alloc_timer: Instant,
47 refresh_perms_timer: Instant,
48}
49
50impl RelayState {
51 pub(super) fn new(
52 relayed_addr: RelayedAddr,
53 integrity: MessageIntegrity,
54 nonce: Nonce,
55 lifetime: Duration,
56 ) -> Self {
57 debug!("initial lifetime: {} seconds", lifetime.as_secs());
58
59 Self {
60 relayed_addr,
61 integrity,
62 nonce,
63 lifetime,
64 perm_map: HashMap::new(),
65 refresh_alloc_timer: Instant::now().add(lifetime / 2),
66 refresh_perms_timer: Instant::now().add(PERM_REFRESH_INTERVAL),
67 }
68 }
69
70 pub(super) fn set_nonce_from_msg(&mut self, msg: &Message) {
71 match Nonce::get_from_as(msg, ATTR_NONCE) {
73 Ok(nonce) => {
74 self.nonce = nonce;
75 debug!("refresh allocation: 438, got new nonce.");
76 }
77 Err(_) => warn!("refresh allocation: 438 but no nonce."),
78 }
79 }
80}
81
82pub struct Relay<'a> {
87 pub(crate) relayed_addr: RelayedAddr,
88 pub(crate) client: &'a mut Client,
89}
90
91impl Relay<'_> {
92 pub fn create_permission(&mut self, peer_addr: SocketAddr) -> Result<Option<TransactionId>> {
102 if let Some(relay) = self.client.relays.get_mut(&self.relayed_addr) {
103 relay
104 .perm_map
105 .entry(peer_addr)
106 .or_insert_with(Permission::default);
107 if let Some(perm) = relay.perm_map.get(&peer_addr)
108 && perm.state() == PermState::Idle
109 {
110 return Ok(Some(
111 self.create_permissions(&[peer_addr], Some(peer_addr))?,
112 ));
113 }
114 Ok(None)
115 } else {
116 Err(Error::ErrConnClosed)
117 }
118 }
119
120 pub(crate) fn poll_timeout(&self) -> Option<Instant> {
121 if let Some(relay) = self.client.relays.get(&self.relayed_addr) {
122 if relay.refresh_alloc_timer < relay.refresh_perms_timer {
123 Some(relay.refresh_alloc_timer)
124 } else {
125 Some(relay.refresh_perms_timer)
126 }
127 } else {
128 None
129 }
130 }
131
132 pub(crate) fn handle_timeout(&mut self, now: Instant) {
133 let (refresh_alloc_timer, refresh_perms_timer) =
134 if let Some(relay) = self.client.relays.get_mut(&self.relayed_addr) {
135 let refresh_alloc_timer = if relay.refresh_alloc_timer <= now {
136 let step = (relay.lifetime / 2).max(MIN_ALLOC_REFRESH_INTERVAL);
139 relay.refresh_alloc_timer = now.add(step);
140 Some(relay.lifetime)
141 } else {
142 None
143 };
144
145 let refresh_perms_timer = if relay.refresh_perms_timer <= now {
146 relay.refresh_perms_timer = now.add(PERM_REFRESH_INTERVAL);
147 true
148 } else {
149 false
150 };
151
152 (refresh_alloc_timer, refresh_perms_timer)
153 } else {
154 (None, false)
155 };
156
157 if let Some(lifetime) = refresh_alloc_timer {
158 let _ = self.refresh_allocation(lifetime);
159 }
160 if refresh_perms_timer {
161 let _ = self.refresh_permissions();
162 }
163 }
164
165 pub fn send_to(&mut self, p: &[u8], peer_addr: SocketAddr) -> Result<()> {
173 let result = if let Some(relay) = self.client.relays.get_mut(&self.relayed_addr) {
175 if let Some(perm) = relay.perm_map.get_mut(&peer_addr) {
176 if perm.state() != PermState::Permitted {
177 Err(Error::ErrNoPermission)
178 } else {
179 Ok((relay.integrity.clone(), relay.nonce.clone()))
180 }
181 } else {
182 Err(Error::ErrNoPermission)
183 }
184 } else {
185 Err(Error::ErrConnClosed)
186 };
187
188 let (integrity, nonce) = result?;
189
190 self.send(p, peer_addr, integrity, nonce)
191 }
192
193 fn send(
194 &mut self,
195 p: &[u8],
196 peer_addr: SocketAddr,
197 integrity: MessageIntegrity,
198 nonce: Nonce,
199 ) -> Result<()> {
200 let channel_number = {
201 let (bind_st, bind_at, bind_number, bind_addr) = {
202 let b = if let Some(b) = self.client.binding_mgr.find_by_addr(&peer_addr) {
203 b
204 } else {
205 self.client
206 .binding_mgr
207 .create(peer_addr)
208 .ok_or_else(|| Error::Other("Addr not found".to_owned()))?
209 };
210 (b.state(), b.refreshed_at(), b.number, b.addr)
211 };
212
213 if bind_st == BindingState::Idle
214 || bind_st == BindingState::Request
215 || bind_st == BindingState::Failed
216 {
217 if bind_st == BindingState::Idle {
221 if let Some(b) = self.client.binding_mgr.get_by_addr(&bind_addr) {
222 b.set_state(BindingState::Request);
223 }
224 self.channel_bind(self.relayed_addr, bind_addr, bind_number, nonce, integrity)?;
225 }
226
227 let mut msg = Message::new();
229 msg.build(&[
230 Box::new(TransactionId::new()),
231 Box::new(MessageType::new(METHOD_SEND, CLASS_INDICATION)),
232 Box::new(proto::data::Data(p.to_vec())),
233 Box::new(proto::peeraddr::PeerAddress {
234 ip: peer_addr.ip(),
235 port: peer_addr.port(),
236 }),
237 Box::new(FINGERPRINT),
238 ])?;
239
240 self.client
242 .write_to(&msg.raw, self.client.turn_server_addr()?);
243 return Ok(());
244 }
245
246 if bind_st == BindingState::Ready
249 && Instant::now()
250 .checked_duration_since(bind_at)
251 .unwrap_or_else(|| Duration::from_secs(0))
252 > PERM_LIFETIME
253 {
254 if let Some(b) = self.client.binding_mgr.get_by_addr(&bind_addr) {
255 b.set_state(BindingState::Refresh);
256 }
257 self.channel_bind(self.relayed_addr, bind_addr, bind_number, nonce, integrity)?;
258 }
259
260 bind_number
261 };
262
263 self.send_channel_data(p, channel_number)
265 }
266
267 pub fn close(&mut self) -> Result<()> {
275 self.refresh_allocation(Duration::from_secs(0))
276 }
277
278 fn create_permissions(
279 &mut self,
280 peer_addrs: &[SocketAddr],
281 peer_addr_opt: Option<SocketAddr>,
282 ) -> Result<TransactionId> {
283 let (username, realm) = (self.client.username(), self.client.realm());
284 if let Some(relay) = self.client.relays.get_mut(&self.relayed_addr) {
285 let msg = {
286 let mut setters: Vec<Box<dyn Setter>> = vec![
287 Box::new(TransactionId::new()),
288 Box::new(MessageType::new(METHOD_CREATE_PERMISSION, CLASS_REQUEST)),
289 ];
290
291 for addr in peer_addrs {
292 setters.push(Box::new(proto::peeraddr::PeerAddress {
293 ip: addr.ip(),
294 port: addr.port(),
295 }));
296 }
297
298 setters.push(Box::new(username));
299 setters.push(Box::new(realm));
300 setters.push(Box::new(relay.nonce.clone()));
301 setters.push(Box::new(relay.integrity.clone()));
302 setters.push(Box::new(FINGERPRINT));
303
304 let mut msg = Message::new();
305 msg.build(&setters)?;
306 msg
307 };
308
309 Ok(self.client.perform_transaction(
310 &msg,
311 self.client.turn_server_addr()?,
312 TransactionType::CreatePermissionRequest(self.relayed_addr, peer_addr_opt),
313 ))
314 } else {
315 Err(Error::ErrConnClosed)
316 }
317 }
318
319 pub(super) fn handle_create_permission_response(
320 &mut self,
321 res: Message,
322 peer_addr_opt: Option<SocketAddr>,
323 ) -> Result<()> {
324 if let Some(relay) = self.client.relays.get_mut(&self.relayed_addr) {
325 if res.typ.class == CLASS_ERROR_RESPONSE {
326 let mut code = ErrorCodeAttribute::default();
327 let result = code.get_from(&res);
328 let err = if result.is_err() {
329 Error::Other(format!("{}", res.typ))
330 } else if code.code == CODE_STALE_NONCE {
331 relay.set_nonce_from_msg(&res);
332 Error::ErrTryAgain
333 } else {
334 Error::Other(format!("{} (error {})", res.typ, code))
335 };
336 if let Some(peer_addr) = peer_addr_opt {
337 self.client
338 .events
339 .push_back(Event::CreatePermissionError(res.transaction_id, err));
340 relay.perm_map.remove(&peer_addr);
341 }
342 } else if let Some(peer_addr) = peer_addr_opt
343 && let Some(perm) = relay.perm_map.get_mut(&peer_addr)
344 {
345 perm.set_state(PermState::Permitted);
346 self.client
347 .events
348 .push_back(Event::CreatePermissionResponse(
349 res.transaction_id,
350 peer_addr,
351 ));
352 }
353
354 Ok(())
355 } else {
356 Err(Error::ErrConnClosed)
357 }
358 }
359
360 pub(super) fn refresh_allocation(&mut self, lifetime: Duration) -> Result<()> {
361 let (username, realm) = (self.client.username(), self.client.realm());
362 if let Some(relay) = self.client.relays.get_mut(&self.relayed_addr) {
363 let mut msg = Message::new();
364 msg.build(&[
365 Box::new(TransactionId::new()),
366 Box::new(MessageType::new(METHOD_REFRESH, CLASS_REQUEST)),
367 Box::new(proto::lifetime::Lifetime(lifetime)),
368 Box::new(username),
369 Box::new(realm),
370 Box::new(relay.nonce.clone()),
371 Box::new(relay.integrity.clone()),
372 Box::new(FINGERPRINT),
373 ])?;
374
375 let _ = self.client.perform_transaction(
376 &msg,
377 self.client.turn_server_addr()?,
378 TransactionType::RefreshRequest(self.relayed_addr),
379 );
380
381 Ok(())
382 } else {
383 Err(Error::ErrConnClosed)
384 }
385 }
386
387 pub(super) fn handle_refresh_allocation_response(&mut self, res: Message) -> Result<()> {
388 let mut released = false;
389 let result = if let Some(relay) = self.client.relays.get_mut(&self.relayed_addr) {
390 if res.typ.class == CLASS_ERROR_RESPONSE {
391 let mut code = ErrorCodeAttribute::default();
392 let result = code.get_from(&res);
393 if result.is_err() {
394 Err(Error::Other(format!("{}", res.typ)))
395 } else if code.code == CODE_STALE_NONCE {
396 relay.set_nonce_from_msg(&res);
397 Ok(())
399 } else {
400 Err(Error::Other(format!("{} (error {})", res.typ, code)))
401 }
402 } else {
403 let mut updated_lifetime = proto::lifetime::Lifetime::default();
405 updated_lifetime.get_from(&res)?;
406
407 relay.lifetime = updated_lifetime.0;
408 debug!("updated lifetime: {} seconds", relay.lifetime.as_secs());
409
410 released = relay.lifetime.is_zero();
415
416 Ok(())
417 }
418 } else {
419 Err(Error::ErrConnClosed)
420 };
421
422 if released {
423 self.client.relays.remove(&self.relayed_addr);
424 debug!("allocation released; relay {} dropped", self.relayed_addr);
425 }
426
427 result
428 }
429
430 pub(super) fn refresh_permissions(&mut self) -> Result<()> {
431 if let Some(relay) = self.client.relays.get_mut(&self.relayed_addr) {
432 #[allow(clippy::map_clone)]
433 let addrs: Vec<SocketAddr> = relay.perm_map.keys().map(|addr| *addr).collect();
434 if addrs.is_empty() {
435 debug!("no permission to refresh");
436 return Ok(());
437 }
438 let _ = self.create_permissions(&addrs, None)?;
439 Ok(())
440 } else {
441 Err(Error::ErrConnClosed)
442 }
443 }
444
445 fn channel_bind(
446 &mut self,
447 relayed_addr: RelayedAddr,
448 bind_addr: SocketAddr,
449 bind_number: u16,
450 nonce: Nonce,
451 integrity: MessageIntegrity,
452 ) -> Result<()> {
453 let (msg, turn_server_addr) = {
454 let setters: Vec<Box<dyn Setter>> = vec![
455 Box::new(TransactionId::new()),
456 Box::new(MessageType::new(METHOD_CHANNEL_BIND, CLASS_REQUEST)),
457 Box::new(proto::peeraddr::PeerAddress {
458 ip: bind_addr.ip(),
459 port: bind_addr.port(),
460 }),
461 Box::new(proto::channum::ChannelNumber(bind_number)),
462 Box::new(self.client.username()),
463 Box::new(self.client.realm()),
464 Box::new(nonce),
465 Box::new(integrity),
466 Box::new(FINGERPRINT),
467 ];
468
469 let mut msg = Message::new();
470 msg.build(&setters)?;
471
472 (msg, self.client.turn_server_addr()?)
473 };
474
475 debug!("UDPConn.bind call PerformTransaction 1");
476 let _ = self.client.perform_transaction(
477 &msg,
478 turn_server_addr,
479 TransactionType::ChannelBindRequest(relayed_addr, bind_addr),
480 );
481
482 Ok(())
483 }
484
485 pub(super) fn handle_channel_bind_response(
486 &mut self,
487 res: Message,
488 bind_addr: SocketAddr,
489 ) -> Result<()> {
490 if let Some(relay) = self.client.relays.get_mut(&self.relayed_addr) {
491 let result = if res.typ.class == CLASS_ERROR_RESPONSE {
492 let mut code = ErrorCodeAttribute::default();
493 let result = code.get_from(&res);
494 if result.is_err() {
495 Err(Error::Other(format!("{}", res.typ)))
496 } else if code.code == CODE_STALE_NONCE {
497 relay.set_nonce_from_msg(&res);
498 Err(Error::ErrTryAgain)
499 } else {
500 Err(Error::Other(format!("{} (error {})", res.typ, code)))
501 }
502 } else if res.typ != MessageType::new(METHOD_CHANNEL_BIND, CLASS_SUCCESS_RESPONSE) {
503 Err(Error::ErrUnexpectedResponse)
504 } else {
505 Ok(())
506 };
507
508 if let Err(err) = result {
509 if Error::ErrUnexpectedResponse != err {
510 self.client.binding_mgr.delete_by_addr(&bind_addr);
511 } else if let Some(b) = self.client.binding_mgr.get_by_addr(&bind_addr) {
512 b.set_state(BindingState::Failed);
513 }
514
515 warn!("bind() failed: {}", err);
517 } else if let Some(b) = self.client.binding_mgr.get_by_addr(&bind_addr) {
518 b.set_refreshed_at(Instant::now());
519 b.set_state(BindingState::Ready);
520 debug!("channel binding successful: {}", bind_addr);
521 }
522 Ok(())
523 } else {
524 Err(Error::ErrConnClosed)
525 }
526 }
527
528 fn send_channel_data(&mut self, data: &[u8], channel_number: u16) -> Result<()> {
529 let mut ch_data = proto::chandata::ChannelData {
530 data: data.to_vec(),
531 number: proto::channum::ChannelNumber(channel_number),
532 ..Default::default()
533 };
534 ch_data.encode();
535
536 self.client
537 .write_to(&ch_data.raw, self.client.turn_server_addr()?);
538
539 Ok(())
540 }
541}