Commit 33e2053e authored by Nick Mathewson's avatar Nick Mathewson 🐘
Browse files

Make return code from router_add_to_routerlist a nice sensible enum. Based on...

Make return code from router_add_to_routerlist a nice sensible enum.  Based on patch from Sebastian.

svn:r17656
parent 43393b4b
Loading
Loading
Loading
Loading
+17 −17
Changes for src/or/directory.c: 17 added lines, 17 removed lines.
Original line number Diff line number Diff line
@@ -3061,34 +3061,34 @@ directory_handle_command_post(dir_connection_t *conn, const char *headers,

  if (authdir_mode_handles_descs(options, -1) &&
      !strcmp(url,"/tor/")) { /* server descriptor post */
    const char *msg = NULL;
    const char *msg = "[None]";
    uint8_t purpose = authdir_mode_bridge(options) ?
                      ROUTER_PURPOSE_BRIDGE : ROUTER_PURPOSE_GENERAL;
    int r = dirserv_add_multiple_descriptors(body, purpose,
    was_router_added_t r = dirserv_add_multiple_descriptors(body, purpose,
                                             conn->_base.address, &msg);
    tor_assert(msg);
    if (r > 0)
    if (WRA_WAS_ADDED(r))
      dirserv_get_directory(); /* rebuild and write to disk */
    switch (r) {
      case -1:
        log_notice(LD_DIRSERV,
                   "Rejected router descriptor or extra-info from %s "

    if (r == ROUTER_ADDED_NOTIFY_GENERATOR) {
      /* Accepted with a message. */
      log_info(LD_DIRSERV,
               "Problematic router descriptor or extra-info from %s "
               "(\"%s\").",
               conn->_base.address, msg);
        /* fall through */
      case 1:
        /* malformed descriptor, or something wrong */
      write_http_status_line(conn, 400, msg);
        break;
      case 0: /* accepted but discarded */
    } else if (r == ROUTER_ADDED_SUCCESSFULLY) {
      write_http_status_line(conn, 200, msg);
    } else if (WRA_WAS_OUTDATED(r)) {
      write_http_response_header_impl(conn, -1, NULL, NULL,
                                      "X-Descriptor-Not-New: Yes\r\n", -1);
        break;
      case 2: /* accepted */
        write_http_status_line(conn, 200, msg);
        break;
    } else {
      log_info(LD_DIRSERV,
               "Rejected router descriptor or extra-info from %s "
               "(\"%s\").",
               conn->_base.address, msg);
      write_http_status_line(conn, 400, msg);
    }
    goto done;
  }

  if (options->HSAuthoritativeDir &&
+27 −11
Changes for src/or/dirserv.c: 27 added lines, 11 removed lines.
Original line number Diff line number Diff line
@@ -564,14 +564,27 @@ authdir_wants_to_reject_router(routerinfo_t *ri, const char **msg,
  return 0;
}

/** True iff <b>a</b> is more severe than <b>b</b> */
static int
WRA_MORE_SEVERE(was_router_added_t a, was_router_added_t b)
{
  if (b == ROUTER_ADDED_SUCCESSFULLY) {
    return a;
  } else if (b == ROUTER_ADDED_NOTIFY_GENERATOR) {
    return !WRA_WAS_ADDED(a);
  } else {
    return a < b;
  }
}

/** As for dirserv_add_descriptor, but accepts multiple documents, and
 * returns the most severe error that occurred for any one of them. */
int
was_router_added_t
dirserv_add_multiple_descriptors(const char *desc, uint8_t purpose,
                                 const char *source,
                                 const char **msg)
{
  int r=100; /* higher than any actual return value. */
  int r=ROUTER_ADDED_NOTIFY_GENERATOR; /* highest possible return value. */
  int r_tmp;
  const char *msg_out;
  smartlist_t *list;
@@ -603,7 +616,7 @@ dirserv_add_multiple_descriptors(const char *desc, uint8_t purpose,
        msg_out = NULL;
        tor_assert(ri->purpose == purpose);
        r_tmp = dirserv_add_descriptor(ri, &msg_out);
        if (r_tmp < r) {
        if (WRA_MORE_SEVERE(r_tmp, r)) {
          r = r_tmp;
          *msg = msg_out;
        }
@@ -619,7 +632,7 @@ dirserv_add_multiple_descriptors(const char *desc, uint8_t purpose,
        msg_out = NULL;

        r_tmp = dirserv_add_extrainfo(ei, &msg_out);
        if (r_tmp < r) {
        if (WRA_MORE_SEVERE(r_tmp, r)) {
          r = r_tmp;
          *msg = msg_out;
        }
@@ -638,25 +651,27 @@ dirserv_add_multiple_descriptors(const char *desc, uint8_t purpose,
    }
  }

  return r <= 2 ? r : 2;
  return r;
}

/** Examine the parsed server descriptor in <b>ri</b> and maybe insert it into
 * the list of server descriptors. Set *<b>msg</b> to a message that should be
 * passed back to the origin of this descriptor.
 *

 * Return 2 if descriptor is well-formed and accepted;
 *  1 if well-formed and accepted but origin should hear *msg;
 *  0 if well-formed but redundant with one we already have;
 * -1 if it is rejected and origin should hear *msg;
 *

 * This function is only called when fresh descriptors are posted, not when
 * we re-load the cache.
 */
int
was_router_added_t
dirserv_add_descriptor(routerinfo_t *ri, const char **msg)
{
  int r;
  was_router_added_t r;
  routerinfo_t *ri_old;
  char *desc = NULL;
  size_t desclen = 0;
@@ -703,11 +718,12 @@ dirserv_add_descriptor(routerinfo_t *ri, const char **msg)
    desc = tor_strndup(ri->cache_info.signed_descriptor_body, desclen);
  }

  if ((r = router_add_to_routerlist(ri, msg, 0, 0))<0) {
    if (r < -1 && desc) /* unless the routerinfo was fine, just out-of-date */
  r = router_add_to_routerlist(ri, msg, 0, 0);
  if (!WRA_WAS_ADDED(r)) {
    /* unless the routerinfo was fine, just out-of-date */
    if (WRA_WAS_REJECTED(r) && desc)
      control_event_or_authdir_new_descriptor("REJECTED", desc, desclen, *msg);
    tor_free(desc);
    return r == -1 ? 0 : -1;
  } else {
    smartlist_t *changed;
    control_event_or_authdir_new_descriptor("ACCEPTED", desc, desclen, *msg);
@@ -721,8 +737,8 @@ dirserv_add_descriptor(routerinfo_t *ri, const char **msg)
        "Descriptor for invalid server accepted";
    }
    tor_free(desc);
    return r == 0 ? 2 : 1;
  }
  return r;
}

/** As dirserv_add_descriptor, but for an extrainfo_t <b>ei</b>. */
+39 −4
Changes for src/or/or.h: 39 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -3410,10 +3410,12 @@ int dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk);
int dirserv_load_fingerprint_file(void);
void dirserv_free_fingerprint_list(void);
const char *dirserv_get_nickname_by_digest(const char *digest);
int dirserv_add_multiple_descriptors(const char *desc, uint8_t purpose,
enum was_router_added_t dirserv_add_multiple_descriptors(
                                     const char *desc, uint8_t purpose,
                                     const char *source,
                                     const char **msg);
int dirserv_add_descriptor(routerinfo_t *ri, const char **msg);
enum was_router_added_t dirserv_add_descriptor(routerinfo_t *ri,
                                               const char **msg);
int getinfo_helper_dirserv_unregistered(control_connection_t *conn,
                                        const char *question, char **answer);
void dirserv_free_descriptors(void);
@@ -4388,8 +4390,41 @@ void routerlist_remove(routerlist_t *rl, routerinfo_t *ri, int make_old);
void routerlist_free_all(void);
void routerlist_reset_warnings(void);
void router_set_status(const char *digest, int up);
int router_add_to_routerlist(routerinfo_t *router, const char **msg,
                             int from_cache, int from_fetch);

/** Return value for router_add_to_routerlist() and dirserv_add_descriptor() */
typedef enum was_router_added_t {
  ROUTER_ADDED_SUCCESSFULLY = 0,
  ROUTER_ADDED_NOTIFY_GENERATOR = 1,
  ROUTER_WAS_NOT_NEW = -1,
  ROUTER_NOT_IN_CONSENSUS = -2,
  ROUTER_NOT_IN_CONSENSUS_OR_NETWORKSTATUS = -3,
  ROUTER_AUTHDIR_REJECTS = -4,
} was_router_added_t;

static int WRA_WAS_ADDED(was_router_added_t s);
static int WRA_WAS_OUTDATED(was_router_added_t s);
static int WRA_WAS_REJECTED(was_router_added_t s);
/**DOCDOC*/
static INLINE int
WRA_WAS_ADDED(was_router_added_t s) {
  return s == ROUTER_ADDED_SUCCESSFULLY || s == ROUTER_ADDED_NOTIFY_GENERATOR;
}
/**DOCDOC*/
static INLINE int WRA_WAS_OUTDATED(was_router_added_t s)
{
  return (s == ROUTER_WAS_NOT_NEW ||
          s == ROUTER_NOT_IN_CONSENSUS ||
          s == ROUTER_NOT_IN_CONSENSUS_OR_NETWORKSTATUS);
}
/**DOCDOC*/
static INLINE int WRA_WAS_REJECTED(was_router_added_t s)
{
  return (s == ROUTER_AUTHDIR_REJECTS);
}
was_router_added_t router_add_to_routerlist(routerinfo_t *router,
                                            const char **msg,
                                            int from_cache,
                                            int from_fetch);
int router_add_extrainfo_to_routerlist(extrainfo_t *ei, const char **msg,
                                        int from_cache, int from_fetch);
void routerlist_remove_old_routers(void);
+1 −1
Changes for src/or/router.c: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -541,7 +541,7 @@ init_keys(void)
        log_err(LD_GENERAL,"Generated a routerinfo we couldn't parse.");
        return -1;
      }
      if (dirserv_add_descriptor(ri, &m) < 0) {
      if (!WRA_WAS_ADDED(dirserv_add_descriptor(ri, &m))) {
        log_err(LD_GENERAL,"Unable to add own descriptor to directory: %s",
                m?m:"<unknown error>");
        return -1;
+19 −17
Changes for src/or/routerlist.c: 19 added lines, 17 removed lines.
Original line number Diff line number Diff line
@@ -2923,7 +2923,7 @@ router_set_status(const char *digest, int up)
 * routers_update_status_from_consensus_networkstatus; subsequently, you
 * should call router_rebuild_store and routerlist_descriptors_added.
 */
int
was_router_added_t
router_add_to_routerlist(routerinfo_t *router, const char **msg,
                         int from_cache, int from_fetch)
{
@@ -2950,7 +2950,7 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
             router->nickname);
    *msg = "Router descriptor was not new.";
    routerinfo_free(router);
    return -1;
    return ROUTER_WAS_NOT_NEW;
  }

  if (authdir) {
@@ -2958,7 +2958,7 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
                                       !from_cache && !from_fetch)) {
      tor_assert(*msg);
      routerinfo_free(router);
      return -2;
      return ROUTER_AUTHDIR_REJECTS;
    }
    authdir_believes_valid = router->is_valid;
  } else if (from_fetch) {
@@ -2979,7 +2979,7 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
        signed_desc_append_to_journal(&router->cache_info,
                                      &routerlist->desc_store);
      routerlist_insert_old(routerlist, router);
      return -1;
      return ROUTER_NOT_IN_CONSENSUS_OR_NETWORKSTATUS;
    }
  }

@@ -3013,7 +3013,7 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
                                    &routerlist->desc_store);
    routerlist_insert_old(routerlist, router);
    *msg = "Skipping router descriptor: not in consensus.";
    return -1;
    return ROUTER_NOT_IN_CONSENSUS;
  }

  /* If we have a router with the same identity key, choose the newer one. */
@@ -3031,7 +3031,7 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
                                      &routerlist->desc_store);
      routerlist_insert_old(routerlist, router);
      *msg = "Router descriptor was not new.";
      return -1;
      return ROUTER_WAS_NOT_NEW;
    } else {
      /* Same key, and either new, or listed in the consensus. */
      log_debug(LD_DIR, "Replacing entry for router '%s/%s' [%s]",
@@ -3052,7 +3052,7 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
      *msg = authdir_believes_valid ? "Valid server updated" :
        ("Invalid server updated. (This dirserver is marking your "
         "server as unapproved.)");
      return 0;
      return ROUTER_ADDED_SUCCESSFULLY;
    }
  }

@@ -3063,7 +3063,7 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
    signed_desc_append_to_journal(&router->cache_info,
                                  &routerlist->desc_store);
  directory_set_dirty();
  return 0;
  return ROUTER_ADDED_SUCCESSFULLY;
}

/** Insert <b>ei</b> into the routerlist, or free it. Other arguments are
@@ -3390,7 +3390,7 @@ router_load_single_router(const char *s, uint8_t purpose, int cache,
                          const char **msg)
{
  routerinfo_t *ri;
  int r;
  was_router_added_t r;
  smartlist_t *lst;
  char annotation_buf[ROUTER_ANNOTATION_BUF_LEN];
  tor_assert(msg);
@@ -3420,10 +3420,11 @@ router_load_single_router(const char *s, uint8_t purpose, int cache,
  smartlist_add(lst, ri);
  routers_update_status_from_consensus_networkstatus(lst, 0);

  if ((r=router_add_to_routerlist(ri, msg, 0, 0))<0) {
  r = router_add_to_routerlist(ri, msg, 0, 0);
  if (!WRA_WAS_ADDED(r)) {
    /* we've already assigned to *msg now, and ri is already freed */
    tor_assert(*msg);
    if (r < -1)
    if (r == ROUTER_AUTHDIR_REJECTS)
      log_warn(LD_DIR, "Couldn't add router to list: %s Dropping.", *msg);
    smartlist_free(lst);
    return 0;
@@ -3469,8 +3470,8 @@ router_load_routers_from_string(const char *s, const char *eos,

  log_info(LD_DIR, "%d elements to add", smartlist_len(routers));

  SMARTLIST_FOREACH(routers, routerinfo_t *, ri,
  {
  SMARTLIST_FOREACH_BEGIN(routers, routerinfo_t *, ri) {
    was_router_added_t r;
    if (requested_fingerprints) {
      base16_encode(fp, sizeof(fp), descriptor_digests ?
                      ri->cache_info.signed_descriptor_digest :
@@ -3491,13 +3492,14 @@ router_load_routers_from_string(const char *s, const char *eos,
      }
    }

    if (router_add_to_routerlist(ri, &msg, from_cache, !from_cache) >= 0) {
    r = router_add_to_routerlist(ri, &msg, from_cache, !from_cache);
    if (WRA_WAS_ADDED(r)) {
      any_changed = 1;
      smartlist_add(changed, ri);
      routerlist_descriptors_added(changed, from_cache);
      smartlist_clear(changed);
    }
  });
  } SMARTLIST_FOREACH_END(ri);

  routerlist_assert_ok(routerlist);

@@ -4182,14 +4184,14 @@ update_consensus_router_descriptor_downloads(time_t now)
             smartlist_len(no_longer_old));
    SMARTLIST_FOREACH(no_longer_old, signed_descriptor_t *, sd, {
        const char *msg;
        int r;
        was_router_added_t r;
        routerinfo_t *ri = routerlist_reparse_old(rl, sd);
        if (!ri) {
          log_warn(LD_BUG, "Failed to re-parse a router.");
          continue;
        }
        r = router_add_to_routerlist(ri, &msg, 1, 0);
        if (r == -1) {
        if (WRA_WAS_OUTDATED(r)) {
          log_warn(LD_DIR, "Couldn't add re-parsed router: %s",
                   msg?msg:"???");
        }
Loading