Index: tlsBIO.c ================================================================== --- tlsBIO.c +++ tlsBIO.c @@ -127,11 +127,11 @@ dprintf("[chan=%p] BioWrite(%d) -> %d [tclEof=%d; tclErrno=%d]", (void *) chan, bufLen, ret, tclEofChan, Tcl_GetErrno()); BIO_clear_flags(bio, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY); if (tclEofChan && ret <= 0) { - dprintf("Got EOF while reading, returning a Connection Reset error which maps to Soft EOF"); + dprintf("Got EOF while writing, returning a Connection Reset error which maps to Soft EOF"); Tcl_SetErrno(ECONNRESET); ret = 0; } else if (ret == 0) { dprintf("Got 0 from Tcl_WriteRaw, and EOF is not set; ret = 0"); dprintf("Setting retry read flag"); Index: tlsIO.c ================================================================== --- tlsIO.c +++ tlsIO.c @@ -387,10 +387,17 @@ if (statePtr->flags & TLS_TCL_CALLBACK) { /* don't process any bytes while verify callback is running */ dprintf("Callback is running, reading 0 bytes"); return(0); } + + if (statePtr->flags & TLS_TCL_EOF) { + dprintf("Asked to read after reaching EOF, we are treating this as fatal."); + bytesRead = 0; + *errorCodePtr = ECONNRESET; + return(bytesRead); + } dprintf("Calling Tls_WaitForConnect"); tlsConnect = Tls_WaitForConnect(statePtr, errorCodePtr, 0); if (tlsConnect < 0) { dprintf("Got an error waiting to connect (tlsConnect = %i, *errorCodePtr = %i)", tlsConnect, *errorCodePtr); @@ -476,10 +483,16 @@ dprintf("Unknown error (err = %i), mapping to EOF", err); *errorCodePtr = 0; bytesRead = 0; break; } + + if (bufSize != 0 && bytesRead == 0 && *errorCodePtr == 0) { + dprintf("Detected EOF, setting the EOF flag"); + statePtr->flags |= TLS_TCL_EOF; + *errorCodePtr = ECONNRESET; + } dprintf("Input(%d) -> %d [%d]", bufSize, bytesRead, *errorCodePtr); return(bytesRead); } @@ -516,22 +529,30 @@ dprintf("Don't process output while callbacks are running") written = -1; *errorCodePtr = EAGAIN; return(-1); } + + if (statePtr->flags & TLS_TCL_EOF) { + dprintf("Asked to write after reaching EOF, we are treating this as fatal."); + written = 0; + *errorCodePtr = ECONNRESET; + return(written); + } dprintf("Calling Tls_WaitForConnect"); tlsConnect = Tls_WaitForConnect(statePtr, errorCodePtr, 1); if (tlsConnect < 0) { dprintf("Got an error waiting to connect (tlsConnect = %i, *errorCodePtr = %i)", tlsConnect, *errorCodePtr); written = -1; if (*errorCodePtr == ECONNRESET) { - dprintf("Got connection reset"); + dprintf("Got connection reset (setting EOF flag)"); /* Soft EOF */ - *errorCodePtr = 0; + *errorCodePtr = ECONNRESET; written = 0; + statePtr->flags |= TLS_TCL_EOF; } return(written); } @@ -584,11 +605,11 @@ break; case SSL_ERROR_WANT_X509_LOOKUP: dprintf(" write X BLOCK"); break; case SSL_ERROR_ZERO_RETURN: - dprintf(" closed"); + dprintf(" closed (EOF reached)"); written = 0; *errorCodePtr = 0; break; case SSL_ERROR_SYSCALL: backingError = ERR_get_error(); @@ -615,10 +636,16 @@ break; default: dprintf(" unknown err: %d", err); break; } + + if (toWrite != 0 && written == 0 && *errorCodePtr == 0) { + dprintf("Detected EOF, setting the EOF flag"); + statePtr->flags |= TLS_TCL_EOF; + *errorCodePtr = ECONNRESET; + } dprintf("Output(%d) -> %d", toWrite, written); return(written); } Index: tlsInt.h ================================================================== --- tlsInt.h +++ tlsInt.h @@ -124,10 +124,11 @@ * looping problem. [Bug 1652380] */ #define TLS_TCL_HANDSHAKE_FAILED (1<<5) /* Set on handshake failures and once * set, all further I/O will result * in ECONNABORTED errors. */ #define TLS_TCL_FASTPATH (1<<6) /* The parent channel is being used directly by the SSL library */ +#define TLS_TCL_EOF (1<<7) /* We initiated EOF, any further attempts to write will return an error */ #define TLS_TCL_DELAY (5) /* * This structure describes the per-instance state * of an ssl channel.