[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] Resolve XXXXs in tortls.c



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

Modified Files:
	tortls.c 
Log Message:
Resolve XXXXs in tortls.c

Index: tortls.c
===================================================================
RCS file: /home/or/cvsroot/src/common/tortls.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- tortls.c	11 Sep 2003 21:12:39 -0000	1.6
+++ tortls.c	11 Sep 2003 21:38:57 -0000	1.7
@@ -10,6 +10,7 @@
 #include "./crypto.h"
 #include "./tortls.h"
 #include "./util.h"
+#include "./log.h"
 
 #include <assert.h>
 #include <openssl/ssl.h>
@@ -271,7 +272,7 @@
     tls->state = TOR_TLS_ST_CLOSED;
     return TOR_TLS_CLOSE;
   } else {
-    /*  XXXX Make sure it's not TOR_TLS_DONE. */
+    assert(err != TOR_TLS_DONE);
     return err;
   }
 }
@@ -287,12 +288,12 @@
   int r, err;
   assert(tls && tls->ssl);
   assert(tls->state == TOR_TLS_ST_OPEN);
+  if (n == 0)
+    return 0;
   r = SSL_write(tls->ssl, cp, n);
   err = tor_tls_get_error(tls, r, 1);
-  if (err == _TOR_TLS_ZERORETURN) {
-    /* should never happen XXXX */
-    return 0;
-  } else if (err == TOR_TLS_DONE) {
+  assert(err != _TOR_TLS_ZERORETURN);
+  if (err == TOR_TLS_DONE) {
     return r;
   } else {
     return err;
@@ -332,41 +333,54 @@
   char buf[128];
   assert(tls && tls->ssl);
 
-  if (tls->state == TOR_TLS_ST_SENTCLOSE) {
-    do {
-      r = SSL_read(tls->ssl, buf, 128);
-    } while (r>0);
+  while (1) {
+    if (tls->state == TOR_TLS_ST_SENTCLOSE) {
+      /* If we've already called shutdown once to send a close message,
+       * we read until the other side has closed too.
+       */
+      do {
+	r = SSL_read(tls->ssl, buf, 128);
+      } while (r>0);
+      err = tor_tls_get_error(tls, r, 1);
+      if (err == _TOR_TLS_ZERORETURN) {
+	tls->state = TOR_TLS_ST_GOTCLOSE;
+	/* fall through... */
+      } else {
+	if (err == _TOR_TLS_SYSCALL)
+	  err = TOR_TLS_ERROR;
+	return err;
+      }
+    }
+
+    r = SSL_shutdown(tls->ssl);
+    if (r == 1) {
+      /* If shutdown returns 1, the connection is entirely closed. */
+      tls->state = TOR_TLS_ST_CLOSED;
+      return TOR_TLS_DONE;
+    }
     err = tor_tls_get_error(tls, r, 1);
-    if (err == _TOR_TLS_ZERORETURN) {
-      tls->state = TOR_TLS_ST_GOTCLOSE;
-      /* fall through */
+    if (err == _TOR_TLS_SYSCALL) {
+      /* The underlying TCP connection closed while we were shutting down. */
+      tls->state = TOR_TLS_ST_CLOSED; 
+      return TOR_TLS_DONE;
+    } else if (err == _TOR_TLS_ZERORETURN) {
+      /* The TLS connection says that it sent a shutdown record, but
+       * isn't done shutting down yet.  Make sure that this hasn't
+       * happened before, then go back to the start of the function
+       * and try to read.
+       */
+      if (tls->state == TOR_TLS_ST_GOTCLOSE || 
+	  tls->state == TOR_TLS_ST_SENTCLOSE) {
+	log(LOG_ERR, 
+	    "TLS returned \"half-closed\" value while already half-closed");
+	return TOR_TLS_ERROR;
+      }
+      tls->state = TOR_TLS_ST_SENTCLOSE;
+      /* fall through ... */
     } else {
-      if (err == _TOR_TLS_SYSCALL)
-        err = TOR_TLS_ERROR;
       return err;
     }
-  }
-
-  r = SSL_shutdown(tls->ssl);
-  if (r == 1) {
-    tls->state = TOR_TLS_ST_CLOSED;
-    return TOR_TLS_DONE;
-  }
-  err = tor_tls_get_error(tls, r, 1);
-  if (err == _TOR_TLS_SYSCALL)
-    return TOR_TLS_ST_CLOSED; /* XXXX is this right? */
-  else if (err == _TOR_TLS_ZERORETURN) {
-    if (tls->state == TOR_TLS_ST_GOTCLOSE || 
-        tls->state == TOR_TLS_ST_SENTCLOSE) {
-      /* XXXX log; unexpected. */
-      return TOR_TLS_ERROR;
-    }
-    tls->state = TOR_TLS_ST_SENTCLOSE;
-    return tor_tls_shutdown(tls);
-  } else {
-    /* XXXX log if not error. */
-    return err;
-  }
+  } /* end loop */
 }
 
 /* Return true iff this TLS connection is authenticated.