@desklink/host 0.5.3 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +25 -17
  2. package/dist/engineProcess.d.ts +5 -0
  3. package/dist/engineProcess.d.ts.map +1 -1
  4. package/dist/engineProcess.js +5 -3
  5. package/dist/engineProcess.js.map +1 -1
  6. package/engine/Cargo.lock +6 -8
  7. package/engine/Cargo.toml +13 -1
  8. package/engine/src/clipboard.rs +0 -34
  9. package/engine/src/convert.rs +0 -170
  10. package/engine/src/cursor.rs +0 -23
  11. package/engine/src/input.rs +0 -65
  12. package/engine/src/input_mac.rs +0 -11
  13. package/engine/src/keeper.rs +0 -137
  14. package/engine/src/keymap.rs +0 -107
  15. package/engine/src/keymap_mac.rs +0 -25
  16. package/engine/src/mac.rs +0 -28
  17. package/engine/src/peer.rs +224 -0
  18. package/engine/src/portal.rs +0 -18
  19. package/engine/src/protocol.rs +0 -162
  20. package/engine/src/x11.rs +0 -13
  21. package/engine/vendor/rtc-ice/Cargo.toml +137 -0
  22. package/engine/vendor/rtc-ice/DESKLINK-PATCH.md +59 -0
  23. package/engine/vendor/rtc-ice/LICENSE-APACHE +201 -0
  24. package/engine/vendor/rtc-ice/LICENSE-MIT +21 -0
  25. package/engine/vendor/rtc-ice/README.md +30 -0
  26. package/engine/vendor/rtc-ice/examples/ping_pong.rs +376 -0
  27. package/engine/vendor/rtc-ice/src/agent/agent_config.rs +126 -0
  28. package/engine/vendor/rtc-ice/src/agent/agent_proto.rs +172 -0
  29. package/engine/vendor/rtc-ice/src/agent/agent_selector.rs +566 -0
  30. package/engine/vendor/rtc-ice/src/agent/agent_stats.rs +292 -0
  31. package/engine/vendor/rtc-ice/src/agent/agent_test.rs +3388 -0
  32. package/engine/vendor/rtc-ice/src/agent/mod.rs +1662 -0
  33. package/engine/vendor/rtc-ice/src/attributes/control/control_test.rs +168 -0
  34. package/engine/vendor/rtc-ice/src/attributes/control/mod.rs +142 -0
  35. package/engine/vendor/rtc-ice/src/attributes/mod.rs +6 -0
  36. package/engine/vendor/rtc-ice/src/attributes/priority/mod.rs +37 -0
  37. package/engine/vendor/rtc-ice/src/attributes/priority/priority_test.rs +39 -0
  38. package/engine/vendor/rtc-ice/src/attributes/use_candidate/mod.rs +33 -0
  39. package/engine/vendor/rtc-ice/src/attributes/use_candidate/use_candidate_test.rs +19 -0
  40. package/engine/vendor/rtc-ice/src/candidate/candidate_host.rs +53 -0
  41. package/engine/vendor/rtc-ice/src/candidate/candidate_pair.rs +215 -0
  42. package/engine/vendor/rtc-ice/src/candidate/candidate_pair_test.rs +201 -0
  43. package/engine/vendor/rtc-ice/src/candidate/candidate_peer_reflexive.rs +49 -0
  44. package/engine/vendor/rtc-ice/src/candidate/candidate_relay.rs +53 -0
  45. package/engine/vendor/rtc-ice/src/candidate/candidate_relay_test.rs +114 -0
  46. package/engine/vendor/rtc-ice/src/candidate/candidate_server_reflexive.rs +53 -0
  47. package/engine/vendor/rtc-ice/src/candidate/candidate_server_reflexive_test.rs +91 -0
  48. package/engine/vendor/rtc-ice/src/candidate/candidate_test.rs +540 -0
  49. package/engine/vendor/rtc-ice/src/candidate/mod.rs +679 -0
  50. package/engine/vendor/rtc-ice/src/lib.rs +85 -0
  51. package/engine/vendor/rtc-ice/src/mdns/mdns_test.rs +150 -0
  52. package/engine/vendor/rtc-ice/src/mdns/mod.rs +69 -0
  53. package/engine/vendor/rtc-ice/src/network_type/mod.rs +162 -0
  54. package/engine/vendor/rtc-ice/src/network_type/network_type_test.rs +95 -0
  55. package/engine/vendor/rtc-ice/src/rand/mod.rs +91 -0
  56. package/engine/vendor/rtc-ice/src/rand/rand_test.rs +115 -0
  57. package/engine/vendor/rtc-ice/src/state/mod.rs +106 -0
  58. package/engine/vendor/rtc-ice/src/state/state_test.rs +46 -0
  59. package/engine/vendor/rtc-ice/src/stats/mod.rs +166 -0
  60. package/engine/vendor/rtc-ice/src/tcp_type/mod.rs +47 -0
  61. package/engine/vendor/rtc-ice/src/tcp_type/tcp_type_test.rs +18 -0
  62. package/engine/vendor/rtc-ice/src/url/mod.rs +266 -0
  63. package/engine/vendor/rtc-ice/src/url/url_test.rs +142 -0
  64. package/package.json +8 -3
@@ -0,0 +1,91 @@
1
+ use std::time::Duration;
2
+
3
+ use tokio::net::UdpSocket;
4
+
5
+ use super::candidate_relay_test::OptimisticAuthHandler;
6
+ use super::*;
7
+ use crate::agent::agent_config::AgentConfig;
8
+ use crate::agent::agent_vnet_test::{connect_with_vnet, on_connected};
9
+ use crate::agent::Agent;
10
+ use crate::url::{SchemeType, Url};
11
+
12
+ //use std::io::Write;
13
+
14
+ #[tokio::test]
15
+ async fn test_server_reflexive_only_connection() -> Result<()> {
16
+ /*env_logger::Builder::new()
17
+ .format(|buf, record| {
18
+ writeln!(
19
+ buf,
20
+ "{}:{} [{}] {} - {}",
21
+ record.file().unwrap_or("unknown"),
22
+ record.line().unwrap_or(0),
23
+ record.level(),
24
+ chrono::Local::now().format("%H:%M:%S.%6f"),
25
+ record.args()
26
+ )
27
+ })
28
+ .filter(None, LevelFilter::Trace)
29
+ .init();*/
30
+
31
+ let server_listener = Arc::new(UdpSocket::bind("127.0.0.1:0").await?);
32
+ let server_port = server_listener.local_addr()?.port();
33
+
34
+ let server = turn::server::Server::new(turn::server::config::ServerConfig {
35
+ realm: "webrtc.rs".to_owned(),
36
+ auth_handler: Arc::new(OptimisticAuthHandler {}),
37
+ conn_configs: vec![turn::server::config::ConnConfig {
38
+ conn: server_listener,
39
+ relay_addr_generator: Box::new(turn::relay::relay_none::RelayAddressGeneratorNone {
40
+ address: "127.0.0.1".to_owned(),
41
+ net: Arc::new(util::vnet::net::Net::new(None)),
42
+ }),
43
+ }],
44
+ channel_bind_timeout: Duration::from_secs(0),
45
+ alloc_close_notify: None,
46
+ })
47
+ .await?;
48
+
49
+ let cfg0 = AgentConfig {
50
+ network_types: vec![NetworkType::Udp4],
51
+ urls: vec![Url {
52
+ scheme: SchemeType::Stun,
53
+ host: "127.0.0.1".to_owned(),
54
+ port: server_port,
55
+ ..Default::default()
56
+ }],
57
+ candidate_types: vec![CandidateType::ServerReflexive],
58
+ ..Default::default()
59
+ };
60
+
61
+ let a_agent = Arc::new(Agent::new(cfg0).await?);
62
+ let (a_notifier, mut a_connected) = on_connected();
63
+ a_agent.on_connection_state_change(a_notifier);
64
+
65
+ let cfg1 = AgentConfig {
66
+ network_types: vec![NetworkType::Udp4],
67
+ urls: vec![Url {
68
+ scheme: SchemeType::Stun,
69
+ host: "127.0.0.1".to_owned(),
70
+ port: server_port,
71
+ ..Default::default()
72
+ }],
73
+ candidate_types: vec![CandidateType::ServerReflexive],
74
+ ..Default::default()
75
+ };
76
+
77
+ let b_agent = Arc::new(Agent::new(cfg1).await?);
78
+ let (b_notifier, mut b_connected) = on_connected();
79
+ b_agent.on_connection_state_change(b_notifier);
80
+
81
+ connect_with_vnet(&a_agent, &b_agent).await?;
82
+
83
+ let _ = a_connected.recv().await;
84
+ let _ = b_connected.recv().await;
85
+
86
+ a_agent.close().await?;
87
+ b_agent.close().await?;
88
+ server.close().await?;
89
+
90
+ Ok(())
91
+ }
@@ -0,0 +1,540 @@
1
+ use super::*;
2
+ use crate::candidate::candidate_host::CandidateHostConfig;
3
+ use crate::candidate::candidate_pair::CandidatePairState;
4
+ use crate::candidate::candidate_peer_reflexive::CandidatePeerReflexiveConfig;
5
+ use crate::candidate::candidate_relay::CandidateRelayConfig;
6
+ use crate::candidate::candidate_server_reflexive::CandidateServerReflexiveConfig;
7
+ use crate::candidate::{Candidate, unmarshal_candidate};
8
+ use std::time::Instant;
9
+
10
+ #[test]
11
+ fn test_candidate_priority() -> Result<()> {
12
+ let tests = vec![
13
+ (
14
+ Candidate {
15
+ candidate_type: CandidateType::Host,
16
+ component: COMPONENT_RTP,
17
+ ..Default::default()
18
+ },
19
+ 2130706431,
20
+ ),
21
+ (
22
+ Candidate {
23
+ candidate_type: CandidateType::Host,
24
+ component: COMPONENT_RTP,
25
+ network_type: NetworkType::Tcp4,
26
+ tcp_type: TcpType::Active,
27
+ ..Default::default()
28
+ },
29
+ 2128609279,
30
+ ),
31
+ (
32
+ Candidate {
33
+ candidate_type: CandidateType::Host,
34
+ component: COMPONENT_RTP,
35
+ network_type: NetworkType::Tcp4,
36
+ tcp_type: TcpType::Passive,
37
+ ..Default::default()
38
+ },
39
+ 2124414975,
40
+ ),
41
+ (
42
+ Candidate {
43
+ candidate_type: CandidateType::Host,
44
+ component: COMPONENT_RTP,
45
+ network_type: NetworkType::Tcp4,
46
+ tcp_type: TcpType::SimultaneousOpen,
47
+ ..Default::default()
48
+ },
49
+ 2120220671,
50
+ ),
51
+ (
52
+ Candidate {
53
+ candidate_type: CandidateType::PeerReflexive,
54
+ component: COMPONENT_RTP,
55
+ ..Default::default()
56
+ },
57
+ 1862270975,
58
+ ),
59
+ (
60
+ Candidate {
61
+ candidate_type: CandidateType::PeerReflexive,
62
+ component: COMPONENT_RTP,
63
+ network_type: NetworkType::Tcp6,
64
+ tcp_type: TcpType::SimultaneousOpen,
65
+ ..Default::default()
66
+ },
67
+ 1860173823,
68
+ ),
69
+ (
70
+ Candidate {
71
+ candidate_type: CandidateType::PeerReflexive,
72
+ component: COMPONENT_RTP,
73
+ network_type: NetworkType::Tcp6,
74
+ tcp_type: TcpType::Active,
75
+ ..Default::default()
76
+ },
77
+ 1855979519,
78
+ ),
79
+ (
80
+ Candidate {
81
+ candidate_type: CandidateType::PeerReflexive,
82
+ component: COMPONENT_RTP,
83
+ network_type: NetworkType::Tcp6,
84
+ tcp_type: TcpType::Passive,
85
+ ..Default::default()
86
+ },
87
+ 1851785215,
88
+ ),
89
+ (
90
+ Candidate {
91
+ candidate_type: CandidateType::ServerReflexive,
92
+ component: COMPONENT_RTP,
93
+ ..Default::default()
94
+ },
95
+ 1694498815,
96
+ ),
97
+ (
98
+ Candidate {
99
+ candidate_type: CandidateType::Relay,
100
+ component: COMPONENT_RTP,
101
+ ..Default::default()
102
+ },
103
+ 16777215,
104
+ ),
105
+ ];
106
+
107
+ for (candidate, want) in tests {
108
+ let got = candidate.priority();
109
+ assert_eq!(
110
+ got, want,
111
+ "Candidate({candidate}).Priority() = {got}, want {want}"
112
+ );
113
+ }
114
+
115
+ Ok(())
116
+ }
117
+
118
+ #[test]
119
+ fn test_candidate_last_sent() -> Result<()> {
120
+ let mut candidate = Candidate::default();
121
+ assert_eq!(
122
+ candidate.last_sent(),
123
+ None,
124
+ "a fresh candidate has sent nothing"
125
+ );
126
+
127
+ let now = Instant::now();
128
+ candidate.set_last_sent(now);
129
+ assert_eq!(candidate.last_sent(), Some(now));
130
+
131
+ Ok(())
132
+ }
133
+
134
+ #[test]
135
+ fn test_candidate_last_received() -> Result<()> {
136
+ let mut candidate = Candidate::default();
137
+ assert_eq!(
138
+ candidate.last_received(),
139
+ None,
140
+ "a fresh candidate has received nothing"
141
+ );
142
+
143
+ let now = Instant::now();
144
+ candidate.set_last_received(now);
145
+ assert_eq!(candidate.last_received(), Some(now));
146
+
147
+ Ok(())
148
+ }
149
+
150
+ #[test]
151
+ fn test_candidate_foundation() -> Result<()> {
152
+ // All fields are the same
153
+ assert_eq!(
154
+ (Candidate {
155
+ candidate_type: CandidateType::Host,
156
+ network_type: NetworkType::Udp4,
157
+ address: "A".to_owned(),
158
+ ..Default::default()
159
+ })
160
+ .foundation(),
161
+ (Candidate {
162
+ candidate_type: CandidateType::Host,
163
+ network_type: NetworkType::Udp4,
164
+ address: "A".to_owned(),
165
+ ..Default::default()
166
+ })
167
+ .foundation()
168
+ );
169
+
170
+ // Different Address
171
+ assert_ne!(
172
+ (Candidate {
173
+ candidate_type: CandidateType::Host,
174
+ network_type: NetworkType::Udp4,
175
+ address: "A".to_owned(),
176
+ ..Default::default()
177
+ })
178
+ .foundation(),
179
+ (Candidate {
180
+ candidate_type: CandidateType::Host,
181
+ network_type: NetworkType::Udp4,
182
+ address: "B".to_owned(),
183
+ ..Default::default()
184
+ })
185
+ .foundation(),
186
+ );
187
+
188
+ // Different networkType
189
+ assert_ne!(
190
+ (Candidate {
191
+ candidate_type: CandidateType::Host,
192
+ network_type: NetworkType::Udp4,
193
+ address: "A".to_owned(),
194
+ ..Default::default()
195
+ })
196
+ .foundation(),
197
+ (Candidate {
198
+ candidate_type: CandidateType::Host,
199
+ network_type: NetworkType::Udp6,
200
+ address: "A".to_owned(),
201
+ ..Default::default()
202
+ })
203
+ .foundation(),
204
+ );
205
+
206
+ // Different candidateType
207
+ assert_ne!(
208
+ (Candidate {
209
+ candidate_type: CandidateType::Host,
210
+ network_type: NetworkType::Udp4,
211
+ address: "A".to_owned(),
212
+ ..Default::default()
213
+ })
214
+ .foundation(),
215
+ (Candidate {
216
+ candidate_type: CandidateType::PeerReflexive,
217
+ network_type: NetworkType::Udp4,
218
+ address: "A".to_owned(),
219
+ ..Default::default()
220
+ })
221
+ .foundation(),
222
+ );
223
+
224
+ // Port has no effect
225
+ assert_eq!(
226
+ (Candidate {
227
+ candidate_type: CandidateType::Host,
228
+ network_type: NetworkType::Udp4,
229
+ address: "A".to_owned(),
230
+ port: 8080,
231
+ ..Default::default()
232
+ })
233
+ .foundation(),
234
+ (Candidate {
235
+ candidate_type: CandidateType::Host,
236
+ network_type: NetworkType::Udp4,
237
+ address: "A".to_owned(),
238
+ port: 80,
239
+ ..Default::default()
240
+ })
241
+ .foundation()
242
+ );
243
+
244
+ Ok(())
245
+ }
246
+
247
+ #[test]
248
+ fn test_candidate_pair_state_serialization() {
249
+ let tests = vec![
250
+ (CandidatePairState::Unspecified, "\"unspecified\""),
251
+ (CandidatePairState::Waiting, "\"waiting\""),
252
+ (CandidatePairState::InProgress, "\"in-progress\""),
253
+ (CandidatePairState::Failed, "\"failed\""),
254
+ (CandidatePairState::Succeeded, "\"succeeded\""),
255
+ ];
256
+
257
+ for (candidate_pair_state, expected_string) in tests {
258
+ assert_eq!(
259
+ expected_string.to_string(),
260
+ serde_json::to_string(&candidate_pair_state).unwrap()
261
+ );
262
+ }
263
+ }
264
+
265
+ #[test]
266
+ fn test_candidate_pair_state_to_string() {
267
+ let tests = vec![
268
+ (CandidatePairState::Unspecified, "unspecified"),
269
+ (CandidatePairState::Waiting, "waiting"),
270
+ (CandidatePairState::InProgress, "in-progress"),
271
+ (CandidatePairState::Failed, "failed"),
272
+ (CandidatePairState::Succeeded, "succeeded"),
273
+ ];
274
+
275
+ for (candidate_pair_state, expected_string) in tests {
276
+ assert_eq!(candidate_pair_state.to_string(), expected_string);
277
+ }
278
+ }
279
+
280
+ #[test]
281
+ fn test_candidate_type_serialization() {
282
+ let tests = vec![
283
+ (CandidateType::Unspecified, "\"unspecified\""),
284
+ (CandidateType::Host, "\"host\""),
285
+ (CandidateType::ServerReflexive, "\"srflx\""),
286
+ (CandidateType::PeerReflexive, "\"prflx\""),
287
+ (CandidateType::Relay, "\"relay\""),
288
+ ];
289
+
290
+ for (candidate_type, expected_string) in tests {
291
+ assert_eq!(
292
+ serde_json::to_string(&candidate_type).unwrap(),
293
+ expected_string.to_string()
294
+ );
295
+ }
296
+ }
297
+
298
+ #[test]
299
+ fn test_candidate_type_to_string() {
300
+ let tests = vec![
301
+ (CandidateType::Unspecified, "Unknown candidate type"),
302
+ (CandidateType::Host, "host"),
303
+ (CandidateType::ServerReflexive, "srflx"),
304
+ (CandidateType::PeerReflexive, "prflx"),
305
+ (CandidateType::Relay, "relay"),
306
+ ];
307
+
308
+ for (candidate_type, expected_string) in tests {
309
+ assert_eq!(candidate_type.to_string(), expected_string);
310
+ }
311
+ }
312
+
313
+ #[test]
314
+ fn test_candidate_marshal() -> Result<()> {
315
+ let tests = vec![
316
+ (
317
+ Some(Candidate {
318
+ network_type: NetworkType::Udp6,
319
+ candidate_type: CandidateType::Host,
320
+ address: "fcd9:e3b8:12ce:9fc5:74a5:c6bb:d8b:e08a".to_owned(),
321
+ port: 53987,
322
+ priority_override: 500,
323
+ foundation_override: "750".to_owned(),
324
+ ..Default::default()
325
+ }),
326
+ "750 1 udp 500 fcd9:e3b8:12ce:9fc5:74a5:c6bb:d8b:e08a 53987 typ host",
327
+ ),
328
+ (
329
+ Some(Candidate {
330
+ network_type: NetworkType::Udp4,
331
+ candidate_type: CandidateType::Host,
332
+ address: "10.0.75.1".to_owned(),
333
+ port: 53634,
334
+ ..Default::default()
335
+ }),
336
+ "4273957277 1 udp 2130706431 10.0.75.1 53634 typ host",
337
+ ),
338
+ (
339
+ Some(Candidate {
340
+ network_type: NetworkType::Udp4,
341
+ candidate_type: CandidateType::ServerReflexive,
342
+ address: "191.228.238.68".to_owned(),
343
+ port: 53991,
344
+ related_address: Some(CandidateRelatedAddress {
345
+ address: "192.168.0.274".to_owned(),
346
+ port: 53991,
347
+ }),
348
+ ..Default::default()
349
+ }),
350
+ "647372371 1 udp 1694498815 191.228.238.68 53991 typ srflx raddr 192.168.0.274 rport 53991",
351
+ ),
352
+ (
353
+ Some(Candidate {
354
+ network_type: NetworkType::Udp4,
355
+ candidate_type: CandidateType::Relay,
356
+ address: "50.0.0.1".to_owned(),
357
+ port: 5000,
358
+ related_address: Some(CandidateRelatedAddress {
359
+ address: "192.168.0.1".to_owned(),
360
+ port: 5001,
361
+ }),
362
+ ..Default::default()
363
+ }),
364
+ "848194626 1 udp 16777215 50.0.0.1 5000 typ relay raddr 192.168.0.1 rport 5001",
365
+ ),
366
+ (
367
+ Some(Candidate {
368
+ network_type: NetworkType::Tcp4,
369
+ candidate_type: CandidateType::Host,
370
+ address: "192.168.0.196".to_owned(),
371
+ port: 0,
372
+ tcp_type: TcpType::Active,
373
+ ..Default::default()
374
+ }),
375
+ "1052353102 1 tcp 2128609279 192.168.0.196 0 typ host tcptype active",
376
+ ),
377
+ /*TODO: mDNS (
378
+ Some(Candidate{
379
+ network_type: NetworkType::Udp4,
380
+ candidate_type: CandidateType::Host,
381
+ address: "e2494022-4d9a-4c1e-a750-cc48d4f8d6ee.local".to_owned(),
382
+ port: 60542,
383
+ ..Default::default()
384
+ }),
385
+ "1380287402 1 udp 2130706431 e2494022-4d9a-4c1e-a750-cc48d4f8d6ee.local 60542 typ host",
386
+ ),*/
387
+ // Invalid candidates
388
+ (None, ""),
389
+ (None, "1938809241"),
390
+ (
391
+ None,
392
+ "1986380506 99999999 udp 2122063615 10.0.75.1 53634 typ host generation 0 network-id 2",
393
+ ),
394
+ (
395
+ None,
396
+ "1986380506 1 udp 99999999999 10.0.75.1 53634 typ host",
397
+ ),
398
+ (
399
+ None,
400
+ "4207374051 1 udp 1685790463 191.228.238.68 99999999 typ srflx raddr 192.168.0.278 rport 53991 generation 0 network-id 3",
401
+ ),
402
+ (
403
+ None,
404
+ "4207374051 1 udp 1685790463 191.228.238.68 53991 typ srflx raddr",
405
+ ),
406
+ (
407
+ None,
408
+ "4207374051 1 udp 1685790463 191.228.238.68 53991 typ srflx raddr 192.168.0.278 rport 99999999 generation 0 network-id 3",
409
+ ),
410
+ (
411
+ None,
412
+ "4207374051 INVALID udp 2130706431 10.0.75.1 53634 typ host",
413
+ ),
414
+ (None, "4207374051 1 udp INVALID 10.0.75.1 53634 typ host"),
415
+ (
416
+ None,
417
+ "4207374051 INVALID udp 2130706431 10.0.75.1 INVALID typ host",
418
+ ),
419
+ (
420
+ None,
421
+ "4207374051 1 udp 2130706431 10.0.75.1 53634 typ INVALID",
422
+ ),
423
+ ];
424
+
425
+ for (candidate, marshaled) in tests {
426
+ let actual_candidate = unmarshal_candidate(marshaled);
427
+ if let Some(candidate) = candidate {
428
+ if let Ok(actual_candidate) = actual_candidate {
429
+ assert!(
430
+ candidate.equal(&actual_candidate),
431
+ "{} vs {}",
432
+ candidate.marshal(),
433
+ marshaled
434
+ );
435
+ assert_eq!(marshaled, actual_candidate.marshal());
436
+ } else {
437
+ panic!("expected ok");
438
+ }
439
+ } else {
440
+ assert!(actual_candidate.is_err(), "expected error");
441
+ }
442
+ }
443
+
444
+ Ok(())
445
+ }
446
+
447
+ /// Regression test: a candidate's base address must be the local (bound)
448
+ /// transport address. For server/peer-reflexive candidates that is the
449
+ /// related address, not the NAT-mapped candidate address (RFC 8445 §5.1.1).
450
+ #[test]
451
+ fn test_candidate_base_addr() -> Result<()> {
452
+ let host = CandidateHostConfig {
453
+ base_config: CandidateConfig {
454
+ network: "udp".to_owned(),
455
+ address: "192.168.0.2".to_owned(),
456
+ port: 5000,
457
+ component: 1,
458
+ ..Default::default()
459
+ },
460
+ ..Default::default()
461
+ }
462
+ .new_candidate_host()?;
463
+ assert_eq!(host.base_addr(), host.addr(), "host base is itself");
464
+
465
+ let srflx = CandidateServerReflexiveConfig {
466
+ base_config: CandidateConfig {
467
+ network: "udp".to_owned(),
468
+ address: "10.79.12.1".to_owned(),
469
+ port: 60823,
470
+ component: 1,
471
+ ..Default::default()
472
+ },
473
+ rel_addr: "192.168.0.2".to_owned(),
474
+ rel_port: 5000,
475
+ ..Default::default()
476
+ }
477
+ .new_candidate_server_reflexive()?;
478
+ assert_eq!(
479
+ srflx.base_addr(),
480
+ "192.168.0.2:5000".parse().unwrap(),
481
+ "srflx base must be the related (host) address"
482
+ );
483
+ assert_ne!(srflx.base_addr(), srflx.addr());
484
+
485
+ let prflx = CandidatePeerReflexiveConfig {
486
+ base_config: CandidateConfig {
487
+ network: "udp".to_owned(),
488
+ address: "10.79.12.1".to_owned(),
489
+ port: 60824,
490
+ component: 1,
491
+ ..Default::default()
492
+ },
493
+ rel_addr: "192.168.0.2".to_owned(),
494
+ rel_port: 5000,
495
+ ..Default::default()
496
+ }
497
+ .new_candidate_peer_reflexive()?;
498
+ assert_eq!(
499
+ prflx.base_addr(),
500
+ "192.168.0.2:5000".parse().unwrap(),
501
+ "prflx base must be the related (host) address"
502
+ );
503
+
504
+ // Missing/unparseable related address falls back to the candidate address.
505
+ let prflx_no_rel = CandidatePeerReflexiveConfig {
506
+ base_config: CandidateConfig {
507
+ network: "udp".to_owned(),
508
+ address: "10.79.12.1".to_owned(),
509
+ port: 60825,
510
+ component: 1,
511
+ ..Default::default()
512
+ },
513
+ rel_addr: "".to_owned(),
514
+ rel_port: 0,
515
+ ..Default::default()
516
+ }
517
+ .new_candidate_peer_reflexive()?;
518
+ assert_eq!(prflx_no_rel.base_addr(), prflx_no_rel.addr());
519
+
520
+ let relay = CandidateRelayConfig {
521
+ base_config: CandidateConfig {
522
+ network: "udp".to_owned(),
523
+ address: "50.0.0.1".to_owned(),
524
+ port: 5000,
525
+ component: 1,
526
+ ..Default::default()
527
+ },
528
+ rel_addr: "192.168.0.2".to_owned(),
529
+ rel_port: 5001,
530
+ ..Default::default()
531
+ }
532
+ .new_candidate_relay()?;
533
+ assert_eq!(
534
+ relay.base_addr(),
535
+ relay.addr(),
536
+ "relay base is the relayed address itself"
537
+ );
538
+
539
+ Ok(())
540
+ }