aboutsummaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2008-07-24 13:44:04 +0000
committerNick Mathewson <nickm@torproject.org>2008-07-24 13:44:04 +0000
commit3ce6e2fba290eb5d3a4d0a3ca2f61658245b52b6 (patch)
tree08c562380df129cb4c8c896eecba0f3d8013d262 /src/or
parented781e69716248111ef1a2ddc1b9add671bd8d16 (diff)
downloadtor-3ce6e2fba290eb5d3a4d0a3ca2f61658245b52b6.tar
tor-3ce6e2fba290eb5d3a4d0a3ca2f61658245b52b6.tar.gz
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
Diffstat (limited to 'src/or')
-rw-r--r--src/or/connection.c2
-rw-r--r--src/or/connection_or.c2
-rw-r--r--src/or/control.c2
-rw-r--r--src/or/dirserv.c2
-rw-r--r--src/or/dnsserv.c2
-rw-r--r--src/or/or.h6
-rw-r--r--src/or/policies.c59
-rw-r--r--src/or/rendcommon.c2
-rw-r--r--src/or/router.c4
-rw-r--r--src/or/routerlist.c2
-rw-r--r--src/or/routerparse.c53
-rw-r--r--src/or/test.c9
12 files changed, 88 insertions, 57 deletions
diff --git a/src/or/connection.c b/src/or/connection.c
index 002d10a03..8c7cca1ba 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -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
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 0ed957eb6..1c6c85bd1 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -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);
}
}
diff --git a/src/or/control.c b/src/or/control.c
index 06902bcd8..aaf4701a1 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -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")) {
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index 04544d7f4..df3a913a1 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -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");
diff --git a/src/or/dnsserv.c b/src/or/dnsserv.c
index c88193e15..18623f6a4 100644
--- a/src/or/dnsserv.c
+++ b/src/or/dnsserv.c
@@ -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;
diff --git a/src/or/or.h b/src/or/or.h
index 6975b16fd..342a57022 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -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);
diff --git a/src/or/policies.c b/src/or/policies.c
index 06ca6cdde..fb5c0d56b 100644
--- a/src/or/policies.c
+++ b/src/or/policies.c
@@ -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;
diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c
index e7ac4a1f0..b9e2e81f0 100644
--- a/src/or/rendcommon.c
+++ b/src/or/rendcommon.c
@@ -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"
diff --git a/src/or/router.c b/src/or/router.c
index 4cd02370a..bd8cb8351 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -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;
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 896f0be4a..c662aa2dc 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -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,
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 6492d4baf..811e276a7 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -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;
}
diff --git a/src/or/test.c b/src/or/test.c
index 1b3e5c3b3..71df85ad5 100644
--- a/src/or/test.c
+++ b/src/or/test.c
@@ -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);