[tor-commits] [stegotorus/master] fixing another blocksize bug and making transmit timer handling work properly in failure cases

zwol at torproject.org zwol at torproject.org
Fri Jul 20 23:17:06 UTC 2012


commit 7846fc0071e903619227d7dde41dc5aaa91c0d70
Author: Jeffrey Wang <jeffreyw at stanford.edu>
Date:   Thu Dec 8 09:17:19 2011 +0000

    fixing another blocksize bug and making transmit timer handling work properly in failure cases
    
    git-svn-id: svn+ssh://spartan.csl.sri.com/svn/private/DEFIANCE@178 a58ff0ac-194c-e011-a152-003048836090
---
 src/protocol/chop.cc |   34 +++++++++++++++++++++++++++++-----
 src/util.cc          |   25 +++++++++++++++++++++++++
 src/util.h           |    7 +++++++
 3 files changed, 61 insertions(+), 5 deletions(-)

diff --git a/src/protocol/chop.cc b/src/protocol/chop.cc
index f960fbb..51d3195 100644
--- a/src/protocol/chop.cc
+++ b/src/protocol/chop.cc
@@ -299,6 +299,7 @@ chop_send_block(conn_t *d,
   chop_header hdr;
   struct evbuffer_iovec v;
   uint8_t *p;
+  struct timeval *exp_time = NULL;
 
   log_assert(evbuffer_get_length(block) == 0);
   log_assert(evbuffer_get_length(source) >= length);
@@ -332,10 +333,17 @@ chop_send_block(conn_t *d,
   if (evbuffer_commit_space(block, &v, 1))
     goto fail;
 
-  // TODO: this should be moved after the steg transmit, but currently that
-  // prevents conn_transmit_soon calls inside steg transmit
-  if (dest->must_transmit_timer)
+  /* save the expiration time of the must_transmit_timer in case of failure */
+  if (dest->must_transmit_timer) {
+    exp_time = new struct timeval;
+    if (evtimer_pending(dest->must_transmit_timer, exp_time)) {
+      log_debug("saved must_transmit_timer value in case of failure");
+    } else {
+      delete exp_time;
+      exp_time = NULL;
+    }
     evtimer_del(dest->must_transmit_timer);
+  }
 
   if (dest->steg->transmit(block, dest))
     goto fail_committed;
@@ -352,6 +360,10 @@ chop_send_block(conn_t *d,
     ckt->sent_fin = true;
   log_debug(dest, "sent %lu+%u byte block [flags %04hx]",
             (unsigned long)CHOP_WIRE_HDR_LEN, length, flags);
+
+  if (exp_time != NULL)
+    delete exp_time;
+
   return 0;
 
  fail:
@@ -360,6 +372,18 @@ chop_send_block(conn_t *d,
  fail_committed:
   evbuffer_drain(block, evbuffer_get_length(block));
   log_warn(dest, "allocation or buffer copy failed");
+
+  /* restore timer if necessary */
+  if (exp_time != NULL) {
+    if (!evtimer_pending(dest->must_transmit_timer, NULL)) {
+      struct timeval cur_time, timeout;
+      gettimeofday(&cur_time, NULL);
+      timeval_subtract(exp_time, &cur_time, &timeout);
+      evtimer_add(dest->must_transmit_timer, &timeout);
+    }
+    delete exp_time;
+  }
+
   return -1;
 }
 
@@ -524,13 +548,13 @@ must_transmit_timer_cb(evutil_socket_t, short, void *arg)
     return;
   }
   room = conn->steg->transmit_room(conn);
-  if (!room) {
+  if (room <= CHOP_BLOCK_OVERHD) {
     log_warn(conn, "must transmit, but no transmit room");
     return;
   }
 
   log_debug(conn, "must transmit");
-  chop_send_targeted(conn->circuit, conn, room);
+  chop_send_targeted(conn->circuit, conn, room - CHOP_BLOCK_OVERHD);
 }
 
 /* Receive subroutines. */
diff --git a/src/util.cc b/src/util.cc
index 79bfbd6..9987871 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -704,3 +704,28 @@ void
   logpfx(LOG_SEV_DEBUG, FN, cn);
   logfmt(LOG_SEV_DEBUG, format);
 }
+
+/************************* Time Functions **************************/
+
+int timeval_subtract(struct timeval *x, struct timeval *y,
+		     struct timeval *result) {
+  /* Perform the carry for the later subtraction by updating y. */
+  if (x->tv_usec < y->tv_usec) {
+    int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
+    y->tv_usec -= 1000000 * nsec;
+    y->tv_sec += nsec;
+  }
+  if (x->tv_usec - y->tv_usec > 1000000) {
+    int nsec = (x->tv_usec - y->tv_usec) / 1000000;
+    y->tv_usec += 1000000 * nsec;
+    y->tv_sec -= nsec;
+  }
+
+  /* Compute the time remaining to wait.                                        
+     tv_usec is certainly positive. */
+  result->tv_sec = x->tv_sec - y->tv_sec;
+  result->tv_usec = x->tv_usec - y->tv_usec;
+
+  /* Return 1 if result is negative. */
+  return x->tv_sec < y->tv_sec;
+}
diff --git a/src/util.h b/src/util.h
index 5dccad3..392d15a 100644
--- a/src/util.h
+++ b/src/util.h
@@ -273,4 +273,11 @@ void log_debug(conn_t *conn,const char *format, ...)
                 __FILE__, __LINE__, #expr);             \
   } while (0)
 
+/***** Time. *****/
+
+/** Compute x - y and store the value result. Returns 1 if the difference is
+    negative, and 0 otherwise. **/
+int timeval_subtract(struct timeval *x, struct timeval *y,
+		     struct timeval *result);
+
 #endif





More information about the tor-commits mailing list