static uint64_t hash(DnsResourceRecord *rr) {
        struct siphash state;

        siphash24_init(&state, HASH_KEY.bytes);
        dns_resource_record_hash_func(rr, &state);
        return siphash24_finalize(&state);
}
Exemple #2
0
static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r, const char *id, usec_t ts) {
        JournalRateLimitGroup *g;
        struct siphash state;

        assert(r);
        assert(id);

        g = new0(JournalRateLimitGroup, 1);
        if (!g)
                return NULL;

        g->id = strdup(id);
        if (!g->id)
                goto fail;

        siphash24_init(&state, r->hash_key);
        string_hash_func(g->id, &state);
        g->hash = siphash24_finalize(&state);

        journal_rate_limit_vacuum(r, ts);

        LIST_PREPEND(bucket, r->buckets[g->hash % BUCKETS_MAX], g);
        LIST_PREPEND(lru, r->lru, g);
        if (!g->lru_next)
                r->lru_tail = g;
        r->n_groups++;

        g->parent = r;
        return g;

fail:
        journal_rate_limit_group_free(g);
        return NULL;
}
Exemple #3
0
static int do_test(const uint8_t *in, size_t len, const uint8_t *key) {
        struct siphash state = {};
        uint64_t out = 0;
        unsigned i, j;

        out = siphash24(in, len, key);
        assert_se(out == 0xa129ca6149be45e5);

        /* verify the internal state as given in the above paper */
        siphash24_init(&state, key);
        assert_se(state.v0 == 0x7469686173716475);
        assert_se(state.v1 == 0x6b617f6d656e6665);
        assert_se(state.v2 == 0x6b7f62616d677361);
        assert_se(state.v3 == 0x7b6b696e727e6c7b);
        siphash24_compress(in, len, &state);
        assert_se(state.v0 == 0x4a017198de0a59e0);
        assert_se(state.v1 == 0x0d52f6f62a4f59a4);
        assert_se(state.v2 == 0x634cb3577b01fd3d);
        assert_se(state.v3 == 0xa5224d6f55c7d9c8);
        out = siphash24_finalize(&state);
        assert_se(out == 0xa129ca6149be45e5);
        assert_se(state.v0 == 0xf6bcd53893fecff1);
        assert_se(state.v1 == 0x54b9964c7ea0d937);
        assert_se(state.v2 == 0x1b38329c099bb55a);
        assert_se(state.v3 == 0x1814bb89ad7be679);

        /* verify that decomposing the input in three chunks gives the
           same result */
        for (i = 0; i < len; i++) {
                for (j = i; j < len; j++) {
                        siphash24_init(&state, key);
                        siphash24_compress(in, i, &state);
                        siphash24_compress(&in[i], j - i, &state);
                        siphash24_compress(&in[j], len - j, &state);
                        out = siphash24_finalize(&state);
                        assert_se(out == 0xa129ca6149be45e5);
                }
        }
        return 0;
}
Exemple #4
0
static void test_message_handler(void) {
        _cleanup_(sd_dhcp_server_unrefp) sd_dhcp_server *server = NULL;
        struct {
                DHCPMessage message;
                struct {
                        uint8_t code;
                        uint8_t length;
                        uint8_t type;
                } _packed_ option_type;
                struct {
                        uint8_t code;
                        uint8_t length;
                        be32_t address;
                } _packed_ option_requested_ip;
                struct {
                        uint8_t code;
                        uint8_t length;
                        be32_t address;
                } _packed_ option_server_id;
                struct {
                        uint8_t code;
                        uint8_t length;
                        uint8_t id[7];
                } _packed_ option_client_id;
                uint8_t end;
        } _packed_ test = {
                .message.op = BOOTREQUEST,
                .message.htype = ARPHRD_ETHER,
                .message.hlen = ETHER_ADDR_LEN,
                .message.xid = htobe32(0x12345678),
                .message.chaddr = { 'A', 'B', 'C', 'D', 'E', 'F' },
                .option_type.code = SD_DHCP_OPTION_MESSAGE_TYPE,
                .option_type.length = 1,
                .option_type.type = DHCP_DISCOVER,
                .end = SD_DHCP_OPTION_END,
        };
        struct in_addr address_lo = {
                .s_addr = htonl(INADDR_LOOPBACK),
        };

        assert_se(sd_dhcp_server_new(&server, 1) >= 0);
        assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 8, 0, 0) >= 0);
        assert_se(sd_dhcp_server_attach_event(server, NULL, 0) >= 0);
        assert_se(sd_dhcp_server_start(server) >= 0);

        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);

        test.end = 0;
        /* TODO, shouldn't this fail? */
        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
        test.end = SD_DHCP_OPTION_END;
        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);

        test.option_type.code = 0;
        test.option_type.length = 0;
        test.option_type.type = 0;
        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
        test.option_type.code = SD_DHCP_OPTION_MESSAGE_TYPE;
        test.option_type.length = 1;
        test.option_type.type = DHCP_DISCOVER;
        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);

        test.message.op = 0;
        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
        test.message.op = BOOTREQUEST;
        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);

        test.message.htype = 0;
        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
        test.message.htype = ARPHRD_ETHER;
        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);

        test.message.hlen = 0;
        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
        test.message.hlen = ETHER_ADDR_LEN;
        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);

        test.option_type.type = DHCP_REQUEST;
        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
        test.option_requested_ip.code = SD_DHCP_OPTION_REQUESTED_IP_ADDRESS;
        test.option_requested_ip.length = 4;
        test.option_requested_ip.address = htobe32(0x12345678);
        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_NAK);
        test.option_server_id.code = SD_DHCP_OPTION_SERVER_IDENTIFIER;
        test.option_server_id.length = 4;
        test.option_server_id.address = htobe32(INADDR_LOOPBACK);
        test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 3);
        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_ACK);

        test.option_server_id.address = htobe32(0x12345678);
        test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 3);
        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
        test.option_server_id.address = htobe32(INADDR_LOOPBACK);
        test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 4);
        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
        test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 3);
        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_ACK);

        test.option_client_id.code = SD_DHCP_OPTION_CLIENT_IDENTIFIER;
        test.option_client_id.length = 7;
        test.option_client_id.id[0] = 0x01;
        test.option_client_id.id[1] = 'A';
        test.option_client_id.id[2] = 'B';
        test.option_client_id.id[3] = 'C';
        test.option_client_id.id[4] = 'D';
        test.option_client_id.id[5] = 'E';
        test.option_client_id.id[6] = 'F';
        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_ACK);

        test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 30);
        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
}

static uint64_t client_id_hash_helper(DHCPClientId *id, uint8_t key[HASH_KEY_SIZE]) {
        struct siphash state;

        siphash24_init(&state, key);
        client_id_hash_func(id, &state);

        return htole64(siphash24_finalize(&state));
}

static void test_client_id_hash(void) {
        DHCPClientId a = {
                .length = 4,
        }, b = {
Exemple #5
0
int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available) {
        uint64_t h;
        JournalRateLimitGroup *g;
        JournalRateLimitPool *p;
        struct siphash state;
        unsigned burst;
        usec_t ts;

        assert(id);

        /* Returns:
         *
         * 0     → the log message shall be suppressed,
         * 1 + n → the log message shall be permitted, and n messages were dropped from the peer before
         * < 0   → error
         */

        if (!r)
                return 1;

        if (r->interval == 0 || r->burst == 0)
                return 1;

        burst = burst_modulate(r->burst, available);

        ts = now(CLOCK_MONOTONIC);

        siphash24_init(&state, r->hash_key);
        string_hash_func(id, &state);
        h = siphash24_finalize(&state);
        g = r->buckets[h % BUCKETS_MAX];

        LIST_FOREACH(bucket, g, g)
                if (streq(g->id, id))
                        break;

        if (!g) {
                g = journal_rate_limit_group_new(r, id, ts);
                if (!g)
                        return -ENOMEM;
        }

        p = &g->pools[priority_map[priority]];

        if (p->begin <= 0) {
                p->suppressed = 0;
                p->num = 1;
                p->begin = ts;
                return 1;
        }

        if (p->begin + r->interval < ts) {
                unsigned s;

                s = p->suppressed;
                p->suppressed = 0;
                p->num = 1;
                p->begin = ts;

                return 1 + s;
        }

        if (p->num < burst) {
                p->num++;
                return 1;
        }

        p->suppressed++;
        return 0;
}