summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-10-17 01:57:34 +0000
committerNick Mathewson <nickm@torproject.org>2004-10-17 01:57:34 +0000
commit8d27385c234da5d4085dae78b7ecd5efa4c79481 (patch)
tree77e54b60062718a73ff9dafab1be77cfab89e6ea
parent5efc49600a66dc90795e4a88488f04b506a6d4c5 (diff)
downloadtor-8d27385c234da5d4085dae78b7ecd5efa4c79481.tar.gz
tor-8d27385c234da5d4085dae78b7ecd5efa4c79481.zip
Implement RedirectExit.
svn:r2550
-rw-r--r--doc/TODO8
-rw-r--r--src/or/config.c6
-rw-r--r--src/or/connection_edge.c23
3 files changed, 30 insertions, 7 deletions
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);