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