tssl.nim 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. discard """
  2. joinable: false
  3. disabled: "freebsd"
  4. disabled: "openbsd"
  5. """
  6. # disabled: pending bug #15713
  7. import std/[net, nativesockets, assertions, typedthreads]
  8. when defined(posix): import os, posix
  9. else:
  10. import winlean
  11. const SD_SEND = 1
  12. when not defined(ssl):
  13. {.error: "This test must be compiled with -d:ssl".}
  14. const DummyData = "dummy data\n"
  15. proc abruptShutdown(port: Port) {.thread.} =
  16. let clientContext = newContext(verifyMode = CVerifyNone)
  17. var client = newSocket(buffered = false)
  18. clientContext.wrapSocket(client)
  19. client.connect("localhost", port)
  20. discard client.recvLine()
  21. client.getFd.close()
  22. proc notifiedShutdown(port: Port) {.thread.} =
  23. let clientContext = newContext(verifyMode = CVerifyNone)
  24. var client = newSocket(buffered = false)
  25. clientContext.wrapSocket(client)
  26. client.connect("localhost", port)
  27. discard client.recvLine()
  28. client.close()
  29. proc main() =
  30. when defined(posix):
  31. var
  32. ignoreAction = Sigaction(sa_handler: SIG_IGN)
  33. oldSigPipeHandler: Sigaction
  34. if sigemptyset(ignoreAction.sa_mask) == -1:
  35. raiseOSError(osLastError(), "Couldn't create an empty signal set")
  36. if sigaction(SIGPIPE, ignoreAction, oldSigPipeHandler) == -1:
  37. raiseOSError(osLastError(), "Couldn't ignore SIGPIPE")
  38. let serverContext = newContext(verifyMode = CVerifyNone,
  39. certFile = "tests/testdata/mycert.pem",
  40. keyFile = "tests/testdata/mycert.pem")
  41. block peer_close_during_write_without_shutdown:
  42. var server = newSocket(buffered = false)
  43. defer: server.close()
  44. serverContext.wrapSocket(server)
  45. server.bindAddr(address = "localhost")
  46. let (_, port) = server.getLocalAddr()
  47. server.listen()
  48. var clientThread: Thread[Port]
  49. createThread(clientThread, abruptShutdown, port)
  50. var peer: Socket
  51. try:
  52. server.accept(peer)
  53. peer.send(DummyData)
  54. joinThread clientThread
  55. while true:
  56. # Send data until we get EPIPE.
  57. peer.send(DummyData, {})
  58. except OSError:
  59. discard
  60. finally:
  61. peer.close()
  62. when defined(posix):
  63. if sigaction(SIGPIPE, oldSigPipeHandler, nil) == -1:
  64. raiseOSError(osLastError(), "Couldn't restore SIGPIPE handler")
  65. block peer_close_before_received_shutdown:
  66. var server = newSocket(buffered = false)
  67. defer: server.close()
  68. serverContext.wrapSocket(server)
  69. server.bindAddr(address = "localhost")
  70. let (_, port) = server.getLocalAddr()
  71. server.listen()
  72. var clientThread: Thread[Port]
  73. createThread(clientThread, abruptShutdown, port)
  74. var peer: Socket
  75. try:
  76. server.accept(peer)
  77. peer.send(DummyData)
  78. joinThread clientThread
  79. # Tell the OS to close off the write side so shutdown attempts will
  80. # be met with SIGPIPE.
  81. when defined(posix):
  82. discard peer.getFd.shutdown(SHUT_WR)
  83. else:
  84. discard peer.getFd.shutdown(SD_SEND)
  85. finally:
  86. peer.close()
  87. block peer_close_after_received_shutdown:
  88. var server = newSocket(buffered = false)
  89. defer: server.close()
  90. serverContext.wrapSocket(server)
  91. server.bindAddr(address = "localhost")
  92. let (_, port) = server.getLocalAddr()
  93. server.listen()
  94. var clientThread: Thread[Port]
  95. createThread(clientThread, notifiedShutdown, port)
  96. var peer: Socket
  97. try:
  98. server.accept(peer)
  99. peer.send(DummyData)
  100. doAssert peer.recv(1024) == "" # Get the shutdown notification
  101. joinThread clientThread
  102. # Tell the OS to close off the write side so shutdown attempts will
  103. # be met with SIGPIPE.
  104. when defined(posix):
  105. discard peer.getFd.shutdown(SHUT_WR)
  106. else:
  107. discard peer.getFd.shutdown(SD_SEND)
  108. finally:
  109. peer.close()
  110. when isMainModule: main()