From c4379cdfb9f2091e6058448480d42568dc131fcf Mon Sep 17 00:00:00 2001 From: Richard Nyberg Date: Sun, 6 Aug 2006 19:28:20 +0000 Subject: [PATCH] Send keepalives. --- btpd/net.c | 1 + btpd/net_buf.c | 15 ++++++++++++++- btpd/net_buf.h | 2 ++ btpd/net_types.h | 1 + btpd/peer.c | 15 ++++++++++++++- btpd/peer.h | 1 + 6 files changed, 33 insertions(+), 2 deletions(-) diff --git a/btpd/net.c b/btpd/net.c index 1aa7bd9..37307d6 100644 --- a/btpd/net.c +++ b/btpd/net.c @@ -221,6 +221,7 @@ net_write(struct peer *p, unsigned long wmax) btpd_ev_add(&p->out_ev, NULL); p->t_wantwrite = btpd_seconds; } + p->t_lastwrite = btpd_seconds; return nwritten; } diff --git a/btpd/net_buf.c b/btpd/net_buf.c index e927a09..5b09ddb 100644 --- a/btpd/net_buf.c +++ b/btpd/net_buf.c @@ -7,6 +7,7 @@ static struct net_buf *m_choke; static struct net_buf *m_unchoke; static struct net_buf *m_interest; static struct net_buf *m_uninterest; +static struct net_buf *m_keepalive; static void kill_buf_no(char *buf, size_t len) @@ -57,13 +58,25 @@ nb_create_onesized(char mtype, int btype) return out; } -static struct net_buf *nb_singleton(struct net_buf *nb) +static struct net_buf * +nb_singleton(struct net_buf *nb) { nb_hold(nb); nb->kill_buf = kill_buf_abort; return nb; } +struct net_buf * +nb_create_keepalive(void) +{ + if (m_keepalive == NULL) { + m_keepalive = nb_create_alloc(NB_KEEPALIVE, 4); + net_write32(m_keepalive->buf, 0); + nb_singleton(m_keepalive); + } + return m_keepalive; +} + struct net_buf * nb_create_piece(uint32_t index, uint32_t begin, size_t blen) { diff --git a/btpd/net_buf.h b/btpd/net_buf.h index 0972c63..a04bcd7 100644 --- a/btpd/net_buf.h +++ b/btpd/net_buf.h @@ -14,6 +14,7 @@ #define NB_MULTIHAVE 11 #define NB_BITDATA 12 #define NB_SHAKE 13 +#define NB_KEEPALIVE 14 struct net_buf { short type; @@ -33,6 +34,7 @@ BTPDQ_HEAD(nb_tq, nb_link); struct torrent; struct peer; +struct net_buf *nb_create_keepalive(void); struct net_buf *nb_create_piece(uint32_t index, uint32_t begin, size_t blen); struct net_buf *nb_create_torrentdata(char *block, size_t blen); struct net_buf *nb_create_request(uint32_t index, diff --git a/btpd/net_types.h b/btpd/net_types.h index 9ade854..ff5b99a 100644 --- a/btpd/net_types.h +++ b/btpd/net_types.h @@ -62,6 +62,7 @@ struct peer { unsigned long count_up, count_dwn; long t_created; + long t_lastwrite; long t_wantwrite; long t_nointerest; diff --git a/btpd/peer.c b/btpd/peer.c index c8f60dc..714489d 100644 --- a/btpd/peer.c +++ b/btpd/peer.c @@ -106,6 +106,9 @@ void peer_sent(struct peer *p, struct net_buf *nb) { switch (nb->type) { + case NB_KEEPALIVE: + btpd_log(BTPD_L_MSG, "sent keepalive to %p\n", p); + break; case NB_CHOKE: btpd_log(BTPD_L_MSG, "sent choke to %p\n", p); break; @@ -175,6 +178,12 @@ peer_requested(struct peer *p, uint32_t piece, uint32_t block) return 0; } +void +peer_keepalive(struct peer *p) +{ + peer_send(p, nb_create_keepalive()); +} + void peer_cancel(struct peer *p, struct block_request *req, struct net_buf *nb) { @@ -266,6 +275,7 @@ peer_create_common(int sd) p->sd = sd; p->flags = PF_I_CHOKE | PF_P_CHOKE; p->t_created = btpd_seconds; + p->t_lastwrite = btpd_seconds; p->t_nointerest = btpd_seconds; BTPDQ_INIT(&p->my_reqs); BTPDQ_INIT(&p->outq); @@ -516,7 +526,10 @@ void peer_on_tick(struct peer *p) { if (p->flags & PF_ATTACHED) { - if (!BTPDQ_EMPTY(&p->outq) && btpd_seconds - p->t_wantwrite >= 60) { + if (BTPDQ_EMPTY(&p->outq)) { + if (btpd_seconds - p->t_lastwrite >= 120) + peer_keepalive(p); + } else if (btpd_seconds - p->t_wantwrite >= 60) { btpd_log(BTPD_L_CONN, "write attempt timed out.\n"); goto kill; } diff --git a/btpd/peer.h b/btpd/peer.h index cce6841..7d51c98 100644 --- a/btpd/peer.h +++ b/btpd/peer.h @@ -21,6 +21,7 @@ void peer_send(struct peer *p, struct net_buf *nb); int peer_unsend(struct peer *p, struct nb_link *nl); void peer_sent(struct peer *p, struct net_buf *nb); +void peer_keepalive(struct peer *p); void peer_unchoke(struct peer *p); void peer_choke(struct peer *p); void peer_unwant(struct peer *p, uint32_t index);