From 464dc43cc476d47d69b11cf13a72432ea77bd62e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=96=87=E5=9D=9B?= Date: Tue, 23 May 2023 03:23:39 +0000 Subject: [PATCH] fix group_exclude logic miss & add some corner case --- scanner/adapter_hs/adapter_hs.cpp | 30 +- src/maat_api.c | 31 +- src/maat_bool_plugin.c | 34 +- src/maat_compile.c | 95 +- src/maat_expr.c | 17 +- src/maat_flag.c | 1 - src/maat_fqdn_plugin.c | 55 +- src/maat_garbage_collection.c | 21 +- src/maat_group.c | 129 ++- src/maat_interval.c | 1 - src/maat_ip.c | 1 - src/maat_ip_plugin.c | 87 +- src/maat_kv.c | 15 +- src/maat_plugin.c | 27 +- src/maat_redis_monitor.c | 18 +- src/maat_rule.c | 2 +- src/maat_stat.c | 5 +- test/CMakeLists.txt | 2 + test/group_exclude/group_exclude_L4.conf | 136 +++ test/group_exclude/group_exclude_L4.png | Bin 0 -> 76281 bytes test/group_exclude/group_exclude_exceed.conf | 76 ++ test/group_exclude/group_exclude_exceed.png | Bin 0 -> 47141 bytes test/group_exclude/group_exclude_gtest.cpp | 303 ++++- test/maat_framework_gtest.cpp | 796 +++++++++---- test/maat_framework_perf_gtest.cpp | 758 ++++++++++++- test/maat_json.json | 106 ++ test/tsg_table_info.conf | 15 + test/tsgrule/TSG_IP_LOCATION_BUILT_IN.head_1k | 1001 +++++++++++++++++ .../full_config_index.00000000000000106967 | 2 + 29 files changed, 3317 insertions(+), 447 deletions(-) create mode 100644 test/group_exclude/group_exclude_L4.conf create mode 100644 test/group_exclude/group_exclude_L4.png create mode 100644 test/group_exclude/group_exclude_exceed.conf create mode 100644 test/group_exclude/group_exclude_exceed.png create mode 100644 test/tsg_table_info.conf create mode 100644 test/tsgrule/TSG_IP_LOCATION_BUILT_IN.head_1k create mode 100644 test/tsgrule/full/index/full_config_index.00000000000000106967 diff --git a/scanner/adapter_hs/adapter_hs.cpp b/scanner/adapter_hs/adapter_hs.cpp index ec2a5b9..987b106 100644 --- a/scanner/adapter_hs/adapter_hs.cpp +++ b/scanner/adapter_hs/adapter_hs.cpp @@ -223,9 +223,18 @@ void adpt_hs_compile_data_free(struct adpt_hs_compile_data *hs_cd) FREE(hs_cd->patterns[i]); } - FREE(hs_cd->patterns); + FREE(hs_cd->patterns); + } + + if (hs_cd->pattern_lens != NULL) { FREE(hs_cd->pattern_lens); + } + + if (hs_cd->ids != NULL) { FREE(hs_cd->ids); + } + + if (hs_cd->flags != NULL) { FREE(hs_cd->flags); } @@ -290,8 +299,6 @@ struct bool_expr *bool_exprs_new(struct expr_rule *rules, size_t n_rule, struct bool_exprs[i].items[j].item_id = pattern_index++; bool_exprs[i].items[j].not_flag = 0; - // printf("item_id:%llu, pat:%s pat_len:%zu\n", - // bool_exprs[i].items[j].item_id, exprs[i].patterns[j].pat, exprs[i].patterns[j].pat_len); } bool_exprs[i].expr_id = rules[i].expr_id; @@ -405,21 +412,6 @@ struct adapter_hs *adapter_hs_new(size_t n_worker_thread, } hs_instance->n_patterns = pattern_cnt; - //mytest - // for (size_t i = 0; i < n_expr; i++) { - // { - // printf(" exprs[%zu] expr_id:%llu, item_num:%zu\n", - // i, bool_exprs[i].expr_id, bool_exprs[i].item_num); - // printf("item_id: "); - // for (size_t j = 0; j < bool_exprs[i].item_num; j++) - // { - // printf("%llu ", bool_exprs[i].items[j].item_id); - // } - // } - // printf("\n"); - // } - - /* create bool matcher */ size_t mem_size = 0; int hs_ret = 0; @@ -502,7 +494,6 @@ void adapter_hs_free(struct adapter_hs *hs_instance) } FREE(hs_instance->hs_rt->literal_scratches); - hs_instance->hs_rt->literal_scratches = NULL; } @@ -515,7 +506,6 @@ void adapter_hs_free(struct adapter_hs *hs_instance) } FREE(hs_instance->hs_rt->regex_scratches); - hs_instance->hs_rt->regex_scratches = NULL; } if (hs_instance->hs_rt->bm != NULL) { diff --git a/src/maat_api.c b/src/maat_api.c index 92e2d12..44531ee 100644 --- a/src/maat_api.c +++ b/src/maat_api.c @@ -283,7 +283,6 @@ void _maat_free(struct maat *maat_instance) if (maat_instance->opts.accept_tags != NULL) { FREE(maat_instance->opts.accept_tags); - maat_instance->opts.accept_tags = NULL; } pthread_mutex_destroy(&(maat_instance->background_update_mutex)); @@ -529,20 +528,21 @@ int generic_plugin_table_set_ex_schema(struct table_manager *tbl_mgr, int table_ enum table_type table_type = table_manager_get_table_type(tbl_mgr, table_id); switch (table_type) { case TABLE_TYPE_PLUGIN: - ret = plugin_table_set_ex_container_schema(schema, table_id, new_func, free_func, dup_func, - free, argl, argp); + ret = plugin_table_set_ex_container_schema(schema, table_id, new_func, free_func, + dup_func, free, argl, argp); break; case TABLE_TYPE_IP_PLUGIN: - ret = ip_plugin_table_set_ex_container_schema(schema, table_id, new_func, free_func, dup_func, - free, argl, argp); + ret = ip_plugin_table_set_ex_container_schema(schema, table_id, new_func, free_func, + dup_func, free, argl, argp); break; case TABLE_TYPE_FQDN_PLUGIN: - ret = fqdn_plugin_table_set_ex_container_schema(schema, table_id, new_func, free_func, dup_func, - (void (*)(void *))fqdn_rule_free, argl, argp); + ret = fqdn_plugin_table_set_ex_container_schema(schema, table_id, new_func, free_func, + dup_func, (void (*)(void *))fqdn_rule_free, + argl, argp); break; case TABLE_TYPE_BOOL_PLUGIN: - ret = bool_plugin_table_set_ex_container_schema(schema, table_id, new_func, free_func, dup_func, - free, argl, argp); + ret = bool_plugin_table_set_ex_container_schema(schema, table_id, new_func, free_func, + dup_func, free, argl, argp); break; default: log_error(logger, MODULE_MAAT_API, @@ -720,18 +720,19 @@ int maat_plugin_table_ex_schema_register(struct maat *maat_instance, int ret = -1; enum table_type table_type = table_manager_get_table_type(maat_instance->tbl_mgr, table_id); if (TABLE_TYPE_COMPILE == table_type) { - ret = compile_table_ex_schema_register(maat_instance, table_id, - new_func, free_func, dup_func, argl, argp); + ret = compile_table_ex_schema_register(maat_instance, table_id, new_func, free_func, + dup_func, argl, argp); } else { - ret = generic_plugin_table_ex_schema_register(maat_instance, table_name, table_id, - new_func, free_func, dup_func, argl, argp); + ret = generic_plugin_table_ex_schema_register(maat_instance, table_name, table_id, new_func, + free_func, dup_func, argl, argp); } pthread_mutex_unlock(&(maat_instance->background_update_mutex)); return ret; } -void *maat_plugin_table_get_ex_data(struct maat *maat_instance, int table_id, const char *key) +void *maat_plugin_table_get_ex_data(struct maat *maat_instance, int table_id, + const char *key) { if (NULL == maat_instance || table_id < 0 || table_id >= MAX_TABLE_NUM @@ -768,7 +769,7 @@ void *maat_plugin_table_get_ex_data(struct maat *maat_instance, int table_id, co } int maat_ip_plugin_table_get_ex_data(struct maat *maat_instance, int table_id, - const struct ip_addr *ip_addr, void **ex_data_array, + const struct ip_addr *ip_addr, void **ex_data_array, size_t n_ex_data) { if (NULL == maat_instance || table_id < 0 || table_id >= MAX_TABLE_NUM diff --git a/src/maat_bool_plugin.c b/src/maat_bool_plugin.c index 9b8d156..95e0834 100644 --- a/src/maat_bool_plugin.c +++ b/src/maat_bool_plugin.c @@ -56,7 +56,7 @@ void *bool_plugin_schema_new(cJSON *json, struct table_manager *tbl_mgr, schema->table_id = item->valueint; } else { log_error(logger, MODULE_BOOL_PLUGIN, - "[%s:%d] table %s has no table_id column", + "[%s:%d] table: <%s> schema has no table_id column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -64,7 +64,7 @@ void *bool_plugin_schema_new(cJSON *json, struct table_manager *tbl_mgr, item = cJSON_GetObjectItem(json, "custom"); if (NULL == item || item->type != cJSON_Object) { log_error(logger, MODULE_BOOL_PLUGIN, - "[%s:%d] table %s has no custom column", + "[%s:%d] table: <%s> schema has no custom column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -74,7 +74,7 @@ void *bool_plugin_schema_new(cJSON *json, struct table_manager *tbl_mgr, schema->item_id_column = custom_item->valueint; } else { log_error(logger, MODULE_BOOL_PLUGIN, - "[%s:%d] table %s has no item_id column", + "[%s:%d] table: <%s> schema has no item_id column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -84,7 +84,7 @@ void *bool_plugin_schema_new(cJSON *json, struct table_manager *tbl_mgr, schema->bool_expr_column = custom_item->valueint; } else { log_error(logger, MODULE_BOOL_PLUGIN, - "[%s:%d] table %s has no bool_expr column", + "[%s:%d] table: <%s> schema has no bool_expr column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -185,7 +185,8 @@ void *bool_plugin_runtime_new(void *bool_plugin_schema, size_t max_thread_num, bool_plugin_rt->ex_data_rt = ex_data_runtime_new(schema->table_id, logger); if (1 == schema->container_schema.set_flag) { - ex_data_runtime_set_ex_container_schema(bool_plugin_rt->ex_data_rt, &(schema->container_schema)); + ex_data_runtime_set_ex_container_schema(bool_plugin_rt->ex_data_rt, + &(schema->container_schema)); } bool_plugin_rt->n_worker_thread = max_thread_num; @@ -254,8 +255,8 @@ int bool_plugin_runtime_update_row(struct bool_plugin_runtime *bool_plugin_rt, return 0; } -int bool_plugin_accept_tag_match(struct bool_plugin_schema *schema, const char *line, - struct log_handle *logger) +int bool_plugin_accept_tag_match(struct bool_plugin_schema *schema, const char *table_name, + const char *line, struct log_handle *logger) { size_t column_offset = 0; size_t column_len = 0; @@ -266,8 +267,8 @@ int bool_plugin_accept_tag_match(struct bool_plugin_schema *schema, const char * &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_BOOL_PLUGIN, - "[%s:%d] bool_plugin table(table_id:%d) has no rule_tag, line:%s", - __FUNCTION__, __LINE__, schema->table_id, line); + "[%s:%d] table: <%s> has no rule_tag in line:%s", + __FUNCTION__, __LINE__, table_name, line); return TAG_MATCH_ERR; } @@ -278,12 +279,15 @@ int bool_plugin_accept_tag_match(struct bool_plugin_schema *schema, const char * FREE(tag_str); if (TAG_MATCH_ERR == ret) { log_error(logger, MODULE_BOOL_PLUGIN, - "[%s:%d] bool_plugin table(table_id:%d) has invalid tag format, line:%s", - __FUNCTION__, __LINE__, schema->table_id, line); + "[%s:%d] table: <%s> has invalid tag format in line:%s", + __FUNCTION__, __LINE__, table_name, line); return TAG_MATCH_ERR; } if (TAG_MATCH_UNMATCHED == ret) { + log_error(logger, MODULE_BOOL_PLUGIN, + "[%s:%d] table: <%s> has unmatched tag in line:%s", + __FUNCTION__, __LINE__, table_name, line); return TAG_MATCH_UNMATCHED; } } @@ -296,7 +300,7 @@ struct bool_expr * bool_plugin_expr_new(const char *line, struct bool_plugin_schema *schema, const char *table_name, struct log_handle *logger) { - int ret = bool_plugin_accept_tag_match(schema, line, logger); + int ret = bool_plugin_accept_tag_match(schema, table_name, line, logger); if (ret == TAG_MATCH_UNMATCHED) { return NULL; } @@ -312,7 +316,7 @@ bool_plugin_expr_new(const char *line, struct bool_plugin_schema *schema, ret = get_column_pos(line, schema->item_id_column, &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_BOOL_PLUGIN, - "[%s:%d] bool_plugin table:%s line:%s has no item_id column", + "[%s:%d] table: <%s> has no item_id in line:%s", __FUNCTION__, __LINE__, table_name, line); goto error; } @@ -321,7 +325,7 @@ bool_plugin_expr_new(const char *line, struct bool_plugin_schema *schema, ret = get_column_pos(line, schema->bool_expr_column, &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_BOOL_PLUGIN, - "[%s:%d] bool_plugin table:%s line:%s has no bool_expr column", + "[%s:%d] table: <%s> has no bool_expr in line:%s", __FUNCTION__, __LINE__, table_name, line); goto error; } @@ -337,7 +341,7 @@ bool_plugin_expr_new(const char *line, struct bool_plugin_schema *schema, n_item++; if (ret != 1 || n_item > MAX_ITEMS_PER_BOOL_EXPR) { log_error(logger, MODULE_BOOL_PLUGIN, - "[%s:%d] bool_plugin table:%s line:%s has invalid format of bool_expr column", + "[%s:%d] table: <%s> has invalid format of bool_expr in line:%s", __FUNCTION__, __LINE__, table_name, line); goto error; } diff --git a/src/maat_compile.c b/src/maat_compile.c index 44b10d5..58ebd81 100644 --- a/src/maat_compile.c +++ b/src/maat_compile.c @@ -118,7 +118,6 @@ struct compile_runtime { struct group2compile_runtime { long long not_flag_group; - long long version; long long rule_num; long long update_err_cnt; struct compile_runtime *ref_compile_rt; @@ -229,7 +228,7 @@ void maat_compile_free(struct maat_compile *compile) clause_state->in_use = 0; } compile->magic = 0; - free(compile); + FREE(compile); } void rcu_maat_compile_free(void *user_ctx, void *data) @@ -328,14 +327,15 @@ void *compile_schema_new(cJSON *json, struct table_manager *tbl_mgr, compile_schema->table_id = item->valueint; } else { log_error(logger, MODULE_COMPILE, - "[%s:%d] table %s has no table_id column", table_name); + "[%s:%d] table: <%s> schema has no table_id column", + __FUNCTION__, __LINE__, table_name); goto error; } item = cJSON_GetObjectItem(json, "custom"); if (item == NULL || item->type != cJSON_Object) { log_error(logger, MODULE_COMPILE, - "[%s:%d] table %s has no custom column", + "[%s:%d] table: <%s> schema has no custom column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -345,7 +345,8 @@ void *compile_schema_new(cJSON *json, struct table_manager *tbl_mgr, compile_schema->compile_id_column = custom_item->valueint; } else { log_error(logger, MODULE_COMPILE, - "[%s:%d] table %s has no compile_id column", table_name); + "[%s:%d] table: <%s> schema has no compile_id column", + __FUNCTION__, __LINE__, table_name); goto error; } @@ -359,7 +360,8 @@ void *compile_schema_new(cJSON *json, struct table_manager *tbl_mgr, compile_schema->declared_clause_num_column = custom_item->valueint; } else { log_error(logger, MODULE_COMPILE, - "[%s:%d] table %s has no clause_num column", table_name); + "[%s:%d] table: <%s> schema has no clause_num column", + __FUNCTION__, __LINE__, table_name); goto error; } @@ -386,7 +388,7 @@ void *group2compile_schema_new(cJSON *json, struct table_manager *tbl_mgr, g2c_schema->table_id = item->valueint; } else { log_error(logger, MODULE_COMPILE, - "[%s:%d] table %s has no table_id column", + "[%s:%d] table: <%s> schema has no table_id column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -396,7 +398,7 @@ void *group2compile_schema_new(cJSON *json, struct table_manager *tbl_mgr, g2c_schema->associated_compile_table_id = item->valueint; } else { log_error(logger, MODULE_COMPILE, - "[%s:%d] table %s has no associated_compile_table_id column", + "[%s:%d] table: <%s> schema has no associated_compile_table_id column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -404,7 +406,7 @@ void *group2compile_schema_new(cJSON *json, struct table_manager *tbl_mgr, item = cJSON_GetObjectItem(json, "custom"); if (item == NULL || item->type != cJSON_Object) { log_error(logger, MODULE_COMPILE, - "[%s:%d] table %s has no custom column", + "[%s:%d] table: <%s> schema has no custom column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -414,7 +416,7 @@ void *group2compile_schema_new(cJSON *json, struct table_manager *tbl_mgr, g2c_schema->group_id_column = custom_item->valueint; } else { log_error(logger, MODULE_COMPILE, - "[%s:%d] table %s has no group_id column", + "[%s:%d] table: <%s> schema has no group_id column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -424,7 +426,7 @@ void *group2compile_schema_new(cJSON *json, struct table_manager *tbl_mgr, g2c_schema->compile_id_column = custom_item->valueint; } else { log_error(logger, MODULE_COMPILE, - "[%s:%d] table %s has no compile_id column", + "[%s:%d] table: <%s> schema has no compile_id column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -434,7 +436,7 @@ void *group2compile_schema_new(cJSON *json, struct table_manager *tbl_mgr, g2c_schema->not_flag_column = custom_item->valueint; } else { log_error(logger, MODULE_COMPILE, - "[%s:%d] table %s has no not_flag column", + "[%s:%d] table: <%s> schema has no not_flag column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -444,7 +446,7 @@ void *group2compile_schema_new(cJSON *json, struct table_manager *tbl_mgr, g2c_schema->vtable_name_column = custom_item->valueint; } else { log_error(logger, MODULE_COMPILE, - "[%s:%d] table %s has no virtual_table_name column", + "[%s:%d] table: <%s> schema has no virtual_table_name column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -454,7 +456,7 @@ void *group2compile_schema_new(cJSON *json, struct table_manager *tbl_mgr, g2c_schema->clause_index_column = custom_item->valueint; } else { log_error(logger, MODULE_COMPILE, - "[%s:%d] table %s has no clause_index column", + "[%s:%d] table: <%s> schema has no clause_index column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -490,7 +492,7 @@ int compile_accept_tag_match(struct compile_schema *schema, const char *line, &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_COMPILE, - "[%s:%d] compile table:%s has no rule_tag in line:%s", + "[%s:%d] table: <%s> has no rule_tag in line:%s", __FUNCTION__, __LINE__, table_name, line); return TAG_MATCH_ERR; } @@ -502,12 +504,15 @@ int compile_accept_tag_match(struct compile_schema *schema, const char *line, FREE(tag_str); if (TAG_MATCH_ERR == ret) { log_error(logger, MODULE_COMPILE, - "[%s:%d] compile table:%s has invalid tag format in line:%s", + "[%s:%d] table: <%s> has invalid tag format in line:%s", __FUNCTION__, __LINE__, table_name, line); return TAG_MATCH_ERR; } if (TAG_MATCH_UNMATCHED == ret) { + log_error(logger, MODULE_COMPILE, + "[%s:%d] table: <%s> has unmatched tag in line:%s", + __FUNCTION__, __LINE__, table_name, line); return TAG_MATCH_UNMATCHED; } } @@ -522,9 +527,6 @@ compile_item_new(const char *line, struct compile_schema *compile_schema, { int ret = compile_accept_tag_match(compile_schema, line, table_name, logger); if (ret == TAG_MATCH_UNMATCHED) { - log_error(logger, MODULE_COMPILE, - "[%s:%d] compile table:%s accept tag unmatched in line:%s", - __FUNCTION__, __LINE__, table_name, line); return NULL; } @@ -536,7 +538,7 @@ compile_item_new(const char *line, struct compile_schema *compile_schema, &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_COMPILE, - "[%s:%d] compile table:%s has no compile_id in line:%s", + "[%s:%d] table: <%s> has no compile_id in line:%s", __FUNCTION__, __LINE__, table_name, line); goto error; } @@ -546,7 +548,7 @@ compile_item_new(const char *line, struct compile_schema *compile_schema, &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_COMPILE, - "[%s:%d] compile table:%s has no clause_num in line:%s", + "[%s:%d] table: <%s> has no clause_num in line:%s", __FUNCTION__, __LINE__, table_name, line); goto error; } @@ -577,7 +579,8 @@ void *compile_runtime_new(void *compile_schema, size_t max_thread_num, struct compile_runtime *compile_rt = ALLOC(struct compile_runtime, 1); - compile_rt->expr_match_buff = ALLOC(struct bool_expr_match, max_thread_num * MAX_SCANNER_HIT_COMPILE_NUM); + compile_rt->expr_match_buff = ALLOC(struct bool_expr_match, + max_thread_num * MAX_SCANNER_HIT_COMPILE_NUM); compile_rt->version = time(NULL); compile_rt->cfg_hash_tbl = rcu_hash_new(rcu_maat_compile_free, NULL); compile_rt->clause_by_literals_hash = NULL; @@ -746,7 +749,7 @@ group2compile_item_new(const char *line, struct group2compile_schema *g2c_schema int ret = get_column_pos(line, g2c_schema->group_id_column, &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_COMPILE, - "[%s:%d] group2compile table:%s line:%s has no group_id", + "[%s:%d] table: <%s> has no group_id in line:%s", __FUNCTION__, __LINE__, table_name, line); goto error; } @@ -755,7 +758,7 @@ group2compile_item_new(const char *line, struct group2compile_schema *g2c_schema ret = get_column_pos(line, g2c_schema->compile_id_column, &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_COMPILE, - "[%s:%d] group2compile table:%s line:%s has no compile_id", + "[%s:%d] table: <%s> has no compile_id in line:%s", __FUNCTION__, __LINE__, table_name, line); goto error; } @@ -764,7 +767,7 @@ group2compile_item_new(const char *line, struct group2compile_schema *g2c_schema ret = get_column_pos(line, g2c_schema->not_flag_column, &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_COMPILE, - "[%s:%d] group2compile table:%s line:%s has no NOT_flag", + "[%s:%d] table: <%s> has no NOT_flag in line:%s ", __FUNCTION__, __LINE__, table_name, line); goto error; } @@ -773,14 +776,14 @@ group2compile_item_new(const char *line, struct group2compile_schema *g2c_schema ret = get_column_pos(line, g2c_schema->vtable_name_column, &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_COMPILE, - "[%s:%d] group2compile table:%s line:%s has no virtual_table_name", + "[%s:%d] table: <%s> has no virtual_table_name in line:%s", __FUNCTION__, __LINE__, table_name, line); goto error; } if (column_len > NAME_MAX) { log_error(logger, MODULE_COMPILE, - "[%s:%d] group2compile table:%s line:%s virtual_table_name length too long", + "[%s:%d] table: <%s> virtual_table_name length too long in line:%s", __FUNCTION__, __LINE__, table_name, line); goto error; } @@ -791,8 +794,8 @@ group2compile_item_new(const char *line, struct group2compile_schema *g2c_schema g2c_item->vtable_id = table_manager_get_table_id(g2c_schema->ref_tbl_mgr, vtable_name); if (g2c_item->vtable_id < 0) { log_error(logger, MODULE_COMPILE, - "[%s:%d] group2compile table:%s line:%s unknown virtual table:%s", - __FUNCTION__, __LINE__, table_name, line, vtable_name); + "[%s:%d] table: <%s> has unknown virtual table:%s in line:%s", + __FUNCTION__, __LINE__, table_name, vtable_name, line); goto error; } } @@ -800,7 +803,7 @@ group2compile_item_new(const char *line, struct group2compile_schema *g2c_schema ret = get_column_pos(line, g2c_schema->clause_index_column, &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_COMPILE, - "[%s:%d] group2compile table:%s line:%s has no clause_index", + "[%s:%d] table: <%s> has no clause_index in line:%s", __FUNCTION__, __LINE__, table_name, line); goto error; } @@ -960,7 +963,7 @@ struct bool_matcher *maat_compile_bool_matcher_new(struct compile_runtime *compi #if 0 struct maat_literal_id *p = NULL; for(p = (struct maat_literal_id *)utarray_front(iter_compile->clause_states[i].ut_literal_ids); p!=NULL; - p=(struct maat_literal_id *)utarray_next(iter_compile->clause_states[i].ut_literal_ids,p)) { + p = (struct maat_literal_id *)utarray_next(iter_compile->clause_states[i].ut_literal_ids, p)) { printf(" compile_rt:%p compile_id:%lld, clause_id:%llu, literal{%lld: %lld}\n", compile_rt, iter_compile->compile_id, iter_compile->clause_states[i].clause_id, p->group_id, p->vtable_id); } @@ -986,8 +989,8 @@ struct bool_matcher *maat_compile_bool_matcher_new(struct compile_runtime *compi // STEP 3, build bool matcher size_t mem_size = 0; if (0 == expr_cnt) { - log_error(compile_rt->logger, MODULE_COMPILE, "[%s:%d] No bool expression to build bool matcher.", - __FUNCTION__, __LINE__); + log_error(compile_rt->logger, MODULE_COMPILE, + "[%s:%d] No bool expression to build bool matcher.", __FUNCTION__, __LINE__); FREE(bool_expr_array); return NULL; } @@ -995,7 +998,8 @@ struct bool_matcher *maat_compile_bool_matcher_new(struct compile_runtime *compi struct bool_matcher *bm = bool_matcher_new(bool_expr_array, expr_cnt, &mem_size); if (bm != NULL) { log_info(compile_rt->logger, MODULE_COMPILE, - "Build bool matcher of %zu expressions with %zu bytes memory.", expr_cnt, mem_size); + "Build bool matcher of %zu expressions with %zu bytes memory.", + expr_cnt, mem_size); } else { log_error(compile_rt->logger, MODULE_COMPILE, "[%s:%d] Build bool matcher failed!", __FUNCTION__, __LINE__); @@ -1215,14 +1219,21 @@ void compile_rule_free(struct compile_rule *compile_rule) struct compile_schema *schema = compile_rule->ref_schema; assert(compile_rule->magic_num == COMPILE_RULE_MAGIC); - if (1 == schema->set_flag) - { + if (1 == schema->set_flag) { rule_ex_data_free(schema->table_id, compile_rule->ex_data, &(schema->ex_schema)); *compile_rule->ex_data = NULL; } - FREE(compile_rule->ex_data); + + if (compile_rule->ex_data != NULL) { + FREE(compile_rule->ex_data); + } + compile_rule->declared_clause_num = -1; - FREE(compile_rule->table_line); + + if (compile_rule->table_line != NULL) { + FREE(compile_rule->table_line); + } + FREE(compile_rule); } @@ -1468,7 +1479,7 @@ void maat_compile_state_free(struct maat_compile_state *compile_state) compile_state->this_scan_hit_clauses = NULL; } - free(compile_state); + FREE(compile_state); } static int maat_compile_hit_path_add(UT_array *hit_paths, long long item_id, long long group_id, @@ -1533,7 +1544,8 @@ size_t compile_runtime_get_hit_paths(struct compile_runtime *compile_rt, size_t new_hit_path_cnt = 0; struct maat_compile *compile = NULL; struct maat_literal_id literal_id = {0, 0}; - struct bool_expr_match *expr_match = compile_rt->expr_match_buff + compile_state->thread_id * MAX_SCANNER_HIT_COMPILE_NUM; + struct bool_expr_match *expr_match = compile_rt->expr_match_buff + + (compile_state->thread_id * MAX_SCANNER_HIT_COMPILE_NUM); assert(compile_state->thread_id >= 0); if (compile_state->compile_rt_version != compile_rt->version) { @@ -1910,7 +1922,7 @@ int group2compile_runtime_update(void *g2c_runtime, void *g2c_schema, group_ref = ALLOC(struct group_reference, 1); group_ref->group_id = g2c_item->group_id; HASH_ADD_KEYPTR(hh, compile_rt->group_ref_hash, (char *)&(group_ref->group_id), - sizeof(long long), group_ref); + sizeof(long long), group_ref); } group_ref->ref_by_compile_cnt++; pthread_mutex_unlock(&(compile_rt->mutex)); @@ -1933,6 +1945,7 @@ int group2compile_runtime_update(void *g2c_runtime, void *g2c_schema, int group_referenced_by_compile(struct compile_runtime *compile_rt, long long group_id) { struct group_reference *group_ref = NULL; + pthread_mutex_lock(&(compile_rt->mutex)); HASH_FIND(hh, compile_rt->group_ref_hash, (char *)&group_id, sizeof(long long), group_ref); if (group_ref != NULL) { diff --git a/src/maat_expr.c b/src/maat_expr.c index 2282e28..1fdd8e0 100644 --- a/src/maat_expr.c +++ b/src/maat_expr.c @@ -444,6 +444,10 @@ void expr_rule_reset(struct expr_rule *rule) void expr_item_free(struct expr_item *item) { + if (NULL == item) { + return; + } + if (item->user_data != NULL && item->user_data_free != NULL) { item->user_data_free(item->user_data); @@ -737,15 +741,6 @@ int expr_item_to_expr_rule(struct expr_item *expr_item, struct expr_rule *expr_r expr_rule->user_tag = expr_item->user_data; expr_rule->n_patterns = sub_expr_cnt; - //mytest - // printf("expr_rule->expr_id:%u\n", expr_rule->expr_id); - // printf("expr_rule->n_patterns:%zu\n", expr_rule->n_patterns); - // for (size_t i = 0; i < expr_rule->n_patterns; i++) { - // printf("expr_rule->patterns[%zu].pat:%s\n", i, expr_rule->patterns[i].pat); - // printf("expr_rule->patterns[%zu].pat_len:%zu\n", i, expr_rule->patterns[i].pat_len); - // printf("expr_rule->patterns[%zu].l_offset:%d\n", i, expr_rule->patterns[i].l_offset); - // printf("expr_rule->patterns[%zu].r_offset:%d\n", i, expr_rule->patterns[i].r_offset); - // } return 0; } @@ -876,8 +871,8 @@ int expr_runtime_commit(void *expr_runtime, const char *table_name, long long ma expr_rt->version = maat_rt_version; log_info(expr_rt->logger, MODULE_EXPR, - "table[%s] commit %zu expr rules and rebuild adapter_hs completed, version:%lld", - table_name, rule_cnt, expr_rt->version); + "table[%s] has %zu rules, commit %zu expr rules and rebuild adapter_hs completed, version:%lld", + table_name, rule_cnt, real_rule_cnt, expr_rt->version); if (rules != NULL) { for (i = 0; i < rule_cnt; i++) { diff --git a/src/maat_flag.c b/src/maat_flag.c index e156e2f..95c91d5 100644 --- a/src/maat_flag.c +++ b/src/maat_flag.c @@ -425,7 +425,6 @@ int flag_runtime_update(void *flag_runtime, void *flag_schema, const char *table if (ret < 0) { if (flag_item != NULL) { flag_item_free(flag_item); - flag_item = NULL; } flag_rt->update_err_cnt++; return -1; diff --git a/src/maat_fqdn_plugin.c b/src/maat_fqdn_plugin.c index ca3990e..144ba59 100644 --- a/src/maat_fqdn_plugin.c +++ b/src/maat_fqdn_plugin.c @@ -56,7 +56,7 @@ void *fqdn_plugin_schema_new(cJSON *json, struct table_manager *tbl_mgr, schema->table_id = item->valueint; } else { log_error(logger, MODULE_FQDN_PLUGIN, - "[%s:%d] table %s has no table_id column", + "[%s:%d] table: <%s> schema has no table_id column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -64,7 +64,7 @@ void *fqdn_plugin_schema_new(cJSON *json, struct table_manager *tbl_mgr, item = cJSON_GetObjectItem(json, "custom"); if (NULL == item || item->type != cJSON_Object) { log_error(logger, MODULE_FQDN_PLUGIN, - "[%s:%d] table %s has no custom column", + "[%s:%d] table: <%s> schema has no custom column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -74,7 +74,7 @@ void *fqdn_plugin_schema_new(cJSON *json, struct table_manager *tbl_mgr, schema->item_id_column = custom_item->valueint; } else { log_error(logger, MODULE_FQDN_PLUGIN, - "[%s:%d] table %s has no item_id column", + "[%s:%d] table: <%s> schema has no item_id column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -84,7 +84,7 @@ void *fqdn_plugin_schema_new(cJSON *json, struct table_manager *tbl_mgr, schema->suffix_flag_column = custom_item->valueint; } else { log_error(logger, MODULE_FQDN_PLUGIN, - "[%s:%d] table %s has no suffix_match_method column", + "[%s:%d] table: <%s> schema has no suffix_match_method column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -95,7 +95,7 @@ void *fqdn_plugin_schema_new(cJSON *json, struct table_manager *tbl_mgr, schema->fqdn_column = custom_item->valueint; } else { log_error(logger, MODULE_FQDN_PLUGIN, - "[%s:%d] table %s has no fqdn column", + "[%s:%d] table: <%s> schema has no fqdn column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -159,9 +159,15 @@ struct ex_container_schema *fqdn_plugin_table_get_ex_container_schema(void *fqdn void fqdn_rule_free(struct FQDN_rule *fqdn_rule) { + if (NULL == fqdn_rule) { + return; + } + assert(fqdn_rule->user_tag == NULL); - free(fqdn_rule->FQDN); - fqdn_rule->FQDN = NULL; + if (fqdn_rule->FQDN != NULL) { + FREE(fqdn_rule->FQDN); + } + free(fqdn_rule); } @@ -220,8 +226,8 @@ void fqdn_plugin_runtime_free(void *fqdn_plugin_runtime) FREE(fqdn_plugin_rt); } -int fqdn_plugin_accept_tag_match(struct fqdn_plugin_schema *schema, const char *line, - struct log_handle *logger) +int fqdn_plugin_accept_tag_match(struct fqdn_plugin_schema *schema, const char *table_name, + const char *line, struct log_handle *logger) { size_t column_offset = 0; size_t column_len = 0; @@ -232,8 +238,8 @@ int fqdn_plugin_accept_tag_match(struct fqdn_plugin_schema *schema, const char * &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_FQDN_PLUGIN, - "[%s:%d] fqdn_plugin table(table_id:%d) has no rule_tag, line:%s", - __FUNCTION__, __LINE__, schema->table_id, line); + "[%s:%d] table: <%s> has no rule_tag in line:%s", + __FUNCTION__, __LINE__, table_name, line); return TAG_MATCH_ERR; } @@ -244,12 +250,15 @@ int fqdn_plugin_accept_tag_match(struct fqdn_plugin_schema *schema, const char * FREE(tag_str); if (TAG_MATCH_ERR == ret) { log_error(logger, MODULE_FQDN_PLUGIN, - "[%s:%d] fqdn_plugin table(table_id:%d) has invalid tag format, line:%s", - __FUNCTION__, __LINE__, schema->table_id, line); + "[%s:%d] table: <%s> has invalid tag format in line:%s", + __FUNCTION__, __LINE__, table_name, line); return TAG_MATCH_ERR; } if (TAG_MATCH_UNMATCHED == ret) { + log_error(logger, MODULE_FQDN_PLUGIN, + "[%s:%d] table: <%s> has unmatched tag in line:%s", + __FUNCTION__, __LINE__, table_name, line); return TAG_MATCH_UNMATCHED; } } @@ -262,7 +271,7 @@ struct FQDN_rule * fqdn_plugin_rule_new(const char *line, struct fqdn_plugin_schema *schema, const char *table_name, struct log_handle *logger) { - int ret = fqdn_plugin_accept_tag_match(schema, line, logger); + int ret = fqdn_plugin_accept_tag_match(schema, table_name, line, logger); if (ret == TAG_MATCH_UNMATCHED) { return NULL; } @@ -276,7 +285,7 @@ fqdn_plugin_rule_new(const char *line, struct fqdn_plugin_schema *schema, ret = get_column_pos(line, schema->item_id_column, &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_FQDN_PLUGIN, - "[%s:%d] fqdn_plugin table:%s line:%s has no item_id column", + "[%s:%d] table: <%s> has no item_id in line:%s", __FUNCTION__, __LINE__, table_name, line); goto error; } @@ -285,7 +294,7 @@ fqdn_plugin_rule_new(const char *line, struct fqdn_plugin_schema *schema, ret = get_column_pos(line, schema->suffix_flag_column, &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_FQDN_PLUGIN, - "[%s:%d] fqdn_plugin table:%s line:%s has no suffix_match_method column", + "[%s:%d] table: <%s> has no suffix_match_method in line:%s", __FUNCTION__, __LINE__, table_name, line); goto error; } @@ -294,7 +303,7 @@ fqdn_plugin_rule_new(const char *line, struct fqdn_plugin_schema *schema, ret = get_column_pos(line, schema->fqdn_column, &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_FQDN_PLUGIN, - "[%s:%d] fqdn_plugin table:%s line:%s has no fqdn column", + "[%s:%d] table: <%s> has no fqdn in line:%s", __FUNCTION__, __LINE__, table_name, line); goto error; } @@ -323,6 +332,10 @@ error: void fqdn_plugin_rule_free(struct FQDN_rule *rule) { + if (NULL == rule) { + return; + } + if (rule->FQDN != NULL) { FREE(rule->FQDN); } @@ -386,7 +399,8 @@ int fqdn_plugin_runtime_update(void *fqdn_plugin_runtime, void *fqdn_plugin_sche if (1 == schema->container_schema.set_flag) { if (1 == is_valid) { // add - fqdn_plugin_rule = fqdn_plugin_rule_new(line, schema, table_name, fqdn_plugin_rt->logger); + fqdn_plugin_rule = fqdn_plugin_rule_new(line, schema, table_name, + fqdn_plugin_rt->logger); if (NULL == fqdn_plugin_rule) { fqdn_plugin_rt->update_err_cnt++; return -1; @@ -396,7 +410,7 @@ int fqdn_plugin_runtime_update(void *fqdn_plugin_runtime, void *fqdn_plugin_sche const char *key = line + item_id_offset; size_t key_len = item_id_len; ret = fqdn_plugin_runtime_update_row(fqdn_plugin_rt, table_name, line, key, key_len, - fqdn_plugin_rule, is_valid); + fqdn_plugin_rule, is_valid); if (ret < 0) { if (fqdn_plugin_rule != NULL) { fqdn_plugin_rule_free(fqdn_plugin_rule); @@ -419,7 +433,8 @@ void garbage_fqdn_engine_free(void *fqdn_engine, void *arg) FQDN_engine_free(engine); } -int fqdn_plugin_runtime_commit(void *fqdn_plugin_runtime, const char *table_name, long long maat_rt_version) +int fqdn_plugin_runtime_commit(void *fqdn_plugin_runtime, const char *table_name, + long long maat_rt_version) { if (NULL == fqdn_plugin_runtime) { return -1; diff --git a/src/maat_garbage_collection.c b/src/maat_garbage_collection.c index 65fe619..02f760a 100644 --- a/src/maat_garbage_collection.c +++ b/src/maat_garbage_collection.c @@ -42,8 +42,12 @@ struct maat_garbage_bin *maat_garbage_bin_new(int default_timeout) return bin; } -void maat_garbage_bin_free(struct maat_garbage_bin* bin) +void maat_garbage_bin_free(struct maat_garbage_bin *bin) { + if (NULL == bin) { + return; + } + struct maat_garbage_bag *p = NULL; while ((p = TAILQ_FIRST(&bin->garbage_q)) != NULL) { @@ -51,6 +55,7 @@ void maat_garbage_bin_free(struct maat_garbage_bin* bin) if (p->arg != NULL) { FREE(p->arg); } + TAILQ_REMOVE(&bin->garbage_q, p, entries); FREE(p); bin->bag_cnt--; @@ -59,12 +64,16 @@ void maat_garbage_bin_free(struct maat_garbage_bin* bin) FREE(bin); } -size_t maat_garbage_bin_get_size(struct maat_garbage_bin* bin) +size_t maat_garbage_bin_get_size(struct maat_garbage_bin *bin) { + if (NULL == bin) { + return 0; + } + return bin->bag_cnt; } -void maat_garbage_bagging(struct maat_garbage_bin* bin, void* garbage, void *arg, +void maat_garbage_bagging(struct maat_garbage_bin *bin, void *garbage, void *arg, void (* func)(void *, void *)) { struct maat_garbage_bag *bag = ALLOC(struct maat_garbage_bag, 1); @@ -77,7 +86,8 @@ void maat_garbage_bagging(struct maat_garbage_bin* bin, void* garbage, void *arg TAILQ_INSERT_TAIL(&bin->garbage_q, bag, entries); bin->bag_cnt++; } -void maat_garbage_collect_routine(struct maat_garbage_bin* bin) + +void maat_garbage_collect_routine(struct maat_garbage_bin *bin) { struct maat_garbage_bag *p = NULL, *tmp = NULL; size_t n_clollected = 0, n_bag = 0; @@ -101,9 +111,10 @@ void maat_garbage_collect_routine(struct maat_garbage_bin* bin) bin->bag_cnt -= n_clollected; } -void maat_garbage_collect_by_force(struct maat_garbage_bin* bin) +void maat_garbage_collect_by_force(struct maat_garbage_bin *bin) { struct maat_garbage_bag *p = NULL; + while ((p = TAILQ_FIRST(&bin->garbage_q)) != NULL) { p->garbage_free(p->garbage, p->arg); if (p->arg != NULL) { diff --git a/src/maat_group.c b/src/maat_group.c index cdc8b5a..331edf0 100644 --- a/src/maat_group.c +++ b/src/maat_group.c @@ -153,6 +153,10 @@ void group2group_schema_free(void *g2g_schema) void group_vertex_free(struct maat_group *group) { + if (NULL == group) { + return; + } + if (group->incl_super_group_ids != NULL) { utarray_free(group->incl_super_group_ids); group->incl_super_group_ids = NULL; @@ -194,6 +198,10 @@ struct maat_group_topology *maat_group_topology_new(struct log_handle *logger) void maat_group_topology_free(struct maat_group_topology *group_topo) { + if (NULL == group_topo) { + return; + } + struct maat_group *group = NULL, *tmp_group = NULL; HASH_CLEAR(hh_vertex_id, group_topo->hash_by_vertex_id);//No need group memory clean up. @@ -770,7 +778,7 @@ void get_candidate_super_group_ids(struct maat_group_topology *group_topo, { long long *p = NULL; - //Find super candidates + //Find super candidates for (p = (long long *)utarray_front(hit_group_ids); p != NULL; p = (long long *)utarray_next(hit_group_ids, p)) { struct maat_group *group = group_topology_find_group(group_topo, *p); @@ -792,6 +800,74 @@ void get_candidate_super_group_ids(struct maat_group_topology *group_topo, } } +void verify_group_by_sub_include_groups(struct maat_group *group, UT_array *candidate_group_ids, + UT_array *kept_super_group_ids, UT_array *all_hit_group_ids) +{ + size_t remove_idx = 0; + long long *tmp_id = NULL; + + // delete groups whose all incl sub not in all_hit_group_ids + if (utarray_len(group->incl_sub_group_ids) != 0) { + int sub_incl_flag = 0; + + for (tmp_id = (long long *)utarray_front(group->incl_sub_group_ids); tmp_id != NULL; + tmp_id = (long long *)utarray_next(group->incl_sub_group_ids, tmp_id)) { + if (utarray_find(candidate_group_ids, tmp_id, compare_group_id)) { + sub_incl_flag = 1; + break; + } + } + + if (0 == sub_incl_flag) { + tmp_id = utarray_find(all_hit_group_ids, &(group->group_id), compare_group_id); + if (tmp_id != NULL) { + remove_idx = utarray_eltidx(all_hit_group_ids, tmp_id); + utarray_erase(all_hit_group_ids, remove_idx, 1); + } + + tmp_id = utarray_find(kept_super_group_ids, &(group->group_id), compare_group_id); + if (tmp_id != NULL) { + remove_idx = utarray_eltidx(kept_super_group_ids, tmp_id); + utarray_erase(kept_super_group_ids, remove_idx, 1); + } + } + } +} + +void verify_group_by_sub_exclude_groups(struct maat_group *group, UT_array *candidate_group_ids, + UT_array *kept_super_group_ids, UT_array *all_hit_group_ids) +{ + if (0 == utarray_len(group->excl_sub_group_ids)) { + return; + } + + // delete groups whose excl sub in all_hit_group_ids + int sub_excl_flag = 0; + long long *tmp_id = NULL; + for (tmp_id = (long long *)utarray_front(group->excl_sub_group_ids); tmp_id != NULL; + tmp_id = (long long *)utarray_next(group->excl_sub_group_ids, tmp_id)) { + if (utarray_find(candidate_group_ids, tmp_id, compare_group_id)) { + sub_excl_flag = 1; + break; + } + } + + if (1 == sub_excl_flag) { + size_t remove_idx = 0; + tmp_id = utarray_find(all_hit_group_ids, &(group->group_id), compare_group_id); + if (tmp_id != NULL) { + remove_idx = utarray_eltidx(all_hit_group_ids, tmp_id); + utarray_erase(all_hit_group_ids, remove_idx, 1); + } + + tmp_id = utarray_find(kept_super_group_ids, &(group->group_id), compare_group_id); + if (tmp_id != NULL) { + remove_idx = utarray_eltidx(kept_super_group_ids, tmp_id); + utarray_erase(kept_super_group_ids, remove_idx, 1); + } + } +} + void verify_candidate_super_group_ids(struct maat_group_topology *group_topo, UT_array *candidate_super_group_ids, UT_array *all_hit_group_ids, @@ -802,6 +878,7 @@ void verify_candidate_super_group_ids(struct maat_group_topology *group_topo, utarray_new(candidate_group_ids, &ut_group_id_icd); + /* merge this round of candidate super groups with hit groups from the previous round */ for (p = (long long *)utarray_front(candidate_super_group_ids); p != NULL; p = (long long *)utarray_next(candidate_super_group_ids, p)) { utarray_push_back(candidate_group_ids, p); @@ -832,10 +909,11 @@ void verify_candidate_super_group_ids(struct maat_group_topology *group_topo, } } - //delete group_id from kept_group_ids + //kept super groups should not store this group if (1 == sub_excl_flag) { continue; } + utarray_push_back(kept_super_group_ids, p); utarray_sort(kept_super_group_ids, compare_group_id); @@ -855,7 +933,8 @@ void verify_candidate_super_group_ids(struct maat_group_topology *group_topo, } /** - * delete groups whose all incl sub is non-exist in all_hit_group_ids + * 1. delete groups whose excl sub in all_hit_group_ids + * 2. delete groups whose all incl sub is non-exist in all_hit_group_ids */ for (p = (long long *)utarray_front(candidate_group_ids); p != NULL; p = (long long *)utarray_next(candidate_group_ids, p)) { @@ -864,38 +943,15 @@ void verify_candidate_super_group_ids(struct maat_group_topology *group_topo, continue; } - if (0 == utarray_len(group->incl_sub_group_ids)) { - continue; - } - - int sub_incl_flag = 0; - long long *tmp_id = NULL; - for (tmp_id = (long long *)utarray_front(group->incl_sub_group_ids); tmp_id != NULL; - tmp_id = (long long *)utarray_next(group->incl_sub_group_ids, tmp_id)) { - if (utarray_find(candidate_group_ids, tmp_id, compare_group_id)) { - sub_incl_flag = 1; - break; - } - } - - if (0 == sub_incl_flag) { - tmp_id = utarray_find(all_hit_group_ids, p, compare_group_id); - assert(tmp_id != NULL); - size_t remove_idx = utarray_eltidx(all_hit_group_ids, tmp_id); - utarray_erase(all_hit_group_ids, remove_idx, 1); - - tmp_id = utarray_find(kept_super_group_ids, p, compare_group_id); - if (tmp_id != NULL) { - remove_idx = utarray_eltidx(kept_super_group_ids, tmp_id); - utarray_erase(kept_super_group_ids, remove_idx, 1); - } - } + verify_group_by_sub_exclude_groups(group, candidate_group_ids, + kept_super_group_ids, all_hit_group_ids); + verify_group_by_sub_include_groups(group, candidate_group_ids, + kept_super_group_ids, all_hit_group_ids); } utarray_free(candidate_group_ids); } -#define MAX_RECURSION_DEPTH 5 void get_super_group_ids(struct maat_group_topology *group_topo, UT_array *hit_group_ids, UT_array *all_hit_group_ids, size_t depth) { @@ -903,6 +959,8 @@ void get_super_group_ids(struct maat_group_topology *group_topo, UT_array *hit_g UT_array *kept_super_group_ids; if (depth >= MAX_RECURSION_DEPTH) { + log_error(group_topo->logger, MODULE_GROUP, + "[%s:%d]exceed max recursion depth(5)", __FUNCTION__, __LINE__); return; } @@ -911,7 +969,7 @@ void get_super_group_ids(struct maat_group_topology *group_topo, UT_array *hit_g /** candidate super groups means all hit groups' super include group, - no need to consider super exclude groups + don't consider super exclude groups for example: hit_groups = {g4, g11} g4's super include groups = {g7, g8} @@ -941,9 +999,12 @@ void get_super_group_ids(struct maat_group_topology *group_topo, UT_array *hit_g x \ / \ \ x \/ \ \ g3 g4 g5 g11 - candidates = {g4, g11, g7, g8, g12} - g12's sub_exclude g8 in candidates, so g12 should be dropped - after verify candidates, all hit super groups = {g7, g8}, + candidate super groups = {g7, g8, g12} + verify logic: + 1. g12's sub_exclude g8 in candidates, so g12 should be dropped + 2. g7 & g8, their sub_include in hit groups, so kept them + if their all sub_include not exist in hit groups, they should be dropped + after verify candidates, kept super groups = {g7, g8}, all hit groups = {g4, g11, g7, g8} */ verify_candidate_super_group_ids(group_topo, candidate_super_group_ids, all_hit_group_ids, diff --git a/src/maat_interval.c b/src/maat_interval.c index 4753a23..d6b0c14 100644 --- a/src/maat_interval.c +++ b/src/maat_interval.c @@ -423,7 +423,6 @@ int interval_runtime_update(void *interval_runtime, void *interval_schema, if (ret < 0) { if (interval_item != NULL) { interval_item_free(interval_item); - interval_item = NULL; } interval_rt->update_err_cnt++; return -1; diff --git a/src/maat_ip.c b/src/maat_ip.c index 440c77b..5d1b404 100644 --- a/src/maat_ip.c +++ b/src/maat_ip.c @@ -535,7 +535,6 @@ int ip_runtime_update(void *ip_runtime, void *ip_schema, if (ret < 0) { if (ip_item != NULL) { ip_item_free(ip_item); - ip_item = NULL; } ip_rt->update_err_cnt++; return -1; diff --git a/src/maat_ip_plugin.c b/src/maat_ip_plugin.c index d471ad2..f99062b 100644 --- a/src/maat_ip_plugin.c +++ b/src/maat_ip_plugin.c @@ -51,7 +51,6 @@ struct ip_plugin_runtime { void *ip_plugin_schema_new(cJSON *json, struct table_manager *tbl_mgr, const char *table_name, struct log_handle *logger) { - size_t read_cnt = 0; struct ip_plugin_schema *schema = ALLOC(struct ip_plugin_schema, 1); schema->logger = logger; @@ -59,13 +58,17 @@ void *ip_plugin_schema_new(cJSON *json, struct table_manager *tbl_mgr, cJSON *item = cJSON_GetObjectItem(json, "table_id"); if (item != NULL && item->type == cJSON_Number) { schema->table_id = item->valueint; - read_cnt++; + } else { + log_error(logger, MODULE_IP_PLUGIN, + "[%s:%d] table: <%s> schema has no table_id column", + __FUNCTION__, __LINE__, table_name); + goto error; } item = cJSON_GetObjectItem(json, "custom"); if (NULL == item || item->type != cJSON_Object) { log_error(logger, MODULE_IP_PLUGIN, - "[%s:%d] table %s has no custom column", + "[%s:%d] table: <%s> schema has no custom column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -73,33 +76,54 @@ void *ip_plugin_schema_new(cJSON *json, struct table_manager *tbl_mgr, custom_item = cJSON_GetObjectItem(item, "item_id"); if (custom_item != NULL && custom_item->type == cJSON_Number) { schema->item_id_column = custom_item->valueint; - read_cnt++; + } else { + log_error(logger, MODULE_IP_PLUGIN, + "[%s:%d] table: <%s> schema has no item_id column", + __FUNCTION__, __LINE__, table_name); + goto error; } custom_item = cJSON_GetObjectItem(item, "ip_type"); if (custom_item != NULL && custom_item->type == cJSON_Number) { schema->ip_type_column = custom_item->valueint; - read_cnt++; + } else { + log_error(logger, MODULE_IP_PLUGIN, + "[%s:%d] table: <%s> schema has no ip_type column", + __FUNCTION__, __LINE__, table_name); + goto error; } custom_item = cJSON_GetObjectItem(item, "start_ip"); if (custom_item != NULL && custom_item->type == cJSON_Number) { schema->start_ip_column = custom_item->valueint; - read_cnt++; + } else { + log_error(logger, MODULE_IP_PLUGIN, + "[%s:%d] table: <%s> schema has no start_ip column", + __FUNCTION__, __LINE__, table_name); + goto error; } custom_item = cJSON_GetObjectItem(item, "end_ip"); if (custom_item != NULL && custom_item->type == cJSON_Number) { schema->end_ip_column = custom_item->valueint; - read_cnt++; + } else { + log_error(logger, MODULE_IP_PLUGIN, + "[%s:%d] table: <%s> schema has no end_ip column", + __FUNCTION__, __LINE__, table_name); + goto error; } custom_item = cJSON_GetObjectItem(item, "addr_format"); if (custom_item != NULL && custom_item->type == cJSON_Number) { schema->addr_format_column = custom_item->valueint; - //TODO: just because test table not add this column - //read_cnt++; - } + } + //TODO: just because test table has no addr_format + // else { + // log_error(logger, MODULE_IP_PLUGIN, + // "[%s:%d] table: <%s> schema has no addr_format column", + // __FUNCTION__, __LINE__, table_name); + // goto error; + // } // rule_tag is optional custom_item = cJSON_GetObjectItem(item, "rule_tag"); @@ -108,10 +132,6 @@ void *ip_plugin_schema_new(cJSON *json, struct table_manager *tbl_mgr, } schema->ref_tbl_mgr = tbl_mgr; - - if (read_cnt < 5) { - goto error; - } return schema; error: @@ -128,8 +148,8 @@ void ip_plugin_schema_free(void *ip_plugin_schema) FREE(ip_plugin_schema); } -int ip_plugin_accept_tag_match(struct ip_plugin_schema *schema, const char *line, - struct log_handle *logger) +int ip_plugin_accept_tag_match(struct ip_plugin_schema *schema, const char *table_name, + const char *line, struct log_handle *logger) { size_t column_offset = 0; size_t column_len = 0; @@ -140,8 +160,8 @@ int ip_plugin_accept_tag_match(struct ip_plugin_schema *schema, const char *line &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_IP_PLUGIN, - "[%s:%d] ip_plugin table(table_id:%d) has no rule_tag, line:%s", - __FUNCTION__, __LINE__, schema->table_id, line); + "[%s:%d] table: <%s> has no rule_tag in line:%s", + __FUNCTION__, __LINE__, table_name, line); return TAG_MATCH_ERR; } @@ -152,12 +172,15 @@ int ip_plugin_accept_tag_match(struct ip_plugin_schema *schema, const char *line FREE(tag_str); if (TAG_MATCH_ERR == ret) { log_error(logger, MODULE_IP_PLUGIN, - "[%s:%d] ip_plugin table(table_id:%d) has invalid tag format, line:%s", - __FUNCTION__, __LINE__, schema->table_id, line); + "[%s:%d] table: <%s> has invalid tag format in line:%s", + __FUNCTION__, __LINE__, table_name, line); return TAG_MATCH_ERR; } if (TAG_MATCH_UNMATCHED == ret) { + log_error(logger, MODULE_IP_PLUGIN, + "[%s:%d] table: <%s> has unmatched tag in line:%s", + __FUNCTION__, __LINE__, table_name, line); return TAG_MATCH_UNMATCHED; } } @@ -170,7 +193,7 @@ struct ip_rule * ip_plugin_rule_new(const char *line, struct ip_plugin_schema *schema, const char *table_name, struct log_handle *logger) { - int ret = ip_plugin_accept_tag_match(schema, line, logger); + int ret = ip_plugin_accept_tag_match(schema, table_name, line, logger); if (ret == TAG_MATCH_UNMATCHED) { return NULL; } @@ -185,7 +208,7 @@ ip_plugin_rule_new(const char *line, struct ip_plugin_schema *schema, ret = get_column_pos(line, schema->item_id_column, &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_IP_PLUGIN, - "[%s:%d] ip plugin table:%s line:%s has no item_id", + "[%s:%d] table: <%s> has no item_id in line:%s", __FUNCTION__, __LINE__, table_name, line); goto error; } @@ -194,15 +217,15 @@ ip_plugin_rule_new(const char *line, struct ip_plugin_schema *schema, ret = get_column_pos(line, schema->ip_type_column, &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_IP_PLUGIN, - "[%s:%d] ip plugin table:%s line:%s has no ip_type", + "[%s:%d] table: <%s> has no ip_type in line:%s", __FUNCTION__, __LINE__, table_name, line); goto error; } ip_plugin_rule->type = atoi(line + column_offset); if (ip_plugin_rule->type != IPv4 && ip_plugin_rule->type != IPv6) { log_error(logger, MODULE_IP_PLUGIN, - "[%s:%d] ip_plugin table:%s line:%s ip_type[%d] invalid", - __FUNCTION__, __LINE__, table_name, line, ip_plugin_rule->type); + "[%s:%d] table: <%s> ip_type[%d] invalid in line:%s", + __FUNCTION__, __LINE__, table_name, ip_plugin_rule->type, line); goto error; } @@ -230,7 +253,7 @@ ip_plugin_rule_new(const char *line, struct ip_plugin_schema *schema, ret = get_column_pos(line, schema->start_ip_column, &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_IP_PLUGIN, - "[%s:%d] ip_plugin table:%s line:%s has no start_ip", + "[%s:%d] table: <%s> has no start_ip in line:%s", __FUNCTION__, __LINE__, table_name, line); goto error; } @@ -239,7 +262,7 @@ ip_plugin_rule_new(const char *line, struct ip_plugin_schema *schema, ret = get_column_pos(line, schema->end_ip_column, &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_IP_PLUGIN, - "[%s:%d] ip_plugin table:%s line:%s has no end_ip", + "[%s:%d] table: <%s> has no end_ip in line:%s", __FUNCTION__, __LINE__, table_name, line); goto error; } @@ -252,7 +275,7 @@ ip_plugin_rule_new(const char *line, struct ip_plugin_schema *schema, &ip_plugin_rule->ipv4_rule.end_ip); if (ret < 0) { log_error(logger, MODULE_IP_PLUGIN, - "[%s:%d] ip_plugin table:%s line:%s ip_format2range(ip4) failed", + "[%s:%d] table: <%s> ip_format2range(ip4) failed in line:%s", __FUNCTION__, __LINE__, table_name, line); goto error; } @@ -264,7 +287,7 @@ ip_plugin_rule_new(const char *line, struct ip_plugin_schema *schema, ip_plugin_rule->ipv6_rule.end_ip); if (ret < 0) { log_error(logger, MODULE_IP_PLUGIN, - "[%s:%d] ip_plugin table:%s line:%s ip_format2range(ip6) failed", + "[%s:%d] table: <%s> ip_format2range(ip6) failed in line:%s", __FUNCTION__, __LINE__, table_name, line); goto error; } @@ -359,7 +382,8 @@ void *ip_plugin_runtime_new(void *ip_plugin_schema, size_t max_thread_num, ip_plugin_rt->ex_data_rt = ex_data_runtime_new(schema->table_id, logger); if (1 == schema->container_schema.set_flag) { - ex_data_runtime_set_ex_container_schema(ip_plugin_rt->ex_data_rt, &(schema->container_schema)); + ex_data_runtime_set_ex_container_schema(ip_plugin_rt->ex_data_rt, + &(schema->container_schema)); } ip_plugin_rt->n_worker_thread = max_thread_num; @@ -458,7 +482,8 @@ int ip_plugin_runtime_update(void *ip_plugin_runtime, void *ip_plugin_schema, return 0; } -int ip_plugin_runtime_commit(void *ip_plugin_runtime, const char *table_name, long long maat_rt_version) +int ip_plugin_runtime_commit(void *ip_plugin_runtime, const char *table_name, + long long maat_rt_version) { if (NULL == ip_plugin_runtime) { return -1; diff --git a/src/maat_kv.c b/src/maat_kv.c index ee282de..3c586af 100644 --- a/src/maat_kv.c +++ b/src/maat_kv.c @@ -48,10 +48,15 @@ struct maat_kv_pair* maat_kv_pair_new(const char* key, size_t keylen, long long return kv; } -void maat_kv_pair_free(struct maat_kv_pair* kv) +void maat_kv_pair_free(struct maat_kv_pair *kv) { - FREE(kv->key); - kv->key = NULL; + if (NULL == kv) { + return; + } + + if (kv->key != NULL) { + FREE(kv->key); + } FREE(kv); } @@ -62,7 +67,7 @@ struct maat_kv_store* maat_kv_store_new(void) return store; } -void maat_kv_store_free(struct maat_kv_store* store) +void maat_kv_store_free(struct maat_kv_store *store) { if (NULL == store) { return; @@ -79,7 +84,7 @@ void maat_kv_store_free(struct maat_kv_store* store) FREE(store); } -int maat_kv_register_unNull(struct maat_kv_store* store, const char *key, size_t keylen, long long value) +int maat_kv_register_unNull(struct maat_kv_store *store, const char *key, size_t keylen, long long value) { if (keylen > MAAT_KV_MAX_KEY_LEN) { return -1; diff --git a/src/maat_plugin.c b/src/maat_plugin.c index 8b996aa..809b8d4 100644 --- a/src/maat_plugin.c +++ b/src/maat_plugin.c @@ -87,7 +87,7 @@ void *plugin_schema_new(cJSON *json, struct table_manager *tbl_mgr, cJSON *item = cJSON_GetObjectItem(json, "table_id"); if (NULL == item || item->type != cJSON_Number) { log_error(logger, MODULE_PLUGIN, - "[%s:%d] plugin table %s has no table_id column", + "[%s:%d] table: <%s> schema has no table_id column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -99,7 +99,7 @@ void *plugin_schema_new(cJSON *json, struct table_manager *tbl_mgr, custom_item = cJSON_GetObjectItem(item, "key"); if (NULL == custom_item || custom_item->type != cJSON_Number) { log_error(logger, MODULE_PLUGIN, - "[%s:%d] plugin table: %s has no key column", + "[%s:%d] table: <%s> schema has no key column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -108,7 +108,7 @@ void *plugin_schema_new(cJSON *json, struct table_manager *tbl_mgr, custom_item = cJSON_GetObjectItem(item, "key_type"); if (NULL == custom_item || custom_item->type != cJSON_String) { log_error(logger, MODULE_PLUGIN, - "[%s:%d] plugin table: %s has no key_type column", + "[%s:%d] table: <%s> schema has no key_type column", __FUNCTION__, __LINE__, table_name); goto error; } @@ -119,9 +119,8 @@ void *plugin_schema_new(cJSON *json, struct table_manager *tbl_mgr, schema->key_type = PLUGIN_KEY_TYPE_INTEGER; } else { log_error(logger, MODULE_PLUGIN, - "[%s:%d] plugin table: %s key_type:%s illegal", - __FUNCTION__, __LINE__, table_name, - custom_item->valuestring); + "[%s:%d] table: <%s> schema key_type:%s is illegal, just allow {pointer} or {integer}", + __FUNCTION__, __LINE__, table_name, custom_item->valuestring); goto error; } @@ -274,7 +273,8 @@ void *plugin_runtime_new(void *plugin_schema, size_t max_thread_num, plugin_rt->ex_data_rt = ex_data_runtime_new(schema->table_id, logger); if (1 == schema->container_schema.set_flag) { - ex_data_runtime_set_ex_container_schema(plugin_rt->ex_data_rt, &(schema->container_schema)); + ex_data_runtime_set_ex_container_schema(plugin_rt->ex_data_rt, + &(schema->container_schema)); } plugin_rt->ref_garbage_bin = garbage_bin; @@ -319,7 +319,8 @@ int plugin_runtime_update_row(struct plugin_runtime *plugin_rt, void *ex_data = ex_data_runtime_row2ex_data(plugin_rt->ex_data_rt, table_name, row, key, key_len); struct ex_container *ex_container = ex_container_new(ex_data, NULL); - ret = ex_data_runtime_add_ex_container(plugin_rt->ex_data_rt, key, key_len, ex_container); + ret = ex_data_runtime_add_ex_container(plugin_rt->ex_data_rt, key, key_len, + ex_container); if (ret < 0) { return -1; } @@ -353,7 +354,7 @@ int plugin_accept_tag_match(struct plugin_schema *schema, const char *table_name int ret = get_column_pos(line, schema->rule_tag_column, &column_offset, &column_len); if (ret < 0) { log_error(logger, MODULE_PLUGIN, - "[%s:%d] plugin table:%s has no rule_tag, line:%s", + "[%s:%d] table: <%s> has no rule_tag in line:%s", __FUNCTION__, __LINE__, table_name, line); return TAG_MATCH_ERR; } @@ -365,12 +366,15 @@ int plugin_accept_tag_match(struct plugin_schema *schema, const char *table_name FREE(tag_str); if (TAG_MATCH_ERR == ret) { log_error(logger, MODULE_PLUGIN, - "[%s:%d] plugin table:%s has invalid tag format, line:%s", + "[%s:%d] table: <%s> has invalid tag format in line:%s", __FUNCTION__, __LINE__, table_name, line); return TAG_MATCH_ERR; } if (TAG_MATCH_UNMATCHED == ret) { + log_error(logger, MODULE_PLUGIN, + "[%s:%d] table: <%s> has unmatched tag in line:%s", + __FUNCTION__, __LINE__, table_name, line); return TAG_MATCH_UNMATCHED; } } @@ -427,7 +431,8 @@ int plugin_runtime_update(void *plugin_runtime, void *plugin_schema, return 0; } -int plugin_runtime_commit(void *plugin_runtime, const char *table_name, long long maat_rt_version) +int plugin_runtime_commit(void *plugin_runtime, const char *table_name, + long long maat_rt_version) { if (NULL == plugin_runtime) { return -1; diff --git a/src/maat_redis_monitor.c b/src/maat_redis_monitor.c index c3323ac..aeaed9a 100644 --- a/src/maat_redis_monitor.c +++ b/src/maat_redis_monitor.c @@ -411,16 +411,28 @@ int get_inc_key_list(long long instance_version, long long target_version, void serial_rule_free(struct serial_rule *s_rule) { + if (NULL == s_rule) { + return; + } + if (s_rule->table_line != NULL) { FREE(s_rule->table_line); } if (s_rule->n_foreign > 0) { for (int i = 0; i < s_rule->n_foreign; i++) { - FREE(s_rule->f_keys[i].filename); - FREE(s_rule->f_keys[i].key); + if (s_rule->f_keys[i].filename != NULL) { + FREE(s_rule->f_keys[i].filename); + } + + if (s_rule->f_keys[i].key != NULL) { + FREE(s_rule->f_keys[i].key); + } } - FREE(s_rule->f_keys); + + if (s_rule->f_keys != NULL) { + FREE(s_rule->f_keys); + } } FREE(s_rule); diff --git a/src/maat_rule.c b/src/maat_rule.c index 4591639..a751888 100644 --- a/src/maat_rule.c +++ b/src/maat_rule.c @@ -55,7 +55,7 @@ void maat_item_inner_free(void *item_inner) assert(item->magic_num == ITEM_RULE_MAGIC); item->magic_num = 0; - free(item); + FREE(item); } struct maat_runtime* maat_runtime_create(long long version, struct maat *maat_instance) diff --git a/src/maat_stat.c b/src/maat_stat.c index 313e652..cb12318 100644 --- a/src/maat_stat.c +++ b/src/maat_stat.c @@ -185,7 +185,7 @@ void maat_stat_free(struct maat_stat *stat) stat->fs_handle = NULL; } - free(stat); + FREE(stat); } int maat_stat_init(struct maat_stat *stat, struct table_manager *tbl_mgr, @@ -287,8 +287,7 @@ void maat_fieldstat_table_row_output(struct maat_stat *stat, int perf_on) break; } - if (table_type == TABLE_TYPE_PLUGIN || table_type == TABLE_TYPE_COMPILE || - table_type == TABLE_TYPE_GROUP2COMPILE || table_type == TABLE_TYPE_GROUP2GROUP) { + if (table_type == TABLE_TYPE_PLUGIN ) { continue; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 20ef57f..8a5e4c5 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -30,12 +30,14 @@ target_link_libraries(maat_ex_data_gtest maat_frame_static gtest_static) add_subdirectory(group_exclude) file(COPY table_info.conf DESTINATION ./) +file(COPY tsg_table_info.conf DESTINATION ./) file(COPY file_test_tableinfo.conf DESTINATION ./) file(COPY literal_expr.conf DESTINATION ./) file(COPY regex_expr.conf DESTINATION ./) file(COPY maat_json.json DESTINATION ./) file(COPY maat_json.json DESTINATION ../tools/) file(COPY ntcrule DESTINATION ./) +file(COPY tsgrule DESTINATION ./) file(COPY testdata DESTINATION ./) file(COPY test_streamfiles DESTINATION ./) file(COPY json_update DESTINATION ./) diff --git a/test/group_exclude/group_exclude_L4.conf b/test/group_exclude/group_exclude_L4.conf new file mode 100644 index 0000000..a18c6bb --- /dev/null +++ b/test/group_exclude/group_exclude_L4.conf @@ -0,0 +1,136 @@ +{ + "add_items": [ + { + "group_id": 14, + "super_group_id": 8, + "is_exclude": 0 + }, + { + "group_id": 14, + "super_group_id": 9, + "is_exclude": 0 + }, + { + "group_id": 8, + "super_group_id": 5, + "is_exclude": 0 + }, + { + "group_id": 9, + "super_group_id": 1, + "is_exclude": 0 + }, + { + "group_id": 16, + "super_group_id": 9, + "is_exclude": 0 + }, + { + "group_id": 16, + "super_group_id": 10, + "is_exclude": 0 + }, + { + "group_id": 10, + "super_group_id": 7, + "is_exclude": 0 + }, + { + "group_id": 7, + "super_group_id": 6, + "is_exclude": 0 + }, + { + "group_id": 6, + "super_group_id": 1, + "is_exclude": 0 + }, + { + "group_id": 17, + "super_group_id": 11, + "is_exclude": 0 + }, + { + "group_id": 17, + "super_group_id": 12, + "is_exclude": 0 + }, + { + "group_id": 17, + "super_group_id":13, + "is_exclude": 0 + }, + { + "group_id": 11, + "super_group_id": 6, + "is_exclude": 0 + }, + { + "group_id": 12, + "super_group_id": 7, + "is_exclude": 0 + }, + { + "group_id": 7, + "super_group_id": 2, + "is_exclude": 0 + }, + { + "group_id": 7, + "super_group_id": 4, + "is_exclude": 0 + }, + { + "group_id": 13, + "super_group_id": 3, + "is_exclude": 0 + }, + { + "group_id": 15, + "super_group_id": 8, + "is_exclude": 1 + }, + { + "group_id": 9, + "super_group_id": 5, + "is_exclude": 1 + }, + { + "group_id": 5, + "super_group_id": 1, + "is_exclude": 1 + }, + { + "group_id": 10, + "super_group_id": 6, + "is_exclude": 1 + }, + { + "group_id": 6, + "super_group_id": 2, + "is_exclude": 1 + }, + { + "group_id": 6, + "super_group_id": 3, + "is_exclude": 1 + }, + { + "group_id": 18, + "super_group_id":13, + "is_exclude": 1 + }, + { + "group_id": 13, + "super_group_id": 4, + "is_exclude": 1 + } + ], + "del_items": [ + { + "group_id": 10, + "super_group_id": 6, + "is_exclude": 1 + } + ] +} \ No newline at end of file diff --git a/test/group_exclude/group_exclude_L4.png b/test/group_exclude/group_exclude_L4.png new file mode 100644 index 0000000000000000000000000000000000000000..25830f230f048250b58a21f59e4aa1808563b03a GIT binary patch literal 76281 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⋙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�n-z87t&dn8JY@uNt|+7j;Tx$-jqwZ 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 literal 0 HcmV?d00001 diff --git a/test/group_exclude/group_exclude_gtest.cpp b/test/group_exclude/group_exclude_gtest.cpp index 074c087..4e0ff4f 100644 --- a/test/group_exclude/group_exclude_gtest.cpp +++ b/test/group_exclude/group_exclude_gtest.cpp @@ -11,6 +11,7 @@ #define MAX_ITEM_NUM 64 #define WAIT_FOR_EFFECTIVE_S 2 +#define MAX_G2G_SCAN_TIMES (1000 * 1000) const char *table_info_path = "./table_info.conf"; @@ -138,38 +139,34 @@ protected: log_error(logger, MODULE_GROUP_EXCLUDE_GTEST, "group2group_schema_new failed."); assert(0); } - - g2g_runtime = group2group_runtime_new(g2g_schema, 1, garbage_bin, logger); - if (NULL == g2g_runtime) { - log_error(logger, MODULE_GROUP_EXCLUDE_GTEST, "group2group_runtime_new failed."); - assert(0); - } - } static void TearDownTestCase() { log_handle_destroy(logger); maat_garbage_bin_free(garbage_bin); - group2group_runtime_free(g2g_runtime); group2group_schema_free(g2g_schema); } static void *g2g_schema; - static void *g2g_runtime; static struct log_handle *logger; static struct maat_garbage_bin *garbage_bin; }; void *MaatGroupExclude::g2g_schema; -void *MaatGroupExclude::g2g_runtime; struct log_handle *MaatGroupExclude::logger; struct maat_garbage_bin *MaatGroupExclude::garbage_bin; -TEST_F(MaatGroupExclude, level_3_basic) { +TEST_F(MaatGroupExclude, level_3_function) { char table_line[1024]; struct group2group_rule rules; const char *table_name = "EXCLUDE_GROUP2GROUP"; + void *g2g_runtime = group2group_runtime_new(g2g_schema, 1, garbage_bin, logger); + if (NULL == g2g_runtime) { + log_error(logger, MODULE_GROUP_EXCLUDE_GTEST, "group2group_runtime_new failed."); + assert(0); + } + int ret = parse_config_file("group_exclude_L3.conf", &rules); EXPECT_EQ(ret, 0); @@ -199,7 +196,7 @@ TEST_F(MaatGroupExclude, level_3_basic) { group2group_runtime_commit(g2g_runtime, table_name, 2); super_group_cnt = group2group_runtime_get_super_groups(g2g_runtime, hit_group_ids, 2, - super_group_ids, MAX_ITEM_NUM); + super_group_ids, MAX_ITEM_NUM); EXPECT_EQ(super_group_cnt, 3); EXPECT_EQ(super_group_ids[0], 1); EXPECT_EQ(super_group_ids[1], 6); @@ -213,12 +210,290 @@ TEST_F(MaatGroupExclude, level_3_basic) { group2group_runtime_commit(g2g_runtime, table_name, 3); super_group_cnt = group2group_runtime_get_super_groups(g2g_runtime, hit_group_ids, 2, - super_group_ids, MAX_ITEM_NUM); + super_group_ids, MAX_ITEM_NUM); EXPECT_EQ(super_group_cnt, 4); EXPECT_EQ(super_group_ids[0], 1); EXPECT_EQ(super_group_ids[1], 4); EXPECT_EQ(super_group_ids[2], 6); EXPECT_EQ(super_group_ids[3], 7); + + group2group_runtime_free(g2g_runtime); +} + +TEST_F(MaatGroupExclude, level_3_perf) { + char table_line[1024]; + struct group2group_rule rules; + const char *table_name = "EXCLUDE_GROUP2GROUP"; + + void *g2g_runtime = group2group_runtime_new(g2g_schema, 1, garbage_bin, logger); + if (NULL == g2g_runtime) { + log_error(logger, MODULE_GROUP_EXCLUDE_GTEST, "group2group_runtime_new failed."); + assert(0); + } + + int ret = parse_config_file("group_exclude_L3.conf", &rules); + EXPECT_EQ(ret, 0); + + for (size_t i = 0; i < rules.n_add_item; i++) { + memset(table_line, 0, sizeof(table_line)); + + sprintf(table_line, "%lld\t%lld\t%d\t%d", rules.add_items[i].group_id, + rules.add_items[i].super_group_id, rules.add_items[i].is_exclude, 1); + group2group_runtime_update(g2g_runtime, g2g_schema, table_name, table_line, 4); + } + + group2group_runtime_commit(g2g_runtime, table_name, 4); + + long long hit_group_ids[2] = {11, 13}; + long long super_group_ids[MAX_ITEM_NUM]; + size_t super_group_cnt = 0; + struct timespec start, end; + struct log_handle *logger = MaatGroupExclude::logger; + + clock_gettime(CLOCK_MONOTONIC, &start); + for (int i = 0; i < MAX_G2G_SCAN_TIMES; i++) { + super_group_cnt = group2group_runtime_get_super_groups(g2g_runtime, hit_group_ids, 2, + super_group_ids, MAX_ITEM_NUM); + EXPECT_EQ(super_group_cnt, 2); + EXPECT_EQ(super_group_ids[0], 2); + EXPECT_EQ(super_group_ids[1], 7); + } + clock_gettime(CLOCK_MONOTONIC, &end); + long long time_elapse_ms = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000; + log_info(logger, MODULE_GROUP_EXCLUDE_GTEST, "level_3_basic hit 2 super_groups scan consume time %lldms", + time_elapse_ms); + + //delete group_id = 7, super_group_id = 6, is_exclude = 1 + memset(table_line, 0, sizeof(table_line)); + sprintf(table_line, "%lld\t%lld\t%d\t%d", rules.del_items[0].group_id, + rules.del_items[0].super_group_id, rules.del_items[0].is_exclude, 0); + group2group_runtime_update(g2g_runtime, g2g_schema, table_name, table_line, 4); + group2group_runtime_commit(g2g_runtime, table_name, 5); + + clock_gettime(CLOCK_MONOTONIC, &start); + for (int i = 0; i < MAX_G2G_SCAN_TIMES; i++) { + super_group_cnt = group2group_runtime_get_super_groups(g2g_runtime, hit_group_ids, 2, + super_group_ids, MAX_ITEM_NUM); + EXPECT_EQ(super_group_cnt, 3); + EXPECT_EQ(super_group_ids[0], 1); + EXPECT_EQ(super_group_ids[1], 6); + EXPECT_EQ(super_group_ids[2], 7); + } + clock_gettime(CLOCK_MONOTONIC, &end); + time_elapse_ms = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000; + log_info(logger, MODULE_GROUP_EXCLUDE_GTEST, "level_3_basic hit 3 super_groups scan consume time %lldms", + time_elapse_ms); + + //delete group_id = 13, super_group_id = 4, is_exclude = 1 + memset(table_line, 0, sizeof(table_line)); + sprintf(table_line, "%lld\t%lld\t%d\t%d", rules.del_items[1].group_id, + rules.del_items[1].super_group_id, rules.del_items[1].is_exclude, 0); + group2group_runtime_update(g2g_runtime, g2g_schema, table_name, table_line, 4); + group2group_runtime_commit(g2g_runtime, table_name, 6); + + clock_gettime(CLOCK_MONOTONIC, &start); + for (int i = 0; i < MAX_G2G_SCAN_TIMES; i++) { + super_group_cnt = group2group_runtime_get_super_groups(g2g_runtime, hit_group_ids, 2, + super_group_ids, MAX_ITEM_NUM); + EXPECT_EQ(super_group_cnt, 4); + EXPECT_EQ(super_group_ids[0], 1); + EXPECT_EQ(super_group_ids[1], 4); + EXPECT_EQ(super_group_ids[2], 6); + EXPECT_EQ(super_group_ids[3], 7); + } + clock_gettime(CLOCK_MONOTONIC, &end); + time_elapse_ms = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000; + log_info(logger, MODULE_GROUP_EXCLUDE_GTEST, "level_3_basic hit 4 super_groups scan consume time %lldms", + time_elapse_ms); + + group2group_runtime_free(g2g_runtime); +} + +TEST_F(MaatGroupExclude, level_4_function) { + char table_line[1024]; + struct group2group_rule rules; + const char *table_name = "EXCLUDE_GROUP2GROUP"; + + void *g2g_runtime = group2group_runtime_new(g2g_schema, 1, garbage_bin, logger); + if (NULL == g2g_runtime) { + log_error(logger, MODULE_GROUP_EXCLUDE_GTEST, "group2group_runtime_new failed."); + assert(0); + } + + int ret = parse_config_file("group_exclude_L4.conf", &rules); + EXPECT_EQ(ret, 0); + + for (size_t i = 0; i < rules.n_add_item; i++) { + memset(table_line, 0, sizeof(table_line)); + + sprintf(table_line, "%lld\t%lld\t%d\t%d", rules.add_items[i].group_id, + rules.add_items[i].super_group_id, rules.add_items[i].is_exclude, 1); + group2group_runtime_update(g2g_runtime, g2g_schema, table_name, table_line, 4); + } + + group2group_runtime_commit(g2g_runtime, table_name, 7); + + long long hit_group_ids[2] = {14, 16}; + long long super_group_ids[MAX_ITEM_NUM]; + size_t super_group_cnt = group2group_runtime_get_super_groups(g2g_runtime, hit_group_ids, 2, + super_group_ids, MAX_ITEM_NUM); + EXPECT_EQ(super_group_cnt, 5); + EXPECT_EQ(super_group_ids[0], 4); + EXPECT_EQ(super_group_ids[1], 7); + EXPECT_EQ(super_group_ids[2], 8); + EXPECT_EQ(super_group_ids[3], 9); + EXPECT_EQ(super_group_ids[4], 10); + + //delete group_id = 10, super_group_id = 6, is_exclude = 1 + memset(table_line, 0, sizeof(table_line)); + sprintf(table_line, "%lld\t%lld\t%d\t%d", rules.del_items[0].group_id, + rules.del_items[0].super_group_id, rules.del_items[0].is_exclude, 0); + group2group_runtime_update(g2g_runtime, g2g_schema, table_name, table_line, 4); + group2group_runtime_commit(g2g_runtime, table_name, 8); + + super_group_cnt = group2group_runtime_get_super_groups(g2g_runtime, hit_group_ids, 2, + super_group_ids, MAX_ITEM_NUM); + EXPECT_EQ(super_group_cnt, 7); + EXPECT_EQ(super_group_ids[0], 1); + EXPECT_EQ(super_group_ids[1], 4); + EXPECT_EQ(super_group_ids[2], 6); + EXPECT_EQ(super_group_ids[3], 7); + EXPECT_EQ(super_group_ids[4], 8); + EXPECT_EQ(super_group_ids[5], 9); + EXPECT_EQ(super_group_ids[6], 10); + + group2group_runtime_free(g2g_runtime); +} + +TEST_F(MaatGroupExclude, level_4_perf) { + char table_line[1024]; + struct group2group_rule rules; + const char *table_name = "EXCLUDE_GROUP2GROUP"; + + void *g2g_runtime = group2group_runtime_new(g2g_schema, 1, garbage_bin, logger); + if (NULL == g2g_runtime) { + log_error(logger, MODULE_GROUP_EXCLUDE_GTEST, "group2group_runtime_new failed."); + assert(0); + } + + int ret = parse_config_file("group_exclude_L4.conf", &rules); + EXPECT_EQ(ret, 0); + + for (size_t i = 0; i < rules.n_add_item; i++) { + memset(table_line, 0, sizeof(table_line)); + + sprintf(table_line, "%lld\t%lld\t%d\t%d", rules.add_items[i].group_id, + rules.add_items[i].super_group_id, rules.add_items[i].is_exclude, 1); + group2group_runtime_update(g2g_runtime, g2g_schema, table_name, table_line, 4); + } + + group2group_runtime_commit(g2g_runtime, table_name, 7); + + long long hit_group_ids[2] = {14, 16}; + long long super_group_ids[MAX_ITEM_NUM]; + size_t super_group_cnt = 0; + struct timespec start, end; + struct log_handle *logger = MaatGroupExclude::logger; + + clock_gettime(CLOCK_MONOTONIC, &start); + for (int i = 0; i < MAX_G2G_SCAN_TIMES; i++) { + super_group_cnt = group2group_runtime_get_super_groups(g2g_runtime, hit_group_ids, 2, + super_group_ids, MAX_ITEM_NUM); + EXPECT_EQ(super_group_cnt, 5); + EXPECT_EQ(super_group_ids[0], 4); + EXPECT_EQ(super_group_ids[1], 7); + EXPECT_EQ(super_group_ids[2], 8); + EXPECT_EQ(super_group_ids[3], 9); + EXPECT_EQ(super_group_ids[4], 10); + } + clock_gettime(CLOCK_MONOTONIC, &end); + long long time_elapse_ms = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000; + log_info(logger, MODULE_GROUP_EXCLUDE_GTEST, "level_4_basic hit 5 super_groups scan consume time %lldms", + time_elapse_ms); + + //delete group_id = 10, super_group_id = 6, is_exclude = 1 + memset(table_line, 0, sizeof(table_line)); + sprintf(table_line, "%lld\t%lld\t%d\t%d", rules.del_items[0].group_id, + rules.del_items[0].super_group_id, rules.del_items[0].is_exclude, 0); + group2group_runtime_update(g2g_runtime, g2g_schema, table_name, table_line, 4); + group2group_runtime_commit(g2g_runtime, table_name, 8); + + clock_gettime(CLOCK_MONOTONIC, &start); + for (int i = 0; i < MAX_G2G_SCAN_TIMES; i++) { + super_group_cnt = group2group_runtime_get_super_groups(g2g_runtime, hit_group_ids, 2, + super_group_ids, MAX_ITEM_NUM); + EXPECT_EQ(super_group_cnt, 7); + EXPECT_EQ(super_group_ids[0], 1); + EXPECT_EQ(super_group_ids[1], 4); + EXPECT_EQ(super_group_ids[2], 6); + EXPECT_EQ(super_group_ids[3], 7); + EXPECT_EQ(super_group_ids[4], 8); + EXPECT_EQ(super_group_ids[5], 9); + EXPECT_EQ(super_group_ids[6], 10); + } + clock_gettime(CLOCK_MONOTONIC, &end); + time_elapse_ms = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000; + log_info(logger, MODULE_GROUP_EXCLUDE_GTEST, "level_4_basic hit 7 super_groups scan consume time %lldms", + time_elapse_ms); + + group2group_runtime_free(g2g_runtime); +} + +TEST_F(MaatGroupExclude, level_exceed_function) { + char table_line[1024]; + struct group2group_rule rules; + const char *table_name = "EXCLUDE_GROUP2GROUP"; + + void *g2g_runtime = group2group_runtime_new(g2g_schema, 1, garbage_bin, logger); + if (NULL == g2g_runtime) { + log_error(logger, MODULE_GROUP_EXCLUDE_GTEST, "group2group_runtime_new failed."); + assert(0); + } + + int ret = parse_config_file("group_exclude_exceed.conf", &rules); + EXPECT_EQ(ret, 0); + + for (size_t i = 0; i < rules.n_add_item; i++) { + memset(table_line, 0, sizeof(table_line)); + + sprintf(table_line, "%lld\t%lld\t%d\t%d", rules.add_items[i].group_id, + rules.add_items[i].super_group_id, rules.add_items[i].is_exclude, 1); + group2group_runtime_update(g2g_runtime, g2g_schema, table_name, table_line, 4); + } + + group2group_runtime_commit(g2g_runtime, table_name, 8); + + long long hit_group_ids[2] = {7, 13}; + long long super_group_ids[MAX_ITEM_NUM]; + size_t super_group_cnt = group2group_runtime_get_super_groups(g2g_runtime, hit_group_ids, 2, + super_group_ids, MAX_ITEM_NUM); + EXPECT_EQ(super_group_cnt, 6); + EXPECT_EQ(super_group_ids[0], 4); + EXPECT_EQ(super_group_ids[1], 5); + EXPECT_EQ(super_group_ids[2], 8); + EXPECT_EQ(super_group_ids[3], 10); + EXPECT_EQ(super_group_ids[4], 11); + EXPECT_EQ(super_group_ids[5], 12); + + //delete group_id = 13, super_group_id = 10, is_exclude = 0 + memset(table_line, 0, sizeof(table_line)); + sprintf(table_line, "%lld\t%lld\t%d\t%d", rules.del_items[0].group_id, + rules.del_items[0].super_group_id, rules.del_items[0].is_exclude, 0); + group2group_runtime_update(g2g_runtime, g2g_schema, table_name, table_line, 4); + group2group_runtime_commit(g2g_runtime, table_name, 9); + + hit_group_ids[0] = 7; + hit_group_ids[1] = 10; + super_group_cnt = group2group_runtime_get_super_groups(g2g_runtime, hit_group_ids, 2, + super_group_ids, MAX_ITEM_NUM); + EXPECT_EQ(super_group_cnt, 5); + EXPECT_EQ(super_group_ids[0], 2); + EXPECT_EQ(super_group_ids[1], 4); + EXPECT_EQ(super_group_ids[2], 5); + EXPECT_EQ(super_group_ids[3], 8); + EXPECT_EQ(super_group_ids[4], 11); + + group2group_runtime_free(g2g_runtime); } int main(int argc, char ** argv) @@ -227,4 +502,4 @@ int main(int argc, char ** argv) ::testing::InitGoogleTest(&argc, argv); ret=RUN_ALL_TESTS(); return ret; -} +} \ No newline at end of file diff --git a/test/maat_framework_gtest.cpp b/test/maat_framework_gtest.cpp index fd47047..bcfba6f 100644 --- a/test/maat_framework_gtest.cpp +++ b/test/maat_framework_gtest.cpp @@ -343,7 +343,8 @@ class MaatIris : public testing::Test { protected: static void SetUpTestCase() { - const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"},{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; logger = log_handle_create("./maat_framework_gtest.log", 0); @@ -537,7 +538,8 @@ class MaatFlagScan : public testing::Test { protected: static void SetUpTestCase() { - const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"},{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; char redis_ip[64] = "127.0.0.1"; int redis_port = 6379; int redis_db = 0; @@ -592,8 +594,9 @@ TEST_F(MaatFlagScan, basic) { int ret = maat_scan_flag(maat_instance, flag_table_id, scan_data, results, ARRAY_SIZE, &n_hit_result, state); EXPECT_EQ(ret, MAAT_SCAN_HIT); - EXPECT_EQ(n_hit_result, 1); - EXPECT_EQ(results[0], 192); + EXPECT_EQ(n_hit_result, 2); + EXPECT_EQ(results[0], 207); + EXPECT_EQ(results[1], 192); struct maat_hit_path hit_path[HIT_PATH_SIZE] = {0}; int n_read = 0; @@ -607,8 +610,9 @@ TEST_F(MaatFlagScan, basic) { ret = maat_scan_flag(maat_instance, flag_table_id, scan_data, results, ARRAY_SIZE, &n_hit_result, state); EXPECT_EQ(ret, MAAT_SCAN_HIT); - EXPECT_EQ(n_hit_result, 1); - EXPECT_EQ(results[0], 192); + EXPECT_EQ(n_hit_result, 2); + EXPECT_EQ(results[0], 207); + EXPECT_EQ(results[1], 192); maat_state_reset(state); scan_data = 6; @@ -675,9 +679,10 @@ TEST_F(MaatFlagScan, hitMultiCompile) { int ret = maat_scan_flag(maat_instance, flag_table_id, flag_scan_data, results, ARRAY_SIZE, &n_hit_result, state); EXPECT_EQ(ret, MAAT_SCAN_HIT); - EXPECT_EQ(n_hit_result, 2); - EXPECT_EQ(results[0], 194); - EXPECT_EQ(results[1], 192); + EXPECT_EQ(n_hit_result, 3); + EXPECT_EQ(results[0], 207); + EXPECT_EQ(results[1], 194); + EXPECT_EQ(results[2], 192); memset(results, 0, sizeof(results)); ret = maat_scan_flag(maat_instance, flag_table_id, flag_scan_data, results, @@ -709,8 +714,9 @@ TEST_F(MaatFlagScan, hitRepeatedCompile) { int ret = maat_scan_flag(maat_instance, flag_table_id, flag_scan_data1, results, ARRAY_SIZE, &n_hit_result, state); EXPECT_EQ(ret, MAAT_SCAN_HIT); - EXPECT_EQ(n_hit_result, 1); - EXPECT_EQ(results[0], 192); + EXPECT_EQ(n_hit_result, 2); + EXPECT_EQ(results[0], 207); + EXPECT_EQ(results[1], 192); //compile_id:192 flag: 0000 0001 mask: 0000 0011 //compile_id:194 flag: 0001 0101 mask: 0001 1111 @@ -780,7 +786,8 @@ class MaatStringScan : public testing::Test { protected: static void SetUpTestCase() { - const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"},{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; char redis_ip[64] = "127.0.0.1"; int redis_port = 6379; int redis_db = 0; @@ -879,28 +886,6 @@ TEST_F(MaatStringScan, Regex) { EXPECT_EQ(results[0], 146); maat_state_free(state); state = NULL; - //TODO: -#if 0 - size_t i = 0; - n_hit_result = 0; - memset(results, 0, sizeof(results)); - const char *sni_should_not_hit[] = {"instagram.fbcdn.net", "a.instagram.fbcdn.net"}; - const char *sni_should_hit[] = {"xx.fbcdn.net", "ainstagram.fbcdn.net"}; - for (i = 0; i < sizeof(sni_should_not_hit)/sizeof(const char *); i++) { - ret = maat_scan_string(g_maat_instance, table_id, 0, sni_should_not_hit[i], strlen(sni_should_not_hit[i]), - results, 5, &n_hit_result, &state); - EXPECT_EQ(ret, 0); - maat_state_free(&state); - } - - for (i = 0; i < sizeof(sni_should_hit)/sizeof(const char *); i++) { - ret = maat_scan_string(g_maat_instance, table_id, 0, sni_should_hit[i], strlen(sni_should_hit[i]), - results, 5, &n_hit_result, &state); - EXPECT_GE(ret, 1); - EXPECT_EQ(results[0], 149); - maat_state_free(&state); - } -#endif } TEST_F(MaatStringScan, ExprPlus) { @@ -1139,8 +1124,9 @@ TEST_F(MaatStringScan, HexBinCaseSensitive) { ret = maat_scan_string(maat_instance, table_id, scan_data2, strlen(scan_data2), results, ARRAY_SIZE, &n_hit_result, state); EXPECT_EQ(ret, MAAT_SCAN_HIT); - EXPECT_EQ(n_hit_result, 1); - EXPECT_EQ(results[0], 191); + EXPECT_EQ(n_hit_result, 2); + EXPECT_EQ(results[0], 206); + EXPECT_EQ(results[1], 191); maat_state_free(state); } @@ -1249,36 +1235,6 @@ TEST_F(MaatStringScan, MaatUnescape) { state = NULL; } -#if 0 -TEST_F(MaatStringScan, RegexWithNotContains) { - const char *should_NOT_hit_scan_data = "new.qq.com/rain/a/TWF2021042600418000"; - const char *should_hit_scan_data = "fakesina.com/rain/a/TWF2021042600418000"; - const char *table_name = "HTTP_URL"; - struct maat *maat_instance = MaatStringScan::_shared_maat_instance; - int thread_id = 0; - - int table_id = maat_get_table_id(maat_instance, table_name); - ASSERT_GT(table_id, 0); - - long long results[ARRAY_SIZE] = {0}; - size_t n_hit_result = 0; - struct maat_state *state = maat_state_new(maat_instance, thread_id); - - int ret = maat_scan_string(maat_instance, table_id, should_NOT_hit_scan_data, - strlen(should_NOT_hit_scan_data), results, ARRAY_SIZE, - &n_hit_result, state); - EXPECT_EQ(ret, MAAT_SCAN_OK); - maat_state_reset(state); - - ret = maat_scan_string(maat_instance, table_id, should_hit_scan_data, - strlen(should_hit_scan_data), results, ARRAY_SIZE, - &n_hit_result, state); - EXPECT_EQ(ret, MAAT_SCAN_HIT); - EXPECT_EQ(n_hit_result, 1); - EXPECT_EQ(results[0], 183); - maat_state_free(state); -} -#endif TEST_F(MaatStringScan, OffsetChunk64) { const char *table_name = "IMAGE_FP"; const char *file_name = "./testdata/mesa_logo.jpg"; @@ -1356,29 +1312,45 @@ TEST_F(MaatStringScan, OffsetChunk1460) { maat_state_free(state); state = NULL; } -#if 0 -TEST_F(MaatStringScan, GBKEncodedURL) { - const char *table_name = "HTTP_URL"; + +TEST_F(MaatStringScan, StreamScanUTF8) { + const char *table_name = "TROJAN_PAYLOAD"; + const char* file_name = "./testdata/jd.com.html"; long long results[ARRAY_SIZE] = {0}; size_t n_hit_result = 0; int thread_id = 0; + char scan_data[2048]; struct maat *maat_instance = MaatStringScan::_shared_maat_instance; struct maat_state *state = maat_state_new(maat_instance, thread_id); - const char *url_gb2312 = "www.baidu.com/?wd=C%23%D6%D0%B9%FA"; + + FILE *fp = fopen(file_name, "r"); + ASSERT_FALSE(fp == NULL); int table_id = maat_get_table_id(maat_instance, table_name); ASSERT_GT(table_id, 0); - int ret = maat_scan_string(maat_instance, table_id, thread_id, url_gb2312, - strlen(url_gb2312), results, ARRAY_SIZE, &n_hit_result, - state); - EXPECT_EQ(ret, MAAT_SCAN_HIT); - EXPECT_EQ(n_hit_result, 1); - EXPECT_EQ(results[0], 129); + struct maat_stream *sp = maat_stream_new(maat_instance, table_id, state); + ASSERT_FALSE(sp == NULL); + + int pass_flag = 0; + while (0 == feof(fp)) { + size_t read_size = fread(scan_data, 1, sizeof(scan_data), fp); + int ret = maat_stream_scan(sp, scan_data, read_size, results, ARRAY_SIZE, + &n_hit_result, state); + if (ret == MAAT_SCAN_HIT) { + pass_flag = 1; + break; + } + } + + EXPECT_EQ(pass_flag, 1); + EXPECT_EQ(results[0], 157); + maat_stream_free(sp); + fclose(fp); maat_state_free(state); state = NULL; } -#endif + TEST_F(MaatStringScan, StreamInput) { long long results[ARRAY_SIZE] = {0}; size_t n_hit_result = 0; @@ -1577,7 +1549,8 @@ class MaatIPScan : public testing::Test { protected: static void SetUpTestCase() { - const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"},{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; char redis_ip[64] = "127.0.0.1"; int redis_port = 6379; int redis_db = 0; @@ -1637,8 +1610,9 @@ TEST_F(MaatIPScan, IPv4_IPPort) { ret = maat_scan_ipv4(maat_instance, table_id, sip, port, proto, results, ARRAY_SIZE, &n_hit_result, state); EXPECT_EQ(ret, MAAT_SCAN_HIT); - EXPECT_EQ(n_hit_result, 1); - EXPECT_EQ(results[0], 154); + EXPECT_EQ(n_hit_result, 2); + EXPECT_EQ(results[0], 208); + EXPECT_EQ(results[1], 154); maat_state_free(state); state = NULL; } @@ -1808,7 +1782,8 @@ class MaatIntervalScan : public testing::Test { protected: static void SetUpTestCase() { - const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"},{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; char redis_ip[64] = "127.0.0.1"; int redis_port = 6379; int redis_db = 0; @@ -1889,8 +1864,9 @@ TEST_F(MaatIntervalScan, IntervalPlus) { ret = maat_scan_integer(maat_instance, table_id, scan_data1, results, ARRAY_SIZE, &n_hit_result, state); EXPECT_EQ(ret, MAAT_SCAN_HIT); - EXPECT_EQ(n_hit_result, 1); - EXPECT_EQ(results[0], 179); + EXPECT_EQ(n_hit_result, 2); + EXPECT_EQ(results[0], 209); + EXPECT_EQ(results[1], 179); maat_state_free(state); state = NULL; } @@ -1899,7 +1875,8 @@ class NOTLogic : public testing::Test { protected: static void SetUpTestCase() { - const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"},{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; char redis_ip[64] = "127.0.0.1"; int redis_port = 6379; int redis_db = 0; @@ -1939,7 +1916,8 @@ struct log_handle *NOTLogic::logger; TEST_F(NOTLogic, OneRegion) { const char *string_should_hit = "This string ONLY contains must-contained-string-of-rule-143."; - const char *string_should_not_hit = "This string contains both must-contained-string-of-rule-143 and must-not-contained-string-of-rule-143."; + const char *string_should_not_hit = "This string contains both must-contained-string-of-rule-143 " + "and must-not-contained-string-of-rule-143."; long long results[ARRAY_SIZE] = {0}; size_t n_hit_result = 0; int thread_id = 0; @@ -1968,8 +1946,9 @@ TEST_F(NOTLogic, OneRegion) { } TEST_F(NOTLogic, ScanNotAtLast) { - const char *string_should_hit="This string ONLY contains must-contained-string-of-rule-144."; - const char *string_should_not_hit="This string contains both must-contained-string-of-rule-144 and must-not-contained-string-of-rule-144."; + const char *string_should_hit = "This string ONLY contains must-contained-string-of-rule-144."; + const char *string_should_not_hit = "This string contains both must-contained-string-of-rule-144 " + "and must-not-contained-string-of-rule-144."; long long results[ARRAY_SIZE] = {0}; size_t n_hit_result = 0; int thread_id = 0; @@ -2154,7 +2133,8 @@ class ExcludeLogic : public testing::Test { protected: static void SetUpTestCase() { - const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"},{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; char redis_ip[64] = "127.0.0.1"; int redis_port = 6379; int redis_db = 0; @@ -2428,96 +2408,6 @@ TEST_F(ExcludeLogic, ExcludeInDifferentLevel) { maat_state_free(state); } -// TEST_F(ExcludeLogic, ScanHitAtLastEmptyExpr) { -// const char *string_should_not_hit = "This string should not hit."; -// const char *string_match_no_region = "This string is matched against a empty table."; -// long long results[ARRAY_SIZE] = {0}; -// size_t n_hit_result = 0; -// int thread_id = 0; -// const char *not_hit_table_name = "HTTP_URL"; -// const char *hit_table_name = "IP_PLUS_CONFIG"; -// const char *empty_table_name = "EMPTY_KEYWORD"; -// struct maat *maat_instance = ExcludeLogic::_shared_maat_instance; -// struct maat_state *state = maat_state_new(maat_instance, thread_id); - -// int not_hit_table_id = maat_get_table_id(maat_instance, not_hit_table_name); -// ASSERT_GT(not_hit_table_id, 0); - -// int ret = maat_scan_string(maat_instance, not_hit_table_id, -// string_should_not_hit, strlen(string_should_not_hit), -// results, ARRAY_SIZE, &n_hit_result, state); -// EXPECT_EQ(ret, MAAT_SCAN_OK); - -// uint32_t sip; -// inet_pton(AF_INET, "10.0.8.186", &sip); -// uint16_t port = htons(18611); -// int proto = 6; - -// int hit_table_id = maat_get_table_id(maat_instance, hit_table_name); -// ASSERT_GT(hit_table_id, 0); - -// ret = maat_scan_ipv4(maat_instance, hit_table_id, sip, port, proto, results, -// ARRAY_SIZE, &n_hit_result, state); -// EXPECT_EQ(ret, MAAT_SCAN_HIT); -// EXPECT_EQ(n_hit_result, 1); -// EXPECT_EQ(results[0], 186); - -// int empty_table_id = maat_get_table_id(maat_instance, empty_table_name); -// ASSERT_GT(empty_table_id, 0); - -// ret = maat_scan_string(maat_instance, empty_table_id, string_match_no_region, -// strlen(string_match_no_region), results, ARRAY_SIZE, -// &n_hit_result, state); -// EXPECT_EQ(ret, MAAT_SCAN_OK); - -// maat_state_free(state); -// state = NULL; -// } - -// TEST_F(ExcludeLogic, ScanHitAtLastEmptyInteger) { -// const char *string_should_not_hit = "This string should not hit."; -// long long results[ARRAY_SIZE] = {0}; -// size_t n_hit_result = 0; -// int thread_id = 0; -// const char *not_hit_table_name = "HTTP_URL"; -// const char *hit_table_name = "IP_PLUS_CONFIG"; -// const char *empty_table_name = "EMPTY_INTERGER"; -// struct maat *maat_instance = ExcludeLogic::_shared_maat_instance; -// struct maat_state *state = maat_state_new(maat_instance, thread_id); - -// int not_hit_table_id = maat_get_table_id(maat_instance, not_hit_table_name); -// ASSERT_GT(not_hit_table_id, 0); - -// int ret = maat_scan_string(maat_instance, not_hit_table_id, string_should_not_hit, -// strlen(string_should_not_hit), results, ARRAY_SIZE, -// &n_hit_result, state); -// EXPECT_EQ(ret, MAAT_SCAN_OK); - -// uint32_t sip; -// inet_pton(AF_INET, "10.0.8.187", &sip); -// uint16_t port = htons(18611); -// int proto = 6; - -// int hit_table_id = maat_get_table_id(maat_instance, hit_table_name); -// ASSERT_GT(hit_table_id, 0); - -// ret = maat_scan_ipv4(maat_instance, hit_table_id, sip, port, proto, -// results, ARRAY_SIZE, &n_hit_result, state); -// EXPECT_EQ(ret, MAAT_SCAN_HIT); -// EXPECT_EQ(n_hit_result, 1); -// EXPECT_EQ(results[0], 187); - -// int empty_table_id = maat_get_table_id(maat_instance, empty_table_name); -// ASSERT_GT(empty_table_id, 0); - -// ret = maat_scan_integer(maat_instance, empty_table_id, 2015, -// results, ARRAY_SIZE, &n_hit_result, state); -// EXPECT_EQ(ret, MAAT_SCAN_OK); - -// maat_state_free(state); -// state = NULL; -// } - TEST_F(ExcludeLogic, ScanNotIP) { const char *string_should_hit = "This string ONLY contains must-contained-string-of-rule-201."; long long results[ARRAY_SIZE] = {0}; @@ -2595,7 +2485,8 @@ class PluginTable : public testing::Test { protected: static void SetUpTestCase() { - const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"},{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; char redis_ip[64] = "127.0.0.1"; int redis_port = 6379; int redis_db = 0; @@ -2751,7 +2642,8 @@ class IPPluginTable : public testing::Test { protected: static void SetUpTestCase() { - const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"},{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; char redis_ip[64] = "127.0.0.1"; int redis_port = 6379; int redis_db = 0; @@ -2892,7 +2784,8 @@ class FQDNPluginTable : public testing::Test { protected: static void SetUpTestCase() { - const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"},{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; char redis_ip[64] = "127.0.0.1"; int redis_port = 6379; int redis_db = 0; @@ -3060,7 +2953,8 @@ class BoolPluginTable : public testing::Test { protected: static void SetUpTestCase() { - const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"},{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; char redis_ip[64] = "127.0.0.1"; int redis_port = 6379; int redis_db = 0; @@ -3116,14 +3010,16 @@ TEST_F(BoolPluginTable, EX_DATA) { struct bool_plugin_ud *result[6]; unsigned long long items_1[] = {999}; - ret = maat_bool_plugin_table_get_ex_data(maat_instance, table_id, items_1, 1, (void**)result, 6); + ret = maat_bool_plugin_table_get_ex_data(maat_instance, table_id, items_1, + 1, (void**)result, 6); EXPECT_EQ(ret, 0); for (i = 0; i < ret; i++) { bool_plugin_ex_free_cb(0, (void**)&(result[i]), 0, NULL); } unsigned long long items_2[] = {1, 2, 1000}; - ret = maat_bool_plugin_table_get_ex_data(maat_instance, table_id, items_2, 3, (void**)result, 6); + ret = maat_bool_plugin_table_get_ex_data(maat_instance, table_id, items_2, + 3, (void**)result, 6); EXPECT_EQ(ret, 1); EXPECT_EQ(result[0]->id, 301); for (i = 0; i < ret; i++) { @@ -3131,14 +3027,17 @@ TEST_F(BoolPluginTable, EX_DATA) { } unsigned long long items_3[]={101, 102, 1000}; - ret = maat_bool_plugin_table_get_ex_data(maat_instance, table_id, items_3, 3, (void**)result, 6); + ret = maat_bool_plugin_table_get_ex_data(maat_instance, table_id, items_3, + 3, (void**)result, 6); EXPECT_EQ(ret, 4); for (i = 0; i < ret; i++) { bool_plugin_ex_free_cb(0, (void**)&(result[i]), 0, NULL); } unsigned long long items_4[]={7, 0, 1, 2, 3, 4, 5, 6, 7, 7, 7}; - ret = maat_bool_plugin_table_get_ex_data(maat_instance, table_id, items_4, sizeof(items_4)/sizeof(unsigned long long), (void**)result, 6); + ret = maat_bool_plugin_table_get_ex_data(maat_instance, table_id, items_4, + sizeof(items_4)/sizeof(unsigned long long), + (void**)result, 6); EXPECT_EQ(ret, 1); EXPECT_EQ(result[0]->id, 305); for (i = 0; i < ret; i++) { @@ -3150,7 +3049,8 @@ class VirtualTable : public testing::Test { protected: static void SetUpTestCase() { - const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"},{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; char redis_ip[64] = "127.0.0.1"; int redis_port = 6379; int redis_db = 0; @@ -3211,7 +3111,8 @@ class CompileTable : public testing::Test { protected: static void SetUpTestCase() { - const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"},{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; char redis_ip[64] = "127.0.0.1"; int redis_port = 6379; int redis_db = 0; @@ -3324,7 +3225,8 @@ TEST_F(CompileTable, Conjunction1) { long long results[ARRAY_SIZE] = {0}; size_t n_hit_result = 0; int thread_id = 0; - const char *scan_data = "i.ytimg.com/vi/OtCNcustg_I/hqdefault.jpg?sqp=-oaymwEZCNACELwBSFXyq4qpAwsIARUAAIhCGAFwAQ==&rs=AOn4CLDOp_5fHMaCA9XZuJdCRv4DNDorMg"; + const char *scan_data = "i.ytimg.com/vi/OtCNcustg_I/hqdefault.jpg?sqp=-oaymwEZCNAC" + "ELwBSFXyq4qpAwsIARUAAIhCGAFwAQ==&rs=AOn4CLDOp_5fHMaCA9XZuJdCRv4DNDorMg"; const char *table_name = "HTTP_URL"; struct maat *maat_instance = CompileTable::_shared_maat_instance; struct maat_state *state = maat_state_new(maat_instance, thread_id); @@ -3350,7 +3252,8 @@ TEST_F(CompileTable, Conjunction2) { long long results[ARRAY_SIZE] = {0}; size_t n_hit_result = 0; int thread_id = 0; - const char *scan_data = "i.ytimg.com/vi/OtCNcustg_I/hqdefault.jpg?sqp=-oaymwEZCNACELwBSFXyq4qpAwsIARUAAIhCGAFwAQ==&rs=AOn4CLDOp_5fHMaCA9XZuJdCRv4DNDorMg"; + const char *scan_data = "i.ytimg.com/vi/OtCNcustg_I/hqdefault.jpg?sqp=-oaymwEZCNACELw" + "BSFXyq4qpAwsIARUAAIhCGAFwAQ==&rs=AOn4CLDOp_5fHMaCA9XZuJdCRv4DNDorMg"; const char *table_name = "HTTP_URL"; struct maat *maat_instance = CompileTable::_shared_maat_instance; struct maat_state *state = maat_state_new(maat_instance, thread_id); @@ -3634,7 +3537,8 @@ class TableInfo : public testing::Test { protected: static void SetUpTestCase() { - const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"},{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; char redis_ip[64] = "127.0.0.1"; int redis_port = 6379; int redis_db = 0; @@ -3798,7 +3702,8 @@ class HierarchyTest : public testing::Test { protected: static void SetUpTestCase() { - const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"},{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; char redis_ip[64] = "127.0.0.1"; int redis_port = 6379; int redis_db = 0; @@ -4331,8 +4236,10 @@ TEST_F(MaatCmdTest, SubGroup) { const char *compile_table_name = "COMPILE"; const char *scan_data1 = "www.v2ex.com/t/573028#程序员的核心竞争力是什么"; const char *keyword1 = "程序员&核心竞争力"; - const char *scan_data2 = "https://ask.leju.com/bj/detail/12189672562229248/?bi=tg&type=sina-pc&pos=index-dbtlwzl&wt_campaign=M_5CE750003F393&wt_source=PDPS_514ACACFD9E770"; - const char *keyword2 = "ask.leju.com/b&/detail/12189672562229248/?&?bi=tg\\&type=sina-pc\\&&\\&pos=index-dbtlwzl\\&&\\&type=sina-pc\\&pos=index-dbtlwzl\\&"; + const char *scan_data2 = "https://ask.leju.com/bj/detail/12189672562229248/?bi=tg&type=sina-pc" + "&pos=index-dbtlwzl&wt_campaign=M_5CE750003F393&wt_source=PDPS_514ACACFD9E770"; + const char *keyword2 = "ask.leju.com/b&/detail/12189672562229248/?&?bi=tg\\&type=sina-pc\\&&\\&pos=" + "index-dbtlwzl\\&&\\&type=sina-pc\\&pos=index-dbtlwzl\\&"; int thread_id = 0; struct maat *maat_instance = MaatCmdTest::_shared_maat_instance; struct maat_state *state = maat_state_new(maat_instance, thread_id); @@ -4602,7 +4509,8 @@ TEST_F(MaatCmdTest, VirtualTable) { sleep(2); - const char* http_req_hdr_ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"; + const char* http_req_hdr_ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " + "(KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"; const char* http_resp_hdr_cookie = "uid=12345678;BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; sugstore=1;"; long long results[ARRAY_SIZE] = {0}; size_t n_hit_result = 0; @@ -5058,7 +4966,8 @@ TEST_F(MaatCmdTest, UpdateIPPlugin) { inet_pton(AF_INET, "192.168.30.100", &(ipv4.ipv4)); memset(results, 0, sizeof(results)); - ret = maat_ip_plugin_table_get_ex_data(maat_instance, table_id, &ipv4, (void **)results, ARRAY_SIZE); + ret = maat_ip_plugin_table_get_ex_data(maat_instance, table_id, &ipv4, + (void **)results, ARRAY_SIZE); EXPECT_EQ(ret, 2); EXPECT_EQ(results[0]->rule_id, 101); EXPECT_EQ(results[1]->rule_id, 102); @@ -5070,7 +4979,8 @@ TEST_F(MaatCmdTest, UpdateIPPlugin) { inet_pton(AF_INET6, "2001:db8:1234::5210", &(ipv6.ipv6)); memset(results, 0, sizeof(results)); - ret = maat_ip_plugin_table_get_ex_data(maat_instance, table_id, &ipv6, (void **)results, ARRAY_SIZE); + ret = maat_ip_plugin_table_get_ex_data(maat_instance, table_id, &ipv6, + (void **)results, ARRAY_SIZE); EXPECT_EQ(ret, 2); EXPECT_EQ(results[0]->rule_id, 104); EXPECT_EQ(results[1]->rule_id, 103); @@ -5093,7 +5003,8 @@ TEST_F(MaatCmdTest, UpdateIPPlugin) { sleep(WAIT_FOR_EFFECTIVE_S); memset(results, 0, sizeof(results)); - ret = maat_ip_plugin_table_get_ex_data(maat_instance, table_id, &ipv4, (void **)results, ARRAY_SIZE); + ret = maat_ip_plugin_table_get_ex_data(maat_instance, table_id, &ipv4, + (void **)results, ARRAY_SIZE); EXPECT_EQ(ret, 0); } @@ -5326,7 +5237,8 @@ TEST_F(MaatCmdTest, GroupInMassCompiles) { sleep(WAIT_FOR_EFFECTIVE_S); const char* http_url1 = "https://www.baidu.com/s?wd=tsg"; - const char* http_url2 = "https://www.baidu.com/s?wd=zhengzhou&rsv_spt=1&rsv_iqid=0x8b4cae8100000560&issp=1&f=8&rsv_bp=1"; + const char* http_url2 = "https://www.baidu.com/s?wd=zhengzhou&rsv_spt=1" + "&rsv_iqid=0x8b4cae8100000560&issp=1&f=8&rsv_bp=1"; int url_table_id = maat_get_table_id(maat_instance, table_url); ASSERT_GT(url_table_id, 0); @@ -5446,7 +5358,8 @@ TEST_F(MaatCmdTest, HitPath) { sleep(WAIT_FOR_EFFECTIVE_S); const char* http_url = "en.wikipedia.org/wiki/Path_(graph_theory)"; - const char* http_resp_hdr_cookie = "laptop=thinkpad X1 extrem;time=2020-02-11T15:34:00;main[XWJOKE]=hoho; Hm_lvt_bbac0322e6ee13093f98d5c4b5a10912=1578874808;"; + const char* http_resp_hdr_cookie = "laptop=thinkpad X1 extrem;time=2020-02-11T15:34:00;" + "main[XWJOKE]=hoho; Hm_lvt_bbac0322e6ee13093f98d5c4b5a10912=1578874808;"; int table_id = maat_get_table_id(maat_instance, "HTTP_REQUEST_HEADER"); ASSERT_GT(table_id, 0); @@ -5937,6 +5850,68 @@ TEST_F(MaatCmdTest, UpdateDeadLockDetection) { state = NULL; } +TEST_F(MaatCmdTest, StreamScanWhenExprTableIncUpdate) { + const char* g2c_table_name = "GROUP2COMPILE"; + const char* compile_table_name = "COMPILE"; + const char* scan_table_name = "KEYWORDS_TABLE"; + int thread_id = 0; + struct maat *maat_instance = MaatCmdTest::_shared_maat_instance; + struct maat_state *state = maat_state_new(maat_instance, thread_id); + + long long compile1_id = maat_cmd_incrby(maat_instance, "TEST_SEQ", 1); + int ret = compile_table_set_line(maat_instance, compile_table_name, MAAT_OP_ADD, compile1_id, + "null", 1, 0); + EXPECT_EQ(ret, 1); + + //group1 -> compile1 + long long group1_id = maat_cmd_incrby(maat_instance, "SEQUENCE_GROUP", 1); + ret = group2compile_table_set_line(maat_instance, g2c_table_name, MAAT_OP_ADD, group1_id, + compile1_id, 0, "null", 0, 0); + EXPECT_EQ(ret, 1); + + sleep(WAIT_FOR_EFFECTIVE_S); + + const char *scan_data = "Here is a stream-keywords-001-inc-update, this should hit."; + long long results[ARRAY_SIZE] = {0}; + size_t n_hit_result = 0; + + int table_id = maat_get_table_id(maat_instance, scan_table_name); + ASSERT_GT(table_id, 0); + + struct maat_stream *stream = maat_stream_new(maat_instance, table_id, state); + ret = maat_stream_scan(stream, scan_data, strlen(scan_data), results, ARRAY_SIZE, + &n_hit_result, state); + EXPECT_EQ(ret, MAAT_SCAN_OK); + + //item1 -> group1 -> compile1 + long long item1_id = maat_cmd_incrby(maat_instance, "SEQUENCE_REGION", 1); + ret = expr_table_set_line(maat_instance, scan_table_name, MAAT_OP_ADD, item1_id, group1_id, + "stream-keywords-001-inc-update", NULL, 0, 0, 0, 0); /*EXPR_TYPE_STRING MATCH_METHOD_SUB*/ + EXPECT_EQ(ret, 1); + + sleep(WAIT_FOR_EFFECTIVE_S); + + /* maat_stream store expr_runtime version when maat_stream_new(). + Add new expr_item has changed expr_runtime version which has been sensed by maat_stream_scan. + */ + ret = maat_stream_scan(stream, scan_data, strlen(scan_data), results, ARRAY_SIZE, + &n_hit_result, state); + EXPECT_EQ(ret, MAAT_SCAN_OK); + + maat_stream_free(stream); + + stream = maat_stream_new(maat_instance, table_id, state); + ret = maat_stream_scan(stream, scan_data, strlen(scan_data), results, ARRAY_SIZE, + &n_hit_result, state); + EXPECT_EQ(ret, MAAT_SCAN_HIT); + EXPECT_EQ(n_hit_result, 1); + EXPECT_EQ(results[0], compile1_id); + + maat_stream_free(stream); + maat_state_free(state); + state = NULL; +} + TEST_F(MaatCmdTest, StreamScanSegfaultWhenVersionRollBack_TSG6324) { const char* g2c_table_name = "GROUP2COMPILE"; const char* compile_table_name = "COMPILE"; @@ -5959,12 +5934,12 @@ TEST_F(MaatCmdTest, StreamScanSegfaultWhenVersionRollBack_TSG6324) { //item1 -> group1 -> compile1 long long item1_id = maat_cmd_incrby(maat_instance, "SEQUENCE_REGION", 1); ret = expr_table_set_line(maat_instance, scan_table_name, MAAT_OP_ADD, item1_id, group1_id, - "stream-keywords-001", NULL, 0, 0, 0, 0); /*EXPR_TYPE_STRING MATCH_METHOD_SUB*/ + "stream-keywords-002", NULL, 0, 0, 0, 0); /*EXPR_TYPE_STRING MATCH_METHOD_SUB*/ EXPECT_EQ(ret, 1); sleep(WAIT_FOR_EFFECTIVE_S); - const char *scan_data = "Here is a stream-keywords-001, this should hit."; + const char *scan_data = "Here is a stream-keywords-002, this should hit."; long long results[ARRAY_SIZE] = {0}; size_t n_hit_result = 0; @@ -5989,18 +5964,382 @@ TEST_F(MaatCmdTest, StreamScanSegfaultWhenVersionRollBack_TSG6324) { ret = maat_stream_scan(stream, scan_data, strlen(scan_data), results, ARRAY_SIZE, &n_hit_result, state); - EXPECT_EQ(ret, 0); //Scan was interupted after full update. + EXPECT_EQ(ret, MAAT_SCAN_OK); //Scan was interupted after full update. maat_stream_free(stream); maat_state_free(state); state = NULL; } +TEST_F(MaatCmdTest, IPAndStreamScanWhenIncUpdate) { + const char *g2c_table_name = "GROUP2COMPILE"; + const char *compile_table_name = "COMPILE"; + const char *expr_table_name = "KEYWORDS_TABLE"; + const char *ip_table_name = "IP_PLUS_CONFIG"; + int thread_id = 0; + struct maat *maat_instance = MaatCmdTest::_shared_maat_instance; + struct maat_state *state = maat_state_new(maat_instance, thread_id); + + long long compile1_id = maat_cmd_incrby(maat_instance, "TEST_SEQ", 1); + int ret = compile_table_set_line(maat_instance, compile_table_name, MAAT_OP_ADD, compile1_id, + "null", 2, 0); + EXPECT_EQ(ret, 1); + + //group1 -> compile1 + long long group1_id = maat_cmd_incrby(maat_instance, "SEQUENCE_GROUP", 1); + ret = group2compile_table_set_line(maat_instance, g2c_table_name, MAAT_OP_ADD, group1_id, + compile1_id, 0, "null", 0, 0); + EXPECT_EQ(ret, 1); + + //item1 -> group1 -> compile1 + long long item1_id = maat_cmd_incrby(maat_instance, "SEQUENCE_REGION", 1); + ret = expr_table_set_line(maat_instance, expr_table_name, MAAT_OP_ADD, item1_id, group1_id, + "stream-keywords-003", NULL, 0, 0, 0, 0); /*EXPR_TYPE_STRING MATCH_METHOD_SUB*/ + EXPECT_EQ(ret, 1); + + /* item1 -> group1 -> compile1 + / + item2 -> group2 --/ + */ + long long item2_id = maat_cmd_incrby(maat_instance, "SEQUENCE_REGION", 1); + long long group2_id = maat_cmd_incrby(maat_instance, "SEQUENCE_GROUP", 1); + ret = ip_table_set_line(maat_instance, ip_table_name, MAAT_OP_ADD, item2_id, group2_id, + IPv4, "100.100.100.1", "100.100.100.1", 100, 100, 0); + EXPECT_EQ(ret, 1); + + ret = group2compile_table_set_line(maat_instance, g2c_table_name, MAAT_OP_ADD, group2_id, + compile1_id, 0, "null", 1, 0); + EXPECT_EQ(ret, 1); + + sleep(WAIT_FOR_EFFECTIVE_S); + + long long results[ARRAY_SIZE] = {0}; + size_t n_hit_result = 0; + char ip_str[32] = "100.100.100.1"; + uint32_t ip_addr; + ret = inet_pton(AF_INET, ip_str, &ip_addr); + EXPECT_EQ(ret, 1); + + uint16_t port = htons(100); + int proto = 6; + + int table_id = maat_get_table_id(maat_instance, ip_table_name); + ASSERT_GT(table_id, 0); + + ret = maat_scan_ipv4(maat_instance, table_id, ip_addr, port, proto, results, + ARRAY_SIZE, &n_hit_result, state); + EXPECT_EQ(ret, MAAT_SCAN_HALF_HIT); + + //add compile2 for compile runtime inc update + long long compile2_id = maat_cmd_incrby(maat_instance, "TEST_SEQ", 1); + ret = compile_table_set_line(maat_instance, compile_table_name, MAAT_OP_ADD, compile2_id, + "null", 1, 0); + EXPECT_EQ(ret, 1); + + sleep(WAIT_FOR_EFFECTIVE_S); + + const char *scan_data = "Here is a stream-keywords-003, this should hit."; + table_id = maat_get_table_id(maat_instance, expr_table_name); + ASSERT_GT(table_id, 0); + + struct maat_stream *stream = maat_stream_new(maat_instance, table_id, state); + ret = maat_stream_scan(stream, scan_data, strlen(scan_data), results, ARRAY_SIZE, + &n_hit_result, state); + EXPECT_EQ(ret, MAAT_SCAN_HIT); + EXPECT_EQ(n_hit_result, 1); + EXPECT_EQ(results[0], compile1_id); + + /* + becase compile1_id has been returned, maat_scan_xx will not return duplicate compile_id again + */ + table_id = maat_get_table_id(maat_instance, ip_table_name); + ASSERT_GT(table_id, 0); + ret = maat_scan_ipv4(maat_instance, table_id, ip_addr, port, proto, results, + ARRAY_SIZE, &n_hit_result, state); + EXPECT_EQ(ret, MAAT_SCAN_HALF_HIT); + + maat_stream_free(stream); + maat_state_free(state); + state = NULL; +} + +TEST_F(MaatCmdTest, IPAndStreamScanWhenFullUpdate) { + const char *g2c_table_name = "GROUP2COMPILE"; + const char *compile_table_name = "COMPILE"; + const char *ip_table_name = "IP_PLUS_CONFIG"; + const char *expr_table_name = "KEYWORDS_TABLE"; + int thread_id = 0; + struct maat *maat_instance = MaatCmdTest::_shared_maat_instance; + struct maat_state *state = maat_state_new(maat_instance, thread_id); + + long long compile1_id = maat_cmd_incrby(maat_instance, "TEST_SEQ", 1); + int ret = compile_table_set_line(maat_instance, compile_table_name, MAAT_OP_ADD, compile1_id, + "null", 1, 0); + EXPECT_EQ(ret, 1); + + //group1 -> compile1 + long long group1_id = maat_cmd_incrby(maat_instance, "SEQUENCE_GROUP", 1); + ret = group2compile_table_set_line(maat_instance, g2c_table_name, MAAT_OP_ADD, group1_id, + compile1_id, 0, "null", 0, 0); + EXPECT_EQ(ret, 1); + + //item1 -> group1 -> compile1 + long long item1_id = maat_cmd_incrby(maat_instance, "SEQUENCE_REGION", 1); + ret = expr_table_set_line(maat_instance, expr_table_name, MAAT_OP_ADD, item1_id, group1_id, + "stream-keywords-004", NULL, 0, 0, 0, 0); /*EXPR_TYPE_STRING MATCH_METHOD_SUB*/ + EXPECT_EQ(ret, 1); + + /* item1 -> group1 -> compile1 + / + item2 -> group2 --/ + */ + long long item2_id = maat_cmd_incrby(maat_instance, "SEQUENCE_REGION", 1); + long long group2_id = maat_cmd_incrby(maat_instance, "SEQUENCE_GROUP", 1); + ret = ip_table_set_line(maat_instance, ip_table_name, MAAT_OP_ADD, item2_id, group2_id, + IPv4, "100.100.100.2", "100.100.100.2", 100, 100, 0); + EXPECT_EQ(ret, 1); + + ret = group2compile_table_set_line(maat_instance, g2c_table_name, MAAT_OP_ADD, group2_id, + compile1_id, 0, "null", 1, 0); + EXPECT_EQ(ret, 1); + + sleep(WAIT_FOR_EFFECTIVE_S); + + long long results[ARRAY_SIZE] = {0}; + size_t n_hit_result = 0; + char ip_str[32] = "100.100.100.2"; + uint32_t ip_addr; + ret = inet_pton(AF_INET, ip_str, &ip_addr); + EXPECT_EQ(ret, 1); + + uint16_t port = htons(100); + int proto = 6; + + int table_id = maat_get_table_id(maat_instance, ip_table_name); + ASSERT_GT(table_id, 0); + + ret = maat_scan_ipv4(maat_instance, table_id, ip_addr, port, proto, results, + ARRAY_SIZE, &n_hit_result, state); + EXPECT_EQ(ret, MAAT_SCAN_HALF_HIT); + + //DON'T DO THIS!!! + //Roll back version, trigger full update. + maat_cmd_incrby(maat_instance, "MAAT_VERSION", -100); + + //Wating for scanner garbage collect expiration. + sleep(10); + + const char *scan_data = "Here is a stream-keywords-004, this should hit."; + table_id = maat_get_table_id(maat_instance, expr_table_name); + ASSERT_GT(table_id, 0); + + struct maat_stream *stream = maat_stream_new(maat_instance, table_id, state); + ret = maat_stream_scan(stream, scan_data, strlen(scan_data), results, ARRAY_SIZE, + &n_hit_result, state); + EXPECT_EQ(ret, MAAT_SCAN_HALF_HIT); + + /* maat_state keep the compile_rt version when maat_state_new(). + After full updating, new compile_rt version is different from that of maat_state, + so MAAT_SCAN_HIT will never happen. + */ + table_id = maat_get_table_id(maat_instance, ip_table_name); + ASSERT_GT(table_id, 0); + ret = maat_scan_ipv4(maat_instance, table_id, ip_addr, port, proto, results, + ARRAY_SIZE, &n_hit_result, state); + EXPECT_EQ(ret, MAAT_SCAN_HALF_HIT); + + maat_stream_free(stream); + maat_state_free(state); + state = NULL; +} + +TEST_F(MaatCmdTest, IPAndStringScanWhenIncUpdate) { + const char *g2c_table_name = "GROUP2COMPILE"; + const char *compile_table_name = "COMPILE"; + const char *expr_table_name = "HTTP_URL"; + const char *ip_table_name = "IP_PLUS_CONFIG"; + const char *keywords = "IP&stringinc"; + int thread_id = 0; + struct maat *maat_instance = MaatCmdTest::_shared_maat_instance; + struct maat_state *state = maat_state_new(maat_instance, thread_id); + + long long compile1_id = maat_cmd_incrby(maat_instance, "TEST_SEQ", 1); + int ret = compile_table_set_line(maat_instance, compile_table_name, MAAT_OP_ADD, compile1_id, + "null", 2, 0); + EXPECT_EQ(ret, 1); + + //group1 -> compile1 + long long group1_id = maat_cmd_incrby(maat_instance, "SEQUENCE_GROUP", 1); + ret = group2compile_table_set_line(maat_instance, g2c_table_name, MAAT_OP_ADD, group1_id, + compile1_id, 0, "null", 0, 0); + EXPECT_EQ(ret, 1); + + //item1 -> group1 -> compile1 + long long item1_id = maat_cmd_incrby(maat_instance, "SEQUENCE_REGION", 1); + ret = expr_table_set_line(maat_instance, expr_table_name, MAAT_OP_ADD, item1_id, group1_id, + keywords, NULL, 1, 0, 0, 0); /*EXPR_TYPE_AND MATCH_METHOD_SUB*/ + EXPECT_EQ(ret, 1); + + /* item1 -> group1 -> compile1 + / + item2 -> group2 --/ + */ + long long item2_id = maat_cmd_incrby(maat_instance, "SEQUENCE_REGION", 1); + long long group2_id = maat_cmd_incrby(maat_instance, "SEQUENCE_GROUP", 1); + ret = ip_table_set_line(maat_instance, ip_table_name, MAAT_OP_ADD, item2_id, group2_id, + IPv4, "100.100.100.1", "100.100.100.1", 100, 100, 0); + EXPECT_EQ(ret, 1); + + ret = group2compile_table_set_line(maat_instance, g2c_table_name, MAAT_OP_ADD, group2_id, + compile1_id, 0, "null", 1, 0); + EXPECT_EQ(ret, 1); + + sleep(WAIT_FOR_EFFECTIVE_S); + + long long results[ARRAY_SIZE] = {0}; + size_t n_hit_result = 0; + char ip_str[32] = "100.100.100.1"; + uint32_t ip_addr; + ret = inet_pton(AF_INET, ip_str, &ip_addr); + EXPECT_EQ(ret, 1); + + uint16_t port = htons(100); + int proto = 6; + + int table_id = maat_get_table_id(maat_instance, ip_table_name); + ASSERT_GT(table_id, 0); + + ret = maat_scan_ipv4(maat_instance, table_id, ip_addr, port, proto, results, + ARRAY_SIZE, &n_hit_result, state); + EXPECT_EQ(ret, MAAT_SCAN_HALF_HIT); + + //add compile2 for compile runtime inc update + long long compile2_id = maat_cmd_incrby(maat_instance, "TEST_SEQ", 1); + ret = compile_table_set_line(maat_instance, compile_table_name, MAAT_OP_ADD, compile2_id, + "null", 1, 0); + EXPECT_EQ(ret, 1); + + sleep(WAIT_FOR_EFFECTIVE_S); + + const char *scan_data = "Here is a IP and stringinc, this should hit."; + table_id = maat_get_table_id(maat_instance, expr_table_name); + ASSERT_GT(table_id, 0); + + ret = maat_scan_string(maat_instance, table_id, scan_data, strlen(scan_data), + results, ARRAY_SIZE, &n_hit_result, state); + EXPECT_EQ(ret, MAAT_SCAN_HIT); + EXPECT_EQ(n_hit_result, 1); + EXPECT_EQ(results[0], compile1_id); + + /* + becase compile1_id has been returned, maat_scan_xx will not return duplicate compile_id again + */ + table_id = maat_get_table_id(maat_instance, ip_table_name); + ASSERT_GT(table_id, 0); + ret = maat_scan_ipv4(maat_instance, table_id, ip_addr, port, proto, results, + ARRAY_SIZE, &n_hit_result, state); + EXPECT_EQ(ret, MAAT_SCAN_HALF_HIT); + + maat_state_free(state); + state = NULL; +} + +TEST_F(MaatCmdTest, IPAndStringScanWhenFullupdate) { + const char *g2c_table_name = "GROUP2COMPILE"; + const char *compile_table_name = "COMPILE"; + const char *ip_table_name = "IP_PLUS_CONFIG"; + const char *expr_table_name = "HTTP_URL"; + const char *keywords = "IP&string"; + int thread_id = 0; + struct maat *maat_instance = MaatCmdTest::_shared_maat_instance; + struct maat_state *state = maat_state_new(maat_instance, thread_id); + + long long compile1_id = maat_cmd_incrby(maat_instance, "TEST_SEQ", 1); + int ret = compile_table_set_line(maat_instance, compile_table_name, MAAT_OP_ADD, compile1_id, + "null", 1, 0); + EXPECT_EQ(ret, 1); + + //group1 -> compile1 + long long group1_id = maat_cmd_incrby(maat_instance, "SEQUENCE_GROUP", 1); + ret = group2compile_table_set_line(maat_instance, g2c_table_name, MAAT_OP_ADD, group1_id, + compile1_id, 0, "null", 0, 0); + EXPECT_EQ(ret, 1); + + //item1 -> group1 -> compile1 + long long item1_id = maat_cmd_incrby(maat_instance, "SEQUENCE_REGION", 1); + ret = expr_table_set_line(maat_instance, expr_table_name, MAAT_OP_ADD, item1_id, group1_id, + keywords, "null", 1, 0, 0, 0); /*EXPR_TYPE_AND MATCH_METHOD_SUB*/ + EXPECT_EQ(ret, 1); + + /* item1 -> group1 -> compile1 + / + item2 -> group2 --/ + */ + long long item2_id = maat_cmd_incrby(maat_instance, "SEQUENCE_REGION", 1); + long long group2_id = maat_cmd_incrby(maat_instance, "SEQUENCE_GROUP", 1); + ret = ip_table_set_line(maat_instance, ip_table_name, MAAT_OP_ADD, item2_id, group2_id, + IPv4, "100.100.100.3", "100.100.100.3", 100, 100, 0); + EXPECT_EQ(ret, 1); + + ret = group2compile_table_set_line(maat_instance, g2c_table_name, MAAT_OP_ADD, group2_id, + compile1_id, 0, "null", 1, 0); + EXPECT_EQ(ret, 1); + + sleep(WAIT_FOR_EFFECTIVE_S); + + long long results[ARRAY_SIZE] = {0}; + size_t n_hit_result = 0; + char ip_str[32] = "100.100.100.3"; + uint32_t ip_addr; + ret = inet_pton(AF_INET, ip_str, &ip_addr); + EXPECT_EQ(ret, 1); + + uint16_t port = htons(100); + int proto = 6; + + int table_id = maat_get_table_id(maat_instance, ip_table_name); + ASSERT_GT(table_id, 0); + + ret = maat_scan_ipv4(maat_instance, table_id, ip_addr, port, proto, results, + ARRAY_SIZE, &n_hit_result, state); + EXPECT_EQ(ret, MAAT_SCAN_HALF_HIT); + + //DON'T DO THIS!!! + //Roll back version, trigger full update. + maat_cmd_incrby(maat_instance, "MAAT_VERSION", -100); + + //Wating for scanner garbage collect expiration. + sleep(10); + + const char *scan_data = "scan IP and string, this should hit."; + table_id = maat_get_table_id(maat_instance, expr_table_name); + ASSERT_GT(table_id, 0); + + ret = maat_scan_string(maat_instance, table_id, scan_data, strlen(scan_data), + results, ARRAY_SIZE, &n_hit_result, state); + EXPECT_EQ(ret, MAAT_SCAN_HALF_HIT); + + /* maat_state keep the compile_rt version when maat_state_new(). + After full updating, new compile_rt version is different from that of maat_state, + so MAAT_SCAN_HIT will never happen. + */ + table_id = maat_get_table_id(maat_instance, ip_table_name); + ASSERT_GT(table_id, 0); + + ret = maat_scan_ipv4(maat_instance, table_id, ip_addr, port, proto, results, + ARRAY_SIZE, &n_hit_result, state); + EXPECT_EQ(ret, MAAT_SCAN_HALF_HIT); + + maat_state_free(state); + state = NULL; +} + class MaatRollbackTest : public testing::Test { protected: static void SetUpTestCase() { - const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"},{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; char redis_ip[64] = "127.0.0.1"; int redis_port = 6379; int redis_db = 0; @@ -6173,6 +6512,55 @@ TEST_F(MaatRollbackTest, FullConfigRollback) { state = NULL; } +TEST_F(MaatRollbackTest, FullConfigRollbackWhenScanUnfinished) { + const char *table_name = "HTTP_URL"; + struct maat *maat_instance = MaatRollbackTest::_shared_maat_instance; + struct log_handle *logger = MaatRollbackTest::logger; + + int table_id = maat_get_table_id(maat_instance, table_name); + ASSERT_GT(table_id, 0); + + long long results[ARRAY_SIZE] = {0}; + size_t n_hit_result = 0; + int thread_id = 0; + struct maat_state *state = maat_state_new(maat_instance, thread_id); + const char *scan_data = "http://www.cyberessays.com/search_results.php?action=search&query=username,abckkk,1234567"; + + int ret = maat_scan_string(maat_instance, table_id, scan_data, strlen(scan_data), + results, ARRAY_SIZE, &n_hit_result, state); + EXPECT_EQ(ret, MAAT_SCAN_HIT); + EXPECT_EQ(n_hit_result, 1); + EXPECT_EQ(results[0], 125); + maat_state_reset(state); + + sleep(5); + char redis_ip[64] = "127.0.0.1"; + int redis_port = 6379; + int redis_db = 0; + redisContext *c = maat_cmd_connect_redis(redis_ip, redis_port, redis_db, logger); + EXPECT_TRUE(c != NULL); + + ret = clear_config_in_redis(c, logger); + EXPECT_EQ(ret, 0); + + ret = write_config_to_redis(redis_ip, redis_port, redis_db, logger); + EXPECT_EQ(ret, 0); + + ret = rollback_redis_version(c, logger); + EXPECT_EQ(ret, 0); + redisFree(c); + + sleep(WAIT_FOR_EFFECTIVE_S); + + ret = maat_scan_string(maat_instance, table_id, scan_data, strlen(scan_data), + results, ARRAY_SIZE, &n_hit_result, state); + EXPECT_EQ(ret, MAAT_SCAN_HIT); + EXPECT_EQ(n_hit_result, 1); + EXPECT_EQ(results[0], 125); + maat_state_free(state); + state = NULL; +} + int main(int argc, char ** argv) { int ret=0; diff --git a/test/maat_framework_perf_gtest.cpp b/test/maat_framework_perf_gtest.cpp index a9718f2..36cfaf0 100644 --- a/test/maat_framework_perf_gtest.cpp +++ b/test/maat_framework_perf_gtest.cpp @@ -294,7 +294,8 @@ class MaatPerfStringScan : public testing::Test { protected: static void SetUpTestCase() { - const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"},{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; char redis_ip[64] = "127.0.0.1"; int redis_port = 6379; int redis_db = 0; @@ -308,7 +309,7 @@ protected: struct maat_options *opts = maat_options_new(); maat_options_set_redis(opts, redis_ip, redis_port, redis_db); - maat_options_set_logger(opts, "./maat_framework_gtest.log", LOG_LEVEL_INFO); + maat_options_set_logger(opts, "./maat_framework_perf_gtest.log", LOG_LEVEL_INFO); maat_options_set_accept_tags(opts, accept_tags); maat_options_set_caller_thread_number(opts, 5); @@ -362,7 +363,7 @@ void *perf_string_scan_thread(void *arg) int *is_all_hit = ALLOC(int, 1); *is_all_hit = (hit_times == param->test_count ? 1 : 0); log_info(param->logger, MODULE_FRAMEWORK_PERF_GTEST, - "thread_id:%d time_elapse:%lldms hit_times:%d", + "thread_id:%d string_scan time_elapse:%lldms hit_times:%d", param->thread_id, param->time_elapse_ms, hit_times); return is_all_hit; } @@ -421,7 +422,7 @@ void *perf_ip_scan_thread(void *arg) int *is_all_hit = ALLOC(int, 1); *is_all_hit = (hit_times == param->test_count ? 1 : 0); log_info(param->logger, MODULE_FRAMEWORK_PERF_GTEST, - "thread_id:%d time_elapse:%lldms hit_times:%d", + "thread_id:%d ip_scan time_elapse:%lldms hit_times:%d", param->thread_id, param->time_elapse_ms, hit_times); return is_all_hit; } @@ -456,7 +457,7 @@ void *perf_ip_update_thread(void *arg) return is_all_hit; } -TEST_F(MaatPerfStringScan, basic) { +TEST_F(MaatPerfStringScan, MultiThread) { const char *table_name = "KEYWORDS_TABLE"; struct maat *maat_instance = MaatPerfStringScan::_shared_maat_instance; @@ -498,14 +499,169 @@ TEST_F(MaatPerfStringScan, basic) { } scan_per_second = scan_count * 1000 / time_elapse_ms; //EXPECT_GT(scan_per_second, 800 * 1000); - printf("High match rate on %d-threads speed %lld lookups/s/thread\n", PERF_THREAD_NUM, scan_per_second); + log_info(maat_instance->logger, MODULE_FRAMEWORK_PERF_GTEST, + "StringScan match rate on %d-threads speed %lld lookups/s/thread", + PERF_THREAD_NUM, scan_per_second); +} + +class MaatPerfStreamScan : public testing::Test +{ +protected: + static void SetUpTestCase() { + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + char redis_ip[64] = "127.0.0.1"; + int redis_port = 6379; + int redis_db = 0; + + logger = log_handle_create("./maat_framework_perf_gtest.log", 0); + int ret = write_config_to_redis(redis_ip, redis_port, redis_db, logger); + if (ret < 0) { + log_error(logger, MODULE_FRAMEWORK_PERF_GTEST, + "[%s:%d] write config to redis failed.", __FUNCTION__, __LINE__); + } + + struct maat_options *opts = maat_options_new(); + maat_options_set_redis(opts, redis_ip, redis_port, redis_db); + maat_options_set_logger(opts, "./maat_framework_perf_gtest.log", LOG_LEVEL_INFO); + maat_options_set_accept_tags(opts, accept_tags); + maat_options_set_caller_thread_number(opts, 5); + + _shared_maat_instance = maat_new(opts, table_info_path); + maat_options_free(opts); + if (NULL == _shared_maat_instance) { + log_error(logger, MODULE_FRAMEWORK_PERF_GTEST, + "[%s:%d] create maat instance in MaatFlagScan failed.", + __FUNCTION__, __LINE__); + } + } + + static void TearDownTestCase() { + maat_free(_shared_maat_instance); + log_handle_destroy(logger); + } + + static struct log_handle *logger; + static struct maat *_shared_maat_instance; +}; + +struct maat *MaatPerfStreamScan::_shared_maat_instance; +struct log_handle *MaatPerfStreamScan::logger; + +void *perf_stream_scan_thread(void *arg) +{ + struct thread_param *param = (struct thread_param *)arg; + struct maat *maat_instance = param->maat_instance; + const char *table_name = param->table_name; + struct timespec start, end; + const char *scan_data = "http://www.cyberessays.com/search_results.php?action=search&query=yulingjing,abckkk,1234567"; + long long results[ARRAY_SIZE] = {0}; + int ret = 0, hit_times = 0; + size_t n_hit_result = 0; + struct maat_state *state_array[ARRAY_SIZE]; + struct maat_stream *sp[ARRAY_SIZE]; + int table_id = maat_get_table_id(maat_instance, table_name); + + clock_gettime(CLOCK_MONOTONIC, &start); + for (int i = 0; i < param->test_count; i++) { + for (int j = 0; j < ARRAY_SIZE; j++) { + state_array[j] = maat_state_new(maat_instance, param->thread_id); + sp[j] = maat_stream_new(maat_instance, table_id, state_array[j]); + + ret = maat_stream_scan(sp[j], scan_data, strlen(scan_data), results, ARRAY_SIZE, + &n_hit_result, state_array[j]); + if (ret == MAAT_SCAN_HIT) { + hit_times++; + } + maat_stream_free(sp[j]); + maat_state_free(state_array[j]); + } + } + clock_gettime(CLOCK_MONOTONIC, &end); + + param->time_elapse_ms = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000; + int *is_all_hit = ALLOC(int, 1); + *is_all_hit = ((hit_times == param->test_count*ARRAY_SIZE) ? 1 : 0); + + log_info(param->logger, MODULE_FRAMEWORK_PERF_GTEST, + "thread_id:%d stream_scan time_elapse:%lldms hit_times:%d", + param->thread_id, param->time_elapse_ms, hit_times); + return is_all_hit; +} + +void *perf_stream_update_thread(void *arg) +{ + struct thread_param *param = (struct thread_param *)arg; + struct maat *maat_instance = param->maat_instance; + const char *table_name = param->table_name; + const int CMD_EXPR_NUM = 10; + char keyword_buf[128]; + + for (int i = 0; i < CMD_EXPR_NUM; i++) { + random_keyword_generate(keyword_buf, sizeof(keyword_buf)); + test_add_expr_command(maat_instance, table_name, keyword_buf); + sleep(1); + } + + int *is_all_hit = ALLOC(int, 1); + *is_all_hit = 1; + + return is_all_hit; +} + +TEST_F(MaatPerfStreamScan, MultiThread) { + const char *table_name = "HTTP_URL"; + struct maat *maat_instance = MaatPerfStreamScan::_shared_maat_instance; + + int table_id = maat_get_table_id(maat_instance, table_name); + ASSERT_GT(table_id, 0); + + pthread_t threads[PERF_THREAD_NUM + 1]; + struct thread_param thread_params[PERF_THREAD_NUM + 1]; + int i = 0; + int *is_all_hit = NULL; + + for (i = 0; i < PERF_THREAD_NUM + 1; i++) { + thread_params[i].maat_instance = maat_instance; + thread_params[i].thread_id = i; + thread_params[i].table_name = table_name; + thread_params[i].test_count = 100 * 1000; + thread_params[i].time_elapse_ms = 0; + thread_params[i].logger = logger; + + if (i < PERF_THREAD_NUM) { + pthread_create(&threads[i], NULL, perf_stream_scan_thread, thread_params+i); + } else { + thread_params[i].test_count = 0; + pthread_create(&threads[i], NULL, perf_stream_update_thread, thread_params+i); + } + } + + long long time_elapse_ms = 0; + long long scan_count = 0; + long long scan_per_second = 0; + for (i = 0; i < PERF_THREAD_NUM + 1; i++) { + pthread_join(threads[i], (void **)&is_all_hit); + time_elapse_ms += thread_params[i].time_elapse_ms; + scan_count += thread_params[i].test_count; + //maybe expr_runtime rebuild in stream_scan, so should not expect is_all_hit always 1 + //EXPECT_EQ(*is_all_hit, 1); + *is_all_hit = 0; + free(is_all_hit); + } + scan_per_second = scan_count * 1000 / time_elapse_ms; + + log_info(maat_instance->logger, MODULE_FRAMEWORK_PERF_GTEST, + "StreamScan match rate on %d-threads speed %lld lookups/s/thread", + PERF_THREAD_NUM, scan_per_second); } class MaatPerfIPScan : public testing::Test { protected: static void SetUpTestCase() { - const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"},{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; char redis_ip[64] = "127.0.0.1"; int redis_port = 6379; int redis_db = 0; @@ -544,7 +700,7 @@ protected: struct maat *MaatPerfIPScan::_shared_maat_instance; struct log_handle *MaatPerfIPScan::logger; -TEST_F(MaatPerfIPScan, basic) +TEST_F(MaatPerfIPScan, MultiThread) { const char *table_name = "IP_PLUS_CONFIG"; struct maat *maat_instance = MaatPerfIPScan::_shared_maat_instance; @@ -561,7 +717,7 @@ TEST_F(MaatPerfIPScan, basic) thread_params[i].maat_instance = maat_instance; thread_params[i].thread_id = i; thread_params[i].table_name = table_name; - thread_params[i].test_count = 1 * 1000 * 1000; + thread_params[i].test_count = 10 * 1000 * 1000; thread_params[i].time_elapse_ms = 0; thread_params[i].logger = logger; @@ -586,8 +742,588 @@ TEST_F(MaatPerfIPScan, basic) free(is_all_hit); } scan_per_second = scan_count * 1000 / time_elapse_ms; - //EXPECT_GT(scan_per_second, 800 * 1000); - printf("High match rate on %d-threads speed %lld lookups/s/thread\n", PERF_THREAD_NUM, scan_per_second); + + log_info(maat_instance->logger, MODULE_FRAMEWORK_PERF_GTEST, + "IPScan match rate on %d-threads speed %lld lookups/s/thread", + PERF_THREAD_NUM, scan_per_second); +} + +class MaatPerfFQDNPluginScan : public testing::Test +{ +protected: + static void SetUpTestCase() { + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + char redis_ip[64] = "127.0.0.1"; + int redis_port = 6379; + int redis_db = 0; + + logger = log_handle_create("./maat_framework_perf_gtest.log", 0); + int ret = write_config_to_redis(redis_ip, redis_port, redis_db, logger); + if (ret < 0) { + log_error(logger, MODULE_FRAMEWORK_PERF_GTEST, + "[%s:%d] write config to redis failed.", __FUNCTION__, __LINE__); + } + + struct maat_options *opts = maat_options_new(); + maat_options_set_redis(opts, redis_ip, redis_port, redis_db); + maat_options_set_logger(opts, "./maat_framework_perf_gtest.log", LOG_LEVEL_INFO); + maat_options_set_accept_tags(opts, accept_tags); + maat_options_set_caller_thread_number(opts, 5); + + _shared_maat_instance = maat_new(opts, table_info_path); + maat_options_free(opts); + if (NULL == _shared_maat_instance) { + log_error(logger, MODULE_FRAMEWORK_PERF_GTEST, + "[%s:%d] create maat instance in MaatFlagScan failed.", + __FUNCTION__, __LINE__); + } + } + + static void TearDownTestCase() { + maat_free(_shared_maat_instance); + log_handle_destroy(logger); + } + + static struct log_handle *logger; + static struct maat *_shared_maat_instance; +}; + +struct maat *MaatPerfFQDNPluginScan::_shared_maat_instance; +struct log_handle *MaatPerfFQDNPluginScan::logger; + +struct perf_fqdn_plugin_ud { + long long rule_id; + int catid; + int ref_cnt; +}; + +void perf_fqdn_plugin_EX_new_cb(const char *table_name, int table_id, const char *key, + const char *table_line, void **ad, long argl, void *argp) +{ + int *counter=(int *)argp; + size_t column_offset=0, column_len=0; + + struct perf_fqdn_plugin_ud *ud = ALLOC(struct perf_fqdn_plugin_ud, 1); + int ret = maat_helper_read_column(table_line, 1, &column_offset, &column_len); + EXPECT_EQ(ret, 0); + + ud->rule_id = atoll(table_line+column_offset); + ret = maat_helper_read_column(table_line, 4, &column_offset, &column_len); + EXPECT_EQ(ret, 0); + + sscanf(table_line+column_offset, "catid=%d",&ud->catid); + ud->ref_cnt = 1; + *ad = ud; + (*counter)++; +} + +void perf_fqdn_plugin_EX_free_cb(int table_id, void **ad, long argl, void *argp) +{ + struct perf_fqdn_plugin_ud *u = (struct perf_fqdn_plugin_ud *)(*ad); + if ((__sync_sub_and_fetch(&u->ref_cnt, 1) == 0)) { + free(u); + *ad = NULL; + } +} + +void perf_fqdn_plugin_EX_dup_cb(int table_id, void **to, void **from, long argl, void *argp) +{ + struct perf_fqdn_plugin_ud *u = (struct perf_fqdn_plugin_ud *)(*from); + __sync_add_and_fetch(&(u->ref_cnt), 1); + *to = u; +} + +void* perf_fqdn_plugin_scan_thread(void *arg) +{ + struct thread_param *param = (struct thread_param *)arg; + struct maat *maat_instance = param->maat_instance; + struct perf_fqdn_plugin_ud *result[ARRAY_SIZE]; + + int i=0, j=0, ret=0, hit_times=0; + int table_id = maat_get_table_id(maat_instance, param->table_name); + + memset(&result, 0, sizeof(result)); + struct timespec start, end; + + clock_gettime(CLOCK_MONOTONIC, &start); + for (i = 0; i < param->test_count; i++) { + + ret = maat_fqdn_plugin_table_get_ex_data(maat_instance, table_id, + "r3---sn-i3belne6.example2.com", + (void**)result, ARRAY_SIZE); + if (ret == 2) { + hit_times++; + } + + for (j = 0; j < ret; j++) { + perf_fqdn_plugin_EX_free_cb(0, (void**)&(result[j]), 0, NULL); + } + } + clock_gettime(CLOCK_MONOTONIC, &end); + + param->time_elapse_ms = (end.tv_sec-start.tv_sec)*1000 + (end.tv_nsec-start.tv_nsec)/1000000; + int* is_all_hit = (int*)malloc(sizeof(int)); + *is_all_hit = (hit_times == param->test_count) ? 1 : 0; + log_info(param->logger, MODULE_FRAMEWORK_PERF_GTEST, + "thread_id:%d fqdn_plugin_get_ex_data time_elapse:%lldms hit_times:%d", + param->thread_id, param->time_elapse_ms, hit_times); + + return is_all_hit; +} + +void random_fqdn_generate(char *fqdn_buff, int sz) +{ + int min_fqdn_len = 6, max_fqdn_len = 32; + int i=0, j=0; + + int len = random() % (max_fqdn_len - min_fqdn_len) + min_fqdn_len; + if (len >= sz) { + len = sz - 1; + } + + for (i = 0; i < len-4; i++) { + fqdn_buff[i] = 'a' + random() % ('z' - 'a'); + if (j > 5) { + if (random() % 3 == 0) { + fqdn_buff[i] = '.'; + j = 0; + } + } + j++; + } + fqdn_buff[i] = '\0'; +} + +void *perf_fqdn_plugin_update_thread(void *arg) +{ + struct thread_param *param = (struct thread_param *)arg; + struct maat *maat_instance = param->maat_instance; + const int CMD_EXPR_NUM = 20; + int i = 0; + struct maat_cmd_line line_rule; + char line_buff[1024], fqdn_buff[256]; + + for (i = 0; i < CMD_EXPR_NUM; i++) { + line_rule.rule_id = (int)maat_cmd_incrby(maat_instance, "TEST_PLUG_SEQ", 1); + line_rule.table_name = param->table_name; + random_fqdn_generate(fqdn_buff, sizeof(fqdn_buff)); + snprintf(line_buff, 1024, "%lld\t1\t%s\tcatid=4\t1", line_rule.rule_id, fqdn_buff); + line_rule.table_line = line_buff; + line_rule.expire_after = 0; + maat_cmd_set_line(maat_instance, &line_rule); + sleep(WAIT_FOR_EFFECTIVE_S); + } + + int *is_all_hit = (int *)malloc(sizeof(int)); + *is_all_hit = 1; + + return is_all_hit; +} + +TEST_F(MaatPerfFQDNPluginScan, MultiThread) { + struct maat *maat_instance = MaatPerfFQDNPluginScan::_shared_maat_instance; + const char *table_name = "TEST_FQDN_PLUGIN_WITH_EXDATA"; + int fqdn_plugin_ex_data_counter = 0; + + int table_id = maat_get_table_id(maat_instance, table_name); + ASSERT_GT(table_id, 0); + + pthread_t threads[PERF_THREAD_NUM + 1]; + struct thread_param thread_params[PERF_THREAD_NUM + 1]; + int i = 0; + int *is_all_hit = NULL; + + int ret = maat_plugin_table_ex_schema_register(maat_instance, table_name, + perf_fqdn_plugin_EX_new_cb, + perf_fqdn_plugin_EX_free_cb, + perf_fqdn_plugin_EX_dup_cb, + 0, &fqdn_plugin_ex_data_counter); + ASSERT_TRUE(ret>=0); + + for (i = 0; i < PERF_THREAD_NUM + 1; i++) { + thread_params[i].maat_instance = maat_instance; + thread_params[i].thread_id = i; + thread_params[i].table_name = table_name; + thread_params[i].test_count = 1 * 1000 * 1000; + thread_params[i].time_elapse_ms = 0; + thread_params[i].logger = logger; + + if (i < PERF_THREAD_NUM) { + pthread_create(&threads[i], NULL, perf_fqdn_plugin_scan_thread, thread_params + i); + } else { + thread_params[i].test_count = 0; + pthread_create(&threads[i], NULL, perf_fqdn_plugin_update_thread, thread_params + i); + } + } + + long long time_elapse_ms = 0; + long long scan_count = 0; + long long scan_per_second = 0; + for (i = 0; i < PERF_THREAD_NUM + 1; i++) { + pthread_join(threads[i], (void **)&is_all_hit); + time_elapse_ms += thread_params[i].time_elapse_ms; + scan_count += thread_params[i].test_count; + + EXPECT_EQ(*is_all_hit, 1); + *is_all_hit = 0; + free(is_all_hit); + } + scan_per_second = scan_count * 1000 / time_elapse_ms; + + log_info(maat_instance->logger, MODULE_FRAMEWORK_PERF_GTEST, + "FQDNPluginScan match rate on %d-threads speed %lld lookups/s/thread", + PERF_THREAD_NUM, scan_per_second); +} + +class MaatPerfBoolPluginScan : public testing::Test +{ +protected: + static void SetUpTestCase() { + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + char redis_ip[64] = "127.0.0.1"; + int redis_port = 6379; + int redis_db = 0; + + logger = log_handle_create("./maat_framework_perf_gtest.log", 0); + int ret = write_config_to_redis(redis_ip, redis_port, redis_db, logger); + if (ret < 0) { + log_error(logger, MODULE_FRAMEWORK_PERF_GTEST, + "[%s:%d] write config to redis failed.", __FUNCTION__, __LINE__); + } + + struct maat_options *opts = maat_options_new(); + maat_options_set_redis(opts, redis_ip, redis_port, redis_db); + maat_options_set_logger(opts, "./maat_framework_perf_gtest.log", LOG_LEVEL_INFO); + maat_options_set_accept_tags(opts, accept_tags); + maat_options_set_caller_thread_number(opts, 5); + + _shared_maat_instance = maat_new(opts, table_info_path); + maat_options_free(opts); + if (NULL == _shared_maat_instance) { + log_error(logger, MODULE_FRAMEWORK_PERF_GTEST, + "[%s:%d] create maat instance in BoolPluginScan failed.", + __FUNCTION__, __LINE__); + } + } + + static void TearDownTestCase() { + maat_free(_shared_maat_instance); + log_handle_destroy(logger); + } + + static struct log_handle *logger; + static struct maat *_shared_maat_instance; +}; + +struct maat *MaatPerfBoolPluginScan::_shared_maat_instance; +struct log_handle *MaatPerfBoolPluginScan::logger; + +struct bool_plugin_ud { + int id; + char *name; + int ref_cnt; +}; +void perf_bool_plugin_ex_new_cb(const char *table_name, int table_id, const char *key, + const char *table_line, void **ad, long argl, void *argp) +{ + int *counter=(int *)argp; + size_t column_offset=0, column_len=0; + struct bool_plugin_ud *ud = ALLOC(struct bool_plugin_ud, 1); + + int ret = get_column_pos(table_line, 1, &column_offset, &column_len); + EXPECT_EQ(ret, 0); + + ud->id = atoi(table_line + column_offset); + ret = get_column_pos(table_line, 3, &column_offset, &column_len); + EXPECT_EQ(ret, 0); + + ud->name = (char *)malloc(column_len+1); + memcpy(ud->name, table_line+column_offset, column_len); + ud->ref_cnt = 1; + *ad = ud; + (*counter)++; +} +void perf_bool_plugin_ex_free_cb(int table_id, void **ad, long argl, void *argp) +{ + struct bool_plugin_ud *u = (struct bool_plugin_ud *)(*ad); + if ((__sync_sub_and_fetch(&u->ref_cnt, 1) == 0)) + { + free(u->name); + free(u); + *ad = NULL; + } +} +void perf_bool_plugin_ex_dup_cb(int table_id, void **to, void **from, long argl, void *argp) +{ + struct bool_plugin_ud *u = (struct bool_plugin_ud *)(*from); + __sync_add_and_fetch(&(u->ref_cnt), 1); + *to = u; +} + +void* perf_bool_plugin_scan_thread(void *arg) +{ + struct thread_param *param = (struct thread_param *)arg; + struct maat *maat_instance = param->maat_instance; + struct perf_fqdn_plugin_ud *result[ARRAY_SIZE]; + + int i=0, j=0, ret=0, hit_times=0; + int table_id = maat_get_table_id(maat_instance, param->table_name); + + memset(&result, 0, sizeof(result)); + struct timespec start, end; + unsigned long long items_4[]={7, 0, 1, 2, 3, 4, 5, 6, 7, 7, 7}; + + clock_gettime(CLOCK_MONOTONIC, &start); + for (i = 0; i < param->test_count; i++) { + + ret = maat_bool_plugin_table_get_ex_data(maat_instance, table_id, items_4, + sizeof(items_4)/sizeof(unsigned long long), + (void**)result, 6); + if (ret == 1) { + hit_times++; + } + + for (j = 0; j < ret; j++) { + perf_bool_plugin_ex_free_cb(0, (void**)&(result[j]), 0, NULL); + } + } + clock_gettime(CLOCK_MONOTONIC, &end); + + param->time_elapse_ms = (end.tv_sec-start.tv_sec)*1000 + (end.tv_nsec-start.tv_nsec)/1000000; + int* is_all_hit = (int*)malloc(sizeof(int)); + *is_all_hit = (hit_times == param->test_count) ? 1 : 0; + + log_info(param->logger, MODULE_FRAMEWORK_PERF_GTEST, + "thread_id:%d bool_plugin_get_ex_data time_elapse:%lldms hit_times:%d", + param->thread_id, param->time_elapse_ms, hit_times); + + return is_all_hit; +} + +void *perf_bool_plugin_update_thread(void *arg) +{ + struct thread_param *param = (struct thread_param *)arg; + struct maat *maat_instance = param->maat_instance; + const int CMD_EXPR_NUM = 20; + int i = 0; + struct maat_cmd_line line_rule; + char line_buff[1024]; + + for (i = 0; i < CMD_EXPR_NUM; i++) { + line_rule.rule_id = (int)maat_cmd_incrby(maat_instance, "TEST_PLUG_SEQ", 1); + line_rule.table_name = param->table_name; + snprintf(line_buff, 1024, "%lld\t1&%d\ttunnel2\t1", line_rule.rule_id, i); + line_rule.table_line = line_buff; + line_rule.expire_after = 0; + maat_cmd_set_line(maat_instance, &line_rule); + sleep(WAIT_FOR_EFFECTIVE_S); + } + + int *is_all_hit = (int *)malloc(sizeof(int)); + *is_all_hit = 1; + + return is_all_hit; +} + +TEST_F(MaatPerfBoolPluginScan, MultiThread) { + int ex_data_counter = 0; + const char *table_name = "TEST_BOOL_PLUGIN_WITH_EXDATA"; + struct maat *maat_instance = MaatPerfBoolPluginScan::_shared_maat_instance; + + int table_id = maat_get_table_id(maat_instance, table_name); + ASSERT_GT(table_id, 0); + + int ret = maat_plugin_table_ex_schema_register(maat_instance, table_name, + perf_bool_plugin_ex_new_cb, + perf_bool_plugin_ex_free_cb, + perf_bool_plugin_ex_dup_cb, + 0, &ex_data_counter); + ASSERT_TRUE(ret >= 0); + + pthread_t threads[PERF_THREAD_NUM + 1]; + struct thread_param thread_params[PERF_THREAD_NUM + 1]; + int i = 0; + int *is_all_hit = NULL; + + for (i = 0; i < PERF_THREAD_NUM + 1; i++) { + thread_params[i].maat_instance = maat_instance; + thread_params[i].thread_id = i; + thread_params[i].table_name = table_name; + thread_params[i].test_count = 1 * 1000 * 1000; + thread_params[i].time_elapse_ms = 0; + thread_params[i].logger = logger; + + if (i < PERF_THREAD_NUM) { + pthread_create(&threads[i], NULL, perf_bool_plugin_scan_thread, thread_params + i); + } else { + thread_params[i].test_count = 0; + pthread_create(&threads[i], NULL, perf_bool_plugin_update_thread, thread_params + i); + } + } + + long long time_elapse_ms = 0; + long long scan_count = 0; + long long scan_per_second = 0; + for (i = 0; i < PERF_THREAD_NUM + 1; i++) { + pthread_join(threads[i], (void **)&is_all_hit); + time_elapse_ms += thread_params[i].time_elapse_ms; + scan_count += thread_params[i].test_count; + + EXPECT_EQ(*is_all_hit, 1); + *is_all_hit = 0; + free(is_all_hit); + } + scan_per_second = scan_count * 1000 / time_elapse_ms; + + log_info(maat_instance->logger, MODULE_FRAMEWORK_PERF_GTEST, + "BoolPluginScan match rate on %d-threads speed %lld lookups/s/thread", + PERF_THREAD_NUM, scan_per_second); +} + +class MaatPerfFileScan : public testing::Test +{ +protected: + static void SetUpTestCase() { + logger = log_handle_create("./maat_framework_perf_gtest.log", 0); + const char *rule_folder = "./tsgrule/full/index"; + const char *table_info = "./tsg_table_info.conf"; + + struct maat_options *opts = maat_options_new(); + maat_options_set_iris(opts, rule_folder, rule_folder); + maat_options_set_logger(opts, "./maat_framework_perf_gtest.log", LOG_LEVEL_INFO); + maat_options_set_caller_thread_number(opts, 5); + + _shared_maat_instance = maat_new(opts, table_info); + maat_options_free(opts); + if (NULL == _shared_maat_instance) { + log_error(logger, MODULE_FRAMEWORK_PERF_GTEST, + "[%s:%d] create maat instance in MaatPerfFileScan failed.", + __FUNCTION__, __LINE__); + } + } + + static void TearDownTestCase() { + maat_free(_shared_maat_instance); + log_handle_destroy(logger); + } + + static struct log_handle *logger; + static struct maat *_shared_maat_instance; +}; + +struct maat *MaatPerfFileScan::_shared_maat_instance; +struct log_handle *MaatPerfFileScan::logger; + +struct perf_ip_plugin_ud { + long long rule_id; + int ref_cnt; +}; + +void perf_ip_plugin_EX_new_cb(const char *table_name, int table_id, const char *key, + const char *table_line, void **ad, long argl, void *argp) +{ + int *counter=(int *)argp, ret=0; + size_t column_offset=0, column_len=0; + + struct perf_ip_plugin_ud *ud = ALLOC(struct perf_ip_plugin_ud, 1); + ret = maat_helper_read_column(table_line, 1, &column_offset, &column_len); + EXPECT_EQ(ret, 0); + + ud->rule_id = atoll(table_line+column_offset); + ret = maat_helper_read_column(table_line, 5, &column_offset, &column_len); + EXPECT_EQ(ret, 0); + + ud->ref_cnt = 1; + *ad = ud; + (*counter)++; +} + +void perf_ip_plugin_EX_free_cb(int table_id, void **ad, long argl, void *argp) +{ + struct perf_ip_plugin_ud *u = (struct perf_ip_plugin_ud*)(*ad); + if ((__sync_sub_and_fetch(&u->ref_cnt, 1) == 0)) { + free(u); + *ad = NULL; + } +} + +void perf_ip_plugin_EX_dup_cb(int table_id, void **to, void **from, long argl, void *argp) +{ + struct perf_ip_plugin_ud *u = (struct perf_ip_plugin_ud*)(*from); + __sync_add_and_fetch(&(u->ref_cnt), 1); + *to = u; +} + +static void *ip_plugin_get_thread(void *arg) +{ + const char *table_name = "TSG_IP_LOCATION_BUILT_IN"; + int test_times = 1000*1000, hit_times = 0; + int ret = 0, i=0, j=0; + struct maat *maat_instance = (struct maat *)arg; + + int table_id = maat_get_table_id(maat_instance, table_name); + + struct timespec start, end; + struct ip_addr ipv4; + ipv4.ip_type = IPv4; + + inet_pton(AF_INET, "191.70.72.1", &ipv4.ipv4); + + clock_gettime(CLOCK_MONOTONIC, &start); + struct perf_ip_plugin_ud *results[ARRAY_SIZE]; + for (i = 0; i < test_times; i++) { + ret = maat_ip_plugin_table_get_ex_data(maat_instance, table_id, &ipv4, (void**)results, 4); + if (ret > 0) { + hit_times++; + } + + for (j = 0; j < ret; j++) { + perf_ip_plugin_EX_free_cb(table_id, (void**)&(results[j]), 0, NULL); + } + } + clock_gettime(CLOCK_MONOTONIC, &end); + + long long time_elapse_ms = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000; + log_info(maat_instance->logger, MODULE_FRAMEWORK_PERF_GTEST, + "ip_plugin_get_ex_data time_elapse:%lldms hit_times:%d", + time_elapse_ms, hit_times); + + int *is_all_hit = (int *)malloc(sizeof(int)); + *is_all_hit = (hit_times == test_times) ? 1 : 0; + return is_all_hit; +} + +TEST_F(MaatPerfFileScan, IPPlugin) { + struct maat *maat_instance = MaatPerfFileScan::_shared_maat_instance; + const char* table_name = "TSG_IP_LOCATION_BUILT_IN"; + int ip_plugin_ex_data_counter = 0; + int* is_all_hit = NULL; + + int table_id = maat_get_table_id(maat_instance, table_name); + ASSERT_GT(table_id, 0); + + int ret = maat_plugin_table_ex_schema_register(maat_instance, table_name, + perf_ip_plugin_EX_new_cb, + perf_ip_plugin_EX_free_cb, + perf_ip_plugin_EX_dup_cb, + 0, &ip_plugin_ex_data_counter); + ASSERT_TRUE(ret>=0); + + int i = 0; + pthread_t threads[PERF_THREAD_NUM]; + + for (i = 0; i < PERF_THREAD_NUM; i++) { + pthread_create(&(threads[i]), NULL, ip_plugin_get_thread, maat_instance); + } + + for (i = 0; i < PERF_THREAD_NUM; i++) { + pthread_join(threads[i], (void**)&is_all_hit); + EXPECT_EQ(*is_all_hit, 1); + *is_all_hit=0; + free(is_all_hit); + } } int main(int argc, char ** argv) diff --git a/test/maat_json.json b/test/maat_json.json index 96df074..28755d9 100644 --- a/test/maat_json.json +++ b/test/maat_json.json @@ -2836,6 +2836,112 @@ "group_name": "Untitled" } ] + }, + { + "compile_id": 206, + "service": 0, + "action": 0, + "do_blacklist": 0, + "do_log": 0, + "effective_rage": 0, + "user_region": "duplicateRuleFor191", + "is_valid": "yes", + "groups": [ + { + "regions": [ + { + "table_type": "expr", + "table_name": "KEYWORDS_TABLE", + "table_content": { + "keywords": "54455354", + "expr_type": "none", + "format": "hexbin", + "match_method": "sub" + } + } + ], + "group_name": "Untitled" + } + ] + }, + { + "compile_id": 207, + "service": 0, + "action": 0, + "do_blacklist": 0, + "do_log": 0, + "user_region": "duplicateRuleFor192", + "is_valid": "yes", + "groups": [ + { + "regions": [ + { + "table_type": "flag", + "table_name": "FLAG_CONFIG", + "table_content": { + "flag": 1, + "flag_mask": 3 + } + } + ] + } + ] + }, + { + "compile_id": 208, + "service": 0, + "action": 0, + "do_blacklist": 0, + "do_log": 0, + "effective_rage": 0, + "user_region": "duplicateRuleFor154", + "is_valid": "yes", + "groups": [ + { + "regions": [ + { + "table_type": "ip_plus", + "table_name": "IP_PLUS_CONFIG", + "table_content": { + "addr_type": "ipv4", + "addr_format": "range", + "ip1": "10.0.7.100", + "ip2": "10.0.7.106", + "port_format": "range", + "port1": "65530", + "port2": "65535", + "protocol": 6 + } + } + ], + "not_flag": 0 + } + ] + }, + { + "compile_id": 209, + "service": 1, + "action": 1, + "do_blacklist": 1, + "do_log": 1, + "user_region": "duplicateRuleFor179", + "is_valid": "yes", + "groups": [ + { + "group_name": "Untitled", + "regions": [ + { + "table_name": "INTERGER_PLUS", + "table_type": "interval_plus", + "table_content": { + "district": "interval.plus", + "low_boundary": 2020, + "up_boundary": 2020 + } + } + ] + } + ] } ], "plugin_table": [ diff --git a/test/tsg_table_info.conf b/test/tsg_table_info.conf new file mode 100644 index 0000000..f6bbdb4 --- /dev/null +++ b/test/tsg_table_info.conf @@ -0,0 +1,15 @@ +[ + { + "table_id": 42, + "table_name":"TSG_IP_LOCATION_BUILT_IN", + "table_type":"ip_plugin", + "valid_column":18, + "custom": { + "item_id":1, + "ip_type":3, + "start_ip":4, + "end_ip":5, + "addr_format":7 + } + } +] \ No newline at end of file diff --git a/test/tsgrule/TSG_IP_LOCATION_BUILT_IN.head_1k b/test/tsgrule/TSG_IP_LOCATION_BUILT_IN.head_1k new file mode 100644 index 0000000..9db65b4 --- /dev/null +++ b/test/tsgrule/TSG_IP_LOCATION_BUILT_IN.head_1k @@ -0,0 +1,1001 @@ +0000001000 +10000 3150851 4 88.91.240.0 88.91.240.255 60.159 11.1407 20.0 en EU Europe NO Norway 30 Viken Jessheim Europe/Oslo 1 1618978544000000 0 +100000 2736041 4 83.132.250.0 83.132.251.255 41.7703 -8.5627 100.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000000 3688689 4 191.66.192.0 191.66.223.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000001 3688689 4 191.66.224.0 191.66.255.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000002 3688689 4 191.67.32.0 191.67.63.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000003 3688689 4 191.67.64.0 191.67.79.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000004 3688689 4 191.67.112.0 191.67.127.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000005 3688689 4 191.67.128.0 191.67.143.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000006 3688689 4 191.67.144.0 191.67.159.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000007 3688689 4 191.67.160.0 191.67.191.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000008 3688689 4 191.67.224.0 191.67.239.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000009 3688689 4 191.67.240.0 191.67.255.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100001 2736041 4 87.196.4.0 87.196.4.255 41.7662 -8.5883 100.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000010 3688689 4 191.68.32.0 191.68.63.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000011 3688689 4 191.68.64.0 191.68.79.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000012 3688689 4 191.68.112.0 191.68.119.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000013 3688689 4 191.68.144.0 191.68.159.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000014 3688689 4 191.68.184.0 191.68.191.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000015 3688689 4 191.68.192.0 191.68.195.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000016 3688689 4 191.68.216.0 191.68.223.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000017 3688689 4 191.68.240.0 191.68.247.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000018 3688689 4 191.69.1.0 191.69.1.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000019 3688689 4 191.69.2.0 191.69.3.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100002 2736041 4 89.155.23.0 89.155.23.255 41.7857 -8.6447 20.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000020 3688689 4 191.69.4.0 191.69.7.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000021 3688689 4 191.69.16.0 191.69.31.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000022 3688689 4 191.69.54.0 191.69.55.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000023 3688689 4 191.69.64.0 191.69.65.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000024 3688689 4 191.69.117.0 191.69.117.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000025 3688689 4 191.69.120.0 191.69.127.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000026 3688689 4 191.69.128.0 191.69.135.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000027 3688689 4 191.69.144.0 191.69.159.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000028 3688689 4 191.69.168.0 191.69.171.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000029 3688689 4 191.69.176.0 191.69.183.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100003 2736041 4 89.181.91.0 89.181.91.255 41.8721 -8.5768 20.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000030 3688689 4 191.69.184.0 191.69.191.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000031 3688689 4 191.69.202.128 191.69.202.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000032 3688689 4 191.69.208.0 191.69.209.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000033 3688689 4 191.69.210.0 191.69.210.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000034 3688689 4 191.69.212.0 191.69.215.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000035 3688689 4 191.69.216.0 191.69.223.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000036 3688689 4 191.69.248.0 191.69.255.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000037 3688689 4 191.70.52.0 191.70.55.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000038 3688689 4 191.70.56.0 191.70.63.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000039 3688689 4 191.70.64.0 191.70.71.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100004 2736041 4 89.181.139.128 89.181.139.255 41.7662 -8.5883 1.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000040 3688689 4 191.70.72.0 191.70.75.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000041 3688689 4 191.70.76.0 191.70.79.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000042 3688689 4 191.70.80.0 191.70.95.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000043 3688689 4 191.70.104.0 191.70.111.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000044 3688689 4 191.70.112.0 191.70.127.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000045 3688689 4 191.70.136.0 191.70.143.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000046 3688689 4 191.70.160.0 191.70.175.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000047 3688689 4 191.70.184.0 191.70.191.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000048 3688689 4 191.70.210.0 191.70.211.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000049 3688689 4 191.70.212.0 191.70.215.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100005 2736041 4 94.61.24.0 94.61.24.255 41.7662 -8.5883 100.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000050 3688689 4 191.70.216.0 191.70.223.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000051 3688689 4 191.70.224.0 191.70.239.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000052 3688689 4 191.70.248.0 191.70.255.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000053 3688689 4 191.71.64.0 191.71.95.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000054 3688689 4 191.71.112.0 191.71.127.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000055 3688689 4 191.71.192.0 191.71.255.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000056 3688689 4 191.72.0.0 191.72.15.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000057 3688689 4 191.72.16.0 191.72.23.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000058 3688689 4 191.72.96.0 191.72.127.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000059 3688689 4 191.72.132.0 191.72.135.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100006 2736041 4 94.61.44.0 94.61.44.255 41.7662 -8.5883 20.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000060 3688689 4 191.72.160.0 191.72.175.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000061 3688689 4 191.72.196.0 191.72.199.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000062 3688689 4 191.72.208.0 191.72.223.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000063 3688689 4 191.72.240.0 191.72.247.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000064 3688689 4 191.73.0.0 191.73.15.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000065 3688689 4 191.73.56.0 191.73.59.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000066 3688689 4 191.73.64.0 191.73.95.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000067 3688689 4 191.73.96.0 191.73.103.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000068 3688689 4 191.73.110.0 191.73.111.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000069 3688689 4 191.73.112.0 191.73.127.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100007 2736041 4 94.61.51.0 94.61.51.255 41.7662 -8.5883 100.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000070 3688689 4 191.73.128.0 191.73.143.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000071 3688689 4 191.73.160.0 191.73.167.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000072 3688689 4 191.73.178.0 191.73.179.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000073 3688689 4 191.74.12.0 191.74.13.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000074 3688689 4 191.74.16.0 191.74.31.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000075 3688689 4 191.74.64.0 191.74.79.255 4.6493 -74.0617 1000.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000076 3688689 4 191.74.80.0 191.74.95.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000077 3688689 4 191.74.96.0 191.74.111.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000078 3688689 4 191.74.116.0 191.74.117.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000079 3688689 4 191.74.120.0 191.74.127.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100008 2736041 4 94.61.60.0 94.61.61.255 41.7662 -8.5883 50.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000080 3688689 4 191.74.128.0 191.74.131.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000081 3688689 4 191.74.134.0 191.74.135.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000082 3688689 4 191.74.138.0 191.74.139.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000083 3688689 4 191.74.144.0 191.74.159.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000084 3688689 4 191.74.160.0 191.74.175.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000085 3688689 4 191.74.176.0 191.74.191.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000086 3688689 4 191.74.200.0 191.74.207.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000087 3688689 4 191.74.216.0 191.74.223.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000088 3688689 4 191.74.228.0 191.74.231.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000089 3688689 4 191.74.240.0 191.74.255.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100009 2736041 4 95.69.30.0 95.69.30.255 41.7662 -8.5883 200.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000090 3688689 4 191.75.0.0 191.75.7.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000091 3688689 4 191.75.8.0 191.75.11.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000092 3688689 4 191.75.12.0 191.75.13.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000093 3688689 4 191.75.15.0 191.75.15.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000094 3688689 4 191.75.16.0 191.75.31.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000095 3688689 4 191.75.32.0 191.75.39.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000096 3688689 4 191.75.48.0 191.75.63.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000097 3688689 4 191.75.72.0 191.75.79.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000098 3688689 4 191.75.80.0 191.75.83.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000099 3688689 4 191.75.84.0 191.75.87.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +10001 3150851 4 89.10.197.0 89.10.197.127 60.1427 11.1671 10.0 en EU Europe NO Norway 30 Viken Jessheim Europe/Oslo 1 1618978544000000 0 +100010 2736041 4 144.64.44.0 144.64.45.255 41.7662 -8.5883 5.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000100 3688689 4 191.75.88.0 191.75.95.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000101 3688689 4 191.75.118.0 191.75.118.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000102 3688689 4 191.75.120.0 191.75.127.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000103 3688689 4 191.75.128.0 191.75.135.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000104 3688689 4 191.75.136.0 191.75.143.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000105 3688689 4 191.75.144.0 191.75.151.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000106 3688689 4 191.75.152.0 191.75.159.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000107 3688689 4 191.75.160.0 191.75.167.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000108 3688689 4 191.75.176.0 191.75.191.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000109 3688689 4 191.75.196.0 191.75.199.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100011 2736041 4 148.71.170.0 148.71.171.255 41.7662 -8.5883 100.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000110 3688689 4 191.75.200.0 191.75.207.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000111 3688689 4 191.75.208.0 191.75.223.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000112 3688689 4 191.76.0.0 191.76.31.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000113 3688689 4 191.76.64.0 191.76.67.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000114 3688689 4 191.76.68.0 191.76.71.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000115 3688689 4 191.76.72.0 191.76.79.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000116 3688689 4 191.76.80.0 191.76.95.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000117 3688689 4 191.76.96.0 191.76.111.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000118 3688689 4 191.76.112.0 191.76.127.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000119 3688689 4 191.76.160.0 191.76.167.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100012 2736041 4 161.230.16.0 161.230.17.255 41.7662 -8.5883 100.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000120 3688689 4 191.76.168.0 191.76.175.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000121 3688689 4 191.76.192.0 191.76.207.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000122 3688689 4 191.76.208.0 191.76.223.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000123 3688689 4 191.76.228.0 191.76.231.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000124 3688689 4 191.76.234.0 191.76.235.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000125 3688689 4 191.79.8.0 191.79.11.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000126 3688689 4 191.79.32.0 191.79.47.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000127 3688689 4 191.79.52.0 191.79.55.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000128 3688689 4 191.79.56.0 191.79.63.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000129 3688689 4 191.79.64.0 191.79.95.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100013 2736041 4 161.230.48.0 161.230.49.255 41.7662 -8.5883 100.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000130 3688689 4 191.79.128.0 191.79.159.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000131 3688689 4 191.79.192.0 191.79.255.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000132 3688689 4 191.88.198.0 191.88.198.127 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000133 3688689 4 191.88.208.0 191.88.215.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000134 3688689 4 191.88.216.0 191.88.219.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000135 3688689 4 191.88.220.0 191.88.223.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000136 3688689 4 191.89.17.0 191.89.17.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000137 3688689 4 191.89.23.0 191.89.23.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000138 3688689 4 191.89.82.128 191.89.82.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000139 3688689 4 191.89.112.0 191.89.113.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100014 2736041 4 178.166.72.0 178.166.73.255 41.7662 -8.5883 200.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000140 3688689 4 191.89.114.0 191.89.115.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000141 3688689 4 191.89.116.0 191.89.117.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000142 3688689 4 191.89.119.0 191.89.119.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000143 3688689 4 191.89.120.0 191.89.127.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000144 3688689 4 191.89.166.0 191.89.167.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000145 3688689 4 191.89.232.0 191.89.232.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000146 3688689 4 191.89.233.0 191.89.233.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000147 3688689 4 191.89.234.0 191.89.234.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000148 3688689 4 191.89.235.0 191.89.235.127 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000149 3688689 4 191.89.235.128 191.89.235.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100015 2736041 4 188.83.232.0 188.83.235.255 41.7662 -8.5883 5.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000150 3688689 4 191.89.236.0 191.89.237.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000151 3688689 4 191.89.238.0 191.89.238.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000152 3688689 4 191.89.239.0 191.89.239.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000153 3688689 4 191.92.160.0 191.92.167.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000154 3688689 4 191.92.168.0 191.92.171.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000155 3688689 4 191.92.172.0 191.92.173.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000156 3688689 4 191.92.175.0 191.92.175.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000157 3688689 4 191.92.176.0 191.92.177.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000158 3688689 4 191.92.180.0 191.92.183.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000159 3688689 4 191.92.184.0 191.92.191.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100016 2736041 4 188.251.66.0 188.251.66.255 41.7662 -8.5883 20.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000160 3688689 4 191.92.208.0 191.92.209.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000161 3688689 4 191.92.210.0 191.92.211.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000162 3688689 4 191.92.233.0 191.92.233.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000163 3688689 4 191.93.0.0 191.93.15.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000164 3688689 4 191.93.16.0 191.93.31.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000165 3688689 4 191.95.1.0 191.95.1.255 4.6493 -74.0617 1000.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000166 3688689 4 191.95.26.128 191.95.26.159 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000167 3688689 4 191.95.48.0 191.95.48.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000168 3688689 4 191.95.49.32 191.95.49.63 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000169 3688689 4 191.95.49.64 191.95.49.127 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100017 2736041 4 193.126.146.128 193.126.146.255 41.6803 -8.5569 50.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000170 3688689 4 191.95.49.128 191.95.49.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000171 3688689 4 191.95.50.0 191.95.50.31 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000172 3688689 4 191.95.50.48 191.95.50.63 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000173 3688689 4 191.95.50.64 191.95.50.127 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000174 3688689 4 191.95.50.128 191.95.50.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000175 3688689 4 191.95.51.0 191.95.51.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000176 3688689 4 191.95.52.0 191.95.52.127 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000177 3688689 4 191.95.52.128 191.95.52.191 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000178 3688689 4 191.95.52.192 191.95.52.207 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000179 3688689 4 191.95.52.208 191.95.52.215 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100018 2736041 6 2001:8a0:f7c0:: 2001:8a0:f7df:ffff:ffff:ffff:ffff:ffff 41.8721 -8.5768 20.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000180 3688689 4 191.95.52.224 191.95.52.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000181 3688689 4 191.95.53.0 191.95.53.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000182 3688689 4 191.95.54.0 191.95.54.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000183 3688689 4 191.95.55.0 191.95.55.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000184 3688689 4 191.95.56.0 191.95.57.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000185 3688689 4 191.95.58.0 191.95.58.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000186 3688689 4 191.95.59.0 191.95.59.15 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000187 3688689 4 191.95.59.32 191.95.59.63 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000188 3688689 4 191.95.59.64 191.95.59.127 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000189 3688689 4 191.95.59.128 191.95.59.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100019 2736041 6 2001:8a0:f7f8:: 2001:8a0:f7f9:ffff:ffff:ffff:ffff:ffff 41.7662 -8.5883 20.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000190 3688689 4 191.95.60.0 191.95.60.63 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000191 3688689 4 191.95.60.80 191.95.60.95 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000192 3688689 4 191.95.60.96 191.95.60.127 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000193 3688689 4 191.95.60.128 191.95.60.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000194 3688689 4 191.95.61.0 191.95.61.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000195 3688689 4 191.95.62.0 191.95.62.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000196 3688689 4 191.95.63.0 191.95.63.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000197 3688689 4 191.95.128.64 191.95.128.127 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000198 3688689 4 191.95.128.128 191.95.128.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000199 3688689 4 191.95.167.0 191.95.167.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +10002 3150851 4 90.149.228.192 90.149.228.255 60.1574 11.1694 5.0 en EU Europe NO Norway 30 Viken Jessheim Europe/Oslo 1 1618978544000000 0 +100020 2736041 6 2001:8a0:f7fb:: 2001:8a0:f7fb:ffff:ffff:ffff:ffff:ffff 41.7662 -8.5883 10.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000200 3688689 4 191.95.168.128 191.95.168.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000201 3688689 4 191.95.170.128 191.95.170.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000202 3688689 4 191.95.171.128 191.95.171.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000203 3688689 4 191.95.173.0 191.95.173.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000204 3688689 4 191.97.0.0 191.97.0.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000205 3688689 4 191.97.6.0 191.97.6.127 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000206 3688689 4 191.97.12.128 191.97.12.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000207 3688689 4 191.97.13.128 191.97.13.159 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000208 3688689 4 191.98.99.0 191.98.99.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000209 3688689 4 191.102.73.224 191.102.73.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100021 2736041 6 2001:8a0:f7fc:: 2001:8a0:f7ff:ffff:ffff:ffff:ffff:ffff 41.7662 -8.5883 10.0 en EU Europe PT Portugal 16 Viana\bdo\bCastelo Ponte\bde\bLima Europe/Lisbon 1 1618978544000000 0 +1000210 3688689 4 191.102.76.0 191.102.76.127 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000211 3688689 4 191.102.82.0 191.102.82.127 4.6493 -74.0617 1000.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000212 3688689 4 191.102.82.128 191.102.82.191 4.6493 -74.0617 1000.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000213 3688689 4 191.102.82.192 191.102.82.207 4.6493 -74.0617 1000.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000214 3688689 4 191.102.82.208 191.102.82.215 4.6493 -74.0617 1000.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000215 3688689 4 191.102.82.216 191.102.82.217 4.6493 -74.0617 1000.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000216 3688689 4 191.102.82.219 191.102.82.219 4.6493 -74.0617 1000.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000217 3688689 4 191.102.82.220 191.102.82.223 4.6493 -74.0617 1000.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000218 3688689 4 191.102.82.224 191.102.82.255 4.6493 -74.0617 1000.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000219 3688689 4 191.102.84.0 191.102.84.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100022 2972719 4 86.233.244.0 86.233.244.255 46.2915 -0.2512 20.0 en EU Europe FR France NAQ Nouvelle-Aquitaine Thorigne Europe/Paris 1 1618978544000000 0 +1000220 3688689 4 191.102.93.0 191.102.93.127 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000221 3688689 4 191.102.93.208 191.102.93.223 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000222 3688689 4 191.102.93.224 191.102.93.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000223 3688689 4 191.102.96.64 191.102.96.127 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000224 3688689 4 191.102.106.128 191.102.106.143 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000225 3688689 4 191.102.108.0 191.102.109.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000226 3688689 4 191.102.110.0 191.102.110.127 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000227 3688689 4 191.102.110.128 191.102.110.159 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000228 3688689 4 191.102.110.160 191.102.110.175 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000229 3688689 4 191.102.110.184 191.102.110.191 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100023 2972719 4 176.184.228.0 176.184.228.127 46.2915 -0.2512 100.0 en EU Europe FR France NAQ Nouvelle-Aquitaine Thorigne Europe/Paris 1 1618978544000000 0 +1000230 3688689 4 191.102.110.192 191.102.110.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000231 3688689 4 191.102.113.136 191.102.113.143 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000232 3688689 4 191.102.114.0 191.102.114.127 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000233 3688689 4 191.102.114.192 191.102.114.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000234 3688689 4 191.102.116.0 191.102.116.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000235 3688689 4 191.102.120.0 191.102.120.127 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000236 3688689 4 191.102.120.144 191.102.120.151 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000237 3688689 4 191.102.120.160 191.102.120.191 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000238 3688689 4 191.102.120.232 191.102.120.239 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000239 3688689 4 191.102.120.240 191.102.120.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100024 2972719 4 176.184.228.192 176.184.228.255 46.2915 -0.2512 100.0 en EU Europe FR France NAQ Nouvelle-Aquitaine Thorigne Europe/Paris 1 1618978544000000 0 +1000240 3688689 4 191.102.126.0 191.102.126.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000241 3688689 4 191.102.196.0 191.102.196.127 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000242 3688689 4 191.102.197.128 191.102.197.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000243 3688689 4 191.102.198.0 191.102.198.127 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000244 3688689 4 191.102.199.0 191.102.199.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000245 3688689 4 191.102.224.0 191.102.231.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000246 3688689 4 191.106.140.56 191.106.140.63 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000247 3688689 4 191.106.207.0 191.106.207.127 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000248 3688689 4 191.109.3.0 191.109.3.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000249 3688689 4 191.109.30.0 191.109.30.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100025 2972719 4 176.184.229.0 176.184.229.63 46.2915 -0.2512 100.0 en EU Europe FR France NAQ Nouvelle-Aquitaine Thorigne Europe/Paris 1 1618978544000000 0 +1000250 3688689 4 191.109.44.128 191.109.44.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000251 3688689 4 191.109.45.0 191.109.45.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000252 3688689 4 191.109.65.0 191.109.65.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000253 3688689 4 191.109.74.0 191.109.74.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000254 3688689 4 191.109.105.0 191.109.105.127 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000255 3688689 4 191.109.129.0 191.109.129.255 4.6493 -74.0617 1000.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000256 3688689 4 191.109.130.0 191.109.131.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000257 3688689 4 191.109.133.0 191.109.133.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000258 3688689 4 191.109.134.0 191.109.134.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000259 3688689 4 191.109.137.0 191.109.137.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100026 2972719 4 176.184.229.64 176.184.229.95 46.2915 -0.2512 100.0 en EU Europe FR France NAQ Nouvelle-Aquitaine Thorigne Europe/Paris 1 1618978544000000 0 +1000260 3688689 4 191.109.138.0 191.109.138.127 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000261 3688689 4 191.109.140.0 191.109.140.63 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000262 3688689 4 191.109.140.128 191.109.140.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000263 3688689 4 191.109.141.128 191.109.141.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000264 3688689 4 191.109.144.0 191.109.144.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000265 3688689 4 191.109.145.0 191.109.145.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000266 3688689 4 191.109.146.0 191.109.146.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000267 3688689 4 191.109.148.0 191.109.148.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000268 3688689 4 191.109.152.0 191.109.152.127 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000269 3688689 4 191.109.153.0 191.109.153.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100027 2972719 4 176.184.229.96 176.184.229.111 46.2915 -0.2512 100.0 en EU Europe FR France NAQ Nouvelle-Aquitaine Thorigne Europe/Paris 1 1618978544000000 0 +1000270 3688689 4 191.109.154.0 191.109.155.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000271 3688689 4 191.109.156.0 191.109.157.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000272 3688689 4 191.109.159.128 191.109.159.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000273 3688689 4 191.109.162.0 191.109.162.127 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000274 3688689 4 191.109.165.0 191.109.165.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000275 3688689 4 191.109.169.0 191.109.169.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000276 3688689 4 191.109.171.0 191.109.171.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000277 3688689 4 191.109.172.0 191.109.172.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000278 3688689 4 191.109.173.192 191.109.173.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000279 3688689 4 191.109.174.0 191.109.174.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100028 2972719 4 176.184.229.112 176.184.229.119 46.2915 -0.2512 100.0 en EU Europe FR France NAQ Nouvelle-Aquitaine Thorigne Europe/Paris 1 1618978544000000 0 +1000280 3688689 4 191.109.175.0 191.109.175.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000281 3688689 4 191.109.176.0 191.109.176.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000282 3688689 4 191.109.177.0 191.109.177.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000283 3688689 4 191.109.186.0 191.109.186.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000284 3688689 4 191.109.189.0 191.109.189.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000285 3688689 4 191.109.190.0 191.109.190.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000286 3688689 4 191.109.194.0 191.109.195.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000287 3688689 4 191.109.196.0 191.109.199.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000288 3688689 4 191.109.200.0 191.109.200.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000289 3688689 4 191.109.206.0 191.109.207.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100029 2972719 4 176.184.229.120 176.184.229.123 46.2915 -0.2512 100.0 en EU Europe FR France NAQ Nouvelle-Aquitaine Thorigne Europe/Paris 1 1618978544000000 0 +1000290 3688689 4 191.109.209.128 191.109.209.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000291 3688689 4 191.109.210.0 191.109.210.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000292 3688689 4 191.109.211.0 191.109.211.127 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000293 3688689 4 191.109.212.0 191.109.213.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000294 3688689 4 191.109.215.0 191.109.215.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000295 3688689 4 191.109.216.0 191.109.217.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000296 3688689 4 191.109.218.0 191.109.218.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000297 3688689 4 191.109.219.0 191.109.219.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000298 3688689 4 191.109.222.0 191.109.223.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000299 3688689 4 191.109.224.0 191.109.224.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +10003 3150851 4 91.186.73.0 91.186.73.255 60.1392 11.167 500.0 en EU Europe NO Norway 30 Viken Jessheim Europe/Oslo 1 1618978544000000 0 +100030 2972719 4 176.184.229.124 176.184.229.125 46.2915 -0.2512 100.0 en EU Europe FR France NAQ Nouvelle-Aquitaine Thorigne Europe/Paris 1 1618978544000000 0 +1000300 3688689 4 191.109.225.0 191.109.225.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000301 3688689 4 191.109.226.0 191.109.227.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000302 3688689 4 191.109.228.0 191.109.231.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000303 3688689 4 191.109.232.0 191.109.233.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000304 3688689 4 191.109.234.0 191.109.234.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000305 3688689 4 191.109.235.128 191.109.235.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000306 3688689 4 191.109.236.0 191.109.237.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000307 3688689 4 191.109.238.0 191.109.238.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000308 3688689 4 191.109.239.0 191.109.239.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000309 3688689 4 191.109.240.0 191.109.240.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100031 2972719 4 176.184.229.126 176.184.229.126 46.2915 -0.2512 100.0 en EU Europe FR France NAQ Nouvelle-Aquitaine Thorigne Europe/Paris 1 1618978544000000 0 +1000310 3688689 4 191.109.241.0 191.109.241.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000311 3688689 4 191.109.242.0 191.109.242.127 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000312 3688689 4 191.109.242.128 191.109.242.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000313 3688689 4 191.109.244.0 191.109.247.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000314 3688689 4 191.109.249.0 191.109.249.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000315 3688689 4 191.109.250.0 191.109.251.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000316 3688689 4 191.109.252.128 191.109.252.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000317 3688689 4 191.109.254.0 191.109.255.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000318 3688689 4 191.110.134.128 191.110.134.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000319 3688689 4 191.111.151.0 191.111.151.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100032 2972719 4 176.184.229.128 176.184.229.255 46.2915 -0.2512 100.0 en EU Europe FR France NAQ Nouvelle-Aquitaine Thorigne Europe/Paris 1 1618978544000000 0 +1000320 3688689 4 191.111.154.0 191.111.154.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000321 3688689 4 191.144.0.0 191.144.31.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000322 3688689 4 191.144.32.0 191.144.39.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000323 3688689 4 191.144.48.0 191.144.63.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000324 3688689 4 191.144.72.0 191.144.79.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000325 3688689 4 191.144.80.0 191.144.95.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000326 3688689 4 191.144.167.0 191.144.167.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000327 3688689 4 191.144.188.0 191.144.189.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000328 3688689 4 191.144.192.0 191.144.207.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000329 3688689 4 191.144.208.0 191.144.211.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100033 257302 4 46.177.173.128 46.177.173.255 38.05 23.8333 10.0 en EU Europe GR Greece I Attica Melissia Europe/Athens 1 1618978544000000 0 +1000330 3688689 4 191.144.212.0 191.144.213.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000331 3688689 4 191.144.215.0 191.144.215.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000332 3688689 4 191.144.216.0 191.144.223.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000333 3688689 4 191.144.224.0 191.144.255.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000334 3688689 4 191.145.32.0 191.145.63.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000335 3688689 4 191.145.64.0 191.145.95.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000336 3688689 4 191.145.128.0 191.145.159.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000337 3688689 4 191.146.0.0 191.146.31.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000338 3688689 4 191.146.32.0 191.146.47.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000339 3688689 4 191.146.64.0 191.146.95.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100034 257302 4 79.166.20.0 79.166.20.127 38.05 23.8333 200.0 en EU Europe GR Greece I Attica Melissia Europe/Athens 1 1618978544000000 0 +1000340 3688689 4 191.146.96.0 191.146.127.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000341 3688689 4 191.146.128.0 191.146.159.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000342 3688689 4 191.146.176.0 191.146.191.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000343 3688689 4 191.146.196.0 191.146.199.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000344 3688689 4 191.146.200.0 191.146.207.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000345 3688689 4 191.146.208.0 191.146.223.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000346 3688689 4 191.148.224.0 191.148.231.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000347 3688689 4 191.149.0.0 191.149.15.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000348 3688689 4 191.149.16.0 191.149.31.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000349 3688689 4 191.149.44.0 191.149.47.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100035 634814 4 85.131.98.0 85.131.98.255 60.5789 26.9563 200.0 en EU Europe FI Finland 09 Kymenlaakso Tavastila Europe/Helsinki 1 1618978544000000 0 +1000350 3688689 4 191.149.64.0 191.149.79.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000351 3688689 4 191.149.96.0 191.149.103.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000352 3688689 4 191.149.104.0 191.149.111.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000353 3688689 4 191.149.160.0 191.149.191.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000354 3688689 4 191.149.192.0 191.149.207.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000355 3688689 4 191.149.208.0 191.149.223.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000356 3688689 4 191.151.36.0 191.151.36.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000357 3688689 4 191.151.40.0 191.151.47.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000358 3688689 4 191.151.48.0 191.151.63.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000359 3688689 4 191.151.128.0 191.151.131.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100036 701822 4 93.170.26.0 93.170.26.255 47.0951 37.5413 100.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000360 3688689 4 191.151.184.0 191.151.187.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000361 3688689 4 191.151.200.0 191.151.207.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000362 3688689 4 191.151.208.0 191.151.223.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000363 3688689 4 191.151.224.0 191.151.255.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000364 3688689 4 191.153.64.0 191.153.71.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000365 3688689 4 191.153.80.0 191.153.95.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000366 3688689 4 191.154.16.0 191.154.23.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000367 3688689 4 191.154.28.0 191.154.31.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000368 3688689 4 191.154.32.0 191.154.39.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000369 3688689 4 191.154.56.0 191.154.63.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100037 701822 4 146.158.31.0 146.158.31.255 47.0951 37.5413 100.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000370 3688689 4 191.154.80.0 191.154.83.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000371 3688689 4 191.154.88.0 191.154.95.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000372 3688689 4 191.154.96.0 191.154.111.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000373 3688689 4 191.154.112.0 191.154.127.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000374 3688689 4 191.154.128.0 191.154.131.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000375 3688689 4 191.154.132.0 191.154.133.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000376 3688689 4 191.154.135.0 191.154.135.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000377 3688689 4 191.154.136.0 191.154.143.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000378 3688689 4 191.154.144.0 191.154.159.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000379 3688689 4 191.154.160.0 191.154.175.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100038 701822 4 5.104.32.0 5.104.35.255 47.0951 37.5413 50.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000380 3688689 4 191.154.176.0 191.154.191.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000381 3688689 4 191.154.192.0 191.154.223.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000382 3688689 4 191.154.224.0 191.154.231.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000383 3688689 4 191.154.248.0 191.154.255.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000384 3688689 4 191.155.160.0 191.155.175.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000385 3688689 4 191.156.11.192 191.156.11.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000386 3688689 4 191.156.18.0 191.156.18.31 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000387 3688689 4 191.156.18.32 191.156.18.47 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000388 3688689 4 191.156.18.64 191.156.18.127 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000389 3688689 4 191.156.18.128 191.156.18.191 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100039 701822 4 5.104.36.0 5.104.39.255 47.0951 37.5413 100.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000390 3688689 4 191.156.19.0 191.156.19.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000391 3688689 4 191.156.24.0 191.156.25.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000392 3688689 4 191.156.26.0 191.156.26.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000393 3688689 4 191.156.27.0 191.156.27.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000394 3688689 4 191.156.28.0 191.156.29.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000395 3688689 4 191.156.30.128 191.156.30.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000396 3688689 4 191.156.31.0 191.156.31.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000397 3688689 4 191.156.33.0 191.156.33.127 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000398 3688689 4 191.156.34.128 191.156.34.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000399 3688689 4 191.156.35.0 191.156.35.127 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +10004 3150851 4 109.189.3.0 109.189.3.255 60.1379 11.2041 1.0 en EU Europe NO Norway 30 Viken Jessheim Europe/Oslo 1 1618978544000000 0 +100040 701822 4 5.104.40.0 5.104.47.255 47.0951 37.5413 1000.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000400 3688689 4 191.156.36.128 191.156.36.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000401 3688689 4 191.156.37.0 191.156.37.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000402 3688689 4 191.156.41.128 191.156.41.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000403 3688689 4 191.156.42.128 191.156.42.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000404 3688689 4 191.156.43.48 191.156.43.63 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000405 3688689 4 191.156.43.224 191.156.43.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000406 3688689 4 191.156.44.0 191.156.44.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000407 3688689 4 191.156.45.128 191.156.45.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000408 3688689 4 191.156.46.0 191.156.46.127 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000409 3688689 4 191.156.47.0 191.156.47.127 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100041 701822 4 5.104.48.0 5.104.63.255 47.0951 37.5413 100.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000410 3688689 4 191.156.48.0 191.156.48.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000411 3688689 4 191.156.49.0 191.156.49.31 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000412 3688689 4 191.156.49.48 191.156.49.63 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000413 3688689 4 191.156.49.64 191.156.49.127 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000414 3688689 4 191.156.49.128 191.156.49.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000415 3688689 4 191.156.50.0 191.156.50.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000416 3688689 4 191.156.51.0 191.156.51.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000417 3688689 4 191.156.52.0 191.156.55.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000418 3688689 4 191.156.56.0 191.156.57.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000419 3688689 4 191.156.58.0 191.156.58.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100042 701822 4 5.105.0.0 5.105.3.255 47.0951 37.5413 20.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000420 3688689 4 191.156.59.0 191.156.59.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000421 3688689 4 191.156.60.0 191.156.60.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000422 3688689 4 191.156.61.0 191.156.61.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000423 3688689 4 191.156.62.0 191.156.62.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000424 3688689 4 191.156.63.0 191.156.63.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000425 3688689 4 191.156.64.0 191.156.65.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000426 3688689 4 191.156.66.0 191.156.66.127 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000427 3688689 4 191.156.66.192 191.156.66.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000428 3688689 4 191.156.67.0 191.156.67.127 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000429 3688689 4 191.156.68.0 191.156.68.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100043 701822 4 5.105.4.0 5.105.5.255 47.0951 37.5413 500.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000430 3688689 4 191.156.69.0 191.156.69.255 4.6493 -74.0617 1000.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000431 3688689 4 191.156.70.0 191.156.70.127 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000432 3688689 4 191.156.70.128 191.156.70.191 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000433 3688689 4 191.156.71.0 191.156.71.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000434 3688689 4 191.156.72.0 191.156.72.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000435 3688689 4 191.156.73.0 191.156.73.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000436 3688689 4 191.156.74.128 191.156.74.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000437 3688689 4 191.156.75.0 191.156.75.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000438 3688689 4 191.156.76.0 191.156.76.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000439 3688689 4 191.156.77.0 191.156.77.255 4.6493 -74.0617 1000.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100044 701822 4 5.105.6.0 5.105.6.255 47.0951 37.5413 50.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000440 3688689 4 191.156.78.0 191.156.78.127 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000441 3688689 4 191.156.79.0 191.156.79.127 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000442 3688689 4 191.157.248.0 191.157.251.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000443 3688689 4 191.158.4.0 191.158.5.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000444 3688689 4 191.158.32.0 191.158.39.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000445 3688689 4 191.158.64.0 191.158.79.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000446 3688689 4 191.158.104.0 191.158.107.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000447 3688689 4 191.158.108.0 191.158.108.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000448 3688689 4 191.158.110.0 191.158.111.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000449 3688689 4 191.158.112.0 191.158.127.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100045 701822 4 5.105.7.0 5.105.7.255 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000450 3688689 4 191.158.128.0 191.158.159.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000451 3688689 4 191.158.160.0 191.158.167.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000452 3688689 4 191.158.192.0 191.158.199.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000453 3688689 4 191.158.200.0 191.158.207.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000454 3688689 4 191.158.240.0 191.158.255.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000455 3688689 4 191.159.0.0 191.159.3.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000456 3688689 4 191.159.48.0 191.159.63.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000457 3688689 4 191.159.80.0 191.159.87.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000458 3688689 4 191.159.92.0 191.159.95.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000459 3688689 4 191.159.96.0 191.159.127.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100046 701822 4 5.105.8.0 5.105.15.255 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000460 3688689 4 191.159.128.0 191.159.135.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000461 3688689 4 191.159.208.0 191.159.215.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000462 3688689 4 191.159.240.0 191.159.255.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000463 3688689 4 198.49.128.0 198.49.129.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000464 3688689 4 198.49.131.0 198.49.131.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000465 3688689 4 200.2.64.0 200.2.65.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000466 3688689 4 200.2.66.0 200.2.66.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000467 3688689 4 200.2.67.0 200.2.67.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000468 3688689 4 200.2.68.0 200.2.71.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000469 3688689 4 200.3.147.0 200.3.147.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100047 701822 4 5.105.16.0 5.105.31.255 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000470 3688689 4 200.3.148.0 200.3.151.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000471 3688689 4 200.3.152.0 200.3.155.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000472 3688689 4 200.3.246.0 200.3.246.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000473 3688689 4 200.4.20.0 200.4.20.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000474 3688689 4 200.4.26.0 200.4.26.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000475 3688689 4 200.4.30.0 200.4.30.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000476 3688689 4 200.6.170.112 200.6.170.127 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000477 3688689 4 200.6.173.0 200.6.173.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000478 3688689 4 200.10.164.0 200.10.164.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000479 3688689 4 200.13.192.0 200.13.223.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100048 701822 4 5.105.32.0 5.105.39.255 47.0951 37.5413 20.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000480 3688689 4 200.13.232.0 200.13.233.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000481 3688689 4 200.13.235.0 200.13.235.127 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000482 3688689 4 200.13.236.0 200.13.239.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000483 3688689 4 200.14.40.0 200.14.41.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000484 3688689 4 200.14.42.0 200.14.42.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000485 3688689 4 200.14.45.0 200.14.45.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000486 3688689 4 200.14.206.128 200.14.206.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000487 3688689 4 200.14.239.0 200.14.239.127 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000488 3688689 4 200.14.253.0 200.14.253.127 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000489 3688689 4 200.21.176.0 200.21.183.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100049 701822 4 5.105.40.0 5.105.43.255 47.0951 37.5413 20.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000490 3688689 4 200.21.192.0 200.21.195.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000491 3688689 4 200.21.240.0 200.21.240.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000492 3688689 4 200.25.0.0 200.25.15.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000493 3688689 4 200.25.16.0 200.25.19.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000494 3688689 4 200.25.24.0 200.25.25.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000495 3688689 4 200.25.26.0 200.25.26.255 4.5806 -74.0421 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000496 3688689 4 200.25.27.0 200.25.27.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000497 3688689 4 200.25.28.0 200.25.31.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000498 3688689 4 200.25.32.0 200.25.47.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000499 3688689 4 200.25.48.0 200.25.55.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +10005 3150851 4 109.189.4.0 109.189.4.255 60.1503 11.1644 10.0 en EU Europe NO Norway 30 Viken Jessheim Europe/Oslo 1 1618978544000000 0 +100050 701822 4 5.105.44.0 5.105.45.255 47.0951 37.5413 20.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000500 3688689 4 200.25.56.0 200.25.57.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000501 3688689 4 200.25.62.0 200.25.63.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000502 3688689 4 200.25.64.0 200.25.127.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000503 3688689 4 200.25.224.0 200.25.231.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000504 3688689 4 200.25.232.0 200.25.232.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000505 3688689 4 200.25.233.0 200.25.233.127 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000506 3688689 4 200.25.233.128 200.25.233.159 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000507 3688689 4 200.25.233.160 200.25.233.163 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000508 3688689 4 200.25.233.164 200.25.233.165 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000509 3688689 4 200.25.233.167 200.25.233.167 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100051 701822 4 5.105.46.0 5.105.46.255 47.0951 37.5413 20.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000510 3688689 4 200.25.233.168 200.25.233.175 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000511 3688689 4 200.25.233.176 200.25.233.191 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000512 3688689 4 200.25.233.192 200.25.233.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000513 3688689 4 200.25.234.0 200.25.235.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000514 3688689 4 200.25.236.0 200.25.239.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000515 3688689 4 200.26.136.0 200.26.139.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000516 3688689 4 200.26.146.0 200.26.147.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000517 3688689 4 200.26.152.0 200.26.153.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000518 3688689 4 200.26.155.0 200.26.155.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000519 3688689 4 200.26.156.0 200.26.159.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100052 701822 4 5.105.47.0 5.105.47.255 47.0951 37.5413 20.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000520 3688689 4 200.30.80.0 200.30.81.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000521 3688689 4 200.30.83.0 200.30.83.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000522 3688689 4 200.30.84.0 200.30.87.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000523 3688689 4 200.30.88.0 200.30.91.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000524 3688689 4 200.30.92.0 200.30.93.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000525 3688689 4 200.30.96.0 200.30.127.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000526 3688689 4 200.31.23.208 200.31.23.223 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000527 3688689 4 200.31.64.0 200.31.67.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000528 3688689 4 200.47.216.0 200.47.219.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000529 3688689 4 200.69.68.0 200.69.68.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100053 701822 4 5.105.48.0 5.105.55.255 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000530 3688689 4 200.69.71.128 200.69.71.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000531 3688689 4 200.69.73.0 200.69.73.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000532 3688689 4 200.69.74.0 200.69.74.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000533 3688689 4 200.69.75.0 200.69.75.127 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000534 3688689 4 200.69.81.0 200.69.81.63 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000535 3688689 4 200.69.81.64 200.69.81.95 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000536 3688689 4 200.69.81.128 200.69.81.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000537 3688689 4 200.69.82.0 200.69.82.127 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000538 3688689 4 200.69.83.0 200.69.83.63 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000539 3688689 4 200.69.83.128 200.69.83.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100054 701822 4 5.105.56.0 5.105.59.255 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000540 3688689 4 200.69.101.0 200.69.101.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000541 3688689 4 200.69.103.0 200.69.103.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000542 3688689 4 200.69.125.190 200.69.125.191 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000543 3688689 4 200.69.125.196 200.69.125.199 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000544 3688689 4 200.69.125.204 200.69.125.207 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000545 3688689 4 200.69.125.212 200.69.125.215 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000546 3688689 4 200.69.125.220 200.69.125.220 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000547 3688689 4 200.71.32.0 200.71.39.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000548 3688689 4 200.71.42.0 200.71.43.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000549 3688689 4 200.71.44.0 200.71.45.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100055 701822 4 5.105.60.0 5.105.61.255 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000550 3688689 4 200.71.50.0 200.71.51.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000551 3688689 4 200.71.52.0 200.71.55.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000552 3688689 4 200.71.57.0 200.71.57.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000553 3688689 4 200.71.58.0 200.71.59.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000554 3688689 4 200.71.62.0 200.71.63.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000555 3688689 4 200.74.136.0 200.74.139.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000556 3688689 4 200.74.144.0 200.74.159.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000557 3688689 4 200.75.32.0 200.75.33.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000558 3688689 4 200.75.40.0 200.75.43.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000559 3688689 4 200.75.44.0 200.75.44.3 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100056 701822 4 5.105.62.0 5.105.62.127 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000560 3688689 4 200.75.44.4 200.75.44.5 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000561 3688689 4 200.75.44.7 200.75.44.7 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000562 3688689 4 200.75.44.8 200.75.44.15 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000563 3688689 4 200.75.44.16 200.75.44.31 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000564 3688689 4 200.75.44.32 200.75.44.63 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000565 3688689 4 200.75.44.64 200.75.44.127 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000566 3688689 4 200.75.44.128 200.75.44.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000567 3688689 4 200.75.45.0 200.75.45.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000568 3688689 4 200.75.46.0 200.75.47.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000569 3688689 4 200.75.48.0 200.75.49.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100057 701822 4 5.105.62.128 5.105.62.255 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000570 3688689 4 200.85.224.0 200.85.227.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000571 3688689 4 200.85.228.0 200.85.229.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000572 3688689 4 200.85.230.0 200.85.230.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000573 3688689 4 200.85.232.0 200.85.239.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000574 3688689 4 200.85.240.0 200.85.243.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000575 3688689 4 200.85.248.0 200.85.255.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000576 3688689 4 200.89.224.0 200.89.231.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000577 3688689 4 200.89.236.0 200.89.239.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000578 3688689 4 200.89.240.0 200.89.255.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000579 3688689 4 200.91.206.0 200.91.207.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100058 701822 4 5.105.63.0 5.105.63.255 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000580 3688689 4 200.91.208.0 200.91.208.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000581 3688689 4 200.91.210.0 200.91.210.255 4.6493 -74.0617 1000.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000582 3688689 4 200.91.218.0 200.91.219.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000583 3688689 4 200.91.224.0 200.91.227.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000584 3688689 4 200.91.228.0 200.91.228.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000585 3688689 4 200.91.229.0 200.91.229.127 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000586 3688689 4 200.91.229.128 200.91.229.143 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000587 3688689 4 200.91.229.152 200.91.229.159 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000588 3688689 4 200.91.229.160 200.91.229.191 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000589 3688689 4 200.91.229.192 200.91.229.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100059 701822 4 5.105.64.0 5.105.67.255 47.0951 37.5413 500.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000590 3688689 4 200.91.230.0 200.91.231.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000591 3688689 4 200.91.232.0 200.91.239.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000592 3688689 4 200.91.240.0 200.91.255.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000593 3688689 4 200.93.135.192 200.93.135.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000594 3688689 4 200.93.144.0 200.93.147.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000595 3688689 4 200.93.154.0 200.93.155.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000596 3688689 4 200.93.167.0 200.93.167.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000597 3688689 4 200.93.168.64 200.93.168.127 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000598 3688689 4 200.93.168.128 200.93.168.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000599 3688689 4 200.93.169.0 200.93.169.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +10006 3150851 4 176.11.178.128 176.11.178.255 60.1379 11.2041 100.0 en EU Europe NO Norway 30 Viken Jessheim Europe/Oslo 1 1618978544000000 0 +100060 701822 4 5.105.68.0 5.105.68.255 47.0951 37.5413 500.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000600 3688689 4 200.93.170.0 200.93.171.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000601 3688689 4 200.93.172.0 200.93.175.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000602 3688689 4 200.93.176.0 200.93.191.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000603 3688689 4 200.106.160.0 200.106.191.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000604 3688689 4 200.106.192.0 200.106.223.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000605 3688689 4 200.116.7.0 200.116.7.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000606 3688689 4 200.116.50.0 200.116.51.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000607 3688689 4 200.116.52.0 200.116.55.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000608 3688689 4 200.116.61.0 200.116.61.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000609 3688689 4 200.116.77.0 200.116.77.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100061 701822 4 5.105.69.0 5.105.69.255 47.0951 37.5413 500.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000610 3688689 4 200.116.104.0 200.116.104.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000611 3688689 4 200.116.122.0 200.116.123.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000612 3688689 4 200.116.124.0 200.116.127.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000613 3688689 4 200.116.147.0 200.116.147.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000614 3688689 4 200.116.183.0 200.116.183.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000615 3688689 4 200.116.206.128 200.116.206.255 4.6493 -74.0617 1000.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000616 3688689 4 200.118.0.0 200.118.15.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000617 3688689 4 200.118.16.0 200.118.19.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000618 3688689 4 200.118.20.0 200.118.21.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000619 3688689 4 200.118.24.0 200.118.31.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100062 701822 4 5.105.70.0 5.105.71.255 47.0951 37.5413 500.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000620 3688689 4 200.118.40.0 200.118.47.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000621 3688689 4 200.118.52.0 200.118.55.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000622 3688689 4 200.118.58.0 200.118.59.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000623 3688689 4 200.118.60.0 200.118.63.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000624 3688689 4 200.118.64.0 200.118.71.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000625 3688689 4 200.118.72.0 200.118.75.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000626 3688689 4 200.118.76.0 200.118.77.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000627 3688689 4 200.118.78.0 200.118.78.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000628 3688689 4 200.118.79.0 200.118.79.15 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000629 3688689 4 200.118.79.16 200.118.79.19 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100063 701822 4 5.105.72.0 5.105.75.255 47.0951 37.5413 500.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000630 3688689 4 200.118.79.21 200.118.79.21 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000631 3688689 4 200.118.79.22 200.118.79.23 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000632 3688689 4 200.118.79.24 200.118.79.31 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000633 3688689 4 200.118.79.32 200.118.79.63 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000634 3688689 4 200.118.79.64 200.118.79.127 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000635 3688689 4 200.118.79.128 200.118.79.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000636 3688689 4 200.118.80.0 200.118.95.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000637 3688689 4 200.118.96.0 200.118.99.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000638 3688689 4 200.118.100.0 200.118.103.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000639 3688689 4 200.118.112.0 200.118.112.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100064 701822 4 5.105.76.0 5.105.76.255 47.0951 37.5413 500.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000640 3688689 4 200.118.114.0 200.118.114.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000641 3688689 4 200.118.116.0 200.118.119.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000642 3688689 4 200.118.128.0 200.118.129.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000643 3688689 4 200.118.130.0 200.118.131.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000644 3688689 4 200.118.132.0 200.118.135.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000645 3688689 4 200.118.140.0 200.118.140.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000646 3688689 4 200.118.142.0 200.118.143.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000647 3688689 4 200.118.144.0 200.118.147.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000648 3688689 4 200.118.148.0 200.118.149.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000649 3688689 4 200.118.150.0 200.118.151.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100065 701822 4 5.105.78.0 5.105.78.255 47.0951 37.5413 500.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000650 3688689 4 200.118.152.0 200.118.159.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000651 3688689 4 200.118.168.0 200.118.171.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000652 3688689 4 200.118.184.0 200.118.191.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000653 3688689 4 200.118.192.0 200.118.193.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000654 3688689 4 200.118.200.0 200.118.203.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000655 3688689 4 200.118.208.0 200.118.209.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000656 3688689 4 200.118.210.0 200.118.211.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000657 3688689 4 200.118.216.0 200.118.217.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000658 3688689 4 200.118.219.0 200.118.219.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000659 3688689 4 200.118.220.0 200.118.223.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100066 701822 4 5.105.79.128 5.105.79.255 47.0951 37.5413 500.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000660 3688689 4 200.118.224.0 200.118.227.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000661 3688689 4 200.118.232.0 200.118.239.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000662 3688689 4 200.118.240.0 200.118.243.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000663 3688689 4 200.118.244.0 200.118.244.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000664 3688689 4 200.118.246.0 200.118.247.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000665 3688689 4 200.118.248.0 200.118.248.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000666 3688689 4 200.118.249.0 200.118.249.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000667 3688689 4 200.118.250.0 200.118.251.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000668 3688689 4 200.118.252.0 200.118.253.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000669 3688689 4 200.119.16.0 200.119.31.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100067 701822 4 5.105.80.0 5.105.87.255 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000670 3688689 4 200.119.32.0 200.119.47.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000671 3688689 4 200.119.48.0 200.119.48.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000672 3688689 4 200.119.49.0 200.119.49.127 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000673 3688689 4 200.119.50.0 200.119.50.127 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000674 3688689 4 200.119.51.0 200.119.51.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000675 3688689 4 200.119.52.0 200.119.52.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000676 3688689 4 200.119.53.128 200.119.53.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000677 3688689 4 200.119.54.0 200.119.54.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000678 3688689 4 200.119.55.0 200.119.55.127 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000679 3688689 4 200.119.55.128 200.119.55.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100068 701822 4 5.105.88.0 5.105.91.255 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000680 3688689 4 200.119.56.0 200.119.59.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000681 3688689 4 200.119.60.0 200.119.61.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000682 3688689 4 200.119.62.0 200.119.63.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000683 3688689 4 200.119.84.0 200.119.84.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000684 3688689 4 200.119.96.0 200.119.111.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000685 3688689 4 200.119.114.0 200.119.115.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000686 3688689 4 200.119.124.0 200.119.125.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000687 3688689 4 200.119.126.0 200.119.126.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000688 3688689 4 200.122.193.232 200.122.193.233 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000689 3688689 4 200.122.217.0 200.122.217.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100069 701822 4 5.105.92.0 5.105.93.255 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000690 3688689 4 200.122.224.0 200.122.231.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000691 3688689 4 200.122.232.0 200.122.235.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000692 3688689 4 200.122.236.128 200.122.236.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000693 3688689 4 200.122.240.0 200.122.241.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000694 3688689 4 200.122.244.0 200.122.247.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000695 3688689 4 200.122.248.0 200.122.248.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000696 3688689 4 200.122.250.0 200.122.250.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000697 3688689 4 200.122.254.0 200.122.255.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000698 3688689 4 200.124.124.0 200.124.125.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000699 3688689 4 201.131.78.0 201.131.78.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +10007 3150851 4 176.11.225.224 176.11.225.255 60.159 11.1407 100.0 en EU Europe NO Norway 30 Viken Jessheim Europe/Oslo 1 1618978544000000 0 +100070 701822 4 5.105.94.0 5.105.94.255 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000700 3688689 4 201.184.0.0 201.184.0.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000701 3688689 4 201.184.2.0 201.184.2.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000702 3688689 4 201.184.3.128 201.184.3.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000703 3688689 4 201.184.4.0 201.184.5.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000704 3688689 4 201.184.8.0 201.184.15.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000705 3688689 4 201.184.37.0 201.184.37.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000706 3688689 4 201.184.41.0 201.184.41.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000707 3688689 4 201.184.43.0 201.184.43.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000708 3688689 4 201.184.65.0 201.184.65.127 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000709 3688689 4 201.184.65.128 201.184.65.191 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100071 701822 4 5.105.95.0 5.105.95.127 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000710 3688689 4 201.184.65.192 201.184.65.207 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000711 3688689 4 201.184.65.208 201.184.65.211 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000712 3688689 4 201.184.65.212 201.184.65.212 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000713 3688689 4 201.184.65.214 201.184.65.215 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000714 3688689 4 201.184.65.216 201.184.65.223 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000715 3688689 4 201.184.65.224 201.184.65.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000716 3688689 4 201.184.66.0 201.184.67.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000717 3688689 4 201.184.69.0 201.184.69.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000718 3688689 4 201.184.70.0 201.184.71.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000719 3688689 4 201.184.72.0 201.184.73.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100072 701822 4 5.105.95.128 5.105.95.191 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000720 3688689 4 201.184.75.0 201.184.75.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000721 3688689 4 201.184.76.0 201.184.79.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000722 3688689 4 201.184.80.0 201.184.81.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000723 3688689 4 201.184.84.0 201.184.87.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000724 3688689 4 201.184.88.0 201.184.88.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000725 3688689 4 201.184.89.128 201.184.89.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000726 3688689 4 201.184.90.0 201.184.91.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000727 3688689 4 201.184.94.0 201.184.95.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000728 3688689 4 201.184.96.0 201.184.99.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000729 3688689 4 201.184.100.0 201.184.101.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100073 701822 4 5.105.95.192 5.105.95.207 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000730 3688689 4 201.184.103.0 201.184.103.63 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000731 3688689 4 201.184.103.64 201.184.103.79 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000732 3688689 4 201.184.103.96 201.184.103.127 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000733 3688689 4 201.184.103.128 201.184.103.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000734 3688689 4 201.184.104.0 201.184.107.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000735 3688689 4 201.184.108.0 201.184.108.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000736 3688689 4 201.184.109.0 201.184.109.127 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000737 3688689 4 201.184.110.0 201.184.111.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000738 3688689 4 201.184.112.128 201.184.112.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000739 3688689 4 201.184.115.0 201.184.115.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100074 701822 4 5.105.95.208 5.105.95.223 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000740 3688689 4 201.184.116.0 201.184.119.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000741 3688689 4 201.184.120.0 201.184.127.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000742 3688689 4 201.185.60.0 201.185.63.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000743 3688689 4 201.185.64.0 201.185.64.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000744 3688689 4 201.185.65.0 201.185.65.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000745 3688689 4 201.185.72.0 201.185.73.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000746 3688689 4 201.185.74.0 201.185.75.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000747 3688689 4 201.185.80.0 201.185.95.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000748 3688689 4 201.185.96.0 201.185.96.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000749 3688689 4 201.185.97.0 201.185.97.127 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100075 701822 4 5.105.95.224 5.105.95.255 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000750 3688689 4 201.185.97.128 201.185.97.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000751 3688689 4 201.185.98.0 201.185.98.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000752 3688689 4 201.185.99.0 201.185.99.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000753 3688689 4 201.185.100.0 201.185.101.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000754 3688689 4 201.185.102.0 201.185.103.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000755 3688689 4 201.185.104.0 201.185.111.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000756 3688689 4 201.185.112.0 201.185.127.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000757 3688689 4 201.185.128.0 201.185.131.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000758 3688689 4 201.185.132.0 201.185.132.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000759 3688689 4 201.185.134.0 201.185.135.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100076 701822 4 5.105.96.0 5.105.111.255 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000760 3688689 4 201.185.136.0 201.185.136.127 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000761 3688689 4 201.185.136.128 201.185.136.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000762 3688689 4 201.185.137.0 201.185.137.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000763 3688689 4 201.185.138.0 201.185.139.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000764 3688689 4 201.185.140.0 201.185.143.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000765 3688689 4 201.185.144.0 201.185.151.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000766 3688689 4 201.185.152.0 201.185.153.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000767 3688689 4 201.185.154.0 201.185.155.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000768 3688689 4 201.185.156.0 201.185.159.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000769 3688689 4 201.216.0.0 201.216.3.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100077 701822 4 5.105.112.0 5.105.115.255 47.0951 37.5413 50.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000770 3688689 4 201.216.6.0 201.216.7.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000771 3688689 4 201.216.12.0 201.216.12.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000772 3688689 4 201.216.13.0 201.216.13.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000773 3688689 4 201.216.14.0 201.216.15.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000774 3688689 4 201.216.16.0 201.216.17.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000775 3688689 4 201.216.18.0 201.216.19.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000776 3688689 4 201.216.20.0 201.216.23.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000777 3688689 4 201.216.28.0 201.216.29.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000778 3688689 4 201.216.32.0 201.216.35.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000779 3688689 4 201.216.38.0 201.216.39.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100078 701822 4 5.105.116.0 5.105.116.127 47.0951 37.5413 50.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000780 3688689 4 201.216.40.0 201.216.41.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000781 3688689 4 201.216.46.0 201.216.47.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000782 3688689 4 201.216.48.0 201.216.63.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000783 3688689 4 201.217.192.0 201.217.195.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000784 3688689 4 201.217.196.0 201.217.197.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000785 3688689 4 201.217.198.0 201.217.198.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000786 3688689 4 201.217.200.0 201.217.201.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000787 3688689 4 201.217.203.0 201.217.203.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000788 3688689 4 201.217.205.0 201.217.205.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000789 3688689 4 201.217.209.0 201.217.209.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100079 701822 4 5.105.116.128 5.105.116.191 47.0951 37.5413 50.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000790 3688689 4 201.217.210.0 201.217.211.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000791 3688689 4 201.217.213.0 201.217.213.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000792 3688689 4 201.217.216.0 201.217.216.127 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000793 3688689 4 201.217.217.0 201.217.217.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000794 3688689 4 201.217.218.0 201.217.219.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000795 3688689 4 201.217.220.0 201.217.223.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000796 3688689 4 201.219.219.0 201.219.219.127 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000797 3688689 4 201.219.219.128 201.219.219.191 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000798 3688689 4 201.219.219.192 201.219.219.199 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000799 3688689 4 201.219.219.208 201.219.219.223 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +10008 3150851 4 193.214.55.128 193.214.55.255 60.1574 11.1694 200.0 en EU Europe NO Norway 30 Viken Jessheim Europe/Oslo 1 1618978544000000 0 +100080 701822 4 5.105.116.192 5.105.116.255 47.0951 37.5413 50.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000800 3688689 4 201.219.219.224 201.219.219.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000801 3688689 4 201.221.160.0 201.221.167.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000802 3688689 4 201.221.172.0 201.221.175.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000803 3688689 4 201.221.176.0 201.221.183.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000804 3688689 4 201.221.188.0 201.221.191.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000805 3688689 4 201.228.81.0 201.228.81.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000806 3688689 4 201.228.82.0 201.228.82.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000807 3688689 4 201.228.83.0 201.228.83.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000808 3688689 4 201.228.224.0 201.228.225.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000809 3688689 4 201.228.226.0 201.228.226.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100081 701822 4 5.105.117.0 5.105.117.255 47.0951 37.5413 50.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000810 3688689 4 201.228.228.0 201.228.228.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000811 3688689 4 201.228.229.0 201.228.229.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000812 3688689 4 201.228.230.0 201.228.230.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000813 3688689 4 201.228.231.0 201.228.231.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000814 3688689 4 201.228.232.0 201.228.235.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000815 3688689 4 201.228.238.0 201.228.239.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000816 3688689 4 201.228.240.0 201.228.240.255 4.6493 -74.0617 1000.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000817 3688689 4 201.228.241.0 201.228.241.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000818 3688689 4 201.228.243.0 201.228.243.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000819 3688689 4 201.228.244.0 201.228.244.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100082 701822 4 5.105.118.0 5.105.119.255 47.0951 37.5413 50.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000820 3688689 4 201.228.245.64 201.228.245.127 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000821 3688689 4 201.228.245.128 201.228.245.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000822 3688689 4 201.228.246.0 201.228.247.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000823 3688689 4 201.228.248.128 201.228.248.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000824 3688689 4 201.228.249.0 201.228.249.255 4.6493 -74.0617 50.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000825 3688689 4 201.228.250.0 201.228.251.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000826 3688689 4 201.228.252.0 201.228.252.255 4.6493 -74.0617 500.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000827 3688689 4 201.228.253.0 201.228.253.127 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000828 3688689 4 201.228.253.128 201.228.253.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000829 3688689 4 201.228.254.0 201.228.254.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100083 701822 4 5.105.120.0 5.105.123.255 47.0951 37.5413 50.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000830 3688689 4 201.232.244.0 201.232.244.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000831 3688689 4 201.233.136.0 201.233.136.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000832 3688689 4 201.233.201.0 201.233.201.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000833 3688689 4 201.233.232.0 201.233.232.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000834 3688689 4 201.233.233.0 201.233.233.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000835 3688689 4 201.233.234.0 201.233.234.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000836 3688689 4 201.233.235.0 201.233.235.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000837 3688689 4 201.233.236.0 201.233.239.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000838 3688689 4 201.234.245.168 201.234.245.175 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000839 3688689 4 201.236.210.0 201.236.210.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100084 701822 4 5.105.124.0 5.105.125.255 47.0951 37.5413 50.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000840 3688689 4 201.244.4.0 201.244.5.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000841 3688689 4 201.244.20.0 201.244.23.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000842 3688689 4 201.244.32.0 201.244.35.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000843 3688689 4 201.244.36.0 201.244.37.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000844 3688689 4 201.244.40.128 201.244.40.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000845 3688689 4 201.244.41.0 201.244.41.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000846 3688689 4 201.244.42.0 201.244.43.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000847 3688689 4 201.244.44.0 201.244.47.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000848 3688689 4 201.244.48.0 201.244.63.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000849 3688689 4 201.244.64.0 201.244.95.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100085 701822 4 5.105.126.0 5.105.127.255 47.0951 37.5413 50.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000850 3688689 4 201.244.96.0 201.244.99.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000851 3688689 4 201.244.100.0 201.244.101.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000852 3688689 4 201.244.102.0 201.244.102.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000853 3688689 4 201.244.103.0 201.244.103.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000854 3688689 4 201.244.104.0 201.244.104.127 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000855 3688689 4 201.244.105.0 201.244.105.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000856 3688689 4 201.244.106.0 201.244.107.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000857 3688689 4 201.244.108.0 201.244.108.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000858 3688689 4 201.244.109.0 201.244.109.127 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000859 3688689 4 201.244.110.0 201.244.111.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100086 701822 4 5.105.128.0 5.105.135.255 47.0951 37.5413 1.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000860 3688689 4 201.244.112.0 201.244.127.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000861 3688689 4 201.244.128.0 201.244.135.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000862 3688689 4 201.244.136.0 201.244.137.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000863 3688689 4 201.244.138.0 201.244.138.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000864 3688689 4 201.244.139.0 201.244.139.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000865 3688689 4 201.244.140.0 201.244.143.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000866 3688689 4 201.244.144.0 201.244.159.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000867 3688689 4 201.244.160.0 201.244.161.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000868 3688689 4 201.244.163.0 201.244.163.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000869 3688689 4 201.244.167.0 201.244.167.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100087 701822 4 5.105.144.0 5.105.144.255 47.0951 37.5413 100.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000870 3688689 4 201.244.168.0 201.244.169.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000871 3688689 4 201.244.170.0 201.244.170.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000872 3688689 4 201.244.172.0 201.244.175.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000873 3688689 4 201.244.176.0 201.244.176.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000874 3688689 4 201.244.178.0 201.244.179.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000875 3688689 4 201.244.180.0 201.244.183.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000876 3688689 4 201.244.184.0 201.244.191.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000877 3688689 4 201.244.192.0 201.244.195.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000878 3688689 4 201.244.196.0 201.244.196.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000879 3688689 4 201.244.197.0 201.244.197.127 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100088 701822 4 5.105.145.0 5.105.145.255 47.0951 37.5413 200.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000880 3688689 4 201.244.197.128 201.244.197.255 4.6493 -74.0617 1.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000881 3688689 4 201.244.198.0 201.244.199.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000882 3688689 4 201.244.200.0 201.244.207.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000883 3688689 4 201.244.208.0 201.244.223.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000884 3688689 4 201.244.224.0 201.244.225.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000885 3688689 4 201.244.226.0 201.244.226.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000886 3688689 4 201.244.227.0 201.244.227.127 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000887 3688689 4 201.244.227.192 201.244.227.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000888 3688689 4 201.244.228.0 201.244.231.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000889 3688689 4 201.244.232.0 201.244.232.127 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +100089 701822 4 5.105.146.0 5.105.147.255 47.0951 37.5413 10.0 en EU Europe UA Ukraine 14 Donets'ka\bOblast' Mariupol Europe/Kiev 1 1618978544000000 0 +1000890 3688689 4 201.244.232.128 201.244.232.255 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000891 3688689 4 201.244.233.0 201.244.233.127 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000892 3688689 4 201.244.234.0 201.244.234.255 4.6493 -74.0617 20.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000893 3688689 4 201.244.235.0 201.244.235.127 4.6493 -74.0617 10.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000894 3688689 4 201.244.235.128 201.244.235.191 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000895 3688689 4 201.244.236.0 201.244.236.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000896 3688689 4 201.244.237.0 201.244.237.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000897 3688689 4 201.244.238.0 201.244.239.255 4.6493 -74.0617 200.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000898 3688689 4 201.244.240.0 201.244.241.255 4.6493 -74.0617 5.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +1000899 3688689 4 201.244.242.0 201.244.242.255 4.6493 -74.0617 100.0 en SA South\bAmerica CO Colombia DC Bogota\bD.C. Bogotá America/Bogota 1 1618978544000000 0 +10009 3150851 4 195.1.152.128 195.1.152.255 60.159 11.1407 100.0 en EU Europe NO Norway 30 Viken Jessheim Europe/Oslo 1 1618978544000000 0 diff --git a/test/tsgrule/full/index/full_config_index.00000000000000106967 b/test/tsgrule/full/index/full_config_index.00000000000000106967 new file mode 100644 index 0000000..f34f6f2 --- /dev/null +++ b/test/tsgrule/full/index/full_config_index.00000000000000106967 @@ -0,0 +1,2 @@ +TSG_IP_LOCATION_BUILT_IN 1000 ./tsgrule/TSG_IP_LOCATION_BUILT_IN.head_1k +