[or-cvs] make end relay cells have payloads

Roger Dingledine arma at seul.org
Wed Oct 22 07:55:46 UTC 2003


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

Modified Files:
	config.c connection.c connection_edge.c dns.c or.h 
Log Message:
make end relay cells have payloads
move default exit policy into config files


Index: config.c
===================================================================
RCS file: /home/or/cvsroot/src/or/config.c,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -d -r1.62 -r1.63
--- config.c	22 Oct 2003 06:03:11 -0000	1.62
+++ config.c	22 Oct 2003 07:55:44 -0000	1.63
@@ -163,7 +163,7 @@
     config_compare(list, "SocksBindAddress",CONFIG_TYPE_STRING,&options->SocksBindAddress) ||
     config_compare(list, "ORBindAddress",  CONFIG_TYPE_STRING, &options->ORBindAddress) ||
     config_compare(list, "User",           CONFIG_TYPE_STRING, &options->User) ||
-    config_compare(list, "Group",           CONFIG_TYPE_STRING, &options->Group) ||
+    config_compare(list, "Group",          CONFIG_TYPE_STRING, &options->Group) ||
 
     /* int options */
     config_compare(list, "MaxConn",         CONFIG_TYPE_INT, &options->MaxConn) ||
@@ -210,13 +210,17 @@
   tor_free(options->Address);
   tor_free(options->PidFile);
   tor_free(options->ExitPolicy);
+  tor_free(options->SocksBindAddress);
+  tor_free(options->ORBindAddress);
+  tor_free(options->User);
+  tor_free(options->Group);
 }
 
 void init_options(or_options_t *options) {
 /* give reasonable values for each option. Defaults to zero. */
   memset(options,0,sizeof(or_options_t));
   options->LogLevel = tor_strdup("info");
-  options->ExitPolicy = tor_strdup("reject 127.0.0.1:*,reject 18.244.0.188:25,accept *:*");
+  options->ExitPolicy = tor_strdup("reject 127.0.0.1:*");
   options->SocksBindAddress = tor_strdup("127.0.0.1");
   options->ORBindAddress = tor_strdup("0.0.0.0");
   options->loglevel = LOG_INFO;

Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection.c,v
retrieving revision 1.124
retrieving revision 1.125
diff -u -d -r1.124 -r1.125
--- connection.c	21 Oct 2003 09:48:17 -0000	1.124
+++ connection.c	22 Oct 2003 07:55:44 -0000	1.125
@@ -642,7 +642,7 @@
 
   if(!connection_speaks_cells(conn)) {
      log_fn(LOG_INFO,"Aci %d: At an edge. Marking connection for close.", aci);
-     connection_edge_end(conn, NULL, 0, conn->cpath_layer);
+     connection_edge_end(conn, END_STREAM_REASON_DESTROY, conn->cpath_layer);
      /* if they already sent a destroy, they know. XXX can just close? */
      return 0;
   }

Index: connection_edge.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_edge.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- connection_edge.c	21 Oct 2003 08:37:07 -0000	1.42
+++ connection_edge.c	22 Oct 2003 07:55:44 -0000	1.43
@@ -27,7 +27,7 @@
     conn->done_receiving = 1;
     shutdown(conn->s, 0); /* XXX check return, refactor NM */
     if (conn->done_sending) {
-      connection_edge_end(conn, NULL, 0, conn->cpath_layer);
+      connection_edge_end(conn, END_STREAM_REASON_DONE, conn->cpath_layer);
     } else {
       connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_END,
                                    NULL, 0, conn->cpath_layer);
@@ -36,7 +36,7 @@
 #else 
     /* eof reached, kill it. */
     log_fn(LOG_INFO,"conn (fd %d) reached eof. Closing.", conn->s);
-    connection_edge_end(conn, NULL, 0, conn->cpath_layer);
+    connection_edge_end(conn, END_STREAM_REASON_DONE, conn->cpath_layer);
     return -1;
 #endif
   }
@@ -44,14 +44,14 @@
   switch(conn->state) {
     case AP_CONN_STATE_SOCKS_WAIT:
       if(connection_ap_handshake_process_socks(conn) < 0) {
-        connection_edge_end(conn, NULL, 0, conn->cpath_layer);
+        connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
         return -1;
       }
       return 0;
     case AP_CONN_STATE_OPEN:
     case EXIT_CONN_STATE_OPEN:
       if(connection_edge_package_raw_inbuf(conn) < 0) {
-        connection_edge_end(conn, NULL, 0, conn->cpath_layer);
+        connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
         return -1;
       }
       return 0;
@@ -63,15 +63,45 @@
   return 0;
 }
 
-void connection_edge_end(connection_t *conn, void *payload, int payload_len,
-                         crypt_path_t *cpath_layer) {
-  circuit_t *circ = circuit_get_by_conn(conn);
+char *connection_edge_end_reason(char *payload, unsigned char length) {
+  if(length < 1) {
+    log_fn(LOG_WARN,"End cell arrived with length 0. Should be at least 1.");
+    return "MALFORMED";
+  }
+  if(*payload < END_STREAM_REASON_MISC || *payload > END_STREAM_REASON_DONE) {
+    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_EXITPOLICY:     return "exit policy failed";
+    case END_STREAM_REASON_DESTROY:        return "destroyed";
+    case END_STREAM_REASON_DONE:           return "closed normally";
+  }
+  assert(0);
+  return "";
+}
+
+void connection_edge_end(connection_t *conn, char reason, crypt_path_t *cpath_layer) {
+  char payload[5];
+  int payload_len=1;
+  circuit_t *circ;
 
   if(conn->has_sent_end) {
     log_fn(LOG_WARN,"It appears I've already sent the end. Are you calling me twice?");
     return;
   }
 
+  payload[0] = reason;
+  if(reason == END_STREAM_REASON_EXITPOLICY) {
+    *(uint32_t *)(payload+1) = htonl(conn->addr);
+    *(uint16_t *)(payload+5) = htons(conn->port);
+    payload_len += 6;
+  }
+
+  circ = circuit_get_by_conn(conn);
   if(circ) {
     log_fn(LOG_DEBUG,"Marking conn (fd %d) and sending end.",conn->s);
     connection_edge_send_command(conn, circ, RELAY_COMMAND_END,
@@ -145,16 +175,18 @@
 
   if(conn && conn->state != AP_CONN_STATE_OPEN && conn->state != EXIT_CONN_STATE_OPEN) {
     if(conn->type == CONN_TYPE_EXIT && relay_command == RELAY_COMMAND_END) {
-      log_fn(LOG_INFO,"Exit got end before we're connected. Marking for close.");
-      conn->marked_for_close = 1;
+      log_fn(LOG_INFO,"Exit got end (%s) before we're connected. Marking for close.",
+        connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, cell->length));
       if(conn->state == EXIT_CONN_STATE_RESOLVING) {
         log_fn(LOG_INFO,"...and informing resolver we don't want the answer anymore.");
         dns_cancel_pending_resolve(conn->address, conn);
       }
+      conn->marked_for_close = 1;
+      conn->has_sent_end = 1;
       return 0;
     } else {
       log_fn(LOG_WARN,"Got an unexpected relay cell, not in 'open' state. Closing.");
-      connection_edge_end(conn, NULL, 0, conn->cpath_layer);
+      connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
       return -1;
     }
   }
@@ -175,7 +207,7 @@
       if((edge_type == EDGE_AP && --layer_hint->deliver_window < 0) ||
          (edge_type == EDGE_EXIT && --circ->deliver_window < 0)) {
         log_fn(LOG_WARN,"(relay data) circ deliver_window below 0. Killing.");
-        connection_edge_end(conn, NULL, 0, conn->cpath_layer);
+        connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
         return -1;
       }
       log_fn(LOG_DEBUG,"circ deliver_window now %d.", edge_type == EDGE_AP ? layer_hint->deliver_window : circ->deliver_window);
@@ -203,10 +235,24 @@
       return 0;
     case RELAY_COMMAND_END:
       if(!conn) {
-        log_fn(LOG_INFO,"end cell dropped, unknown stream %d.",*(int*)conn->stream_id);
+        log_fn(LOG_INFO,"end cell (%s) dropped, unknown stream %d.",
+          connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, cell->length),
+          *(int*)conn->stream_id);
         return 0;
       }
-      log_fn(LOG_INFO,"end cell for stream %d. Removing stream.",*(int*)conn->stream_id);
+      log_fn(LOG_INFO,"end cell (%s) for stream %d. Removing stream.",
+        connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, cell->length),
+        *(int*)conn->stream_id);
+      if(cell->length && *(cell->payload+RELAY_HEADER_SIZE) ==
+                           END_STREAM_REASON_EXITPOLICY) {
+        /* No need to close the connection. We'll hold it open while
+         * we try a new exit node.
+         * cell->payload+RELAY_HEADER_SIZE+1 holds the addr and then
+         * port of the destination. Which is good, because we've
+         * forgotten it.
+         */
+        /* XXX */
+      }
 
 #ifdef HALF_OPEN
       conn->done_sending = 1;
@@ -268,7 +314,7 @@
       log_fn(LOG_INFO,"Connected! Notifying application.");
       if(connection_ap_handshake_socks_reply(conn, NULL, 0, 1) < 0) {
         log_fn(LOG_INFO,"Writing to socks-speaking application failed. Closing.");
-        connection_edge_end(conn, NULL, 0, conn->cpath_layer);
+        connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
       }
       break;
     case RELAY_COMMAND_SENDME:
@@ -612,30 +658,28 @@
   /* send it off to the gethostbyname farm */
   switch(dns_resolve(n_stream)) {
     case 1: /* resolve worked */
-      if(connection_exit_connect(n_stream) >= 0)
-        return 0;
-      /* else fall through */
+      connection_exit_connect(n_stream);
+      return 0;
     case -1: /* resolve failed */
-      log_fn(LOG_WARN,"Resolve or connect failed (%s).", n_stream->address);
-      connection_edge_end(n_stream, NULL, 0, NULL);
-      connection_remove(n_stream);
-      connection_free(n_stream);
-    case 0: /* resolve added to pending list */
-      ;
+      log_fn(LOG_WARN,"Resolve failed (%s).", n_stream->address);
+      connection_edge_end(n_stream, END_STREAM_REASON_RESOLVEFAILED, NULL);
+    /* case 0, resolve added to pending list */
   }
   return 0;
 }
 
-int connection_exit_connect(connection_t *conn) {
+void connection_exit_connect(connection_t *conn) {
 
   if(router_compare_to_exit_policy(conn) < 0) {
     log_fn(LOG_INFO,"%s:%d failed exit policy. Closing.", conn->address, conn->port);
-    return -1;
+    connection_edge_end(conn, END_STREAM_REASON_EXITPOLICY, NULL);
+    return;
   }
 
   switch(connection_connect(conn, conn->address, conn->addr, conn->port)) {
     case -1:
-      return -1;
+      connection_edge_end(conn, END_STREAM_REASON_CONNECTFAILED, NULL);
+      return;
     case 0:
       connection_set_poll_socket(conn);
       conn->state = EXIT_CONN_STATE_CONNECTING;
@@ -643,7 +687,7 @@
       connection_watch_events(conn, POLLOUT | POLLIN | POLLERR);
       /* writable indicates finish, readable indicates broken link,
          error indicates broken link in windowsland. */
-      return 0;
+      return;
     /* case 1: fall through */
   }
 
@@ -659,7 +703,6 @@
   /* also, deliver a 'connected' cell back through the circuit. */
   connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_CONNECTED,
                                NULL, 0, conn->cpath_layer);
-  return 0;
 }
 
 /*

Index: dns.c
===================================================================
RCS file: /home/or/cvsroot/src/or/dns.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- dns.c	21 Oct 2003 08:37:07 -0000	1.35
+++ dns.c	22 Oct 2003 07:55:44 -0000	1.36
@@ -220,7 +220,7 @@
     /* mark all pending connections to fail */
     while(resolve->pending_connections) {
       pend = resolve->pending_connections;
-      connection_edge_end(pend->conn, NULL, 0, NULL);
+      connection_edge_end(pend->conn, END_STREAM_REASON_MISC, NULL);
       resolve->pending_connections = pend->next;
       free(pend);
     }
@@ -272,9 +272,10 @@
   while(resolve->pending_connections) {
     pend = resolve->pending_connections;
     pend->conn->addr = resolve->answer;
-    if(resolve->state == CACHE_STATE_FAILED || connection_exit_connect(pend->conn) < 0) {
-      connection_edge_end(pend->conn, NULL, 0, NULL);
-    }
+    if(resolve->state == CACHE_STATE_FAILED)
+      connection_edge_end(pend->conn, END_STREAM_REASON_RESOLVEFAILED, NULL);
+    else
+      connection_exit_connect(pend->conn);
     resolve->pending_connections = pend->next;
     free(pend);
   }

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.171
retrieving revision 1.172
diff -u -d -r1.171 -r1.172
--- or.h	22 Oct 2003 06:03:11 -0000	1.171
+++ or.h	22 Oct 2003 07:55:44 -0000	1.172
@@ -192,6 +192,13 @@
 
 #define RELAY_HEADER_SIZE 8
 
+#define END_STREAM_REASON_MISC 1
+#define END_STREAM_REASON_RESOLVEFAILED 2
+#define END_STREAM_REASON_CONNECTFAILED 3
+#define END_STREAM_REASON_EXITPOLICY 4
+#define END_STREAM_REASON_DESTROY 5
+#define END_STREAM_REASON_DONE 6
+
 /* default cipher function */
 #define DEFAULT_CIPHER CRYPTO_CIPHER_AES_CTR
 /* Used to en/decrypt onion skins */
@@ -226,16 +233,6 @@
 /* legal characters in a nickname */
 #define LEGAL_NICKNAME_CHARACTERS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
 
-/* structure of a socks client operation */
-typedef struct {
-   unsigned char version;     /* socks version number */
-   unsigned char command;     /* command code */
-   uint16_t destport; /* destination port, host order */
-   uint32_t destip;   /* destination address, host order */
-   /* userid follows, terminated by a \0 */
-   /* dest host follows, terminated by a \0 */
-} socks4_t;
-
 #define SOCKS4_NETWORK_LEN 8
 
 typedef uint16_t aci_t;
@@ -593,8 +590,7 @@
 /********************************* connection_edge.c ***************************/
 
 int connection_edge_process_inbuf(connection_t *conn);
-void connection_edge_end(connection_t *conn, void *payload, int payload_len,
-                         crypt_path_t *cpath_layer);
+void connection_edge_end(connection_t *conn, char reason, crypt_path_t *cpath_layer);
 
 void connection_edge_send_command(connection_t *fromconn, circuit_t *circ, int relay_command,
                                   void *payload, int payload_len, crypt_path_t *cpath_layer);
@@ -605,7 +601,7 @@
 
 int connection_edge_package_raw_inbuf(connection_t *conn);
 
-int connection_exit_connect(connection_t *conn);
+void connection_exit_connect(connection_t *conn);
 
 extern uint64_t stats_n_data_cells_packaged;
 extern uint64_t stats_n_data_bytes_packaged;



More information about the tor-commits mailing list