test_geoip.c (21268B)
1 /* Copyright (c) 2001-2004, Roger Dingledine. 2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 3 * Copyright (c) 2007-2021, The Tor Project, Inc. */ 4 /* See LICENSE for licensing information */ 5 6 #include "orconfig.h" 7 8 /* These macros pull in declarations for some functions and structures that 9 * are typically file-private. */ 10 #define GEOIP_PRIVATE 11 #include "core/or/or.h" 12 #include "app/config/config.h" 13 #include "lib/geoip/geoip.h" 14 #include "feature/stats/geoip_stats.h" 15 #include "test/test.h" 16 17 /* Record odd numbered fake-IPs using ipv6, even numbered fake-IPs 18 * using ipv4. Since our fake geoip database is the same between 19 * ipv4 and ipv6, we should get the same result no matter which 20 * address family we pick for each IP. */ 21 #define SET_TEST_ADDRESS(i) do { \ 22 if ((i) & 1) { \ 23 SET_TEST_IPV6(i); \ 24 tor_addr_from_in6(&addr, &in6); \ 25 } else { \ 26 tor_addr_from_ipv4h(&addr, (uint32_t) i); \ 27 } \ 28 } while (0) 29 30 /* Make sure that country ID actually works. */ 31 #define SET_TEST_IPV6(i) \ 32 do { \ 33 set_uint32(in6.s6_addr + 12, htonl((uint32_t) (i))); \ 34 } while (0) 35 #define CHECK_COUNTRY(country, val) do { \ 36 /* test ipv4 country lookup */ \ 37 tt_str_op(country, OP_EQ, \ 38 geoip_get_country_name(geoip_get_country_by_ipv4(val))); \ 39 /* test ipv6 country lookup */ \ 40 SET_TEST_IPV6(val); \ 41 tt_str_op(country, OP_EQ, \ 42 geoip_get_country_name(geoip_get_country_by_ipv6(&in6))); \ 43 } while (0) 44 45 /** Run unit tests for GeoIP code. */ 46 static void 47 test_geoip(void *arg) 48 { 49 int i, j; 50 time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */ 51 char *s = NULL, *v = NULL; 52 const char *bridge_stats_1 = 53 "bridge-stats-end 2010-08-12 13:27:30 (86400 s)\n" 54 "bridge-ips zz=24,xy=8\n" 55 "bridge-ip-versions v4=16,v6=16\n" 56 "bridge-ip-transports <OR>=24\n", 57 *dirreq_stats_1 = 58 "dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n" 59 "dirreq-v3-ips ab=8\n" 60 "dirreq-v3-reqs ab=8\n" 61 "dirreq-v3-resp " 62 "served=0,ok=0,not-enough-sigs=0,unavailable=0,not-found=0," 63 "not-modified=0,busy=0\n" 64 "dirreq-v3-direct-dl complete=0,timeout=0,running=0\n" 65 "dirreq-v3-tunneled-dl complete=0,timeout=0,running=0\n", 66 *dirreq_stats_2 = 67 "dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n" 68 "dirreq-v3-ips \n" 69 "dirreq-v3-reqs \n" 70 "dirreq-v3-resp " 71 "served=0,ok=0,not-enough-sigs=0,unavailable=0,not-found=0," 72 "not-modified=0,busy=0\n" 73 "dirreq-v3-direct-dl complete=0,timeout=0,running=0\n" 74 "dirreq-v3-tunneled-dl complete=0,timeout=0,running=0\n", 75 *dirreq_stats_3 = 76 "dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n" 77 "dirreq-v3-ips \n" 78 "dirreq-v3-reqs \n" 79 "dirreq-v3-resp " 80 "served=8,ok=8,not-enough-sigs=0,unavailable=0,not-found=0," 81 "not-modified=0,busy=0\n" 82 "dirreq-v3-direct-dl complete=0,timeout=0,running=0\n" 83 "dirreq-v3-tunneled-dl complete=0,timeout=0,running=0\n", 84 *dirreq_stats_4 = 85 "dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n" 86 "dirreq-v3-ips \n" 87 "dirreq-v3-reqs \n" 88 "dirreq-v3-resp " 89 "served=8,ok=8,not-enough-sigs=0,unavailable=0,not-found=0," 90 "not-modified=0,busy=0\n" 91 "dirreq-v3-direct-dl complete=0,timeout=0,running=0\n" 92 "dirreq-v3-tunneled-dl complete=0,timeout=0,running=4\n", 93 *entry_stats_1 = 94 "entry-stats-end 2010-08-12 13:27:30 (86400 s)\n" 95 "entry-ips ab=8\n", 96 *entry_stats_2 = 97 "entry-stats-end 2010-08-12 13:27:30 (86400 s)\n" 98 "entry-ips \n"; 99 tor_addr_t addr; 100 struct in6_addr in6; 101 102 /* Populate the DB a bit. Add these in order, since we can't do the final 103 * 'sort' step. These aren't very good IP addresses, but they're perfectly 104 * fine uint32_t values. */ 105 (void)arg; 106 tt_int_op(0,OP_EQ, geoip_parse_entry("10,50,AB", AF_INET)); 107 tt_int_op(0,OP_EQ, geoip_parse_entry("52,90,XY", AF_INET)); 108 tt_int_op(0,OP_EQ, geoip_parse_entry("95,100,AB", AF_INET)); 109 tt_int_op(0,OP_EQ, geoip_parse_entry("\"105\",\"140\",\"ZZ\"", AF_INET)); 110 tt_int_op(0,OP_EQ, geoip_parse_entry("\"150\",\"190\",\"XY\"", AF_INET)); 111 tt_int_op(0,OP_EQ, geoip_parse_entry("\"200\",\"250\",\"AB\"", AF_INET)); 112 113 /* Populate the IPv6 DB equivalently with fake IPs in the same range */ 114 tt_int_op(0,OP_EQ, geoip_parse_entry("::a,::32,AB", AF_INET6)); 115 tt_int_op(0,OP_EQ, geoip_parse_entry("::34,::5a,XY", AF_INET6)); 116 tt_int_op(0,OP_EQ, geoip_parse_entry("::5f,::64,AB", AF_INET6)); 117 tt_int_op(0,OP_EQ, geoip_parse_entry("::69,::8c,ZZ", AF_INET6)); 118 tt_int_op(0,OP_EQ, geoip_parse_entry("::96,::be,XY", AF_INET6)); 119 tt_int_op(0,OP_EQ, geoip_parse_entry("::c8,::fa,AB", AF_INET6)); 120 121 /* We should have 4 countries: ??, ab, xy, zz. */ 122 tt_int_op(4,OP_EQ, geoip_get_n_countries()); 123 memset(&in6, 0, sizeof(in6)); 124 125 CHECK_COUNTRY("??", 3); 126 CHECK_COUNTRY("ab", 32); 127 CHECK_COUNTRY("??", 5); 128 CHECK_COUNTRY("??", 51); 129 CHECK_COUNTRY("xy", 150); 130 CHECK_COUNTRY("xy", 190); 131 CHECK_COUNTRY("??", 2000); 132 133 tt_int_op(0,OP_EQ, geoip_get_country_by_ipv4(3)); 134 SET_TEST_IPV6(3); 135 tt_int_op(0,OP_EQ, geoip_get_country_by_ipv6(&in6)); 136 137 get_options_mutable()->BridgeRelay = 1; 138 get_options_mutable()->BridgeRecordUsageByCountry = 1; 139 /* Put 9 observations in AB... */ 140 for (i=32; i < 40; ++i) { 141 SET_TEST_ADDRESS(i); 142 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now-7200); 143 } 144 SET_TEST_ADDRESS(225); 145 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now-7200); 146 /* and 3 observations in XY, several times. */ 147 for (j=0; j < 10; ++j) 148 for (i=52; i < 55; ++i) { 149 SET_TEST_ADDRESS(i); 150 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now-3600); 151 } 152 /* and 17 observations in ZZ... */ 153 for (i=110; i < 127; ++i) { 154 SET_TEST_ADDRESS(i); 155 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now); 156 } 157 geoip_get_client_history(GEOIP_CLIENT_CONNECT, &s, &v); 158 tt_assert(s); 159 tt_assert(v); 160 tt_str_op("zz=24,ab=16,xy=8",OP_EQ, s); 161 tt_str_op("v4=16,v6=16",OP_EQ, v); 162 tor_free(s); 163 tor_free(v); 164 165 /* Now clear out all the AB observations. */ 166 geoip_remove_old_clients(now-6000); 167 geoip_get_client_history(GEOIP_CLIENT_CONNECT, &s, &v); 168 tt_assert(s); 169 tt_assert(v); 170 tt_str_op("zz=24,xy=8",OP_EQ, s); 171 tt_str_op("v4=16,v6=16",OP_EQ, v); 172 tor_free(s); 173 tor_free(v); 174 175 /* Start testing bridge statistics by making sure that we don't output 176 * bridge stats without initializing them. */ 177 s = geoip_format_bridge_stats(now + 86400); 178 tt_ptr_op(s, OP_EQ, NULL); 179 180 /* Initialize stats and generate the bridge-stats history string out of 181 * the connecting clients added above. */ 182 geoip_bridge_stats_init(now); 183 s = geoip_format_bridge_stats(now + 86400); 184 tt_assert(s); 185 tt_str_op(bridge_stats_1,OP_EQ, s); 186 tor_free(s); 187 188 /* Stop collecting bridge stats and make sure we don't write a history 189 * string anymore. */ 190 geoip_bridge_stats_term(); 191 s = geoip_format_bridge_stats(now + 86400); 192 tt_ptr_op(s, OP_EQ, NULL); 193 194 /* Stop being a bridge and start being a directory mirror that gathers 195 * directory request statistics. */ 196 geoip_bridge_stats_term(); 197 get_options_mutable()->BridgeRelay = 0; 198 get_options_mutable()->BridgeRecordUsageByCountry = 0; 199 get_options_mutable()->DirReqStatistics = 1; 200 201 /* Start testing dirreq statistics by making sure that we don't collect 202 * dirreq stats without initializing them. */ 203 SET_TEST_ADDRESS(100); 204 geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now); 205 s = geoip_format_dirreq_stats(now + 86400); 206 tt_ptr_op(s, OP_EQ, NULL); 207 208 /* Initialize stats, note one connecting client, and generate the 209 * dirreq-stats history string. */ 210 geoip_dirreq_stats_init(now); 211 SET_TEST_ADDRESS(100); 212 geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now); 213 s = geoip_format_dirreq_stats(now + 86400); 214 tt_str_op(dirreq_stats_1,OP_EQ, s); 215 tor_free(s); 216 217 /* Stop collecting stats, add another connecting client, and ensure we 218 * don't generate a history string. */ 219 geoip_dirreq_stats_term(); 220 SET_TEST_ADDRESS(101); 221 geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now); 222 s = geoip_format_dirreq_stats(now + 86400); 223 tt_ptr_op(s, OP_EQ, NULL); 224 225 /* Re-start stats, add a connecting client, reset stats, and make sure 226 * that we get an all empty history string. */ 227 geoip_dirreq_stats_init(now); 228 SET_TEST_ADDRESS(100); 229 geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now); 230 geoip_reset_dirreq_stats(now); 231 s = geoip_format_dirreq_stats(now + 86400); 232 tt_str_op(dirreq_stats_2,OP_EQ, s); 233 tor_free(s); 234 235 /* Note a successful network status response and make sure that it 236 * appears in the history string. */ 237 geoip_note_ns_response(GEOIP_SERVED); 238 geoip_note_ns_response(GEOIP_SUCCESS); 239 s = geoip_format_dirreq_stats(now + 86400); 240 tt_str_op(dirreq_stats_3,OP_EQ, s); 241 tor_free(s); 242 243 /* Start a tunneled directory request. */ 244 geoip_start_dirreq((uint64_t) 1, 1024, DIRREQ_TUNNELED); 245 s = geoip_format_dirreq_stats(now + 86400); 246 tt_str_op(dirreq_stats_4,OP_EQ, s); 247 tor_free(s); 248 249 /* Stop collecting directory request statistics and start gathering 250 * entry stats. */ 251 geoip_dirreq_stats_term(); 252 get_options_mutable()->DirReqStatistics = 0; 253 get_options_mutable()->EntryStatistics = 1; 254 255 /* Start testing entry statistics by making sure that we don't collect 256 * anything without initializing entry stats. */ 257 SET_TEST_ADDRESS(100); 258 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now); 259 s = geoip_format_entry_stats(now + 86400); 260 tt_ptr_op(s, OP_EQ, NULL); 261 262 /* Initialize stats, note one connecting client, and generate the 263 * entry-stats history string. */ 264 geoip_entry_stats_init(now); 265 SET_TEST_ADDRESS(100); 266 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now); 267 s = geoip_format_entry_stats(now + 86400); 268 tt_str_op(entry_stats_1,OP_EQ, s); 269 tor_free(s); 270 271 /* Stop collecting stats, add another connecting client, and ensure we 272 * don't generate a history string. */ 273 geoip_entry_stats_term(); 274 SET_TEST_ADDRESS(101); 275 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now); 276 s = geoip_format_entry_stats(now + 86400); 277 tt_ptr_op(s, OP_EQ, NULL); 278 279 /* Re-start stats, add a connecting client, reset stats, and make sure 280 * that we get an all empty history string. */ 281 geoip_entry_stats_init(now); 282 SET_TEST_ADDRESS(100); 283 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now); 284 geoip_reset_entry_stats(now); 285 s = geoip_format_entry_stats(now + 86400); 286 tt_str_op(entry_stats_2,OP_EQ, s); 287 tor_free(s); 288 289 /* Test the OOM handler. Add a client, run the OOM. */ 290 geoip_entry_stats_init(now); 291 SET_TEST_ADDRESS(100); 292 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, 293 now - (12 * 60 * 60)); 294 /* We've seen this 12 hours ago. Run the OOM, it should clean the entry 295 * because it is above the minimum cutoff of 4 hours. */ 296 size_t bytes_removed = geoip_client_cache_handle_oom(now, 1000); 297 tt_size_op(bytes_removed, OP_GT, 0); 298 299 /* Do it again but this time with an entry with a lower cutoff. */ 300 geoip_entry_stats_init(now); 301 SET_TEST_ADDRESS(100); 302 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, 303 now - (3 * 60 * 60)); 304 bytes_removed = geoip_client_cache_handle_oom(now, 1000); 305 tt_size_op(bytes_removed, OP_EQ, 0); 306 307 /* Stop collecting entry statistics. */ 308 geoip_entry_stats_term(); 309 get_options_mutable()->EntryStatistics = 0; 310 311 done: 312 tor_free(s); 313 tor_free(v); 314 } 315 316 static void 317 test_geoip_with_pt(void *arg) 318 { 319 time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */ 320 char *s = NULL; 321 int i; 322 tor_addr_t addr; 323 struct in6_addr in6; 324 325 (void)arg; 326 get_options_mutable()->BridgeRelay = 1; 327 get_options_mutable()->BridgeRecordUsageByCountry = 1; 328 329 memset(&in6, 0, sizeof(in6)); 330 331 /* No clients seen yet. */ 332 s = geoip_get_transport_history(); 333 tor_assert(!s); 334 335 /* 4 connections without a pluggable transport */ 336 for (i=0; i < 4; ++i) { 337 SET_TEST_ADDRESS(i); 338 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now-7200); 339 } 340 341 /* 9 connections with "alpha" */ 342 for (i=4; i < 13; ++i) { 343 SET_TEST_ADDRESS(i); 344 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "alpha", now-7200); 345 } 346 347 /* one connection with "beta" */ 348 SET_TEST_ADDRESS(13); 349 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "beta", now-7200); 350 351 /* 14 connections with "charlie" */ 352 for (i=14; i < 28; ++i) { 353 SET_TEST_ADDRESS(i); 354 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "charlie", now-7200); 355 } 356 357 /* 131 connections with "ddr" */ 358 for (i=28; i < 159; ++i) { 359 SET_TEST_ADDRESS(i); 360 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "ddr", now-7200); 361 } 362 363 /* 8 connections with "entropy" */ 364 for (i=159; i < 167; ++i) { 365 SET_TEST_ADDRESS(i); 366 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "entropy", now-7200); 367 } 368 369 /* 2 connections from the same IP with two different transports. */ 370 SET_TEST_ADDRESS(++i); 371 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "fire", now-7200); 372 geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "google", now-7200); 373 374 /* Test the transport history string. */ 375 s = geoip_get_transport_history(); 376 tor_assert(s); 377 tt_str_op(s,OP_EQ, "<OR>=8,alpha=16,beta=8,charlie=16,ddr=136," 378 "entropy=8,fire=8,google=8"); 379 380 /* Stop collecting entry statistics. */ 381 geoip_entry_stats_term(); 382 get_options_mutable()->EntryStatistics = 0; 383 384 done: 385 tor_free(s); 386 } 387 388 #undef SET_TEST_ADDRESS 389 #undef SET_TEST_IPV6 390 #undef CHECK_COUNTRY 391 392 static const char GEOIP_CONTENT[] = 393 "134445936,134445939,MP\n" 394 "134445940,134447103,GU\n" 395 "134447104,134738943,US\n" 396 "134738944,134739199,CA\n" 397 "134739200,135192575,US\n" 398 "135192576,135200767,MX\n" 399 "135200768,135430143,US\n" 400 "135430144,135430399,CA\n" 401 "135430400,135432191,US\n"; 402 403 static void 404 test_geoip_load_file(void *arg) 405 { 406 (void)arg; 407 char *contents = NULL; 408 char *dhex = NULL; 409 410 /* A nonexistent filename should fail. */ 411 tt_int_op(-1, OP_EQ, 412 geoip_load_file(AF_INET, "/you/did/not/put/a/file/here/I/hope", 413 LOG_INFO)); 414 415 /* We start out with only "Ningunpartia" in the database. */ 416 tt_int_op(1, OP_EQ, geoip_get_n_countries()); 417 tt_str_op("??", OP_EQ, geoip_get_country_name(0)); 418 /* Any lookup attempt should say "-1" because we have no info */ 419 tt_int_op(-1, OP_EQ, geoip_get_country_by_ipv4(0x01020304)); 420 /* There should be no 'digest' for a nonexistent file */ 421 tt_str_op("0000000000000000000000000000000000000000", OP_EQ, 422 geoip_db_digest(AF_INET)); 423 424 const char *fname = get_fname("geoip"); 425 tt_int_op(0, OP_EQ, write_str_to_file(fname, GEOIP_CONTENT, 1)); 426 427 int rv = geoip_load_file(AF_INET, fname, LOG_WARN); 428 if (rv != 0) { 429 TT_GRIPE(("Unable to load geoip from %s", escaped(fname))); 430 } 431 tt_int_op(0, OP_EQ, rv); 432 433 /* Check that we loaded some countries; this will fail if there are ever 434 * fewer than 5 countries in our test above. */ 435 tt_int_op(geoip_get_n_countries(), OP_GE, 5); 436 437 /* Let's see where 8.8.8.8 is. */ 438 int country = geoip_get_country_by_ipv4(0x08080808); 439 tt_int_op(country, OP_GE, 1); /* It shouldn't be 'unknown' or 'nowhere' */ 440 const char *cc = geoip_get_country_name(country); 441 tt_int_op(strlen(cc), OP_EQ, 2); 442 443 /* The digest should be set.... */ 444 tt_str_op("0000000000000000000000000000000000000000", OP_NE, 445 geoip_db_digest(AF_INET)); 446 447 /* And it should be set correctly */ 448 contents = read_file_to_str(fname, RFTS_BIN, NULL); 449 uint8_t d[DIGEST_LEN]; 450 crypto_digest((char*)d, contents, strlen(contents)); 451 dhex = tor_strdup(hex_str((char*)d, DIGEST_LEN)); 452 tt_str_op(dhex, OP_EQ, geoip_db_digest(AF_INET)); 453 454 /* Make sure geoip_free_all() works. */ 455 geoip_free_all(); 456 tt_int_op(1, OP_EQ, geoip_get_n_countries()); 457 tt_str_op("??", OP_EQ, geoip_get_country_name(0)); 458 tt_int_op(-1, OP_EQ, geoip_get_country_by_ipv4(0x01020304)); 459 tt_str_op("0000000000000000000000000000000000000000", OP_EQ, 460 geoip_db_digest(AF_INET)); // <--- nick bets this will fail. 461 462 done: 463 tor_free(contents); 464 tor_free(dhex); 465 } 466 467 static void 468 test_geoip6_load_file(void *arg) 469 { 470 (void)arg; 471 struct in6_addr iaddr6; 472 char *contents = NULL; 473 char *dhex = NULL; 474 475 /* A nonexistent filename should fail. */ 476 tt_int_op(-1, OP_EQ, 477 geoip_load_file(AF_INET6, "/you/did/not/put/a/file/here/I/hope", 478 LOG_INFO)); 479 480 /* Any lookup attempt should say "-1" because we have no info */ 481 tor_inet_pton(AF_INET6, "2001:4860:4860::8888", &iaddr6); 482 tt_int_op(-1, OP_EQ, geoip_get_country_by_ipv6(&iaddr6)); 483 484 /* Load geiop6 file */ 485 const char *fname6 = get_fname("geoip6"); 486 const char CONTENT[] = 487 "2001:4830:6010::,2001:4830:601f:ffff:ffff:ffff:ffff:ffff,GB\n" 488 "2001:4830:6020::,2001:4830:ffff:ffff:ffff:ffff:ffff:ffff,US\n" 489 "2001:4838::,2001:4838:ffff:ffff:ffff:ffff:ffff:ffff,US\n" 490 "2001:4840::,2001:4840:ffff:ffff:ffff:ffff:ffff:ffff,XY\n" 491 "2001:4848::,2001:4848:ffff:ffff:ffff:ffff:ffff:ffff,ZD\n" 492 "2001:4850::,2001:4850:ffff:ffff:ffff:ffff:ffff:ffff,RO\n" 493 "2001:4858::,2001:4858:ffff:ffff:ffff:ffff:ffff:ffff,TC\n" 494 "2001:4860::,2001:4860:ffff:ffff:ffff:ffff:ffff:ffff,US\n" 495 "2001:4868::,2001:4868:ffff:ffff:ffff:ffff:ffff:ffff,US\n" 496 "2001:4870::,2001:4871:ffff:ffff:ffff:ffff:ffff:ffff,NB\n" 497 "2001:4878::,2001:4878:128:ffff:ffff:ffff:ffff:ffff,US\n" 498 "2001:4878:129::,2001:4878:129:ffff:ffff:ffff:ffff:ffff,CR\n" 499 "2001:4878:12a::,2001:4878:203:ffff:ffff:ffff:ffff:ffff,US\n" 500 "2001:4878:204::,2001:4878:204:ffff:ffff:ffff:ffff:ffff,DE\n" 501 "2001:4878:205::,2001:4878:214:ffff:ffff:ffff:ffff:ffff,US\n"; 502 tt_int_op(0, OP_EQ, write_str_to_file(fname6, CONTENT, 1)); 503 504 tt_int_op(0, OP_EQ, geoip_load_file(AF_INET6, fname6, LOG_WARN)); 505 506 /* Check that we loaded some countries; this will fail if there are ever 507 * fewer than 5 countries in our test data above. */ 508 tt_int_op(geoip_get_n_countries(), OP_GE, 5); 509 510 /* Let's see where 2001:4860:4860::8888 (google dns) is. */ 511 const char *caddr6 = "2001:4860:4860::8888"; 512 tor_inet_pton(AF_INET6, caddr6, &iaddr6); 513 int country6 = geoip_get_country_by_ipv6(&iaddr6); 514 tt_int_op(country6, OP_GE, 1); 515 516 const char *cc6 = geoip_get_country_name(country6); 517 tt_int_op(strlen(cc6), OP_EQ, 2); 518 519 /* The digest should be set.... */ 520 tt_str_op("0000000000000000000000000000000000000000", OP_NE, 521 geoip_db_digest(AF_INET6)); 522 523 /* And it should be set correctly */ 524 contents = read_file_to_str(fname6, RFTS_BIN, NULL); 525 uint8_t d[DIGEST_LEN]; 526 crypto_digest((char*)d, contents, strlen(contents)); 527 dhex = tor_strdup(hex_str((char*)d, DIGEST_LEN)); 528 tt_str_op(dhex, OP_EQ, geoip_db_digest(AF_INET6)); 529 530 /* Make sure geoip_free_all() works. */ 531 geoip_free_all(); 532 tt_int_op(1, OP_EQ, geoip_get_n_countries()); 533 tt_str_op("??", OP_EQ, geoip_get_country_name(0)); 534 tor_inet_pton(AF_INET6, "::1:2:3:4", &iaddr6); 535 tt_int_op(-1, OP_EQ, geoip_get_country_by_ipv6(&iaddr6)); 536 tt_str_op("0000000000000000000000000000000000000000", OP_EQ, 537 geoip_db_digest(AF_INET6)); 538 539 done: 540 tor_free(contents); 541 tor_free(dhex); 542 } 543 544 static void 545 test_geoip_load_2nd_file(void *arg) 546 { 547 (void)arg; 548 549 char *fname_geoip = tor_strdup(get_fname("geoip_data")); 550 char *fname_empty = tor_strdup(get_fname("geoip_empty")); 551 552 tt_int_op(0, OP_EQ, write_str_to_file(fname_geoip, GEOIP_CONTENT, 1)); 553 tt_int_op(0, OP_EQ, write_str_to_file(fname_empty, "\n", 1)); 554 555 /* Load 1st geoip file */ 556 tt_int_op(0, OP_EQ, geoip_load_file(AF_INET, fname_geoip, LOG_WARN)); 557 558 /* Load 2nd geoip (empty) file */ 559 /* It has to be the same IP address family */ 560 tt_int_op(0, OP_EQ, geoip_load_file(AF_INET, fname_empty, LOG_WARN)); 561 562 /* Check that there is no geoip information for 8.8.8.8, */ 563 /* since loading the empty 2nd file should have delete it. */ 564 int country = geoip_get_country_by_ipv4(0x08080808); 565 tt_int_op(country, OP_EQ, 0); 566 567 done: 568 tor_free(fname_geoip); 569 tor_free(fname_empty); 570 } 571 572 #define ENT(name) \ 573 { #name, test_ ## name , 0, NULL, NULL } 574 #define FORK(name) \ 575 { #name, test_ ## name , TT_FORK, NULL, NULL } 576 577 struct testcase_t geoip_tests[] = { 578 { "geoip", test_geoip, TT_FORK, NULL, NULL }, 579 { "geoip_with_pt", test_geoip_with_pt, TT_FORK, NULL, NULL }, 580 { "load_file", test_geoip_load_file, TT_FORK, NULL, NULL }, 581 { "load_file6", test_geoip6_load_file, TT_FORK, NULL, NULL }, 582 { "load_2nd_file", test_geoip_load_2nd_file, TT_FORK, NULL, NULL }, 583 584 END_OF_TESTCASES 585 };