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

[or-cvs] r8777: Start implementing reason extension for stream events to mat (in tor/trunk: . doc src/or)



Author: nickm
Date: 2006-10-20 13:54:36 -0400 (Fri, 20 Oct 2006)
New Revision: 8777

Modified:
   tor/trunk/
   tor/trunk/doc/control-spec.txt
   tor/trunk/src/or/connection.c
   tor/trunk/src/or/connection_edge.c
   tor/trunk/src/or/control.c
   tor/trunk/src/or/or.h
Log:
 r9303@Kushana:  nickm | 2006-10-20 12:07:34 -0400
 Start implementing reason extension for stream events to match the one one used by circuit events. (Not a complete implementation yet; actual reasons are not passed to control.c)



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

Modified: tor/trunk/doc/control-spec.txt
===================================================================
--- tor/trunk/doc/control-spec.txt	2006-10-20 16:22:53 UTC (rev 8776)
+++ tor/trunk/doc/control-spec.txt	2006-10-20 17:54:36 UTC (rev 8777)
@@ -835,6 +835,7 @@
     The syntax is:
 
       "650" SP "STREAM" SP StreamID SP StreamStatus SP CircID SP Target
+          [SP "REASON=" Reason [ SP "REMOTE_REASON=" Reason ]] CRLF
 
       StreamStatus =
                "NEW"          / ; New request to connect
@@ -851,6 +852,24 @@
   The circuit ID designates which circuit this stream is attached to.  If
   the stream is unattached, the circuit ID "0" is given.
 
+      Reason = "MISC" / "RESOLVEFAILED" / "CONNECTREFUSED" /
+               "EXITPOLICY" / "DESTROY" / "DONE" / "TIMEOUT" /
+               "HIBERNATING" / "INTERNAL"/ "RESOURCELIMIT" /
+               "CONNRESET" / "TORPROTOCOL" / "NOTDIRECTORY" / "END"
+
+   The "REASON" field is provided only for FAILED, CLOSED, and DETACHED
+   events, and only if extended events are enabled (see 3.19).  Clients MUST
+   accept reasons not listed above.  Reasons are as given in tor-spec.txt,
+   except for:
+
+      END          (We received a RELAY_END cell from the other side of thise
+                    stream.)
+
+   The "REMOTE_REASON" field is provided only when we receive a RELAY_END
+   cell, and only if extended events are enabled.  It contains the actual
+   reason given by the remote OR for closing the stream. Clients MUST accept
+   reasons not listed above.  Reasons are as listed in tor-spec.txt.
+
 4.1.3. OR Connection status changed
 
   The syntax is:

Modified: tor/trunk/src/or/connection.c
===================================================================
--- tor/trunk/src/or/connection.c	2006-10-20 16:22:53 UTC (rev 8776)
+++ tor/trunk/src/or/connection.c	2006-10-20 17:54:36 UTC (rev 8777)
@@ -458,9 +458,9 @@
         log_warn(LD_BUG,"Bug: Closing stream (marked at %s:%d) without sending"
                  " back a socks reply.",
                  conn->marked_for_close_file, conn->marked_for_close);
-      } else {
-        control_event_stream_status(edge_conn, STREAM_EVENT_CLOSED);
       }
+      control_event_stream_status(edge_conn, STREAM_EVENT_CLOSED,
+                                  END_STREAM_REASON_FIXME_XXXX);
       break;
     case CONN_TYPE_EXIT:
       edge_conn = TO_EDGE_CONN(conn);

Modified: tor/trunk/src/or/connection_edge.c
===================================================================
--- tor/trunk/src/or/connection_edge.c	2006-10-20 16:22:53 UTC (rev 8776)
+++ tor/trunk/src/or/connection_edge.c	2006-10-20 17:54:36 UTC (rev 8777)
@@ -498,7 +498,8 @@
 int
 connection_ap_detach_retriable(edge_connection_t *conn, origin_circuit_t *circ)
 {
-  control_event_stream_status(conn, STREAM_EVENT_FAILED_RETRIABLE);
+  control_event_stream_status(conn, STREAM_EVENT_FAILED_RETRIABLE,
+                              END_STREAM_REASON_FIXME_XXXX);
   conn->_base.timestamp_lastread = time(NULL);
   if (! get_options()->LeaveStreamsUnattached) {
     conn->_base.state = AP_CONN_STATE_CIRCUIT_WAIT;
@@ -1436,9 +1437,9 @@
   } /* else socks handshake is done, continue processing */
 
   if (socks->command == SOCKS_COMMAND_CONNECT)
-    control_event_stream_status(conn, STREAM_EVENT_NEW);
+    control_event_stream_status(conn, STREAM_EVENT_NEW, 0);
   else
-    control_event_stream_status(conn, STREAM_EVENT_NEW_RESOLVE);
+    control_event_stream_status(conn, STREAM_EVENT_NEW_RESOLVE, 0);
 
   if (options->LeaveStreamsUnattached) {
     conn->_base.state = AP_CONN_STATE_CONTROLLER_WAIT;
@@ -1480,7 +1481,7 @@
   }
   /* we have the original destination */
 
-  control_event_stream_status(conn, STREAM_EVENT_NEW);
+  control_event_stream_status(conn, STREAM_EVENT_NEW, 0);
 
   if (options->LeaveStreamsUnattached) {
     conn->_base.state = AP_CONN_STATE_CONTROLLER_WAIT;
@@ -1557,7 +1558,7 @@
   ap_conn->_base.state = AP_CONN_STATE_CONNECT_WAIT;
   log_info(LD_APP,"Address/port sent, ap socket %d, n_circ_id %d",
            ap_conn->_base.s, circ->_base.n_circ_id);
-  control_event_stream_status(ap_conn, STREAM_EVENT_SENT_CONNECT);
+  control_event_stream_status(ap_conn, STREAM_EVENT_SENT_CONNECT, 0);
   return 0;
 }
 
@@ -1623,7 +1624,7 @@
   ap_conn->_base.state = AP_CONN_STATE_RESOLVE_WAIT;
   log_info(LD_APP,"Address sent for resolve, ap socket %d, n_circ_id %d",
            ap_conn->_base.s, circ->_base.n_circ_id);
-  control_event_stream_status(ap_conn, STREAM_EVENT_SENT_RESOLVE);
+  control_event_stream_status(ap_conn, STREAM_EVENT_SENT_RESOLVE, 0);
   return 0;
 }
 
@@ -1781,7 +1782,8 @@
   tor_assert(conn->socks_request); /* make sure it's an AP stream */
 
   control_event_stream_status(conn,
-     status==SOCKS5_SUCCEEDED ? STREAM_EVENT_SUCCEEDED : STREAM_EVENT_FAILED);
+     status==SOCKS5_SUCCEEDED ? STREAM_EVENT_SUCCEEDED : STREAM_EVENT_FAILED,
+                              END_STREAM_REASON_FIXME_XXXX);
 
   if (conn->socks_request->has_finished) {
     log_warn(LD_BUG, "Harmless bug: duplicate calls to "

Modified: tor/trunk/src/or/control.c
===================================================================
--- tor/trunk/src/or/control.c	2006-10-20 16:22:53 UTC (rev 8776)
+++ tor/trunk/src/or/control.c	2006-10-20 17:54:36 UTC (rev 8777)
@@ -2946,10 +2946,34 @@
   return 0;
 }
 
+/* DOCDOC */
+static const char *
+stream_end_reason_to_string(int reason)
+{
+  reason &= ~END_CIRC_REASON_FLAG_REMOTE;
+  switch (reason) {
+    case END_STREAM_REASON_MISC: return "MISC";
+    case END_STREAM_REASON_RESOLVEFAILED: return "RESOLVEFAILED";
+    case END_STREAM_REASON_CONNECTREFUSED: return "CONNECTREFUSED";
+    case END_STREAM_REASON_EXITPOLICY: return "EXITPOLICY";
+    case END_STREAM_REASON_DESTROY: return "DESTROY";
+    case END_STREAM_REASON_DONE: return "DONE";
+    case END_STREAM_REASON_TIMEOUT: return "TIMEOUT";
+    case END_STREAM_REASON_HIBERNATING: return "HIBERNATING";
+    case END_STREAM_REASON_INTERNAL: return "INTERNAL";
+    case END_STREAM_REASON_RESOURCELIMIT: return "RESOURCELIMIT";
+    case END_STREAM_REASON_CONNRESET: return "CONNRESET";
+    case END_STREAM_REASON_TORPROTOCOL: return "TORPROTOCOL";
+    case END_STREAM_REASON_NOTDIRECTORY: return "NOTDIRECTORY";
+    default: return NULL;
+  }
+}
+
 /** Something has happened to the stream associated with AP connection
  * <b>conn</b>: tell any interested control connections. */
 int
-control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp)
+control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp,
+                            int reason_code)
 {
   char *msg;
   size_t len;
@@ -2971,9 +2995,11 @@
     tor_free(msg);
   }
   if (EVENT_IS_INTERESTING1(EVENT_STREAM_STATUS)) {
+    char reason_buf[64];
     const char *status;
     circuit_t *circ;
     origin_circuit_t *origin_circ = NULL;
+    reason_buf[0] = '\0';
     switch (tp)
       {
       case STREAM_EVENT_SENT_CONNECT: status = "SENTCONNECT"; break;
@@ -2988,15 +3014,33 @@
         log_warn(LD_BUG, "Unrecognized status code %d", (int)tp);
         return 0;
       }
+    if (reason_code && (tp == STREAM_EVENT_FAILED ||
+                        tp == STREAM_EVENT_CLOSED ||
+                        tp == STREAM_EVENT_FAILED_RETRIABLE)) {
+      const char *reason_str = stream_end_reason_to_string(reason_code);
+      char *r = NULL;
+      if (!reason_str) {
+        r = tor_malloc(16);
+        tor_snprintf(r, 16, "UNKNOWN_%d", reason_code);
+        reason_str = r;
+      }
+      if (reason_code & END_STREAM_REASON_FLAG_REMOTE)
+        tor_snprintf(reason_buf, sizeof(reason_buf),
+                     "REASON=END REMOTE_REASON=%s", reason_str);
+      else
+        tor_snprintf(reason_buf, sizeof(reason_buf),
+                     "REASON=%s", reason_str);
+      tor_free(r);
+    }
     circ = circuit_get_by_edge_conn(conn);
     if (circ && CIRCUIT_IS_ORIGIN(circ))
       origin_circ = TO_ORIGIN_CIRCUIT(circ);
-    send_control1_event(EVENT_STREAM_STATUS, ALL_NAMES,
-                        "650 STREAM %lu %s %lu %s\r\n",
+    send_control1_event_extended(EVENT_STREAM_STATUS, ALL_NAMES,
+                        "650 STREAM %lu %s %lu %s@%s\r\n",
                         (unsigned long)conn->global_identifier, status,
                         origin_circ?
                            (unsigned long)origin_circ->global_identifier : 0ul,
-                        buf);
+                        buf, reason_buf);
     /* XXX need to specify its intended exit, etc? */
   }
   return 0;

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2006-10-20 16:22:53 UTC (rev 8776)
+++ tor/trunk/src/or/or.h	2006-10-20 17:54:36 UTC (rev 8777)
@@ -464,6 +464,10 @@
 #define RELAY_COMMAND_RENDEZVOUS_ESTABLISHED 39
 #define RELAY_COMMAND_INTRODUCE_ACK 40
 
+/* XXXX Placeholder: remove me as soon as we have correct reasons sent
+ * everywhere. */
+#define END_STREAM_REASON_FIXME_XXXX 0
+
 #define END_STREAM_REASON_MISC 1
 #define END_STREAM_REASON_RESOLVEFAILED 2
 #define END_STREAM_REASON_CONNECTREFUSED 3
@@ -479,6 +483,10 @@
 #define END_STREAM_REASON_TORPROTOCOL 13
 #define END_STREAM_REASON_NOTDIRECTORY 14
 
+/* OR this with the argument to control_event_stream_status to indicate that
+ * the reason came from an END cell. */
+#define END_STREAM_REASON_FLAG_REMOTE     512
+
 /* These high-numbered end reasons are not part of the official spec,
  * and are not intended to be put in relay end cells. They are here
  * to be more informative when sending back socks replies to the
@@ -2089,7 +2097,8 @@
 int control_event_circuit_status(origin_circuit_t *circ,
                                  circuit_status_event_t e, int reason);
 int control_event_stream_status(edge_connection_t *conn,
-                                stream_status_event_t e);
+                                stream_status_event_t e,
+                                int reason);
 int control_event_or_conn_status(or_connection_t *conn,
                                  or_conn_status_event_t e);
 int control_event_bandwidth_used(uint32_t n_read, uint32_t n_written);