Commit 7fa5d224 authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

Implement "families" of coadministered nodes; prevent them all from appearing on the same circuit.


svn:r2523
parent e448879e
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -1080,16 +1080,16 @@ static routerinfo_t *choose_good_middle_server(cpath_build_state_t *state,
  excluded = smartlist_create();
  if((r = router_get_by_digest(state->chosen_exit_digest))) {
    smartlist_add(excluded, r);
    routerlist_add_friends(excluded, r);
    routerlist_add_family(excluded, r);
  }
  if((r = routerlist_find_my_routerinfo())) {
    smartlist_add(excluded, r);
    routerlist_add_friends(excluded, r);
    routerlist_add_family(excluded, r);
  }
  for (i = 0, cpath = head; i < cur_len; ++i, cpath=cpath->next) {
    if((r = router_get_by_digest(cpath->identity_digest))) {
      smartlist_add(excluded, r);
      routerlist_add_friends(excluded, r);
      routerlist_add_family(excluded, r);
    }
  }
  choice = router_choose_random_node("", options.ExcludeNodes, excluded,
@@ -1106,11 +1106,11 @@ static routerinfo_t *choose_good_entry_server(cpath_build_state_t *state)

  if((r = router_get_by_digest(state->chosen_exit_digest))) {
    smartlist_add(excluded, r);
    routerlist_add_friends(excluded, r);
    routerlist_add_family(excluded, r);
  }
  if((r = routerlist_find_my_routerinfo())) {
    smartlist_add(excluded, r);
    routerlist_add_friends(excluded, r);
    routerlist_add_family(excluded, r);
  }
  if(options.FascistFirewall) {
    /* exclude all ORs that listen on the wrong port */
+39 −4
Original line number Diff line number Diff line
@@ -244,6 +244,7 @@ config_assign(or_options_t *options, struct config_line_t *list)

      config_compare(list, "FascistFirewall",CONFIG_TYPE_BOOL, &options->FascistFirewall) ||
      config_compare(list, "FirewallPorts",CONFIG_TYPE_CSV, &options->FirewallPorts) ||
      config_compare(list, "MyFamily",      CONFIG_TYPE_STRING, &options->MyFamily) ||

      config_compare(list, "Group",          CONFIG_TYPE_STRING, &options->Group) ||

@@ -517,6 +518,7 @@ init_options(or_options_t *options)
  options->RendConfigLines = NULL;
  options->FirewallPorts = NULL;
  options->DirServers = NULL;
  options->MyFamily = NULL;
}

static char *
@@ -554,6 +556,30 @@ get_default_conf_file(void)
#endif
}

/** Verify whether lst is a string containing valid-looking space-separated
 * nicknames, or NULL. Return 0 on success. Warn and return -1 on failure.
 */
static int check_nickname_list(const char *lst, const char *name)
{ 
  int r = 0;
  smartlist_t *sl;

  if (!lst)
    return 0;
  sl = smartlist_create();
  smartlist_split_string(sl, lst, ",", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  SMARTLIST_FOREACH(sl, const char *, s,
    {
      if (!is_legal_nickname_or_hexdigest(s)) {
        log_fn(LOG_WARN, "Invalid nickname '%s' in %s line", s, name);
        r = -1;
      }
    });
  SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
  smartlist_free(sl); 
  return r;
}

/** Read a configuration file into <b>options</b>, finding the configuration
 * file location based on the command line.  After loading the options,
 * validate them for consistency. Return 0 if success, <0 if failure. */
@@ -838,6 +864,19 @@ getconfig(int argc, char **argv, or_options_t *options)
    }
  }

  if (check_nickname_list(options->ExitNodes, "ExitNodes"))
    return -1;
  if (check_nickname_list(options->EntryNodes, "EntryNodes"))
    return -1;
  if (check_nickname_list(options->ExcludeNodes, "ExcludeNodes"))
    return -1;
  if (check_nickname_list(options->RendNodes, "RendNodes"))
    return -1;
  if (check_nickname_list(options->RendNodes, "RendExcludeNodes"))
    return -1;
  if (check_nickname_list(options->MyFamily, "MyFamily"))
    return -1;
  
  clear_trusted_dir_servers();
  if (!options->DirServers) {
    add_default_trusted_dirservers();
@@ -848,10 +887,6 @@ getconfig(int argc, char **argv, or_options_t *options)
    }
  }

  /* XXX look at the various nicknamelists and make sure they're
   * valid and don't have hostnames that are too long.
   */

  if (rend_config_services(options) < 0) {
    result = -1;
  }
+4 −3
Original line number Diff line number Diff line
@@ -597,6 +597,8 @@ typedef struct {
  int is_verified; /**< Has a trusted dirserver validated this OR? */
  int is_trusted_dir; /**< Do we trust this OR as a directory server? */

  smartlist_t *declared_family; /**< Nicknames of router which this router
                                 * claims are its family. */
} routerinfo_t;

/** Contents of a directory of onion routers. */
@@ -890,8 +892,6 @@ typedef struct {
  int NumCpus; /**< How many CPUs should we try to use? */
  int RunTesting; /**< If true, create testing circuits to measure how well the
                   * other ORs are running. */
  struct config_line_t *TrustedDirs; /**< List of fingerprints of keys that are
                                          allowed to sign directories. */
  struct config_line_t *RendConfigLines; /**< List of configuration lines
                                          * for rendezvous services. */
  char *ContactInfo; /**< Contact info to be published in the directory */
@@ -902,6 +902,7 @@ typedef struct {

  struct config_line_t *DirServers; /**< List of configuration lines
                                     * for directory servers. */
  char *MyFamily; /**< Declared family for this OR. */
} or_options_t;

/* XXX are these good enough defaults? */
@@ -1415,7 +1416,7 @@ routerinfo_t *router_pick_directory_server(int requireothers);
trusted_dir_server_t *router_pick_trusteddirserver(int requireothers);
int all_trusted_directory_servers_down(void);
struct smartlist_t;
void routerlist_add_friends(struct smartlist_t *sl, routerinfo_t *router);
void routerlist_add_family(struct smartlist_t *sl, routerinfo_t *router);
void add_nickname_list_to_smartlist(struct smartlist_t *sl, const char *list, int warn_if_down);
routerinfo_t *routerlist_find_my_routerinfo(void);
int router_nickname_matches(routerinfo_t *router, const char *nickname);
+20 −2
Original line number Diff line number Diff line
@@ -552,6 +552,13 @@ int router_rebuild_descriptor(void) {
  ri->is_trusted_dir = authdir_mode();
  if(desc_routerinfo) /* inherit values */
    ri->is_verified = desc_routerinfo->is_verified;
  if (options.MyFamily) {
    ri->declared_family = smartlist_create();
    smartlist_split_string(ri->declared_family, options.MyFamily, ",",
                           SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  } else {
    ri->declared_family = NULL;
  }

  if (desc_routerinfo)
    routerinfo_free(desc_routerinfo);
@@ -600,6 +607,7 @@ int router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
  int result=0;
  struct exit_policy_t *tmpe;
  char *bandwidth_usage;
  char *family_line;
#ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
  char *s_tmp, *s_dup;
  const char *cp;
@@ -639,6 +647,16 @@ int router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
  /* How busy have we been? */
  bandwidth_usage = rep_hist_get_bandwidth_lines();

  if (router->declared_family && smartlist_len(router->declared_family)) {
    char *s = smartlist_join_strings(router->declared_family, " ", 0);
    size_t n = strlen(s) + strlen("opt family ") + 2; /* 1 for \n, 1 for \0. */
    family_line = tor_malloc(n);
    snprintf(family_line, n, "opt family %s\n", s);
    tor_free(s);
  } else {
    family_line = tor_strdup("");
  }

  /* Generate the easy portion of the router descriptor. */
  result = snprintf(s, maxlen,
                    "router %s %s %d %d %d\n"
@@ -648,7 +666,7 @@ int router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
                    "opt uptime %ld\n"
                    "bandwidth %d %d %d\n"
                    "onion-key\n%s"
                    "signing-key\n%s%s",
                    "signing-key\n%s%s%s",
    router->nickname,
    router->address,
    router->or_port,
@@ -665,7 +683,7 @@ int router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
    (int) router->bandwidthburst,
    (int) router->bandwidthcapacity,
    onion_pkey, identity_pkey,
    bandwidth_usage);
    family_line, bandwidth_usage);

  tor_free(onion_pkey);
  tor_free(identity_pkey);
+29 −3
Original line number Diff line number Diff line
@@ -225,11 +225,28 @@ int all_trusted_directory_servers_down(void) {
  return 1;
}

/** Add all the friends of <b>router</b> to the smartlist <b>sl</b>.
/** Add all the family of <b>router</b> to the smartlist <b>sl</b>.
 */
void routerlist_add_friends(smartlist_t *sl, routerinfo_t *router) {
void routerlist_add_family(smartlist_t *sl, routerinfo_t *router) {
  routerinfo_t *r;

  if (!router->declared_family)
    return;
  
  /* Add every r such that router declares familyhip with r, and r
   * declares familyhip with router. */
  SMARTLIST_FOREACH(router->declared_family, const char *, n,
    {
      if (!(r = router_get_by_nickname(n)))
        continue;
      if (!r->declared_family)
        continue;
      SMARTLIST_FOREACH(r->declared_family, const char *, n2,
        {
          if (router_nickname_matches(router, n2))
            smartlist_add(sl, r);
        });
    });
}

/** Given a comma-and-whitespace separated list of nicknames, see which
@@ -583,6 +600,10 @@ void routerinfo_free(routerinfo_t *router)
    crypto_free_pk_env(router->onion_pkey);
  if (router->identity_pkey)
    crypto_free_pk_env(router->identity_pkey);
  if (router->declared_family) {
    SMARTLIST_FOREACH(router->declared_family, char *, s, tor_free(s));
    smartlist_free(router->declared_family);
  }
  exit_policy_free(router->exit_policy);
  tor_free(router);
}
@@ -611,6 +632,11 @@ routerinfo_t *routerinfo_copy(const routerinfo_t *router)
    (*e)->string = tor_strdup((*e)->string);
    e = & ((*e)->next);
  }
  if (r->declared_family) {
    r->declared_family = smartlist_create();
    SMARTLIST_FOREACH(router->declared_family, const char *, s,
                      smartlist_add(r->declared_family, tor_strdup(s)));
  }
  return r;
}

Loading