clia_turn/relay/
relay_range.rs1use std::net::IpAddr;
2
3use async_trait::async_trait;
4use util::vnet::net::*;
5
6use super::*;
7use crate::error::*;
8
9pub struct RelayAddressGeneratorRanges {
11 pub relay_address: IpAddr,
13
14 pub min_port: u16,
16
17 pub max_port: u16,
19
20 pub max_retries: u16,
22
23 pub address: String,
25
26 pub net: Arc<Net>,
27}
28
29#[async_trait]
30impl RelayAddressGenerator for RelayAddressGeneratorRanges {
31 fn validate(&self) -> Result<()> {
32 if self.min_port == 0 {
33 Err(Error::ErrMinPortNotZero)
34 } else if self.max_port == 0 {
35 Err(Error::ErrMaxPortNotZero)
36 } else if self.max_port < self.min_port {
37 Err(Error::ErrMaxPortLessThanMinPort)
38 } else if self.address.is_empty() {
39 Err(Error::ErrListeningAddressInvalid)
40 } else {
41 Ok(())
42 }
43 }
44
45 async fn allocate_conn(
46 &self,
47 use_ipv4: bool,
48 requested_port: u16,
49 ) -> Result<(Arc<dyn Conn + Send + Sync>, SocketAddr)> {
50 let max_retries = if self.max_retries == 0 {
51 10
52 } else {
53 self.max_retries
54 };
55
56 if requested_port != 0 {
57 let addr = self
58 .net
59 .resolve_addr(use_ipv4, &format!("{}:{}", self.address, requested_port))
60 .await?;
61 let conn = self.net.bind(addr).await?;
62 let mut relay_addr = conn.local_addr()?;
63 relay_addr.set_ip(self.relay_address);
64 return Ok((conn, relay_addr));
65 }
66
67 for _ in 0..max_retries {
68 let port = self.min_port + rand::random::<u16>() % (self.max_port - self.min_port + 1);
69 let addr = self
70 .net
71 .resolve_addr(use_ipv4, &format!("{}:{}", self.address, port))
72 .await?;
73 let conn = match self.net.bind(addr).await {
74 Ok(conn) => conn,
75 Err(_) => continue,
76 };
77
78 let mut relay_addr = conn.local_addr()?;
79 relay_addr.set_ip(self.relay_address);
80 return Ok((conn, relay_addr));
81 }
82
83 Err(Error::ErrMaxRetriesExceeded)
84 }
85}