asyncnet, net: don't attempt SSL_shutdown if a fatal error occurred (#15066)
* asyncnet, net: don't attempt SSL_shutdown if a fatal error occurred Per TLS standard and SSL_shutdown(3ssl). This should prevent errors coming from a close() after a bad event (ie. the other end of the pipe is closed before shutdown can be negotiated). Ref #9867 * tssl: try sending until an error occur * tssl: cleanup * tssl: actually run the test I forgot to make the test run :P * tssl: run the test on ARC, maybe then it'll be happy * tssl: turns off ARC, switch tlsEmulation on for freebsd * tssl: document why tlsEmulation is employed * net: move SafeDisconn handling logic to socketError
This commit is contained in:
parent
0788a7f970
commit
20315637aa
4 changed files with 120 additions and 34 deletions
|
|
@ -123,6 +123,7 @@ type
|
|||
sslContext: SslContext
|
||||
bioIn: BIO
|
||||
bioOut: BIO
|
||||
sslNoShutdown: bool
|
||||
domain: Domain
|
||||
sockType: SockType
|
||||
protocol: Protocol
|
||||
|
|
@ -200,9 +201,10 @@ proc newAsyncSocket*(domain, sockType, protocol: cint,
|
|||
Protocol(protocol), buffered, inheritable)
|
||||
|
||||
when defineSsl:
|
||||
proc getSslError(handle: SslPtr, err: cint): cint =
|
||||
proc getSslError(socket: AsyncSocket, err: cint): cint =
|
||||
assert socket.isSsl
|
||||
assert err < 0
|
||||
var ret = SSL_get_error(handle, err.cint)
|
||||
var ret = SSL_get_error(socket.sslHandle, err.cint)
|
||||
case ret
|
||||
of SSL_ERROR_ZERO_RETURN:
|
||||
raiseSSLError("TLS/SSL connection failed to initiate, socket closed prematurely.")
|
||||
|
|
@ -213,6 +215,7 @@ when defineSsl:
|
|||
of SSL_ERROR_WANT_X509_LOOKUP:
|
||||
raiseSSLError("Function for x509 lookup has been called.")
|
||||
of SSL_ERROR_SYSCALL, SSL_ERROR_SSL:
|
||||
socket.sslNoShutdown = true
|
||||
raiseSSLError()
|
||||
else: raiseSSLError("Unknown Error")
|
||||
|
||||
|
|
@ -265,7 +268,7 @@ when defineSsl:
|
|||
# If the operation failed, try to see if SSL has some data to read
|
||||
# or write.
|
||||
if opResult < 0:
|
||||
let err = getSslError(socket.sslHandle, opResult.cint)
|
||||
let err = getSslError(socket, opResult.cint)
|
||||
let fut = appeaseSsl(socket, flags, err.cint)
|
||||
yield fut
|
||||
if not fut.read():
|
||||
|
|
@ -718,7 +721,7 @@ proc close*(socket: AsyncSocket) =
|
|||
# Don't call SSL_shutdown if the connection has not been fully
|
||||
# established, see:
|
||||
# https://github.com/openssl/openssl/issues/710#issuecomment-253897666
|
||||
if SSL_in_init(socket.sslHandle) == 0:
|
||||
if not socket.sslNoShutdown and SSL_in_init(socket.sslHandle) == 0:
|
||||
ErrClearError()
|
||||
SSL_shutdown(socket.sslHandle)
|
||||
else:
|
||||
|
|
@ -747,6 +750,8 @@ when defineSsl:
|
|||
socket.bioOut = bioNew(bioSMem())
|
||||
sslSetBio(socket.sslHandle, socket.bioIn, socket.bioOut)
|
||||
|
||||
socket.sslNoShutdown = true
|
||||
|
||||
proc wrapConnectedSocket*(ctx: SslContext, socket: AsyncSocket,
|
||||
handshake: SslHandshakeType,
|
||||
hostname: string = "") =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue