[or-cvs] Implement all of control interface except authentication, s...
Nick Mathewson
nickm at seul.org
Wed Nov 3 18:33:10 UTC 2004
Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/tmp/cvs-serv12980/src/or
Modified Files:
circuitbuild.c circuitlist.c circuituse.c connection.c
connection_edge.c connection_or.c control.c dirserv.c main.c
or.h router.c routerlist.c test.c
Log Message:
- Implement all of control interface except authentication, setconfig,
and actually making the sockets.
- Make sure that identity-based nicknames start with $.
- Use new string_join interface.
Index: circuitbuild.c
===================================================================
RCS file: /home/or/cvsroot/src/or/circuitbuild.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -d -r1.47 -r1.48
--- circuitbuild.c 3 Nov 2004 10:08:44 -0000 1.47
+++ circuitbuild.c 3 Nov 2004 18:33:06 -0000 1.48
@@ -63,6 +63,40 @@
return test_circ_id;
}
+/** Allocate and return a comma-separated list of the currently built
+ * elements of circuit_t.
+ */
+char *circuit_list_path(circuit_t *circ)
+{
+ struct crypt_path_t *hop;
+ routerinfo_t *r;
+ smartlist_t *elements;
+ char *s;
+ tor_assert(CIRCUIT_IS_ORIGIN(circ));
+ tor_assert(circ->cpath);
+
+ elements = smartlist_create();
+
+ for (hop = circ->cpath; hop; hop = hop->next) {
+ if (hop->state != CPATH_STATE_OPEN)
+ break;
+ if ((r = router_get_by_digest(hop->identity_digest))) {
+ smartlist_add(elements, tor_strdup(r->nickname));
+ } else if (circ->purpose == CIRCUIT_PURPOSE_C_REND_JOINED) {
+ smartlist_add(elements, tor_strdup("<rendezvous splice>"));
+ } else {
+ s = tor_malloc(HEX_DIGEST_LEN+2);
+ s[0]='$';
+ base16_encode(s+1,HEX_DIGEST_LEN+1,hop->identity_digest,DIGEST_LEN);
+ smartlist_add(elements, s);
+ }
+ }
+
+ s = smartlist_join_strings(elements, ",", 0, NULL);
+ SMARTLIST_FOREACH(elements, char*, cp, tor_free(cp));
+ return s;
+}
+
/** Log, at severity <b>severity</b>, the nicknames of each router in
* circ's cpath. Also log the length of the cpath, and the intended
* exit point.
@@ -220,6 +254,8 @@
return NULL;
}
+ control_event_circuit_status(circ, CIRC_EVENT_LAUNCHED);
+
/* now see if we're already connected to the first OR in 'route' */
tor_assert(firsthop);
@@ -604,6 +640,8 @@
hop->state = CPATH_STATE_OPEN;
log_fn(LOG_INFO,"finished");
circuit_log_path(LOG_INFO,circ);
+ control_event_circuit_status(circ, CIRC_EVENT_EXTENDED);
+
return 0;
}
Index: circuitlist.c
===================================================================
RCS file: /home/or/cvsroot/src/or/circuitlist.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- circuitlist.c 27 Oct 2004 21:14:10 -0000 1.14
+++ circuitlist.c 3 Nov 2004 18:33:06 -0000 1.15
@@ -74,6 +74,7 @@
*/
circuit_t *circuit_new(uint16_t p_circ_id, connection_t *p_conn) {
circuit_t *circ;
+ static uint32_t n_circuits_allocated = 0;
circ = tor_malloc_zero(sizeof(circuit_t));
circ->magic = CIRCUIT_MAGIC;
@@ -93,6 +94,7 @@
circ->deliver_window = CIRCWINDOW_START;
circ->next_stream_id = crypto_pseudo_rand_int(1<<16);
+ circ->global_identifier = n_circuits_allocated++;
circuit_add(circ);
@@ -353,10 +355,15 @@
* links worked and which didn't.
*/
if (circ->state != CIRCUIT_STATE_OPEN) {
- if(CIRCUIT_IS_ORIGIN(circ))
+ if(CIRCUIT_IS_ORIGIN(circ)) {
circuit_build_failed(circ); /* take actions if necessary */
+ }
circuit_rep_hist_note_result(circ);
}
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ control_event_circuit_status(circ,
+ (circ->state == CIRCUIT_STATE_OPEN)?CIRC_EVENT_CLOSED:CIRC_EVENT_FAILED);
+ }
if (circ->purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) {
tor_assert(circ->state == CIRCUIT_STATE_OPEN);
/* treat this like getting a nack from it */
Index: circuituse.c
===================================================================
RCS file: /home/or/cvsroot/src/or/circuituse.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- circuituse.c 27 Oct 2004 06:48:16 -0000 1.19
+++ circuituse.c 3 Nov 2004 18:33:06 -0000 1.20
@@ -489,6 +489,8 @@
*/
void circuit_has_opened(circuit_t *circ) {
+ control_event_circuit_status(circ, CIRC_EVENT_BUILT);
+
switch(circ->purpose) {
case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
rend_client_rendcirc_has_opened(circ);
Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection.c,v
retrieving revision 1.278
retrieving revision 1.279
diff -u -d -r1.278 -r1.279
--- connection.c 3 Nov 2004 16:38:04 -0000 1.278
+++ connection.c 3 Nov 2004 18:33:06 -0000 1.279
@@ -198,12 +198,15 @@
case CONN_TYPE_OR:
/* Remember why we're closing this connection. */
if (conn->state != OR_CONN_STATE_OPEN) {
- if(connection_or_nonopen_was_started_here(conn))
+ if(connection_or_nonopen_was_started_here(conn)) {
rep_hist_note_connect_failed(conn->identity_digest, time(NULL));
+ control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED);
+ }
} else if (0) { // XXX reason == CLOSE_REASON_UNUSED_OR_CONN) {
rep_hist_note_disconnect(conn->identity_digest, time(NULL));
} 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);
}
break;
case CONN_TYPE_AP:
@@ -212,6 +215,8 @@
connection_ap_handshake_socks_reply(conn, NULL, 0, 0);
conn->socks_request->has_finished = 1;
conn->hold_open_until_flushed = 1;
+ } else {
+ control_event_stream_status(conn, STREAM_EVENT_CLOSED);
}
break;
case CONN_TYPE_EXIT:
Index: connection_edge.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_edge.c,v
retrieving revision 1.222
retrieving revision 1.223
diff -u -d -r1.222 -r1.223
--- connection_edge.c 31 Oct 2004 20:28:41 -0000 1.222
+++ connection_edge.c 3 Nov 2004 18:33:07 -0000 1.223
@@ -521,6 +521,7 @@
ap_conn->deliver_window = STREAMWINDOW_START;
ap_conn->state = AP_CONN_STATE_CONNECT_WAIT;
log_fn(LOG_INFO,"Address/port sent, ap socket %d, n_circ_id %d",ap_conn->s,circ->n_circ_id);
+ control_event_stream_status(ap_conn, STREAM_EVENT_SENT_CONNECT);
return 0;
}
@@ -561,6 +562,7 @@
ap_conn->state = AP_CONN_STATE_RESOLVE_WAIT;
log_fn(LOG_INFO,"Address sent for resolve, ap socket %d, n_circ_id %d",ap_conn->s,circ->n_circ_id);
+ control_event_stream_status(ap_conn, STREAM_EVENT_SENT_RESOLVE);
return 0;
}
@@ -689,6 +691,9 @@
size_t replylen, int success) {
char buf[256];
+ control_event_stream_status(conn,
+ success ? STREAM_EVENT_SUCCEEDED : STREAM_EVENT_FAILED);
+
if(replylen) { /* we already have a reply in mind */
connection_write_to_buf(reply, replylen, conn);
return;
Index: connection_or.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_or.c,v
retrieving revision 1.131
retrieving revision 1.132
diff -u -d -r1.131 -r1.132
--- connection_or.c 17 Oct 2004 21:51:20 -0000 1.131
+++ connection_or.c 3 Nov 2004 18:33:07 -0000 1.132
@@ -140,8 +140,9 @@
if (n) {
conn->nickname = tor_strdup(n);
} else {
- conn->nickname = tor_malloc(HEX_DIGEST_LEN+1);
- base16_encode(conn->nickname, HEX_DIGEST_LEN+1,
+ conn->nickname = tor_malloc(HEX_DIGEST_LEN+2);
+ conn->nickname[0] = '$';
+ base16_encode(conn->nickname+1, HEX_DIGEST_LEN+1,
conn->identity_digest, DIGEST_LEN);
}
tor_free(conn->address);
@@ -223,10 +224,12 @@
/* 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);
conn->state = OR_CONN_STATE_CONNECTING;
+ control_event_or_conn_status(conn, OR_CONN_EVENT_LAUNCHED);
switch(connection_connect(conn, conn->address, addr, port)) {
case -1:
router_mark_as_down(conn->identity_digest);
+ control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED);
connection_free(conn);
return NULL;
case 0:
@@ -376,6 +379,7 @@
log_fn(options.DirPort ? LOG_WARN : LOG_INFO,
"Other side (%s:%d) is '%s', but we tried to connect to '%s'",
conn->address, conn->port, nickname, conn->nickname);
+ control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED);
return -1;
}
} else {
@@ -393,6 +397,7 @@
circuit_n_conn_done(conn, 1); /* send the pending creates, if any. */
/* Note the success */
rep_hist_note_connect_succeeded(conn->identity_digest, time(NULL));
+ control_event_or_conn_status(conn, OR_CONN_EVENT_CONNECTED);
return 0;
}
Index: control.c
===================================================================
RCS file: /home/or/cvsroot/src/or/control.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- control.c 3 Nov 2004 10:08:44 -0000 1.2
+++ control.c 3 Nov 2004 18:33:07 -0000 1.3
@@ -43,6 +43,8 @@
"authenticate",
};
+extern or_options_t options;
+
static uint32_t global_event_mask = 0;
static void update_global_event_mask(void);
@@ -131,17 +133,57 @@
}
}
-static int
+static int
handle_control_setconf(connection_t *conn, uint16_t len,
const char *body)
{
/* XXXX009 NM */
return 0;
}
-static int handle_control_getconf(connection_t *conn, uint16_t len,
+
+static int handle_control_getconf(connection_t *conn, uint16_t body_len,
const char *body)
{
- /* XXXX009 NM */
+ smartlist_t *answer_elements = NULL;
+ char *msg = NULL;
+ size_t msg_len;
+
+ if (body[body_len-1] != '\0') {
+ send_control_error(conn, ERR_UNSPECIFIED,
+ "getconf message body not nul-terminated.");
+ return 0;
+ }
+ /* Now we can be sure that body will end in a nul-terminated string. */
+
+ answer_elements = smartlist_create();
+ while (body_len) {
+ size_t question_len = strlen(body);
+ struct config_line_t *answer = config_get_assigned_option(&options,body);
+ if (!answer) {
+ send_control_error(conn, ERR_UNRECOGNIZED_CONFIG_KEY, body);
+ goto done;
+ } else {
+ while (answer) {
+ struct config_line_t *next;
+ smartlist_add(answer_elements, answer->key);
+ smartlist_add(answer_elements, answer->value);
+ next = answer->next;
+ tor_free(answer);
+ answer = next;
+ }
+ }
+ body += question_len+1;
+ body_len -= question_len+1;
+ }
+
+ msg = smartlist_join_strings2(answer_elements, "\0", 1, 0, &msg_len);
+ send_control_message(conn, CONTROL_CMD_CONFVALUE, msg_len, msg);
+
+ done:
+ SMARTLIST_FOREACH(answer_elements, char *, cp, tor_free(cp));
+ smartlist_free(answer_elements);
+ tor_free(msg);
+
return 0;
}
static int handle_control_setevents(connection_t *conn, uint16_t len,
@@ -263,37 +305,63 @@
goto again; /* There might be more data. */
}
-int control_event_circuit_status(circuit_t *circ)
+int control_event_circuit_status(circuit_t *circ, circuit_status_event_t tp)
{
+ char *path, *msg;
+ size_t path_len;
if (!EVENT_IS_INTERESTING(EVENT_CIRCUIT_STATUS))
return 0;
+ tor_assert(circ);
+ tor_assert(CIRCUIT_IS_ORIGIN(circ));
- /* XXXXX009 NM */
+ path = circuit_list_path(circ);
+ 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->global_identifier));
+ strlcpy(msg+5,path,path_len+1);
+ send_control_event(EVENT_STREAM_STATUS, (uint16_t)(path_len+6), msg);
+ tor_free(path);
+ tor_free(msg);
return 0;
}
-int control_event_stream_status(connection_t *conn)
+int control_event_stream_status(connection_t *conn, stream_status_event_t tp)
{
+ char *msg;
+ size_t len;
tor_assert(conn->type == CONN_TYPE_AP);
+ tor_assert(conn->socks_request);
if (!EVENT_IS_INTERESTING(EVENT_STREAM_STATUS))
return 0;
- /* XXXXX009 NM */
+ len = strlen(conn->socks_request->address);
+ msg = tor_malloc(5+len+1);
+ msg[0] = (uint8_t) tp;
+ set_uint32(msg+1, htonl(conn->s)); /* ???? Is this a security problem? */
+ strlcpy(msg+5, conn->socks_request->address, len+1);
+ send_control_event(EVENT_STREAM_STATUS, (uint16_t)(5+len+1), msg);
+ tor_free(msg);
return 0;
}
-int control_event_or_conn_status(connection_t *conn)
+int control_event_or_conn_status(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;
- /* XXXXX009 NM */
-
+ buf[0] = (uint8_t)tp;
+ strlcpy(buf+1,conn->nickname,sizeof(buf)-1);
+ len = strlen(buf+1);
+ send_control_event(EVENT_OR_CONN_STATUS, (uint16_t)(len+1), buf);
return 0;
}
@@ -311,19 +379,18 @@
return 0;
}
-int control_event_warning(const char *msg)
+void control_event_logmsg(int severity, const char *msg)
{
size_t len;
+ if (severity > LOG_WARN) /* Less important than warning? ignore for now. */
+ return;
if (!EVENT_IS_INTERESTING(EVENT_WARNING))
- return 0;
+ return;
len = strlen(msg);
- send_control_event(EVENT_WARNING, len+1, msg);
-
- return 0;
+ send_control_event(EVENT_WARNING, (uint16_t)(len+1), msg);
}
-
/*
Local Variabls:
mode:c
Index: dirserv.c
===================================================================
RCS file: /home/or/cvsroot/src/or/dirserv.c,v
retrieving revision 1.109
retrieving revision 1.110
diff -u -d -r1.109 -r1.110
--- dirserv.c 2 Nov 2004 03:02:17 -0000 1.109
+++ dirserv.c 3 Nov 2004 18:33:07 -0000 1.110
@@ -523,9 +523,9 @@
});
if (running_routers_out)
- *running_routers_out = smartlist_join_strings(rr_entries, " ", 0);
+ *running_routers_out = smartlist_join_strings(rr_entries, " ", 0,NULL);
if (router_status_out)
- *router_status_out = smartlist_join_strings(rs_entries, " ", 0);
+ *router_status_out = smartlist_join_strings(rs_entries, " ", 0,NULL);
SMARTLIST_FOREACH(rr_entries, char *, cp, tor_free(cp));
SMARTLIST_FOREACH(rs_entries, char *, cp, tor_free(cp));
@@ -611,7 +611,7 @@
smartlist_split_string(versions, ln->value, ",",
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
}
- recommended_versions = smartlist_join_strings(versions,",",0);
+ recommended_versions = smartlist_join_strings(versions,",",0,NULL);
SMARTLIST_FOREACH(versions,char *,s,tor_free(s));
smartlist_free(versions);
}
Index: main.c
===================================================================
RCS file: /home/or/cvsroot/src/or/main.c,v
retrieving revision 1.350
retrieving revision 1.351
diff -u -d -r1.350 -r1.351
--- main.c 3 Nov 2004 16:38:04 -0000 1.350
+++ main.c 3 Nov 2004 18:33:07 -0000 1.351
@@ -971,6 +971,7 @@
/* Close the temporary log we used while starting up, if it isn't already
* gone. */
close_temp_logs();
+ add_callback_log(LOG_WARN, LOG_ERR, control_event_logmsg);
/* Start backgrounding the process, if requested. */
if (options.RunAsDaemon) {
Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.455
retrieving revision 1.456
diff -u -d -r1.455 -r1.456
--- or.h 3 Nov 2004 01:32:26 -0000 1.455
+++ or.h 3 Nov 2004 18:33:07 -0000 1.456
@@ -822,6 +822,10 @@
* is not marked for close. */
struct circuit_t *rend_splice;
+ /** Quasi-global identifier for this circuit; used for control.c */
+ /* XXXX009 NM This can get re-used after 2**32 circuits. */
+ uint32_t global_identifier;
+
struct circuit_t *next; /**< Next circuit in linked list. */
};
@@ -1000,6 +1004,7 @@
/********************************* circuitbuild.c **********************/
+char *circuit_list_path(circuit_t *circ);
void circuit_log_path(int severity, circuit_t *circ);
void circuit_rep_hist_note_result(circuit_t *circ);
void circuit_dump_by_conn(connection_t *conn, int severity);
@@ -1084,6 +1089,8 @@
struct exit_policy_t **dest);
void exit_policy_free(struct exit_policy_t *p);
const char *get_data_directory(or_options_t *options);
+struct config_line_t *config_get_assigned_option(or_options_t *options,
+ const char *key);
/********************************* connection.c ***************************/
@@ -1202,14 +1209,37 @@
/********************************* control.c ***************************/
+typedef enum circuit_status_event_t {
+ CIRC_EVENT_LAUNCHED = 0,
+ CIRC_EVENT_BUILT = 1,
+ CIRC_EVENT_EXTENDED = 2,
+ CIRC_EVENT_FAILED = 3,
+ CIRC_EVENT_CLOSED = 4,
+} circuit_status_event_t;
+
+typedef enum stream_status_event_t {
+ STREAM_EVENT_SENT_CONNECT = 0,
+ STREAM_EVENT_SENT_RESOLVE = 1,
+ STREAM_EVENT_SUCCEEDED = 2,
+ STREAM_EVENT_FAILED = 3,
+ STREAM_EVENT_CLOSED = 4
+} stream_status_event_t;
+
+typedef enum or_conn_status_event_t {
+ OR_CONN_EVENT_LAUNCHED = 0,
+ OR_CONN_EVENT_CONNECTED = 1,
+ OR_CONN_EVENT_FAILED = 2,
+ OR_CONN_EVENT_CLOSED = 3,
+} or_conn_status_event_t;
+
int connection_control_finished_flushing(connection_t *conn);
int connection_control_process_inbuf(connection_t *conn);
-int control_event_circuit_status(circuit_t *circ);
-int control_event_stream_status(connection_t *conn);
-int control_event_or_conn_status(connection_t *conn);
+int control_event_circuit_status(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_bandwidth_used(uint32_t n_read, uint32_t n_written);
-int control_event_warning(const char *msg);
+void control_event_logmsg(int severity, const char *msg);
/********************************* cpuworker.c *****************************/
@@ -1543,7 +1573,7 @@
int router_parse_list_from_string(const char **s,
routerlist_t **dest,
smartlist_t *good_nickname_list,
- int rr_format,
+ int rr_format,
time_t published);
int router_parse_routerlist_from_directory(const char *s,
routerlist_t **dest,
Index: router.c
===================================================================
RCS file: /home/or/cvsroot/src/or/router.c,v
retrieving revision 1.107
retrieving revision 1.108
diff -u -d -r1.107 -r1.108
--- router.c 2 Nov 2004 02:28:51 -0000 1.107
+++ router.c 3 Nov 2004 18:33:07 -0000 1.108
@@ -640,8 +640,9 @@
bandwidth_usage = rep_hist_get_bandwidth_lines();
if (router->declared_family && smartlist_len(router->declared_family)) {
- char *s = smartlist_join_strings(router->declared_family, " ", 0);
- size_t n = strlen(s) + strlen("opt family ") + 2; /* 1 for \n, 1 for \0. */
+ size_t n;
+ char *s = smartlist_join_strings(router->declared_family, " ", 0, &n);
+ n += strlen("opt family ") + 2; /* 1 for \n, 1 for \0. */
family_line = tor_malloc(n);
tor_snprintf(family_line, n, "opt family %s\n", s);
tor_free(s);
Index: routerlist.c
===================================================================
RCS file: /home/or/cvsroot/src/or/routerlist.c,v
retrieving revision 1.173
retrieving revision 1.174
diff -u -d -r1.173 -r1.174
--- routerlist.c 3 Nov 2004 10:08:44 -0000 1.173
+++ routerlist.c 3 Nov 2004 18:33:07 -0000 1.174
@@ -1167,7 +1167,7 @@
r->status_set_at = time(NULL);
}
});
-
+
return 0;
}
Index: test.c
===================================================================
RCS file: /home/or/cvsroot/src/or/test.c,v
retrieving revision 1.138
retrieving revision 1.139
diff -u -d -r1.138 -r1.139
--- test.c 2 Nov 2004 03:02:17 -0000 1.138
+++ test.c 3 Nov 2004 18:33:07 -0000 1.139
@@ -566,19 +566,19 @@
test_streq("a", smartlist_get(sl, 1));
test_streq("bc", smartlist_get(sl, 2));
test_streq("", smartlist_get(sl, 3));
- cp = smartlist_join_strings(sl, "", 0);
+ cp = smartlist_join_strings(sl, "", 0, NULL);
test_streq(cp, "abcabc");
tor_free(cp);
- cp = smartlist_join_strings(sl, "!", 0);
+ cp = smartlist_join_strings(sl, "!", 0, NULL);
test_streq(cp, "abc!a!bc!");
tor_free(cp);
- cp = smartlist_join_strings(sl, "XY", 0);
+ cp = smartlist_join_strings(sl, "XY", 0, NULL);
test_streq(cp, "abcXYaXYbcXY");
tor_free(cp);
- cp = smartlist_join_strings(sl, "XY", 1);
+ cp = smartlist_join_strings(sl, "XY", 1, NULL);
test_streq(cp, "abcXYaXYbcXYXY");
tor_free(cp);
- cp = smartlist_join_strings(sl, "", 1);
+ cp = smartlist_join_strings(sl, "", 1, NULL);
test_streq(cp, "abcabc");
tor_free(cp);
More information about the tor-commits
mailing list