Ground-Zerro / HydraRoute Public
Code Issues Pull requests Actions Releases View on GitHub ↗
2.8 KB c
#include "../include/geodat.h"
#include "../include/util.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

static size_t put_varint(uint8_t *p, uint64_t v) {
    size_t n = 0;
    while (v >= 0x80) { p[n++] = (uint8_t)(v | 0x80); v >>= 7; }
    p[n++] = (uint8_t)v;
    return n;
}

static size_t put_bytes(uint8_t *p, uint8_t tag, const void *data, uint64_t declared, size_t len) {
    size_t n = 0;
    p[n++] = tag;
    n += put_varint(p + n, declared);
    memcpy(p + n, data, len);
    return n + len;
}

static size_t geosite_entry(uint8_t *p, const char *code, uint64_t code_decl,
                            const char *domain, uint64_t domain_decl) {
    uint8_t dom[300], body[600];
    size_t dn = 0, bn = 0;
    dom[dn++] = 0x08;
    dom[dn++] = 2;
    dn += put_bytes(dom + dn, 0x12, domain, domain_decl, strlen(domain));
    bn += put_bytes(body + bn, 0x0A, code, code_decl, strlen(code));
    bn += put_bytes(body + bn, 0x12, dom, dn, dn);
    return put_bytes(p, 0x0A, body, bn, bn);
}

static void write_file(const char *path, const uint8_t *data, size_t len) {
    FILE *f = fopen(path, "wb");
    assert(f);
    assert(fwrite(data, 1, len, f) == len);
    fclose(f);
}

static int load(const char *path, const char *tag, const char *probe) {
    char files[1][512];
    snprintf(files[0], sizeof(files[0]), "%s", path);
    geosite_rule_t rule;
    memset(&rule, 0, sizeof(rule));
    snprintf(rule.tag, sizeof(rule.tag), "%s", tag);
    snprintf(rule.policy_name, sizeof(rule.policy_name), "HR");
    domain_hashtable_t *ht = ht_create();
    build_geosite_domain_map((const char (*)[512])files, 1, &rule, 1, ht);
    int found = ht_lookup(ht, probe, strlen(probe)) != NULL;
    ht_destroy(ht);
    return found;
}

int main(void) {
    char path[] = "/tmp/check_geodat_XXXXXX";
    int fd = mkstemp(path);
    assert(fd >= 0);
    close(fd);
    alarm(5);

    uint8_t buf[4096];
    size_t n = 0;
    n += geosite_entry(buf + n, "other", 5, "skip.example", 12);
    n += geosite_entry(buf + n, "test", 4, "example.com", 11);
    write_file(path, buf, n);
    assert(load(path, "TEST", "example.com"));
    assert(!load(path, "TEST", "skip.example"));
    assert(!load(path, "TES", "example.com"));

    n = geosite_entry(buf, "test", 0xFFFFFFFFu, "example.com", 11);
    write_file(path, buf, n);
    assert(!load(path, "TEST", "example.com"));

    n = geosite_entry(buf, "test", 4, "example.com", 0xFFFFFFFAu);
    write_file(path, buf, n);
    assert(!load(path, "TEST", "example.com"));

    n = 0;
    buf[n++] = 0x0A;
    n += put_varint(buf + n, 0xFFFFFFFFFFFFull);
    n += geosite_entry(buf + n, "test", 4, "example.com", 11);
    write_file(path, buf, n);
    assert(!load(path, "TEST", "example.com"));

    unlink(path);
    puts("check_geodat: OK");
    return 0;
}