Пример #1
0
void handle_message(cjdnsadmin_t *adm, char *buffer, ssize_t len) {
    // TODO: fix memory leak
    struct bencode *b = ben_decode(buffer, len);
    if (!b) {
        fprintf(stderr, "bencode error: %lu\n",len);
        printf("message from cjdns: \"%*s\"\n", (int)len, buffer);
        return;
    }
    // Get IPs
    struct bencode *table = ben_dict_get_by_str(b, "routingTable");
    size_t i, num_items = ben_list_len(table);
    for (i = 0; i < num_items; i++) {
        struct bencode *item = ben_list_get(table, i);
        struct bencode *ip = ben_dict_get_by_str(item, "ip");
        if (ben_is_str(ip)) {
            const char *ip_str = ben_str_val(ip);
            if (adm->on_found_ip) {
                (*adm->on_found_ip)(adm->on_found_ip_obj, ip_str);
            }
        }
    }
    // check if there is more
    struct bencode *more = ben_dict_get_by_str(b, "more");
    int more_int = more && ben_is_int(more) && ben_int_val(more);
    if (more_int == 1) {
        // get the next page of the routing table
        adm->fetch_peers_page++;
        cjdnsadmin_fetch_peers(adm);
    } else {
        // start from the first page next time
        adm->fetch_peers_page = 0;
    }
    ben_free(b);
}
Пример #2
0
void p2p_decode(UCHAR * bencode, size_t bensize, IP * from)
{
	BEN *packet = NULL;
	BEN *y = NULL;

	/* Parse request */
	packet = ben_dec(bencode, bensize);
	if (packet == NULL) {
		info(_log, from, "Decoding UDP packet failed:");
		return;
	} else if (packet->t != BEN_DICT) {
		info(_log, from, "UDP packet is not a dictionary:");
		ben_free(packet);
		return;
	}

	/* Type of message */
	y = ben_dict_search_str(packet, "y");
	if (!ben_is_str(y) || ben_str_i(y) != 1) {
		info(_log, from, "Message type missing or broken:");
		ben_free(packet);
		return;
	}

	mutex_block(_main->work->mutex);

	switch (*y->v.s->s) {

	case 'q':
		p2p_request(packet, from);
		break;
	case 'r':
		p2p_reply(packet, from);
		break;
	case 'e':
		p2p_error(packet, from);
		break;
	default:
		info(_log, from, "Drop invalid message type '%c' from",
		     *y->v.s->s);
	}

	mutex_unblock(_main->work->mutex);

	ben_free(packet);
}
Пример #3
0
BEN *ben_dict_search_str(BEN * node, const char *buffer)
{
	BEN *result = NULL;
	BEN *key = ben_init(BEN_STR);
	ben_str(key, (UCHAR *) buffer, strlen(buffer));
	result = ben_dict_search_key(node, key);
	ben_free(key);
	return result;
}
Пример #4
0
void tuple_free(TUPLE * tuple)
{
	ben_free(tuple->key);
	ben_free(tuple->val);
	myfree(tuple);
}
Пример #5
0
void p2p_decrypt(UCHAR * bencode, size_t bensize, IP * from)
{
	BEN *packet = NULL;
	BEN *salt = NULL;
	BEN *aes = NULL;
	struct obj_str *plain = NULL;

	/* Parse request */
	packet = ben_dec(bencode, bensize);
	if (!ben_is_dict(packet)) {
		info(_log, from, "Decoding AES packet failed:");
		ben_free(packet);
		return;
	}

	/* Salt */
	salt = ben_dict_search_str(packet, "s");
	if (!ben_is_str(salt) || ben_str_i(salt) != AES_IV_SIZE) {
		info(_log, from, "Salt missing or broken:");
		ben_free(packet);
		return;
	}

	/* Encrypted AES message */
	aes = ben_dict_search_str(packet, "a");
	if (!ben_is_str(aes) || ben_str_i(aes) <= 2) {
		info(_log, from, "AES message missing or broken:");
		ben_free(packet);
		return;
	}

	/* Decrypt message */
	plain = aes_decrypt(ben_str_s(aes), ben_str_i(aes),
			    ben_str_s(salt),
			    _main->conf->key, strlen(_main->conf->key));
	if (plain == NULL) {
		info(_log, from, "Decoding AES message failed:");
		ben_free(packet);
		return;
	}

	/* AES packet too small */
	if (plain->i < SHA1_SIZE) {
		ben_free(packet);
		str_free(plain);
		info(_log, from, "AES packet contains less than 20 bytes:");
		return;
	}

	/* Validate bencode */
	if (!ben_validate(plain->s, plain->i)) {
		ben_free(packet);
		str_free(plain);
		info(_log, from, "AES packet contains broken bencode:");
		return;
	}

	/* Parse message */
	p2p_decode(plain->s, plain->i, from);

	/* Free */
	ben_free(packet);
	str_free(plain);
}
Пример #6
0
static void on_written(uv_udp_send_t* req, int status) {
    CHECK(status);
    struct bencode* b = req->data;
    ben_free(b);
}