mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 06:13:31 +01:00
r17346@aud-055: nickm | 2008-07-24 15:37:19 +0200
Make generic address manipulation functions work better. Switch address policy code to use tor_addr_t, so it can handle IPv6. That is a good place to start. svn:r16178
This commit is contained in:
parent
ed781e6971
commit
3ce6e2fba2
@ -960,6 +960,22 @@ tor_addr_to_sockaddr(const tor_addr_t *a,
|
||||
}
|
||||
}
|
||||
|
||||
/** DOCDOC */
|
||||
void
|
||||
tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa)
|
||||
{
|
||||
memset(&a, 0, sizeof(tor_addr_t));
|
||||
if (sa->sa_family == AF_INET) {
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *) sa;
|
||||
a->family = AF_INET;
|
||||
a->addr.in_addr.s_addr = sin->sin_addr.s_addr;
|
||||
} else if (sa->sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
|
||||
a->family = AF_INET6;
|
||||
memcpy(&a->addr.in6_addr, &sin6->sin6_addr, sizeof(struct in6_addr));
|
||||
}
|
||||
}
|
||||
|
||||
/** Set *addr to the IP address (in dotted-quad notation) stored in c.
|
||||
* Return 1 on success, 0 if c is badly formatted. (Like inet_aton(c,addr),
|
||||
* but works on Windows and Solaris.)
|
||||
|
@ -361,17 +361,18 @@ typedef struct tor_addr_t
|
||||
/* DOCDOC*/
|
||||
static INLINE uint32_t tor_addr_to_ipv4n(const tor_addr_t *a);
|
||||
static INLINE uint32_t tor_addr_to_ipv4h(const tor_addr_t *a);
|
||||
static INLINE uint32_t tor_addr_to_mapped_ipv4n(const tor_addr_t *a);
|
||||
static INLINE uint32_t tor_addr_to_mapped_ipv4h(const tor_addr_t *a);
|
||||
static INLINE sa_family_t tor_addr_family(const tor_addr_t *a);
|
||||
static INLINE const struct in_addr *tor_addr_to_in(const tor_addr_t *a);
|
||||
static INLINE const struct in6_addr *tor_addr_to_in6(const tor_addr_t *a);
|
||||
socklen_t tor_addr_to_sockaddr(const tor_addr_t *a, uint16_t port,
|
||||
struct sockaddr *sa_out);
|
||||
void tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa);
|
||||
|
||||
static INLINE const struct in6_addr *
|
||||
tor_addr_to_in6(const tor_addr_t *a)
|
||||
{
|
||||
return &a->addr.in6_addr;
|
||||
return a->family == AF_INET6 ? &a->addr.in6_addr : NULL;
|
||||
}
|
||||
|
||||
#define tor_addr_to_in6_addr16(x) S6_ADDR16(*tor_addr_to_in6(x))
|
||||
@ -380,7 +381,7 @@ tor_addr_to_in6(const tor_addr_t *a)
|
||||
static INLINE uint32_t
|
||||
tor_addr_to_ipv4n(const tor_addr_t *a)
|
||||
{
|
||||
return a->addr.in_addr.s_addr;
|
||||
return a->family == AF_INET ? a->addr.in_addr.s_addr : 0;
|
||||
}
|
||||
static INLINE uint32_t
|
||||
tor_addr_to_ipv4h(const tor_addr_t *a)
|
||||
@ -388,7 +389,7 @@ tor_addr_to_ipv4h(const tor_addr_t *a)
|
||||
return ntohl(tor_addr_to_ipv4n(a));
|
||||
}
|
||||
static INLINE uint32_t
|
||||
tor_addr_to_mapped_ipv4n(const tor_addr_t *a)
|
||||
tor_addr_to_mapped_ipv4h(const tor_addr_t *a)
|
||||
{
|
||||
return ntohl(tor_addr_to_in6_addr32(a)[3]);
|
||||
}
|
||||
@ -400,11 +401,12 @@ tor_addr_family(const tor_addr_t *a)
|
||||
static INLINE const struct in_addr *
|
||||
tor_addr_to_in(const tor_addr_t *a)
|
||||
{
|
||||
return &a->addr.in_addr;
|
||||
return a->family == AF_INET ? &a->addr.in_addr : NULL;
|
||||
}
|
||||
|
||||
#define INET_NTOA_BUF_LEN 16 /* 255.255.255.255 */
|
||||
#define TOR_ADDR_BUF_LEN 46 /* ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255 */
|
||||
#define TOR_ADDR_BUF_LEN 48 /* [ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255]
|
||||
*/
|
||||
|
||||
int tor_inet_aton(const char *cp, struct in_addr *addr) ATTR_NONNULL((1,2));
|
||||
const char *tor_inet_ntop(int af, const void *src, char *dst, size_t len);
|
||||
|
@ -2230,17 +2230,27 @@ tor_addr_is_internal(const tor_addr_t *addr, int for_listening)
|
||||
|
||||
/** Convert a tor_addr_t <b>addr</b> into a string, and store it in
|
||||
* <b>dest</b> of size <b>len</b>. Returns a pointer to dest on success,
|
||||
* or NULL on failure.
|
||||
* or NULL on failure. If <b>decorate</b>, surround IPv6 addresses with
|
||||
* brackets.
|
||||
*/
|
||||
const char *
|
||||
tor_addr_to_str(char *dest, const tor_addr_t *addr, int len)
|
||||
tor_addr_to_str(char *dest, const tor_addr_t *addr, int len, int decorate)
|
||||
{
|
||||
const char *ptr;
|
||||
tor_assert(addr && dest);
|
||||
|
||||
switch (tor_addr_family(addr)) {
|
||||
case AF_INET:
|
||||
ptr = tor_inet_ntop(AF_INET, &addr->addr.in_addr, dest, len);
|
||||
if (len<3)
|
||||
return NULL;
|
||||
if (decorate)
|
||||
ptr = tor_inet_ntop(AF_INET, &addr->addr.in_addr, dest+1, len-2);
|
||||
else
|
||||
ptr = tor_inet_ntop(AF_INET, &addr->addr.in_addr, dest, len);
|
||||
if (ptr && decorate) {
|
||||
*dest = '[';
|
||||
memcpy(dest+strlen(dest), "]", 2);
|
||||
}
|
||||
break;
|
||||
case AF_INET6:
|
||||
ptr = tor_inet_ntop(AF_INET6, &addr->addr.in6_addr, dest, len);
|
||||
@ -2739,6 +2749,29 @@ tor_addr_is_null(const tor_addr_t *addr)
|
||||
//return 1;
|
||||
}
|
||||
|
||||
/** Return true iff <b>addr</b> is a loopback address */
|
||||
int
|
||||
tor_addr_is_loopback(const tor_addr_t *addr)
|
||||
{
|
||||
tor_assert(addr);
|
||||
switch (tor_addr_family(addr)) {
|
||||
case AF_INET6: {
|
||||
/* ::1 */
|
||||
uint32_t *a32 = tor_addr_to_in6_addr32(addr);
|
||||
return (a32[0] == 0) && (a32[1] == 0) && (a32[2] == 0) && (a32[3] == 1);
|
||||
}
|
||||
case AF_INET:
|
||||
/* 127.0.0.1 */
|
||||
return (tor_addr_to_ipv4h(addr) & 0xff000000) == 0x7f000000;
|
||||
case AF_UNSPEC:
|
||||
return 0;
|
||||
default:
|
||||
tor_fragile_assert();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Given an IPv4 in_addr struct *<b>in</b> (in network order, as usual),
|
||||
* write it as a string into the <b>buf_len</b>-byte buffer in
|
||||
* <b>buf</b>.
|
||||
@ -2756,12 +2789,11 @@ tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len)
|
||||
|
||||
/** Take a 32-bit host-order ipv4 address <b>v4addr</b> and store it in the
|
||||
* tor_addr *<b>dest</b>.
|
||||
*
|
||||
* XXXX_IP6 Temporary, for use while 32-bit int addresses are still being
|
||||
* passed around.
|
||||
*/
|
||||
/* XXXX_IP6 Temporary, for use while 32-bit int addresses are still being
|
||||
* passed around. */
|
||||
void
|
||||
tor_addr_from_ipv4(tor_addr_t *dest, uint32_t v4addr)
|
||||
tor_addr_from_ipv4h(tor_addr_t *dest, uint32_t v4addr)
|
||||
{
|
||||
tor_assert(dest);
|
||||
memset(dest, 0, sizeof(dest));
|
||||
@ -2816,12 +2848,22 @@ tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
|
||||
v_family[0] = tor_addr_family(addr1);
|
||||
v_family[1] = tor_addr_family(addr2);
|
||||
|
||||
if (v_family[0] == AF_UNSPEC) {
|
||||
if (v_family[1] == AF_UNSPEC)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
} else {
|
||||
if (v_family[1] == AF_UNSPEC)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (v_family[0] == AF_INET) { /* If this is native IPv4, note the address */
|
||||
/* Later we risk overwriting a v4-mapped address */
|
||||
ip4a = tor_addr_to_ipv4h(addr1);
|
||||
} else if ((v_family[0] == AF_INET6) && tor_addr_is_v4(addr1)) {
|
||||
v_family[0] = AF_INET;
|
||||
ip4a = tor_addr_to_mapped_ipv4n(addr1);
|
||||
ip4a = tor_addr_to_mapped_ipv4h(addr1);
|
||||
}
|
||||
|
||||
if (v_family[1] == AF_INET) { /* If this is native IPv4, note the address */
|
||||
@ -2829,7 +2871,7 @@ tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
|
||||
ip4b = tor_addr_to_ipv4h(addr2);
|
||||
} else if ((v_family[1] == AF_INET6) && tor_addr_is_v4(addr2)) {
|
||||
v_family[1] = AF_INET;
|
||||
ip4b = tor_addr_to_mapped_ipv4n(addr2);
|
||||
ip4b = tor_addr_to_mapped_ipv4h(addr2);
|
||||
}
|
||||
|
||||
if (v_family[0] > v_family[1]) /* Comparison of virtual families */
|
||||
@ -2885,11 +2927,40 @@ tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** Return a hash code based on the address addr */
|
||||
unsigned int
|
||||
tor_addr_hash(const tor_addr_t *addr)
|
||||
{
|
||||
switch (tor_addr_family(addr)) {
|
||||
case AF_INET:
|
||||
return tor_addr_to_ipv4h(addr);
|
||||
case AF_UNSPEC:
|
||||
return 0x4e4d5342;
|
||||
case AF_INET6: {
|
||||
const uint32_t *u = tor_addr_to_in6_addr32(addr);
|
||||
return u[0] + u[1] + u[2] + u[3];
|
||||
}
|
||||
default:
|
||||
tor_fragile_assert();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** Return a newly allocatd string with a representation of <b>addr</b>. */
|
||||
char *
|
||||
tor_dup_addr(const tor_addr_t *addr)
|
||||
{
|
||||
char buf[TOR_ADDR_BUF_LEN];
|
||||
tor_addr_to_str(buf, addr, sizeof(buf), 0);
|
||||
return tor_strdup(buf);
|
||||
}
|
||||
|
||||
/** Given a host-order <b>addr</b>, call tor_inet_ntop() on it
|
||||
* and return a strdup of the resulting address.
|
||||
*/
|
||||
char *
|
||||
tor_dup_addr(uint32_t addr)
|
||||
tor_dup_ip(uint32_t addr)
|
||||
{
|
||||
char buf[TOR_ADDR_BUF_LEN];
|
||||
struct in_addr in;
|
||||
|
@ -276,23 +276,27 @@ int parse_addr_and_port_range(const char *s, uint32_t *addr_out,
|
||||
int addr_mask_get_bits(uint32_t mask);
|
||||
int addr_mask_cmp_bits(uint32_t a1, uint32_t a2, maskbits_t bits);
|
||||
int tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len);
|
||||
char *tor_dup_addr(uint32_t addr) ATTR_MALLOC;
|
||||
char *tor_dup_addr(const tor_addr_t *addr) ATTR_MALLOC;
|
||||
char *tor_dup_ip(uint32_t addr) ATTR_MALLOC;
|
||||
int get_interface_address(int severity, uint32_t *addr);
|
||||
|
||||
int get_interface_address6(int severity, sa_family_t family, tor_addr_t *addr);
|
||||
int tor_addr_compare(const tor_addr_t *addr1, const tor_addr_t *addr2);
|
||||
int tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
|
||||
maskbits_t mask);
|
||||
unsigned int tor_addr_hash(const tor_addr_t *addr);
|
||||
int tor_addr_is_v4(const tor_addr_t *addr);
|
||||
int tor_addr_is_internal(const tor_addr_t *ip, int for_listening) ATTR_PURE;
|
||||
int tor_addr_parse_mask_ports(const char *s,
|
||||
tor_addr_t *addr_out, maskbits_t *mask_out,
|
||||
uint16_t *port_min_out, uint16_t *port_max_out);
|
||||
const char * tor_addr_to_str(char *dest, const tor_addr_t *addr, int len);
|
||||
const char * tor_addr_to_str(char *dest, const tor_addr_t *addr, int len,
|
||||
int decorate);
|
||||
int tor_addr_from_str(tor_addr_t *addr, const char *src);
|
||||
void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src);
|
||||
void tor_addr_from_ipv4(tor_addr_t *dest, uint32_t v4addr);
|
||||
void tor_addr_from_ipv4h(tor_addr_t *dest, uint32_t v4addr);
|
||||
int tor_addr_is_null(const tor_addr_t *addr);
|
||||
int tor_addr_is_loopback(const tor_addr_t *addr);
|
||||
|
||||
/* Process helpers */
|
||||
void start_daemon(void);
|
||||
|
@ -1036,7 +1036,7 @@ connection_handle_listener_read(connection_t *conn, int new_type)
|
||||
/* remember the remote address */
|
||||
newconn->addr = ntohl(remote.sin_addr.s_addr);
|
||||
newconn->port = ntohs(remote.sin_port);
|
||||
newconn->address = tor_dup_addr(newconn->addr);
|
||||
newconn->address = tor_dup_ip(newconn->addr);
|
||||
|
||||
} else if (conn->socket_family == AF_UNIX) {
|
||||
/* For now only control ports can be unix domain sockets
|
||||
|
@ -434,7 +434,7 @@ connection_or_init_conn_from_address(or_connection_t *conn,
|
||||
conn->identity_digest, DIGEST_LEN);
|
||||
}
|
||||
tor_free(conn->_base.address);
|
||||
conn->_base.address = tor_dup_addr(addr);
|
||||
conn->_base.address = tor_dup_ip(addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1382,7 +1382,7 @@ getinfo_helper_misc(control_connection_t *conn, const char *question,
|
||||
uint32_t addr;
|
||||
if (router_pick_published_address(get_options(), &addr) < 0)
|
||||
return -1;
|
||||
*answer = tor_dup_addr(addr);
|
||||
*answer = tor_dup_ip(addr);
|
||||
} else if (!strcmp(question, "dir-usage")) {
|
||||
*answer = directory_dump_request_log();
|
||||
} else if (!strcmp(question, "fingerprint")) {
|
||||
|
@ -2165,7 +2165,7 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
|
||||
}
|
||||
if (!strchr(hostname, '.')) {
|
||||
tor_free(hostname);
|
||||
hostname = tor_dup_addr(addr);
|
||||
hostname = tor_dup_ip(addr);
|
||||
}
|
||||
if (crypto_pk_get_digest(private_key, signing_key_digest)<0) {
|
||||
log_err(LD_BUG, "Error computing signing key digest");
|
||||
|
@ -118,7 +118,7 @@ evdns_server_callback(struct evdns_server_request *req, void *_data)
|
||||
|
||||
TO_CONN(conn)->addr = ntohl(sin->sin_addr.s_addr);
|
||||
TO_CONN(conn)->port = ntohs(sin->sin_port);
|
||||
TO_CONN(conn)->address = tor_dup_addr(TO_CONN(conn)->addr);
|
||||
TO_CONN(conn)->address = tor_dup_ip(TO_CONN(conn)->addr);
|
||||
|
||||
if (q->type == EVDNS_TYPE_A)
|
||||
conn->socks_request->command = SOCKS_COMMAND_RESOLVE;
|
||||
|
@ -1148,8 +1148,7 @@ typedef struct addr_policy_t {
|
||||
maskbits_t maskbits; /**< Accept/reject all addresses <b>a</b> such that the
|
||||
* first <b>maskbits</b> bits of <b>a</b> match
|
||||
* <b>addr</b>. */
|
||||
/* XXXX_IP6 make this ipv6-capable */
|
||||
uint32_t addr; /**< Base address to accept or reject. */
|
||||
tor_addr_t addr; /**< Base address to accept or reject. */
|
||||
uint16_t prt_min; /**< Lowest port number to accept/reject. */
|
||||
uint16_t prt_max; /**< Highest port number to accept/reject. */
|
||||
} addr_policy_t;
|
||||
@ -3635,7 +3634,8 @@ int exit_policy_is_general_exit(smartlist_t *policy);
|
||||
int policy_is_reject_star(smartlist_t *policy);
|
||||
int getinfo_helper_policies(control_connection_t *conn,
|
||||
const char *question, char **answer);
|
||||
int policy_write_item(char *buf, size_t buflen, addr_policy_t *item);
|
||||
int policy_write_item(char *buf, size_t buflen, addr_policy_t *item,
|
||||
int format_for_desc);
|
||||
|
||||
void addr_policy_list_free(smartlist_t *p);
|
||||
void addr_policy_free(addr_policy_t *p);
|
||||
|
@ -45,7 +45,9 @@ policy_expand_private(smartlist_t **policy)
|
||||
{
|
||||
static const char *private_nets[] = {
|
||||
"0.0.0.0/8", "169.254.0.0/16",
|
||||
"127.0.0.0/8", "192.168.0.0/16", "10.0.0.0/8", "172.16.0.0/12", NULL };
|
||||
"127.0.0.0/8", "192.168.0.0/16", "10.0.0.0/8", "172.16.0.0/12",
|
||||
// "fc00::/7", "fe80::/10", "fec0::/10", "::/127",
|
||||
NULL };
|
||||
uint16_t port_min, port_max;
|
||||
|
||||
int i;
|
||||
@ -67,9 +69,8 @@ policy_expand_private(smartlist_t **policy)
|
||||
memcpy(&policy, p, sizeof(addr_policy_t));
|
||||
policy.is_private = 0;
|
||||
policy.is_canonical = 0;
|
||||
if (parse_addr_and_port_range(private_nets[i],
|
||||
&policy.addr,
|
||||
&policy.maskbits, &port_min, &port_max)) {
|
||||
if (tor_addr_parse_mask_ports(private_nets[i], &policy.addr,
|
||||
&policy.maskbits, &port_min, &port_max)<0) {
|
||||
tor_assert(0);
|
||||
}
|
||||
smartlist_add(tmp, addr_policy_get_canonical_entry(&policy));
|
||||
@ -408,7 +409,7 @@ cmp_single_addr_policy(addr_policy_t *a, addr_policy_t *b)
|
||||
return r;
|
||||
if ((r=((int)a->is_private - (int)b->is_private)))
|
||||
return r;
|
||||
if ((r=((int)a->addr - (int)b->addr)))
|
||||
if ((r=tor_addr_compare(&a->addr, &b->addr)))
|
||||
return r;
|
||||
if ((r=((int)a->maskbits - (int)b->maskbits)))
|
||||
return r;
|
||||
@ -464,7 +465,7 @@ policy_hash(policy_map_ent_t *ent)
|
||||
if (a->is_private)
|
||||
r = 0x1234abcd;
|
||||
else
|
||||
r = (unsigned int)a->addr;
|
||||
r = tor_addr_hash(&a->addr);
|
||||
r += a->prt_min << 8;
|
||||
r += a->prt_max << 16;
|
||||
r += a->maskbits;
|
||||
@ -522,7 +523,7 @@ addr_policy_get_canonical_entry(addr_policy_t *e)
|
||||
* addresses (127.0.0.1, and so on). But we'll try this for now.
|
||||
*/
|
||||
addr_policy_result_t
|
||||
compare_addr_to_addr_policy(uint32_t addr, uint16_t port,
|
||||
compare_addr_to_addr_policy(uint32_t _addr, uint16_t port,
|
||||
smartlist_t *policy)
|
||||
{
|
||||
int maybe_reject = 0;
|
||||
@ -530,13 +531,18 @@ compare_addr_to_addr_policy(uint32_t addr, uint16_t port,
|
||||
int match = 0;
|
||||
int maybe = 0;
|
||||
int i, len;
|
||||
int addr_is_unknown;
|
||||
tor_addr_t addr;
|
||||
/*XXXX021 ipv6 this function should take a tor_addr_t, not a uint32_t. */
|
||||
tor_addr_from_ipv4h(&addr, _addr);
|
||||
addr_is_unknown = tor_addr_is_null(&addr);
|
||||
|
||||
len = policy ? smartlist_len(policy) : 0;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
addr_policy_t *tmpe = smartlist_get(policy, i);
|
||||
maybe = 0;
|
||||
if (!addr) {
|
||||
if (addr_is_unknown) {
|
||||
/* Address is unknown. */
|
||||
if ((port >= tmpe->prt_min && port <= tmpe->prt_max) ||
|
||||
(!port && tmpe->prt_min<=1 && tmpe->prt_max>=65535)) {
|
||||
@ -552,7 +558,7 @@ compare_addr_to_addr_policy(uint32_t addr, uint16_t port,
|
||||
}
|
||||
} else {
|
||||
/* Address is known */
|
||||
if (!addr_mask_cmp_bits(addr, tmpe->addr, tmpe->maskbits)) {
|
||||
if (!tor_addr_compare_masked(&addr, &tmpe->addr, tmpe->maskbits)) {
|
||||
if (port >= tmpe->prt_min && port <= tmpe->prt_max) {
|
||||
/* Exact match for the policy */
|
||||
match = 1;
|
||||
@ -595,7 +601,7 @@ addr_policy_covers(addr_policy_t *a, addr_policy_t *b)
|
||||
/* a has more fixed bits than b; it can't possibly cover b. */
|
||||
return 0;
|
||||
}
|
||||
if (addr_mask_cmp_bits(a->addr, b->addr, a->maskbits)) {
|
||||
if (tor_addr_compare_masked(&a->addr, &b->addr, a->maskbits)) {
|
||||
/* There's a fixed bit in a that's set differently in b. */
|
||||
return 0;
|
||||
}
|
||||
@ -618,7 +624,7 @@ addr_policy_intersects(addr_policy_t *a, addr_policy_t *b)
|
||||
minbits = a->maskbits;
|
||||
else
|
||||
minbits = b->maskbits;
|
||||
if (addr_mask_cmp_bits(a->addr, b->addr, minbits))
|
||||
if (tor_addr_compare_masked(&a->addr, &b->addr, minbits))
|
||||
return 0;
|
||||
if (a->prt_max < b->prt_min || b->prt_max < a->prt_min)
|
||||
return 0;
|
||||
@ -670,8 +676,8 @@ exit_policy_remove_redundancies(smartlist_t *dest)
|
||||
tor_assert(j > i);
|
||||
if (addr_policy_covers(ap, tmp)) {
|
||||
char p1[POLICY_BUF_LEN], p2[POLICY_BUF_LEN];
|
||||
policy_write_item(p1, sizeof(p1), tmp);
|
||||
policy_write_item(p2, sizeof(p2), ap);
|
||||
policy_write_item(p1, sizeof(p1), tmp, 0);
|
||||
policy_write_item(p2, sizeof(p2), ap, 0);
|
||||
log(LOG_DEBUG, LD_CONFIG, "Removing exit policy %s (%d). It is made "
|
||||
"redundant by %s (%d).", p1, j, p2, i);
|
||||
smartlist_del_keeporder(dest, j--);
|
||||
@ -699,8 +705,8 @@ exit_policy_remove_redundancies(smartlist_t *dest)
|
||||
} else { /* policy_types are equal. */
|
||||
if (addr_policy_covers(tmp, ap)) {
|
||||
char p1[POLICY_BUF_LEN], p2[POLICY_BUF_LEN];
|
||||
policy_write_item(p1, sizeof(p1), ap);
|
||||
policy_write_item(p2, sizeof(p2), tmp);
|
||||
policy_write_item(p1, sizeof(p1), ap, 0);
|
||||
policy_write_item(p2, sizeof(p2), tmp, 0);
|
||||
log(LOG_DEBUG, LD_CONFIG, "Removing exit policy %s. It is already "
|
||||
"covered by %s.", p1, p2);
|
||||
smartlist_del_keeporder(dest, i--);
|
||||
@ -774,8 +780,8 @@ exit_policy_is_general_exit(smartlist_t *policy)
|
||||
continue; /* Doesn't cover our port. */
|
||||
if (p->maskbits > 8)
|
||||
continue; /* Narrower than a /8. */
|
||||
if ((p->addr & 0xff000000ul) == 0x7f000000ul)
|
||||
continue; /* 127.x */
|
||||
if (tor_addr_is_loopback(&p->addr))
|
||||
continue; /* 127.x or ::1. */
|
||||
/* We have a match that is at least a /8. */
|
||||
if (p->policy_type == ADDR_POLICY_ACCEPT) {
|
||||
++n_allowed;
|
||||
@ -807,16 +813,18 @@ policy_is_reject_star(smartlist_t *policy)
|
||||
/** Write a single address policy to the buf_len byte buffer at buf. Return
|
||||
* the number of characters written, or -1 on failure. */
|
||||
int
|
||||
policy_write_item(char *buf, size_t buflen, addr_policy_t *policy)
|
||||
policy_write_item(char *buf, size_t buflen, addr_policy_t *policy,
|
||||
int format_for_desc)
|
||||
{
|
||||
struct in_addr in;
|
||||
size_t written = 0;
|
||||
char addrbuf[INET_NTOA_BUF_LEN];
|
||||
char addrbuf[TOR_ADDR_BUF_LEN];
|
||||
const char *addrpart;
|
||||
int result;
|
||||
const int is_accept = policy->policy_type == ADDR_POLICY_ACCEPT;
|
||||
const int is_ip6 = tor_addr_family(&policy->addr) == AF_INET6;
|
||||
|
||||
tor_addr_to_str(buf, &policy->addr, sizeof(buf), 1);
|
||||
|
||||
in.s_addr = htonl(policy->addr);
|
||||
tor_inet_ntoa(&in, addrbuf, sizeof(addrbuf));
|
||||
/* write accept/reject 1.2.3.4 */
|
||||
if (policy->is_private)
|
||||
addrpart = "private";
|
||||
@ -824,8 +832,11 @@ policy_write_item(char *buf, size_t buflen, addr_policy_t *policy)
|
||||
addrpart = "*";
|
||||
else
|
||||
addrpart = addrbuf;
|
||||
result = tor_snprintf(buf, buflen, "%s %s",
|
||||
policy->policy_type == ADDR_POLICY_ACCEPT ? "accept" : "reject",
|
||||
|
||||
result = tor_snprintf(buf, buflen, "%s%s%s %s",
|
||||
(is_ip6&&format_for_desc)?"opt ":"",
|
||||
is_accept ? "accept" : "reject",
|
||||
(is_ip6&&format_for_desc)?"6":"",
|
||||
addrpart);
|
||||
if (result < 0)
|
||||
return -1;
|
||||
|
@ -200,7 +200,7 @@ rend_encode_v2_intro_points(char **ipos_base64,
|
||||
goto done;
|
||||
}
|
||||
/* Assemble everything for this introduction point. */
|
||||
address = tor_dup_addr(info->addr);
|
||||
address = tor_dup_ip(info->addr);
|
||||
res = tor_snprintf(unenc + unenc_written, unenc_len - unenc_written,
|
||||
"introduction-point %s\n"
|
||||
"ip-address %s\n"
|
||||
|
@ -1252,7 +1252,7 @@ router_rebuild_descriptor(int force)
|
||||
|
||||
ri = tor_malloc_zero(sizeof(routerinfo_t));
|
||||
ri->cache_info.routerlist_index = -1;
|
||||
ri->address = tor_dup_addr(addr);
|
||||
ri->address = tor_dup_ip(addr);
|
||||
ri->nickname = tor_strdup(options->Nickname);
|
||||
ri->addr = addr;
|
||||
ri->or_port = options->ORPort;
|
||||
@ -1728,7 +1728,7 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
|
||||
int i;
|
||||
for (i = 0; i < smartlist_len(router->exit_policy); ++i) {
|
||||
tmpe = smartlist_get(router->exit_policy, i);
|
||||
result = policy_write_item(s+written, maxlen-written, tmpe);
|
||||
result = policy_write_item(s+written, maxlen-written, tmpe, 1);
|
||||
if (result < 0) {
|
||||
log_warn(LD_BUG,"descriptor policy_write_item ran out of room!");
|
||||
return -1;
|
||||
|
@ -204,7 +204,7 @@ trusted_dirs_load_certs_from_string(const char *contents, int from_store,
|
||||
if (cert->addr && cert->dir_port &&
|
||||
(ds->addr != cert->addr ||
|
||||
ds->dir_port != cert->dir_port)) {
|
||||
char *a = tor_dup_addr(cert->addr);
|
||||
char *a = tor_dup_ip(cert->addr);
|
||||
log_notice(LD_DIR, "Updating address for directory authority %s "
|
||||
"from %s:%d to %s:%d based on in certificate.",
|
||||
ds->nickname, ds->address, (int)ds->dir_port,
|
||||
|
@ -23,9 +23,11 @@ const char routerparse_c_id[] =
|
||||
*/
|
||||
typedef enum {
|
||||
K_ACCEPT = 0,
|
||||
K_ACCEPT6,
|
||||
K_DIRECTORY_SIGNATURE,
|
||||
K_RECOMMENDED_SOFTWARE,
|
||||
K_REJECT,
|
||||
K_REJECT6,
|
||||
K_ROUTER,
|
||||
K_SIGNED_DIRECTORY,
|
||||
K_SIGNING_KEY,
|
||||
@ -214,7 +216,9 @@ typedef struct token_rule_t {
|
||||
static token_rule_t routerdesc_token_table[] = {
|
||||
T0N("reject", K_REJECT, ARGS, NO_OBJ ),
|
||||
T0N("accept", K_ACCEPT, ARGS, NO_OBJ ),
|
||||
T1_START( "router", K_ROUTER, GE(5), NO_OBJ ),
|
||||
T0N("reject6", K_REJECT6, ARGS, NO_OBJ ),
|
||||
T0N("accept6", K_ACCEPT6, ARGS, NO_OBJ ),
|
||||
T1_START( "router", K_ROUTER, GE(5), NO_OBJ ),
|
||||
T1( "signing-key", K_SIGNING_KEY, NO_ARGS, NEED_KEY_1024 ),
|
||||
T1( "onion-key", K_ONION_KEY, NO_ARGS, NEED_KEY_1024 ),
|
||||
T1_END( "router-signature", K_ROUTER_SIGNATURE, NO_ARGS, NEED_OBJ ),
|
||||
@ -2607,12 +2611,12 @@ router_parse_addr_policy_item_from_string(const char *s, int assume_action)
|
||||
log_warn(LD_DIR, "Error reading address policy: %s", tok->error);
|
||||
goto err;
|
||||
}
|
||||
if (tok->tp != K_ACCEPT && tok->tp != K_REJECT) {
|
||||
if (tok->tp != K_ACCEPT && tok->tp != K_ACCEPT6 &&
|
||||
tok->tp != K_REJECT && tok->tp != K_REJECT6) {
|
||||
log_warn(LD_DIR, "Expected 'accept' or 'reject'.");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Now that we've gotten an addr policy, add it to the router. */
|
||||
r = router_parse_addr_policy(tok);
|
||||
goto done;
|
||||
err:
|
||||
@ -2638,6 +2642,17 @@ router_add_exit_policy(routerinfo_t *router, directory_token_t *tok)
|
||||
if (! router->exit_policy)
|
||||
router->exit_policy = smartlist_create();
|
||||
|
||||
if (((tok->tp == K_ACCEPT6 || tok->tp == K_REJECT6) &&
|
||||
tor_addr_family(&newe->addr) == AF_INET)
|
||||
||
|
||||
((tok->tp == K_ACCEPT || tok->tp == K_REJECT) &&
|
||||
tor_addr_family(&newe->addr) == AF_INET6)) {
|
||||
log_warn(LD_DIR, "Mismatch between field type and address type in exit "
|
||||
"policy");
|
||||
addr_policy_free(newe);
|
||||
return -1;
|
||||
}
|
||||
|
||||
smartlist_add(router->exit_policy, newe);
|
||||
|
||||
return 0;
|
||||
@ -2651,7 +2666,8 @@ router_parse_addr_policy(directory_token_t *tok)
|
||||
addr_policy_t newe;
|
||||
char *arg;
|
||||
|
||||
tor_assert(tok->tp == K_REJECT || tok->tp == K_ACCEPT);
|
||||
tor_assert(tok->tp == K_REJECT || tok->tp == K_REJECT6 ||
|
||||
tok->tp == K_ACCEPT || tok->tp == K_ACCEPT6);
|
||||
|
||||
if (tok->n_args != 1)
|
||||
return NULL;
|
||||
@ -2662,18 +2678,18 @@ router_parse_addr_policy(directory_token_t *tok)
|
||||
|
||||
memset(&newe, 0, sizeof(newe));
|
||||
|
||||
newe.policy_type = (tok->tp == K_REJECT) ? ADDR_POLICY_REJECT
|
||||
: ADDR_POLICY_ACCEPT;
|
||||
if (tok->tp == K_REJECT || tok->tp == K_REJECT6)
|
||||
newe.policy_type = ADDR_POLICY_REJECT;
|
||||
else
|
||||
newe.policy_type = ADDR_POLICY_ACCEPT;
|
||||
|
||||
if (parse_addr_and_port_range(arg, &newe.addr, &newe.maskbits,
|
||||
&newe.prt_min, &newe.prt_max))
|
||||
goto policy_read_failed;
|
||||
if (tor_addr_parse_mask_ports(arg, &newe.addr, &newe.maskbits,
|
||||
&newe.prt_min, &newe.prt_max) < 0) {
|
||||
log_warn(LD_DIR,"Couldn't parse line %s. Dropping", escaped(arg));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return addr_policy_get_canonical_entry(&newe);
|
||||
|
||||
policy_read_failed:
|
||||
log_warn(LD_DIR,"Couldn't parse line %s. Dropping", escaped(arg));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Parse an exit policy line of the format "accept/reject private:...".
|
||||
@ -2700,8 +2716,10 @@ router_parse_addr_policy_private(directory_token_t *tok)
|
||||
return NULL;
|
||||
|
||||
memset(&result, 0, sizeof(result));
|
||||
result.policy_type = (tok->tp == K_REJECT) ? ADDR_POLICY_REJECT
|
||||
: ADDR_POLICY_ACCEPT;
|
||||
if (tok->tp == K_REJECT || tok->tp == K_REJECT6)
|
||||
result.policy_type = ADDR_POLICY_REJECT;
|
||||
else
|
||||
result.policy_type = ADDR_POLICY_ACCEPT;
|
||||
result.is_private = 1;
|
||||
result.prt_min = port_min;
|
||||
result.prt_max = port_max;
|
||||
@ -3076,8 +3094,9 @@ find_all_exitpolicy(smartlist_t *s)
|
||||
{
|
||||
smartlist_t *out = smartlist_create();
|
||||
SMARTLIST_FOREACH(s, directory_token_t *, t,
|
||||
if (t->tp == K_ACCEPT || t->tp == K_REJECT)
|
||||
smartlist_add(out,t));
|
||||
if (t->tp == K_ACCEPT || t->tp == K_ACCEPT6 ||
|
||||
t->tp == K_REJECT || t->tp == K_REJECT6)
|
||||
smartlist_add(out,t));
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -2519,11 +2519,11 @@ test_dir_format(void)
|
||||
ex1 = tor_malloc_zero(sizeof(addr_policy_t));
|
||||
ex2 = tor_malloc_zero(sizeof(addr_policy_t));
|
||||
ex1->policy_type = ADDR_POLICY_ACCEPT;
|
||||
ex1->addr = 0;
|
||||
tor_addr_from_ipv4h(&ex1->addr, 0);
|
||||
ex1->maskbits = 0;
|
||||
ex1->prt_min = ex1->prt_max = 80;
|
||||
ex2->policy_type = ADDR_POLICY_REJECT;
|
||||
ex2->addr = 18 << 24;
|
||||
tor_addr_from_ipv4h(&ex2->addr, 18<<24);
|
||||
ex2->maskbits = 8;
|
||||
ex2->prt_min = ex2->prt_max = 24;
|
||||
r2 = tor_malloc_zero(sizeof(routerinfo_t));
|
||||
@ -3279,9 +3279,10 @@ test_policies(void)
|
||||
policy = smartlist_create();
|
||||
|
||||
p = router_parse_addr_policy_item_from_string("reject 192.168.0.0/16:*",-1);
|
||||
test_assert(p != NULL);
|
||||
test_eq(ADDR_POLICY_REJECT, p->policy_type);
|
||||
tor_addr_from_ipv4(&tar, 0xc0a80000u);
|
||||
test_assert(p->addr == 0xc0a80000u);
|
||||
tor_addr_from_ipv4h(&tar, 0xc0a80000u);
|
||||
test_eq(0, tor_addr_compare(&p->addr, &tar));
|
||||
test_eq(16, p->maskbits);
|
||||
test_eq(1, p->prt_min);
|
||||
test_eq(65535, p->prt_max);
|
||||
|
Loading…
Reference in New Issue
Block a user