Ver código fonte

Split peer information. Make id hash functions available.

struct peer is now peer and meta_peer. meta_peer can be used as
a handle that won't be affected if a peer vanishes. The meta_peers
are kept in a hash table to enable fast lookup by peer id.
master
Richard Nyberg 16 anos atrás
pai
commit
89a95cbdf5
8 arquivos alterados com 137 adições e 84 exclusões
  1. +3
    -0
      btpd/btpd.h
  2. +22
    -20
      btpd/net.c
  3. +12
    -3
      btpd/net_types.h
  4. +74
    -37
      btpd/peer.c
  5. +2
    -0
      btpd/peer.h
  6. +1
    -13
      btpd/tlib.c
  7. +11
    -11
      btpd/upload.c
  8. +12
    -0
      btpd/util.c

+ 3
- 0
btpd/btpd.h Ver arquivo

@@ -85,6 +85,9 @@ void btpd_timer_del(struct timeout *to);
void btpd_shutdown(void); void btpd_shutdown(void);
int btpd_is_stopping(void); int btpd_is_stopping(void);


int btpd_id_eq(const void *k1, const void *k2);
uint32_t btpd_id_hash(const void *k);

const uint8_t *btpd_get_peer_id(void); const uint8_t *btpd_get_peer_id(void);


void td_acquire_lock(void); void td_acquire_lock(void);


+ 22
- 20
btpd/net.c Ver arquivo

@@ -26,16 +26,7 @@ struct peer_tq net_unattached = BTPDQ_HEAD_INITIALIZER(net_unattached);
int int
net_torrent_has_peer(struct net *n, const uint8_t *id) net_torrent_has_peer(struct net *n, const uint8_t *id)
{ {
int has = 0;
struct peer *p = BTPDQ_FIRST(&n->peers);
while (p != NULL) {
if (bcmp(p->id, id, 20) == 0) {
has = 1;
break;
}
p = BTPDQ_NEXT(p, p_entry);
}
return has;
return mptbl_find(n->mptbl, id) != NULL;
} }


void void
@@ -45,8 +36,11 @@ net_create(struct torrent *tp)
n->tp = tp; n->tp = tp;
tp->net = n; tp->net = n;


if ((n->mptbl = mptbl_create(3, btpd_id_eq, btpd_id_hash)) == NULL)
btpd_err("Out of memory.\n");

BTPDQ_INIT(&n->getlst); BTPDQ_INIT(&n->getlst);
n->busy_field = btpd_calloc(ceil(tp->npieces / 8.0), 1); n->busy_field = btpd_calloc(ceil(tp->npieces / 8.0), 1);
n->piece_count = btpd_calloc(tp->npieces, sizeof(*n->piece_count)); n->piece_count = btpd_calloc(tp->npieces, sizeof(*n->piece_count));
} }
@@ -54,6 +48,14 @@ net_create(struct torrent *tp)
void void
net_kill(struct torrent *tp) net_kill(struct torrent *tp)
{ {
struct htbl_iter it;
struct meta_peer *mp = mptbl_iter_first(tp->net->mptbl, &it);
while (mp != NULL) {
struct meta_peer *mps = mp;
mp = mptbl_iter_del(&it);
mp_kill(mps);
}
mptbl_free(tp->net->mptbl);
free(tp->net->piece_count); free(tp->net->piece_count);
free(tp->net->busy_field); free(tp->net->busy_field);
free(tp->net); free(tp->net);
@@ -235,7 +237,7 @@ net_dispatch_msg(struct peer *p, const char *buf)
res = 1; res = 1;
break; break;
case MSG_REQUEST: case MSG_REQUEST:
if ((p->flags & (PF_P_WANT|PF_I_CHOKE)) == PF_P_WANT) {
if ((p->mp->flags & (PF_P_WANT|PF_I_CHOKE)) == PF_P_WANT) {
index = dec_be32(buf); index = dec_be32(buf);
begin = dec_be32(buf + 4); begin = dec_be32(buf + 4);
length = dec_be32(buf + 8); length = dec_be32(buf + 8);
@@ -310,7 +312,7 @@ net_state(struct peer *p, const char *buf)
peer_set_in_state(p, SHAKE_INFO, 20); peer_set_in_state(p, SHAKE_INFO, 20);
break; break;
case SHAKE_INFO: case SHAKE_INFO:
if (p->flags & PF_INCOMING) {
if (p->mp->flags & PF_INCOMING) {
struct torrent *tp = torrent_by_hash(buf); struct torrent *tp = torrent_by_hash(buf);
if (tp == NULL || !net_active(tp)) if (tp == NULL || !net_active(tp))
goto bad; goto bad;
@@ -324,7 +326,7 @@ net_state(struct peer *p, const char *buf)
if ((net_torrent_has_peer(p->n, buf) if ((net_torrent_has_peer(p->n, buf)
|| bcmp(buf, btpd_get_peer_id(), 20) == 0)) || bcmp(buf, btpd_get_peer_id(), 20) == 0))
goto bad; goto bad;
bcopy(buf, p->id, 20);
bcopy(buf, p->mp->id, 20);
peer_on_shake(p); peer_on_shake(p);
peer_set_in_state(p, BTP_MSGSIZE, 4); peer_set_in_state(p, BTP_MSGSIZE, 4);
break; break;
@@ -561,14 +563,14 @@ net_bw_tick(void)
while ((p = BTPDQ_FIRST(&net_bw_readq)) != NULL && m_bw_bytes_in > 0) { while ((p = BTPDQ_FIRST(&net_bw_readq)) != NULL && m_bw_bytes_in > 0) {
BTPDQ_REMOVE(&net_bw_readq, p, rq_entry); BTPDQ_REMOVE(&net_bw_readq, p, rq_entry);
btpd_ev_enable(&p->ioev, EV_READ); btpd_ev_enable(&p->ioev, EV_READ);
p->flags &= ~PF_ON_READQ;
p->mp->flags &= ~PF_ON_READQ;
m_bw_bytes_in -= net_read(p, m_bw_bytes_in); m_bw_bytes_in -= net_read(p, m_bw_bytes_in);
} }
} else { } else {
while ((p = BTPDQ_FIRST(&net_bw_readq)) != NULL) { while ((p = BTPDQ_FIRST(&net_bw_readq)) != NULL) {
BTPDQ_REMOVE(&net_bw_readq, p, rq_entry); BTPDQ_REMOVE(&net_bw_readq, p, rq_entry);
btpd_ev_enable(&p->ioev, EV_READ); btpd_ev_enable(&p->ioev, EV_READ);
p->flags &= ~PF_ON_READQ;
p->mp->flags &= ~PF_ON_READQ;
net_read(p, 0); net_read(p, 0);
} }
} }
@@ -578,14 +580,14 @@ net_bw_tick(void)
&& m_bw_bytes_out > 0)) { && m_bw_bytes_out > 0)) {
BTPDQ_REMOVE(&net_bw_writeq, p, wq_entry); BTPDQ_REMOVE(&net_bw_writeq, p, wq_entry);
btpd_ev_enable(&p->ioev, EV_WRITE); btpd_ev_enable(&p->ioev, EV_WRITE);
p->flags &= ~PF_ON_WRITEQ;
p->mp->flags &= ~PF_ON_WRITEQ;
m_bw_bytes_out -= net_write(p, m_bw_bytes_out); m_bw_bytes_out -= net_write(p, m_bw_bytes_out);
} }
} else { } else {
while ((p = BTPDQ_FIRST(&net_bw_writeq)) != NULL) { while ((p = BTPDQ_FIRST(&net_bw_writeq)) != NULL) {
BTPDQ_REMOVE(&net_bw_writeq, p, wq_entry); BTPDQ_REMOVE(&net_bw_writeq, p, wq_entry);
btpd_ev_enable(&p->ioev, EV_WRITE); btpd_ev_enable(&p->ioev, EV_WRITE);
p->flags &= ~PF_ON_WRITEQ;
p->mp->flags &= ~PF_ON_WRITEQ;
net_write(p, 0); net_write(p, 0);
} }
} }
@@ -622,7 +624,7 @@ net_read_cb(struct peer *p)
m_bw_bytes_in -= net_read(p, m_bw_bytes_in); m_bw_bytes_in -= net_read(p, m_bw_bytes_in);
else { else {
btpd_ev_disable(&p->ioev, EV_READ); btpd_ev_disable(&p->ioev, EV_READ);
p->flags |= PF_ON_READQ;
p->mp->flags |= PF_ON_READQ;
BTPDQ_INSERT_TAIL(&net_bw_readq, p, rq_entry); BTPDQ_INSERT_TAIL(&net_bw_readq, p, rq_entry);
} }
} }
@@ -636,7 +638,7 @@ net_write_cb(struct peer *p)
m_bw_bytes_out -= net_write(p, m_bw_bytes_out); m_bw_bytes_out -= net_write(p, m_bw_bytes_out);
else { else {
btpd_ev_disable(&p->ioev, EV_WRITE); btpd_ev_disable(&p->ioev, EV_WRITE);
p->flags |= PF_ON_WRITEQ;
p->mp->flags |= PF_ON_WRITEQ;
BTPDQ_INSERT_TAIL(&net_bw_writeq, p, wq_entry); BTPDQ_INSERT_TAIL(&net_bw_writeq, p, wq_entry);
} }
} }


+ 12
- 3
btpd/net_types.h Ver arquivo

@@ -21,6 +21,7 @@ struct net {


unsigned npeers; unsigned npeers;
struct peer_tq peers; struct peer_tq peers;
struct mptbl *mptbl;
}; };


enum input_state { enum input_state {
@@ -33,16 +34,24 @@ enum input_state {
BTP_MSGBODY BTP_MSGBODY
}; };


struct meta_peer {
struct peer *p;
HTBL_ENTRY(chain);
uint16_t flags;
uint16_t refs;
uint8_t id[20];
};

HTBL_TYPE(mptbl, meta_peer, uint8_t, id, chain);

struct peer { struct peer {
int sd; int sd;
uint16_t flags;
uint8_t *piece_field; uint8_t *piece_field;
uint32_t npieces; uint32_t npieces;
uint32_t nwant; uint32_t nwant;


uint8_t id[20];

struct net *n; struct net *n;
struct meta_peer *mp;


struct block_request_tq my_reqs; struct block_request_tq my_reqs;




+ 74
- 37
btpd/peer.c Ver arquivo

@@ -2,6 +2,36 @@


#include <ctype.h> #include <ctype.h>


struct meta_peer *
mp_create(void)
{
return btpd_calloc(1, sizeof(struct meta_peer));
}

void
mp_kill(struct meta_peer *mp)
{
free(mp);
}

void
mp_hold(struct meta_peer *mp)
{
mp->refs++;
}

void
mp_drop(struct meta_peer *mp, struct net *n)
{
assert(mp->refs > 0);
mp->refs--;
if (mp->refs == 0) {
if (mp->flags & PF_ATTACHED)
assert(mptbl_remove(n->mptbl, mp->id) == mp);
mp_kill(mp);
}
}

void void
peer_kill(struct peer *p) peer_kill(struct peer *p)
{ {
@@ -9,7 +39,7 @@ peer_kill(struct peer *p)


btpd_log(BTPD_L_CONN, "killed peer %p\n", p); btpd_log(BTPD_L_CONN, "killed peer %p\n", p);


if (p->flags & PF_ATTACHED) {
if (p->mp->flags & PF_ATTACHED) {
BTPDQ_REMOVE(&p->n->peers, p, p_entry); BTPDQ_REMOVE(&p->n->peers, p, p_entry);
p->n->npeers--; p->n->npeers--;
if (p->n->active) { if (p->n->active) {
@@ -18,9 +48,9 @@ peer_kill(struct peer *p)
} }
} else } else
BTPDQ_REMOVE(&net_unattached, p, p_entry); BTPDQ_REMOVE(&net_unattached, p, p_entry);
if (p->flags & PF_ON_READQ)
if (p->mp->flags & PF_ON_READQ)
BTPDQ_REMOVE(&net_bw_readq, p, rq_entry); BTPDQ_REMOVE(&net_bw_readq, p, rq_entry);
if (p->flags & PF_ON_WRITEQ)
if (p->mp->flags & PF_ON_WRITEQ)
BTPDQ_REMOVE(&net_bw_writeq, p, wq_entry); BTPDQ_REMOVE(&net_bw_writeq, p, wq_entry);


btpd_ev_del(&p->ioev); btpd_ev_del(&p->ioev);
@@ -34,6 +64,8 @@ peer_kill(struct peer *p)
nl = next; nl = next;
} }


p->mp->p = NULL;
mp_drop(p->mp, p->n);
if (p->in.buf != NULL) if (p->in.buf != NULL)
free(p->in.buf); free(p->in.buf);
if (p->piece_field != NULL) if (p->piece_field != NULL)
@@ -83,9 +115,9 @@ peer_unsend(struct peer *p, struct nb_link *nl)
nb_drop(nl->nb); nb_drop(nl->nb);
free(nl); free(nl);
if (BTPDQ_EMPTY(&p->outq)) { if (BTPDQ_EMPTY(&p->outq)) {
if (p->flags & PF_ON_WRITEQ) {
if (p->mp->flags & PF_ON_WRITEQ) {
BTPDQ_REMOVE(&net_bw_writeq, p, wq_entry); BTPDQ_REMOVE(&net_bw_writeq, p, wq_entry);
p->flags &= ~PF_ON_WRITEQ;
p->mp->flags &= ~PF_ON_WRITEQ;
} else } else
btpd_ev_disable(&p->ioev, EV_WRITE); btpd_ev_disable(&p->ioev, EV_WRITE);
} }
@@ -106,7 +138,7 @@ peer_sent(struct peer *p, struct net_buf *nb)
break; break;
case NB_UNCHOKE: case NB_UNCHOKE:
btpd_log(BTPD_L_MSG, "sent unchoke to %p\n", p); btpd_log(BTPD_L_MSG, "sent unchoke to %p\n", p);
p->flags &= ~PF_NO_REQUESTS;
p->mp->flags &= ~PF_NO_REQUESTS;
break; break;
case NB_INTEREST: case NB_INTEREST:
btpd_log(BTPD_L_MSG, "sent interest to %p\n", p); btpd_log(BTPD_L_MSG, "sent interest to %p\n", p);
@@ -199,7 +231,7 @@ peer_cancel(struct peer *p, struct block_request *req, struct net_buf *nb)
void void
peer_unchoke(struct peer *p) peer_unchoke(struct peer *p)
{ {
p->flags &= ~PF_I_CHOKE;
p->mp->flags &= ~PF_I_CHOKE;
peer_send(p, nb_create_unchoke()); peer_send(p, nb_create_unchoke());
} }


@@ -218,7 +250,7 @@ peer_choke(struct peer *p)
nl = next; nl = next;
} }


p->flags |= PF_I_CHOKE;
p->mp->flags |= PF_I_CHOKE;
peer_send(p, nb_create_choke()); peer_send(p, nb_create_choke());
} }


@@ -229,7 +261,7 @@ peer_want(struct peer *p, uint32_t index)
p->nwant++; p->nwant++;
if (p->nwant == 1) { if (p->nwant == 1) {
if (p->nreqs_out == 0) { if (p->nreqs_out == 0) {
assert((p->flags & PF_DO_UNWANT) == 0);
assert((p->mp->flags & PF_DO_UNWANT) == 0);
int unsent = 0; int unsent = 0;
struct nb_link *nl = BTPDQ_LAST(&p->outq, nb_tq); struct nb_link *nl = BTPDQ_LAST(&p->outq, nb_tq);
if (nl != NULL && nl->nb->type == NB_UNINTEREST) if (nl != NULL && nl->nb->type == NB_UNINTEREST)
@@ -237,10 +269,10 @@ peer_want(struct peer *p, uint32_t index)
if (!unsent) if (!unsent)
peer_send(p, nb_create_interest()); peer_send(p, nb_create_interest());
} else { } else {
assert((p->flags & PF_DO_UNWANT) != 0);
p->flags &= ~PF_DO_UNWANT;
assert((p->mp->flags & PF_DO_UNWANT) != 0);
p->mp->flags &= ~PF_DO_UNWANT;
} }
p->flags |= PF_I_WANT;
p->mp->flags |= PF_I_WANT;
} }
} }


@@ -250,12 +282,12 @@ peer_unwant(struct peer *p, uint32_t index)
assert(p->nwant > 0); assert(p->nwant > 0);
p->nwant--; p->nwant--;
if (p->nwant == 0) { if (p->nwant == 0) {
p->flags &= ~PF_I_WANT;
p->mp->flags &= ~PF_I_WANT;
p->t_nointerest = btpd_seconds; p->t_nointerest = btpd_seconds;
if (p->nreqs_out == 0) if (p->nreqs_out == 0)
peer_send(p, nb_create_uninterest()); peer_send(p, nb_create_uninterest());
else else
p->flags |= PF_DO_UNWANT;
p->mp->flags |= PF_DO_UNWANT;
} }
} }


@@ -264,8 +296,12 @@ peer_create_common(int sd)
{ {
struct peer *p = btpd_calloc(1, sizeof(*p)); struct peer *p = btpd_calloc(1, sizeof(*p));


p->mp = mp_create();
mp_hold(p->mp);
p->mp->p = p;

p->sd = sd; p->sd = sd;
p->flags = PF_I_CHOKE | PF_P_CHOKE;
p->mp->flags = PF_I_CHOKE | PF_P_CHOKE;
p->t_created = btpd_seconds; p->t_created = btpd_seconds;
p->t_lastwrite = btpd_seconds; p->t_lastwrite = btpd_seconds;
p->t_nointerest = btpd_seconds; p->t_nointerest = btpd_seconds;
@@ -285,7 +321,7 @@ void
peer_create_in(int sd) peer_create_in(int sd)
{ {
struct peer *p = peer_create_common(sd); struct peer *p = peer_create_common(sd);
p->flags |= PF_INCOMING;
p->mp->flags |= PF_INCOMING;
} }


void void
@@ -344,9 +380,9 @@ peer_create_out_compact(struct net *n, int family, const char *compact)
void void
peer_on_no_reqs(struct peer *p) peer_on_no_reqs(struct peer *p)
{ {
if ((p->flags & PF_DO_UNWANT) != 0) {
if ((p->mp->flags & PF_DO_UNWANT) != 0) {
assert(p->nwant == 0); assert(p->nwant == 0);
p->flags &= ~PF_DO_UNWANT;
p->mp->flags &= ~PF_DO_UNWANT;
peer_send(p, nb_create_uninterest()); peer_send(p, nb_create_uninterest());
} }
} }
@@ -362,8 +398,8 @@ peer_on_shake(struct peer *p)
{ {
uint8_t printid[21]; uint8_t printid[21];
int i; int i;
for (i = 0; i < 20 && isprint(p->id[i]); i++)
printid[i] = p->id[i];
for (i = 0; i < 20 && isprint(p->mp->id[i]); i++)
printid[i] = p->mp->id[i];
printid[i] = '\0'; printid[i] = '\0';
btpd_log(BTPD_L_MSG, "received shake(%s) from %p\n", printid, p); btpd_log(BTPD_L_MSG, "received shake(%s) from %p\n", printid, p);
p->piece_field = btpd_calloc(1, (int)ceil(p->n->tp->npieces / 8.0)); p->piece_field = btpd_calloc(1, (int)ceil(p->n->tp->npieces / 8.0));
@@ -377,9 +413,10 @@ peer_on_shake(struct peer *p)
} }
} }


mptbl_insert(p->n->mptbl, p->mp);
BTPDQ_REMOVE(&net_unattached, p, p_entry); BTPDQ_REMOVE(&net_unattached, p, p_entry);
BTPDQ_INSERT_HEAD(&p->n->peers, p, p_entry); BTPDQ_INSERT_HEAD(&p->n->peers, p, p_entry);
p->flags |= PF_ATTACHED;
p->mp->flags |= PF_ATTACHED;
p->n->npeers++; p->n->npeers++;


ul_on_new_peer(p); ul_on_new_peer(p);
@@ -390,10 +427,10 @@ void
peer_on_choke(struct peer *p) peer_on_choke(struct peer *p)
{ {
btpd_log(BTPD_L_MSG, "received choke from %p\n", p); btpd_log(BTPD_L_MSG, "received choke from %p\n", p);
if ((p->flags & PF_P_CHOKE) != 0)
if ((p->mp->flags & PF_P_CHOKE) != 0)
return; return;
else { else {
p->flags |= PF_P_CHOKE;
p->mp->flags |= PF_P_CHOKE;
dl_on_choke(p); dl_on_choke(p);
struct nb_link *nl = BTPDQ_FIRST(&p->outq); struct nb_link *nl = BTPDQ_FIRST(&p->outq);
while (nl != NULL) { while (nl != NULL) {
@@ -409,10 +446,10 @@ void
peer_on_unchoke(struct peer *p) peer_on_unchoke(struct peer *p)
{ {
btpd_log(BTPD_L_MSG, "received unchoke from %p\n", p); btpd_log(BTPD_L_MSG, "received unchoke from %p\n", p);
if ((p->flags & PF_P_CHOKE) == 0)
if ((p->mp->flags & PF_P_CHOKE) == 0)
return; return;
else { else {
p->flags &= ~PF_P_CHOKE;
p->mp->flags &= ~PF_P_CHOKE;
dl_on_unchoke(p); dl_on_unchoke(p);
} }
} }
@@ -421,10 +458,10 @@ void
peer_on_interest(struct peer *p) peer_on_interest(struct peer *p)
{ {
btpd_log(BTPD_L_MSG, "received interest from %p\n", p); btpd_log(BTPD_L_MSG, "received interest from %p\n", p);
if ((p->flags & PF_P_WANT) != 0)
if ((p->mp->flags & PF_P_WANT) != 0)
return; return;
else { else {
p->flags |= PF_P_WANT;
p->mp->flags |= PF_P_WANT;
ul_on_interest(p); ul_on_interest(p);
} }
} }
@@ -433,10 +470,10 @@ void
peer_on_uninterest(struct peer *p) peer_on_uninterest(struct peer *p)
{ {
btpd_log(BTPD_L_MSG, "received uninterest from %p\n", p); btpd_log(BTPD_L_MSG, "received uninterest from %p\n", p);
if ((p->flags & PF_P_WANT) == 0)
if ((p->mp->flags & PF_P_WANT) == 0)
return; return;
else { else {
p->flags &= ~PF_P_WANT;
p->mp->flags &= ~PF_P_WANT;
p->t_nointerest = btpd_seconds; p->t_nointerest = btpd_seconds;
ul_on_uninterest(p); ul_on_uninterest(p);
} }
@@ -497,14 +534,14 @@ peer_on_request(struct peer *p, uint32_t index, uint32_t begin,
{ {
btpd_log(BTPD_L_MSG, "received request(%u,%u,%u) from %p\n", btpd_log(BTPD_L_MSG, "received request(%u,%u,%u) from %p\n",
index, begin, length, p); index, begin, length, p);
if ((p->flags & PF_NO_REQUESTS) == 0) {
if ((p->mp->flags & PF_NO_REQUESTS) == 0) {
peer_send(p, nb_create_piece(index, begin, length)); peer_send(p, nb_create_piece(index, begin, length));
peer_send(p, nb_create_torrentdata()); peer_send(p, nb_create_torrentdata());
p->npiece_msgs++; p->npiece_msgs++;
if (p->npiece_msgs >= MAXPIECEMSGS) { if (p->npiece_msgs >= MAXPIECEMSGS) {
peer_send(p, nb_create_choke()); peer_send(p, nb_create_choke());
peer_send(p, nb_create_unchoke()); peer_send(p, nb_create_unchoke());
p->flags |= PF_NO_REQUESTS;
p->mp->flags |= PF_NO_REQUESTS;
} }
} }
} }
@@ -531,7 +568,7 @@ peer_on_cancel(struct peer *p, uint32_t index, uint32_t begin,
void void
peer_on_tick(struct peer *p) peer_on_tick(struct peer *p)
{ {
if (p->flags & PF_ATTACHED) {
if (p->mp->flags & PF_ATTACHED) {
if (BTPDQ_EMPTY(&p->outq)) { if (BTPDQ_EMPTY(&p->outq)) {
if (btpd_seconds - p->t_lastwrite >= 120) if (btpd_seconds - p->t_lastwrite >= 120)
peer_keepalive(p); peer_keepalive(p);
@@ -539,7 +576,7 @@ peer_on_tick(struct peer *p)
btpd_log(BTPD_L_CONN, "write attempt timed out.\n"); btpd_log(BTPD_L_CONN, "write attempt timed out.\n");
goto kill; goto kill;
} }
if ((cm_full(p->n->tp) && !(p->flags & PF_P_WANT) &&
if ((cm_full(p->n->tp) && !(p->mp->flags & PF_P_WANT) &&
btpd_seconds - p->t_nointerest >= 600)) { btpd_seconds - p->t_nointerest >= 600)) {
btpd_log(BTPD_L_CONN, "no interest for 10 minutes.\n"); btpd_log(BTPD_L_CONN, "no interest for 10 minutes.\n");
goto kill; goto kill;
@@ -556,7 +593,7 @@ kill:
int int
peer_chokes(struct peer *p) peer_chokes(struct peer *p)
{ {
return p->flags & PF_P_CHOKE;
return p->mp->flags & PF_P_CHOKE;
} }


int int
@@ -574,13 +611,13 @@ peer_laden(struct peer *p)
int int
peer_wanted(struct peer *p) peer_wanted(struct peer *p)
{ {
return (p->flags & PF_I_WANT) == PF_I_WANT;
return (p->mp->flags & PF_I_WANT) == PF_I_WANT;
} }


int int
peer_leech_ok(struct peer *p) peer_leech_ok(struct peer *p)
{ {
return (p->flags & (PF_I_WANT|PF_P_CHOKE)) == PF_I_WANT;
return (p->mp->flags & (PF_I_WANT|PF_P_CHOKE)) == PF_I_WANT;
} }


int int
@@ -592,7 +629,7 @@ peer_active_down(struct peer *p)
int int
peer_active_up(struct peer *p) peer_active_up(struct peer *p)
{ {
return (p->flags & (PF_P_WANT|PF_I_CHOKE)) == PF_P_WANT
return (p->mp->flags & (PF_P_WANT|PF_I_CHOKE)) == PF_P_WANT
|| p->npiece_msgs > 0; || p->npiece_msgs > 0;
} }




+ 2
- 0
btpd/peer.h Ver arquivo

@@ -64,4 +64,6 @@ int peer_has(struct peer *p, uint32_t index);
int peer_leech_ok(struct peer *p); int peer_leech_ok(struct peer *p);
int peer_full(struct peer *p); int peer_full(struct peer *p);


void mp_kill(struct meta_peer *mp);

#endif #endif

+ 1
- 13
btpd/tlib.c Ver arquivo

@@ -295,18 +295,6 @@ num_hash(const void *k)
return *(const unsigned *)k; return *(const unsigned *)k;
} }


static int
id_test(const void *k1, const void *k2)
{
return bcmp(k1, k2, 20) == 0;
}

static uint32_t
id_hash(const void *k)
{
return dec_be32(k + 16);
}

void void
tlib_init(void) tlib_init(void)
{ {
@@ -316,7 +304,7 @@ tlib_init(void)
char file[PATH_MAX]; char file[PATH_MAX];


m_numtbl = numtbl_create(1, num_test, num_hash); m_numtbl = numtbl_create(1, num_test, num_hash);
m_hashtbl = hashtbl_create(1, id_test, id_hash);
m_hashtbl = hashtbl_create(1, btpd_id_eq, btpd_id_hash);
if (m_numtbl == NULL || m_hashtbl == NULL) if (m_numtbl == NULL || m_hashtbl == NULL)
btpd_err("Out of memory.\n"); btpd_err("Out of memory.\n");




+ 11
- 11
btpd/upload.c Ver arquivo

@@ -33,12 +33,12 @@ choke_do(void)
if (m_max_uploads < 0) { if (m_max_uploads < 0) {
struct peer *p; struct peer *p;
BTPDQ_FOREACH(p, &m_peerq, ul_entry) BTPDQ_FOREACH(p, &m_peerq, ul_entry)
if (p->flags & PF_I_CHOKE)
if (p->mp->flags & PF_I_CHOKE)
peer_unchoke(p); peer_unchoke(p);
} else if (m_max_uploads == 0) { } else if (m_max_uploads == 0) {
struct peer *p; struct peer *p;
BTPDQ_FOREACH(p, &m_peerq, ul_entry) BTPDQ_FOREACH(p, &m_peerq, ul_entry)
if ((p->flags & PF_I_CHOKE) == 0)
if ((p->mp->flags & PF_I_CHOKE) == 0)
peer_choke(p); peer_choke(p);
} else { } else {
struct peer_sort worthy[m_npeers]; struct peer_sort worthy[m_npeers];
@@ -68,9 +68,9 @@ choke_do(void)


bzero(unchoked, sizeof(unchoked)); bzero(unchoked, sizeof(unchoked));
for (i = nworthy - 1; i >= 0 && found < m_max_uploads - 1; i--) { for (i = nworthy - 1; i >= 0 && found < m_max_uploads - 1; i--) {
if ((worthy[i].p->flags & PF_P_WANT) != 0)
if ((worthy[i].p->mp->flags & PF_P_WANT) != 0)
found++; found++;
if ((worthy[i].p->flags & PF_I_CHOKE) != 0)
if ((worthy[i].p->mp->flags & PF_I_CHOKE) != 0)
peer_unchoke(worthy[i].p); peer_unchoke(worthy[i].p);
unchoked[worthy[i].i] = 1; unchoked[worthy[i].i] = 1;
} }
@@ -79,12 +79,12 @@ choke_do(void)
BTPDQ_FOREACH(p, &m_peerq, ul_entry) { BTPDQ_FOREACH(p, &m_peerq, ul_entry) {
if (!unchoked[i]) { if (!unchoked[i]) {
if (found < m_max_uploads && !peer_full(p)) { if (found < m_max_uploads && !peer_full(p)) {
if (p->flags & PF_P_WANT)
if (p->mp->flags & PF_P_WANT)
found++; found++;
if (p->flags & PF_I_CHOKE)
if (p->mp->flags & PF_I_CHOKE)
peer_unchoke(p); peer_unchoke(p);
} else { } else {
if ((p->flags & PF_I_CHOKE) == 0)
if ((p->mp->flags & PF_I_CHOKE) == 0)
peer_choke(p); peer_choke(p);
} }
} }
@@ -98,7 +98,7 @@ shuffle_optimists(void)
{ {
for (int i = 0; i < m_npeers; i++) { for (int i = 0; i < m_npeers; i++) {
struct peer *p = BTPDQ_FIRST(&m_peerq); struct peer *p = BTPDQ_FIRST(&m_peerq);
if ((p->flags & (PF_P_WANT|PF_I_CHOKE)) == (PF_P_WANT|PF_I_CHOKE)) {
if ((p->mp->flags & (PF_P_WANT|PF_I_CHOKE)) == (PF_P_WANT|PF_I_CHOKE)) {
break; break;
} else { } else {
BTPDQ_REMOVE(&m_peerq, p, ul_entry); BTPDQ_REMOVE(&m_peerq, p, ul_entry);
@@ -143,7 +143,7 @@ ul_on_lost_peer(struct peer *p)
assert(m_npeers > 0); assert(m_npeers > 0);
BTPDQ_REMOVE(&m_peerq, p, ul_entry); BTPDQ_REMOVE(&m_peerq, p, ul_entry);
m_npeers--; m_npeers--;
if ((p->flags & (PF_P_WANT|PF_I_CHOKE)) == PF_P_WANT)
if ((p->mp->flags & (PF_P_WANT|PF_I_CHOKE)) == PF_P_WANT)
choke_do(); choke_do();
} }


@@ -161,14 +161,14 @@ ul_on_lost_torrent(struct net *n)
void void
ul_on_interest(struct peer *p) ul_on_interest(struct peer *p)
{ {
if ((p->flags & PF_I_CHOKE) == 0)
if ((p->mp->flags & PF_I_CHOKE) == 0)
choke_do(); choke_do();
} }


void void
ul_on_uninterest(struct peer *p) ul_on_uninterest(struct peer *p)
{ {
if ((p->flags & PF_I_CHOKE) == 0)
if ((p->mp->flags & PF_I_CHOKE) == 0)
choke_do(); choke_do();
} }




+ 12
- 0
btpd/util.c Ver arquivo

@@ -3,6 +3,18 @@
#include <stdarg.h> #include <stdarg.h>
#include <time.h> #include <time.h>


int
btpd_id_eq(const void *k1, const void *k2)
{
return bcmp(k1, k2, 20) == 0;
}

uint32_t
btpd_id_hash(const void *k)
{
return dec_be32(k + 16);
}

void * void *
btpd_malloc(size_t size) btpd_malloc(size_t size)
{ {


Carregando…
Cancelar
Salvar