[or-cvs] teach directory servers to handle renddesc responses

Roger Dingledine arma at seul.org
Thu Apr 1 21:32:03 UTC 2004


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

Modified Files:
	directory.c main.c or.h 
Log Message:
teach directory servers to handle renddesc responses


Index: directory.c
===================================================================
RCS file: /home/or/cvsroot/src/or/directory.c,v
retrieving revision 1.78
retrieving revision 1.79
diff -u -d -r1.78 -r1.79
--- directory.c	31 Mar 2004 22:02:13 -0000	1.78
+++ directory.c	1 Apr 2004 21:32:01 -0000	1.79
@@ -24,11 +24,11 @@
 
   if(purpose == DIR_PURPOSE_FETCH_DIR)
     log_fn(LOG_DEBUG,"initiating directory fetch");
-  if(purpose == DIR_PURPOSE_FETCH_HIDSERV)
+  if(purpose == DIR_PURPOSE_FETCH_RENDDESC)
     log_fn(LOG_DEBUG,"initiating hidden-service descriptor fetch");
   if(purpose == DIR_PURPOSE_UPLOAD_DIR)
     log_fn(LOG_DEBUG,"initiating server descriptor upload");
-  if(purpose == DIR_PURPOSE_UPLOAD_HIDSERV)
+  if(purpose == DIR_PURPOSE_UPLOAD_RENDDESC)
     log_fn(LOG_DEBUG,"initiating hidden-service descriptor upload");
 
   if (!router) { /* i guess they didn't have one in mind for me to use */
@@ -111,12 +111,18 @@
                payload_len, payload);
       connection_write_to_buf(tmp, strlen(tmp), conn);
       break;
-    case DIR_PURPOSE_FETCH_HIDSERV:
+    case DIR_PURPOSE_FETCH_RENDDESC:
       assert(payload);
+
+      /* this must be true or we wouldn't be doing the lookup */
+      assert(payload_len <= REND_SERVICE_ID_LEN);
+      memcpy(conn->rend_query, payload, payload_len);
+      conn->rend_query[payload_len] = 0;
+
       snprintf(tmp, sizeof(tmp), "GET /hidserv/%s HTTP/1.0\r\n\r\n", payload);
       connection_write_to_buf(tmp, strlen(tmp), conn);
       break;
-    case DIR_PURPOSE_UPLOAD_HIDSERV:
+    case DIR_PURPOSE_UPLOAD_RENDDESC:
       assert(payload);
       snprintf(tmp, sizeof(tmp),
         "POST /hidserv/ HTTP/1.0\r\nContent-Length: %d\r\n\r\n", payload_len);
@@ -175,9 +181,9 @@
 }
 
 int connection_dir_process_inbuf(connection_t *conn) {
-  char *directory;
+  char *body;
   char *headers;
-  int dir_len=0;
+  int body_len=0;
   int status_code;
 
   assert(conn && conn->type == CONN_TYPE_DIR);
@@ -192,7 +198,7 @@
 
     switch(fetch_from_buf_http(conn->inbuf,
                                &headers, MAX_HEADERS_SIZE,
-                               &directory, &dir_len, MAX_DIR_SIZE)) {
+                               &body, &body_len, MAX_DIR_SIZE)) {
       case -1: /* overflow */
         log_fn(LOG_WARN,"'fetch' response too large. Failing.");
         connection_mark_for_close(conn,0);
@@ -206,28 +212,28 @@
 
     if(parse_http_response(headers, &status_code, NULL) < 0) {
       log_fn(LOG_WARN,"Unparseable headers. Closing.");
-      free(directory); free(headers);
+      free(body); free(headers);
       connection_mark_for_close(conn,0);
       return -1;
     }
 
     if(conn->purpose == DIR_PURPOSE_FETCH_DIR) {
       /* fetch/process the directory to learn about new routers. */
-      log_fn(LOG_INFO,"Received directory (size %d):\n%s", dir_len, directory);
-      if(status_code == 503 || dir_len == 0) {
+      log_fn(LOG_INFO,"Received directory (size %d):\n%s", body_len, body);
+      if(status_code == 503 || body_len == 0) {
         log_fn(LOG_INFO,"Empty directory. Ignoring.");
-        free(directory); free(headers);
+        free(body); free(headers);
         connection_mark_for_close(conn,0);
         return 0;
       }
       if(status_code != 200) {
         log_fn(LOG_WARN,"Received http status code %d from dirserver. Failing.",
                status_code);
-        free(directory); free(headers);
+        free(body); free(headers);
         connection_mark_for_close(conn,0);
         return -1;
       }
-      if(router_set_routerlist_from_directory(directory, conn->identity_pkey) < 0){
+      if(router_set_routerlist_from_directory(body, conn->identity_pkey) < 0){
         log_fn(LOG_INFO,"...but parsing failed. Ignoring.");
       } else {
         log_fn(LOG_INFO,"updated routers.");
@@ -239,18 +245,15 @@
       if(options.ORPort) { /* connect to them all */
         router_retry_connections();
       }
-      free(directory); free(headers);
-      connection_mark_for_close(conn,0);
-      return 0;
     }
 
     if(conn->purpose == DIR_PURPOSE_UPLOAD_DIR) {
       switch(status_code) {
         case 200:
-          log_fn(LOG_INFO,"eof (status 200) while reading upload response: finished.");
+          log_fn(LOG_INFO,"eof (status 200) after uploading server descriptor: finished.");
           break;
         case 400:
-          log_fn(LOG_WARN,"http status 400 (bad request) response from dirserver.");
+          log_fn(LOG_WARN,"http status 400 (bad request) response from dirserver. Malformed server descriptor?");
           break;
         case 403:
           log_fn(LOG_WARN,"http status 403 (unapproved server) response from dirserver. Is your clock skewed? Have you mailed arma your identity fingerprint? Are you using the right key?");
@@ -260,21 +263,46 @@
           log_fn(LOG_WARN,"http status %d response unrecognized.", status_code);
           break;
       }
-      free(directory); free(headers);
-      connection_mark_for_close(conn,0);
-      return 0;
     }
 
-    if(conn->purpose == DIR_PURPOSE_FETCH_HIDSERV) {
-
-
+    if(conn->purpose == DIR_PURPOSE_FETCH_RENDDESC) {
+      log_fn(LOG_INFO,"Received rendezvous descriptor (size %d, status code %d)",
+             body_len, status_code);
+      switch(status_code) {
+        case 200:
+          if(rend_cache_store(body, body_len) < 0) {
+            log_fn(LOG_WARN,"Failed to store rendezvous descriptor. Abandoning stream.");
+            /* alice's ap_stream is just going to have to time out. */
+          } else {
+            /* success. notify pending connections about this. */
+            //alice_notify_desc_fetched(conn->rend_query);
+          }
+          break;
+        case 404:
+          //alice_notify_desc_not_fetched(conn->rend_query);
+          break;
+        case 400:
+          log_fn(LOG_WARN,"http status 400 (bad request). Dirserver didn't like our rendezvous query?");
+          break;
+      }
     }
 
-    if(conn->purpose == DIR_PURPOSE_UPLOAD_HIDSERV) {
-
-
+    if(conn->purpose == DIR_PURPOSE_UPLOAD_RENDDESC) {
+      switch(status_code) {
+        case 200:
+          log_fn(LOG_INFO,"eof (status 200) after uploading rendezvous descriptor: finished.");
+          break;
+        case 400:
+          log_fn(LOG_WARN,"http status 400 (bad request) response from dirserver. Malformed rendezvous descriptor?");
+          break;
+        default:
+          log_fn(LOG_WARN,"http status %d response unrecognized.", status_code);
+          break;
+      }
     }
-    assert(0); /* never reached */
+    free(body); free(headers);
+    connection_mark_for_close(conn,0);
+    return 0;
   }
 
   if(conn->state == DIR_CONN_STATE_SERVER_COMMAND_WAIT) {

Index: main.c
===================================================================
RCS file: /home/or/cvsroot/src/or/main.c,v
retrieving revision 1.220
retrieving revision 1.221
diff -u -d -r1.220 -r1.221
--- main.c	1 Apr 2004 03:44:49 -0000	1.220
+++ main.c	1 Apr 2004 21:32:01 -0000	1.221
@@ -283,7 +283,7 @@
 
   /* just for testing */
   directory_initiate_command(router_pick_directory_server(),
-                             DIR_PURPOSE_FETCH_HIDSERV, "foo", 3);
+                             DIR_PURPOSE_FETCH_RENDDESC, "foo", 3);
 
   rend_services_init(); /* get bob to initialize all his hidden services */
 

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.276
retrieving revision 1.277
diff -u -d -r1.276 -r1.277
--- or.h	1 Apr 2004 20:33:29 -0000	1.276
+++ or.h	1 Apr 2004 21:32:01 -0000	1.277
@@ -170,6 +170,11 @@
 #define AP_CONN_STATE_OPEN 8
 #define _AP_CONN_STATE_MAX 8
 
+#define _AP_PURPOSE_MIN 1
+#define AP_PURPOSE_GENERAL 1
+#define AP_PURPOSE_
+#define _AP_PURPOSE_MAX 1
+
 #define _DIR_CONN_STATE_MIN 1
 #define DIR_CONN_STATE_CONNECTING 1
 #define DIR_CONN_STATE_CLIENT_SENDING 2
@@ -180,9 +185,9 @@
 
 #define _DIR_PURPOSE_MIN 1
 #define DIR_PURPOSE_FETCH_DIR 1
-#define DIR_PURPOSE_FETCH_HIDSERV 2
+#define DIR_PURPOSE_FETCH_RENDDESC 2
 #define DIR_PURPOSE_UPLOAD_DIR 3
-#define DIR_PURPOSE_UPLOAD_HIDSERV 4
+#define DIR_PURPOSE_UPLOAD_RENDDESC 4
 #define DIR_PURPOSE_SERVER 5
 #define _DIR_PURPOSE_MAX 5
 
@@ -235,6 +240,9 @@
 #define END_STREAM_REASON_TIMEOUT 7
 #define _MAX_END_STREAM_REASON 7
 
+/* length of 'y' portion of 'y.onion' URL. */
+#define REND_SERVICE_ID_LEN 16
+
 /* Reasons used by connection_mark_for_close */
 #define CLOSE_REASON_UNUSED_OR_CONN 100
 
@@ -343,7 +351,7 @@
 
   uint8_t type;
   uint8_t state;
-  uint8_t purpose; /* only used for DIR types currently */
+  uint8_t purpose; /* only used for DIR and AP types currently */
   uint8_t wants_to_read; /* should we start reading again once
                           * the bandwidth throttler allows it?
                           */
@@ -391,6 +399,9 @@
                         * add 'bandwidth' to this, capping it at 10*bandwidth.
                         */
 
+/* Used only by dir connections: */
+  char rend_query[REND_SERVICE_ID_LEN+1];
+
 /* Used only by edge connections: */
   uint16_t stream_id;
   struct connection_t *next_stream; /* points to the next stream at this edge, if any */
@@ -543,7 +554,7 @@
   char rend_service[CRYPTO_SHA1_DIGEST_LEN];
 
   /* Holds rendezvous cookie if purpose is REND_POINT_WAITING or
-   * S_RENDEZVOUSING.  Filled with zeroes otherwise.
+   * S_RENDEZVOUSING or C_ESTABLISH_REND. Filled with zeroes otherwise.
   */
   char rend_cookie[REND_COOKIE_LEN];
 
@@ -999,9 +1010,6 @@
 
 /********************************* rendcommon.c ***************************/
 
-/* length of 'y' portion of 'y.onion' URL. */
-#define REND_SERVICE_ID_LEN 16
-
 typedef struct rend_service_descriptor_t {
   crypto_pk_env_t *pk;
   time_t timestamp;



More information about the tor-commits mailing list