1 use super::*;
2
3 #[test]
test_external_ip_mapper_validate_ip_string() -> Result<()>4 fn test_external_ip_mapper_validate_ip_string() -> Result<()> {
5 let ip = validate_ip_string("1.2.3.4")?;
6 assert!(ip.is_ipv4(), "should be true");
7 assert_eq!("1.2.3.4", ip.to_string(), "should be true");
8
9 let ip = validate_ip_string("2601:4567::5678")?;
10 assert!(!ip.is_ipv4(), "should be false");
11 assert_eq!("2601:4567::5678", ip.to_string(), "should be true");
12
13 let result = validate_ip_string("bad.6.6.6");
14 assert!(result.is_err(), "should fail");
15
16 Ok(())
17 }
18
19 #[test]
test_external_ip_mapper_new_external_ip_mapper() -> Result<()>20 fn test_external_ip_mapper_new_external_ip_mapper() -> Result<()> {
21 // ips being empty should succeed but mapper will still be nil
22 let m = ExternalIpMapper::new(CandidateType::Unspecified, &[])?;
23 assert!(m.is_none(), "should be none");
24
25 // IPv4 with no explicit local IP, defaults to CandidateTypeHost
26 let m = ExternalIpMapper::new(CandidateType::Unspecified, &["1.2.3.4".to_owned()])?.unwrap();
27 assert_eq!(m.candidate_type, CandidateType::Host, "should match");
28 assert!(m.ipv4_mapping.ip_sole.is_some());
29 assert!(m.ipv6_mapping.ip_sole.is_none());
30 assert_eq!(m.ipv4_mapping.ip_map.len(), 0, "should match");
31 assert_eq!(m.ipv6_mapping.ip_map.len(), 0, "should match");
32
33 // IPv4 with no explicit local IP, using CandidateTypeServerReflexive
34 let m =
35 ExternalIpMapper::new(CandidateType::ServerReflexive, &["1.2.3.4".to_owned()])?.unwrap();
36 assert_eq!(
37 CandidateType::ServerReflexive,
38 m.candidate_type,
39 "should match"
40 );
41 assert!(m.ipv4_mapping.ip_sole.is_some());
42 assert!(m.ipv6_mapping.ip_sole.is_none());
43 assert_eq!(m.ipv4_mapping.ip_map.len(), 0, "should match");
44 assert_eq!(m.ipv6_mapping.ip_map.len(), 0, "should match");
45
46 // IPv4 with no explicit local IP, defaults to CandidateTypeHost
47 let m = ExternalIpMapper::new(CandidateType::Unspecified, &["2601:4567::5678".to_owned()])?
48 .unwrap();
49 assert_eq!(m.candidate_type, CandidateType::Host, "should match");
50 assert!(m.ipv4_mapping.ip_sole.is_none());
51 assert!(m.ipv6_mapping.ip_sole.is_some());
52 assert_eq!(m.ipv4_mapping.ip_map.len(), 0, "should match");
53 assert_eq!(m.ipv6_mapping.ip_map.len(), 0, "should match");
54
55 // IPv4 and IPv6 in the mix
56 let m = ExternalIpMapper::new(
57 CandidateType::Unspecified,
58 &["1.2.3.4".to_owned(), "2601:4567::5678".to_owned()],
59 )?
60 .unwrap();
61 assert_eq!(m.candidate_type, CandidateType::Host, "should match");
62 assert!(m.ipv4_mapping.ip_sole.is_some());
63 assert!(m.ipv6_mapping.ip_sole.is_some());
64 assert_eq!(m.ipv4_mapping.ip_map.len(), 0, "should match");
65 assert_eq!(m.ipv6_mapping.ip_map.len(), 0, "should match");
66
67 // Unsupported candidate type - CandidateTypePeerReflexive
68 let result = ExternalIpMapper::new(CandidateType::PeerReflexive, &["1.2.3.4".to_owned()]);
69 assert!(result.is_err(), "should fail");
70
71 // Unsupported candidate type - CandidateTypeRelay
72 let result = ExternalIpMapper::new(CandidateType::PeerReflexive, &["1.2.3.4".to_owned()]);
73 assert!(result.is_err(), "should fail");
74
75 // Cannot duplicate mapping IPv4 family
76 let result = ExternalIpMapper::new(
77 CandidateType::ServerReflexive,
78 &["1.2.3.4".to_owned(), "5.6.7.8".to_owned()],
79 );
80 assert!(result.is_err(), "should fail");
81
82 // Cannot duplicate mapping IPv6 family
83 let result = ExternalIpMapper::new(
84 CandidateType::ServerReflexive,
85 &["2201::1".to_owned(), "2201::0002".to_owned()],
86 );
87 assert!(result.is_err(), "should fail");
88
89 // Invalide external IP string
90 let result = ExternalIpMapper::new(CandidateType::ServerReflexive, &["bad.2.3.4".to_owned()]);
91 assert!(result.is_err(), "should fail");
92
93 // Invalide local IP string
94 let result = ExternalIpMapper::new(
95 CandidateType::ServerReflexive,
96 &["1.2.3.4/10.0.0.bad".to_owned()],
97 );
98 assert!(result.is_err(), "should fail");
99
100 Ok(())
101 }
102
103 #[test]
test_external_ip_mapper_new_external_ip_mapper_with_explicit_local_ip() -> Result<()>104 fn test_external_ip_mapper_new_external_ip_mapper_with_explicit_local_ip() -> Result<()> {
105 // IPv4 with explicit local IP, defaults to CandidateTypeHost
106 let m = ExternalIpMapper::new(CandidateType::Unspecified, &["1.2.3.4/10.0.0.1".to_owned()])?
107 .unwrap();
108 assert_eq!(m.candidate_type, CandidateType::Host, "should match");
109 assert!(m.ipv4_mapping.ip_sole.is_none());
110 assert!(m.ipv6_mapping.ip_sole.is_none());
111 assert_eq!(m.ipv4_mapping.ip_map.len(), 1, "should match");
112 assert_eq!(m.ipv6_mapping.ip_map.len(), 0, "should match");
113
114 // Cannot assign two ext IPs for one local IPv4
115 let result = ExternalIpMapper::new(
116 CandidateType::Unspecified,
117 &["1.2.3.4/10.0.0.1".to_owned(), "1.2.3.5/10.0.0.1".to_owned()],
118 );
119 assert!(result.is_err(), "should fail");
120
121 // Cannot assign two ext IPs for one local IPv6
122 let result = ExternalIpMapper::new(
123 CandidateType::Unspecified,
124 &[
125 "2200::1/fe80::1".to_owned(),
126 "2200::0002/fe80::1".to_owned(),
127 ],
128 );
129 assert!(result.is_err(), "should fail");
130
131 // Cannot mix different IP family in a pair (1)
132 let result =
133 ExternalIpMapper::new(CandidateType::Unspecified, &["2200::1/10.0.0.1".to_owned()]);
134 assert!(result.is_err(), "should fail");
135
136 // Cannot mix different IP family in a pair (2)
137 let result = ExternalIpMapper::new(CandidateType::Unspecified, &["1.2.3.4/fe80::1".to_owned()]);
138 assert!(result.is_err(), "should fail");
139
140 // Invalid pair
141 let result = ExternalIpMapper::new(
142 CandidateType::Unspecified,
143 &["1.2.3.4/192.168.0.2/10.0.0.1".to_owned()],
144 );
145 assert!(result.is_err(), "should fail");
146
147 Ok(())
148 }
149
150 #[test]
test_external_ip_mapper_new_external_ip_mapper_with_implicit_local_ip() -> Result<()>151 fn test_external_ip_mapper_new_external_ip_mapper_with_implicit_local_ip() -> Result<()> {
152 // Mixing inpicit and explicit local IPs not allowed
153 let result = ExternalIpMapper::new(
154 CandidateType::Unspecified,
155 &["1.2.3.4".to_owned(), "1.2.3.5/10.0.0.1".to_owned()],
156 );
157 assert!(result.is_err(), "should fail");
158
159 // Mixing inpicit and explicit local IPs not allowed
160 let result = ExternalIpMapper::new(
161 CandidateType::Unspecified,
162 &["1.2.3.5/10.0.0.1".to_owned(), "1.2.3.4".to_owned()],
163 );
164 assert!(result.is_err(), "should fail");
165
166 Ok(())
167 }
168
169 #[test]
test_external_ip_mapper_find_external_ip_without_explicit_local_ip() -> Result<()>170 fn test_external_ip_mapper_find_external_ip_without_explicit_local_ip() -> Result<()> {
171 // IPv4 with explicit local IP, defaults to CandidateTypeHost
172 let m = ExternalIpMapper::new(
173 CandidateType::Unspecified,
174 &["1.2.3.4".to_owned(), "2200::1".to_owned()],
175 )?
176 .unwrap();
177 assert!(m.ipv4_mapping.ip_sole.is_some());
178 assert!(m.ipv6_mapping.ip_sole.is_some());
179
180 // find external IPv4
181 let ext_ip = m.find_external_ip("10.0.0.1")?;
182 assert_eq!(ext_ip.to_string(), "1.2.3.4", "should match");
183
184 // find external IPv6
185 let ext_ip = m.find_external_ip("fe80::0001")?; // use '0001' instead of '1' on purpse
186 assert_eq!(ext_ip.to_string(), "2200::1", "should match");
187
188 // Bad local IP string
189 let result = m.find_external_ip("really.bad");
190 assert!(result.is_err(), "should fail");
191
192 Ok(())
193 }
194
195 #[test]
test_external_ip_mapper_find_external_ip_with_explicit_local_ip() -> Result<()>196 fn test_external_ip_mapper_find_external_ip_with_explicit_local_ip() -> Result<()> {
197 // IPv4 with explicit local IP, defaults to CandidateTypeHost
198 let m = ExternalIpMapper::new(
199 CandidateType::Unspecified,
200 &[
201 "1.2.3.4/10.0.0.1".to_owned(),
202 "1.2.3.5/10.0.0.2".to_owned(),
203 "2200::1/fe80::1".to_owned(),
204 "2200::2/fe80::2".to_owned(),
205 ],
206 )?
207 .unwrap();
208
209 // find external IPv4
210 let ext_ip = m.find_external_ip("10.0.0.1")?;
211 assert_eq!(ext_ip.to_string(), "1.2.3.4", "should match");
212
213 let ext_ip = m.find_external_ip("10.0.0.2")?;
214 assert_eq!(ext_ip.to_string(), "1.2.3.5", "should match");
215
216 let result = m.find_external_ip("10.0.0.3");
217 assert!(result.is_err(), "should fail");
218
219 // find external IPv6
220 let ext_ip = m.find_external_ip("fe80::0001")?; // use '0001' instead of '1' on purpse
221 assert_eq!(ext_ip.to_string(), "2200::1", "should match");
222
223 let ext_ip = m.find_external_ip("fe80::0002")?; // use '0002' instead of '2' on purpse
224 assert_eq!(ext_ip.to_string(), "2200::2", "should match");
225
226 let result = m.find_external_ip("fe80::3");
227 assert!(result.is_err(), "should fail");
228
229 // Bad local IP string
230 let result = m.find_external_ip("really.bad");
231 assert!(result.is_err(), "should fail");
232
233 Ok(())
234 }
235
236 #[test]
test_external_ip_mapper_find_external_ip_with_empty_map() -> Result<()>237 fn test_external_ip_mapper_find_external_ip_with_empty_map() -> Result<()> {
238 let m = ExternalIpMapper::new(CandidateType::Unspecified, &["1.2.3.4".to_owned()])?.unwrap();
239
240 // attempt to find IPv6 that does not exist in the map
241 let result = m.find_external_ip("fe80::1");
242 assert!(result.is_err(), "should fail");
243
244 let m = ExternalIpMapper::new(CandidateType::Unspecified, &["2200::1".to_owned()])?.unwrap();
245
246 // attempt to find IPv4 that does not exist in the map
247 let result = m.find_external_ip("10.0.0.1");
248 assert!(result.is_err(), "should fail");
249
250 Ok(())
251 }
252