summaryrefslogtreecommitdiff
path: root/src/or/connection.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2011-05-02 15:05:10 -0400
committerNick Mathewson <nickm@torproject.org>2011-05-13 10:41:18 -0400
commit5fec8fe559b1a1f4bcb55c8f2c1f048f5abee3de (patch)
tree05687be34c2f683bf80127a14ae0caeed48a61e0 /src/or/connection.c
parente0d5a6e1849673589c5b7f04d89e25194167344d (diff)
downloadtor-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.c45
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: