[or-cvs] continue beating at pieces of The Bug

Roger Dingledine arma at seul.org
Fri Apr 9 21:31:11 UTC 2004


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

Modified Files:
	connection_edge.c dns.c 
Log Message:
continue beating at pieces of The Bug


Index: connection_edge.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_edge.c,v
retrieving revision 1.155
retrieving revision 1.156
diff -u -d -r1.155 -r1.156
--- connection_edge.c	9 Apr 2004 17:51:57 -0000	1.155
+++ connection_edge.c	9 Apr 2004 21:31:09 -0000	1.156
@@ -216,6 +216,53 @@
   return 0;
 }
 
+int connection_edge_process_relay_cell_not_open(
+    relay_header_t *rh, cell_t *cell, circuit_t *circ,
+    connection_t *conn, crypt_path_t *layer_hint) {
+  uint32_t addr;
+
+  if(rh->command == RELAY_COMMAND_END) {
+    log_fn(LOG_INFO,"Edge got end (%s) before we're connected. Marking for close.",
+      connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, rh->length));
+    if(CIRCUIT_IS_ORIGIN(circ))
+      circuit_log_path(LOG_INFO,circ);
+    conn->has_sent_end = 1; /* we just got an 'end', don't need to send one */
+    connection_mark_for_close(conn, 0);
+    /* XXX This is where we should check if reason is EXITPOLICY, and reattach */
+    /* XXX here we should send a socks reject back if necessary, and hold
+     * open til flushed */
+    return 0;
+  }
+  if(conn->type == CONN_TYPE_AP && rh->command == RELAY_COMMAND_CONNECTED) {
+    if(conn->state != AP_CONN_STATE_CONNECT_WAIT) {
+      log_fn(LOG_WARN,"Got 'connected' while not in state connect_wait. Dropping.");
+      return 0;
+    }
+//    log_fn(LOG_INFO,"Connected! Notifying application.");
+    conn->state = AP_CONN_STATE_OPEN;
+    if (rh->length >= 4) {
+      addr = ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE));
+      client_dns_set_entry(conn->socks_request->address, addr);
+    }
+    log_fn(LOG_INFO,"'connected' received after %d seconds.",
+           (int)(time(NULL) - conn->timestamp_lastread));
+    circuit_log_path(LOG_INFO,circ);
+    connection_ap_handshake_socks_reply(conn, NULL, 0, 1);
+    conn->socks_request->has_finished = 1;
+    /* handle anything that might have queued */
+    if (connection_edge_package_raw_inbuf(conn) < 0) {
+      connection_mark_for_close(conn, END_STREAM_REASON_MISC);
+      return 0;
+    }
+    return 0;
+  } else {
+    log_fn(LOG_WARN,"Got an unexpected relay command %d, in state %d (%s). Closing.",
+           rh->command, conn->state, conn_state_to_string[conn->type][conn->state]);
+    connection_mark_for_close(conn, END_STREAM_REASON_MISC);
+    return -1;
+  }
+}
+
 /* an incoming relay cell has arrived. return -1 if you want to tear down the
  * circuit, else 0. */
 int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
@@ -235,47 +282,11 @@
   /* either conn is NULL, in which case we've got a control cell, or else
    * conn points to the recognized stream. */
 
-  if(conn && conn->state != AP_CONN_STATE_OPEN && conn->state != EXIT_CONN_STATE_OPEN) {
-    if(rh.command == RELAY_COMMAND_END) {
-      log_fn(LOG_INFO,"Edge got end (%s) before we're connected. Marking for close.",
-        connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, rh.length));
-      if(CIRCUIT_IS_ORIGIN(circ))
-        circuit_log_path(LOG_INFO,circ);
-      conn->has_sent_end = 1; /* we just got an 'end', don't need to send one */
-      connection_mark_for_close(conn, 0);
-      /* XXX This is where we should check if reason is EXITPOLICY, and reattach */
-      /* XXX here we should send a socks reject back if necessary, and hold
-       * open til flushed */
-      return 0;
-    }
-    if(conn->type == CONN_TYPE_AP && rh.command == RELAY_COMMAND_CONNECTED) {
-      if(conn->state != AP_CONN_STATE_CONNECT_WAIT) {
-        log_fn(LOG_WARN,"Got 'connected' while not in state connect_wait. Dropping.");
-        return 0;
-      }
-//      log_fn(LOG_INFO,"Connected! Notifying application.");
-      conn->state = AP_CONN_STATE_OPEN;
-      if (rh.length >= 4) {
-        addr = ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE));
-        client_dns_set_entry(conn->socks_request->address, addr);
-      }
-      log_fn(LOG_INFO,"'connected' received after %d seconds.",
-             (int)(time(NULL) - conn->timestamp_lastread));
-      circuit_log_path(LOG_INFO,circ);
-      connection_ap_handshake_socks_reply(conn, NULL, 0, 1);
-      conn->socks_request->has_finished = 1;
-      /* handle anything that might have queued */
-      if (connection_edge_package_raw_inbuf(conn) < 0) {
-        connection_mark_for_close(conn, END_STREAM_REASON_MISC);
-        return 0;
-      }
-      return 0;
-    } else {
-      log_fn(LOG_WARN,"Got an unexpected relay command %d, in state %d (%s). Closing.",
-             rh.command, conn->state, conn_state_to_string[conn->type][conn->state]);
-      connection_mark_for_close(conn, END_STREAM_REASON_MISC);
-      return -1;
-    }
+  if(conn &&
+     conn->state != AP_CONN_STATE_OPEN &&
+     conn->state != EXIT_CONN_STATE_OPEN) {
+    return connection_edge_process_relay_cell_not_open(
+             &rh, cell, circ, conn, layer_hint);
   }
 
   switch(rh.command) {
@@ -1146,7 +1157,8 @@
     return 0;
   }
   n_stream->address = tor_strdup(cell->payload + RELAY_HEADER_SIZE);
-  n_stream->state = EXIT_CONN_STATE_RESOLVING;
+  n_stream->state = EXIT_CONN_STATE_RESOLVEFAILED;
+  /* default to failed, change in dns_resolve if it turns out not to fail */
 
   /* send it off to the gethostbyname farm */
   switch(dns_resolve(n_stream)) {
@@ -1155,9 +1167,6 @@
       return 0;
     case -1: /* resolve failed */
       log_fn(LOG_INFO,"Resolve failed (%s).", n_stream->address);
-      /* Set the state so that we don't try to remove n_stream from a DNS
-       * pending list. */
-      n_stream->state = EXIT_CONN_STATE_RESOLVEFAILED;
       connection_mark_for_close(n_stream, END_STREAM_REASON_RESOLVEFAILED);
       break;
     case 0: /* resolve added to pending list */

Index: dns.c
===================================================================
RCS file: /home/or/cvsroot/src/or/dns.c,v
retrieving revision 1.75
retrieving revision 1.76
diff -u -d -r1.75 -r1.76
--- dns.c	9 Apr 2004 21:06:14 -0000	1.75
+++ dns.c	9 Apr 2004 21:31:09 -0000	1.76
@@ -115,14 +115,11 @@
   uint32_t now = time(NULL);
   assert_connection_ok(exitconn, 0);
 
-  /* XXX leave disabled for dirservers so we can find the conn-munging bug */
-  if(!options.DirPort) {
-    /* first check if exitconn->address is an IP. If so, we already
-     * know the answer. */
-    if (tor_inet_aton(exitconn->address, &in) != 0) {
-      exitconn->addr = ntohl(in.s_addr);
-      return 1;
-    }
+  /* first check if exitconn->address is an IP. If so, we already
+   * know the answer. */
+  if (tor_inet_aton(exitconn->address, &in) != 0) {
+    exitconn->addr = ntohl(in.s_addr);
+    return 1;
   }
 
   /* then take this opportunity to see if there are any expired
@@ -143,6 +140,7 @@
         resolve->pending_connections = pending_connection;
         log_fn(LOG_DEBUG,"Connection (fd %d) waiting for pending DNS resolve of '%s'",
                exitconn->s, exitconn->address);
+        exitconn->state = EXIT_CONN_STATE_RESOLVING;
         return 0;
       case CACHE_STATE_VALID:
         exitconn->addr = resolve->addr;
@@ -166,6 +164,7 @@
   pending_connection->conn = exitconn;
   pending_connection->next = NULL;
   resolve->pending_connections = pending_connection;
+  exitconn->state = EXIT_CONN_STATE_RESOLVING;
 
   /* add us to the linked list of resolves */
   if (!oldest_cached_resolve) {
@@ -183,6 +182,8 @@
   connection_t *dnsconn;
   unsigned char len;
 
+  assert(exitconn->state == EXIT_CONN_STATE_RESOLVING);
+
   spawn_enough_dnsworkers(); /* respawn here, to be sure there are enough */
 
   dnsconn = connection_get_by_type_state(CONN_TYPE_DNSWORKER, DNSWORKER_STATE_IDLE);
@@ -376,8 +377,10 @@
     pend = resolve->pending_connections;
     assert_connection_ok(pend->conn,time(NULL));
     pend->conn->addr = resolve->addr;
-    /* prevent double-remove */
+
+    /* prevent double-remove. (this may get changed below.) */
     pend->conn->state = EXIT_CONN_STATE_RESOLVEFAILED;
+
     if(resolve->state == CACHE_STATE_FAILED) {
       pendconn = pend->conn; /* don't pass complex things to the
                                 connection_mark_for_close macro */



More information about the tor-commits mailing list