OpenSSL 3.0 introduced a new ssl option `SSL_OP_IGNORE_UNEXPECTED_EOF`.  If this is not set, and OpenSSL receives an unexpected EOF, it is treated as a fatal error.  TclTLS does not set this, which can lead do unexpected errors.  For example:

	$ cat

	#\
	exec tclsh8.6 "$0" ${1+"$@"}

	package require tls

	proc main host {

	    global done

	    set req [subst {
	GET / HTTP/1.1
	Host: $host
	Connection: close

	}]

	    set s [socket $host 443]

	    tls::import $s -require 0 -ssl2 0 -ssl3 0 -tls1 1 -servername $host

	    tls::handshake $s

	    fconfigure $s -translation crlf -blocking 0 -buffering none

	    puts -nonewline $s $req

	    set done 0

	    fileevent $s readable [list read_response $s]

	    vwait done

	    close $s

	}

	proc read_response s {

	    global done

	    while 1 {

	        if { [eof $s] } {
	            puts stderr "read_response: got EOF"
	            set done 1
	            break
	        }

	        if { [catch { set resp [read $s] } error] } {
	            puts stderr "read_response: error = $error"
	            set done 1
	            break
	        }

	        puts stderr "read_response: $resp"

	        if { [fblocked $s] } {
	            break
	        }

	    }

	    if { $done } {
	        fileevent $s readable [list]
	    }

	}

	main [lindex $argv 0]
	$
	read_response: HTTP/1.1 301 Moved Permanently
	Location:
	Content-Type: text/html; charset=UTF-8
	Content-Security-Policy-Report-Only: object-src 'none';base-uri 'self';script-src 'nonce-RriZ0vurw26vE_UywsmQQg' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri
	Date: Fri, 10 Nov 2023 18:16:14 GMT
	Expires: Fri, 10 Nov 2023 18:16:14 GMT
	Cache-Control: private, max-age=2592000
	Server: gws
	Content-Length: 220
	X-XSS-Protection: 0
	X-Frame-Options: SAMEORIGIN
	Set-Cookie: CONSENT=PENDING+895; expires=Sun, 09-Nov-2025 18:16:14 GMT; path=/; Secure
	P3P: CP="This is not a P3P policy! See for more info."
	Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
	Connection: close

	<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
	<TITLE>301
	<H1>301 Moved</H1>
	The document has moved
	<A


	read_response: error = error reading "sock560f01ccd5c0": software caused connection abort

Setting the option:

	$ fossil diff
	Index: tls.c
	==================================================================
	--- tls.c
	+++ tls.c
	@@ -1212,10 +1212,13 @@
	 #endif

	     SSL_CTX_set_app_data( ctx, (VOID*)interp); /* remember the interpreter */
	     SSL_CTX_set_options( ctx, SSL_OP_ALL);     /* all SSL bug workarounds */
	     SSL_CTX_set_options( ctx, off);    /* all SSL bug workarounds */
	+#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
	+    SSL_CTX_set_options( ctx, SSL_OP_IGNORE_UNEXPECTED_EOF);
	+#endif
	     SSL_CTX_sess_set_cache_size( ctx, 128);

	     if (ciphers != NULL)
	        SSL_CTX_set_cipher_list(ctx, ciphers);


causes the EOF to be handled as expected:

	$
	read_response: HTTP/1.1 301 Moved Permanently
	Location:
	Content-Type: text/html; charset=UTF-8
	Content-Security-Policy-Report-Only: object-src 'none';base-uri 'self';script-src 'nonce-GtEz85sCnLQF8adC4dzohw' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri
	Date: Fri, 10 Nov 2023 18:24:57 GMT
	Expires: Fri, 10 Nov 2023 18:24:57 GMT
	Cache-Control: private, max-age=2592000
	Server: gws
	Content-Length: 220
	X-XSS-Protection: 0
	X-Frame-Options: SAMEORIGIN
	Set-Cookie: CONSENT=PENDING+011; expires=Sun, 09-Nov-2025 18:24:57 GMT; path=/; Secure
	P3P: CP="This is not a P3P policy! See for more info."
	Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
	Connection: close

	<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
	<TITLE>301
	<H1>301 Moved</H1>
	The document has moved
	<A


	read_response:
	read_response: got EOF