[or-cvs] cleanups, bugfixes, more verbose logs

Roger Dingledine arma at seul.org
Wed Sep 24 21:24:55 UTC 2003


Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/home2/arma/work/onion/cvs/src/or

Modified Files:
	buffers.c circuit.c config.c connection.c connection_or.c 
	main.c or.h 
Log Message:
cleanups, bugfixes, more verbose logs

Fixed up the assert_*_ok funcs some (more work remains)

Changed config so it reads either /etc/torrc or the -f arg, never both

Finally tracked down a nasty bug with our use of tls:
  It turns out that if you ask SSL_read() for no more than n bytes, it
  will read the entire record from the network (and maybe part of the next
  record, I'm not sure), give you n bytes of it, and keep the remaining
  bytes internally. This is fine, except our poll-for-read looks at the
  network, and there are no bytes pending on the network, so we never know
  to ask SSL_read() for more bytes. Currently I've hacked it so if we ask
  for n bytes and it returns n bytes, then it reads again right then. This
  will interact poorly with our rate limiting; we need a cleaner solution.


Index: buffers.c
===================================================================
RCS file: /home/or/cvsroot/src/or/buffers.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- buffers.c	21 Sep 2003 06:44:53 -0000	1.35
+++ buffers.c	24 Sep 2003 21:24:52 -0000	1.36
@@ -69,7 +69,7 @@
     return 0;
   } else { /* we read some bytes */
     *buf_datalen += read_result;
-//    log_fn(LOG_DEBUG,"Read %d bytes. %d on inbuf.",read_result, *buf_datalen);
+    log_fn(LOG_DEBUG,"Read %d bytes. %d on inbuf.",read_result, *buf_datalen);
     return read_result;
   }
 }
@@ -88,6 +88,7 @@
   if (r<0) 
     return r;
   *buf_datalen += r;
+  log_fn(LOG_DEBUG,"Read %d bytes. %d on inbuf.",r, *buf_datalen);
   return r;
 } 
 
@@ -147,6 +148,8 @@
   *buf_datalen -= r;
   *buf_flushlen -= r;
   memmove(*buf, *buf+r, *buf_datalen);
+  log_fn(LOG_DEBUG,"flushed %d bytes, %d ready to flush, %d remain.",
+    r,*buf_flushlen,*buf_datalen);
   return r;
 }
 
@@ -168,7 +171,7 @@
 
   memcpy(*buf+*buf_datalen, string, string_len);
   *buf_datalen += string_len;
-//  log_fn(LOG_DEBUG,"added %d bytes to buf (now %d total).",string_len, *buf_datalen);
+  log_fn(LOG_DEBUG,"added %d bytes to buf (now %d total).",string_len, *buf_datalen);
   return *buf_datalen;
 }
 

Index: circuit.c
===================================================================
RCS file: /home/or/cvsroot/src/or/circuit.c,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -d -r1.66 -r1.67
--- circuit.c	18 Sep 2003 08:11:31 -0000	1.66
+++ circuit.c	24 Sep 2003 21:24:52 -0000	1.67
@@ -949,7 +949,7 @@
 }
 
 
-void assert_cpath_layer_ok(crypt_path_t *cp)
+void assert_cpath_layer_ok(const crypt_path_t *cp)
 {
   assert(cp->f_crypto);
   assert(cp->b_crypto);
@@ -960,8 +960,10 @@
     case CPATH_STATE_CLOSED:
     case CPATH_STATE_OPEN:
       assert(!cp->handshake_state);
+      break;
     case CPATH_STATE_AWAITING_KEYS:
       assert(cp->handshake_state);
+      break;
     default:
       assert(0);
     }
@@ -969,7 +971,7 @@
   assert(cp->deliver_window >= 0);
 }
 
-void assert_cpath_ok(crypt_path_t *cp)
+void assert_cpath_ok(const crypt_path_t *cp)
 {
   while(cp->prev)
     cp = cp->prev;
@@ -989,7 +991,7 @@
   }
 }
 
-void assert_circuit_ok(circuit_t *c) 
+void assert_circuit_ok(const circuit_t *c) 
 {
   connection_t *conn;
 

Index: config.c
===================================================================
RCS file: /home/or/cvsroot/src/or/config.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- config.c	12 Sep 2003 22:45:31 -0000	1.42
+++ config.c	24 Sep 2003 21:24:52 -0000	1.43
@@ -230,7 +230,7 @@
 int getconfig(int argc, char **argv, or_options_t *options) {
   struct config_line *cl;
   FILE *cf;
-  char fname[256];
+  char *fname;
   int i;
   int result = 0;
 
@@ -247,40 +247,29 @@
   options->TotalBandwidth = 800000; /* at most 800kB/s total sustained incoming */
   options->NumCpus = 1;
   options->CertFile = "default.cert";
-//  options->ReconnectPeriod = 6001;
-
-/* get config lines from /etc/torrc and assign them */
-#define rcfile "torrc"
-  snprintf(fname,256,"/etc/%s",rcfile);
-
-  cf = config_open(fname);
-  if(cf) {
-    /* we got it open. pull out the config lines. */
-    cl = config_get_lines(cf);
-    config_assign(options,cl);
-    config_free_lines(cl);
-    config_close(cf);
-  }
-  /* if we failed to open it, ignore */
 
 /* learn config file name, get config lines, assign them */
   i = 1;
   while(i < argc-1 && strcmp(argv[i],"-f")) {
-//    log(LOG_DEBUG,"examining arg %d (%s), it's not -f.",i,argv[i]);
     i++;
   }
   if(i < argc-1) { /* we found one */
-    log(LOG_DEBUG,"Opening specified config file '%s'",argv[i+1]);
-    cf = config_open(argv[i+1]);
-    if(!cf) { /* it's defined but not there. that's no good. */
-      log(LOG_ERR, "Unable to open configuration file '%s'.",argv[i+1]);
-      return -1;
-    }
-    cl = config_get_lines(cf);
-    config_assign(options,cl);
-    config_free_lines(cl);
-    config_close(cf);
+    fname = argv[i+1];
+  } else { /* didn't find one, try /etc/torrc */
+    fname = "/etc/torrc";
+  }
+  log(LOG_DEBUG,"Opening config file '%s'",fname);
+
+  cf = config_open(fname);
+  if(!cf) { /* it's defined but not there. that's no good. */
+    log(LOG_ERR, "Unable to open configuration file '%s'.",fname);
+    return -1;
   }
+
+  cl = config_get_lines(cf);
+  config_assign(options,cl);
+  config_free_lines(cl);
+  config_close(cf);
  
 /* go through command-line variables too */
   cl = config_get_commandlines(argc,argv);
@@ -334,7 +323,7 @@
 
   if(options->OnionRouter && options->Nickname == NULL) {
     log_fn(LOG_ERR,"Nickname required for OnionRouter, but not found.");
-    return -1;
+    result = -1;
   }
 
   if(options->DirPort > 0 && options->SigningPrivateKeyFile == NULL) {

Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection.c,v
retrieving revision 1.100
retrieving revision 1.101
diff -u -d -r1.100 -r1.101
--- connection.c	21 Sep 2003 06:15:43 -0000	1.100
+++ connection.c	24 Sep 2003 21:24:52 -0000	1.101
@@ -150,6 +150,8 @@
     return -1;
   }
   conn->s = s;
+  conn->receiver_bucket = -1; /* non-cell connections don't do receiver buckets */
+  conn->bandwidth = -1;
 
   if(connection_add(conn) < 0) { /* no space, forget it */
     log_fn(LOG_DEBUG,"connection_add failed. Giving up.");
@@ -478,6 +480,8 @@
       at_most = 10*(CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE);
     }
 
+    at_most = 103; /* an unusual number, to force bugs into the open */
+
     if(at_most > global_read_bucket)
       at_most = global_read_bucket;
   }
@@ -521,7 +525,11 @@
     log_fn(LOG_DEBUG,"buckets (%d, %d) exhausted. Pausing.", global_read_bucket, conn->receiver_bucket);
     conn->wants_to_read = 1;
     connection_stop_reading(conn);
+    return 0;
   }
+  if(connection_speaks_cells(conn) && conn->state != OR_CONN_STATE_CONNECTING)
+    if(result == at_most)
+      return connection_read_to_buf(conn);
   return 0;
 }
 
@@ -572,10 +580,12 @@
         log_fn(LOG_DEBUG,"tls error. breaking.");
         return -1; /* XXX deal with close better */
       case TOR_TLS_WANTWRITE:
+        log_fn(LOG_DEBUG,"wanted write.");
         /* we're already writing */
         return 0;
       case TOR_TLS_WANTREAD:
         /* Make sure to avoid a loop if the receive buckets are empty. */
+        log_fn(LOG_DEBUG,"wanted read.");
         if(!connection_is_reading(conn)) {
           connection_stop_writing(conn);
           conn->wants_to_write = 1;
@@ -721,6 +731,7 @@
 
 void assert_connection_ok(connection_t *conn, time_t now)
 {
+  return;
   assert(conn);
   assert(conn->type >= _CONN_TYPE_MIN);
   assert(conn->type <= _CONN_TYPE_MAX);
@@ -730,24 +741,29 @@
   
   /* buffers */
   assert(conn->inbuf);
-  assert(conn->inbuflen <= conn->inbuf_datalen);
+  assert(conn->inbuflen >= conn->inbuf_datalen);
   assert(conn->inbuflen >= 0);
-  assert(conn->inbuf_datalen > 0);
+  assert(conn->inbuf_datalen >= 0);
   assert(conn->outbuf);
-  assert(conn->outbuflen <= conn->outbuf_datalen);
+  assert(conn->outbuflen >= conn->outbuf_datalen);
   assert(conn->outbuflen >= 0);
-  assert(conn->outbuf_datalen > 0);
+  assert(conn->outbuf_datalen >= 0);
 
   assert(!now || conn->timestamp_lastread <= now);
   assert(!now || conn->timestamp_lastwritten <= now);
   assert(conn->timestamp_created <= conn->timestamp_lastread);
   assert(conn->timestamp_created <= conn->timestamp_lastwritten);
   
+  if(conn->type != CONN_TYPE_OR && conn->type != CONN_TYPE_DIR)
+    assert(!conn->pkey);
+  /* pkey is set if we're a dir client, or if we're an OR in state OPEN
+   * connected to another OR.
+   */
+
   if (conn->type != CONN_TYPE_OR) {
     assert(conn->bandwidth == -1);
     assert(conn->receiver_bucket == -1);
     /* Addr, port, address XXX */
-    assert(!conn->pkey);
     assert(!conn->tls);
   } else {
     assert(conn->bandwidth);
@@ -755,7 +771,6 @@
     assert(conn->receiver_bucket <= 10*conn->bandwidth);
     assert(conn->addr && conn->port);
     assert(conn->address);
-    assert(conn->pkey);
     if (conn->state != OR_CONN_STATE_CONNECTING)
       assert(conn->tls);
   }
@@ -772,8 +787,10 @@
     assert(!conn->next_stream || 
            conn->next_stream->type == CONN_TYPE_EXIT ||
            conn->next_stream->type == CONN_TYPE_AP);
-    assert(conn->cpath_layer);
-    assert_cpath_layer_ok(conn->cpath_layer);
+    if(conn->type == CONN_TYPE_AP && conn->state == AP_CONN_STATE_OPEN)
+      assert(conn->cpath_layer);
+    if(conn->cpath_layer)
+      assert_cpath_layer_ok(conn->cpath_layer);
     /* XXX unchecked, package window, deliver window. */
   }
 

Index: connection_or.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_or.c,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -d -r1.51 -r1.52
--- connection_or.c	16 Sep 2003 21:20:09 -0000	1.51
+++ connection_or.c	24 Sep 2003 21:24:52 -0000	1.52
@@ -144,13 +144,12 @@
   return connection_write_to_buf(n, CELL_NETWORK_SIZE, conn);
 }
 
+/* if there's a whole cell there, pull it off and process it. */
 int connection_process_cell_from_inbuf(connection_t *conn) {
-  /* check if there's a whole cell there.
-   *    * if yes, pull it off, decrypt it if we're not doing TLS, and process it.
-   *       */
   char buf[CELL_NETWORK_SIZE];
   cell_t cell;
  
+  log_fn(LOG_DEBUG,"%d: starting, inbuf_datalen %d.",conn->s,conn->inbuf_datalen);
   if(conn->inbuf_datalen < CELL_NETWORK_SIZE) /* entire response available? */
     return 0; /* not yet */
  
@@ -159,7 +158,6 @@
   /* retrieve cell info from buf (create the host-order struct from the network-order string) */
   cell_unpack(&cell, buf);
  
-//  log_fn(LOG_DEBUG,"Decrypted cell is of type %u (ACI %u).",cellp->command,cellp->aci);
   command_process_cell(&cell, conn);
  
   return connection_process_inbuf(conn); /* process the remainder of the buffer */

Index: main.c
===================================================================
RCS file: /home/or/cvsroot/src/or/main.c,v
retrieving revision 1.99
retrieving revision 1.100
diff -u -d -r1.99 -r1.100
--- main.c	23 Sep 2003 19:47:41 -0000	1.99
+++ main.c	24 Sep 2003 21:24:52 -0000	1.100
@@ -256,7 +256,7 @@
      * discussion of POLLIN vs POLLHUP */
 
   conn = connection_array[i];
-  //log_fn(LOG_DEBUG,"socket %d wants to read.",conn->s);
+  log_fn(LOG_DEBUG,"socket %d wants to read.",conn->s);
  
   assert_connection_ok(conn, time(NULL));
 
@@ -284,7 +284,7 @@
     return; /* this conn doesn't want to write */
 
   conn = connection_array[i];
-  //log_fn(LOG_DEBUG,"socket %d wants to write.",conn->s);
+  log_fn(LOG_DEBUG,"socket %d wants to write.",conn->s);
 
   assert_connection_ok(conn, time(NULL));
 
@@ -307,7 +307,12 @@
     log_fn(LOG_DEBUG,"Cleaning up connection.");
     if(conn->s >= 0) { /* might be an incomplete edge connection */
       /* FIXME there's got to be a better way to check for this -- and make other checks? */
-      connection_handle_write(conn); /* flush it first */
+      if(connection_speaks_cells(conn) && conn->state != OR_CONN_STATE_CONNECTING)
+        flush_buf_tls(conn->tls, &conn->outbuf, &conn->outbuflen,
+                      &conn->outbuf_flushlen, &conn->outbuf_datalen);
+      else
+        flush_buf(conn->s, &conn->outbuf, &conn->outbuflen,
+                  &conn->outbuf_flushlen, &conn->outbuf_datalen);
       if(connection_wants_to_flush(conn)) /* not done flushing */
         log_fn(LOG_WARNING,"Conn (socket %d) still wants to flush. Losing %d bytes!",conn->s, conn->inbuf_datalen);
     }

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.135
retrieving revision 1.136
diff -u -d -r1.135 -r1.136
--- or.h	21 Sep 2003 06:44:53 -0000	1.135
+++ or.h	24 Sep 2003 21:24:52 -0000	1.136
@@ -118,7 +118,7 @@
 #define CONN_TYPE_DIR 9
 #define CONN_TYPE_DNSWORKER 10
 #define CONN_TYPE_CPUWORKER 11
-#define _CONN_TYPE_MAX 3
+#define _CONN_TYPE_MAX 11
 
 #define LISTENER_STATE_READY 0
 
@@ -490,9 +490,9 @@
 int circuit_finish_handshake(circuit_t *circ, char *reply);
 int circuit_truncated(circuit_t *circ, crypt_path_t *layer);
 
-void assert_cpath_ok(crypt_path_t *c);
-void assert_cpath_layer_ok(crypt_path_t *c);
-void assert_circuit_ok(circuit_t *c);
+void assert_cpath_ok(const crypt_path_t *c);
+void assert_cpath_layer_ok(const crypt_path_t *c);
+void assert_circuit_ok(const circuit_t *c);
 
 /********************************* command.c ***************************/
 



More information about the tor-commits mailing list