[or-cvs] Forward-port new reasons; clean up code more; add code to c...

Nick Mathewson nickm at seul.org
Tue Mar 1 22:16:19 UTC 2005


Update of /home/or/cvsroot/tor/src/or
In directory moria.mit.edu:/tmp/cvs-serv20853/src/or

Modified Files:
	buffers.c connection.c connection_edge.c or.h relay.c 
Log Message:
Forward-port new reasons; clean up code more; add code to convert new reasons to SOCKS5 reply codes; add code to convert errnos to reasons.  New code still needs to get invoked.

Index: buffers.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/buffers.c,v
retrieving revision 1.126
retrieving revision 1.127
diff -u -d -r1.126 -r1.127
--- buffers.c	22 Feb 2005 08:18:34 -0000	1.126
+++ buffers.c	1 Mar 2005 22:16:15 -0000	1.127
@@ -472,7 +472,7 @@
         if (!nummethods || !memchr(buf->mem+2, 0, nummethods)) {
           log_fn(LOG_WARN,"socks5: offered methods don't include 'no auth'. Rejecting.");
           req->replylen = 2; /* 2 bytes of response */
-          req->reply[0] = 5; /* socks5 reply */
+          req->reply[0] = 5;
           req->reply[1] = '\xFF'; /* reject all methods */
           return -1;
         }
@@ -480,7 +480,7 @@
 
         req->replylen = 2; /* 2 bytes of response */
         req->reply[0] = 5; /* socks5 reply */
-        req->reply[1] = 0; /* choose the 'no auth' method */
+        req->reply[1] = SOCKS5_SUCCEEDED;
         req->socks_version = 5; /* remember that we've already negotiated auth */
         log_fn(LOG_DEBUG,"socks5: accepted method 0");
         return 0;

Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/connection.c,v
retrieving revision 1.333
retrieving revision 1.334
diff -u -d -r1.333 -r1.334
--- connection.c	1 Mar 2005 01:15:01 -0000	1.333
+++ connection.c	1 Mar 2005 22:16:15 -0000	1.334
@@ -914,7 +914,7 @@
     connection_close_immediate(conn); /* Don't flush; connection is dead. */
     if (CONN_IS_EDGE(conn)) {
       connection_edge_end(conn, (char)(connection_state_is_open(conn) ?
-                  END_STREAM_REASON_MISC : END_STREAM_REASON_CONNECTFAILED),
+                  END_STREAM_REASON_MISC : END_STREAM_REASON_CONNECTREFUSED),
                   conn->cpath_layer);
     }
     connection_mark_for_close(conn);
@@ -1092,7 +1092,7 @@
       if (!ERRNO_IS_CONN_EINPROGRESS(e)) {
         log_fn(LOG_INFO,"in-progress connect failed. Removing.");
         if (CONN_IS_EDGE(conn))
-          connection_edge_end(conn, END_STREAM_REASON_CONNECTFAILED,
+          connection_edge_end(conn, END_STREAM_REASON_CONNECTREFUSED,
                               conn->cpath_layer);
 
         connection_close_immediate(conn);

Index: connection_edge.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/connection_edge.c,v
retrieving revision 1.285
retrieving revision 1.286
diff -u -d -r1.285 -r1.286
--- connection_edge.c	24 Feb 2005 11:44:08 -0000	1.285
+++ connection_edge.c	1 Mar 2005 22:16:15 -0000	1.286
@@ -875,21 +875,21 @@
     /* SOCKS5 */
     buf[0] = 0x05; /* version */
     if (answer_type == RESOLVED_TYPE_IPV4 && answer_len == 4) {
-      buf[1] = 0; /* succeeded */
+      buf[1] = SOCKS5_SUCCEEDED;
       buf[2] = 0; /* reserved */
       buf[3] = 0x01; /* IPv4 address type */
       memcpy(buf+4, answer, 4); /* address */
       set_uint16(buf+8, 0); /* port == 0. */
       replylen = 10;
     } else if (answer_type == RESOLVED_TYPE_IPV6 && answer_len == 16) {
-      buf[1] = 0; /* succeeded */
+      buf[1] = SOCKS5_SUCCEEDED;
       buf[2] = 0; /* reserved */
       buf[3] = 0x04; /* IPv6 address type */
       memcpy(buf+4, answer, 16); /* address */
       set_uint16(buf+20, 0); /* port == 0. */
       replylen = 22;
     } else {
-      buf[1] = 0x04; /* host unreachable */
+      buf[1] = SOCKS5_HOST_UNREACHABLE;
       memset(buf+2, 0, 8);
       replylen = 10;
     }
@@ -1156,7 +1156,8 @@
   log_fn(LOG_DEBUG,"about to try connecting");
   switch (connection_connect(conn, conn->address, addr, port)) {
     case -1:
-      connection_edge_end(conn, END_STREAM_REASON_CONNECTFAILED, conn->cpath_layer);
+      connection_edge_end(conn, END_STREAM_REASON_CONNECTREFUSED,
+                          conn->cpath_layer);
       circuit_detach_stream(circuit_get_by_conn(conn), conn);
       connection_free(conn);
       return;

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.545
retrieving revision 1.546
diff -u -d -r1.545 -r1.546
--- or.h	1 Mar 2005 01:15:00 -0000	1.545
+++ or.h	1 Mar 2005 22:16:15 -0000	1.546
@@ -413,16 +413,18 @@
 #define RELAY_COMMAND_RENDEZVOUS_ESTABLISHED 39
 #define RELAY_COMMAND_INTRODUCE_ACK 40
 
-#define _MIN_END_STREAM_REASON 1
 #define END_STREAM_REASON_MISC 1
 #define END_STREAM_REASON_RESOLVEFAILED 2
-#define END_STREAM_REASON_CONNECTFAILED 3
+#define END_STREAM_REASON_CONNECTREFUSED 3
 #define END_STREAM_REASON_EXITPOLICY 4
 #define END_STREAM_REASON_DESTROY 5
 #define END_STREAM_REASON_DONE 6
 #define END_STREAM_REASON_TIMEOUT 7
-#define END_STREAM_REASON_RESOURCELIMIT 8
-#define _MAX_END_STREAM_REASON 8
+/* 8 is unallocated. */
+#define END_STREAM_REASON_HIBERNATING 9
+#define END_STREAM_REASON_INTERNAL 10
+#define END_STREAM_REASON_RESOURCELIMIT 11
+#define END_STREAM_REASON_CONNRESET 12
 
 #define RESOLVED_TYPE_IPV4 4
 #define RESOLVED_TYPE_IPV6 6
@@ -466,6 +468,18 @@
 
 #define SOCKS4_NETWORK_LEN 8
 
+typedef enum {
+  SOCKS5_SUCCEEDED                  = 0x00,
+  SOCKS5_GENERAL_ERROR              = 0x01,
+  SOCKS5_NOT_ALLOWED                = 0x02,
+  SOCKS5_NET_UNREACHABLE            = 0x03,
+  SOCKS5_HOST_UNREACHABLE           = 0x04,
+  SOCKS5_CONNECTION_REFUSED         = 0x05,
+  SOCKS5_TTL_EXPIRED                = 0x06,
+  SOCKS5_COMMAND_NOT_SUPPORTED      = 0x07,
+  SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED = 0x08,
+} socks5_reply_status_t;
+
 /*
  * Relay payload:
  *         Relay command           [1 byte]
@@ -1512,6 +1526,10 @@
                                  size_t payload_len, crypt_path_t *cpath_layer);
 int connection_edge_package_raw_inbuf(connection_t *conn, int package_partial);
 void connection_edge_consider_sending_sendme(connection_t *conn);
+socks5_reply_status_t connection_edge_end_reason_sock5_response(char *payload, uint16_t length);
+int errno_to_end_reasaon(int e);
+
+
 
 extern uint64_t stats_n_data_cells_packaged;
 extern uint64_t stats_n_data_bytes_packaged;

Index: relay.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/relay.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- relay.c	24 Feb 2005 11:44:08 -0000	1.41
+++ relay.c	1 Mar 2005 22:16:15 -0000	1.42
@@ -457,26 +457,105 @@
  * why the stream is closing.
  */
 static const char *
-connection_edge_end_reason(char *payload, uint16_t length) {
+connection_edge_end_reason_str(char *payload, uint16_t length) {
   if (length < 1) {
     log_fn(LOG_WARN,"End cell arrived with length 0. Should be at least 1.");
     return "MALFORMED";
   }
-  if (*payload < _MIN_END_STREAM_REASON || *payload > _MAX_END_STREAM_REASON) {
-    log_fn(LOG_WARN,"Reason for ending (%d) not recognized.",*payload);
-    return "MALFORMED";
-  }
   switch (*payload) {
     case END_STREAM_REASON_MISC:           return "misc error";
     case END_STREAM_REASON_RESOLVEFAILED:  return "resolve failed";
-    case END_STREAM_REASON_CONNECTFAILED:  return "connect failed";
+    case END_STREAM_REASON_CONNECTREFUSED: return "connection refused";
     case END_STREAM_REASON_EXITPOLICY:     return "exit policy failed";
     case END_STREAM_REASON_DESTROY:        return "destroyed";
     case END_STREAM_REASON_DONE:           return "closed normally";
     case END_STREAM_REASON_TIMEOUT:        return "gave up (timeout)";
+    case END_STREAM_REASON_HIBERNATING:    return "server is hibernating";
+    case END_STREAM_REASON_INTERNAL:       return "internal error at server";
+    case END_STREAM_REASON_RESOURCELIMIT:  return "server out of resources";
+    case END_STREAM_REASON_CONNRESET:      return "connection reset";
+    default:
+      log_fn(LOG_WARN,"Reason for ending (%d) not recognized.",*payload);
+      return "unknown";
+  }
+}
+
+socks5_reply_status_t
+connection_edge_end_reason_sock5_response(char *payload, uint16_t length) {
+  if (length < 1) {
+    log_fn(LOG_WARN,"End cell arrived with length 0. Should be at least 1.");
+    return SOCKS5_GENERAL_ERROR;
+  }
+  switch (*payload) {
+    case END_STREAM_REASON_MISC:
+      return SOCKS5_GENERAL_ERROR;
+    case END_STREAM_REASON_RESOLVEFAILED:
+      return SOCKS5_HOST_UNREACHABLE;
+    case END_STREAM_REASON_CONNECTREFUSED:
+      return SOCKS5_CONNECTION_REFUSED;
+    case END_STREAM_REASON_EXITPOLICY:
+      return SOCKS5_CONNECTION_REFUSED;
+    case END_STREAM_REASON_DESTROY:
+      return SOCKS5_GENERAL_ERROR;
+    case END_STREAM_REASON_DONE:
+      return SOCKS5_SUCCEEDED;
+    case END_STREAM_REASON_TIMEOUT:
+      return SOCKS5_TTL_EXPIRED;
+    case END_STREAM_REASON_RESOURCELIMIT:
+      return SOCKS5_GENERAL_ERROR;
+    case END_STREAM_REASON_HIBERNATING:
+      return SOCKS5_GENERAL_ERROR;
+    case END_STREAM_REASON_INTERNAL:
+      return SOCKS5_GENERAL_ERROR;
+    case END_STREAM_REASON_CONNRESET:
+      return SOCKS5_CONNECTION_REFUSED;
+    default:
+      log_fn(LOG_WARN,"Reason for ending (%d) not recognized.",*payload);
+      return SOCKS5_GENERAL_ERROR;
+  }
+}
+
+#ifdef MS_WINDOWS
+#define E_CASE(s) case s: case WSA ## s
+#define W_CASE(s) case s:
+#else
+#define E_CASE(s) case s
+#define W_CASE(s)
+#endif
+
+int
+errno_to_end_reasaon(int e)
+{
+  switch (e) {
+    E_CASE(EPIPE):
+      return END_STREAM_REASON_DONE;
+    E_CASE(EBADF):
+    E_CASE(EFAULT):
+    E_CASE(EINVAL):
+    E_CASE(EISCONN):
+    E_CASE(ENOTSOCK):
+    E_CASE(EPROTONOSUPPORT):
+    E_CASE(EAFNOSUPPORT):
+    E_CASE(EACCES):
+    E_CASE(ENOTCONN):
+    E_CASE(ENETUNREACH):
+      return END_STREAM_REASON_INTERNAL;
+    E_CASE(ECONNREFUSED):
+      return END_STREAM_REASON_CONNECTREFUSED;
+    E_CASE(ECONNRESET):
+      return END_STREAM_REASON_CONNRESET;
+    E_CASE(ETIMEDOUT):
+      return END_STREAM_REASON_TIMEOUT;
+    E_CASE(ENOBUFS):
+    E_CASE(ENOMEM):
+    E_CASE(ENFILE):
+    E_CASE(EMFILE):
+      return END_STREAM_REASON_RESOURCELIMIT;
+    default:
+      log_fn(LOG_INFO, "Didn't recognize errno %d (%s); telling the OP that we are ending a stream for 'misc' reason.",
+             e, tor_socket_strerror(e));
+      return END_STREAM_REASON_MISC;
   }
-  tor_assert(0);
-  return "";
 }
 
 /** How many times will I retry a stream that fails due to DNS
@@ -567,7 +646,8 @@
       }
     }
     log_fn(LOG_INFO,"Edge got end (%s) before we're connected. Marking for close.",
-      connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, rh->length));
+           connection_edge_end_reason_str(cell->payload+RELAY_HEADER_SIZE,
+                                          rh->length));
     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 */
@@ -722,14 +802,16 @@
     case RELAY_COMMAND_END:
       if (!conn) {
         log_fn(LOG_INFO,"end cell (%s) dropped, unknown stream.",
-          connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, rh.length));
+               connection_edge_end_reason_str(cell->payload+RELAY_HEADER_SIZE,
+                                              rh.length));
         return 0;
       }
 /* XXX add to this log_fn the exit node's nickname? */
       log_fn(LOG_INFO,"%d: end cell (%s) for stream %d. Removing stream. Size %d.",
-        conn->s,
-        connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, rh.length),
-        conn->stream_id, (int)conn->stream_size);
+             conn->s,
+             connection_edge_end_reason_str(cell->payload+RELAY_HEADER_SIZE,
+                                            rh.length),
+             conn->stream_id, (int)conn->stream_size);
 
 #ifdef HALF_OPEN
       conn->done_sending = 1;



More information about the tor-commits mailing list