diff options
author | Nick Mathewson <nickm@torproject.org> | 2005-09-14 02:36:29 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2005-09-14 02:36:29 +0000 |
commit | 7c6679d8dc260f6fb6f183c83b0d058b3ba0852c (patch) | |
tree | 5efc4885c13c0177f05fa750f280b89ad855bd99 /src/or/connection.c | |
parent | 93be26a74a843e0aa671f04f0f62b2b3590f6e11 (diff) | |
download | tor-7c6679d8dc260f6fb6f183c83b0d058b3ba0852c.tar.gz tor-7c6679d8dc260f6fb6f183c83b0d058b3ba0852c.zip |
Add new config.c function to set options that can fail, and roll back if they do. This should solve the setconf-an-impossible-port bug.
svn:r5046
Diffstat (limited to 'src/or/connection.c')
-rw-r--r-- | src/or/connection.c | 62 |
1 files changed, 45 insertions, 17 deletions
diff --git a/src/or/connection.c b/src/or/connection.c index 8474ad5c68..e4d913965b 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -13,8 +13,8 @@ const char connection_c_id[] = "$Id$"; #include "or.h" -static int connection_create_listener(const char *bindaddress, - uint16_t bindport, int type); +static connection_t *connection_create_listener(const char *bindaddress, + uint16_t bindport, int type); static int connection_init_accepted_conn(connection_t *conn); static int connection_handle_listener_read(connection_t *conn, int new_type); static int connection_receiver_bucket_should_increase(connection_t *conn); @@ -474,8 +474,9 @@ connection_expire_held_open(void) * If <b>bindaddress</b> includes a port, we bind on that port; otherwise, we * use bindport. */ -static int -connection_create_listener(const char *bindaddress, uint16_t bindport, int type) +static connection_t * +connection_create_listener(const char *bindaddress, uint16_t bindport, + int type) { struct sockaddr_in bindaddr; /* where to bind */ char *address = NULL; @@ -490,7 +491,7 @@ connection_create_listener(const char *bindaddress, uint16_t bindport, int type) memset(&bindaddr,0,sizeof(struct sockaddr_in)); if (parse_addr_port(bindaddress, &address, &addr, &usePort)<0) { log_fn(LOG_WARN, "Error parsing/resolving BindAddress %s",bindaddress); - return -1; + return NULL; } if (usePort==0) @@ -551,11 +552,11 @@ connection_create_listener(const char *bindaddress, uint16_t bindport, int type) conn->state = LISTENER_STATE_READY; connection_start_reading(conn); - return 0; + return conn; err: tor_free(address); - return -1; + return NULL; } /** Do basic sanity checking on a newly received socket. Return 0 @@ -804,10 +805,15 @@ connection_connect(connection_t *conn, char *address, * Otherwise, only relaunch the listeners of this type if the number of * existing connections is not as configured (e.g., because one died), * or if the existing connections do not match those configured. + * + * Add all old conns that should be closed to <b>replaced_conns</b>. + * Add all new connections to <b>new_conns</b>. */ static int retry_listeners(int type, config_line_t *cfg, - int port_option, const char *default_addr, int force) + int port_option, const char *default_addr, int force, + smartlist_t *replaced_conns, + smartlist_t *new_conns) { smartlist_t *launch = smartlist_create(); int free_launch_elts = 1; @@ -829,6 +835,11 @@ retry_listeners(int type, config_line_t *cfg, smartlist_add(launch, line); } + /* + SMARTLIST_FOREACH(launch, config_line_t *, l, + log_fn(LOG_NOTICE, "#%s#%s", l->key, l->value)); + */ + get_connection_array(&carray,&n_conn); for (i=0; i < n_conn; ++i) { conn = carray[i]; @@ -862,8 +873,12 @@ retry_listeners(int type, config_line_t *cfg, /* This one isn't configured. Close it. */ log_fn(LOG_NOTICE, "Closing %s on %s:%d", conn_type_to_string(type), conn->address, conn->port); - connection_close_immediate(conn); - connection_mark_for_close(conn); + if (replaced_conns) { + smartlist_add(replaced_conns, conn); + } else { + connection_close_immediate(conn); + connection_mark_for_close(conn); + } } else { /* It's configured; we don't need to launch it. */ log_fn(LOG_INFO, "Already have %s on %s:%d", @@ -876,9 +891,14 @@ retry_listeners(int type, config_line_t *cfg, i = 0; SMARTLIST_FOREACH(launch, config_line_t *, cfg, { - if (connection_create_listener(cfg->value, (uint16_t) port_option, - type)<0) + conn = connection_create_listener(cfg->value, (uint16_t) port_option, + type); + if (!conn) { i = -1; + } else { + if (new_conns) + smartlist_add(new_conns, conn); + } }); if (free_launch_elts) { @@ -894,24 +914,32 @@ retry_listeners(int type, config_line_t *cfg, * <b>force</b> is true, close and relaunch all listeners. If <b>force</b> * is false, then only relaunch listeners when we have the wrong number of * connections for a given type. + * + * Add all old conns that should be closed to <b>replaced_conns</b>. + * Add all new connections to <b>new_conns</b>. */ int -retry_all_listeners(int force) +retry_all_listeners(int force, smartlist_t *replaced_conns, + smartlist_t *new_conns) { or_options_t *options = get_options(); if (server_mode(options) && retry_listeners(CONN_TYPE_OR_LISTENER, options->ORBindAddress, - options->ORPort, "0.0.0.0", force)<0) + options->ORPort, "0.0.0.0", force, + replaced_conns, new_conns)<0) return -1; if (retry_listeners(CONN_TYPE_DIR_LISTENER, options->DirBindAddress, - options->DirPort, "0.0.0.0", force)<0) + options->DirPort, "0.0.0.0", force, + replaced_conns, new_conns)<0) return -1; if (retry_listeners(CONN_TYPE_AP_LISTENER, options->SocksBindAddress, - options->SocksPort, "127.0.0.1", force)<0) + options->SocksPort, "127.0.0.1", force, + replaced_conns, new_conns)<0) return -1; if (retry_listeners(CONN_TYPE_CONTROL_LISTENER, NULL, - options->ControlPort, "127.0.0.1", force)<0) + options->ControlPort, "127.0.0.1", force, + replaced_conns, new_conns)<0) return -1; return 0; |