diff options
author | Nick Mathewson <nickm@torproject.org> | 2003-09-11 21:38:57 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2003-09-11 21:38:57 +0000 |
commit | 529d3bc56fdacf40cfafc1f6761aab381f8a3aef (patch) | |
tree | 22686b4c3ecb8813fef693a2f093ab240a64ad24 /src/common | |
parent | f5b4ef1fa2134f062c925ec75a8329a44585f763 (diff) | |
download | tor-529d3bc56fdacf40cfafc1f6761aab381f8a3aef.tar tor-529d3bc56fdacf40cfafc1f6761aab381f8a3aef.tar.gz |
Resolve XXXXs in tortls.c
svn:r443
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/tortls.c | 86 |
1 files changed, 50 insertions, 36 deletions
diff --git a/src/common/tortls.c b/src/common/tortls.c index 346f350cb..1017cb27f 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. |