diff options
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/buffers.c | 22 | ||||
-rw-r--r-- | src/or/connection.c | 12 | ||||
-rw-r--r-- | src/or/connection_edge.c | 2 | ||||
-rw-r--r-- | src/or/connection_exit.c | 6 | ||||
-rw-r--r-- | src/or/connection_or.c | 8 | ||||
-rw-r--r-- | src/or/directory.c | 8 | ||||
-rw-r--r-- | src/or/main.c | 21 | ||||
-rw-r--r-- | src/or/or.h | 1 | ||||
-rw-r--r-- | src/or/test.c | 2 |
9 files changed, 62 insertions, 20 deletions
diff --git a/src/or/buffers.c b/src/or/buffers.c index 4a89b260d4..3ea26dbabb 100644 --- a/src/or/buffers.c +++ b/src/or/buffers.c @@ -36,6 +36,9 @@ void buf_free(char *buf) { int read_to_buf(int s, int at_most, char **buf, int *buflen, int *buf_datalen, int *reached_eof) { int read_result; +#ifdef MS_WINDOWS + int e; +#endif assert(buf && *buf && buflen && buf_datalen && reached_eof && (s>=0)); @@ -62,9 +65,15 @@ int read_to_buf(int s, int at_most, char **buf, int *buflen, int *buf_datalen, i // log_fn(LOG_DEBUG,"reading at most %d bytes.",at_most); read_result = read(s, *buf+*buf_datalen, at_most); if (read_result < 0) { - if(errno!=EAGAIN) { /* it's a real error */ + if(!ERRNO_EAGAIN(errno)) { /* it's a real error */ return -1; } +#ifdef MS_WINDOWS + e = correct_socket_errno(s); + if(!ERRNO_EAGAIN(errno)) { /* no, it *is* a real error! */ + return -1; + } +#endif return 0; } else if (read_result == 0) { log_fn(LOG_DEBUG,"Encountered eof"); @@ -84,6 +93,9 @@ int flush_buf(int s, char **buf, int *buflen, int *buf_flushlen, int *buf_datale * return -1 or how many bytes remain to be flushed */ int write_result; +#ifdef MS_WINDOWS + int e; +#endif assert(buf && *buf && buflen && buf_flushlen && buf_datalen && (s>=0) && (*buf_flushlen <= *buf_datalen)); @@ -94,9 +106,15 @@ int flush_buf(int s, char **buf, int *buflen, int *buf_flushlen, int *buf_datale write_result = write(s, *buf, *buf_flushlen); if (write_result < 0) { - if(errno!=EAGAIN) { /* it's a real error */ + if(!ERRNO_EAGAIN(errno)) { /* it's a real error */ + return -1; + } +#ifdef MS_WINDOWS + e = correct_socket_errno(s); + if(!ERRNO_EAGAIN(errno)) { /* no, it *is* a real error! */ return -1; } +#endif log_fn(LOG_DEBUG,"write() would block, returning."); return 0; } else { diff --git a/src/or/connection.c b/src/or/connection.c index c75b4b3793..78bf0dca55 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -188,11 +188,21 @@ int connection_handle_listener_read(connection_t *conn, int new_type, int new_st connection_t *newconn; struct sockaddr_in remote; /* information about the remote peer when connecting to other routers */ int remotelen = sizeof(struct sockaddr_in); /* length of the remote address */ +#ifdef MS_WINDOWS + int e; +#endif news = accept(conn->s,(struct sockaddr *)&remote,&remotelen); if (news == -1) { /* accept() error */ - if(errno==EAGAIN) + if(ERRNO_EAGAIN(errno)) { +#ifdef MS_WINDOWS + e = correct_socket_errno(conn->s); + if (ERRNO_EAGAIN(e)) + return 0; +#else return 0; /* he hung up before we could accept(). that's fine. */ +#endif + } /* else there was a real error. */ log_fn(LOG_ERR,"accept() failed. Closing."); return -1; diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 9ce0ab56ba..a2dcaeffd6 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -265,7 +265,7 @@ int connection_edge_finished_flushing(connection_t *conn) { switch(conn->state) { case EXIT_CONN_STATE_CONNECTING: if (getsockopt(conn->s, SOL_SOCKET, SO_ERROR, (void*)&e, &len) < 0) { /* not yet */ - if(errno != EINPROGRESS){ + if(!ERRNO_CONN_EINPROGRESS(errno)) { /* yuck. kill it. */ log_fn(LOG_DEBUG,"in-progress exit connect failed. Removing."); return -1; diff --git a/src/or/connection_exit.c b/src/or/connection_exit.c index 1daf9ad8f9..148f401e9b 100644 --- a/src/or/connection_exit.c +++ b/src/or/connection_exit.c @@ -90,7 +90,7 @@ int connection_exit_connect(connection_t *conn) { log_fn(LOG_DEBUG,"Connecting to %s:%u.",conn->address,conn->port); if(connect(s,(struct sockaddr *)&dest_addr,sizeof(dest_addr)) < 0) { - if(errno != EINPROGRESS){ + if(!ERRNO_CONN_EINPROGRESS(errno)) { /* yuck. kill it. */ perror("connect"); log_fn(LOG_DEBUG,"Connect failed."); @@ -102,7 +102,9 @@ int connection_exit_connect(connection_t *conn) { conn->state = EXIT_CONN_STATE_CONNECTING; log_fn(LOG_DEBUG,"connect in progress, socket %d.",s); - connection_watch_events(conn, POLLOUT | POLLIN); + connection_watch_events(conn, POLLOUT | POLLIN | POLLERR); + /* writable indicates finish, readable indicates broken link, + error indicates broken link in windowsland. */ return 0; } } diff --git a/src/or/connection_or.c b/src/or/connection_or.c index ccf3be06ad..75a02d0d73 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -62,7 +62,7 @@ int connection_or_finished_flushing(connection_t *conn) { return or_handshake_op_finished_sending_keys(conn); case OR_CONN_STATE_CLIENT_CONNECTING: if (getsockopt(conn->s, SOL_SOCKET, SO_ERROR, (void*)&e, &len) < 0) { /* not yet */ - if(errno != EINPROGRESS){ + if(!ERRNO_CONN_EINPROGRESS(errno)){ /* yuck. kill it. */ log_fn(LOG_DEBUG,"in-progress connect failed. Removing."); return -1; @@ -156,7 +156,7 @@ connection_t *connection_or_connect(routerinfo_t *router) { log(LOG_DEBUG,"connection_or_connect() : Trying to connect to %s:%u.",router->address,router->or_port); if(connect(s,(struct sockaddr *)&router_addr,sizeof(router_addr)) < 0){ - if(errno != EINPROGRESS){ + if(!ERRNO_CONN_EINPROGRESS(errno)) { /* yuck. kill it. */ connection_free(conn); return NULL; @@ -170,7 +170,9 @@ connection_t *connection_or_connect(routerinfo_t *router) { } log(LOG_DEBUG,"connection_or_connect() : connect in progress."); - connection_watch_events(conn, POLLIN | POLLOUT); /* writable indicates finish, readable indicates broken link */ + connection_watch_events(conn, POLLIN | POLLOUT | POLLERR); + /* writable indicates finish, readable indicates broken link, + error indicates broken link on windows */ conn->state = OR_CONN_STATE_CLIENT_CONNECTING; return conn; } diff --git a/src/or/directory.c b/src/or/directory.c index 1c4fb95b56..e402123dd2 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -66,7 +66,7 @@ void directory_initiate_fetch(routerinfo_t *router) { log_fn(LOG_DEBUG,"Trying to connect to %s:%u.",router->address,router->dir_port); if(connect(s,(struct sockaddr *)&router_addr,sizeof(router_addr)) < 0){ - if(errno != EINPROGRESS){ + if(!ERRNO_CONN_EINPROGRESS(errno)) { /* yuck. kill it. */ router_forget_router(conn->addr, conn->port); /* don't try him again */ connection_free(conn); @@ -81,7 +81,9 @@ void directory_initiate_fetch(routerinfo_t *router) { } log_fn(LOG_DEBUG,"connect in progress."); - connection_watch_events(conn, POLLIN | POLLOUT); /* writable indicates finish, readable indicates broken link */ + connection_watch_events(conn, POLLIN | POLLOUT | POLLERR); + /* writable indicates finish, readable indicates broken link, + error indicates broken link in windowsland. */ conn->state = DIR_CONN_STATE_CONNECTING; return; } @@ -255,7 +257,7 @@ int connection_dir_finished_flushing(connection_t *conn) { switch(conn->state) { case DIR_CONN_STATE_CONNECTING: if (getsockopt(conn->s, SOL_SOCKET, SO_ERROR, (void*)&e, &len) < 0) { /* not yet */ - if(errno != EINPROGRESS){ + if(!ERRNO_CONN_EINPROGRESS(errno)) { /* yuck. kill it. */ log_fn(LOG_DEBUG,"in-progress connect failed. Removing."); router_forget_router(conn->addr, conn->port); /* don't try him again */ diff --git a/src/or/main.c b/src/or/main.c index 9206d7b78b..c5206aebc4 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -243,7 +243,6 @@ void connection_start_writing(connection_t *conn) { poll_array[conn->poll_index].events |= POLLOUT; } - static void conn_read(int i) { int retval; connection_t *conn; @@ -252,6 +251,13 @@ static void conn_read(int i) { assert(conn); // log_fn(LOG_DEBUG,"socket %d has something to read.",conn->s); +#ifdef MS_WINDOWS + if (poll_array[i].revents & POLLERR) { + retval = -1; + goto error; + } +#endif + if (conn->type == CONN_TYPE_OR_LISTENER) { retval = connection_or_handle_listener_read(conn); } else if (conn->type == CONN_TYPE_AP_LISTENER) { @@ -274,14 +280,17 @@ static void conn_read(int i) { } } +#ifdef MS_WINDOWS + error: +#endif if(retval < 0) { /* this connection is broken. remove it */ log_fn(LOG_INFO,"%s connection broken, removing.", conn_type_to_string[conn->type]); connection_remove(conn); connection_free(conn); if(i<nfds) { /* we just replaced the one at i with a new one. process it too. */ - if(poll_array[i].revents & POLLIN || - poll_array[i].revents & POLLHUP ) /* something to read */ + if(poll_array[i].revents & (POLLIN|POLLHUP|POLLERR)) + /* something to read */ conn_read(i); } } @@ -565,10 +574,10 @@ static int do_main_loop(void) { } if(poll_result > 0) { /* we have at least one connection to deal with */ - /* do all the reads first, so we can detect closed sockets */ + /* do all the reads and errors first, so we can detect closed sockets */ for(i=0;i<nfds;i++) - if(poll_array[i].revents & POLLIN || - poll_array[i].revents & POLLHUP ) /* something to read */ + if(poll_array[i].revents & (POLLIN|POLLHUP|POLLERR)) + /* something to read, or an error. */ conn_read(i); /* this also blows away broken connections */ /* see http://www.greenend.org.uk/rjk/2001/06/poll.html for discussion * of POLLIN vs POLLHUP */ diff --git a/src/or/or.h b/src/or/or.h index 72bdf0bbba..83c80a36b0 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -89,7 +89,6 @@ #define snprintf _snprintf #endif - #include "../common/crypto.h" #include "../common/log.h" #include "../common/util.h" diff --git a/src/or/test.c b/src/or/test.c index acc3896afd..3d769c39aa 100644 --- a/src/or/test.c +++ b/src/or/test.c @@ -7,7 +7,7 @@ #include <fcntl.h> #endif -#ifdef _MSC_VER +#ifdef MS_WINDOWS /* For mkdir() */ #include <direct.h> #endif |