tor-commits
Threads by month
- ----- 2025 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
May 2019
- 17 participants
- 2795 discussions
commit e253a117c0a2db9315ac44f09cfba5e854f4e172
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Wed May 15 04:46:05 2019 +0000
Bug 28780: Add tests
Also test circpad expiry safeguard.
---
src/core/or/circuituse.c | 4 +-
src/test/test_circuitpadding.c | 188 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 190 insertions(+), 2 deletions(-)
diff --git a/src/core/or/circuituse.c b/src/core/or/circuituse.c
index bdab47683..485c38905 100644
--- a/…
[View More]src/core/or/circuituse.c
+++ b/src/core/or/circuituse.c
@@ -70,7 +70,7 @@
#include "core/or/origin_circuit_st.h"
#include "core/or/socks_request_st.h"
-static void circuit_expire_old_circuits_clientside(void);
+STATIC void circuit_expire_old_circuits_clientside(void);
static void circuit_increment_failure_count(void);
/** Check whether the hidden service destination of the stream at
@@ -1474,7 +1474,7 @@ circuit_detach_stream(circuit_t *circ, edge_connection_t *conn)
/** Find each circuit that has been unused for too long, or dirty
* for too long and has no streams on it: mark it for close.
*/
-static void
+STATIC void
circuit_expire_old_circuits_clientside(void)
{
struct timeval cutoff, now;
diff --git a/src/test/test_circuitpadding.c b/src/test/test_circuitpadding.c
index db175fece..2e6715944 100644
--- a/src/test/test_circuitpadding.c
+++ b/src/test/test_circuitpadding.c
@@ -41,6 +41,7 @@
TOR_NSEC_PER_USEC*TOR_USEC_PER_SEC)
extern smartlist_t *connection_array;
+void circuit_expire_old_circuits_clientside(void);
circid_t get_unique_circ_id_by_chan(channel_t *chan);
void helper_create_basic_machine(void);
@@ -2550,6 +2551,192 @@ test_circuitpadding_reduce_disable(void *arg)
circuitmux_free(dummy_channel.cmux);
}
+/** Just a basic machine whose whole purpose is to reach the END state */
+static void
+helper_create_ender_machine(void)
+{
+ /* Start, burst */
+ circpad_machine_states_init(&circ_client_machine, 2);
+
+ circ_client_machine.states[CIRCPAD_STATE_START].
+ next_state[CIRCPAD_EVENT_NONPADDING_RECV] = CIRCPAD_STATE_END;
+
+ circ_client_machine.conditions.state_mask = CIRCPAD_STATE_ALL;
+ circ_client_machine.conditions.purpose_mask = CIRCPAD_PURPOSE_ALL;
+}
+
+static time_t mocked_timeofday;
+/** Set timeval to a mock date and time. This is necessary
+ * to make tor_gettimeofday() mockable. */
+static void
+mock_tor_gettimeofday(struct timeval *timeval)
+{
+ timeval->tv_sec = mocked_timeofday;
+ timeval->tv_usec = 0;
+}
+
+/** Test manual managing of circuit lifetimes by the circuitpadding
+ * subsystem. In particular this test goes through all the cases of the
+ * circpad_marked_circuit_for_padding() function, via
+ * circuit_mark_for_close() as well as
+ * circuit_expire_old_circuits_clientside(). */
+static void
+test_circuitpadding_manage_circuit_lifetime(void *arg)
+{
+ circpad_machine_runtime_t *mi;
+
+ (void) arg;
+
+ client_side = (circuit_t *)origin_circuit_new();
+ client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL;
+ monotime_enable_test_mocking();
+ MOCK(tor_gettimeofday, mock_tor_gettimeofday);
+ mocked_timeofday = 23;
+
+ helper_create_ender_machine();
+
+ /* Enable manual circuit lifetime manage for this test */
+ circ_client_machine.manage_circ_lifetime = 1;
+
+ /* Test setup */
+ client_side->padding_machine[0] = &circ_client_machine;
+ client_side->padding_info[0] =
+ circpad_circuit_machineinfo_new(client_side, 0);
+ mi = client_side->padding_info[0];
+
+ tt_int_op(mi->current_state, OP_EQ, CIRCPAD_STATE_START);
+
+ /* Check that the circuit is not marked for close */
+ tt_int_op(client_side->marked_for_close, OP_EQ, 0);
+ tt_int_op(client_side->purpose, OP_EQ, CIRCUIT_PURPOSE_C_GENERAL);
+
+ /* Mark this circuit for close due to a remote reason */
+ circuit_mark_for_close(client_side,
+ END_CIRC_REASON_FLAG_REMOTE|END_CIRC_REASON_NONE);
+ tt_ptr_op(client_side->padding_info[0], OP_NE, NULL);
+ tt_int_op(client_side->marked_for_close, OP_NE, 0);
+ tt_int_op(client_side->purpose, OP_EQ, CIRCUIT_PURPOSE_C_GENERAL);
+ client_side->marked_for_close = 0;
+
+ /* Mark this circuit for close due to a protocol issue */
+ circuit_mark_for_close(client_side, END_CIRC_REASON_TORPROTOCOL);
+ tt_int_op(client_side->marked_for_close, OP_NE, 0);
+ tt_int_op(client_side->purpose, OP_EQ, CIRCUIT_PURPOSE_C_GENERAL);
+ client_side->marked_for_close = 0;
+
+ /* Mark a measurement circuit for close */
+ client_side->purpose = CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT;
+ circuit_mark_for_close(client_side, END_CIRC_REASON_NONE);
+ tt_int_op(client_side->marked_for_close, OP_NE, 0);
+ tt_int_op(client_side->purpose, OP_EQ, CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT);
+ client_side->marked_for_close = 0;
+
+ /* Mark a general circuit for close */
+ client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL;
+ circuit_mark_for_close(client_side, END_CIRC_REASON_NONE);
+
+ /* Check that this circuit is still not marked for close since we are
+ * managing the lifetime manually, but the circuit was tagged as such by the
+ * circpadding subsystem */
+ tt_int_op(client_side->marked_for_close, OP_EQ, 0);
+ tt_int_op(client_side->purpose, OP_EQ, CIRCUIT_PURPOSE_C_CIRCUIT_PADDING);
+
+ /* We just tested case (1) from the comments of
+ * circpad_circuit_should_be_marked_for_close() */
+
+ /* Transition the machine to the END state but did not delete its machine */
+ tt_ptr_op(client_side->padding_info[0], OP_NE, NULL);
+ circpad_cell_event_nonpadding_received(client_side);
+ tt_int_op(mi->current_state, OP_EQ, CIRCPAD_STATE_END);
+
+ /* We just tested case (3) from the comments of
+ * circpad_circuit_should_be_marked_for_close().
+ * Now let's go for case (2). */
+
+ /* Reset the close mark */
+ client_side->marked_for_close = 0;
+
+ /* Mark this circuit for close */
+ circuit_mark_for_close(client_side, 0);
+
+ /* See that the circ got closed since we are already in END state */
+ tt_int_op(client_side->marked_for_close, OP_NE, 0);
+
+ /* We just tested case (2). Now let's see that case (4) is unreachable as
+ that comment claims */
+
+ /* First, reset all close marks and tags */
+ client_side->marked_for_close = 0;
+ client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL;
+
+ /* Now re-create the ender machine so that we can transition to END again */
+ /* Free up some stuff first */
+ circpad_circuit_free_all_machineinfos(client_side);
+ tor_free(circ_client_machine.states);
+ helper_create_ender_machine();
+
+ client_side->padding_machine[0] = &circ_client_machine;
+ client_side->padding_info[0] =
+ circpad_circuit_machineinfo_new(client_side, 0);
+ mi = client_side->padding_info[0];
+
+ /* Check we are in START. */
+ tt_int_op(mi->current_state, OP_EQ, CIRCPAD_STATE_START);
+
+ /* Test that we don't expire this circuit yet */
+ client_side->timestamp_dirty = 0;
+ client_side->state = CIRCUIT_STATE_OPEN;
+ tor_gettimeofday(&client_side->timestamp_began);
+ TO_ORIGIN_CIRCUIT(client_side)->circuit_idle_timeout = 23;
+ mocked_timeofday += 24;
+ circuit_expire_old_circuits_clientside();
+ circuit_expire_old_circuits_clientside();
+ circuit_expire_old_circuits_clientside();
+ tt_int_op(client_side->timestamp_dirty, OP_NE, 0);
+ tt_int_op(client_side->marked_for_close, OP_EQ, 0);
+ tt_int_op(client_side->purpose, OP_EQ, CIRCUIT_PURPOSE_C_CIRCUIT_PADDING);
+
+ /* Runaway circpad test: if the machine does not transition to end,
+ * test that after CIRCPAD_DELAY_MAX_SECS, we get marked anyway */
+ mocked_timeofday = client_side->timestamp_dirty
+ + get_options()->MaxCircuitDirtiness + 2;
+ client_side->padding_info[0]->last_cell_time_sec =
+ approx_time()-(CIRCPAD_DELAY_MAX_SECS+10);
+ circuit_expire_old_circuits_clientside();
+ tt_int_op(client_side->marked_for_close, OP_NE, 0);
+
+ /* Test back to normal: if we had activity, we won't close */
+ client_side->padding_info[0]->last_cell_time_sec = approx_time();
+ client_side->marked_for_close = 0;
+ circuit_expire_old_circuits_clientside();
+ tt_int_op(client_side->marked_for_close, OP_EQ, 0);
+
+ /* Transition to END, but before we're past the dirty timer */
+ mocked_timeofday = client_side->timestamp_dirty;
+ circpad_cell_event_nonpadding_received(client_side);
+ tt_int_op(mi->current_state, OP_EQ, CIRCPAD_STATE_END);
+
+ /* Verify that the circuit was not closed. */
+ tt_int_op(client_side->marked_for_close, OP_EQ, 0);
+
+ /* Now that we are in END state, we can be closed by expiry, but via
+ * the timestamp_dirty path, not the idle path. So first test not dirty
+ * enough. */
+ mocked_timeofday = client_side->timestamp_dirty;
+ circuit_expire_old_circuits_clientside();
+ tt_int_op(client_side->marked_for_close, OP_EQ, 0);
+ mocked_timeofday = client_side->timestamp_dirty
+ + get_options()->MaxCircuitDirtiness + 2;
+ circuit_expire_old_circuits_clientside();
+ tt_int_op(client_side->marked_for_close, OP_NE, 0);
+
+ done:
+ free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side));
+ tor_free(circ_client_machine.states);
+ monotime_disable_test_mocking();
+ UNMOCK(tor_gettimeofday);
+}
+
#define TEST_CIRCUITPADDING(name, flags) \
{ #name, test_##name, (flags), NULL, NULL }
@@ -2570,5 +2757,6 @@ struct testcase_t circuitpadding_tests[] = {
TEST_CIRCUITPADDING(circuitpadding_closest_token_removal, TT_FORK),
TEST_CIRCUITPADDING(circuitpadding_closest_token_removal_usec, TT_FORK),
TEST_CIRCUITPADDING(circuitpadding_token_removal_exact, TT_FORK),
+ TEST_CIRCUITPADDING(circuitpadding_manage_circuit_lifetime, TT_FORK),
END_OF_TESTCASES
};
[View Less]
1
0
commit 5cc988a947e8ba10e2682274465a82ff22e7c93d
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Thu Apr 18 20:35:22 2019 +0000
Bug 28780: Changes file
---
changes/ticket28780 | 3 +++
1 file changed, 3 insertions(+)
diff --git a/changes/ticket28780 b/changes/ticket28780
new file mode 100644
index 000000000..d7c6693f8
--- /dev/null
+++ b/changes/ticket28780
@@ -0,0 +1,3 @@
+ o Minor features (circuit padding):
+ - Provide the ability for circuit padding machines to …
[View More]hold a circuit open
+ until they are done padding it. Closes ticket 28780.
[View Less]
1
0

[tor/master] Pathbias should continue to ignore previously ignored circs.
by asn@torproject.org 15 May '19
by asn@torproject.org 15 May '19
15 May '19
commit b98bcd789e45fb6a09ef92ab15052a6c19e24887
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Wed May 8 21:21:03 2019 +0000
Pathbias should continue to ignore previously ignored circs.
If circuit padding wants to keep a circuit open and pathbias used to ignore
it, pathbias should continue to ignore it.
This may catch other purpose-change related miscounts (such as timeout
measurement, cannibalization, onion service circuit transitions, and
…
[View More]vanguards).
---
src/feature/client/circpathbias.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/src/feature/client/circpathbias.c b/src/feature/client/circpathbias.c
index e6af649ba..2be9984a6 100644
--- a/src/feature/client/circpathbias.c
+++ b/src/feature/client/circpathbias.c
@@ -400,12 +400,13 @@ pathbias_should_count(origin_circuit_t *circ)
/* Check to see if the shouldcount result has changed due to a
* unexpected purpose change that would affect our results */
if (circ->pathbias_shouldcount == PATHBIAS_SHOULDCOUNT_IGNORED) {
- log_info(LD_BUG,
- "Circuit %d is now being counted despite being ignored "
- "in the past. Purpose is %s, path state is %s",
- circ->global_identifier,
- circuit_purpose_to_string(circ->base_.purpose),
- pathbias_state_to_string(circ->path_state));
+ log_info(LD_CIRC,
+ "Circuit %d is not being counted by pathbias because it was "
+ "ignored in the past. Purpose is %s, path state is %s",
+ circ->global_identifier,
+ circuit_purpose_to_string(circ->base_.purpose),
+ pathbias_state_to_string(circ->path_state));
+ return 0;
}
circ->pathbias_shouldcount = PATHBIAS_SHOULDCOUNT_COUNTED;
[View Less]
1
0

[tor/master] The practracker beatings will continue until the files get smaller.
by asn@torproject.org 15 May '19
by asn@torproject.org 15 May '19
15 May '19
commit ff2a9809353c1166cb494dac3a14502b8ee24013
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Wed May 15 04:47:50 2019 +0000
The practracker beatings will continue until the files get smaller.
---
scripts/maint/practracker/exceptions.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/maint/practracker/exceptions.txt b/scripts/maint/practracker/exceptions.txt
index 24452b615..aea6ef84b 100644
--- a/scripts/maint/practracker/exceptions.txt
+++…
[View More] b/scripts/maint/practracker/exceptions.txt
@@ -92,7 +92,7 @@ problem function-size /src/core/or/circuitlist.c:circuits_handle_oom() 117
problem function-size /src/core/or/circuitmux.c:circuitmux_set_policy() 110
problem function-size /src/core/or/circuitmux.c:circuitmux_attach_circuit() 114
problem function-size /src/core/or/circuitstats.c:circuit_build_times_parse_state() 124
-problem file-size /src/core/or/circuituse.c 3155
+problem file-size /src/core/or/circuituse.c 3156
problem function-size /src/core/or/circuituse.c:circuit_is_acceptable() 133
problem function-size /src/core/or/circuituse.c:circuit_expire_building() 394
problem function-size /src/core/or/circuituse.c:circuit_log_ancient_one_hop_circuits() 126
[View Less]
1
0

[tor/master] Add control port circuit ID to all pathbias bug messages.
by asn@torproject.org 15 May '19
by asn@torproject.org 15 May '19
15 May '19
commit 56738ff8c626b21d6e3d146c9a2c0c4d18f3884a
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Wed May 8 21:28:00 2019 +0000
Add control port circuit ID to all pathbias bug messages.
To ease debugging of miscount issues, attach vanguards with --loglevel DEBUG
and obtain control port logs (or use any other control port CIRC and
CIRC_MINOR event logging mechanism).
---
src/feature/client/circpathbias.c | 18 ++++++++++++------
1 file changed, 12 …
[View More]insertions(+), 6 deletions(-)
diff --git a/src/feature/client/circpathbias.c b/src/feature/client/circpathbias.c
index 2be9984a6..3544dbb85 100644
--- a/src/feature/client/circpathbias.c
+++ b/src/feature/client/circpathbias.c
@@ -371,8 +371,9 @@ pathbias_should_count(origin_circuit_t *circ)
!circ->build_state->onehop_tunnel) {
if ((rate_msg = rate_limit_log(&count_limit, approx_time()))) {
log_info(LD_BUG,
- "One-hop circuit has length %d. Path state is %s. "
+ "One-hop circuit %d has length %d. Path state is %s. "
"Circuit is a %s currently %s.%s",
+ circ->global_identifier,
circ->build_state->desired_path_len,
pathbias_state_to_string(circ->path_state),
circuit_purpose_to_string(circ->base_.purpose),
@@ -437,8 +438,9 @@ pathbias_count_build_attempt(origin_circuit_t *circ)
if ((rate_msg = rate_limit_log(&circ_attempt_notice_limit,
approx_time()))) {
log_info(LD_BUG,
- "Opened circuit is in strange path state %s. "
+ "Opened circuit %d is in strange path state %s. "
"Circuit is a %s currently %s.%s",
+ circ->global_identifier,
pathbias_state_to_string(circ->path_state),
circuit_purpose_to_string(circ->base_.purpose),
circuit_state_to_string(circ->base_.state),
@@ -471,8 +473,9 @@ pathbias_count_build_attempt(origin_circuit_t *circ)
if ((rate_msg = rate_limit_log(&circ_attempt_notice_limit,
approx_time()))) {
log_info(LD_BUG,
- "Unopened circuit has strange path state %s. "
+ "Unopened circuit %d has strange path state %s. "
"Circuit is a %s currently %s.%s",
+ circ->global_identifier,
pathbias_state_to_string(circ->path_state),
circuit_purpose_to_string(circ->base_.purpose),
circuit_state_to_string(circ->base_.state),
@@ -541,8 +544,9 @@ pathbias_count_build_success(origin_circuit_t *circ)
if ((rate_msg = rate_limit_log(&success_notice_limit,
approx_time()))) {
log_info(LD_BUG,
- "Succeeded circuit is in strange path state %s. "
+ "Succeeded circuit %d is in strange path state %s. "
"Circuit is a %s currently %s.%s",
+ circ->global_identifier,
pathbias_state_to_string(circ->path_state),
circuit_purpose_to_string(circ->base_.purpose),
circuit_state_to_string(circ->base_.state),
@@ -577,8 +581,9 @@ pathbias_count_build_success(origin_circuit_t *circ)
if ((rate_msg = rate_limit_log(&success_notice_limit,
approx_time()))) {
log_info(LD_BUG,
- "Opened circuit is in strange path state %s. "
+ "Opened circuit %d is in strange path state %s. "
"Circuit is a %s currently %s.%s",
+ circ->global_identifier,
pathbias_state_to_string(circ->path_state),
circuit_purpose_to_string(circ->base_.purpose),
circuit_state_to_string(circ->base_.state),
@@ -604,8 +609,9 @@ pathbias_count_use_attempt(origin_circuit_t *circ)
if (circ->path_state < PATH_STATE_BUILD_SUCCEEDED) {
log_notice(LD_BUG,
- "Used circuit is in strange path state %s. "
+ "Used circuit %d is in strange path state %s. "
"Circuit is a %s currently %s.",
+ circ->global_identifier,
pathbias_state_to_string(circ->path_state),
circuit_purpose_to_string(circ->base_.purpose),
circuit_state_to_string(circ->base_.state));
[View Less]
1
0

[tor/master] Merge branch 'bug28780-squashed3-rebased' into bug28780_rebase
by asn@torproject.org 15 May '19
by asn@torproject.org 15 May '19
15 May '19
commit d71fa707dd01bdaa2ed301e82ace6fd23f63e638
Merge: a7779df84 ff2a98093
Author: George Kadianakis <desnacked(a)riseup.net>
Date: Wed May 15 16:46:51 2019 +0300
Merge branch 'bug28780-squashed3-rebased' into bug28780_rebase
changes/ticket28780 | 3 +
scripts/maint/practracker/exceptions.txt | 2 +-
src/core/or/circuitlist.c | 11 ++
src/core/or/circuitlist.h | 28 ++---
src/core/or/circuitpadding.c | 119 ++++++…
[View More]++++++++++++-
src/core/or/circuitpadding.h | 31 +++++
src/core/or/circuituse.c | 5 +-
src/feature/client/circpathbias.c | 31 +++--
src/test/test_circuitpadding.c | 188 +++++++++++++++++++++++++++++++
9 files changed, 388 insertions(+), 30 deletions(-)
diff --cc src/core/or/circuitpadding.c
index cd58a191d,68140356c..ddf28ea62
--- a/src/core/or/circuitpadding.c
+++ b/src/core/or/circuitpadding.c
@@@ -1649,16 -1649,13 +1760,17 @@@ circpad_cell_event_nonpadding_sent(circ
/* If there are no machines then this loop should not iterate */
FOR_EACH_ACTIVE_CIRCUIT_MACHINE_BEGIN(i, on_circ) {
- /* First, update any RTT estimate */
+ /* First, update any timestamps */
+ on_circ->padding_info[i]->last_cell_time_sec = approx_time();
circpad_estimate_circ_rtt_on_send(on_circ, on_circ->padding_info[i]);
- /* Remove a token: this is the idea of adaptive padding, since we have an
- * ideal distribution that we want our distribution to look like. */
- if (!circpad_machine_remove_token(on_circ->padding_info[i])) {
+ /* Then, do accounting */
+ circpad_machine_count_nonpadding_sent(on_circ->padding_info[i]);
+
+ /* Check to see if we've run out of tokens for this state already,
+ * and if not, check for other state transitions */
+ if (check_machine_token_supply(on_circ->padding_info[i])
+ == CIRCPAD_STATE_UNCHANGED) {
/* If removing a token did not cause a transition, check if
* non-padding sent event should */
circpad_machine_spec_transition(on_circ->padding_info[i],
@@@ -1699,16 -1697,9 +1812,17 @@@ voi
circpad_cell_event_padding_sent(circuit_t *on_circ)
{
FOR_EACH_ACTIVE_CIRCUIT_MACHINE_BEGIN(i, on_circ) {
- on_circ->padding_info[i]->last_cell_time_sec = approx_time();
- circpad_machine_spec_transition(on_circ->padding_info[i],
+ /* Check to see if we've run out of tokens for this state already,
+ * and if not, check for other state transitions */
+ if (check_machine_token_supply(on_circ->padding_info[i])
+ == CIRCPAD_STATE_UNCHANGED) {
+ /* If removing a token did not cause a transition, check if
+ * non-padding sent event should */
+
++ on_circ->padding_info[i]->last_cell_time_sec = approx_time();
+ circpad_machine_spec_transition(on_circ->padding_info[i],
CIRCPAD_EVENT_PADDING_SENT);
+ }
} FOR_EACH_ACTIVE_CIRCUIT_MACHINE_END;
}
[View Less]
1
0

15 May '19
commit ba4fe1a73e57016915004ef49e9e10abd306422d
Author: Cecylia Bocovich <cohosh(a)torproject.org>
Date: Fri May 10 12:03:07 2019 -0400
Added an option to specify metrics log file
Previously the metrics log file was hardcoded and the broker wasn't
behaving properly if it was unable to open the file for logging.
Added a commandline option to specify the logfile that defaults to
Stdout.
Fixed up some documentation and log output formatting
---
…
[View More]broker/broker.go | 25 +++++++++++++++++++++----
broker/geoip.go | 3 ++-
broker/metrics.go | 17 +++--------------
3 files changed, 26 insertions(+), 19 deletions(-)
diff --git a/broker/broker.go b/broker/broker.go
index 4db1511..361040a 100644
--- a/broker/broker.go
+++ b/broker/broker.go
@@ -10,6 +10,7 @@ import (
"crypto/tls"
"flag"
"fmt"
+ "io"
"io/ioutil"
"log"
"net"
@@ -37,10 +38,10 @@ type BrokerContext struct {
metrics *Metrics
}
-func NewBrokerContext() *BrokerContext {
+func NewBrokerContext(metricsLogger *log.Logger) *BrokerContext {
snowflakes := new(SnowflakeHeap)
heap.Init(snowflakes)
- metrics, err := NewMetrics()
+ metrics, err := NewMetrics(metricsLogger)
if err != nil {
panic(err.Error())
@@ -253,6 +254,7 @@ func main() {
var geoip6Database string
var disableTLS bool
var disableGeoip bool
+ var metricsFilename string
flag.StringVar(&acmeEmail, "acme-email", "", "optional contact email for Let's Encrypt notifications")
flag.StringVar(&acmeHostnamesCommas, "acme-hostnames", "", "comma-separated hostnames for TLS certificate")
@@ -261,11 +263,27 @@ func main() {
flag.StringVar(&geoip6Database, "geoip6db", "/usr/share/tor/geoip6", "path to correctly formatted geoip database mapping IPv6 address ranges to country codes")
flag.BoolVar(&disableTLS, "disable-tls", false, "don't use HTTPS")
flag.BoolVar(&disableGeoip, "disable-geoip", false, "don't use geoip for stats collection")
+ flag.StringVar(&metricsFilename, "metrics-log", "", "path to metrics logging output")
flag.Parse()
+ var metricsFile io.Writer = os.Stdout
+ var err error
+
log.SetFlags(log.LstdFlags | log.LUTC)
- ctx := NewBrokerContext()
+ if metricsFilename != "" {
+ metricsFile, err = os.OpenFile(metricsFilename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
+
+ if err != nil {
+ log.Fatal(err.Error())
+ }
+ } else {
+ metricsFile = os.Stdout
+ }
+
+ metricsLogger := log.New(metricsFile, "", log.LstdFlags|log.LUTC)
+
+ ctx := NewBrokerContext(metricsLogger)
if !disableGeoip {
err := ctx.metrics.LoadGeoipDatabases(geoipDatabase, geoip6Database)
@@ -283,7 +301,6 @@ func main() {
http.Handle("/answer", SnowflakeHandler{ctx, proxyAnswers})
http.Handle("/debug", SnowflakeHandler{ctx, debugHandler})
- var err error
server := http.Server{
Addr: addr,
}
diff --git a/broker/geoip.go b/broker/geoip.go
index 27a87fd..16cada1 100644
--- a/broker/geoip.go
+++ b/broker/geoip.go
@@ -209,7 +209,8 @@ func GeoIPLoadFile(table GeoIPTable, pathname string) error {
return nil
}
-//Returns the country location of an IPv4 or IPv6 address.
+//Returns the country location of an IPv4 or IPv6 address, and a boolean value
+//that indicates whether the IP address was present in the geoip database
func GetCountryByAddr(table GeoIPTable, ip net.IP) (string, bool) {
table.Lock()
diff --git a/broker/metrics.go b/broker/metrics.go
index 9eabe57..f961d1f 100644
--- a/broker/metrics.go
+++ b/broker/metrics.go
@@ -5,7 +5,6 @@ import (
"fmt"
"log"
"net"
- "os"
"sync"
"time"
)
@@ -28,7 +27,7 @@ type Metrics struct {
}
func (s CountryStats) Display() string {
- return fmt.Sprintln(s.counts)
+ return fmt.Sprint(s.counts)
}
func (m *Metrics) UpdateCountryStats(addr string) {
@@ -56,9 +55,7 @@ func (m *Metrics) UpdateCountryStats(addr string) {
}
//update map of countries and counts
- if country != "" {
- m.countryStats.counts[country]++
- }
+ m.countryStats.counts[country]++
return
}
@@ -88,17 +85,9 @@ func (m *Metrics) LoadGeoipDatabases(geoipDB string, geoip6DB string) error {
return nil
}
-func NewMetrics() (*Metrics, error) {
+func NewMetrics(metricsLogger *log.Logger) (*Metrics, error) {
m := new(Metrics)
- f, err := os.OpenFile("metrics.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
-
- if err != nil {
- return nil, err
- }
-
- metricsLogger := log.New(f, "", log.LstdFlags|log.LUTC)
-
m.countryStats = CountryStats{
counts: make(map[string]int),
}
[View Less]
1
0

[snowflake/master] Implemented geoip lookups for the snowflake broker. This heavily based off of how tor maps IP addresses to country codes, and relies on the provided ipv4 and ipv6 files.
by cohosh@torproject.org 15 May '19
by cohosh@torproject.org 15 May '19
15 May '19
commit 171c55a9b1aa34a0ec6d4413eb4e4b14954450d1
Author: Cecylia Bocovich <cohosh(a)torproject.org>
Date: Wed Mar 13 13:51:38 2019 -0400
Implemented geoip lookups for the snowflake broker. This heavily based off of how tor maps IP addresses to country codes, and relies on the provided ipv4 and ipv6 files.
---
broker/broker.go | 54 +-
broker/geoip.go | 239 ++++++++
broker/metrics.go | 106 +++-
broker/snowflake-broker_test.go | 103 …
[View More]++++
broker/test_geoip | 1236 +++++++++++++++++++++++++++++++++++++++
broker/test_geoip6 | 693 ++++++++++++++++++++++
6 files changed, 2428 insertions(+), 3 deletions(-)
diff --git a/broker/broker.go b/broker/broker.go
index a41aadb..faa6f4a 100644
--- a/broker/broker.go
+++ b/broker/broker.go
@@ -12,8 +12,12 @@ import (
"fmt"
"io/ioutil"
"log"
+ "net"
"net/http"
+ "os"
+ "os/signal"
"strings"
+ "syscall"
"time"
"golang.org/x/crypto/acme/autocert"
@@ -36,11 +40,21 @@ type BrokerContext struct {
func NewBrokerContext() *BrokerContext {
snowflakes := new(SnowflakeHeap)
heap.Init(snowflakes)
+ metrics, err := NewMetrics()
+
+ if err != nil {
+ panic(err.Error())
+ }
+
+ if metrics == nil {
+ panic("Failed to create metrics")
+ }
+
return &BrokerContext{
snowflakes: snowflakes,
idToSnowflake: make(map[string]*Snowflake),
proxyPolls: make(chan *ProxyPoll),
- metrics: new(Metrics),
+ metrics: metrics,
}
}
@@ -203,6 +217,16 @@ func proxyAnswers(ctx *BrokerContext, w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest)
return
}
+
+ // Get proxy country stats
+ remoteIP, _, err := net.SplitHostPort(r.RemoteAddr)
+ if err != nil {
+ log.Println("Error processing proxy IP: ", err.Error())
+ } else {
+
+ ctx.metrics.UpdateCountryStats(remoteIP)
+ }
+
log.Println("Received answer: ", body)
snowflake.answerChannel <- body
}
@@ -213,6 +237,7 @@ func debugHandler(ctx *BrokerContext, w http.ResponseWriter, r *http.Request) {
s += fmt.Sprintf("\nsnowflake %d: %s", snowflake.index, snowflake.id)
}
s += fmt.Sprintf("\n\nroundtrip avg: %d", ctx.metrics.clientRoundtripEstimate)
+ s += fmt.Sprintf("\n\nsnowflake country stats: %s", ctx.metrics.countryStats.Display())
w.Write([]byte(s))
}
@@ -225,18 +250,31 @@ func main() {
var acmeEmail string
var acmeHostnamesCommas string
var addr string
+ var geoipDatabase string
+ var geoip6Database string
var disableTLS bool
+ var disableGeoip bool
flag.StringVar(&acmeEmail, "acme-email", "", "optional contact email for Let's Encrypt notifications")
flag.StringVar(&acmeHostnamesCommas, "acme-hostnames", "", "comma-separated hostnames for TLS certificate")
flag.StringVar(&addr, "addr", ":443", "address to listen on")
+ flag.StringVar(&geoipDatabase, "geoipdb", "/usr/share/tor/geoip", "path to correctly formatted geoip database mapping IPv4 address ranges to country codes")
+ flag.StringVar(&geoip6Database, "geoip6db", "/usr/share/tor/geoip6", "path to correctly formatted geoip database mapping IPv6 address ranges to country codes")
flag.BoolVar(&disableTLS, "disable-tls", false, "don't use HTTPS")
+ flag.BoolVar(&disableGeoip, "disable-geoip", false, "don't use geoip for stats collection")
flag.Parse()
log.SetFlags(log.LstdFlags | log.LUTC)
ctx := NewBrokerContext()
+ if !disableGeoip {
+ err := ctx.metrics.LoadGeoipDatabases(geoipDatabase, geoip6Database)
+ if err != nil {
+ log.Fatal(err.Error())
+ }
+ }
+
go ctx.Broker()
http.HandleFunc("/robots.txt", robotsTxtHandler)
@@ -251,6 +289,20 @@ func main() {
Addr: addr,
}
+ sigChan := make(chan os.Signal, 1)
+ signal.Notify(sigChan, syscall.SIGHUP)
+
+ // go routine to handle a SIGHUP signal to allow the broker operator to send
+ // a SIGHUP signal when the geoip database files are updated, without requiring
+ // a restart of the broker
+ go func() {
+ for {
+ signal := <-sigChan
+ log.Println("Received signal:", signal, ". Reloading geoip databases.")
+ ctx.metrics.LoadGeoipDatabases(geoipDatabase, geoip6Database)
+ }
+ }()
+
if acmeHostnamesCommas != "" {
acmeHostnames := strings.Split(acmeHostnamesCommas, ",")
log.Printf("ACME hostnames: %q", acmeHostnames)
diff --git a/broker/geoip.go b/broker/geoip.go
new file mode 100644
index 0000000..27a87fd
--- /dev/null
+++ b/broker/geoip.go
@@ -0,0 +1,239 @@
+/*
+This code is for loading database data that maps ip addresses to countries
+for collecting and presenting statistics on snowflake use that might alert us
+to censorship events.
+
+The functions here are heavily based off of how tor maintains and searches their
+geoip database
+
+The tables used for geoip data must be structured as follows:
+
+Recognized line format for IPv4 is:
+ INTIPLOW,INTIPHIGH,CC
+ where INTIPLOW and INTIPHIGH are IPv4 addresses encoded as big-endian 4-byte unsigned
+ integers, and CC is a country code.
+
+Note that the IPv4 line format
+ "INTIPLOW","INTIPHIGH","CC","CC3","COUNTRY NAME"
+is not currently supported.
+
+Recognized line format for IPv6 is:
+ IPV6LOW,IPV6HIGH,CC
+ where IPV6LOW and IPV6HIGH are IPv6 addresses and CC is a country code.
+
+It also recognizes, and skips over, blank lines and lines that start
+with '#' (comments).
+
+*/
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "crypto/sha1"
+ "encoding/hex"
+ "fmt"
+ "io"
+ "log"
+ "net"
+ "os"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+)
+
+type GeoIPTable interface {
+ parseEntry(string) (*GeoIPEntry, error)
+ Len() int
+ Append(GeoIPEntry)
+ ElementAt(int) GeoIPEntry
+ Lock()
+ Unlock()
+}
+
+type GeoIPEntry struct {
+ ipLow net.IP
+ ipHigh net.IP
+ country string
+}
+
+type GeoIPv4Table struct {
+ table []GeoIPEntry
+
+ lock sync.Mutex // synchronization for geoip table accesses and reloads
+}
+
+type GeoIPv6Table struct {
+ table []GeoIPEntry
+
+ lock sync.Mutex // synchronization for geoip table accesses and reloads
+}
+
+func (table GeoIPv4Table) Len() int { return len(table.table) }
+func (table GeoIPv6Table) Len() int { return len(table.table) }
+
+func (table *GeoIPv4Table) Append(entry GeoIPEntry) {
+ (*table).table = append(table.table, entry)
+}
+func (table *GeoIPv6Table) Append(entry GeoIPEntry) {
+ (*table).table = append(table.table, entry)
+}
+
+func (table GeoIPv4Table) ElementAt(i int) GeoIPEntry { return table.table[i] }
+func (table GeoIPv6Table) ElementAt(i int) GeoIPEntry { return table.table[i] }
+
+func (table *GeoIPv4Table) Lock() { (*table).lock.Lock() }
+func (table *GeoIPv6Table) Lock() { (*table).lock.Lock() }
+
+func (table *GeoIPv4Table) Unlock() { (*table).lock.Unlock() }
+func (table *GeoIPv6Table) Unlock() { (*table).lock.Unlock() }
+
+// Convert a geoip IP address represented as a big-endian unsigned integer to net.IP
+func geoipStringToIP(ipStr string) (net.IP, error) {
+ ip, err := strconv.ParseUint(ipStr, 10, 32)
+ if err != nil {
+ return net.IPv4(0, 0, 0, 0), fmt.Errorf("Error parsing IP %s", ipStr)
+ }
+ var bytes [4]byte
+ bytes[0] = byte(ip & 0xFF)
+ bytes[1] = byte((ip >> 8) & 0xFF)
+ bytes[2] = byte((ip >> 16) & 0xFF)
+ bytes[3] = byte((ip >> 24) & 0xFF)
+
+ return net.IPv4(bytes[3], bytes[2], bytes[1], bytes[0]), nil
+}
+
+//Parses a line in the provided geoip file that corresponds
+//to an address range and a two character country code
+func (table *GeoIPv4Table) parseEntry(candidate string) (*GeoIPEntry, error) {
+
+ if candidate[0] == '#' {
+ return nil, nil
+ }
+
+ parsedCandidate := strings.Split(candidate, ",")
+
+ if len(parsedCandidate) != 3 {
+ return nil, fmt.Errorf("Provided geoip file is incorrectly formatted. Could not parse line:\n%s", parsedCandidate)
+ }
+
+ low, err := geoipStringToIP(parsedCandidate[0])
+ if err != nil {
+ return nil, err
+ }
+ high, err := geoipStringToIP(parsedCandidate[1])
+ if err != nil {
+ return nil, err
+ }
+
+ geoipEntry := &GeoIPEntry{
+ ipLow: low,
+ ipHigh: high,
+ country: parsedCandidate[2],
+ }
+
+ return geoipEntry, nil
+}
+
+//Parses a line in the provided geoip file that corresponds
+//to an address range and a two character country code
+func (table *GeoIPv6Table) parseEntry(candidate string) (*GeoIPEntry, error) {
+
+ if candidate[0] == '#' {
+ return nil, nil
+ }
+
+ parsedCandidate := strings.Split(candidate, ",")
+
+ if len(parsedCandidate) != 3 {
+ return nil, fmt.Errorf("")
+ }
+
+ low := net.ParseIP(parsedCandidate[0])
+ if low == nil {
+ return nil, fmt.Errorf("")
+ }
+ high := net.ParseIP(parsedCandidate[1])
+ if high == nil {
+ return nil, fmt.Errorf("")
+ }
+
+ geoipEntry := &GeoIPEntry{
+ ipLow: low,
+ ipHigh: high,
+ country: parsedCandidate[2],
+ }
+
+ return geoipEntry, nil
+}
+
+//Loads provided geoip file into our tables
+//Entries are stored in a table
+func GeoIPLoadFile(table GeoIPTable, pathname string) error {
+ //open file
+ geoipFile, err := os.Open(pathname)
+ if err != nil {
+ return err
+ }
+ defer geoipFile.Close()
+
+ hash := sha1.New()
+
+ table.Lock()
+ defer table.Unlock()
+
+ hashedFile := io.TeeReader(geoipFile, hash)
+
+ //read in strings and call parse function
+ scanner := bufio.NewScanner(hashedFile)
+ for scanner.Scan() {
+ entry, err := table.parseEntry(scanner.Text())
+ if err != nil {
+ return fmt.Errorf("Provided geoip file is incorrectly formatted. Line is: %+q", scanner.Text())
+ }
+
+ if entry != nil {
+ table.Append(*entry)
+ }
+
+ }
+ if err := scanner.Err(); err != nil {
+ return err
+ }
+
+ sha1Hash := hex.EncodeToString(hash.Sum(nil))
+ log.Println("Using geoip file ", pathname, " with checksum", sha1Hash)
+ log.Println("Loaded ", table.Len(), " entries into table")
+
+ return nil
+}
+
+//Returns the country location of an IPv4 or IPv6 address.
+func GetCountryByAddr(table GeoIPTable, ip net.IP) (string, bool) {
+
+ table.Lock()
+ defer table.Unlock()
+
+ //look IP up in database
+ index := sort.Search(table.Len(), func(i int) bool {
+ entry := table.ElementAt(i)
+ return (bytes.Compare(ip.To16(), entry.ipHigh.To16()) <= 0)
+ })
+
+ if index == table.Len() {
+ return "", false
+ }
+
+ // check to see if addr is in the range specified by the returned index
+ // search on IPs in invalid ranges (e.g., 127.0.0.0/8) will return the
+ //country code of the next highest range
+ entry := table.ElementAt(index)
+ if !(bytes.Compare(ip.To16(), entry.ipLow.To16()) >= 0 &&
+ bytes.Compare(ip.To16(), entry.ipHigh.To16()) <= 0) {
+ return "", false
+ }
+
+ return table.ElementAt(index).country, true
+
+}
diff --git a/broker/metrics.go b/broker/metrics.go
index 002fdfe..9eabe57 100644
--- a/broker/metrics.go
+++ b/broker/metrics.go
@@ -2,16 +2,118 @@ package main
import (
// "golang.org/x/net/internal/timeseries"
+ "fmt"
+ "log"
+ "net"
+ "os"
+ "sync"
"time"
)
+var (
+ once sync.Once
+)
+
+type CountryStats struct {
+ counts map[string]int
+}
+
// Implements Observable
type Metrics struct {
+ tablev4 *GeoIPv4Table
+ tablev6 *GeoIPv6Table
+ countryStats CountryStats
// snowflakes timeseries.Float
clientRoundtripEstimate time.Duration
}
-func NewMetrics() *Metrics {
+func (s CountryStats) Display() string {
+ return fmt.Sprintln(s.counts)
+}
+
+func (m *Metrics) UpdateCountryStats(addr string) {
+
+ var country string
+ var ok bool
+
+ ip := net.ParseIP(addr)
+ if ip.To4() != nil {
+ //This is an IPv4 address
+ if m.tablev4 == nil {
+ return
+ }
+ country, ok = GetCountryByAddr(m.tablev4, ip)
+ } else {
+ if m.tablev6 == nil {
+ return
+ }
+ country, ok = GetCountryByAddr(m.tablev6, ip)
+ }
+
+ if !ok {
+ country = "??"
+ log.Println("Unknown geoip")
+ }
+
+ //update map of countries and counts
+ if country != "" {
+ m.countryStats.counts[country]++
+ }
+
+ return
+}
+
+func (m *Metrics) LoadGeoipDatabases(geoipDB string, geoip6DB string) error {
+
+ // Load geoip databases
+ log.Println("Loading geoip databases")
+ tablev4 := new(GeoIPv4Table)
+ err := GeoIPLoadFile(tablev4, geoipDB)
+ if err != nil {
+ m.tablev4 = nil
+ return err
+ } else {
+ m.tablev4 = tablev4
+ }
+
+ tablev6 := new(GeoIPv6Table)
+ err = GeoIPLoadFile(tablev6, geoip6DB)
+ if err != nil {
+ m.tablev6 = nil
+ return err
+ } else {
+ m.tablev6 = tablev6
+ }
+
+ return nil
+}
+
+func NewMetrics() (*Metrics, error) {
m := new(Metrics)
- return m
+
+ f, err := os.OpenFile("metrics.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
+
+ if err != nil {
+ return nil, err
+ }
+
+ metricsLogger := log.New(f, "", log.LstdFlags|log.LUTC)
+
+ m.countryStats = CountryStats{
+ counts: make(map[string]int),
+ }
+
+ // Write to log file every hour with updated metrics
+ go once.Do(func() {
+ heartbeat := time.Tick(time.Hour)
+ for range heartbeat {
+ metricsLogger.Println("Country stats: ", m.countryStats.Display())
+
+ //restore all metrics to original values
+ m.countryStats.counts = make(map[string]int)
+
+ }
+ })
+
+ return m, nil
}
diff --git a/broker/snowflake-broker_test.go b/broker/snowflake-broker_test.go
index 109d7df..463c5e7 100644
--- a/broker/snowflake-broker_test.go
+++ b/broker/snowflake-broker_test.go
@@ -4,6 +4,7 @@ import (
"bytes"
"container/heap"
. "github.com/smartystreets/goconvey/convey"
+ "net"
"net/http"
"net/http/httptest"
"testing"
@@ -268,3 +269,105 @@ func TestSnowflakeHeap(t *testing.T) {
So(r.index, ShouldEqual, -1)
})
}
+
+func TestGeoip(t *testing.T) {
+ Convey("Geoip", t, func() {
+ tv4 := new(GeoIPv4Table)
+ err := GeoIPLoadFile(tv4, "test_geoip")
+ So(err, ShouldEqual, nil)
+ tv6 := new(GeoIPv6Table)
+ err = GeoIPLoadFile(tv6, "test_geoip6")
+ So(err, ShouldEqual, nil)
+
+ Convey("IPv4 Country Mapping Tests", func() {
+ for _, test := range []struct {
+ addr, cc string
+ ok bool
+ }{
+ {
+ "129.97.208.23", //uwaterloo
+ "CA",
+ true,
+ },
+ {
+ "127.0.0.1",
+ "",
+ false,
+ },
+ {
+ "255.255.255.255",
+ "",
+ false,
+ },
+ {
+ "0.0.0.0",
+ "",
+ false,
+ },
+ {
+ "223.252.127.255", //test high end of range
+ "JP",
+ true,
+ },
+ {
+ "223.252.127.255", //test low end of range
+ "JP",
+ true,
+ },
+ } {
+ country, ok := GetCountryByAddr(tv4, net.ParseIP(test.addr))
+ So(country, ShouldEqual, test.cc)
+ So(ok, ShouldResemble, test.ok)
+ }
+ })
+
+ Convey("IPv6 Country Mapping Tests", func() {
+ for _, test := range []struct {
+ addr, cc string
+ ok bool
+ }{
+ {
+ "2620:101:f000:0:250:56ff:fe80:168e", //uwaterloo
+ "CA",
+ true,
+ },
+ {
+ "fd00:0:0:0:0:0:0:1",
+ "",
+ false,
+ },
+ {
+ "0:0:0:0:0:0:0:0",
+ "",
+ false,
+ },
+ {
+ "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
+ "",
+ false,
+ },
+ {
+ "2a07:2e47:ffff:ffff:ffff:ffff:ffff:ffff", //test high end of range
+ "FR",
+ true,
+ },
+ {
+ "2a07:2e40::", //test low end of range
+ "FR",
+ true,
+ },
+ } {
+ country, ok := GetCountryByAddr(tv6, net.ParseIP(test.addr))
+ So(country, ShouldEqual, test.cc)
+ So(ok, ShouldResemble, test.ok)
+ }
+ })
+
+ // Make sure things behave properly if geoip file fails to load
+ ctx := NewBrokerContext()
+ ctx.metrics.LoadGeoipDatabases("invalid_filename", "invalid_filename6")
+ ctx.metrics.UpdateCountryStats("127.0.0.1")
+ So(ctx.metrics.tablev4, ShouldEqual, nil)
+
+ })
+}
diff --git a/broker/test_geoip b/broker/test_geoip
new file mode 100644
index 0000000..885c8ab
--- /dev/null
+++ b/broker/test_geoip
@@ -0,0 +1,1236 @@
+# Last updated based on February 7 2018 Maxmind GeoLite2 Country
+# wget https://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz
+# gunzip GeoLite2-Country.mmdb.gz
+# python mmdb-convert.py GeoLite2-Country.mmdb
+16777216,16777471,AU
+16777472,16778239,CN
+16778240,16779263,AU
+16779264,16781311,CN
+16781312,16785407,JP
+16785408,16793599,CN
+16793600,16809983,JP
+16809984,16842751,TH
+16842752,16843007,CN
+16843008,16843263,AU
+16843264,16859135,CN
+16859136,16875519,JP
+16875520,16908287,TH
+16908288,16909055,CN
+16909056,16909311,US
+16909312,16941055,CN
+16941056,16973823,TH
+16973824,17039359,CN
+17039360,17039615,AU
+2111307776,2111832063,CN
+2111832064,2112487423,TW
+2112487424,2112618495,VN
+2112618496,2112880639,NZ
+2112880640,2113560063,KR
+2113560064,2113560319,SG
+2113560320,2113683455,KR
+2113683456,2113684607,JP
+2113684608,2113684671,TW
+2113684672,2113685663,JP
+2113685664,2113685695,SG
+2113685696,2113687999,JP
+2113688000,2113688031,AU
+2113688032,2113688959,JP
+2113688960,2113688991,SG
+2113688992,2113691135,JP
+2113691136,2113691391,SG
+2113691392,2113692415,JP
+2113692416,2113692671,HK
+2113692672,2113693599,JP
+2113693600,2113693615,HK
+2113693616,2113693879,JP
+2113693880,2113693887,AU
+2113693888,2113693951,JP
+2113693952,2113694207,HK
+2113694208,2113695279,JP
+2113695280,2113695287,SG
+2113695288,2113716223,JP
+2113716224,2113724927,SG
+2113724928,2113725183,IN
+2113725184,2113728511,SG
+2113728512,2113732607,JP
+2113732608,2113761279,AU
+2113761280,2113765375,VN
+2113765376,2113798143,HK
+2113798144,2113811455,AU
+2113811456,2113812479,GB
+2113812480,2113813503,JP
+2113813504,2113830911,AU
+2113830912,2113863679,CN
+2113863680,2113929215,AU
+2113929216,2130706431,JP
+2147483648,2147483903,NL
+2147483904,2147484671,RO
+2147484672,2147485695,TR
+2147485696,2147487743,DK
+2147487744,2147489791,NO
+2147489792,2147491839,RU
+2147491840,2147494911,DE
+2147494912,2147495167,RO
+2147495168,2147495423,DE
+2147495424,2147496959,RO
+2147496960,2147497215,ES
+2147497216,2147497471,RO
+2147497472,2147497727,PL
+2147497728,2147498239,DE
+2147498240,2147498495,RO
+2147498496,2147500031,DE
+2147500032,2147501055,NL
+2147501056,2147501311,SK
+2147501312,2147501567,NL
+2147501568,2147501823,GL
+2147501824,2147502079,US
+2147502080,2147504127,DK
+2147504128,2147508223,RU
+2147508224,2147510271,DE
+2147510272,2147510783,UA
+2147510784,2147511039,RU
+2147511040,2147512319,CY
+2147512320,2147514879,DE
+2147514880,2147516415,IT
+2147516416,2147520511,RU
+2147520512,2147524607,DE
+2147524608,2147526655,RU
+2147526656,2147528703,UA
+2147528704,2147532799,CZ
+2147532800,2147534847,DE
+2147534848,2147549183,CY
+2147549184,2147557375,US
+2147557376,2147557631,TW
+2147557632,2147557887,SG
+2147557888,2147558143,DE
+2147558144,2147558399,TH
+2147558400,2147558655,KR
+2147558656,2147558911,TW
+2147558912,2147559167,SG
+2147559168,2147559423,TH
+2147559424,2147559679,SG
+2147559680,2147559935,US
+2147559936,2147560191,DE
+2147560192,2147560447,RU
+2147560448,2147560703,TH
+2147560704,2147560959,TW
+2147560960,2147562239,US
+2147562240,2147562495,RU
+2147562496,2147563263,US
+2147563264,2147563519,RU
+2147563520,2147564287,US
+2147564288,2147564543,AE
+2147564544,2147564799,US
+2147564800,2147565055,SG
+2147565056,2147565311,HK
+2147565312,2147565999,TW
+2147566000,2147566047,JP
+2147566048,2147566079,TW
+2147566080,2147569407,US
+2147569408,2147569663,TH
+2147569664,2147570431,US
+2147570432,2147570687,JP
+2147570688,2147571455,US
+2147571456,2147571711,SG
+2147571712,2147573503,US
+2147573504,2147573759,SG
+2147573760,2147575039,US
+2147575040,2147575551,TW
+2147575552,2147575807,SG
+2147575808,2147576575,US
+2147576576,2147576831,TW
+2147576832,2147577087,TH
+2147577088,2147577599,ID
+2147577600,2147579647,US
+2147579648,2147579903,ID
+2147579904,2147580927,US
+2147580928,2147581183,ID
+2147581184,2147581439,TH
+2147581440,2147592703,US
+2147592704,2147592959,HK
+2147592960,2147600127,US
+2147600128,2147600383,SG
+2147600384,2147603711,US
+2147603712,2147603967,IN
+2147603968,2147942399,US
+2147942400,2148007935,DE
+2148007936,2148220515,US
+2148220516,2148220535,AU
+2148220536,2148229151,US
+2148229152,2148229183,CA
+2148229184,2148459007,US
+2148459008,2148459519,TW
+2148459520,2148532223,US
+2148532224,2148597759,GB
+2148597760,2148925439,US
+2148925440,2148990975,JP
+2148990976,2149253119,US
+2149253120,2149384191,JP
+2149384192,2150039551,US
+2150039552,2150105087,NO
+2150105088,2150203391,GB
+2150203392,2150236159,AF
+2150236160,2150301695,US
+2150301696,2150367231,CA
+2150367232,2150432767,US
+2150432768,2150498303,IT
+2150498304,2150957055,US
+2150957056,2151022591,JP
+2151022592,2151743487,US
+2151743488,2151759871,BY
+2151759872,2151768063,US
+2151768064,2151770111,GB
+2151770112,2151772159,BA
+2151772160,2151776255,IT
+2151776256,2151778303,AT
+2151778304,2151780351,RU
+2151780352,2151782399,DE
+2151782400,2151784447,ES
+2151784448,2151792639,IR
+2151792640,2151794687,CH
+2151794688,2151796735,IT
+2151796736,2151800831,DE
+2151800832,2151809023,PT
+2151809024,2151940095,IT
+2151940096,2152464383,RU
+2152464384,2152529919,DK
+2152529920,2152562687,NO
+2152562688,2152595455,DK
+2152595456,2152726527,FR
+2152726528,2153119743,US
+2153119744,2153185279,GB
+2153185280,2153250815,SE
+2153250816,2153381887,US
+2153381888,2153382143,JP
+2153382144,2153383679,US
+2153383680,2153383935,HK
+2153383936,2153384447,US
+2153384448,2153385471,GB
+2153385472,2153385599,AT
+2153385600,2153385663,CZ
+2153385664,2153385727,FI
+2153385728,2153385791,PL
+2153385792,2153385855,PT
+2153385856,2153385919,TR
+2153385920,2153385983,US
+2153385984,2153387007,GB
+2153387008,2153387263,CH
+2153387264,2153387519,IS
+2153387520,2153387775,IE
+2153387776,2153388031,CH
+2153388032,2153388287,ES
+2153388288,2153388543,PL
+2153388544,2153391615,US
+2153391616,2153391871,HK
+2153391872,2153394431,US
+2153394432,2153394943,SG
+2153394944,2153395455,US
+2153395456,2153395711,VN
+2153395712,2153396991,US
+2153396992,2153397247,IL
+2153397248,2153397503,IN
+2153397504,2153397759,SA
+2153397760,2153398015,QA
+2153398016,2153398271,BH
+2153398272,2153398783,JP
+2153398784,2153399551,US
+2153399552,2153399807,KR
+2153399808,2153400319,HK
+2153400320,2153401087,TW
+2153401088,2153401599,MO
+2153401600,2153402111,VN
+2153402112,2153402367,PH
+2153402368,2153403135,KR
+2153403136,2153406463,US
+2153406464,2153407487,JP
+2153407488,2153407743,HK
+2153407744,2153407999,AE
+2153408000,2153408511,BR
+2153408512,2153408767,AU
+2153408768,2153409023,PA
+2153409024,2153409279,AR
+2153409280,2153409535,CR
+2153409536,2153409791,CO
+2153409792,2153410047,MX
+2153410048,2153410303,CA
+2153410304,2153410559,TW
+2153410560,2153410815,PA
+2153410816,2153411071,AR
+2153411072,2153411327,CR
+2153411328,2153411583,CO
+2153411584,2153411839,MX
+2153411840,2153412095,SV
+2153412096,2153412351,TW
+2153412352,2153412607,UY
+2153412608,2153413119,AU
+2153413120,2153413631,BR
+2153413632,2153578495,US
+2153578496,2153644031,FR
+2153644032,2153906175,US
+2153906176,2153971711,GB
+2153971712,2154037247,US
+2154037248,2154102783,CA
+2154102784,2154430463,US
+2154430464,2154495999,SG
+2154496000,2154561535,US
+2154561536,2154627071,CN
+2154627072,2155610111,US
+2155610112,2155675647,UA
+2155675648,2155806719,US
+2155806720,2155808767,IT
+2155810816,2155812863,FR
+2155812864,2155814911,GB
+2155814912,2155819007,NL
+2155819008,2155819519,DE
+2155819520,2155821055,CH
+2155821056,2155823103,IT
+2155823104,2155825151,DE
+2155825152,2155827199,AE
+2155827200,2155831295,PL
+2155831296,2155833343,RU
+2155833344,2155833855,SE
+2155833856,2155834623,NL
+2155834624,2155834879,LU
+2155834880,2155835391,NL
+2155835392,2155839487,RO
+2155839488,2155843583,FR
+2155843584,2155845631,RU
+2155845632,2155847679,DE
+2155847680,2155849727,ES
+2155849728,2155851775,TR
+2155853824,2155855871,SE
+2155855872,2155872255,SA
+2155872256,2156003327,US
+2156003328,2156134399,AT
+2156134400,2156265471,US
+2156265472,2156331007,KR
+2156331008,2156593151,US
+2156593152,2156658687,IL
+2156658688,2156691455,IR
+2156691456,2156697599,FR
+2156697600,2156699647,GR
+2156699648,2156703743,RU
+2156703744,2156707839,BG
+2156707840,2156709887,RU
+2156709888,2156711935,ES
+2156711936,2156713983,DE
+2156713984,2156716031,NL
+2156716032,2156718079,RO
+2156718080,2156720127,IS
+2156720128,2156724223,BY
+2156724224,2156855295,CH
+2156855296,2156920831,US
+2156920832,2156986367,CA
+2156986368,2159017983,US
+2159017984,2159083519,DE
+2159083520,2159149055,US
+2159149056,2159280127,CH
+2159280128,2159542271,US
+2159542272,2159607807,AU
+2159607808,2159673343,IN
+2159673344,2159869951,US
+2159869952,2159935487,CA
+2159935488,2160525311,US
+2160525312,2160533503,SG
+2160533504,2160541695,NL
+2160541696,2160590847,SG
+2160590848,2160656383,US
+2160656384,2160657407,BR
+2160657408,2160658431,HN
+2160658432,2160661503,BR
+2160661504,2160662527,AR
+2160662528,2160664575,BR
+2160664576,2160666623,CL
+2160666624,2160676863,BR
+2160676864,2160677887,AR
+2160677888,2160678911,BR
+2160678912,2160679935,GF
+2160679936,2160684031,BR
+2160684032,2160685055,AR
+2160685056,2160686079,DO
+2160686080,2160687103,CL
+2160687104,2160690175,BR
+2160690176,2160691199,AR
+2160691200,2160693247,BR
+2160693248,2160694271,CR
+2160694272,2160697343,BR
+2160697344,2160698367,EC
+2160698368,2160699391,BR
+2160699392,2160700415,AR
+2160700416,2160713727,BR
+2160713728,2160714751,CL
+2160714752,2160716799,BR
+2160716800,2160717823,AR
+2160717824,2160721919,BR
+2160721920,2160852991,US
+2160852992,2160885759,RU
+2160885760,2160893951,AT
+2160893952,2160902143,RU
+2160902144,2160906239,NL
+2160906240,2160908287,FR
+2160908288,2160910335,PL
+2160910336,2160914431,NL
+2160914432,2160918527,SA
+2160918528,2161508351,US
+2161508352,2161573887,FI
+2161573888,2162687999,US
+2162688000,2162753535,GB
+2162753536,2162819071,CA
+2162819072,2162884607,SA
+2162884608,2163212287,US
+2163212288,2163277823,GB
+2163277824,2163408895,US
+2163408896,2163474431,GB
+2163474432,2163605503,US
+2163605504,2163638271,DE
+2163638272,2163638527,US
+2163638528,2163671039,DE
+2163671040,2163867647,US
+2163867648,2163933183,AU
+2163933184,2164260863,US
+2164260864,2164326399,CM
+2164326400,2164981759,US
+2164981760,2165112831,GB
+2165112832,2165178367,DE
+2165178368,2165309439,US
+2165309440,2165374975,SE
+2165374976,2165440511,US
+2165440512,2165506047,NG
+2165506048,2165571583,US
+2165571584,2165637119,FR
+2165637120,2165964799,US
+2165964800,2166030335,DE
+2166030336,2166095871,AT
+2166095872,2166161407,CN
+2166161408,2166292479,US
+2166292480,2166358015,GB
+2166358016,2166562559,US
+2166562560,2166562815,FI
+2166562816,2166571007,US
+2166571008,2166575103,GB
+2166575104,2166594559,US
+2166594560,2166594815,PL
+2166594816,2166729471,US
+2166729472,2166729727,CA
+2166729728,2167209983,US
+2167209984,2167242751,DZ
+2167242752,2167275519,BF
+2167275520,2167930879,US
+2167930880,2167996415,NG
+2167996416,2168193023,US
+2168193024,2168258559,JP
+2168258560,2168651775,US
+2168651776,2168717311,GB
+2168717312,2168782847,US
+2168782848,2168913919,DE
+2168913920,2169372671,US
+2169372672,2169438207,AU
+2169438208,2170028031,US
+2170028032,2170093567,FR
+2170093568,2170159103,US
+2170159104,2170224639,VE
+2170224640,2170421247,US
+2170421248,2170486783,AU
+2170486784,2170552319,US
+2170552320,2170617855,AU
+2170617856,2170683391,CA
+2170683392,2170814463,US
+2170814464,2170879999,CA
+2170880000,2170945535,US
+2170945536,2171011071,FR
+3652593408,3652593471,ES
+3652593472,3652593511,FR
+3652593512,3652593519,ES
+3652593520,3652593631,FR
+3652593632,3652593663,PT
+3652593664,3652593943,FR
+3652593944,3652593951,ES
+3652593952,3652595007,FR
+3652595008,3652595071,DE
+3652595072,3652595167,FR
+3652595168,3652595183,ES
+3652595184,3652595871,FR
+3652595872,3652595935,PL
+3652595936,3652596351,FR
+3652596352,3652596415,IT
+3652596416,3652596479,FR
+3652596480,3652596543,ES
+3652596544,3652596799,FR
+3652596800,3652596831,CZ
+3652596832,3652597183,FR
+3652597184,3652597247,DE
+3652597248,3652597375,FR
+3652597376,3652597383,ES
+3652597384,3652597407,FR
+3652597408,3652597439,PL
+3652597440,3652597887,FR
+3652597888,3652597903,GB
+3652597904,3652599569,FR
+3652599570,3652599570,PT
+3652599571,3652599679,FR
+3652599680,3652599743,IT
+3652599744,3652601855,FR
+3652601856,3652603903,PL
+3652603904,3652608191,FR
+3652608192,3652608223,PT
+3652608224,3652608255,FR
+3652608256,3652608511,GB
+3652608512,3652608639,FR
+3652608640,3652608767,GB
+3652608768,3652609023,FR
+3652609024,3652609279,GB
+3652609280,3652609503,FR
+3652609504,3652609535,FI
+3652609536,3652609727,FR
+3652609728,3652609759,PL
+3652609760,3652609791,CZ
+3652609792,3652609823,FR
+3652609824,3652609855,CZ
+3652609856,3652609919,FR
+3652609920,3652609983,ES
+3652609984,3652610047,BE
+3652610048,3652611135,FR
+3652611136,3652611199,ES
+3652611200,3652611231,FR
+3652611232,3652611263,PT
+3652611264,3652611679,FR
+3652611680,3652611711,PT
+3652611712,3652611775,NL
+3652611776,3652612223,FR
+3652612224,3652612287,ES
+3652612288,3652612351,FR
+3652612352,3652612479,GB
+3652612480,3652612543,IE
+3652612544,3652612607,NL
+3652612608,3652613335,FR
+3652613336,3652613343,ES
+3652613344,3652613375,FR
+3652613376,3652613407,FI
+3652613408,3652613615,FR
+3652613616,3652613623,ES
+3652613624,3652613679,FR
+3652613680,3652613695,LT
+3652613696,3652614015,FR
+3652614016,3652614079,BE
+3652614080,3652615871,FR
+3652615872,3652615935,DE
+3652615936,3652620639,FR
+3652620640,3652620671,CZ
+3652620672,3652620735,PT
+3652620736,3652620799,FR
+3652620800,3652620831,PT
+3652620832,3652621247,FR
+3652621248,3652621311,DE
+3652621312,3652621375,FR
+3652621376,3652621439,ES
+3652621440,3652621503,FR
+3652621504,3652621567,IT
+3652621568,3652621631,FR
+3652621632,3652621663,PT
+3652621664,3652621823,FR
+3652621824,3652621951,IE
+3652621952,3652622271,FR
+3652622272,3652622335,GB
+3652622336,3652622879,FR
+3652622880,3652622911,CZ
+3652622912,3652623679,FR
+3652623680,3652623807,NL
+3652623808,3652624191,FR
+3652624192,3652624319,IT
+3652624320,3652628479,FR
+3652628480,3652628543,IT
+3652628544,3652628607,FR
+3652628608,3652628639,PL
+3652628640,3652628855,FR
+3652628856,3652628863,ES
+3652628864,3652629743,FR
+3652629744,3652629759,ES
+3652629760,3652630015,FR
+3652630016,3652630031,ES
+3652630032,3652630079,FR
+3652630080,3652630111,PL
+3652630112,3652631295,FR
+3652631296,3652631359,BE
+3652631360,3652631391,FR
+3652631392,3652631407,CH
+3652631408,3652631423,FR
+3652631424,3652631455,PL
+3652631456,3652631551,FR
+3652631552,3652631583,CZ
+3652631584,3652631807,FR
+3652631808,3652631823,GB
+3652631824,3652632031,FR
+3652632032,3652632063,PT
+3652632064,3652632303,FR
+3652632304,3652632311,ES
+3652632312,3652633599,FR
+3652633600,3652634623,DE
+3652634624,3652635647,PL
+3652635648,3652638655,FR
+3652638656,3652638719,ES
+3652638720,3652638815,FR
+3652638816,3652638847,FI
+3652638848,3652638975,GB
+3652638976,3652639359,FR
+3652639360,3652639423,DE
+3652639424,3652639679,FR
+3652639680,3652639807,NL
+3652639808,3652640575,FR
+3652640576,3652640703,GB
+3652640704,3652640711,FR
+3652640712,3652640719,ES
+3652640720,3652640767,FR
+3652640768,3652640831,ES
+3652640832,3652641727,FR
+3652641728,3652641791,GB
+3652641792,3652642111,FR
+3652642112,3652642175,IE
+3652642176,3652642239,FR
+3652642240,3652642303,DE
+3652642304,3652642367,FR
+3652642368,3652642431,GB
+3652642432,3652642719,FR
+3652642720,3652642751,PT
+3652642752,3652642975,FR
+3652642976,3652643007,IE
+3652643008,3652643375,FR
+3652643376,3652643379,ES
+3652643380,3652643519,FR
+3652643520,3652643583,NL
+3652643584,3652643647,ES
+3652643648,3652644031,FR
+3652644032,3652644063,BE
+3652644064,3652644199,FR
+3652644200,3652644215,ES
+3652644216,3652644223,FR
+3652644224,3652644239,NL
+3652644240,3652644247,FR
+3652644248,3652644255,ES
+3652644256,3652644351,FR
+3652644352,3652644383,FI
+3652644384,3652644415,PL
+3652644416,3652644575,FR
+3652644576,3652644607,DE
+3652644608,3652645119,FR
+3652645120,3652645503,GB
+3652645504,3652645663,FR
+3652645664,3652645695,FI
+3652645696,3652645887,FR
+3652645888,3652646015,NL
+3652646016,3652646079,ES
+3652646080,3652646111,FR
+3652646112,3652646143,CZ
+3652646144,3652646271,NL
+3652646272,3652646655,FR
+3652646656,3652646719,ES
+3652646720,3652646799,FR
+3652646800,3652646815,PL
+3652646816,3652646847,FR
+3652646848,3652646863,FI
+3652646864,3652648847,FR
+3652648848,3652648863,LT
+3652648864,3652648895,FI
+3652648896,3652648959,DE
+3652648960,3652714495,IE
+3652714496,3653238783,DE
+3653238784,3653369855,CH
+3653369856,3653373951,IT
+3653373952,3653378047,NL
+3653378048,3653382143,DE
+3653382144,3653386239,CH
+3653386240,3653390335,DE
+3653390336,3653394431,FR
+3653394432,3653402623,NL
+3653402624,3653406557,GB
+3653406558,3653406558,GN
+3653406559,3653406617,GB
+3653406618,3653406618,GN
+3653406619,3653407103,GB
+3653407104,3653407111,UG
+3653407112,3653408071,GB
+3653408072,3653408079,NG
+3653408080,3653408231,GB
+3653408232,3653408239,KE
+3653408240,3653410815,GB
+3653410816,3653414911,CZ
+3653414912,3653419007,IT
+3653419008,3653423103,IL
+3653423104,3653427199,GB
+3653427200,3653431295,DE
+3653431296,3653435391,RU
+3653435392,3653439487,DE
+3653439488,3653443583,FR
+3653443584,3653447679,DE
+3653447680,3653451775,LV
+3653451776,3653464063,RU
+3653464064,3653468159,NL
+3653468160,3653472255,GR
+3653476352,3653480447,CZ
+3653480448,3653484543,DK
+3653484544,3653488639,TR
+3653488640,3653492735,RU
+3653492736,3653500927,NL
+3653500928,3653505023,GB
+3653505024,3653509119,KZ
+3653509120,3653513215,NL
+3653513216,3653517311,NO
+3653517312,3653525503,AT
+3653525504,3653529599,RU
+3653529600,3653533695,CZ
+3653533696,3653537791,IT
+3653537792,3653541887,AT
+3653541888,3653545983,UA
+3653545984,3653550079,CH
+3653550080,3653554175,MK
+3653554176,3653558271,CZ
+3653558272,3653566463,GB
+3653566464,3653570559,RU
+3653570560,3653574655,ES
+3653574656,3653578751,CZ
+3653578752,3653582847,SE
+3653582848,3653586943,PL
+3653586944,3653591039,DE
+3653591040,3653595135,LU
+3653595136,3653599231,RU
+3653599232,3653601279,CH
+3653601280,3653603327,BA
+3653603328,3653607423,CZ
+3653611520,3653615615,HU
+3653615616,3653619711,RU
+3653619712,3653623807,CH
+3653623808,3653636095,RU
+3653636096,3653640191,NL
+3653640192,3653648383,GB
+3653648384,3653652479,SE
+3653652480,3653656575,RU
+3653656576,3653660671,GB
+3653660672,3653664767,CZ
+3653664768,3653668863,DE
+3653668864,3653672959,SE
+3653672960,3653681151,RU
+3653681152,3653685247,ES
+3653685248,3653689343,DK
+3653689344,3653693439,LV
+3653693440,3653697535,DE
+3653697536,3653705727,IT
+3653705728,3653708331,NO
+3653708332,3653708332,FI
+3653708333,3653713919,NO
+3653713920,3653718015,DE
+3653718016,3653722111,AT
+3653722112,3653730303,LV
+3653730304,3653734399,BA
+3653734400,3653738495,KE
+3653738496,3653746687,GB
+3653746688,3653750783,DE
+3653750784,3653754879,RU
+3653754880,3653758975,UA
+3653758976,3653763071,RU
+3653763072,3654025215,IT
+3654025216,3654287359,GB
+3654287360,3654608404,SE
+3654608405,3654608405,NO
+3654608406,3654608895,SE
+3654608896,3654609919,NO
+3654609920,3654610431,SE
+3654610432,3654610943,FR
+3654610944,3654610951,SE
+3654610952,3654610959,DE
+3654610960,3654612231,SE
+3654612232,3654612239,AT
+3654612240,3654612271,SE
+3654612272,3654612287,AT
+3654612288,3654614047,SE
+3654614048,3654614063,GB
+3654614064,3654614079,SE
+3654614080,3654614271,FI
+3654614272,3654811647,SE
+3654811648,3654942719,ES
+3654942720,3655073791,IR
+3655073792,3655335935,IT
+3655335936,3657433087,DE
+3657433088,3659415455,CN
+3659415456,3659415487,SG
+3659415488,3659530239,CN
+3659530240,3659595775,TW
+3659595776,3659628543,ID
+3659628544,3659661311,JP
+3659661312,3659792383,TW
+3659792384,3660054527,KR
+3660054528,3660578815,JP
+3660578816,3661103103,KR
+3661103104,3663986687,CN
+3663986688,3663987711,AU
+3663987712,3663987967,ID
+3663987968,3663989247,JP
+3663989248,3663989503,VN
+3663989504,3663989759,ID
+3663989760,3663990271,AU
+3663990272,3663990527,VN
+3663990528,3663990783,JP
+3663990784,3663991295,HK
+3663991296,3663991551,MY
+3663991552,3663991807,AU
+3663992064,3663992319,NZ
+3663992320,3663992575,MY
+3663992576,3663993599,NZ
+3663993600,3663996159,ID
+3663996160,3663996415,AU
+3663996416,3663996671,TH
+3663996672,3663997183,AU
+3663997184,3663997439,ID
+3663997440,3663997695,JP
+3663997696,3663997951,AU
+3663997952,3663998207,MY
+3663998208,3663998463,JP
+3663998464,3663998975,TH
+3663998976,3663999487,IN
+3663999488,3663999743,AU
+3664000000,3664000767,AU
+3664000768,3664001023,ID
+3664001024,3664001279,NZ
+3664001280,3664001535,LK
+3664001536,3664001791,MY
+3664002048,3664002303,VN
+3664002304,3664002559,LK
+3664002560,3664003327,ID
+3664003328,3664003583,NZ
+3664003584,3664003839,TH
+3664003840,3664004095,JP
+3664004352,3664004607,MY
+3664004864,3664005119,KH
+3664005120,3664005887,ID
+3664005888,3664006143,MY
+3664006144,3664006399,AU
+3664006400,3664006655,PF
+3664006656,3664006911,AU
+3664007168,3664008191,AU
+3664008192,3664008447,MN
+3664008448,3664008703,PK
+3664008960,3664010239,AU
+3664010240,3664052223,CN
+3664052224,3664084991,NZ
+3664084992,3664117759,KR
+3664117760,3664248831,HK
+3664248832,3664642047,CN
+3664642048,3664707583,JP
+3664707584,3664773119,MY
+3664773120,3666870271,JP
+3666870272,3666960455,KR
+3666960456,3666960456,US
+3666960457,3667918847,KR
+3667918848,3668967423,TW
+3668967424,3669491711,JP
+3669491712,3669557247,TW
+3669557248,3669590015,AU
+3669590016,3669606399,JP
+3669606400,3669614591,CN
+3669614592,3669616639,NZ
+3669616640,3669618687,AU
+3669618688,3669620735,CN
+3669620736,3669622783,IN
+3669622784,3669688319,SG
+3669688320,3669753855,TW
+3669753856,3670015999,HK
+3670016000,3671064575,CN
+3671064576,3671130111,MY
+3671130112,3671195647,KR
+3671195648,3671326719,TW
+3671326720,3671392255,SG
+3671392256,3671457791,HK
+3671457792,3671588863,AU
+3671588864,3672637439,JP
+3672637440,3673161727,KR
+3673161728,3673686015,CN
+3673686016,3673751551,IN
+3673751552,3673817087,CN
+3673817088,3673882623,HK
+3673882624,3673948159,JP
+3673948160,3674210303,HK
+3674210304,3678404607,JP
+3678404608,3678535679,IN
+3678535680,3678666751,JP
+3678666752,3678928895,TW
+3678928896,3678994431,CN
+3678994432,3679027199,HK
+3679027200,3679059967,JP
+3679059968,3679158271,SG
+3679158272,3679191039,JP
+3679191040,3679453183,HK
+3679453184,3679584255,TW
+3679584256,3679649791,CN
+3679649792,3679682559,ID
+3679682560,3679715327,CN
+3679715328,3679977471,TW
+3679977472,3680108543,NZ
+3680108544,3680124927,TW
+3680124928,3680125951,IN
+3680125952,3680129023,CN
+3680129024,3680133119,PH
+3680133120,3680137215,IN
+3680137216,3680141311,HK
+3680141312,3680174079,AU
+3680174080,3680206847,TW
+3680206848,3680239615,IN
+3680239616,3680403455,MY
+3680403456,3680436223,JP
+3680436224,3680501759,MY
+3680501760,3682598911,JP
+3682598912,3684575268,CN
+3684575269,3684575269,HK
+3684575270,3684696063,CN
+3684696064,3688366079,JP
+3688366080,3689938943,CN
+3689938944,3690070015,KR
+3690070016,3690463231,CN
+3690463232,3690987519,KR
+3690987520,3695181823,JP
+3695181824,3697278975,KR
+3697278976,3697573887,JP
+3697573888,3697582079,GB
+3697582080,3697586175,SG
+3697586176,3697606655,JP
+3697606656,3697655807,AU
+3697655808,3697672191,CN
+3697672192,3697737727,JP
+3697737728,3697803263,KR
+3697803264,3698327551,JP
+3698327552,3698589695,CN
+3698589696,3699376127,KR
+3699376128,3700424703,TW
+3700424704,3700752383,JP
+3700752384,3700817919,KR
+3700817920,3700981759,JP
+3700981760,3701014527,CN
+3701014528,3701080063,JP
+3701080064,3701211135,CN
+3701211136,3701252095,JP
+3701252096,3701256191,NC
+3701256192,3701258239,SG
+3701258240,3701260287,IN
+3701260288,3701293055,JP
+3701293056,3701301247,AU
+3701301248,3701305343,ID
+3701305344,3701309439,TW
+3701309440,3701374975,JP
+3701374976,3701375999,IN
+3701376000,3701377023,HK
+3701377024,3701380095,IN
+3701380096,3701381119,KH
+3701381120,3701390335,IN
+3701390336,3701391359,AU
+3701391360,3701392383,IN
+3701392384,3701393407,HK
+3701393408,3701394431,MY
+3701394432,3701395455,BD
+3701395456,3701396479,MY
+3701396480,3701397247,NZ
+3701397248,3701397503,AU
+3701397504,3701398527,JP
+3701398528,3701399551,MV
+3701399552,3701400575,HK
+3701400576,3701401599,TW
+3701401600,3701402623,BD
+3701402624,3701403647,BT
+3701403648,3701404671,CN
+3701404672,3701405695,HK
+3701405696,3701406719,JP
+3701406720,3701407743,HK
+3701407744,3701473279,JP
+3701473280,3704619007,CN
+3704619008,3705667583,JP
+3705667584,3705929727,IN
+3705929728,3706060799,TW
+3706060800,3706126335,KR
+3706126336,3706142719,CN
+3706142720,3706159103,VN
+3706159104,3706191871,CN
+3706191872,3706207107,SG
+3706207108,3706207108,US
+3706207109,3706208255,SG
+3706208256,3706224639,CN
+3706224640,3706225663,HK
+3706225664,3706226687,JP
+3706226688,3706231807,HK
+3706231808,3706232831,JP
+3706232832,3706233343,HK
+3706233344,3706234367,JP
+3706234368,3706237951,HK
+3706237952,3706238975,JP
+3706238976,3706244095,HK
+3706244096,3706244863,JP
+3706244864,3706245887,HK
+3706245888,3706246143,JP
+3706246144,3706253823,HK
+3706253824,3706254335,JP
+3706254336,3706256895,HK
+3706256896,3706257151,JP
+3706257152,3706257407,HK
+3706257408,3706322943,AU
+3706322944,3706388479,CN
+3706388480,3706781695,AU
+3706781696,3706847231,HK
+3706847232,3706978303,CN
+3706978304,3707109375,AU
+3707109376,3707174911,HK
+3707174912,3707207679,JP
+3707207680,3707208703,BD
+3707208704,3707209727,NZ
+3707209728,3707211775,CN
+3707211776,3707215871,NP
+3707215872,3707217919,BD
+3707217920,3707219967,ID
+3707219968,3707222015,AU
+3707222016,3707224063,JP
+3707224064,3707240447,LK
+3707240448,3707568127,CN
+3707568128,3707633663,AU
+3707633664,3707699199,JP
+3707699200,3707764735,SG
+3707764736,3708600319,CN
+3708600320,3708616703,JP
+3708616704,3708813311,CN
+3708813312,3715629055,JP
+3715629056,3715653631,TW
+3715653632,3715655679,BD
+3715655680,3715657727,IN
+3715657728,3715661823,SG
+3715661824,3715670015,AU
+3715670016,3715671039,KH
+3715671040,3715672063,AU
+3715672064,3715674111,JP
+3715674112,3715678207,HK
+3715678208,3715694591,PK
+3715694592,3715710975,VN
+3715710976,3715719167,AU
+3715719168,3715727359,PH
+3715727360,3715729151,AU
+3715729152,3715729407,NZ
+3715729408,3715735551,AU
+3715735552,3715741695,JP
+3715741696,3715743743,PH
+3715743744,3715760127,JP
+3715760128,3715891199,CN
+3715891200,3716153343,HK
+3716153344,3716170239,SG
+3716170240,3716170494,TH
+3716170495,3716171519,SG
+3716171520,3716171775,JP
+3716171776,3716172031,SG
+3716172032,3716172287,JP
+3716172288,3716173055,SG
+3716173056,3716173311,JP
+3716173312,3716173567,SG
+3716173568,3716173823,JP
+3716173824,3716174079,SG
+3716174080,3716174083,TH
+3716174084,3716174335,JP
+3716174336,3716175615,SG
+3716175616,3716176895,JP
+3716176896,3716178175,SG
+3716178176,3716178943,JP
+3716178944,3716179967,SG
+3716179968,3716181759,JP
+3716181760,3716182783,SG
+3716182784,3716183295,JP
+3716183296,3716183551,SG
+3716183552,3716184063,JP
+3716184064,3716184319,SG
+3716184320,3716184575,JP
+3716184576,3716184831,SG
+3716184832,3716185087,JP
+3716185088,3716186111,SG
+3716186112,3716415487,CN
+3716415488,3716431871,VN
+3716431872,3716440063,KR
+3716440064,3716444159,JP
+3716444160,3716446207,PK
+3716446208,3716464639,JP
+3716464640,3716481023,ID
+3716481024,3716489215,VN
+3716489216,3716493311,MY
+3716493312,3716497407,KR
+3716497408,3716513791,JP
+3716513792,3716530175,KR
+3716530176,3716538367,AU
+3716538368,3716546559,CN
+3716546560,3716677631,IN
+3716677632,3716808703,CN
+3716808704,3718840319,KR
+3718840320,3718905855,TW
+3718905856,3719036927,JP
+3719036928,3719823359,CN
+3719823360,3720347647,JP
+3720347648,3720859647,CN
+3720859648,3720863743,AU
+3720863744,3723493375,CN
+3723493376,3725590527,JP
+3725590528,3730833407,CN
+3730833408,3732602879,KR
+3732602880,3732668415,TH
+3732668416,3732733951,ID
+3732733952,3732799487,CN
+3732799488,3732832255,PH
+3732832256,3732865023,CN
+3732865024,3732930559,PH
+3732930560,3733979135,CN
+3733979136,3734503423,JP
+3734503424,3734765567,NZ
+3734765568,3734896639,TW
+3734896640,3735027711,JP
+3735027712,3735289855,CN
+3735289856,3735388159,SG
+3735388160,3735404543,LK
+3735404544,3735420927,ID
+3735420928,3735551999,HK
+3735552000,3739222015,CN
+3739222016,3739570175,JP
+3739570176,3739572223,ID
+3739572224,3739574271,AU
+3739574272,3739680767,JP
+3739680768,3739697151,KR
+3739697152,3739746303,JP
+3739746304,3740270591,KR
+3740270592,3740925951,CN
+3740925952,3741024255,TW
+3741024256,3741057023,KR
+3741057024,3741319167,VN
+3741319168,3742367743,CN
+3742367744,3742629887,HK
+3742629888,3742760959,CN
+3742760960,3742892031,TW
+3742892032,3742957567,TH
+3742957568,3742973951,PH
+3742973952,3742982143,SG
+3742982144,3742986239,ID
+3742986240,3742988287,AU
+3742988288,3742990335,VU
+3742990336,3743006719,JP
+3743006720,3743014911,TH
+3743014912,3743016959,AU
+3743016960,3743019007,SG
+3743019008,3743022079,MY
+3743022080,3743023103,BD
+3743023104,3743027199,TW
+3743027200,3743028223,IN
+3743028224,3743029247,AF
+3743029248,3743030271,NZ
+3743030272,3743035391,IN
+3743035392,3743039487,HK
+3743039488,3743055871,TW
+3743055872,3743088639,KR
+3743088640,3743093647,AU
+3743093648,3743093648,NZ
+3743093649,3743096831,AU
+3743096832,3743105023,TW
+3743105024,3743106047,AU
+3743106048,3743109119,JP
+3743109120,3743113215,BD
+3743113216,3743115263,AU
+3743115264,3743117311,VN
+3743117312,3743118335,BD
+3743118336,3743119359,JP
+3743119360,3743120383,IN
+3743120384,3743121407,JP
+3743121408,3743125503,MY
+3743125504,3743129599,ID
+3743129600,3743130623,HK
+3743130624,3743130879,SG
+3743130880,3743131135,HK
+3743131136,3743133695,SG
+3743133696,3743134719,AU
+3743134720,3743135743,JP
+3743135744,3743136767,CN
+3743136768,3743137791,MY
+3743137792,3743154175,TH
+3743154176,3743186943,MY
+3743186944,3743219711,KR
+3743219712,3743252479,JP
+3743252480,3743264767,NC
+3743264768,3743268863,JP
+3743268864,3743272959,IN
+3743272960,3743273983,CN
+3743273984,3743275007,BD
+3743275008,3743276031,HK
+3743276032,3743277055,IN
+3743277056,3743281151,PK
+3743281152,3743282175,AU
+3743282176,3743283199,JP
+3743283200,3743284223,HK
+3743284224,3743285247,CN
+3743285248,3743416319,IN
+3743416320,3745513471,KR
+3745513472,3749052415,CN
+3749052416,3749183487,HK
+3749183488,3749838847,CN
+3749838848,3749839871,SG
+3749839872,3749840895,IN
+3749840896,3749841919,CN
+3749841920,3749842943,AU
+3749842944,3749843967,PH
+3749843968,3749844991,ID
+3749844992,3749846015,AU
+3749846016,3749847039,IN
+3749847040,3749855231,HK
+3749855232,3749969919,KR
+3749969920,3750232063,JP
+3750232064,3750756351,TW
+3750756352,3752067071,CN
+3752067072,3752132607,ID
+3752132608,3752133631,BD
+3752133632,3752134655,ID
+3752134656,3752136703,TW
+3752136704,3752137727,NZ
+3752137728,3752138751,JP
+3752138752,3752140799,IN
+3752140800,3752148991,JP
+3752148992,3752153087,NZ
+3752153088,3752157183,JP
+3752157184,3752165375,AU
+3752165376,3752198143,KR
+3752198144,3752329215,CN
+3752329216,3752853503,KR
+3752853504,3753902079,IN
+3753902080,3754033151,CN
+3754033152,3754164223,KR
+3754164224,3754229759,IN
+3754229760,3754295295,HK
+3754295296,3754426367,CN
+3754426368,3754491903,TW
+3754491904,3754688511,CN
+3754688512,3754950655,TH
+3754950656,3755474943,CN
+3755474944,3755737087,JP
+3755737088,3755868159,CN
+3755868160,3755933695,KR
+3755933696,3755966463,JP
+3755966464,3755974655,IN
+3755974656,3755976703,JP
+3755976704,3755978751,KH
+3755978752,3755986943,CN
+3755986944,3755988991,JP
+3755988992,3755990015,HK
+3755990016,3755991039,SG
+3755991040,3755999231,JP
+3755999232,3757047807,IN
+3757047808,3757834239,CN
+3757834240,3757850623,AU
+3757850624,3757858815,JP
+3757858816,3757862911,AU
+3757862912,3757867007,JP
+3757867008,3757875519,CN
+3757875520,3757875583,HK
+3757875584,3757899775,CN
+3757899776,3757965311,KR
+3757965312,3758063615,CN
+3758063616,3758079999,HK
+3758080000,3758088191,KR
+3758088192,3758090239,ID
+3758090240,3758091263,AU
+3758091264,3758092287,CN
+3758092288,3758093311,HK
+3758093312,3758094335,IN
+3758094336,3758095359,HK
+3758095360,3758095871,CN
+3758095872,3758096127,SG
+3758096128,3758096383,AU
diff --git a/broker/test_geoip6 b/broker/test_geoip6
new file mode 100644
index 0000000..80279f3
--- /dev/null
+++ b/broker/test_geoip6
@@ -0,0 +1,693 @@
+# Last updated based on February 7 2018 Maxmind GeoLite2 Country
+# wget https://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz
+# gunzip GeoLite2-Country.mmdb.gz
+# python mmdb-convert.py GeoLite2-Country.mmdb
+600:8801:9400:5a1:948b:ab15:dde3:61a3,600:8801:9400:5a1:948b:ab15:dde3:61a3,US
+2001:200::,2001:200:ffff:ffff:ffff:ffff:ffff:ffff,JP
+2001:208::,2001:208:ffff:ffff:ffff:ffff:ffff:ffff,SG
+2001:218::,2001:218:ffff:ffff:ffff:ffff:ffff:ffff,JP
+2001:220::,2001:220:ffff:ffff:ffff:ffff:ffff:ffff,KR
+2001:230::,2001:230:ffff:ffff:ffff:ffff:ffff:ffff,KR
+2001:238::,2001:238:ffff:ffff:ffff:ffff:ffff:ffff,TW
+2001:240::,2001:240:ffff:ffff:ffff:ffff:ffff:ffff,JP
+2620:21:2000::,2620:21:2000:ffff:ffff:ffff:ffff:ffff,US
+2620:21:4000::,2620:21:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:21:6000::,2620:21:600f:ffff:ffff:ffff:ffff:ffff,US
+2620:21:8000::,2620:21:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:21:a000::,2620:21:a000:ffff:ffff:ffff:ffff:ffff,US
+2620:21:c000::,2620:21:c000:ffff:ffff:ffff:ffff:ffff,CA
+2620:21:e000::,2620:21:e000:ffff:ffff:ffff:ffff:ffff,US
+2620:22::,2620:22::ffff:ffff:ffff:ffff:ffff,US
+2620:22:2000::,2620:22:2000:ffff:ffff:ffff:ffff:ffff,US
+2620:22:4000::,2620:22:4000:ffff:ffff:ffff:ffff:ffff,CA
+2620:22:6000::,2620:22:6000:ffff:ffff:ffff:ffff:ffff,US
+2620:c2:8000::,2620:c2:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:c2:c000::,2620:c2:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:c3::,2620:c3::ffff:ffff:ffff:ffff:ffff,US
+2620:c3:4000::,2620:c3:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:c3:8000::,2620:c3:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:c3:c000::,2620:c3:c00f:ffff:ffff:ffff:ffff:ffff,US
+2620:c4::,2620:c4::ffff:ffff:ffff:ffff:ffff,US
+2620:c4:4000::,2620:c4:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:c4:8000::,2620:c4:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:c4:c000::,2620:c4:c000:ffff:ffff:ffff:ffff:ffff,CA
+2620:c5::,2620:c5::ffff:ffff:ffff:ffff:ffff,US
+2620:c5:4000::,2620:c5:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:c5:c000::,2620:c5:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:c6::,2620:c6::ffff:ffff:ffff:ffff:ffff,US
+2620:c6:4000::,2620:c6:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:c6:8000::,2620:c6:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:c6:c000::,2620:c6:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:c7::,2620:c7::ffff:ffff:ffff:ffff:ffff,US
+2620:c7:4000::,2620:c7:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:c7:8000::,2620:c7:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:c7:c000::,2620:c7:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:c8::,2620:c8::ffff:ffff:ffff:ffff:ffff,US
+2620:c8:4000::,2620:c8:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:c8:c000::,2620:c8:c00f:ffff:ffff:ffff:ffff:ffff,US
+2620:c9::,2620:c9::ffff:ffff:ffff:ffff:ffff,US
+2620:c9:4000::,2620:c9:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:c9:8000::,2620:c9:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:c9:c000::,2620:c9:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:ca::,2620:ca::ffff:ffff:ffff:ffff:ffff,US
+2620:ca:4000::,2620:ca:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:ca:8000::,2620:ca:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:ca:c000::,2620:ca:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:cb::,2620:cb:f:ffff:ffff:ffff:ffff:ffff,US
+2620:cb:4000::,2620:cb:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:cb:8000::,2620:cb:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:cb:c000::,2620:cb:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:cc::,2620:cc::ffff:ffff:ffff:ffff:ffff,US
+2620:cc:4000::,2620:cc:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:cc:8000::,2620:cc:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:cc:c000::,2620:cc:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:cd::,2620:cd::ffff:ffff:ffff:ffff:ffff,US
+2620:cd:4000::,2620:cd:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:cd:8000::,2620:cd:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:cd:c000::,2620:cd:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:ce::,2620:ce::ffff:ffff:ffff:ffff:ffff,US
+2620:ce:4000::,2620:ce:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:ce:8000::,2620:ce:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:ce:c000::,2620:ce:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:cf:4000::,2620:cf:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:cf:8000::,2620:cf:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:cf:c000::,2620:cf:c00f:ffff:ffff:ffff:ffff:ffff,US
+2620:d0::,2620:d0::ffff:ffff:ffff:ffff:ffff,US
+2620:d0:4000::,2620:d0:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:d0:8000::,2620:d0:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:d0:c000::,2620:d0:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:d1::,2620:d1::ffff:ffff:ffff:ffff:ffff,US
+2620:d1:4000::,2620:d1:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:d1:8000::,2620:d1:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:d1:c000::,2620:d1:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:d2::,2620:d2::ffff:ffff:ffff:ffff:ffff,US
+2620:d2:4000::,2620:d2:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:d2:8000::,2620:d2:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:d2:c000::,2620:d2:c000:ffff:ffff:ffff:ffff:ffff,CA
+2620:d3:4000::,2620:d3:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:d3:8000::,2620:d3:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:d3:c000::,2620:d3:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:d4::,2620:d4::ffff:ffff:ffff:ffff:ffff,US
+2620:d4:4000::,2620:d4:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:d4:8000::,2620:d4:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:d5::,2620:d5::ffff:ffff:ffff:ffff:ffff,US
+2620:d5:4000::,2620:d5:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:d5:8000::,2620:d5:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:d5:c000::,2620:d5:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:d6::,2620:d6::ffff:ffff:ffff:ffff:ffff,US
+2620:d6:4000::,2620:d6:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:d6:8000::,2620:d6:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:d6:c000::,2620:d6:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:d7::,2620:d7::ffff:ffff:ffff:ffff:ffff,US
+2620:d7:4000::,2620:d7:4000:ffff:ffff:ffff:ffff:ffff,CA
+2620:d7:8000::,2620:d7:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:d7:c000::,2620:d7:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:d8::,2620:d8::ffff:ffff:ffff:ffff:ffff,US
+2620:d8:4000::,2620:d8:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:d8:8000::,2620:d8:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:d8:c000::,2620:d8:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:d9::,2620:d9::ffff:ffff:ffff:ffff:ffff,US
+2620:d9:4000::,2620:d9:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:d9:8000::,2620:d9:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:d9:c000::,2620:d9:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:da::,2620:da::ffff:ffff:ffff:ffff:ffff,US
+2620:da:4000::,2620:da:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:da:c000::,2620:da:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:db::,2620:db::ffff:ffff:ffff:ffff:ffff,US
+2620:db:4000::,2620:db:4000:ffff:ffff:ffff:ffff:ffff,CA
+2620:db:8000::,2620:db:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:db:c000::,2620:db:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:dc::,2620:dc::ffff:ffff:ffff:ffff:ffff,US
+2620:dc:8::,2620:dc:8:ffff:ffff:ffff:ffff:ffff,US
+2620:dc:4000::,2620:dc:40ff:ffff:ffff:ffff:ffff:ffff,US
+2620:dc:8000::,2620:dc:8000:ffff:ffff:ffff:ffff:ffff,CA
+2620:dc:c000::,2620:dc:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:dd::,2620:dd::ffff:ffff:ffff:ffff:ffff,CA
+2620:dd:4000::,2620:dd:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:dd:8000::,2620:dd:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:dd:c000::,2620:dd:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:de::,2620:de::ffff:ffff:ffff:ffff:ffff,US
+2620:de:4000::,2620:de:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:de:8000::,2620:de:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:de:c000::,2620:de:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:df::,2620:df::ffff:ffff:ffff:ffff:ffff,US
+2620:df:4000::,2620:df:400f:ffff:ffff:ffff:ffff:ffff,US
+2620:df:8000::,2620:df:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:df:c000::,2620:df:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:e0::,2620:e0::ffff:ffff:ffff:ffff:ffff,US
+2620:e0:4000::,2620:e0:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:e0:8000::,2620:e0:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:e0:c000::,2620:e0:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:e1::,2620:e1::ffff:ffff:ffff:ffff:ffff,US
+2620:e1:4000::,2620:e1:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:e1:8000::,2620:e1:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:e1:c000::,2620:e1:c000:ffff:ffff:ffff:ffff:ffff,VG
+2620:e2::,2620:e2::ffff:ffff:ffff:ffff:ffff,US
+2620:e2:4000::,2620:e2:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:e2:8000::,2620:e2:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:e2:c000::,2620:e2:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:e3::,2620:e3::ffff:ffff:ffff:ffff:ffff,US
+2620:e3:4000::,2620:e3:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:e3:8000::,2620:e3:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:e3:c000::,2620:e3:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:e4::,2620:e4::ffff:ffff:ffff:ffff:ffff,US
+2620:e4:4000::,2620:e4:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:e4:8000::,2620:e4:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:e4:c000::,2620:e4:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:e5::,2620:e5::ffff:ffff:ffff:ffff:ffff,US
+2620:e5:4000::,2620:e5:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:e5:8000::,2620:e5:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:e5:c000::,2620:e5:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:e6::,2620:e6::ffff:ffff:ffff:ffff:ffff,US
+2620:e6:4000::,2620:e6:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:e6:8000::,2620:e6:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:e6:c000::,2620:e6:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:e7::,2620:e7::ffff:ffff:ffff:ffff:ffff,US
+2620:e7:4000::,2620:e7:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:e7:8000::,2620:e7:8000:ffff:ffff:ffff:ffff:ffff,CA
+2620:e7:c000::,2620:e7:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:e8::,2620:e8::ffff:ffff:ffff:ffff:ffff,US
+2620:e8:4000::,2620:e8:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:e8:8000::,2620:e8:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:e8:c000::,2620:e8:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:e9::,2620:e9::ffff:ffff:ffff:ffff:ffff,US
+2620:e9:4000::,2620:e9:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:e9:8000::,2620:e9:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:e9:c000::,2620:e9:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:ea::,2620:ea:f:ffff:ffff:ffff:ffff:ffff,US
+2620:ea:4000::,2620:ea:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:ea:8000::,2620:ea:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:eb::,2620:eb::ffff:ffff:ffff:ffff:ffff,US
+2620:eb:4000::,2620:eb:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:eb:8000::,2620:eb:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:eb:c000::,2620:eb:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:ec::,2620:ec::ffff:ffff:ffff:ffff:ffff,US
+2620:ec:4000::,2620:ec:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:ec:8000::,2620:ec:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:ec:c000::,2620:ec:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:ed::,2620:ed::ffff:ffff:ffff:ffff:ffff,US
+2620:ed:4000::,2620:ed:4000:ffff:ffff:ffff:ffff:ffff,CA
+2620:ed:8000::,2620:ed:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:ed:c000::,2620:ed:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:ee::,2620:ee::ffff:ffff:ffff:ffff:ffff,US
+2620:ee:4000::,2620:ee:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:ee:8000::,2620:ee:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:ee:c000::,2620:ee:c00f:ffff:ffff:ffff:ffff:ffff,US
+2620:ef:4000::,2620:ef:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:ef:8000::,2620:ef:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:ef:c000::,2620:ef:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:f0::,2620:f0::ffff:ffff:ffff:ffff:ffff,US
+2620:f0:4000::,2620:f0:400f:ffff:ffff:ffff:ffff:ffff,US
+2620:f0:8000::,2620:f0:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:f0:c000::,2620:f0:c002:ffff:ffff:ffff:ffff:ffff,US
+2620:f0:c003::,2620:f0:c003:ffff:ffff:ffff:ffff:ffff,NL
+2620:f0:c004::,2620:f0:c004:ffff:ffff:ffff:ffff:ffff,US
+2620:f0:c005::,2620:f0:c005:ffff:ffff:ffff:ffff:ffff,SG
+2620:f0:c006::,2620:f0:c009:ffff:ffff:ffff:ffff:ffff,US
+2620:f0:c00a::,2620:f0:c00a:ffff:ffff:ffff:ffff:ffff,CA
+2620:f0:c00b::,2620:f0:c00f:ffff:ffff:ffff:ffff:ffff,US
+2620:f1:4000::,2620:f1:4000:ffff:ffff:ffff:ffff:ffff,CA
+2620:f1:8000::,2620:f1:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:f1:c000::,2620:f1:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:f2::,2620:f2::ffff:ffff:ffff:ffff:ffff,CA
+2620:f2:4000::,2620:f2:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:f2:8000::,2620:f2:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:f2:c000::,2620:f2:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:f3::,2620:f3::ffff:ffff:ffff:ffff:ffff,US
+2620:f3:4000::,2620:f3:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:f3:8000::,2620:f3:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:f3:c000::,2620:f3:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:f4::,2620:f4::ffff:ffff:ffff:ffff:ffff,US
+2620:f4:4000::,2620:f4:40ff:ffff:ffff:ffff:ffff:ffff,US
+2620:f4:8000::,2620:f4:8000:ffff:ffff:ffff:ffff:ffff,CA
+2620:f4:c000::,2620:f4:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:f5::,2620:f5::ffff:ffff:ffff:ffff:ffff,US
+2620:f5:4000::,2620:f5:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:f5:8000::,2620:f5:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:f5:c000::,2620:f5:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:f6::,2620:f6::ffff:ffff:ffff:ffff:ffff,CA
+2620:f6:4000::,2620:f6:400f:ffff:ffff:ffff:ffff:ffff,US
+2620:f6:8000::,2620:f6:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:f6:c000::,2620:f6:c000:ffff:ffff:ffff:ffff:ffff,CA
+2620:f7::,2620:f7::ffff:ffff:ffff:ffff:ffff,US
+2620:f7:4000::,2620:f7:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:f7:8000::,2620:f7:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:f7:c000::,2620:f7:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:f8::,2620:f8::ffff:ffff:ffff:ffff:ffff,US
+2620:f8:4000::,2620:f8:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:f8:8000::,2620:f8:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:f8:c000::,2620:f8:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:f9::,2620:f9:f:ffff:ffff:ffff:ffff:ffff,US
+2620:f9:4000::,2620:f9:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:f9:8000::,2620:f9:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:f9:c000::,2620:f9:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:fa::,2620:fa::ffff:ffff:ffff:ffff:ffff,US
+2620:fa:4000::,2620:fa:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:fa:8000::,2620:fa:8000:ffff:ffff:ffff:ffff:ffff,CA
+2620:fa:c000::,2620:fa:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:fb::,2620:fb::ffff:ffff:ffff:ffff:ffff,US
+2620:fb:4000::,2620:fb:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:fb:8000::,2620:fb:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:fc::,2620:fc::ffff:ffff:ffff:ffff:ffff,CA
+2620:fc:4000::,2620:fc:4000:ffff:ffff:ffff:ffff:ffff,CA
+2620:fc:8000::,2620:fc:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:fc:c000::,2620:fc:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:fd::,2620:fd::ffff:ffff:ffff:ffff:ffff,CA
+2620:fd:4000::,2620:fd:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:fd:8000::,2620:fd:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:fd:c000::,2620:fd:c000:ffff:ffff:ffff:ffff:ffff,CA
+2620:fe::,2620:fe::ffff:ffff:ffff:ffff:ffff,US
+2620:fe:2040::,2620:fe:2040:ffff:ffff:ffff:ffff:ffff,US
+2620:fe:8000::,2620:fe:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:fe:c000::,2620:fe:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:ff::,2620:ff::ffff:ffff:ffff:ffff:ffff,US
+2620:ff:4000::,2620:ff:4000:ffff:ffff:ffff:ffff:ffff,US
+2620:ff:8000::,2620:ff:8000:ffff:ffff:ffff:ffff:ffff,US
+2620:ff:c000::,2620:ff:c000:ffff:ffff:ffff:ffff:ffff,US
+2620:100::,2620:100:f:ffff:ffff:ffff:ffff:ffff,US
+2620:100:3000::,2620:100:3007:ffff:ffff:ffff:ffff:ffff,US
+2620:100:4000::,2620:100:403f:ffff:ffff:ffff:ffff:ffff,US
+2620:100:5000::,2620:100:5007:ffff:ffff:ffff:ffff:ffff,US
+2620:100:6000::,2620:100:60ff:ffff:ffff:ffff:ffff:ffff,US
+2620:100:7000::,2620:100:700f:ffff:ffff:ffff:ffff:ffff,US
+2620:100:8000::,2620:100:8003:ffff:ffff:ffff:ffff:ffff,US
+2620:100:9000::,2620:100:900f:ffff:ffff:ffff:ffff:ffff,US
+2620:100:a000::,2620:100:a00f:ffff:ffff:ffff:ffff:ffff,US
+2620:100:c000::,2620:100:c03f:ffff:ffff:ffff:ffff:ffff,US
+2620:100:d000::,2620:100:d00f:ffff:ffff:ffff:ffff:ffff,US
+2620:100:e000::,2620:100:e00f:ffff:ffff:ffff:ffff:ffff,US
+2620:100:f000::,2620:100:f00f:ffff:ffff:ffff:ffff:ffff,US
+2620:101::,2620:101:3:ffff:ffff:ffff:ffff:ffff,US
+2620:101:1000::,2620:101:103f:ffff:ffff:ffff:ffff:ffff,US
+2620:101:2000::,2620:101:201f:ffff:ffff:ffff:ffff:ffff,US
+2620:101:3000::,2620:101:303f:ffff:ffff:ffff:ffff:ffff,US
+2620:101:4000::,2620:101:403f:ffff:ffff:ffff:ffff:ffff,US
+2620:101:5000::,2620:101:503f:ffff:ffff:ffff:ffff:ffff,US
+2620:101:6000::,2620:101:6001:ffff:ffff:ffff:ffff:ffff,US
+2620:101:7000::,2620:101:7001:ffff:ffff:ffff:ffff:ffff,US
+2620:101:8000::,2620:101:80f1:ffff:ffff:ffff:ffff:ffff,US
+2620:101:80f2::,2620:101:80f2:7fff:ffff:ffff:ffff:ffff,CA
+2620:101:80f2:8000::,2620:101:80ff:ffff:ffff:ffff:ffff:ffff,US
+2620:101:9000::,2620:101:900f:ffff:ffff:ffff:ffff:ffff,US
+2620:101:b000::,2620:101:b07f:ffff:ffff:ffff:ffff:ffff,US
+2620:101:c000::,2620:101:c0ff:ffff:ffff:ffff:ffff:ffff,CA
+2620:101:d000::,2620:101:d007:ffff:ffff:ffff:ffff:ffff,US
+2620:101:e000::,2620:101:e00f:ffff:ffff:ffff:ffff:ffff,US
+2620:101:f000::,2620:101:f001:ffff:ffff:ffff:ffff:ffff,CA
+2620:102::,2620:102:f:ffff:ffff:ffff:ffff:ffff,US
+2620:102:2000::,2620:102:200f:ffff:ffff:ffff:ffff:ffff,US
+2620:102:3000::,2620:102:300f:ffff:ffff:ffff:ffff:ffff,US
+2620:102:4000::,2620:102:403f:ffff:ffff:ffff:ffff:ffff,US
+2a07:14c0::,2a07:14c7:ffff:ffff:ffff:ffff:ffff:ffff,RU
+2a07:1500::,2a07:1507:ffff:ffff:ffff:ffff:ffff:ffff,GB
+2a07:1540::,2a07:1547:ffff:ffff:ffff:ffff:ffff:ffff,NO
+2a07:1580::,2a07:1587:ffff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:15c0::,2a07:15c7:ffff:ffff:ffff:ffff:ffff:ffff,TR
+2a07:1600::,2a07:1607:ffff:ffff:ffff:ffff:ffff:ffff,NO
+2a07:1640::,2a07:1647:ffff:ffff:ffff:ffff:ffff:ffff,NO
+2a07:1680::,2a07:1687:ffff:ffff:ffff:ffff:ffff:ffff,NO
+2a07:16c0::,2a07:16c7:ffff:ffff:ffff:ffff:ffff:ffff,ES
+2a07:1700::,2a07:1707:ffff:ffff:ffff:ffff:ffff:ffff,NO
+2a07:1740::,2a07:1747:ffff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:1780::,2a07:1787:ffff:ffff:ffff:ffff:ffff:ffff,RU
+2a07:17c0::,2a07:17c7:ffff:ffff:ffff:ffff:ffff:ffff,UA
+2a07:1800::,2a07:1807:ffff:ffff:ffff:ffff:ffff:ffff,AT
+2a07:1840::,2a07:1847:ffff:ffff:ffff:ffff:ffff:ffff,RU
+2a07:1880::,2a07:1887:ffff:ffff:ffff:ffff:ffff:ffff,IT
+2a07:18c0::,2a07:18c7:ffff:ffff:ffff:ffff:ffff:ffff,FR
+2a07:1900::,2a07:1907:ffff:ffff:ffff:ffff:ffff:ffff,FR
+2a07:1940::,2a07:1947:ffff:ffff:ffff:ffff:ffff:ffff,IT
+2a07:1980::,2a07:1987:ffff:ffff:ffff:ffff:ffff:ffff,IL
+2a07:19c0::,2a07:19c7:ffff:ffff:ffff:ffff:ffff:ffff,FR
+2a07:1a00::,2a07:1a07:ffff:ffff:ffff:ffff:ffff:ffff,ES
+2a07:1a40::,2a07:1a47:ffff:ffff:ffff:ffff:ffff:ffff,PL
+2a07:1a80::,2a07:1a80:6fff:ffff:ffff:ffff:ffff:ffff,SE
+2a07:1a80:7000::,2a07:1a80:70ff:ffff:ffff:ffff:ffff:ffff,AT
+2a07:1a80:7100::,2a07:1a87:ffff:ffff:ffff:ffff:ffff:ffff,SE
+2a07:1ac0::,2a07:1ac7:ffff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:1b00::,2a07:1b07:ffff:ffff:ffff:ffff:ffff:ffff,GB
+2a07:1b40::,2a07:1b47:ffff:ffff:ffff:ffff:ffff:ffff,GB
+2a07:1b80::,2a07:1b87:ffff:ffff:ffff:ffff:ffff:ffff,AT
+2a07:1bc0::,2a07:1bc7:ffff:ffff:ffff:ffff:ffff:ffff,PL
+2a07:1c00::,2a07:1c07:ffff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:1c40::,2a07:1c44:3ff:ffff:ffff:ffff:ffff:ffff,AT
+2a07:1c44:400::,2a07:1c44:4ff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:1c44:500::,2a07:1c44:609:ffff:ffff:ffff:ffff:ffff,AT
+2a07:1c44:60a::,2a07:1c44:60a:ffff:ffff:ffff:ffff:ffff,DE
+2a07:1c44:60b::,2a07:1c44:619:ffff:ffff:ffff:ffff:ffff,AT
+2a07:1c44:61a::,2a07:1c44:61a:ffff:ffff:ffff:ffff:ffff,KR
+2a07:1c44:61b::,2a07:1c44:67f:ffff:ffff:ffff:ffff:ffff,AT
+2a07:1c44:680::,2a07:1c44:6bf:ffff:ffff:ffff:ffff:ffff,KR
+2a07:1c44:6c0::,2a07:1c44:6ff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:1c44:700::,2a07:1c44:70f:ffff:ffff:ffff:ffff:ffff,US
+2a07:1c44:710::,2a07:1c44:1800:ffff:ffff:ffff:ffff:ffff,AT
+2a07:1c44:1801::,2a07:1c44:1802:ffff:ffff:ffff:ffff:ffff,US
+2a07:1c44:1803::,2a07:1c44:35ff:ffff:ffff:ffff:ffff:ffff,AT
+2a07:1c44:3600::,2a07:1c44:36ff:ffff:ffff:ffff:ffff:ffff,GB
+2a07:1c44:3700::,2a07:1c44:3fff:ffff:ffff:ffff:ffff:ffff,AT
+2a07:1c44:4000::,2a07:1c44:40ff:ffff:ffff:ffff:ffff:ffff,US
+2a07:1c44:4100::,2a07:1c44:42ff:ffff:ffff:ffff:ffff:ffff,AT
+2a07:1c44:4300::,2a07:1c44:43ff:ffff:ffff:ffff:ffff:ffff,HR
+2a07:1c44:4400::,2a07:1c44:4fff:ffff:ffff:ffff:ffff:ffff,AT
+2a07:1c44:5000::,2a07:1c44:51ff:ffff:ffff:ffff:ffff:ffff,US
+2a07:1c44:5200::,2a07:1c47:ffff:ffff:ffff:ffff:ffff:ffff,AT
+2a07:1c80::,2a07:1c87:ffff:ffff:ffff:ffff:ffff:ffff,SE
+2a07:1cc0::,2a07:1cc7:ffff:ffff:ffff:ffff:ffff:ffff,PL
+2a07:1d00::,2a07:1d07:ffff:ffff:ffff:ffff:ffff:ffff,IR
+2a07:1d40::,2a07:1d47:ffff:ffff:ffff:ffff:ffff:ffff,RU
+2a07:1d80::,2a07:1d87:ffff:ffff:ffff:ffff:ffff:ffff,FR
+2a07:1dc0::,2a07:1dc7:ffff:ffff:ffff:ffff:ffff:ffff,PL
+2a07:1e00::,2a07:1e07:ffff:ffff:ffff:ffff:ffff:ffff,KZ
+2a07:1e40::,2a07:1e47:ffff:ffff:ffff:ffff:ffff:ffff,RU
+2a07:1e80::,2a07:1e87:ffff:ffff:ffff:ffff:ffff:ffff,NL
+2a07:1ec0::,2a07:1ec7:ffff:ffff:ffff:ffff:ffff:ffff,IT
+2a07:1f00::,2a07:1f07:ffff:ffff:ffff:ffff:ffff:ffff,CH
+2a07:1f40::,2a07:1f47:ffff:ffff:ffff:ffff:ffff:ffff,CZ
+2a07:1f80::,2a07:1f87:ffff:ffff:ffff:ffff:ffff:ffff,US
+2a07:1fc0::,2a07:1fc7:ffff:ffff:ffff:ffff:ffff:ffff,FR
+2a07:2000::,2a07:2007:ffff:ffff:ffff:ffff:ffff:ffff,IQ
+2a07:2040::,2a07:2047:ffff:ffff:ffff:ffff:ffff:ffff,ES
+2a07:2080::,2a07:2087:ffff:ffff:ffff:ffff:ffff:ffff,NL
+2a07:20c0::,2a07:20c7:ffff:ffff:ffff:ffff:ffff:ffff,CZ
+2a07:2100::,2a07:2107:ffff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:2140::,2a07:2147:ffff:ffff:ffff:ffff:ffff:ffff,CH
+2a07:2180::,2a07:2187:ffff:ffff:ffff:ffff:ffff:ffff,SE
+2a07:21c0::,2a07:21c7:ffff:ffff:ffff:ffff:ffff:ffff,TR
+2a07:2200::,2a07:2207:ffff:ffff:ffff:ffff:ffff:ffff,IR
+2a07:2240::,2a07:2247:ffff:ffff:ffff:ffff:ffff:ffff,NO
+2a07:2280::,2a07:2287:ffff:ffff:ffff:ffff:ffff:ffff,RU
+2a07:2300::,2a07:2307:ffff:ffff:ffff:ffff:ffff:ffff,NO
+2a07:2340::,2a07:2347:ffff:ffff:ffff:ffff:ffff:ffff,SE
+2a07:2380::,2a07:2387:ffff:ffff:ffff:ffff:ffff:ffff,ES
+2a07:23c0::,2a07:23c7:ffff:ffff:ffff:ffff:ffff:ffff,GB
+2a07:2400::,2a07:2407:ffff:ffff:ffff:ffff:ffff:ffff,FR
+2a07:2440::,2a07:2447:ffff:ffff:ffff:ffff:ffff:ffff,SE
+2a07:2480::,2a07:2487:ffff:ffff:ffff:ffff:ffff:ffff,IR
+2a07:24c0::,2a07:24c7:ffff:ffff:ffff:ffff:ffff:ffff,GB
+2a07:2500::,2a07:2507:ffff:ffff:ffff:ffff:ffff:ffff,DK
+2a07:2540::,2a07:2547:ffff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:2580::,2a07:2587:ffff:ffff:ffff:ffff:ffff:ffff,IT
+2a07:25c0::,2a07:25c7:ffff:ffff:ffff:ffff:ffff:ffff,GB
+2a07:2600::,2a07:2607:ffff:ffff:ffff:ffff:ffff:ffff,NL
+2a07:2640::,2a07:2647:ffff:ffff:ffff:ffff:ffff:ffff,GB
+2a07:2680::,2a07:2687:ffff:ffff:ffff:ffff:ffff:ffff,DK
+2a07:26c0::,2a07:26c7:ffff:ffff:ffff:ffff:ffff:ffff,BE
+2a07:2700::,2a07:2707:ffff:ffff:ffff:ffff:ffff:ffff,TR
+2a07:2740::,2a07:2747:ffff:ffff:ffff:ffff:ffff:ffff,NL
+2a07:2780::,2a07:2787:ffff:ffff:ffff:ffff:ffff:ffff,GB
+2a07:27c0::,2a07:27c7:ffff:ffff:ffff:ffff:ffff:ffff,NL
+2a07:2800::,2a07:2807:ffff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:2840::,2a07:2847:ffff:ffff:ffff:ffff:ffff:ffff,IT
+2a07:2880::,2a07:2887:ffff:ffff:ffff:ffff:ffff:ffff,NL
+2a07:28c0::,2a07:28c7:ffff:ffff:ffff:ffff:ffff:ffff,FR
+2a07:2900::,2a07:291f:ffff:ffff:ffff:ffff:ffff:ffff,CH
+2a07:2a00::,2a07:2a07:ffff:ffff:ffff:ffff:ffff:ffff,ES
+2a07:2a40::,2a07:2a47:ffff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:2a80::,2a07:2a87:ffff:ffff:ffff:ffff:ffff:ffff,SE
+2a07:2ac0::,2a07:2ac7:ffff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:2b00::,2a07:2b07:ffff:ffff:ffff:ffff:ffff:ffff,FR
+2a07:2b40::,2a07:2b47:ffff:ffff:ffff:ffff:ffff:ffff,NO
+2a07:2b80::,2a07:2b87:ffff:ffff:ffff:ffff:ffff:ffff,NL
+2a07:2bc0::,2a07:2bc7:ffff:ffff:ffff:ffff:ffff:ffff,ES
+2a07:2c00::,2a07:2c07:ffff:ffff:ffff:ffff:ffff:ffff,NL
+2a07:2c40::,2a07:2c47:ffff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:2c80::,2a07:2c87:ffff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:2cc0::,2a07:2cc7:ffff:ffff:ffff:ffff:ffff:ffff,IT
+2a07:2d00::,2a07:2d07:ffff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:2d40::,2a07:2d47:ffff:ffff:ffff:ffff:ffff:ffff,CH
+2a07:2d80::,2a07:2d87:ffff:ffff:ffff:ffff:ffff:ffff,FR
+2a07:2dc0::,2a07:2dc7:ffff:ffff:ffff:ffff:ffff:ffff,FI
+2a07:2e00::,2a07:2e07:ffff:ffff:ffff:ffff:ffff:ffff,CH
+2a07:2e40::,2a07:2e47:ffff:ffff:ffff:ffff:ffff:ffff,FR
+2a07:2e80::,2a07:2e87:ffff:ffff:ffff:ffff:ffff:ffff,IT
+2a07:2ec0::,2a07:2ec7:ffff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:2f00::,2a07:2f07:ffff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:2f40::,2a07:2f47:ffff:ffff:ffff:ffff:ffff:ffff,UA
+2a07:2f80::,2a07:2f87:ffff:ffff:ffff:ffff:ffff:ffff,NO
+2a07:2fc0::,2a07:2fc7:ffff:ffff:ffff:ffff:ffff:ffff,RU
+2a07:3000::,2a07:3007:ffff:ffff:ffff:ffff:ffff:ffff,ES
+2a07:3040::,2a07:3047:ffff:ffff:ffff:ffff:ffff:ffff,PL
+2a07:3080::,2a07:3087:ffff:ffff:ffff:ffff:ffff:ffff,RU
+2a07:30c0::,2a07:30c7:ffff:ffff:ffff:ffff:ffff:ffff,CZ
+2a07:3100::,2a07:3107:ffff:ffff:ffff:ffff:ffff:ffff,RO
+2a07:3140::,2a07:3147:ffff:ffff:ffff:ffff:ffff:ffff,BE
+2a07:3180::,2a07:3187:ffff:ffff:ffff:ffff:ffff:ffff,NO
+2a07:31c0::,2a07:31c7:ffff:ffff:ffff:ffff:ffff:ffff,NL
+2a07:3200::,2a07:3207:ffff:ffff:ffff:ffff:ffff:ffff,NL
+2a07:3240::,2a07:3247:ffff:ffff:ffff:ffff:ffff:ffff,NO
+2a07:3280::,2a07:3287:ffff:ffff:ffff:ffff:ffff:ffff,NO
+2a07:32c0::,2a07:32c7:ffff:ffff:ffff:ffff:ffff:ffff,NO
+2a07:3300::,2a07:3307:ffff:ffff:ffff:ffff:ffff:ffff,TR
+2a07:3340::,2a07:3347:ffff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:3380::,2a07:3387:ffff:ffff:ffff:ffff:ffff:ffff,NL
+2a07:33c0::,2a07:33c7:ffff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:3400::,2a07:3407:ffff:ffff:ffff:ffff:ffff:ffff,UA
+2a07:3440::,2a07:3447:ffff:ffff:ffff:ffff:ffff:ffff,NL
+2a07:3480::,2a07:3487:ffff:ffff:ffff:ffff:ffff:ffff,RU
+2a07:3500::,2a07:3507:ffff:ffff:ffff:ffff:ffff:ffff,NL
+2a07:3540::,2a07:3547:ffff:ffff:ffff:ffff:ffff:ffff,IT
+2a07:3580::,2a07:3587:ffff:ffff:ffff:ffff:ffff:ffff,ES
+2a07:35c0::,2a07:35c7:ffff:ffff:ffff:ffff:ffff:ffff,UA
+2a07:3600::,2a07:3607:ffff:ffff:ffff:ffff:ffff:ffff,GB
+2a07:3640::,2a07:3647:ffff:ffff:ffff:ffff:ffff:ffff,NL
+2a07:3680::,2a07:3687:ffff:ffff:ffff:ffff:ffff:ffff,LB
+2a07:36c0::,2a07:36c7:ffff:ffff:ffff:ffff:ffff:ffff,NL
+2a07:3700::,2a07:3707:ffff:ffff:ffff:ffff:ffff:ffff,RU
+2a07:3740::,2a07:3747:ffff:ffff:ffff:ffff:ffff:ffff,AT
+2a07:3780::,2a07:3787:ffff:ffff:ffff:ffff:ffff:ffff,IS
+2a07:37c0::,2a07:37c7:ffff:ffff:ffff:ffff:ffff:ffff,BE
+2a07:3800::,2a07:3807:ffff:ffff:ffff:ffff:ffff:ffff,FR
+2a07:3840::,2a07:3847:ffff:ffff:ffff:ffff:ffff:ffff,HR
+2a07:3880::,2a07:3887:ffff:ffff:ffff:ffff:ffff:ffff,NO
+2a07:38c0::,2a07:38c7:ffff:ffff:ffff:ffff:ffff:ffff,GB
+2a07:3900::,2a07:3907:ffff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:3940::,2a07:3947:ffff:ffff:ffff:ffff:ffff:ffff,FR
+2a07:3980::,2a07:3987:ffff:ffff:ffff:ffff:ffff:ffff,NL
+2a07:39c0::,2a07:39c7:ffff:ffff:ffff:ffff:ffff:ffff,DK
+2a07:3a00::,2a07:3a07:ffff:ffff:ffff:ffff:ffff:ffff,ES
+2a07:3a80::,2a07:3a87:ffff:ffff:ffff:ffff:ffff:ffff,FR
+2a07:3ac0::,2a07:3ac7:ffff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:3b00::,2a07:3b07:ffff:ffff:ffff:ffff:ffff:ffff,FR
+2a07:3b40::,2a07:3b47:ffff:ffff:ffff:ffff:ffff:ffff,RU
+2a07:3b80::,2a07:3b87:ffff:ffff:ffff:ffff:ffff:ffff,GI
+2a07:3bc0::,2a07:3bc7:ffff:ffff:ffff:ffff:ffff:ffff,NL
+2a07:3c00::,2a07:3c07:ffff:ffff:ffff:ffff:ffff:ffff,NL
+2a07:3c40::,2a07:3c47:ffff:ffff:ffff:ffff:ffff:ffff,DE
+2a07:3c80::,2a07:3c87:ffff:ffff:ffff:ffff:ffff:ffff,RU
+2a07:3d00::,2a07:3d07:ffff:ffff:ffff:ffff:ffff:ffff,IT
+2a07:3d80::,2a07:3d87:ffff:ffff:ffff:ffff:ffff:ffff,CZ
+2a07:3dc0::,2a07:3dc7:ffff:ffff:ffff:ffff:ffff:ffff,DK
+2a07:3e00::,2a07:3e07:ffff:ffff:ffff:ffff:ffff:ffff,CH
+2a07:3e40::,2a07:3e47:ffff:ffff:ffff:ffff:ffff:ffff,RU
+2a07:3e80::,2a07:3e87:ffff:ffff:ffff:ffff:ffff:ffff,NL
+2a07:3ec0::,2a07:3ec7:ffff:ffff:ffff:ffff:ffff:ffff,GB
+2a07:3f00::,2a07:3f07:ffff:ffff:ffff:ffff:ffff:ffff,FR
+2a07:3f40::,2a07:3f47:ffff:ffff:ffff:ffff:ffff:ffff,IE
+2a07:3f80::,2a07:3f87:ffff:ffff:ffff:ffff:ffff:ffff,SK
+2a07:3fc0::,2a07:3fc7:ffff:ffff:ffff:ffff:ffff:ffff,SE
+2a07:4000::,2a07:4007:ffff:ffff:ffff:ffff:ffff:ffff,NO
+2a07:4040::,2a07:4047:ffff:ffff:ffff:ffff:ffff:ffff,SE
+2a07:4080::,2a07:4087:ffff:ffff:ffff:ffff:ffff:ffff,AT
+2a07:40c0::,2a07:40c7:ffff:ffff:ffff:ffff:ffff:ffff,IL
+2a07:4100::,2a07:4107:ffff:ffff:ffff:ffff:ffff:ffff,FR
+2a07:4140::,2a07:4147:ffff:ffff:ffff:ffff:ffff:ffff,MD
+2a07:4180::,2a07:4187:ffff:ffff:ffff:ffff:ffff:ffff,GB
+2a07:41c0::,2a07:41c7:ffff:ffff:ffff:ffff:ffff:ffff,RU
+2a07:4200::,2a07:4207:ffff:ffff:ffff:ffff:ffff:ffff,FR
+2a07:4240::,2a07:4247:ffff:ffff:ffff:ffff:ffff:ffff,RU
+2a07:4280::,2a07:4287:ffff:ffff:ffff:ffff:ffff:ffff,GB
+2a07:42c0::,2a07:42c7:ffff:ffff:ffff:ffff:ffff:ffff,DK
+2a07:4340::,2a07:4347:ffff:ffff:ffff:ffff:ffff:ffff,AE
+2a0c:af80::,2a0c:af87:ffff:ffff:ffff:ffff:ffff:ffff,GB
+2c0f:f950::,2c0f:f950:ffff:ffff:ffff:ffff:ffff:ffff,SS
+2c0f:f958::,2c0f:f958:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:f960::,2c0f:f960:ffff:ffff:ffff:ffff:ffff:ffff,TZ
+2c0f:f968::,2c0f:f968:ffff:ffff:ffff:ffff:ffff:ffff,MZ
+2c0f:f970::,2c0f:f970:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:f978::,2c0f:f978:ffff:ffff:ffff:ffff:ffff:ffff,CD
+2c0f:f980::,2c0f:f980:ffff:ffff:ffff:ffff:ffff:ffff,NA
+2c0f:f988::,2c0f:f988:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:f990::,2c0f:f990:ffff:ffff:ffff:ffff:ffff:ffff,GN
+2c0f:f998::,2c0f:f998:ffff:ffff:ffff:ffff:ffff:ffff,MR
+2c0f:f9a0::,2c0f:f9a0:ffff:ffff:ffff:ffff:ffff:ffff,MW
+2c0f:f9a8::,2c0f:f9a8:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:f9b0::,2c0f:f9b0:ffff:ffff:ffff:ffff:ffff:ffff,GA
+2c0f:f9b8::,2c0f:f9b8:1:ffff:ffff:ffff:ffff:ffff,MU
+2c0f:f9b8:2::,2c0f:f9b8:2:ffff:ffff:ffff:ffff:ffff,US
+2c0f:f9b8:3::,2c0f:f9b8:ffff:ffff:ffff:ffff:ffff:ffff,MU
+2c0f:f9c0::,2c0f:f9c0:ffff:ffff:ffff:ffff:ffff:ffff,BW
+2c0f:f9c8::,2c0f:f9c8:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:f9d0::,2c0f:f9d0:ffff:ffff:ffff:ffff:ffff:ffff,TZ
+2c0f:f9d8::,2c0f:f9d8:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:f9e0::,2c0f:f9e0:ffff:ffff:ffff:ffff:ffff:ffff,NG
+2c0f:f9e8::,2c0f:f9e8:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:f9f0::,2c0f:f9f0:ffff:ffff:ffff:ffff:ffff:ffff,MG
+2c0f:f9f8::,2c0f:f9f8:ffff:ffff:ffff:ffff:ffff:ffff,BJ
+2c0f:fa00::,2c0f:fa00:ffff:ffff:ffff:ffff:ffff:ffff,GH
+2c0f:fa08::,2c0f:fa08:ffff:ffff:ffff:ffff:ffff:ffff,CD
+2c0f:fa10::,2c0f:fa10:fffc:ffff:ffff:ffff:ffff:ffff,MU
+2c0f:fa10:fffd::,2c0f:fa10:fffd:7fff:ffff:ffff:ffff:ffff,ZM
+2c0f:fa10:fffd:8000::,2c0f:fa10:ffff:ffff:ffff:ffff:ffff:ffff,MU
+2c0f:fa18::,2c0f:fa18:ffff:ffff:ffff:ffff:ffff:ffff,MA
+2c0f:fa20::,2c0f:fa20:ffff:ffff:ffff:ffff:ffff:ffff,SS
+2c0f:fa28::,2c0f:fa28:ffff:ffff:ffff:ffff:ffff:ffff,MG
+2c0f:fa38::,2c0f:fa38:ffff:ffff:ffff:ffff:ffff:ffff,AO
+2c0f:fa40::,2c0f:fa40:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fa48::,2c0f:fa48:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fa58::,2c0f:fa58:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fa60::,2c0f:fa60:ffff:ffff:ffff:ffff:ffff:ffff,AO
+2c0f:fa68::,2c0f:fa68:ffff:ffff:ffff:ffff:ffff:ffff,GH
+2c0f:fa70::,2c0f:fa70:ffff:ffff:ffff:ffff:ffff:ffff,AO
+2c0f:fa78::,2c0f:fa78:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fa80::,2c0f:fa80:ffff:ffff:ffff:ffff:ffff:ffff,AO
+2c0f:fa88::,2c0f:fa88:ffff:ffff:ffff:ffff:ffff:ffff,ST
+2c0f:fa90::,2c0f:fa90:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fa98::,2c0f:fa98:ffff:ffff:ffff:ffff:ffff:ffff,ZW
+2c0f:faa0::,2c0f:faa7:ffff:ffff:ffff:ffff:ffff:ffff,SD
+2c0f:fab0::,2c0f:fabf:ffff:ffff:ffff:ffff:ffff:ffff,TN
+2c0f:fac0::,2c0f:fac0:ffff:ffff:ffff:ffff:ffff:ffff,MW
+2c0f:fac8::,2c0f:fac8:ffff:ffff:ffff:ffff:ffff:ffff,BW
+2c0f:fad8::,2c0f:fad8:ffff:ffff:ffff:ffff:ffff:ffff,CM
+2c0f:fae0::,2c0f:fae0:ffff:ffff:ffff:ffff:ffff:ffff,CM
+2c0f:fae8::,2c0f:fae8:ffff:ffff:ffff:ffff:ffff:ffff,KE
+2c0f:faf0::,2c0f:faf0:ffff:ffff:ffff:ffff:ffff:ffff,AO
+2c0f:faf8::,2c0f:faf8:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fb00::,2c0f:fb00:ffff:ffff:ffff:ffff:ffff:ffff,UG
+2c0f:fb08::,2c0f:fb08:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fb10::,2c0f:fb10:ffff:ffff:ffff:ffff:ffff:ffff,LY
+2c0f:fb18::,2c0f:fb18:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fb20::,2c0f:fb20:ffff:ffff:ffff:ffff:ffff:ffff,MA
+2c0f:fb30::,2c0f:fb30:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fb38::,2c0f:fb38:ffff:ffff:ffff:ffff:ffff:ffff,SO
+2c0f:fb40::,2c0f:fb40:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fb48::,2c0f:fb48:ffff:ffff:ffff:ffff:ffff:ffff,MZ
+2c0f:fb50::,2c0f:fb50:ffff:ffff:ffff:ffff:ffff:ffff,KE
+2c0f:fb58::,2c0f:fb58:ffff:ffff:ffff:ffff:ffff:ffff,AO
+2c0f:fb60::,2c0f:fb60:ffff:ffff:ffff:ffff:ffff:ffff,KE
+2c0f:fb68::,2c0f:fb68:ffff:ffff:ffff:ffff:ffff:ffff,LS
+2c0f:fb70::,2c0f:fb70:ffff:ffff:ffff:ffff:ffff:ffff,AO
+2c0f:fb78::,2c0f:fb78:ffff:ffff:ffff:ffff:ffff:ffff,TZ
+2c0f:fb80::,2c0f:fb80:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fb88::,2c0f:fb88:ffff:ffff:ffff:ffff:ffff:ffff,TZ
+2c0f:fb90::,2c0f:fb90:ffff:ffff:ffff:ffff:ffff:ffff,MZ
+2c0f:fb98::,2c0f:fb98:ffff:ffff:ffff:ffff:ffff:ffff,NG
+2c0f:fba0::,2c0f:fba0:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fba8::,2c0f:fba8:ffff:ffff:ffff:ffff:ffff:ffff,NG
+2c0f:fbb0::,2c0f:fbb0:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fbb8::,2c0f:fbb8:ffff:ffff:ffff:ffff:ffff:ffff,TZ
+2c0f:fbc0::,2c0f:fbc0:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fbc8::,2c0f:fbc8:ffff:ffff:ffff:ffff:ffff:ffff,UG
+2c0f:fbd0::,2c0f:fbd0:ffff:ffff:ffff:ffff:ffff:ffff,GN
+2c0f:fbd8::,2c0f:fbd8:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fbe0::,2c0f:fc1f:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fc40::,2c0f:fc40:ffff:ffff:ffff:ffff:ffff:ffff,EG
+2c0f:fc48::,2c0f:fc48:ffff:ffff:ffff:ffff:ffff:ffff,MW
+2c0f:fc58::,2c0f:fc58:ffff:ffff:ffff:ffff:ffff:ffff,MW
+2c0f:fc60::,2c0f:fc61:ffff:ffff:ffff:ffff:ffff:ffff,NG
+2c0f:fc68::,2c0f:fc68:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fc70::,2c0f:fc70:ffff:ffff:ffff:ffff:ffff:ffff,KE
+2c0f:fc80::,2c0f:fc80:ffff:ffff:ffff:ffff:ffff:ffff,KE
+2c0f:fc88::,2c0f:fc89:ffff:ffff:ffff:ffff:ffff:ffff,EG
+2c0f:fc90::,2c0f:fc90:ffff:ffff:ffff:ffff:ffff:ffff,NG
+2c0f:fc98::,2c0f:fc98:ffff:ffff:ffff:ffff:ffff:ffff,NG
+2c0f:fca0::,2c0f:fca0:ffff:ffff:ffff:ffff:ffff:ffff,GH
+2c0f:fca8::,2c0f:fca8:ffff:ffff:ffff:ffff:ffff:ffff,GH
+2c0f:fcb0::,2c0f:fcb0:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fcb8::,2c0f:fcb8:ffff:ffff:ffff:ffff:ffff:ffff,GM
+2c0f:fcc8::,2c0f:fcc8:ffff:ffff:ffff:ffff:ffff:ffff,ZM
+2c0f:fcd0::,2c0f:fcd0:ffff:ffff:ffff:ffff:ffff:ffff,ZM
+2c0f:fcd8::,2c0f:fcd8:ffff:ffff:ffff:ffff:ffff:ffff,SO
+2c0f:fce0::,2c0f:fce0:ffff:ffff:ffff:ffff:ffff:ffff,KE
+2c0f:fce8::,2c0f:fce8:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fcf0::,2c0f:fcf0:ffff:ffff:ffff:ffff:ffff:ffff,TZ
+2c0f:fcf8::,2c0f:fcf8:ffff:ffff:ffff:ffff:ffff:ffff,GH
+2c0f:fd00::,2c0f:fd00:ffff:ffff:ffff:ffff:ffff:ffff,LS
+2c0f:fd08::,2c0f:fd08:ffff:ffff:ffff:ffff:ffff:ffff,GM
+2c0f:fd10::,2c0f:fd10:ffff:ffff:ffff:ffff:ffff:ffff,TZ
+2c0f:fd18::,2c0f:fd18:ffff:ffff:ffff:ffff:ffff:ffff,SC
+2c0f:fd20::,2c0f:fd20:ffff:ffff:ffff:ffff:ffff:ffff,TZ
+2c0f:fd28::,2c0f:fd28:ffff:ffff:ffff:ffff:ffff:ffff,NG
+2c0f:fd30::,2c0f:fd30:ffff:ffff:ffff:ffff:ffff:ffff,TZ
+2c0f:fd38::,2c0f:fd38:ffff:ffff:ffff:ffff:ffff:ffff,NG
+2c0f:fd40::,2c0f:fd40:ffff:ffff:ffff:ffff:ffff:ffff,ZM
+2c0f:fd48::,2c0f:fd48:ffff:ffff:ffff:ffff:ffff:ffff,ZW
+2c0f:fd50::,2c0f:fd50:ffff:ffff:ffff:ffff:ffff:ffff,MW
+2c0f:fd58::,2c0f:fd58:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fd60::,2c0f:fd60:ffff:ffff:ffff:ffff:ffff:ffff,UG
+2c0f:fd68::,2c0f:fd68:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fd78::,2c0f:fd78:ffff:ffff:ffff:ffff:ffff:ffff,BI
+2c0f:fd80::,2c0f:fd80:ffff:ffff:ffff:ffff:ffff:ffff,BF
+2c0f:fd88::,2c0f:fd88:ffff:ffff:ffff:ffff:ffff:ffff,GH
+2c0f:fd90::,2c0f:fd90:ffff:ffff:ffff:ffff:ffff:ffff,ZM
+2c0f:fd98::,2c0f:fd98:ffff:ffff:ffff:ffff:ffff:ffff,ZM
+2c0f:fda0::,2c0f:fda0:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fda8::,2c0f:fda8:ffff:ffff:ffff:ffff:ffff:ffff,TZ
+2c0f:fdb0::,2c0f:fdb0:ffff:ffff:ffff:ffff:ffff:ffff,TZ
+2c0f:fdb8::,2c0f:fdb8:ffff:ffff:ffff:ffff:ffff:ffff,UG
+2c0f:fdc0::,2c0f:fdc0:ffff:ffff:ffff:ffff:ffff:ffff,TZ
+2c0f:fdc8::,2c0f:fdc8:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fdd0::,2c0f:fdd0:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fdd8::,2c0f:fdd8:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fde8::,2c0f:fde8:ffff:ffff:ffff:ffff:ffff:ffff,MW
+2c0f:fdf0::,2c0f:fdf0:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fdf8::,2c0f:fdf8:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fe08::,2c0f:fe08:ffff:ffff:ffff:ffff:ffff:ffff,KE
+2c0f:fe10::,2c0f:fe10:ffff:ffff:ffff:ffff:ffff:ffff,UG
+2c0f:fe18::,2c0f:fe18:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fe20::,2c0f:fe20:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fe28::,2c0f:fe28:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fe30::,2c0f:fe30:ffff:ffff:ffff:ffff:ffff:ffff,MU
+2c0f:fe38::,2c0f:fe38:ffff:ffff:ffff:ffff:ffff:ffff,KE
+2c0f:fe40::,2c0f:fe40:8001:f:ffff:ffff:ffff:ffff,MU
+2c0f:fe40:8001:10::,2c0f:fe40:8001:10:ffff:ffff:ffff:ffff,KE
+2c0f:fe40:8001:11::,2c0f:fe40:80fe:ffff:ffff:ffff:ffff:ffff,MU
+2c0f:fe40:80ff::,2c0f:fe40:80ff:7fff:ffff:ffff:ffff:ffff,KE
+2c0f:fe40:80ff:8000::,2c0f:fe40:ffff:ffff:ffff:ffff:ffff:ffff,MU
+2c0f:fe50::,2c0f:fe50:ffff:ffff:ffff:ffff:ffff:ffff,DZ
+2c0f:fe58::,2c0f:fe58:ffff:ffff:ffff:ffff:ffff:ffff,LS
+2c0f:fe60::,2c0f:fe60:ffff:ffff:ffff:ffff:ffff:ffff,RW
+2c0f:fe68::,2c0f:fe68:ffff:ffff:ffff:ffff:ffff:ffff,MU
+2c0f:fe70::,2c0f:fe70:ffff:ffff:ffff:ffff:ffff:ffff,UG
+2c0f:fe78::,2c0f:fe78:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fe88::,2c0f:fe88:ffff:ffff:ffff:ffff:ffff:ffff,KE
+2c0f:fe90::,2c0f:fe90:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fe98::,2c0f:fe98:ffff:ffff:ffff:ffff:ffff:ffff,TZ
+2c0f:fea0::,2c0f:fea0:ffff:ffff:ffff:ffff:ffff:ffff,NG
+2c0f:fea8::,2c0f:fea8:ffff:ffff:ffff:ffff:ffff:ffff,NG
+2c0f:feb0::,2c0f:feb0:16:ffff:ffff:ffff:ffff:ffff,MU
+2c0f:feb0:17::,2c0f:feb0:17:7fff:ffff:ffff:ffff:ffff,KE
+2c0f:feb0:17:8000::,2c0f:feb0:1e:ffff:ffff:ffff:ffff:ffff,MU
+2c0f:feb0:1f::,2c0f:feb0:1f:7fff:ffff:ffff:ffff:ffff,ZA
+2c0f:feb0:1f:8000::,2c0f:feb0:1f:ffff:ffff:ffff:ffff:ffff,MU
+2c0f:feb0:20::,2c0f:feb0:20:7fff:ffff:ffff:ffff:ffff,ZA
+2c0f:feb0:20:8000::,2c0f:feb0:2f:7fff:ffff:ffff:ffff:ffff,MU
+2c0f:feb0:2f:8000::,2c0f:feb0:2f:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:feb0:30::,2c0f:feb1:ffff:ffff:ffff:ffff:ffff:ffff,MU
+2c0f:feb8::,2c0f:feb8:ffff:ffff:ffff:ffff:ffff:ffff,ZM
+2c0f:fec0::,2c0f:fec0:ffff:ffff:ffff:ffff:ffff:ffff,UG
+2c0f:fec8::,2c0f:fec8:ffff:ffff:ffff:ffff:ffff:ffff,SD
+2c0f:fed8::,2c0f:fed8:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:fee0::,2c0f:fee0:ffff:ffff:ffff:ffff:ffff:ffff,EG
+2c0f:fef0::,2c0f:fef0:ffff:ffff:ffff:ffff:ffff:ffff,SC
+2c0f:fef8::,2c0f:fef8:ffff:ffff:ffff:ffff:ffff:ffff,KE
+2c0f:ff00::,2c0f:ff00:ffff:ffff:ffff:ffff:ffff:ffff,BW
+2c0f:ff08::,2c0f:ff08:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:ff10::,2c0f:ff10:ffff:ffff:ffff:ffff:ffff:ffff,CD
+2c0f:ff18::,2c0f:ff18:ffff:ffff:ffff:ffff:ffff:ffff,KE
+2c0f:ff20::,2c0f:ff20:ffff:ffff:ffff:ffff:ffff:ffff,NG
+2c0f:ff28::,2c0f:ff28:ffff:ffff:ffff:ffff:ffff:ffff,SD
+2c0f:ff30::,2c0f:ff30:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:ff40::,2c0f:ff80:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:ff88::,2c0f:ff88:ffff:ffff:ffff:ffff:ffff:ffff,NG
+2c0f:ff90::,2c0f:ff90:ffff:ffff:ffff:ffff:ffff:ffff,KE
+2c0f:ff98::,2c0f:ff98:ffff:ffff:ffff:ffff:ffff:ffff,UG
+2c0f:ffa0::,2c0f:ffa0:ffff:ffff:ffff:ffff:ffff:ffff,UG
+2c0f:ffa8::,2c0f:ffa8:ffff:ffff:ffff:ffff:ffff:ffff,LS
+2c0f:ffb0::,2c0f:ffb0:ffff:ffff:ffff:ffff:ffff:ffff,NG
+2c0f:ffb8::,2c0f:ffb8:ffff:ffff:ffff:ffff:ffff:ffff,SD
+2c0f:ffc0::,2c0f:ffc0:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:ffc8::,2c0f:ffc8:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:ffd0::,2c0f:ffd0:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:ffd8::,2c0f:ffd8:ffff:ffff:ffff:ffff:ffff:ffff,ZA
+2c0f:ffe8::,2c0f:ffe8:ffff:ffff:ffff:ffff:ffff:ffff,NG
+2c0f:fff0::,2c0f:fff0:ffff:ffff:ffff:ffff:ffff:ffff,NG
[View Less]
1
0
commit 72e54bdc2e277e7189cffffc9481bd57dfd1401d
Author: Cecylia Bocovich <cohosh(a)torproject.org>
Date: Thu May 9 18:13:48 2019 -0400
Remove geoip metrics from /debug
For now we can just log the proxy geoip statistics locally
---
broker/broker.go | 1 -
1 file changed, 1 deletion(-)
diff --git a/broker/broker.go b/broker/broker.go
index faa6f4a..4db1511 100644
--- a/broker/broker.go
+++ b/broker/broker.go
@@ -237,7 +237,6 @@ func debugHandler(ctx *BrokerContext, w http.…
[View More]ResponseWriter, r *http.Request) {
s += fmt.Sprintf("\nsnowflake %d: %s", snowflake.index, snowflake.id)
}
s += fmt.Sprintf("\n\nroundtrip avg: %d", ctx.metrics.clientRoundtripEstimate)
- s += fmt.Sprintf("\n\nsnowflake country stats: %s", ctx.metrics.countryStats.Display())
w.Write([]byte(s))
}
[View Less]
1
0
commit 6b002c5f22e0e794c086d6655afe72dc3cd7bc43
Merge: 1133e01 ba4fe1a
Author: Cecylia Bocovich <cohosh(a)torproject.org>
Date: Wed May 15 11:07:33 2019 -0400
Merge branch 'geoip_squashed'
broker/broker.go | 73 ++-
broker/geoip.go | 240 ++++++++
broker/metrics.go | 95 ++-
broker/snowflake-broker_test.go | 103 ++++
broker/test_geoip | 1236 +++++++++++++++++++++++++++++++++++++++
broker/test_geoip6 | …
[View More] 693 ++++++++++++++++++++++
6 files changed, 2434 insertions(+), 6 deletions(-)
diff --cc broker/broker.go
index a18ca1b,361040a..ae27a47
--- a/broker/broker.go
+++ b/broker/broker.go
@@@ -13,12 -13,14 +13,15 @@@ import
"io"
"io/ioutil"
"log"
+ "net"
"net/http"
"os"
+ "os/signal"
"strings"
+ "syscall"
"time"
+ "git.torproject.org/pluggable-transports/snowflake.git/common/safelog"
"golang.org/x/crypto/acme/autocert"
)
@@@ -206,7 -218,17 +219,17 @@@ func proxyAnswers(ctx *BrokerContext,
w.WriteHeader(http.StatusBadRequest)
return
}
+
+ // Get proxy country stats
+ remoteIP, _, err := net.SplitHostPort(r.RemoteAddr)
+ if err != nil {
+ log.Println("Error processing proxy IP: ", err.Error())
+ } else {
+
+ ctx.metrics.UpdateCountryStats(remoteIP)
+ }
+
- log.Println("Received answer: ", body)
+ log.Println("Received answer.")
snowflake.answerChannel <- body
}
@@@ -228,20 -250,24 +251,30 @@@ func main()
var acmeEmail string
var acmeHostnamesCommas string
var addr string
+ var geoipDatabase string
+ var geoip6Database string
var disableTLS bool
+ var certFilename, keyFilename string
+ var disableGeoip bool
+ var metricsFilename string
flag.StringVar(&acmeEmail, "acme-email", "", "optional contact email for Let's Encrypt notifications")
flag.StringVar(&acmeHostnamesCommas, "acme-hostnames", "", "comma-separated hostnames for TLS certificate")
+ flag.StringVar(&certFilename, "cert", "", "TLS certificate file")
+ flag.StringVar(&keyFilename, "key", "", "TLS private key file")
flag.StringVar(&addr, "addr", ":443", "address to listen on")
+ flag.StringVar(&geoipDatabase, "geoipdb", "/usr/share/tor/geoip", "path to correctly formatted geoip database mapping IPv4 address ranges to country codes")
+ flag.StringVar(&geoip6Database, "geoip6db", "/usr/share/tor/geoip6", "path to correctly formatted geoip database mapping IPv6 address ranges to country codes")
flag.BoolVar(&disableTLS, "disable-tls", false, "don't use HTTPS")
+ flag.BoolVar(&disableGeoip, "disable-geoip", false, "don't use geoip for stats collection")
+ flag.StringVar(&metricsFilename, "metrics-log", "", "path to metrics logging output")
flag.Parse()
- var metricsFile io.Writer = os.Stdout
+ var err error
++ var metricsFile io.Writer = os.Stdout
+ var logOutput io.Writer = os.Stderr
+ //We want to send the log output through our scrubber first
+ log.SetOutput(&safelog.LogScrubber{Output: logOutput})
log.SetFlags(log.LstdFlags | log.LUTC)
@@@ -261,13 -305,20 +312,27 @@@
Addr: addr,
}
+ sigChan := make(chan os.Signal, 1)
+ signal.Notify(sigChan, syscall.SIGHUP)
+
+ // go routine to handle a SIGHUP signal to allow the broker operator to send
+ // a SIGHUP signal when the geoip database files are updated, without requiring
+ // a restart of the broker
+ go func() {
+ for {
+ signal := <-sigChan
+ log.Println("Received signal:", signal, ". Reloading geoip databases.")
+ ctx.metrics.LoadGeoipDatabases(geoipDatabase, geoip6Database)
+ }
+ }()
+
+ // Handle the various ways of setting up TLS. The legal configurations
+ // are:
+ // --acme-hostnames (with optional --acme-email)
+ // --cert and --key together
+ // --disable-tls
+ // The outputs of this block of code are the disableTLS,
+ // needHTTP01Listener, certManager, and getCertificate variables.
if acmeHostnamesCommas != "" {
acmeHostnames := strings.Split(acmeHostnamesCommas, ",")
log.Printf("ACME hostnames: %q", acmeHostnames)
[View Less]
1
0