[tor-commits] [tor/master] Make introduction points expire

nickm at torproject.org nickm at torproject.org
Wed Nov 30 01:55:00 UTC 2011


commit 1eba4f0cc370f576537edc3461899b87e71ea107
Author: Robert Ransom <rransom.8774 at gmail.com>
Date:   Fri Oct 28 18:35:55 2011 -0700

    Make introduction points expire
---
 changes/intro-point-expiration |    5 ++++
 src/or/or.h                    |   25 ++++++++++++++++++++++
 src/or/rendservice.c           |   44 ++++++++++++++++++++++++++++++++++-----
 3 files changed, 68 insertions(+), 6 deletions(-)

diff --git a/changes/intro-point-expiration b/changes/intro-point-expiration
new file mode 100644
index 0000000..3de33c1
--- /dev/null
+++ b/changes/intro-point-expiration
@@ -0,0 +1,5 @@
+  o Minor features:
+
+    - Expire old or over-used hidden service introduction points.
+      Required by fix for bug 3460.
+
diff --git a/src/or/or.h b/src/or/or.h
index 9e4cd89..9c81d0e 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -3461,6 +3461,26 @@ typedef struct rend_encoded_v2_service_descriptor_t {
  * introduction point.  See also rend_intro_point_t.unreachable_count. */
 #define MAX_INTRO_POINT_REACHABILITY_FAILURES 5
 
+/** The maximum number of distinct INTRODUCE2 cells which a hidden
+ * service's introduction point will receive before it begins to
+ * expire.
+ *
+ * XXX023 Is this number at all sane? */
+#define INTRO_POINT_LIFETIME_INTRODUCTIONS 16384
+
+/** The minimum number of seconds that an introduction point will last
+ * before expiring due to old age.  (If it receives
+ * INTRO_POINT_LIFETIME_INTRODUCTIONS INTRODUCE2 cells, it may expire
+ * sooner.)
+ *
+ * XXX023 Should this be configurable? */
+#define INTRO_POINT_LIFETIME_MIN_SECONDS 18*60*60
+/** The maximum number of seconds that an introduction point will last
+ * before expiring due to old age.
+ *
+ * XXX023 Should this be configurable? */
+#define INTRO_POINT_LIFETIME_MAX_SECONDS 24*60*60
+
 /** Introduction point information.  Used both in rend_service_t (on
  * the service side) and in rend_service_descriptor_t (on both the
  * client and service side). */
@@ -3494,6 +3514,11 @@ typedef struct rend_intro_point_t {
    * published. */
   time_t time_published;
 
+  /** (Service side only) The time at which this intro point should
+   * (start to) expire, or -1 if we haven't decided when this intro
+   * point should expire. */
+  time_t time_to_expire;
+
   /** (Service side only) The time at which we decided that this intro
    * point should start expiring, or -1 if this intro point is not yet
    * expiring.
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index fcbdff0..ee34edf 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -1917,16 +1917,47 @@ upload_service_descriptor(rend_service_t *service)
 
 /** Return non-zero iff <b>intro</b> should 'expire' now (i.e. we
  * should stop publishing it in new descriptors and eventually close
- * it).
- *
- * XXXX This is a dummy function for now.  It will actually do
- * something in a later commit. */
+ * it). */
 static int
 intro_point_should_expire_now(rend_intro_point_t *intro,
                               time_t now)
 {
-  (void)intro; (void)now;
-  return 0;
+  tor_assert(intro != NULL);
+
+  if (intro->time_published == -1) {
+    /* Don't expire an intro point if we haven't even published it yet. */
+    return 0;
+  }
+
+  if (intro->time_expiring != -1) {
+    /* We've already started expiring this intro point.  *Don't* let
+     * this function's result 'flap'. */
+    return 1;
+  }
+
+  if (intro->introduction_count >= INTRO_POINT_LIFETIME_INTRODUCTIONS) {
+    /* This intro point has been used too many times.  Expire it now. */
+    return 1;
+  }
+
+  if (intro->time_to_expire == -1) {
+    /* This intro point has been published, but we haven't picked an
+     * expiration time for it.  Pick one now. */
+    int intro_point_lifetime_seconds =
+      INTRO_POINT_LIFETIME_MIN_SECONDS +
+      crypto_rand_int(INTRO_POINT_LIFETIME_MAX_SECONDS -
+                      INTRO_POINT_LIFETIME_MIN_SECONDS);
+
+    /* Start the expiration timer now, rather than when the intro
+     * point was first published.  There shouldn't be much of a time
+     * difference. */
+    intro->time_to_expire = now + intro_point_lifetime_seconds;
+
+    return 0;
+  }
+
+  /* This intro point has a time to expire set already.  Use it. */
+  return (now >= intro->time_to_expire);
 }
 
 /** For every service, check how many intro points it currently has, and:
@@ -2107,6 +2138,7 @@ rend_services_introduce(void)
       intro->intro_key = crypto_new_pk_env();
       tor_assert(!crypto_pk_generate_key(intro->intro_key));
       intro->time_published = -1;
+      intro->time_to_expire = -1;
       intro->time_expiring = -1;
       smartlist_add(service->intro_nodes, intro);
       log_info(LD_REND, "Picked router %s as an intro point for %s.",





More information about the tor-commits mailing list