diff options
author | Roger Dingledine <arma@torproject.org> | 2005-04-06 15:42:35 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2005-04-06 15:42:35 +0000 |
commit | 70f3b3ef8677e5aaab7831b015e97f91840d9d07 (patch) | |
tree | dba252dd8a42928147637ef6d1c65fe338d8de69 /src/or | |
parent | 9cbaf4603d56a521b9d6e82489cd5aea624a395b (diff) | |
download | tor-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
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/connection.c | 47 |
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); |