aboutsummaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2008-12-19 18:52:00 +0000
committerNick Mathewson <nickm@torproject.org>2008-12-19 18:52:00 +0000
commit029be5ad02cfec8d9b96b3466a03a353183f561a (patch)
tree1cd1a87b153e8aabfef10d8d6d8f8813f6e1bdf0 /src/or
parentefb863189cd4500e9cdaf8f5665f9756ae12dfde (diff)
downloadtor-029be5ad02cfec8d9b96b3466a03a353183f561a.tar.gz
tor-029be5ad02cfec8d9b96b3466a03a353183f561a.zip
Move in-addr.arpa parsing and generation into address.c, and simplify the code that does it elsewhere. Incidentally, this lets exit servers answer requests for ip6.arpa addresses.
svn:r17707
Diffstat (limited to 'src/or')
-rw-r--r--src/or/connection_edge.c60
-rw-r--r--src/or/dns.c69
-rw-r--r--src/or/eventdns.c4
-rw-r--r--src/or/eventdns.h4
-rw-r--r--src/or/or.h1
-rw-r--r--src/or/test.c64
6 files changed, 107 insertions, 95 deletions
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 620db73a62..9b192b5565 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -1436,17 +1436,10 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
if (options->ClientDNSRejectInternalAddresses) {
/* Don't let people try to do a reverse lookup on 10.0.0.1. */
tor_addr_t addr;
- struct in_addr in;
int ok;
- if (!strcasecmpend(socks->address, ".in-addr.arpa"))
- ok = !parse_inaddr_arpa_address(socks->address, &in);
- else
- ok = tor_inet_aton(socks->address, &in);
- /*XXXX021 make this a function. */
- addr.family = AF_INET;
- memcpy(&addr.addr.in_addr, &in, sizeof(struct in_addr));
-
- if (ok && tor_addr_is_internal(&addr, 0)) {
+ ok = tor_addr_parse_reverse_lookup_name(
+ &addr, socks->address, AF_UNSPEC, 1);
+ if (ok == 1 && tor_addr_is_internal(&addr, 0)) {
connection_ap_handshake_socks_resolved(conn, RESOLVED_TYPE_ERROR,
0, NULL, -1, TIME_MAX);
connection_mark_unattached_ap(conn,
@@ -2130,7 +2123,7 @@ connection_ap_handshake_send_resolve(edge_connection_t *ap_conn)
{
int payload_len, command;
const char *string_addr;
- char inaddr_buf[32];
+ char inaddr_buf[REVERSE_LOOKUP_NAME_BUF_LEN];
origin_circuit_t *circ;
tor_assert(ap_conn->on_circuit);
circ = TO_ORIGIN_CIRCUIT(ap_conn->on_circuit);
@@ -2155,36 +2148,29 @@ connection_ap_handshake_send_resolve(edge_connection_t *ap_conn)
payload_len = (int)strlen(string_addr)+1;
tor_assert(payload_len <= RELAY_PAYLOAD_SIZE);
} else {
- struct in_addr in;
- uint32_t a;
- size_t len = strlen(ap_conn->socks_request->address);
- char c = 0;
- /* XXXX This logic is a little ugly: we check for an in-addr.arpa ending
- * on the address. If we have one, the address is already in the right
- * order, so we'll leave it alone later. Otherwise, we reverse it and
- * turn it into an in-addr.arpa address. */
- if (!strcasecmpend(ap_conn->socks_request->address, ".in-addr.arpa")) {
- /* Temporarily truncate the address, so we can give it to inet_aton. */
- c = ap_conn->socks_request->address[len-13];
- ap_conn->socks_request->address[len-13] = '\0';
- }
- if (tor_inet_aton(ap_conn->socks_request->address, &in) == 0) {
+ /* command == SOCKS_COMMAND_RESOLVE_PTR */
+ const char *a = ap_conn->socks_request->address;
+ tor_addr_t addr;
+ int r;
+
+ /* We're doing a reverse lookup. The input could be an IP address, or
+ * could be an .in-addr.arpa or .ip6.arpa address */
+ r = tor_addr_parse_reverse_lookup_name(&addr, a, AF_INET, 1);
+ if (r <= 0) {
+ log_warn(LD_APP, "Rejecting ill-formed reverse lookup of %s",
+ safe_str(a));
connection_mark_unattached_ap(ap_conn, END_STREAM_REASON_INTERNAL);
return -1;
}
- if (c) {
- /* this path happens on DNS. Can we unify? XXXX021 */
- ap_conn->socks_request->address[len-13] = c;
- strlcpy(inaddr_buf, ap_conn->socks_request->address, sizeof(inaddr_buf));
- } else {
- /* this path happens on tor-resolve. Can we unify? XXXX021 */
- a = ntohl(in.s_addr);
- tor_snprintf(inaddr_buf, sizeof(inaddr_buf), "%d.%d.%d.%d.in-addr.arpa",
- (int)(uint8_t)((a )&0xff),
- (int)(uint8_t)((a>>8 )&0xff),
- (int)(uint8_t)((a>>16)&0xff),
- (int)(uint8_t)((a>>24)&0xff));
+
+ r = tor_addr_to_reverse_lookup_name(inaddr_buf, sizeof(inaddr_buf), &addr);
+ if (r < 0) {
+ log_warn(LD_BUG, "Couldn't generate reverse lookup hostname of %s",
+ safe_str(a));
+ connection_mark_unattached_ap(ap_conn, END_STREAM_REASON_INTERNAL);
+ return -1;
}
+
string_addr = inaddr_buf;
payload_len = (int)strlen(inaddr_buf)+1;
tor_assert(payload_len <= RELAY_PAYLOAD_SIZE);
diff --git a/src/or/dns.c b/src/or/dns.c
index a83c48981d..191fd068c1 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -494,49 +494,6 @@ send_resolved_hostname_cell(edge_connection_t *conn, const char *hostname)
// log_notice(LD_EXIT, "Sent");
}
-/** Given a lower-case <b>address</b>, check to see whether it's a
- * 1.2.3.4.in-addr.arpa address used for reverse lookups. If so,
- * parse it and place the address in <b>in</b> if present. Return 1 on success;
- * 0 if the address is not in in-addr.arpa format, and -1 if the address is
- * malformed. */
-/* XXXX021 move this to address.c; unify with logic in connection_edge.c */
-int
-parse_inaddr_arpa_address(const char *address, struct in_addr *in)
-{
- char buf[INET_NTOA_BUF_LEN];
- char *cp;
- size_t len;
- struct in_addr inaddr;
-
- cp = strstr(address, ".in-addr.arpa");
- if (!cp || *(cp+strlen(".in-addr.arpa")))
- return 0; /* not an .in-addr.arpa address */
-
- len = cp - address;
-
- if (len >= INET_NTOA_BUF_LEN)
- return -1; /* Too long. */
-
- memcpy(buf, address, len);
- buf[len] = '\0';
- if (tor_inet_aton(buf, &inaddr) == 0)
- return -1; /* malformed. */
-
- if (in) {
- uint32_t a;
- /* reverse the bytes */
- a = (uint32_t) ( ((inaddr.s_addr & 0x000000fful) << 24)
- |((inaddr.s_addr & 0x0000ff00ul) << 8)
- |((inaddr.s_addr & 0x00ff0000ul) >> 8)
- |((inaddr.s_addr & 0xff000000ul) >> 24));
- inaddr.s_addr = a;
-
- memcpy(in, &inaddr, sizeof(inaddr));
- }
-
- return 1;
-}
-
/** See if we have a cache entry for <b>exitconn</b>-\>address. if so,
* if resolve valid, put it into <b>exitconn</b>-\>addr and return 1.
* If resolve failed, free exitconn and return -1.
@@ -646,7 +603,7 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve,
cached_resolve_t search;
pending_connection_t *pending_connection;
routerinfo_t *me;
- struct in_addr in;
+ tor_addr_t addr;
time_t now = time(NULL);
uint8_t is_reverse = 0;
int r;
@@ -657,8 +614,8 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve,
/* first check if exitconn->_base.address is an IP. If so, we already
* know the answer. */
- if (tor_inet_aton(exitconn->_base.address, &in) != 0) {
- tor_addr_from_ipv4n(&exitconn->_base.addr, in.s_addr);
+ if (tor_addr_from_str(&addr, exitconn->_base.address)<0) {
+ tor_addr_assign(&exitconn->_base.addr, &addr);
exitconn->address_ttl = DEFAULT_DNS_TTL;
return 1;
}
@@ -685,11 +642,12 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve,
* .in-addr.arpa address but this isn't a resolve request, kill the
* connection.
*/
- if ((r = parse_inaddr_arpa_address(exitconn->_base.address, &in)) != 0) {
+ if ((r = tor_addr_parse_reverse_lookup_name(&addr, exitconn->_base.address,
+ AF_UNSPEC, 0)) != 0) {
if (r == 1) {
is_reverse = 1;
- if (is_internal_IP(ntohl(in.s_addr), 0)) /* internal address */
- return -1;
+ if (tor_addr_is_internal(&addr, 0)) /* internal address? */
+ return -1;
}
if (!is_reverse || !is_resolve) {
@@ -1298,7 +1256,7 @@ static int
launch_resolve(edge_connection_t *exitconn)
{
char *addr = tor_strdup(exitconn->_base.address);
- struct in_addr in;
+ tor_addr_t a;
int r;
int options = get_options()->ServerDNSSearchDomains ? 0
: DNS_QUERY_NO_SEARCH;
@@ -1311,7 +1269,8 @@ launch_resolve(edge_connection_t *exitconn)
}
}
- r = parse_inaddr_arpa_address(exitconn->_base.address, &in);
+ r = tor_addr_parse_reverse_lookup_name(
+ &a, exitconn->_base.address, AF_UNSPEC, 0);
if (r == 0) {
log_info(LD_EXIT, "Launching eventdns request for %s",
escaped_safe_str(exitconn->_base.address));
@@ -1320,8 +1279,12 @@ launch_resolve(edge_connection_t *exitconn)
} else if (r == 1) {
log_info(LD_EXIT, "Launching eventdns reverse request for %s",
escaped_safe_str(exitconn->_base.address));
- r = evdns_resolve_reverse(&in, DNS_QUERY_NO_SEARCH,
- evdns_callback, addr);
+ if (tor_addr_family(&a) == AF_INET)
+ r = evdns_resolve_reverse(tor_addr_to_in(&a), DNS_QUERY_NO_SEARCH,
+ evdns_callback, addr);
+ else
+ r = evdns_resolve_reverse_ipv6(tor_addr_to_in6(&a), DNS_QUERY_NO_SEARCH,
+ evdns_callback, addr);
} else if (r == -1) {
log_warn(LD_BUG, "Somehow a malformed in-addr.arpa address reached here.");
}
diff --git a/src/or/eventdns.c b/src/or/eventdns.c
index 2b28b2bf94..cd486caaa1 100644
--- a/src/or/eventdns.c
+++ b/src/or/eventdns.c
@@ -2534,7 +2534,7 @@ int evdns_resolve_ipv6(const char *name, int flags,
}
}
-int evdns_resolve_reverse(struct in_addr *in, int flags, evdns_callback_type callback, void *ptr) {
+int evdns_resolve_reverse(const struct in_addr *in, int flags, evdns_callback_type callback, void *ptr) {
char buf[32];
struct request *req;
u32 a;
@@ -2552,7 +2552,7 @@ int evdns_resolve_reverse(struct in_addr *in, int flags, evdns_callback_type cal
return 0;
}
-int evdns_resolve_reverse_ipv6(struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr) {
+int evdns_resolve_reverse_ipv6(const struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr) {
/* 32 nybbles, 32 periods, "ip6.arpa", NUL. */
char buf[73];
char *cp;
diff --git a/src/or/eventdns.h b/src/or/eventdns.h
index d1c34ade7c..df5b936923 100644
--- a/src/or/eventdns.h
+++ b/src/or/eventdns.h
@@ -268,8 +268,8 @@ int evdns_resolve_ipv4(const char *name, int flags, evdns_callback_type callback
int evdns_resolve_ipv6(const char *name, int flags, evdns_callback_type callback, void *ptr);
struct in_addr;
struct in6_addr;
-int evdns_resolve_reverse(struct in_addr *in, int flags, evdns_callback_type callback, void *ptr);
-int evdns_resolve_reverse_ipv6(struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr);
+int evdns_resolve_reverse(const struct in_addr *in, int flags, evdns_callback_type callback, void *ptr);
+int evdns_resolve_reverse_ipv6(const struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr);
int evdns_set_option(const char *option, const char *val, int flags);
int evdns_resolv_conf_parse(int flags, const char *);
#ifdef MS_WINDOWS
diff --git a/src/or/or.h b/src/or/or.h
index b766083f44..9093127ee3 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -3541,7 +3541,6 @@ int dns_resolve(edge_connection_t *exitconn);
void dns_launch_correctness_checks(void);
int dns_seems_to_be_broken(void);
void dns_reset_correctness_checks(void);
-int parse_inaddr_arpa_address(const char *address, struct in_addr *in);
/********************************* dnsserv.c ************************/
diff --git a/src/or/test.c b/src/or/test.c
index 8b07ee536a..28bf46f952 100644
--- a/src/or/test.c
+++ b/src/or/test.c
@@ -1621,6 +1621,70 @@ test_util_ip6_helpers(void)
p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
test_streq(p1, "18.0.0.1");
+ /* Test tor_addr_parse_reverse_lookup_name */
+ i = tor_addr_parse_reverse_lookup_name(&t1, "Foobar.baz", AF_UNSPEC, 0);
+ test_eq(0, i);
+ i = tor_addr_parse_reverse_lookup_name(&t1, "Foobar.baz", AF_UNSPEC, 1);
+ test_eq(0, i);
+ i = tor_addr_parse_reverse_lookup_name(&t1, "1.0.168.192.in-addr.arpa",
+ AF_UNSPEC, 1);
+ test_eq(1, i);
+ test_eq(tor_addr_family(&t1), AF_INET);
+ p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
+ test_streq(p1, "192.168.0.1");
+ i = tor_addr_parse_reverse_lookup_name(&t1, "192.168.0.99", AF_UNSPEC, 0);
+ test_eq(0, i);
+ i = tor_addr_parse_reverse_lookup_name(&t1, "192.168.0.99", AF_UNSPEC, 1);
+ test_eq(1, i);
+ p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
+ test_streq(p1, "192.168.0.99");
+ memset(&t1, 0, sizeof(t1));
+ i = tor_addr_parse_reverse_lookup_name(&t1,
+ "0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f."
+ "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
+ "ip6.ARPA",
+ AF_UNSPEC, 0);
+ test_eq(1, i);
+ p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
+ test_streq(p1, "[9dee:effe:ebe1:beef:fedc:ba98:7654:3210]");
+ /* Failing cases. */
+ i = tor_addr_parse_reverse_lookup_name(&t1,
+ "6.7.8.9.a.b.c.d.e.f."
+ "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
+ "ip6.ARPA",
+ AF_UNSPEC, 0);
+ test_eq(i, -1);
+ i = tor_addr_parse_reverse_lookup_name(&t1,
+ "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.f.0."
+ "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
+ "ip6.ARPA",
+ AF_UNSPEC, 0);
+ test_eq(i, -1);
+ i = tor_addr_parse_reverse_lookup_name(&t1,
+ "6.7.8.9.a.b.c.d.e.f.X.0.0.0.0.9."
+ "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
+ "ip6.ARPA",
+ AF_UNSPEC, 0);
+ test_eq(i, -1);
+ i = tor_addr_parse_reverse_lookup_name(&t1, "32.1.1.in-addr.arpa",
+ AF_UNSPEC, 0);
+ /* test_eq(i, -1); XXXX021 Apparently '32.1.1' is a valid aton address. */
+ i = tor_addr_parse_reverse_lookup_name(&t1, ".in-addr.arpa",
+ AF_UNSPEC, 0);
+ test_eq(i, -1);
+ i = tor_addr_parse_reverse_lookup_name(&t1, "1.2.3.4.5.in-addr.arpa",
+ AF_UNSPEC, 0);
+ test_eq(i, -1);
+ i = tor_addr_parse_reverse_lookup_name(&t1, "1.2.3.4.5.in-addr.arpa",
+ AF_INET6, 0);
+ test_eq(i, -1);
+ i = tor_addr_parse_reverse_lookup_name(&t1,
+ "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.0."
+ "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
+ "ip6.ARPA",
+ AF_INET, 0);
+ test_eq(i, -1);
+
/* test tor_addr_parse_mask_ports */
test_addr_mask_ports_parse("[::f]/17:47-95", AF_INET6,
0, 0, 0, 0x0000000f, 17, 47, 95);