summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2003-09-11 21:38:57 +0000
committerNick Mathewson <nickm@torproject.org>2003-09-11 21:38:57 +0000
commit529d3bc56fdacf40cfafc1f6761aab381f8a3aef (patch)
tree22686b4c3ecb8813fef693a2f093ab240a64ad24
parentf5b4ef1fa2134f062c925ec75a8329a44585f763 (diff)
downloadtor-529d3bc56fdacf40cfafc1f6761aab381f8a3aef.tar.gz
tor-529d3bc56fdacf40cfafc1f6761aab381f8a3aef.zip
Resolve XXXXs in tortls.c
svn:r443
-rw-r--r--src/common/tortls.c86
1 files changed, 50 insertions, 36 deletions
diff --git a/src/common/tortls.c b/src/common/tortls.c
index 346f350cbb..1017cb27fb 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -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 @@ tor_tls_read(tor_tls *tls, char *cp, int len)
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 @@ tor_tls_write(tor_tls *tls, char *cp, int n)
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 @@ tor_tls_shutdown(tor_tls *tls)
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.