a tracker with connections even if we add a lot of torrents with the same tracker at the same time.master
@@ -19,6 +19,7 @@ enum http_state { | |||||
}; | }; | ||||
struct http { | struct http { | ||||
long t_created; | |||||
enum http_state state; | enum http_state state; | ||||
char *url; | char *url; | ||||
CURL *curlh; | CURL *curlh; | ||||
@@ -62,6 +63,7 @@ http_get(struct http **ret, | |||||
h->state = HS_ADD; | h->state = HS_ADD; | ||||
h->cb = cb; | h->cb = cb; | ||||
h->cb_arg = arg; | h->cb_arg = arg; | ||||
h->t_created = btpd_seconds; | |||||
if ((h->curlh = curl_easy_init()) == NULL) | if ((h->curlh = curl_easy_init()) == NULL) | ||||
btpd_err("Fatal error in curl.\n"); | btpd_err("Fatal error in curl.\n"); | ||||
@@ -88,6 +90,26 @@ http_get(struct http **ret, | |||||
return 0; | return 0; | ||||
} | } | ||||
long | |||||
http_server_busy_time(const char *url, long s) | |||||
{ | |||||
struct http *h; | |||||
size_t len = strlen(url); | |||||
pthread_mutex_lock(&m_httpq_lock); | |||||
h = BTPDQ_LAST(&m_httpq, http_tq); | |||||
while (h != NULL && | |||||
!((h->state == HS_ACTIVE || h->state == HS_ADD) && | |||||
strncmp(url, h->url, len) == 0)) | |||||
h = BTPDQ_PREV(h, http_tq, entry); | |||||
pthread_mutex_unlock(&m_httpq_lock); | |||||
if (h == NULL || btpd_seconds - h->t_created >= s) | |||||
return 0; | |||||
else | |||||
return s - (btpd_seconds - h->t_created); | |||||
} | |||||
void | void | ||||
http_cancel(struct http *http) | http_cancel(struct http *http) | ||||
{ | { | ||||
@@ -24,6 +24,8 @@ int http_get(struct http **ret, | |||||
void http_cancel(struct http *http); | void http_cancel(struct http *http); | ||||
int http_succeeded(struct http_res *res); | int http_succeeded(struct http_res *res); | ||||
long http_server_busy_time(const char *url, long s); | |||||
void http_init(void); | void http_init(void); | ||||
#endif | #endif |
@@ -180,6 +180,7 @@ timer_cb(int fd, short type, void *arg) | |||||
static void | static void | ||||
tr_send(struct torrent *tp, enum tr_event event) | tr_send(struct torrent *tp, enum tr_event event) | ||||
{ | { | ||||
long busy_secs; | |||||
char e_hash[61], e_id[61], qc;; | char e_hash[61], e_id[61], qc;; | ||||
const uint8_t *peer_id = btpd_get_peer_id(); | const uint8_t *peer_id = btpd_get_peer_id(); | ||||
@@ -187,6 +188,13 @@ tr_send(struct torrent *tp, enum tr_event event) | |||||
tr->event = event; | tr->event = event; | ||||
if (tr->ttype == TIMER_TIMEOUT) | if (tr->ttype == TIMER_TIMEOUT) | ||||
http_cancel(tr->req); | http_cancel(tr->req); | ||||
if ((busy_secs = http_server_busy_time(tp->meta.announce, 3)) > 0) { | |||||
tr->ttype = TIMER_RETRY; | |||||
btpd_ev_add(&tr->timer, (& (struct timeval) { busy_secs, 0 })); | |||||
return; | |||||
} | |||||
tr->ttype = TIMER_TIMEOUT; | tr->ttype = TIMER_TIMEOUT; | ||||
btpd_ev_add(&tr->timer, REQ_TIMEOUT); | btpd_ev_add(&tr->timer, REQ_TIMEOUT); | ||||