Пример #1
0
F_NONNULL
static void geoip2_list_xlate_recurse(geoip2_t* db, nlist_t* nl, struct in6_addr ip, unsigned depth, const uint32_t node_count, const uint32_t node_num) {
    dmn_assert(db); dmn_assert(nl);
    dmn_assert(depth < 129U);

    if(!depth) {
        log_err("plugin_geoip: map '%s': GeoIP2 database '%s': Error while traversing tree nodes: depth too low", db->map_name, db->pathname);
        siglongjmp(db->jbuf, 1);
    }

    // skip v4-like spaces other than canonical compat area
    if(
        (depth == 32 && (
               !memcmp(ip.s6_addr, start_v4mapped, 12U)
            || !memcmp(ip.s6_addr, start_siit, 12U)
            || !memcmp(ip.s6_addr, start_wkp, 12U)
        ))
        || (depth == 96U && !memcmp(ip.s6_addr, start_teredo, 4U))
        || (depth == 112U && !memcmp(ip.s6_addr, start_6to4, 2U))
    )
        return;

    MMDB_search_node_s node;
    int read_rv = MMDB_read_node(&db->mmdb, node_num, &node);
    if(read_rv != MMDB_SUCCESS) {
        log_err("plugin_geoip: map '%s': GeoIP2 database '%s': Error while traversing tree nodes: %s",
            db->map_name, db->pathname, MMDB_strerror(read_rv));
        siglongjmp(db->jbuf, 1);
    }

    const uint32_t zero_node_num = node.left_record;
    const uint32_t one_node_num = node.right_record;
    const unsigned new_depth = depth - 1U;
    const unsigned mask = 128U - new_depth;

    if(zero_node_num >= node_count)
        nlist_append(nl, ip.s6_addr, mask, geoip2_get_dclist_cached(db, zero_node_num - node_count));
    else
        geoip2_list_xlate_recurse(db, nl, ip, new_depth, node_count, zero_node_num);

    SETBIT_v6(ip.s6_addr, mask - 1U);

    if(one_node_num >= node_count)
        nlist_append(nl, ip.s6_addr, mask, geoip2_get_dclist_cached(db, one_node_num - node_count));
    else
        geoip2_list_xlate_recurse(db, nl, ip, new_depth, node_count, one_node_num);
}
Пример #2
0
void run_read_node_tests(MMDB_s *mmdb, const uint32_t tests[][5],
                         int test_count,
                         uint8_t record_size)
{
    for (int i = 0; i < test_count; i++) {
        uint32_t node_number = tests[i][0];
        MMDB_search_node_s node;
        int status = MMDB_read_node(mmdb, node_number, &node);
        if (MMDB_SUCCESS == status) {
            cmp_ok(node.left_record, "==", tests[i][1],
                   "left record for node %i is %i - %i bit DB",
                   node_number, tests[i][1], record_size);
            cmp_ok(node.left_record_type, "==", tests[i][2],
                   "left record type for node %i is %i", node_number,
                   tests[i][2]);
            if (node.left_record_type == MMDB_RECORD_TYPE_DATA) {
                test_entry_data(mmdb, &node.left_record_entry, node_number,
                                "left");
            }

            cmp_ok(node.right_record, "==", tests[i][3],
                   "right record for node %i is %i - %i bit DB",
                   node_number, tests[i][3], record_size);
            cmp_ok(node.right_record_type, "==", tests[i][4],
                   "right record type for node %i is %i", node_number,
                   tests[i][4]);

            if (node.right_record_type == MMDB_RECORD_TYPE_DATA) {
                test_entry_data(mmdb, &node.right_record_entry, node_number,
                                "right");
            }
        } else {
            diag("call to MMDB_read_node for node %i failed - %i bit DB",
                 node_number,
                 record_size);
        }
    }
}