Commit bbaa3c77 authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

Implement more control spec functionality

- Mapaddress
- Postdescriptor
- GetInfo on descriptors

Required changes elsewhere:
- Keep the most recent running_routers_t in the routerlist_t. That way we
  can learn about new routers and remember whether we were last told that
  they were up or down.  Also enables more simplifications.
- Keep the signed descriptor inside routerinfo_t.  This makes
  descriptor_entry_t in dirservers.c unneeded.
- Rename AddressMap (the verb) to MapAddress. Keep AddressMap as a noun.
- Check addresses for plausibility before mapping them.


svn:r3696
parent d21f007a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -86,6 +86,8 @@ int tor_snprintf(char *str, size_t size, const char *format, ...)
     CHECK_PRINTF(3,4);
int tor_vsnprintf(char *str, size_t size, const char *format, va_list args);

#define TOR_ISAPLHA(c)   isalpha((int)(unsigned char)(c))
#define TOR_ISALNUM(c)   isalnum((int)(unsigned char)(c))
#define TOR_ISSPACE(c)   isspace((int)(unsigned char)(c))
#define TOR_ISXDIGIT(c) isxdigit((int)(unsigned char)(c))
#define TOR_ISDIGIT(c)   isdigit((int)(unsigned char)(c))
+15 −0
Original line number Diff line number Diff line
@@ -1266,6 +1266,21 @@ tor_inet_ntoa(struct in_addr *in, char *buf, size_t buf_len)
                      (int)(uint8_t)((a    )&0xff));
}

/* DOCDOC */
int
is_plausible_address(const char *name)
{
  const char *cp;
  tor_assert(name);
  /* We could check better here. */
  for (cp=name; *cp; cp++) {
    if (*cp != '.' && *cp != '-' && !TOR_ISALNUM(*cp))
      return 0;
  }

  return 1;
}

/* =====
 * Process helpers
 * ===== */
+1 −0
Original line number Diff line number Diff line
@@ -128,6 +128,7 @@ int parse_addr_and_port_range(const char *s, uint32_t *addr_out,
                              uint16_t *port_max_out);
#define INET_NTOA_BUF_LEN 16
int tor_inet_ntoa(struct in_addr *in, char *buf, size_t buf_len);
int is_plausible_address(const char *name);

/* Process helpers */
void start_daemon(const char *desired_cwd);
+12 −3
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ static config_var_t config_vars[] = {
  VAR("ExcludeNodes",        STRING,   ExcludeNodes,         NULL),
  VAR("TrackHostExits",      CSV,      TrackHostExits,       NULL),
  VAR("TrackHostExitsExpire",INTERVAL, TrackHostExitsExpire, "30 minutes"),
  VAR("AddressMap",          LINELIST, AddressMap,           NULL),
  VAR("MapAddress",          LINELIST, AddressMap,           NULL),
  VAR("FascistFirewall",     BOOL,     FascistFirewall,      "0"),
  VAR("FirewallPorts",       CSV,      FirewallPorts,        "80,443"),
  VAR("MyFamily",            STRING,   MyFamily,             NULL),
@@ -1824,9 +1824,18 @@ config_register_addressmaps(or_options_t *options) {
    if (smartlist_len(elts) >= 2) {
      from = smartlist_get(elts,0);
      to = smartlist_get(elts,1);
      if (!is_plausible_address(from)) {
        log_fn(LOG_WARN,"Skipping invalid argument '%s' to MapAddress",from);
      } else if (!is_plausible_address(to)) {
        log_fn(LOG_WARN,"Skipping invalid argument '%s' to MapAddress",to);
      } else {
        addressmap_register(from, tor_strdup(to), 0);
        if (smartlist_len(elts)>2) {
          log_fn(LOG_WARN,"Ignoring extra arguments to MapAddress.");
        }
      }
    } else {
      log_fn(LOG_WARN,"AddressMap '%s' has too few arguments. Ignoring.", opt->value);
      log_fn(LOG_WARN,"MapAddress '%s' has too few arguments. Ignoring.", opt->value);
    }
    SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
    smartlist_clear(elts);
+60 −3
Original line number Diff line number Diff line
@@ -117,6 +117,7 @@ static void update_global_event_mask(void);
static void send_control_message(connection_t *conn, uint16_t type,
                                 uint16_t len, const char *body);
static void send_control_done(connection_t *conn);
static void send_control_done2(connection_t *conn, const char *msg, size_t len);
static void send_control_error(connection_t *conn, uint16_t error,
                               const char *message);
static void send_control_event(uint16_t event, uint16_t len, const char *body);
@@ -192,6 +193,11 @@ send_control_done(connection_t *conn)
  send_control_message(conn, CONTROL_CMD_DONE, 0, NULL);
}

static void send_control_done2(connection_t *conn, const char *msg, size_t len)
{
  send_control_message(conn, CONTROL_CMD_DONE, len, msg);
}

/** Send an error message with error code <b>error</b> and body
 * <b>message</b> down the connection <b>conn</b> */
static void
@@ -445,7 +451,46 @@ handle_control_signal(connection_t *conn, uint16_t len,
static int
handle_control_mapaddress(connection_t *conn, uint16_t len, const char *body)
{
  send_control_error(conn,ERR_UNRECOGNIZED_TYPE,"not yet implemented");
  smartlist_t *elts;
  smartlist_t *lines;
  smartlist_t *reply;
  char *r;
  size_t sz;
  lines = smartlist_create();
  elts = smartlist_create();
  reply = smartlist_create();
  smartlist_split_string(lines, body, "\n",
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  SMARTLIST_FOREACH(lines, const char *, line,
  {
    smartlist_split_string(elts, body, " ", 0, 2);
    if (smartlist_len(elts) == 2) {
      const char *from = smartlist_get(elts,0);
      const char *to = smartlist_get(elts,1);
      if (!is_plausible_address(from)) {
        log_fn(LOG_WARN,"Skipping invalid argument '%s' in MapAddress msg",from);
      } else if (!is_plausible_address(to)) {
        log_fn(LOG_WARN,"Skipping invalid argument '%s' in AddressMap msg",to);
      } else {
        addressmap_register(from, tor_strdup(to), 0);
        smartlist_add(reply, tor_strdup(line));
      }
    } else {
      log_fn(LOG_WARN, "Skipping MapAddress line with wrong number of items.");
    }
    SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp));
    smartlist_clear(elts);
  });
  SMARTLIST_FOREACH(lines, char *, cp, tor_free(cp));
  smartlist_free(lines);
  smartlist_free(elts);

  r = smartlist_join_strings(reply, "\n", 1, &sz);
  send_control_done2(conn,sz,r);

  SMARTLIST_FOREACH(reply, char *, cp, tor_free(cp));
  smartlist_free(reply);
  tor_free(r);
  return 0;
}

@@ -455,7 +500,12 @@ handle_getinfo_helper(const char *question)
  if (!strcmp(question, "version")) {
    return tor_strdup(VERSION);
  } else if (!strcmpstart(question, "desc/id/")) {
    return NULL; /* XXXX */
    routerinfo_t *ri = router_get_by_hexdigest(question+strlen("desc/id/"));
    if (!ri)
      return NULL;
    if (!ri->signed_descriptor)
      return NULL;
    return tor_strdup(ri->signed_descriptor);
  } else if (!strcmp(question, "desc/all-ids")) {
    routerlist_t *rl;
    char *answer, *cp;
@@ -540,7 +590,14 @@ static int
handle_control_postdescriptor(connection_t *conn, uint16_t len,
                              const char *body)
{
  send_control_error(conn,ERR_UNRECOGNIZED_TYPE,"not yet implemented");
  if (router_load_single_router(body)<0) {
    /* XXXX a more specific error would be nice. */
    send_control_error(conn,ERR_UNSPECIFIED,
                       "Could not parse descriptor or add it");
    return 0;
  }

  send_control_done(conn);
  return 0;
}

Loading