[tor-commits] [tor/master] Merge remote-tracking branch 'rransom-tor/bug3460-v4'

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


commit 628b735fe39e13cc37afb567b32d4b006da51c89
Merge: 441ab6c a2791f4
Author: Nick Mathewson <nickm at torproject.org>
Date:   Tue Nov 29 20:56:39 2011 -0500

    Merge remote-tracking branch 'rransom-tor/bug3460-v4'
    
    Conflicts:
    	src/or/rendservice.c

 changes/bug3460                                    |   11 +
 changes/intro-point-expiration                     |    5 +
 changes/per-intro-point-replay-cache               |    7 +
 .../reduce-hs-intro-dh-key-replay-cache-lifetime   |    9 +
 src/or/or.h                                        |   59 +++-
 src/or/rendcommon.c                                |    5 +
 src/or/rendservice.c                               |  348 +++++++++++++++-----
 7 files changed, 363 insertions(+), 81 deletions(-)

diff --cc src/or/rendservice.c
index e0c1a8c,2c54f30..0ded538
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@@ -1412,8 -1452,9 +1458,9 @@@ rend_service_intro_has_opened(origin_ci
  
    /* If we already have enough introduction circuits for this service,
     * redefine this one as a general circuit or close it, depending. */
-   if (count_established_intro_points(serviceid) > NUM_INTRO_POINTS) {
+   if (count_established_intro_points(serviceid) >
+       (int)service->n_intro_points_wanted) { /* XXX023 remove cast */
 -    or_options_t *options = get_options();
 +    const or_options_t *options = get_options();
      if (options->ExcludeNodes) {
        /* XXXX in some future version, we can test whether the transition is
           allowed or not given the actual nodes in the circuit.  But for now,
@@@ -1863,15 -1963,17 +1985,17 @@@ voi
  rend_services_introduce(void)
  {
    int i,j,r;
 -  routerinfo_t *router;
 +  const node_t *node;
    rend_service_t *service;
    rend_intro_point_t *intro;
-   int changed, prev_intro_nodes;
+   int intro_point_set_changed, prev_intro_nodes;
+   unsigned int n_intro_points_unexpired;
+   unsigned int n_intro_points_to_open;
 -  smartlist_t *intro_routers;
 +  smartlist_t *intro_nodes;
    time_t now;
 -  or_options_t *options = get_options();
 +  const or_options_t *options = get_options();
  
 -  intro_routers = smartlist_create();
 +  intro_nodes = smartlist_create();
    now = time(NULL);
  
    for (i=0; i < smartlist_len(rend_service_list); ++i) {
@@@ -1893,39 -2004,85 +2026,85 @@@
  
      /* Find out which introduction points we have in progress for this
         service. */
-     for (j=0; j < smartlist_len(service->intro_nodes); ++j) {
-       intro = smartlist_get(service->intro_nodes, j);
+     SMARTLIST_FOREACH_BEGIN(service->intro_nodes, rend_intro_point_t *, intro){
+       origin_circuit_t *intro_circ =
+         find_intro_circuit(intro, service->pk_digest);
+ 
+       if (intro->time_expiring + INTRO_POINT_EXPIRATION_GRACE_PERIOD > now) {
+         /* This intro point has completely expired.  Remove it, and
+          * mark the circuit for close if it's still alive. */
+         if (intro_circ != NULL) {
+           circuit_mark_for_close(TO_CIRCUIT(intro_circ),
+                                  END_CIRC_REASON_FINISHED);
+         }
+         rend_intro_point_free(intro);
+         intro = NULL; /* SMARTLIST_DEL_CURRENT takes a name, not a value. */
+         SMARTLIST_DEL_CURRENT(service->intro_nodes, intro);
+         /* We don't need to set intro_point_set_changed here, because
+          * this intro point wouldn't have been published in a current
+          * descriptor anyway. */
+         continue;
+       }
+ 
 -      router = router_get_by_digest(intro->extend_info->identity_digest);
 -      if (!router || !intro_circ) {
 +      node = node_get_by_id(intro->extend_info->identity_digest);
-       if (!node || !find_intro_circuit(intro, service->pk_digest)) {
-         log_info(LD_REND,"Giving up on %s as intro point for %s.",
++      if (!node || !intro_circ) {
+         int removing_this_intro_point_changes_the_intro_point_set = 1;
+         log_info(LD_REND, "Giving up on %s as intro point for %s"
+                  " (circuit disappeared).",
                   safe_str_client(extend_info_describe(intro->extend_info)),
                   safe_str_client(service->service_id));
-         if (service->desc) {
-           SMARTLIST_FOREACH(service->desc->intro_nodes, rend_intro_point_t *,
-                             dintro, {
-             if (tor_memeq(dintro->extend_info->identity_digest,
-                 intro->extend_info->identity_digest, DIGEST_LEN)) {
-               log_info(LD_REND, "The intro point we are giving up on was "
-                                 "included in the last published descriptor. "
-                                 "Marking current descriptor as dirty.");
-               service->desc_is_dirty = now;
-             }
-           });
+         if (intro->time_expiring != -1) {
+           log_info(LD_REND, "We were already expiring the intro point; "
+                    "no need to mark the HS descriptor as dirty over this.");
+           removing_this_intro_point_changes_the_intro_point_set = 0;
+         } else if (intro->listed_in_last_desc) {
+           log_info(LD_REND, "The intro point we are giving up on was "
+                    "included in the last published descriptor. "
+                    "Marking current descriptor as dirty.");
+           service->desc_is_dirty = now;
          }
          rend_intro_point_free(intro);
-         smartlist_del(service->intro_nodes,j--);
-         changed = 1;
+         intro = NULL; /* SMARTLIST_DEL_CURRENT takes a name, not a value. */
+         SMARTLIST_DEL_CURRENT(service->intro_nodes, intro);
+         if (removing_this_intro_point_changes_the_intro_point_set)
+           intro_point_set_changed = 1;
        }
+ 
+       if (intro != NULL && intro_point_should_expire_now(intro, now)) {
+         log_info(LD_REND, "Expiring %s as intro point for %s.",
+                  safe_str_client(extend_info_describe(intro->extend_info)),
+                  safe_str_client(service->service_id));
+ 
+         /* The polite (and generally Right) way to expire an intro
+          * point is to establish a new one to replace it, publish a
+          * new descriptor that doesn't list any expiring intro points,
+          * and *then*, once our upload attempts for the new descriptor
+          * have ended (whether in success or failure), close the
+          * expiring intro points.
+          *
+          * Unfortunately, we can't find out when the new descriptor
+          * has actually been uploaded, so we'll have to settle for a
+          * five-minute timer.  Start it.  XXX023 This sucks. */
+         intro->time_expiring = now;
+ 
+         intro_point_set_changed = 1;
+       }
+ 
+       if (intro != NULL && intro->time_expiring == -1)
+         ++n_intro_points_unexpired;
+ 
 -      if (router)
 -        smartlist_add(intro_routers, router);
 +      if (node)
 +        smartlist_add(intro_nodes, (void*)node);
-     }
- 
-     /* We have enough intro points, and the intro points we thought we had were
-      * all connected.
-      */
-     if (!changed && smartlist_len(service->intro_nodes) >= NUM_INTRO_POINTS) {
-       /* We have all our intro points! Start a fresh period and reset the
-        * circuit count. */
+     } SMARTLIST_FOREACH_END(intro);
+ 
+     if (!intro_point_set_changed &&
+         (n_intro_points_unexpired >= service->n_intro_points_wanted)) {
+       /* We have enough intro circuits in progress, and none of our
+        * intro circuits have died since the last call to
+        * rend_services_introduce!  Start a fresh period and reset the
+        * circuit count.
+        *
+        * XXXX WTF? */
        service->intro_period_started = now;
        service->n_intro_circuits_launched = 0;
        continue;
@@@ -1943,29 -2108,36 +2130,36 @@@
       * we'll drop them from the list of intro points next time we
       * go through the above "find out which introduction points we have
       * in progress" loop. */
- #define NUM_INTRO_POINTS_INIT (NUM_INTRO_POINTS + 2)
-     for (j=prev_intro_nodes; j < (prev_intro_nodes == 0 ?
-              NUM_INTRO_POINTS_INIT : NUM_INTRO_POINTS); ++j) {
+     n_intro_points_to_open = (service->n_intro_points_wanted +
+                               (prev_intro_nodes == 0 ? 2 : 0));
+     for (j = (int)n_intro_points_unexpired;
+          j < (int)n_intro_points_to_open;
+          ++j) { /* XXXX remove casts */
 -      router_crn_flags_t flags = CRN_NEED_UPTIME;
 +      router_crn_flags_t flags = CRN_NEED_UPTIME|CRN_NEED_DESC;
        if (get_options()->_AllowInvalid & ALLOW_INVALID_INTRODUCTION)
          flags |= CRN_ALLOW_INVALID;
 -      router = router_choose_random_node(intro_routers,
 -                                         options->ExcludeNodes, flags);
 -      if (!router) {
 +      node = router_choose_random_node(intro_nodes,
 +                                       options->ExcludeNodes, flags);
 +      if (!node) {
          log_warn(LD_REND,
-                  "Could only establish %d introduction points for %s.",
-                  smartlist_len(service->intro_nodes), service->service_id);
+                  "Could only establish %d introduction points for %s; "
+                  "wanted %u.",
+                  smartlist_len(service->intro_nodes), service->service_id,
+                  n_intro_points_to_open);
          break;
        }
-       changed = 1;
+       intro_point_set_changed = 1;
 -      smartlist_add(intro_routers, router);
 +      smartlist_add(intro_nodes, (void*)node);
        intro = tor_malloc_zero(sizeof(rend_intro_point_t));
 -      intro->extend_info = extend_info_from_router(router);
 +      intro->extend_info = extend_info_from_node(node);
        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.",
 -               safe_str_client(router_describe(router)),
 +               safe_str_client(node_describe(node)),
                 safe_str_client(service->service_id));
      }
  



More information about the tor-commits mailing list