Browse Source

Implement the multitracker extension. Removed checks for URLs that

btpd can handle for now, so if no such URLs exists there will be a
lot of tracker errors reported.
master
Richard Nyberg 18 years ago
parent
commit
1911f326a6
1 changed files with 36 additions and 15 deletions
  1. +36
    -15
      btpd/tracker_req.c

+ 36
- 15
btpd/tracker_req.c View File

@@ -27,11 +27,12 @@ enum timer_type {
};

struct tracker {
struct mi_announce *ann;
enum timer_type ttype;
enum tr_event event;
int interval;
unsigned nerrors;
int tier, url;
struct mi_announce *ann;
struct http *req;
struct event timer;
};
@@ -129,6 +130,33 @@ tr_set_stopped(struct torrent *tp)
torrent_on_tr_stopped(tp);
}

static char *
get_url(struct tracker *tr)
{
return tr->ann->tiers[tr->tier].urls[tr->url];
}

static void
good_url(struct tracker *tr)
{
char *set = tr->ann->tiers[tr->tier].urls[tr->url], *hold;
for (int i = 0; i <= tr->url; i++) {
hold = tr->ann->tiers[tr->tier].urls[i];
tr->ann->tiers[tr->tier].urls[i] = set;
set = hold;
}
tr->tier = 0;
tr->url = 0;
}

static void
next_url(struct tracker *tr)
{
tr->url = (tr->url + 1) % tr->ann->tiers[tr->tier].nurls;
if (tr->url == 0)
tr->tier = (tr->tier + 1) % tr->ann->ntiers;
}

static void
http_cb(struct http *req, struct http_res *res, void *arg)
{
@@ -138,6 +166,7 @@ http_cb(struct http *req, struct http_res *res, void *arg)
tr->req = NULL;
if (res->res == HRES_OK && parse_reply(tp, res->content, res->length,
tr->event != TR_EV_STOPPED) == 0) {
good_url(tr);
tr->nerrors = 0;
tr->ttype = TIMER_INTERVAL;
btpd_ev_add(&tr->timer, (& (struct timeval) { tr->interval, 0 }));
@@ -168,6 +197,7 @@ timer_cb(int fd, short type, void *arg)
break;
}
case TIMER_RETRY:
next_url(tr);
tr_send(tp, tr->event);
break;
case TIMER_INTERVAL:
@@ -190,7 +220,7 @@ tr_send(struct torrent *tp, enum tr_event event)
if (tr->ttype == TIMER_TIMEOUT)
http_cancel(tr->req);

if ((busy_secs = http_server_busy_time(tr->ann->tiers[0].urls[0], 3)) > 0) {
if ((busy_secs = http_server_busy_time(get_url(tr), 3)) > 0) {
tr->ttype = TIMER_RETRY;
btpd_ev_add(&tr->timer, (& (struct timeval) { busy_secs, 0 }));
return;
@@ -199,7 +229,7 @@ tr_send(struct torrent *tp, enum tr_event event)
tr->ttype = TIMER_TIMEOUT;
btpd_ev_add(&tr->timer, REQ_TIMEOUT);

qc = (strchr(tr->ann->tiers[0].urls[0], '?') == NULL) ? '?' : '&';
qc = (strchr(get_url(tr), '?') == NULL) ? '?' : '&';

for (int i = 0; i < 20; i++)
snprintf(e_hash + i * 3, 4, "%%%.2x", tp->tl->hash[i]);
@@ -209,7 +239,7 @@ tr_send(struct torrent *tp, enum tr_event event)
http_get(&tr->req, http_cb, tp,
"%s%cinfo_hash=%s&peer_id=%s&port=%d&uploaded=%llu"
"&downloaded=%llu&left=%llu&compact=1%s%s",
tr->ann->tiers[0].urls[0], qc, e_hash, e_id, net_port,
get_url(tr), qc, e_hash, e_id, net_port,
tp->net->uploaded, tp->net->downloaded,
(long long)tp->total_length - cm_content(tp),
event == TR_EV_EMPTY ? "" : "&event=", m_events[event]);
@@ -218,18 +248,9 @@ tr_send(struct torrent *tp, enum tr_event event)
int
tr_create(struct torrent *tp, const char *mi)
{
struct mi_announce *ann = mi_announce(mi);
if (ann == NULL)
btpd_err("out of memory.\n");
if (strncmp(ann->tiers[0].urls[0],
"http://", sizeof("http://") - 1) != 0) {
btpd_log(BTPD_L_ERROR,
"btpd currently has no support for the protocol specified in "
"'%s'.\n", ann->tiers[0].urls[0]);
return EINVAL;
}
tp->tr = btpd_calloc(1, sizeof(*tp->tr));
tp->tr->ann = ann;
if ((tp->tr->ann = mi_announce(mi)) == NULL)
btpd_err("Out of memory.\n");
evtimer_set(&tp->tr->timer, timer_cb, tp);
return 0;
}


Loading…
Cancel
Save