[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] Forward-port the checking of



Update of /home2/or/cvsroot/tor/src/or
In directory moria.mit.edu:/home2/arma/work/onion/cvs/tor/src/or

Modified Files:
	connection.c 
Log Message:
Forward-port the checking of
sin_addr.s_addr == 0 || sin->sin_port == 0.
This just happened on moria2, so I guess it happens rarely
on Linux as well as OS X.
We can't afford to accept OR conns from 0.0.0.0:0, since we
send created cells back to the first addr:port that matches,
and we'd better not send them to the wrong place.
So, let's drop them all for now, and see if we can find a pattern
later.


Index: connection.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/connection.c,v
retrieving revision 1.356
retrieving revision 1.357
diff -u -d -r1.356 -r1.357
--- connection.c	6 Apr 2005 15:19:32 -0000	1.356
+++ connection.c	6 Apr 2005 15:42:35 -0000	1.357
@@ -476,6 +476,31 @@
   return 0;
 }
 
+/** Do basic sanity checking on a newly received socket. Return 0
+ * if it looks ok, else return -1. */
+static int
+check_sockaddr_in(struct sockaddr *sa, int len, int level)
+{
+  int ok = 1;
+  struct sockaddr_in *sin=(struct sockaddr_in*)sa;
+
+  if (len != sizeof(struct sockaddr_in)) {
+    log_fn(level, "Length of address not as expected: %d vs %d",
+           len,(int)sizeof(struct sockaddr_in));
+    ok = 0;
+  }
+  if (sa->sa_family != AF_INET) {
+    log_fn(level, "Family of address not as expected: %d vs %d",
+           sa->sa_family, AF_INET);
+    ok = 0;
+  }
+  if (sin->sin_addr.s_addr == 0 || sin->sin_port == 0) {
+    log_fn(level, "Address for new connection has address/port equal to zero.");
+    ok = 0;
+  }
+  return ok ? 0 : -1;
+}
+
 /** The listener connection <b>conn</b> told poll() it wanted to read.
  * Call accept() on conn-\>s, and add the new connection if necessary.
  */
@@ -484,9 +509,12 @@
   connection_t *newconn;
   /* information about the remote peer when connecting to other routers */
   struct sockaddr_in remote;
+  char addrbuf[256];
   /* length of the remote address. Must be an int, since accept() needs that. */
-  int remotelen = sizeof(struct sockaddr_in);
+  int remotelen = 256;
   char tmpbuf[INET_NTOA_BUF_LEN];
+  tor_assert(remotelen >= sizeof(struct sockaddr_in));
+  memset(addrbuf, 0, sizeof(addrbuf));
 
   news = accept(conn->s,(struct sockaddr *)&remote,&remotelen);
   if (!SOCKET_IS_POLLABLE(news)) {
@@ -516,6 +544,22 @@
 
   set_socket_nonblocking(news);
 
+  if (check_sockaddr_in((struct sockaddr*)addrbuf, remotelen, LOG_INFO)<0) {
+    log_fn(LOG_INFO, "accept() returned a strange address; trying getsockname().");
+    remotelen=256;
+    memset(addrbuf, 0, sizeof(addrbuf));
+    if (getsockname(news, (struct sockaddr*)addrbuf, &remotelen)<0) {
+      log_fn(LOG_WARN, "getsockname() failed.");
+    } else {
+      if (check_sockaddr_in((struct sockaddr*)addrbuf, remotelen, LOG_WARN)<0) {
+        log_fn(LOG_WARN,"Something's wrong with this conn. Closing it.");
+        tor_close_socket(news);
+        return 0;
+      }
+    }
+  }
+  memcpy(&remote, addrbuf, sizeof(struct sockaddr_in));
+
   /* process entrance policies here, before we even create the connection */
   if (new_type == CONN_TYPE_AP) {
     /* check sockspolicy to see if we should accept it */
@@ -544,7 +588,6 @@
   /* remember the remote address */
   newconn->address = tor_malloc(INET_NTOA_BUF_LEN);
   tor_inet_ntoa(&remote.sin_addr, newconn->address, INET_NTOA_BUF_LEN);
-
   newconn->addr = ntohl(remote.sin_addr.s_addr);
   newconn->port = ntohs(remote.sin_port);