summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2005-04-06 15:42:35 +0000
committerRoger Dingledine <arma@torproject.org>2005-04-06 15:42:35 +0000
commit70f3b3ef8677e5aaab7831b015e97f91840d9d07 (patch)
treedba252dd8a42928147637ef6d1c65fe338d8de69
parent9cbaf4603d56a521b9d6e82489cd5aea624a395b (diff)
downloadtor-70f3b3ef8677e5aaab7831b015e97f91840d9d07.tar.gz
tor-70f3b3ef8677e5aaab7831b015e97f91840d9d07.zip
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. svn:r4028
-rw-r--r--src/or/connection.c47
1 files changed, 45 insertions, 2 deletions
diff --git a/src/or/connection.c b/src/or/connection.c
index 270deb9dc7..33c23189dd 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -476,6 +476,31 @@ static int connection_create_listener(const char *bindaddress, uint16_t bindport
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 @@ static int connection_handle_listener_read(connection_t *conn, int new_type) {
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 @@ static int connection_handle_listener_read(connection_t *conn, int new_type) {
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 @@ static int connection_handle_listener_read(connection_t *conn, int new_type) {
/* 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);