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