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) = if let Some(relay) =
134 self.client.relays.get_mut(&self.relayed_addr)
135 {
136 let refresh_alloc_timer = if relay.refresh_alloc_timer <= now {
137 let step = (relay.lifetime / 2).max(MIN_ALLOC_REFRESH_INTERVAL);
140 relay.refresh_alloc_timer = relay.refresh_alloc_timer.add(step);
141 Some(relay.lifetime)
142 } else {
143 None
144 };
145
146 let refresh_perms_timer = if relay.refresh_perms_timer <= now {
147 relay.refresh_perms_timer = relay.refresh_perms_timer.add(PERM_REFRESH_INTERVAL);
148 true
149 } else {
150 false
151 };
152
153 (refresh_alloc_timer, refresh_perms_timer)
154 } else {
155 (None, false)
156 };
157
158 if let Some(lifetime) = refresh_alloc_timer {
159 let _ = self.refresh_allocation(lifetime);
160 }
161 if refresh_perms_timer {
162 let _ = self.refresh_permissions();
163 }
164 }
165
166 pub fn send_to(&mut self, p: &[u8], peer_addr: SocketAddr) -> Result<()> {
174 let result = if let Some(relay) = self.client.relays.get_mut(&self.relayed_addr) {
176 if let Some(perm) = relay.perm_map.get_mut(&peer_addr) {
177 if perm.state() != PermState::Permitted {
178 Err(Error::ErrNoPermission)
179 } else {
180 Ok((relay.integrity.clone(), relay.nonce.clone()))
181 }
182 } else {
183 Err(Error::ErrNoPermission)
184 }
185 } else {
186 Err(Error::ErrConnClosed)
187 };
188
189 let (integrity, nonce) = result?;
190
191 self.send(p, peer_addr, integrity, nonce)
192 }
193
194 fn send(
195 &mut self,
196 p: &[u8],
197 peer_addr: SocketAddr,
198 integrity: MessageIntegrity,
199 nonce: Nonce,
200 ) -> Result<()> {
201 let channel_number = {
202 let (bind_st, bind_at, bind_number, bind_addr) = {
203 let b = if let Some(b) = self.client.binding_mgr.find_by_addr(&peer_addr) {
204 b
205 } else {
206 self.client
207 .binding_mgr
208 .create(peer_addr)
209 .ok_or_else(|| Error::Other("Addr not found".to_owned()))?
210 };
211 (b.state(), b.refreshed_at(), b.number, b.addr)
212 };
213
214 if bind_st == BindingState::Idle
215 || bind_st == BindingState::Request
216 || bind_st == BindingState::Failed
217 {
218 if bind_st == BindingState::Idle {
222 if let Some(b) = self.client.binding_mgr.get_by_addr(&bind_addr) {
223 b.set_state(BindingState::Request);
224 }
225 self.channel_bind(self.relayed_addr, bind_addr, bind_number, nonce, integrity)?;
226 }
227
228 let mut msg = Message::new();
230 msg.build(&[
231 Box::new(TransactionId::new()),
232 Box::new(MessageType::new(METHOD_SEND, CLASS_INDICATION)),
233 Box::new(proto::data::Data(p.to_vec())),
234 Box::new(proto::peeraddr::PeerAddress {
235 ip: peer_addr.ip(),
236 port: peer_addr.port(),
237 }),
238 Box::new(FINGERPRINT),
239 ])?;
240
241 self.client
243 .write_to(&msg.raw, self.client.turn_server_addr()?);
244 return Ok(());
245 }
246
247 if bind_st == BindingState::Ready
250 && Instant::now()
251 .checked_duration_since(bind_at)
252 .unwrap_or_else(|| Duration::from_secs(0))
253 > PERM_LIFETIME
254 {
255 if let Some(b) = self.client.binding_mgr.get_by_addr(&bind_addr) {
256 b.set_state(BindingState::Refresh);
257 }
258 self.channel_bind(self.relayed_addr, bind_addr, bind_number, nonce, integrity)?;
259 }
260
261 bind_number
262 };
263
264 self.send_channel_data(p, channel_number)
266 }
267
268 pub fn close(&mut self) -> Result<()> {
276 self.refresh_allocation(Duration::from_secs(0))
277 }
278
279 fn create_permissions(
280 &mut self,
281 peer_addrs: &[SocketAddr],
282 peer_addr_opt: Option<SocketAddr>,
283 ) -> Result<TransactionId> {
284 let (username, realm) = (self.client.username(), self.client.realm());
285 if let Some(relay) = self.client.relays.get_mut(&self.relayed_addr) {
286 let msg = {
287 let mut setters: Vec<Box<dyn Setter>> = vec![
288 Box::new(TransactionId::new()),
289 Box::new(MessageType::new(METHOD_CREATE_PERMISSION, CLASS_REQUEST)),
290 ];
291
292 for addr in peer_addrs {
293 setters.push(Box::new(proto::peeraddr::PeerAddress {
294 ip: addr.ip(),
295 port: addr.port(),
296 }));
297 }
298
299 setters.push(Box::new(username));
300 setters.push(Box::new(realm));
301 setters.push(Box::new(relay.nonce.clone()));
302 setters.push(Box::new(relay.integrity.clone()));
303 setters.push(Box::new(FINGERPRINT));
304
305 let mut msg = Message::new();
306 msg.build(&setters)?;
307 msg
308 };
309
310 Ok(self.client.perform_transaction(
311 &msg,
312 self.client.turn_server_addr()?,
313 TransactionType::CreatePermissionRequest(self.relayed_addr, peer_addr_opt),
314 ))
315 } else {
316 Err(Error::ErrConnClosed)
317 }
318 }
319
320 pub(super) fn handle_create_permission_response(
321 &mut self,
322 res: Message,
323 peer_addr_opt: Option<SocketAddr>,
324 ) -> Result<()> {
325 if let Some(relay) = self.client.relays.get_mut(&self.relayed_addr) {
326 if res.typ.class == CLASS_ERROR_RESPONSE {
327 let mut code = ErrorCodeAttribute::default();
328 let result = code.get_from(&res);
329 let err = if result.is_err() {
330 Error::Other(format!("{}", res.typ))
331 } else if code.code == CODE_STALE_NONCE {
332 relay.set_nonce_from_msg(&res);
333 Error::ErrTryAgain
334 } else {
335 Error::Other(format!("{} (error {})", res.typ, code))
336 };
337 if let Some(peer_addr) = peer_addr_opt {
338 self.client
339 .events
340 .push_back(Event::CreatePermissionError(res.transaction_id, err));
341 relay.perm_map.remove(&peer_addr);
342 }
343 } else if let Some(peer_addr) = peer_addr_opt
344 && let Some(perm) = relay.perm_map.get_mut(&peer_addr)
345 {
346 perm.set_state(PermState::Permitted);
347 self.client
348 .events
349 .push_back(Event::CreatePermissionResponse(
350 res.transaction_id,
351 peer_addr,
352 ));
353 }
354
355 Ok(())
356 } else {
357 Err(Error::ErrConnClosed)
358 }
359 }
360
361 pub(super) fn refresh_allocation(&mut self, lifetime: Duration) -> Result<()> {
362 let (username, realm) = (self.client.username(), self.client.realm());
363 if let Some(relay) = self.client.relays.get_mut(&self.relayed_addr) {
364 let mut msg = Message::new();
365 msg.build(&[
366 Box::new(TransactionId::new()),
367 Box::new(MessageType::new(METHOD_REFRESH, CLASS_REQUEST)),
368 Box::new(proto::lifetime::Lifetime(lifetime)),
369 Box::new(username),
370 Box::new(realm),
371 Box::new(relay.nonce.clone()),
372 Box::new(relay.integrity.clone()),
373 Box::new(FINGERPRINT),
374 ])?;
375
376 let _ = self.client.perform_transaction(
377 &msg,
378 self.client.turn_server_addr()?,
379 TransactionType::RefreshRequest(self.relayed_addr),
380 );
381
382 Ok(())
383 } else {
384 Err(Error::ErrConnClosed)
385 }
386 }
387
388 pub(super) fn handle_refresh_allocation_response(&mut self, res: Message) -> Result<()> {
389 let mut released = false;
390 let result = if let Some(relay) = self.client.relays.get_mut(&self.relayed_addr) {
391 if res.typ.class == CLASS_ERROR_RESPONSE {
392 let mut code = ErrorCodeAttribute::default();
393 let result = code.get_from(&res);
394 if result.is_err() {
395 Err(Error::Other(format!("{}", res.typ)))
396 } else if code.code == CODE_STALE_NONCE {
397 relay.set_nonce_from_msg(&res);
398 Ok(())
400 } else {
401 Err(Error::Other(format!("{} (error {})", res.typ, code)))
402 }
403 } else {
404 let mut updated_lifetime = proto::lifetime::Lifetime::default();
406 updated_lifetime.get_from(&res)?;
407
408 relay.lifetime = updated_lifetime.0;
409 debug!("updated lifetime: {} seconds", relay.lifetime.as_secs());
410
411 released = relay.lifetime.is_zero();
416
417 Ok(())
418 }
419 } else {
420 Err(Error::ErrConnClosed)
421 };
422
423 if released {
424 self.client.relays.remove(&self.relayed_addr);
425 debug!("allocation released; relay {} dropped", self.relayed_addr);
426 }
427
428 result
429 }
430
431 pub(super) fn refresh_permissions(&mut self) -> Result<()> {
432 if let Some(relay) = self.client.relays.get_mut(&self.relayed_addr) {
433 #[allow(clippy::map_clone)]
434 let addrs: Vec<SocketAddr> = relay.perm_map.keys().map(|addr| *addr).collect();
435 if addrs.is_empty() {
436 debug!("no permission to refresh");
437 return Ok(());
438 }
439 let _ = self.create_permissions(&addrs, None)?;
440 Ok(())
441 } else {
442 Err(Error::ErrConnClosed)
443 }
444 }
445
446 fn channel_bind(
447 &mut self,
448 relayed_addr: RelayedAddr,
449 bind_addr: SocketAddr,
450 bind_number: u16,
451 nonce: Nonce,
452 integrity: MessageIntegrity,
453 ) -> Result<()> {
454 let (msg, turn_server_addr) = {
455 let setters: Vec<Box<dyn Setter>> = vec![
456 Box::new(TransactionId::new()),
457 Box::new(MessageType::new(METHOD_CHANNEL_BIND, CLASS_REQUEST)),
458 Box::new(proto::peeraddr::PeerAddress {
459 ip: bind_addr.ip(),
460 port: bind_addr.port(),
461 }),
462 Box::new(proto::channum::ChannelNumber(bind_number)),
463 Box::new(self.client.username()),
464 Box::new(self.client.realm()),
465 Box::new(nonce),
466 Box::new(integrity),
467 Box::new(FINGERPRINT),
468 ];
469
470 let mut msg = Message::new();
471 msg.build(&setters)?;
472
473 (msg, self.client.turn_server_addr()?)
474 };
475
476 debug!("UDPConn.bind call PerformTransaction 1");
477 let _ = self.client.perform_transaction(
478 &msg,
479 turn_server_addr,
480 TransactionType::ChannelBindRequest(relayed_addr, bind_addr),
481 );
482
483 Ok(())
484 }
485
486 pub(super) fn handle_channel_bind_response(
487 &mut self,
488 res: Message,
489 bind_addr: SocketAddr,
490 ) -> Result<()> {
491 if let Some(relay) = self.client.relays.get_mut(&self.relayed_addr) {
492 let result = if res.typ.class == CLASS_ERROR_RESPONSE {
493 let mut code = ErrorCodeAttribute::default();
494 let result = code.get_from(&res);
495 if result.is_err() {
496 Err(Error::Other(format!("{}", res.typ)))
497 } else if code.code == CODE_STALE_NONCE {
498 relay.set_nonce_from_msg(&res);
499 Err(Error::ErrTryAgain)
500 } else {
501 Err(Error::Other(format!("{} (error {})", res.typ, code)))
502 }
503 } else if res.typ != MessageType::new(METHOD_CHANNEL_BIND, CLASS_SUCCESS_RESPONSE) {
504 Err(Error::ErrUnexpectedResponse)
505 } else {
506 Ok(())
507 };
508
509 if let Err(err) = result {
510 if Error::ErrUnexpectedResponse != err {
511 self.client.binding_mgr.delete_by_addr(&bind_addr);
512 } else if let Some(b) = self.client.binding_mgr.get_by_addr(&bind_addr) {
513 b.set_state(BindingState::Failed);
514 }
515
516 warn!("bind() failed: {}", err);
518 } else if let Some(b) = self.client.binding_mgr.get_by_addr(&bind_addr) {
519 b.set_refreshed_at(Instant::now());
520 b.set_state(BindingState::Ready);
521 debug!("channel binding successful: {}", bind_addr);
522 }
523 Ok(())
524 } else {
525 Err(Error::ErrConnClosed)
526 }
527 }
528
529 fn send_channel_data(&mut self, data: &[u8], channel_number: u16) -> Result<()> {
530 let mut ch_data = proto::chandata::ChannelData {
531 data: data.to_vec(),
532 number: proto::channum::ChannelNumber(channel_number),
533 ..Default::default()
534 };
535 ch_data.encode();
536
537 self.client
538 .write_to(&ch_data.raw, self.client.turn_server_addr()?);
539
540 Ok(())
541 }
542}