diff --git a/doc/TODO b/doc/TODO index e51804ecd9..5793e754c7 100644 --- a/doc/TODO +++ b/doc/TODO @@ -28,9 +28,9 @@ R - figure out enclaves, e.g. so we know what to recommend that people do, and so running a tor server on your website is helpful. - Do enclaves for same IP only. - Resolve first, then if IP is an OR, connect to next guy. -N - let tor servers use proxies for port 80 exits - - Use generic port redirector for IP/bits:Port->IP:Port . - - Make use of them when we're doing exit connections. + o let tor servers use proxies for port 80 exits + o Use generic port redirector for IP/bits:Port->IP:Port . + o Make use of them when we're doing exit connections. X We should set things in options to NULL, not rely on memset(...0) being equivalent. o We should check for memset(0) setting things to NULL with autoconf, @@ -59,6 +59,8 @@ R - learn from ben about his openssl-reinitialization-trick to D nt services on win32. 0.0.9 and beyond: + - Should redirects change conn->addr/port or not? Either HTTP + proxying or exit redirection is doing the wrong thing. - fix sprintf's to snprintf's? . Make intro points and rendezvous points accept $KEYID in addition to nicknames. diff --git a/src/or/config.c b/src/or/config.c index 21d8e6fbab..f0746b79ab 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -38,6 +38,7 @@ static int parse_dir_server_line(const char *line); static int parse_redirect_line(or_options_t *options, struct config_line_t *line); + /** Helper: Read a list of configuration options from the command line. */ static struct config_line_t * config_get_commandlines(int argc, char **argv) @@ -483,9 +484,10 @@ free_options(or_options_t *options) config_free_lines(options->NodeFamilies); config_free_lines(options->RedirectExit); if (options->RedirectExitList) { - SMARTLIST_FOREACH(options->RedirectExitList,exit_redirect_t *, p, tor_free(p)); + SMARTLIST_FOREACH(options->RedirectExitList, + exit_redirect_t *, p, tor_free(p)); smartlist_free(options->RedirectExitList); - options->RedirectExitList = NULL; + options->RedirectExitList = NULL; } if (options->FirewallPorts) { SMARTLIST_FOREACH(options->FirewallPorts, char *, cp, tor_free(cp)); diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 81b069d54e..f82ed6de0d 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -599,7 +599,7 @@ int connection_ap_make_bridge(char *address, uint16_t port) { conn->socks_request->command = SOCKS_COMMAND_CONNECT; conn->address = tor_strdup("(local bridge)"); - conn->addr = ntohs(0); + conn->addr = 0; conn->port = 0; if(connection_add(conn) < 0) { /* no space, forget it */ @@ -882,6 +882,8 @@ int connection_exit_begin_resolve(cell_t *cell, circuit_t *circ) { */ void connection_exit_connect(connection_t *conn) { unsigned char connected_payload[4]; + uint32_t addr; + uint16_t port; if (!connection_edge_is_rendezvous_stream(conn) && router_compare_to_my_exit_policy(conn) == ADDR_POLICY_REJECTED) { @@ -892,8 +894,24 @@ void connection_exit_connect(connection_t *conn) { return; } + addr = conn->addr; + port = conn->port; + SMARTLIST_FOREACH(options.RedirectExitList, exit_redirect_t *, r, + { + if ((addr&r->mask)==(r->addr&r->mask) && + (r->port_min <= port) && (port <= r->port_max)) { + struct in_addr in; + addr = r->addr_dest; + port = r->port_dest; + in.s_addr = htonl(addr); + log_fn(LOG_DEBUG, "Redirecting connection from %s:%d to %s:%d", + conn->address, conn->port, inet_ntoa(in), port); + break; + } + }); + log_fn(LOG_DEBUG,"about to try connecting"); - switch(connection_connect(conn, conn->address, conn->addr, conn->port)) { + switch(connection_connect(conn, conn->address, addr, port)) { case -1: connection_edge_end(conn, END_STREAM_REASON_CONNECTFAILED, conn->cpath_layer); circuit_detach_stream(circuit_get_by_conn(conn), conn); @@ -922,6 +940,7 @@ void connection_exit_connect(connection_t *conn) { connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_CONNECTED, NULL, 0, conn->cpath_layer); } else { /* normal stream */ + /* This must be the original address, not the redirected address. */ *(uint32_t*)connected_payload = htonl(conn->addr); connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_CONNECTED, connected_payload, 4, conn->cpath_layer);