summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2006-07-26 19:07:26 +0000
committerNick Mathewson <nickm@torproject.org>2006-07-26 19:07:26 +0000
commit4ff4577beb7b7aa286059a5070b23357fff48bf3 (patch)
tree87c11a323c91def209efc2d0eb79b768f8f2e804
parent18771e851fab7ec12051636eda1dad7e13b11095 (diff)
downloadtor-4ff4577beb7b7aa286059a5070b23357fff48bf3.tar.gz
tor-4ff4577beb7b7aa286059a5070b23357fff48bf3.zip
r6908@Kushana: nickm | 2006-07-26 12:38:52 -0400
Refactor connection_t into edge, or, dir, control, and base subtypes. This might save some RAM on busy exit servers, but really matters most in terms of correctness. svn:r6906
-rw-r--r--src/or/circuitbuild.c45
-rw-r--r--src/or/circuitlist.c68
-rw-r--r--src/or/circuituse.c57
-rw-r--r--src/or/command.c28
-rw-r--r--src/or/connection.c408
-rw-r--r--src/or/connection_edge.c307
-rw-r--r--src/or/connection_or.c196
-rw-r--r--src/or/control.c322
-rw-r--r--src/or/cpuworker.c5
-rw-r--r--src/or/directory.c253
-rw-r--r--src/or/dirserv.c25
-rw-r--r--src/or/dns.c140
-rw-r--r--src/or/hibernate.c7
-rw-r--r--src/or/main.c52
-rw-r--r--src/or/or.h280
-rw-r--r--src/or/relay.c135
-rw-r--r--src/or/rendclient.c23
-rw-r--r--src/or/rendservice.c10
-rw-r--r--src/or/router.c6
-rw-r--r--src/or/routerlist.c9
20 files changed, 1275 insertions, 1101 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index e58e253f48..7a256371ba 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -60,14 +60,13 @@ static void entry_guards_changed(void);
* Return it, or 0 if can't get a unique circ_id.
*/
static uint16_t
-get_unique_circ_id_by_conn(connection_t *conn)
+get_unique_circ_id_by_conn(or_connection_t *conn)
{
uint16_t test_circ_id;
uint16_t attempts=0;
uint16_t high_bit;
tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_OR);
high_bit = (conn->circ_id_type == CIRC_ID_TYPE_HIGHER) ? 1<<15 : 0;
do {
/* Sequentially iterate over test_circ_id=1...1<<15-1 until we find a
@@ -277,7 +276,7 @@ int
circuit_handle_first_hop(origin_circuit_t *circ)
{
crypt_path_t *firsthop;
- connection_t *n_conn;
+ or_connection_t *n_conn;
char tmpbuf[INET_NTOA_BUF_LEN];
struct in_addr in;
@@ -298,15 +297,15 @@ circuit_handle_first_hop(origin_circuit_t *circ)
/* If we don't have an open conn, or the conn we have is obsolete
* (i.e. old or broken) and the other side will let us make a second
* connection without dropping it immediately... */
- if (!n_conn || n_conn->state != OR_CONN_STATE_OPEN ||
- (n_conn->is_obsolete &&
+ if (!n_conn || n_conn->_base.state != OR_CONN_STATE_OPEN ||
+ (n_conn->_base.or_is_obsolete &&
router_digest_version_as_new_as(firsthop->extend_info->identity_digest,
"0.1.1.9-alpha-cvs"))) {
/* not currently connected */
circ->_base.n_addr = firsthop->extend_info->addr;
circ->_base.n_port = firsthop->extend_info->port;
- if (!n_conn || n_conn->is_obsolete) { /* launch the connection */
+ if (!n_conn || n_conn->_base.or_is_obsolete) { /* launch the connection */
n_conn = connection_or_connect(firsthop->extend_info->addr,
firsthop->extend_info->port,
firsthop->extend_info->identity_digest);
@@ -323,8 +322,8 @@ circuit_handle_first_hop(origin_circuit_t *circ)
*/
return 0;
} else { /* it's already open. use it. */
- circ->_base.n_addr = n_conn->addr;
- circ->_base.n_port = n_conn->port;
+ circ->_base.n_addr = n_conn->_base.addr;
+ circ->_base.n_port = n_conn->_base.port;
circ->_base.n_conn = n_conn;
log_debug(LD_CIRC,"Conn open. Delivering first onion skin.");
if (circuit_send_next_onion_skin(circ) < 0) {
@@ -341,7 +340,7 @@ circuit_handle_first_hop(origin_circuit_t *circ)
* Status is 1 if connect succeeded, or 0 if connect failed.
*/
void
-circuit_n_conn_done(connection_t *or_conn, int status)
+circuit_n_conn_done(or_connection_t *or_conn, int status)
{
extern smartlist_t *circuits_pending_or_conns;
smartlist_t *changed_circs;
@@ -419,7 +418,6 @@ circuit_deliver_create_cell(circuit_t *circ, uint8_t cell_type,
tor_assert(circ);
tor_assert(circ->n_conn);
- tor_assert(circ->n_conn->type == CONN_TYPE_OR);
tor_assert(payload);
tor_assert(cell_type == CELL_CREATE || cell_type == CELL_CREATE_FAST);
@@ -621,7 +619,7 @@ circuit_note_clock_jumped(int seconds_elapsed)
int
circuit_extend(cell_t *cell, circuit_t *circ)
{
- connection_t *n_conn;
+ or_connection_t *n_conn;
relay_header_t rh;
char *onionskin;
char *id_digest=NULL;
@@ -651,8 +649,8 @@ circuit_extend(cell_t *cell, circuit_t *circ)
/* If we don't have an open conn, or the conn we have is obsolete
* (i.e. old or broken) and the other side will let us make a second
* connection without dropping it immediately... */
- if (!n_conn || n_conn->state != OR_CONN_STATE_OPEN ||
- (n_conn->is_obsolete &&
+ if (!n_conn || n_conn->_base.state != OR_CONN_STATE_OPEN ||
+ (n_conn->_base.or_is_obsolete &&
router_digest_version_as_new_as(id_digest,"0.1.1.9-alpha-cvs"))) {
struct in_addr in;
char tmpbuf[INET_NTOA_BUF_LEN];
@@ -668,9 +666,9 @@ circuit_extend(cell_t *cell, circuit_t *circ)
/* imprint the circuit with its future n_conn->id */
memcpy(circ->n_conn_id_digest, id_digest, DIGEST_LEN);
- if (n_conn && !n_conn->is_obsolete) {
- circ->n_addr = n_conn->addr;
- circ->n_port = n_conn->port;
+ if (n_conn && !n_conn->_base.or_is_obsolete) {
+ circ->n_addr = n_conn->_base.addr;
+ circ->n_port = n_conn->_base.port;
} else {
/* we should try to open a connection */
n_conn = connection_or_connect(circ->n_addr, circ->n_port, id_digest);
@@ -689,12 +687,12 @@ circuit_extend(cell_t *cell, circuit_t *circ)
}
/* these may be different if the router connected to us from elsewhere */
- circ->n_addr = n_conn->addr;
- circ->n_port = n_conn->port;
+ circ->n_addr = n_conn->_base.addr;
+ circ->n_port = n_conn->_base.port;
circ->n_conn = n_conn;
memcpy(circ->n_conn_id_digest, n_conn->identity_digest, DIGEST_LEN);
- log_debug(LD_CIRC,"n_conn is %s:%u",n_conn->address,n_conn->port);
+ log_debug(LD_CIRC,"n_conn is %s:%u",n_conn->_base.address,n_conn->_base.port);
if (circuit_deliver_create_cell(circ, CELL_CREATE, onionskin) < 0)
return -1;
@@ -910,7 +908,7 @@ onionskin_answer(or_circuit_t *circ, uint8_t cell_type, char *payload,
connection_or_write_cell_to_buf(&cell, circ->p_conn);
log_debug(LD_CIRC,"Finished sending 'created' cell.");
- if (!is_local_IP(circ->p_conn->addr) &&
+ if (!is_local_IP(circ->p_conn->_base.addr) &&
!connection_or_nonopen_was_started_here(circ->p_conn)) {
/* record that we could process create cells from a non-local conn
* that we didn't initiate; presumably this means that create cells
@@ -1048,8 +1046,9 @@ ap_stream_wants_exit_attention(connection_t *conn)
if (conn->type == CONN_TYPE_AP &&
conn->state == AP_CONN_STATE_CIRCUIT_WAIT &&
!conn->marked_for_close &&
- !connection_edge_is_rendezvous_stream(conn) &&
- !circuit_stream_is_being_handled(conn, 0, MIN_CIRCUITS_HANDLING_STREAM))
+ !connection_edge_is_rendezvous_stream(TO_EDGE_CONN(conn)) &&
+ !circuit_stream_is_being_handled(TO_EDGE_CONN(conn), 0,
+ MIN_CIRCUITS_HANDLING_STREAM))
return 1;
return 0;
}
@@ -1134,7 +1133,7 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
for (j = 0; j < n_connections; ++j) { /* iterate over connections */
if (!ap_stream_wants_exit_attention(carray[j]))
continue; /* Skip everything but APs in CIRCUIT_WAIT */
- if (connection_ap_can_use_exit(carray[j], router)) {
+ if (connection_ap_can_use_exit(TO_EDGE_CONN(carray[j]), router)) {
++n_supported[i];
// log_fn(LOG_DEBUG,"%s is supported. n_supported[%d] now %d.",
// router->nickname, i, n_supported[i]);
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index db8b7577f2..90929d0051 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -33,7 +33,7 @@ static void circuit_free_cpath_node(crypt_path_t *victim);
* very important here, since we need to do it every time a cell arrives.) */
typedef struct orconn_circid_circuit_map_t {
HT_ENTRY(orconn_circid_circuit_map_t) node;
- connection_t *or_conn;
+ or_connection_t *or_conn;
uint16_t circ_id;
circuit_t *circuit;
} orconn_circid_circuit_map_t;
@@ -70,8 +70,8 @@ orconn_circid_circuit_map_t *_last_circid_orconn_ent = NULL;
static void
circuit_set_circid_orconn_helper(circuit_t *circ, uint16_t id,
- connection_t *conn,
- uint16_t old_id, connection_t *old_conn)
+ or_connection_t *conn,
+ uint16_t old_id, or_connection_t *old_conn)
{
orconn_circid_circuit_map_t search;
orconn_circid_circuit_map_t *found;
@@ -85,7 +85,7 @@ circuit_set_circid_orconn_helper(circuit_t *circ, uint16_t id,
}
if (old_conn) { /* we may need to remove it from the conn-circid map */
- tor_assert(old_conn->magic == CONNECTION_MAGIC);
+ tor_assert(old_conn->_base.magic == OR_CONNECTION_MAGIC);
search.circ_id = old_id;
search.or_conn = old_conn;
found = HT_REMOVE(orconn_circid_map, &orconn_circid_circuit_map, &search);
@@ -119,10 +119,10 @@ circuit_set_circid_orconn_helper(circuit_t *circ, uint16_t id,
* to the (orconn,id)-\>circuit map. */
void
circuit_set_p_circid_orconn(or_circuit_t *circ, uint16_t id,
- connection_t *conn)
+ or_connection_t *conn)
{
uint16_t old_id;
- connection_t *old_conn;
+ or_connection_t *old_conn;
old_id = circ->p_circ_id;
old_conn = circ->p_conn;
@@ -140,10 +140,10 @@ circuit_set_p_circid_orconn(or_circuit_t *circ, uint16_t id,
* to the (orconn,id)-\>circuit map. */
void
circuit_set_n_circid_orconn(circuit_t *circ, uint16_t id,
- connection_t *conn)
+ or_connection_t *conn)
{
uint16_t old_id;
- connection_t *old_conn;
+ or_connection_t *old_conn;
old_id = circ->n_circ_id;
old_conn = circ->n_conn;
@@ -279,7 +279,7 @@ origin_circuit_new(void)
}
or_circuit_t *
-or_circuit_new(uint16_t p_circ_id, connection_t *p_conn)
+or_circuit_new(uint16_t p_circ_id, or_connection_t *p_conn)
{
/* CircIDs */
or_circuit_t *circ;
@@ -379,9 +379,9 @@ circuit_free_all(void)
if (! CIRCUIT_IS_ORIGIN(global_circuitlist)) {
or_circuit_t *or_circ = TO_OR_CIRCUIT(global_circuitlist);
while (or_circ->resolving_streams) {
- connection_t *next;
+ edge_connection_t *next;
next = or_circ->resolving_streams->next_stream;
- connection_free(or_circ->resolving_streams);
+ connection_free(TO_CONN(or_circ->resolving_streams));
or_circ->resolving_streams = next;
}
}
@@ -439,7 +439,7 @@ void
circuit_dump_by_conn(connection_t *conn, int severity)
{
circuit_t *circ;
- connection_t *tmpconn;
+ edge_connection_t *tmpconn;
for (circ=global_circuitlist;circ;circ = circ->next) {
circid_t n_circ_id = circ->n_circ_id, p_circ_id = 0;
@@ -449,25 +449,26 @@ circuit_dump_by_conn(connection_t *conn, int severity)
if (! CIRCUIT_IS_ORIGIN(circ))
p_circ_id = TO_OR_CIRCUIT(circ)->p_circ_id;
- if (! CIRCUIT_IS_ORIGIN(circ) && TO_OR_CIRCUIT(circ)->p_conn == conn)
+ if (! CIRCUIT_IS_ORIGIN(circ) && TO_OR_CIRCUIT(circ)->p_conn &&
+ TO_CONN(TO_OR_CIRCUIT(circ)->p_conn) == conn)
circuit_dump_details(severity, circ, conn->poll_index, "App-ward",
p_circ_id, n_circ_id);
if (CIRCUIT_IS_ORIGIN(circ)) {
for (tmpconn=TO_ORIGIN_CIRCUIT(circ)->p_streams; tmpconn;
tmpconn=tmpconn->next_stream) {
- if (tmpconn == conn) {
+ if (TO_CONN(tmpconn) == conn) {
circuit_dump_details(severity, circ, conn->poll_index, "App-ward",
p_circ_id, n_circ_id);
}
}
}
- if (circ->n_conn == conn)
+ if (circ->n_conn && TO_CONN(circ->n_conn) == conn)
circuit_dump_details(severity, circ, conn->poll_index, "Exit-ward",
n_circ_id, p_circ_id);
if (! CIRCUIT_IS_ORIGIN(circ)) {
for (tmpconn=TO_OR_CIRCUIT(circ)->n_streams; tmpconn;
tmpconn=tmpconn->next_stream) {
- if (tmpconn == conn) {
+ if (TO_CONN(tmpconn) == conn) {
circuit_dump_details(severity, circ, conn->poll_index, "Exit-ward",
n_circ_id, p_circ_id);
}
@@ -476,7 +477,9 @@ circuit_dump_by_conn(connection_t *conn, int severity)
if (!circ->n_conn && circ->n_addr && circ->n_port &&
circ->n_addr == conn->addr &&
circ->n_port == conn->port &&
- !memcmp(conn->identity_digest, circ->n_conn_id_digest, DIGEST_LEN)) {
+ conn->type == CONN_TYPE_OR &&
+ !memcmp(TO_OR_CONN(conn)->identity_digest, circ->n_conn_id_digest,
+ DIGEST_LEN)) {
circuit_dump_details(severity, circ, conn->poll_index,
(circ->state == CIRCUIT_STATE_OPEN &&
!CIRCUIT_IS_ORIGIN(circ)) ?
@@ -509,13 +512,11 @@ circuit_get_by_global_id(uint32_t id)
* Return NULL if no such circuit exists.
*/
static INLINE circuit_t *
-circuit_get_by_circid_orconn_impl(uint16_t circ_id, connection_t *conn)
+circuit_get_by_circid_orconn_impl(uint16_t circ_id, or_connection_t *conn)
{
orconn_circid_circuit_map_t search;
orconn_circid_circuit_map_t *found;
- tor_assert(conn->type == CONN_TYPE_OR);
-
if (_last_circid_orconn_ent &&
circ_id == _last_circid_orconn_ent->circ_id &&
conn == _last_circid_orconn_ent->or_conn) {
@@ -560,7 +561,7 @@ circuit_get_by_circid_orconn_impl(uint16_t circ_id, connection_t *conn)
* Return NULL if no such circuit exists.
*/
circuit_t *
-circuit_get_by_circid_orconn(uint16_t circ_id, connection_t *conn)
+circuit_get_by_circid_orconn(uint16_t circ_id, or_connection_t *conn)
{
circuit_t *circ = circuit_get_by_circid_orconn_impl(circ_id, conn);
if (!circ || circ->marked_for_close)
@@ -575,7 +576,7 @@ circuit_get_by_circid_orconn(uint16_t circ_id, connection_t *conn)
* Return NULL if no such circuit exists.
*/
int
-circuit_id_used_on_conn(uint16_t circ_id, connection_t *conn)
+circuit_id_used_on_conn(uint16_t circ_id, or_connection_t *conn)
{
circuit_t *circ = circuit_get_by_circid_orconn_impl(circ_id, conn);
if (circ && circ->marked_for_close)
@@ -587,10 +588,9 @@ circuit_id_used_on_conn(uint16_t circ_id, connection_t *conn)
/** Return the circuit that a given edge connection is using. */
circuit_t *
-circuit_get_by_edge_conn(connection_t *conn)
+circuit_get_by_edge_conn(edge_connection_t *conn)
{
circuit_t *circ;
- tor_assert(CONN_IS_EDGE(conn));
circ = conn->on_circuit;
tor_assert(!circ ||
@@ -605,7 +605,7 @@ circuit_get_by_edge_conn(connection_t *conn)
* been marked already.
*/
void
-circuit_unlink_all_from_or_conn(connection_t *conn, int reason)
+circuit_unlink_all_from_or_conn(or_connection_t *conn, int reason)
{
circuit_t *circ;
for (circ = global_circuitlist; circ; circ = circ->next) {
@@ -820,8 +820,6 @@ void
_circuit_mark_for_close(circuit_t *circ, int reason, int line,
const char *file)
{
- connection_t *conn;
-
assert_circuit_ok(circ);
tor_assert(line);
tor_assert(file);
@@ -889,18 +887,19 @@ _circuit_mark_for_close(circuit_t *circ, int reason, int line,
if (! CIRCUIT_IS_ORIGIN(circ)) {
or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
+ edge_connection_t *conn;
for (conn=or_circ->n_streams; conn; conn=conn->next_stream)
connection_edge_destroy(or_circ->p_circ_id, conn);
while (or_circ->resolving_streams) {
conn = or_circ->resolving_streams;
or_circ->resolving_streams = conn->next_stream;
- if (!conn->marked_for_close) {
+ if (!conn->_base.marked_for_close) {
/* The other side will see a DESTROY, and infer that the connections
* are closing because the circuit is getting torn down. No need
* to send an end cell. */
- conn->has_sent_end = 1;
- connection_mark_for_close(conn);
+ conn->_base.edge_has_sent_end = 1;
+ connection_mark_for_close(TO_CONN(conn));
}
conn->on_circuit = NULL;
}
@@ -909,6 +908,7 @@ _circuit_mark_for_close(circuit_t *circ, int reason, int line,
connection_or_send_destroy(or_circ->p_circ_id, or_circ->p_conn, reason);
} else {
origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
+ edge_connection_t *conn;
for (conn=ocirc->p_streams; conn; conn=conn->next_stream)
connection_edge_destroy(circ->n_circ_id, conn);
}
@@ -987,7 +987,7 @@ assert_cpath_ok(const crypt_path_t *cp)
void
assert_circuit_ok(const circuit_t *c)
{
- connection_t *conn;
+ edge_connection_t *conn;
const or_circuit_t *or_circ = NULL;
const origin_circuit_t *origin_circ = NULL;
@@ -1002,24 +1002,22 @@ assert_circuit_ok(const circuit_t *c)
or_circ = TO_OR_CIRCUIT((circuit_t*)c);
if (c->n_conn) {
- tor_assert(c->n_conn->type == CONN_TYPE_OR);
tor_assert(!memcmp(c->n_conn->identity_digest, c->n_conn_id_digest,
DIGEST_LEN));
if (c->n_circ_id)
tor_assert(c == circuit_get_by_circid_orconn(c->n_circ_id, c->n_conn));
}
if (or_circ && or_circ->p_conn) {
- tor_assert(or_circ->p_conn->type == CONN_TYPE_OR);
if (or_circ->p_circ_id)
tor_assert(c == circuit_get_by_circid_orconn(or_circ->p_circ_id,
or_circ->p_conn));
}
if (origin_circ)
for (conn = origin_circ->p_streams; conn; conn = conn->next_stream)
- tor_assert(conn->type == CONN_TYPE_AP);
+ tor_assert(conn->_base.type == CONN_TYPE_AP);
if (or_circ)
for (conn = or_circ->n_streams; conn; conn = conn->next_stream)
- tor_assert(conn->type == CONN_TYPE_EXIT);
+ tor_assert(conn->_base.type == CONN_TYPE_EXIT);
tor_assert(c->deliver_window >= 0);
tor_assert(c->package_window >= 0);
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index bad840a032..aac359809d 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -26,7 +26,7 @@ static void circuit_increment_failure_count(void);
* Else return 0.
*/
static int
-circuit_is_acceptable(circuit_t *circ, connection_t *conn,
+circuit_is_acceptable(circuit_t *circ, edge_connection_t *conn,
int must_be_open, uint8_t purpose,
int need_uptime, int need_internal,
time_t now)
@@ -155,7 +155,7 @@ circuit_is_better(circuit_t *a, circuit_t *b, uint8_t purpose)
* closest introduce-purposed circuit that you can find.
*/
static origin_circuit_t *
-circuit_get_best(connection_t *conn, int must_be_open, uint8_t purpose,
+circuit_get_best(edge_connection_t *conn, int must_be_open, uint8_t purpose,
int need_uptime, int need_internal)
{
circuit_t *circ, *best=NULL;
@@ -255,7 +255,7 @@ circuit_expire_building(time_t now)
if (victim->n_conn)
log_info(LD_CIRC,"Abandoning circ %s:%d:%d (state %d:%s, purpose %d)",
- victim->n_conn->address, victim->n_port, victim->n_circ_id,
+ victim->n_conn->_base.address, victim->n_port, victim->n_circ_id,
victim->state, circuit_state_to_string(victim->state),
victim->purpose);
else
@@ -296,7 +296,7 @@ circuit_remove_handled_ports(smartlist_t *needed_ports)
* Else return 0.
*/
int
-circuit_stream_is_being_handled(connection_t *conn, uint16_t port, int min)
+circuit_stream_is_being_handled(edge_connection_t *conn, uint16_t port, int min)
{
circuit_t *circ;
routerinfo_t *exitrouter;
@@ -457,9 +457,9 @@ circuit_build_needed_circs(time_t now)
* lists of <b>circ</b>, then remove it from the list.
*/
void
-circuit_detach_stream(circuit_t *circ, connection_t *conn)
+circuit_detach_stream(circuit_t *circ, edge_connection_t *conn)
{
- connection_t *prevconn;
+ edge_connection_t *prevconn;
tor_assert(circ);
tor_assert(conn);
@@ -536,10 +536,11 @@ circuit_about_to_close_connection(connection_t *conn)
if (!connection_state_is_open(conn)) {
/* Inform any pending (not attached) circs that they should
* give up. */
- circuit_n_conn_done(conn, 0);
+ circuit_n_conn_done(TO_OR_CONN(conn), 0);
}
/* Now close all the attached circuits on it. */
- circuit_unlink_all_from_or_conn(conn, END_CIRC_REASON_OR_CONN_CLOSED);
+ circuit_unlink_all_from_or_conn(TO_OR_CONN(conn),
+ END_CIRC_REASON_OR_CONN_CLOSED);
return;
}
case CONN_TYPE_AP:
@@ -550,11 +551,11 @@ circuit_about_to_close_connection(connection_t *conn)
* been sent. But don't kill the circuit.
*/
- circ = circuit_get_by_edge_conn(conn);
+ circ = circuit_get_by_edge_conn(TO_EDGE_CONN(conn));
if (!circ)
return;
- circuit_detach_stream(circ, conn);
+ circuit_detach_stream(circ, TO_EDGE_CONN(conn));
}
} /* end switch */
}
@@ -683,7 +684,7 @@ circuit_build_failed(origin_circuit_t *circ)
circ->cpath->state != CPATH_STATE_OPEN) {
/* We failed at the first hop. If there's an OR connection
to blame, blame it. */
- connection_t *n_conn = NULL;
+ or_connection_t *n_conn = NULL;
if (circ->_base.n_conn) {
n_conn = circ->_base.n_conn;
} else if (circ->_base.state == CIRCUIT_STATE_OR_WAIT) {
@@ -695,8 +696,8 @@ circuit_build_failed(origin_circuit_t *circ)
log_info(LD_OR,
"Our circuit failed to get a response from the first hop "
"(%s:%d). I'm going to try to rotate to a better connection.",
- n_conn->address, n_conn->port);
- n_conn->is_obsolete = 1;
+ n_conn->_base.address, n_conn->_base.port);
+ n_conn->_base.or_is_obsolete = 1;
entry_guard_set_status(n_conn->identity_digest, 0);
}
}
@@ -893,7 +894,7 @@ circuit_reset_failure_count(int timeout)
* Write the found or in-progress or launched circ into *circp.
*/
static int
-circuit_get_open_circ_or_launch(connection_t *conn,
+circuit_get_open_circ_or_launch(edge_connection_t *conn,
uint8_t desired_circuit_purpose,
origin_circuit_t **circp)
{
@@ -903,7 +904,7 @@ circuit_get_open_circ_or_launch(connection_t *conn,
tor_assert(conn);
tor_assert(circp);
- tor_assert(conn->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;
need_uptime = smartlist_string_num_isin(get_options()->LongLivedPorts,
@@ -966,7 +967,7 @@ circuit_get_open_circ_or_launch(connection_t *conn,
"No intro points for '%s': refetching service descriptor.",
safe_str(conn->rend_query));
rend_client_refetch_renddesc(conn->rend_query);
- conn->state = AP_CONN_STATE_RENDDESC_WAIT;
+ conn->_base.state = AP_CONN_STATE_RENDDESC_WAIT;
return 0;
}
log_info(LD_REND,"Chose '%s' as intro point for '%s'.",
@@ -1033,13 +1034,13 @@ circuit_get_open_circ_or_launch(connection_t *conn,
* circ's cpath.
*/
static void
-link_apconn_to_circ(connection_t *apconn, origin_circuit_t *circ)
+link_apconn_to_circ(edge_connection_t *apconn, origin_circuit_t *circ)
{
/* add it into the linked list of streams on this circuit */
log_debug(LD_APP|LD_CIRC, "attaching new conn to circ. n_circ_id %d.",
circ->_base.n_circ_id);
/* reset it, so we can measure circ timeouts */
- apconn->timestamp_lastread = time(NULL);
+ apconn->_base.timestamp_lastread = time(NULL);
apconn->next_stream = circ->p_streams;
apconn->on_circuit = TO_CIRCUIT(circ);
/* assert_connection_ok(conn, time(NULL)); */
@@ -1054,7 +1055,7 @@ link_apconn_to_circ(connection_t *apconn, origin_circuit_t *circ)
/** If an exit wasn't specifically chosen, save the history for future
* use. */
static void
-consider_recording_trackhost(connection_t *conn, origin_circuit_t *circ)
+consider_recording_trackhost(edge_connection_t *conn, origin_circuit_t *circ)
{
int found_needle = 0;
char *str;
@@ -1108,18 +1109,17 @@ consider_recording_trackhost(connection_t *conn, origin_circuit_t *circ)
* send a begin or resolve cell as appropriate. Return values are as
* for connection_ap_handshake_attach_circuit. */
int
-connection_ap_handshake_attach_chosen_circuit(connection_t *conn,
+connection_ap_handshake_attach_chosen_circuit(edge_connection_t *conn,
origin_circuit_t *circ)
{
tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_AP);
- tor_assert(conn->state == AP_CONN_STATE_CIRCUIT_WAIT ||
- conn->state == AP_CONN_STATE_CONTROLLER_WAIT);
+ tor_assert(conn->_base.state == AP_CONN_STATE_CIRCUIT_WAIT ||
+ conn->_base.state == AP_CONN_STATE_CONTROLLER_WAIT);
tor_assert(conn->socks_request);
tor_assert(circ);
tor_assert(circ->_base.state == CIRCUIT_STATE_OPEN);
- conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
+ conn->_base.state = AP_CONN_STATE_CIRCUIT_WAIT;
if (!circ->_base.timestamp_dirty)
circ->_base.timestamp_dirty = time(NULL);
@@ -1146,19 +1146,18 @@ connection_ap_handshake_attach_chosen_circuit(connection_t *conn,
* right next step, and return 1.
*/
int
-connection_ap_handshake_attach_circuit(connection_t *conn)
+connection_ap_handshake_attach_circuit(edge_connection_t *conn)
{
int retval;
int conn_age;
int severity;
tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_AP);
- tor_assert(conn->state == AP_CONN_STATE_CIRCUIT_WAIT);
+ tor_assert(conn->_base.state == AP_CONN_STATE_CIRCUIT_WAIT);
tor_assert(conn->socks_request);
- conn_age = time(NULL) - conn->timestamp_created;
- severity = (!conn->addr && !conn->port) ? LOG_INFO : LOG_NOTICE;
+ conn_age = time(NULL) - conn->_base.timestamp_created;
+ severity = (!conn->_base.addr && !conn->_base.port) ? LOG_INFO : LOG_NOTICE;
if (conn_age > get_options()->SocksTimeout) {
log_fn(severity, LD_APP,
"Tried for %d seconds to get a connection to %s:%d. Giving up.",
diff --git a/src/or/command.c b/src/or/command.c
index 49fcc654c7..9e3e529737 100644
--- a/src/or/command.c
+++ b/src/or/command.c
@@ -27,10 +27,10 @@ uint64_t stats_n_relay_cells_processed = 0;
uint64_t stats_n_destroy_cells_processed = 0;
/* These are the main four functions for processing cells */
-static void command_process_create_cell(cell_t *cell, connection_t *conn);
-static void command_process_created_cell(cell_t *cell, connection_t *conn);
-static void command_process_relay_cell(cell_t *cell, connection_t *conn);
-static void command_process_destroy_cell(cell_t *cell, connection_t *conn);
+static void command_process_create_cell(cell_t *cell, or_connection_t *conn);
+static void command_process_created_cell(cell_t *cell, or_connection_t *conn);
+static void command_process_relay_cell(cell_t *cell, or_connection_t *conn);
+static void command_process_destroy_cell(cell_t *cell, or_connection_t *conn);
#ifdef KEEP_TIMING_STATS
/** This is a wrapper function around the actual function that processes the
@@ -38,8 +38,8 @@ static void command_process_destroy_cell(cell_t *cell, connection_t *conn);
* by the number of microseconds used by the call to <b>*func(cell, conn)</b>.
*/
static void
-command_time_process_cell(cell_t *cell, connection_t *conn, int *time,
- void (*func)(cell_t *, connection_t *))
+command_time_process_cell(cell_t *cell, or_connection_t *conn, int *time,
+ void (*func)(cell_t *, or_connection_t *))
{
struct timeval start, end;
long time_passed;
@@ -68,7 +68,7 @@ command_time_process_cell(cell_t *cell, connection_t *conn, int *time,
* process each type of cell.
*/
void
-command_process_cell(cell_t *cell, connection_t *conn)
+command_process_cell(cell_t *cell, or_connection_t *conn)
{
#ifdef KEEP_TIMING_STATS
/* how many of each cell have we seen so far this second? needs better
@@ -159,7 +159,7 @@ command_process_cell(cell_t *cell, connection_t *conn)
* picked up again when the cpuworker finishes decrypting it.
*/
static void
-command_process_create_cell(cell_t *cell, connection_t *conn)
+command_process_create_cell(cell_t *cell, or_connection_t *conn)
{
or_circuit_t *circ;
int id_is_high;
@@ -191,7 +191,7 @@ command_process_create_cell(cell_t *cell, connection_t *conn)
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Received CREATE cell (circID %d) for known circ. "
"Dropping (age %d).",
- cell->circ_id, (int)(time(NULL) - conn->timestamp_created));
+ cell->circ_id, (int)(time(NULL) - conn->_base.timestamp_created));
if (router)
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Details: nickname \"%s\", platform %s.",
@@ -241,7 +241,7 @@ command_process_create_cell(cell_t *cell, connection_t *conn)
* extend to the next hop in the circuit if necessary.
*/
static void
-command_process_created_cell(cell_t *cell, connection_t *conn)
+command_process_created_cell(cell_t *cell, or_connection_t *conn)
{
circuit_t *circ;
@@ -290,7 +290,7 @@ command_process_created_cell(cell_t *cell, connection_t *conn)
* circuit_receive_relay_cell() for actual processing.
*/
static void
-command_process_relay_cell(cell_t *cell, connection_t *conn)
+command_process_relay_cell(cell_t *cell, or_connection_t *conn)
{
circuit_t *circ;
int reason;
@@ -300,7 +300,7 @@ command_process_relay_cell(cell_t *cell, connection_t *conn)
if (!circ) {
log_debug(LD_OR,
"unknown circuit %d on connection from %s:%d. Dropping.",
- cell->circ_id, conn->address, conn->port);
+ cell->circ_id, conn->_base.address, conn->_base.port);
return;
}
@@ -345,7 +345,7 @@ command_process_relay_cell(cell_t *cell, connection_t *conn)
* and passes the destroy cell onward if necessary).
*/
static void
-command_process_destroy_cell(cell_t *cell, connection_t *conn)
+command_process_destroy_cell(cell_t *cell, or_connection_t *conn)
{
circuit_t *circ;
uint8_t reason;
@@ -354,7 +354,7 @@ command_process_destroy_cell(cell_t *cell, connection_t *conn)
reason = (uint8_t)cell->payload[0];
if (!circ) {
log_info(LD_OR,"unknown circuit %d on connection from %s:%d. Dropping.",
- cell->circ_id, conn->address, conn->port);
+ cell->circ_id, conn->_base.address, conn->_base.port);
return;
}
log_debug(LD_OR,"Received for circID %d.",cell->circ_id);
diff --git a/src/or/connection.c b/src/or/connection.c
index f3c4eea534..21f3d89974 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -18,7 +18,7 @@ static connection_t *connection_create_listener(const char *listenaddress,
uint16_t listenport, int type);
static int connection_init_accepted_conn(connection_t *conn);
static int connection_handle_listener_read(connection_t *conn, int new_type);
-static int connection_receiver_bucket_should_increase(connection_t *conn);
+static int connection_receiver_bucket_should_increase(or_connection_t *conn);
static int connection_finished_flushing(connection_t *conn);
static int connection_flushed_some(connection_t *conn);
static int connection_finished_connecting(connection_t *conn);
@@ -161,9 +161,35 @@ connection_new(int type)
static uint32_t n_connections_allocated = 0;
connection_t *conn;
time_t now = time(NULL);
+ size_t length;
+ uint32_t magic;
- conn = tor_malloc_zero(sizeof(connection_t));
- conn->magic = CONNECTION_MAGIC;
+ switch (type) {
+ case CONN_TYPE_OR:
+ length = sizeof(or_connection_t);
+ magic = OR_CONNECTION_MAGIC;
+ break;
+ case CONN_TYPE_EXIT:
+ case CONN_TYPE_AP:
+ length = sizeof(edge_connection_t);
+ magic = EDGE_CONNECTION_MAGIC;
+ break;
+ case CONN_TYPE_DIR:
+ length = sizeof(dir_connection_t);
+ magic = DIR_CONNECTION_MAGIC;
+ break;
+ case CONN_TYPE_CONTROL:
+ length = sizeof(control_connection_t);
+ magic = CONTROL_CONNECTION_MAGIC;
+ break;
+ default:
+ length = sizeof(connection_t);
+ magic = BASE_CONNECTION_MAGIC;
+ break;
+ }
+
+ conn = tor_malloc_zero(length);
+ conn->magic = magic;
conn->s = -1; /* give it a default of 'not used' */
conn->poll_index = -1; /* also default to 'not used' */
conn->global_identifier = n_connections_allocated++;
@@ -174,10 +200,11 @@ connection_new(int type)
conn->outbuf = buf_new();
}
if (type == CONN_TYPE_AP) {
- conn->socks_request = tor_malloc_zero(sizeof(socks_request_t));
+ TO_EDGE_CONN(conn)->socks_request =
+ tor_malloc_zero(sizeof(socks_request_t));
}
-
- conn->next_circ_id = crypto_rand_int(1<<15);
+ if (type == CONN_TYPE_OR)
+ TO_OR_CONN(conn)->next_circ_id = crypto_rand_int(1<<15);
conn->timestamp_created = now;
conn->timestamp_lastread = now;
@@ -209,28 +236,72 @@ connection_unregister(connection_t *conn)
static void
_connection_free(connection_t *conn)
{
- tor_assert(conn->magic == CONNECTION_MAGIC);
+ void *mem;
+ switch (conn->type) {
+ case CONN_TYPE_OR:
+ tor_assert(conn->magic == OR_CONNECTION_MAGIC);
+ mem = TO_OR_CONN(conn);
+ break;
+ case CONN_TYPE_AP:
+ case CONN_TYPE_EXIT:
+ tor_assert(conn->magic == EDGE_CONNECTION_MAGIC);
+ mem = TO_EDGE_CONN(conn);
+ break;
+ case CONN_TYPE_DIR:
+ tor_assert(conn->magic == DIR_CONNECTION_MAGIC);
+ mem = TO_DIR_CONN(conn);
+ break;
+ case CONN_TYPE_CONTROL:
+ tor_assert(conn->magic == CONTROL_CONNECTION_MAGIC);
+ mem = TO_CONTROL_CONN(conn);
+ break;
+ default:
+ tor_assert(conn->magic == BASE_CONNECTION_MAGIC);
+ mem = conn;
+ break;
+ }
if (!connection_is_listener(conn)) {
buf_free(conn->inbuf);
buf_free(conn->outbuf);
}
+
tor_free(conn->address);
- tor_free(conn->chosen_exit_name);
if (connection_speaks_cells(conn)) {
- if (conn->tls) {
- tor_tls_free(conn->tls);
- conn->tls = NULL;
+ or_connection_t *or_conn = TO_OR_CONN(conn);
+ if (or_conn->tls) {
+ tor_tls_free(or_conn->tls);
+ or_conn->tls = NULL;
}
+
+ tor_free(or_conn->nickname);
+ }
+ if (CONN_IS_EDGE(conn)) {
+ edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
+ tor_free(edge_conn->chosen_exit_name);
+ tor_free(edge_conn->socks_request);
+ }
+ if (conn->type == CONN_TYPE_CONTROL) {
+ control_connection_t *control_conn = TO_CONTROL_CONN(conn);
+ tor_free(control_conn->incoming_cmd);
}
- tor_free(conn->nickname);
- tor_free(conn->socks_request);
- tor_free(conn->incoming_cmd);
tor_free(conn->read_event); /* Probably already freed by connection_free. */
tor_free(conn->write_event); /* Probably already freed by connection_free. */
- tor_free(conn->requested_resource);
+
+ if (conn->type == CONN_TYPE_DIR) {
+ dir_connection_t *dir_conn = TO_DIR_CONN(conn);
+ tor_free(dir_conn->requested_resource);
+ if (dir_conn->zlib_state)
+ tor_zlib_free(dir_conn->zlib_state);
+ if (dir_conn->fingerprint_stack) {
+ SMARTLIST_FOREACH(dir_conn->fingerprint_stack, char *, cp, tor_free(cp));
+ smartlist_free(dir_conn->fingerprint_stack);
+ }
+ if (dir_conn->cached_dir)
+ cached_dir_decref(dir_conn->cached_dir);
+ }
if (conn->s >= 0) {
log_debug(LD_NET,"closing fd %d.",conn->s);
@@ -238,21 +309,13 @@ _connection_free(connection_t *conn)
}
if (conn->type == CONN_TYPE_OR &&
- !tor_digest_is_zero(conn->identity_digest)) {
+ !tor_digest_is_zero(TO_OR_CONN(conn)->identity_digest)) {
log_warn(LD_BUG, "called on OR conn with non-zeroed identity_digest");
- connection_or_remove_from_identity_map(conn);
- }
- if (conn->zlib_state)
- tor_zlib_free(conn->zlib_state);
- if (conn->fingerprint_stack) {
- SMARTLIST_FOREACH(conn->fingerprint_stack, char *, cp, tor_free(cp));
- smartlist_free(conn->fingerprint_stack);
+ connection_or_remove_from_identity_map(TO_OR_CONN(conn));
}
- if (conn->cached_dir)
- cached_dir_decref(conn->cached_dir);
memset(conn, 0xAA, sizeof(connection_t)); /* poison memory */
- tor_free(conn);
+ tor_free(mem);
}
/** Make sure <b>conn</b> isn't in any of the global conn lists; then free it.
@@ -266,12 +329,12 @@ connection_free(connection_t *conn)
if (connection_speaks_cells(conn)) {
if (conn->state == OR_CONN_STATE_OPEN)
directory_set_dirty();
- if (!tor_digest_is_zero(conn->identity_digest)) {
- connection_or_remove_from_identity_map(conn);
+ if (!tor_digest_is_zero(TO_OR_CONN(conn)->identity_digest)) {
+ connection_or_remove_from_identity_map(TO_OR_CONN(conn));
}
}
if (conn->type == CONN_TYPE_CONTROL) {
- conn->event_mask = 0;
+ TO_CONTROL_CONN(conn)->event_mask = 0;
control_update_global_event_mask();
}
connection_unregister(conn);
@@ -297,7 +360,7 @@ connection_free_all(void)
/* We don't want to log any messages to controllers. */
for (i=0;i<n;i++)
if (carray[i]->type == CONN_TYPE_CONTROL)
- carray[i]->event_mask = 0;
+ TO_CONTROL_CONN(carray[i])->event_mask = 0;
control_update_global_event_mask();
/* Unlink everything from the identity map. */
@@ -326,11 +389,14 @@ void
connection_about_to_close_connection(connection_t *conn)
{
circuit_t *circ;
+ dir_connection_t *dir_conn;
+ or_connection_t *or_conn;
+ edge_connection_t *edge_conn;
assert(conn->marked_for_close);
if (CONN_IS_EDGE(conn)) {
- if (!conn->has_sent_end) {
+ if (!conn->edge_has_sent_end) {
log_warn(LD_BUG, "Harmless bug: Edge connection (marked at %s:%d) "
"hasn't sent end yet?",
conn->marked_for_close_file, conn->marked_for_close);
@@ -340,23 +406,25 @@ connection_about_to_close_connection(connection_t *conn)
switch (conn->type) {
case CONN_TYPE_DIR:
+ dir_conn = TO_DIR_CONN(conn);
if (conn->state < DIR_CONN_STATE_CLIENT_FINISHED) {
/* It's a directory connection and connecting or fetching
* failed: forget about this router, and maybe try again. */
- connection_dir_request_failed(conn);
+ connection_dir_request_failed(dir_conn);
// XXX if it's rend desc we may want to retry -RD
}
if (conn->purpose == DIR_PURPOSE_FETCH_RENDDESC)
- rend_client_desc_here(conn->rend_query); /* give it a try */
+ rend_client_desc_here(dir_conn->rend_query); /* give it a try */
break;
case CONN_TYPE_OR:
+ or_conn = TO_OR_CONN(conn);
/* Remember why we're closing this connection. */
if (conn->state != OR_CONN_STATE_OPEN) {
- if (connection_or_nonopen_was_started_here(conn)) {
- rep_hist_note_connect_failed(conn->identity_digest, time(NULL));
- entry_guard_set_status(conn->identity_digest, 0);
- router_set_status(conn->identity_digest, 0);
- control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED);
+ if (connection_or_nonopen_was_started_here(or_conn)) {
+ rep_hist_note_connect_failed(or_conn->identity_digest, time(NULL));
+ entry_guard_set_status(or_conn->identity_digest, 0);
+ router_set_status(or_conn->identity_digest, 0);
+ control_event_or_conn_status(or_conn, OR_CONN_EVENT_FAILED);
}
} else if (conn->hold_open_until_flushed) {
/* XXXX009 We used to have an arg that told us whether we closed the
@@ -368,30 +436,32 @@ connection_about_to_close_connection(connection_t *conn)
* flushing still get noted as dead, not disconnected. But this is an
* improvement. -NM
*/
- rep_hist_note_disconnect(conn->identity_digest, time(NULL));
- control_event_or_conn_status(conn, OR_CONN_EVENT_CLOSED);
- } else if (conn->identity_digest) {
- rep_hist_note_connection_died(conn->identity_digest, time(NULL));
- control_event_or_conn_status(conn, OR_CONN_EVENT_CLOSED);
+ rep_hist_note_disconnect(or_conn->identity_digest, time(NULL));
+ control_event_or_conn_status(or_conn, OR_CONN_EVENT_CLOSED);
+ } else if (or_conn->identity_digest) {
+ rep_hist_note_connection_died(or_conn->identity_digest, time(NULL));
+ control_event_or_conn_status(or_conn, OR_CONN_EVENT_CLOSED);
}
break;
case CONN_TYPE_AP:
- if (conn->socks_request->has_finished == 0) {
+ edge_conn = TO_EDGE_CONN(conn);
+ if (edge_conn->socks_request->has_finished == 0) {
/* since conn gets removed right after this function finishes,
* there's no point trying to send back a reply at this point. */
log_warn(LD_BUG,"Bug: Closing stream (marked at %s:%d) without sending"
" back a socks reply.",
conn->marked_for_close_file, conn->marked_for_close);
} else {
- control_event_stream_status(conn, STREAM_EVENT_CLOSED);
+ control_event_stream_status(edge_conn, STREAM_EVENT_CLOSED);
}
break;
case CONN_TYPE_EXIT:
+ edge_conn = TO_EDGE_CONN(conn);
if (conn->state == EXIT_CONN_STATE_RESOLVING) {
- circ = circuit_get_by_edge_conn(conn);
+ circ = circuit_get_by_edge_conn(edge_conn);
if (circ)
- circuit_detach_stream(circ, conn);
- connection_dns_remove(conn);
+ circuit_detach_stream(circ, edge_conn);
+ connection_dns_remove(edge_conn);
}
break;
case CONN_TYPE_DNSWORKER:
@@ -731,8 +801,8 @@ connection_init_accepted_conn(connection_t *conn)
switch (conn->type) {
case CONN_TYPE_OR:
- control_event_or_conn_status(conn, OR_CONN_EVENT_NEW);
- return connection_tls_start_handshake(conn, 1);
+ control_event_or_conn_status(TO_OR_CONN(conn), OR_CONN_EVENT_NEW);
+ return connection_tls_start_handshake(TO_OR_CONN(conn), 1);
case CONN_TYPE_AP:
conn->state = AP_CONN_STATE_SOCKS_WAIT;
break;
@@ -1006,9 +1076,11 @@ connection_bucket_read_limit(connection_t *conn)
if (at_most > global_read_bucket)
at_most = global_read_bucket;
- if (connection_speaks_cells(conn) && conn->state == OR_CONN_STATE_OPEN)
- if (at_most > conn->receiver_bucket)
- at_most = conn->receiver_bucket;
+ if (connection_speaks_cells(conn) && conn->state == OR_CONN_STATE_OPEN) {
+ or_connection_t *or_conn = TO_OR_CONN(conn);
+ if (at_most > or_conn->receiver_bucket)
+ at_most = or_conn->receiver_bucket;
+ }
if (at_most < 0)
return 0;
@@ -1052,7 +1124,7 @@ connection_read_bucket_decrement(connection_t *conn, int num_read)
{
global_read_bucket -= num_read;
if (connection_speaks_cells(conn) && conn->state == OR_CONN_STATE_OPEN) {
- conn->receiver_bucket -= num_read;
+ TO_OR_CONN(conn)->receiver_bucket -= num_read;
}
}
@@ -1069,7 +1141,7 @@ connection_consider_empty_buckets(connection_t *conn)
}
if (connection_speaks_cells(conn) &&
conn->state == OR_CONN_STATE_OPEN &&
- conn->receiver_bucket <= 0) {
+ TO_OR_CONN(conn)->receiver_bucket <= 0) {
LOG_FN_CONN(conn,
(LOG_DEBUG,LD_NET,"receiver bucket exhausted. Pausing."));
conn->wants_to_read = 1;
@@ -1114,12 +1186,15 @@ connection_bucket_refill(struct timeval *now)
for (i=0;i<n;i++) {
conn = carray[i];
- if (connection_receiver_bucket_should_increase(conn)) {
- conn->receiver_bucket += conn->bandwidthrate;
- if (conn->receiver_bucket > conn->bandwidthburst)
- conn->receiver_bucket = conn->bandwidthburst;
- //log_fn(LOG_DEBUG,"Receiver bucket %d now %d.", i,
- // conn->receiver_bucket);
+ if (connection_speaks_cells(conn)) {
+ or_connection_t *or_conn = TO_OR_CONN(conn);
+ if (connection_receiver_bucket_should_increase(or_conn)) {
+ or_conn->receiver_bucket += or_conn->bandwidthrate;
+ if (or_conn->receiver_bucket > or_conn->bandwidthburst)
+ or_conn->receiver_bucket = or_conn->bandwidthburst;
+ //log_fn(LOG_DEBUG,"Receiver bucket %d now %d.", i,
+ // conn->receiver_bucket);
+ }
}
if (conn->wants_to_read == 1 /* it's marked to turn reading back on now */
@@ -1128,7 +1203,7 @@ connection_bucket_refill(struct timeval *now)
* not the best place to check this.) */
&& (!connection_speaks_cells(conn) ||
conn->state != OR_CONN_STATE_OPEN ||
- conn->receiver_bucket > 0)) {
+ TO_OR_CONN(conn)->receiver_bucket > 0)) {
/* and either a non-cell conn or a cell conn with non-empty bucket */
LOG_FN_CONN(conn, (LOG_DEBUG,LD_NET,"waking up conn (fd %d)",conn->s));
conn->wants_to_read = 0;
@@ -1145,15 +1220,12 @@ connection_bucket_refill(struct timeval *now)
* should add another pile of tokens to it?
*/
static int
-connection_receiver_bucket_should_increase(connection_t *conn)
+connection_receiver_bucket_should_increase(or_connection_t *conn)
{
tor_assert(conn);
- if (!connection_speaks_cells(conn))
- return 0; /* edge connections don't use receiver_buckets */
- if (conn->state != OR_CONN_STATE_OPEN)
+ if (conn->_base.state != OR_CONN_STATE_OPEN)
return 0; /* only open connections play the rate limiting game */
-
if (conn->receiver_bucket >= conn->bandwidthburst)
return 0;
@@ -1200,15 +1272,15 @@ loop_again:
/* There's a read error; kill the connection.*/
connection_close_immediate(conn); /* Don't flush; connection is dead. */
if (CONN_IS_EDGE(conn)) {
- connection_edge_end_errno(conn, conn->cpath_layer);
- if (conn->socks_request) /* broken, so don't send a socks reply back */
- conn->socks_request->has_finished = 1;
+ edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
+ connection_edge_end_errno(edge_conn, edge_conn->cpath_layer);
+ if (edge_conn->socks_request) /* broken, don't send a socks reply back */
+ edge_conn->socks_request->has_finished = 1;
}
connection_mark_for_close(conn);
return -1;
}
- if (CONN_IS_EDGE(conn) &&
- try_to_read != max_to_read) {
+ if (CONN_IS_EDGE(conn) && try_to_read != max_to_read) {
/* instruct it not to try to package partial cells. */
if (connection_process_inbuf(conn, 0) < 0) {
return -1;
@@ -1265,29 +1337,32 @@ connection_read_to_buf(connection_t *conn, int *max_to_read)
if (connection_speaks_cells(conn) &&
conn->state > OR_CONN_STATE_PROXY_READING) {
int pending;
+ or_connection_t *or_conn = TO_OR_CONN(conn);
if (conn->state == OR_CONN_STATE_HANDSHAKING) {
/* continue handshaking even if global token bucket is empty */
- return connection_tls_continue_handshake(conn);
+ return connection_tls_continue_handshake(or_conn);
}
log_debug(LD_NET,
"%d: starting, inbuf_datalen %d (%d pending in tls object)."
" at_most %d.",
conn->s,(int)buf_datalen(conn->inbuf),
- tor_tls_get_pending_bytes(conn->tls), at_most);
+ tor_tls_get_pending_bytes(or_conn->tls), at_most);
/* else open, or closing */
- result = read_to_buf_tls(conn->tls, at_most, conn->inbuf);
+ result = read_to_buf_tls(or_conn->tls, at_most, conn->inbuf);
switch (result) {
case TOR_TLS_CLOSE:
log_info(LD_NET,"TLS connection closed on read. Closing. "
"(Nickname %s, address %s",
- conn->nickname ? conn->nickname : "not set", conn->address);
+ or_conn->nickname ? or_conn->nickname : "not set",
+ conn->address);
return -1;
case TOR_TLS_ERROR:
log_info(LD_NET,"tls error. breaking (nickname %s, address %s).",
- conn->nickname ? conn->nickname : "not set", conn->address);
+ or_conn->nickname ? or_conn->nickname : "not set",
+ conn->address);
return -1;
case TOR_TLS_WANTWRITE:
connection_start_writing(conn);
@@ -1299,12 +1374,12 @@ connection_read_to_buf(connection_t *conn, int *max_to_read)
default:
break;
}
- pending = tor_tls_get_pending_bytes(conn->tls);
+ pending = tor_tls_get_pending_bytes(or_conn->tls);
if (pending) {
/* XXXX If we have any pending bytes, read them now. This *can*
* take us over our read allotment, but really we shouldn't be
* believing that SSL bytes are the same as TCP bytes anyway. */
- int r2 = read_to_buf_tls(conn->tls, pending, conn->inbuf);
+ int r2 = read_to_buf_tls(or_conn->tls, pending, conn->inbuf);
if (r2<0) {
log_warn(LD_BUG, "Bug: apparently, reading pending bytes can fail.");
return -1;
@@ -1409,7 +1484,8 @@ connection_handle_write(connection_t *conn)
log_warn(LD_BUG,
"getsockopt() syscall failed?! Please report to tor-ops.");
if (CONN_IS_EDGE(conn))
- connection_edge_end_errno(conn, conn->cpath_layer);
+ connection_edge_end_errno(TO_EDGE_CONN(conn),
+ TO_EDGE_CONN(conn)->cpath_layer);
connection_mark_for_close(conn);
return -1;
}
@@ -1418,7 +1494,8 @@ connection_handle_write(connection_t *conn)
if (!ERRNO_IS_CONN_EINPROGRESS(e)) {
log_info(LD_NET,"in-progress connect failed. Removing.");
if (CONN_IS_EDGE(conn))
- connection_edge_end_errno(conn, conn->cpath_layer);
+ connection_edge_end_errno(TO_EDGE_CONN(conn),
+ TO_EDGE_CONN(conn)->cpath_layer);
connection_close_immediate(conn);
connection_mark_for_close(conn);
@@ -1426,7 +1503,7 @@ connection_handle_write(connection_t *conn)
* ignores unrecognized routers
*/
if (conn->type == CONN_TYPE_OR && !get_options()->HttpsProxy)
- router_set_status(conn->identity_digest, 0);
+ router_set_status(TO_OR_CONN(conn)->identity_digest, 0);
return -1;
} else {
return 0; /* no change, see if next time is better */
@@ -1441,9 +1518,10 @@ connection_handle_write(connection_t *conn)
if (connection_speaks_cells(conn) &&
conn->state > OR_CONN_STATE_PROXY_READING) {
+ or_connection_t *or_conn = TO_OR_CONN(conn);
if (conn->state == OR_CONN_STATE_HANDSHAKING) {
connection_stop_writing(conn);
- if (connection_tls_continue_handshake(conn) < 0) {
+ if (connection_tls_continue_handshake(or_conn) < 0) {
/* Don't flush; connection is dead. */
connection_close_immediate(conn);
connection_mark_for_close(conn);
@@ -1453,7 +1531,7 @@ connection_handle_write(connection_t *conn)
}
/* else open, or closing */
- result = flush_buf_tls(conn->tls, conn->outbuf,
+ result = flush_buf_tls(or_conn->tls, conn->outbuf,
max_to_write, &conn->outbuf_flushlen);
switch (result) {
case TOR_TLS_ERROR:
@@ -1491,7 +1569,8 @@ connection_handle_write(connection_t *conn)
max_to_write, &conn->outbuf_flushlen));
if (result < 0) {
if (CONN_IS_EDGE(conn))
- connection_edge_end_errno(conn, conn->cpath_layer);
+ connection_edge_end_errno(TO_EDGE_CONN(conn),
+ TO_EDGE_CONN(conn)->cpath_layer);
connection_close_immediate(conn); /* Don't flush; connection is dead. */
connection_mark_for_close(conn);
@@ -1521,16 +1600,17 @@ connection_handle_write(connection_t *conn)
/* A controller event has just happened with such urgency that we
* need to write it onto controller <b>conn</b> immediately. */
void
-_connection_controller_force_write(connection_t *conn)
+_connection_controller_force_write(control_connection_t *control_conn)
{
/* XXX This is hideous code duplication, but raising it seems a little
* tricky for now. Think more about this one. We only call it for
* EVENT_ERR_MSG, so messing with buckets a little isn't such a big problem.
*/
int result;
- tor_assert(conn);
- tor_assert(!conn->tls);
- tor_assert(conn->type == CONN_TYPE_CONTROL);
+ connection_t *conn;
+ tor_assert(control_conn);
+ conn = TO_CONN(control_conn);
+
if (conn->marked_for_close || conn->s < 0)
return;
@@ -1580,7 +1660,7 @@ connection_write_to_buf(const char *string, size_t len, connection_t *conn)
wrong compared to our max outbuf size. close the whole circuit. */
log_warn(LD_NET,
"write_to_buf failed. Closing circuit (fd %d).", conn->s);
- circuit_mark_for_close(circuit_get_by_edge_conn(conn),
+ circuit_mark_for_close(circuit_get_by_edge_conn(TO_EDGE_CONN(conn)),
END_CIRC_REASON_INTERNAL);
} else {
log_warn(LD_NET,
@@ -1595,15 +1675,17 @@ connection_write_to_buf(const char *string, size_t len, connection_t *conn)
}
void
-connection_write_to_buf_zlib(connection_t *conn,
+connection_write_to_buf_zlib(dir_connection_t *dir_conn,
tor_zlib_state_t *state,
const char *data, size_t data_len,
int done)
{
int r;
size_t old_datalen;
+ connection_t *conn;
if (!data_len)
return;
+ conn = TO_CONN(dir_conn);
/* if it's marked for close, only allow write if we mean to flush it */
if (conn->marked_for_close && !conn->hold_open_until_flushed)
return;
@@ -1614,18 +1696,9 @@ connection_write_to_buf_zlib(connection_t *conn,
conn->outbuf, state, data, data_len,
done));
if (r < 0) {
- if (CONN_IS_EDGE(conn)) {
- /* if it failed, it means we have our package/delivery windows set
- wrong compared to our max outbuf size. close the whole circuit. */
- log_warn(LD_NET,
- "write_to_buf failed. Closing circuit (fd %d).", conn->s);
- circuit_mark_for_close(circuit_get_by_edge_conn(conn),
- END_CIRC_REASON_INTERNAL);
- } else {
- log_warn(LD_NET,
- "write_to_buf failed. Closing connection (fd %d).", conn->s);
- connection_mark_for_close(conn);
- }
+ log_warn(LD_NET,
+ "write_to_buf failed. Closing connection (fd %d).", conn->s);
+ connection_mark_for_close(conn);
return;
}
@@ -1635,11 +1708,12 @@ connection_write_to_buf_zlib(connection_t *conn,
/** Return the conn to addr/port that has the most recent
* timestamp_created, or NULL if no such conn exists. */
-connection_t *
+or_connection_t *
connection_or_exact_get_by_addr_port(uint32_t addr, uint16_t port)
{
int i, n;
- connection_t *conn, *best=NULL;
+ connection_t *conn;
+ or_connection_t *best=NULL;
connection_t **carray;
get_connection_array(&carray,&n);
@@ -1649,8 +1723,8 @@ connection_or_exact_get_by_addr_port(uint32_t addr, uint16_t port)
conn->addr == addr &&
conn->port == port &&
!conn->marked_for_close &&
- (!best || best->timestamp_created < conn->timestamp_created))
- best = conn;
+ (!best || best->_base.timestamp_created < conn->timestamp_created))
+ best = TO_OR_CONN(conn);
}
return best;
}
@@ -1772,14 +1846,22 @@ connection_get_by_type_state_rendquery(int type, int state,
connection_t *conn;
connection_t **carray;
+ tor_assert(type == CONN_TYPE_DIR ||
+ type == CONN_TYPE_AP || type == CONN_TYPE_EXIT);
+
get_connection_array(&carray,&n);
for (i=0;i<n;i++) {
conn = carray[i];
if (conn->type == type &&
!conn->marked_for_close &&
- (!state || state == conn->state) &&
- !rend_cmp_service_ids(rendquery, conn->rend_query))
- return conn;
+ (!state || state == conn->state)) {
+ if (type == CONN_TYPE_DIR &&
+ rend_cmp_service_ids(rendquery, TO_DIR_CONN(conn)->rend_query))
+ return conn;
+ else if (CONN_IS_EDGE(conn) &&
+ rend_cmp_service_ids(rendquery, TO_EDGE_CONN(conn)->rend_query))
+ return conn;
+ }
}
return NULL;
}
@@ -1949,18 +2031,18 @@ connection_process_inbuf(connection_t *conn, int package_partial)
switch (conn->type) {
case CONN_TYPE_OR:
- return connection_or_process_inbuf(conn);
+ return connection_or_process_inbuf(TO_OR_CONN(conn));
case CONN_TYPE_EXIT:
case CONN_TYPE_AP:
- return connection_edge_process_inbuf(conn, package_partial);
+ return connection_edge_process_inbuf(TO_EDGE_CONN(conn), package_partial);
case CONN_TYPE_DIR:
- return connection_dir_process_inbuf(conn);
+ return connection_dir_process_inbuf(TO_DIR_CONN(conn));
case CONN_TYPE_DNSWORKER:
return connection_dns_process_inbuf(conn);
case CONN_TYPE_CPUWORKER:
return connection_cpu_process_inbuf(conn);
case CONN_TYPE_CONTROL:
- return connection_control_process_inbuf(conn);
+ return connection_control_process_inbuf(TO_CONTROL_CONN(conn));
default:
log_err(LD_BUG,"Bug: got unexpected conn type %d.", conn->type);
tor_fragile_assert();
@@ -1974,7 +2056,7 @@ connection_flushed_some(connection_t *conn)
{
if (conn->type == CONN_TYPE_DIR &&
conn->state == DIR_CONN_STATE_SERVER_WRITING)
- return connection_dirserv_flushed_some(conn);
+ return connection_dirserv_flushed_some(TO_DIR_CONN(conn));
else
return 0;
}
@@ -1994,18 +2076,18 @@ connection_finished_flushing(connection_t *conn)
switch (conn->type) {
case CONN_TYPE_OR:
- return connection_or_finished_flushing(conn);
+ return connection_or_finished_flushing(TO_OR_CONN(conn));
case CONN_TYPE_AP:
case CONN_TYPE_EXIT:
- return connection_edge_finished_flushing(conn);
+ return connection_edge_finished_flushing(TO_EDGE_CONN(conn));
case CONN_TYPE_DIR:
- return connection_dir_finished_flushing(conn);
+ return connection_dir_finished_flushing(TO_DIR_CONN(conn));
case CONN_TYPE_DNSWORKER:
return connection_dns_finished_flushing(conn);
case CONN_TYPE_CPUWORKER:
return connection_cpu_finished_flushing(conn);
case CONN_TYPE_CONTROL:
- return connection_control_finished_flushing(conn);
+ return connection_control_finished_flushing(TO_CONTROL_CONN(conn));
default:
log_err(LD_BUG,"Bug: got unexpected conn type %d.", conn->type);
tor_fragile_assert();
@@ -2026,11 +2108,11 @@ connection_finished_connecting(connection_t *conn)
switch (conn->type)
{
case CONN_TYPE_OR:
- return connection_or_finished_connecting(conn);
+ return connection_or_finished_connecting(TO_OR_CONN(conn));
case CONN_TYPE_EXIT:
- return connection_edge_finished_connecting(conn);
+ return connection_edge_finished_connecting(TO_EDGE_CONN(conn));
case CONN_TYPE_DIR:
- return connection_dir_finished_connecting(conn);
+ return connection_dir_finished_connecting(TO_DIR_CONN(conn));
default:
log_err(LD_BUG,"Bug: got unexpected conn type %d.", conn->type);
tor_fragile_assert();
@@ -2044,18 +2126,18 @@ connection_reached_eof(connection_t *conn)
{
switch (conn->type) {
case CONN_TYPE_OR:
- return connection_or_reached_eof(conn);
+ return connection_or_reached_eof(TO_OR_CONN(conn));
case CONN_TYPE_AP:
case CONN_TYPE_EXIT:
- return connection_edge_reached_eof(conn);
+ return connection_edge_reached_eof(TO_EDGE_CONN(conn));
case CONN_TYPE_DIR:
- return connection_dir_reached_eof(conn);
+ return connection_dir_reached_eof(TO_DIR_CONN(conn));
case CONN_TYPE_DNSWORKER:
return connection_dns_reached_eof(conn);
case CONN_TYPE_CPUWORKER:
return connection_cpu_reached_eof(conn);
case CONN_TYPE_CONTROL:
- return connection_control_reached_eof(conn);
+ return connection_control_reached_eof(TO_CONTROL_CONN(conn));
default:
log_err(LD_BUG,"Bug: got unexpected conn type %d.", conn->type);
tor_fragile_assert();
@@ -2071,9 +2153,26 @@ assert_connection_ok(connection_t *conn, time_t now)
{
(void) now; /* XXXX unused. */
tor_assert(conn);
- tor_assert(conn->magic == CONNECTION_MAGIC);
tor_assert(conn->type >= _CONN_TYPE_MIN);
tor_assert(conn->type <= _CONN_TYPE_MAX);
+ switch (conn->type) {
+ case CONN_TYPE_OR:
+ tor_assert(conn->magic == OR_CONNECTION_MAGIC);
+ break;
+ case CONN_TYPE_AP:
+ case CONN_TYPE_EXIT:
+ tor_assert(conn->magic == EDGE_CONNECTION_MAGIC);
+ break;
+ case CONN_TYPE_DIR:
+ tor_assert(conn->magic == DIR_CONNECTION_MAGIC);
+ break;
+ case CONN_TYPE_CONTROL:
+ tor_assert(conn->magic == CONTROL_CONNECTION_MAGIC);
+ break;
+ default:
+ tor_assert(conn->magic == BASE_CONNECTION_MAGIC);
+ break;
+ }
if (conn->outbuf_flushlen > 0) {
tor_assert(connection_is_writing(conn) || conn->wants_to_write);
@@ -2100,9 +2199,8 @@ assert_connection_ok(connection_t *conn, time_t now)
*/
#endif
- if (conn->type != CONN_TYPE_OR) {
- tor_assert(!conn->tls);
- } else {
+ if (conn->type == CONN_TYPE_OR) {
+ or_connection_t *or_conn = TO_OR_CONN(conn);
if (conn->state == OR_CONN_STATE_OPEN) {
/* tor_assert(conn->bandwidth > 0); */
/* the above isn't necessarily true: if we just did a TLS
@@ -2115,42 +2213,30 @@ assert_connection_ok(connection_t *conn, time_t now)
// tor_assert(conn->addr && conn->port);
tor_assert(conn->address);
if (conn->state > OR_CONN_STATE_PROXY_READING)
- tor_assert(conn->tls);
+ tor_assert(or_conn->tls);
}
- if (! CONN_IS_EDGE(conn)) {
- tor_assert(!conn->stream_id);
- tor_assert(!conn->next_stream);
- tor_assert(!conn->cpath_layer);
- tor_assert(!conn->package_window);
- tor_assert(!conn->deliver_window);
-#if 0
- tor_assert(!conn->done_sending);
- tor_assert(!conn->done_receiving);
-#endif
- } else {
+ if (CONN_IS_EDGE(conn)) {
+ edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
/* XXX unchecked: package window, deliver window. */
- }
- if (conn->type == CONN_TYPE_AP) {
- tor_assert(conn->socks_request);
- if (conn->state == AP_CONN_STATE_OPEN) {
- tor_assert(conn->socks_request->has_finished);
- if (!conn->marked_for_close) {
- tor_assert(conn->cpath_layer);
- assert_cpath_layer_ok(conn->cpath_layer);
+ if (conn->type == CONN_TYPE_AP) {
+
+ tor_assert(edge_conn->socks_request);
+ if (conn->state == AP_CONN_STATE_OPEN) {
+ tor_assert(edge_conn->socks_request->has_finished);
+ if (!conn->marked_for_close) {
+ tor_assert(edge_conn->cpath_layer);
+ assert_cpath_layer_ok(edge_conn->cpath_layer);
+ }
}
}
- } else {
- tor_assert(!conn->socks_request);
- }
- if (conn->type == CONN_TYPE_EXIT) {
- tor_assert(conn->purpose == EXIT_PURPOSE_CONNECT ||
- conn->purpose == EXIT_PURPOSE_RESOLVE);
- } else if (conn->type != CONN_TYPE_DIR) {
- tor_assert(!conn->purpose); /* only used for dir types currently */
+ if (conn->type == CONN_TYPE_EXIT) {
+ tor_assert(conn->purpose == EXIT_PURPOSE_CONNECT ||
+ conn->purpose == EXIT_PURPOSE_RESOLVE);
+ }
}
if (conn->type != CONN_TYPE_DIR) {
- tor_assert(!conn->requested_resource);
+ tor_assert(!conn->purpose); /* only used for dir types currently */
}
switch (conn->type)
@@ -2164,7 +2250,7 @@ assert_connection_ok(connection_t *conn, time_t now)
case CONN_TYPE_OR:
tor_assert(conn->state >= _OR_CONN_STATE_MIN);
tor_assert(conn->state <= _OR_CONN_STATE_MAX);
- tor_assert(conn->n_circuits >= 0);
+ tor_assert(TO_OR_CONN(conn)->n_circuits >= 0);
break;
case CONN_TYPE_EXIT:
tor_assert(conn->state >= _EXIT_CONN_STATE_MIN);
@@ -2175,7 +2261,7 @@ assert_connection_ok(connection_t *conn, time_t now)
case CONN_TYPE_AP:
tor_assert(conn->state >= _AP_CONN_STATE_MIN);
tor_assert(conn->state <= _AP_CONN_STATE_MAX);
- tor_assert(conn->socks_request);
+ tor_assert(TO_EDGE_CONN(conn)->socks_request);
break;
case CONN_TYPE_DIR:
tor_assert(conn->state >= _DIR_CONN_STATE_MIN);
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 10284723d4..a70ad9a6ff 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -16,22 +16,22 @@ const char connection_edge_c_id[] =
/* List of exit_redirect_t */
static smartlist_t *redirect_exit_list = NULL;
-static int connection_ap_handshake_process_socks(connection_t *conn);
+static int connection_ap_handshake_process_socks(edge_connection_t *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
* has_sent_end to 1, and mark the conn.
*/
void
-_connection_mark_unattached_ap(connection_t *conn, int endreason,
+_connection_mark_unattached_ap(edge_connection_t *conn, int endreason,
int line, const char *file)
{
- tor_assert(conn->type == CONN_TYPE_AP);
- conn->has_sent_end = 1; /* no circ yet */
+ tor_assert(conn->_base.type == CONN_TYPE_AP);
+ conn->_base.edge_has_sent_end = 1; /* no circ yet */
- if (conn->marked_for_close) {
+ if (conn->_base.marked_for_close) {
/* This call will warn as appropriate. */
- _connection_mark_for_close(conn, line, file);
+ _connection_mark_for_close(TO_CONN(conn), line, file);
return;
}
@@ -51,27 +51,28 @@ _connection_mark_unattached_ap(connection_t *conn, int endreason,
0, NULL, -1);
}
- _connection_mark_for_close(conn, line, file);
- conn->hold_open_until_flushed = 1;
+ _connection_mark_for_close(TO_CONN(conn), line, file);
+ conn->_base.hold_open_until_flushed = 1;
}
/** There was an EOF. Send an end and mark the connection for close.
*/
int
-connection_edge_reached_eof(connection_t *conn)
+connection_edge_reached_eof(edge_connection_t *conn)
{
- if (buf_datalen(conn->inbuf) && connection_state_is_open(conn)) {
+ if (buf_datalen(conn->_base.inbuf) &&
+ connection_state_is_open(TO_CONN(conn))) {
/* it still has stuff to process. don't let it die yet. */
return 0;
}
- log_info(LD_EDGE,"conn (fd %d) reached eof. Closing.", conn->s);
- if (!conn->marked_for_close) {
+ log_info(LD_EDGE,"conn (fd %d) reached eof. Closing.", conn->_base.s);
+ if (!conn->_base.marked_for_close) {
/* only mark it if not already marked. it's possible to
* get the 'end' right around when the client hangs up on us. */
connection_edge_end(conn, END_STREAM_REASON_DONE, conn->cpath_layer);
if (conn->socks_request) /* eof, so don't send a socks reply back */
conn->socks_request->has_finished = 1;
- connection_mark_for_close(conn);
+ connection_mark_for_close(TO_CONN(conn));
}
return 0;
}
@@ -86,12 +87,11 @@ connection_edge_reached_eof(connection_t *conn)
* else return 0.
*/
int
-connection_edge_process_inbuf(connection_t *conn, int package_partial)
+connection_edge_process_inbuf(edge_connection_t *conn, int package_partial)
{
tor_assert(conn);
- tor_assert(CONN_IS_EDGE(conn));
- switch (conn->state) {
+ switch (conn->_base.state) {
case AP_CONN_STATE_SOCKS_WAIT:
if (connection_ap_handshake_process_socks(conn) < 0) {
/* already marked */
@@ -102,7 +102,7 @@ connection_edge_process_inbuf(connection_t *conn, int package_partial)
case EXIT_CONN_STATE_OPEN:
if (connection_edge_package_raw_inbuf(conn, package_partial) < 0) {
/* (We already sent an end cell if possible) */
- connection_mark_for_close(conn);
+ connection_mark_for_close(TO_CONN(conn));
return -1;
}
return 0;
@@ -114,13 +114,13 @@ connection_edge_process_inbuf(connection_t *conn, int package_partial)
case AP_CONN_STATE_CONTROLLER_WAIT:
log_info(LD_EDGE,
"data from edge while in '%s' state. Leaving it on buffer.",
- conn_state_to_string(conn->type, conn->state));
+ conn_state_to_string(conn->_base.type, conn->_base.state));
return 0;
}
- log_warn(LD_BUG,"Bug: Got unexpected state %d. Closing.",conn->state);
+ log_warn(LD_BUG,"Bug: Got unexpected state %d. Closing.",conn->_base.state);
tor_fragile_assert();
connection_edge_end(conn, END_STREAM_REASON_INTERNAL, conn->cpath_layer);
- connection_mark_for_close(conn);
+ connection_mark_for_close(TO_CONN(conn));
return -1;
}
@@ -128,19 +128,17 @@ connection_edge_process_inbuf(connection_t *conn, int package_partial)
* Mark it for close and return 0.
*/
int
-connection_edge_destroy(uint16_t circ_id, connection_t *conn)
+connection_edge_destroy(uint16_t circ_id, edge_connection_t *conn)
{
- tor_assert(CONN_IS_EDGE(conn));
-
- if (!conn->marked_for_close) {
+ if (!conn->_base.marked_for_close) {
log_info(LD_EDGE,
"CircID %d: At an edge. Marking connection for close.", circ_id);
- if (conn->type == CONN_TYPE_AP) {
+ if (conn->_base.type == CONN_TYPE_AP) {
connection_mark_unattached_ap(conn, END_STREAM_REASON_DESTROY);
} else {
- conn->has_sent_end = 1; /* closing the circuit, nothing to send to */
- connection_mark_for_close(conn);
- conn->hold_open_until_flushed = 1;
+ conn->_base.edge_has_sent_end = 1; /* closing the circuit, nothing to send to */
+ connection_mark_for_close(TO_CONN(conn));
+ conn->_base.hold_open_until_flushed = 1;
}
}
conn->cpath_layer = NULL;
@@ -157,44 +155,46 @@ connection_edge_destroy(uint16_t circ_id, connection_t *conn)
* else return 0.
*/
int
-connection_edge_end(connection_t *conn, char reason, crypt_path_t *cpath_layer)
+connection_edge_end(edge_connection_t *conn, char reason,
+ crypt_path_t *cpath_layer)
{
char payload[RELAY_PAYLOAD_SIZE];
size_t payload_len=1;
circuit_t *circ;
- if (conn->has_sent_end) {
+ if (conn->_base.edge_has_sent_end) {
log_warn(LD_BUG,"Harmless bug: Calling connection_edge_end (reason %d) "
"on an already ended stream?", reason);
tor_fragile_assert();
return -1;
}
- if (conn->marked_for_close) {
+ if (conn->_base.marked_for_close) {
log_warn(LD_BUG,
"Bug: called on conn that's already marked for close at %s:%d.",
- conn->marked_for_close_file, conn->marked_for_close);
+ conn->_base.marked_for_close_file, conn->_base.marked_for_close);
return 0;
}
payload[0] = reason;
if (reason == END_STREAM_REASON_EXITPOLICY &&
!connection_edge_is_rendezvous_stream(conn)) {
- set_uint32(payload+1, htonl(conn->addr));
+ set_uint32(payload+1, htonl(conn->_base.addr));
set_uint32(payload+5, htonl(dns_clip_ttl(conn->address_ttl)));
payload_len += 8;
}
circ = circuit_get_by_edge_conn(conn);
if (circ && !circ->marked_for_close) {
- log_debug(LD_EDGE,"Marking conn (fd %d) and sending end.",conn->s);
+ log_debug(LD_EDGE,"Marking conn (fd %d) and sending end.",conn->_base.s);
connection_edge_send_command(conn, circ, RELAY_COMMAND_END,
payload, payload_len, cpath_layer);
} else {
- log_debug(LD_EDGE,"Marking conn (fd %d); no circ to send end.",conn->s);
+ log_debug(LD_EDGE,"Marking conn (fd %d); no circ to send end.",
+ conn->_base.s);
}
- conn->has_sent_end = 1;
+ conn->_base.edge_has_sent_end = 1;
return 0;
}
@@ -203,11 +203,11 @@ connection_edge_end(connection_t *conn, char reason, crypt_path_t *cpath_layer)
* an appropriate relay end cell to <b>cpath_layer</b>.
**/
int
-connection_edge_end_errno(connection_t *conn, crypt_path_t *cpath_layer)
+connection_edge_end_errno(edge_connection_t *conn, crypt_path_t *cpath_layer)
{
uint8_t reason;
tor_assert(conn);
- reason = (uint8_t)errno_to_end_reason(tor_socket_errno(conn->s));
+ reason = (uint8_t)errno_to_end_reason(tor_socket_errno(conn->_base.s));
return connection_edge_end(conn, reason, cpath_layer);
}
@@ -222,15 +222,14 @@ connection_edge_end_errno(connection_t *conn, crypt_path_t *cpath_layer)
* return 0.
*/
int
-connection_edge_finished_flushing(connection_t *conn)
+connection_edge_finished_flushing(edge_connection_t *conn)
{
tor_assert(conn);
- tor_assert(CONN_IS_EDGE(conn));
- switch (conn->state) {
+ switch (conn->_base.state) {
case AP_CONN_STATE_OPEN:
case EXIT_CONN_STATE_OPEN:
- connection_stop_writing(conn);
+ connection_stop_writing(TO_CONN(conn));
connection_edge_consider_sending_sendme(conn);
return 0;
case AP_CONN_STATE_SOCKS_WAIT:
@@ -238,10 +237,10 @@ connection_edge_finished_flushing(connection_t *conn)
case AP_CONN_STATE_CIRCUIT_WAIT:
case AP_CONN_STATE_CONNECT_WAIT:
case AP_CONN_STATE_CONTROLLER_WAIT:
- connection_stop_writing(conn);
+ connection_stop_writing(TO_CONN(conn));
return 0;
default:
- log_warn(LD_BUG,"BUG: called in unexpected state %d.", conn->state);
+ log_warn(LD_BUG,"BUG: called in unexpected state %d.", conn->_base.state);
tor_fragile_assert();
return -1;
}
@@ -252,13 +251,15 @@ connection_edge_finished_flushing(connection_t *conn)
* data, deliver 'CONNECTED' relay cells as appropriate, and check
* any pending data that may have been received. */
int
-connection_edge_finished_connecting(connection_t *conn)
+connection_edge_finished_connecting(edge_connection_t *edge_conn)
{
char valbuf[INET_NTOA_BUF_LEN];
+ connection_t *conn;
struct in_addr in;
- tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_EXIT);
+ tor_assert(edge_conn);
+ tor_assert(edge_conn->_base.type == CONN_TYPE_EXIT);
+ conn = TO_CONN(edge_conn);
tor_assert(conn->state == EXIT_CONN_STATE_CONNECTING);
in.s_addr = htonl(conn->addr);
@@ -272,23 +273,27 @@ connection_edge_finished_connecting(connection_t *conn)
* cells */
connection_start_writing(conn);
/* deliver a 'connected' relay cell back through the circuit. */
- if (connection_edge_is_rendezvous_stream(conn)) {
- if (connection_edge_send_command(conn, circuit_get_by_edge_conn(conn),
+ if (connection_edge_is_rendezvous_stream(edge_conn)) {
+ if (connection_edge_send_command(edge_conn,
+ circuit_get_by_edge_conn(edge_conn),
RELAY_COMMAND_CONNECTED, NULL, 0,
- conn->cpath_layer) < 0)
+ edge_conn->cpath_layer) < 0)
return 0; /* circuit is closed, don't continue */
} else {
char connected_payload[8];
set_uint32(connected_payload, htonl(conn->addr));
set_uint32(connected_payload+4,
- htonl(dns_clip_ttl(conn->address_ttl)));
- if (connection_edge_send_command(conn, circuit_get_by_edge_conn(conn),
- RELAY_COMMAND_CONNECTED, connected_payload, 8, conn->cpath_layer) < 0)
+ htonl(dns_clip_ttl(edge_conn->address_ttl)));
+ if (connection_edge_send_command(edge_conn,
+ circuit_get_by_edge_conn(edge_conn),
+ RELAY_COMMAND_CONNECTED,
+ connected_payload, 8,
+ edge_conn->cpath_layer) < 0)
return 0; /* circuit is closed, don't continue */
}
- tor_assert(conn->package_window > 0);
+ tor_assert(edge_conn->package_window > 0);
/* in case the server has written anything */
- return connection_edge_process_inbuf(conn, 1);
+ return connection_edge_process_inbuf(edge_conn, 1);
}
/** Define a schedule for how long to wait between retrying
@@ -297,7 +302,7 @@ connection_edge_finished_connecting(connection_t *conn)
* 10 seconds for the second, and 15 seconds for each retry after
* that. Hopefully this will improve the expected experience. */
static int
-compute_socks_timeout(connection_t *conn)
+compute_socks_timeout(edge_connection_t *conn)
{
if (conn->num_socks_retries == 0)
return 5;
@@ -319,7 +324,7 @@ void
connection_ap_expire_beginning(void)
{
connection_t **carray;
- connection_t *conn;
+ edge_connection_t *conn;
circuit_t *circ;
const char *nickname;
int n, i;
@@ -331,24 +336,24 @@ connection_ap_expire_beginning(void)
get_connection_array(&carray, &n);
for (i = 0; i < n; ++i) {
- conn = carray[i];
- if (conn->type != CONN_TYPE_AP)
+ if (carray[i]->type != CONN_TYPE_AP)
continue;
+ conn = TO_EDGE_CONN(carray[i]);
/* if it's an internal bridge connection, don't yell its status. */
- severity = (!conn->addr && !conn->port) ? LOG_INFO : LOG_NOTICE;
- if (conn->state == AP_CONN_STATE_CONTROLLER_WAIT) {
- if (now - conn->timestamp_lastread >= options->SocksTimeout) {
+ severity = (!conn->_base.addr && !conn->_base.port) ? LOG_INFO : LOG_NOTICE;
+ if (conn->_base.state == AP_CONN_STATE_CONTROLLER_WAIT) {
+ if (now - conn->_base.timestamp_lastread >= options->SocksTimeout) {
log_fn(severity, LD_APP, "Closing unattached stream.");
connection_mark_unattached_ap(conn, END_STREAM_REASON_TIMEOUT);
}
continue;
}
- if (conn->state != AP_CONN_STATE_RESOLVE_WAIT &&
- conn->state != AP_CONN_STATE_CONNECT_WAIT)
+ if (conn->_base.state != AP_CONN_STATE_RESOLVE_WAIT &&
+ conn->_base.state != AP_CONN_STATE_CONNECT_WAIT)
continue;
cutoff = compute_socks_timeout(conn);
- if (now - conn->timestamp_lastread < cutoff)
+ if (now - conn->_base.timestamp_lastread < cutoff)
continue;
circ = circuit_get_by_edge_conn(conn);
if (!circ) { /* it's vanished? */
@@ -358,11 +363,11 @@ connection_ap_expire_beginning(void)
continue;
}
if (circ->purpose == CIRCUIT_PURPOSE_C_REND_JOINED) {
- if (now - conn->timestamp_lastread > options->SocksTimeout) {
+ if (now - conn->_base.timestamp_lastread > options->SocksTimeout) {
log_fn(severity, LD_REND,
"Rend stream is %d seconds late. Giving up on address"
" '%s.onion'.",
- (int)(now - conn->timestamp_lastread),
+ (int)(now - conn->_base.timestamp_lastread),
safe_str(conn->socks_request->address));
connection_edge_end(conn, END_STREAM_REASON_TIMEOUT,
conn->cpath_layer);
@@ -376,20 +381,20 @@ connection_ap_expire_beginning(void)
log_fn(cutoff < 15 ? LOG_INFO : severity, LD_APP,
"We tried for %d seconds to connect to '%s' using exit '%s'."
" Retrying on a new circuit.",
- (int)(now - conn->timestamp_lastread),
+ (int)(now - conn->_base.timestamp_lastread),
safe_str(conn->socks_request->address),
nickname ? nickname : "*unnamed*");
/* send an end down the circuit */
connection_edge_end(conn, END_STREAM_REASON_TIMEOUT, conn->cpath_layer);
/* un-mark it as ending, since we're going to reuse it */
- conn->has_sent_end = 0;
+ conn->_base.edge_has_sent_end = 0;
/* kludge to make us not try this circuit again, yet to allow
* current streams on it to survive if they can: make it
* unattractive to use for new streams */
tor_assert(circ->timestamp_dirty);
circ->timestamp_dirty -= options->MaxCircuitDirtiness;
/* give our stream another 'cutoff' seconds to try */
- conn->timestamp_lastread += cutoff;
+ conn->_base.timestamp_lastread += cutoff;
conn->num_socks_retries++;
/* move it back into 'pending' state, and try to attach. */
if (connection_ap_detach_retriable(conn, TO_ORIGIN_CIRCUIT(circ))<0) {
@@ -406,6 +411,7 @@ connection_ap_attach_pending(void)
{
connection_t **carray;
connection_t *conn;
+ edge_connection_t *edge_conn;
int n, i;
get_connection_array(&carray, &n);
@@ -416,8 +422,9 @@ connection_ap_attach_pending(void)
conn->type != CONN_TYPE_AP ||
conn->state != AP_CONN_STATE_CIRCUIT_WAIT)
continue;
- if (connection_ap_handshake_attach_circuit(conn) < 0) {
- connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
+ edge_conn = TO_EDGE_CONN(conn);
+ if (connection_ap_handshake_attach_circuit(edge_conn) < 0) {
+ connection_mark_unattached_ap(edge_conn, END_STREAM_REASON_CANT_ATTACH);
}
}
}
@@ -430,16 +437,16 @@ connection_ap_attach_pending(void)
* Returns -1 on err, 1 on success, 0 on not-yet-sure.
*/
int
-connection_ap_detach_retriable(connection_t *conn, origin_circuit_t *circ)
+connection_ap_detach_retriable(edge_connection_t *conn, origin_circuit_t *circ)
{
control_event_stream_status(conn, STREAM_EVENT_FAILED_RETRIABLE);
- conn->timestamp_lastread = time(NULL);
+ conn->_base.timestamp_lastread = time(NULL);
if (! get_options()->LeaveStreamsUnattached) {
- conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
+ conn->_base.state = AP_CONN_STATE_CIRCUIT_WAIT;
circuit_detach_stream(TO_CIRCUIT(circ),conn);
return connection_ap_handshake_attach_circuit(conn);
} else {
- conn->state = AP_CONN_STATE_CONTROLLER_WAIT;
+ conn->_base.state = AP_CONN_STATE_CONTROLLER_WAIT;
circuit_detach_stream(TO_CIRCUIT(circ),conn);
return 0;
}
@@ -1011,7 +1018,7 @@ addressmap_get_mappings(smartlist_t *sl, time_t min_expires,
* rendezvous descriptor is already here and fresh enough).
*/
int
-connection_ap_handshake_rewrite_and_attach(connection_t *conn,
+connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
origin_circuit_t *circ)
{
socks_request_t *socks = conn->socks_request;
@@ -1137,7 +1144,7 @@ connection_ap_handshake_rewrite_and_attach(connection_t *conn,
/* help predict this next time */
rep_hist_note_used_port(socks->port, time(NULL));
}
- conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
+ conn->_base.state = AP_CONN_STATE_CIRCUIT_WAIT;
if ((circ &&
connection_ap_handshake_attach_chosen_circuit(conn, circ) < 0) ||
(!circ &&
@@ -1182,21 +1189,21 @@ connection_ap_handshake_rewrite_and_attach(connection_t *conn,
return -1;
}
if (r==0) {
- conn->state = AP_CONN_STATE_RENDDESC_WAIT;
+ conn->_base.state = AP_CONN_STATE_RENDDESC_WAIT;
log_info(LD_REND, "Unknown descriptor %s. Fetching.",
safe_str(conn->rend_query));
rend_client_refetch_renddesc(conn->rend_query);
} else { /* r > 0 */
#define NUM_SECONDS_BEFORE_REFETCH (60*15)
if (time(NULL) - entry->received < NUM_SECONDS_BEFORE_REFETCH) {
- conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
+ conn->_base.state = AP_CONN_STATE_CIRCUIT_WAIT;
log_info(LD_REND, "Descriptor is here and fresh enough. Great.");
if (connection_ap_handshake_attach_circuit(conn) < 0) {
connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
return -1;
}
} else {
- conn->state = AP_CONN_STATE_RENDDESC_WAIT;
+ conn->_base.state = AP_CONN_STATE_RENDDESC_WAIT;
log_info(LD_REND, "Stale descriptor %s. Refetching.",
safe_str(conn->rend_query));
rend_client_refetch_renddesc(conn->rend_query);
@@ -1218,25 +1225,25 @@ connection_ap_handshake_rewrite_and_attach(connection_t *conn,
* for close), else return 0.
*/
static int
-connection_ap_handshake_process_socks(connection_t *conn)
+connection_ap_handshake_process_socks(edge_connection_t *conn)
{
socks_request_t *socks;
int sockshere;
or_options_t *options = get_options();
tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_AP);
- tor_assert(conn->state == AP_CONN_STATE_SOCKS_WAIT);
+ tor_assert(conn->_base.type == CONN_TYPE_AP);
+ tor_assert(conn->_base.state == AP_CONN_STATE_SOCKS_WAIT);
tor_assert(conn->socks_request);
socks = conn->socks_request;
log_debug(LD_APP,"entered.");
- sockshere = fetch_from_buf_socks(conn->inbuf, socks,
+ sockshere = fetch_from_buf_socks(conn->_base.inbuf, socks,
options->TestSocks, options->SafeSocks);
if (sockshere == 0) {
if (socks->replylen) {
- connection_write_to_buf(socks->reply, socks->replylen, conn);
+ connection_write_to_buf(socks->reply, socks->replylen, TO_CONN(conn));
/* zero it out so we can do another round of negotiation */
socks->replylen = 0;
} else {
@@ -1263,7 +1270,7 @@ connection_ap_handshake_process_socks(connection_t *conn)
control_event_stream_status(conn, STREAM_EVENT_NEW_RESOLVE);
if (options->LeaveStreamsUnattached) {
- conn->state = AP_CONN_STATE_CONTROLLER_WAIT;
+ conn->_base.state = AP_CONN_STATE_CONTROLLER_WAIT;
return 0;
}
return connection_ap_handshake_rewrite_and_attach(conn, NULL);
@@ -1275,7 +1282,7 @@ connection_ap_handshake_process_socks(connection_t *conn)
static uint16_t
get_unique_stream_id_by_circ(origin_circuit_t *circ)
{
- connection_t *tmpconn;
+ edge_connection_t *tmpconn;
uint16_t test_stream_id;
uint32_t attempts=0;
@@ -1300,14 +1307,14 @@ again:
* If ap_conn is broken, mark it for close and return -1. Else return 0.
*/
int
-connection_ap_handshake_send_begin(connection_t *ap_conn,
+connection_ap_handshake_send_begin(edge_connection_t *ap_conn,
origin_circuit_t *circ)
{
char payload[CELL_PAYLOAD_SIZE];
int payload_len;
- tor_assert(ap_conn->type == CONN_TYPE_AP);
- tor_assert(ap_conn->state == AP_CONN_STATE_CIRCUIT_WAIT);
+ tor_assert(ap_conn->_base.type == CONN_TYPE_AP);
+ tor_assert(ap_conn->_base.state == AP_CONN_STATE_CIRCUIT_WAIT);
tor_assert(ap_conn->socks_request);
ap_conn->stream_id = get_unique_stream_id_by_circ(circ);
@@ -1334,9 +1341,9 @@ connection_ap_handshake_send_begin(connection_t *ap_conn,
ap_conn->package_window = STREAMWINDOW_START;
ap_conn->deliver_window = STREAMWINDOW_START;
- ap_conn->state = AP_CONN_STATE_CONNECT_WAIT;
+ ap_conn->_base.state = AP_CONN_STATE_CONNECT_WAIT;
log_info(LD_APP,"Address/port sent, ap socket %d, n_circ_id %d",
- ap_conn->s, circ->_base.n_circ_id);
+ ap_conn->_base.s, circ->_base.n_circ_id);
control_event_stream_status(ap_conn, STREAM_EVENT_SENT_CONNECT);
return 0;
}
@@ -1347,14 +1354,14 @@ connection_ap_handshake_send_begin(connection_t *ap_conn,
* If ap_conn is broken, mark it for close and return -1. Else return 0.
*/
int
-connection_ap_handshake_send_resolve(connection_t *ap_conn,
+connection_ap_handshake_send_resolve(edge_connection_t *ap_conn,
origin_circuit_t *circ)
{
int payload_len;
const char *string_addr;
- tor_assert(ap_conn->type == CONN_TYPE_AP);
- tor_assert(ap_conn->state == AP_CONN_STATE_CIRCUIT_WAIT);
+ tor_assert(ap_conn->_base.type == CONN_TYPE_AP);
+ tor_assert(ap_conn->_base.state == AP_CONN_STATE_CIRCUIT_WAIT);
tor_assert(ap_conn->socks_request);
tor_assert(ap_conn->socks_request->command == SOCKS_COMMAND_RESOLVE);
tor_assert(circ->_base.purpose == CIRCUIT_PURPOSE_C_GENERAL);
@@ -1378,9 +1385,9 @@ connection_ap_handshake_send_resolve(connection_t *ap_conn,
string_addr, payload_len, ap_conn->cpath_layer) < 0)
return -1; /* circuit is closed, don't continue */
- ap_conn->state = AP_CONN_STATE_RESOLVE_WAIT;
+ ap_conn->_base.state = AP_CONN_STATE_RESOLVE_WAIT;
log_info(LD_APP,"Address sent for resolve, ap socket %d, n_circ_id %d",
- ap_conn->s, circ->_base.n_circ_id);
+ ap_conn->_base.s, circ->_base.n_circ_id);
control_event_stream_status(ap_conn, STREAM_EVENT_SENT_RESOLVE);
return 0;
}
@@ -1395,7 +1402,7 @@ int
connection_ap_make_bridge(char *address, uint16_t port)
{
int fd[2];
- connection_t *conn;
+ edge_connection_t *conn;
int err;
log_info(LD_APP,"Making AP bridge to %s:%d ...",safe_str(address),port);
@@ -1413,8 +1420,8 @@ connection_ap_make_bridge(char *address, uint16_t port)
set_socket_nonblocking(fd[0]);
set_socket_nonblocking(fd[1]);
- conn = connection_new(CONN_TYPE_AP);
- conn->s = fd[0];
+ conn = TO_EDGE_CONN(connection_new(CONN_TYPE_AP));
+ conn->_base.s = fd[0];
/* populate conn->socks_request */
@@ -1426,18 +1433,18 @@ connection_ap_make_bridge(char *address, uint16_t port)
conn->socks_request->port = port;
conn->socks_request->command = SOCKS_COMMAND_CONNECT;
- conn->address = tor_strdup("(local bridge)");
- conn->addr = 0;
- conn->port = 0;
+ conn->_base.address = tor_strdup("(local bridge)");
+ conn->_base.addr = 0;
+ conn->_base.port = 0;
- if (connection_add(conn) < 0) { /* no space, forget it */
- connection_free(conn); /* this closes fd[0] */
+ if (connection_add(TO_CONN(conn)) < 0) { /* no space, forget it */
+ connection_free(TO_CONN(conn)); /* this closes fd[0] */
tor_close_socket(fd[1]);
return -1;
}
- conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
- connection_start_reading(conn);
+ conn->_base.state = AP_CONN_STATE_CIRCUIT_WAIT;
+ connection_start_reading(TO_CONN(conn));
/* attaching to a dirty circuit is fine */
if (connection_ap_handshake_attach_circuit(conn) < 0) {
@@ -1456,7 +1463,7 @@ connection_ap_make_bridge(char *address, uint16_t port)
* in the socks extensions document.
**/
void
-connection_ap_handshake_socks_resolved(connection_t *conn,
+connection_ap_handshake_socks_resolved(edge_connection_t *conn,
int answer_type,
size_t answer_len,
const char *answer,
@@ -1523,7 +1530,7 @@ connection_ap_handshake_socks_resolved(connection_t *conn,
* If <b>reply</b> is undefined, <b>status</b> can't be 0.
*/
void
-connection_ap_handshake_socks_reply(connection_t *conn, char *reply,
+connection_ap_handshake_socks_reply(edge_connection_t *conn, char *reply,
size_t replylen,
socks5_reply_status_t status) {
char buf[256];
@@ -1538,7 +1545,7 @@ connection_ap_handshake_socks_reply(connection_t *conn, char *reply,
return;
}
if (replylen) { /* we already have a reply in mind */
- connection_write_to_buf(reply, replylen, conn);
+ connection_write_to_buf(reply, replylen, TO_CONN(conn));
conn->socks_request->has_finished = 1;
return;
}
@@ -1548,7 +1555,7 @@ connection_ap_handshake_socks_reply(connection_t *conn, char *reply,
#define SOCKS4_REJECT 91
buf[1] = (status==SOCKS5_SUCCEEDED ? SOCKS4_GRANTED : SOCKS4_REJECT);
/* leave version, destport, destip zero */
- connection_write_to_buf(buf, SOCKS4_NETWORK_LEN, conn);
+ connection_write_to_buf(buf, SOCKS4_NETWORK_LEN, TO_CONN(conn));
} else if (conn->socks_request->socks_version == 5) {
buf[0] = 5; /* version 5 */
buf[1] = (char)status;
@@ -1556,7 +1563,7 @@ connection_ap_handshake_socks_reply(connection_t *conn, char *reply,
buf[3] = 1; /* ipv4 addr */
memset(buf+4,0,6); /* Set external addr/port to 0.
The spec doesn't seem to say what to do here. -RD */
- connection_write_to_buf(buf,10,conn);
+ connection_write_to_buf(buf,10,TO_CONN(conn));
}
/* If socks_version isn't 4 or 5, don't send anything.
* This can happen in the case of AP bridges. */
@@ -1583,7 +1590,7 @@ connection_ap_handshake_socks_reply(connection_t *conn, char *reply,
int
connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
{
- connection_t *n_stream;
+ edge_connection_t *n_stream;
relay_header_t rh;
char *address=NULL;
uint16_t port;
@@ -1623,11 +1630,11 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
#endif
log_debug(LD_EXIT,"Creating new exit connection.");
- n_stream = connection_new(CONN_TYPE_EXIT);
- n_stream->purpose = EXIT_PURPOSE_CONNECT;
+ n_stream = TO_EDGE_CONN(connection_new(CONN_TYPE_EXIT));
+ n_stream->_base.purpose = EXIT_PURPOSE_CONNECT;
n_stream->stream_id = rh.stream_id;
- n_stream->port = port;
+ n_stream->_base.port = port;
/* leave n_stream->s at -1, because it's not yet valid */
n_stream->package_window = STREAMWINDOW_START;
n_stream->deliver_window = STREAMWINDOW_START;
@@ -1635,18 +1642,18 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
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.");
- n_stream->address = tor_strdup("(rendezvous)");
- n_stream->state = EXIT_CONN_STATE_CONNECTING;
+ n_stream->_base.address = tor_strdup("(rendezvous)");
+ n_stream->_base.state = EXIT_CONN_STATE_CONNECTING;
strlcpy(n_stream->rend_query, origin_circ->rend_query,
sizeof(n_stream->rend_query));
tor_assert(connection_edge_is_rendezvous_stream(n_stream));
assert_circuit_ok(circ);
if (rend_service_set_connection_addr_port(n_stream, origin_circ) < 0) {
log_info(LD_REND,"Didn't find rendezvous service (port %d)",
- n_stream->port);
+ n_stream->_base.port);
connection_edge_end(n_stream, END_STREAM_REASON_EXITPOLICY,
n_stream->cpath_layer);
- connection_free(n_stream);
+ connection_free(TO_CONN(n_stream));
/* knock the whole thing down, somebody screwed up */
circuit_mark_for_close(circ, END_CIRC_REASON_CONNECTFAILED);
tor_free(address);
@@ -1667,14 +1674,14 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
return 0;
}
tor_strlower(address);
- n_stream->address = address;
- n_stream->state = EXIT_CONN_STATE_RESOLVEFAILED;
+ n_stream->_base.address = address;
+ n_stream->_base.state = EXIT_CONN_STATE_RESOLVEFAILED;
/* default to failed, change in dns_resolve if it turns out not to fail */
if (we_are_hibernating()) {
connection_edge_end(n_stream, END_STREAM_REASON_HIBERNATING,
n_stream->cpath_layer);
- connection_free(n_stream);
+ connection_free(TO_CONN(n_stream));
return 0;
}
log_debug(LD_EXIT,"about to start the dns_resolve().");
@@ -1713,7 +1720,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
int
connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ)
{
- connection_t *dummy_conn;
+ edge_connection_t *dummy_conn;
relay_header_t rh;
assert_circuit_ok(TO_CIRCUIT(circ));
@@ -1726,13 +1733,13 @@ connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ)
* resolved; but if we didn't store them in a connection like this,
* the housekeeping in dns.c would get way more complicated.)
*/
- dummy_conn = connection_new(CONN_TYPE_EXIT);
+ dummy_conn = TO_EDGE_CONN(connection_new(CONN_TYPE_EXIT));
dummy_conn->stream_id = rh.stream_id;
- dummy_conn->address = tor_strndup(cell->payload+RELAY_HEADER_SIZE,
- rh.length);
- dummy_conn->port = 0;
- dummy_conn->state = EXIT_CONN_STATE_RESOLVEFAILED;
- dummy_conn->purpose = EXIT_PURPOSE_RESOLVE;
+ dummy_conn->_base.address = tor_strndup(cell->payload+RELAY_HEADER_SIZE,
+ rh.length);
+ dummy_conn->_base.port = 0;
+ dummy_conn->_base.state = EXIT_CONN_STATE_RESOLVEFAILED;
+ dummy_conn->_base.purpose = EXIT_PURPOSE_RESOLVE;
/* send it off to the gethostbyname farm */
switch (dns_resolve(dummy_conn)) {
@@ -1740,8 +1747,8 @@ connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ)
/* Connection freed; don't touch it. */
return 0;
case 1: /* The result was cached; a resolved cell was sent. */
- if (!dummy_conn->marked_for_close)
- connection_free(dummy_conn);
+ if (!dummy_conn->_base.marked_for_close)
+ connection_free(TO_CONN(dummy_conn));
return 0;
case 0: /* resolve added to pending list */
dummy_conn->next_stream = circ->resolving_streams;
@@ -1761,17 +1768,19 @@ connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ)
* streams must not reveal what IP they connected to.)
*/
void
-connection_exit_connect(connection_t *conn)
+connection_exit_connect(edge_connection_t *edge_conn)
{
uint32_t addr;
uint16_t port;
+ connection_t *conn = TO_CONN(edge_conn);
- if (!connection_edge_is_rendezvous_stream(conn) &&
- router_compare_to_my_exit_policy(conn)) {
+ if (!connection_edge_is_rendezvous_stream(edge_conn) &&
+ router_compare_to_my_exit_policy(edge_conn)) {
log_info(LD_EXIT,"%s:%d failed exit policy. Closing.",
escaped_safe_str(conn->address), conn->port);
- connection_edge_end(conn, END_STREAM_REASON_EXITPOLICY, conn->cpath_layer);
- circuit_detach_stream(circuit_get_by_edge_conn(conn), conn);
+ connection_edge_end(edge_conn, END_STREAM_REASON_EXITPOLICY,
+ edge_conn->cpath_layer);
+ circuit_detach_stream(circuit_get_by_edge_conn(edge_conn), edge_conn);
connection_free(conn);
return;
}
@@ -1802,8 +1811,8 @@ connection_exit_connect(connection_t *conn)
log_debug(LD_EXIT,"about to try connecting");
switch (connection_connect(conn, conn->address, addr, port)) {
case -1:
- connection_edge_end_errno(conn, conn->cpath_layer);
- circuit_detach_stream(circuit_get_by_edge_conn(conn), conn);
+ connection_edge_end_errno(edge_conn, edge_conn->cpath_layer);
+ circuit_detach_stream(circuit_get_by_edge_conn(edge_conn), edge_conn);
connection_free(conn);
return;
case 0:
@@ -1825,20 +1834,20 @@ connection_exit_connect(connection_t *conn)
connection_watch_events(conn, EV_READ);
/* also, deliver a 'connected' cell back through the circuit. */
- if (connection_edge_is_rendezvous_stream(conn)) { /* rendezvous stream */
+ if (connection_edge_is_rendezvous_stream(edge_conn)) { /* rendezvous stream */
/* don't send an address back! */
- connection_edge_send_command(conn, circuit_get_by_edge_conn(conn),
+ connection_edge_send_command(edge_conn, circuit_get_by_edge_conn(edge_conn),
RELAY_COMMAND_CONNECTED,
- NULL, 0, conn->cpath_layer);
+ NULL, 0, edge_conn->cpath_layer);
} else { /* normal stream */
/* This must be the original address, not the redirected address. */
char connected_payload[8];
set_uint32(connected_payload, htonl(conn->addr));
set_uint32(connected_payload+4,
- htonl(dns_clip_ttl(conn->address_ttl)));
- connection_edge_send_command(conn, circuit_get_by_edge_conn(conn),
+ htonl(dns_clip_ttl(edge_conn->address_ttl)));
+ connection_edge_send_command(edge_conn, circuit_get_by_edge_conn(edge_conn),
RELAY_COMMAND_CONNECTED,
- connected_payload, 8, conn->cpath_layer);
+ connected_payload, 8, edge_conn->cpath_layer);
}
}
@@ -1846,7 +1855,7 @@ connection_exit_connect(connection_t *conn)
* it is a general stream.
*/
int
-connection_edge_is_rendezvous_stream(connection_t *conn)
+connection_edge_is_rendezvous_stream(edge_connection_t *conn)
{
tor_assert(conn);
if (*conn->rend_query) /* XXX */
@@ -1860,10 +1869,10 @@ connection_edge_is_rendezvous_stream(connection_t *conn)
* resolved.)
*/
int
-connection_ap_can_use_exit(connection_t *conn, routerinfo_t *exit)
+connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit)
{
tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_AP);
+ tor_assert(conn->_base.type == CONN_TYPE_AP);
tor_assert(conn->socks_request);
tor_assert(exit);
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 9b574d4902..4a9f8f4e93 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -19,8 +19,8 @@ const char connection_or_c_id[] =
#define TIGHT_CERT_ALLOW_SKEW (90*60)
-static int connection_tls_finish_handshake(connection_t *conn);
-static int connection_or_process_cells_from_inbuf(connection_t *conn);
+static int connection_tls_finish_handshake(or_connection_t *conn);
+static int connection_or_process_cells_from_inbuf(or_connection_t *conn);
/**************************************************************/
@@ -32,11 +32,10 @@ static digestmap_t *orconn_identity_map = NULL;
/** If conn is listed in orconn_identity_map, remove it, and clear
* conn->identity_digest. */
void
-connection_or_remove_from_identity_map(connection_t *conn)
+connection_or_remove_from_identity_map(or_connection_t *conn)
{
- connection_t *tmp;
+ or_connection_t *tmp;
tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_OR);
if (!orconn_identity_map)
return;
tmp = digestmap_get(orconn_identity_map, conn->identity_digest);
@@ -73,8 +72,9 @@ connection_or_clear_identity_map(void)
for (i = 0; i < n; ++i) {
connection_t* conn = carray[i];
if (conn->type == CONN_TYPE_OR) {
- memset(conn->identity_digest, 0, DIGEST_LEN);
- conn->next_with_same_id = NULL;
+ or_connection_t *or_conn = TO_OR_CONN(conn);
+ memset(or_conn->identity_digest, 0, DIGEST_LEN);
+ or_conn->next_with_same_id = NULL;
}
}
@@ -87,11 +87,10 @@ connection_or_clear_identity_map(void)
/** Change conn->identity_digest to digest, and add conn into
* orconn_digest_map. */
static void
-connection_or_set_identity_digest(connection_t *conn, const char *digest)
+connection_or_set_identity_digest(or_connection_t *conn, const char *digest)
{
- connection_t *tmp;
+ or_connection_t *tmp;
tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_OR);
tor_assert(digest);
if (!orconn_identity_map)
@@ -136,10 +135,10 @@ cell_unpack(cell_t *dest, const char *src)
}
int
-connection_or_reached_eof(connection_t *conn)
+connection_or_reached_eof(or_connection_t *conn)
{
log_info(LD_OR,"OR connection reached EOF. Closing.");
- connection_mark_for_close(conn);
+ connection_mark_for_close(TO_CONN(conn));
return 0;
}
@@ -149,13 +148,14 @@ connection_or_reached_eof(connection_t *conn)
* and hope for better luck next time.
*/
static int
-connection_or_read_proxy_response(connection_t *conn)
+connection_or_read_proxy_response(or_connection_t *or_conn)
{
char *headers;
char *reason=NULL;
int status_code;
time_t date_header;
int compression;
+ connection_t *conn = TO_CONN(or_conn);
switch (fetch_from_buf_http(conn->inbuf,
&headers, MAX_HEADERS_SIZE,
@@ -185,7 +185,7 @@ connection_or_read_proxy_response(connection_t *conn)
"HTTPS connect to '%s' successful! (200 %s) Starting TLS.",
conn->address, escaped(reason));
tor_free(reason);
- if (connection_tls_start_handshake(conn, 0) < 0) {
+ if (connection_tls_start_handshake(or_conn, 0) < 0) {
/* TLS handshaking error of some kind. */
connection_mark_for_close(conn);
@@ -209,12 +209,11 @@ connection_or_read_proxy_response(connection_t *conn)
* (else do nothing).
*/
int
-connection_or_process_inbuf(connection_t *conn)
+connection_or_process_inbuf(or_connection_t *conn)
{
tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_OR);
- switch (conn->state) {
+ switch (conn->_base.state) {
case OR_CONN_STATE_PROXY_READING:
return connection_or_read_proxy_response(conn);
case OR_CONN_STATE_OPEN:
@@ -233,24 +232,22 @@ connection_or_process_inbuf(connection_t *conn)
* return 0.
*/
int
-connection_or_finished_flushing(connection_t *conn)
+connection_or_finished_flushing(or_connection_t *conn)
{
tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_OR);
-
- assert_connection_ok(conn,0);
+ assert_connection_ok(TO_CONN(conn),0);
- switch (conn->state) {
+ switch (conn->_base.state) {
case OR_CONN_STATE_PROXY_FLUSHING:
log_debug(LD_OR,"finished sending CONNECT to proxy.");
- conn->state = OR_CONN_STATE_PROXY_READING;
- connection_stop_writing(conn);
+ conn->_base.state = OR_CONN_STATE_PROXY_READING;
+ connection_stop_writing(TO_CONN(conn));
break;
case OR_CONN_STATE_OPEN:
- connection_stop_writing(conn);
+ connection_stop_writing(TO_CONN(conn));
break;
default:
- log_err(LD_BUG,"BUG: called in unexpected state %d.", conn->state);
+ log_err(LD_BUG,"BUG: called in unexpected state %d.", conn->_base.state);
tor_fragile_assert();
return -1;
}
@@ -260,10 +257,11 @@ connection_or_finished_flushing(connection_t *conn)
/** Connected handler for OR connections: begin the TLS handshake.
*/
int
-connection_or_finished_connecting(connection_t *conn)
+connection_or_finished_connecting(or_connection_t *or_conn)
{
- tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_OR);
+ connection_t *conn;
+ tor_assert(or_conn);
+ conn = TO_CONN(or_conn);
tor_assert(conn->state == OR_CONN_STATE_CONNECTING);
log_debug(LD_OR,"OR connect() to router at %s:%u finished.",
@@ -298,7 +296,7 @@ connection_or_finished_connecting(connection_t *conn)
return 0;
}
- if (connection_tls_start_handshake(conn, 0) < 0) {
+ if (connection_tls_start_handshake(or_conn, 0) < 0) {
/* TLS handshaking error of some kind. */
connection_mark_for_close(conn);
return -1;
@@ -310,7 +308,7 @@ connection_or_finished_connecting(connection_t *conn)
* have an addr/port/id_digest, then fill in as much as we can. Start
* by checking to see if this describes a router we know. */
static void
-connection_or_init_conn_from_address(connection_t *conn,
+connection_or_init_conn_from_address(or_connection_t *conn,
uint32_t addr, uint16_t port,
const char *id_digest,
int started_here)
@@ -320,19 +318,19 @@ connection_or_init_conn_from_address(connection_t *conn,
conn->bandwidthrate = (int)options->BandwidthRate;
conn->receiver_bucket = conn->bandwidthburst = (int)options->BandwidthBurst;
connection_or_set_identity_digest(conn, id_digest);
- conn->addr = addr;
- conn->port = port;
+ conn->_base.addr = addr;
+ conn->_base.port = port;
if (r) {
if (!started_here) {
/* Override the addr/port, so our log messages will make sense.
* This is dangerous, since if we ever try looking up a conn by
* its actual addr/port, we won't remember. Careful! */
- conn->addr = r->addr;
- conn->port = r->or_port;
+ conn->_base.addr = r->addr;
+ conn->_base.port = r->or_port;
}
conn->nickname = tor_strdup(r->nickname);
- tor_free(conn->address);
- conn->address = tor_strdup(r->address);
+ tor_free(conn->_base.address);
+ conn->_base.address = tor_strdup(r->address);
} else {
const char *n;
/* If we're an authoritative directory server, we may know a
@@ -346,8 +344,8 @@ connection_or_init_conn_from_address(connection_t *conn,
base16_encode(conn->nickname+1, HEX_DIGEST_LEN+1,
conn->identity_digest, DIGEST_LEN);
}
- tor_free(conn->address);
- conn->address = tor_dup_addr(addr);
+ tor_free(conn->_base.address);
+ conn->_base.address = tor_dup_addr(addr);
}
}
@@ -360,11 +358,11 @@ connection_or_init_conn_from_address(connection_t *conn,
* 4) Then if there are any non-empty conns, ignore empty conns.
* 5) Of the remaining conns, prefer newer conns.
*/
-connection_t *
+or_connection_t *
connection_or_get_by_identity_digest(const char *digest)
{
int newer;
- connection_t *conn, *best=NULL;
+ or_connection_t *conn, *best=NULL;
if (!orconn_identity_map)
return NULL;
@@ -372,26 +370,26 @@ connection_or_get_by_identity_digest(const char *digest)
conn = digestmap_get(orconn_identity_map, digest);
for (; conn; conn = conn->next_with_same_id) {
- tor_assert(conn->magic == CONNECTION_MAGIC);
- tor_assert(conn->type == CONN_TYPE_OR);
+ tor_assert(conn->_base.magic == OR_CONNECTION_MAGIC);
+ tor_assert(conn->_base.type == CONN_TYPE_OR);
tor_assert(!memcmp(conn->identity_digest, digest, DIGEST_LEN));
- if (conn->marked_for_close)
+ if (conn->_base.marked_for_close)
continue;
if (!best) {
best = conn; /* whatever it is, it's better than nothing. */
continue;
}
- if (best->state == OR_CONN_STATE_OPEN &&
- conn->state != OR_CONN_STATE_OPEN)
+ if (best->_base.state == OR_CONN_STATE_OPEN &&
+ conn->_base.state != OR_CONN_STATE_OPEN)
continue; /* avoid non-open conns if we can */
- newer = best->timestamp_created < conn->timestamp_created;
+ newer = best->_base.timestamp_created < conn->_base.timestamp_created;
- if (!best->is_obsolete && conn->is_obsolete)
+ if (!best->_base.or_is_obsolete && conn->_base.or_is_obsolete)
continue; /* We never prefer obsolete over non-obsolete connections. */
if (
/* We prefer non-obsolete connections: */
- (best->is_obsolete && !conn->is_obsolete) ||
+ (best->_base.or_is_obsolete && !conn->_base.or_is_obsolete) ||
/* If both have circuits we prefer the newer: */
(best->n_circuits && conn->n_circuits && newer) ||
/* If neither has circuits we prefer the newer: */
@@ -418,10 +416,10 @@ connection_or_get_by_identity_digest(const char *digest)
*
* Return the launched conn, or NULL if it failed.
*/
-connection_t *
+or_connection_t *
connection_or_connect(uint32_t addr, uint16_t port, const char *id_digest)
{
- connection_t *conn;
+ or_connection_t *conn;
or_options_t *options = get_options();
tor_assert(id_digest);
@@ -431,11 +429,11 @@ connection_or_connect(uint32_t addr, uint16_t port, const char *id_digest)
return NULL;
}
- conn = connection_new(CONN_TYPE_OR);
+ conn = TO_OR_CONN(connection_new(CONN_TYPE_OR));
/* set up conn so it's got all the data we need to remember */
connection_or_init_conn_from_address(conn, addr, port, id_digest, 1);
- conn->state = OR_CONN_STATE_CONNECTING;
+ conn->_base.state = OR_CONN_STATE_CONNECTING;
control_event_or_conn_status(conn, OR_CONN_EVENT_LAUNCHED);
if (options->HttpsProxy) {
@@ -444,7 +442,7 @@ connection_or_connect(uint32_t addr, uint16_t port, const char *id_digest)
port = options->HttpsProxyPort;
}
- switch (connection_connect(conn, conn->address, addr, port)) {
+ switch (connection_connect(TO_CONN(conn), conn->_base.address, addr, port)) {
case -1:
/* If the connection failed immediately, and we're using
* an https proxy, our https proxy is down. Don't blame the
@@ -454,10 +452,10 @@ connection_or_connect(uint32_t addr, uint16_t port, const char *id_digest)
router_set_status(conn->identity_digest, 0);
}
control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED);
- connection_free(conn);
+ connection_free(TO_CONN(conn));
return NULL;
case 0:
- connection_watch_events(conn, EV_READ | EV_WRITE);
+ connection_watch_events(TO_CONN(conn), EV_READ | EV_WRITE);
/* writable indicates finish, readable indicates broken link,
error indicates broken link on windows */
return conn;
@@ -480,16 +478,16 @@ connection_or_connect(uint32_t addr, uint16_t port, const char *id_digest)
* Return -1 if <b>conn</b> is broken, else return 0.
*/
int
-connection_tls_start_handshake(connection_t *conn, int receiving)
+connection_tls_start_handshake(or_connection_t *conn, int receiving)
{
- conn->state = OR_CONN_STATE_HANDSHAKING;
- conn->tls = tor_tls_new(conn->s, receiving);
+ conn->_base.state = OR_CONN_STATE_HANDSHAKING;
+ conn->tls = tor_tls_new(conn->_base.s, receiving);
if (!conn->tls) {
log_warn(LD_BUG,"tor_tls_new failed. Closing.");
return -1;
}
- connection_start_reading(conn);
- log_debug(LD_OR,"starting TLS handshake on fd %d", conn->s);
+ connection_start_reading(TO_CONN(conn));
+ log_debug(LD_OR,"starting TLS handshake on fd %d", conn->_base.s);
if (connection_tls_continue_handshake(conn) < 0) {
return -1;
}
@@ -502,7 +500,7 @@ connection_tls_start_handshake(connection_t *conn, int receiving)
* Return -1 if <b>conn</b> is broken, else return 0.
*/
int
-connection_tls_continue_handshake(connection_t *conn)
+connection_tls_continue_handshake(or_connection_t *conn)
{
check_no_tls_errors();
switch (tor_tls_handshake(conn->tls)) {
@@ -513,7 +511,7 @@ connection_tls_continue_handshake(connection_t *conn)
case TOR_TLS_DONE:
return connection_tls_finish_handshake(conn);
case TOR_TLS_WANTWRITE:
- connection_start_writing(conn);
+ connection_start_writing(TO_CONN(conn));
log_debug(LD_OR,"wanted write");
return 0;
case TOR_TLS_WANTREAD: /* handshaking conns are *always* reading */
@@ -531,9 +529,9 @@ connection_tls_continue_handshake(connection_t *conn)
* one day so we're clearer.
*/
int
-connection_or_nonopen_was_started_here(connection_t *conn)
+connection_or_nonopen_was_started_here(or_connection_t *conn)
{
- tor_assert(conn->type == CONN_TYPE_OR);
+ tor_assert(conn->_base.type == CONN_TYPE_OR);
if (!conn->tls)
return 1; /* it's still in proxy states or something */
return !tor_tls_is_server(conn->tls);
@@ -557,7 +555,7 @@ connection_or_nonopen_was_started_here(connection_t *conn)
* this guy; and note that this guy is reachable.
*/
static int
-connection_or_check_valid_handshake(connection_t *conn, char *digest_rcvd)
+connection_or_check_valid_handshake(or_connection_t *conn, char *digest_rcvd)
{
routerinfo_t *router;
crypto_pk_env_t *identity_rcvd=NULL;
@@ -568,7 +566,7 @@ connection_or_check_valid_handshake(connection_t *conn, char *digest_rcvd)
check_no_tls_errors();
if (! tor_tls_peer_has_cert(conn->tls)) {
log_info(LD_PROTOCOL,"Peer (%s:%d) didn't send a cert! Closing.",
- conn->address, conn->port);
+ conn->_base.address, conn->_base.port);
return -1;
}
check_no_tls_errors();
@@ -576,17 +574,17 @@ connection_or_check_valid_handshake(connection_t *conn, char *digest_rcvd)
sizeof(nickname))) {
log_fn(severity,LD_PROTOCOL,"Other side (%s:%d) has a cert without a "
"valid nickname. Closing.",
- conn->address, conn->port);
+ conn->_base.address, conn->_base.port);
return -1;
}
check_no_tls_errors();
log_debug(LD_OR, "Other side (%s:%d) claims to be router '%s'",
- conn->address, conn->port, nickname);
+ conn->_base.address, conn->_base.port, nickname);
if (tor_tls_verify(severity, conn->tls, &identity_rcvd) < 0) {
log_fn(severity,LD_OR,"Other side, which claims to be router '%s' (%s:%d),"
" has a cert but it's invalid. Closing.",
- nickname, conn->address, conn->port);
+ nickname, conn->_base.address, conn->_base.port);
return -1;
}
check_no_tls_errors();
@@ -607,7 +605,7 @@ connection_or_check_valid_handshake(connection_t *conn, char *digest_rcvd)
log_fn(severity, LD_OR,
"Identity key not as expected for router claiming to be "
"'%s' (%s:%d)",
- nickname, conn->address, conn->port);
+ nickname, conn->_base.address, conn->_base.port);
return -1;
}
@@ -623,7 +621,7 @@ connection_or_check_valid_handshake(connection_t *conn, char *digest_rcvd)
log_fn(severity, LD_OR,
"Identity key not as expected for router at %s:%d: wanted %s "
"but got %s",
- conn->address, conn->port, expected, seen);
+ conn->_base.address, conn->_base.port, expected, seen);
entry_guard_set_status(conn->identity_digest, 0);
router_set_status(conn->identity_digest, 0);
control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED);
@@ -633,7 +631,7 @@ connection_or_check_valid_handshake(connection_t *conn, char *digest_rcvd)
/* We initiated this connection to address:port. Drop all routers
* with the same address:port and a different key or nickname.
*/
- dirserv_orconn_tls_done(conn->address, conn->port,
+ dirserv_orconn_tls_done(conn->_base.address, conn->_base.port,
digest_rcvd, nickname, as_advertised);
}
if (!as_advertised)
@@ -654,7 +652,7 @@ connection_or_check_valid_handshake(connection_t *conn, char *digest_rcvd)
* directory to be dirty (only matters if I'm an authdirserver).
*/
static int
-connection_tls_finish_handshake(connection_t *conn)
+connection_tls_finish_handshake(or_connection_t *conn)
{
char digest_rcvd[DIGEST_LEN];
int started_here = connection_or_nonopen_was_started_here(conn);
@@ -664,7 +662,7 @@ connection_tls_finish_handshake(connection_t *conn)
return -1;
if (!started_here) {
- connection_or_init_conn_from_address(conn,conn->addr,conn->port,
+ connection_or_init_conn_from_address(conn,conn->_base.addr,conn->_base.port,
digest_rcvd, 0);
/* Annotate that we received a TLS connection.
@@ -677,12 +675,12 @@ connection_tls_finish_handshake(connection_t *conn)
* The reason this bandaid is here is because there's a bug in
* Tor 0.1.1.x where middle hops don't always send their create
* cell; so some servers rarely find themselves reachable. */
-// if (!is_local_IP(conn->addr))
+// if (!is_local_IP(conn->_base.addr))
// router_orport_found_reachable();
}
directory_set_dirty();
- conn->state = OR_CONN_STATE_OPEN;
+ conn->_base.state = OR_CONN_STATE_OPEN;
control_event_or_conn_status(conn, OR_CONN_EVENT_CONNECTED);
if (started_here) {
rep_hist_note_connect_succeeded(conn->identity_digest, time(NULL));
@@ -692,7 +690,7 @@ connection_tls_finish_handshake(connection_t *conn)
}
router_set_status(conn->identity_digest, 1);
}
- connection_watch_events(conn, EV_READ);
+ connection_watch_events(TO_CONN(conn), EV_READ);
circuit_n_conn_done(conn, 1); /* send the pending creates, if any. */
return 0;
}
@@ -704,18 +702,17 @@ connection_tls_finish_handshake(connection_t *conn)
* ready, then try to flush the record now.
*/
void
-connection_or_write_cell_to_buf(const cell_t *cell, connection_t *conn)
+connection_or_write_cell_to_buf(const cell_t *cell, or_connection_t *conn)
{
char networkcell[CELL_NETWORK_SIZE];
char *n = networkcell;
tor_assert(cell);
tor_assert(conn);
- tor_assert(connection_speaks_cells(conn));
cell_pack(n, cell);
- connection_write_to_buf(n, CELL_NETWORK_SIZE, conn);
+ connection_write_to_buf(n, CELL_NETWORK_SIZE, TO_CONN(conn));
#define MIN_TLS_FLUSHLEN 15872
/* openssl tls record size is 16383, this is close. The goal here is to
@@ -723,26 +720,28 @@ connection_or_write_cell_to_buf(const cell_t *cell, connection_t *conn)
* during periods of high load we won't read the entire megabyte from
* input before pushing any data out. It also has the feature of not
* growing huge outbufs unless something is slow. */
- if (conn->outbuf_flushlen-CELL_NETWORK_SIZE < MIN_TLS_FLUSHLEN &&
- conn->outbuf_flushlen >= MIN_TLS_FLUSHLEN) {
- int extra = conn->outbuf_flushlen - MIN_TLS_FLUSHLEN;
- conn->outbuf_flushlen = MIN_TLS_FLUSHLEN;
- if (connection_handle_write(conn) < 0) {
- if (!conn->marked_for_close) {
+ if (conn->_base.outbuf_flushlen-CELL_NETWORK_SIZE < MIN_TLS_FLUSHLEN &&
+ conn->_base.outbuf_flushlen >= MIN_TLS_FLUSHLEN) {
+ int extra = conn->_base.outbuf_flushlen - MIN_TLS_FLUSHLEN;
+ conn->_base.outbuf_flushlen = MIN_TLS_FLUSHLEN;
+ if (connection_handle_write(TO_CONN(conn)) < 0) {
+ if (!conn->_base.marked_for_close) {
/* this connection is broken. remove it. */
log_warn(LD_BUG,
"Bug: unhandled error on write for OR conn (fd %d); removing",
- conn->s);
+ conn->_base.s);
tor_fragile_assert();
- conn->has_sent_end = 1; /* don't cry wolf about duplicate close */
+ // XXX This was supposed to be edge-only!
+ // conn->has_sent_end = 1; /* don't cry wolf about duplicate close */
+
/* XXX do we need a close-immediate here, so we don't try to flush? */
- connection_mark_for_close(conn);
+ connection_mark_for_close(TO_CONN(conn));
}
return;
}
if (extra) {
- conn->outbuf_flushlen += extra;
- connection_start_writing(conn);
+ conn->_base.outbuf_flushlen += extra;
+ connection_start_writing(TO_CONN(conn));
}
}
}
@@ -755,7 +754,7 @@ connection_or_write_cell_to_buf(const cell_t *cell, connection_t *conn)
* Always return 0.
*/
static int
-connection_or_process_cells_from_inbuf(connection_t *conn)
+connection_or_process_cells_from_inbuf(or_connection_t *conn)
{
char buf[CELL_NETWORK_SIZE];
cell_t cell;
@@ -763,13 +762,13 @@ connection_or_process_cells_from_inbuf(connection_t *conn)
loop:
log_debug(LD_OR,
"%d: starting, inbuf_datalen %d (%d pending in tls object).",
- conn->s,(int)buf_datalen(conn->inbuf),
+ conn->_base.s,(int)buf_datalen(conn->_base.inbuf),
tor_tls_get_pending_bytes(conn->tls));
- if (buf_datalen(conn->inbuf) < CELL_NETWORK_SIZE) /* whole response
- available? */
+ if (buf_datalen(conn->_base.inbuf) < CELL_NETWORK_SIZE) /* whole response
+ available? */
return 0; /* not yet */
- connection_fetch_from_buf(buf, CELL_NETWORK_SIZE, conn);
+ connection_fetch_from_buf(buf, CELL_NETWORK_SIZE, TO_CONN(conn));
/* retrieve cell info from buf (create the host-order struct from the
* network-order string) */
@@ -787,12 +786,11 @@ loop:
* Return 0.
*/
int
-connection_or_send_destroy(uint16_t circ_id, connection_t *conn, int reason)
+connection_or_send_destroy(uint16_t circ_id, or_connection_t *conn, int reason)
{
cell_t cell;
tor_assert(conn);
- tor_assert(connection_speaks_cells(conn));
memset(&cell, 0, sizeof(cell_t));
cell.circ_id = circ_id;
diff --git a/src/or/control.c b/src/or/control.c
index 7737e9a21f..d8e2fb5a7b 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -131,57 +131,57 @@ static int disable_log_messages = 0;
static int authentication_cookie_is_set = 0;
static char authentication_cookie[AUTHENTICATION_COOKIE_LEN];
-static void connection_printf_to_buf(connection_t *conn,
+static void connection_printf_to_buf(control_connection_t *conn,
const char *format, ...)
CHECK_PRINTF(2,3);
/*static*/ size_t write_escaped_data(const char *data, size_t len,
int translate_newlines, char **out);
/*static*/ size_t read_escaped_data(const char *data, size_t len,
int translate_newlines, char **out);
-static void send_control0_message(connection_t *conn, uint16_t type,
+static void send_control0_message(control_connection_t *conn, uint16_t type,
uint32_t len, const char *body);
-static void send_control_done(connection_t *conn);
-static void send_control_done2(connection_t *conn, const char *msg,
+static void send_control_done(control_connection_t *conn);
+static void send_control_done2(control_connection_t *conn, const char *msg,
size_t len);
-static void send_control0_error(connection_t *conn, uint16_t error,
+static void send_control0_error(control_connection_t *conn, uint16_t error,
const char *message);
static void send_control0_event(uint16_t event, uint32_t len,
const char *body);
static void send_control1_event(uint16_t event, const char *format, ...)
CHECK_PRINTF(2,3);
-static int handle_control_setconf(connection_t *conn, uint32_t len,
+static int handle_control_setconf(control_connection_t *conn, uint32_t len,
char *body);
-static int handle_control_resetconf(connection_t *conn, uint32_t len,
+static int handle_control_resetconf(control_connection_t *conn, uint32_t len,
char *body);
-static int handle_control_getconf(connection_t *conn, uint32_t len,
+static int handle_control_getconf(control_connection_t *conn, uint32_t len,
const char *body);
-static int handle_control_setevents(connection_t *conn, uint32_t len,
+static int handle_control_setevents(control_connection_t *conn, uint32_t len,
const char *body);
-static int handle_control_authenticate(connection_t *conn, uint32_t len,
+static int handle_control_authenticate(control_connection_t *conn, uint32_t len,
const char *body);
-static int handle_control_saveconf(connection_t *conn, uint32_t len,
+static int handle_control_saveconf(control_connection_t *conn, uint32_t len,
const char *body);
-static int handle_control_signal(connection_t *conn, uint32_t len,
+static int handle_control_signal(control_connection_t *conn, uint32_t len,
const char *body);
-static int handle_control_mapaddress(connection_t *conn, uint32_t len,
+static int handle_control_mapaddress(control_connection_t *conn, uint32_t len,
const char *body);
-static int handle_control_getinfo(connection_t *conn, uint32_t len,
+static int handle_control_getinfo(control_connection_t *conn, uint32_t len,
const char *body);
-static int handle_control_extendcircuit(connection_t *conn, uint32_t len,
+static int handle_control_extendcircuit(control_connection_t *conn, uint32_t len,
const char *body);
-static int handle_control_setpurpose(connection_t *conn, int for_circuits,
+static int handle_control_setpurpose(control_connection_t *conn, int for_circuits,
uint32_t len, const char *body);
-static int handle_control_attachstream(connection_t *conn, uint32_t len,
+static int handle_control_attachstream(control_connection_t *conn, uint32_t len,
const char *body);
-static int handle_control_postdescriptor(connection_t *conn, uint32_t len,
+static int handle_control_postdescriptor(control_connection_t *conn, uint32_t len,
const char *body);
-static int handle_control_redirectstream(connection_t *conn, uint32_t len,
+static int handle_control_redirectstream(control_connection_t *conn, uint32_t len,
const char *body);
-static int handle_control_closestream(connection_t *conn, uint32_t len,
+static int handle_control_closestream(control_connection_t *conn, uint32_t len,
const char *body);
-static int handle_control_closecircuit(connection_t *conn, uint32_t len,
+static int handle_control_closecircuit(control_connection_t *conn, uint32_t len,
const char *body);
-static int write_stream_target_to_buf(connection_t *conn, char *buf,
+static int write_stream_target_to_buf(edge_connection_t *conn, char *buf,
size_t len);
/** Given a possibly invalid message type code <b>cmd</b>, return a
@@ -235,10 +235,11 @@ control_update_global_event_mask(void)
for (i = 0; i < n_conns; ++i) {
if (conns[i]->type == CONN_TYPE_CONTROL &&
STATE_IS_OPEN(conns[i]->state)) {
- if (STATE_IS_V0(conns[i]->state))
- global_event_mask0 |= conns[i]->event_mask;
+ control_connection_t *conn = TO_CONTROL_CONN(conns[i]);
+ if (STATE_IS_V0(conn->_base.state))
+ global_event_mask0 |= conn->event_mask;
else
- global_event_mask1 |= conns[i]->event_mask;
+ global_event_mask1 |= conn->event_mask;
}
}
@@ -281,10 +282,10 @@ control_adjust_event_log_severity(void)
* <b>conn</b>-\>outbuf
*/
static INLINE void
-connection_write_str_to_buf(const char *s, connection_t *conn)
+connection_write_str_to_buf(const char *s, control_connection_t *conn)
{
size_t len = strlen(s);
- connection_write_to_buf(s, len, conn);
+ connection_write_to_buf(s, len, TO_CONN(conn));
}
/** Given a <b>len</b>-character string in <b>data</b>, made of lines
@@ -446,7 +447,7 @@ get_escaped_string(const char *start, size_t in_len_max,
* Currently the length of the message is limited to 1024 (including the
* ending \n\r\0. */
static void
-connection_printf_to_buf(connection_t *conn, const char *format, ...)
+connection_printf_to_buf(control_connection_t *conn, const char *format, ...)
{
#define CONNECTION_PRINTF_TO_BUF_BUFFERSIZE 1024
va_list ap;
@@ -462,41 +463,41 @@ connection_printf_to_buf(connection_t *conn, const char *format, ...)
buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-2] = '\n';
buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-3] = '\r';
}
- connection_write_to_buf(buf, len, conn);
+ connection_write_to_buf(buf, len, TO_CONN(conn));
}
/** Send a message of type <b>type</b> containing <b>len</b> bytes
* from <b>body</b> along the control connection <b>conn</b> */
static void
-send_control0_message(connection_t *conn, uint16_t type, uint32_t len,
- const char *body)
+send_control0_message(control_connection_t *conn, uint16_t type, uint32_t len,
+ const char *body)
{
char buf[10];
tor_assert(conn);
- tor_assert(STATE_IS_V0(conn->state));
+ tor_assert(STATE_IS_V0(conn->_base.state));
tor_assert(len || !body);
tor_assert(type <= _CONTROL0_CMD_MAX_RECOGNIZED);
if (len < 65536) {
set_uint16(buf, htons(len));
set_uint16(buf+2, htons(type));
- connection_write_to_buf(buf, 4, conn);
+ connection_write_to_buf(buf, 4, TO_CONN(conn));
if (len)
- connection_write_to_buf(body, len, conn);
+ connection_write_to_buf(body, len, TO_CONN(conn));
} else {
set_uint16(buf, htons(65535));
set_uint16(buf+2, htons(CONTROL0_CMD_FRAGMENTHEADER));
set_uint16(buf+4, htons(type));
set_uint32(buf+6, htonl(len));
- connection_write_to_buf(buf, 10, conn);
- connection_write_to_buf(body, 65535-6, conn);
+ connection_write_to_buf(buf, 10, TO_CONN(conn));
+ connection_write_to_buf(body, 65535-6, TO_CONN(conn));
len -= (65535-6);
body += (65535-6);
while (len) {
size_t chunklen = (len<65535)?len:65535;
set_uint16(buf, htons((uint16_t)chunklen));
set_uint16(buf+2, htons(CONTROL0_CMD_FRAGMENT));
- connection_write_to_buf(buf, 4, conn);
- connection_write_to_buf(body, chunklen, conn);
+ connection_write_to_buf(buf, 4, TO_CONN(conn));
+ connection_write_to_buf(body, chunklen, TO_CONN(conn));
len -= chunklen;
body += chunklen;
}
@@ -505,9 +506,9 @@ send_control0_message(connection_t *conn, uint16_t type, uint32_t len,
/** Send a "DONE" message down the control connection <b>conn</b> */
static void
-send_control_done(connection_t *conn)
+send_control_done(control_connection_t *conn)
{
- if (STATE_IS_V0(conn->state)) {
+ if (STATE_IS_V0(conn->_base.state)) {
send_control0_message(conn, CONTROL0_CMD_DONE, 0, NULL);
} else {
connection_write_str_to_buf("250 OK\r\n", conn);
@@ -518,7 +519,7 @@ send_control_done(connection_t *conn)
* as provided in the <b>len</b> bytes at <b>msg</b>.
*/
static void
-send_control_done2(connection_t *conn, const char *msg, size_t len)
+send_control_done2(control_connection_t *conn, const char *msg, size_t len)
{
if (len==0)
len = strlen(msg);
@@ -528,7 +529,7 @@ send_control_done2(connection_t *conn, const char *msg, size_t len)
/** Send an error message with error code <b>error</b> and body
* <b>message</b> down the connection <b>conn</b> */
static void
-send_control0_error(connection_t *conn, uint16_t error, const char *message)
+send_control0_error(control_connection_t *conn, uint16_t error, const char *message)
{
char buf[256];
size_t len;
@@ -561,11 +562,13 @@ send_control0_event(uint16_t event, uint32_t len, const char *body)
for (i = 0; i < n_conns; ++i) {
if (conns[i]->type == CONN_TYPE_CONTROL &&
!conns[i]->marked_for_close &&
- conns[i]->state == CONTROL_CONN_STATE_OPEN_V0 &&
- conns[i]->event_mask & (1<<event)) {
- send_control0_message(conns[i], CONTROL0_CMD_EVENT, buflen, buf);
- if (event == EVENT_ERR_MSG)
- _connection_controller_force_write(conns[i]);
+ conns[i]->state == CONTROL_CONN_STATE_OPEN_V0) {
+ control_connection_t *control_conn = TO_CONTROL_CONN(conns[i]);
+ if (control_conn->event_mask & (1<<event)) {
+ send_control0_message(control_conn, CONTROL0_CMD_EVENT, buflen, buf);
+ if (event == EVENT_ERR_MSG)
+ _connection_controller_force_write(control_conn);
+ }
}
}
@@ -586,11 +589,13 @@ send_control1_event_string(uint16_t event, const char *msg)
for (i = 0; i < n_conns; ++i) {
if (conns[i]->type == CONN_TYPE_CONTROL &&
!conns[i]->marked_for_close &&
- conns[i]->state == CONTROL_CONN_STATE_OPEN_V1 &&
- conns[i]->event_mask & (1<<event)) {
- connection_write_to_buf(msg, strlen(msg), conns[i]);
- if (event == EVENT_ERR_MSG)
- _connection_controller_force_write(conns[i]);
+ conns[i]->state == CONTROL_CONN_STATE_OPEN_V1) {
+ control_connection_t *control_conn = TO_CONTROL_CONN(conns[i]);
+ if (control_conn->event_mask & (1<<event)) {
+ connection_write_to_buf(msg, strlen(msg), TO_CONN(control_conn));
+ if (event == EVENT_ERR_MSG)
+ _connection_controller_force_write(control_conn);
+ }
}
}
}
@@ -657,14 +662,14 @@ get_stream(const char *id)
* it passes <b>use_defaults</b> on to options_trial_assign().
*/
static int
-control_setconf_helper(connection_t *conn, uint32_t len, char *body,
+control_setconf_helper(control_connection_t *conn, uint32_t len, char *body,
int use_defaults, int clear_first)
{
int r;
config_line_t *lines=NULL;
char *start = body;
char *errstring = NULL;
- int v0 = STATE_IS_V0(conn->state);
+ int v0 = STATE_IS_V0(conn->_base.state);
if (!v0) {
char *config = tor_malloc(len+1);
@@ -761,7 +766,7 @@ control_setconf_helper(connection_t *conn, uint32_t len, char *body,
/** Called when we receive a SETCONF message: parse the body and try
* to update our configuration. Reply with a DONE or ERROR message. */
static int
-handle_control_setconf(connection_t *conn, uint32_t len, char *body)
+handle_control_setconf(control_connection_t *conn, uint32_t len, char *body)
{
return control_setconf_helper(conn, len, body, 0, 1);
}
@@ -769,9 +774,9 @@ handle_control_setconf(connection_t *conn, uint32_t len, char *body)
/** Called when we receive a RESETCONF message: parse the body and try
* to update our configuration. Reply with a DONE or ERROR message. */
static int
-handle_control_resetconf(connection_t *conn, uint32_t len, char *body)
+handle_control_resetconf(control_connection_t *conn, uint32_t len, char *body)
{
- int v0 = STATE_IS_V0(conn->state);
+ int v0 = STATE_IS_V0(conn->_base.state);
tor_assert(!v0);
return control_setconf_helper(conn, len, body, 1, 1);
}
@@ -779,7 +784,7 @@ handle_control_resetconf(connection_t *conn, uint32_t len, char *body)
/** Called when we receive a GETCONF message. Parse the request, and
* reply with a CONFVALUE or an ERROR message */
static int
-handle_control_getconf(connection_t *conn, uint32_t body_len, const char *body)
+handle_control_getconf(control_connection_t *conn, uint32_t body_len, const char *body)
{
smartlist_t *questions = NULL;
smartlist_t *answers = NULL;
@@ -787,7 +792,7 @@ handle_control_getconf(connection_t *conn, uint32_t body_len, const char *body)
char *msg = NULL;
size_t msg_len;
or_options_t *options = get_options();
- int v0 = STATE_IS_V0(conn->state);
+ int v0 = STATE_IS_V0(conn->_base.state);
questions = smartlist_create();
(void) body_len; /* body is nul-terminated; so we can ignore len. */
@@ -858,7 +863,7 @@ handle_control_getconf(connection_t *conn, uint32_t body_len, const char *body)
tor_assert(strlen(tmp)>4);
tmp[3] = ' ';
msg = smartlist_join_strings(answers, "", 0, &msg_len);
- connection_write_to_buf(msg, msg_len, conn);
+ connection_write_to_buf(msg, msg_len, TO_CONN(conn));
} else {
connection_write_str_to_buf("250 OK\r\n", conn);
}
@@ -882,13 +887,13 @@ handle_control_getconf(connection_t *conn, uint32_t body_len, const char *body)
/** Called when we get a SETEVENTS message: update conn->event_mask,
* and reply with DONE or ERROR. */
static int
-handle_control_setevents(connection_t *conn, uint32_t len, const char *body)
+handle_control_setevents(control_connection_t *conn, uint32_t len, const char *body)
{
uint16_t event_code;
uint32_t event_mask = 0;
unsigned int extended = 0;
- if (STATE_IS_V0(conn->state)) {
+ if (STATE_IS_V0(conn->_base.state)) {
if (len % 2) {
send_control0_error(conn, ERR_SYNTAX,
"Odd number of bytes in setevents message");
@@ -950,7 +955,7 @@ handle_control_setevents(connection_t *conn, uint32_t len, const char *body)
smartlist_free(events);
}
conn->event_mask = event_mask;
- conn->control_events_are_extended = extended;
+ conn->_base.control_events_are_extended = extended;
control_update_global_event_mask();
send_control_done(conn);
@@ -987,13 +992,13 @@ decode_hashed_password(char *buf, const char *hashed)
* OPEN. Reply with DONE or ERROR.
*/
static int
-handle_control_authenticate(connection_t *conn, uint32_t len, const char *body)
+handle_control_authenticate(control_connection_t *conn, uint32_t len, const char *body)
{
int used_quoted_string = 0;
or_options_t *options = get_options();
char *password;
size_t password_len;
- if (STATE_IS_V0(conn->state)) {
+ if (STATE_IS_V0(conn->_base.state)) {
password = (char*)body;
password_len = len;
} else {
@@ -1047,7 +1052,7 @@ handle_control_authenticate(connection_t *conn, uint32_t len, const char *body)
}
err:
- if (STATE_IS_V0(conn->state))
+ if (STATE_IS_V0(conn->_base.state))
send_control0_error(conn,ERR_REJECTED_AUTHENTICATION,
"Authentication failed");
else {
@@ -1061,12 +1066,12 @@ handle_control_authenticate(connection_t *conn, uint32_t len, const char *body)
}
return 0;
ok:
- log_info(LD_CONTROL, "Authenticated control connection (%d)", conn->s);
+ log_info(LD_CONTROL, "Authenticated control connection (%d)", conn->_base.s);
send_control_done(conn);
- if (STATE_IS_V0(conn->state))
- conn->state = CONTROL_CONN_STATE_OPEN_V0;
+ if (STATE_IS_V0(conn->_base.state))
+ conn->_base.state = CONTROL_CONN_STATE_OPEN_V0;
else {
- conn->state = CONTROL_CONN_STATE_OPEN_V1;
+ conn->_base.state = CONTROL_CONN_STATE_OPEN_V1;
tor_free(password);
}
return 0;
@@ -1075,13 +1080,13 @@ handle_control_authenticate(connection_t *conn, uint32_t len, const char *body)
/** Called when we get a SAVECONF command. Try to flush the current options to
* disk, and report success or failure. */
static int
-handle_control_saveconf(connection_t *conn, uint32_t len,
+handle_control_saveconf(control_connection_t *conn, uint32_t len,
const char *body)
{
(void) len;
(void) body;
if (options_save_current()<0) {
- if (STATE_IS_V0(conn->state))
+ if (STATE_IS_V0(conn->_base.state))
send_control0_error(conn, ERR_INTERNAL,
"Unable to write configuration to disk.");
else
@@ -1097,11 +1102,11 @@ handle_control_saveconf(connection_t *conn, uint32_t len,
* report success or failure. (If the signal results in a shutdown, success
* may not be reported.) */
static int
-handle_control_signal(connection_t *conn, uint32_t len,
+handle_control_signal(control_connection_t *conn, uint32_t len,
const char *body)
{
int sig;
- if (STATE_IS_V0(conn->state)) {
+ if (STATE_IS_V0(conn->_base.state)) {
if (len != 1) {
send_control0_error(conn, ERR_SYNTAX,
"Body of SIGNAL command too long or too short.");
@@ -1138,7 +1143,7 @@ handle_control_signal(connection_t *conn, uint32_t len,
}
if (control_signal_act(sig) < 0) {
- if (STATE_IS_V0(conn->state))
+ if (STATE_IS_V0(conn->_base.state))
send_control0_error(conn, ERR_SYNTAX, "Unrecognized signal number.");
else
connection_write_str_to_buf("551 Internal error acting on signal\r\n",
@@ -1152,14 +1157,14 @@ handle_control_signal(connection_t *conn, uint32_t len,
/** Called when we get a MAPADDRESS command; try to bind all listed addresses,
* and report success or failrue. */
static int
-handle_control_mapaddress(connection_t *conn, uint32_t len, const char *body)
+handle_control_mapaddress(control_connection_t *conn, uint32_t len, const char *body)
{
smartlist_t *elts;
smartlist_t *lines;
smartlist_t *reply;
char *r;
size_t sz;
- int v0 = STATE_IS_V0(conn->state);
+ int v0 = STATE_IS_V0(conn->_base.state);
(void) len; /* body is nul-terminated, so it's safe to ignore the length. */
lines = smartlist_create();
@@ -1257,12 +1262,12 @@ handle_control_mapaddress(connection_t *conn, uint32_t len, const char *body)
if (smartlist_len(reply)) {
((char*)smartlist_get(reply,smartlist_len(reply)-1))[3] = ' ';
r = smartlist_join_strings(reply, "\r\n", 1, &sz);
- connection_write_to_buf(r, sz, conn);
+ connection_write_to_buf(r, sz, TO_CONN(conn));
tor_free(r);
} else {
const char *response =
"512 syntax error: not enough arguments to mapaddress.\r\n";
- connection_write_to_buf(response, strlen(response), conn);
+ connection_write_to_buf(response, strlen(response), TO_CONN(conn));
}
}
@@ -1399,6 +1404,7 @@ handle_getinfo_helper(const char *question, char **answer)
get_connection_array(&conns, &n_conns);
for (i=0; i < n_conns; ++i) {
const char *state;
+ edge_connection_t *conn;
char *s;
size_t slen;
circuit_t *circ;
@@ -1406,12 +1412,13 @@ handle_getinfo_helper(const char *question, char **answer)
conns[i]->marked_for_close ||
conns[i]->state == AP_CONN_STATE_SOCKS_WAIT)
continue;
- switch (conns[i]->state)
+ conn = TO_EDGE_CONN(conns[i]);
+ switch (conn->_base.state)
{
case AP_CONN_STATE_CONTROLLER_WAIT:
case AP_CONN_STATE_CIRCUIT_WAIT:
- if (conns[i]->socks_request &&
- conns[i]->socks_request->command == SOCKS_COMMAND_RESOLVE)
+ if (conn->socks_request &&
+ conn->socks_request->command == SOCKS_COMMAND_RESOLVE)
state = "NEWRESOLVE";
else
state = "NEW";
@@ -1425,15 +1432,15 @@ handle_getinfo_helper(const char *question, char **answer)
state = "SUCCEEDED"; break;
default:
log_warn(LD_BUG, "Asked for stream in unknown state %d",
- conns[i]->state);
+ conn->_base.state);
continue;
}
- circ = circuit_get_by_edge_conn(conns[i]);
- write_stream_target_to_buf(conns[i], buf, sizeof(buf));
+ circ = circuit_get_by_edge_conn(conn);
+ write_stream_target_to_buf(conn, buf, sizeof(buf));
slen = strlen(buf)+strlen(state)+32;
s = tor_malloc(slen+1);
tor_snprintf(s, slen, "%lu %s %lu %s",
- (unsigned long) conns[i]->global_identifier,state,
+ (unsigned long) conn->_base.global_identifier,state,
circ?(unsigned long)circ->global_identifier : 0ul,
buf);
smartlist_add(status, s);
@@ -1451,10 +1458,11 @@ handle_getinfo_helper(const char *question, char **answer)
char *s;
char name[128];
size_t slen;
- connection_t *conn = conns[i];
- if (conn->type != CONN_TYPE_OR || conn->marked_for_close)
+ or_connection_t *conn;
+ if (conns[i]->type != CONN_TYPE_OR || conns[i]->marked_for_close)
continue;
- if (conn->state == OR_CONN_STATE_OPEN)
+ conn = TO_OR_CONN(conns[i]);
+ if (conn->_base.state == OR_CONN_STATE_OPEN)
state = "CONNECTED";
else if (conn->nickname)
state = "LAUNCHED";
@@ -1464,7 +1472,7 @@ handle_getinfo_helper(const char *question, char **answer)
strlcpy(name, conn->nickname, sizeof(name));
else
tor_snprintf(name, sizeof(name), "%s:%d",
- conn->address, conn->port);
+ conn->_base.address, conn->_base.port);
slen = strlen(name)+strlen(state)+2;
s = tor_malloc(slen+1);
@@ -1544,14 +1552,14 @@ handle_getinfo_helper(const char *question, char **answer)
/** Called when we receive a GETINFO command. Try to fetch all requested
* information, and reply with information or error message. */
static int
-handle_control_getinfo(connection_t *conn, uint32_t len, const char *body)
+handle_control_getinfo(control_connection_t *conn, uint32_t len, const char *body)
{
smartlist_t *questions = NULL;
smartlist_t *answers = NULL;
smartlist_t *unrecognized = NULL;
char *msg = NULL, *ans = NULL;
size_t msg_len;
- int v0 = STATE_IS_V0(conn->state);
+ int v0 = STATE_IS_V0(conn->_base.state);
(void) len; /* body is nul-terminated, so it's safe to ignore the length. */
questions = smartlist_create();
@@ -1615,7 +1623,7 @@ handle_control_getinfo(connection_t *conn, uint32_t len, const char *body)
size_t len;
len = write_escaped_data(v, strlen(v), 1, &esc);
connection_printf_to_buf(conn, "250+%s=\r\n", k);
- connection_write_to_buf(esc, len, conn);
+ connection_write_to_buf(esc, len, TO_CONN(conn));
tor_free(esc);
}
}
@@ -1662,7 +1670,7 @@ get_purpose(char *string, int for_circuits, uint8_t *purpose)
/** Called when we get an EXTENDCIRCUIT message. Try to extend the listed
* circuit, and report success or failure. */
static int
-handle_control_extendcircuit(connection_t *conn, uint32_t len,
+handle_control_extendcircuit(control_connection_t *conn, uint32_t len,
const char *body)
{
smartlist_t *router_nicknames=NULL, *routers=NULL;
@@ -1672,7 +1680,7 @@ handle_control_extendcircuit(connection_t *conn, uint32_t len,
char reply[4];
uint8_t intended_purpose = CIRCUIT_PURPOSE_C_GENERAL;
- v0 = STATE_IS_V0(conn->state);
+ v0 = STATE_IS_V0(conn->_base.state);
router_nicknames = smartlist_create();
if (v0) {
@@ -1816,7 +1824,7 @@ handle_control_extendcircuit(connection_t *conn, uint32_t len,
* is 1) or SETROUTERPURPOSE message. If we can find
* the circuit/router and it's a valid purpose, change it. */
static int
-handle_control_setpurpose(connection_t *conn, int for_circuits,
+handle_control_setpurpose(control_connection_t *conn, int for_circuits,
uint32_t len, const char *body)
{
circuit_t *circ = NULL;
@@ -1868,14 +1876,15 @@ done:
/** Called when we get an ATTACHSTREAM message. Try to attach the requested
* stream, and report success or failure. */
static int
-handle_control_attachstream(connection_t *conn, uint32_t len,
+handle_control_attachstream(control_connection_t *conn, uint32_t len,
const char *body)
{
connection_t *ap_conn = NULL;
circuit_t *circ = NULL;
int zero_circ;
+ edge_connection_t *edge_conn;
- if (STATE_IS_V0(conn->state)) {
+ if (STATE_IS_V0(conn->_base.state)) {
uint32_t conn_id;
uint32_t circ_id;
if (len < 8) {
@@ -1927,7 +1936,7 @@ handle_control_attachstream(connection_t *conn, uint32_t len,
if (ap_conn->state != AP_CONN_STATE_CONTROLLER_WAIT &&
ap_conn->state != AP_CONN_STATE_CONNECT_WAIT &&
ap_conn->state != AP_CONN_STATE_RESOLVE_WAIT) {
- if (STATE_IS_V0(conn->state)) {
+ if (STATE_IS_V0(conn->_base.state)) {
send_control0_error(conn, ERR_NO_STREAM,
"Connection is not managed by controller.");
} else {
@@ -1938,20 +1947,23 @@ handle_control_attachstream(connection_t *conn, uint32_t len,
return 0;
}
+ edge_conn = TO_EDGE_CONN(ap_conn);
+
/* Do we need to detach it first? */
if (ap_conn->state != AP_CONN_STATE_CONTROLLER_WAIT) {
- circuit_t *tmpcirc = circuit_get_by_edge_conn(ap_conn);
- connection_edge_end(ap_conn, END_STREAM_REASON_TIMEOUT, conn->cpath_layer);
+ circuit_t *tmpcirc = circuit_get_by_edge_conn(edge_conn);
+ connection_edge_end(edge_conn, END_STREAM_REASON_TIMEOUT,
+ edge_conn->cpath_layer);
/* Un-mark it as ending, since we're going to reuse it. */
- ap_conn->has_sent_end = 0;
+ ap_conn->edge_has_sent_end = 0;
if (tmpcirc)
- circuit_detach_stream(tmpcirc,ap_conn);
+ circuit_detach_stream(tmpcirc,edge_conn);
ap_conn->state = AP_CONN_STATE_CONTROLLER_WAIT;
}
if (circ &&
(circ->state != CIRCUIT_STATE_OPEN || ! CIRCUIT_IS_ORIGIN(circ))) {
- if (STATE_IS_V0(conn->state))
+ if (STATE_IS_V0(conn->_base.state))
send_control0_error(conn, ERR_INTERNAL,
"Refuse to attach stream to non-open, origin circ.");
else
@@ -1960,9 +1972,9 @@ handle_control_attachstream(connection_t *conn, uint32_t len,
conn);
return 0;
}
- if (connection_ap_handshake_rewrite_and_attach(ap_conn,
+ if (connection_ap_handshake_rewrite_and_attach(edge_conn,
circ ? TO_ORIGIN_CIRCUIT(circ) : NULL) < 0) {
- if (STATE_IS_V0(conn->state))
+ if (STATE_IS_V0(conn->_base.state))
send_control0_error(conn, ERR_INTERNAL, "Unable to attach stream.");
else
connection_write_str_to_buf("551 Unable to attach stream\r\n", conn);
@@ -1975,11 +1987,11 @@ handle_control_attachstream(connection_t *conn, uint32_t len,
/** Called when we get a POSTDESCRIPTOR message. Try to learn the provided
* descriptor, and report success or failure. */
static int
-handle_control_postdescriptor(connection_t *conn, uint32_t len,
+handle_control_postdescriptor(control_connection_t *conn, uint32_t len,
const char *body)
{
char *desc;
- int v0 = STATE_IS_V0(conn->state);
+ int v0 = STATE_IS_V0(conn->_base.state);
const char *msg=NULL;
uint8_t purpose = ROUTER_PURPOSE_GENERAL;
@@ -2034,14 +2046,14 @@ handle_control_postdescriptor(connection_t *conn, uint32_t len,
/** Called when we receive a REDIRECTSTERAM command. Try to change the target
* address of the named AP stream, and report success or failure. */
static int
-handle_control_redirectstream(connection_t *conn, uint32_t len,
+handle_control_redirectstream(control_connection_t *conn, uint32_t len,
const char *body)
{
connection_t *ap_conn = NULL;
uint32_t conn_id;
char *new_addr = NULL;
uint16_t new_port = 0;
- if (STATE_IS_V0(conn->state)) {
+ if (STATE_IS_V0(conn->_base.state)) {
if (len < 6) {
send_control0_error(conn, ERR_SYNTAX,
"redirectstream message too short");
@@ -2051,7 +2063,7 @@ handle_control_redirectstream(connection_t *conn, uint32_t len,
if (!(ap_conn = connection_get_by_global_id(conn_id))
|| ap_conn->state != CONN_TYPE_AP
- || !ap_conn->socks_request) {
+ || !TO_EDGE_CONN(ap_conn)->socks_request) {
send_control0_error(conn, ERR_NO_STREAM,
"No AP connection found with given ID");
return 0;
@@ -2066,7 +2078,7 @@ handle_control_redirectstream(connection_t *conn, uint32_t len,
connection_printf_to_buf(conn,
"512 Missing argument to REDIRECTSTREAM\r\n");
else if (!(ap_conn = get_stream(smartlist_get(args, 0)))
- || !ap_conn->socks_request) {
+ || !TO_EDGE_CONN(ap_conn)->socks_request) {
connection_printf_to_buf(conn, "552 Unknown stream \"%s\"\r\n",
(char*)smartlist_get(args, 0));
} else {
@@ -2089,25 +2101,28 @@ handle_control_redirectstream(connection_t *conn, uint32_t len,
return 0;
}
- strlcpy(ap_conn->socks_request->address, new_addr,
- sizeof(ap_conn->socks_request->address));
- if (new_port)
- ap_conn->socks_request->port = new_port;
- tor_free(new_addr);
- send_control_done(conn);
- return 0;
+ {
+ edge_connection_t *ap = TO_EDGE_CONN(ap_conn);
+ strlcpy(ap->socks_request->address, new_addr,
+ sizeof(ap->socks_request->address));
+ if (new_port)
+ ap->socks_request->port = new_port;
+ tor_free(new_addr);
+ send_control_done(conn);
+ return 0;
+ }
}
/** Called when we get a CLOSESTREAM command; try to close the named stream
* and report success or failure. */
static int
-handle_control_closestream(connection_t *conn, uint32_t len,
+handle_control_closestream(control_connection_t *conn, uint32_t len,
const char *body)
{
connection_t *ap_conn=NULL;
uint8_t reason=0;
- if (STATE_IS_V0(conn->state)) {
+ if (STATE_IS_V0(conn->_base.state)) {
uint32_t conn_id;
if (len < 6) {
send_control0_error(conn, ERR_SYNTAX, "closestream message too short");
@@ -2119,7 +2134,7 @@ handle_control_closestream(connection_t *conn, uint32_t len,
if (!(ap_conn = connection_get_by_global_id(conn_id))
|| ap_conn->state != CONN_TYPE_AP
- || !ap_conn->socks_request) {
+ || !TO_EDGE_CONN(ap_conn)->socks_request) {
send_control0_error(conn, ERR_NO_STREAM,
"No AP connection found with given ID");
return 0;
@@ -2151,7 +2166,7 @@ handle_control_closestream(connection_t *conn, uint32_t len,
return 0;
}
- connection_mark_unattached_ap(ap_conn, reason);
+ connection_mark_unattached_ap(TO_EDGE_CONN(ap_conn), reason);
send_control_done(conn);
return 0;
}
@@ -2159,13 +2174,13 @@ handle_control_closestream(connection_t *conn, uint32_t len,
/** Called when we get a CLOSECIRCUIT command; try to close the named circuit
* and report success or failure. */
static int
-handle_control_closecircuit(connection_t *conn, uint32_t len,
+handle_control_closecircuit(control_connection_t *conn, uint32_t len,
const char *body)
{
circuit_t *circ = NULL;
int safe = 0;
- if (STATE_IS_V0(conn->state)) {
+ if (STATE_IS_V0(conn->_base.state)) {
uint32_t circ_id;
if (len < 5) {
send_control0_error(conn, ERR_SYNTAX, "closecircuit message too short");
@@ -2221,7 +2236,7 @@ handle_control_closecircuit(connection_t *conn, uint32_t len,
* fragments and report failure.
*/
static int
-handle_control_fragments(connection_t *conn, uint16_t command_type,
+handle_control_fragments(control_connection_t *conn, uint16_t command_type,
uint32_t body_len, char *body)
{
if (command_type == CONTROL0_CMD_FRAGMENTHEADER) {
@@ -2262,24 +2277,22 @@ handle_control_fragments(connection_t *conn, uint16_t command_type,
/** Called when <b>conn</b> has no more bytes left on its outbuf. */
int
-connection_control_finished_flushing(connection_t *conn)
+connection_control_finished_flushing(control_connection_t *conn)
{
tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_CONTROL);
- connection_stop_writing(conn);
+ connection_stop_writing(TO_CONN(conn));
return 0;
}
/** Called when <b>conn</b> has gotten its socket closed. */
int
-connection_control_reached_eof(connection_t *conn)
+connection_control_reached_eof(control_connection_t *conn)
{
tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_CONTROL);
log_info(LD_CONTROL,"Control connection reached EOF. Closing.");
- connection_mark_for_close(conn);
+ connection_mark_for_close(TO_CONN(conn));
return 0;
}
@@ -2287,16 +2300,15 @@ connection_control_reached_eof(connection_t *conn)
* commands from conn->inbuf, and execute them.
*/
static int
-connection_control_process_inbuf_v1(connection_t *conn)
+connection_control_process_inbuf_v1(control_connection_t *conn)
{
size_t data_len;
int cmd_len;
char *args;
tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_CONTROL);
- tor_assert(conn->state == CONTROL_CONN_STATE_OPEN_V1 ||
- conn->state == CONTROL_CONN_STATE_NEEDAUTH_V1);
+ tor_assert(conn->_base.state == CONTROL_CONN_STATE_OPEN_V1 ||
+ conn->_base.state == CONTROL_CONN_STATE_NEEDAUTH_V1);
if (!conn->incoming_cmd) {
conn->incoming_cmd = tor_malloc(1024);
@@ -2311,7 +2323,7 @@ connection_control_process_inbuf_v1(connection_t *conn)
/* First, fetch a line. */
do {
data_len = conn->incoming_cmd_len - conn->incoming_cmd_cur_len;
- r = fetch_from_buf_line(conn->inbuf,
+ r = fetch_from_buf_line(conn->_base.inbuf,
conn->incoming_cmd+conn->incoming_cmd_cur_len,
&data_len);
if (r == 0)
@@ -2361,11 +2373,11 @@ connection_control_process_inbuf_v1(connection_t *conn)
if (!strcasecmp(conn->incoming_cmd, "QUIT")) {
connection_write_str_to_buf("250 closing connection\r\n", conn);
- connection_mark_for_close(conn);
+ connection_mark_for_close(TO_CONN(conn));
return 0;
}
- if (conn->state == CONTROL_CONN_STATE_NEEDAUTH_V1 &&
+ if (conn->_base.state == CONTROL_CONN_STATE_NEEDAUTH_V1 &&
strcasecmp(conn->incoming_cmd, "AUTHENTICATE")) {
connection_write_str_to_buf("514 Authentication required.\r\n", conn);
conn->incoming_cmd_cur_len = 0;
@@ -2436,7 +2448,7 @@ connection_control_process_inbuf_v1(connection_t *conn)
* commands from conn->inbuf, and execute them.
*/
static int
-connection_control_process_inbuf_v0(connection_t *conn)
+connection_control_process_inbuf_v0(control_connection_t *conn)
{
uint32_t body_len;
uint16_t command_type;
@@ -2444,15 +2456,15 @@ connection_control_process_inbuf_v0(connection_t *conn)
again:
/* Try to suck a control message from the buffer. */
- switch (fetch_from_buf_control0(conn->inbuf, &body_len, &command_type, &body,
- conn->state == CONTROL_CONN_STATE_NEEDAUTH_V0))
+ switch (fetch_from_buf_control0(conn->_base.inbuf, &body_len, &command_type, &body,
+ conn->_base.state == CONTROL_CONN_STATE_NEEDAUTH_V0))
{
case -2:
tor_free(body);
log_info(LD_CONTROL,
"Detected v1 control protocol on connection (fd %d)",
- conn->s);
- conn->state = CONTROL_CONN_STATE_NEEDAUTH_V1;
+ conn->_base.s);
+ conn->_base.state = CONTROL_CONN_STATE_NEEDAUTH_V1;
return connection_control_process_inbuf_v1(conn);
case -1:
tor_free(body);
@@ -2470,7 +2482,7 @@ connection_control_process_inbuf_v0(connection_t *conn)
/* We got a command. If we need authentication, only authentication
* commands will be considered. */
- if (conn->state == CONTROL_CONN_STATE_NEEDAUTH_V0 &&
+ if (conn->_base.state == CONTROL_CONN_STATE_NEEDAUTH_V0 &&
command_type != CONTROL0_CMD_AUTHENTICATE) {
log_info(LD_CONTROL, "Rejecting '%s' command; authentication needed.",
control_cmd_to_string(command_type));
@@ -2584,12 +2596,11 @@ connection_control_process_inbuf_v0(connection_t *conn)
/** Called when <b>conn</b> has received more bytes on its inbuf.
*/
int
-connection_control_process_inbuf(connection_t *conn)
+connection_control_process_inbuf(control_connection_t *conn)
{
tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_CONTROL);
- if (STATE_IS_V0(conn->state))
+ if (STATE_IS_V0(conn->_base.state))
return connection_control_process_inbuf_v0(conn);
else
return connection_control_process_inbuf_v1(conn);
@@ -2644,7 +2655,7 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp)
* <b>conn</b>, and write it to <b>buf</b>. Return 0 on success, -1 on
* failure. */
static int
-write_stream_target_to_buf(connection_t *conn, char *buf, size_t len)
+write_stream_target_to_buf(edge_connection_t *conn, char *buf, size_t len)
{
char buf2[256];
if (conn->chosen_exit_name)
@@ -2663,12 +2674,11 @@ write_stream_target_to_buf(connection_t *conn, char *buf, size_t len)
/** Something has happened to the stream associated with AP connection
* <b>conn</b>: tell any interested control connections. */
int
-control_event_stream_status(connection_t *conn, stream_status_event_t tp)
+control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp)
{
char *msg;
size_t len;
char buf[256];
- tor_assert(conn->type == CONN_TYPE_AP);
tor_assert(conn->socks_request);
if (!EVENT_IS_INTERESTING(EVENT_STREAM_STATUS))
@@ -2679,7 +2689,7 @@ control_event_stream_status(connection_t *conn, stream_status_event_t tp)
len = strlen(buf);
msg = tor_malloc(5+len+1);
msg[0] = (uint8_t) tp;
- set_uint32(msg+1, htonl(conn->global_identifier));
+ set_uint32(msg+1, htonl(conn->_base.global_identifier));
strlcpy(msg+5, buf, len+1);
send_control0_event(EVENT_STREAM_STATUS, (uint32_t)(5+len+1), msg);
@@ -2705,7 +2715,7 @@ control_event_stream_status(connection_t *conn, stream_status_event_t tp)
circ = circuit_get_by_edge_conn(conn);
send_control1_event(EVENT_STREAM_STATUS,
"650 STREAM %lu %s %lu %s\r\n",
- (unsigned long)conn->global_identifier, status,
+ (unsigned long)conn->_base.global_identifier, status,
circ?(unsigned long)circ->global_identifier : 0ul,
buf);
/* XXX need to specify its intended exit, etc? */
@@ -2716,13 +2726,11 @@ control_event_stream_status(connection_t *conn, stream_status_event_t tp)
/** Something has happened to the OR connection <b>conn</b>: tell any
* interested control connections. */
int
-control_event_or_conn_status(connection_t *conn,or_conn_status_event_t tp)
+control_event_or_conn_status(or_connection_t *conn,or_conn_status_event_t tp)
{
char buf[HEX_DIGEST_LEN+3]; /* status, dollar, identity, NUL */
size_t len;
- tor_assert(conn->type == CONN_TYPE_OR);
-
if (!EVENT_IS_INTERESTING(EVENT_OR_CONN_STATUS))
return 0;
@@ -2739,7 +2747,7 @@ control_event_or_conn_status(connection_t *conn,or_conn_status_event_t tp)
strlcpy(name, conn->nickname, sizeof(name));
else
tor_snprintf(name, sizeof(name), "%s:%d",
- conn->address, conn->port);
+ conn->_base.address, conn->_base.port);
switch (tp)
{
case OR_CONN_EVENT_LAUNCHED: status = "LAUNCHED"; break;
diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c
index 1ed91b0426..66827bf20e 100644
--- a/src/or/cpuworker.c
+++ b/src/or/cpuworker.c
@@ -137,7 +137,7 @@ connection_cpu_process_inbuf(connection_t *conn)
uint32_t addr;
uint16_t port;
uint16_t circ_id;
- connection_t *p_conn;
+ or_connection_t *p_conn;
circuit_t *circ;
tor_assert(conn);
@@ -473,7 +473,8 @@ assign_to_cpuworker(connection_t *cpuworker, uint8_t question_type,
log_info(LD_OR,"circ->p_conn gone. Failing circ.");
return -1;
}
- tag_pack(tag, circ->p_conn->addr, circ->p_conn->port, circ->p_circ_id);
+ tag_pack(tag, circ->p_conn->_base.addr, circ->p_conn->_base.port,
+ circ->p_circ_id);
cpuworker->state = CPUWORKER_STATE_BUSY_ONION;
/* touch the lastwritten timestamp, since that's how we check to
diff --git a/src/or/directory.c b/src/or/directory.c
index c6af9b86a1..e788a0a1a9 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -38,16 +38,16 @@ directory_initiate_command(const char *address, uint32_t addr, uint16_t port,
const char *payload, size_t payload_len);
static void
-directory_send_command(connection_t *conn, const char *platform,
+directory_send_command(dir_connection_t *conn, const char *platform,
int purpose, const char *resource,
const char *payload, size_t payload_len);
-static int directory_handle_command(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 purpose_is_private(uint8_t purpose);
static char *http_get_header(const char *headers, const char *which);
static void http_set_address_origin(const char *headers, connection_t *conn);
-static void connection_dir_download_networkstatus_failed(connection_t *conn);
-static void connection_dir_download_routerdesc_failed(connection_t *conn);
+static void connection_dir_download_networkstatus_failed(dir_connection_t *conn);
+static void connection_dir_download_routerdesc_failed(dir_connection_t *conn);
static void dir_networkstatus_download_failed(smartlist_t *failed);
static void dir_routerdesc_download_failed(smartlist_t *failed);
static void note_request(const char *key, size_t bytes);
@@ -261,24 +261,24 @@ directory_initiate_command_routerstatus(routerstatus_t *status,
* directory server: Mark the router as down and try again if possible.
*/
void
-connection_dir_request_failed(connection_t *conn)
+connection_dir_request_failed(dir_connection_t *conn)
{
if (router_digest_is_me(conn->identity_digest))
return; /* this was a test fetch. don't retry. */
router_set_status(conn->identity_digest, 0); /* don't try him again */
- if (conn->purpose == DIR_PURPOSE_FETCH_DIR ||
- conn->purpose == DIR_PURPOSE_FETCH_RUNNING_LIST) {
+ if (conn->_base.purpose == DIR_PURPOSE_FETCH_DIR ||
+ conn->_base.purpose == DIR_PURPOSE_FETCH_RUNNING_LIST) {
log_info(LD_DIR, "Giving up on directory server at '%s:%d'; retrying",
- conn->address, conn->port);
- directory_get_from_dirserver(conn->purpose, NULL,
+ conn->_base.address, conn->_base.port);
+ directory_get_from_dirserver(conn->_base.purpose, NULL,
0 /* don't retry_if_no_servers */);
- } else if (conn->purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS) {
+ } else if (conn->_base.purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS) {
log_info(LD_DIR, "Giving up on directory server at '%s'; retrying",
- conn->address);
+ conn->_base.address);
connection_dir_download_networkstatus_failed(conn);
- } else if (conn->purpose == DIR_PURPOSE_FETCH_SERVERDESC) {
+ } else if (conn->_base.purpose == DIR_PURPOSE_FETCH_SERVERDESC) {
log_info(LD_DIR, "Giving up on directory server at '%s'; retrying",
- conn->address);
+ conn->_base.address);
connection_dir_download_routerdesc_failed(conn);
}
}
@@ -288,7 +288,7 @@ connection_dir_request_failed(connection_t *conn)
* retry the fetch now, later, or never.
*/
static void
-connection_dir_download_networkstatus_failed(connection_t *conn)
+connection_dir_download_networkstatus_failed(dir_connection_t *conn)
{
if (!conn->requested_resource) {
/* We never reached directory_send_command, which means that we never
@@ -301,7 +301,7 @@ connection_dir_download_networkstatus_failed(connection_t *conn)
smartlist_t *trusted_dirs = router_get_trusted_dir_servers();
SMARTLIST_FOREACH(trusted_dirs, trusted_dir_server_t *, ds,
++ds->n_networkstatus_failures);
- directory_get_from_dirserver(conn->purpose, "all.z",
+ directory_get_from_dirserver(conn->_base.purpose, "all.z",
0 /* don't retry_if_no_servers */);
} else if (!strcmpstart(conn->requested_resource, "fp/")) {
/* We were trying to download by fingerprint; mark them all as having
@@ -321,7 +321,7 @@ connection_dir_download_networkstatus_failed(connection_t *conn)
* on connection <b>conn</b> failed.
*/
static void
-connection_dir_download_routerdesc_failed(connection_t *conn)
+connection_dir_download_routerdesc_failed(dir_connection_t *conn)
{
/* Try again. No need to increment the failure count for routerdescs, since
* it's not their fault.*/
@@ -342,7 +342,7 @@ directory_initiate_command(const char *address, uint32_t addr,
int private_connection, const char *resource,
const char *payload, size_t payload_len)
{
- connection_t *conn;
+ dir_connection_t *conn;
tor_assert(address);
tor_assert(addr);
@@ -376,18 +376,18 @@ directory_initiate_command(const char *address, uint32_t addr,
tor_assert(0);
}
- conn = connection_new(CONN_TYPE_DIR);
+ conn = TO_DIR_CONN(connection_new(CONN_TYPE_DIR));
/* set up conn so it's got all the data we need to remember */
- conn->addr = addr;
- conn->port = dir_port;
- conn->address = tor_strdup(address);
+ conn->_base.addr = addr;
+ conn->_base.port = dir_port;
+ conn->_base.address = tor_strdup(address);
memcpy(conn->identity_digest, digest, DIGEST_LEN);
- conn->purpose = purpose;
+ conn->_base.purpose = purpose;
/* give it an initial state */
- conn->state = DIR_CONN_STATE_CONNECTING;
+ conn->_base.state = DIR_CONN_STATE_CONNECTING;
conn->dirconn_direct = (private_connection == 0);
if (!private_connection) {
@@ -398,19 +398,19 @@ directory_initiate_command(const char *address, uint32_t addr,
dir_port = get_options()->HttpProxyPort;
}
- switch (connection_connect(conn, conn->address, addr, dir_port)) {
+ switch (connection_connect(TO_CONN(conn), conn->_base.address, addr, dir_port)) {
case -1:
connection_dir_request_failed(conn); /* retry if we want */
- connection_free(conn);
+ connection_free(TO_CONN(conn));
return;
case 1:
- conn->state = DIR_CONN_STATE_CLIENT_SENDING; /* start flushing conn */
+ conn->_base.state = DIR_CONN_STATE_CLIENT_SENDING; /* start flushing conn */
/* fall through */
case 0:
/* queue the command on the outbuf */
directory_send_command(conn, platform, purpose, resource,
payload, payload_len);
- connection_watch_events(conn, EV_READ | EV_WRITE);
+ connection_watch_events(TO_CONN(conn), EV_READ | EV_WRITE);
/* writable indicates finish, readable indicates broken link,
error indicates broken link in windowsland. */
}
@@ -419,23 +419,24 @@ directory_initiate_command(const char *address, uint32_t addr,
* populate it and add it at the right state
* socketpair and hook up both sides
*/
- conn->s = connection_ap_make_bridge(conn->address, conn->port);
- if (conn->s < 0) {
+ conn->_base.s = connection_ap_make_bridge(conn->_base.address,
+ conn->_base.port);
+ if (conn->_base.s < 0) {
log_warn(LD_NET,"Making AP bridge to dirserver failed.");
- connection_mark_for_close(conn);
+ connection_mark_for_close(TO_CONN(conn));
return;
}
- if (connection_add(conn) < 0) {
+ if (connection_add(TO_CONN(conn)) < 0) {
log_warn(LD_NET,"Unable to add AP bridge to dirserver.");
- connection_mark_for_close(conn);
+ connection_mark_for_close(TO_CONN(conn));
return;
}
- conn->state = DIR_CONN_STATE_CLIENT_SENDING;
+ conn->_base.state = DIR_CONN_STATE_CLIENT_SENDING;
/* queue the command on the outbuf */
directory_send_command(conn, platform, purpose, resource,
payload, payload_len);
- connection_watch_events(conn, EV_READ | EV_WRITE);
+ connection_watch_events(TO_CONN(conn), EV_READ | EV_WRITE);
}
}
@@ -443,7 +444,7 @@ directory_initiate_command(const char *address, uint32_t addr,
* are as in directory_initiate_command.
*/
static void
-directory_send_command(connection_t *conn, const char *platform,
+directory_send_command(dir_connection_t *conn, const char *platform,
int purpose, const char *resource,
const char *payload, size_t payload_len)
{
@@ -456,18 +457,18 @@ directory_send_command(connection_t *conn, const char *platform,
size_t len;
tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_DIR);
+ tor_assert(conn->_base.type == CONN_TYPE_DIR);
tor_free(conn->requested_resource);
if (resource)
conn->requested_resource = tor_strdup(resource);
/* come up with a string for which Host: we want */
- if (conn->port == 80) {
- strlcpy(hoststring, conn->address, sizeof(hoststring));
+ if (conn->_base.port == 80) {
+ strlcpy(hoststring, conn->_base.address, sizeof(hoststring));
} else {
tor_snprintf(hoststring, sizeof(hoststring),"%s:%d",
- conn->address, conn->port);
+ conn->_base.address, conn->_base.port);
}
/* come up with some proxy lines, if we're using one. */
@@ -564,8 +565,8 @@ directory_send_command(connection_t *conn, const char *platform,
}
tor_snprintf(request, sizeof(request), "%s %s", httpcommand, proxystring);
- connection_write_to_buf(request, strlen(request), conn);
- connection_write_to_buf(url, strlen(url), conn);
+ connection_write_to_buf(request, strlen(request), TO_CONN(conn));
+ connection_write_to_buf(url, strlen(url), TO_CONN(conn));
tor_free(url);
if (!strcmp(httpcommand, "GET") && !payload) {
@@ -580,11 +581,11 @@ directory_send_command(connection_t *conn, const char *platform,
hoststring,
proxyauthstring);
}
- connection_write_to_buf(request, strlen(request), conn);
+ connection_write_to_buf(request, strlen(request), TO_CONN(conn));
if (payload) {
/* then send the payload afterwards too */
- connection_write_to_buf(payload, payload_len, conn);
+ connection_write_to_buf(payload, payload_len, TO_CONN(conn));
}
}
@@ -804,7 +805,7 @@ body_is_plausible(const char *body, size_t len, int purpose)
* The caller will take care of marking the connection for close.
*/
static int
-connection_dir_client_reached_eof(connection_t *conn)
+connection_dir_client_reached_eof(dir_connection_t *conn)
{
char *body;
char *headers;
@@ -816,17 +817,17 @@ connection_dir_client_reached_eof(connection_t *conn)
int compression;
int plausible;
int skewed=0;
- int allow_partial = conn->purpose == DIR_PURPOSE_FETCH_SERVERDESC;
+ int allow_partial = conn->_base.purpose == DIR_PURPOSE_FETCH_SERVERDESC;
int was_compressed=0;
- switch (fetch_from_buf_http(conn->inbuf,
+ switch (fetch_from_buf_http(conn->_base.inbuf,
&headers, MAX_HEADERS_SIZE,
&body, &body_len, MAX_DIR_SIZE,
allow_partial)) {
case -1: /* overflow */
log_warn(LD_PROTOCOL,
"'fetch' response too large (server '%s:%d'). Closing.",
- conn->address, conn->port);
+ conn->_base.address, conn->_base.port);
return -1;
case 0:
log_info(LD_HTTP,
@@ -839,7 +840,7 @@ connection_dir_client_reached_eof(connection_t *conn)
if (parse_http_response(headers, &status_code, &date_header,
&compression, &reason) < 0) {
log_warn(LD_HTTP,"Unparseable headers (server '%s:%d'). Closing.",
- conn->address, conn->port);
+ conn->_base.address, conn->_base.port);
tor_free(body); tor_free(headers);
return -1;
}
@@ -847,7 +848,7 @@ connection_dir_client_reached_eof(connection_t *conn)
log_debug(LD_DIR,
"Received response from directory server '%s:%d': %d %s",
- conn->address, conn->port, status_code, escaped(reason));
+ conn->_base.address, conn->_base.port, status_code, escaped(reason));
/* now check if it's got any hints for us about our IP address. */
if (server_mode(get_options())) {
@@ -867,7 +868,7 @@ connection_dir_client_reached_eof(connection_t *conn)
LD_HTTP,
"Received directory with skewed time (server '%s:%d'): "
"we are %d minutes %s, or the directory is %d minutes %s.",
- conn->address, conn->port,
+ conn->_base.address, conn->_base.port,
abs(delta)/60, delta>0 ? "ahead" : "behind",
abs(delta)/60, delta>0 ? "behind" : "ahead");
skewed = 1; /* don't check the recommended-versions line */
@@ -880,12 +881,12 @@ connection_dir_client_reached_eof(connection_t *conn)
if (status_code == 503) {
log_info(LD_DIR,"Received http status code %d (%s) from server "
"'%s:%d'. I'll try again soon.",
- status_code, escaped(reason), conn->address, conn->port);
+ status_code, escaped(reason), conn->_base.address, conn->_base.port);
tor_free(body); tor_free(headers); tor_free(reason);
return -1;
}
- plausible = body_is_plausible(body, body_len, conn->purpose);
+ plausible = body_is_plausible(body, body_len, conn->_base.purpose);
if (compression || !plausible) {
char *new_body = NULL;
size_t new_len = 0;
@@ -912,7 +913,7 @@ connection_dir_client_reached_eof(connection_t *conn)
log_info(LD_HTTP, "HTTP body from server '%s:%d' was labeled %s, "
"but it seems to be %s.%s",
- conn->address, conn->port, description1, description2,
+ conn->_base.address, conn->_base.port, description1, description2,
(compression>0 && guessed>0)?" Trying both.":"");
}
/* Try declared compression first if we can. */
@@ -929,7 +930,7 @@ connection_dir_client_reached_eof(connection_t *conn)
if (!plausible && !new_body) {
log_fn(LOG_PROTOCOL_WARN, LD_HTTP,
"Unable to decompress HTTP body (server '%s:%d').",
- conn->address, conn->port);
+ conn->_base.address, conn->_base.port);
tor_free(body); tor_free(headers); tor_free(reason);
return -1;
}
@@ -941,38 +942,38 @@ connection_dir_client_reached_eof(connection_t *conn)
}
}
- if (conn->purpose == DIR_PURPOSE_FETCH_DIR) {
+ if (conn->_base.purpose == DIR_PURPOSE_FETCH_DIR) {
/* fetch/process the directory to cache it. */
log_info(LD_DIR,"Received directory (size %d) from server '%s:%d'",
- (int)body_len, conn->address, conn->port);
+ (int)body_len, conn->_base.address, conn->_base.port);
if (status_code != 200) {
log_warn(LD_DIR,"Received http status code %d (%s) from server "
"'%s:%d'. I'll try again soon.",
- status_code, escaped(reason), conn->address, conn->port);
+ status_code, escaped(reason), conn->_base.address, conn->_base.port);
tor_free(body); tor_free(headers); tor_free(reason);
return -1;
}
if (router_parse_directory(body) < 0) {
log_notice(LD_DIR,"I failed to parse the directory I fetched from "
- "'%s:%d'. Ignoring.", conn->address, conn->port);
+ "'%s:%d'. Ignoring.", conn->_base.address, conn->_base.port);
}
note_request(was_compressed?"dl/dir.z":"dl/dir", orig_len);
}
- if (conn->purpose == DIR_PURPOSE_FETCH_RUNNING_LIST) {
+ if (conn->_base.purpose == DIR_PURPOSE_FETCH_RUNNING_LIST) {
/* just update our list of running routers, if this list is new info */
log_info(LD_DIR,"Received running-routers list (size %d)", (int)body_len);
if (status_code != 200) {
log_warn(LD_DIR,"Received http status code %d (%s) from server "
"'%s:%d'. I'll try again soon.",
- status_code, escaped(reason), conn->address, conn->port);
+ status_code, escaped(reason), conn->_base.address, conn->_base.port);
tor_free(body); tor_free(headers); tor_free(reason);
return -1;
}
if (router_parse_runningrouters(body)<0) {
log_warn(LD_DIR,
"Bad running-routers from server '%s:%d'. I'll try again soon.",
- conn->address, conn->port);
+ conn->_base.address, conn->_base.port);
tor_free(body); tor_free(headers); tor_free(reason);
return -1;
}
@@ -980,16 +981,16 @@ connection_dir_client_reached_eof(connection_t *conn)
"dl/running-routers", orig_len);
}
- if (conn->purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS) {
+ if (conn->_base.purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS) {
smartlist_t *which = NULL;
char *cp;
log_info(LD_DIR,"Received networkstatus objects (size %d) from server "
- "'%s:%d'",(int) body_len, conn->address, conn->port);
+ "'%s:%d'",(int) body_len, conn->_base.address, conn->_base.port);
if (status_code != 200) {
log_warn(LD_DIR,
"Received http status code %d (%s) from server "
"'%s:%d' while fetching \"/tor/status/%s\". I'll try again soon.",
- status_code, escaped(reason), conn->address, conn->port,
+ status_code, escaped(reason), conn->_base.address, conn->_base.port,
conn->requested_resource);
tor_free(body); tor_free(headers); tor_free(reason);
connection_dir_download_networkstatus_failed(conn);
@@ -1038,11 +1039,11 @@ connection_dir_client_reached_eof(connection_t *conn)
}
}
- if (conn->purpose == DIR_PURPOSE_FETCH_SERVERDESC) {
+ if (conn->_base.purpose == DIR_PURPOSE_FETCH_SERVERDESC) {
smartlist_t *which = NULL;
int n_asked_for = 0;
log_info(LD_DIR,"Received server info (size %d) from server '%s:%d'",
- (int)body_len, conn->address, conn->port);
+ (int)body_len, conn->_base.address, conn->_base.port);
note_request(was_compressed?"dl/server.z":"dl/server", orig_len);
if (conn->requested_resource &&
!strcmpstart(conn->requested_resource,"d/")) {
@@ -1059,7 +1060,7 @@ connection_dir_client_reached_eof(connection_t *conn)
log_fn(dir_okay ? LOG_INFO : LOG_WARN, LD_DIR,
"Received http status code %d (%s) from server '%s:%d' "
"while fetching \"/tor/server/%s\". I'll try again soon.",
- status_code, escaped(reason), conn->address, conn->port,
+ status_code, escaped(reason), conn->_base.address, conn->_base.port,
conn->requested_resource);
if (!which) {
connection_dir_download_routerdesc_failed(conn);
@@ -1085,7 +1086,7 @@ connection_dir_client_reached_eof(connection_t *conn)
if (which) { /* mark remaining ones as failed */
log_info(LD_DIR, "Received %d/%d routers requested from %s:%d",
n_asked_for-smartlist_len(which), n_asked_for,
- conn->address, (int)conn->port);
+ conn->_base.address, (int)conn->_base.port);
if (smartlist_len(which)) {
dir_routerdesc_download_failed(which);
}
@@ -1098,13 +1099,13 @@ connection_dir_client_reached_eof(connection_t *conn)
routerinfo_t *me = router_get_my_routerinfo();
if (me &&
router_digest_is_me(conn->identity_digest) &&
- me->addr == conn->addr &&
- me->dir_port == conn->port)
+ me->addr == conn->_base.addr &&
+ me->dir_port == conn->_base.port)
router_dirport_found_reachable();
}
}
- if (conn->purpose == DIR_PURPOSE_UPLOAD_DIR) {
+ if (conn->_base.purpose == DIR_PURPOSE_UPLOAD_DIR) {
switch (status_code) {
case 200:
log_info(LD_GENERAL,"eof (status 200) after uploading server "
@@ -1113,7 +1114,7 @@ connection_dir_client_reached_eof(connection_t *conn)
case 400:
log_warn(LD_GENERAL,"http status 400 (%s) response from "
"dirserver '%s:%d'. Please correct.",
- escaped(reason), conn->address, conn->port);
+ escaped(reason), conn->_base.address, conn->_base.port);
break;
case 403:
log_warn(LD_GENERAL,
@@ -1121,19 +1122,19 @@ connection_dir_client_reached_eof(connection_t *conn)
"'%s:%d'. Is your clock skewed? Have you mailed us your key "
"fingerprint? Are you using the right key? Are you using a "
"private IP address? See http://tor.eff.org/doc/"
- "tor-doc-server.html",escaped(reason), conn->address, conn->port);
+ "tor-doc-server.html",escaped(reason), conn->_base.address, conn->_base.port);
break;
default:
log_warn(LD_GENERAL,
"http status %d (%s) reason unexpected (server '%s:%d').",
- status_code, escaped(reason), conn->address, conn->port);
+ status_code, escaped(reason), conn->_base.address, conn->_base.port);
break;
}
/* return 0 in all cases, since we don't want to mark any
* dirservers down just because they don't like us. */
}
- if (conn->purpose == DIR_PURPOSE_FETCH_RENDDESC) {
+ if (conn->_base.purpose == DIR_PURPOSE_FETCH_RENDDESC) {
log_info(LD_REND,"Received rendezvous descriptor (size %d, status %d "
"(%s))",
(int)body_len, status_code, escaped(reason));
@@ -1145,7 +1146,7 @@ connection_dir_client_reached_eof(connection_t *conn)
* cleans it up */
} else {
/* success. notify pending connections about this. */
- conn->purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
+ conn->_base.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
rend_client_desc_here(conn->rend_query);
}
break;
@@ -1161,12 +1162,12 @@ connection_dir_client_reached_eof(connection_t *conn)
default:
log_warn(LD_REND,"http status %d (%s) response unexpected (server "
"'%s:%d').",
- status_code, escaped(reason), conn->address, conn->port);
+ status_code, escaped(reason), conn->_base.address, conn->_base.port);
break;
}
}
- if (conn->purpose == DIR_PURPOSE_UPLOAD_RENDDESC) {
+ if (conn->_base.purpose == DIR_PURPOSE_UPLOAD_RENDDESC) {
switch (status_code) {
case 200:
log_info(LD_REND,
@@ -1176,12 +1177,12 @@ connection_dir_client_reached_eof(connection_t *conn)
case 400:
log_warn(LD_REND,"http status 400 (%s) response from dirserver "
"'%s:%d'. Malformed rendezvous descriptor?",
- escaped(reason), conn->address, conn->port);
+ escaped(reason), conn->_base.address, conn->_base.port);
break;
default:
log_warn(LD_REND,"http status %d (%s) response unexpected (server "
"'%s:%d').",
- status_code, escaped(reason), conn->address, conn->port);
+ status_code, escaped(reason), conn->_base.address, conn->_base.port);
break;
}
}
@@ -1191,20 +1192,20 @@ connection_dir_client_reached_eof(connection_t *conn)
/** Called when a directory connection reaches EOF */
int
-connection_dir_reached_eof(connection_t *conn)
+connection_dir_reached_eof(dir_connection_t *conn)
{
int retval;
- if (conn->state != DIR_CONN_STATE_CLIENT_READING) {
+ if (conn->_base.state != DIR_CONN_STATE_CLIENT_READING) {
log_info(LD_HTTP,"conn reached eof, not reading. Closing.");
- connection_close_immediate(conn); /* error: give up on flushing */
- connection_mark_for_close(conn);
+ connection_close_immediate(TO_CONN(conn)); /* error: give up on flushing */
+ connection_mark_for_close(TO_CONN(conn));
return -1;
}
retval = connection_dir_client_reached_eof(conn);
if (retval == 0) /* success */
- conn->state = DIR_CONN_STATE_CLIENT_FINISHED;
- connection_mark_for_close(conn);
+ conn->_base.state = DIR_CONN_STATE_CLIENT_FINISHED;
+ connection_mark_for_close(TO_CONN(conn));
return retval;
}
@@ -1212,10 +1213,10 @@ connection_dir_reached_eof(connection_t *conn)
* directory servers and connections <em>at</em> directory servers.)
*/
int
-connection_dir_process_inbuf(connection_t *conn)
+connection_dir_process_inbuf(dir_connection_t *conn)
{
tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_DIR);
+ tor_assert(conn->_base.type == CONN_TYPE_DIR);
/* Directory clients write, then read data until they receive EOF;
* directory servers read data until they get an HTTP command, then
@@ -1224,9 +1225,9 @@ connection_dir_process_inbuf(connection_t *conn)
*/
/* If we're on the dirserver side, look for a command. */
- if (conn->state == DIR_CONN_STATE_SERVER_COMMAND_WAIT) {
+ if (conn->_base.state == DIR_CONN_STATE_SERVER_COMMAND_WAIT) {
if (directory_handle_command(conn) < 0) {
- connection_mark_for_close(conn);
+ connection_mark_for_close(TO_CONN(conn));
return -1;
}
return 0;
@@ -1234,7 +1235,7 @@ connection_dir_process_inbuf(connection_t *conn)
/* XXX for READ states, might want to make sure inbuf isn't too big */
- if (!conn->inbuf_reached_eof)
+ if (!conn->_base.inbuf_reached_eof)
log_debug(LD_HTTP,"Got data, not eof. Leaving on inbuf.");
return 0;
}
@@ -1243,7 +1244,7 @@ connection_dir_process_inbuf(connection_t *conn)
* <b>status</b> and <b>reason_phrase</b>. Write it to <b>conn</b>.
*/
static void
-write_http_status_line(connection_t *conn, int status,
+write_http_status_line(dir_connection_t *conn, int status,
const char *reason_phrase)
{
char buf[256];
@@ -1252,12 +1253,12 @@ write_http_status_line(connection_t *conn, int status,
log_warn(LD_BUG,"Bug: status line too long.");
return;
}
- connection_write_to_buf(buf, strlen(buf), conn);
+ connection_write_to_buf(buf, strlen(buf), TO_CONN(conn));
}
/** DOCDOC */
static void
-write_http_response_header(connection_t *conn, ssize_t length,
+write_http_response_header(dir_connection_t *conn, ssize_t length,
const char *type, const char *encoding)
{
char date[RFC1123_TIME_LEN+1];
@@ -1272,7 +1273,7 @@ write_http_response_header(connection_t *conn, ssize_t length,
tor_snprintf(cp, sizeof(tmp),
"HTTP/1.0 200 OK\r\nDate: %s\r\nContent-Type: %s\r\n"
X_ADDRESS_HEADER "%s\r\n",
- date, type, conn->address);
+ date, type, conn->_base.address);
cp += strlen(tmp);
if (encoding) {
tor_snprintf(cp, sizeof(tmp)-(cp-tmp),
@@ -1288,7 +1289,7 @@ write_http_response_header(connection_t *conn, ssize_t length,
memcpy(cp, "\r\n", 3);
else
tor_assert(0);
- connection_write_to_buf(tmp, strlen(tmp), conn);
+ connection_write_to_buf(tmp, strlen(tmp), TO_CONN(conn));
}
/** Helper function: return 1 if there are any dir conns of purpose
@@ -1308,7 +1309,7 @@ already_fetching_directory(int purpose)
if (conn->type == CONN_TYPE_DIR &&
conn->purpose == purpose &&
!conn->marked_for_close &&
- !router_digest_is_me(conn->identity_digest))
+ !router_digest_is_me(TO_DIR_CONN(conn)->identity_digest))
return 1;
}
return 0;
@@ -1389,7 +1390,7 @@ directory_dump_request_log(void)
* conn-\>outbuf. If the request is unrecognized, send a 400.
* Always return 0. */
static int
-directory_handle_command_get(connection_t *conn, char *headers,
+directory_handle_command_get(dir_connection_t *conn, char *headers,
char *body, size_t body_len)
{
size_t dlen;
@@ -1401,7 +1402,7 @@ directory_handle_command_get(connection_t *conn, char *headers,
log_debug(LD_DIRSERV,"Received GET command.");
- conn->state = DIR_CONN_STATE_SERVER_WRITING;
+ conn->_base.state = DIR_CONN_STATE_SERVER_WRITING;
if (parse_http_url(headers, &url) < 0) {
write_http_status_line(conn, 400, "Bad request");
@@ -1471,7 +1472,7 @@ directory_handle_command_get(connection_t *conn, char *headers,
write_http_response_header(conn, dlen,
deflated?"application/octet-stream":"text/plain",
deflated?"deflate":"identity");
- connection_write_to_buf(cp, strlen(cp), conn);
+ connection_write_to_buf(cp, strlen(cp), TO_CONN(conn));
return 0;
}
@@ -1583,7 +1584,7 @@ directory_handle_command_get(connection_t *conn, char *headers,
NULL);
note_request("/tor/rendezvous?/", desc_len);
/* need to send descp separately, because it may include nuls */
- connection_write_to_buf(descp, desc_len, conn);
+ connection_write_to_buf(descp, desc_len, TO_CONN(conn));
break;
case 0: /* well-formed but not present */
write_http_status_line(conn, 404, "Not found");
@@ -1600,7 +1601,7 @@ directory_handle_command_get(connection_t *conn, char *headers,
char *bytes = directory_dump_request_log();
size_t len = strlen(bytes);
write_http_response_header(conn, len, "text/plain", NULL);
- connection_write_to_buf(bytes, len, conn);
+ connection_write_to_buf(bytes, len, TO_CONN(conn));
tor_free(bytes);
tor_free(url);
return 0;
@@ -1611,12 +1612,12 @@ directory_handle_command_get(connection_t *conn, char *headers,
char robots[] = "User-agent: *\r\nDisallow: /\r\n";
size_t len = strlen(robots);
write_http_response_header(conn, len, "text/plain", NULL);
- connection_write_to_buf(robots, len, conn);
+ connection_write_to_buf(robots, len, TO_CONN(conn));
tor_free(url);
return 0;
}
- if (!strcmp(url,"/tor/dir-all-weaselhack") && (conn->addr == 0x7f000001ul) &&
+ if (!strcmp(url,"/tor/dir-all-weaselhack") && (conn->_base.addr == 0x7f000001ul) &&
authdir_mode(get_options())) {
/* XXX until weasel rewrites his scripts XXXX012 */
char *new_directory=NULL;
@@ -1633,7 +1634,7 @@ directory_handle_command_get(connection_t *conn, char *headers,
write_http_response_header(conn, dlen, "text/plain", "identity");
- connection_write_to_buf(new_directory, dlen, conn);
+ connection_write_to_buf(new_directory, dlen, TO_CONN(conn));
tor_free(new_directory);
tor_free(url);
return 0;
@@ -1651,14 +1652,14 @@ directory_handle_command_get(connection_t *conn, char *headers,
* response into conn-\>outbuf. If the request is unrecognized, send a
* 400. Always return 0. */
static int
-directory_handle_command_post(connection_t *conn, char *headers,
+directory_handle_command_post(dir_connection_t *conn, char *headers,
char *body, size_t body_len)
{
char *url = NULL;
log_debug(LD_DIRSERV,"Received POST command.");
- conn->state = DIR_CONN_STATE_SERVER_WRITING;
+ conn->_base.state = DIR_CONN_STATE_SERVER_WRITING;
if (!authdir_mode(get_options())) {
/* we just provide cached directories; we don't want to
@@ -1685,7 +1686,7 @@ directory_handle_command_post(connection_t *conn, char *headers,
case -1:
case 1:
log_notice(LD_DIRSERV,"Rejected router descriptor from %s.",
- conn->address);
+ conn->_base.address);
/* malformed descriptor, or something wrong */
write_http_status_line(conn, 400, msg);
break;
@@ -1703,7 +1704,7 @@ directory_handle_command_post(connection_t *conn, char *headers,
// char tmp[1024*2+1];
log_fn(LOG_PROTOCOL_WARN, LD_DIRSERV,
"Rejected rend descriptor (length %d) from %s.",
- (int)body_len, conn->address);
+ (int)body_len, conn->_base.address);
#if 0
if (body_len <= 1024) {
base16_encode(tmp, sizeof(tmp), body, body_len);
@@ -1731,21 +1732,21 @@ directory_handle_command_post(connection_t *conn, char *headers,
* buffer. Return a 0 on success, or -1 on error.
*/
static int
-directory_handle_command(connection_t *conn)
+directory_handle_command(dir_connection_t *conn)
{
char *headers=NULL, *body=NULL;
size_t body_len=0;
int r;
tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_DIR);
+ tor_assert(conn->_base.type == CONN_TYPE_DIR);
- switch (fetch_from_buf_http(conn->inbuf,
+ switch (fetch_from_buf_http(conn->_base.inbuf,
&headers, MAX_HEADERS_SIZE,
&body, &body_len, MAX_BODY_SIZE, 0)) {
case -1: /* overflow */
log_warn(LD_DIRSERV,
- "Invalid input from address '%s'. Closing.", conn->address);
+ "Invalid input from address '%s'. Closing.", conn->_base.address);
return -1;
case 0:
log_debug(LD_DIRSERV,"command not all here yet.");
@@ -1753,7 +1754,7 @@ directory_handle_command(connection_t *conn)
/* case 1, fall through */
}
- http_set_address_origin(headers, conn);
+ http_set_address_origin(headers, TO_CONN(conn));
//log_debug(LD_DIRSERV,"headers %s, body %s.", headers, body);
if (!strncasecmp(headers,"GET",3))
@@ -1776,23 +1777,23 @@ directory_handle_command(connection_t *conn)
* appropriate.
*/
int
-connection_dir_finished_flushing(connection_t *conn)
+connection_dir_finished_flushing(dir_connection_t *conn)
{
tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_DIR);
+ tor_assert(conn->_base.type == CONN_TYPE_DIR);
- switch (conn->state) {
+ switch (conn->_base.state) {
case DIR_CONN_STATE_CLIENT_SENDING:
log_debug(LD_DIR,"client finished sending command.");
- conn->state = DIR_CONN_STATE_CLIENT_READING;
- connection_stop_writing(conn);
+ conn->_base.state = DIR_CONN_STATE_CLIENT_READING;
+ connection_stop_writing(TO_CONN(conn));
return 0;
case DIR_CONN_STATE_SERVER_WRITING:
log_debug(LD_DIRSERV,"Finished writing server response. Closing.");
- connection_mark_for_close(conn);
+ connection_mark_for_close(TO_CONN(conn));
return 0;
default:
- log_warn(LD_BUG,"Bug: called in unexpected state %d.", conn->state);
+ log_warn(LD_BUG,"Bug: called in unexpected state %d.", conn->_base.state);
tor_fragile_assert();
return -1;
}
@@ -1802,16 +1803,16 @@ connection_dir_finished_flushing(connection_t *conn)
/** Connected handler for directory connections: begin sending data to the
* server */
int
-connection_dir_finished_connecting(connection_t *conn)
+connection_dir_finished_connecting(dir_connection_t *conn)
{
tor_assert(conn);
- tor_assert(conn->type == CONN_TYPE_DIR);
- tor_assert(conn->state == DIR_CONN_STATE_CONNECTING);
+ tor_assert(conn->_base.type == CONN_TYPE_DIR);
+ tor_assert(conn->_base.state == DIR_CONN_STATE_CONNECTING);
log_debug(LD_HTTP,"Dir connection to router %s:%u established.",
- conn->address,conn->port);
+ conn->_base.address,conn->_base.port);
- conn->state = DIR_CONN_STATE_CLIENT_SENDING; /* start flushing conn */
+ conn->_base.state = DIR_CONN_STATE_CLIENT_SENDING; /* start flushing conn */
return 0;
}
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index c17bbafe80..6a07d3ca54 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -1825,7 +1825,7 @@ dirserv_test_reachability(int try_all)
#define DIRSERV_BUFFER_MIN 16384
static int
-connection_dirserv_finish_spooling(connection_t *conn)
+connection_dirserv_finish_spooling(dir_connection_t *conn)
{
if (conn->zlib_state) {
connection_write_to_buf_zlib(conn, conn->zlib_state, "", 0, 1);
@@ -1838,12 +1838,12 @@ connection_dirserv_finish_spooling(connection_t *conn)
/** DOCDOC */
static int
-connection_dirserv_add_servers_to_outbuf(connection_t *conn)
+connection_dirserv_add_servers_to_outbuf(dir_connection_t *conn)
{
int by_fp = conn->dir_spool_src == DIR_SPOOL_SERVER_BY_FP;
while (smartlist_len(conn->fingerprint_stack) &&
- buf_datalen(conn->outbuf) < DIRSERV_BUFFER_MIN) {
+ buf_datalen(conn->_base.outbuf) < DIRSERV_BUFFER_MIN) {
const char *body;
char *fp = smartlist_pop_last(conn->fingerprint_stack);
signed_descriptor_t *sd = NULL;
@@ -1875,7 +1875,7 @@ connection_dirserv_add_servers_to_outbuf(connection_t *conn)
} else {
connection_write_to_buf(body,
sd->signed_descriptor_len,
- conn);
+ TO_CONN(conn));
}
}
@@ -1890,11 +1890,11 @@ connection_dirserv_add_servers_to_outbuf(connection_t *conn)
/** DOCDOC */
static int
-connection_dirserv_add_dir_bytes_to_outbuf(connection_t *conn)
+connection_dirserv_add_dir_bytes_to_outbuf(dir_connection_t *conn)
{
int bytes, remaining;
- bytes = DIRSERV_BUFFER_MIN - buf_datalen(conn->outbuf);
+ bytes = DIRSERV_BUFFER_MIN - buf_datalen(conn->_base.outbuf);
tor_assert(bytes > 0);
tor_assert(conn->cached_dir);
if (bytes < 8192)
@@ -1909,7 +1909,7 @@ connection_dirserv_add_dir_bytes_to_outbuf(connection_t *conn)
bytes, bytes == remaining);
} else {
connection_write_to_buf(conn->cached_dir->dir_z + conn->cached_dir_offset,
- bytes, conn);
+ bytes, TO_CONN(conn));
}
conn->cached_dir_offset += bytes;
if (conn->cached_dir_offset == (int)conn->cached_dir->dir_z_len) {
@@ -1923,10 +1923,10 @@ connection_dirserv_add_dir_bytes_to_outbuf(connection_t *conn)
/* DOCDOC */
static int
-connection_dirserv_add_networkstatus_bytes_to_outbuf(connection_t *conn)
+connection_dirserv_add_networkstatus_bytes_to_outbuf(dir_connection_t *conn)
{
- while (buf_datalen(conn->outbuf) < DIRSERV_BUFFER_MIN) {
+ while (buf_datalen(conn->_base.outbuf) < DIRSERV_BUFFER_MIN) {
if (conn->cached_dir) {
int uncompressing = (conn->zlib_state != NULL);
int r = connection_dirserv_add_dir_bytes_to_outbuf(conn);
@@ -1973,13 +1973,12 @@ connection_dirserv_add_networkstatus_bytes_to_outbuf(connection_t *conn)
/** Called whenever we have flushed some directory data in state
* SERVER_WRITING. */
int
-connection_dirserv_flushed_some(connection_t *conn)
+connection_dirserv_flushed_some(dir_connection_t *conn)
{
- tor_assert(conn->type == CONN_TYPE_DIR);
- tor_assert(conn->state == DIR_CONN_STATE_SERVER_WRITING);
+ tor_assert(conn->_base.state == DIR_CONN_STATE_SERVER_WRITING);
if (conn->dir_spool_src == DIR_SPOOL_NONE
- || buf_datalen(conn->outbuf) >= DIRSERV_BUFFER_MIN)
+ || buf_datalen(conn->_base.outbuf) >= DIRSERV_BUFFER_MIN)
return 0;
switch (conn->dir_spool_src) {
diff --git a/src/or/dns.c b/src/or/dns.c
index 3844741ee0..ee38480aca 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -53,7 +53,7 @@ static time_t last_rotation_time=0;
/** Linked list of connections waiting for a DNS answer. */
typedef struct pending_connection_t {
- connection_t *conn;
+ edge_connection_t *conn;
struct pending_connection_t *next;
} pending_connection_t;
@@ -83,8 +83,8 @@ static void purge_expired_resolves(uint32_t now);
static void dns_purge_resolve(cached_resolve_t *resolve);
static void dns_found_answer(const char *address, uint32_t addr, char outcome,
uint32_t ttl);
-static void send_resolved_cell(connection_t *conn, uint8_t answer_type);
-static int assign_to_dnsworker(connection_t *exitconn);
+static void send_resolved_cell(edge_connection_t *conn, uint8_t answer_type);
+static int assign_to_dnsworker(edge_connection_t *exitconn);
#ifndef USE_EVENTDNS
static int dnsworker_main(void *data);
static int spawn_dnsworker(void);
@@ -226,7 +226,7 @@ purge_expired_resolves(uint32_t now)
{
cached_resolve_t *resolve;
pending_connection_t *pend;
- connection_t *pendconn;
+ edge_connection_t *pendconn;
/* this is fast because the linked list
* oldest_cached_resolve is ordered by when they came in.
@@ -251,12 +251,12 @@ purge_expired_resolves(uint32_t now)
pend = resolve->pending_connections;
resolve->pending_connections = pend->next;
/* Connections should only be pending if they have no socket. */
- tor_assert(pend->conn->s == -1);
+ tor_assert(pend->conn->_base.s == -1);
pendconn = pend->conn;
connection_edge_end(pendconn, END_STREAM_REASON_TIMEOUT,
pendconn->cpath_layer);
circuit_detach_stream(circuit_get_by_edge_conn(pendconn), pendconn);
- connection_free(pendconn);
+ connection_free(TO_CONN(pendconn));
tor_free(pend);
}
}
@@ -273,7 +273,7 @@ purge_expired_resolves(uint32_t now)
/** Send a response to the RESOVLE request of a connection. answer_type must
* be one of RESOLVED_TYPE_(IPV4|ERROR|ERROR_TRANSIENT) */
static void
-send_resolved_cell(connection_t *conn, uint8_t answer_type)
+send_resolved_cell(edge_connection_t *conn, uint8_t answer_type)
{
char buf[RELAY_PAYLOAD_SIZE];
size_t buflen;
@@ -286,7 +286,7 @@ send_resolved_cell(connection_t *conn, uint8_t answer_type)
{
case RESOLVED_TYPE_IPV4:
buf[1] = 4;
- set_uint32(buf+2, htonl(conn->addr));
+ set_uint32(buf+2, htonl(conn->_base.addr));
set_uint32(buf+6, htonl(ttl));
buflen = 10;
break;
@@ -337,7 +337,7 @@ insert_resolve(cached_resolve_t *r)
* dns farm, and return 0.
*/
int
-dns_resolve(connection_t *exitconn)
+dns_resolve(edge_connection_t *exitconn)
{
cached_resolve_t *resolve;
cached_resolve_t search;
@@ -345,17 +345,17 @@ dns_resolve(connection_t *exitconn)
struct in_addr in;
circuit_t *circ;
uint32_t now = time(NULL);
- assert_connection_ok(exitconn, 0);
- tor_assert(exitconn->s == -1);
+ assert_connection_ok(TO_CONN(exitconn), 0);
+ tor_assert(exitconn->_base.s == -1);
assert_cache_ok();
- /* first check if exitconn->address is an IP. If so, we already
+ /* first check if exitconn->_base.address is an IP. If so, we already
* know the answer. */
- if (tor_inet_aton(exitconn->address, &in) != 0) {
- exitconn->addr = ntohl(in.s_addr);
+ if (tor_inet_aton(exitconn->_base.address, &in) != 0) {
+ exitconn->_base.addr = ntohl(in.s_addr);
exitconn->address_ttl = DEFAULT_DNS_TTL;
- if (exitconn->purpose == EXIT_PURPOSE_RESOLVE)
+ if (exitconn->_base.purpose == EXIT_PURPOSE_RESOLVE)
send_resolved_cell(exitconn, RESOLVED_TYPE_IPV4);
return 1;
}
@@ -364,11 +364,11 @@ dns_resolve(connection_t *exitconn)
* resolves in the hash table. */
purge_expired_resolves(now);
- /* lower-case exitconn->address, so it's in canonical form */
- tor_strlower(exitconn->address);
+ /* lower-case exitconn->_base.address, so it's in canonical form */
+ tor_strlower(exitconn->_base.address);
/* now check the hash table to see if 'address' is already there. */
- strlcpy(search.address, exitconn->address, sizeof(search.address));
+ strlcpy(search.address, exitconn->_base.address, sizeof(search.address));
resolve = HT_FIND(cache_map, &cache_root, &search);
if (resolve && resolve->expire > now) { /* already there */
switch (resolve->state) {
@@ -381,27 +381,27 @@ dns_resolve(connection_t *exitconn)
resolve->pending_connections = pending_connection;
log_debug(LD_EXIT,"Connection (fd %d) waiting for pending DNS "
"resolve of %s",
- exitconn->s, escaped_safe_str(exitconn->address));
- exitconn->state = EXIT_CONN_STATE_RESOLVING;
+ exitconn->_base.s, escaped_safe_str(exitconn->_base.address));
+ exitconn->_base.state = EXIT_CONN_STATE_RESOLVING;
return 0;
case CACHE_STATE_VALID:
- exitconn->addr = resolve->addr;
+ exitconn->_base.addr = resolve->addr;
exitconn->address_ttl = resolve->ttl;
log_debug(LD_EXIT,"Connection (fd %d) found cached answer for %s",
- exitconn->s, escaped_safe_str(exitconn->address));
- if (exitconn->purpose == EXIT_PURPOSE_RESOLVE)
+ exitconn->_base.s, escaped_safe_str(exitconn->_base.address));
+ if (exitconn->_base.purpose == EXIT_PURPOSE_RESOLVE)
send_resolved_cell(exitconn, RESOLVED_TYPE_IPV4);
return 1;
case CACHE_STATE_FAILED:
log_debug(LD_EXIT,"Connection (fd %d) found cached error for %s",
- exitconn->s, escaped_safe_str(exitconn->address));
- if (exitconn->purpose == EXIT_PURPOSE_RESOLVE)
+ exitconn->_base.s, escaped_safe_str(exitconn->_base.address));
+ if (exitconn->_base.purpose == EXIT_PURPOSE_RESOLVE)
send_resolved_cell(exitconn, RESOLVED_TYPE_ERROR);
circ = circuit_get_by_edge_conn(exitconn);
if (circ)
circuit_detach_stream(circ, exitconn);
- if (!exitconn->marked_for_close)
- connection_free(exitconn);
+ if (!exitconn->_base.marked_for_close)
+ connection_free(TO_CONN(exitconn));
return -1;
}
tor_assert(0);
@@ -411,17 +411,17 @@ dns_resolve(connection_t *exitconn)
resolve->magic = CACHED_RESOLVE_MAGIC;
resolve->state = CACHE_STATE_PENDING;
resolve->expire = now + DEFAULT_DNS_TTL; /* this will get replaced. */
- strlcpy(resolve->address, exitconn->address, sizeof(resolve->address));
+ strlcpy(resolve->address, exitconn->_base.address, sizeof(resolve->address));
/* add us to the pending list */
pending_connection = tor_malloc_zero(sizeof(pending_connection_t));
pending_connection->conn = exitconn;
resolve->pending_connections = pending_connection;
- exitconn->state = EXIT_CONN_STATE_RESOLVING;
+ exitconn->_base.state = EXIT_CONN_STATE_RESOLVING;
insert_resolve(resolve);
log_debug(LD_EXIT,"Assigning question %s to dnsworker.",
- escaped_safe_str(exitconn->address));
+ escaped_safe_str(exitconn->_base.address));
assert_cache_ok();
return assign_to_dnsworker(exitconn);
}
@@ -429,7 +429,7 @@ dns_resolve(connection_t *exitconn)
/** Log an error and abort if conn is waiting for a DNS resolve.
*/
void
-assert_connection_edge_not_dns_pending(connection_t *conn)
+assert_connection_edge_not_dns_pending(edge_connection_t *conn)
{
pending_connection_t *pend;
cached_resolve_t **resolve;
@@ -455,9 +455,9 @@ assert_all_pending_dns_resolves_ok(void)
for (pend = (*resolve)->pending_connections;
pend;
pend = pend->next) {
- assert_connection_ok(pend->conn, 0);
- tor_assert(pend->conn->s == -1);
- tor_assert(!connection_in_array(pend->conn));
+ assert_connection_ok(TO_CONN(pend->conn), 0);
+ tor_assert(pend->conn->_base.s == -1);
+ tor_assert(!connection_in_array(TO_CONN(pend->conn)));
}
}
}
@@ -465,26 +465,26 @@ assert_all_pending_dns_resolves_ok(void)
/** Remove <b>conn</b> from the list of connections waiting for conn-\>address.
*/
void
-connection_dns_remove(connection_t *conn)
+connection_dns_remove(edge_connection_t *conn)
{
pending_connection_t *pend, *victim;
cached_resolve_t search;
cached_resolve_t *resolve;
- tor_assert(conn->type == CONN_TYPE_EXIT);
- tor_assert(conn->state == EXIT_CONN_STATE_RESOLVING);
+ tor_assert(conn->_base.type == CONN_TYPE_EXIT);
+ tor_assert(conn->_base.state == EXIT_CONN_STATE_RESOLVING);
- strlcpy(search.address, conn->address, sizeof(search.address));
+ strlcpy(search.address, conn->_base.address, sizeof(search.address));
resolve = HT_FIND(cache_map, &cache_root, &search);
if (!resolve) {
log_notice(LD_BUG, "Address %s is not pending. Dropping.",
- escaped_safe_str(conn->address));
+ escaped_safe_str(conn->_base.address));
return;
}
tor_assert(resolve->pending_connections);
- assert_connection_ok(conn,0);
+ assert_connection_ok(TO_CONN(conn),0);
pend = resolve->pending_connections;
@@ -493,7 +493,7 @@ connection_dns_remove(connection_t *conn)
tor_free(pend);
log_debug(LD_EXIT, "First connection (fd %d) no longer waiting "
"for resolve of %s",
- conn->s, escaped_safe_str(conn->address));
+ conn->_base.s, escaped_safe_str(conn->_base.address));
return;
} else {
for ( ; pend->next; pend = pend->next) {
@@ -503,7 +503,7 @@ connection_dns_remove(connection_t *conn)
tor_free(victim);
log_debug(LD_EXIT,
"Connection (fd %d) no longer waiting for resolve of %s",
- conn->s, escaped_safe_str(conn->address));
+ conn->_base.s, escaped_safe_str(conn->_base.address));
return; /* more are pending */
}
}
@@ -521,7 +521,7 @@ dns_cancel_pending_resolve(char *address)
pending_connection_t *pend;
cached_resolve_t search;
cached_resolve_t *resolve;
- connection_t *pendconn;
+ edge_connection_t *pendconn;
circuit_t *circ;
strlcpy(search.address, address, sizeof(search.address));
@@ -549,18 +549,18 @@ dns_cancel_pending_resolve(char *address)
escaped_safe_str(address));
while (resolve->pending_connections) {
pend = resolve->pending_connections;
- pend->conn->state = EXIT_CONN_STATE_RESOLVEFAILED;
+ pend->conn->_base.state = EXIT_CONN_STATE_RESOLVEFAILED;
pendconn = pend->conn;
- assert_connection_ok(pendconn, 0);
- tor_assert(pendconn->s == -1);
- if (!pendconn->marked_for_close) {
+ assert_connection_ok(TO_CONN(pendconn), 0);
+ tor_assert(pendconn->_base.s == -1);
+ if (!pendconn->_base.marked_for_close) {
connection_edge_end(pendconn, END_STREAM_REASON_RESOURCELIMIT,
pendconn->cpath_layer);
}
circ = circuit_get_by_edge_conn(pendconn);
if (circ)
circuit_detach_stream(circ, pendconn);
- connection_free(pendconn);
+ connection_free(TO_CONN(pendconn));
resolve->pending_connections = pend->next;
tor_free(pend);
}
@@ -612,7 +612,7 @@ dns_found_answer(const char *address, uint32_t addr, char outcome,
pending_connection_t *pend;
cached_resolve_t search;
cached_resolve_t *resolve;
- connection_t *pendconn;
+ edge_connection_t *pendconn;
circuit_t *circ;
assert_cache_ok();
@@ -659,16 +659,16 @@ dns_found_answer(const char *address, uint32_t addr, char outcome,
while (resolve->pending_connections) {
pend = resolve->pending_connections;
- assert_connection_ok(pend->conn,time(NULL));
- pend->conn->addr = resolve->addr;
+ assert_connection_ok(TO_CONN(pend->conn),time(NULL));
+ pend->conn->_base.addr = resolve->addr;
pend->conn->address_ttl = resolve->ttl;
pendconn = pend->conn; /* don't pass complex things to the
connection_mark_for_close macro */
if (resolve->state == CACHE_STATE_FAILED) {
/* prevent double-remove. */
- pendconn->state = EXIT_CONN_STATE_RESOLVEFAILED;
- if (pendconn->purpose == EXIT_PURPOSE_CONNECT) {
+ pendconn->_base.state = EXIT_CONN_STATE_RESOLVEFAILED;
+ if (pendconn->_base.purpose == EXIT_PURPOSE_CONNECT) {
connection_edge_end(pendconn, END_STREAM_REASON_RESOLVEFAILED,
pendconn->cpath_layer);
/* This detach must happen after we send the end cell. */
@@ -678,11 +678,11 @@ dns_found_answer(const char *address, uint32_t addr, char outcome,
/* This detach must happen after we send the resolved cell. */
circuit_detach_stream(circuit_get_by_edge_conn(pendconn), pendconn);
}
- connection_free(pendconn);
+ connection_free(TO_CONN(pendconn));
} else {
- if (pendconn->purpose == EXIT_PURPOSE_CONNECT) {
+ if (pendconn->_base.purpose == EXIT_PURPOSE_CONNECT) {
/* prevent double-remove. */
- pend->conn->state = EXIT_CONN_STATE_CONNECTING;
+ pend->conn->_base.state = EXIT_CONN_STATE_CONNECTING;
circ = circuit_get_by_edge_conn(pend->conn);
tor_assert(circ);
@@ -698,12 +698,12 @@ dns_found_answer(const char *address, uint32_t addr, char outcome,
} else {
/* prevent double-remove. This isn't really an accurate state,
* but it does the right thing. */
- pendconn->state = EXIT_CONN_STATE_RESOLVEFAILED;
+ pendconn->_base.state = EXIT_CONN_STATE_RESOLVEFAILED;
send_resolved_cell(pendconn, RESOLVED_TYPE_IPV4);
circ = circuit_get_by_edge_conn(pendconn);
tor_assert(circ);
circuit_detach_stream(circ, pendconn);
- connection_free(pendconn);
+ connection_free(TO_CONN(pendconn));
}
}
resolve->pending_connections = pend->next;
@@ -722,14 +722,14 @@ dns_found_answer(const char *address, uint32_t addr, char outcome,
* <b>exitconn</b>-\>address; tell that dns worker to begin resolving.
*/
static int
-assign_to_dnsworker(connection_t *exitconn)
+assign_to_dnsworker(edge_connection_t *exitconn)
{
connection_t *dnsconn;
unsigned char len;
- tor_assert(exitconn->state == EXIT_CONN_STATE_RESOLVING);
- assert_connection_ok(exitconn, 0);
- tor_assert(exitconn->s == -1);
+ tor_assert(exitconn->_base.state == EXIT_CONN_STATE_RESOLVING);
+ assert_connection_ok(TO_CONN(exitconn), 0);
+ tor_assert(exitconn->_base.s == -1);
/* respawn here, to be sure there are enough */
if (spawn_enough_dnsworkers() < 0) {
@@ -741,18 +741,18 @@ assign_to_dnsworker(connection_t *exitconn)
if (!dnsconn) {
log_warn(LD_EXIT,"no idle dns workers. Failing.");
- if (exitconn->purpose == EXIT_PURPOSE_RESOLVE)
+ if (exitconn->_base.purpose == EXIT_PURPOSE_RESOLVE)
send_resolved_cell(exitconn, RESOLVED_TYPE_ERROR_TRANSIENT);
goto err;
}
log_debug(LD_EXIT,
"Connection (fd %d) needs to resolve %s; assigning "
- "to DNSWorker (fd %d)", exitconn->s,
- escaped_safe_str(exitconn->address), dnsconn->s);
+ "to DNSWorker (fd %d)", exitconn->_base.s,
+ escaped_safe_str(exitconn->_base.address), dnsconn->s);
tor_free(dnsconn->address);
- dnsconn->address = tor_strdup(exitconn->address);
+ dnsconn->address = tor_strdup(exitconn->_base.address);
dnsconn->state = DNSWORKER_STATE_BUSY;
/* touch the lastwritten timestamp, since that's how we check to
* see how long it's been since we asked the question, and sometimes
@@ -766,7 +766,7 @@ assign_to_dnsworker(connection_t *exitconn)
return 0;
err:
- dns_cancel_pending_resolve(exitconn->address); /* also sends end and frees */
+ dns_cancel_pending_resolve(exitconn->_base.address); /* also sends end and frees */
return -1;
}
@@ -1172,11 +1172,11 @@ eventdns_callback(int result, char type, int count, int ttl, void *addresses,
static int
assign_to_dnsworker(connection_t *exitconn)
{
- char *addr = tor_strdup(exitconn->address);
+ char *addr = tor_strdup(exitconn->_base.address);
int r;
log_info(LD_EXIT, "Launching eventdns request for %s",
- escaped_safe_str(exitconn->address));
- r = eventdns_resolve(exitconn->address, DNS_QUERY_NO_SEARCH,
+ escaped_safe_str(exitconn->_base.address));
+ r = eventdns_resolve(exitconn->_base.address, DNS_QUERY_NO_SEARCH,
eventdns_callback, addr);
if (r) {
log_warn(LD_EXIT, "eventdns rejected address %s: error %d.",
diff --git a/src/or/hibernate.c b/src/or/hibernate.c
index 5f1131da71..a1aca0327a 100644
--- a/src/or/hibernate.c
+++ b/src/or/hibernate.c
@@ -786,11 +786,12 @@ hibernate_go_dormant(time_t now)
(conn = connection_get_by_type(CONN_TYPE_AP)) ||
(conn = connection_get_by_type(CONN_TYPE_EXIT))) {
if (CONN_IS_EDGE(conn))
- connection_edge_end(conn, END_STREAM_REASON_HIBERNATING,
- conn->cpath_layer);
+ connection_edge_end(TO_EDGE_CONN(conn), END_STREAM_REASON_HIBERNATING,
+ TO_EDGE_CONN(conn)->cpath_layer);
log_info(LD_NET,"Closing conn type %d", conn->type);
if (conn->type == CONN_TYPE_AP) /* send socks failure if needed */
- connection_mark_unattached_ap(conn, END_STREAM_REASON_HIBERNATING);
+ connection_mark_unattached_ap(TO_EDGE_CONN(conn),
+ END_STREAM_REASON_HIBERNATING);
else
connection_mark_for_close(conn);
}
diff --git a/src/or/main.c b/src/or/main.c
index 180b15030f..80516d34e8 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -212,11 +212,11 @@ connection_unlink(connection_t *conn, int remove)
}
smartlist_remove(closeable_connection_lst, conn);
if (conn->type == CONN_TYPE_EXIT) {
- assert_connection_edge_not_dns_pending(conn);
+ assert_connection_edge_not_dns_pending(TO_EDGE_CONN(conn));
}
- if (conn->type == CONN_TYPE_OR &&
- !tor_digest_is_zero(conn->identity_digest)) {
- connection_or_remove_from_identity_map(conn);
+ if (conn->type == CONN_TYPE_OR) {
+ if (!tor_digest_is_zero(TO_OR_CONN(conn)->identity_digest))
+ connection_or_remove_from_identity_map(TO_OR_CONN(conn));
}
connection_free(conn);
}
@@ -413,7 +413,8 @@ conn_read_callback(int fd, short event, void *_conn)
tor_fragile_assert();
#endif
if (CONN_IS_EDGE(conn))
- connection_edge_end_errno(conn, conn->cpath_layer);
+ connection_edge_end_errno(TO_EDGE_CONN(conn),
+ TO_EDGE_CONN(conn)->cpath_layer);
connection_mark_for_close(conn);
}
}
@@ -443,7 +444,8 @@ conn_write_callback(int fd, short events, void *_conn)
"Bug: unhandled error on write for %s connection (fd %d); removing",
conn_type_to_string(conn->type), conn->s);
tor_fragile_assert();
- conn->has_sent_end = 1; /* otherwise we cry wolf about duplicate close */
+ if (CONN_IS_EDGE(conn))
+ conn->edge_has_sent_end = 1; /* otherwise we cry wolf about duplicate close */
/* XXX do we need a close-immediate here, so we don't try to flush? */
connection_mark_for_close(conn);
}
@@ -489,7 +491,7 @@ conn_close_if_marked(int i)
conn->marked_for_close_file, conn->marked_for_close);
if (connection_speaks_cells(conn)) {
if (conn->state == OR_CONN_STATE_OPEN) {
- retval = flush_buf_tls(conn->tls, conn->outbuf, sz,
+ retval = flush_buf_tls(TO_OR_CONN(conn)->tls, conn->outbuf, sz,
&conn->outbuf_flushlen);
} else
retval = -1; /* never flush non-open broken tls connections */
@@ -544,12 +546,13 @@ directory_all_unreachable(time_t now)
while ((conn = connection_get_by_type_state(CONN_TYPE_AP,
AP_CONN_STATE_CIRCUIT_WAIT))) {
+ edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
log_notice(LD_NET,
"Is your network connection down? "
"Failing connection to '%s:%d'.",
- safe_str(conn->socks_request->address),
- conn->socks_request->port);
- connection_mark_unattached_ap(conn, END_STREAM_REASON_NET_UNREACHABLE);
+ safe_str(edge_conn->socks_request->address),
+ edge_conn->socks_request->port);
+ connection_mark_unattached_ap(edge_conn, END_STREAM_REASON_NET_UNREACHABLE);
}
}
@@ -582,6 +585,7 @@ run_connection_housekeeping(int i, time_t now)
cell_t cell;
connection_t *conn = connection_array[i];
or_options_t *options = get_options();
+ or_connection_t *or_conn;
if (conn->outbuf && !buf_datalen(conn->outbuf))
conn->timestamp_lastempty = now;
@@ -602,7 +606,7 @@ run_connection_housekeeping(int i, time_t now)
buf_datalen(conn->inbuf)>=1024) {
log_info(LD_DIR,"Trying to extract information from wedged server desc "
"download.");
- connection_dir_reached_eof(conn);
+ connection_dir_reached_eof(TO_DIR_CONN(conn));
} else {
connection_mark_for_close(conn);
}
@@ -612,17 +616,19 @@ run_connection_housekeeping(int i, time_t now)
if (!connection_speaks_cells(conn))
return; /* we're all done here, the rest is just for OR conns */
- if (!conn->is_obsolete) {
+ or_conn = TO_OR_CONN(conn);
+
+ if (!conn->or_is_obsolete) {
if (conn->timestamp_created + TIME_BEFORE_OR_CONN_IS_OBSOLETE < now) {
log_info(LD_OR,
"Marking OR conn to %s:%d obsolete (fd %d, %d secs old).",
conn->address, conn->port, conn->s,
(int)(now - conn->timestamp_created));
- conn->is_obsolete = 1;
+ conn->or_is_obsolete = 1;
} else {
- connection_t *best =
- connection_or_get_by_identity_digest(conn->identity_digest);
- if (best && best != conn &&
+ or_connection_t *best =
+ connection_or_get_by_identity_digest(or_conn->identity_digest);
+ if (best && best != or_conn &&
(conn->state == OR_CONN_STATE_OPEN ||
now > conn->timestamp_created + TLS_HANDSHAKE_TIMEOUT)) {
/* We only mark as obsolete connections that already are in
@@ -637,16 +643,16 @@ run_connection_housekeeping(int i, time_t now)
"(fd %d, %d secs old).",
conn->address, conn->port, conn->s,
(int)(now - conn->timestamp_created));
- conn->is_obsolete = 1;
+ conn->or_is_obsolete = 1;
}
}
}
- if (conn->is_obsolete && !conn->n_circuits) {
+ if (conn->or_is_obsolete && !or_conn->n_circuits) {
/* no unmarked circs -- mark it now */
log_info(LD_OR,
"Expiring non-used OR connection to fd %d (%s:%d) [Obsolete].",
- conn->s,conn->address, conn->port);
+ conn->s, conn->address, conn->port);
connection_mark_for_close(conn);
conn->hold_open_until_flushed = 1;
return;
@@ -655,20 +661,20 @@ run_connection_housekeeping(int i, time_t now)
/* If we haven't written to an OR connection for a while, then either nuke
the connection or send a keepalive, depending. */
if (now >= conn->timestamp_lastwritten + options->KeepalivePeriod) {
- routerinfo_t *router = router_get_by_digest(conn->identity_digest);
+ routerinfo_t *router = router_get_by_digest(or_conn->identity_digest);
if (!connection_state_is_open(conn)) {
log_info(LD_OR,"Expiring non-open OR connection to fd %d (%s:%d).",
conn->s,conn->address, conn->port);
connection_mark_for_close(conn);
conn->hold_open_until_flushed = 1;
- } else if (we_are_hibernating() && !conn->n_circuits &&
+ } else if (we_are_hibernating() && !or_conn->n_circuits &&
!buf_datalen(conn->outbuf)) {
log_info(LD_OR,"Expiring non-used OR connection to fd %d (%s:%d) "
"[Hibernating or exiting].",
conn->s,conn->address, conn->port);
connection_mark_for_close(conn);
conn->hold_open_until_flushed = 1;
- } else if (!clique_mode(options) && !conn->n_circuits &&
+ } else if (!clique_mode(options) && !or_conn->n_circuits &&
(!router || !server_mode(options) ||
!router_is_clique_mode(router))) {
log_info(LD_OR,"Expiring non-used OR connection to fd %d (%s:%d) "
@@ -692,7 +698,7 @@ run_connection_housekeeping(int i, time_t now)
conn->address, conn->port);
memset(&cell,0,sizeof(cell_t));
cell.command = CELL_PADDING;
- connection_or_write_cell_to_buf(&cell, conn);
+ connection_or_write_cell_to_buf(&cell, or_conn);
}
}
}
diff --git a/src/or/or.h b/src/or/or.h
index 8ce5d8692d..0db44e5898 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -576,7 +576,11 @@ typedef struct {
typedef struct buf_t buf_t;
typedef struct socks_request_t socks_request_t;
-#define CONNECTION_MAGIC 0x7C3C304Eu
+#define BASE_CONNECTION_MAGIC 0x7C3C304Eu
+#define OR_CONNECTION_MAGIC 0x7D31FF03u
+#define EDGE_CONNECTION_MAGIC 0xF0374013u
+#define DIR_CONNECTION_MAGIC 0x9988ffeeu
+#define CONTROL_CONNECTION_MAGIC 0x8abc765du
/** Description of a connection to another host or process, and associated
* data.
@@ -609,14 +613,15 @@ struct connection_t {
unsigned hold_open_until_flushed:1; /**< Despite this connection's being
* marked for close, do we flush it
* before closing it? */
- unsigned has_sent_end:1; /**< For debugging; only used on edge connections.
- * Set once we've set the stream end,
+
+ unsigned edge_has_sent_end:1; /**< For debugging; only used on edge
+ * connections. Set once we've set the stream end,
* and check in circuit_about_to_close_connection(). */
/** For control connections only. If set, we send extended info with control
* events as appropriate. */
unsigned int control_events_are_extended:1;
/** Used for OR conns that shouldn't get any new circs attached to them. */
- unsigned int is_obsolete:1;
+ unsigned int or_is_obsolete:1;
int s; /**< Our socket; -1 if this connection is closed. */
int poll_index; /* XXXX rename. */
@@ -648,22 +653,23 @@ struct connection_t {
* we marked for close? */
char *address; /**< FQDN (or IP) of the guy on the other end.
* strdup into this, because free_connection frees it. */
- uint32_t address_ttl; /**< TTL for address-to-addr mapping on exit
- * connection. Exit connections only. */
+
+ /** Quasi-global identifier for this connection; used for control.c */
+ /* XXXX NM This can get re-used after 2**32 circuits. */
+ uint32_t global_identifier;
+
+};
+
+typedef struct connection_t connection_t;
+
+/** DOCDOC */
+typedef struct or_connection_t {
+ connection_t _base;
+
char identity_digest[DIGEST_LEN]; /**< Hash of the public RSA key for
* the other side's signing key. */
char *nickname; /**< Nickname of OR on other side (if any). */
- /** Nickname of planned exit node -- used with .exit support. */
- char *chosen_exit_name;
- /** If 1, and we fail to reach the chosen exit, stop requiring it. */
- unsigned int chosen_exit_optional:1;
- /** Number of times we've reassigned this application connection to
- * a new circuit. We keep track because the timeout is longer if we've
- * already retried several times. */
- int num_socks_retries;
-
-/* Used only by OR connections: */
tor_tls_t *tls; /**< TLS connection state (OR only.) */
/* bandwidth* and receiver_bucket only used by ORs in OPEN state: */
@@ -677,16 +683,19 @@ struct connection_t {
* we use? */
int n_circuits; /**< How many circuits use this connection as p_conn or
* n_conn ? */
- struct connection_t *next_with_same_id; /**< Next connection with same
+ struct or_connection_t *next_with_same_id; /**< Next connection with same
* identity digest as this one. */
uint16_t next_circ_id; /**< Which circ_id do we try to use next on
* this connection? This is always in the
* range 0..1<<15-1. (OR only.)*/
+} or_connection_t;
+
+typedef struct edge_connection_t {
+ connection_t _base;
-/* Used only by edge connections: */
uint16_t stream_id;
- struct connection_t *next_stream; /**< Points to the next stream at this
- * edge, if any (Edge only). */
+ struct edge_connection_t *next_stream; /**< Points to the next stream at this
+ * edge, if any (Edge only). */
struct crypt_path_t *cpath_layer; /**< A pointer to which node in the circ
* this conn exits at. (Edge only.) */
int package_window; /**< How many more relay cells can i send into the
@@ -694,6 +703,36 @@ struct connection_t {
int deliver_window; /**< How many more relay cells can end at me? (Edge
* only.) */
+ /** Number of times we've reassigned this application connection to
+ * a new circuit. We keep track because the timeout is longer if we've
+ * already retried several times. */
+ int num_socks_retries;
+
+ /** Nickname of planned exit node -- used with .exit support. */
+ char *chosen_exit_name;
+ /** If 1, and we fail to reach the chosen exit, stop requiring it. */
+ unsigned int chosen_exit_optional:1;
+
+/* Used only by AP connections */
+ socks_request_t *socks_request; /**< SOCKS structure describing request (AP
+ * only.) */
+
+ struct circuit_t *on_circuit; /**< The circuit (if any) that this edge
+ * connection is using. */
+
+ uint32_t address_ttl; /**< TTL for address-to-addr mapping on exit
+ * connection. Exit connections only. */
+
+/* Used only by DIR and AP connections: */
+ char rend_query[REND_SERVICE_ID_LEN+1]; /**< What rendezvous service are we
+ * querying for? (DIR/AP only) */
+
+
+} edge_connection_t;
+
+typedef struct dir_connection_t {
+ connection_t _base;
+
/* Used only by Dir connections */
char *requested_resource; /**< Which 'resource' did we ask the directory
* for? */
@@ -708,31 +747,55 @@ struct connection_t {
off_t cached_dir_offset;
tor_zlib_state_t *zlib_state;
-/* Used only by AP connections */
- socks_request_t *socks_request; /**< SOCKS structure describing request (AP
- * only.) */
+/* Used only by DIR and AP connections: */
+ char rend_query[REND_SERVICE_ID_LEN+1]; /**< What rendezvous service are we
+ * querying for? (DIR/AP only) */
- /** Quasi-global identifier for this connection; used for control.c */
- /* XXXX NM This can get re-used after 2**32 circuits. */
- uint32_t global_identifier;
+ char identity_digest[DIGEST_LEN]; /**< Hash of the public RSA key for
+ * the directory server's signing key. */
+} dir_connection_t;
+
+typedef struct control_connection_t {
+ connection_t _base;
/* Used only by control connections */
uint32_t event_mask;
uint32_t incoming_cmd_len;
uint32_t incoming_cmd_cur_len;
char *incoming_cmd;
-
-/* Used only by DIR and AP connections: */
- struct circuit_t *on_circuit; /**< The circuit (if any) that this edge
- * connection is using. */
- char rend_query[REND_SERVICE_ID_LEN+1]; /**< What rendezvous service are we
- * querying for? (DIR/AP only) */
-
/* Used only by control v0 connections */
uint16_t incoming_cmd_type;
-};
+} control_connection_t;
-typedef struct connection_t connection_t;
+#define TO_CONN(c) &(((c)->_base))
+#define DOWNCAST(from, to, ptr) \
+ (to*) (((from*)(ptr)) - STRUCT_OFFSET(to, _base))
+
+or_connection_t *TO_OR_CONN(connection_t *);
+dir_connection_t *TO_DIR_CONN(connection_t *);
+edge_connection_t *TO_EDGE_CONN(connection_t *);
+control_connection_t *TO_CONTROL_CONN(connection_t *);
+
+extern INLINE or_connection_t *TO_OR_CONN(connection_t *c)
+{
+ tor_assert(c->magic == OR_CONNECTION_MAGIC);
+ return DOWNCAST(connection_t, or_connection_t, c);
+}
+extern INLINE dir_connection_t *TO_DIR_CONN(connection_t *c)
+{
+ tor_assert(c->magic == DIR_CONNECTION_MAGIC);
+ return DOWNCAST(connection_t, dir_connection_t, c);
+}
+extern INLINE edge_connection_t *TO_EDGE_CONN(connection_t *c)
+{
+ tor_assert(c->magic == EDGE_CONNECTION_MAGIC);
+ return DOWNCAST(connection_t, edge_connection_t, c);
+}
+extern INLINE control_connection_t *TO_CONTROL_CONN(connection_t *c)
+{
+ tor_assert(c->magic == CONTROL_CONNECTION_MAGIC);
+ return DOWNCAST(connection_t, control_connection_t, c);
+}
typedef enum {
ADDR_POLICY_ACCEPT=1,
@@ -1072,7 +1135,7 @@ typedef struct circuit_t {
* ORIGIN_CIRCUIT_MAGIC or OR_CIRCUIT_MAGIC. */
/** The OR connection that is next in this circuit. */
- connection_t *n_conn;
+ or_connection_t *n_conn;
/** The identity hash of n_conn. */
char n_conn_id_digest[DIGEST_LEN];
/** The circuit_id used in the next (forward) hop of this circuit. */
@@ -1121,7 +1184,7 @@ typedef struct origin_circuit_t {
circuit_t _base;
/** Linked list of AP streams associated with this circuit. */
- connection_t *p_streams;
+ edge_connection_t *p_streams;
/** Build state for this circuit. It includes the intended path
* length, the chosen exit router, rendezvous information, etc.
*/
@@ -1164,12 +1227,12 @@ typedef struct or_circuit_t {
/** The circuit_id used in the previous (backward) hop of this circuit. */
circid_t p_circ_id;
/** The OR connection that is previous in this circuit. */
- connection_t *p_conn;
+ or_connection_t *p_conn;
/** Linked list of Exit streams associated with this circuit. */
- connection_t *n_streams;
+ edge_connection_t *n_streams;
/** Linked list of Exit streams associated with this circuit that are
* still being resolved. */
- connection_t *resolving_streams;
+ edge_connection_t *resolving_streams;
/** The cipher used by intermediate hops for cells heading toward the
* OP. */
crypto_cipher_env_t *p_crypto;
@@ -1210,14 +1273,16 @@ or_circuit_t *TO_OR_CIRCUIT(circuit_t *x);
extern INLINE or_circuit_t *TO_OR_CIRCUIT(circuit_t *x)
{
tor_assert(x->magic == OR_CIRCUIT_MAGIC);
- return (or_circuit_t*) (((char*)x) - STRUCT_OFFSET(or_circuit_t, _base));
+ //return (or_circuit_t*) (((char*)x) - STRUCT_OFFSET(or_circuit_t, _base));
+ return DOWNCAST(circuit_t, or_circuit_t, x);
}
origin_circuit_t *TO_ORIGIN_CIRCUIT(circuit_t *x);
extern INLINE origin_circuit_t *TO_ORIGIN_CIRCUIT(circuit_t *x)
{
tor_assert(x->magic == ORIGIN_CIRCUIT_MAGIC);
- return (origin_circuit_t*)
- (((char*)x) - STRUCT_OFFSET(origin_circuit_t, _base));
+ //return (origin_circuit_t*)
+ // (((char*)x) - STRUCT_OFFSET(origin_circuit_t, _base));
+ return DOWNCAST(circuit_t, origin_circuit_t, x);
}
#define ALLOW_INVALID_ENTRY 1
@@ -1554,7 +1619,7 @@ origin_circuit_t *circuit_establish_circuit(uint8_t purpose,
int need_uptime, int need_capacity,
int internal);
int circuit_handle_first_hop(origin_circuit_t *circ);
-void circuit_n_conn_done(connection_t *or_conn, int status);
+void circuit_n_conn_done(or_connection_t *or_conn, int status);
int inform_testing_reachability(void);
int circuit_send_next_onion_skin(origin_circuit_t *circ);
void circuit_note_clock_jumped(int seconds_elapsed);
@@ -1593,17 +1658,18 @@ circuit_t * _circuit_get_global_list(void);
const char *circuit_state_to_string(int state);
void circuit_dump_by_conn(connection_t *conn, int severity);
void circuit_set_p_circid_orconn(or_circuit_t *circ, uint16_t id,
- connection_t *conn);
+ or_connection_t *conn);
void circuit_set_n_circid_orconn(circuit_t *circ, uint16_t id,
- connection_t *conn);
+ or_connection_t *conn);
void circuit_set_state(circuit_t *circ, int state);
void circuit_close_all_marked(void);
origin_circuit_t *origin_circuit_new(void);
-or_circuit_t *or_circuit_new(uint16_t p_circ_id, connection_t *p_conn);
-circuit_t *circuit_get_by_circid_orconn(uint16_t circ_id, connection_t *conn);
-int circuit_id_used_on_conn(uint16_t circ_id, connection_t *conn);
-circuit_t *circuit_get_by_edge_conn(connection_t *conn);
-void circuit_unlink_all_from_or_conn(connection_t *conn, int reason);
+or_circuit_t *or_circuit_new(uint16_t p_circ_id, or_connection_t *p_conn);
+circuit_t *circuit_get_by_circid_orconn(uint16_t circ_id,
+ or_connection_t *conn);
+int circuit_id_used_on_conn(uint16_t circ_id, or_connection_t *conn);
+circuit_t *circuit_get_by_edge_conn(edge_connection_t *conn);
+void circuit_unlink_all_from_or_conn(or_connection_t *conn, int reason);
circuit_t *circuit_get_by_global_id(uint32_t id);
origin_circuit_t *circuit_get_by_rend_query_and_purpose(const char *rend_query,
uint8_t purpose);
@@ -1631,10 +1697,10 @@ void circuit_free_all(void);
void circuit_expire_building(time_t now);
void circuit_remove_handled_ports(smartlist_t *needed_ports);
-int circuit_stream_is_being_handled(connection_t *conn, uint16_t port,
+int circuit_stream_is_being_handled(edge_connection_t *conn, uint16_t port,
int min);
void circuit_build_needed_circs(time_t now);
-void circuit_detach_stream(circuit_t *circ, connection_t *conn);
+void circuit_detach_stream(circuit_t *circ, edge_connection_t *conn);
void circuit_about_to_close_connection(connection_t *conn);
void circuit_has_opened(origin_circuit_t *circ);
void circuit_build_failed(origin_circuit_t *circ);
@@ -1650,13 +1716,13 @@ origin_circuit_t *circuit_launch_by_router(uint8_t purpose, routerinfo_t *exit,
int need_uptime, int need_capacity,
int is_internal);
void circuit_reset_failure_count(int timeout);
-int connection_ap_handshake_attach_chosen_circuit(connection_t *conn,
+int connection_ap_handshake_attach_chosen_circuit(edge_connection_t *conn,
origin_circuit_t *circ);
-int connection_ap_handshake_attach_circuit(connection_t *conn);
+int connection_ap_handshake_attach_circuit(edge_connection_t *conn);
/********************************* command.c ***************************/
-void command_process_cell(cell_t *cell, connection_t *conn);
+void command_process_cell(cell_t *cell, or_connection_t *conn);
extern uint64_t stats_n_padding_cells_processed;
extern uint64_t stats_n_create_cells_processed;
@@ -1730,15 +1796,15 @@ int connection_fetch_from_buf(char *string, size_t len, connection_t *conn);
int connection_wants_to_flush(connection_t *conn);
int connection_outbuf_too_full(connection_t *conn);
int connection_handle_write(connection_t *conn);
-void _connection_controller_force_write(connection_t *conn);
+void _connection_controller_force_write(control_connection_t *conn);
void connection_write_to_buf(const char *string, size_t len,
connection_t *conn);
-void connection_write_to_buf_zlib(connection_t *conn,
+void connection_write_to_buf_zlib(dir_connection_t *conn,
tor_zlib_state_t *state,
const char *data, size_t data_len,
int done);
-connection_t *connection_or_exact_get_by_addr_port(uint32_t addr,
+or_connection_t *connection_or_exact_get_by_addr_port(uint32_t addr,
uint16_t port);
connection_t *connection_get_by_global_id(uint32_t id);
@@ -1759,34 +1825,34 @@ int connection_state_is_connecting(connection_t *conn);
char *alloc_http_authenticator(const char *authenticator);
void assert_connection_ok(connection_t *conn, time_t now);
-int connection_or_nonopen_was_started_here(connection_t *conn);
+int connection_or_nonopen_was_started_here(or_connection_t *conn);
/********************************* connection_edge.c *************************/
#define connection_mark_unattached_ap(conn, endreason) \
_connection_mark_unattached_ap((conn), (endreason), __LINE__, _SHORT_FILE_)
-void _connection_mark_unattached_ap(connection_t *conn, int endreason,
+void _connection_mark_unattached_ap(edge_connection_t *conn, int endreason,
int line, const char *file);
-int connection_edge_reached_eof(connection_t *conn);
-int connection_edge_process_inbuf(connection_t *conn, int package_partial);
-int connection_edge_destroy(uint16_t circ_id, connection_t *conn);
-int connection_edge_end(connection_t *conn, char reason,
+int connection_edge_reached_eof(edge_connection_t *conn);
+int connection_edge_process_inbuf(edge_connection_t *conn, int package_partial);
+int connection_edge_destroy(uint16_t circ_id, edge_connection_t *conn);
+int connection_edge_end(edge_connection_t *conn, char reason,
crypt_path_t *cpath_layer);
-int connection_edge_end_errno(connection_t *conn, crypt_path_t *cpath_layer);
-int connection_edge_finished_flushing(connection_t *conn);
-int connection_edge_finished_connecting(connection_t *conn);
+int connection_edge_end_errno(edge_connection_t *conn, crypt_path_t *cpath_layer);
+int connection_edge_finished_flushing(edge_connection_t *conn);
+int connection_edge_finished_connecting(edge_connection_t *conn);
-int connection_ap_handshake_send_begin(connection_t *ap_conn,
+int connection_ap_handshake_send_begin(edge_connection_t *ap_conn,
origin_circuit_t *circ);
-int connection_ap_handshake_send_resolve(connection_t *ap_conn,
+int connection_ap_handshake_send_resolve(edge_connection_t *ap_conn,
origin_circuit_t *circ);
int connection_ap_make_bridge(char *address, uint16_t port);
-void connection_ap_handshake_socks_reply(connection_t *conn, char *reply,
+void connection_ap_handshake_socks_reply(edge_connection_t *conn, char *reply,
size_t replylen,
socks5_reply_status_t status);
-void connection_ap_handshake_socks_resolved(connection_t *conn,
+void connection_ap_handshake_socks_resolved(edge_connection_t *conn,
int answer_type,
size_t answer_len,
const char *answer,
@@ -1794,12 +1860,12 @@ void connection_ap_handshake_socks_resolved(connection_t *conn,
int connection_exit_begin_conn(cell_t *cell, circuit_t *circ);
int connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ);
-void connection_exit_connect(connection_t *conn);
-int connection_edge_is_rendezvous_stream(connection_t *conn);
-int connection_ap_can_use_exit(connection_t *conn, routerinfo_t *exit);
+void connection_exit_connect(edge_connection_t *conn);
+int connection_edge_is_rendezvous_stream(edge_connection_t *conn);
+int connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit);
void connection_ap_expire_beginning(void);
void connection_ap_attach_pending(void);
-int connection_ap_detach_retriable(connection_t *conn, origin_circuit_t *circ);
+int connection_ap_detach_retriable(edge_connection_t *conn, origin_circuit_t *circ);
void addressmap_init(void);
void addressmap_clean(time_t now);
@@ -1820,7 +1886,7 @@ int address_is_in_virtual_range(const char *addr);
const char *addressmap_register_virtual_address(int type, char *new_address);
void addressmap_get_mappings(smartlist_t *sl, time_t min_expires,
time_t max_expires);
-int connection_ap_handshake_rewrite_and_attach(connection_t *conn,
+int connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
origin_circuit_t *circ);
void set_exit_redirects(smartlist_t *lst);
@@ -1831,23 +1897,23 @@ hostname_type_t parse_extended_hostname(char *address);
/********************************* connection_or.c ***************************/
-void connection_or_remove_from_identity_map(connection_t *conn);
+void connection_or_remove_from_identity_map(or_connection_t *conn);
void connection_or_clear_identity_map(void);
-connection_t *connection_or_get_by_identity_digest(const char *digest);
+or_connection_t *connection_or_get_by_identity_digest(const char *digest);
-int connection_or_reached_eof(connection_t *conn);
-int connection_or_process_inbuf(connection_t *conn);
-int connection_or_finished_flushing(connection_t *conn);
-int connection_or_finished_connecting(connection_t *conn);
+int connection_or_reached_eof(or_connection_t *conn);
+int connection_or_process_inbuf(or_connection_t *conn);
+int connection_or_finished_flushing(or_connection_t *conn);
+int connection_or_finished_connecting(or_connection_t *conn);
-connection_t *connection_or_connect(uint32_t addr, uint16_t port,
+or_connection_t *connection_or_connect(uint32_t addr, uint16_t port,
const char *id_digest);
-int connection_tls_start_handshake(connection_t *conn, int receiving);
-int connection_tls_continue_handshake(connection_t *conn);
+int connection_tls_start_handshake(or_connection_t *conn, int receiving);
+int connection_tls_continue_handshake(or_connection_t *conn);
-void connection_or_write_cell_to_buf(const cell_t *cell, connection_t *conn);
-int connection_or_send_destroy(uint16_t circ_id, connection_t *conn,
+void connection_or_write_cell_to_buf(const cell_t *cell, or_connection_t *conn);
+int connection_or_send_destroy(uint16_t circ_id, or_connection_t *conn,
int reason);
/********************************* control.c ***************************/
@@ -1906,14 +1972,14 @@ void control_adjust_event_log_severity(void);
#define LOG_FN_CONN(conn, args) \
CONN_LOG_PROTECT(conn, log_fn args)
-int connection_control_finished_flushing(connection_t *conn);
-int connection_control_reached_eof(connection_t *conn);
-int connection_control_process_inbuf(connection_t *conn);
+int connection_control_finished_flushing(control_connection_t *conn);
+int connection_control_reached_eof(control_connection_t *conn);
+int connection_control_process_inbuf(control_connection_t *conn);
int control_event_circuit_status(origin_circuit_t *circ,
circuit_status_event_t e);
-int control_event_stream_status(connection_t *conn, stream_status_event_t e);
-int control_event_or_conn_status(connection_t *conn, or_conn_status_event_t e);
+int control_event_stream_status(edge_connection_t *conn, stream_status_event_t e);
+int control_event_or_conn_status(or_connection_t *conn, or_conn_status_event_t e);
int control_event_bandwidth_used(uint32_t n_read, uint32_t n_written);
void control_event_logmsg(int severity, unsigned int domain, const char *msg);
int control_event_descriptors_changed(smartlist_t *routers);
@@ -1959,11 +2025,11 @@ void directory_initiate_command_routerstatus(routerstatus_t *status,
int parse_http_response(const char *headers, int *code, time_t *date,
int *compression, char **response);
-int connection_dir_reached_eof(connection_t *conn);
-int connection_dir_process_inbuf(connection_t *conn);
-int connection_dir_finished_flushing(connection_t *conn);
-int connection_dir_finished_connecting(connection_t *conn);
-void connection_dir_request_failed(connection_t *conn);
+int connection_dir_reached_eof(dir_connection_t *conn);
+int connection_dir_process_inbuf(dir_connection_t *conn);
+int connection_dir_finished_flushing(dir_connection_t *conn);
+int connection_dir_finished_connecting(dir_connection_t *conn);
+void connection_dir_request_failed(dir_connection_t *conn);
int dir_split_resource_into_fingerprints(const char *resource,
smartlist_t *fp_out, int *compresseed_out,
int decode_hex, int sort_uniq);
@@ -1971,7 +2037,7 @@ char *directory_dump_request_log(void);
/********************************* dirserv.c ***************************/
-int connection_dirserv_flushed_some(connection_t *conn);
+int connection_dirserv_flushed_some(dir_connection_t *conn);
int dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk);
int dirserv_parse_fingerprint_file(const char *fname);
void dirserv_free_fingerprint_list(void);
@@ -2021,11 +2087,11 @@ int connection_dns_finished_flushing(connection_t *conn);
int connection_dns_reached_eof(connection_t *conn);
int connection_dns_process_inbuf(connection_t *conn);
void dnsworkers_rotate(void);
-void connection_dns_remove(connection_t *conn);
-void assert_connection_edge_not_dns_pending(connection_t *conn);
+void connection_dns_remove(edge_connection_t *conn);
+void assert_connection_edge_not_dns_pending(edge_connection_t *conn);
void assert_all_pending_dns_resolves_ok(void);
void dns_cancel_pending_resolve(char *question);
-int dns_resolve(connection_t *exitconn);
+int dns_resolve(edge_connection_t *exitconn);
/********************************* hibernate.c **********************/
@@ -2146,12 +2212,12 @@ int circuit_receive_relay_cell(cell_t *cell, circuit_t *circ,
void relay_header_pack(char *dest, const relay_header_t *src);
void relay_header_unpack(relay_header_t *dest, const char *src);
-int connection_edge_send_command(connection_t *fromconn, circuit_t *circ,
+int connection_edge_send_command(edge_connection_t *fromconn, circuit_t *circ,
int relay_command, const char *payload,
size_t payload_len,
crypt_path_t *cpath_layer);
-int connection_edge_package_raw_inbuf(connection_t *conn, int package_partial);
-void connection_edge_consider_sending_sendme(connection_t *conn);
+int connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial);
+void connection_edge_consider_sending_sendme(edge_connection_t *conn);
socks5_reply_status_t connection_edge_end_reason_socks5_response(int reason);
int errno_to_end_reason(int e);
@@ -2283,7 +2349,7 @@ void rend_service_rendezvous_has_opened(origin_circuit_t *circuit);
int rend_service_introduce(origin_circuit_t *circuit, const char *request,
size_t request_len);
void rend_service_relaunch_rendezvous(origin_circuit_t *oldcirc);
-int rend_service_set_connection_addr_port(connection_t *conn,
+int rend_service_set_connection_addr_port(edge_connection_t *conn,
origin_circuit_t *circ);
void rend_service_dump_stats(int severity);
void rend_service_free_all(void);
@@ -2332,7 +2398,7 @@ void mark_my_descriptor_dirty(void);
void check_descriptor_bandwidth_changed(time_t now);
void check_descriptor_ipaddress_changed(time_t now);
void router_new_address_suggestion(const char *suggestion);
-int router_compare_to_my_exit_policy(connection_t *conn);
+int router_compare_to_my_exit_policy(edge_connection_t *conn);
routerinfo_t *router_get_my_routerinfo(void);
const char *router_get_my_descriptor(void);
int router_digest_is_me(const char *digest);
diff --git a/src/or/relay.c b/src/or/relay.c
index 997035fe22..35154f1af2 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -16,19 +16,19 @@ const char relay_c_id[] =
static int relay_crypt(circuit_t *circ, cell_t *cell, int cell_direction,
crypt_path_t **layer_hint, char *recognized);
-static connection_t *relay_lookup_conn(circuit_t *circ, cell_t *cell,
+static edge_connection_t *relay_lookup_conn(circuit_t *circ, cell_t *cell,
int cell_direction);
static int
connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
- connection_t *conn,
+ edge_connection_t *conn,
crypt_path_t *layer_hint);
static void
circuit_consider_sending_sendme(circuit_t *circ, crypt_path_t *layer_hint);
static void
circuit_resume_edge_reading(circuit_t *circ, crypt_path_t *layer_hint);
static int
-circuit_resume_edge_reading_helper(connection_t *conn,
+circuit_resume_edge_reading_helper(edge_connection_t *conn,
circuit_t *circ,
crypt_path_t *layer_hint);
static int
@@ -144,7 +144,7 @@ relay_crypt_one_payload(crypto_cipher_env_t *cipher, char *in,
int
circuit_receive_relay_cell(cell_t *cell, circuit_t *circ, int cell_direction)
{
- connection_t *conn=NULL;
+ or_connection_t *or_conn=NULL;
crypt_path_t *layer_hint=NULL;
char recognized=0;
int reason;
@@ -162,7 +162,7 @@ circuit_receive_relay_cell(cell_t *cell, circuit_t *circ, int cell_direction)
}
if (recognized) {
- conn = relay_lookup_conn(circ, cell, cell_direction);
+ edge_connection_t *conn = relay_lookup_conn(circ, cell, cell_direction);
if (cell_direction == CELL_DIRECTION_OUT) {
++stats_n_relay_cells_delivered;
log_debug(LD_OR,"Sending away from origin.");
@@ -190,16 +190,16 @@ circuit_receive_relay_cell(cell_t *cell, circuit_t *circ, int cell_direction)
/* not recognized. pass it on. */
if (cell_direction == CELL_DIRECTION_OUT) {
cell->circ_id = circ->n_circ_id; /* switch it */
- conn = circ->n_conn;
+ or_conn = circ->n_conn;
} else if (! CIRCUIT_IS_ORIGIN(circ)) {
cell->circ_id = TO_OR_CIRCUIT(circ)->p_circ_id; /* switch it */
- conn = TO_OR_CIRCUIT(circ)->p_conn;
+ or_conn = TO_OR_CIRCUIT(circ)->p_conn;
} else {
// XXXX NM WARN.
return 0;
}
- if (!conn) {
+ if (!or_conn) {
// XXXX Can this splice stuff be done more cleanly?
if (! CIRCUIT_IS_ORIGIN(circ) &&
TO_OR_CIRCUIT(circ)->rend_splice &&
@@ -225,7 +225,7 @@ circuit_receive_relay_cell(cell_t *cell, circuit_t *circ, int cell_direction)
log_debug(LD_OR,"Passing on unrecognized cell.");
++stats_n_relay_cells_relayed;
- connection_or_write_cell_to_buf(cell, conn);
+ connection_or_write_cell_to_buf(cell, or_conn);
return 0;
}
@@ -323,7 +323,7 @@ circuit_package_relay_cell(cell_t *cell, circuit_t *circ,
int cell_direction,
crypt_path_t *layer_hint)
{
- connection_t *conn; /* where to send the cell */
+ or_connection_t *conn; /* where to send the cell */
if (cell_direction == CELL_DIRECTION_OUT) {
crypt_path_t *thishop; /* counter for repeated crypts */
@@ -369,10 +369,10 @@ circuit_package_relay_cell(cell_t *cell, circuit_t *circ,
/** If cell's stream_id matches the stream_id of any conn that's
* attached to circ, return that conn, else return NULL.
*/
-static connection_t *
+static edge_connection_t *
relay_lookup_conn(circuit_t *circ, cell_t *cell, int cell_direction)
{
- connection_t *tmpconn;
+ edge_connection_t *tmpconn;
relay_header_t rh;
relay_header_unpack(&rh, cell->payload);
@@ -387,7 +387,8 @@ relay_lookup_conn(circuit_t *circ, cell_t *cell, int cell_direction)
if (CIRCUIT_IS_ORIGIN(circ)) {
for (tmpconn = TO_ORIGIN_CIRCUIT(circ)->p_streams; tmpconn;
tmpconn=tmpconn->next_stream) {
- if (rh.stream_id == tmpconn->stream_id && !tmpconn->marked_for_close) {
+ if (rh.stream_id == tmpconn->stream_id &&
+ !tmpconn->_base.marked_for_close) {
log_debug(LD_APP,"found conn for stream %d.", rh.stream_id);
return tmpconn;
}
@@ -395,7 +396,7 @@ relay_lookup_conn(circuit_t *circ, cell_t *cell, int cell_direction)
} else {
for (tmpconn = TO_OR_CIRCUIT(circ)->n_streams; tmpconn;
tmpconn=tmpconn->next_stream) {
- if (rh.stream_id == tmpconn->stream_id && !tmpconn->marked_for_close) {
+ if (rh.stream_id == tmpconn->stream_id && !tmpconn->_base.marked_for_close) {
log_debug(LD_EXIT,"found conn for stream %d.", rh.stream_id);
if (cell_direction == CELL_DIRECTION_OUT ||
connection_edge_is_rendezvous_stream(tmpconn))
@@ -404,7 +405,7 @@ relay_lookup_conn(circuit_t *circ, cell_t *cell, int cell_direction)
}
for (tmpconn = TO_OR_CIRCUIT(circ)->resolving_streams; tmpconn;
tmpconn=tmpconn->next_stream) {
- if (rh.stream_id == tmpconn->stream_id && !tmpconn->marked_for_close) {
+ if (rh.stream_id == tmpconn->stream_id && !tmpconn->_base.marked_for_close) {
log_debug(LD_EXIT,"found conn for stream %d.", rh.stream_id);
return tmpconn;
}
@@ -452,7 +453,7 @@ relay_header_unpack(relay_header_t *dest, const char *src)
* return -1. Else return 0.
*/
int
-connection_edge_send_command(connection_t *fromconn, circuit_t *circ,
+connection_edge_send_command(edge_connection_t *fromconn, circuit_t *circ,
int relay_command, const char *payload,
size_t payload_len, crypt_path_t *cpath_layer)
{
@@ -461,22 +462,22 @@ connection_edge_send_command(connection_t *fromconn, circuit_t *circ,
int cell_direction;
/* XXXX NM Split this function into a separate versions per circuit type? */
- if (fromconn && fromconn->marked_for_close) {
+ if (fromconn && fromconn->_base.marked_for_close) {
log_warn(LD_BUG,
"Bug: called on conn that's already marked for close at %s:%d.",
- fromconn->marked_for_close_file, fromconn->marked_for_close);
+ fromconn->_base.marked_for_close_file, fromconn->_base.marked_for_close);
return 0;
}
if (!circ) {
tor_assert(fromconn);
- if (fromconn->type == CONN_TYPE_AP) {
+ if (fromconn->_base.type == CONN_TYPE_AP) {
log_info(LD_APP,"no circ. Closing conn.");
connection_mark_unattached_ap(fromconn, END_STREAM_REASON_INTERNAL);
} else {
log_info(LD_EXIT,"no circ. Closing conn.");
- fromconn->has_sent_end = 1; /* no circ to send to */
- connection_mark_for_close(fromconn);
+ fromconn->_base.edge_has_sent_end = 1; /* no circ to send to */
+ connection_mark_for_close(TO_CONN(fromconn));
}
return -1;
}
@@ -665,7 +666,7 @@ edge_reason_is_retriable(int reason)
static int
connection_edge_process_end_not_open(
relay_header_t *rh, cell_t *cell, origin_circuit_t *circ,
- connection_t *conn, crypt_path_t *layer_hint)
+ edge_connection_t *conn, crypt_path_t *layer_hint)
{
struct in_addr in;
routerinfo_t *exitrouter;
@@ -673,7 +674,7 @@ connection_edge_process_end_not_open(
(void) layer_hint; /* unused */
if (rh->length > 0 && edge_reason_is_retriable(reason) &&
- conn->type == CONN_TYPE_AP) {
+ conn->_base.type == CONN_TYPE_AP) {
log_info(LD_APP,"Address '%s' refused due to '%s'. Considering retrying.",
safe_str(conn->socks_request->address),
connection_edge_end_reason_str(reason));
@@ -775,12 +776,12 @@ connection_edge_process_end_not_open(
log_info(LD_APP,
"Edge got end (%s) before we're connected. Marking for close.",
connection_edge_end_reason_str(rh->length > 0 ? reason : -1));
- if (conn->type == CONN_TYPE_AP) {
+ if (conn->_base.type == CONN_TYPE_AP) {
circuit_log_path(LOG_INFO,LD_APP,circ);
connection_mark_unattached_ap(conn, reason);
} else {
- conn->has_sent_end = 1; /* we just got an 'end', don't need to send one */
- connection_mark_for_close(conn);
+ conn->_base.edge_has_sent_end = 1; /* we just got an 'end', don't need to send one */
+ connection_mark_for_close(TO_CONN(conn));
}
return 0;
}
@@ -795,7 +796,7 @@ connection_edge_process_end_not_open(
static int
connection_edge_process_relay_cell_not_open(
relay_header_t *rh, cell_t *cell, circuit_t *circ,
- connection_t *conn, crypt_path_t *layer_hint)
+ edge_connection_t *conn, crypt_path_t *layer_hint)
{
if (rh->command == RELAY_COMMAND_END) {
if (CIRCUIT_IS_ORIGIN(circ))
@@ -806,17 +807,17 @@ connection_edge_process_relay_cell_not_open(
return 0;
}
- if (conn->type == CONN_TYPE_AP && rh->command == RELAY_COMMAND_CONNECTED) {
+ if (conn->_base.type == CONN_TYPE_AP && rh->command == RELAY_COMMAND_CONNECTED) {
tor_assert(CIRCUIT_IS_ORIGIN(circ));
- if (conn->state != AP_CONN_STATE_CONNECT_WAIT) {
+ if (conn->_base.state != AP_CONN_STATE_CONNECT_WAIT) {
log_warn(LD_APP,"Got 'connected' while not in state connect_wait. "
"Dropping.");
return 0;
}
// log_fn(LOG_INFO,"Connected! Notifying application.");
- conn->state = AP_CONN_STATE_OPEN;
+ conn->_base.state = AP_CONN_STATE_OPEN;
log_info(LD_APP,"'connected' received after %d seconds.",
- (int)(time(NULL) - conn->timestamp_lastread));
+ (int)(time(NULL) - conn->_base.timestamp_lastread));
if (rh->length >= 4) {
uint32_t addr = ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE));
int ttl;
@@ -840,15 +841,15 @@ connection_edge_process_relay_cell_not_open(
/* handle anything that might have queued */
if (connection_edge_package_raw_inbuf(conn, 1) < 0) {
/* (We already sent an end cell if possible) */
- connection_mark_for_close(conn);
+ connection_mark_for_close(TO_CONN(conn));
return 0;
}
return 0;
}
- if (conn->type == CONN_TYPE_AP && rh->command == RELAY_COMMAND_RESOLVED) {
+ if (conn->_base.type == CONN_TYPE_AP && rh->command == RELAY_COMMAND_RESOLVED) {
int ttl;
int answer_len;
- if (conn->state != AP_CONN_STATE_RESOLVE_WAIT) {
+ if (conn->_base.state != AP_CONN_STATE_RESOLVE_WAIT) {
log_warn(LD_APP,"Got a 'resolved' cell while not in state resolve_wait. "
"Dropping.");
return 0;
@@ -877,8 +878,8 @@ connection_edge_process_relay_cell_not_open(
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Got an unexpected relay command %d, in state %d (%s). Dropping.",
- rh->command, conn->state,
- conn_state_to_string(conn->type, conn->state));
+ rh->command, conn->_base.state,
+ conn_state_to_string(conn->_base.type, conn->_base.state));
return 0; /* for forward compatibility, don't kill the circuit */
// connection_edge_end(conn, END_STREAM_REASON_TORPROTOCOL,
// conn->cpath_layer);
@@ -897,7 +898,7 @@ connection_edge_process_relay_cell_not_open(
*/
static int
connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
- connection_t *conn,
+ edge_connection_t *conn,
crypt_path_t *layer_hint)
{
static int num_seen=0;
@@ -922,7 +923,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
/* either conn is NULL, in which case we've got a control cell, or else
* conn points to the recognized stream. */
- if (conn && !connection_state_is_open(conn))
+ if (conn && !connection_state_is_open(TO_CONN(conn)))
return connection_edge_process_relay_cell_not_open(
&rh, cell, circ, conn, layer_hint);
@@ -950,7 +951,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
"(relay data) circ deliver_window below 0. Killing.");
connection_edge_end(conn, END_STREAM_REASON_TORPROTOCOL,
conn->cpath_layer);
- connection_mark_for_close(conn);
+ connection_mark_for_close(TO_CONN(conn));
return -END_CIRC_REASON_TORPROTOCOL;
}
log_debug(domain,"circ deliver_window now %d.", layer_hint ?
@@ -971,7 +972,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
stats_n_data_bytes_received += rh.length;
connection_write_to_buf(cell->payload + RELAY_HEADER_SIZE,
- rh.length, conn);
+ rh.length, TO_CONN(conn));
connection_edge_consider_sending_sendme(conn);
return 0;
case RELAY_COMMAND_END:
@@ -983,7 +984,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
}
/* XXX add to this log_fn the exit node's nickname? */
log_info(domain,"%d: end cell (%s) for stream %d. Removing stream.",
- conn->s,
+ conn->_base.s,
connection_edge_end_reason_str(rh.length > 0 ?
*(char *)(cell->payload+RELAY_HEADER_SIZE) : -1),
conn->stream_id);
@@ -991,12 +992,12 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
log_warn(LD_BUG,
"Bug: open stream hasn't sent socks answer yet? Closing.");
/* We just *got* an end; no reason to send one. */
- conn->has_sent_end = 1;
- if (!conn->marked_for_close) {
+ conn->_base.edge_has_sent_end = 1;
+ if (!conn->_base.marked_for_close) {
/* only mark it if not already marked. it's possible to
* get the 'end' right around when the client hangs up on us. */
- connection_mark_for_close(conn);
- conn->hold_open_until_flushed = 1;
+ connection_mark_for_close(TO_CONN(conn));
+ conn->_base.hold_open_until_flushed = 1;
}
return 0;
case RELAY_COMMAND_EXTEND:
@@ -1076,11 +1077,11 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
conn->package_window += STREAMWINDOW_INCREMENT;
log_debug(domain,"stream-level sendme, packagewindow now %d.",
conn->package_window);
- connection_start_reading(conn);
+ connection_start_reading(TO_CONN(conn));
/* handle whatever might still be on the inbuf */
if (connection_edge_package_raw_inbuf(conn, 1) < 0) {
/* (We already sent an end cell if possible) */
- connection_mark_for_close(conn);
+ connection_mark_for_close(TO_CONN(conn));
return 0;
}
return 0;
@@ -1139,7 +1140,7 @@ uint64_t stats_n_data_bytes_received = 0;
* be marked for close, else return 0.
*/
int
-connection_edge_package_raw_inbuf(connection_t *conn, int package_partial)
+connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial)
{
size_t amount_to_process, length;
char payload[CELL_PAYLOAD_SIZE];
@@ -1147,11 +1148,11 @@ connection_edge_package_raw_inbuf(connection_t *conn, int package_partial)
unsigned domain = conn->cpath_layer ? LD_APP : LD_EXIT;
tor_assert(conn);
- tor_assert(!connection_speaks_cells(conn));
- if (conn->marked_for_close) {
+
+ if (conn->_base.marked_for_close) {
log_warn(LD_BUG,
"Bug: called on conn that's already marked for close at %s:%d.",
- conn->marked_for_close_file, conn->marked_for_close);
+ conn->_base.marked_for_close_file, conn->_base.marked_for_close);
return 0;
}
@@ -1169,11 +1170,11 @@ repeat_connection_edge_package_raw_inbuf:
if (conn->package_window <= 0) {
log_info(domain,"called with package_window %d. Skipping.",
conn->package_window);
- connection_stop_reading(conn);
+ connection_stop_reading(TO_CONN(conn));
return 0;
}
- amount_to_process = buf_datalen(conn->inbuf);
+ amount_to_process = buf_datalen(conn->_base.inbuf);
if (!amount_to_process)
return 0;
@@ -1189,10 +1190,10 @@ repeat_connection_edge_package_raw_inbuf:
stats_n_data_bytes_packaged += length;
stats_n_data_cells_packaged += 1;
- connection_fetch_from_buf(payload, length, conn);
+ connection_fetch_from_buf(payload, length, TO_CONN(conn));
- log_debug(domain,"(%d) Packaging %d bytes (%d waiting).", conn->s,
- (int)length, (int)buf_datalen(conn->inbuf));
+ log_debug(domain,"(%d) Packaging %d bytes (%d waiting).", conn->_base.s,
+ (int)length, (int)buf_datalen(conn->_base.inbuf));
if (connection_edge_send_command(conn, circ, RELAY_COMMAND_DATA,
payload, length, conn->cpath_layer) < 0)
@@ -1208,7 +1209,7 @@ repeat_connection_edge_package_raw_inbuf:
}
if (--conn->package_window <= 0) { /* is it 0 after decrement? */
- connection_stop_reading(conn);
+ connection_stop_reading(TO_CONN(conn));
log_debug(domain,"conn->package_window reached 0.");
circuit_consider_stop_edge_reading(circ, conn->cpath_layer);
return 0; /* don't process the inbuf any more */
@@ -1226,11 +1227,11 @@ repeat_connection_edge_package_raw_inbuf:
* low, send back a suitable number of stream-level sendme cells.
*/
void
-connection_edge_consider_sending_sendme(connection_t *conn)
+connection_edge_consider_sending_sendme(edge_connection_t *conn)
{
circuit_t *circ;
- if (connection_outbuf_too_full(conn))
+ if (connection_outbuf_too_full(TO_CONN(conn)))
return;
circ = circuit_get_by_edge_conn(conn);
@@ -1244,7 +1245,7 @@ connection_edge_consider_sending_sendme(connection_t *conn)
while (conn->deliver_window < STREAMWINDOW_START - STREAMWINDOW_INCREMENT) {
log_debug(conn->cpath_layer?LD_APP:LD_EXIT,
"Outbuf %d, Queueing stream sendme.",
- (int)conn->outbuf_flushlen);
+ (int)conn->_base.outbuf_flushlen);
conn->deliver_window += STREAMWINDOW_INCREMENT;
if (connection_edge_send_command(conn, circ, RELAY_COMMAND_SENDME,
NULL, 0, conn->cpath_layer) < 0) {
@@ -1278,21 +1279,21 @@ circuit_resume_edge_reading(circuit_t *circ, crypt_path_t *layer_hint)
* of a linked list of edge streams that should each be considered.
*/
static int
-circuit_resume_edge_reading_helper(connection_t *conn,
+circuit_resume_edge_reading_helper(edge_connection_t *conn,
circuit_t *circ,
crypt_path_t *layer_hint)
{
for ( ; conn; conn=conn->next_stream) {
- if (conn->marked_for_close)
+ if (conn->_base.marked_for_close)
continue;
if ((!layer_hint && conn->package_window > 0) ||
(layer_hint && conn->package_window > 0 &&
conn->cpath_layer == layer_hint)) {
- connection_start_reading(conn);
+ connection_start_reading(TO_CONN(conn));
/* handle whatever might still be on the inbuf */
if (connection_edge_package_raw_inbuf(conn, 1)<0) {
/* (We already sent an end cell if possible) */
- connection_mark_for_close(conn);
+ connection_mark_for_close(TO_CONN(conn));
continue;
}
@@ -1315,7 +1316,7 @@ circuit_resume_edge_reading_helper(connection_t *conn,
static int
circuit_consider_stop_edge_reading(circuit_t *circ, crypt_path_t *layer_hint)
{
- connection_t *conn = NULL;
+ edge_connection_t *conn = NULL;
unsigned domain = layer_hint ? LD_APP : LD_EXIT;
if (!layer_hint) {
@@ -1325,7 +1326,7 @@ circuit_consider_stop_edge_reading(circuit_t *circ, crypt_path_t *layer_hint)
if (circ->package_window <= 0) {
log_debug(domain,"yes, not-at-origin. stopped.");
for (conn = or_circ->n_streams; conn; conn=conn->next_stream)
- connection_stop_reading(conn);
+ connection_stop_reading(TO_CONN(conn));
return 1;
}
return 0;
@@ -1344,7 +1345,7 @@ circuit_consider_stop_edge_reading(circuit_t *circ, crypt_path_t *layer_hint)
for (conn = TO_ORIGIN_CIRCUIT(circ)->p_streams; conn;
conn=conn->next_stream)
if (conn->cpath_layer == layer_hint)
- connection_stop_reading(conn);
+ connection_stop_reading(TO_CONN(conn));
return 1;
}
return 0;
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index 3445bd5c88..00471bbc23 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -430,7 +430,7 @@ rend_client_receive_rendezvous(origin_circuit_t *circ, const char *request,
void
rend_client_desc_here(const char *query)
{
- connection_t *conn;
+ edge_connection_t *conn;
rend_cache_entry_t *entry;
time_t now = time(NULL);
int i, n_conns;
@@ -439,25 +439,26 @@ rend_client_desc_here(const char *query)
get_connection_array(&carray, &n_conns);
for (i = 0; i < n_conns; ++i) {
- conn = carray[i];
- if (conn->type != CONN_TYPE_AP ||
- conn->state != AP_CONN_STATE_RENDDESC_WAIT ||
- conn->marked_for_close ||
- rend_cmp_service_ids(query, conn->rend_query))
+ if (carray[i]->type != CONN_TYPE_AP ||
+ carray[i]->state != AP_CONN_STATE_RENDDESC_WAIT ||
+ carray[i]->marked_for_close)
+ continue;
+ conn = TO_EDGE_CONN(carray[i]);
+ if (rend_cmp_service_ids(query, conn->rend_query))
continue;
- assert_connection_ok(conn, now);
+ assert_connection_ok(TO_CONN(conn), now);
if (rend_cache_lookup_entry(conn->rend_query, -1, &entry) == 1 &&
entry->parsed->n_intro_points > 0) {
/* either this fetch worked, or it failed but there was a
* valid entry from before which we should reuse */
log_info(LD_REND,"Rend desc is usable. Launching circuits.");
- conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
+ conn->_base.state = AP_CONN_STATE_CIRCUIT_WAIT;
/* restart their timeout values, so they get a fair shake at
* connecting to the hidden service. */
- conn->timestamp_created = now;
- conn->timestamp_lastread = now;
- conn->timestamp_lastwritten = now;
+ conn->_base.timestamp_created = now;
+ conn->_base.timestamp_lastread = now;
+ conn->_base.timestamp_lastwritten = now;
if (connection_ap_handshake_attach_circuit(conn) < 0) {
/* it will never work */
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index d0bb33d138..0cda1d95c0 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -1121,7 +1121,7 @@ rend_service_dump_stats(int severity)
* or 0 for success.
*/
int
-rend_service_set_connection_addr_port(connection_t *conn,
+rend_service_set_connection_addr_port(edge_connection_t *conn,
origin_circuit_t *circ)
{
rend_service_t *service;
@@ -1142,14 +1142,14 @@ rend_service_set_connection_addr_port(connection_t *conn,
}
for (i = 0; i < smartlist_len(service->ports); ++i) {
p = smartlist_get(service->ports, i);
- if (conn->port == p->virtual_port) {
- conn->addr = p->real_addr;
- conn->port = p->real_port;
+ if (conn->_base.port == p->virtual_port) {
+ conn->_base.addr = p->real_addr;
+ conn->_base.port = p->real_port;
return 0;
}
}
log_info(LD_REND, "No virtual port mapping exists for port %d on service %s",
- conn->port,serviceid);
+ conn->_base.port,serviceid);
return -1;
}
diff --git a/src/or/router.c b/src/or/router.c
index 3ae6d1a24a..63262c483c 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -650,16 +650,16 @@ router_upload_dir_desc_to_dirservers(int force)
* conn. Return 0 if we accept; non-0 if we reject.
*/
int
-router_compare_to_my_exit_policy(connection_t *conn)
+router_compare_to_my_exit_policy(edge_connection_t *conn)
{
tor_assert(desc_routerinfo);
/* make sure it's resolved to something. this way we can't get a
'maybe' below. */
- if (!conn->addr)
+ if (!conn->_base.addr)
return -1;
- return compare_addr_to_addr_policy(conn->addr, conn->port,
+ return compare_addr_to_addr_policy(conn->_base.addr, conn->_base.port,
desc_routerinfo->exit_policy) != ADDR_POLICY_ACCEPTED;
}
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 46cb160918..5eb804477d 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -1705,13 +1705,13 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
/* mark-for-close connections using the old key, so we can
* make new ones with the new key.
*/
- connection_t *conn;
+ or_connection_t *conn;
while ((conn = connection_or_get_by_identity_digest(
old_router->cache_info.identity_digest))) {
log_info(LD_DIR,"Closing conn to router '%s'; there is now a named "
"router with that name.",
old_router->nickname);
- connection_mark_for_close(conn);
+ connection_mark_for_close(TO_CONN(conn));
}
routerlist_remove(routerlist, old_router, i--, 0);
} else if (old_router->is_named) {
@@ -3317,8 +3317,9 @@ list_pending_descriptor_downloads(digestmap_t *result)
if (conn->type == CONN_TYPE_DIR &&
conn->purpose == DIR_PURPOSE_FETCH_SERVERDESC &&
!conn->marked_for_close) {
- if (!strcmpstart(conn->requested_resource, prefix))
- dir_split_resource_into_fingerprints(conn->requested_resource+p_len,
+ dir_connection_t *dir_conn = TO_DIR_CONN(conn);
+ if (!strcmpstart(dir_conn->requested_resource, prefix))
+ dir_split_resource_into_fingerprints(dir_conn->requested_resource+p_len,
tmp, NULL, 1, 0);
}
}