From b529666a82f4da878e3d7520e672297cde70d9cd Mon Sep 17 00:00:00 2001 From: Richard Nyberg Date: Sun, 3 Jul 2005 13:02:43 +0000 Subject: [PATCH] Use compact mode for tracker requests. --- btpd/btpd.h | 1 + btpd/net.c | 50 +++++++++++++++++++++++++--------------------- btpd/net.h | 1 + btpd/peer.c | 23 ++++++++++++++++++++- btpd/peer.h | 2 +- btpd/tracker_req.c | 36 +++++++++++++++++++++++---------- 6 files changed, 78 insertions(+), 35 deletions(-) diff --git a/btpd/btpd.h b/btpd/btpd.h index d3cf990..e5d102d 100644 --- a/btpd/btpd.h +++ b/btpd/btpd.h @@ -2,6 +2,7 @@ #define BTPD_H #include +#include #include #include diff --git a/btpd/net.c b/btpd/net.c index a7a9023..cc908c6 100644 --- a/btpd/net.c +++ b/btpd/net.c @@ -872,12 +872,11 @@ net_shake_read(struct peer *p, unsigned long rmax) if (in->buf_off < 68) break; else { - if (!hs->incoming && bcmp(in->buf + 48, p->id, 20) != 0) - goto bad_shake; - else if (hs->incoming && torrent_has_peer(p->tp, in->buf + 48)) - goto bad_shake; // Not really, but we are already connected - if (hs->incoming) - bcopy(in->buf + 48, p->id, 20); + if (torrent_has_peer(p->tp, in->buf + 48)) + goto bad_shake; // Not really, but we're already connected. + else if (bcmp(in->buf + 48, btpd.peer_id, 20) == 0) + goto bad_shake; // Connection from myself. + bcopy(in->buf + 48, p->id, 20); hs->state = SHAKE_ID; } default: @@ -922,6 +921,22 @@ net_handshake(struct peer *p, int incoming) net_send_shake(p); } +int +net_connect2(struct sockaddr *sa, socklen_t salen, int *sd) +{ + if ((*sd = socket(PF_INET, SOCK_STREAM, 0)) == -1) + return errno; + + set_nonblocking(*sd); + + if (connect(*sd, sa, salen) == -1 && errno != EINPROGRESS) { + btpd_log(BTPD_L_CONN, "Botched connection %s.", strerror(errno)); + close(*sd); + return errno; + } + return 0; +} + int net_connect(const char *ip, int port, int *sd) { @@ -939,25 +954,14 @@ net_connect(const char *ip, int port, int *sd) if (getaddrinfo(ip, portstr, &hints, &res) != 0) return errno; - if (res) { - if ((*sd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { - btpd_log(BTPD_L_CONN, "Botched connection %s.", strerror(errno)); - freeaddrinfo(res); - return errno; - } - set_nonblocking(*sd); - if (connect(*sd, res->ai_addr, res->ai_addrlen) == -1 && - errno != EINPROGRESS) { - btpd_log(BTPD_L_CONN, "Botched connection %s.", strerror(errno)); - close(*sd); - freeaddrinfo(res); - return errno; - } - } + int error = net_connect2(res->ai_addr, res->ai_addrlen, sd); freeaddrinfo(res); - btpd.npeers++; - return 0; + + if (error == 0) + btpd.npeers++; + + return error; } void diff --git a/btpd/net.h b/btpd/net.h index 33137dd..5a2c704 100644 --- a/btpd/net.h +++ b/btpd/net.h @@ -99,6 +99,7 @@ void net_handshake(struct peer *p, int incoming); void net_read_cb(int sd, short type, void *arg); void net_write_cb(int sd, short type, void *arg); +int net_connect2(struct sockaddr *sa, socklen_t salen, int *sd); int net_connect(const char *ip, int port, int *sd); void net_unsend_piece(struct peer *p, struct piece_req *req); diff --git a/btpd/peer.c b/btpd/peer.c index 9c7720e..1ab125f 100644 --- a/btpd/peer.c +++ b/btpd/peer.c @@ -1,4 +1,6 @@ #include +#include +#include #include #include @@ -173,6 +175,25 @@ peer_create_out(struct torrent *tp, p = peer_create_common(sd); p->tp = tp; - bcopy(id, p->id, 20); + //bcopy(id, p->id, 20); + net_handshake(p, 0); +} + +void +peer_create_out_compact(struct torrent *tp, const char *compact) +{ + int sd; + struct peer *p; + struct sockaddr_in addr; + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = *(long *)compact; + addr.sin_port = *(short *)(compact + 4); + + if (net_connect2((struct sockaddr *)&addr, sizeof(addr), &sd) != 0) + return; + + p = peer_create_common(sd); + p->tp = tp; net_handshake(p, 0); } diff --git a/btpd/peer.h b/btpd/peer.h index 3bfbc04..c1e2f75 100644 --- a/btpd/peer.h +++ b/btpd/peer.h @@ -58,7 +58,7 @@ unsigned long peer_get_rate(unsigned long *rates); void peer_create_in(int sd); void peer_create_out(struct torrent *tp, const uint8_t *id, const char *ip, int port); - +void peer_create_out_compact(struct torrent *tp, const char *compact); void peer_kill(struct peer *p); #endif diff --git a/btpd/tracker_req.c b/btpd/tracker_req.c index 0db0a6a..ad14c57 100644 --- a/btpd/tracker_req.c +++ b/btpd/tracker_req.c @@ -21,7 +21,7 @@ #define PRIu64 "llu" #endif -#define REQ_SIZE (getpagesize() * 2) +#define REQ_SIZE (1024 + 6 * 50) struct tracker_req { enum tr_event tr_event; @@ -102,16 +102,29 @@ tracker_done(struct child *child) tp->tracker_time = btpd.seconds + interval; - if ((benc_dget_lst(req->res->buf, "peers", &peers)) != 0) { - btpd_log(BTPD_L_TRACKER, "Bad data from tracker.\n"); - failed = 1; - goto out; + int error = 0; + size_t length; + + if ((error = benc_dget_lst(req->res->buf, "peers", &peers)) == 0) { + for (peers = benc_first(peers); + peers != NULL && btpd.npeers < btpd.maxpeers; + peers = benc_next(peers)) + maybe_connect_to(tp, peers); } - for (peers = benc_first(peers); - peers != NULL && btpd.npeers < btpd.maxpeers; - peers = benc_next(peers)) - maybe_connect_to(tp, peers); + if (error == EINVAL) { + error = benc_dget_str(req->res->buf, "peers", &peers, &length); + if (error == 0 && length % 6 == 0) { + for (size_t i = 0; i < length; i += 6) + peer_create_out_compact(tp, peers + i * 6); + } + } + + if (error != 0) { + btpd_log(BTPD_L_ERROR, "Bad data from tracker.\n"); + failed = 1; + goto out; + } out: if (failed) { @@ -165,10 +178,13 @@ create_url(struct tracker_req *req, struct torrent *tp, char **url) left = torrent_bytes_left(tp); - i = asprintf(url, "%s%cinfo_hash=%s&peer_id=%s&port=%d" + i = asprintf(url, "%s%cinfo_hash=%s" + "&peer_id=%s" + "&port=%d" "&uploaded=%" PRIu64 "&downloaded=%" PRIu64 "&left=%" PRIu64 + "&compact=1" "%s%s", tp->meta.announce, qc, e_hash, e_id, btpd.port, tp->uploaded, tp->downloaded, left,