[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r9207: Count TLS bytes accurately: previously, we counted only the (in tor/trunk: . doc src/common src/or)



Author: nickm
Date: 2006-12-28 22:42:46 -0500 (Thu, 28 Dec 2006)
New Revision: 9207

Modified:
   tor/trunk/
   tor/trunk/ChangeLog
   tor/trunk/doc/TODO
   tor/trunk/src/common/tortls.c
   tor/trunk/src/common/tortls.h
   tor/trunk/src/or/connection.c
Log:
 r11741@Kushana:  nickm | 2006-12-28 22:41:29 -0500
 Count TLS bytes accurately: previously, we counted only the number of bytes read or transmitted via tls, not the number of extra bytes used to do so.  This has been a lonstanding wart.  The fix "Works for me".



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r11741] on c95137ef-5f19-0410-b913-86e773d04f59

Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2006-12-29 02:49:12 UTC (rev 9206)
+++ tor/trunk/ChangeLog	2006-12-29 03:42:46 UTC (rev 9207)
@@ -16,6 +16,9 @@
       same directory as tor.exe (Bug #356) and default to using the torrc
       located in the %appdata%\Tor\ of the user who installed the service.
       Patch from Matt Edman.
+    - Include TLS overhead when counting bandwidth usage; previously, we
+      would count only the bytes sent over TLS, but not the bytes used to
+      send them.
 
   o Minor features:
     - Start using the state file to store bandwidth accounting data:

Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO	2006-12-29 02:49:12 UTC (rev 9206)
+++ tor/trunk/doc/TODO	2006-12-29 03:42:46 UTC (rev 9207)
@@ -296,7 +296,7 @@
   - a way to pick entry guards based wholly on extend_info equivalent;
     a way to export extend_info equivalent.
 
-  - Count TLS bandwidth more accurately
+  o Count TLS bandwidth more accurately
 
   - Better estimates in the directory of whether servers have good uptime
     (high expected time to failure) or good guard qualities (high

Modified: tor/trunk/src/common/tortls.c
===================================================================
--- tor/trunk/src/common/tortls.c	2006-12-29 02:49:12 UTC (rev 9206)
+++ tor/trunk/src/common/tortls.c	2006-12-29 03:42:46 UTC (rev 9207)
@@ -53,9 +53,11 @@
     TOR_TLS_ST_SENTCLOSE, TOR_TLS_ST_CLOSED
   } state; /**< The current SSL state, depending on which operations have
             * completed successfully. */
-  int isServer;
+  int isServer; /**< True iff this is a server-side connection */
   size_t wantwrite_n; /**< 0 normally, >0 if we returned wantwrite last
                        * time. */
+  unsigned long last_write_count;
+  unsigned long last_read_count;
 };
 
 static X509* tor_tls_create_certificate(crypto_pk_env_t *rsa,
@@ -339,7 +341,7 @@
     goto error;
   }
 
-  result = tor_malloc(sizeof(tor_tls_context_t));
+  result = tor_malloc_zero(sizeof(tor_tls_context_t));
 #ifdef EVERYONE_HAS_AES
   /* Tell OpenSSL to only use TLS1 */
   if (!(result->ctx = SSL_CTX_new(TLSv1_method())))
@@ -415,7 +417,7 @@
 tor_tls_new(int sock, int isServer)
 {
   BIO *bio = NULL;
-  tor_tls_t *result = tor_malloc(sizeof(tor_tls_t));
+  tor_tls_t *result = tor_malloc_zero(sizeof(tor_tls_t));
 
   tor_assert(global_tls_context); /* make sure somebody made it first */
   if (!(result->ssl = SSL_new(global_tls_context->ctx))) {
@@ -860,20 +862,24 @@
   return tls->wantwrite_n;
 }
 
-/** Return the number of bytes read across the underlying socket. */
-unsigned long
-tor_tls_get_n_bytes_read(tor_tls_t *tls)
+/** Sets n_read and n_written to the number of bytes read and written,
+ * respectivey, on the raw socket used by <b>tls</b> since the last time this
+ * function was called on <b>tls</b>. */
+void
+tor_tls_get_n_raw_bytes(tor_tls_t *tls, size_t *n_read, size_t *n_written)
 {
-  tor_assert(tls);
-  return BIO_number_read(SSL_get_rbio(tls->ssl));
+  unsigned long r, w;
+  r = BIO_number_read(SSL_get_rbio(tls->ssl));
+  w = BIO_number_written(SSL_get_wbio(tls->ssl));
+  /* If we wrapped around, this should still give us the right answer, unless
+   * we wrapped around by more than ULONG_MAX since the last time we called
+   * this function.
+   */
+  *n_read = (size_t)(r - tls->last_read_count);
+  *n_written = (size_t)(w - tls->last_write_count);
+  tls->last_read_count = r;
+  tls->last_write_count = w;
 }
-/** Return the number of bytes written across the underlying socket. */
-unsigned long
-tor_tls_get_n_bytes_written(tor_tls_t *tls)
-{
-  tor_assert(tls);
-  return BIO_number_written(SSL_get_wbio(tls->ssl));
-}
 
 /** Implement check_no_tls_errors: If there are any pending OpenSSL
  * errors, log an error message. */

Modified: tor/trunk/src/common/tortls.h
===================================================================
--- tor/trunk/src/common/tortls.h	2006-12-29 02:49:12 UTC (rev 9206)
+++ tor/trunk/src/common/tortls.h	2006-12-29 03:42:46 UTC (rev 9207)
@@ -43,8 +43,8 @@
 int tor_tls_get_pending_bytes(tor_tls_t *tls);
 size_t tor_tls_get_forced_write_size(tor_tls_t *tls);
 
-unsigned long tor_tls_get_n_bytes_read(tor_tls_t *tls);
-unsigned long tor_tls_get_n_bytes_written(tor_tls_t *tls);
+void tor_tls_get_n_raw_bytes(tor_tls_t *tls,
+                             size_t *n_read, size_t *n_written);
 
 /* Log and abort if there are unhandled TLS errors in OpenSSL's error stack.
  */

Modified: tor/trunk/src/or/connection.c
===================================================================
--- tor/trunk/src/or/connection.c	2006-12-29 02:49:12 UTC (rev 9206)
+++ tor/trunk/src/or/connection.c	2006-12-29 03:42:46 UTC (rev 9207)
@@ -1418,6 +1418,7 @@
 {
   int result, at_most = *max_to_read;
   size_t bytes_in_buf, more_to_read;
+  size_t n_read = 0, n_written = 0;
 
   if (at_most == -1) { /* we need to initialize it */
     /* how many bytes are we allowed to read? */
@@ -1475,7 +1476,7 @@
     }
     pending = tor_tls_get_pending_bytes(or_conn->tls);
     if (pending) {
-      /* XXXX012 If we have any pending bytes, read them now.  This *can*
+      /* If we have any pending bytes, we read them now.  This *can*
        * take us over our read allotment, but really we shouldn't be
        * believing that SSL bytes are the same as TCP bytes anyway. */
       int r2 = read_to_buf_tls(or_conn->tls, pending, conn->inbuf);
@@ -1487,6 +1488,9 @@
       }
     }
 
+    tor_tls_get_n_raw_bytes(or_conn->tls, &n_read, &n_written);
+    log_debug(LD_GENERAL, "After TLS read of %d: %ld read, %ld written",
+              result, (long)n_read, (long)n_written);
   } else {
     int reached_eof = 0;
     CONN_LOG_PROTECT(conn,
@@ -1498,15 +1502,24 @@
 
     if (result < 0)
       return -1;
+    n_read = (size_t) result;
   }
 
-  if (result > 0) { /* change *max_to_read */
-    *max_to_read = at_most - result;
+  if (n_read > 0) { /* change *max_to_read */
+    *max_to_read = at_most - n_read;
   }
 
-  if (result > 0 && !is_internal_IP(conn->addr, 0)) { /* remember it */
-    rep_hist_note_bytes_read(result, time(NULL));
-    connection_read_bucket_decrement(conn, result);
+  if (!is_internal_IP(conn->addr, 0)) {
+    /* For non-local IPs, remember if we flushed any bytes over the wire. */
+    time_t now = time(NULL);
+    if (n_read > 0) {
+      rep_hist_note_bytes_read(n_read, now);
+      connection_read_bucket_decrement(conn, n_read);
+    }
+    if (n_written > 0) {
+      rep_hist_note_bytes_written(n_written, now);
+      global_write_bucket -= n_written;
+    }
   }
 
   if (more_to_read && result == at_most) {
@@ -1520,6 +1533,8 @@
    * have reached 0 on a different conn, and this guy needs to
    * know to stop reading. */
   connection_consider_empty_read_buckets(conn);
+  if (n_written > 0)
+    connection_consider_empty_write_buckets(conn);
 
   return 0;
 }
@@ -1571,6 +1586,7 @@
   int result;
   int max_to_write;
   time_t now = time(NULL);
+  size_t n_read = 0, n_written = 0;
 
   tor_assert(!connection_is_listener(conn));
 
@@ -1664,6 +1680,10 @@
        * is empty, so we can stop writing.
        */
     }
+
+    tor_tls_get_n_raw_bytes(or_conn->tls, &n_read, &n_written);
+    log_debug(LD_GENERAL, "After TLS write of %d: %ld read, %ld written",
+              result, (long)n_read, (long)n_written);
   } else {
     CONN_LOG_PROTECT(conn,
              result = flush_buf(conn->s, conn->outbuf,
@@ -1677,13 +1697,25 @@
       connection_mark_for_close(conn);
       return -1;
     }
+    n_written = (size_t) result;
   }
 
+  if (!is_internal_IP(conn->addr, 0)) {
+    /* For non-local IPs, remember if we flushed any bytes over the wire. */
+    time_t now = time(NULL);
+    if (n_written > 0) {
+      rep_hist_note_bytes_written(n_written, now);
+      global_write_bucket -= n_written;
+    }
+    if (n_read > 0) {
+      rep_hist_note_bytes_read(n_read, now);
+      global_read_bucket -= n_read;
+    }
+  }
+
   if (result > 0) {
-    if (!is_internal_IP(conn->addr, 0)) { /* remember it */
-      rep_hist_note_bytes_written(result, time(NULL));
-      global_write_bucket -= result;
-    }
+    /* If we wrote any bytes from our buffer, then call the appropriate
+     * functions. */
     if (connection_flushed_some(conn) < 0)
       connection_mark_for_close(conn);
   }
@@ -1700,6 +1732,9 @@
    * have reached 0 on a different conn, and this guy needs to
    * know to stop writing. */
   connection_consider_empty_write_buckets(conn);
+  if (n_read > 0)
+    connection_consider_empty_read_buckets(conn);
+
   return 0;
 }