Browse Source

Merge remote-tracking branch 'origin/maint-0.2.2'

Nick Mathewson 12 years ago
parent
commit
f75660958c
2 changed files with 18 additions and 17 deletions
  1. 8 0
      changes/bug1240
  2. 10 17
      src/or/connection.c

+ 8 - 0
changes/bug1240

@@ -0,0 +1,8 @@
+  o Minor bugfixes:
+    - When running with an older Linux kernel that erroneously responds
+      to strange nmap behavior by having accept() return successfully
+      with a zero-length socket, just close the connection. Previously,
+      we would try harder to learn the remote address: but there was no
+      such remote address to learn, and our method for trying to learn
+      it was incorrect. Fixes bugs #1240, #4745, and #4747. Bugfix on
+      0.1.0.3-rc. Reported and diagnosed by "r1eo".

+ 10 - 17
src/or/connection.c

@@ -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) {