@@ -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
@@ -464,15 +464,64 @@ The following code describes these functions in more detail:
464464 ...
465465
466466 @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."""
467+ def shutdown (self , how : Literal[0 , 1 , 2 ]) -> None :
468+ """
469+ Shutdown TLS and the underlying socket.
470+
471+ Proper TLS applications ought to signal their peers when they're
472+ done sending data by sending a closing alert.
473+
474+ * ``socket.SHUT_WR`` (``1``) sends the closing alert to the peer and
475+ then prevents sending any further message. Proper TLS application
476+ **MUST** call this method with this parameter to gracefully close
477+ the TLS connection. *Safe* in TLS 1.3. Actually acts like
478+ ``SHUT_RDWD`` in TLS 1.2 and is as *unsafe* as ``SHUT_RD``.
479+
480+ * ``socket.SHUT_RD`` (``0``) simulates receiving the closing alert
481+ from the peer and then ignores all further received messages.
482+ *Unsafe* (risk of data loss) unless the connection is otherwise
483+ known to be over thanks to the application-layer protocol (e.g.
484+ HTTP Content-Length).
485+
486+ * ``socket.SHUT_RDWR`` (``2``) does both ``SHUT_RD`` and ``SHUT_WR``.
487+ As *unsafe* as ``SHUT_RD``.
488+
489+ In TLS 1.2, the closing alert is synchronous, receiving it triggers
490+ an immediate closing alert response, and both connections are
491+ immediately shut. It means that ``SHUT_WR`` acts like ``SHUT_RDWR``
492+ and is unsafe unless all the data have been received.
493+
494+ In TLS 1.3, the closing alert is asynchronous, sending the closing
495+ alert only closes the sender's sending-end and receiver's
496+ receiving-end. The peer can keep on sending data until he
497+ independently decides to close its own sending-end of the
498+ connection. There is not risk of data truncation with ``SHUT_WR``.
499+
500+ .. danger::
501+
502+ Both ``socket.SHUT_RD`` (``0``) and ``socket.SHUT_RDWR`` (``2``)
503+ pose a risk of data loss, only use them when facing a bad actor
504+ or when the connection is otherwise known to be over.
505+
506+ In TLS 1.2 the same risk applies also to ``socket.SHUT_WR`` (``1``).
507+ """
508+ ...
509+
510+ @abstractmethod
511+ def close (self ) -> None :
512+ """
513+ Close the underlying socket, but only when it is safe to do so.
514+
515+ When the sending-end of the connection is still open, it sends a
516+ closing alert before closing the socket, raising ``WantWriteError``
517+ when it fails.
518+
519+ When the receiving-end of the connection is still open, it always
520+ raises ``WantReadError`` as there's a risk of data loss / truncation
521+ attack. The user must first either: (safe) ``recv`` until the peer
522+ closes its sending-end of the connection, or (unsafe) take the risk
523+ and unilateraly ``shutdown`` the reading-end of the connection.
524+ """
476525 ...
477526
478527 @abstractmethod
0 commit comments