@@ -422,7 +422,7 @@ need to implement the following:
422422
423423* ``recv `` and ``send ``
424424* ``accept `` (server-side)
425- * ``close ``
425+ * ``shutdown `` and `` close ``
426426* ``getsockname ``
427427* ``getpeername ``
428428
@@ -438,6 +438,12 @@ The following code describes these functions in more detail:
438438
439439.. code-block :: python
440440
441+ class TLSShutdownMode (enum .IntEnum ):
442+ SHUT_RD = 0
443+ SHUT_WR = 1
444+ SHUT_RDWR = 2
445+
446+
441447 class TLSSocket (Protocol ):
442448 """ This class implements a socket.socket-like object that creates an OS
443449 socket, wraps it in an SSL context, and provides read and write methods
@@ -464,15 +470,41 @@ The following code describes these functions in more detail:
464470 ...
465471
466472 @abstractmethod
467- def close (self , force : bool = False ) -> None :
468- """ Shuts down the connection and mark the socket closed.
469- If force is True, this method should send the close_notify alert and shut down
470- the socket without waiting for the other side.
471- If force is False, this method should send the close_notify alert and raise
472- the WantReadError exception until a corresponding close_notify alert has been
473- received from the other side.
474- In either case, this method should return WantWriteError if sending the
475- close_notify alert currently fails."""
473+ def shutdown (self , how : TLSShutdownMode) -> None :
474+ """
475+ Shutdown TLS and the underlying socket.
476+
477+ * ``SHUT_RD`` (``0``) unilateraly close the receiving-side: discard
478+ present and future unread messages.
479+ * ``SHUT_WR`` (``1``) gracefully close the sending-side: send a
480+ closing alert and prevent sending more messages.
481+ * ``SHUT_RDWR`` (``2``): both ``SHUT_WR`` and ``SHUT_RD``.
482+
483+ .. danger::
484+
485+ Both ``shutdown(SHUT_RD)`` and ``shutdown(SHUT_RDWR)`` pose a
486+ risk of data loss: they are unsafe unless the connection is
487+ otherwise known to be over or when truncation is not an issue.
488+
489+ In TLS 1.2, the same risk applies also to ``shutdown(SHUT_WR)``.
490+ """
491+ ...
492+
493+ @abstractmethod
494+ def close (self ) -> None :
495+ """
496+ Close the underlying socket, but only when it is safe to do so.
497+
498+ When the sending-side of the connection is still open, it gracefully
499+ closes the TLS sending-side before closing the socket, raising
500+ ``WantWriteError`` when it fails.
501+
502+ When the receiving-side of the connection is still open, it always
503+ raises ``WantReadError`` as there's a risk of data loss / truncation
504+ attack. The user must first either: (safe) ``recv`` until the peer
505+ closes its sending-side of the connection, or (unsafe) take the risk
506+ and unilateraly ``shutdown`` the receiving-side of the connection.
507+ """
476508 ...
477509
478510 @abstractmethod
0 commit comments