mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 23:53:32 +01:00
Infrastructure to test BEGIN_DIR cells.
New socks command CONNECT_DIR. New config option TunnelDirConns that builds a circ ending at the directory server and delivers a BEGIN_DIR cell if it's running 0.1.2.2-alpha or later. We still need to make one-hop circs when appropriate, while making other conns avoid them. svn:r9098
This commit is contained in:
parent
f5164ba61d
commit
0dbf725927
@ -974,6 +974,7 @@ fetch_from_buf_socks(buf_t *buf, socks_request_t *req,
|
|||||||
return 0; /* not yet */
|
return 0; /* not yet */
|
||||||
req->command = (unsigned char) *(buf->cur+1);
|
req->command = (unsigned char) *(buf->cur+1);
|
||||||
if (req->command != SOCKS_COMMAND_CONNECT &&
|
if (req->command != SOCKS_COMMAND_CONNECT &&
|
||||||
|
req->command != SOCKS_COMMAND_CONNECT_DIR &&
|
||||||
req->command != SOCKS_COMMAND_RESOLVE &&
|
req->command != SOCKS_COMMAND_RESOLVE &&
|
||||||
req->command != SOCKS_COMMAND_RESOLVE_PTR) {
|
req->command != SOCKS_COMMAND_RESOLVE_PTR) {
|
||||||
/* not a connect or resolve or a resolve_ptr? we don't support it. */
|
/* not a connect or resolve or a resolve_ptr? we don't support it. */
|
||||||
@ -1065,6 +1066,7 @@ fetch_from_buf_socks(buf_t *buf, socks_request_t *req,
|
|||||||
|
|
||||||
req->command = (unsigned char) *(buf->cur+1);
|
req->command = (unsigned char) *(buf->cur+1);
|
||||||
if (req->command != SOCKS_COMMAND_CONNECT &&
|
if (req->command != SOCKS_COMMAND_CONNECT &&
|
||||||
|
req->command != SOCKS_COMMAND_CONNECT_DIR &&
|
||||||
req->command != SOCKS_COMMAND_RESOLVE) {
|
req->command != SOCKS_COMMAND_RESOLVE) {
|
||||||
/* not a connect or resolve? we don't support it. (No resolve_ptr with
|
/* not a connect or resolve? we don't support it. (No resolve_ptr with
|
||||||
* socks4.) */
|
* socks4.) */
|
||||||
|
@ -902,16 +902,18 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
|
|||||||
origin_circuit_t **circp)
|
origin_circuit_t **circp)
|
||||||
{
|
{
|
||||||
origin_circuit_t *circ;
|
origin_circuit_t *circ;
|
||||||
int is_resolve;
|
int check_exit_policy;
|
||||||
int need_uptime, need_internal;
|
int need_uptime, need_internal;
|
||||||
|
|
||||||
tor_assert(conn);
|
tor_assert(conn);
|
||||||
tor_assert(circp);
|
tor_assert(circp);
|
||||||
tor_assert(conn->_base.state == AP_CONN_STATE_CIRCUIT_WAIT);
|
tor_assert(conn->_base.state == AP_CONN_STATE_CIRCUIT_WAIT);
|
||||||
is_resolve = (conn->socks_request->command == SOCKS_COMMAND_RESOLVE ||
|
check_exit_policy =
|
||||||
conn->socks_request->command == SOCKS_COMMAND_RESOLVE_PTR);
|
(conn->socks_request->command == SOCKS_COMMAND_CONNECT) &&
|
||||||
|
!connection_edge_is_rendezvous_stream(conn);
|
||||||
|
|
||||||
need_uptime = smartlist_string_num_isin(get_options()->LongLivedPorts,
|
need_uptime = (conn->socks_request->command == SOCKS_COMMAND_CONNECT) &&
|
||||||
|
smartlist_string_num_isin(get_options()->LongLivedPorts,
|
||||||
conn->socks_request->port);
|
conn->socks_request->port);
|
||||||
need_internal = desired_circuit_purpose != CIRCUIT_PURPOSE_C_GENERAL;
|
need_internal = desired_circuit_purpose != CIRCUIT_PURPOSE_C_GENERAL;
|
||||||
|
|
||||||
@ -941,7 +943,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Do we need to check exit policy? */
|
/* Do we need to check exit policy? */
|
||||||
if (!is_resolve && !connection_edge_is_rendezvous_stream(conn)) {
|
if (check_exit_policy) {
|
||||||
struct in_addr in;
|
struct in_addr in;
|
||||||
uint32_t addr = 0;
|
uint32_t addr = 0;
|
||||||
if (tor_inet_aton(conn->socks_request->address, &in))
|
if (tor_inet_aton(conn->socks_request->address, &in))
|
||||||
@ -1125,11 +1127,15 @@ connection_ap_handshake_attach_chosen_circuit(edge_connection_t *conn,
|
|||||||
|
|
||||||
link_apconn_to_circ(conn, circ);
|
link_apconn_to_circ(conn, circ);
|
||||||
tor_assert(conn->socks_request);
|
tor_assert(conn->socks_request);
|
||||||
if (conn->socks_request->command == SOCKS_COMMAND_CONNECT) {
|
switch (conn->socks_request->command) {
|
||||||
|
case SOCKS_COMMAND_CONNECT:
|
||||||
consider_recording_trackhost(conn, circ);
|
consider_recording_trackhost(conn, circ);
|
||||||
|
/* fall through */
|
||||||
|
case SOCKS_COMMAND_CONNECT_DIR:
|
||||||
if (connection_ap_handshake_send_begin(conn, circ)<0)
|
if (connection_ap_handshake_send_begin(conn, circ)<0)
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
break;
|
||||||
|
default:
|
||||||
if (connection_ap_handshake_send_resolve(conn, circ)<0)
|
if (connection_ap_handshake_send_resolve(conn, circ)<0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -247,6 +247,7 @@ static config_var_t _option_vars[] = {
|
|||||||
OBSOLETE("TrafficShaping"),
|
OBSOLETE("TrafficShaping"),
|
||||||
VAR("TransListenAddress", LINELIST, TransListenAddress, NULL),
|
VAR("TransListenAddress", LINELIST, TransListenAddress, NULL),
|
||||||
VAR("TransPort", UINT, TransPort, "0"),
|
VAR("TransPort", UINT, TransPort, "0"),
|
||||||
|
VAR("TunnelDirConns", BOOL, TunnelDirConns, "0"),
|
||||||
VAR("UseEntryGuards", BOOL, UseEntryGuards, "1"),
|
VAR("UseEntryGuards", BOOL, UseEntryGuards, "1"),
|
||||||
VAR("User", STRING, User, NULL),
|
VAR("User", STRING, User, NULL),
|
||||||
VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "0"),
|
VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "0"),
|
||||||
|
@ -55,7 +55,7 @@ _connection_mark_unattached_ap(edge_connection_t *conn, int endreason,
|
|||||||
"Bug: stream (marked at %s:%d) sending two socks replies?",
|
"Bug: stream (marked at %s:%d) sending two socks replies?",
|
||||||
file, line);
|
file, line);
|
||||||
|
|
||||||
if (conn->socks_request->command == SOCKS_COMMAND_CONNECT)
|
if (SOCKS_COMMAND_IS_CONNECT(conn->socks_request->command))
|
||||||
connection_ap_handshake_socks_reply(conn, NULL, 0, endreason);
|
connection_ap_handshake_socks_reply(conn, NULL, 0, endreason);
|
||||||
else
|
else
|
||||||
connection_ap_handshake_socks_resolved(conn, RESOLVED_TYPE_ERROR,
|
connection_ap_handshake_socks_resolved(conn, RESOLVED_TYPE_ERROR,
|
||||||
@ -1213,6 +1213,8 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
|
|||||||
// XXXX NM Do anything here?
|
// XXXX NM Do anything here?
|
||||||
|
|
||||||
rep_hist_note_used_resolve(time(NULL)); /* help predict this next time */
|
rep_hist_note_used_resolve(time(NULL)); /* help predict this next time */
|
||||||
|
} else if (socks->command == SOCKS_COMMAND_CONNECT_DIR) {
|
||||||
|
; /* nothing */
|
||||||
} else {
|
} else {
|
||||||
tor_fragile_assert();
|
tor_fragile_assert();
|
||||||
}
|
}
|
||||||
@ -1230,7 +1232,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
|
|||||||
rend_cache_entry_t *entry;
|
rend_cache_entry_t *entry;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (socks->command != SOCKS_COMMAND_CONNECT) {
|
if (!SOCKS_COMMAND_IS_CONNECT(socks->command)) {
|
||||||
/* if it's a resolve request, fail it right now, rather than
|
/* if it's a resolve request, fail it right now, rather than
|
||||||
* building all the circuits and then realizing it won't work. */
|
* building all the circuits and then realizing it won't work. */
|
||||||
log_warn(LD_APP,
|
log_warn(LD_APP,
|
||||||
@ -1450,7 +1452,7 @@ connection_ap_handshake_process_socks(edge_connection_t *conn)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (socks->command == SOCKS_COMMAND_CONNECT)
|
if (SOCKS_COMMAND_IS_CONNECT(socks->command))
|
||||||
control_event_stream_status(conn, STREAM_EVENT_NEW, 0);
|
control_event_stream_status(conn, STREAM_EVENT_NEW, 0);
|
||||||
else
|
else
|
||||||
control_event_stream_status(conn, STREAM_EVENT_NEW_RESOLVE, 0);
|
control_event_stream_status(conn, STREAM_EVENT_NEW_RESOLVE, 0);
|
||||||
@ -1546,7 +1548,7 @@ connection_ap_process_natd(edge_connection_t *conn)
|
|||||||
|
|
||||||
if (strcmpstart(tmp_buf, "[DEST ")) {
|
if (strcmpstart(tmp_buf, "[DEST ")) {
|
||||||
log_warn(LD_APP,"Natd handshake was ill-formed; closing. The client "
|
log_warn(LD_APP,"Natd handshake was ill-formed; closing. The client "
|
||||||
"said: '%s'",
|
"said: %s",
|
||||||
escaped(tmp_buf));
|
escaped(tmp_buf));
|
||||||
connection_mark_unattached_ap(conn, END_STREAM_REASON_INVALID_NATD_DEST);
|
connection_mark_unattached_ap(conn, END_STREAM_REASON_INVALID_NATD_DEST);
|
||||||
return -1;
|
return -1;
|
||||||
@ -1564,7 +1566,7 @@ connection_ap_process_natd(edge_connection_t *conn)
|
|||||||
socks->port = (uint16_t)
|
socks->port = (uint16_t)
|
||||||
tor_parse_long(tbuf, 10, 1, 65535, &port_ok, &daddr);
|
tor_parse_long(tbuf, 10, 1, 65535, &port_ok, &daddr);
|
||||||
if (!port_ok) {
|
if (!port_ok) {
|
||||||
log_warn(LD_APP,"Natd handshake failed; port '%s' is ill-formed or out "
|
log_warn(LD_APP,"Natd handshake failed; port %s is ill-formed or out "
|
||||||
"of range.", escaped(tbuf));
|
"of range.", escaped(tbuf));
|
||||||
connection_mark_unattached_ap(conn, END_STREAM_REASON_INVALID_NATD_DEST);
|
connection_mark_unattached_ap(conn, END_STREAM_REASON_INVALID_NATD_DEST);
|
||||||
return -1;
|
return -1;
|
||||||
@ -1620,10 +1622,12 @@ connection_ap_handshake_send_begin(edge_connection_t *ap_conn,
|
|||||||
{
|
{
|
||||||
char payload[CELL_PAYLOAD_SIZE];
|
char payload[CELL_PAYLOAD_SIZE];
|
||||||
int payload_len;
|
int payload_len;
|
||||||
|
int begin_type;
|
||||||
|
|
||||||
tor_assert(ap_conn->_base.type == CONN_TYPE_AP);
|
tor_assert(ap_conn->_base.type == CONN_TYPE_AP);
|
||||||
tor_assert(ap_conn->_base.state == AP_CONN_STATE_CIRCUIT_WAIT);
|
tor_assert(ap_conn->_base.state == AP_CONN_STATE_CIRCUIT_WAIT);
|
||||||
tor_assert(ap_conn->socks_request);
|
tor_assert(ap_conn->socks_request);
|
||||||
|
tor_assert(SOCKS_COMMAND_IS_CONNECT(ap_conn->socks_request->command));
|
||||||
|
|
||||||
ap_conn->stream_id = get_unique_stream_id_by_circ(circ);
|
ap_conn->stream_id = get_unique_stream_id_by_circ(circ);
|
||||||
if (ap_conn->stream_id==0) {
|
if (ap_conn->stream_id==0) {
|
||||||
@ -1641,9 +1645,11 @@ connection_ap_handshake_send_begin(edge_connection_t *ap_conn,
|
|||||||
log_debug(LD_APP,
|
log_debug(LD_APP,
|
||||||
"Sending relay cell to begin stream %d.", ap_conn->stream_id);
|
"Sending relay cell to begin stream %d.", ap_conn->stream_id);
|
||||||
|
|
||||||
|
begin_type = ap_conn->socks_request->command == SOCKS_COMMAND_CONNECT ?
|
||||||
|
RELAY_COMMAND_BEGIN : RELAY_COMMAND_BEGIN_DIR;
|
||||||
|
|
||||||
if (connection_edge_send_command(ap_conn, TO_CIRCUIT(circ),
|
if (connection_edge_send_command(ap_conn, TO_CIRCUIT(circ),
|
||||||
RELAY_COMMAND_BEGIN,
|
begin_type, payload, payload_len,
|
||||||
payload, payload_len,
|
|
||||||
ap_conn->cpath_layer) < 0)
|
ap_conn->cpath_layer) < 0)
|
||||||
return -1; /* circuit is closed, don't continue */
|
return -1; /* circuit is closed, don't continue */
|
||||||
|
|
||||||
@ -1669,15 +1675,14 @@ connection_ap_handshake_send_resolve(edge_connection_t *ap_conn,
|
|||||||
const char *string_addr;
|
const char *string_addr;
|
||||||
char inaddr_buf[32];
|
char inaddr_buf[32];
|
||||||
|
|
||||||
command = ap_conn->socks_request->command;
|
|
||||||
|
|
||||||
tor_assert(ap_conn->_base.type == CONN_TYPE_AP);
|
tor_assert(ap_conn->_base.type == CONN_TYPE_AP);
|
||||||
tor_assert(ap_conn->_base.state == AP_CONN_STATE_CIRCUIT_WAIT);
|
tor_assert(ap_conn->_base.state == AP_CONN_STATE_CIRCUIT_WAIT);
|
||||||
tor_assert(ap_conn->socks_request);
|
tor_assert(ap_conn->socks_request);
|
||||||
tor_assert(command == SOCKS_COMMAND_RESOLVE ||
|
|
||||||
command == SOCKS_COMMAND_RESOLVE_PTR);
|
|
||||||
tor_assert(circ->_base.purpose == CIRCUIT_PURPOSE_C_GENERAL);
|
tor_assert(circ->_base.purpose == CIRCUIT_PURPOSE_C_GENERAL);
|
||||||
|
|
||||||
|
command = ap_conn->socks_request->command;
|
||||||
|
tor_assert(SOCKS_COMMAND_IS_RESOLVE(command));
|
||||||
|
|
||||||
ap_conn->stream_id = get_unique_stream_id_by_circ(circ);
|
ap_conn->stream_id = get_unique_stream_id_by_circ(circ);
|
||||||
if (ap_conn->stream_id==0) {
|
if (ap_conn->stream_id==0) {
|
||||||
connection_mark_unattached_ap(ap_conn, END_STREAM_REASON_INTERNAL);
|
connection_mark_unattached_ap(ap_conn, END_STREAM_REASON_INTERNAL);
|
||||||
@ -1729,7 +1734,8 @@ connection_ap_handshake_send_resolve(edge_connection_t *ap_conn,
|
|||||||
* Return the other end of the socketpair, or -1 if error.
|
* Return the other end of the socketpair, or -1 if error.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
connection_ap_make_bridge(char *address, uint16_t port)
|
connection_ap_make_bridge(char *address, uint16_t port,
|
||||||
|
const char *digest, int command)
|
||||||
{
|
{
|
||||||
int fd[2];
|
int fd[2];
|
||||||
edge_connection_t *conn;
|
edge_connection_t *conn;
|
||||||
@ -1761,7 +1767,13 @@ connection_ap_make_bridge(char *address, uint16_t port)
|
|||||||
strlcpy(conn->socks_request->address, address,
|
strlcpy(conn->socks_request->address, address,
|
||||||
sizeof(conn->socks_request->address));
|
sizeof(conn->socks_request->address));
|
||||||
conn->socks_request->port = port;
|
conn->socks_request->port = port;
|
||||||
conn->socks_request->command = SOCKS_COMMAND_CONNECT;
|
conn->socks_request->command = command;
|
||||||
|
if (command == SOCKS_COMMAND_CONNECT_DIR) {
|
||||||
|
conn->chosen_exit_name = tor_malloc(HEX_DIGEST_LEN+2);
|
||||||
|
conn->chosen_exit_name[0] = '$';
|
||||||
|
base16_encode(conn->chosen_exit_name+1,HEX_DIGEST_LEN+1,
|
||||||
|
digest, DIGEST_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
conn->_base.address = tor_strdup("(local bridge)");
|
conn->_base.address = tor_strdup("(local bridge)");
|
||||||
conn->_base.addr = 0;
|
conn->_base.addr = 0;
|
||||||
@ -2396,8 +2408,7 @@ connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit)
|
|||||||
exit->exit_policy);
|
exit->exit_policy);
|
||||||
if (r == ADDR_POLICY_REJECTED || r == ADDR_POLICY_PROBABLY_REJECTED)
|
if (r == ADDR_POLICY_REJECTED || r == ADDR_POLICY_PROBABLY_REJECTED)
|
||||||
return 0;
|
return 0;
|
||||||
} else { /* Some kind of a resolve. */
|
} else if (SOCKS_COMMAND_IS_RESOLVE(conn->socks_request->command)) {
|
||||||
|
|
||||||
/* Can't support reverse lookups without eventdns. */
|
/* Can't support reverse lookups without eventdns. */
|
||||||
if (conn->socks_request->command == SOCKS_COMMAND_RESOLVE_PTR &&
|
if (conn->socks_request->command == SOCKS_COMMAND_RESOLVE_PTR &&
|
||||||
exit->has_old_dnsworkers)
|
exit->has_old_dnsworkers)
|
||||||
|
@ -1619,8 +1619,7 @@ getinfo_helper_events(control_connection_t *control_conn,
|
|||||||
case AP_CONN_STATE_CONTROLLER_WAIT:
|
case AP_CONN_STATE_CONTROLLER_WAIT:
|
||||||
case AP_CONN_STATE_CIRCUIT_WAIT:
|
case AP_CONN_STATE_CIRCUIT_WAIT:
|
||||||
if (conn->socks_request &&
|
if (conn->socks_request &&
|
||||||
(conn->socks_request->command == SOCKS_COMMAND_RESOLVE ||
|
SOCKS_COMMAND_IS_RESOLVE(conn->socks_request->command))
|
||||||
conn->socks_request->command == SOCKS_COMMAND_RESOLVE_PTR))
|
|
||||||
state = "NEWRESOLVE";
|
state = "NEWRESOLVE";
|
||||||
else
|
else
|
||||||
state = "NEW";
|
state = "NEW";
|
||||||
|
@ -39,7 +39,7 @@ directory_initiate_command(const char *address, uint32_t addr, uint16_t port,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
directory_send_command(dir_connection_t *conn, const char *platform,
|
directory_send_command(dir_connection_t *conn, const char *platform,
|
||||||
int purpose, const char *resource,
|
int purpose, int direct, const char *resource,
|
||||||
const char *payload, size_t payload_len);
|
const char *payload, size_t payload_len);
|
||||||
static int directory_handle_command(dir_connection_t *conn);
|
static int directory_handle_command(dir_connection_t *conn);
|
||||||
static int body_is_plausible(const char *body, size_t body_len, int purpose);
|
static int body_is_plausible(const char *body, size_t body_len, int purpose);
|
||||||
@ -370,12 +370,18 @@ directory_initiate_command(const char *address, uint32_t addr,
|
|||||||
const char *payload, size_t payload_len)
|
const char *payload, size_t payload_len)
|
||||||
{
|
{
|
||||||
dir_connection_t *conn;
|
dir_connection_t *conn;
|
||||||
|
or_options_t *options = get_options();
|
||||||
|
int want_to_tunnel = options->TunnelDirConns && platform &&
|
||||||
|
tor_version_as_new_as(platform, "0.1.2.2-alpha");
|
||||||
|
|
||||||
tor_assert(address);
|
tor_assert(address);
|
||||||
tor_assert(addr);
|
tor_assert(addr);
|
||||||
tor_assert(dir_port);
|
tor_assert(dir_port);
|
||||||
tor_assert(digest);
|
tor_assert(digest);
|
||||||
|
|
||||||
|
log_debug(LD_DIR, "private %d, want_to_tunnel %d.",
|
||||||
|
private_connection, want_to_tunnel);
|
||||||
|
|
||||||
switch (purpose) {
|
switch (purpose) {
|
||||||
case DIR_PURPOSE_FETCH_DIR:
|
case DIR_PURPOSE_FETCH_DIR:
|
||||||
log_debug(LD_DIR,"initiating directory fetch");
|
log_debug(LD_DIR,"initiating directory fetch");
|
||||||
@ -415,14 +421,14 @@ directory_initiate_command(const char *address, uint32_t addr,
|
|||||||
|
|
||||||
/* give it an initial state */
|
/* give it an initial state */
|
||||||
conn->_base.state = DIR_CONN_STATE_CONNECTING;
|
conn->_base.state = DIR_CONN_STATE_CONNECTING;
|
||||||
conn->dirconn_direct = (private_connection == 0);
|
|
||||||
|
|
||||||
if (!private_connection) {
|
if (!private_connection && !want_to_tunnel) {
|
||||||
/* then we want to connect directly */
|
/* then we want to connect directly */
|
||||||
|
|
||||||
if (get_options()->HttpProxy) {
|
conn->dirconn_direct = 1;
|
||||||
addr = get_options()->HttpProxyAddr;
|
if (options->HttpProxy) {
|
||||||
dir_port = get_options()->HttpProxyPort;
|
addr = options->HttpProxyAddr;
|
||||||
|
dir_port = options->HttpProxyPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (connection_connect(TO_CONN(conn), conn->_base.address, addr,
|
switch (connection_connect(TO_CONN(conn), conn->_base.address, addr,
|
||||||
@ -437,7 +443,7 @@ directory_initiate_command(const char *address, uint32_t addr,
|
|||||||
/* fall through */
|
/* fall through */
|
||||||
case 0:
|
case 0:
|
||||||
/* queue the command on the outbuf */
|
/* queue the command on the outbuf */
|
||||||
directory_send_command(conn, platform, purpose, resource,
|
directory_send_command(conn, platform, purpose, 1, resource,
|
||||||
payload, payload_len);
|
payload, payload_len);
|
||||||
connection_watch_events(TO_CONN(conn), EV_READ | EV_WRITE);
|
connection_watch_events(TO_CONN(conn), EV_READ | EV_WRITE);
|
||||||
/* writable indicates finish, readable indicates broken link,
|
/* writable indicates finish, readable indicates broken link,
|
||||||
@ -448,8 +454,13 @@ directory_initiate_command(const char *address, uint32_t addr,
|
|||||||
* populate it and add it at the right state
|
* populate it and add it at the right state
|
||||||
* socketpair and hook up both sides
|
* socketpair and hook up both sides
|
||||||
*/
|
*/
|
||||||
conn->_base.s = connection_ap_make_bridge(conn->_base.address,
|
conn->dirconn_direct = 0;
|
||||||
conn->_base.port);
|
conn->_base.s =
|
||||||
|
connection_ap_make_bridge(conn->_base.address, conn->_base.port,
|
||||||
|
digest,
|
||||||
|
private_connection ?
|
||||||
|
SOCKS_COMMAND_CONNECT :
|
||||||
|
SOCKS_COMMAND_CONNECT_DIR);
|
||||||
if (conn->_base.s < 0) {
|
if (conn->_base.s < 0) {
|
||||||
log_warn(LD_NET,"Making AP bridge to dirserver failed.");
|
log_warn(LD_NET,"Making AP bridge to dirserver failed.");
|
||||||
connection_mark_for_close(TO_CONN(conn));
|
connection_mark_for_close(TO_CONN(conn));
|
||||||
@ -463,7 +474,7 @@ directory_initiate_command(const char *address, uint32_t addr,
|
|||||||
}
|
}
|
||||||
conn->_base.state = DIR_CONN_STATE_CLIENT_SENDING;
|
conn->_base.state = DIR_CONN_STATE_CLIENT_SENDING;
|
||||||
/* queue the command on the outbuf */
|
/* queue the command on the outbuf */
|
||||||
directory_send_command(conn, platform, purpose, resource,
|
directory_send_command(conn, platform, purpose, 0, resource,
|
||||||
payload, payload_len);
|
payload, payload_len);
|
||||||
connection_watch_events(TO_CONN(conn), EV_READ | EV_WRITE);
|
connection_watch_events(TO_CONN(conn), EV_READ | EV_WRITE);
|
||||||
}
|
}
|
||||||
@ -474,7 +485,7 @@ directory_initiate_command(const char *address, uint32_t addr,
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
directory_send_command(dir_connection_t *conn, const char *platform,
|
directory_send_command(dir_connection_t *conn, const char *platform,
|
||||||
int purpose, const char *resource,
|
int purpose, int direct, const char *resource,
|
||||||
const char *payload, size_t payload_len)
|
const char *payload, size_t payload_len)
|
||||||
{
|
{
|
||||||
char proxystring[256];
|
char proxystring[256];
|
||||||
@ -501,7 +512,7 @@ directory_send_command(dir_connection_t *conn, const char *platform,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* come up with some proxy lines, if we're using one. */
|
/* come up with some proxy lines, if we're using one. */
|
||||||
if (get_options()->HttpProxy) {
|
if (direct && get_options()->HttpProxy) {
|
||||||
char *base64_authenticator=NULL;
|
char *base64_authenticator=NULL;
|
||||||
const char *authenticator = get_options()->HttpProxyAuthenticator;
|
const char *authenticator = get_options()->HttpProxyAuthenticator;
|
||||||
|
|
||||||
|
13
src/or/or.h
13
src/or/or.h
@ -1648,8 +1648,10 @@ typedef struct {
|
|||||||
char *ServerDNSResolvConfFile; /**< If provided, we configure our internal
|
char *ServerDNSResolvConfFile; /**< If provided, we configure our internal
|
||||||
* resolver from the file here rather than from
|
* resolver from the file here rather than from
|
||||||
* /etc/resolv.conf (Unix) or the registry (Windows). */
|
* /etc/resolv.conf (Unix) or the registry (Windows). */
|
||||||
int EnforceDistinctSubnets; /** If true, don't allow multiple routers in the
|
int EnforceDistinctSubnets; /**< If true, don't allow multiple routers in the
|
||||||
* same network zone in the same circuit. */
|
* same network zone in the same circuit. */
|
||||||
|
int TunnelDirConns; /**< If true, use BEGIN_DIR rather than BEGIN when
|
||||||
|
* possible. */
|
||||||
} or_options_t;
|
} or_options_t;
|
||||||
|
|
||||||
/** Persistent state for an onion router, as saved to disk. */
|
/** Persistent state for an onion router, as saved to disk. */
|
||||||
@ -1705,17 +1707,21 @@ static INLINE void or_state_mark_dirty(or_state_t *state, time_t when)
|
|||||||
|
|
||||||
#define MAX_SOCKS_REPLY_LEN 1024
|
#define MAX_SOCKS_REPLY_LEN 1024
|
||||||
#define MAX_SOCKS_ADDR_LEN 256
|
#define MAX_SOCKS_ADDR_LEN 256
|
||||||
|
|
||||||
#define SOCKS_COMMAND_CONNECT 0x01
|
#define SOCKS_COMMAND_CONNECT 0x01
|
||||||
|
#define SOCKS_COMMAND_CONNECT_DIR 0xE0
|
||||||
#define SOCKS_COMMAND_RESOLVE 0xF0
|
#define SOCKS_COMMAND_RESOLVE 0xF0
|
||||||
#define SOCKS_COMMAND_RESOLVE_PTR 0xF1
|
#define SOCKS_COMMAND_RESOLVE_PTR 0xF1
|
||||||
|
|
||||||
|
#define SOCKS_COMMAND_IS_CONNECT(c) ((c)==SOCKS_COMMAND_CONNECT || \
|
||||||
|
(c)==SOCKS_COMMAND_CONNECT_DIR)
|
||||||
#define SOCKS_COMMAND_IS_RESOLVE(c) ((c)==SOCKS_COMMAND_RESOLVE || \
|
#define SOCKS_COMMAND_IS_RESOLVE(c) ((c)==SOCKS_COMMAND_RESOLVE || \
|
||||||
(c)==SOCKS_COMMAND_RESOLVE_PTR)
|
(c)==SOCKS_COMMAND_RESOLVE_PTR)
|
||||||
|
|
||||||
/** State of a SOCKS request from a user to an OP */
|
/** State of a SOCKS request from a user to an OP */
|
||||||
struct socks_request_t {
|
struct socks_request_t {
|
||||||
char socks_version; /**< Which version of SOCKS did the client use? */
|
char socks_version; /**< Which version of SOCKS did the client use? */
|
||||||
int command; /**< What has the user requested? One of CONNECT or RESOLVE. */
|
int command; /**< What has the user requested? One from the above list. */
|
||||||
size_t replylen; /**< Length of <b>reply</b>. */
|
size_t replylen; /**< Length of <b>reply</b>. */
|
||||||
char reply[MAX_SOCKS_REPLY_LEN]; /**< Write an entry into this string if
|
char reply[MAX_SOCKS_REPLY_LEN]; /**< Write an entry into this string if
|
||||||
* we want to specify our own socks reply,
|
* we want to specify our own socks reply,
|
||||||
@ -2017,7 +2023,8 @@ int connection_ap_handshake_send_begin(edge_connection_t *ap_conn,
|
|||||||
int connection_ap_handshake_send_resolve(edge_connection_t *ap_conn,
|
int connection_ap_handshake_send_resolve(edge_connection_t *ap_conn,
|
||||||
origin_circuit_t *circ);
|
origin_circuit_t *circ);
|
||||||
|
|
||||||
int connection_ap_make_bridge(char *address, uint16_t port);
|
int connection_ap_make_bridge(char *address, uint16_t port,
|
||||||
|
const char *digest, int command);
|
||||||
void connection_ap_handshake_socks_reply(edge_connection_t *conn, char *reply,
|
void connection_ap_handshake_socks_reply(edge_connection_t *conn, char *reply,
|
||||||
size_t replylen,
|
size_t replylen,
|
||||||
int endreason);
|
int endreason);
|
||||||
|
@ -900,8 +900,7 @@ connection_edge_process_relay_cell_not_open(
|
|||||||
"not in state resolve_wait. Dropping.");
|
"not in state resolve_wait. Dropping.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
tor_assert(conn->socks_request->command == SOCKS_COMMAND_RESOLVE ||
|
tor_assert(SOCKS_COMMAND_IS_RESOLVE(conn->socks_request->command));
|
||||||
conn->socks_request->command == SOCKS_COMMAND_RESOLVE_PTR);
|
|
||||||
answer_len = cell->payload[RELAY_HEADER_SIZE+1];
|
answer_len = cell->payload[RELAY_HEADER_SIZE+1];
|
||||||
if (rh->length < 2 || answer_len+2>rh->length) {
|
if (rh->length < 2 || answer_len+2>rh->length) {
|
||||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||||
|
@ -1015,7 +1015,8 @@ router_new_address_suggestion(const char *suggestion)
|
|||||||
|
|
||||||
/* first, learn what the IP address actually is */
|
/* first, learn what the IP address actually is */
|
||||||
if (!tor_inet_aton(suggestion, &in)) {
|
if (!tor_inet_aton(suggestion, &in)) {
|
||||||
log_debug(LD_DIR, "Malformed X-Your-Address-Is header. Ignoring.");
|
log_debug(LD_DIR, "Malformed X-Your-Address-Is header %s. Ignoring.",
|
||||||
|
escaped(suggestion));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addr = ntohl(in.s_addr);
|
addr = ntohl(in.s_addr);
|
||||||
|
@ -1821,6 +1821,8 @@ tor_version_as_new_as(const char *platform, const char *cutoff)
|
|||||||
char *s, *start;
|
char *s, *start;
|
||||||
char tmp[128];
|
char tmp[128];
|
||||||
|
|
||||||
|
tor_assert(platform);
|
||||||
|
|
||||||
if (tor_version_parse(cutoff, &cutoff_version)<0) {
|
if (tor_version_parse(cutoff, &cutoff_version)<0) {
|
||||||
log_warn(LD_DIR,"Bug: cutoff version '%s' unparseable.",cutoff);
|
log_warn(LD_DIR,"Bug: cutoff version '%s' unparseable.",cutoff);
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user