Commit 0df40a39 authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

[forward-port] Implement an option, VirtualAddrMask, to set which addresses...

[forward-port] Implement an option, VirtualAddrMask, to set which addresses get handed out in response to mapaddress requests. Needs testing and docs!


svn:r6398
parent 6ebd8865
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -238,6 +238,7 @@ static config_var_t _option_vars[] = {
  VAR("User",                STRING,   User,                 NULL),
  VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir,   "0"),
  VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "0"),
  VAR("VirtualAddrNetwork",  STRING,   VirtualAddrNetwork,   "127.192.0.0/10"),
  VAR("__LeaveStreamsUnattached", BOOL,LeaveStreamsUnattached, "0"),
  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
};
@@ -677,6 +678,7 @@ options_act(or_options_t *old_options)
  size_t len;
  or_options_t *options = get_options();
  int running_tor = options->command == CMD_RUN_TOR;
  const char *msg;

  clear_trusted_dir_servers();
  if (options->DirServers) {
@@ -745,6 +747,7 @@ options_act(or_options_t *old_options)

  /* Register addressmap directives */
  config_register_addressmaps(options);
  parse_virtual_addr_network(options->VirtualAddrNetwork, 0, &msg);

  /* Update address policies. */
  policies_parse_from_options(options);
@@ -2404,6 +2407,9 @@ options_validate(or_options_t *old_options, or_options_t *options,
  if (rend_config_services(options, 1) < 0)
    REJECT("Failed to configure rendezvous options. See logs for details.");

  if (parse_virtual_addr_network(options->VirtualAddrNetwork, 1, msg)<0)
    return -1;

  return 0;
#undef REJECT
#undef COMPLAIN
+69 −13
Original line number Diff line number Diff line
@@ -750,15 +750,65 @@ client_dns_set_addressmap(const char *address, uint32_t val,
                      time(NULL) + ttl);
}

/* Currently, we hand out 127.192.0.1 through 127.254.254.254.
/* By default, we hand out 127.192.0.1 through 127.254.254.254.
 * These addresses should map to localhost, so even if the
 * application accidentally tried to connect to them directly (not
 * via Tor), it wouldn't get too far astray.
 *
 * Eventually, we should probably make this configurable.
 */
#define MIN_UNUSED_IPV4 0x7fc00001u
#define MAX_UNUSED_IPV4 0x7ffefefeu
static uint32_t virtual_addr_network = 0x7fc00000u;
static uint32_t virtual_addr_netmask = 0xffc00000u;
static int virtual_addr_netmask_bits = 10;
static uint32_t next_virtual_addr    = 0x7fc00000u;

/** Read a netmask of the form 127.192.0.0/10 from "val", and check whether
 * it's a valid set of virtual addresses to hand out in response to MAPADDRESS
 * requests.  Return 0 on success; set *msg and return -1 on failure.  If
 * validate_only is false, sets the actual virtual address range to the parsed
 * value. */
int
parse_virtual_addr_network(const char *val, int validate_only,
                           const char **msg)
{
  uint32_t addr, mask;
  uint16_t port_min, port_max;
  int bits;

  if (parse_addr_and_port_range(val, &addr, &mask, &port_min, &port_max)) {
    *msg = "Error parsing VirtualAddressNetwork";
    return -1;
  }

  if (port_min != 1 || port_max != 65535) {
    *msg = "Can't specify ports on VirtualAddressNetwork";
    return -1;
  }

  bits = addr_mask_get_bits(mask);
  if (bits < 0) {
    *msg = "VirtualAddressNetwork must have a mask that can be expressed "
      "as a prefix";
    return -1;
  }

  if (bits > 16) {
    *msg = "VirtualAddressNetwork expects a class B network or larger";
    return -1;
  }

  if (validate_only)
    return 0;

  virtual_addr_network = addr & mask;
  virtual_addr_netmask = mask;
  virtual_addr_netmask_bits = bits;

  if ((next_virtual_addr & mask) != addr)
    next_virtual_addr = addr;

  return 0;
}

/**
 * Return true iff <b>addr</b> is likely to have been returned by
@@ -773,7 +823,7 @@ address_is_in_virtual_range(const char *address)
    return 1;
  } else if (tor_inet_aton(address, &in)) {
    uint32_t addr = ntohl(in.s_addr);
    if (addr >= MIN_UNUSED_IPV4 && addr <= MAX_UNUSED_IPV4)
    if ((addr & virtual_addr_netmask) == virtual_addr_network)
      return 1;
  }
  return 0;
@@ -787,7 +837,6 @@ static char *
addressmap_get_virtual_address(int type)
{
  char buf[64];
  static uint32_t next_ipv4 = MIN_UNUSED_IPV4;
  struct in_addr in;

  if (type == RESOLVED_TYPE_HOSTNAME) {
@@ -799,19 +848,26 @@ addressmap_get_virtual_address(int type)
    } while (strmap_get(addressmap, buf));
    return tor_strdup(buf);
  } else if (type == RESOLVED_TYPE_IPV4) {
    while (1) {
    uint32_t available = 1u << virtual_addr_netmask_bits;
    while (available) {
      /* Don't hand out any .0 or .255 address. */
      while ((next_ipv4 & 0xff) == 0 ||
             (next_ipv4 & 0xff) == 0xff)
        ++next_ipv4;
      in.s_addr = htonl(next_ipv4);
      while ((next_virtual_addr & 0xff) == 0 ||
             (next_virtual_addr & 0xff) == 0xff) {
        ++next_virtual_addr;
      }
      in.s_addr = htonl(next_virtual_addr);
      tor_inet_ntoa(&in, buf, sizeof(buf));
      if (!strmap_get(addressmap, buf))
        break;

      ++next_ipv4;
      if (next_ipv4 > MAX_UNUSED_IPV4)
        next_ipv4 = MIN_UNUSED_IPV4;
      ++next_virtual_addr;
      --available;
      if (! --available) {
        log_warn(LD_CONFIG, "Ran out of virtual addresses!");
        return NULL;
      }
      if ((next_virtual_addr & virtual_addr_netmask) != virtual_addr_network)
        next_virtual_addr = virtual_addr_network;
    }
    return tor_strdup(buf);
  } else {
+5 −0
Original line number Diff line number Diff line
@@ -1383,6 +1383,9 @@ typedef struct {
                       * of our PK time by sending CREATE_FAST cells? */

  addr_policy_t *reachable_addr_policy; /**< Parsed from ReachableAddresses */

  char *VirtualAddrNetwork; /**< Address and mask to hand out for virtual
                             * MAPADDRESS requests. */
} or_options_t;

/** Persistent state for an onion router, as saved to disk. */
@@ -1725,6 +1728,8 @@ void addressmap_rewrite(char *address, size_t maxlen);
int addressmap_already_mapped(const char *address);
void addressmap_register(const char *address, char *new_address,
                         time_t expires);
int parse_virtual_addr_network(const char *val, int validate_only,
                               const char **msg);
int client_dns_incr_failures(const char *address);
void client_dns_clear_failures(const char *address);
void client_dns_set_addressmap(const char *address, uint32_t val,