Browse Source

break connection_edge_end out of connection_mark_for_close

svn:r1858
Roger Dingledine 21 years ago
parent
commit
1cf1836990
10 changed files with 112 additions and 89 deletions
  1. 2 6
      src/or/circuit.c
  2. 28 23
      src/or/connection.c
  3. 46 25
      src/or/connection_edge.c
  4. 4 4
      src/or/connection_or.c
  5. 3 3
      src/or/cpuworker.c
  6. 10 10
      src/or/directory.c
  7. 7 5
      src/or/dns.c
  8. 5 5
      src/or/main.c
  9. 3 6
      src/or/or.h
  10. 4 2
      src/or/rendclient.c

+ 2 - 6
src/or/circuit.c

@@ -913,11 +913,6 @@ void circuit_about_to_close_connection(connection_t *conn) {
       if(!circ)
         return;
 
-      if(!conn->has_sent_end) {
-        log_fn(LOG_WARN,"Edge connection hasn't sent end yet? Bug.");
-        connection_mark_for_close(conn, END_STREAM_REASON_MISC);
-      }
-
       circuit_detach_stream(circ, conn);
 
   } /* end switch */
@@ -1619,7 +1614,8 @@ int circuit_truncated(circuit_t *circ, crypt_path_t *layer) {
         /* no need to send 'end' relay cells,
          * because the other side's already dead
          */
-        connection_mark_for_close(stream,0);
+        stream->has_sent_end = 1;
+        connection_mark_for_close(stream);
       }
     }
 

+ 28 - 23
src/or/connection.c

@@ -172,11 +172,19 @@ void connection_free_all(void) {
 
 void connection_about_to_close_connection(connection_t *conn)
 {
-  if(conn->type == CONN_TYPE_DIR)
-    if(conn->purpose == DIR_PURPOSE_FETCH_RENDDESC)
-      rend_client_desc_fetched(conn->rend_query, 0);
-
-
+  switch(conn->type) {
+    case CONN_TYPE_DIR:
+      if(conn->purpose == DIR_PURPOSE_FETCH_RENDDESC)
+        rend_client_desc_fetched(conn->rend_query, 0);
+      break;
+    case CONN_TYPE_AP:
+    case CONN_TYPE_EXIT:
+      if(!conn->has_sent_end) {
+        log_fn(LOG_WARN,"Edge connection hasn't sent end yet? Bug.");
+        connection_mark_for_close(conn);
+      }
+      break;
+  }
 }
 
 /** Close the underlying socket for <b>conn</b>, so we don't try to
@@ -213,9 +221,8 @@ void connection_close_immediate(connection_t *conn)
  *   - DNS conns need to fail any resolves that are pending on them.
  */
 int
-_connection_mark_for_close(connection_t *conn, char reason)
+_connection_mark_for_close(connection_t *conn)
 {
-  int retval = 0;
   assert_connection_ok(conn,0);
 
   if (conn->marked_for_close) {
@@ -240,7 +247,7 @@ _connection_mark_for_close(connection_t *conn, char reason)
          * you look at this more? -RD */
         if(conn->nickname)
           rep_hist_note_connect_failed(conn->nickname, time(NULL));
-      } else if (reason == CLOSE_REASON_UNUSED_OR_CONN) {
+      } else if (0) { // XXX reason == CLOSE_REASON_UNUSED_OR_CONN) {
         rep_hist_note_disconnect(conn->nickname, time(NULL));
       } else {
         rep_hist_note_connection_died(conn->nickname, time(NULL));
@@ -257,9 +264,6 @@ _connection_mark_for_close(connection_t *conn, char reason)
     case CONN_TYPE_EXIT:
       if (conn->state == EXIT_CONN_STATE_RESOLVING)
         connection_dns_remove(conn);
-      if (!conn->has_sent_end && reason &&
-          connection_edge_end(conn, reason, conn->cpath_layer) < 0)
-        retval = -1;
       break;
     case CONN_TYPE_DNSWORKER:
       if (conn->state == DNSWORKER_STATE_BUSY) {
@@ -277,7 +281,7 @@ _connection_mark_for_close(connection_t *conn, char reason)
    * we get our whole 15 seconds */
   conn->timestamp_lastwritten = time(NULL);
 
-  return retval;
+  return 0;
 }
 
 /** Find each connection that has hold_open_until_flushed set to
@@ -383,7 +387,7 @@ static int connection_handle_listener_read(connection_t *conn, int new_type) {
     }
     /* else there was a real error. */
     log_fn(LOG_WARN,"accept() failed. Closing listener.");
-    connection_mark_for_close(conn,0);
+    connection_mark_for_close(conn);
     return -1;
   }
   log(LOG_INFO,"Connection accepted on socket %d (child of fd %d).",news, conn->s);
@@ -403,7 +407,7 @@ static int connection_handle_listener_read(connection_t *conn, int new_type) {
   }
 
   if(connection_init_accepted_conn(newconn) < 0) {
-    connection_mark_for_close(newconn,0);
+    connection_mark_for_close(newconn);
     return 0;
   }
   return 0;
@@ -492,7 +496,7 @@ static void listener_close_if_present(int type) {
   conn = connection_get_by_type(type);
   if (conn) {
     connection_close_immediate(conn);
-    connection_mark_for_close(conn,0);
+    connection_mark_for_close(conn);
   }
 }
 
@@ -688,7 +692,8 @@ int connection_handle_read(connection_t *conn) {
     }
     /* There's a read error; kill the connection.*/
     connection_close_immediate(conn); /* Don't flush; connection is dead. */
-    connection_mark_for_close(conn, END_STREAM_REASON_MISC);
+    conn->has_sent_end = 1;
+    connection_mark_for_close(conn);
     return -1;
   }
   if(connection_process_inbuf(conn) < 0) {
@@ -797,10 +802,8 @@ int connection_handle_write(connection_t *conn) {
       /* not yet */
       if(!ERRNO_IS_CONN_EINPROGRESS(tor_socket_errno(conn->s))) {
         log_fn(LOG_DEBUG,"in-progress connect failed. Removing.");
-        /* The reason here only applies to exit connections, but it's
-         * harmless to set it elsewhere. */
         connection_close_immediate(conn);
-        connection_mark_for_close(conn,END_STREAM_REASON_CONNECTFAILED);
+        connection_mark_for_close(conn);
         if (conn->nickname)
           router_mark_as_down(conn->nickname);
         return -1;
@@ -817,7 +820,7 @@ int connection_handle_write(connection_t *conn) {
       connection_stop_writing(conn);
       if(connection_tls_continue_handshake(conn) < 0) {
         connection_close_immediate(conn); /* Don't flush; connection is dead. */
-        connection_mark_for_close(conn, 0);
+        connection_mark_for_close(conn);
         return -1;
       }
       return 0;
@@ -829,7 +832,7 @@ int connection_handle_write(connection_t *conn) {
       case TOR_TLS_CLOSE:
         log_fn(LOG_INFO,"tls error. breaking.");
         connection_close_immediate(conn); /* Don't flush; connection is dead. */
-        connection_mark_for_close(conn, 0);
+        connection_mark_for_close(conn);
         return -1; /* XXX deal with close better */
       case TOR_TLS_WANTWRITE:
         log_fn(LOG_DEBUG,"wanted write.");
@@ -855,7 +858,8 @@ int connection_handle_write(connection_t *conn) {
   } else {
     if (flush_buf(conn->s, conn->outbuf, &conn->outbuf_flushlen) < 0) {
       connection_close_immediate(conn); /* Don't flush; connection is dead. */
-      connection_mark_for_close(conn, END_STREAM_REASON_MISC);
+      conn->has_sent_end = 1;
+      connection_mark_for_close(conn);
       return -1;
     }
   }
@@ -881,7 +885,8 @@ void connection_write_to_buf(const char *string, int len, connection_t *conn) {
 
   if(write_to_buf(string, len, conn->outbuf) < 0) {
     log_fn(LOG_WARN,"write_to_buf failed. Closing connection (fd %d).", conn->s);
-    connection_mark_for_close(conn,0);
+    /* XXX should call connection_edge_end() ? */
+    connection_mark_for_close(conn);
     return;
   }
 

+ 46 - 25
src/or/connection_edge.c

@@ -72,7 +72,8 @@ int connection_edge_process_inbuf(connection_t *conn) {
     conn->done_receiving = 1;
     shutdown(conn->s, 0); /* XXX check return, refactor NM */
     if (conn->done_sending) {
-      connection_mark_for_close(conn, END_STREAM_REASON_DONE);
+      connection_edge_end(conn, END_STREAM_REASON_DONE, conn->cpath_layer);
+      connection_mark_for_close(conn);
     } else {
       connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_END,
                                    NULL, 0, conn->cpath_layer);
@@ -81,7 +82,8 @@ int connection_edge_process_inbuf(connection_t *conn) {
 #else
     /* eof reached, kill it. */
     log_fn(LOG_INFO,"conn (fd %d) reached eof. Closing.", conn->s);
-    connection_mark_for_close(conn, END_STREAM_REASON_DONE);
+    connection_edge_end(conn, END_STREAM_REASON_DONE, conn->cpath_layer);
+    connection_mark_for_close(conn);
     conn->hold_open_until_flushed = 1; /* just because we shouldn't read
                                           doesn't mean we shouldn't write */
     return 0;
@@ -91,7 +93,8 @@ int connection_edge_process_inbuf(connection_t *conn) {
   switch(conn->state) {
     case AP_CONN_STATE_SOCKS_WAIT:
       if(connection_ap_handshake_process_socks(conn) < 0) {
-        connection_mark_for_close(conn, END_STREAM_REASON_MISC);
+        conn->has_sent_end = 1; /* no circ yet */
+        connection_mark_for_close(conn);
         conn->hold_open_until_flushed = 1;
         return -1;
       }
@@ -104,7 +107,8 @@ int connection_edge_process_inbuf(connection_t *conn) {
         return 0;
       }
       if(connection_edge_package_raw_inbuf(conn) < 0) {
-        connection_mark_for_close(conn, END_STREAM_REASON_MISC);
+        connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
+        connection_mark_for_close(conn);
         return -1;
       }
       return 0;
@@ -117,7 +121,8 @@ int connection_edge_process_inbuf(connection_t *conn) {
       return 0;
   }
   log_fn(LOG_WARN,"Got unexpected state %d. Closing.",conn->state);
-  connection_mark_for_close(conn, END_STREAM_REASON_MISC);
+  connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
+  connection_mark_for_close(conn);
   return -1;
 }
 
@@ -132,7 +137,7 @@ int connection_edge_destroy(uint16_t circ_id, connection_t *conn) {
   log_fn(LOG_INFO,"CircID %d: At an edge. Marking connection for close.",
          circ_id);
   conn->has_sent_end = 1; /* we're closing the circuit, nothing to send to */
-  connection_mark_for_close(conn, END_STREAM_REASON_DESTROY);
+  connection_mark_for_close(conn);
   conn->hold_open_until_flushed = 1;
   return 0;
 }
@@ -172,7 +177,9 @@ connection_edge_end_reason(char *payload, uint16_t length) {
  * Return -1 if this function has already been called on this conn,
  * else return 0.
  */
-int connection_edge_end(connection_t *conn, char reason, crypt_path_t *cpath_layer) {
+int
+connection_edge_end(connection_t *conn, char reason, crypt_path_t *cpath_layer)
+{
   char payload[5];
   int payload_len=1;
   circuit_t *circ;
@@ -222,7 +229,8 @@ int connection_edge_send_command(connection_t *fromconn, circuit_t *circ,
   if(!circ) {
     log_fn(LOG_WARN,"no circ. Closing conn.");
     tor_assert(fromconn);
-    connection_mark_for_close(fromconn, 0);
+    fromconn->has_sent_end = 1; /* no circ to send to */
+    connection_mark_for_close(fromconn);
     return -1;
   }
 
@@ -309,7 +317,7 @@ connection_edge_process_relay_cell_not_open(
     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);
+    connection_mark_for_close(conn);
     return 0;
   }
 
@@ -331,7 +339,8 @@ connection_edge_process_relay_cell_not_open(
     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);
+      connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
+      connection_mark_for_close(conn);
       return 0;
     }
     return 0;
@@ -339,7 +348,8 @@ connection_edge_process_relay_cell_not_open(
 
   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);
+  connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
+  connection_mark_for_close(conn);
   return -1;
 }
 
@@ -396,7 +406,8 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
       if((layer_hint && --layer_hint->deliver_window < 0) ||
          (!layer_hint && --circ->deliver_window < 0)) {
         log_fn(LOG_WARN,"(relay data) circ deliver_window below 0. Killing.");
-        connection_mark_for_close(conn, END_STREAM_REASON_MISC);
+        connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
+        connection_mark_for_close(conn);
         return -1;
       }
       log_fn(LOG_DEBUG,"circ deliver_window now %d.", layer_hint ?
@@ -436,13 +447,13 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
       if (conn->done_receiving) {
         /* We just *got* an end; no reason to send one. */
         conn->has_sent_end = 1;
-        connection_mark_for_close(conn, 0);
+        connection_mark_for_close(conn);
         conn->hold_open_until_flushed = 1;
       }
 #else
       /* We just *got* an end; no reason to send one. */
       conn->has_sent_end = 1;
-      connection_mark_for_close(conn, 0);
+      connection_mark_for_close(conn);
       conn->hold_open_until_flushed = 1;
 #endif
       return 0;
@@ -711,14 +722,15 @@ void connection_ap_expire_beginning(void) {
     circ = circuit_get_by_conn(conn);
     if(!circ) { /* it's vanished? */
       log_fn(LOG_INFO,"Conn is in connect-wait, but lost its circ.");
-      connection_mark_for_close(conn,0);
+      connection_mark_for_close(conn);
       continue;
     }
     if(circ->purpose == CIRCUIT_PURPOSE_C_REND_JOINED) {
       if (now - conn->timestamp_lastread > 45) {
         log_fn(LOG_WARN,"Rend stream is %d seconds late. Giving up.",
                (int)(now - conn->timestamp_lastread));
-        connection_mark_for_close(conn,END_STREAM_REASON_TIMEOUT);
+        connection_edge_end(conn, END_STREAM_REASON_TIMEOUT, conn->cpath_layer);
+        connection_mark_for_close(conn);
       }
       continue;
     }
@@ -727,7 +739,8 @@ void connection_ap_expire_beginning(void) {
       log_fn(LOG_WARN,"Stream is %d seconds late. Giving up.",
              15*conn->num_retries);
       circuit_log_path(LOG_WARN, circ);
-      connection_mark_for_close(conn,END_STREAM_REASON_TIMEOUT);
+      connection_edge_end(conn, END_STREAM_REASON_TIMEOUT, conn->cpath_layer);
+      connection_mark_for_close(conn);
     } else {
       log_fn(LOG_WARN,"Stream is %d seconds late. Retrying.",
              (int)(now - conn->timestamp_lastread));
@@ -750,7 +763,8 @@ void connection_ap_expire_beginning(void) {
       if(connection_ap_handshake_attach_circuit(conn)<0) {
         /* it will never work */
         /* Don't need to send end -- we're not connected */
-        connection_mark_for_close(conn, 0);
+        conn->has_sent_end = 1;
+        connection_mark_for_close(conn);
       }
     } /* end if max_retries */
   } /* end for */
@@ -775,7 +789,8 @@ void connection_ap_attach_pending(void)
     if(connection_ap_handshake_attach_circuit(conn) < 0) {
       /* -1 means it will never work */
       /* Don't send end; there is no 'other side' yet */
-      connection_mark_for_close(conn,0);
+      conn->has_sent_end = 1;
+      connection_mark_for_close(conn);
     }
   }
 }
@@ -1141,7 +1156,8 @@ int connection_ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ)
   ap_conn->stream_id = get_unique_stream_id_by_circ(circ);
   if (ap_conn->stream_id==0) {
     /* Don't send end: there is no 'other side' yet */
-    connection_mark_for_close(ap_conn, 0);
+    ap_conn->has_sent_end = 1;
+    connection_mark_for_close(ap_conn);
     circuit_mark_for_close(circ);
     return -1;
   }
@@ -1220,7 +1236,8 @@ int connection_ap_make_bridge(char *address, uint16_t port) {
 
   /* attaching to a dirty circuit is fine */
   if (connection_ap_handshake_attach_circuit(conn) < 0) {
-    connection_mark_for_close(conn, 0);
+    conn->has_sent_end = 1; /* no circ to send to */
+    connection_mark_for_close(conn);
     tor_close_socket(fd[1]);
     return -1;
   }
@@ -1332,7 +1349,8 @@ static int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
     assert_circuit_ok(circ);
     if(rend_service_set_connection_addr_port(n_stream, circ) < 0) {
       log_fn(LOG_INFO,"Didn't find rendezvous service (port %d)",n_stream->port);
-      connection_mark_for_close(n_stream, END_STREAM_REASON_EXITPOLICY);
+      connection_edge_end(n_stream, END_STREAM_REASON_EXITPOLICY, n_stream->cpath_layer);
+      connection_mark_for_close(n_stream);
       connection_free(n_stream);
       circuit_mark_for_close(circ); /* knock the whole thing down, somebody screwed up */
       return 0;
@@ -1366,7 +1384,8 @@ static int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
       return 0;
     case -1: /* resolve failed */
       log_fn(LOG_INFO,"Resolve failed (%s).", n_stream->address);
-      connection_mark_for_close(n_stream, END_STREAM_REASON_RESOLVEFAILED);
+      connection_edge_end(n_stream, END_STREAM_REASON_RESOLVEFAILED, n_stream->cpath_layer);
+      connection_mark_for_close(n_stream);
       connection_free(n_stream);
       break;
     case 0: /* resolve added to pending list */
@@ -1392,7 +1411,8 @@ void connection_exit_connect(connection_t *conn) {
   if (!connection_edge_is_rendezvous_stream(conn) &&
       router_compare_to_my_exit_policy(conn) == ADDR_POLICY_REJECTED) {
     log_fn(LOG_INFO,"%s:%d failed exit policy. Closing.", conn->address, conn->port);
-    connection_mark_for_close(conn, END_STREAM_REASON_EXITPOLICY);
+    connection_edge_end(conn, END_STREAM_REASON_EXITPOLICY, conn->cpath_layer);
+    connection_mark_for_close(conn);
     circuit_detach_stream(circuit_get_by_conn(conn), conn);
     connection_free(conn);
     return;
@@ -1401,7 +1421,8 @@ void connection_exit_connect(connection_t *conn) {
   log_fn(LOG_DEBUG,"about to try connecting");
   switch(connection_connect(conn, conn->address, conn->addr, conn->port)) {
     case -1:
-      connection_mark_for_close(conn, END_STREAM_REASON_CONNECTFAILED);
+      connection_edge_end(conn, END_STREAM_REASON_CONNECTFAILED, conn->cpath_layer);
+      connection_mark_for_close(conn);
       circuit_detach_stream(circuit_get_by_conn(conn), conn);
       connection_free(conn);
       return;

+ 4 - 4
src/or/connection_or.c

@@ -47,7 +47,7 @@ int connection_or_process_inbuf(connection_t *conn) {
 
   if(conn->inbuf_reached_eof) {
     log_fn(LOG_INFO,"OR connection reached EOF. Closing.");
-    connection_mark_for_close(conn,0);
+    connection_mark_for_close(conn);
     return 0;
   }
 
@@ -89,8 +89,8 @@ int connection_or_finished_connecting(connection_t *conn)
          conn->address,conn->port);
 
   if(connection_tls_start_handshake(conn, 0) < 0) {
-    /* TLS handhaking error of some kind. */
-    connection_mark_for_close(conn,0);
+    /* TLS handshaking error of some kind. */
+    connection_mark_for_close(conn);
     return -1;
   }
   return 0;
@@ -163,7 +163,7 @@ connection_t *connection_or_connect(routerinfo_t *router) {
     return conn;
 
   /* failure */
-  connection_mark_for_close(conn, 0);
+  connection_mark_for_close(conn);
   return NULL;
 }
 

+ 3 - 3
src/or/cpuworker.c

@@ -83,7 +83,7 @@ void cpuworkers_rotate(void)
   connection_t *cpuworker;
   while ((cpuworker = connection_get_by_type_state(CONN_TYPE_CPUWORKER,
                                                    CPUWORKER_STATE_IDLE))) {
-    connection_mark_for_close(cpuworker,0);
+    connection_mark_for_close(cpuworker);
     --num_cpuworkers;
   }
   last_rotation_time = time(NULL);
@@ -117,7 +117,7 @@ int connection_cpu_process_inbuf(connection_t *conn) {
     }
     num_cpuworkers--;
     spawn_enough_cpuworkers(); /* try to regrow. hope we don't end up spinning. */
-    connection_mark_for_close(conn,0);
+    connection_mark_for_close(conn);
     return 0;
   }
 
@@ -161,7 +161,7 @@ done_processing:
   conn->state = CPUWORKER_STATE_IDLE;
   num_cpuworkers_busy--;
   if (conn->timestamp_created < last_rotation_time) {
-    connection_mark_for_close(conn,0);
+    connection_mark_for_close(conn);
     num_cpuworkers--;
     spawn_enough_cpuworkers();
   } else {

+ 10 - 10
src/or/directory.c

@@ -106,7 +106,7 @@ void directory_initiate_command(routerinfo_t *router, int purpose,
     conn->s = connection_ap_make_bridge(conn->address, conn->port);
     if(conn->s < 0) {
       log_fn(LOG_WARN,"Making AP bridge to dirserver failed.");
-      connection_mark_for_close(conn, 0);
+      connection_mark_for_close(conn);
       return;
     }
 
@@ -232,7 +232,7 @@ int connection_dir_process_inbuf(connection_t *conn) {
     if(conn->state != DIR_CONN_STATE_CLIENT_READING) {
       log_fn(LOG_INFO,"conn reached eof, not reading. Closing.");
       connection_close_immediate(conn); /* it was an error; give up on flushing */
-      connection_mark_for_close(conn,0);
+      connection_mark_for_close(conn);
       return -1;
     }
 
@@ -241,11 +241,11 @@ int connection_dir_process_inbuf(connection_t *conn) {
                                &body, &body_len, MAX_DIR_SIZE)) {
       case -1: /* overflow */
         log_fn(LOG_WARN,"'fetch' response too large. Failing.");
-        connection_mark_for_close(conn,0);
+        connection_mark_for_close(conn);
         return -1;
       case 0:
         log_fn(LOG_INFO,"'fetch' response not all here, but we're at eof. Closing.");
-        connection_mark_for_close(conn,0);
+        connection_mark_for_close(conn);
         return -1;
       /* case 1, fall through */
     }
@@ -253,7 +253,7 @@ int connection_dir_process_inbuf(connection_t *conn) {
     if(parse_http_response(headers, &status_code, NULL) < 0) {
       log_fn(LOG_WARN,"Unparseable headers. Closing.");
       free(body); free(headers);
-      connection_mark_for_close(conn,0);
+      connection_mark_for_close(conn);
       return -1;
     }
 
@@ -263,14 +263,14 @@ int connection_dir_process_inbuf(connection_t *conn) {
       if(status_code == 503 || body_len == 0) {
         log_fn(LOG_INFO,"Empty directory. Ignoring.");
         free(body); free(headers);
-        connection_mark_for_close(conn,0);
+        connection_mark_for_close(conn);
         return 0;
       }
       if(status_code != 200) {
         log_fn(LOG_WARN,"Received http status code %d from dirserver. Failing.",
                status_code);
         free(body); free(headers);
-        connection_mark_for_close(conn,0);
+        connection_mark_for_close(conn);
         return -1;
       }
       if(router_set_routerlist_from_directory(body, conn->identity_pkey) < 0){
@@ -338,14 +338,14 @@ int connection_dir_process_inbuf(connection_t *conn) {
       }
     }
     free(body); free(headers);
-    connection_mark_for_close(conn,0);
+    connection_mark_for_close(conn);
     return 0;
   } /* endif 'reached eof' */
 
   /* If we're on the dirserver side, look for a command. */
   if(conn->state == DIR_CONN_STATE_SERVER_COMMAND_WAIT) {
     if (directory_handle_command(conn) < 0) {
-      connection_mark_for_close(conn,0);
+      connection_mark_for_close(conn);
       return -1;
     }
     return 0;
@@ -538,7 +538,7 @@ int connection_dir_finished_flushing(connection_t *conn) {
       return 0;
     case DIR_CONN_STATE_SERVER_WRITING:
       log_fn(LOG_INFO,"Finished writing server response. Closing.");
-      connection_mark_for_close(conn,0);
+      connection_mark_for_close(conn);
       return 0;
     default:
       log_fn(LOG_WARN,"BUG: called in unexpected state %d.", conn->state);

+ 7 - 5
src/or/dns.c

@@ -343,7 +343,8 @@ void dns_cancel_pending_resolve(char *address) {
     pend->conn->state = EXIT_CONN_STATE_RESOLVEFAILED;
     pendconn = pend->conn; /* don't pass complex things to the
                               connection_mark_for_close macro */
-    connection_mark_for_close(pendconn, END_STREAM_REASON_MISC);
+    connection_edge_end(pendconn, END_STREAM_REASON_MISC, pendconn->cpath_layer);
+    connection_mark_for_close(pendconn);
     resolve->pending_connections = pend->next;
     tor_free(pend);
   }
@@ -433,7 +434,8 @@ static void dns_found_answer(char *address, uint32_t addr, char outcome) {
                                 connection_mark_for_close macro */
       /* prevent double-remove. */
       pendconn->state = EXIT_CONN_STATE_RESOLVEFAILED;
-      connection_mark_for_close(pendconn, END_STREAM_REASON_RESOLVEFAILED);
+      connection_edge_end(pendconn, END_STREAM_REASON_MISC, pendconn->cpath_layer);
+      connection_mark_for_close(pendconn);
       connection_free(pendconn);
     } else {
       /* prevent double-remove. */
@@ -488,7 +490,7 @@ int connection_dns_process_inbuf(connection_t *conn) {
       num_dnsworkers_busy--;
     }
     num_dnsworkers--;
-    connection_mark_for_close(conn,0);
+    connection_mark_for_close(conn);
     return 0;
   }
 
@@ -645,7 +647,7 @@ static void spawn_enough_dnsworkers(void) {
     log_fn(LOG_WARN, "%d DNS workers are spawned; all are busy. Killing one.",
            MAX_DNSWORKERS);
 
-    connection_mark_for_close(dnsconn,0);
+    connection_mark_for_close(dnsconn);
     num_dnsworkers_busy--;
     num_dnsworkers--;
   }
@@ -669,7 +671,7 @@ static void spawn_enough_dnsworkers(void) {
            num_dnsworkers-num_dnsworkers_needed, num_dnsworkers);
     dnsconn = connection_get_by_type_state(CONN_TYPE_DNSWORKER, DNSWORKER_STATE_IDLE);
     tor_assert(dnsconn);
-    connection_mark_for_close(dnsconn,0);
+    connection_mark_for_close(dnsconn);
     num_dnsworkers--;
   }
 }

+ 5 - 5
src/or/main.c

@@ -219,7 +219,7 @@ static void conn_read(int i) {
         /* XXX but it'll clearly happen on MS_WINDOWS from POLLERR, right? */
         log_fn(LOG_ERR,"Unhandled error on read for %s connection (fd %d); removing",
                CONN_TYPE_TO_STRING(conn->type), conn->s);
-        connection_mark_for_close(conn,0);
+        connection_mark_for_close(conn);
       }
   }
   assert_connection_ok(conn, time(NULL));
@@ -250,7 +250,7 @@ static void conn_write(int i) {
       log_fn(LOG_WARN,"Unhandled error on read for %s connection (fd %d); removing",
              CONN_TYPE_TO_STRING(conn->type), conn->s);
       conn->has_sent_end = 1; /* otherwise we cry wolf about duplicate close */
-      connection_mark_for_close(conn,0);
+      connection_mark_for_close(conn);
     }
   }
   assert_connection_ok(conn, time(NULL));
@@ -359,11 +359,11 @@ static void run_connection_housekeeping(int i, time_t now) {
       if(flush_buf(conn->s, conn->outbuf, &conn->outbuf_flushlen) < 0) {
         log_fn(LOG_WARN,"flushing expired directory conn failed.");
         connection_close_immediate(conn);
-        connection_mark_for_close(conn,0);
+        connection_mark_for_close(conn);
         /*  */
       } else {
         /* XXXX Does this next part make sense, really? */
-        connection_mark_for_close(conn,0);
+        connection_mark_for_close(conn);
         conn->hold_open_until_flushed = 1; /* give it a last chance */
       }
     }
@@ -383,7 +383,7 @@ static void run_connection_housekeeping(int i, time_t now) {
       log_fn(LOG_INFO,"Expiring connection to %d (%s:%d).",
              i,conn->address, conn->port);
       /* flush anything waiting, e.g. a destroy for a just-expired circ */
-      connection_mark_for_close(conn,CLOSE_REASON_UNUSED_OR_CONN);
+      connection_mark_for_close(conn);
       conn->hold_open_until_flushed = 1;
     } else {
       /* either a full router, or we've got a circuit. send a padding cell. */

+ 3 - 6
src/or/or.h

@@ -357,9 +357,6 @@
 /** Length of 'y' portion of 'y.onion' URL. */
 #define REND_SERVICE_ID_LEN 16
 
-/* Reasons used by connection_mark_for_close */
-#define CLOSE_REASON_UNUSED_OR_CONN 100
-
 #define CELL_DIRECTION_IN 1
 #define CELL_DIRECTION_OUT 2
 
@@ -955,11 +952,11 @@ void connection_free(connection_t *conn);
 void connection_free_all(void);
 void connection_about_to_close_connection(connection_t *conn);
 void connection_close_immediate(connection_t *conn);
-int _connection_mark_for_close(connection_t *conn, char reason);
+int _connection_mark_for_close(connection_t *conn);
 
-#define connection_mark_for_close(c,r)                                  \
+#define connection_mark_for_close(c)                                    \
   do {                                                                  \
-    if (_connection_mark_for_close(c,r)<0) {                            \
+    if (_connection_mark_for_close(c)<0) {                              \
       log(LOG_WARN,"Duplicate call to connection_mark_for_close at %s:%d (first at %s:%d)", \
           __FILE__,__LINE__,c->marked_for_close_file,c->marked_for_close); \
     } else {                                                            \

+ 4 - 2
src/or/rendclient.c

@@ -380,11 +380,13 @@ void rend_client_desc_fetched(char *query, int success) {
       if (connection_ap_handshake_attach_circuit(conn) < 0) {
         /* it will never work */
         log_fn(LOG_WARN,"attaching to a rend circ failed. Closing conn.");
-        connection_mark_for_close(conn,0);
+        conn->has_sent_end = 1;
+        connection_mark_for_close(conn);
       }
     } else { /* 404, or fetch didn't get that far */
       log_fn(LOG_WARN,"service id '%s' fetched failed, and not in cache. Closing conn.", query);
-      connection_mark_for_close(conn,0);
+      conn->has_sent_end = 1;
+      connection_mark_for_close(conn);
     }
   }
 }