[or-cvs] r12319: More tweaks from karsten, with some cleanup and commentary. (in tor/trunk: . doc src/config src/or)

nickm at seul.org nickm at seul.org
Fri Nov 2 02:25:29 UTC 2007


Author: nickm
Date: 2007-11-01 22:25:28 -0400 (Thu, 01 Nov 2007)
New Revision: 12319

Modified:
   tor/trunk/
   tor/trunk/doc/tor.1.in
   tor/trunk/src/config/torrc.complete.in
   tor/trunk/src/or/config.c
   tor/trunk/src/or/main.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/rendcommon.c
   tor/trunk/src/or/rendservice.c
   tor/trunk/src/or/routerparse.c
Log:
 r14623 at tombo:  nickm | 2007-11-01 22:25:18 -0400
 More tweaks from karsten, with some cleanup and commentary.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r14623] on d9e39d38-0f13-419c-a857-e10a0ce2aa0c

Modified: tor/trunk/doc/tor.1.in
===================================================================
--- tor/trunk/doc/tor.1.in	2007-11-01 20:00:05 UTC (rev 12318)
+++ tor/trunk/doc/tor.1.in	2007-11-02 02:25:28 UTC (rev 12319)
@@ -1107,6 +1107,11 @@
 (Default: 1)
 .LP
 .TP
+\fBHiddenServiceVersion \fR\fIversion\fR,\fIversion\fR,\fI...\fP
+A list of rendezvous service descriptor versions to publish for the hidden
+service. Possible version numbers are 0 and 2. (Default: 0, 2)
+.LP
+.TP
 \fBRendPostPeriod \fR\fIN\fR \fBseconds\fR|\fBminutes\fR|\fBhours\fR|\fBdays\fR|\fBweeks\fP
 Every time the specified period elapses, Tor uploads any rendezvous
 service descriptors to the directory servers.  This information is also

Modified: tor/trunk/src/config/torrc.complete.in
===================================================================
--- tor/trunk/src/config/torrc.complete.in	2007-11-01 20:00:05 UTC (rev 12318)
+++ tor/trunk/src/config/torrc.complete.in	2007-11-02 02:25:28 UTC (rev 12319)
@@ -521,6 +521,10 @@
 ## hidden service. In normal use there is no reason to set this.
 #HiddenServiceExcludeNodes nickname,nickname,...
 
+## Publish the given rendezvous service descriptor versions for the
+## hidden service.
+#HiddenServiceVersion 0,2
+
 ## Every time the specified period elapses, Tor uploads any ren-
 ## dezvous service descriptors to the directory servers.  This
 ## information is also uploaded whenever it changes. 

Modified: tor/trunk/src/or/config.c
===================================================================
--- tor/trunk/src/or/config.c	2007-11-01 20:00:05 UTC (rev 12318)
+++ tor/trunk/src/or/config.c	2007-11-02 02:25:28 UTC (rev 12319)
@@ -192,7 +192,6 @@
   VAR("HiddenServiceNodes",  LINELIST_S, RendConfigLines,    NULL),
   VAR("HiddenServiceOptions",LINELIST_V, RendConfigLines,    NULL),
   VAR("HiddenServicePort",   LINELIST_S, RendConfigLines,    NULL),
-  /*DOCDOC in tor manpage*/
   VAR("HiddenServiceVersion",LINELIST_S, RendConfigLines,    NULL),
   V(HSAuthoritativeDir,          BOOL,     "0"),
   V(HSAuthorityRecordStats,      BOOL,     "0"),

Modified: tor/trunk/src/or/main.c
===================================================================
--- tor/trunk/src/or/main.c	2007-11-01 20:00:05 UTC (rev 12318)
+++ tor/trunk/src/or/main.c	2007-11-02 02:25:28 UTC (rev 12319)
@@ -973,6 +973,7 @@
      * and the rend cache. */
     rep_history_clean(now - options->RephistTrackTime);
     rend_cache_clean();
+    rend_cache_clean_v2_descs_as_dir();
     /* XXX020 we only clean this stuff if DirPort is set?! -RD */
   }
 

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-11-01 20:00:05 UTC (rev 12318)
+++ tor/trunk/src/or/or.h	2007-11-02 02:25:28 UTC (rev 12319)
@@ -1785,6 +1785,11 @@
    * rendezvous service ID, but different descriptor versions.
    * XXXX020 I believe this is a bitmap, but the doc doesn't say so. If so,
    *  why?  A circuit can't be using two different rendezvous decriptors. -NM
+   * Yes, it is a bitmap. The reason is that it might turn out that a version
+   * 3 _can_ use the same introduction point as version 2; only version 0
+   * is incompatible. Would it be clearer to switch to a single version number
+   * for now and switch back to a bitmap, when the above becomes true? -KL
+   * Yes.  "YAGNI." -NM
    */
   uint8_t rend_desc_version;
 
@@ -3485,14 +3490,8 @@
 } rend_cache_entry_t;
 
 void rend_cache_init(void);
-/*XXXX020 clean *and* clean_up *and* clean_v2_dir? Rename some. */
-/*XXXX020 Call clean_up and clean_v2_dir from somewhere; nothing calls them
- * now. */
-/* Those functions were called from the (removed) replication functionality.
- * We need to call them from somewhere periodically; main()? -KL */
 void rend_cache_clean(void);
-void rend_cache_clean_up(void);
-void rend_cache_clean_v2_dir(void);
+void rend_cache_clean_v2_descs_as_dir(void);
 void rend_cache_free_all(void);
 int rend_valid_service_id(const char *query);
 int rend_cache_lookup_desc(const char *query, int version, const char **desc,

Modified: tor/trunk/src/or/rendcommon.c
===================================================================
--- tor/trunk/src/or/rendcommon.c	2007-11-01 20:00:05 UTC (rev 12318)
+++ tor/trunk/src/or/rendcommon.c	2007-11-02 02:25:28 UTC (rev 12319)
@@ -22,6 +22,8 @@
 /** Helper: Release the storage held by the intro key in <b>_ent</b>.
  */
 /*XXXX020 there's also one of these in rendservice.c */
+/* Right. But the only alternative to that (which I know) would be to
+ * write it to or.h. Should I do that? -KL */
 static void
 intro_key_free(void *_ent)
 {
@@ -436,7 +438,6 @@
     /* Add signature. */
     strlcpy(desc_str + written, "signature\n", desc_len - written);
     written += strlen(desc_str + written);
-    desc_str[written] = '\0'; /* XXXX020 strlcpy always nul-terminates. */
     if (crypto_digest(desc_digest, desc_str, written) < 0) {
       log_warn(LD_BUG, "could not create digest.");
       tor_free(desc_str);
@@ -674,25 +675,26 @@
   }
 }
 
-/** Remove all old entries on v2 hidden service directories. */
+/** Remove all old v2 descriptors and those for which this hidden service
+ * directory is not responsible for any more. */
 void
-rend_cache_clean_v2_dir(void)
+rend_cache_clean_v2_descs_as_dir(void)
 {
   digestmap_iter_t *iter;
-  const char *key;
-  void *val;
-  rend_cache_entry_t *ent;
-  time_t cutoff;
-  cutoff = time(NULL) - REND_CACHE_MAX_AGE - REND_CACHE_MAX_SKEW;
+  smartlist_t *hs_dirs = hid_serv_create_routing_table();
+  time_t cutoff = time(NULL) - REND_CACHE_MAX_AGE - REND_CACHE_MAX_SKEW;
   for (iter = digestmap_iter_init(rend_cache_v2_dir);
        !digestmap_iter_done(iter); ) {
+    const char *key;
+    void *val;
+    rend_cache_entry_t *ent;
     digestmap_iter_get(iter, &key, &val);
     ent = val;
-    if (ent->parsed->timestamp < cutoff) {
+    if (ent->parsed->timestamp < cutoff ||
+        !hid_serv_responsible_for_desc_id(key, hs_dirs)) {
       char key_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
       base32_encode(key_base32, sizeof(key_base32), key, DIGEST_LEN);
-      log_info(LD_REND, "Removing descriptor with ID '%s' from cache, "
-                        "because it is too old!",
+      log_info(LD_REND, "Removing descriptor with ID '%s' from cache",
                key_base32);
       iter = digestmap_iter_next_rmv(rend_cache_v2_dir, iter);
       _rend_cache_entry_free(ent);
@@ -700,6 +702,7 @@
       iter = digestmap_iter_next(rend_cache_v2_dir, iter);
     }
   }
+  smartlist_free(hs_dirs);
 }
 
 /** Determines whether <b>a</b> is in the interval of <b>b</b> (excluded) and
@@ -733,35 +736,6 @@
   return 1;
 }
 
-/** Clean up all values for which this node as hidden service directory is
- * not responsible */
-void
-rend_cache_clean_up(void)
-{
-  digestmap_iter_t *iter;
-  smartlist_t *hs_dirs = hid_serv_create_routing_table();
-  for (iter = digestmap_iter_init(rend_cache_v2_dir);
-       !digestmap_iter_done(iter); ) {
-    const char *key;
-    void *val;
-    rend_cache_entry_t *ent;
-    digestmap_iter_get(iter, &key, &val);
-    ent = val;
-    if (!hid_serv_responsible_for_desc_id(key, hs_dirs)) {
-      char key_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
-      base32_encode(key_base32, sizeof(key_base32),
-                    key, DIGEST_LEN);
-      log_info(LD_REND, "Removing descriptor with ID '%s' from cache, "
-                        "because we are not reponsible for it!", key_base32);
-      iter = digestmap_iter_next_rmv(rend_cache_v2_dir, iter);
-      _rend_cache_entry_free(ent);
-    } else {
-      iter = digestmap_iter_next(rend_cache_v2_dir, iter);
-    }
-  }
-  smartlist_free(hs_dirs);
-}
-
 /** Return true iff <b>query</b> is a syntactically valid service ID (as
  * generated by rend_get_service_id).  */
 int
@@ -1067,6 +1041,19 @@
 {
   /*XXXX this seems to have a bit of duplicate code with
    * rend_cache_store_v2_desc_as_dir().  Fix that. */
+  /* Though having similar elements, both functions were separated on
+   * purpose:
+   * - dirs don't care about encoded/encrypted introduction points, clients
+   *   do.
+   * - dirs store descriptors in a separate cache by descriptor ID, whereas
+   *   clients store them by service ID; both caches are different data
+   *   structures and have different access methods.
+   * - dirs store a descriptor only if they are responsible for its ID,
+   *   clients do so in every way (because they have requested it before).
+   * - dirs can process multiple concatenated descriptors which is required
+   *   for replication, whereas clients only accept a single descriptor.
+   * Thus, combining both methods would result in a lot of if statements
+   * which probably would not improve, but worsen code readability. -KL */
   rend_service_descriptor_t *parsed = NULL;
   char desc_id[DIGEST_LEN];
   char *intro_content = NULL;

Modified: tor/trunk/src/or/rendservice.c
===================================================================
--- tor/trunk/src/or/rendservice.c	2007-11-01 20:00:05 UTC (rev 12318)
+++ tor/trunk/src/or/rendservice.c	2007-11-02 02:25:28 UTC (rev 12319)
@@ -62,6 +62,11 @@
   time_t next_upload_time;
   /* XXXX020 A service never actually has both descriptor versions; perhaps
    * this should be an int rather than in intmax. */
+  /* A service can never publish v0 and v2 descriptors, but maybe it can
+   * publish v2 and v3 descriptors in the future. As with origin_circuit_t:
+   * Would it be clearer to switch to a single version number for now and
+   * switch back to a bitmap, when the above becomes true? -KL */
+  /* Yes. s/when/if/.  "YAGNI" -NM. */
   int descriptor_versions; /**< bitmask of rendezvous descriptor versions
                             * that will be published. "0" means "default." */
 } rend_service_t;
@@ -138,7 +143,8 @@
   if (!service->intro_exclude_nodes)
     service->intro_exclude_nodes = tor_strdup("");
   if (service->descriptor_versions == 0)
-    service->descriptor_versions = 1; /* Default is v0 only. */
+    service->descriptor_versions = 1 + (1<<2); /**< Default is v0 and v2 in
+                                                * parallel. */
   service->intro_keys = strmap_new();
 
   /* If the service is configured to publish unversioned (v0) and versioned
@@ -1210,7 +1216,7 @@
         log_info(LD_REND,"Giving up on %s as intro point for %s.",
                  intro, service->service_id);
         tor_free(intro);
-        /* XXXX020 We could also remove the intro key here... */
+        /* XXXXX020 we could also remove the intro key here. */
         smartlist_del(service->intro_nodes,j--);
         changed = 1;
         service->desc_is_dirty = now;

Modified: tor/trunk/src/or/routerparse.c
===================================================================
--- tor/trunk/src/or/routerparse.c	2007-11-01 20:00:05 UTC (rev 12318)
+++ tor/trunk/src/or/routerparse.c	2007-11-02 02:25:28 UTC (rev 12319)
@@ -3257,9 +3257,11 @@
   tor_assert(tok);
   tor_assert(tok->n_args == 1);
   result->version = atoi(tok->args[0]);
-  if (result->version < 2) { /*XXXX020 what if > 2? */
-                             /* Good question: should higher versions
-                              * be rejected by directories? -KL */
+  if (result->version != 2) {
+    /* If it's <2, it shouldn't be under this format.  If the number
+     * is greater than 2, we bumped it because we broke backward
+     * compatibility.  See how version numbers in our other formats
+     * work. */
     log_warn(LD_REND, "Wrong descriptor version: %d", result->version);
     goto err;
   }
@@ -3300,6 +3302,15 @@
                          SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
   for (i = 0; i < smartlist_len(versions); i++) {
     /* XXXX020 validate the numbers here. */
+    /* As above, validating these numbers on a hidden service directory
+     * might require an extension to new valid numbers at some time. But
+     * this would require making a distinction of hidden service direcoties
+     * which accept the old valid numbers and those which accept the new
+     * valid numbers. -KL */
+    /* As above, increased version numbers are for
+     * non-backward-compatible changes.  This code doesn't know how to
+     * parse a v3 descriptor, because a v3 descriptor is by definitition not 
+     * compatible with this code.  */
     version = atoi(smartlist_get(versions, i));
     result->protocols |= 1 << version;
   }
@@ -3308,7 +3319,11 @@
   /* Parse encrypted introduction points. Don't verify. */
   tok = find_first_by_keyword(tokens, R_INTRODUCTION_POINTS);
   tor_assert(tok);
-  /* XXXX020 make sure it's "BEGIN MESSAGE", not "BEGIN SOMETHINGELSE" */
+  if (strcmp(tok->object_type, "MESSAGE")) {
+    log_warn(LD_DIR, "Bad object type: introduction points should be of "
+             "type MESSAGE");
+    goto err;
+  }
   *intro_points_encrypted_out = tok->object_body;
   *intro_points_encrypted_size_out = tok->object_size;
   tok->object_body = NULL; /* Prevent free. */
@@ -3446,8 +3461,14 @@
     info->addr = ntohl(ip.s_addr);
     /* Parse onion port. */
     tok = find_first_by_keyword(tokens, R_IPO_ONION_PORT);
-    /* XXXX020 validate range. */
     info->port = (uint16_t) atoi(tok->args[0]);
+    /* XXXX020 this next check fails with ports like 65537. */
+    if (!info->port) {
+      log_warn(LD_REND, "Introduction point onion port is out of range: %d",
+               info->port);
+      tor_free(info);
+      goto err;
+    }
     /* Parse onion key. */
     tok = find_first_by_keyword(tokens, R_IPO_ONION_KEY);
     info->onion_key = tok->key;
@@ -3461,6 +3482,9 @@
   }
   /* Write extend infos to descriptor. */
   /* XXXX020 what if intro_points (&tc) are already set? */
+  /* This function is not intended to be invoced multiple times for
+   * the same descriptor. Should this be asserted? -KL */
+  /* Yes. -NM */
   parsed->n_intro_points = smartlist_len(intropoints);
   parsed->intro_point_extend_info =
     tor_malloc_zero(sizeof(extend_info_t *) * parsed->n_intro_points);



More information about the tor-commits mailing list