1 use super::candidate_base::*;
2 use super::*;
3 use crate::error::*;
4 use crate::rand::generate_cand_id;
5 use crate::util::*;
6 use std::sync::atomic::{AtomicU16, AtomicU8};
7 
8 /// The config required to create a new `CandidateServerReflexive`.
9 #[derive(Default)]
10 pub struct CandidateServerReflexiveConfig {
11     pub base_config: CandidateBaseConfig,
12 
13     pub rel_addr: String,
14     pub rel_port: u16,
15 }
16 
17 impl CandidateServerReflexiveConfig {
18     /// Creates a new server reflective candidate.
19     pub async fn new_candidate_server_reflexive(self) -> Result<CandidateBase> {
20         let ip: IpAddr = match self.base_config.address.parse() {
21             Ok(ip) => ip,
22             Err(_) => return Err(Error::ErrAddressParseFailed),
23         };
24         let network_type = determine_network_type(&self.base_config.network, &ip)?;
25 
26         let mut candidate_id = self.base_config.candidate_id;
27         if candidate_id.is_empty() {
28             candidate_id = generate_cand_id();
29         }
30 
31         let c = CandidateBase {
32             id: candidate_id,
33             network_type: AtomicU8::new(network_type as u8),
34             candidate_type: CandidateType::ServerReflexive,
35             address: self.base_config.address,
36             port: self.base_config.port,
37             resolved_addr: Mutex::new(create_addr(network_type, ip, self.base_config.port)),
38             component: AtomicU16::new(self.base_config.component),
39             foundation_override: self.base_config.foundation,
40             priority_override: self.base_config.priority,
41             related_address: Some(CandidateRelatedAddress {
42                 address: self.rel_addr,
43                 port: self.rel_port,
44             }),
45             conn: self.base_config.conn,
46             ..CandidateBase::default()
47         };
48 
49         Ok(c)
50     }
51 }
52