1 use super::*; 2 3 #[test] 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] 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!(0, m.ipv4_mapping.ip_map.len(), "should match"); 31 assert_eq!(0, m.ipv6_mapping.ip_map.len(), "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!(0, m.ipv4_mapping.ip_map.len(), "should match"); 44 assert_eq!(0, m.ipv6_mapping.ip_map.len(), "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!(CandidateType::Host, m.candidate_type, "should match"); 50 assert!(m.ipv4_mapping.ip_sole.is_none()); 51 assert!(m.ipv6_mapping.ip_sole.is_some()); 52 assert_eq!(0, m.ipv4_mapping.ip_map.len(), "should match"); 53 assert_eq!(0, m.ipv6_mapping.ip_map.len(), "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!(CandidateType::Host, m.candidate_type, "should match"); 62 assert!(m.ipv4_mapping.ip_sole.is_some()); 63 assert!(m.ipv6_mapping.ip_sole.is_some()); 64 assert_eq!(0, m.ipv4_mapping.ip_map.len(), "should match"); 65 assert_eq!(0, m.ipv6_mapping.ip_map.len(), "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] 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!(CandidateType::Host, m.candidate_type, "should match"); 109 assert!(m.ipv4_mapping.ip_sole.is_none()); 110 assert!(m.ipv6_mapping.ip_sole.is_none()); 111 assert_eq!(1, m.ipv4_mapping.ip_map.len(), "should match"); 112 assert_eq!(0, m.ipv6_mapping.ip_map.len(), "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] 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] 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!("1.2.3.4", ext_ip.to_string(), "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!("2200::1", ext_ip.to_string(), "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] 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!("1.2.3.4", ext_ip.to_string(), "should match"); 212 213 let ext_ip = m.find_external_ip("10.0.0.2")?; 214 assert_eq!("1.2.3.5", ext_ip.to_string(), "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!("2200::1", ext_ip.to_string(), "should match"); 222 223 let ext_ip = m.find_external_ip("fe80::0002")?; // use '0002' instead of '2' on purpse 224 assert_eq!("2200::2", ext_ip.to_string(), "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] 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