[or-cvs] Attempt to make sockets code work right on windows.

Nick Mathewson nickm at seul.org
Thu Aug 14 17:13:54 UTC 2003


Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/tmp/cvs-serv27349/src/or

Modified Files:
	buffers.c connection.c connection_edge.c connection_exit.c 
	connection_or.c directory.c main.c or.h test.c 
Log Message:
Attempt to make sockets code work right on windows.

Index: buffers.c
===================================================================
RCS file: /home/or/cvsroot/src/or/buffers.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- buffers.c	5 Jul 2003 07:10:34 -0000	1.26
+++ buffers.c	14 Aug 2003 17:13:51 -0000	1.27
@@ -36,6 +36,9 @@
 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 @@
 //  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 @@
    * 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 @@
 
   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 {

Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection.c,v
retrieving revision 1.73
retrieving revision 1.74
diff -u -d -r1.73 -r1.74
--- connection.c	12 Aug 2003 03:08:40 -0000	1.73
+++ connection.c	14 Aug 2003 17:13:51 -0000	1.74
@@ -188,11 +188,21 @@
   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;

Index: connection_edge.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_edge.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- connection_edge.c	12 Aug 2003 03:08:41 -0000	1.16
+++ connection_edge.c	14 Aug 2003 17:13:51 -0000	1.17
@@ -265,7 +265,7 @@
   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;

Index: connection_exit.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_exit.c,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -d -r1.38 -r1.39
--- connection_exit.c	14 Aug 2003 03:52:51 -0000	1.38
+++ connection_exit.c	14 Aug 2003 17:13:51 -0000	1.39
@@ -90,7 +90,7 @@
   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 @@
       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;
     }
   }

Index: connection_or.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_or.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- connection_or.c	12 Aug 2003 03:08:41 -0000	1.37
+++ connection_or.c	14 Aug 2003 17:13:51 -0000	1.38
@@ -62,7 +62,7 @@
       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 @@
 
   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 @@
       }
 
       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;
     }

Index: directory.c
===================================================================
RCS file: /home/or/cvsroot/src/or/directory.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- directory.c	12 Aug 2003 15:08:51 -0000	1.21
+++ directory.c	14 Aug 2003 17:13:51 -0000	1.22
@@ -66,7 +66,7 @@
   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 @@
       }
 
       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 @@
   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 */

Index: main.c
===================================================================
RCS file: /home/or/cvsroot/src/or/main.c,v
retrieving revision 1.82
retrieving revision 1.83
diff -u -d -r1.82 -r1.83
--- main.c	12 Aug 2003 15:08:51 -0000	1.82
+++ main.c	14 Aug 2003 17:13:51 -0000	1.83
@@ -243,7 +243,6 @@
   poll_array[conn->poll_index].events |= POLLOUT;
 }
 
-
 static void conn_read(int i) {
   int retval;
   connection_t *conn;
@@ -252,6 +251,13 @@
   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 @@
     }
   }
 
+#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 @@
     }
 
     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 */

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.106
retrieving revision 1.107
diff -u -d -r1.106 -r1.107
--- or.h	14 Aug 2003 03:52:51 -0000	1.106
+++ or.h	14 Aug 2003 17:13:52 -0000	1.107
@@ -89,7 +89,6 @@
 #define snprintf _snprintf
 #endif
 
-
 #include "../common/crypto.h"
 #include "../common/log.h"
 #include "../common/util.h"

Index: test.c
===================================================================
RCS file: /home/or/cvsroot/src/or/test.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- test.c	12 Aug 2003 03:16:15 -0000	1.32
+++ test.c	14 Aug 2003 17:13:52 -0000	1.33
@@ -7,7 +7,7 @@
 #include <fcntl.h>
 #endif
 
-#ifdef _MSC_VER
+#ifdef MS_WINDOWS
 /* For mkdir() */
 #include <direct.h>
 #endif



More information about the tor-commits mailing list