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

[or-cvs] break reached_eof() out of process_inbuf()



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

Modified Files:
	connection.c connection_edge.c connection_or.c control.c 
	cpuworker.c directory.c dns.c or.h 
Log Message:
break reached_eof() out of process_inbuf()


Index: connection.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/connection.c,v
retrieving revision 1.293
retrieving revision 1.294
diff -u -d -r1.293 -r1.294
--- connection.c	21 Nov 2004 07:43:12 -0000	1.293
+++ connection.c	21 Nov 2004 10:14:56 -0000	1.294
@@ -87,6 +87,7 @@
 static int connection_receiver_bucket_should_increase(connection_t *conn);
 static int connection_finished_flushing(connection_t *conn);
 static int connection_finished_connecting(connection_t *conn);
+static int connection_reached_eof(connection_t *conn);
 static int connection_read_to_buf(connection_t *conn, int *max_to_read);
 static int connection_process_inbuf(connection_t *conn, int package_partial);
 static int connection_bucket_read_limit(connection_t *conn);
@@ -856,6 +857,9 @@
   if (connection_process_inbuf(conn, 1) < 0) {
     return -1;
   }
+  if (conn->inbuf_reached_eof && connection_reached_eof(conn) < 0) {
+    return -1;
+  }
   return 0;
 }
 
@@ -1294,7 +1298,7 @@
     case CONN_TYPE_CONTROL:
       return connection_control_process_inbuf(conn);
     default:
-      log_fn(LOG_WARN,"got unexpected conn->type %d.", conn->type);
+      log_fn(LOG_WARN,"got unexpected conn type %d.", conn->type);
       return -1;
   }
 }
@@ -1326,7 +1330,7 @@
     case CONN_TYPE_CONTROL:
       return connection_control_finished_flushing(conn);
     default:
-      log_fn(LOG_WARN,"got unexpected conn->type %d.", conn->type);
+      log_fn(LOG_WARN,"got unexpected conn type %d.", conn->type);
       return -1;
   }
 }
@@ -1349,7 +1353,29 @@
     case CONN_TYPE_DIR:
       return connection_dir_finished_connecting(conn);
     default:
-      tor_assert(0);
+      log_fn(LOG_WARN,"got unexpected conn type %d.", conn->type);
+      return -1;
+  }
+}
+
+static int connection_reached_eof(connection_t *conn)
+{
+  switch (conn->type) {
+    case CONN_TYPE_OR:
+      return connection_or_reached_eof(conn);
+    case CONN_TYPE_AP:
+    case CONN_TYPE_EXIT:
+      return connection_edge_reached_eof(conn);
+    case CONN_TYPE_DIR:
+      return connection_dir_reached_eof(conn);
+    case CONN_TYPE_DNSWORKER:
+      return connection_dns_reached_eof(conn);
+    case CONN_TYPE_CPUWORKER:
+      return connection_cpu_reached_eof(conn);
+    case CONN_TYPE_CONTROL:
+      return connection_control_reached_eof(conn);
+    default:
+      log_fn(LOG_WARN,"got unexpected conn type %d.", conn->type);
       return -1;
   }
 }

Index: connection_edge.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/connection_edge.c,v
retrieving revision 1.235
retrieving revision 1.236
diff -u -d -r1.235 -r1.236
--- connection_edge.c	21 Nov 2004 09:39:01 -0000	1.235
+++ connection_edge.c	21 Nov 2004 10:14:57 -0000	1.236
@@ -18,12 +18,37 @@
 
 static int connection_ap_handshake_process_socks(connection_t *conn);
 
-/** Handle new bytes on conn->inbuf, or notification of eof.
- *
- * If there was an EOF, then send an end and mark the connection
- * for close.
- *
- * Otherwise handle it based on state:
+/** There was an EOF. Send an end and mark the connection for close.
+ */
+int connection_edge_reached_eof(connection_t *conn) {
+#ifdef HALF_OPEN
+  /* eof reached; we're done reading, but we might want to write more. */
+  conn->done_receiving = 1;
+  shutdown(conn->s, 0); /* XXX check return, refactor NM */
+  if (conn->done_sending) {
+    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);
+  }
+  return 0;
+#else
+  /* eof reached, kill it. */
+  log_fn(LOG_INFO,"conn (fd %d) reached eof (stream size %d). Closing.", conn->s, (int)conn->stream_size);
+  connection_edge_end(conn, END_STREAM_REASON_DONE, conn->cpath_layer);
+  if(!conn->marked_for_close) {
+    /* only mark it if not already marked. it's possible to
+     * get the 'end' right around when the client hangs up on us. */
+    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;
+#endif
+}
+
+/** Handle new bytes on conn->inbuf based on state:
  *   - If it's waiting for socks info, try to read another step of the
  *     socks handshake out of conn->inbuf.
  *   - If it's open, then package more relay cells from the stream.
@@ -37,34 +62,6 @@
   tor_assert(conn);
   tor_assert(conn->type == CONN_TYPE_AP || conn->type == CONN_TYPE_EXIT);
 
-  if(conn->inbuf_reached_eof) {
-#ifdef HALF_OPEN
-    /* eof reached; we're done reading, but we might want to write more. */
-    conn->done_receiving = 1;
-    shutdown(conn->s, 0); /* XXX check return, refactor NM */
-    if (conn->done_sending) {
-      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);
-    }
-    return 0;
-#else
-    /* eof reached, kill it. */
-    log_fn(LOG_INFO,"conn (fd %d) reached eof (stream size %d). Closing.", conn->s, (int)conn->stream_size);
-    connection_edge_end(conn, END_STREAM_REASON_DONE, conn->cpath_layer);
-    if(!conn->marked_for_close) {
-      /* only mark it if not already marked. it's possible to
-       * get the 'end' right around when the client hangs up on us. */
-      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;
-#endif
-  }
-
   switch(conn->state) {
     case AP_CONN_STATE_SOCKS_WAIT:
       if(connection_ap_handshake_process_socks(conn) < 0) {

Index: connection_or.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/connection_or.c,v
retrieving revision 1.142
retrieving revision 1.143
diff -u -d -r1.142 -r1.143
--- connection_or.c	20 Nov 2004 00:37:00 -0000	1.142
+++ connection_or.c	21 Nov 2004 10:14:57 -0000	1.143
@@ -40,6 +40,12 @@
   memcpy(dest->payload, src+3, CELL_PAYLOAD_SIZE);
 }
 
+int connection_or_reached_eof(connection_t *conn) {
+  log_fn(LOG_INFO,"OR connection reached EOF. Closing.");
+  connection_mark_for_close(conn);
+  return 0;
+}
+
 /** Handle any new bytes that have come in on connection <b>conn</b>.
  * If conn is in 'open' state, hand it to
  * connection_or_process_cells_from_inbuf()
@@ -50,12 +56,6 @@
   tor_assert(conn);
   tor_assert(conn->type == CONN_TYPE_OR);
 
-  if(conn->inbuf_reached_eof) {
-    log_fn(LOG_INFO,"OR connection reached EOF. Closing.");
-    connection_mark_for_close(conn);
-    return 0;
-  }
-
   if(conn->state != OR_CONN_STATE_OPEN)
     return 0; /* don't do anything */
   return connection_or_process_cells_from_inbuf(conn);

Index: control.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/control.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- control.c	15 Nov 2004 04:02:59 -0000	1.27
+++ control.c	21 Nov 2004 10:14:57 -0000	1.28
@@ -391,8 +391,15 @@
   return 0;
 }
 
-/** Called when <b>conn</b> has received more bytes on its inbuf, or has
- * gotten its socket closed. */
+/** Called when <b>conn</b> has gotten its socket closed. */
+int connection_control_reached_eof(connection_t *conn) {
+  log_fn(LOG_INFO,"Control connection reached EOF. Closing.");
+  connection_mark_for_close(conn);
+  return 0;
+}
+
+/** Called when <b>conn</b> has received more bytes on its inbuf.
+ */
 int
 connection_control_process_inbuf(connection_t *conn) {
   uint16_t body_len, command_type;
@@ -401,12 +408,6 @@
   tor_assert(conn);
   tor_assert(conn->type == CONN_TYPE_CONTROL);
 
-  if(conn->inbuf_reached_eof) {
-    log_fn(LOG_INFO,"Control connection reached EOF. Closing.");
-    connection_mark_for_close(conn);
-    return 0;
-  }
-
  again:
   /* Try to suck a control message from the buffer. */
   switch(fetch_from_buf_control(conn->inbuf, &body_len, &command_type, &body))

Index: cpuworker.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/cpuworker.c,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -d -r1.55 -r1.56
--- cpuworker.c	16 Nov 2004 03:12:53 -0000	1.55
+++ cpuworker.c	21 Nov 2004 10:14:57 -0000	1.56
@@ -91,9 +91,25 @@
   spawn_enough_cpuworkers();
 }
 
+/** If the cpuworker closes the connection,
+ * mark it as closed and spawn a new one as needed. */
+int connection_cpu_reached_eof(connection_t *conn) {
+  log_fn(LOG_WARN,"Read eof. Worker died unexpectedly.");
+  if(conn->state != CPUWORKER_STATE_IDLE) {
+    /* the circ associated with this cpuworker will have to wait until
+     * it gets culled in run_connection_housekeeping(), since we have
+     * no way to find out which circ it was. */
+    log_fn(LOG_WARN,"...and it left a circuit queued; abandoning circ.");
+    num_cpuworkers_busy--;
+  }
+  num_cpuworkers--;
+  spawn_enough_cpuworkers(); /* try to regrow. hope we don't end up spinning. */
+  connection_mark_for_close(conn);
+  return 0;
+}
+
 /** Called when we get data from a cpuworker.  If the answer is not complete,
- * wait for a complete answer.  If the cpuworker closes the connection,
- * mark it as closed and spawn a new one as needed.  If the answer is complete,
+ * wait for a complete answer. If the answer is complete,
  * process it as appropriate.
  */
 int connection_cpu_process_inbuf(connection_t *conn) {
@@ -108,21 +124,6 @@
   tor_assert(conn);
   tor_assert(conn->type == CONN_TYPE_CPUWORKER);
 
-  if(conn->inbuf_reached_eof) {
-    log_fn(LOG_WARN,"Read eof. Worker died unexpectedly.");
-    if(conn->state != CPUWORKER_STATE_IDLE) {
-      /* the circ associated with this cpuworker will have to wait until
-       * it gets culled in run_connection_housekeeping(), since we have
-       * no way to find out which circ it was. */
-      log_fn(LOG_WARN,"...and it left a circuit queued; abandoning circ.");
-      num_cpuworkers_busy--;
-    }
-    num_cpuworkers--;
-    spawn_enough_cpuworkers(); /* try to regrow. hope we don't end up spinning. */
-    connection_mark_for_close(conn);
-    return 0;
-  }
-
   if(conn->state == CPUWORKER_STATE_BUSY_ONION) {
     if(buf_datalen(conn->inbuf) < LEN_ONION_RESPONSE) /* entire answer available? */
       return 0; /* not yet */

Index: directory.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/directory.c,v
retrieving revision 1.168
retrieving revision 1.169
diff -u -d -r1.168 -r1.169
--- directory.c	15 Nov 2004 04:04:20 -0000	1.168
+++ directory.c	21 Nov 2004 10:14:57 -0000	1.169
@@ -683,11 +683,24 @@
   return 0;
 }
 
+int connection_dir_reached_eof(connection_t *conn) {
+  int retval;
+  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);
+    return -1;
+  }
+
+  retval = connection_dir_client_reached_eof(conn);
+  connection_mark_for_close(conn);
+  return retval;
+}
+
 /** Read handler for directory connections.  (That's connections <em>to</em>
  * directory servers and connections <em>at</em> directory servers.)
  */
 int connection_dir_process_inbuf(connection_t *conn) {
-  int retval;
 
   tor_assert(conn);
   tor_assert(conn->type == CONN_TYPE_DIR);
@@ -697,18 +710,6 @@
    * write their response (when it's finished flushing, they mark for
    * close).
    */
-  if(conn->inbuf_reached_eof) {
-    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);
-      return -1;
-    }
-
-    retval = connection_dir_client_reached_eof(conn);
-    connection_mark_for_close(conn);
-    return retval;
-  } /* endif 'reached eof' */
 
   /* If we're on the dirserver side, look for a command. */
   if(conn->state == DIR_CONN_STATE_SERVER_COMMAND_WAIT) {

Index: dns.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/dns.c,v
retrieving revision 1.119
retrieving revision 1.120
diff -u -d -r1.119 -r1.120
--- dns.c	12 Nov 2004 16:39:02 -0000	1.119
+++ dns.c	21 Nov 2004 10:14:57 -0000	1.120
@@ -559,8 +559,18 @@
   return 0;
 }
 
-/** Read handler: called when we get data from a dnsworker.  If the
- * connection is closed, mark the dnsworker as dead.  Otherwise, see
+int connection_dns_reached_eof(connection_t *conn) {
+  log_fn(LOG_WARN,"Read eof. Worker died unexpectedly.");
+  if(conn->state == DNSWORKER_STATE_BUSY) {
+    dns_cancel_pending_resolve(conn->address);
+    num_dnsworkers_busy--;
+  }
+  num_dnsworkers--;
+  connection_mark_for_close(conn);
+  return 0;
+}
+
+/** Read handler: called when we get data from a dnsworker. See
  * if we have a complete answer.  If so, call dns_found_answer on the
  * result.  If not, wait.  Returns 0. */
 int connection_dns_process_inbuf(connection_t *conn) {
@@ -570,17 +580,6 @@
   tor_assert(conn);
   tor_assert(conn->type == CONN_TYPE_DNSWORKER);
 
-  if(conn->inbuf_reached_eof) {
-    log_fn(LOG_WARN,"Read eof. Worker died unexpectedly.");
-    if(conn->state == DNSWORKER_STATE_BUSY) {
-      dns_cancel_pending_resolve(conn->address);
-      num_dnsworkers_busy--;
-    }
-    num_dnsworkers--;
-    connection_mark_for_close(conn);
-    return 0;
-  }
-
   if(conn->state != DNSWORKER_STATE_BUSY) {
     log_fn(LOG_WARN,"Bug: poll() indicated than an idle dns worker was readable. Please report.");
     return 0;

Index: or.h
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.491
retrieving revision 1.492
diff -u -d -r1.491 -r1.492
--- or.h	21 Nov 2004 09:39:01 -0000	1.491
+++ or.h	21 Nov 2004 10:14:57 -0000	1.492
@@ -1196,6 +1196,7 @@
 
 /********************************* connection_edge.c ***************************/
 
+int connection_edge_reached_eof(connection_t *conn);
 int connection_edge_process_inbuf(connection_t *conn, int package_partial);
 int connection_edge_destroy(uint16_t circ_id, connection_t *conn);
 int connection_edge_end(connection_t *conn, char reason, crypt_path_t *cpath_layer);
@@ -1233,6 +1234,7 @@
 
 /********************************* connection_or.c ***************************/
 
+int connection_or_reached_eof(connection_t *conn);
 int connection_or_process_inbuf(connection_t *conn);
 int connection_or_finished_flushing(connection_t *conn);
 int connection_or_finished_connecting(connection_t *conn);
@@ -1272,6 +1274,7 @@
 } or_conn_status_event_t;
 
 int connection_control_finished_flushing(connection_t *conn);
+int connection_control_reached_eof(connection_t *conn);
 int connection_control_process_inbuf(connection_t *conn);
 
 int control_event_circuit_status(circuit_t *circ, circuit_status_event_t e);
@@ -1287,6 +1290,7 @@
 void cpu_init(void);
 void cpuworkers_rotate(void);
 int connection_cpu_finished_flushing(connection_t *conn);
+int connection_cpu_reached_eof(connection_t *conn);
 int connection_cpu_process_inbuf(connection_t *conn);
 int assign_to_cpuworker(connection_t *cpuworker, unsigned char question_type,
                         void *task);
@@ -1297,6 +1301,7 @@
 void directory_post_to_dirservers(uint8_t purpose, const char *payload,
                                   size_t payload_len);
 void directory_get_from_dirserver(uint8_t purpose, const char *resource);
+int connection_dir_reached_eof(connection_t *conn);
 int connection_dir_process_inbuf(connection_t *conn);
 int connection_dir_finished_flushing(connection_t *conn);
 int connection_dir_finished_connecting(connection_t *conn);
@@ -1325,6 +1330,7 @@
 
 void dns_init(void);
 int connection_dns_finished_flushing(connection_t *conn);
+int connection_dns_reached_eof(connection_t *conn);
 int connection_dns_process_inbuf(connection_t *conn);
 void dnsworkers_rotate(void);
 void connection_dns_remove(connection_t *conn);