diff options
author | Nick Mathewson <nickm@torproject.org> | 2011-05-02 15:05:10 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2011-05-13 10:41:18 -0400 |
commit | 5fec8fe559b1a1f4bcb55c8f2c1f048f5abee3de (patch) | |
tree | 05687be34c2f683bf80127a14ae0caeed48a61e0 /src/or/connection.c | |
parent | e0d5a6e1849673589c5b7f04d89e25194167344d (diff) | |
download | tor-5fec8fe559b1a1f4bcb55c8f2c1f048f5abee3de.tar.gz tor-5fec8fe559b1a1f4bcb55c8f2c1f048f5abee3de.zip |
"(Socks|Control|etc)Port auto" now tells Tor to open an arbitrary port
This is the major part of the implementation for trac issue 3076.
Diffstat (limited to 'src/or/connection.c')
-rw-r--r-- | src/or/connection.c | 45 |
1 files changed, 32 insertions, 13 deletions
diff --git a/src/or/connection.c b/src/or/connection.c index eaae791efc..47e5423e0b 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -37,7 +37,7 @@ #include "routerparse.h" static connection_t *connection_create_listener( - struct sockaddr *listensockaddr, + const struct sockaddr *listensockaddr, socklen_t listensocklen, int type, char* address); static void connection_init(time_t now, connection_t *conn, int type, @@ -759,7 +759,7 @@ connection_expire_held_open(void) * The listenaddr struct has to be freed by the caller. */ static struct sockaddr_in * -create_inet_sockaddr(const char *listenaddress, uint16_t listenport, +create_inet_sockaddr(const char *listenaddress, int listenport, char **readable_address, socklen_t *socklen_out) { struct sockaddr_in *listenaddr = NULL; uint32_t addr; @@ -771,8 +771,10 @@ create_inet_sockaddr(const char *listenaddress, uint16_t listenport, "Error parsing/resolving ListenAddress %s", listenaddress); goto err; } - if (usePort==0) - usePort = listenport; + if (usePort==0) { + if (listenport != CFG_AUTO_PORT) + usePort = listenport; + } listenaddr = tor_malloc_zero(sizeof(struct sockaddr_in)); listenaddr->sin_addr.s_addr = htonl(addr); @@ -858,12 +860,13 @@ warn_too_many_conns(void) * to the conn. */ static connection_t * -connection_create_listener(struct sockaddr *listensockaddr, socklen_t socklen, +connection_create_listener(const struct sockaddr *listensockaddr, + socklen_t socklen, int type, char* address) { connection_t *conn; int s; /* the socket we're going to make */ - uint16_t usePort = 0; + uint16_t usePort = 0, gotPort = 0; int start_reading = 0; if (get_n_open_sockets() >= get_options()->_ConnLimit-1) { @@ -872,6 +875,7 @@ connection_create_listener(struct sockaddr *listensockaddr, socklen_t socklen, } if (listensockaddr->sa_family == AF_INET) { + tor_addr_t addr; int is_tcp = (type != CONN_TYPE_AP_DNS_LISTENER); #ifndef MS_WINDOWS int one=1; @@ -879,11 +883,10 @@ connection_create_listener(struct sockaddr *listensockaddr, socklen_t socklen, if (is_tcp) start_reading = 1; - usePort = ntohs( (uint16_t) - ((struct sockaddr_in *)listensockaddr)->sin_port); + tor_addr_from_sockaddr(&addr, listensockaddr, &usePort); log_notice(LD_NET, "Opening %s on %s:%d", - conn_type_to_string(type), address, usePort); + conn_type_to_string(type), fmt_addr(&addr), usePort); s = tor_open_socket(PF_INET, is_tcp ? SOCK_STREAM : SOCK_DGRAM, @@ -921,6 +924,21 @@ connection_create_listener(struct sockaddr *listensockaddr, socklen_t socklen, goto err; } } + + if (usePort != 0) { + gotPort = usePort; + } else { + tor_addr_t addr2; + struct sockaddr_storage ss; + socklen_t ss_len=sizeof(ss); + if (getsockname(s, (struct sockaddr*)&ss, &ss_len)<0) { + log_warn(LD_NET, "getsockname() couldn't learn address for %s: %s", + conn_type_to_string(type), + tor_socket_strerror(tor_socket_errno(s))); + gotPort = 0; + } + tor_addr_from_sockaddr(&addr2, (struct sockaddr*)&ss, &gotPort); + } #ifdef HAVE_SYS_UN_H } else if (listensockaddr->sa_family == AF_UNIX) { start_reading = 1; @@ -968,7 +986,7 @@ connection_create_listener(struct sockaddr *listensockaddr, socklen_t socklen, conn->socket_family = listensockaddr->sa_family; conn->s = s; conn->address = tor_strdup(address); - conn->port = usePort; + conn->port = gotPort; if (connection_add(conn) < 0) { /* no space, forget it */ log_warn(LD_NET,"connection_add for listener failed. Giving up."); @@ -976,8 +994,9 @@ connection_create_listener(struct sockaddr *listensockaddr, socklen_t socklen, goto err; } - log_debug(LD_NET,"%s listening on port %u.", - conn_type_to_string(type), usePort); + log_fn(usePort==gotPort ? LOG_DEBUG : LOG_NOTICE, LD_NET, + "%s listening on port %u.", + conn_type_to_string(type), gotPort); conn->state = LISTENER_STATE_READY; if (start_reading) { @@ -1804,7 +1823,7 @@ retry_listeners(int type, config_line_t *cfg, case AF_INET: listensockaddr = (struct sockaddr *) create_inet_sockaddr(cfg_line->value, - (uint16_t) port_option, + port_option, &address, &listensocklen); break; case AF_UNIX: |