diff options
author | Andrea Shepard <andrea@torproject.org> | 2015-01-07 22:51:24 +0000 |
---|---|---|
committer | Andrea Shepard <andrea@torproject.org> | 2015-01-07 22:51:24 +0000 |
commit | 2ca1c386b0d1c396fa8d8f4b5334349e24a2f9e8 (patch) | |
tree | 0046c3d18d8f7f57a9bddf638a515dbdf07a1439 /src/or/connection.c | |
parent | 48633c07660216d3b852b609c44fa318d55908f0 (diff) | |
download | tor-2ca1c386b0d1c396fa8d8f4b5334349e24a2f9e8.tar.gz tor-2ca1c386b0d1c396fa8d8f4b5334349e24a2f9e8.zip |
Bring sanity to connection_listener_new()
Diffstat (limited to 'src/or/connection.c')
-rw-r--r-- | src/or/connection.c | 200 |
1 files changed, 66 insertions, 134 deletions
diff --git a/src/or/connection.c b/src/or/connection.c index c17a414319..51d891d63a 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -965,7 +965,7 @@ check_location_for_unix_socket(const or_options_t *options, const char *path, { int r = -1; char *p = NULL; - + tor_assert(is_valid_unix_socket_purpose(purpose)); p = tor_strdup(path); @@ -1081,105 +1081,30 @@ connection_listener_new(const struct sockaddr *listensockaddr, } if (listensockaddr->sa_family == AF_INET || - listensockaddr->sa_family == AF_INET6 || - (listensockaddr->sa_family == AF_UNIX && - type != CONN_TYPE_CONTROL_LISTENER)) { + listensockaddr->sa_family == AF_INET6) { int is_stream = (type != CONN_TYPE_AP_DNS_LISTENER); if (is_stream) start_reading = 1; - if ( listensockaddr->sa_family == AF_INET || - listensockaddr->sa_family == AF_INET6) { - - tor_addr_from_sockaddr(&addr, listensockaddr, &usePort); - - log_notice(LD_NET, "Opening %s on %s", - conn_type_to_string(type), fmt_addrport(&addr, usePort)); - - s = tor_open_socket_nonblocking(tor_addr_family(&addr), - is_stream ? SOCK_STREAM : SOCK_DGRAM, - is_stream ? IPPROTO_TCP: IPPROTO_UDP); - if (!SOCKET_OK(s)) { - log_warn(LD_NET, "Socket creation failed: %s", - tor_socket_strerror(tor_socket_errno(-1))); - goto err; - } + tor_addr_from_sockaddr(&addr, listensockaddr, &usePort); - if (make_socket_reuseable(s) < 0) { - log_warn(LD_NET, "Error setting SO_REUSEADDR flag on %s: %s", - conn_type_to_string(type), - tor_socket_strerror(errno)); - } + log_notice(LD_NET, "Opening %s on %s", + conn_type_to_string(type), fmt_addrport(&addr, usePort)); + + s = tor_open_socket_nonblocking(tor_addr_family(&addr), + is_stream ? SOCK_STREAM : SOCK_DGRAM, + is_stream ? IPPROTO_TCP: IPPROTO_UDP); + if (!SOCKET_OK(s)) { + log_warn(LD_NET, "Socket creation failed: %s", + tor_socket_strerror(tor_socket_errno(-1))); + goto err; } -#ifdef HAVE_SYS_UN_H - if (listensockaddr->sa_family == AF_UNIX && - type != CONN_TYPE_CONTROL_LISTENER) { - tor_assert(listensockaddr->sa_family == AF_UNIX); - - if (check_location_for_unix_socket(options, address, - UNIX_SOCKET_PURPOSE_SOCKS_SOCKET) < 0) { - goto err; - } - - log_notice(LD_NET, "Opening SocksSocket %s on %s", - conn_type_to_string(type), address); - - tor_addr_make_unspec(&addr); - - if (unlink(address) < 0 && errno != ENOENT) { - log_warn(LD_NET, "Could not unlink %s: %s", address, - strerror(errno)); - goto err; - } - - s = tor_open_socket_nonblocking(AF_UNIX, SOCK_STREAM, 0); - if (! SOCKET_OK(s)) { - log_warn(LD_NET, "SocksSocket socket creation failed: %s.", - strerror(errno)); - goto err; - } - - if (bind(s, listensockaddr, - (socklen_t)sizeof(struct sockaddr_un)) == -1) { - log_warn(LD_NET, "Bind to %s failed: %s.", address, - tor_socket_strerror(tor_socket_errno(s))); - goto err; - } -#ifdef HAVE_PWD_H - if (options->User) { - pw = getpwnam(options->User); - if (pw == NULL) { - log_warn(LD_NET, - "Unable to chown() %s socket: user %s not found.", - address, options->User); - goto err; - } else if (chown(address, pw->pw_uid, pw->pw_gid) < 0) { - log_warn(LD_NET, "Unable to chown() %s socket: %s.", - address, strerror(errno)); - goto err; - } - } -#endif - - if (options->SocksSocketsGroupWritable) { - /* We need to use chmod; fchmod doesn't work on sockets on all - * platforms. */ - if (chmod(address, 0660) < 0) { - log_warn(LD_FS, "Unable to make %s group-writable.", address); - goto err; - } - } - - if (listen(s, SOMAXCONN) < 0) { - log_warn(LD_NET, "Could not listen on %s: %s", address, - tor_socket_strerror(tor_socket_errno(s))); - goto err; - } + if (make_socket_reuseable(s) < 0) { + log_warn(LD_NET, "Error setting SO_REUSEADDR flag on %s: %s", + conn_type_to_string(type), + tor_socket_strerror(errno)); } -#else - (void)options; -#endif /* HAVE_SYS_UN_H */ #if defined USE_TRANSPARENT && defined(IP_TRANSPARENT) if (options->TransProxyType_parsed == TPT_TPROXY && @@ -1217,54 +1142,57 @@ connection_listener_new(const struct sockaddr *listensockaddr, } #endif - if (listensockaddr->sa_family != AF_UNIX) { - if (bind(s,listensockaddr,socklen) < 0) { - const char *helpfulhint = ""; - int e = tor_socket_errno(s); - if (ERRNO_IS_EADDRINUSE(e)) - helpfulhint = ". Is Tor already running?"; - log_warn(LD_NET, "Could not bind to %s:%u: %s%s", address, usePort, - tor_socket_strerror(e), helpfulhint); - goto err; - } + if (bind(s,listensockaddr,socklen) < 0) { + const char *helpfulhint = ""; + int e = tor_socket_errno(s); + if (ERRNO_IS_EADDRINUSE(e)) + helpfulhint = ". Is Tor already running?"; + log_warn(LD_NET, "Could not bind to %s:%u: %s%s", address, usePort, + tor_socket_strerror(e), helpfulhint); + goto err; + } - if (is_stream) { - if (tor_listen(s) < 0) { - log_warn(LD_NET, "Could not listen on %s:%u: %s", address, usePort, - tor_socket_strerror(tor_socket_errno(s))); - goto err; - } + if (is_stream) { + if (tor_listen(s) < 0) { + log_warn(LD_NET, "Could not listen on %s:%u: %s", address, usePort, + tor_socket_strerror(tor_socket_errno(s))); + 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); + 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 && - type != CONN_TYPE_AP_LISTENER) { + /* + * AF_UNIX generic setup stuff (this covers both CONN_TYPE_CONTROL_LISTENER + * and CONN_TYPE_AP_LISTENER cases) + */ + } else if (listensockaddr->sa_family == AF_UNIX) { + /* We want to start reading for both AF_UNIX cases */ start_reading = 1; - /* For now only control ports can be Unix domain sockets + /* For now only control ports or SOCKS ports can be Unix domain sockets * and listeners at the same time */ - tor_assert(type == CONN_TYPE_CONTROL_LISTENER); + tor_assert(type == CONN_TYPE_CONTROL_LISTENER || + type == CONN_TYPE_AP_LISTENER); - if ( type == CONN_TYPE_CONTROL_LISTENER ) { - if (check_location_for_unix_socket(options, address, - UNIX_SOCKET_PURPOSE_CONTROL_SOCKET) < 0) { + if (check_location_for_unix_socket(options, address, + (type == CONN_TYPE_CONTROL_LISTENER) ? + UNIX_SOCKET_PURPOSE_CONTROL_SOCKET : + UNIX_SOCKET_PURPOSE_SOCKS_SOCKET) < 0) { goto err; - } } log_notice(LD_NET, "Opening %s on %s", @@ -1277,17 +1205,20 @@ connection_listener_new(const struct sockaddr *listensockaddr, strerror(errno)); goto err; } + s = tor_open_socket_nonblocking(AF_UNIX, SOCK_STREAM, 0); if (! SOCKET_OK(s)) { log_warn(LD_NET,"Socket creation failed: %s.", strerror(errno)); goto err; } - if (bind(s, listensockaddr, (socklen_t)sizeof(struct sockaddr_un)) == -1) { + if (bind(s, listensockaddr, + (socklen_t)sizeof(struct sockaddr_un)) == -1) { log_warn(LD_NET,"Bind to %s failed: %s.", address, tor_socket_strerror(tor_socket_errno(s))); goto err; } + #ifdef HAVE_PWD_H if (options->User) { pw = tor_getpwnam(options->User); @@ -1302,7 +1233,9 @@ connection_listener_new(const struct sockaddr *listensockaddr, } } #endif - if (options->ControlSocketsGroupWritable) { + + if (type == CONN_TYPE_CONTROL_LISTENER && + options->ControlSocketsGroupWritable) { /* We need to use chmod; fchmod doesn't work on sockets on all * platforms. */ if (chmod(address, 0660) < 0) { @@ -1311,7 +1244,8 @@ connection_listener_new(const struct sockaddr *listensockaddr, } } - if (options->SocksSocketsGroupWritable) { + if (type == CONN_TYPE_AP_LISTENER && + options->SocksSocketsGroupWritable) { /* We need to use chmod; fchmod doesn't work on sockets on all * platforms. */ if (chmod(address, 0660) < 0) { @@ -1325,8 +1259,6 @@ connection_listener_new(const struct sockaddr *listensockaddr, tor_socket_strerror(tor_socket_errno(s))); goto err; } -#else - (void)options; #endif /* HAVE_SYS_UN_H */ } else { log_err(LD_BUG, "Got unexpected address family %d.", |