webrtc_turn/relay/
relay_range.rs

1use super::*;
2use crate::errors::*;
3
4use std::net::IpAddr;
5use util::vnet::net::*;
6
7use async_trait::async_trait;
8
9// RelayAddressGeneratorRanges can be used to only allocate connections inside a defined port range
10pub struct RelayAddressGeneratorRanges {
11    // relay_address is the IP returned to the user when the relay is created
12    pub relay_address: IpAddr,
13
14    // min_port the minimum port to allocate
15    pub min_port: u16,
16
17    // max_port the maximum (inclusive) port to allocate
18    pub max_port: u16,
19
20    // max_retries the amount of tries to allocate a random port in the defined range
21    pub max_retries: u16,
22
23    // Address is passed to Listen/ListenPacket when creating the Relay
24    pub address: String,
25
26    pub net: Arc<Net>,
27}
28
29#[async_trait]
30impl RelayAddressGenerator for RelayAddressGeneratorRanges {
31    // validate confirms that the RelayAddressGenerator is properly initialized
32    fn validate(&self) -> Result<(), Error> {
33        if self.min_port == 0 {
34            Err(ERR_MIN_PORT_NOT_ZERO.to_owned())
35        } else if self.max_port == 0 {
36            Err(ERR_MAX_PORT_NOT_ZERO.to_owned())
37        } else if self.max_port < self.min_port {
38            Err(ERR_MAX_PORT_LESS_THAN_MIN_PORT.to_owned())
39        } else if self.address.is_empty() {
40            Err(ERR_LISTENING_ADDRESS_INVALID.to_owned())
41        } else {
42            Ok(())
43        }
44    }
45
46    // Allocate a PacketConn (UDP) relay_address
47    async fn allocate_conn(
48        &self,
49        use_ipv4: bool,
50        requested_port: u16,
51    ) -> Result<(Arc<dyn Conn + Send + Sync>, SocketAddr), Error> {
52        let max_retries = if self.max_retries == 0 {
53            10
54        } else {
55            self.max_retries
56        };
57
58        if requested_port != 0 {
59            let addr = self
60                .net
61                .resolve_addr(use_ipv4, &format!("{}:{}", self.address, requested_port))
62                .await?;
63            let conn = self.net.bind(addr).await?;
64            let mut relay_addr = conn.local_addr().await?;
65            relay_addr.set_ip(self.relay_address);
66            return Ok((conn, relay_addr));
67        }
68
69        for _ in 0..max_retries {
70            let port = self.min_port + rand::random::<u16>() % (self.max_port + 1 - self.min_port);
71            let addr = self
72                .net
73                .resolve_addr(use_ipv4, &format!("{}:{}", self.address, port))
74                .await?;
75            let conn = match self.net.bind(addr).await {
76                Ok(conn) => conn,
77                Err(_) => continue,
78            };
79
80            let mut relay_addr = conn.local_addr().await?;
81            relay_addr.set_ip(self.relay_address);
82            return Ok((conn, relay_addr));
83        }
84
85        Err(ERR_MAX_RETRIES_EXCEEDED.to_owned())
86    }
87}