|
@@ -1051,7 +1051,12 @@ connection_create_listener(const struct sockaddr *listensockaddr,
|
|
|
}
|
|
|
|
|
|
/** Do basic sanity checking on a newly received socket. Return 0
|
|
|
- * if it looks ok, else return -1. */
|
|
|
+ * if it looks ok, else return -1.
|
|
|
+ *
|
|
|
+ * Notably, some TCP stacks can erroneously have accept() return successfully
|
|
|
+ * with socklen 0, when the client sends an RST before the accept call (as
|
|
|
+ * nmap does). We want to detect that, and not go on with the connection.
|
|
|
+ */
|
|
|
static int
|
|
|
check_sockaddr(struct sockaddr *sa, int len, int level)
|
|
|
{
|
|
@@ -1117,7 +1122,7 @@ connection_handle_listener_read(connection_t *conn, int new_type)
|
|
|
tor_socket_t news; /* the new socket */
|
|
|
connection_t *newconn;
|
|
|
/* information about the remote peer when connecting to other routers */
|
|
|
- char addrbuf[256];
|
|
|
+ char addrbuf[256]; /*XXX023 use sockaddr_storage instead*/
|
|
|
struct sockaddr *remote = (struct sockaddr*)addrbuf;
|
|
|
/* length of the remote address. Must be whatever accept() needs. */
|
|
|
socklen_t remotelen = (socklen_t)sizeof(addrbuf);
|
|
@@ -1161,21 +1166,9 @@ connection_handle_listener_read(connection_t *conn, int new_type)
|
|
|
uint16_t port;
|
|
|
if (check_sockaddr(remote, remotelen, LOG_INFO)<0) {
|
|
|
log_info(LD_NET,
|
|
|
- "accept() returned a strange address; trying getsockname().");
|
|
|
- remotelen=sizeof(addrbuf);
|
|
|
- memset(addrbuf, 0, sizeof(addrbuf));
|
|
|
- if (getsockname(news, remote, &remotelen)<0) {
|
|
|
- int e = tor_socket_errno(news);
|
|
|
- log_warn(LD_NET, "getsockname() for new connection failed: %s",
|
|
|
- tor_socket_strerror(e));
|
|
|
- } else {
|
|
|
- if (check_sockaddr((struct sockaddr*)addrbuf, remotelen,
|
|
|
- LOG_WARN) < 0) {
|
|
|
- log_warn(LD_NET,"Something's wrong with this conn. Closing it.");
|
|
|
- tor_close_socket(news);
|
|
|
- return 0;
|
|
|
- }
|
|
|
- }
|
|
|
+ "accept() returned a strange address; closing connection.");
|
|
|
+ tor_close_socket(news);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
if (check_sockaddr_family_match(remote->sa_family, conn) < 0) {
|