|  | @@ -764,38 +764,41 @@ 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. */
 | 
	
		
			
				|  |  | + * requests.  Return 0 on success; set *msg (if provided) to a newly allocated
 | 
	
		
			
				|  |  | + * string 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)
 | 
	
		
			
				|  |  | +                           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";
 | 
	
		
			
				|  |  | +    if (msg) *msg = tor_strdup("Error parsing VirtualAddressNetwork");
 | 
	
		
			
				|  |  |      return -1;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    if (port_min != 1 || port_max != 65535) {
 | 
	
		
			
				|  |  | -    *msg = "Can't specify ports on VirtualAddressNetwork";
 | 
	
		
			
				|  |  | +    if (msg) *msg = tor_strdup("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";
 | 
	
		
			
				|  |  | +    if (msg) *msg = tor_strdup("VirtualAddressNetwork must have a mask that "
 | 
	
		
			
				|  |  | +                               "can be expressed as a prefix");
 | 
	
		
			
				|  |  |      return -1;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +#if 0
 | 
	
		
			
				|  |  |    if (bits > 16) {
 | 
	
		
			
				|  |  | -    *msg = "VirtualAddressNetwork expects a class B network or larger";
 | 
	
		
			
				|  |  | +    if (msg) *msg = tor_strdup("VirtualAddressNetwork expects a class B "
 | 
	
		
			
				|  |  | +                               "network or larger");
 | 
	
		
			
				|  |  |      return -1;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    if (validate_only)
 | 
	
		
			
				|  |  |      return 0;
 | 
	
	
		
			
				|  | @@ -848,7 +851,9 @@ addressmap_get_virtual_address(int type)
 | 
	
		
			
				|  |  |      } while (strmap_get(addressmap, buf));
 | 
	
		
			
				|  |  |      return tor_strdup(buf);
 | 
	
		
			
				|  |  |    } else if (type == RESOLVED_TYPE_IPV4) {
 | 
	
		
			
				|  |  | -    uint32_t available = 1u << virtual_addr_netmask_bits;
 | 
	
		
			
				|  |  | +    // This is an imperfect estimate of how many addresses are available, but
 | 
	
		
			
				|  |  | +    // that's ok.
 | 
	
		
			
				|  |  | +    uint32_t available = 1u << (32-virtual_addr_netmask_bits);
 | 
	
		
			
				|  |  |      while (available) {
 | 
	
		
			
				|  |  |        /* Don't hand out any .0 or .255 address. */
 | 
	
		
			
				|  |  |        while ((next_virtual_addr & 0xff) == 0 ||
 | 
	
	
		
			
				|  | @@ -862,6 +867,7 @@ addressmap_get_virtual_address(int type)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |        ++next_virtual_addr;
 | 
	
		
			
				|  |  |        --available;
 | 
	
		
			
				|  |  | +      log_notice(LD_CONFIG, "%d addrs available", (int)available);
 | 
	
		
			
				|  |  |        if (! --available) {
 | 
	
		
			
				|  |  |          log_warn(LD_CONFIG, "Ran out of virtual addresses!");
 | 
	
		
			
				|  |  |          return NULL;
 |