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