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

[or-cvs] r8399: Send out a burst of long-range drop cells after we've establ (tor/trunk/src/or)



Author: arma
Date: 2006-09-15 01:30:25 -0400 (Fri, 15 Sep 2006)
New Revision: 8399

Modified:
   tor/trunk/src/or/circuitlist.c
   tor/trunk/src/or/circuituse.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/router.c
   tor/trunk/src/or/routerlist.c
Log:
Send out a burst of long-range drop cells after we've established that
we're reachable. Spread them over 4 circuits, so hopefully a few will
be fast. This exercises our bandwidth and bootstraps us quicker.


Modified: tor/trunk/src/or/circuitlist.c
===================================================================
--- tor/trunk/src/or/circuitlist.c	2006-09-15 05:20:16 UTC (rev 8398)
+++ tor/trunk/src/or/circuitlist.c	2006-09-15 05:30:25 UTC (rev 8399)
@@ -220,7 +220,7 @@
   }
 }
 
-/** Return the head of the global linked list of circuits. **/
+/** Return the head of the global linked list of circuits. */
 circuit_t *
 _circuit_get_global_list(void)
 {
@@ -650,8 +650,9 @@
 }
 
 /** Return the first circuit in global_circuitlist after <b>start</b>
- * whose rend_pk_digest field is <b>digest</b> and whose purpose is
- * <b>purpose</b>. Returns NULL if no circuit is found.
+ * whose purpose is <b>purpose</b> is purpose, and (if set) whose
+ * <b>digest</b> matches the rend_pk_digest field. Return NULL if no
+ * circuit is found.
  * If <b>start</b> is NULL, begin at the start of the list.
  * DOCDOC origin.
  */

Modified: tor/trunk/src/or/circuituse.c
===================================================================
--- tor/trunk/src/or/circuituse.c	2006-09-15 05:20:16 UTC (rev 8398)
+++ tor/trunk/src/or/circuituse.c	2006-09-15 05:30:25 UTC (rev 8399)
@@ -583,8 +583,6 @@
       log_debug(LD_CIRC, "Closing n_circ_id %d (dirty %d secs ago, purp %d)",
                 circ->n_circ_id, (int)(now - circ->timestamp_dirty),
                 circ->purpose);
-      /* (only general and purpose_c circs can get dirty) */
-      tor_assert(circ->purpose <= CIRCUIT_PURPOSE_C_REND_JOINED);
       circuit_mark_for_close(circ, END_CIRC_AT_ORIGIN);
     } else if (!circ->timestamp_dirty &&
                circ->state == CIRCUIT_STATE_OPEN &&
@@ -599,14 +597,55 @@
   }
 }
 
-/** A testing circuit has completed. Take whatever stats we want. */
+#define NUM_PARALLEL_TESTING_CIRCS 4
+
+static int have_performed_bandwidth_test = 0;
+
+/** Reset have_performed_bandwidth_test, so we'll start building
+ * testing circuits again so we can exercise our bandwidth. */
+void
+reset_bandwidth_test(void)
+{
+  have_performed_bandwidth_test = 0;
+}
+
+/** Return 1 if we've already exercised our bandwidth, or if we
+ * have fewer than NUM_PARALLEL_TESTING_CIRCS testing circuits
+ * established or on the way. Else return 0.
+ */
+int
+circuit_enough_testing_circs(void)
+{
+  circuit_t *circ;
+  int num = 0;
+
+  if (have_performed_bandwidth_test)
+    return 1;
+
+  for (circ = global_circuitlist; circ; circ = circ->next) {
+    if (!circ->marked_for_close && CIRCUIT_IS_ORIGIN(circ) &&
+        circ->purpose == CIRCUIT_PURPOSE_TESTING &&
+        circ->state == CIRCUIT_STATE_OPEN)
+      num++;
+  }
+  return num >= NUM_PARALLEL_TESTING_CIRCS;
+}
+
+/** A testing circuit has completed. Take whatever stats we want.
+ * Noticing reachability is taken care of in onionskin_answer(),
+ * so there's no need to record anything here. But if we still want
+ * to do the bandwidth test, and we now have enough testing circuits
+ * open, do it.
+ */
 static void
 circuit_testing_opened(origin_circuit_t *circ)
 {
-  /* For now, we only use testing circuits to see if our ORPort is
-     reachable. But we remember reachability in onionskin_answer(),
-     so there's no need to record anything here. Just close the circ. */
-  circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_AT_ORIGIN);
+  if (have_performed_bandwidth_test) {
+    circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_AT_ORIGIN);
+  } else if (circuit_enough_testing_circs()) {
+    router_perform_bandwidth_test(NUM_PARALLEL_TESTING_CIRCS, time(NULL));
+    have_performed_bandwidth_test = 1;
+  }
 }
 
 /** A testing circuit has failed to build. Take whatever stats we want. */

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2006-09-15 05:20:16 UTC (rev 8398)
+++ tor/trunk/src/or/or.h	2006-09-15 05:30:25 UTC (rev 8399)
@@ -1753,6 +1753,10 @@
 void circuit_build_needed_circs(time_t now);
 void circuit_detach_stream(circuit_t *circ, edge_connection_t *conn);
 void circuit_about_to_close_connection(connection_t *conn);
+
+void reset_bandwidth_test(void);
+int circuit_enough_testing_circs(void);
+
 void circuit_has_opened(origin_circuit_t *circ);
 void circuit_build_failed(origin_circuit_t *circ);
 origin_circuit_t *circuit_launch_by_nickname(uint8_t purpose,
@@ -2443,13 +2447,14 @@
 void router_orport_found_reachable(void);
 void router_dirport_found_reachable(void);
 void server_has_changed_ip(void);
-void consider_publishable_server(int force);
+void router_perform_bandwidth_test(int num_circs, time_t now);
 
 int authdir_mode(or_options_t *options);
 int clique_mode(or_options_t *options);
 int server_mode(or_options_t *options);
 int advertised_server_mode(void);
 int proxy_mode(or_options_t *options);
+void consider_publishable_server(int force);
 
 int router_is_clique_mode(routerinfo_t *router);
 void router_upload_dir_desc_to_dirservers(int force);

Modified: tor/trunk/src/or/router.c
===================================================================
--- tor/trunk/src/or/router.c	2006-09-15 05:20:16 UTC (rev 8398)
+++ tor/trunk/src/or/router.c	2006-09-15 05:30:25 UTC (rev 8399)
@@ -439,11 +439,13 @@
 consider_testing_reachability(void)
 {
   routerinfo_t *me = router_get_my_routerinfo();
+  int orport_reachable = !check_whether_orport_reachable();
   if (!me)
     return;
 
-  if (!check_whether_orport_reachable()) {
-    log_info(LD_CIRC, "Testing reachability of my ORPort: %s:%d.",
+  if (!orport_reachable || !circuit_enough_testing_circs()) {
+    log_info(LD_CIRC, "Testing %s of my ORPort: %s:%d.",
+             !orport_reachable ? "reachability" : "bandwidth",
              me->address, me->or_port);
     circuit_launch_by_router(CIRCUIT_PURPOSE_TESTING, me, 0, 1, 1);
   }
@@ -488,9 +490,38 @@
   stats_n_seconds_working = 0;
   can_reach_or_port = 0;
   can_reach_dir_port = 0;
+  reset_bandwidth_test();
   mark_my_descriptor_dirty();
 }
 
+/** We have enough testing circuit open. Send a bunch of "drop"
+ * cells down each of them, to exercise our bandwidth. */
+void
+router_perform_bandwidth_test(int num_circs, time_t now)
+{
+  int num_cells = get_options()->BandwidthRate * 10 / CELL_NETWORK_SIZE;
+  int max_cells = num_cells < CIRCWINDOW_START ?
+                    num_cells : CIRCWINDOW_START;
+  int cells_per_circuit = max_cells / num_circs;
+  origin_circuit_t *circ = NULL;
+
+  while ((circ = circuit_get_next_by_pk_and_purpose(circ, NULL,
+                                              CIRCUIT_PURPOSE_TESTING))) {
+    /* dump cells_per_circuit drop cells onto this circ */
+    int i = cells_per_circuit;
+    if (circ->_base.state != CIRCUIT_STATE_OPEN)
+      continue;
+    circ->_base.timestamp_dirty = now;
+    while (i-- > 0) {
+      if (connection_edge_send_command(NULL, TO_CIRCUIT(circ),
+                                       RELAY_COMMAND_DROP,
+                                       NULL, 0, circ->cpath->prev)<0) {
+        return; /* stop if error */
+      }
+    }
+  }
+}
+
 /** Return true iff we believe ourselves to be an authoritative
  * directory server.
  */

Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c	2006-09-15 05:20:16 UTC (rev 8398)
+++ tor/trunk/src/or/routerlist.c	2006-09-15 05:30:25 UTC (rev 8399)
@@ -2129,6 +2129,7 @@
 /** How far in the future do we allow a network-status to get before removing
  * it? (seconds) */
 #define NETWORKSTATUS_ALLOW_SKEW (24*60*60)
+
 /** Given a string <b>s</b> containing a network status that we received at
  * <b>arrived_at</b> from <b>source</b>, try to parse it, see if we want to
  * store it, and put it into our cache as necessary.