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

[or-cvs] Start the process of treating internal circuits and exit ci...



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

Modified Files:
	circuitlist.c circuituse.c or.h rendservice.c rephist.c 
Log Message:
Start the process of treating internal circuits and exit circuits
separately. It's important to keep them separate because internal
circuits have their last hops picked like middle hops, rather than like
exit hops. So exiting on them will break the user's expectations.

- Stop cannibalizing internal circuits for general exits, and stop
  cannibalizing exit circuits for rendezvous stuff.

- Don't let new exit streams attach to internal circuits.

- When deciding if we have enough circuits for internal and for exit,
  don't count the wrong ones.

- Treat predicted resolves as predicted port 80 exits.


Index: circuitlist.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/circuitlist.c,v
retrieving revision 1.73
retrieving revision 1.74
diff -u -d -r1.73 -r1.74
--- circuitlist.c	23 Nov 2005 04:18:45 -0000	1.73
+++ circuitlist.c	25 Nov 2005 08:08:55 -0000	1.74
@@ -552,10 +552,10 @@
  * if required, and if info is defined, does not already use info
  * as any of its hops; or NULL if no circuit fits this description.
  *
- * Avoid returning need_uptime circuits if not necessary.
+ * Return need_uptime circuits if that is requested; and if it's not
+ * requested, return non-uptime circuits if possible, else either.
  *
- * FFFF As a more important goal, not yet implemented, avoid returning
- * internal circuits if not necessary.
+ * Only return internal circuits if that is requested.
  */
 circuit_t *
 circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info,
@@ -575,7 +575,7 @@
         !circ->timestamp_dirty &&
         (!need_uptime || circ->build_state->need_uptime) &&
         (!need_capacity || circ->build_state->need_capacity) &&
-        (!internal || circ->build_state->is_internal)) {
+        (internal == circ->build_state->is_internal)) {
       if (info) {
         /* need to make sure we don't duplicate hops */
         crypt_path_t *hop = circ->cpath;

Index: circuituse.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/circuituse.c,v
retrieving revision 1.90
retrieving revision 1.91
diff -u -d -r1.90 -r1.91
--- circuituse.c	19 Nov 2005 06:57:44 -0000	1.90
+++ circuituse.c	25 Nov 2005 08:08:55 -0000	1.91
@@ -29,10 +29,9 @@
  * Else return 0.
  */
 static int
-circuit_is_acceptable(circuit_t *circ,
-                      connection_t *conn,
-                      int must_be_open,
-                      uint8_t purpose,
+circuit_is_acceptable(circuit_t *circ, connection_t *conn,
+                      int must_be_open, uint8_t purpose,
+                      int need_uptime, int need_internal,
                       time_t now)
 {
   routerinfo_t *exitrouter;
@@ -76,9 +75,9 @@
    */
   exitrouter = build_state_get_exit_router(circ->build_state);
 
-  if (!circ->build_state->need_uptime &&
-      smartlist_string_num_isin(get_options()->LongLivedPorts,
-                                conn->socks_request->port))
+  if (need_uptime && !circ->build_state->need_uptime)
+    return 0;
+  if (need_internal != circ->build_state->is_internal)
     return 0;
 
   if (purpose == CIRCUIT_PURPOSE_C_GENERAL) {
@@ -153,7 +152,8 @@
  * closest introduce-purposed circuit that you can find.
  */
 static circuit_t *
-circuit_get_best(connection_t *conn, int must_be_open, uint8_t purpose)
+circuit_get_best(connection_t *conn, int must_be_open, uint8_t purpose,
+                 int need_uptime, int need_internal)
 {
   circuit_t *circ, *best=NULL;
   time_t now = time(NULL);
@@ -165,7 +165,8 @@
              purpose == CIRCUIT_PURPOSE_C_REND_JOINED);
 
   for (circ=global_circuitlist;circ;circ = circ->next) {
-    if (!circuit_is_acceptable(circ,conn,must_be_open,purpose,now))
+    if (!circuit_is_acceptable(circ,conn,must_be_open,purpose,
+                               need_uptime,need_internal,now))
       continue;
 
     /* now this is an acceptable circ to hand back. but that doesn't
@@ -278,8 +279,9 @@
   }
 }
 
-/** Return 1 if at least <b>min</b> general-purpose circuits will have
- * an acceptable exit node for conn if conn is defined, else for "*:port".
+/** Return 1 if at least <b>min</b> general-purpose non-internal circuits
+ * will have an acceptable exit node for exit stream <b>conn</b> if it
+ * is defined, else for "*:port".
  * Else return 0.
  */
 int
@@ -296,6 +298,7 @@
     if (CIRCUIT_IS_ORIGIN(circ) &&
         !circ->marked_for_close &&
         circ->purpose == CIRCUIT_PURPOSE_C_GENERAL &&
+        !circ->build_state->is_internal &&
         (!circ->timestamp_dirty ||
          circ->timestamp_dirty + get_options()->MaxCircuitDirtiness < now)) {
       exitrouter = build_state_get_exit_router(circ->build_state);
@@ -320,7 +323,7 @@
 }
 
 /** Don't keep more than 10 unused open circuits around. */
-#define MAX_UNUSED_OPEN_CIRCUITS 10
+#define MAX_UNUSED_OPEN_CIRCUITS 12
 
 /** Figure out how many circuits we have open that are clean. Make
  * sure it's enough for all the upcoming behaviors we predict we'll have.
@@ -378,8 +381,8 @@
   }
 
   /* Fourth, see if we need any more hidden service (client) circuits. */
-  if (rep_hist_get_predicted_hidserv(now, &hidserv_needs_uptime,
-                                     &hidserv_needs_capacity) &&
+  if (rep_hist_get_predicted_internal(now, &hidserv_needs_uptime,
+                                      &hidserv_needs_capacity) &&
       ((num_uptime_internal<2 && hidserv_needs_uptime) ||
         num_internal<2)) {
     info(LD_CIRC,"Have %d clean circs (%d uptime-internal, %d internal),"
@@ -867,14 +870,19 @@
 {
   circuit_t *circ;
   int is_resolve;
-  int need_uptime;
+  int need_uptime, need_internal;
 
   tor_assert(conn);
   tor_assert(circp);
   tor_assert(conn->state == AP_CONN_STATE_CIRCUIT_WAIT);
   is_resolve = conn->socks_request->command == SOCKS_COMMAND_RESOLVE;
 
-  circ = circuit_get_best(conn, 1, desired_circuit_purpose);
+  need_uptime = smartlist_string_num_isin(get_options()->LongLivedPorts,
+                                          conn->socks_request->port);
+  need_internal = desired_circuit_purpose != CIRCUIT_PURPOSE_C_GENERAL;
+
+  circ = circuit_get_best(conn, 1, desired_circuit_purpose,
+                          need_uptime, need_internal);
 
   if (circ) {
     *circp = circ;
@@ -898,9 +906,6 @@
     return 0;
   }
 
-  need_uptime = smartlist_string_num_isin(get_options()->LongLivedPorts,
-                                          conn->socks_request->port);
-
   /* Do we need to check exit policy? */
   if (!is_resolve && !connection_edge_is_rendezvous_stream(conn)) {
     struct in_addr in;
@@ -909,19 +914,18 @@
       addr = ntohl(in.s_addr);
     if (router_exit_policy_all_routers_reject(addr, conn->socks_request->port,
                                               need_uptime)) {
-      /* LD_GENERAL? LD_APP? ???? NM */
-      notice(LD_CIRC,"No Tor server exists that allows exit to %s:%d. Rejecting.",
+      notice(LD_APP,"No Tor server exists that allows exit to %s:%d. Rejecting.",
              safe_str(conn->socks_request->address), conn->socks_request->port);
       return -1;
     }
   }
 
   /* is one already on the way? */
-  circ = circuit_get_best(conn, 0, desired_circuit_purpose);
+  circ = circuit_get_best(conn, 0, desired_circuit_purpose,
+                          need_uptime, need_internal);
   if (!circ) {
     extend_info_t *extend_info=NULL;
     uint8_t new_circ_purpose;
-    int is_internal;
 
     if (desired_circuit_purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) {
       /* need to pick an intro point */
@@ -933,7 +937,7 @@
         conn->state = AP_CONN_STATE_RENDDESC_WAIT;
         return 0;
       }
-      info(LD_REND,"Chose %s as intro point for %s.",
+      info(LD_REND,"Chose '%s' as intro point for '%s'.",
            extend_info->nickname, safe_str(conn->rend_query));
     }
 
@@ -960,15 +964,14 @@
     else
       new_circ_purpose = desired_circuit_purpose;
 
-    is_internal = (new_circ_purpose != CIRCUIT_PURPOSE_C_GENERAL || is_resolve);
     circ = circuit_launch_by_extend_info(
-              new_circ_purpose, extend_info, need_uptime, 1, is_internal);
+              new_circ_purpose, extend_info, need_uptime, 1, need_internal);
     if (extend_info)
       extend_info_free(extend_info);
 
     if (desired_circuit_purpose != CIRCUIT_PURPOSE_C_GENERAL) {
       /* help predict this next time */
-      rep_hist_note_used_hidserv(time(NULL), need_uptime, 1);
+      rep_hist_note_used_internal(time(NULL), need_uptime, 1);
       if (circ) {
         /* write the service_id into circ */
         strlcpy(circ->rend_query, conn->rend_query, sizeof(circ->rend_query));

Index: or.h
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.740
retrieving revision 1.741
diff -u -d -r1.740 -r1.741
--- or.h	23 Nov 2005 06:00:58 -0000	1.740
+++ or.h	25 Nov 2005 08:08:55 -0000	1.741
@@ -1947,10 +1947,9 @@
 
 void rep_hist_note_used_port(uint16_t port, time_t now);
 smartlist_t *rep_hist_get_predicted_ports(time_t now);
-void rep_hist_note_used_hidserv(time_t now, int need_uptime, int need_capacity);
-int rep_hist_get_predicted_hidserv(time_t now, int *need_uptime, int *need_capacity);
 void rep_hist_note_used_resolve(time_t now);
-int rep_hist_get_predicted_resolve(time_t now);
+void rep_hist_note_used_internal(time_t now, int need_uptime, int need_capacity);
+int rep_hist_get_predicted_internal(time_t now, int *need_uptime, int *need_capacity);
 
 void rep_hist_free_all(void);
 

Index: rendservice.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/rendservice.c,v
retrieving revision 1.147
retrieving revision 1.148
diff -u -d -r1.147 -r1.148
--- rendservice.c	5 Nov 2005 20:15:27 -0000	1.147
+++ rendservice.c	25 Nov 2005 08:08:56 -0000	1.148
@@ -545,7 +545,7 @@
   circ_needs_uptime = rend_service_requires_uptime(service);
 
   /* help predict this next time */
-  rep_hist_note_used_hidserv(time(NULL), circ_needs_uptime, 1);
+  rep_hist_note_used_internal(time(NULL), circ_needs_uptime, 1);
 
   /* Launch a circuit to alice's chosen rendezvous point.
    */
@@ -652,7 +652,7 @@
   info(LD_REND, "Launching circuit to introduction point %s for service %s",
          nickname, service->service_id);
 
-  rep_hist_note_used_hidserv(time(NULL), 1, 0);
+  rep_hist_note_used_internal(time(NULL), 1, 0);
 
   ++service->n_intro_circuits_launched;
   launched = circuit_launch_by_nickname(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, nickname, 1, 0, 1);

Index: rephist.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/rephist.c,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -d -r1.71 -r1.72
--- rephist.c	23 Nov 2005 04:18:45 -0000	1.71
+++ rephist.c	25 Nov 2005 08:08:56 -0000	1.72
@@ -666,7 +666,7 @@
 
 /** Remember that <b>port</b> has been asked for as of time <b>now</b>.
  * This is used for predicting what sorts of streams we'll make in the
- * future and making circuits to anticipate that.
+ * future and making exit circuits to anticipate that.
  */
 void
 rep_hist_note_used_port(uint16_t port, time_t now)
@@ -727,53 +727,61 @@
   return predicted_ports_list;
 }
 
+/** The user asked us to do a resolve. Rather than keeping track of
+ * timings and such of resolves, we fake it for now by making treating
+ * it the same way as a connection to port 80. This way we will continue
+ * to have circuits lying around if the user only uses Tor for resolves.
+ */
+void
+rep_hist_note_used_resolve(time_t now)
+{
+  rep_hist_note_used_port(80, now);
+}
+
+#if 0
+int
+rep_hist_get_predicted_resolve(time_t now)
+{
+  return 0;
+}
+#endif
+
 /** The last time at which we needed an internal circ. */
-static time_t predicted_hidserv_time = 0;
+static time_t predicted_internal_time = 0;
 /** The last time we needed an internal circ with good uptime. */
-static time_t predicted_hidserv_uptime_time = 0;
+static time_t predicted_internal_uptime_time = 0;
 /** The last time we needed an internal circ with good capacity. */
-static time_t predicted_hidserv_capacity_time = 0;
+static time_t predicted_internal_capacity_time = 0;
 
 /** Remember that we used an internal circ at time <b>now</b>. */
 void
-rep_hist_note_used_hidserv(time_t now, int need_uptime, int need_capacity)
+rep_hist_note_used_internal(time_t now, int need_uptime, int need_capacity)
 {
-  predicted_hidserv_time = now;
+  predicted_internal_time = now;
   if (need_uptime)
-    predicted_hidserv_uptime_time = now;
+    predicted_internal_uptime_time = now;
   if (need_capacity)
-    predicted_hidserv_capacity_time = now;
+    predicted_internal_capacity_time = now;
 }
 
 /** Return 1 if we've used an internal circ recently; else return 0. */
 int
-rep_hist_get_predicted_hidserv(time_t now, int *need_uptime, int *need_capacity)
+rep_hist_get_predicted_internal(time_t now, int *need_uptime, int *need_capacity)
 {
-  if (!predicted_hidserv_time) { /* initialize it */
-    predicted_hidserv_time = now;
-    predicted_hidserv_uptime_time = now;
-    predicted_hidserv_capacity_time = now;
+  if (!predicted_internal_time) { /* initialize it */
+    predicted_internal_time = now;
+    predicted_internal_uptime_time = now;
+    predicted_internal_capacity_time = now;
   }
-  if (predicted_hidserv_time + PREDICTED_CIRCS_RELEVANCE_TIME < now)
+  if (predicted_internal_time + PREDICTED_CIRCS_RELEVANCE_TIME < now)
     return 0; /* too long ago */
-  if (predicted_hidserv_uptime_time + PREDICTED_CIRCS_RELEVANCE_TIME < now)
+  if (predicted_internal_uptime_time + PREDICTED_CIRCS_RELEVANCE_TIME < now)
     *need_uptime = 1;
-  if (predicted_hidserv_capacity_time + PREDICTED_CIRCS_RELEVANCE_TIME < now)
+  if (predicted_internal_capacity_time + PREDICTED_CIRCS_RELEVANCE_TIME < now)
     *need_capacity = 1;
   return 1;
 }
 
-/* not used yet */
-void
-rep_hist_note_used_resolve(time_t now)
-{
-}
-int
-rep_hist_get_predicted_resolve(time_t now)
-{
-  return 0;
-}
-
 /** Free all storage held by the OR/link history caches, by the
  * bandwidth history arrays, or by the port history. */
 void