xref: /webrtc/ice/src/agent/agent_gather_test.rs (revision 6ac0fffd)
1 use super::agent_vnet_test::*;
2 use super::*;
3 use crate::udp_mux::{UDPMuxDefault, UDPMuxParams};
4 use crate::util::*;
5 
6 use ipnet::IpNet;
7 use std::str::FromStr;
8 use tokio::net::UdpSocket;
9 use util::vnet::*;
10 
11 #[tokio::test]
12 async fn test_vnet_gather_no_local_ip_address() -> Result<()> {
13     let vnet = Arc::new(net::Net::new(Some(net::NetConfig::default())));
14 
15     let a = Agent::new(AgentConfig {
16         net: Some(Arc::clone(&vnet)),
17         ..Default::default()
18     })
19     .await?;
20 
21     let local_ips = local_interfaces(
22         &vnet,
23         &a.interface_filter,
24         &a.ip_filter,
25         &[NetworkType::Udp4],
26     )
27     .await;
28     assert!(local_ips.is_empty(), "should return no local IP");
29 
30     a.close().await?;
31 
32     Ok(())
33 }
34 
35 #[tokio::test]
36 async fn test_vnet_gather_dynamic_ip_address() -> Result<()> {
37     let cider = "1.2.3.0/24";
38     let ipnet = IpNet::from_str(cider).map_err(|e| Error::Other(e.to_string()))?;
39 
40     let r = Arc::new(Mutex::new(router::Router::new(router::RouterConfig {
41         cidr: cider.to_owned(),
42         ..Default::default()
43     })?));
44     let nw = Arc::new(net::Net::new(Some(net::NetConfig::default())));
45     connect_net2router(&nw, &r).await?;
46 
47     let a = Agent::new(AgentConfig {
48         net: Some(Arc::clone(&nw)),
49         ..Default::default()
50     })
51     .await?;
52 
53     let local_ips =
54         local_interfaces(&nw, &a.interface_filter, &a.ip_filter, &[NetworkType::Udp4]).await;
55     assert!(!local_ips.is_empty(), "should have one local IP");
56 
57     for ip in &local_ips {
58         if ip.is_loopback() {
59             panic!("should not return loopback IP");
60         }
61         if !ipnet.contains(ip) {
62             panic!("{} should be contained in the CIDR {}", ip, ipnet);
63         }
64     }
65 
66     a.close().await?;
67 
68     Ok(())
69 }
70 
71 #[tokio::test]
72 async fn test_vnet_gather_listen_udp() -> Result<()> {
73     let cider = "1.2.3.0/24";
74     let r = Arc::new(Mutex::new(router::Router::new(router::RouterConfig {
75         cidr: cider.to_owned(),
76         ..Default::default()
77     })?));
78     let nw = Arc::new(net::Net::new(Some(net::NetConfig::default())));
79     connect_net2router(&nw, &r).await?;
80 
81     let a = Agent::new(AgentConfig {
82         net: Some(Arc::clone(&nw)),
83         ..Default::default()
84     })
85     .await?;
86 
87     let local_ips =
88         local_interfaces(&nw, &a.interface_filter, &a.ip_filter, &[NetworkType::Udp4]).await;
89     assert!(!local_ips.is_empty(), "should have one local IP");
90 
91     for ip in local_ips {
92         let _ = listen_udp_in_port_range(&nw, 0, 0, SocketAddr::new(ip, 0)).await?;
93 
94         let result = listen_udp_in_port_range(&nw, 4999, 5000, SocketAddr::new(ip, 0)).await;
95         assert!(
96             result.is_err(),
97             "listenUDP with invalid port range did not return ErrPort"
98         );
99 
100         let conn = listen_udp_in_port_range(&nw, 5000, 5000, SocketAddr::new(ip, 0)).await?;
101         let port = conn.local_addr()?.port();
102         assert_eq!(
103             port, 5000,
104             "listenUDP with port restriction of 5000 listened on incorrect port ({})",
105             port
106         );
107     }
108 
109     a.close().await?;
110 
111     Ok(())
112 }
113 
114 #[tokio::test]
115 async fn test_vnet_gather_with_nat_1to1_as_host_candidates() -> Result<()> {
116     let external_ip0 = "1.2.3.4";
117     let external_ip1 = "1.2.3.5";
118     let local_ip0 = "10.0.0.1";
119     let local_ip1 = "10.0.0.2";
120     let map0 = format!("{}/{}", external_ip0, local_ip0);
121     let map1 = format!("{}/{}", external_ip1, local_ip1);
122 
123     let wan = Arc::new(Mutex::new(router::Router::new(router::RouterConfig {
124         cidr: "1.2.3.0/24".to_owned(),
125         ..Default::default()
126     })?));
127 
128     let lan = Arc::new(Mutex::new(router::Router::new(router::RouterConfig {
129         cidr: "10.0.0.0/24".to_owned(),
130         static_ips: vec![map0.clone(), map1.clone()],
131         nat_type: Some(nat::NatType {
132             mode: nat::NatMode::Nat1To1,
133             ..Default::default()
134         }),
135         ..Default::default()
136     })?));
137 
138     connect_router2router(&lan, &wan).await?;
139 
140     let nw = Arc::new(net::Net::new(Some(net::NetConfig {
141         static_ips: vec![local_ip0.to_owned(), local_ip1.to_owned()],
142         ..Default::default()
143     })));
144 
145     connect_net2router(&nw, &lan).await?;
146 
147     let a = Agent::new(AgentConfig {
148         network_types: vec![NetworkType::Udp4],
149         nat_1to1_ips: vec![map0.clone(), map1.clone()],
150         net: Some(Arc::clone(&nw)),
151         ..Default::default()
152     })
153     .await?;
154 
155     let (done_tx, mut done_rx) = mpsc::channel::<()>(1);
156     let done_tx = Arc::new(Mutex::new(Some(done_tx)));
157     a.on_candidate(Box::new(
158         move |c: Option<Arc<dyn Candidate + Send + Sync>>| {
159             let done_tx_clone = Arc::clone(&done_tx);
160             Box::pin(async move {
161                 if c.is_none() {
162                     let mut tx = done_tx_clone.lock().await;
163                     tx.take();
164                 }
165             })
166         },
167     ));
168 
169     a.gather_candidates()?;
170 
171     log::debug!("wait for gathering is done...");
172     let _ = done_rx.recv().await;
173     log::debug!("gathering is done");
174 
175     let candidates = a.get_local_candidates().await?;
176     assert_eq!(candidates.len(), 2, "There must be two candidates");
177 
178     let mut laddrs = vec![];
179     for candi in &candidates {
180         if let Some(conn) = candi.get_conn() {
181             let laddr = conn.local_addr()?;
182             assert_eq!(
183                 candi.port(),
184                 laddr.port(),
185                 "Unexpected candidate port: {}",
186                 candi.port()
187             );
188             laddrs.push(laddr);
189         }
190     }
191 
192     if candidates[0].address() == external_ip0 {
193         assert_eq!(
194             candidates[1].address(),
195             external_ip1,
196             "Unexpected candidate IP: {}",
197             candidates[1].address()
198         );
199         assert_eq!(
200             laddrs[0].ip().to_string(),
201             local_ip0,
202             "Unexpected listen IP: {}",
203             laddrs[0].ip()
204         );
205         assert_eq!(
206             laddrs[1].ip().to_string(),
207             local_ip1,
208             "Unexpected listen IP: {}",
209             laddrs[1].ip()
210         );
211     } else if candidates[0].address() == external_ip1 {
212         assert_eq!(
213             candidates[1].address(),
214             external_ip0,
215             "Unexpected candidate IP: {}",
216             candidates[1].address()
217         );
218         assert_eq!(
219             laddrs[0].ip().to_string(),
220             local_ip1,
221             "Unexpected listen IP: {}",
222             laddrs[0].ip(),
223         );
224         assert_eq!(
225             laddrs[1].ip().to_string(),
226             local_ip0,
227             "Unexpected listen IP: {}",
228             laddrs[1].ip(),
229         )
230     }
231 
232     a.close().await?;
233 
234     Ok(())
235 }
236 
237 #[tokio::test]
238 async fn test_vnet_gather_with_nat_1to1_as_srflx_candidates() -> Result<()> {
239     let wan = Arc::new(Mutex::new(router::Router::new(router::RouterConfig {
240         cidr: "1.2.3.0/24".to_owned(),
241         ..Default::default()
242     })?));
243 
244     let lan = Arc::new(Mutex::new(router::Router::new(router::RouterConfig {
245         cidr: "10.0.0.0/24".to_owned(),
246         static_ips: vec!["1.2.3.4/10.0.0.1".to_owned()],
247         nat_type: Some(nat::NatType {
248             mode: nat::NatMode::Nat1To1,
249             ..Default::default()
250         }),
251         ..Default::default()
252     })?));
253 
254     connect_router2router(&lan, &wan).await?;
255 
256     let nw = Arc::new(net::Net::new(Some(net::NetConfig {
257         static_ips: vec!["10.0.0.1".to_owned()],
258         ..Default::default()
259     })));
260 
261     connect_net2router(&nw, &lan).await?;
262 
263     let a = Agent::new(AgentConfig {
264         network_types: vec![NetworkType::Udp4],
265         nat_1to1_ips: vec!["1.2.3.4".to_owned()],
266         nat_1to1_ip_candidate_type: CandidateType::ServerReflexive,
267         net: Some(nw),
268         ..Default::default()
269     })
270     .await?;
271 
272     let (done_tx, mut done_rx) = mpsc::channel::<()>(1);
273     let done_tx = Arc::new(Mutex::new(Some(done_tx)));
274     a.on_candidate(Box::new(
275         move |c: Option<Arc<dyn Candidate + Send + Sync>>| {
276             let done_tx_clone = Arc::clone(&done_tx);
277             Box::pin(async move {
278                 if c.is_none() {
279                     let mut tx = done_tx_clone.lock().await;
280                     tx.take();
281                 }
282             })
283         },
284     ));
285 
286     a.gather_candidates()?;
287 
288     log::debug!("wait for gathering is done...");
289     let _ = done_rx.recv().await;
290     log::debug!("gathering is done");
291 
292     let candidates = a.get_local_candidates().await?;
293     assert_eq!(candidates.len(), 2, "There must be two candidates");
294 
295     let mut candi_host = None;
296     let mut candi_srflx = None;
297 
298     for candidate in candidates {
299         match candidate.candidate_type() {
300             CandidateType::Host => {
301                 candi_host = Some(candidate);
302             }
303             CandidateType::ServerReflexive => {
304                 candi_srflx = Some(candidate);
305             }
306             _ => {
307                 panic!("Unexpected candidate type");
308             }
309         }
310     }
311 
312     assert!(candi_host.is_some(), "should not be nil");
313     assert_eq!("10.0.0.1", candi_host.unwrap().address(), "should match");
314     assert!(candi_srflx.is_some(), "should not be nil");
315     assert_eq!("1.2.3.4", candi_srflx.unwrap().address(), "should match");
316 
317     a.close().await?;
318 
319     Ok(())
320 }
321 
322 #[tokio::test]
323 async fn test_vnet_gather_with_interface_filter() -> Result<()> {
324     let r = Arc::new(Mutex::new(router::Router::new(router::RouterConfig {
325         cidr: "1.2.3.0/24".to_owned(),
326         ..Default::default()
327     })?));
328     let nw = Arc::new(net::Net::new(Some(net::NetConfig::default())));
329     connect_net2router(&nw, &r).await?;
330 
331     //"InterfaceFilter should exclude the interface"
332     {
333         let a = Agent::new(AgentConfig {
334             net: Some(Arc::clone(&nw)),
335             interface_filter: Arc::new(Some(Box::new(|_: &str| -> bool {
336                 //assert_eq!("eth0", interface_name);
337                 false
338             }))),
339             ..Default::default()
340         })
341         .await?;
342 
343         let local_ips =
344             local_interfaces(&nw, &a.interface_filter, &a.ip_filter, &[NetworkType::Udp4]).await;
345         assert!(
346             local_ips.is_empty(),
347             "InterfaceFilter should have excluded everything"
348         );
349 
350         a.close().await?;
351     }
352 
353     //"InterfaceFilter should not exclude the interface"
354     {
355         let a = Agent::new(AgentConfig {
356             net: Some(Arc::clone(&nw)),
357             interface_filter: Arc::new(Some(Box::new(|interface_name: &str| -> bool {
358                 "eth0" == interface_name
359             }))),
360             ..Default::default()
361         })
362         .await?;
363 
364         let local_ips =
365             local_interfaces(&nw, &a.interface_filter, &a.ip_filter, &[NetworkType::Udp4]).await;
366         assert_eq!(
367             local_ips.len(),
368             1,
369             "InterfaceFilter should not have excluded everything"
370         );
371 
372         a.close().await?;
373     }
374 
375     Ok(())
376 }
377 
378 #[tokio::test]
379 async fn test_vnet_gather_turn_connection_leak() -> Result<()> {
380     let turn_server_url = Url {
381         scheme: SchemeType::Turn,
382         host: VNET_STUN_SERVER_IP.to_owned(),
383         port: VNET_STUN_SERVER_PORT,
384         username: "user".to_owned(),
385         password: "pass".to_owned(),
386         proto: ProtoType::Udp,
387     };
388 
389     // buildVNet with a Symmetric NATs for both LANs
390     let nat_type = nat::NatType {
391         mapping_behavior: nat::EndpointDependencyType::EndpointAddrPortDependent,
392         filtering_behavior: nat::EndpointDependencyType::EndpointAddrPortDependent,
393         ..Default::default()
394     };
395 
396     let v = build_vnet(nat_type, nat_type).await?;
397 
398     let cfg0 = AgentConfig {
399         urls: vec![turn_server_url.clone()],
400         network_types: supported_network_types(),
401         multicast_dns_mode: MulticastDnsMode::Disabled,
402         nat_1to1_ips: vec![VNET_GLOBAL_IPA.to_owned()],
403         net: Some(Arc::clone(&v.net0)),
404         ..Default::default()
405     };
406 
407     let a_agent = Agent::new(cfg0).await?;
408 
409     {
410         let agent_internal = Arc::clone(&a_agent.internal);
411         Agent::gather_candidates_relay(
412             vec![turn_server_url.clone()],
413             Arc::clone(&v.net0),
414             agent_internal,
415         )
416         .await;
417     }
418 
419     // Assert relay conn leak on close.
420     a_agent.close().await?;
421     v.close().await?;
422 
423     Ok(())
424 }
425 
426 #[tokio::test]
427 async fn test_vnet_gather_muxed_udp() -> Result<()> {
428     let udp_socket = UdpSocket::bind("0.0.0.0:0").await?;
429     let udp_mux = UDPMuxDefault::new(UDPMuxParams::new(udp_socket));
430 
431     let lan = Arc::new(Mutex::new(router::Router::new(router::RouterConfig {
432         cidr: "10.0.0.0/24".to_owned(),
433         nat_type: Some(nat::NatType {
434             mode: nat::NatMode::Nat1To1,
435             ..Default::default()
436         }),
437         ..Default::default()
438     })?));
439 
440     let nw = Arc::new(net::Net::new(Some(net::NetConfig {
441         static_ips: vec!["10.0.0.1".to_owned()],
442         ..Default::default()
443     })));
444 
445     connect_net2router(&nw, &lan).await?;
446 
447     let a = Agent::new(AgentConfig {
448         network_types: vec![NetworkType::Udp4],
449         nat_1to1_ips: vec!["1.2.3.4".to_owned()],
450         net: Some(nw),
451         udp_network: UDPNetwork::Muxed(udp_mux),
452         ..Default::default()
453     })
454     .await?;
455 
456     let (done_tx, mut done_rx) = mpsc::channel::<()>(1);
457     let done_tx = Arc::new(Mutex::new(Some(done_tx)));
458     a.on_candidate(Box::new(
459         move |c: Option<Arc<dyn Candidate + Send + Sync>>| {
460             let done_tx_clone = Arc::clone(&done_tx);
461             Box::pin(async move {
462                 if c.is_none() {
463                     let mut tx = done_tx_clone.lock().await;
464                     tx.take();
465                 }
466             })
467         },
468     ));
469 
470     a.gather_candidates()?;
471 
472     log::debug!("wait for gathering is done...");
473     let _ = done_rx.recv().await;
474     log::debug!("gathering is done");
475 
476     let candidates = a.get_local_candidates().await?;
477     assert_eq!(candidates.len(), 1, "There must be a single candidate");
478 
479     let candi = &candidates[0];
480     let laddr = candi.get_conn().unwrap().local_addr()?;
481     assert_eq!(candi.address(), "1.2.3.4");
482     assert_eq!(
483         candi.port(),
484         laddr.port(),
485         "Unexpected candidate port: {}",
486         candi.port()
487     );
488 
489     Ok(())
490 }
491