diff options
author | Robert Ransom <rransom.8774@gmail.com> | 2011-10-28 18:35:55 -0700 |
---|---|---|
committer | Robert Ransom <rransom.8774@gmail.com> | 2011-10-30 02:17:59 -0700 |
commit | 1eba4f0cc370f576537edc3461899b87e71ea107 (patch) | |
tree | e41f999166f5edb64a6f82ba060e92d9153fdff3 | |
parent | 00885652db8146d992bcf96315a45e7820688145 (diff) | |
download | tor-1eba4f0cc370f576537edc3461899b87e71ea107.tar.gz tor-1eba4f0cc370f576537edc3461899b87e71ea107.zip |
Make introduction points expire
-rw-r--r-- | changes/intro-point-expiration | 5 | ||||
-rw-r--r-- | src/or/or.h | 25 | ||||
-rw-r--r-- | 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 0000000000..3de33c188e --- /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 9e4cd89cf1..9c81d0e134 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 fcbdff0b92..ee34edfa6e 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.", |