[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] Implement the common case of ATTACHSTREAM.
Update of /home/or/cvsroot/tor/src/or
In directory moria.mit.edu:/tmp/cvs-serv32619/src/or
Modified Files:
circuitlist.c circuituse.c config.c connection.c
connection_edge.c control.c or.h
Log Message:
Implement the common case of ATTACHSTREAM.
Index: circuitlist.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/circuitlist.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- circuitlist.c 2 Mar 2005 03:13:05 -0000 1.27
+++ circuitlist.c 12 Mar 2005 04:22:00 -0000 1.28
@@ -183,6 +183,22 @@
tor_free(victim);
}
+/** DOCDOC **/
+circuit_t *
+circuit_get_by_global_id(uint32_t id)
+{
+ circuit_t *circ;
+ for (circ=global_circuitlist;circ;circ = circ->next) {
+ if (circ->global_identifier == id) {
+ if (circ->marked_for_close)
+ return NULL;
+ else
+ return circ;
+ }
+ }
+ return NULL;
+}
+
/** Return a circ such that:
* - circ-\>n_circ_id or circ-\>p_circ_id is equal to <b>circ_id</b>, and
* - circ is attached to <b>conn</b>, either as p_conn, n-conn, or
Index: circuituse.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/circuituse.c,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -d -r1.51 -r1.52
--- circuituse.c 27 Feb 2005 09:47:00 -0000 1.51
+++ circuituse.c 12 Mar 2005 04:22:00 -0000 1.52
@@ -980,6 +980,36 @@
time(NULL) + options->TrackHostExitsExpire);
}
+/* DOCDOC. Return as for connection_ap_handshake_attach_chosen_circuit. */
+int
+connection_ap_handshake_attach_chosen_circuit(connection_t *conn,
+ 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->socks_request);
+ tor_assert(circ);
+
+ conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
+
+ if (!circ->timestamp_dirty)
+ circ->timestamp_dirty = time(NULL);
+
+ link_apconn_to_circ(conn, circ);
+ tor_assert(conn->socks_request);
+ if (conn->socks_request->command == SOCKS_COMMAND_CONNECT) {
+ consider_recording_trackhost(conn, circ);
+ connection_ap_handshake_send_begin(conn, circ);
+ } else {
+ connection_ap_handshake_send_resolve(conn, circ);
+ }
+
+ return 1;
+}
+
+
/** Try to find a safe live circuit for CONN_TYPE_AP connection conn. If
* we don't find one: if conn cannot be handled by any known nodes,
* warn and return -1 (conn needs to die);
@@ -1024,27 +1054,14 @@
if (retval < 1)
return retval;
- /* We have found a suitable circuit for our conn. Hurray. */
- tor_assert(circ);
-
- log_fn(LOG_DEBUG,"Attaching apconn to general circ %d (stream %d sec old).",
+ log_fn(LOG_DEBUG,"Attaching apconn to circ %d (stream %d sec old).",
circ->n_circ_id, conn_age);
/* here, print the circ's path. so people can figure out which circs are sucking. */
circuit_log_path(LOG_INFO,circ);
- if (!circ->timestamp_dirty)
- circ->timestamp_dirty = time(NULL);
-
- link_apconn_to_circ(conn, circ);
- tor_assert(conn->socks_request);
- if (conn->socks_request->command == SOCKS_COMMAND_CONNECT) {
- consider_recording_trackhost(conn, circ);
- connection_ap_handshake_send_begin(conn, circ);
- } else {
- connection_ap_handshake_send_resolve(conn, circ);
- }
+ /* We have found a suitable circuit for our conn. Hurray. */
+ return connection_ap_handshake_attach_chosen_circuit(conn, circ);
- return 1;
} else { /* we're a rendezvous conn */
circuit_t *rendcirc=NULL, *introcirc=NULL;
Index: config.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/config.c,v
retrieving revision 1.320
retrieving revision 1.321
diff -u -d -r1.320 -r1.321
--- config.c 11 Mar 2005 21:39:39 -0000 1.320
+++ config.c 12 Mar 2005 04:22:00 -0000 1.321
@@ -174,6 +174,7 @@
VAR("SysLog", LINELIST_S, OldLogOptions, NULL),
OBSOLETE("TrafficShaping"),
VAR("User", STRING, User, NULL),
+ VAR("__ManageConnections", BOOL, ManageConnections, "1"),
{ NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
};
#undef VAR
@@ -1155,6 +1156,9 @@
if (config_vars[i].type == CONFIG_TYPE_OBSOLETE ||
config_vars[i].type == CONFIG_TYPE_LINELIST_S)
continue;
+ /* Don't save 'hidden' control variables. */
+ if (!strcmpstart(config_vars[i].name, "__"))
+ continue;
if (minimal && option_is_same(options, defaults, config_vars[i].name))
continue;
line = config_get_assigned_option(options, config_vars[i].name);
Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/connection.c,v
retrieving revision 1.335
retrieving revision 1.336
diff -u -d -r1.335 -r1.336
--- connection.c 1 Mar 2005 22:42:31 -0000 1.335
+++ connection.c 12 Mar 2005 04:22:01 -0000 1.336
@@ -1243,6 +1243,30 @@
return best;
}
+
+/** Return the connection with id <b>id</b> if it is not already
+ * marked for close.
+ */
+connection_t *
+connection_get_by_global_id(uint32_t id) {
+ int i, n;
+ connection_t *conn;
+ connection_t **carray;
+
+ get_connection_array(&carray,&n);
+ for (i=0;i<n;i++) {
+ conn = carray[i];
+ if (conn->global_identifier == id) {
+ if (!conn->marked_for_close)
+ return conn;
+ else
+ return NULL;
+ }
+ }
+ return NULL;
+}
+
+
/** Return a connection of type <b>type</b> that is not marked for
* close.
*/
Index: connection_edge.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/connection_edge.c,v
retrieving revision 1.295
retrieving revision 1.296
diff -u -d -r1.295 -r1.296
--- connection_edge.c 11 Mar 2005 21:42:32 -0000 1.295
+++ connection_edge.c 12 Mar 2005 04:22:01 -0000 1.296
@@ -839,16 +839,22 @@
return 0;
}
rep_hist_note_used_resolve(time(NULL)); /* help predict this next time */
+ control_event_stream_status(conn, STREAM_EVENT_NEW_RESOLVE);
} else { /* socks->command == SOCKS_COMMAND_CONNECT */
if (socks->port == 0) {
log_fn(LOG_NOTICE,"Application asked to connect to port 0. Refusing.");
return -1;
}
rep_hist_note_used_port(socks->port, time(NULL)); /* help predict this next time */
+ control_event_stream_status(conn, STREAM_EVENT_NEW);
+ }
+ if (get_options()->ManageConnections) {
+ conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
+ return connection_ap_handshake_attach_circuit(conn);
+ } else {
+ conn->state = AP_CONN_STATE_CONTROLLER_WAIT;
+ return 0;
}
- control_event_stream_status(conn, STREAM_EVENT_NEW);
- conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
- return connection_ap_handshake_attach_circuit(conn);
} else {
/* it's a hidden-service request */
rend_cache_entry_t *entry;
Index: control.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/control.c,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -d -r1.54 -r1.55
--- control.c 10 Mar 2005 18:46:11 -0000 1.54
+++ control.c 12 Mar 2005 04:22:01 -0000 1.55
@@ -61,7 +61,8 @@
#define ERR_UNAUTHORIZED 0x0007
#define ERR_REJECTED_AUTHENTICATION 0x0008
#define ERR_RESOURCE_EXHAUSETED 0x0009
-#define ERR_TOO_LONG 0x000A
+#define ERR_NO_STREAM 0x000A
+#define ERR_NO_CIRC 0x000B
/* Recognized asynchronous event types. */
#define _EVENT_MIN 0x0001
@@ -613,12 +614,6 @@
}
});
- if (msg_len > 65535) {
- /* XXXX What if it *is* this long? */
- send_control_error(conn, ERR_TOO_LONG, body);
- goto done;
- }
-
msg = smartlist_join_strings2(answers, "\0", 1, 1, &msg_len);
send_control_message(conn, CONTROL_CMD_INFOVALUE,
msg_len, msg_len?msg:NULL);
@@ -642,7 +637,47 @@
static int handle_control_attachstream(connection_t *conn, uint32_t len,
const char *body)
{
- send_control_error(conn,ERR_UNRECOGNIZED_TYPE,"not yet implemented");
+ uint32_t conn_id;
+ uint32_t circ_id;
+ connection_t *ap_conn;
+ circuit_t *circ;
+
+ if (len < 8) {
+ send_control_error(conn, ERR_SYNTAX, "attachstream message too short");
+ return 0;
+ }
+
+ conn_id = ntohl(get_uint32(body));
+ circ_id = ntohl(get_uint32(body+4));
+
+ if (!(ap_conn = connection_get_by_global_id(conn_id))) {
+ send_control_error(conn, ERR_NO_STREAM,
+ "No connection found with given ID");
+ return 0;
+ }
+ if (ap_conn->state != AP_CONN_STATE_CONTROLLER_WAIT) {
+ send_control_error(conn, ERR_NO_STREAM,
+ "Connection was not managed by controller.");
+ return 0;
+ }
+
+ if (!circ_id) {
+ ap_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
+ if (connection_ap_handshake_attach_circuit(ap_conn)<0)
+ connection_mark_for_close(ap_conn);
+
+ return 0;
+ }
+
+
+ if (!(circ = circuit_get_by_global_id(circ_id))) {
+ send_control_error(conn, ERR_NO_CIRC, "No circuit found with given ID");
+ return 0;
+ }
+ if (connection_ap_handshake_attach_chosen_circuit(ap_conn, circ) != 1) {
+ send_control_error(conn, ERR_INTERNAL, "Unable to attach stream.");
+ return 0;
+ }
return 0;
}
static int
Index: or.h
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.554
retrieving revision 1.555
diff -u -d -r1.554 -r1.555
--- or.h 11 Mar 2005 21:39:39 -0000 1.554
+++ or.h 12 Mar 2005 04:22:01 -0000 1.555
@@ -256,15 +256,18 @@
/** State for a SOCKS connection: got a y.onion URL; waiting to receive
* rendezvous rescriptor. */
#define AP_CONN_STATE_RENDDESC_WAIT 6
+/** The controller will attach this connection to a circuit; it isn't our
+ * job to do so. */
+#define AP_CONN_STATE_CONTROLLER_WAIT 7
/** State for a SOCKS connection: waiting for a completed circuit. */
-#define AP_CONN_STATE_CIRCUIT_WAIT 7
+#define AP_CONN_STATE_CIRCUIT_WAIT 8
/** State for a SOCKS connection: sent BEGIN, waiting for CONNECTED. */
-#define AP_CONN_STATE_CONNECT_WAIT 8
+#define AP_CONN_STATE_CONNECT_WAIT 9
/** State for a SOCKS connection: send RESOLVE, waiting for RESOLVED. */
-#define AP_CONN_STATE_RESOLVE_WAIT 9
+#define AP_CONN_STATE_RESOLVE_WAIT 10
/** State for a SOCKS connection: ready to send and receive. */
-#define AP_CONN_STATE_OPEN 10
-#define _AP_CONN_STATE_MAX 10
+#define AP_CONN_STATE_OPEN 11
+#define _AP_CONN_STATE_MAX 11
#define _DIR_CONN_STATE_MIN 1
/** State for connection to directory server: waiting for connect(). */
@@ -1053,6 +1056,9 @@
* the control system. */
int CookieAuthentication; /**< Boolean: do we enable cookie-based auth for
* the control system? */
+ int ManageConnections; /**< Boolean: Does Tor attach new connections to
+ * circuits itself (1), or does it let the controller
+ * deal? (0) */
} or_options_t;
#define MAX_SOCKS_REPLY_LEN 1024
@@ -1133,6 +1139,7 @@
circuit_t *circuit_new(uint16_t p_circ_id, connection_t *p_conn);
circuit_t *circuit_get_by_circ_id_conn(uint16_t circ_id, connection_t *conn);
circuit_t *circuit_get_by_conn(connection_t *conn);
+circuit_t *circuit_get_by_global_id(uint32_t id);
circuit_t *circuit_get_by_rend_query_and_purpose(const char *rend_query, uint8_t purpose);
circuit_t *circuit_get_next_by_pk_and_purpose(circuit_t *start,
const char *digest, uint8_t purpose);
@@ -1172,6 +1179,8 @@
circuit_t *circuit_launch_by_identity(uint8_t purpose, const char *exit_digest,
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,
+ circuit_t *circ);
int connection_ap_handshake_attach_circuit(connection_t *conn);
/********************************* command.c ***************************/
@@ -1260,6 +1269,7 @@
connection_t *connection_exact_get_by_addr_port(uint32_t addr, uint16_t port);
connection_t *connection_get_by_identity_digest(const char *digest, int type);
+connection_t *connection_get_by_global_id(uint32_t id);
connection_t *connection_get_by_type(int type);
connection_t *connection_get_by_type_state(int type, int state);
@@ -1365,7 +1375,8 @@
STREAM_EVENT_SUCCEEDED = 2,
STREAM_EVENT_FAILED = 3,
STREAM_EVENT_CLOSED = 4,
- STREAM_EVENT_NEW = 5
+ STREAM_EVENT_NEW = 5,
+ STREAM_EVENT_NEW_RESOLVE = 6
} stream_status_event_t;
typedef enum or_conn_status_event_t {