Implement RedirectExit.

svn:r2550
This commit is contained in:
Nick Mathewson 2004-10-17 01:57:34 +00:00
parent 5efc49600a
commit 8d27385c23
3 changed files with 30 additions and 7 deletions

View File

@ -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.

View File

@ -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));

View File

@ -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);