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

[or-cvs] r10144: Change authority_type_t to a set of flags; use it more consi (in tor/trunk: . src/or)



Author: nickm
Date: 2007-05-09 00:15:46 -0400 (Wed, 09 May 2007)
New Revision: 10144

Modified:
   tor/trunk/
   tor/trunk/src/or/circuitbuild.c
   tor/trunk/src/or/config.c
   tor/trunk/src/or/directory.c
   tor/trunk/src/or/dirserv.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/router.c
   tor/trunk/src/or/routerlist.c
Log:
 r12697@catbus:  nickm | 2007-05-09 00:15:40 -0400
 Change authority_type_t to a set of flags; use it more consistently.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r12697] on 8246c3cf-6607-4228-993b-4d95d33730f1

Modified: tor/trunk/src/or/circuitbuild.c
===================================================================
--- tor/trunk/src/or/circuitbuild.c	2007-05-09 02:20:03 UTC (rev 10143)
+++ tor/trunk/src/or/circuitbuild.c	2007-05-09 04:15:46 UTC (rev 10144)
@@ -1740,7 +1740,8 @@
  * It's a general purpose router unless it's on our bridges list.
  */
 static uint8_t
-get_router_purpose_from_digest(char *digest) {
+get_router_purpose_from_digest(char *digest)
+{
   (void)digest;
   return ROUTER_PURPOSE_GENERAL; /* XXX020 */
 }

Modified: tor/trunk/src/or/config.c
===================================================================
--- tor/trunk/src/or/config.c	2007-05-09 02:20:03 UTC (rev 10143)
+++ tor/trunk/src/or/config.c	2007-05-09 04:15:46 UTC (rev 10144)
@@ -211,7 +211,7 @@
   VAR("PidFile",             STRING,   PidFile,              NULL),
   VAR("PreferTunneledDirConns", BOOL,  PreferTunneledDirConns, "0"),
   VAR("ProtocolWarnings",    BOOL,     ProtocolWarnings,     "0"),
-  VAR("PublishServerDescriptor",STRING,PublishServerDescriptor,"v2"),
+  VAR("PublishServerDescriptor", CSV,  PublishServerDescriptor,"v1,v2"),
   VAR("PublishHidServDescriptors",BOOL,PublishHidServDescriptors, "1"),
   VAR("ReachableAddresses",  LINELIST, ReachableAddresses,   NULL),
   VAR("ReachableDirAddresses",LINELIST,ReachableDirAddresses,NULL),
@@ -1929,7 +1929,7 @@
 
   tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
   if (is_internal_IP(ntohl(in.s_addr), 0) &&
-      options->_PublishServerDescriptor != NO_AUTHORITY) {
+      options->_PublishServerDescriptor) {
     /* make sure we're ok with publishing an internal IP */
     if (!options->DirServers) {
       /* if they are using the default dirservers, disallow internal IPs
@@ -2308,27 +2308,33 @@
   return 0;
 }
 
-/** Parse an authority type from <b>string</b> and write it to *<b>auth</b>.
- * If <b>compatible</b> is non-zero, treat "1" as "v2" and treat "0" as "".
- * Return 0 on success or -1 if not a recognized authority type.
+/** Parse an authority type from <b>list</b> and write it to *<b>auth</b>.  If
+ * <b>compatible</b> is non-zero, treat "1" as "v1,v2" and treat "0" as "".
+ * Return 0 on success or -(idx of first bad member) if not a recognized
+ * authority type.
  */
 static int
-parse_authority_type_from_string(const char *string, authority_type_t *auth,
-                                 int compatible)
+parse_authority_type_from_list(smartlist_t *list, authority_type_t *auth,
+                               int compatible)
 {
   tor_assert(auth);
-  if (!strcasecmp(string, "v1"))
-    *auth = V1_AUTHORITY;
-  else if (!strcasecmp(string, "v2") || (compatible && !strcmp(string, "1")))
-    *auth = V2_AUTHORITY;
-  else if (!strcasecmp(string, "bridge"))
-    *auth = BRIDGE_AUTHORITY;
-  else if (!strcasecmp(string, "hidserv"))
-    *auth = HIDSERV_AUTHORITY;
-  else if (!strcasecmp(string, "") || (compatible && !strcmp(string, "0")))
-    *auth = NO_AUTHORITY;
-  else
-    return -1;
+  *auth = 0;
+  SMARTLIST_FOREACH(list, const char *, string, {
+    if (!strcasecmp(string, "v1"))
+      *auth |= V1_AUTHORITY;
+    else if (compatible && !strcmp(string, "1"))
+      *auth |= V1_AUTHORITY | V2_AUTHORITY;
+    else if (!strcasecmp(string, "v2"))
+      *auth |= V2_AUTHORITY;
+    else if (!strcasecmp(string, "bridge"))
+      *auth |= BRIDGE_AUTHORITY;
+    else if (!strcasecmp(string, "hidserv"))
+      *auth |= HIDSERV_AUTHORITY;
+    else if (!strcasecmp(string, "") || (compatible && !strcmp(string, "0")))
+      /* no authority */;
+    else
+      return - string_sl_idx;
+    });
   return 0;
 }
 
@@ -2473,8 +2479,9 @@
   if (options->NoPublish) {
     log(LOG_WARN, LD_CONFIG,
         "NoPublish is obsolete. Use PublishServerDescriptor instead.");
-    tor_free(options->PublishServerDescriptor);
-    options->PublishServerDescriptor = tor_strdup("");
+    SMARTLIST_FOREACH(options->PublishServerDescriptor, char *, s,
+                      tor_free(s));
+    smartlist_clear(options->PublishServerDescriptor);
   }
 
   if (authdir_mode(options)) {
@@ -2681,11 +2688,11 @@
       });
   }
 
-  if (parse_authority_type_from_string(options->PublishServerDescriptor,
-                               &options->_PublishServerDescriptor, 1) < 0) {
+  if ((i = parse_authority_type_from_list(options->PublishServerDescriptor,
+                               &options->_PublishServerDescriptor, 1) < 0)) {
     r = tor_snprintf(buf, sizeof(buf),
         "Unrecognized value '%s' for PublishServerDescriptor",
-        options->PublishServerDescriptor);
+                  (char*)smartlist_get(options->PublishServerDescriptor, -i));
     *msg = tor_strdup(r >= 0 ? buf : "internal error");
     return -1;
   }
@@ -3564,9 +3571,8 @@
   char *addrport=NULL, *address=NULL, *nickname=NULL, *fingerprint=NULL;
   uint16_t dir_port = 0, or_port = 0;
   char digest[DIGEST_LEN];
-  int is_v1_authority = 0, is_hidserv_authority = 0,
-    is_not_hidserv_authority = 0, is_v2_authority = 1,
-    is_bridge_authority = 0;
+  authority_type_t type = V2_AUTHORITY;
+  int is_not_hidserv_authority = 0, is_not_v2_authority = 0;
 
   items = smartlist_create();
   smartlist_split_string(items, line, NULL,
@@ -3586,15 +3592,15 @@
     if (TOR_ISDIGIT(flag[0]))
       break;
     if (!strcasecmp(flag, "v1")) {
-      is_v1_authority = is_hidserv_authority = 1;
+      type |= (V1_AUTHORITY | HIDSERV_AUTHORITY);
     } else if (!strcasecmp(flag, "hs")) {
-      is_hidserv_authority = 1;
+      type |= HIDSERV_AUTHORITY;
     } else if (!strcasecmp(flag, "no-hs")) {
       is_not_hidserv_authority = 1;
     } else if (!strcasecmp(flag, "bridge")) {
-      is_bridge_authority = 1;
+      type |= BRIDGE_AUTHORITY;
     } else if (!strcasecmp(flag, "no-v2")) {
-      is_v2_authority = 0;
+      is_not_v2_authority = 1;
     } else if (!strcasecmpstart(flag, "orport=")) {
       int ok;
       char *portstring = flag + strlen("orport=");
@@ -3609,9 +3615,10 @@
     tor_free(flag);
     smartlist_del_keeporder(items, 0);
   }
-
   if (is_not_hidserv_authority)
-    is_hidserv_authority = 0;
+    type &= ~HIDSERV_AUTHORITY;
+  if (is_not_v2_authority)
+    type &= ~V2_AUTHORITY;
 
   if (smartlist_len(items) < 2) {
     log_warn(LD_CONFIG, "Too few arguments to DirServer line.");
@@ -3642,10 +3649,7 @@
     log_debug(LD_DIR, "Trusted dirserver at %s:%d (%s)", address,
               (int)dir_port,
               (char*)smartlist_get(items,0));
-    add_trusted_dir_server(nickname, address, dir_port, or_port, digest,
-                           is_v1_authority, is_v2_authority,
-                           is_bridge_authority, is_hidserv_authority);
-
+    add_trusted_dir_server(nickname, address, dir_port, or_port, digest, type);
   }
 
   r = 0;

Modified: tor/trunk/src/or/directory.c
===================================================================
--- tor/trunk/src/or/directory.c	2007-05-09 02:20:03 UTC (rev 10143)
+++ tor/trunk/src/or/directory.c	2007-05-09 04:15:46 UTC (rev 10144)
@@ -83,17 +83,27 @@
   return 1;
 }
 
-/** Return a static string describing <b>auth</b>. */
-const char *
+/** Return a newly allocated string describing <b>auth</b>. */
+char *
 authority_type_to_string(authority_type_t auth)
 {
-  switch(auth) {
-    case V1_AUTHORITY: return "V1";
-    case V2_AUTHORITY: return "V2";
-    case BRIDGE_AUTHORITY: return "Bridge";
-    case HIDSERV_AUTHORITY: return "Hidden service";
-    case NO_AUTHORITY: default: return "[Unexpected authority type]";
+  char *result;
+  smartlist_t *lst = smartlist_create();
+  if (auth & V1_AUTHORITY)
+    smartlist_add(lst, (void*)"V1");
+  if (auth & V2_AUTHORITY)
+    smartlist_add(lst, (void*)"V2");
+  if (auth & BRIDGE_AUTHORITY)
+    smartlist_add(lst, (void*)"Bridge");
+  if (auth & HIDSERV_AUTHORITY)
+    smartlist_add(lst, (void*)"Hidden service");
+  if (smartlist_len(lst)) {
+    result = smartlist_join_strings(lst, ", ", 0, NULL);
+  } else {
+    result = tor_strdup("[Not an authority]");
   }
+  smartlist_free(lst);
+  return result;
 }
 
 /** Start a connection to every suitable directory server, using
@@ -124,16 +134,11 @@
       local_routerstatus_t *lrs = router_get_combined_status_by_digest(
                                                 ds->digest);
       int new_enough;
+      size_t upload_len = payload_len;
 
-      size_t upload_len = payload_len;
-      if (type == HIDSERV_AUTHORITY && !ds->is_hidserv_authority)
+      if ((type & ds->type) == 0)
         continue;
-      if (type == BRIDGE_AUTHORITY && !ds->is_bridge_authority)
-        continue;
-      if (type == V1_AUTHORITY && !ds->is_v1_authority)
-        continue;
-      if (type == V2_AUTHORITY && !ds->is_v2_authority)
-        continue;
+
       found = 1; /* at least one authority of this type was listed */
       if (purpose == DIR_PURPOSE_UPLOAD_DIR)
         ds->has_accepted_serverdesc = 0;
@@ -152,9 +157,10 @@
                                               NULL, payload, upload_len);
     });
   if (!found) {
+    char *s = authority_type_to_string(type);
     log_warn(LD_DIR, "Publishing server descriptor to directory authorities "
-             "of type '%s', but no authorities of that type listed!",
-             authority_type_to_string(type));
+             "of type '%s', but no authorities of that type listed!", s);
+    tor_free(s);
   }
 }
 
@@ -1234,7 +1240,7 @@
           ds->has_accepted_serverdesc = 1;
           servers = router_get_trusted_dir_servers();
           SMARTLIST_FOREACH(servers, trusted_dir_server_t *, d, {
-              if ((d->is_v1_authority || d->is_v2_authority) &&
+              if ((d->type & (V1_AUTHORITY|V2_AUTHORITY)) &&
                   !d->has_accepted_serverdesc) {
                 all_done = 0;
                 break;

Modified: tor/trunk/src/or/dirserv.c
===================================================================
--- tor/trunk/src/or/dirserv.c	2007-05-09 02:20:03 UTC (rev 10143)
+++ tor/trunk/src/or/dirserv.c	2007-05-09 04:15:46 UTC (rev 10144)
@@ -1840,7 +1840,7 @@
     } else {
       SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
                   trusted_dir_server_t *, ds,
-                  if (ds->is_v2_authority)
+                  if (ds->type & V2_AUTHORITY)
                     smartlist_add(result, tor_memdup(ds->digest, DIGEST_LEN)));
     }
     smartlist_sort_digests(result);

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-05-09 02:20:03 UTC (rev 10143)
+++ tor/trunk/src/or/or.h	2007-05-09 04:15:46 UTC (rev 10144)
@@ -1311,9 +1311,13 @@
   time_t expires;
 } authority_cert_t;
 
+/** DOCDOC */
 typedef enum {
-  NO_AUTHORITY=0, V1_AUTHORITY, V2_AUTHORITY,
-  HIDSERV_AUTHORITY, BRIDGE_AUTHORITY
+  NO_AUTHORITY      = 0,
+  V1_AUTHORITY      = 1 << 0,
+  V2_AUTHORITY      = 1 << 1,
+  HIDSERV_AUTHORITY = 1 << 2,
+  BRIDGE_AUTHORITY  = 1 << 3,
 } authority_type_t;
 
 #define CRYPT_PATH_MAGIC 0x70127012u
@@ -1757,7 +1761,7 @@
   int NoPublish;
   /** To what authority types do we publish our descriptor? Choices are
    * "v1", "v2", "bridge", or "". */
-  char *PublishServerDescriptor;
+  smartlist_t *PublishServerDescriptor;
   /** An authority type, derived from PublishServerDescriptor. */
   authority_type_t _PublishServerDescriptor;
   /** Boolean: do we publish hidden service descriptors to the HS auths? */
@@ -2519,7 +2523,7 @@
 
 /********************************* directory.c ***************************/
 
-const char *authority_type_to_string(authority_type_t auth);
+char *authority_type_to_string(authority_type_t auth);
 void directory_post_to_dirservers(uint8_t purpose, authority_type_t type,
                                   const char *payload,
                                   size_t payload_len, size_t extrainfo_len);
@@ -3029,20 +3033,14 @@
   uint16_t or_port; /**< OR port: Used for tunneling connections. */
   char digest[DIGEST_LEN]; /**< Digest of identity key. */
   unsigned int is_running:1; /**< True iff we think this server is running. */
-  /** True iff this server is an authority for the older ("v1") directory
-   * protocol. */
-  unsigned int is_v1_authority:1;
-  /** True iff this server is an authority for the newer ("v2") directory
-   * protocol. */
-  unsigned int is_v2_authority:1;
-  /** True iff this server is an authority for bridge relays. */
-  unsigned int is_bridge_authority:1;
-  /** True iff this server is an authority for hidden services. */
-  unsigned int is_hidserv_authority:1;
+
   /** True iff this server has accepted the most recent server descriptor
    * we tried to upload to it. */
   unsigned int has_accepted_serverdesc:1;
 
+  /** DOCDOC */
+  authority_type_t type;
+
   int n_networkstatus_failures; /**< How many times have we asked for this
                                  * server's network-status unsuccessfully? */
   local_routerstatus_t fake_status; /**< Used when we need to pass this trusted
@@ -3137,9 +3135,7 @@
 
 void add_trusted_dir_server(const char *nickname, const char *address,
                             uint16_t dir_port, uint16_t or_port,
-                            const char *digest, int is_v1_authority,
-                            int is_v2_authority, int is_bridge_authority,
-                            int is_hidserv_authority);
+                            const char *digest, authority_type_t type);
 void clear_trusted_dir_servers(void);
 int any_trusted_dir_is_v1_authority(void);
 networkstatus_t *networkstatus_get_by_digest(const char *digest);
@@ -3237,7 +3233,5 @@
 authority_cert_t *authority_cert_parse_from_string(const char *s,
                                                    char **end_of_string);
 
-
-
 #endif
 

Modified: tor/trunk/src/or/router.c
===================================================================
--- tor/trunk/src/or/router.c	2007-05-09 02:20:03 UTC (rev 10143)
+++ tor/trunk/src/or/router.c	2007-05-09 04:15:46 UTC (rev 10144)
@@ -242,6 +242,7 @@
   char *cp;
   or_options_t *options = get_options();
   or_state_t *state = get_or_state();
+  authority_type_t type;
 
   if (!key_lock)
     key_lock = tor_mutex_new();
@@ -371,15 +372,17 @@
   }
   /* 6b. [authdirserver only] add own key to approved directories. */
   crypto_pk_get_digest(get_identity_key(), digest);
+  type = ((options->V1AuthoritativeDir ? V1_AUTHORITY : 0) |
+          (options->V2AuthoritativeDir ? V2_AUTHORITY : 0) |
+          (options->BridgeAuthoritativeDir ? BRIDGE_AUTHORITY : 0) |
+          (options->HSAuthoritativeDir ? HIDSERV_AUTHORITY : 0));
+
   if (!router_digest_is_trusted_dir(digest)) {
     add_trusted_dir_server(options->Nickname, NULL,
                            (uint16_t)options->DirPort,
                            (uint16_t)options->ORPort,
                            digest,
-                           options->V1AuthoritativeDir, /* v1 authority */
-                           options->V2AuthoritativeDir, /* v2 authority */
-                           options->BridgeAuthoritativeDir, /* bridge auth */
-                           options->HSAuthoritativeDir /*hidserv authority*/);
+                           type);
   }
   return 0; /* success */
 }

Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c	2007-05-09 02:20:03 UTC (rev 10143)
+++ tor/trunk/src/or/routerlist.c	2007-05-09 04:15:46 UTC (rev 10144)
@@ -100,19 +100,22 @@
  * listed by the authorities  */
 static int have_warned_about_new_version = 0;
 
-/** Return the number of v2 directory authorities */
+/** Return the number of directory authorities whose type matches some bit set
+ * in <b>type</b>  */
 static INLINE int
-get_n_v2_authorities(void)
+get_n_authorities(authority_type_t type)
 {
   int n = 0;
   if (!trusted_dir_servers)
     return 0;
   SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
-                    if (ds->is_v2_authority)
+                    if (ds->type & type)
                       ++n);
   return n;
 }
 
+#define get_n_v2_authorities() get_n_authorities(V2_AUTHORITY)
+
 /** Repopulate our list of network_status_t objects from the list cached on
  * disk.  Return 0 on success, -1 on failure. */
 int
@@ -709,12 +712,8 @@
       int is_overloaded =
           d->fake_status.last_dir_503_at + DIR_503_TIMEOUT > now;
       if (!d->is_running) continue;
-      if (type == V1_AUTHORITY && !d->is_v1_authority)
+      if ((type & d->type) == 0)
         continue;
-      if (type == V2_AUTHORITY && !d->is_v2_authority)
-        continue;
-      if (type == HIDSERV_AUTHORITY && !d->is_hidserv_authority)
-        continue;
       if (requireother && me && router_digest_is_me(d->digest))
           continue;
       if (prefer_tunnel &&
@@ -2713,7 +2712,7 @@
   base16_encode(fp, HEX_DIGEST_LEN+1, ns->identity_digest, DIGEST_LEN);
   if (!(trusted_dir =
         router_get_trusteddirserver_by_digest(ns->identity_digest)) ||
-      !trusted_dir->is_v2_authority) {
+      !(trusted_dir->type & V2_AUTHORITY)) {
     log_info(LD_DIR, "Network status was signed, but not by an authoritative "
              "directory we recognize.");
     if (!get_options()->DirPort) {
@@ -3066,7 +3065,7 @@
     SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
        {
          char resource[HEX_DIGEST_LEN+6]; /* fp/hexdigit.z\0 */
-         if (!ds->is_v2_authority)
+         if (!(ds->type & V2_AUTHORITY))
            continue;
          if (router_digest_is_me(ds->digest))
            continue;
@@ -3133,7 +3132,7 @@
   SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
      {
        networkstatus_t *ns = networkstatus_get_by_digest(ds->digest);
-       if (!ds->is_v2_authority)
+       if (!(ds->type & V2_AUTHORITY))
          continue;
        ++n_dirservers;
        if (ds->n_networkstatus_failures > NETWORKSTATUS_N_ALLOWABLE_FAILURES)
@@ -3183,7 +3182,7 @@
       if (i >= n_dirservers)
         i = 0;
       ds = smartlist_get(trusted_dir_servers, i);
-      if (! ds->is_v2_authority)
+      if (!(ds->type & V2_AUTHORITY))
         continue;
       if (n_failed < n_dirservers &&
           ds->n_networkstatus_failures > NETWORKSTATUS_N_ALLOWABLE_FAILURES) {
@@ -3263,9 +3262,7 @@
 void
 add_trusted_dir_server(const char *nickname, const char *address,
                        uint16_t dir_port, uint16_t or_port,
-                       const char *digest, int is_v1_authority,
-                       int is_v2_authority, int is_bridge_authority,
-                       int is_hidserv_authority)
+                       const char *digest, authority_type_t type)
 {
   trusted_dir_server_t *ent;
   uint32_t a;
@@ -3299,10 +3296,7 @@
   ent->dir_port = dir_port;
   ent->or_port = or_port;
   ent->is_running = 1;
-  ent->is_v1_authority = is_v1_authority;
-  ent->is_v2_authority = is_v2_authority;
-  ent->is_bridge_authority = is_bridge_authority;
-  ent->is_hidserv_authority = is_hidserv_authority;
+  ent->type = type;
   memcpy(ent->digest, digest, DIGEST_LEN);
 
   dlen = 64 + strlen(hostname) + (nickname?strlen(nickname):0);
@@ -3361,8 +3355,8 @@
 any_trusted_dir_is_v1_authority(void)
 {
   if (trusted_dir_servers)
-    SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ent,
-                      if (ent->is_v1_authority) return 1);
+    return get_n_authorities(V1_AUTHORITY) > 0;
+
   return 0;
 }
 
@@ -4545,7 +4539,7 @@
 
   SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
     {
-      if (!ds->is_v2_authority)
+      if (!(ds->type & V2_AUTHORITY))
         continue;
       /* If we don't have the status, and we haven't failed to get the status,
        * we haven't tried to get the status. */