[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] Add a new AddressMap directive to rewrite incoming socks ad...
- To: or-cvs@xxxxxxxxxxxxx
- Subject: [or-cvs] Add a new AddressMap directive to rewrite incoming socks ad...
- From: arma@xxxxxxxx (Roger Dingledine)
- Date: Mon, 21 Feb 2005 19:53:10 -0500 (EST)
- Delivered-to: archiver@seul.org
- Delivered-to: or-cvs-outgoing@seul.org
- Delivered-to: or-cvs@seul.org
- Delivery-date: Mon, 21 Feb 2005 19:53:38 -0500
- Reply-to: or-dev@xxxxxxxxxxxxx
- Sender: owner-or-cvs@xxxxxxxxxxxxx
Update of /home2/or/cvsroot/tor/src/or
In directory moria.mit.edu:/home2/arma/work/onion/cvs/tor/src/or
Modified Files:
circuituse.c config.c connection_edge.c main.c or.h relay.c
Log Message:
Add a new AddressMap directive to rewrite incoming socks addresses.
Add a new TrackHostExits directive to trigger addressmaps for
certain incoming socks addresses, for sites that break when your exit
keeps changing.
Redo the client-side dns cache so it's just an addressmap too.
Index: circuituse.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/circuituse.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -d -r1.49 -r1.50
--- circuituse.c 2 Feb 2005 06:26:52 -0000 1.49
+++ circuituse.c 22 Feb 2005 00:53:07 -0000 1.50
@@ -385,7 +385,7 @@
circuit_reset_failure_count(1);
time_to_new_circuit = now + get_options()->NewCircuitPeriod;
if (proxy_mode(get_options()))
- client_dns_clean();
+ addressmap_clean(now);
circuit_expire_old_circuits();
#if 0 /* disable for now, until predict-and-launch-new can cull leftovers */
@@ -768,7 +768,6 @@
uint8_t desired_circuit_purpose,
circuit_t **circp) {
circuit_t *circ;
- uint32_t addr;
int is_resolve;
int need_uptime;
@@ -801,7 +800,10 @@
/* Do we need to check exit policy? */
if (!is_resolve && !connection_edge_is_rendezvous_stream(conn)) {
- addr = client_dns_lookup_entry(conn->socks_request->address);
+ struct in_addr in;
+ uint32_t addr = 0;
+ if (tor_inet_aton(conn->socks_request->address, &in))
+ addr = ntohl(in.s_addr);
if (router_exit_policy_all_routers_reject(addr, conn->socks_request->port,
need_uptime)) {
log_fn(LOG_NOTICE,"No Tor server exists that allows exit to %s:%d. Rejecting.",
@@ -899,6 +901,53 @@
apconn->cpath_layer = circ->cpath->prev;
}
+/** If an exit wasn't specifically chosen, save the history for future
+ * use */
+static void
+consider_recording_trackhost(connection_t *conn, circuit_t *circ) {
+ int found_needle = 0;
+ char *str;
+ or_options_t *options = get_options();
+ size_t len;
+ char *new_address;
+
+ /* Search the addressmap for this conn's destination. */
+ /* If he's not in the address map.. */
+ if (!options->TrackHostExits ||
+ addressmap_already_mapped(conn->socks_request->address))
+ return; /* nothing to track, or already mapped */
+
+ SMARTLIST_FOREACH(options->TrackHostExits, const char *, cp, {
+ if (cp[0] == '.') { /* match end */
+ /* XXX strstr is probably really bad here */
+ if ((str = strstr(conn->socks_request->address, &cp[1]))) {
+ if (str == conn->socks_request->address
+ || strcmp(str, &cp[1]) == 0) {
+ found_needle = 1;
+ }
+ }
+ } else if (strcmp(cp, conn->socks_request->address) == 0) {
+ found_needle = 1;
+ }
+ });
+
+ if (!found_needle)
+ return;
+
+ /* Add this exit/hostname pair to the addressmap. */
+ len = strlen(conn->socks_request->address) + 1 /* '.' */ +
+ strlen(circ->build_state->chosen_exit_name) + 1 /* '.' */ +
+ strlen("exit") + 1 /* '\0' */;
+ new_address = tor_malloc(len);
+
+ tor_snprintf(new_address, len, "%s.%s.exit",
+ conn->socks_request->address,
+ circ->build_state->chosen_exit_name);
+
+ addressmap_register(conn->socks_request->address, new_address,
+ time(NULL) + options->TrackHostExitsExpire);
+}
+
/** Try to find a safe live circuit for CONN_TYPE_AP connection conn. If
* we don't find one: if conn cannot be handled by any known nodes,
* warn and return -1 (conn needs to die);
@@ -957,7 +1006,7 @@
link_apconn_to_circ(conn, circ);
tor_assert(conn->socks_request);
if (conn->socks_request->command == SOCKS_COMMAND_CONNECT) {
-// consider_recording_trackhost(conn, circ);
+ consider_recording_trackhost(conn, circ);
connection_ap_handshake_send_begin(conn, circ);
} else {
connection_ap_handshake_send_resolve(conn, circ);
Index: config.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/config.c,v
retrieving revision 1.312
retrieving revision 1.313
diff -u -d -r1.312 -r1.313
--- config.c 11 Feb 2005 01:26:46 -0000 1.312
+++ config.c 22 Feb 2005 00:53:07 -0000 1.313
@@ -120,6 +120,9 @@
VAR("StrictEntryNodes", BOOL, StrictEntryNodes, "0"),
VAR("ExitPolicy", LINELIST, ExitPolicy, NULL),
VAR("ExcludeNodes", STRING, ExcludeNodes, NULL),
+ VAR("TrackHostExits", CSV, TrackHostExits, NULL),
+ VAR("TrackHostExitsExpire",INTERVAL, TrackHostExitsExpire, "30 minutes"),
+ VAR("AddressMap", LINELIST, AddressMap, NULL),
VAR("FascistFirewall", BOOL, FascistFirewall, "0"),
VAR("FirewallPorts", CSV, FirewallPorts, "80,443"),
VAR("MyFamily", STRING, MyFamily, NULL),
@@ -186,6 +189,7 @@
static int options_validate(or_options_t *options);
static int options_transition_allowed(or_options_t *old, or_options_t *new);
static int check_nickname_list(const char *lst, const char *name);
+static void config_register_addressmaps(or_options_t *options);
static int parse_dir_server_line(const char *line, int validate_only);
static int parse_redirect_line(smartlist_t *result,
@@ -333,6 +337,9 @@
if (options->PidFile)
write_pidfile(options->PidFile);
+ /* Register addressmap directives */
+ config_register_addressmaps(options);
+
/* Update address policies. */
parse_socks_policy();
parse_dir_policy();
@@ -1797,6 +1804,29 @@
return -1;
}
+static void
+config_register_addressmaps(or_options_t *options) {
+ smartlist_t *elts;
+ struct config_line_t *opt;
+ char *from, *to;
+
+ elts = smartlist_create();
+ for (opt = options->AddressMap; opt; opt = opt->next) {
+ smartlist_split_string(elts, opt->value, NULL,
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
+ if (smartlist_len(elts) >= 2) {
+ from = smartlist_get(elts,0);
+ to = smartlist_get(elts,1);
+ addressmap_register(from, tor_strdup(to), 0);
+ } else {
+ log_fn(LOG_WARN,"AddressMap '%s' has too few arguments. Ignoring.", opt->value);
+ }
+ SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
+ smartlist_clear(elts);
+ }
+ smartlist_free(elts);
+}
+
/** If <b>range</b> is of the form MIN-MAX, for MIN and MAX both
* recognized log severity levels, set *<b>min_out</b> to MIN and
* *<b>max_out</b> to MAX and return 0. Else, if <b>range<b> is of
Index: connection_edge.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/connection_edge.c,v
retrieving revision 1.278
retrieving revision 1.279
diff -u -d -r1.278 -r1.279
--- connection_edge.c 17 Feb 2005 01:12:50 -0000 1.278
+++ connection_edge.c 22 Feb 2005 00:53:07 -0000 1.279
@@ -329,6 +329,169 @@
}
}
+/** A client-side struct to remember requests to rewrite addresses
+ * to new addresses. These structs make up a tree, with addressmap
+ * below as its root.
+ *
+ * There are 5 ways to set an address mapping:
+ * - A MapAddress command from the controller [permanent]
+ * - An AddressMap directive in the torrc [permanent]
+ * - When a TrackHostExits torrc directive is triggered [temporary]
+ * - When a dns resolve succeeds [temporary]
+ * - When a dns resolve fails [temporary]
+ *
+ * When an addressmap request is made but one is already registered,
+ * the new one is replaced only if the currently registered one has
+ * no "new_address" (that is, it's in the process of dns resolve),
+ * or if the new one is permanent (expires==0).
+ */
+typedef struct {
+ char *new_address;
+ time_t expires;
+ int num_resolve_failures;
+} addressmap_entry_t;
+
+/** The tree of client-side address rewrite instructions. */
+static strmap_t *addressmap;
+
+/** Initialize addressmap. */
+void addressmap_init(void) {
+ addressmap = strmap_new();
+}
+
+/** Free the memory associated with the addressmap entry <b>_ent</b>. */
+static void
+addressmap_ent_free(void *_ent) {
+ addressmap_entry_t *ent = _ent;
+ tor_free(ent->new_address);
+ tor_free(ent);
+}
+
+/** A helper function for addressmap_clean() below. If ent is too old,
+ * then remove it from the tree and return NULL, else return ent.
+ */
+static void *
+_addressmap_remove_if_expired(const char *addr,
+ addressmap_entry_t *ent,
+ time_t *nowp) {
+ if (ent->expires && ent->expires < *nowp) {
+ log(LOG_NOTICE, "Addressmap: expiring remap (%s to %s)",
+ addr, ent->new_address);
+ addressmap_ent_free(ent);
+ return NULL;
+ } else {
+ return ent;
+ }
+}
+
+/** Clean out entries from the addressmap cache that were
+ * added long enough ago that they are no longer valid.
+ */
+void addressmap_clean(time_t now) {
+ strmap_foreach(addressmap,
+ (strmap_foreach_fn)_addressmap_remove_if_expired, &now);
+}
+
+/** Free all the elements in the addressmap, and free the addressmap
+ * itself. */
+void addressmap_free_all(void) {
+ strmap_free(addressmap, addressmap_ent_free);
+ addressmap = NULL;
+}
+
+/** Look at address, and rewrite it until it doesn't want any
+ * more rewrites; but don't get into an infinite loop.
+ * Don't write more than maxlen chars into address.
+ */
+void addressmap_rewrite(char *address, size_t maxlen) {
+ addressmap_entry_t *ent;
+ int rewrites;
+
+ for (rewrites = 0; rewrites < 16; rewrites++) {
+ ent = strmap_get(addressmap, address);
+
+ if (!ent || !ent->new_address)
+ return; /* done, no rewrite needed */
+
+ log_fn(LOG_NOTICE, "Addressmap: rewriting '%s' to '%s'",
+ address, ent->new_address);
+ strlcpy(address, ent->new_address, maxlen);
+ }
+ log_fn(LOG_WARN,"Loop detected: we've rewritten '%s' 16 times! Using it as-is.",
+ address);
+ /* it's fine to rewrite a rewrite, but don't loop forever */
+}
+
+/** Return 1 if <b>address</b> is already registered, else return 0 */
+int addressmap_already_mapped(const char *address) {
+ return strmap_get(addressmap, address) ? 1 : 0;
+}
+
+/** Register a request to map <b>address</b> to <b>new_address</b>,
+ * which will expire on <b>expires</b> (or 0 if never expires).
+ *
+ * new_address should be a newly dup'ed string, which we'll use or
+ * free as appropriate. We will leave address alone.
+ */
+void addressmap_register(const char *address, char *new_address, time_t expires) {
+ addressmap_entry_t *ent;
+
+ ent = strmap_get(addressmap, address);
+ if (ent && ent->new_address && expires) {
+ log_fn(LOG_NOTICE,"Addressmap ('%s' to '%s') not performed, since it's already mapped to '%s'", address, new_address, ent->new_address);
+ tor_free(new_address);
+ return;
+ }
+ if (ent) { /* we'll replace it */
+ tor_free(ent->new_address);
+ } else { /* make a new one and register it */
+ ent = tor_malloc_zero(sizeof(addressmap_entry_t));
+ strmap_set(addressmap, address, ent);
+ }
+ ent->new_address = new_address;
+ ent->expires = expires;
+ ent->num_resolve_failures = 0;
+
+ log_fn(LOG_NOTICE, "Addressmap: (re)mapped '%s' to '%s'",
+ address, ent->new_address);
+}
+
+/** An attempt to resolve <b>address</b> failed at some OR.
+ * Increment the number of resolve failures we have on record
+ * for it, and then return that number.
+ */
+int client_dns_incr_failures(const char *address)
+{
+ addressmap_entry_t *ent;
+ ent = strmap_get(addressmap,address);
+ if (!ent) {
+ ent = tor_malloc_zero(sizeof(addressmap_entry_t));
+ ent->expires = time(NULL)+MAX_DNS_ENTRY_AGE;
+ strmap_set(addressmap,address,ent);
+ }
+ ++ent->num_resolve_failures;
+ log_fn(LOG_NOTICE,"Address %s now has %d resolve failures.",
+ address, ent->num_resolve_failures);
+ return ent->num_resolve_failures;
+}
+
+/** Record the fact that <b>address</b> resolved to <b>val</b>.
+ * We can now use this in subsequent streams via addressmap_rewrite()
+ * so we can more correctly choose an exit that will allow <b>address</b>.
+ */
+void client_dns_set_addressmap(const char *address, uint32_t val)
+{
+ struct in_addr in;
+
+ tor_assert(address); tor_assert(val);
+
+ if (tor_inet_aton(address, &in))
+ return; /* don't set an addressmap back to ourselves! */
+ in.s_addr = htonl(val);
+ addressmap_register(address, strdup(inet_ntoa(in)),
+ time(NULL) + MAX_DNS_ENTRY_AGE);
+}
+
/** Return 1 if <b>address</b> has funny characters in it like
* colons. Return 0 if it's fine.
*/
@@ -383,6 +546,11 @@
return sockshere;
} /* else socks handshake is done, continue processing */
+ tor_strlower(socks->address); /* normalize it */
+
+ /* For address map controls, remap the address */
+ addressmap_rewrite(socks->address, sizeof(socks->address));
+
/* Parse the address provided by SOCKS. Modify it in-place if it
* specifies a hidden-service (.onion) or particular exit node (.exit).
*/
@@ -408,7 +576,7 @@
}
if (socks->command == SOCKS_COMMAND_RESOLVE) {
- uint32_t answer = 0;
+ uint32_t answer;
struct in_addr in;
/* Reply to resolves immediately if we can. */
if (strlen(socks->address) > RELAY_PAYLOAD_SIZE) {
@@ -416,11 +584,8 @@
connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_ERROR,0,NULL);
return -1;
}
- if (tor_inet_aton(socks->address, &in)) /* see if it's an IP already */
+ if (tor_inet_aton(socks->address, &in)) { /* see if it's an IP already */
answer = in.s_addr;
- if (!answer && !conn->chosen_exit_name) /* if it's not .exit, check cache */
- answer = htonl(client_dns_lookup_entry(socks->address));
- if (answer) {
connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_IPV4,4,
(char*)&answer);
conn->has_sent_end = 1;
@@ -514,8 +679,6 @@
{
char payload[CELL_PAYLOAD_SIZE];
int payload_len;
- struct in_addr in;
- const char *string_addr;
tor_assert(ap_conn->type == CONN_TYPE_AP);
tor_assert(ap_conn->state == AP_CONN_STATE_CIRCUIT_WAIT);
@@ -530,18 +693,10 @@
return -1;
}
- if (circ->purpose == CIRCUIT_PURPOSE_C_GENERAL) {
- in.s_addr = htonl(client_dns_lookup_entry(ap_conn->socks_request->address));
- string_addr = in.s_addr ? inet_ntoa(in) : NULL;
-
- tor_snprintf(payload,RELAY_PAYLOAD_SIZE,
- "%s:%d",
- string_addr ? string_addr : ap_conn->socks_request->address,
- ap_conn->socks_request->port);
- } else {
- tor_snprintf(payload,RELAY_PAYLOAD_SIZE,
- ":%d", ap_conn->socks_request->port);
- }
+ tor_snprintf(payload,RELAY_PAYLOAD_SIZE, "%s:%d",
+ (circ->purpose == CIRCUIT_PURPOSE_C_GENERAL) ?
+ ap_conn->socks_request->address : "",
+ ap_conn->socks_request->port);
payload_len = strlen(payload)+1;
log_fn(LOG_DEBUG,"Sending relay cell to begin stream %d.",ap_conn->stream_id);
@@ -670,7 +825,7 @@
if (answer_type == RESOLVED_TYPE_IPV4) {
uint32_t a = get_uint32(answer);
if (a)
- client_dns_set_entry(conn->socks_request->address, ntohl(a));
+ client_dns_set_addressmap(conn->socks_request->address, ntohl(a));
}
if (conn->socks_request->socks_version == 4) {
@@ -844,6 +999,7 @@
tor_free(address);
return 0;
}
+ tor_strlower(address);
n_stream->address = address;
n_stream->state = EXIT_CONN_STATE_RESOLVEFAILED;
/* default to failed, change in dns_resolve if it turns out not to fail */
@@ -1018,8 +1174,6 @@
*/
int connection_ap_can_use_exit(connection_t *conn, routerinfo_t *exit)
{
- uint32_t addr;
-
tor_assert(conn);
tor_assert(conn->type == CONN_TYPE_AP);
tor_assert(conn->socks_request);
@@ -1042,7 +1196,10 @@
}
if (conn->socks_request->command != SOCKS_COMMAND_RESOLVE) {
- addr = client_dns_lookup_entry(conn->socks_request->address);
+ struct in_addr in;
+ uint32_t addr = 0;
+ if (tor_inet_aton(conn->socks_request->address, &in))
+ addr = ntohl(in.s_addr);
if (router_compare_addr_to_addr_policy(addr, conn->socks_request->port,
exit->exit_policy) == ADDR_POLICY_REJECTED)
return 0;
@@ -1098,164 +1255,6 @@
return 0;
}
-/* ***** Client DNS code ***** */
-
-/* XXX Perhaps this should get merged with the dns.c code somehow. */
-/* XXX But we can't just merge them, because then nodes that act as
- * both OR and OP could be attacked: people could rig the dns cache
- * by answering funny things to stream begin requests, and later
- * other clients would reuse those funny addr's. Hm.
- */
-
-/** A client-side struct to remember the resolved IP (addr) for
- * a given address. These structs make up a tree, with client_dns_map
- * below as its root.
- */
-struct client_dns_entry {
- uint32_t addr; /**< The resolved IP of this entry. */
- time_t expires; /**< At what second does addr expire? */
- int n_failures; /**< How many times has this entry failed to resolve so far? */
-};
-
-/** How many elements are in the client dns cache currently? */
-static int client_dns_size = 0;
-/** The tree of client-side cached DNS resolves. */
-static strmap_t *client_dns_map = NULL;
-
-/** Initialize client_dns_map and client_dns_size. */
-void client_dns_init(void) {
- client_dns_map = strmap_new();
- client_dns_size = 0;
-}
-
-/** Return the client_dns_entry that corresponds to <b>address</b>.
- * If it's not there, allocate and return a new entry for <b>address</b>.
- */
-static struct client_dns_entry *
-_get_or_create_ent(const char *address)
-{
- struct client_dns_entry *ent;
- ent = strmap_get_lc(client_dns_map,address);
- if (!ent) {
- ent = tor_malloc_zero(sizeof(struct client_dns_entry));
- ent->expires = time(NULL)+MAX_DNS_ENTRY_AGE;
- strmap_set_lc(client_dns_map,address,ent);
- ++client_dns_size;
- }
- return ent;
-}
-
-/** Return the IP associated with <b>address</b>, if we know it
- * and it's still fresh enough. Otherwise return 0.
- */
-uint32_t client_dns_lookup_entry(const char *address)
-{
- struct client_dns_entry *ent;
- struct in_addr in;
- time_t now;
-
- tor_assert(address);
-
- if (tor_inet_aton(address, &in)) {
- log_fn(LOG_DEBUG, "Using static address %s (%08lX)", address,
- (unsigned long)ntohl(in.s_addr));
- return ntohl(in.s_addr);
- }
- ent = strmap_get_lc(client_dns_map,address);
- if (!ent || !ent->addr) {
- log_fn(LOG_DEBUG, "No entry found for address %s", address);
- return 0;
- } else {
- now = time(NULL);
- if (ent->expires < now) {
- log_fn(LOG_DEBUG, "Expired entry found for address %s", address);
- strmap_remove_lc(client_dns_map,address);
- tor_free(ent);
- --client_dns_size;
- return 0;
- }
- in.s_addr = htonl(ent->addr);
- log_fn(LOG_DEBUG, "Found cached entry for address %s: %s", address,
- inet_ntoa(in));
- return ent->addr;
- }
-}
-
-/** An attempt to resolve <b>address</b> failed at some OR.
- * Increment the number of resolve failures we have on record
- * for it, and then return that number.
- */
-int client_dns_incr_failures(const char *address)
-{
- struct client_dns_entry *ent;
- ent = _get_or_create_ent(address);
- ++ent->n_failures;
- log_fn(LOG_DEBUG,"Address %s now has %d resolve failures.",
- address, ent->n_failures);
- return ent->n_failures;
-}
-
-/** Record the fact that <b>address</b> resolved to <b>val</b>.
- * We can now use this in subsequent streams in client_dns_lookup_entry(),
- * so we can more correctly choose a router that will allow <b>address</b>
- * to exit from him.
- */
-void client_dns_set_entry(const char *address, uint32_t val)
-{
- struct client_dns_entry *ent;
- struct in_addr in;
- time_t now;
-
- tor_assert(address);
- tor_assert(val);
-
- if (tor_inet_aton(address, &in))
- return;
- now = time(NULL);
- ent = _get_or_create_ent(address);
- in.s_addr = htonl(val);
- log_fn(LOG_DEBUG, "Updating entry for address %s: %s", address,
- inet_ntoa(in));
- ent->addr = val;
- ent->expires = now+MAX_DNS_ENTRY_AGE;
- ent->n_failures = 0;
-}
-
-/** A helper function for client_dns_clean() below. If ent is too old,
- * then remove it from the tree and return NULL, else return ent.
- */
-static void* _remove_if_expired(const char *addr,
- struct client_dns_entry *ent,
- time_t *nowp)
-{
- if (ent->expires < *nowp) {
- --client_dns_size;
- tor_free(ent);
- return NULL;
- } else {
- return ent;
- }
-}
-
-/** Clean out entries from the client-side DNS cache that were
- * resolved long enough ago that they are no longer valid.
- */
-void client_dns_clean(void)
-{
- time_t now;
-
- if (!client_dns_size)
- return;
- now = time(NULL);
- strmap_foreach(client_dns_map, (strmap_foreach_fn)_remove_if_expired, &now);
-}
-
-void client_dns_free_all(void)
-{
- strmap_free(client_dns_map, free);
- client_dns_map = NULL;
-}
-
/** Make connection redirection follow the provided list of
* exit_redirect_t */
void
@@ -1284,20 +1283,18 @@
s = strrchr(address,'.');
if (!s) return 0; /* no dot, thus normal */
- if (!strcasecmp(s+1,"exit")) {
+ if (!strcmp(s+1,"exit")) {
*s = 0; /* null-terminate it */
return EXIT_HOSTNAME; /* .exit */
}
- if (strcasecmp(s+1,"onion"))
+ if (strcmp(s+1,"onion"))
return NORMAL_HOSTNAME; /* neither .exit nor .onion, thus normal */
/* so it is .onion */
*s = 0; /* null-terminate it */
if (strlcpy(query, address, REND_SERVICE_ID_LEN+1) >= REND_SERVICE_ID_LEN+1)
goto failed;
- tor_strlower(query);
if (rend_valid_service_id(query)) {
- tor_strlower(address);
return ONION_HOSTNAME; /* success */
}
failed:
Index: main.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/main.c,v
retrieving revision 1.446
retrieving revision 1.447
diff -u -d -r1.446 -r1.447
--- main.c 11 Feb 2005 01:41:19 -0000 1.446
+++ main.c 22 Feb 2005 00:53:08 -0000 1.447
@@ -1263,7 +1263,7 @@
rep_hist_init();
/* Initialize the service cache. */
rend_cache_init();
- client_dns_init(); /* Init the client dns cache. Do it always, since it's cheap. */
+ addressmap_init(); /* Init the client dns cache. Do it always, since it's cheap. */
/* give it somewhere to log to initially */
add_temp_log();
@@ -1308,7 +1308,7 @@
{
routerlist_free_current();
free_trusted_dir_servers();
- client_dns_free_all();
+ addressmap_free_all();
free_socks_policy();
free_dir_policy();
dirserv_free_all();
Index: or.h
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.535
retrieving revision 1.536
diff -u -d -r1.535 -r1.536
--- or.h 13 Feb 2005 22:31:26 -0000 1.535
+++ or.h 22 Feb 2005 00:53:08 -0000 1.536
@@ -950,6 +950,10 @@
smartlist_t *FirewallPorts; /**< Which ports our firewall allows (strings). */
/** Application ports that require all nodes in circ to have sufficient uptime. */
smartlist_t *LongLivedPorts;
+ /** Should we try to reuse the same exit node for a given host */
+ smartlist_t *TrackHostExits;
+ int TrackHostExitsExpire; /**< Number of seconds until we expire an addressmap */
+ struct config_line_t *AddressMap; /**< List of address map directives. */
int DirFetchPeriod; /**< How often do we fetch new directories? */
int DirPostPeriod; /**< How often do we post our server descriptor to the
* authoritative directory servers? */
@@ -1212,6 +1216,7 @@
connection_t *connection_get_by_type(int type);
connection_t *connection_get_by_type_state(int type, int state);
+connection_t *connection_get_by_type_purpose(int type, int purpose);
connection_t *connection_get_by_type_state_lastwritten(int type, int state);
connection_t *connection_get_by_type_state_rendquery(int type, int state, const char *rendquery);
connection_t *connection_get_by_type_purpose(int type, int purpose);
@@ -1258,16 +1263,19 @@
void connection_ap_expire_beginning(void);
void connection_ap_attach_pending(void);
+void addressmap_init(void);
+void addressmap_clean(time_t now);
+void addressmap_free_all(void);
+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 client_dns_incr_failures(const char *address);
+void client_dns_set_addressmap(const char *address, uint32_t val);
+
void parse_socks_policy(void);
void free_socks_policy(void);
int socks_policy_permits_address(uint32_t addr);
-void client_dns_init(void);
-uint32_t client_dns_lookup_entry(const char *address);
-int client_dns_incr_failures(const char *address);
-void client_dns_set_entry(const char *address, uint32_t val);
-void client_dns_clean(void);
-void client_dns_free_all(void);
void set_exit_redirects(smartlist_t *lst);
typedef enum hostname_type_t {
NORMAL_HOSTNAME, ONION_HOSTNAME, EXIT_HOSTNAME
Index: relay.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/relay.c,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -d -r1.38 -r1.39
--- relay.c 13 Feb 2005 16:17:32 -0000 1.38
+++ relay.c 22 Feb 2005 00:53:08 -0000 1.39
@@ -516,7 +516,7 @@
connection_mark_for_close(conn);
return 0;
}
- client_dns_set_entry(conn->socks_request->address, addr);
+ client_dns_set_addressmap(conn->socks_request->address, addr);
/* check if he *ought* to have allowed it */
exitrouter = router_get_by_digest(circ->build_state->chosen_exit_digest);
@@ -589,7 +589,7 @@
connection_mark_for_close(conn);
return 0;
}
- client_dns_set_entry(conn->socks_request->address, addr);
+ client_dns_set_addressmap(conn->socks_request->address, addr);
}
circuit_log_path(LOG_INFO,circ);
connection_ap_handshake_socks_reply(conn, NULL, 0, 1);