[or-cvs] r9354: Patch from Mike Perry: Track reasons for OR connection failu (in tor/trunk: . doc src/common src/or)

nickm at seul.org nickm at seul.org
Mon Jan 15 21:13:41 UTC 2007


Author: nickm
Date: 2007-01-15 16:13:37 -0500 (Mon, 15 Jan 2007)
New Revision: 9354

Modified:
   tor/trunk/
   tor/trunk/doc/control-spec.txt
   tor/trunk/src/common/tortls.c
   tor/trunk/src/common/tortls.h
   tor/trunk/src/or/buffers.c
   tor/trunk/src/or/circuitbuild.c
   tor/trunk/src/or/connection.c
   tor/trunk/src/or/connection_or.c
   tor/trunk/src/or/control.c
   tor/trunk/src/or/or.h
Log:
 r11957 at Kushana:  nickm | 2007-01-15 15:25:57 -0500
 Patch from Mike Perry: Track reasons for OR connection failure; display them in control events. Needs review and revision.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r11957] on c95137ef-5f19-0410-b913-86e773d04f59

Modified: tor/trunk/doc/control-spec.txt
===================================================================
--- tor/trunk/doc/control-spec.txt	2007-01-15 19:34:33 UTC (rev 9353)
+++ tor/trunk/doc/control-spec.txt	2007-01-15 21:13:37 UTC (rev 9354)
@@ -885,7 +885,8 @@
 4.1.3. OR Connection status changed
 
   The syntax is:
-    "650" SP "ORCONN" SP (ServerID / Target) SP ORStatus
+    "650" SP "ORCONN" SP (ServerID / Target) SP ORStatus [ SP "REASON=" 
+             Reason ] [ SP "NCIRCS=" NumCircuits ]
 
     ORStatus = "NEW" / "LAUNCHED" / "CONNECTED" / "FAILED" / "CLOSED"
 
@@ -898,6 +899,17 @@
   A ServerID is specified unless it's a NEW connection, in which
   case we don't know what server it is yet, so we use Address:Port.
 
+  If extended events are enabled (see 3.19), optional reason and
+  circuit counting information is provided for CLOSED and FAILED
+  events. 
+
+      Reason = "MISC" / "DONE" / "CONNECTREFUSED" /
+               "IDENTITY" / "CONNECTRESET" / "TIMEOUT" / "NOROUTE" /
+               "IOERROR" 
+
+  NumCircuits counts both established and pending circuits.
+
+
 4.1.4. Bandwidth used in the last second
 
   The syntax is:

Modified: tor/trunk/src/common/tortls.c
===================================================================
--- tor/trunk/src/common/tortls.c	2007-01-15 19:34:33 UTC (rev 9353)
+++ tor/trunk/src/common/tortls.c	2007-01-15 21:13:37 UTC (rev 9354)
@@ -73,8 +73,8 @@
 static int tls_library_is_initialized = 0;
 
 /* Module-internal error codes. */
-#define _TOR_TLS_SYSCALL    -6
-#define _TOR_TLS_ZERORETURN -5
+#define _TOR_TLS_SYSCALL    -10
+#define _TOR_TLS_ZERORETURN -9
 
 /* These functions are declared in crypto.c but not exported. */
 EVP_PKEY *_crypto_pk_env_get_evp_pkey(crypto_pk_env_t *env, int private);
@@ -103,6 +103,39 @@
   }
 }
 
+static int
+tor_errno_to_tls_error(int e) {
+#if defined(MS_WINDOWS) && !defined(USE_BSOCKETS)
+  switch(e) {
+    case WSAECONNRESET: // most common
+      return TOR_TLS_ERROR_CONNRESET;
+    case WSAETIMEDOUT:
+      return TOR_TLS_ERROR_TIMEOUT;
+    case WSAENETUNREACH:
+    case WSAEHOSTUNREACH:
+      return TOR_TLS_ERROR_NO_ROUTE;
+    case WSAECONNREFUSED:
+      return TOR_TLS_ERROR_CONNREFUSED; // least common
+    default:
+      return TOR_TLS_ERROR_MISC;
+  }
+#else 
+  switch(e) {
+    case ECONNRESET: // most common
+      return TOR_TLS_ERROR_CONNRESET;
+    case ETIMEDOUT:
+      return TOR_TLS_ERROR_TIMEOUT;
+    case EHOSTUNREACH:
+    case ENETUNREACH:
+      return TOR_TLS_ERROR_NO_ROUTE;
+    case ECONNREFUSED:
+      return TOR_TLS_ERROR_CONNREFUSED; // least common
+    default:
+      return TOR_TLS_ERROR_MISC;
+  }
+#endif
+}
+
 #define CATCH_SYSCALL 1
 #define CATCH_ZERO    2
 
@@ -121,6 +154,7 @@
                   const char *doing, int severity)
 {
   int err = SSL_get_error(tls->ssl, r);
+  int tor_error = TOR_TLS_ERROR_MISC;
   switch (err) {
     case SSL_ERROR_NONE:
       return TOR_TLS_DONE;
@@ -131,25 +165,27 @@
     case SSL_ERROR_SYSCALL:
       if (extra&CATCH_SYSCALL)
         return _TOR_TLS_SYSCALL;
-      if (r == 0)
+      if (r == 0) {
         log(severity, LD_NET, "TLS error: unexpected close while %s", doing);
-      else {
+        tor_error = TOR_TLS_ERROR_IO;
+      } else {
         int e = tor_socket_errno(tls->socket);
         log(severity, LD_NET,
             "TLS error: <syscall error while %s> (errno=%d: %s)",
             doing, e, tor_socket_strerror(e));
+        tor_error = tor_errno_to_tls_error(e);
       }
       tls_log_errors(severity, doing);
-      return TOR_TLS_ERROR;
+      return tor_error;
     case SSL_ERROR_ZERO_RETURN:
       if (extra&CATCH_ZERO)
         return _TOR_TLS_ZERORETURN;
       log(severity, LD_NET, "TLS error: Zero return");
       tls_log_errors(severity, doing);
-      return TOR_TLS_ERROR;
+      return TOR_TLS_ERROR_MISC;
     default:
       tls_log_errors(severity, doing);
-      return TOR_TLS_ERROR;
+      return TOR_TLS_ERROR_MISC;
   }
 }
 
@@ -547,7 +583,7 @@
   if (ERR_peek_error() != 0) {
     tls_log_errors(tls->isServer ? LOG_INFO : LOG_WARN,
                    "handshaking");
-    return TOR_TLS_ERROR;
+    return TOR_TLS_ERROR_MISC;
   }
   if (r == TOR_TLS_DONE) {
     tls->state = TOR_TLS_ST_OPEN;
@@ -607,7 +643,7 @@
          tls->state == TOR_TLS_ST_SENTCLOSE) {
         log(LOG_WARN, LD_NET,
             "TLS returned \"half-closed\" value while already half-closed");
-        return TOR_TLS_ERROR;
+        return TOR_TLS_ERROR_MISC;
       }
       tls->state = TOR_TLS_ST_SENTCLOSE;
       /* fall through ... */

Modified: tor/trunk/src/common/tortls.h
===================================================================
--- tor/trunk/src/common/tortls.h	2007-01-15 19:34:33 UTC (rev 9353)
+++ tor/trunk/src/common/tortls.h	2007-01-15 21:13:37 UTC (rev 9354)
@@ -19,11 +19,16 @@
 typedef struct tor_tls_t tor_tls_t;
 
 /* Possible return values for most tor_tls_* functions. */
-#define TOR_TLS_ERROR       -4
-#define TOR_TLS_CLOSE       -3
-#define TOR_TLS_WANTREAD    -2
-#define TOR_TLS_WANTWRITE   -1
-#define TOR_TLS_DONE         0
+#define TOR_TLS_ERROR_MISC         -9
+#define TOR_TLS_ERROR_IO           -8
+#define TOR_TLS_ERROR_CONNREFUSED  -7
+#define TOR_TLS_ERROR_CONNRESET    -6
+#define TOR_TLS_ERROR_NO_ROUTE     -5
+#define TOR_TLS_ERROR_TIMEOUT      -4
+#define TOR_TLS_CLOSE              -3
+#define TOR_TLS_WANTREAD           -2
+#define TOR_TLS_WANTWRITE          -1
+#define TOR_TLS_DONE                0
 
 void tor_tls_free_all(void);
 int tor_tls_context_new(crypto_pk_env_t *rsa,

Modified: tor/trunk/src/or/buffers.c
===================================================================
--- tor/trunk/src/or/buffers.c	2007-01-15 19:34:33 UTC (rev 9353)
+++ tor/trunk/src/or/buffers.c	2007-01-15 21:13:37 UTC (rev 9354)
@@ -543,7 +543,7 @@
             (int)at_most);
 
   if (buf_ensure_capacity(buf, at_most+buf->datalen))
-    return TOR_TLS_ERROR;
+    return TOR_TLS_ERROR_MISC;
 
   if (at_most + buf->datalen > buf->len)
     at_most = buf->len - buf->datalen;

Modified: tor/trunk/src/or/circuitbuild.c
===================================================================
--- tor/trunk/src/or/circuitbuild.c	2007-01-15 19:34:33 UTC (rev 9353)
+++ tor/trunk/src/or/circuitbuild.c	2007-01-15 21:13:37 UTC (rev 9354)
@@ -897,7 +897,8 @@
    *     means that a connection broke or an extend failed. For now,
    *     just give up.
    */
-  circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_OR_CONN_CLOSED);
+  circuit_mark_for_close(TO_CIRCUIT(circ), 
+          END_CIRC_REASON_FLAG_REMOTE|END_CIRC_REASON_OR_CONN_CLOSED);
   return 0;
 
 #if 0

Modified: tor/trunk/src/or/connection.c
===================================================================
--- tor/trunk/src/or/connection.c	2007-01-15 19:34:33 UTC (rev 9353)
+++ tor/trunk/src/or/connection.c	2007-01-15 21:13:37 UTC (rev 9354)
@@ -435,7 +435,8 @@
           rep_hist_note_connect_failed(or_conn->identity_digest, now);
           entry_guard_register_connect_status(or_conn->identity_digest,0,now);
           router_set_status(or_conn->identity_digest, 0);
-          control_event_or_conn_status(or_conn, OR_CONN_EVENT_FAILED);
+          control_event_or_conn_status(or_conn, OR_CONN_EVENT_FAILED, 
+                  control_tls_error_to_reason(or_conn->tls_error));
         }
         /* Inform any pending (not attached) circs that they should
          * give up. */
@@ -444,10 +445,12 @@
         /* We only set hold_open_until_flushed when we're intentionally
          * closing a connection. */
         rep_hist_note_disconnect(or_conn->identity_digest, now);
-        control_event_or_conn_status(or_conn, OR_CONN_EVENT_CLOSED);
+        control_event_or_conn_status(or_conn, OR_CONN_EVENT_CLOSED,
+                control_tls_error_to_reason(or_conn->tls_error));
       } else if (or_conn->identity_digest) {
         rep_hist_note_connection_died(or_conn->identity_digest, now);
-        control_event_or_conn_status(or_conn, OR_CONN_EVENT_CLOSED);
+        control_event_or_conn_status(or_conn, OR_CONN_EVENT_CLOSED,
+                control_tls_error_to_reason(or_conn->tls_error));
       }
       /* Now close all the attached circuits on it. */
       circuit_unlink_all_from_or_conn(TO_OR_CONN(conn),
@@ -824,7 +827,7 @@
 
   switch (conn->type) {
     case CONN_TYPE_OR:
-      control_event_or_conn_status(TO_OR_CONN(conn), OR_CONN_EVENT_NEW);
+      control_event_or_conn_status(TO_OR_CONN(conn), OR_CONN_EVENT_NEW, 0);
       return connection_tls_start_handshake(TO_OR_CONN(conn), 1);
     case CONN_TYPE_AP:
       switch (listener_type) {
@@ -1457,6 +1460,7 @@
 
     /* else open, or closing */
     result = read_to_buf_tls(or_conn->tls, at_most, conn->inbuf);
+    or_conn->tls_error = result;
 
     switch (result) {
       case TOR_TLS_CLOSE:
@@ -1464,12 +1468,17 @@
                  "(Nickname %s, address %s",
                  or_conn->nickname ? or_conn->nickname : "not set",
                  conn->address);
-        return -1;
-      case TOR_TLS_ERROR:
+        return result;
+      case TOR_TLS_ERROR_IO:
+      case TOR_TLS_ERROR_CONNREFUSED:
+      case TOR_TLS_ERROR_CONNRESET:
+      case TOR_TLS_ERROR_NO_ROUTE:
+      case TOR_TLS_ERROR_TIMEOUT:
+      case TOR_TLS_ERROR_MISC:
         log_info(LD_NET,"tls error. breaking (nickname %s, address %s).",
                  or_conn->nickname ? or_conn->nickname : "not set",
                  conn->address);
-        return -1;
+        return result;
       case TOR_TLS_WANTWRITE:
         connection_start_writing(conn);
         return 0;
@@ -1662,9 +1671,14 @@
     result = flush_buf_tls(or_conn->tls, conn->outbuf,
                            max_to_write, &conn->outbuf_flushlen);
     switch (result) {
-      case TOR_TLS_ERROR:
+      case TOR_TLS_ERROR_IO:
+      case TOR_TLS_ERROR_CONNREFUSED:
+      case TOR_TLS_ERROR_CONNRESET:
+      case TOR_TLS_ERROR_NO_ROUTE:
+      case TOR_TLS_ERROR_TIMEOUT:
+      case TOR_TLS_ERROR_MISC:
       case TOR_TLS_CLOSE:
-        log_info(LD_NET,result==TOR_TLS_ERROR?
+        log_info(LD_NET,result!=TOR_TLS_CLOSE?
                  "tls error. breaking.":"TLS connection closed on flush");
         /* Don't flush; connection is dead. */
         connection_close_immediate(conn);

Modified: tor/trunk/src/or/connection_or.c
===================================================================
--- tor/trunk/src/or/connection_or.c	2007-01-15 19:34:33 UTC (rev 9353)
+++ tor/trunk/src/or/connection_or.c	2007-01-15 21:13:37 UTC (rev 9354)
@@ -435,7 +435,7 @@
   /* set up conn so it's got all the data we need to remember */
   connection_or_init_conn_from_address(conn, addr, port, id_digest, 1);
   conn->_base.state = OR_CONN_STATE_CONNECTING;
-  control_event_or_conn_status(conn, OR_CONN_EVENT_LAUNCHED);
+  control_event_or_conn_status(conn, OR_CONN_EVENT_LAUNCHED, 0);
 
   if (options->HttpsProxy) {
     /* we shouldn't connect directly. use the https proxy instead. */
@@ -453,7 +453,8 @@
                                             time(NULL));
         router_set_status(conn->identity_digest, 0);
       }
-      control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED);
+      control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED, 
+              END_OR_CONN_REASON_TCP_REFUSED);
       connection_free(TO_CONN(conn));
       return NULL;
     case 0:
@@ -508,7 +509,12 @@
 {
   check_no_tls_errors();
   switch (tor_tls_handshake(conn->tls)) {
-    case TOR_TLS_ERROR:
+    case TOR_TLS_ERROR_IO:
+    case TOR_TLS_ERROR_CONNREFUSED:
+    case TOR_TLS_ERROR_CONNRESET:
+    case TOR_TLS_ERROR_NO_ROUTE:
+    case TOR_TLS_ERROR_TIMEOUT:
+    case TOR_TLS_ERROR_MISC:
     case TOR_TLS_CLOSE:
       log_info(LD_OR,"tls error. breaking connection.");
       return -1;
@@ -628,7 +634,8 @@
              conn->_base.address, conn->_base.port, expected, seen);
       entry_guard_register_connect_status(conn->identity_digest,0,time(NULL));
       router_set_status(conn->identity_digest, 0);
-      control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED);
+      control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED,
+              END_OR_CONN_REASON_OR_IDENTITY);
       as_advertised = 0;
     }
     if (authdir_mode(options)) {
@@ -672,7 +679,7 @@
 
   directory_set_dirty();
   conn->_base.state = OR_CONN_STATE_OPEN;
-  control_event_or_conn_status(conn, OR_CONN_EVENT_CONNECTED);
+  control_event_or_conn_status(conn, OR_CONN_EVENT_CONNECTED, 0);
   if (started_here) {
     rep_hist_note_connect_succeeded(conn->identity_digest, time(NULL));
     if (entry_guard_register_connect_status(conn->identity_digest, 1,
@@ -791,3 +798,31 @@
   return 0;
 }
 
+/** Count number of pending circs on an or_conn */
+int 
+connection_or_count_pending_circs(or_connection_t *or_conn)
+{
+  extern smartlist_t *circuits_pending_or_conns;
+  int cnt = 0;
+
+  if (!circuits_pending_or_conns)
+    return 0;
+
+  SMARTLIST_FOREACH(circuits_pending_or_conns, circuit_t *, circ,
+  {
+    if (circ->marked_for_close)
+      continue;
+    tor_assert(circ->state == CIRCUIT_STATE_OR_WAIT);
+    if (!circ->n_conn &&
+        !memcmp(or_conn->identity_digest, circ->n_conn_id_digest,
+                DIGEST_LEN)) {
+      cnt++;
+    }
+  });
+
+  log_debug(LD_CIRC,"or_conn to %s, %d pending circs",
+            or_conn->nickname ? or_conn->nickname : "NULL", cnt);
+  return cnt;
+}
+
+

Modified: tor/trunk/src/or/control.c
===================================================================
--- tor/trunk/src/or/control.c	2007-01-15 19:34:33 UTC (rev 9353)
+++ tor/trunk/src/or/control.c	2007-01-15 21:13:37 UTC (rev 9354)
@@ -3247,13 +3247,65 @@
   }
 }
 
+int
+control_tls_error_to_reason(int e) {
+  switch(e) {
+    case TOR_TLS_ERROR_IO:
+      return END_OR_CONN_REASON_TLS_IO_ERROR;
+    case TOR_TLS_ERROR_CONNREFUSED:
+      return END_OR_CONN_REASON_TCP_REFUSED;
+    case TOR_TLS_ERROR_CONNRESET:
+      return END_OR_CONN_REASON_TLS_CONNRESET;
+    case TOR_TLS_ERROR_NO_ROUTE:
+      return END_OR_CONN_REASON_TLS_NO_ROUTE;
+    case TOR_TLS_ERROR_TIMEOUT:
+      return END_OR_CONN_REASON_TLS_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;
+  }
+}
+
+const char *
+or_conn_end_reason_to_string(int r) {
+  switch(r) {
+    case END_OR_CONN_REASON_DONE:
+      return "REASON=DONE";
+    case END_OR_CONN_REASON_TCP_REFUSED:
+      return "REASON=CONNECTREFUSED";
+    case END_OR_CONN_REASON_OR_IDENTITY:
+      return "REASON=IDENTITY";
+    case END_OR_CONN_REASON_TLS_CONNRESET:
+      return "REASON=CONNECTRESET";
+    case END_OR_CONN_REASON_TLS_TIMEOUT:
+      return "REASON=TIMEOUT";
+    case END_OR_CONN_REASON_TLS_NO_ROUTE:
+      return "REASON=NOROUTE";
+    case END_OR_CONN_REASON_TLS_IO_ERROR:
+      return "REASON=IOERROR";
+    case END_OR_CONN_REASON_TLS_MISC:
+      return "REASON=MISC";
+    case 0:
+      return "";
+    default:
+      log_warn(LD_BUG, "Unrecognized or_conn reason code %d", r);
+      return "REASON=BOGUS";
+  }
+}
+
 /** Something has happened to the OR connection <b>conn</b>: tell any
  * interested control connections. */
 int
-control_event_or_conn_status(or_connection_t *conn,or_conn_status_event_t tp)
+control_event_or_conn_status(or_connection_t *conn,or_conn_status_event_t tp, 
+        int reason)
 {
   char buf[HEX_DIGEST_LEN+3]; /* status, dollar, identity, NUL */
   size_t len;
+  int ncircs = 0;
 
   if (!EVENT_IS_INTERESTING(EVENT_OR_CONN_STATUS))
     return 0;
@@ -3267,6 +3319,7 @@
   if (EVENT_IS_INTERESTING1(EVENT_OR_CONN_STATUS)) {
     const char *status;
     char name[128];
+    char ncircs_buf[32] = {0}; /* > 8 + log10(2^32)=10 + 2 */
     switch (tp)
       {
       case OR_CONN_EVENT_LAUNCHED: status = "LAUNCHED"; break;
@@ -3278,17 +3331,26 @@
         log_warn(LD_BUG, "Unrecognized status code %d", (int)tp);
         return 0;
       }
+    ncircs = connection_or_count_pending_circs(conn);
+    ncircs += conn->n_circuits;
+    if(ncircs && (tp == OR_CONN_EVENT_FAILED || tp == OR_CONN_EVENT_CLOSED)) {
+        tor_snprintf(ncircs_buf, sizeof(ncircs_buf), "%sNCIRCS=%d", 
+                reason ? " " : "", ncircs);
+    }
+
     if (EVENT_IS_INTERESTING1S(EVENT_OR_CONN_STATUS)) {
       orconn_target_get_name(0, name, sizeof(name), conn);
-      send_control1_event(EVENT_OR_CONN_STATUS, SHORT_NAMES,
-                          "650 ORCONN %s %s\r\n",
-                          name, status);
+      send_control1_event_extended(EVENT_OR_CONN_STATUS, SHORT_NAMES,
+                          "650 ORCONN %s %s@%s%s\r\n",
+                          name, status,
+                          or_conn_end_reason_to_string(reason), ncircs_buf);
     }
     if (EVENT_IS_INTERESTING1L(EVENT_OR_CONN_STATUS)) {
       orconn_target_get_name(1, name, sizeof(name), conn);
-      send_control1_event(EVENT_OR_CONN_STATUS, LONG_NAMES,
-                          "650 ORCONN %s %s\r\n",
-                          name, status);
+      send_control1_event_extended(EVENT_OR_CONN_STATUS, LONG_NAMES,
+                          "650 ORCONN %s %s@%s%s\r\n",
+                          name, status,
+                          or_conn_end_reason_to_string(reason), ncircs_buf);
     }
   }
   return 0;

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-01-15 19:34:33 UTC (rev 9353)
+++ tor/trunk/src/or/or.h	2007-01-15 21:13:37 UTC (rev 9354)
@@ -476,6 +476,16 @@
 #define RELAY_COMMAND_RENDEZVOUS_ESTABLISHED 39
 #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
+
 /* Reasons why we (or a remote OR) might close a stream. See tor-spec.txt for
  * documentation of these. */
 #define END_STREAM_REASON_MISC 1
@@ -723,6 +733,7 @@
   char *nickname; /**< Nickname of OR on other side (if any). */
 
   tor_tls_t *tls; /**< TLS connection state */
+  int tls_error; /**< Last tor_tls error code */
 
   time_t timestamp_lastempty; /**< When was the outbuf last completely empty?*/
 
@@ -837,7 +848,7 @@
 } control_connection_t;
 
 /** Cast a connection_t subtype pointer to a connection_t **/
-#define TO_CONN(c) &(((c)->_base))
+#define TO_CONN(c) (&(((c)->_base)))
 /** Helper macro: Given a pointer to to._base, of type from*, return &to. */
 #define DOWNCAST(to, ptr) \
   (to*) (((char*)(ptr)) - STRUCT_OFFSET(to, _base))
@@ -2150,6 +2161,7 @@
                                      or_connection_t *conn);
 int connection_or_send_destroy(uint16_t circ_id, or_connection_t *conn,
                                int reason);
+int connection_or_count_pending_circs(or_connection_t *or_conn);
 
 /********************************* control.c ***************************/
 
@@ -2216,8 +2228,9 @@
 int control_event_stream_status(edge_connection_t *conn,
                                 stream_status_event_t e,
                                 int reason);
+int control_tls_error_to_reason(int e);
 int control_event_or_conn_status(or_connection_t *conn,
-                                 or_conn_status_event_t e);
+                                 or_conn_status_event_t e, int reason);
 int control_event_bandwidth_used(uint32_t n_read, uint32_t n_written);
 void control_event_logmsg(int severity, unsigned int domain, const char *msg);
 int control_event_descriptors_changed(smartlist_t *routers);



More information about the tor-commits mailing list