summary refs log tree commit diff
diff options
context:
space:
mode:
authorRichard Nyberg <rnyberg@murmeldjur.se>2006-08-06 19:28:20 +0000
committerRichard Nyberg <rnyberg@murmeldjur.se>2006-08-06 19:28:20 +0000
commitc4379cdfb9f2091e6058448480d42568dc131fcf (patch)
tree5c4f8d8d249b661f64a8ef9cf9eae882f0f7306c
parent1f4ef6cb15485a56c4a37ce6ac93fd40a8de684d (diff)
downloadbtpd-c4379cdfb9f2091e6058448480d42568dc131fcf.tar.gz
btpd-c4379cdfb9f2091e6058448480d42568dc131fcf.zip
Send keepalives.
-rw-r--r--btpd/net.c1
-rw-r--r--btpd/net_buf.c15
-rw-r--r--btpd/net_buf.h2
-rw-r--r--btpd/net_types.h1
-rw-r--r--btpd/peer.c15
-rw-r--r--btpd/peer.h1
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,7 +58,8 @@ 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;
@@ -65,6 +67,17 @@ static struct net_buf *nb_singleton(struct net_buf *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)
 {
     struct net_buf *out;
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;
@@ -176,6 +179,12 @@ peer_requested(struct peer *p, uint32_t piece, uint32_t block)
 }
 
 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)
 {
     BTPDQ_REMOVE(&p->my_reqs, req, p_entry);
@@ -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);