From b897cb1ec31f2404ecfdddf9da8ad2e106b72278 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 7 Apr 2005 20:25:22 +0000 Subject: Change conn_(type|state)_to_string from const arrays to switch functions so we (I) will not make Tor crash the next time we (I) add a new state. svn:r4045 --- src/or/connection.c | 183 +++++++++++++++++++++++++++-------------------- src/or/connection_edge.c | 2 +- src/or/main.c | 16 ++--- src/or/or.h | 7 +- src/or/relay.c | 2 +- 5 files changed, 117 insertions(+), 93 deletions(-) (limited to 'src/or') diff --git a/src/or/connection.c b/src/or/connection.c index 2ef10c7afc..281eca9599 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -13,78 +13,6 @@ const char connection_c_id[] = "$Id$"; #include "or.h" -/********* START VARIABLES **********/ - -/** Array of strings to make conn-\>type human-readable. */ -const char *conn_type_to_string[] = { - "", /* 0 */ - "OP listener", /* 1 */ - "OP", /* 2 */ - "OR listener", /* 3 */ - "OR", /* 4 */ - "Exit", /* 5 */ - "App listener",/* 6 */ - "App", /* 7 */ - "Dir listener",/* 8 */ - "Dir", /* 9 */ - "DNS worker", /* 10 */ - "CPU worker", /* 11 */ - "Control listener", /* 12 */ - "Control", /* 13 */ -}; - -/** Array of string arrays to make {conn-\>type,conn-\>state} human-readable. */ -const char *conn_state_to_string[][_CONN_TYPE_MAX+1] = { - { NULL }, /* no type associated with 0 */ - { NULL }, /* op listener, obsolete */ - { NULL }, /* op, obsolete */ - { "ready" }, /* or listener, 0 */ - { "", /* OR, 0 */ - "connect()ing", /* 1 */ - "proxy flushing", /* 2 */ - "proxy reading", /* 3 */ - "handshaking", /* 4 */ - "open" }, /* 5 */ - { "", /* exit, 0 */ - "waiting for dest info", /* 1 */ - "connecting", /* 2 */ - "open", /* 3 */ - "resolve failed" }, /* 4 */ - { "ready" }, /* app listener, 0 */ - { "", /* 0 */ - "", /* 1 */ - "", /* 2 */ - "", /* 3 */ - "", /* 4 */ - "awaiting dest info", /* app, 5 */ - "waiting for rendezvous desc", /* 6 */ - "waiting for controller", /* 7 */ - "waiting for safe circuit", /* 8 */ - "waiting for connected", /* 9 */ - "waiting for resolve", /* 10 */ - "open" }, /* 11 */ - { "ready" }, /* dir listener, 0 */ - { "", /* dir, 0 */ - "connecting", /* 1 */ - "client sending", /* 2 */ - "client reading", /* 3 */ - "awaiting command", /* 4 */ - "writing" }, /* 5 */ - { "", /* dns worker, 0 */ - "idle", /* 1 */ - "busy" }, /* 2 */ - { "", /* cpu worker, 0 */ - "idle", /* 1 */ - "busy with onion", /* 2 */ - "busy with handshake" }, /* 3 */ - { "ready" }, /* control listener, 0 */ - { "", /* control, 0 */ - "ready", /* 1 */ - "waiting for authentication", }, /* 2 */ -}; - -/********* END VARIABLES ************/ - static int connection_create_listener(const char *bindaddress, uint16_t bindport, int type); static int connection_init_accepted_conn(connection_t *conn); @@ -99,6 +27,103 @@ static int connection_bucket_read_limit(connection_t *conn); /**************************************************************/ +const char * +conn_type_to_string(int type) +{ + static char buf[64]; + switch (type) { + case CONN_TYPE_OR_LISTENER: return "OR listener"; + case CONN_TYPE_OR: return "OR"; + case CONN_TYPE_EXIT: return "Exit"; + case CONN_TYPE_AP_LISTENER: return "App listener"; + case CONN_TYPE_AP: return "App"; + case CONN_TYPE_DIR_LISTENER: return "Dir listener"; + case CONN_TYPE_DIR: return "Dir"; + case CONN_TYPE_DNSWORKER: return "DNS worker"; + case CONN_TYPE_CPUWORKER: return "CPU worker"; + case CONN_TYPE_CONTROL_LISTENER: return "Control listener"; + case CONN_TYPE_CONTROL: return "Control"; + default: + tor_snprintf(buf, sizeof(buf), "unknown [%d]", type); + return buf; + } +} + +const char * +conn_state_to_string(int type, int state) { + static char buf[96]; + switch (type) { + case CONN_TYPE_OR_LISTENER: + case CONN_TYPE_AP_LISTENER: + case CONN_TYPE_DIR_LISTENER: + case CONN_TYPE_CONTROL_LISTENER: + if (state == LISTENER_STATE_READY) + return "ready"; + break; + case CONN_TYPE_OR: + switch (state) { + case OR_CONN_STATE_CONNECTING: return "connect()ing"; + case OR_CONN_STATE_PROXY_FLUSHING: return "proxy flushing"; + case OR_CONN_STATE_PROXY_READING: return "proxy reading"; + case OR_CONN_STATE_HANDSHAKING: return "proxy reading"; + case OR_CONN_STATE_OPEN: return "open"; + } + break; + case CONN_TYPE_EXIT: + switch (state) { + case EXIT_CONN_STATE_RESOLVING: return "waiting for dest info"; + case EXIT_CONN_STATE_CONNECTING: return "connecting"; + case EXIT_CONN_STATE_OPEN: return "open"; + case EXIT_CONN_STATE_RESOLVEFAILED: return "resolve failed"; + } + break; + case CONN_TYPE_AP: + switch (state) { + case AP_CONN_STATE_SOCKS_WAIT: return "waiting for dest info"; + case AP_CONN_STATE_RENDDESC_WAIT: return "waiting for rendezvous desc"; + case AP_CONN_STATE_CONTROLLER_WAIT: return "waiting for controller"; + case AP_CONN_STATE_CIRCUIT_WAIT: return "waiting for safe circuit"; + case AP_CONN_STATE_CONNECT_WAIT: return "waiting for connect"; + case AP_CONN_STATE_RESOLVE_WAIT: return "waiting for resolve"; + case AP_CONN_STATE_OPEN: return "open"; + } + break; + case CONN_TYPE_DIR: + switch (state) { + case DIR_CONN_STATE_CONNECTING: return "connecting"; + case DIR_CONN_STATE_CLIENT_SENDING: return "client sending"; + case DIR_CONN_STATE_CLIENT_READING: return "cleint reading"; + case DIR_CONN_STATE_SERVER_COMMAND_WAIT: return "waiting for command"; + case DIR_CONN_STATE_SERVER_WRITING: return "writing"; + } + break; + case CONN_TYPE_DNSWORKER: + switch (state) { + case DNSWORKER_STATE_IDLE: return "idle"; + case DNSWORKER_STATE_BUSY: return "busy"; + } + break; + case CONN_TYPE_CPUWORKER: + switch (state) { + case CPUWORKER_STATE_IDLE: return "idle"; + case CPUWORKER_STATE_BUSY_ONION: return "busy with onion"; + } + break; + case CONN_TYPE_CONTROL: + switch (state) { + case CONTROL_CONN_STATE_OPEN: return "open"; + case CONTROL_CONN_STATE_NEEDAUTH: return "waiting for authentication"; + } + break; + } + + tor_snprintf(buf, sizeof(buf), + "unknown state [%d] on unknown [%s] connection", + state, conn_type_to_string(type)); + return buf; +} + + /** Allocate space for a new connection_t. This function just initializes * conn; you must call connection_add() to link it into the main array. * @@ -325,8 +350,9 @@ void connection_close_immediate(connection_t *conn) } if (conn->outbuf_flushlen) { log_fn(LOG_INFO,"fd %d, type %s, state %d, %d bytes on outbuf.", - conn->s, CONN_TYPE_TO_STRING(conn->type), - conn->state, (int)conn->outbuf_flushlen); + conn->s, conn_type_to_string(conn->type), + conn_state_to_string(conn->type, conn->state), + (int)conn->outbuf_flushlen); } connection_unregister(conn); @@ -390,8 +416,9 @@ void connection_expire_held_open(void) if (conn->hold_open_until_flushed) { tor_assert(conn->marked_for_close); if (now - conn->timestamp_lastwritten >= 15) { - log_fn(LOG_NOTICE,"Giving up on marked_for_close conn that's been flushing for 15s (fd %d, type %s, state %d).", - conn->s, CONN_TYPE_TO_STRING(conn->type), conn->state); + log_fn(LOG_NOTICE,"Giving up on marked_for_close conn that's been flushing for 15s (fd %d, type %s, state %s).", + conn->s, conn_type_to_string(conn->type), + conn_state_to_string(conn->type, conn->state)); conn->hold_open_until_flushed = 0; } } @@ -468,7 +495,7 @@ static int connection_create_listener(const char *bindaddress, uint16_t bindport return -1; } - log_fn(LOG_DEBUG,"%s listening on port %u.",conn_type_to_string[type], usePort); + log_fn(LOG_DEBUG,"%s listening on port %u.",conn_type_to_string(type), usePort); conn->state = LISTENER_STATE_READY; connection_start_reading(conn); @@ -772,7 +799,7 @@ static int retry_listeners(int type, struct config_line_t *cfg, /* Otherwise, warn the user and relaunch. */ log_fn(LOG_NOTICE,"We have %d %s(s) open, but we want %d; relaunching.", - have, conn_type_to_string[type], want); + have, conn_type_to_string(type), want); } listener_close_if_present(type); diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 9b920a175d..01c9d44e7a 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -125,7 +125,7 @@ int connection_edge_process_inbuf(connection_t *conn, int package_partial) { case AP_CONN_STATE_RESOLVE_WAIT: case AP_CONN_STATE_CONTROLLER_WAIT: log_fn(LOG_INFO,"data from edge while in '%s' state. Leaving it on buffer.", - conn_state_to_string[conn->type][conn->state]); + conn_state_to_string(conn->type, conn->state)); return 0; } log_fn(LOG_WARN,"Bug: Got unexpected state %d. Closing.",conn->state); diff --git a/src/or/main.c b/src/or/main.c index 7256c2040d..39505f466f 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -142,7 +142,7 @@ int connection_add(connection_t *conn) { nfds++; log_fn(LOG_INFO,"new conn type %s, socket %d, nfds %d.", - CONN_TYPE_TO_STRING(conn->type), conn->s, nfds); + conn_type_to_string(conn->type), conn->s, nfds); return 0; } @@ -158,7 +158,7 @@ int connection_remove(connection_t *conn) { tor_assert(nfds>0); log_fn(LOG_INFO,"removing socket %d (type %s), nfds now %d", - conn->s, CONN_TYPE_TO_STRING(conn->type), nfds-1); + conn->s, conn_type_to_string(conn->type), nfds-1); tor_assert(conn->poll_index >= 0); current_index = conn->poll_index; @@ -358,7 +358,7 @@ conn_read_callback(int fd, short event, void *_conn) if (!conn->marked_for_close) { #ifndef MS_WINDOWS log_fn(LOG_WARN,"Bug: unhandled error on read for %s connection (fd %d); removing", - CONN_TYPE_TO_STRING(conn->type), conn->s); + conn_type_to_string(conn->type), conn->s); #ifdef TOR_FRAGILE tor_assert(0); #endif @@ -390,7 +390,7 @@ static void conn_write_callback(int fd, short events, void *_conn) if (!conn->marked_for_close) { /* this connection is broken. remove it. */ log_fn(LOG_WARN,"Bug: unhandled error on write for %s connection (fd %d); removing", - CONN_TYPE_TO_STRING(conn->type), conn->s); + conn_type_to_string(conn->type), conn->s); #ifdef TOR_FRAGILE tor_assert(0); #endif @@ -431,7 +431,7 @@ static int conn_close_if_marked(int i) { log_fn(LOG_INFO, "Conn (addr %s, fd %d, type %s, state %d) marked, but wants to flush %d bytes. " "(Marked at %s:%d)", - conn->address, conn->s, CONN_TYPE_TO_STRING(conn->type), conn->state, + conn->address, conn->s, conn_type_to_string(conn->type), conn->state, (int)conn->outbuf_flushlen, conn->marked_for_close_file, conn->marked_for_close); if (connection_speaks_cells(conn)) { if (conn->state == OR_CONN_STATE_OPEN) { @@ -449,7 +449,7 @@ static int conn_close_if_marked(int i) { } if (connection_wants_to_flush(conn)) { log_fn(LOG_NOTICE,"Conn (addr %s, fd %d, type %s, state %d) is being closed, but there are still %d bytes we can't write. (Marked at %s:%d)", - conn->address, conn->s, CONN_TYPE_TO_STRING(conn->type), conn->state, + conn->address, conn->s, conn_type_to_string(conn->type), conn->state, (int)buf_datalen(conn->outbuf), conn->marked_for_close_file, conn->marked_for_close); } @@ -1054,8 +1054,8 @@ dumpstats(int severity) { for (i=0;is, conn->type, CONN_TYPE_TO_STRING(conn->type), - conn->state, conn_state_to_string[conn->type][conn->state], (int)(now - conn->timestamp_created)); + i, conn->s, conn->type, conn_type_to_string(conn->type), + conn->state, conn_state_to_string(conn->type, conn->state), (int)(now - conn->timestamp_created)); if (!connection_is_listener(conn)) { log(severity,"Conn %d is to '%s:%d'.",i,conn->address, conn->port); log(severity,"Conn %d: %d bytes waiting on inbuf (last read %d secs ago)",i, diff --git a/src/or/or.h b/src/or/or.h index 09b1fbc5a1..ac3ceb81c7 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1252,11 +1252,8 @@ int save_current_config(void); /********************************* connection.c ***************************/ -#define CONN_TYPE_TO_STRING(t) (((t) < _CONN_TYPE_MIN || (t) > _CONN_TYPE_MAX) ? \ - "Unknown" : conn_type_to_string[(t)]) - -extern const char *conn_type_to_string[]; -extern const char *conn_state_to_string[][_CONN_TYPE_MAX+1]; +const char *conn_type_to_string(int type); +const char *conn_state_to_string(int type, int state); connection_t *connection_new(int type); void connection_unregister(connection_t *conn); diff --git a/src/or/relay.c b/src/or/relay.c index c5554c2634..9ffb1eaa84 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -748,7 +748,7 @@ connection_edge_process_relay_cell_not_open( } log_fn(LOG_WARN,"Got an unexpected relay command %d, in state %d (%s). Closing.", - rh->command, conn->state, conn_state_to_string[conn->type][conn->state]); + rh->command, conn->state, conn_state_to_string(conn->type, conn->state)); connection_edge_end(conn, END_STREAM_REASON_TORPROTOCOL, conn->cpath_layer); connection_mark_for_close(conn); return -1; -- cgit v1.2.3-54-g00ecf