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
63
tests/stdlib/tssl.nim
Normal file
63
tests/stdlib/tssl.nim
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
discard """
|
||||
joinable: false
|
||||
"""
|
||||
|
||||
import net, nativesockets
|
||||
|
||||
when defined(posix): import os, posix
|
||||
|
||||
when not defined(ssl):
|
||||
{.error: "This test must be compiled with -d:ssl".}
|
||||
|
||||
const DummyData = "dummy data\n"
|
||||
|
||||
proc connector(port: Port) {.thread.} =
|
||||
let clientContext = newContext(verifyMode = CVerifyNone)
|
||||
var client = newSocket(buffered = false)
|
||||
clientContext.wrapSocket(client)
|
||||
client.connect("localhost", port)
|
||||
|
||||
discard client.recvLine()
|
||||
client.getFd.close()
|
||||
|
||||
proc main() =
|
||||
let serverContext = newContext(verifyMode = CVerifyNone,
|
||||
certFile = "tests/testdata/mycert.pem",
|
||||
keyFile = "tests/testdata/mycert.pem")
|
||||
|
||||
when defined(posix):
|
||||
var
|
||||
ignoreAction = SigAction(sa_handler: SIG_IGN)
|
||||
oldSigPipeHandler: SigAction
|
||||
if sigemptyset(ignoreAction.sa_mask) == -1:
|
||||
raiseOSError(osLastError(), "Couldn't create an empty signal set")
|
||||
if sigaction(SIGPIPE, ignoreAction, oldSigPipeHandler) == -1:
|
||||
raiseOSError(osLastError(), "Couldn't ignore SIGPIPE")
|
||||
|
||||
block peer_close_without_shutdown:
|
||||
var server = newSocket(buffered = false)
|
||||
defer: server.close()
|
||||
serverContext.wrapSocket(server)
|
||||
server.bindAddr(address = "localhost")
|
||||
let (_, port) = server.getLocalAddr()
|
||||
server.listen()
|
||||
|
||||
var clientThread: Thread[Port]
|
||||
createThread(clientThread, connector, port)
|
||||
|
||||
var peer: Socket
|
||||
try:
|
||||
server.accept(peer)
|
||||
peer.send(DummyData)
|
||||
|
||||
joinThread clientThread
|
||||
|
||||
while true:
|
||||
# Send data until we get EPIPE.
|
||||
peer.send(DummyData, {})
|
||||
except OSError:
|
||||
discard
|
||||
finally:
|
||||
peer.close()
|
||||
|
||||
when isMainModule: main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue