]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
clean up circuit rebuilding some; fix some bugs we hadn't hit yet
authorRoger Dingledine <arma@torproject.org>
Tue, 13 Apr 2004 05:20:52 +0000 (05:20 +0000)
committerRoger Dingledine <arma@torproject.org>
Tue, 13 Apr 2004 05:20:52 +0000 (05:20 +0000)
svn:r1606

src/or/circuit.c
src/or/main.c
src/or/or.h
src/or/rendclient.c
src/or/rendservice.c

index ca9c503aa1450fbebdd53d1b73f5240d7144b3e3..7b51905329a5bb11645eaebc425d6ab53f6fbfec 100644 (file)
@@ -16,6 +16,7 @@ static void circuit_free_cpath_node(crypt_path_t *victim);
 static uint16_t get_unique_circ_id_by_conn(connection_t *conn, int circ_id_type);
 static void circuit_rep_hist_note_result(circuit_t *circ);
 
+void circuit_expire_old_circuits(void);
 static void circuit_is_open(circuit_t *circ);
 static void circuit_build_failed(circuit_t *circ);
 static circuit_t *circuit_establish_circuit(uint8_t purpose, const char *exit_nickname);
@@ -293,10 +294,6 @@ static int circuit_is_acceptable(circuit_t *circ,
   if(conn) {
     /* decide if this circ is suitable for this conn */
 
-//      if(circ->state == CIRCUIT_STATE_OPEN && circ->n_conn) /* open */
-//        exitrouter = router_get_by_addr_port(circ->cpath->prev->addr,
-//                                             circ->cpath->prev->port);
-//      else /* not open */
     /* for rend circs, circ->cpath->prev is not the last router in the
      * circuit, it's the magical extra bob hop. so just check the nickname
      * of the one we meant to finish at.
@@ -442,8 +439,7 @@ circuit_t *circuit_get_rendezvous(const char *cookie)
 
 /* close all circuits that start at us, aren't open, and were born
  * at least MIN_SECONDS_BEFORE_EXPIRING_CIRC seconds ago */
-void circuit_expire_building(void) {
-  int now = time(NULL);
+void circuit_expire_building(time_t now) {
   circuit_t *victim, *circ = global_circuitlist;
 
   while(circ) {
@@ -480,14 +476,15 @@ void circuit_expire_building(void) {
 }
 
 /* count the number of circs starting at us that aren't open */
-int circuit_count_building(void) {
+int circuit_count_building(uint8_t purpose) {
   circuit_t *circ;
   int num=0;
 
   for(circ=global_circuitlist;circ;circ = circ->next) {
-    if(CIRCUIT_IS_ORIGIN(circ)
-       && circ->state != CIRCUIT_STATE_OPEN
-       && !circ->marked_for_close)
+    if(CIRCUIT_IS_ORIGIN(circ) &&
+       circ->state != CIRCUIT_STATE_OPEN &&
+       circ->purpose == purpose &&
+       !circ->marked_for_close)
       num++;
   }
   return num;
@@ -518,41 +515,65 @@ int circuit_stream_is_being_handled(connection_t *conn) {
   return 0;
 }
 
-void circuit_build_needed_circs(time_t now) {
-  static long time_to_new_circuit = 0;
+static circuit_t *
+circuit_get_youngest_clean_open(uint8_t purpose) {
   circuit_t *circ;
+  circuit_t *youngest=NULL;
 
-  if (options.SocksPort)
-    /* launch a new circ for any pending streams that need one */
-    connection_ap_attach_pending();
+  for(circ=global_circuitlist;circ;circ = circ->next) {
+    if(CIRCUIT_IS_ORIGIN(circ) && circ->state == CIRCUIT_STATE_OPEN &&
+       !circ->marked_for_close && circ->purpose == purpose &&
+       !circ->timestamp_dirty &&
+       (!youngest || youngest->timestamp_created < circ->timestamp_created))
+      youngest = circ;
+  }
+  return youngest;
+}
 
 /* Build a new test circuit every 5 minutes */
 #define TESTING_CIRCUIT_INTERVAL 300
 
-  circ = circuit_get_best(NULL, 1, CIRCUIT_PURPOSE_C_GENERAL);
+/* this function is called once a second. its job is to make sure
+ * all services we offer have enough circuits available. Some
+ * services just want enough circuits for current tasks, whereas
+ * others want a minimum set of idle circuits hanging around.
+ */
+void circuit_build_needed_circs(time_t now) {
+  static long time_to_new_circuit = 0;
+  circuit_t *circ;
+
+  /* launch a new circ for any pending streams that need one */
+  connection_ap_attach_pending();
+
+  /* make sure any hidden services have enough intro points */
+  rend_services_init();
+
+  circ = circuit_get_youngest_clean_open(CIRCUIT_PURPOSE_C_GENERAL);
+
   if(time_to_new_circuit < now) {
-    client_dns_clean();
-    circuit_expire_unused_circuits();
     circuit_reset_failure_count();
-    if(circ && circ->timestamp_dirty) {
-      log_fn(LOG_INFO,"Youngest circuit dirty; launching replacement.");
-      /* make a new circuit */
-      circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL);
-    } else if (options.RunTesting && circ &&
+    time_to_new_circuit = now + options.NewCircuitPeriod;
+    if(options.SocksPort)
+      client_dns_clean();
+    circuit_expire_old_circuits();
+
+    if(options.RunTesting && circ &&
                circ->timestamp_created + TESTING_CIRCUIT_INTERVAL < now) {
       log_fn(LOG_INFO,"Creating a new testing circuit.");
       circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL);
     }
-    time_to_new_circuit = now + options.NewCircuitPeriod;
-    time_to_new_circuit = now + options.NewCircuitPeriod;
   }
-#define CIRCUIT_MIN_BUILDING 3
-  if(!circ && circuit_count_building() < CIRCUIT_MIN_BUILDING) {
-    /* if there's no open circ, and less than 3 are on the way,
-     * go ahead and try another.
-     */
+
+#define CIRCUIT_MIN_BUILDING_GENERAL 3
+  /* if there's no open circ, and less than 3 are on the way,
+   * go ahead and try another. */
+  if(!circ && circuit_count_building(CIRCUIT_PURPOSE_C_GENERAL)
+              < CIRCUIT_MIN_BUILDING_GENERAL) {
     circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL);
   }
+
+  /* XXX count idle rendezvous circs and build more */
+
 }
 
 /* update digest from the payload of cell. assign integrity part to cell. */
@@ -1142,7 +1163,7 @@ void circuit_dump_by_conn(connection_t *conn, int severity) {
 /* Don't keep more than 10 unused open circuits around. */
 #define MAX_UNUSED_OPEN_CIRCUITS 10
 
-void circuit_expire_unused_circuits(void) {
+void circuit_expire_old_circuits(void) {
   circuit_t *circ;
   time_t now = time(NULL);
   smartlist_t *unused_open_circs;
index 88faede1fa8c2b8a19eb75815e08af39bd099398..ee7070acd94669a51da49e53f1ae3268b6be6d19 100644 (file)
@@ -297,9 +297,6 @@ void directory_has_arrived(void) {
   if(options.ORPort) { /* connect to them all */
     router_retry_connections();
   }
-
-  rend_services_init(); /* get bob to initialize all his hidden services */
-
 }
 
 /* Perform regular maintenance tasks for a single connection.  This
@@ -366,7 +363,7 @@ static void run_scheduled_events(time_t now) {
    *    We do this before step 3, so it can try building more if
    *    it's not comfortable with the number of available circuits.
    */
-  circuit_expire_building();
+  circuit_expire_building(now);
 
   /* 2b. Also look at pending streams and prune the ones that 'began'
    *     a long time ago but haven't gotten a 'connected' yet.
@@ -385,8 +382,7 @@ static void run_scheduled_events(time_t now) {
    *    that became dirty more than NewCircuitPeriod seconds ago,
    *    and we make a new circ if there are no clean circuits.
    */
-  if(has_fetched_directory &&
-     (options.SocksPort || options.RunTesting))
+  if(has_fetched_directory)
     circuit_build_needed_circs(now);
 
   /* 4. We do housekeeping for each connection... */
@@ -522,10 +518,7 @@ static int do_hup(void) {
     }
     /* Since we aren't fetching a directory, we won't retry rendezvous points
      * when it gets in.  Try again now. */
-    if (rend_services_init()<0) {
-      log_fn(LOG_ERR,"Error updating rendezvous services");
-      return -1;
-    }
+    rend_services_init();
   } else {
     /* fetch a new directory */
     directory_initiate_command(router_pick_directory_server(),
index d5390022fb7df084f4a48ac6eb905c6f790b5e31..9f85af996a255a85eecf6456f6bc486785aa6e16 100644 (file)
 /* here's how circ client-side purposes work:
  *   normal circuits are C_GENERAL.
  *   circuits that are c_introducing are either on their way to
- *     becoming open, or they are open but haven't been used yet.
- *     (as soon as they are used, they are destroyed.)
+ *     becoming open, or they are open and waiting for a
+ *     suitable rendcirc before they send the intro.
+ *   circuits that are c_introduce_ack_wait have sent the intro,
+ *     but haven't gotten a response yet.
  *   circuits that are c_establish_rend are either on their way
  *     to becoming open, or they are open and have sent the
  *     establish_rendezvous cell but haven't received an ack.
  */
 #define CIRCUIT_PURPOSE_C_GENERAL 5 /* normal circuit, with cpath */
 #define CIRCUIT_PURPOSE_C_INTRODUCING 6 /* at Alice, connecting to intro point */
-#define CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT 7 /* at alice, sent INTRODUCE1 to intro point, waiting for ACK/NAK */
+#define CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT 7 /* at Alice, sent INTRODUCE1 to intro point, waiting for ACK/NAK */
 
 #define CIRCUIT_PURPOSE_C_ESTABLISH_REND 8 /* at Alice, waiting for ack */
 #define CIRCUIT_PURPOSE_C_REND_READY 9 /* at Alice, waiting for Bob */
 
 #define CELL_DIRECTION_IN 1
 #define CELL_DIRECTION_OUT 2
-//#define EDGE_EXIT CONN_TYPE_EXIT
-//#define EDGE_AP CONN_TYPE_AP
-//#define CELL_DIRECTION(x) ((x) == EDGE_EXIT ? CELL_DIRECTION_IN : CELL_DIRECTION_OUT)
 
 #ifdef TOR_PERF
 #define CIRCWINDOW_START 10000
  *         Relay payload           [498 bytes]
  */
 
-#if 0
-#define CELL_RELAY_COMMAND(c)         (*(uint8_t*)((c).payload))
-#define SET_CELL_RELAY_COMMAND(c,cmd) (*(uint8_t*)((c).payload) = (cmd))
-
-#define CELL_RELAY_RECOGNIZED(c)       (ntohs(*(uint16_t*)((c).payload+1)))
-#define SET_CELL_RELAY_RECOGNIZED(c,r) (*(uint16_t*)((c).payload+1) = htons(r))
-
-#define STREAM_ID_SIZE 2
-//#define SET_CELL_STREAM_ID(c,id)      memcpy((c).payload+1,(id),STREAM_ID_SIZE)
-#define CELL_RELAY_STREAM_ID(c)        (ntohs(*(uint16_t*)((c).payload+3)))
-#define SET_CELL_RELAY_STREAM_ID(c,id) (*(uint16_t*)((c).payload+3) = htons(id))
-#define ZERO_STREAM 0
-
-/* integrity is the first 32 bits (in network order) of a sha-1 of all
- * cell payloads that are relay cells that have been sent / delivered
- * to the hop on the * circuit (the integrity is zeroed while doing
- * each calculation)
- */
-#define CELL_RELAY_INTEGRITY(c)       (ntohl(*(uint32_t*)((c).payload+5)))
-#define SET_CELL_RELAY_INTEGRITY(c,i) (*(uint32_t*)((c).payload+5) = htonl(i))
-
-/* relay length is how many bytes are used in the cell payload past relay_header_size */
-#define CELL_RELAY_LENGTH(c)         (ntohs(*(uint16_t*)((c).payload+9)))
-#define SET_CELL_RELAY_LENGTH(c,len) (*(uint16_t*)((c).payload+9) = htons(len))
-#endif
-
 #define CELL_PAYLOAD_SIZE 509
 #define CELL_NETWORK_SIZE 512
 
@@ -716,8 +689,8 @@ circuit_t *circuit_get_next_by_pk_and_purpose(circuit_t *circuit,
                                               const char *servid, uint8_t purpose);
 circuit_t *circuit_get_rendezvous(const char *cookie);
 
-void circuit_expire_building(void);
-int circuit_count_building(void);
+void circuit_expire_building(time_t now);
+int circuit_count_building(uint8_t purpose);
 int circuit_stream_is_being_handled(connection_t *conn);
 void circuit_build_needed_circs(time_t now);
 
@@ -1110,7 +1083,7 @@ int rend_cache_store(char *desc, int desc_len);
 
 int rend_config_services(or_options_t *options);
 int rend_service_init_keys(void);
-int rend_services_init(void);
+void rend_services_init(void);
 
 void rend_service_intro_is_ready(circuit_t *circuit);
 int rend_service_intro_established(circuit_t *circuit, const char *request, int request_len);
index 0f2dfa15c906d74eeffa76ca6647d0886e47c44a..27d6fd5f1bfa21f9dd231165ee1908a5129a4113 100644 (file)
@@ -156,7 +156,7 @@ rend_client_introduction_acked(circuit_t *circ,
   char *nickname;
 
   if (circ->purpose != CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) {
-    log_fn(LOG_WARN, "Recieved REND_INTRODUCE_ACK on unexpected circuit %d",
+    log_fn(LOG_WARN, "Received REND_INTRODUCE_ACK on unexpected circuit %d",
            circ->n_circ_id);
     circuit_mark_for_close(circ);
     return -1;
index 793d6d44cb0756ff7d691dd4fd074c180ccfc63e..608a19773bfec32f8d0b60c1d12456a89f891ad7 100644 (file)
@@ -662,7 +662,7 @@ find_intro_circuit(routerinfo_t *router, const char *pk_digest)
  *  - Launch circuits to any new intro points.
  *  - Upload a fresh service descriptor if anything has changed.
  */
-int rend_services_init(void) {
+void rend_services_init(void) {
   int i,j,r;
   routerinfo_t *router;
   routerlist_t *rl;
@@ -759,8 +759,6 @@ int rend_services_init(void) {
   }
   smartlist_free(intro_routers);
   smartlist_free(exclude_routers);
-
-  return 0;
 }
 
 void