Esempio n. 1
0
static void
cli_read_cb(int sd, short type, void *arg)
{
    struct cli *cli = arg;
    uint32_t cmdlen;
    uint8_t *msg = NULL;

    if (read_fully(sd, &cmdlen, sizeof(cmdlen)) != 0)
        goto error;

    msg = btpd_malloc(cmdlen);
    if (read_fully(sd, msg, cmdlen) != 0)
        goto error;

    if (!(benc_validate(msg, cmdlen) == 0 && benc_islst(msg) &&
            benc_first(msg) != NULL && benc_isstr(benc_first(msg))))
        goto error;

    if (cmd_dispatch(cli, msg) != 0)
        goto error;

    free(msg);
    return;

error:
    btpd_ev_del(&cli->read);
    close(cli->sd);
    free(cli);
    if (msg != NULL)
        free(msg);
}
Esempio n. 2
0
static void
parse_reply(struct torrent *tp, struct tr_response *res, const char *content,
            size_t size)
{
    const char *buf;
    size_t len;
    const char *peers;
    const char *v6key[] = {"peers6", "peers_ipv6"};

    if (benc_validate(content, size) != 0)
        goto bad_data;

    if ((buf = benc_dget_any(content, "failure reason")) != NULL) {
        if (!benc_isstr(buf))
            goto bad_data;
        res->type = TR_RES_FAIL;
        res->mi_failure = buf;
        return;
    }

    buf = benc_dget_any(content, "interval");
    if (buf != NULL && benc_isint(buf))
        res->interval = benc_int(buf, NULL);

    if ((peers = benc_dget_any(content, "peers")) == NULL)
        goto after_peers;

    if (benc_islst(peers)) {
        for (peers = benc_first(peers);
                peers != NULL && net_npeers < net_max_peers;
                peers = benc_next(peers))
            maybe_connect_to(tp, peers);
    } else if (benc_isstr(peers)) {
        if (net_ipv4) {
            peers = benc_dget_mem(content, "peers", &len);
            for (size_t i = 0; i < len && net_npeers < net_max_peers; i += 6)
                peer_create_out_compact(tp->net, AF_INET, peers + i);
        }
    } else
        goto bad_data;

after_peers:
    if (!net_ipv6)
        goto after_peers6;
    for (int k = 0; k < 2; k++) {
        peers = benc_dget_any(content, v6key[k]);
        if (peers != NULL && benc_isstr(peers)) {
            peers = benc_dget_mem(content, v6key[k], &len);
            for (size_t i = 0; i < len && net_npeers < net_max_peers; i += 18)
                peer_create_out_compact(tp->net, AF_INET6, peers + i);
        }
    }
after_peers6:
    res->type = TR_RES_OK;
    return;

bad_data:
    res->type = TR_RES_BAD;
}
Esempio n. 3
0
int
mi_test(const char *p, size_t size)
{
    const char *info;
    const char *alst;
    const char *pieces;
    const char *files;
    const char *fdct;
    const char *name;
    size_t slen, npieces;
    off_t length = 0, piece_length;

    if (benc_validate(p, size) != 0 || !benc_isdct(p))
        return 0;

    if ((alst = benc_dget_any(p, "announce-list")) != NULL) {
        if (!benc_islst(alst))
            return 0;
        if (!mi_test_announce_list(alst))
            return 0;
    } else if (benc_dget_mem(p, "announce", NULL) == NULL)
        return 0;

    if ((info = benc_dget_dct(p, "info")) == NULL)
        return 0;
    if ((name = benc_dget_mem(info, "name", &slen)) != NULL)
        if (!mi_test_path(name, slen))
            return 0;
    if ((piece_length = benc_dget_int(info, "piece length")) <= 0)
        return 0;
    if ((pieces = benc_dget_mem(info, "pieces", &slen)) == NULL ||
            slen % 20 != 0)
        return 0;
    npieces = slen / 20;
    if ((length = benc_dget_int(info, "length")) != 0) {
        if (length < 0 || benc_dget_any(info, "files") != NULL)
            return 0;
    } else {
        if ((files = benc_dget_lst(info, "files")) == NULL)
            return 0;
        if (!mi_test_files(files))
            return 0;
        fdct = benc_first(files);
        while (fdct != NULL) {
            length += benc_dget_int(fdct, "length");
            fdct = benc_next(fdct);
        }
    }
    if (length < (npieces - 1) * piece_length ||
            length > npieces * piece_length)
        return 0;
    return 1;
}