summaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2003-08-14 17:13:52 +0000
committerNick Mathewson <nickm@torproject.org>2003-08-14 17:13:52 +0000
commitcd3467bb01cb5bd98b2978fb50bdaa2f3227c980 (patch)
treed91d3689a009c3fa358bae94e883240e83fcb642 /src/or
parent88edae94076cc39d40a39f80b2d6ddadc88fe324 (diff)
downloadtor-cd3467bb01cb5bd98b2978fb50bdaa2f3227c980.tar.gz
tor-cd3467bb01cb5bd98b2978fb50bdaa2f3227c980.zip
Attempt to make sockets code work right on windows.
svn:r398
Diffstat (limited to 'src/or')
-rw-r--r--src/or/buffers.c22
-rw-r--r--src/or/connection.c12
-rw-r--r--src/or/connection_edge.c2
-rw-r--r--src/or/connection_exit.c6
-rw-r--r--src/or/connection_or.c8
-rw-r--r--src/or/directory.c8
-rw-r--r--src/or/main.c21
-rw-r--r--src/or/or.h1
-rw-r--r--src/or/test.c2
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