diff --git a/src/or/circuit.c b/src/or/circuit.c index 1da22e960d..ceb841eb82 100644 --- a/src/or/circuit.c +++ b/src/or/circuit.c @@ -8,6 +8,12 @@ static circuit_t *global_circuitlist=NULL; +char *circuit_state_to_string[] = { + "receiving the onion", /* 0 */ + "connecting to firsthop", /* 1 */ + "open" /* 2 */ +}; + /********* END VARIABLES ************/ void circuit_add(circuit_t *circ) { @@ -399,3 +405,18 @@ void circuit_about_to_close_connection(connection_t *conn) { } } +void circuit_dump_by_conn(connection_t *conn) { + circuit_t *circ; + + for(circ=global_circuitlist;circ;circ = circ->next) { + if(circ->p_conn == conn) { + printf("Conn %d has App-ward circuit: aci %d (other side %d), state %d (%s)\n", + conn->poll_index, circ->p_aci, circ->n_aci, circ->state, circuit_state_to_string[circ->state]); + } + if(circ->n_conn == conn) { + printf("Conn %d has Exit-ward circuit: aci %d (other side %d), state %d (%s)\n", + conn->poll_index, circ->n_aci, circ->p_aci, circ->state, circuit_state_to_string[circ->state]); + } + } +} + diff --git a/src/or/connection.c b/src/or/connection.c index 39fa2965c0..d4c2dc7008 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -8,38 +8,43 @@ extern or_options_t options; /* command-line and config-file options */ -#if 0 -/* these are now out of date :( -RD */ char *conn_type_to_string[] = { - "OP listener", /* 0 */ - "OP", /* 1 */ - "OR listener", /* 2 */ - "OR", /* 3 */ - "App" /* 4 */ + "", /* 0 */ + "OP listener", /* 1 */ + "OP", /* 2 */ + "OR listener", /* 3 */ + "OR", /* 4 */ + "Exit", /* 5 */ + "App listener",/* 6 */ + "App" /* 7 */ }; char *conn_state_to_string[][10] = { + { }, /* no type associated with 0 */ { "ready" }, /* op listener, 0 */ { "awaiting keys", /* op, 0 */ "open", /* 1 */ "close", /* 2 */ "close_wait" }, /* 3 */ { "ready" }, /* or listener, 0 */ - { "connecting (as client)", /* or, 0 */ - "sending auth (as client)", /* 1 */ - "waiting for auth (as client)", /* 2 */ - "sending nonce (as client)", /* 3 */ - "waiting for auth (as server)", /* 4 */ - "sending auth (as server)", /* 5 */ - "waiting for nonce (as server)",/* 6 */ - "open" }, /* 7 */ - { "connecting", /* exit, 0 */ - "open", /* 1 */ - "waiting for dest info", /* 2 */ - "flushing buffer, then will close",/* 3 */ - "close_wait" } /* 4 */ + { "connecting (as OP)", /* or, 0 */ + "sending keys (as OP)", /* 1 */ + "connecting (as client)", /* 2 */ + "sending auth (as client)", /* 3 */ + "waiting for auth (as client)", /* 4 */ + "sending nonce (as client)", /* 5 */ + "waiting for auth (as server)", /* 6 */ + "sending auth (as server)", /* 7 */ + "waiting for nonce (as server)",/* 8 */ + "open" }, /* 9 */ + { "waiting for dest info", /* exit, 0 */ + "connecting", /* 1 */ + "open" }, /* 2 */ + { "ready" }, /* app listener, 0 */ + { "awaiting dest info", /* app, 0 */ + "waiting for OR connection", /* 1 */ + "open" } /* 2 */ }; -#endif /********* END VARIABLES ************/ @@ -402,6 +407,14 @@ int connection_speaks_cells(connection_t *conn) { return 0; } +int connection_is_listener(connection_t *conn) { + if(conn->type == CONN_TYPE_OP_LISTENER || + conn->type == CONN_TYPE_OR_LISTENER || + conn->type == CONN_TYPE_AP_LISTENER) + return 1; + return 0; +} + int connection_state_is_open(connection_t *conn) { assert(conn); diff --git a/src/or/main.c b/src/or/main.c index adf36008be..38afee58e7 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -18,6 +18,8 @@ static struct pollfd poll_array[MAXCONNECTIONS]; static int nfds=0; /* number of connections currently active */ +static int please_dumpstats=0; /* whether we should dump stats during the loop */ + /* private key */ static crypto_pk_env_t *prkey; @@ -439,6 +441,9 @@ int do_main_loop(void) { options.ORPort, options.OPPort, options.APPort); for(;;) { + if(please_dumpstats) { + dumpstats(); + } if(prepare_for_poll(&timeout) < 0) { log(LOG_DEBUG,"do_main_loop(): prepare_for_poll failed, exiting."); return -1; @@ -483,18 +488,46 @@ int do_main_loop(void) { } } -void catch () { +void catchint () { errno = 0; /* netcat does this. it looks fun. */ - log(LOG_DEBUG,"Catching ^c, exiting cleanly."); + log(LOG_NOTICE,"Catching ^c, exiting cleanly."); exit(0); } +void catchusr1 () { + please_dumpstats = 1; +} + +void dumpstats (void) { /* dump stats to stdout */ + int i; + connection_t *conn; + extern char *conn_type_to_string[]; + extern char *conn_state_to_string[][10]; + + printf("Dumping stats:\n"); + + for(i=0;is, conn->type, conn_type_to_string[conn->type], + conn->state, conn_state_to_string[conn->type][conn->state]); + if(!connection_is_listener(conn)) { + printf("Conn %d is to '%s:%d'.\n",i,conn->address, conn->port); + } + circuit_dump_by_conn(conn); /* dump info about all the circuits using this conn */ + printf("\n"); + } + + please_dumpstats = 0; +} + int main(int argc, char *argv[]) { int retval = 0; - signal (SIGINT, catch); /* to catch ^c so we can exit cleanly */ + signal (SIGINT, catchint); /* to catch ^c so we can exit cleanly */ + signal (SIGUSR1, catchusr1); /* to dump stats to stdout */ if ( getoptions(argc,argv,&options) ) exit(1); log(options.loglevel,NULL); /* assign logging severity level from options */ diff --git a/src/or/or.h b/src/or/or.h index 2c2b63166e..316a6b8e22 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -386,6 +386,8 @@ void circuit_close(circuit_t *circ); void circuit_about_to_close_connection(connection_t *conn); /* flush and send destroys for all circuits using conn */ +void circuit_dump_by_conn(connection_t *conn); + /********************************* command.c ***************************/ void command_process_cell(cell_t *cell, connection_t *conn); @@ -439,6 +441,7 @@ void connection_increment_send_timeval(connection_t *conn); void connection_init_timeval(connection_t *conn); int connection_speaks_cells(connection_t *conn); +int connection_is_listener(connection_t *conn); int connection_state_is_open(connection_t *conn); int connection_send_destroy(aci_t aci, connection_t *conn); @@ -555,6 +558,10 @@ int prepare_for_poll(int *timeout); int do_main_loop(void); +void catchint(); +void catchusr1(); +void dumpstats(void); + int main(int argc, char *argv[]); /********************************* onion.c ***************************/