mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-20 10:12:15 +01:00
r8997@Kushana: nickm | 2006-09-28 23:40:22 -0400
[Needs review.] Add a BEGIN_DIR relay cell type for an easier in-protocol way to connect to directory servers through Tor. Previously, clients could only connect to director servers over Tor from exit nodes, but couldn't get directory information anonymously from a non-exit cache without getting a directory server involved. This needs testing, and needs client-side code to actually exercise it. svn:r8527
This commit is contained in:
parent
fe9481fd1c
commit
9dbfb91f17
@ -8,6 +8,11 @@ Changes in version 0.1.2.2-alpha - 2006-??-??
|
||||
support eventdns.
|
||||
- Specify and implement client-side SOCKS5 interface for reverse DNS
|
||||
lookups; see doc/socks-extensions.txt for full information.
|
||||
- Add a BEGIN_DIR relay cell type for an easier in-protocol way to
|
||||
connect to directory servers through Tor. Previously, clients could
|
||||
only connect to director servers over Tor from exit nodes, but couldn't
|
||||
get directory information anonymously from a non-exit cache without
|
||||
getting a directory server involved.
|
||||
|
||||
o Minor features:
|
||||
- Check for name servers (like Earthlink's) that hijack failing DNS
|
||||
|
10
doc/TODO
10
doc/TODO
@ -52,7 +52,7 @@ P - Figure out why openssl 0.9.8c "make test" fails at sha256t test.
|
||||
Items for 0.1.2.x:
|
||||
o re-enable blossom functionality: let tor servers decide if they
|
||||
will use local search when resolving, or not.
|
||||
N - Document it.
|
||||
o Document it.
|
||||
- enumerate events of important things that occur in tor, so vidalia can
|
||||
react.
|
||||
N - Backend implementation
|
||||
@ -61,11 +61,13 @@ R - Actually list all the events (notice and warn log messages are a good
|
||||
N - Specify general event system
|
||||
R - Specify actual events.
|
||||
|
||||
N - Have (and document) a BEGIN_DIR relay cell that means "Connect to your
|
||||
N . Have (and document) a BEGIN_DIR relay cell that means "Connect to your
|
||||
directory port."
|
||||
- Specify
|
||||
- Implement
|
||||
o Specify
|
||||
o Implement
|
||||
- Use for something, so we can be sure it works.
|
||||
- Test and debug
|
||||
|
||||
|
||||
x - We should ship with a list of stable dir mirrors -- they're not
|
||||
trusted like the authorities, but they'll provide more robustness
|
||||
|
@ -624,6 +624,7 @@ TODO:
|
||||
10 -- RELAY_DROP [forward or backward]
|
||||
11 -- RELAY_RESOLVE [forward]
|
||||
12 -- RELAY_RESOLVED [backward]
|
||||
13 -- RELAY_BEGIN_DIR [forward]
|
||||
|
||||
Commands labelled as "forward" must only be sent by the originator
|
||||
of the circuit. Commands labelled as "backward" must only be sent by
|
||||
@ -710,6 +711,16 @@ TODO:
|
||||
Relay RELAY_DROP cells are long-range dummies; upon receiving such
|
||||
a cell, the OR or OP must drop it.
|
||||
|
||||
6.2.1. Opening a directory stream
|
||||
|
||||
If a Tor server is a directory server, it should respond to a
|
||||
RELAY_BEGIN_DIR cell as if it had received a BEGIN cell requesting a
|
||||
connection to its directory port. RELAY_BEGIN_DIR cells ignore exit
|
||||
policy, since the stream is local to the Tor process.
|
||||
|
||||
If the Tor server is not running a directory service, it should respond
|
||||
with a REASON_NOTDIRECTORY RELAY_END cell.
|
||||
|
||||
6.3. Closing streams
|
||||
|
||||
When an anonymized TCP connection is closed, or an edge node
|
||||
@ -738,6 +749,8 @@ TODO:
|
||||
12 -- REASON_CONNRESET (Connection was unexpectedly reset)
|
||||
13 -- REASON_TORPROTOCOL (Sent when closing connection because of
|
||||
Tor protocol violations.)
|
||||
14 -- REASON_NOTDIRECTORY (Client send RELAY_BEGIN_DIR to a
|
||||
non-directory server.)
|
||||
|
||||
(With REASON_EXITPOLICY, the 4-byte IPv4 address or 16-byte IPv6 address
|
||||
forms the optional data; no other reason currently has extra data.
|
||||
|
@ -29,6 +29,7 @@ static smartlist_t *redirect_exit_list = NULL;
|
||||
|
||||
static int connection_ap_handshake_process_socks(edge_connection_t *conn);
|
||||
static int connection_ap_process_transparent(edge_connection_t *conn);
|
||||
static int connection_exit_connect_dir(edge_connection_t *exit_conn);
|
||||
|
||||
/** An AP stream has failed/finished. If it hasn't already sent back
|
||||
* a socks reply, send one now (based on endreason). Also set
|
||||
@ -1813,33 +1814,41 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
|
||||
}
|
||||
|
||||
relay_header_unpack(&rh, cell->payload);
|
||||
|
||||
if (!memchr(cell->payload+RELAY_HEADER_SIZE, 0, rh.length)) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||
"Relay begin cell has no \\0. Dropping.");
|
||||
return 0;
|
||||
}
|
||||
if (parse_addr_port(LOG_PROTOCOL_WARN, cell->payload+RELAY_HEADER_SIZE,
|
||||
&address,NULL,&port)<0) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||
"Unable to parse addr:port in relay begin cell. Dropping.");
|
||||
return 0;
|
||||
}
|
||||
if (port==0) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||
"Missing port in relay begin cell. Dropping.");
|
||||
tor_free(address);
|
||||
return 0;
|
||||
}
|
||||
if (rh.command == RELAY_COMMAND_BEGIN) {
|
||||
if (!memchr(cell->payload+RELAY_HEADER_SIZE, 0, rh.length)) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||
"Relay begin cell has no \\0. Dropping.");
|
||||
return 0;
|
||||
}
|
||||
if (parse_addr_port(LOG_PROTOCOL_WARN, cell->payload+RELAY_HEADER_SIZE,
|
||||
&address,NULL,&port)<0) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||
"Unable to parse addr:port in relay begin cell. Dropping.");
|
||||
return 0;
|
||||
}
|
||||
if (port==0) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||
"Missing port in relay begin cell. Dropping.");
|
||||
tor_free(address);
|
||||
return 0;
|
||||
}
|
||||
#if 0
|
||||
if (!tor_strisprint(address)) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||
"Non-printing characters in address %s in relay "
|
||||
"begin cell. Dropping.", escaped(address));
|
||||
tor_free(address);
|
||||
if (!tor_strisprint(address)) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||
"Non-printing characters in address %s in relay "
|
||||
"begin cell. Dropping.", escaped(address));
|
||||
tor_free(address);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
} else if (rh.command == RELAY_COMMAND_BEGIN_DIR) {
|
||||
or_options_t *options = get_options();
|
||||
address = tor_strdup("127.0.0.1");
|
||||
port = options->DirPort; /* not actually used. */
|
||||
} else {
|
||||
log_warn(LD_BUG, "Got an unexpected command %d", (int)rh.command);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
log_debug(LD_EXIT,"Creating new exit connection.");
|
||||
n_stream = TO_EDGE_CONN(connection_new(CONN_TYPE_EXIT));
|
||||
@ -1851,6 +1860,15 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
|
||||
n_stream->package_window = STREAMWINDOW_START;
|
||||
n_stream->deliver_window = STREAMWINDOW_START;
|
||||
|
||||
if (rh.command == RELAY_COMMAND_BEGIN_DIR &&
|
||||
(!get_options()->DirPort || circ->purpose != CIRCUIT_PURPOSE_OR)) {
|
||||
connection_edge_end(n_stream, END_STREAM_REASON_NOTDIRECTORY,
|
||||
n_stream->cpath_layer);
|
||||
connection_free(TO_CONN(n_stream));
|
||||
tor_free(address);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (circ->purpose == CIRCUIT_PURPOSE_S_REND_JOINED) {
|
||||
origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ);
|
||||
log_debug(LD_REND,"begin is for rendezvous. configuring stream.");
|
||||
@ -1898,6 +1916,13 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
|
||||
}
|
||||
log_debug(LD_EXIT,"about to start the dns_resolve().");
|
||||
|
||||
if (rh.command == RELAY_COMMAND_BEGIN_DIR) {
|
||||
n_stream->next_stream = TO_OR_CIRCUIT(circ)->n_streams;
|
||||
n_stream->on_circuit = circ;
|
||||
TO_OR_CIRCUIT(circ)->n_streams = n_stream;
|
||||
return connection_exit_connect_dir(n_stream);
|
||||
}
|
||||
|
||||
/* send it off to the gethostbyname farm */
|
||||
switch (dns_resolve(n_stream, NULL)) {
|
||||
case 1: /* resolve worked */
|
||||
@ -2067,6 +2092,83 @@ connection_exit_connect(edge_connection_t *edge_conn)
|
||||
}
|
||||
}
|
||||
|
||||
/** Given an exit conn that should attach to us as a directory server, open a
|
||||
* bridge connection with a socketpair, create a new directory conn, and join
|
||||
* them together. Return 0 on success (or if there was an error we could send
|
||||
* back an end cell for). Return -1 if the circuit needs to be torn down.
|
||||
* Either connects exit_conn, or frees it, or marks it as appropriate.
|
||||
*/
|
||||
static int
|
||||
connection_exit_connect_dir(edge_connection_t *exit_conn)
|
||||
{
|
||||
int fd[2];
|
||||
int err;
|
||||
dir_connection_t *dir_conn = NULL;
|
||||
|
||||
log_info(LD_EXIT, "Opening dir bridge");
|
||||
|
||||
if ((err = tor_socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) < 0) {
|
||||
log_warn(LD_NET,
|
||||
"Couldn't construct socketpair (%s). Network down? Delaying.",
|
||||
tor_socket_strerror(-err));
|
||||
connection_edge_end(exit_conn, END_STREAM_REASON_RESOURCELIMIT,
|
||||
exit_conn->cpath_layer);
|
||||
connection_free(TO_CONN(exit_conn));
|
||||
return 0;
|
||||
}
|
||||
|
||||
tor_assert(fd[0] >= 0);
|
||||
tor_assert(fd[1] >= 0);
|
||||
|
||||
set_socket_nonblocking(fd[0]);
|
||||
set_socket_nonblocking(fd[1]);
|
||||
|
||||
exit_conn->_base.s = fd[0];
|
||||
exit_conn->_base.state = EXIT_CONN_STATE_OPEN;
|
||||
|
||||
dir_conn = TO_DIR_CONN(connection_new(CONN_TYPE_DIR));
|
||||
dir_conn->_base.s = fd[1];
|
||||
|
||||
dir_conn->_base.addr = 0x7f000001;
|
||||
dir_conn->_base.port = 0;
|
||||
dir_conn->_base.address = tor_strdup("Tor network");
|
||||
dir_conn->_base.type = CONN_TYPE_DIR;
|
||||
dir_conn->_base.purpose = DIR_PURPOSE_SERVER;
|
||||
dir_conn->_base.state = DIR_CONN_STATE_SERVER_COMMAND_WAIT;
|
||||
|
||||
if (connection_add(TO_CONN(exit_conn))<0) {
|
||||
connection_edge_end(exit_conn, END_STREAM_REASON_RESOURCELIMIT,
|
||||
exit_conn->cpath_layer);
|
||||
/* XXXX Have I got the free/mark distinction right? -NM */
|
||||
connection_free(TO_CONN(exit_conn));
|
||||
connection_free(TO_CONN(dir_conn));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (connection_add(TO_CONN(dir_conn))<0) {
|
||||
connection_edge_end(exit_conn, END_STREAM_REASON_RESOURCELIMIT,
|
||||
exit_conn->cpath_layer);
|
||||
connection_close_immediate(TO_CONN(exit_conn));
|
||||
connection_mark_for_close(TO_CONN(exit_conn));
|
||||
connection_free(TO_CONN(dir_conn));
|
||||
return 0;
|
||||
}
|
||||
|
||||
connection_start_reading(TO_CONN(dir_conn));
|
||||
connection_start_reading(TO_CONN(exit_conn));
|
||||
|
||||
if (connection_edge_send_command(exit_conn,
|
||||
circuit_get_by_edge_conn(exit_conn),
|
||||
RELAY_COMMAND_CONNECTED, NULL, 0,
|
||||
exit_conn->cpath_layer) < 0) {
|
||||
connection_mark_for_close(TO_CONN(exit_conn));
|
||||
connection_mark_for_close(TO_CONN(dir_conn));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Return 1 if <b>conn</b> is a rendezvous stream, or 0 if
|
||||
* it is a general stream.
|
||||
*/
|
||||
|
@ -450,6 +450,7 @@ typedef enum {
|
||||
#define RELAY_COMMAND_DROP 10
|
||||
#define RELAY_COMMAND_RESOLVE 11
|
||||
#define RELAY_COMMAND_RESOLVED 12
|
||||
#define RELAY_COMMAND_BEGIN_DIR 13
|
||||
|
||||
#define RELAY_COMMAND_ESTABLISH_INTRO 32
|
||||
#define RELAY_COMMAND_ESTABLISH_RENDEZVOUS 33
|
||||
@ -474,6 +475,7 @@ typedef enum {
|
||||
#define END_STREAM_REASON_RESOURCELIMIT 11
|
||||
#define END_STREAM_REASON_CONNRESET 12
|
||||
#define END_STREAM_REASON_TORPROTOCOL 13
|
||||
#define END_STREAM_REASON_NOTDIRECTORY 14
|
||||
|
||||
/* These high-numbered end reasons are not part of the official spec,
|
||||
* and are not intended to be put in relay end cells. They are here
|
||||
|
@ -944,6 +944,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
|
||||
// log_info(domain,"Got a relay-level padding cell. Dropping.");
|
||||
return 0;
|
||||
case RELAY_COMMAND_BEGIN:
|
||||
case RELAY_COMMAND_BEGIN_DIR:
|
||||
if (layer_hint &&
|
||||
circ->purpose != CIRCUIT_PURPOSE_S_REND_JOINED) {
|
||||
log_warn(LD_APP,"relay begin request unsupported at AP. Dropping.");
|
||||
|
Loading…
Reference in New Issue
Block a user