}
/** Given a text circuit <b>id</b>, return the corresponding circuit. */
-static circuit_t *
+static origin_circuit_t *
get_circ(const char *id)
{
unsigned long n_id;
}
/** Given a text stream <b>id</b>, return the corresponding AP connection. */
-static connection_t *
+static edge_connection_t *
get_stream(const char *id)
{
unsigned long n_id;
int ok;
- connection_t *conn;
+ edge_connection_t *conn;
n_id = tor_parse_ulong(id, 10, 0, ULONG_MAX, &ok, NULL);
if (!ok)
return NULL;
conn = connection_get_by_global_id(n_id);
- if (!conn || conn->type != CONN_TYPE_AP)
+ if (!conn || conn->_base.type != CONN_TYPE_AP)
return NULL;
return conn;
}
slen = strlen(path)+strlen(state)+20;
s = tor_malloc(slen+1);
tor_snprintf(s, slen, "%lu %s %s",
- (unsigned long)circ->global_identifier,
+ (unsigned long)TO_ORIGIN_CIRCUIT(circ)->global_identifier,
state, path);
smartlist_add(status, s);
tor_free(path);
char *s;
size_t slen;
circuit_t *circ;
+ origin_circuit_t *origin_circ = NULL;
if (conns[i]->type != CONN_TYPE_AP ||
conns[i]->marked_for_close ||
conns[i]->state == AP_CONN_STATE_SOCKS_WAIT)
continue;
}
circ = circuit_get_by_edge_conn(conn);
+ if (CIRCUIT_IS_ORIGIN(circ))
+ origin_circ = TO_ORIGIN_CIRCUIT(circ);
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) conn->_base.global_identifier,state,
- circ?(unsigned long)circ->global_identifier : 0ul,
+ (unsigned long) conn->global_identifier,state,
+ origin_circ?
+ (unsigned long)origin_circ->global_identifier : 0ul,
buf);
smartlist_add(status, s);
}
{
smartlist_t *router_nicknames=NULL, *routers=NULL;
uint32_t circ_id;
- circuit_t *circ = NULL;
+ origin_circuit_t *circ = NULL;
int zero_circ, v0;
char reply[4];
uint8_t intended_purpose = CIRCUIT_PURPOSE_C_GENERAL;
}
}
- if (circ && ! CIRCUIT_IS_ORIGIN(circ)) {
- if (v0)
- send_control0_error(conn, ERR_NO_CIRC,"Circuit does not originate here");
- else
- connection_printf_to_buf(conn,
- "555 Circuit does not originate here\r\n");
- goto done;
- }
-
routers = smartlist_create();
SMARTLIST_FOREACH(router_nicknames, const char *, n,
{
if (zero_circ) {
/* start a new circuit */
- circ = TO_CIRCUIT( origin_circuit_init(intended_purpose, 0, 0, 0) );
+ circ = origin_circuit_init(intended_purpose, 0, 0, 0);
}
/* now circ refers to something that is ready to be extended */
SMARTLIST_FOREACH(routers, routerinfo_t *, r,
{
extend_info_t *info = extend_info_from_router(r);
- circuit_append_new_exit(TO_ORIGIN_CIRCUIT(circ), info);
+ circuit_append_new_exit(circ, info);
extend_info_free(info);
});
/* now that we've populated the cpath, start extending */
if (zero_circ) {
- if (circuit_handle_first_hop(TO_ORIGIN_CIRCUIT(circ)) < 0) {
- circuit_mark_for_close(circ, END_CIRC_AT_ORIGIN);
+ if (circuit_handle_first_hop(circ) < 0) {
+ circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_AT_ORIGIN);
if (v0)
send_control0_error(conn, ERR_INTERNAL, "couldn't start circuit");
else
goto done;
}
} else {
- if (circ->state == CIRCUIT_STATE_OPEN) {
- circuit_set_state(circ, CIRCUIT_STATE_BUILDING);
- if (circuit_send_next_onion_skin(TO_ORIGIN_CIRCUIT(circ)) < 0) {
+ if (circ->_base.state == CIRCUIT_STATE_OPEN) {
+ circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_BUILDING);
+ if (circuit_send_next_onion_skin(circ) < 0) {
log_info(LD_CONTROL,
"send_next_onion_skin failed; circuit marked for closing.");
- circuit_mark_for_close(circ, END_CIRC_AT_ORIGIN);
+ circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_AT_ORIGIN);
if (v0)
send_control0_error(conn, ERR_INTERNAL, "couldn't send onion skin");
else
handle_control_setpurpose(control_connection_t *conn, int for_circuits,
uint32_t len, const char *body)
{
- circuit_t *circ = NULL;
+ origin_circuit_t *circ = NULL;
routerinfo_t *ri = NULL;
uint8_t new_purpose;
smartlist_t *args = smartlist_create();
}
if (for_circuits)
- circ->purpose = new_purpose;
+ circ->_base.purpose = new_purpose;
else
ri->purpose = new_purpose;
connection_write_str_to_buf("250 OK\r\n", conn);
handle_control_attachstream(control_connection_t *conn, uint32_t len,
const char *body)
{
- connection_t *ap_conn = NULL;
- circuit_t *circ = NULL;
+ edge_connection_t *ap_conn = NULL;
+ origin_circuit_t *circ = NULL;
int zero_circ;
- edge_connection_t *edge_conn;
if (STATE_IS_V0(conn->_base.state)) {
uint32_t conn_id;
return 0;
}
- 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 (ap_conn->_base.state != AP_CONN_STATE_CONTROLLER_WAIT &&
+ ap_conn->_base.state != AP_CONN_STATE_CONNECT_WAIT &&
+ ap_conn->_base.state != AP_CONN_STATE_RESOLVE_WAIT) {
if (STATE_IS_V0(conn->_base.state)) {
send_control0_error(conn, ERR_NO_STREAM,
"Connection is not managed by controller.");
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(edge_conn);
- connection_edge_end(edge_conn, END_STREAM_REASON_TIMEOUT,
- edge_conn->cpath_layer);
+ if (ap_conn->_base.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,
+ ap_conn->cpath_layer);
/* Un-mark it as ending, since we're going to reuse it. */
- ap_conn->edge_has_sent_end = 0;
+ ap_conn->_base.edge_has_sent_end = 0;
if (tmpcirc)
- circuit_detach_stream(tmpcirc,edge_conn);
- ap_conn->state = AP_CONN_STATE_CONTROLLER_WAIT;
+ circuit_detach_stream(tmpcirc,ap_conn);
+ ap_conn->_base.state = AP_CONN_STATE_CONTROLLER_WAIT;
}
- if (circ &&
- (circ->state != CIRCUIT_STATE_OPEN || ! CIRCUIT_IS_ORIGIN(circ))) {
+ if (circ && (circ->_base.state != CIRCUIT_STATE_OPEN)) {
if (STATE_IS_V0(conn->_base.state))
send_control0_error(conn, ERR_INTERNAL,
"Refuse to attach stream to non-open, origin circ.");
conn);
return 0;
}
- if (connection_ap_handshake_rewrite_and_attach(edge_conn,
- circ ? TO_ORIGIN_CIRCUIT(circ) : NULL) < 0) {
+ if (connection_ap_handshake_rewrite_and_attach(ap_conn, circ) < 0) {
if (STATE_IS_V0(conn->_base.state))
send_control0_error(conn, ERR_INTERNAL, "Unable to attach stream.");
else
handle_control_redirectstream(control_connection_t *conn, uint32_t len,
const char *body)
{
- connection_t *ap_conn = NULL;
+ edge_connection_t *ap_conn = NULL;
uint32_t conn_id;
char *new_addr = NULL;
uint16_t new_port = 0;
conn_id = ntohl(get_uint32(body));
if (!(ap_conn = connection_get_by_global_id(conn_id))
- || ap_conn->state != CONN_TYPE_AP
- || !TO_EDGE_CONN(ap_conn)->socks_request) {
+ || ap_conn->_base.state != CONN_TYPE_AP
+ || ap_conn->socks_request) {
send_control0_error(conn, ERR_NO_STREAM,
"No AP connection found with given ID");
return 0;
connection_printf_to_buf(conn,
"512 Missing argument to REDIRECTSTREAM\r\n");
else if (!(ap_conn = get_stream(smartlist_get(args, 0)))
- || !TO_EDGE_CONN(ap_conn)->socks_request) {
+ || !ap_conn->socks_request) {
connection_printf_to_buf(conn, "552 Unknown stream \"%s\"\r\n",
(char*)smartlist_get(args, 0));
} else {
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;
- }
+ 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;
}
/** Called when we get a CLOSESTREAM command; try to close the named stream
handle_control_closestream(control_connection_t *conn, uint32_t len,
const char *body)
{
- connection_t *ap_conn=NULL;
+ edge_connection_t *ap_conn=NULL;
uint8_t reason=0;
if (STATE_IS_V0(conn->_base.state)) {
reason = *(uint8_t*)(body+4);
if (!(ap_conn = connection_get_by_global_id(conn_id))
- || ap_conn->state != CONN_TYPE_AP
- || !TO_EDGE_CONN(ap_conn)->socks_request) {
+ || ap_conn->_base.state != CONN_TYPE_AP
+ || ap_conn->socks_request) {
send_control0_error(conn, ERR_NO_STREAM,
"No AP connection found with given ID");
return 0;
return 0;
}
- connection_mark_unattached_ap(TO_EDGE_CONN(ap_conn), reason);
+ connection_mark_unattached_ap(ap_conn, reason);
send_control_done(conn);
return 0;
}
handle_control_closecircuit(control_connection_t *conn, uint32_t len,
const char *body)
{
- circuit_t *circ = NULL;
+ origin_circuit_t *circ = NULL;
int safe = 0;
if (STATE_IS_V0(conn->_base.state)) {
return 0;
}
- if (!safe || !CIRCUIT_IS_ORIGIN(circ) ||
- !TO_ORIGIN_CIRCUIT(circ)->p_streams) {
- circuit_mark_for_close(circ, END_CIRC_REASON_NONE);
+ if (!safe || !circ->p_streams) {
+ circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_NONE);
}
send_control_done(conn);
size_t path_len = strlen(path);
msg = tor_malloc(1+4+path_len+1); /* event, circid, path, NUL. */
msg[0] = (uint8_t) tp;
- set_uint32(msg+1, htonl(circ->_base.global_identifier));
+ set_uint32(msg+1, htonl(circ->global_identifier));
strlcpy(msg+5,path,path_len+1);
send_control0_event(EVENT_CIRCUIT_STATUS, (uint32_t)(path_len+6), msg);
}
send_control1_event(EVENT_CIRCUIT_STATUS,
"650 CIRC %lu %s %s\r\n",
- (unsigned long)circ->_base.global_identifier,
+ (unsigned long)circ->global_identifier,
status, path);
}
tor_free(path);
len = strlen(buf);
msg = tor_malloc(5+len+1);
msg[0] = (uint8_t) tp;
- set_uint32(msg+1, htonl(conn->_base.global_identifier));
+ set_uint32(msg+1, htonl(conn->global_identifier));
strlcpy(msg+5, buf, len+1);
send_control0_event(EVENT_STREAM_STATUS, (uint32_t)(5+len+1), msg);
if (EVENT_IS_INTERESTING1(EVENT_STREAM_STATUS)) {
const char *status;
circuit_t *circ;
+ origin_circuit_t *origin_circ = NULL;
switch (tp)
{
case STREAM_EVENT_SENT_CONNECT: status = "SENTCONNECT"; break;
return 0;
}
circ = circuit_get_by_edge_conn(conn);
+ if (circ && CIRCUIT_IS_ORIGIN(circ))
+ origin_circ = TO_ORIGIN_CIRCUIT(circ);
send_control1_event(EVENT_STREAM_STATUS,
"650 STREAM %lu %s %lu %s\r\n",
- (unsigned long)conn->_base.global_identifier, status,
- circ?(unsigned long)circ->global_identifier : 0ul,
+ (unsigned long)conn->global_identifier, status,
+ origin_circ?
+ (unsigned long)origin_circ->global_identifier : 0ul,
buf);
/* XXX need to specify its intended exit, etc? */
}
uint8_t type; /**< What kind of connection is this? */
uint8_t state; /**< Current state of this connection. */
- uint8_t purpose; /**< Only used for DIR and EXIT types currently. */
+ uint8_t purpose; /**< Only used for DIR and EXIT types currently. !!! */
unsigned wants_to_read:1; /**< Boolean: should we start reading again once
* the bandwidth throttler allows it? */
unsigned wants_to_write:1; /**< Boolean: should we start writing again once
* 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. */
+ * events as appropriate. !!!! */
unsigned int control_events_are_extended:1;
- /** Used for OR conns that shouldn't get any new circs attached to them. */
+ /** Used for OR conns that shouldn't get any new circs attached to them. !!*/
unsigned int or_is_obsolete:1;
/** For AP connections only. If 1, and we fail to reach the chosen exit,
- * stop requiring it. */
+ * stop requiring it. !!! */
unsigned int chosen_exit_optional:1;
int s; /**< Our socket; -1 if this connection is closed. */
struct event *read_event; /**< Libevent event structure. */
struct event *write_event; /**< Libevent event structure. */
buf_t *inbuf; /**< Buffer holding data read over this connection. */
- int inbuf_reached_eof; /**< Boolean: did read() return 0 on this conn? */
- time_t timestamp_lastread; /**< When was the last time poll() said we could
+ int inbuf_reached_eof; /**< Boolean: did read() return 0 on this conn?
+ * (!!!bitfield?)
+ */
+ time_t timestamp_lastread; /**< When was the last time libevent said we could
* read? */
buf_t *outbuf; /**< Buffer holding data to write over this connection. */
size_t outbuf_flushlen; /**< How much data should we try to flush from the
* outbuf? */
- time_t timestamp_lastwritten; /**< When was the last time poll() said we
+ time_t timestamp_lastwritten; /**< When was the last time libevent said we
* could write? */
time_t timestamp_created; /**< When was this connection_t created? */
- time_t timestamp_lastempty; /**< When was the outbuf last completely empty?*/
+ time_t timestamp_lastempty; /**< When was the outbuf last completely empty?
+ * !!!!
+ */
uint32_t addr; /**< IP of the other side of the connection; used to identify
* routers, along with port. */
char *address; /**< FQDN (or IP) of the guy on the other end.
* strdup into this, because free_connection frees it. */
- /** 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;
} connection_t;
/** Subtype of connection_t for an "OR connection" -- that is, one that speaks
uint16_t stream_id; /**< The stream ID used for this edge connection on its
* circuit */
+ /** Quasi-global identifier for this connection; used for control.c */
+ /* XXXX NM This can get re-used after 2**32 streams */
+ uint32_t global_identifier;
+
char rend_query[REND_SERVICE_ID_LEN+1]; /**< What rendezvous service are we
* querying for? (AP only) */
} edge_connection_t;
const char *marked_for_close_file; /**< For debugging: in which file was this
* circuit marked for close? */
- /** Quasi-global identifier for this circuit; used for control.c */
- /* XXXX NM This can get re-used after 2**32 circuits. */
- uint32_t global_identifier;
-
struct circuit_t *next; /**< Next circuit in linked list. */
} circuit_t;
* construct a new AP stream originating at this circuit. */
uint16_t next_stream_id;
+ /** Quasi-global identifier for this circuit; used for control.c */
+ /* XXXX NM This can get re-used after 2**32 circuits. */
+ uint32_t global_identifier;
+
} origin_circuit_t;
/** An or_circuit_t holds information needed to implement a circuit at an
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_global_id(uint32_t id);
origin_circuit_t *circuit_get_by_rend_query_and_purpose(const char *rend_query,
uint8_t purpose);
origin_circuit_t *circuit_get_next_by_pk_and_purpose(origin_circuit_t *start,
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);
+edge_connection_t *connection_get_by_global_id(uint32_t id);
connection_t *connection_get_by_type(int type);
connection_t *connection_get_by_type_purpose(int type, int purpose);