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

[or-cvs] r15116: start sending "bootstrap problem" status events when we're h (in tor/trunk: doc/spec src/or)



Author: arma
Date: 2008-06-10 21:14:23 -0400 (Tue, 10 Jun 2008)
New Revision: 15116

Modified:
   tor/trunk/doc/spec/control-spec.txt
   tor/trunk/src/or/connection.c
   tor/trunk/src/or/connection_edge.c
   tor/trunk/src/or/connection_or.c
   tor/trunk/src/or/directory.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/reasons.c
Log:
start sending "bootstrap problem" status events when we're having troubles
reaching relays.


Modified: tor/trunk/doc/spec/control-spec.txt
===================================================================
--- tor/trunk/doc/spec/control-spec.txt	2008-06-11 00:17:02 UTC (rev 15115)
+++ tor/trunk/doc/spec/control-spec.txt	2008-06-11 01:14:23 UTC (rev 15116)
@@ -1070,7 +1070,7 @@
 
       Reason = "MISC" / "DONE" / "CONNECTREFUSED" /
                "IDENTITY" / "CONNECTRESET" / "TIMEOUT" / "NOROUTE" /
-               "IOERROR"
+               "IOERROR" / "RESOURCELIMIT"
 
   NumCircuits counts both established and pending circuits.
 

Modified: tor/trunk/src/or/connection.c
===================================================================
--- tor/trunk/src/or/connection.c	2008-06-11 00:17:02 UTC (rev 15115)
+++ tor/trunk/src/or/connection.c	2008-06-11 01:14:23 UTC (rev 15116)
@@ -500,14 +500,18 @@
           if (!get_options()->HttpsProxy)
             router_set_status(or_conn->identity_digest, 0);
           if (conn->state == OR_CONN_STATE_CONNECTING) {
-            control_event_or_conn_status(or_conn, OR_CONN_EVENT_FAILED, 0);
+            control_event_or_conn_status(or_conn, OR_CONN_EVENT_FAILED,
+              errno_to_orconn_end_reason(or_conn->socket_error));
             control_event_bootstrap_problem(
-              tor_socket_strerror(or_conn->socket_error), 0);
+              tor_socket_strerror(or_conn->socket_error),
+              errno_to_orconn_end_reason(or_conn->socket_error));
           } else {
             int reason = tls_error_to_orconn_end_reason(or_conn->tls_error);
             control_event_or_conn_status(or_conn, OR_CONN_EVENT_FAILED,
                                          reason);
-            control_event_bootstrap_problem("foo", reason);
+            /* XXX021 come up with a better string for the first arg */
+            control_event_bootstrap_problem(
+              orconn_end_reason_to_control_string(reason), reason);
           }
         }
         /* Inform any pending (not attached) circs that they should
@@ -1097,8 +1101,9 @@
 }
 
 /** Take conn, make a nonblocking socket; try to connect to
- * addr:port (they arrive in *host order*). If fail, return -1. Else
- * assign s to conn-\>s: if connected return 1, if EAGAIN return 0.
+ * addr:port (they arrive in *host order*). If fail, return -1 and if
+ * applicable put your best guess about errno into *<b>socket_error</b>.
+ * Else assign s to conn-\>s: if connected return 1, if EAGAIN return 0.
  *
  * address is used to make the logs useful.
  *
@@ -1106,7 +1111,7 @@
  */
 int
 connection_connect(connection_t *conn, const char *address,
-                   uint32_t addr, uint16_t port)
+                   uint32_t addr, uint16_t port, int *socket_error)
 {
   int s, inprogress = 0;
   struct sockaddr_in dest_addr;
@@ -1123,8 +1128,9 @@
 
   s = tor_open_socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
   if (s < 0) {
+    *socket_error = tor_socket_errno(-1);
     log_warn(LD_NET,"Error creating network socket: %s",
-             tor_socket_strerror(tor_socket_errno(-1)));
+             tor_socket_strerror(*socket_error));
     return -1;
   }
 
@@ -1140,8 +1146,9 @@
     } else {
       if (bind(s, (struct sockaddr*)&ext_addr,
                (socklen_t)sizeof(ext_addr)) < 0) {
+        *socket_error = tor_socket_errno(s);
         log_warn(LD_NET,"Error binding network socket: %s",
-                 tor_socket_strerror(tor_socket_errno(s)));
+                 tor_socket_strerror(*socket_error));
         tor_close_socket(s);
         return -1;
       }
@@ -1165,6 +1172,7 @@
     int e = tor_socket_errno(s);
     if (!ERRNO_IS_CONN_EINPROGRESS(e)) {
       /* yuck. kill it. */
+      *socket_error = e;
       log_info(LD_NET,
                "connect() to %s:%u failed: %s",escaped_safe_str(address),
                port, tor_socket_strerror(e));

Modified: tor/trunk/src/or/connection_edge.c
===================================================================
--- tor/trunk/src/or/connection_edge.c	2008-06-11 00:17:02 UTC (rev 15115)
+++ tor/trunk/src/or/connection_edge.c	2008-06-11 01:14:23 UTC (rev 15116)
@@ -236,7 +236,7 @@
 {
   uint8_t reason;
   tor_assert(conn);
-  reason = (uint8_t)errno_to_stream_end_reason(tor_socket_errno(conn->_base.s));
+  reason = errno_to_stream_end_reason(tor_socket_errno(conn->_base.s));
   return connection_edge_end(conn, reason);
 }
 
@@ -2609,6 +2609,7 @@
   uint32_t addr;
   uint16_t port;
   connection_t *conn = TO_CONN(edge_conn);
+  int socket_error = 0;
 
   if (!connection_edge_is_rendezvous_stream(edge_conn) &&
       router_compare_to_my_exit_policy(edge_conn)) {
@@ -2644,8 +2645,10 @@
   }
 
   log_debug(LD_EXIT,"about to try connecting");
-  switch (connection_connect(conn, conn->address, addr, port)) {
+  switch (connection_connect(conn, conn->address, addr, port, &socket_error)) {
     case -1:
+      /* XXX021 use socket_error below rather than trying to piece things
+       * together from the current errno, which may have been clobbered. */
       connection_edge_end_errno(edge_conn);
       circuit_detach_stream(circuit_get_by_edge_conn(edge_conn), edge_conn);
       connection_free(conn);

Modified: tor/trunk/src/or/connection_or.c
===================================================================
--- tor/trunk/src/or/connection_or.c	2008-06-11 00:17:02 UTC (rev 15115)
+++ tor/trunk/src/or/connection_or.c	2008-06-11 01:14:23 UTC (rev 15116)
@@ -513,6 +513,7 @@
 {
   or_connection_t *conn;
   or_options_t *options = get_options();
+  int socket_error = 0;
 
   tor_assert(id_digest);
 
@@ -534,7 +535,8 @@
     port = options->HttpsProxyPort;
   }
 
-  switch (connection_connect(TO_CONN(conn), conn->_base.address, addr, port)) {
+  switch (connection_connect(TO_CONN(conn), conn->_base.address,
+                             addr, port, &socket_error)) {
     case -1:
       /* If the connection failed immediately, and we're using
        * an https proxy, our https proxy is down. Don't blame the
@@ -545,9 +547,9 @@
         router_set_status(conn->identity_digest, 0);
       }
       control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED,
-              END_OR_CONN_REASON_TCP_REFUSED);
-      /* XXX connection_connect() can fail for all sorts of other reasons */
-      control_event_bootstrap_problem("foo", END_OR_CONN_REASON_TCP_REFUSED);
+                                   errno_to_orconn_end_reason(socket_error));
+      control_event_bootstrap_problem(tor_socket_strerror(socket_error),
+                                   errno_to_orconn_end_reason(socket_error));
       connection_free(TO_CONN(conn));
       return NULL;
     case 0:

Modified: tor/trunk/src/or/directory.c
===================================================================
--- tor/trunk/src/or/directory.c	2008-06-11 00:17:02 UTC (rev 15115)
+++ tor/trunk/src/or/directory.c	2008-06-11 01:14:23 UTC (rev 15116)
@@ -659,6 +659,7 @@
 {
   dir_connection_t *conn;
   or_options_t *options = get_options();
+  int socket_error = 0;
   int use_begindir = supports_begindir &&
                      directory_command_should_use_begindir(options, addr,
                        or_port, router_purpose, anonymized_connection);
@@ -699,7 +700,7 @@
     }
 
     switch (connection_connect(TO_CONN(conn), conn->_base.address, addr,
-                               dir_port)) {
+                               dir_port, &socket_error)) {
       case -1:
         connection_dir_request_failed(conn); /* retry if we want */
         /* XXX we only pass 'conn' above, not 'resource', 'payload',

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2008-06-11 00:17:02 UTC (rev 15115)
+++ tor/trunk/src/or/or.h	2008-06-11 01:14:23 UTC (rev 15116)
@@ -501,14 +501,15 @@
 #define RELAY_COMMAND_INTRODUCE_ACK 40
 
 /* Reasons why an OR connection is closed */
-#define END_OR_CONN_REASON_DONE 1
-#define END_OR_CONN_REASON_TCP_REFUSED  2
-#define END_OR_CONN_REASON_OR_IDENTITY  3
-#define END_OR_CONN_REASON_TLS_CONNRESET 4 /* tls connection reset by peer */
-#define END_OR_CONN_REASON_TLS_TIMEOUT  5
-#define END_OR_CONN_REASON_TLS_NO_ROUTE  6 /* no route to host/net */
-#define END_OR_CONN_REASON_TLS_IO_ERROR  7 /* tls read/write error */
-#define END_OR_CONN_REASON_TLS_MISC  8
+#define END_OR_CONN_REASON_DONE           1
+#define END_OR_CONN_REASON_REFUSED        2 /* connection refused */
+#define END_OR_CONN_REASON_OR_IDENTITY    3
+#define END_OR_CONN_REASON_CONNRESET      4 /* connection reset by peer */
+#define END_OR_CONN_REASON_TIMEOUT        5
+#define END_OR_CONN_REASON_NO_ROUTE       6 /* no route to host/net */
+#define END_OR_CONN_REASON_IO_ERROR       7 /* read/write error */
+#define END_OR_CONN_REASON_RESOURCE_LIMIT 8 /* sockets, buffers, etc */
+#define END_OR_CONN_REASON_MISC           9
 
 /* Reasons why we (or a remote OR) might close a stream. See tor-spec.txt for
  * documentation of these. */
@@ -2742,7 +2743,7 @@
 void connection_expire_held_open(void);
 
 int connection_connect(connection_t *conn, const char *address, uint32_t addr,
-                       uint16_t port);
+                       uint16_t port, int *socket_error);
 int retry_all_listeners(smartlist_t *replaced_conns,
                         smartlist_t *new_conns);
 
@@ -3589,10 +3590,11 @@
 const char *stream_end_reason_to_control_string(int reason);
 const char *stream_end_reason_to_string(int reason);
 socks5_reply_status_t stream_end_reason_to_socks5_response(int reason);
-int errno_to_stream_end_reason(int e);
+uint8_t errno_to_stream_end_reason(int e);
 
 const char *orconn_end_reason_to_control_string(int r);
 int tls_error_to_orconn_end_reason(int e);
+int errno_to_orconn_end_reason(int e);
 
 const char *circuit_end_reason_to_control_string(int reason);
 

Modified: tor/trunk/src/or/reasons.c
===================================================================
--- tor/trunk/src/or/reasons.c	2008-06-11 00:17:02 UTC (rev 15115)
+++ tor/trunk/src/or/reasons.c	2008-06-11 01:14:23 UTC (rev 15116)
@@ -144,9 +144,8 @@
 #endif
 
 /** Given an errno from a failed exit connection, return a reason code
- * appropriate for use in a RELAY END cell.
- */
-int
+ * appropriate for use in a RELAY END cell. */
+uint8_t
 errno_to_stream_end_reason(int e)
 {
   switch (e) {
@@ -192,19 +191,21 @@
   switch (r) {
     case END_OR_CONN_REASON_DONE:
       return "DONE";
-    case END_OR_CONN_REASON_TCP_REFUSED:
+    case END_OR_CONN_REASON_REFUSED:
       return "CONNECTREFUSED";
     case END_OR_CONN_REASON_OR_IDENTITY:
       return "IDENTITY";
-    case END_OR_CONN_REASON_TLS_CONNRESET:
+    case END_OR_CONN_REASON_CONNRESET:
       return "CONNECTRESET";
-    case END_OR_CONN_REASON_TLS_TIMEOUT:
+    case END_OR_CONN_REASON_TIMEOUT:
       return "TIMEOUT";
-    case END_OR_CONN_REASON_TLS_NO_ROUTE:
+    case END_OR_CONN_REASON_NO_ROUTE:
       return "NOROUTE";
-    case END_OR_CONN_REASON_TLS_IO_ERROR:
+    case END_OR_CONN_REASON_IO_ERROR:
       return "IOERROR";
-    case END_OR_CONN_REASON_TLS_MISC:
+    case END_OR_CONN_REASON_RESOURCE_LIMIT:
+      return "RESOURCELIMIT";
+    case END_OR_CONN_REASON_MISC:
       return "MISC";
     case 0:
       return "";
@@ -220,25 +221,62 @@
 {
   switch (e) {
     case TOR_TLS_ERROR_IO:
-      return END_OR_CONN_REASON_TLS_IO_ERROR;
+      return END_OR_CONN_REASON_IO_ERROR;
     case TOR_TLS_ERROR_CONNREFUSED:
-      return END_OR_CONN_REASON_TCP_REFUSED;
+      return END_OR_CONN_REASON_REFUSED;
     case TOR_TLS_ERROR_CONNRESET:
-      return END_OR_CONN_REASON_TLS_CONNRESET;
+      return END_OR_CONN_REASON_CONNRESET;
     case TOR_TLS_ERROR_NO_ROUTE:
-      return END_OR_CONN_REASON_TLS_NO_ROUTE;
+      return END_OR_CONN_REASON_NO_ROUTE;
     case TOR_TLS_ERROR_TIMEOUT:
-      return END_OR_CONN_REASON_TLS_TIMEOUT;
+      return END_OR_CONN_REASON_TIMEOUT;
     case TOR_TLS_WANTREAD:
     case TOR_TLS_WANTWRITE:
     case TOR_TLS_CLOSE:
     case TOR_TLS_DONE:
       return END_OR_CONN_REASON_DONE;
     default:
-      return END_OR_CONN_REASON_TLS_MISC;
+      return END_OR_CONN_REASON_MISC;
   }
 }
 
+/** Given an errno from a failed ORConn connection, return a reason code
+ * appropriate for use in the controller orconn events. */
+/* XXX021 somebody should think about whether the assignments I've made
+ * are accurate or useful. -RD */
+int
+errno_to_orconn_end_reason(int e)
+{
+  switch (e) {
+    case EPIPE:
+      return END_OR_CONN_REASON_DONE;
+    S_CASE(ENOTCONN):
+    S_CASE(ENETUNREACH):
+    case ENETDOWN: /* << somebody should look into the Windows equiv */
+    case EHOSTUNREACH:
+      return END_OR_CONN_REASON_NO_ROUTE;
+    S_CASE(ECONNREFUSED):
+      return END_OR_CONN_REASON_REFUSED;
+    S_CASE(ECONNRESET):
+      return END_OR_CONN_REASON_CONNRESET;
+    S_CASE(ETIMEDOUT):
+      return END_OR_CONN_REASON_TIMEOUT;
+    S_CASE(ENOBUFS):
+    case ENOMEM:
+    case ENFILE:
+    E_CASE(EMFILE):
+    E_CASE(EACCES):
+    E_CASE(EBADF):
+    E_CASE(EFAULT):
+    E_CASE(EINVAL):
+      return END_OR_CONN_REASON_RESOURCE_LIMIT;
+    default:
+      log_info(LD_OR, "Didn't recognize errno %d (%s).",
+               e, tor_socket_strerror(e));
+      return END_OR_CONN_REASON_MISC;
+  }
+}
+
 /***************************** Circuit reasons *****************************/
 
 /** Convert a numeric reason for destroying a circuit into a string for a