duck.utils.xsocket

Custom Duck socket implementations.

Submodules

Package Contents

Classes

SSLObjectReadOrWrite

State on SSL object on whether if we are reading/writing to ssl object.

ssl_xsocket

SSL Wrapper for raw sockets providing async support and transparent delegation of socket methods/attributes.

xsocket

Wrapper for raw sockets providing async support and transparent delegation of socket methods/attributes.

Functions

create_xsocket

Create an xsocket object from provided arguments.

ssl_wrap_socket

Return an SSL xsocket with the same arguments as ssl.wrap_socket.

Data

DEFAULT_BUFSIZE

API

duck.utils.xsocket.DEFAULT_BUFSIZE

None

class duck.utils.xsocket.SSLObjectReadOrWrite

Bases: enum.IntEnum

State on SSL object on whether if we are reading/writing to ssl object.

Initialization

Initialize self. See help(type(self)) for accurate signature.

NOTHING

0

We are reading from the SSL object.

READING

2

We are reading from the SSL object.

WRITING

1

We are reading from the SSL object.

duck.utils.xsocket.create_xsocket(family: int = socket.AF_INET, type: int = socket.SOCK_STREAM, **kwargs) xsocket

Create an xsocket object from provided arguments.

Parameters:
  • family – The socket family. Defaults to socket.AF_INET.

  • type – Type of socket. Defaults to socket.SOCK_STREAM.

duck.utils.xsocket.ssl_wrap_socket(socket_obj: socket.socket, keyfile: str = None, certfile: str = None, version: int = ssl.PROTOCOL_TLS_SERVER, server_side: bool = True, ca_certs=None, ciphers=None, alpn_protocols: list[str] = None) ssl_xsocket

Return an SSL xsocket with the same arguments as ssl.wrap_socket.

Parameters:
  • socket_obj – The underlying socket object to secure.

  • keyfile – Path to the server’s private key file (PEM format).

  • certfile – Path to the server’s certificate file (PEM format).

  • version – SSL Protocol version.

  • server_side – Whether the socket is for the server side.

  • ca_certs – Path to trusted CA certificates.

  • ciphers – Cipher suites string.

  • alpn_protocols – ALPN protocols (e.g., [“h2”, “http/1.1”]).

Returns:

The secure SSL socket.

Return type:

socket.socket

class duck.utils.xsocket.ssl_xsocket(raw_socket: socket.socket, ssl_context: ssl.SSLContext, server_side: bool = True)

Bases: duck.utils.xsocket.xsocket

SSL Wrapper for raw sockets providing async support and transparent delegation of socket methods/attributes.

Initialization

_set_ssl_attributes()

Dynamically exposes non-callable public attributes from self.ssl_obj onto self. Creates properties with both getter and setter to reflect changes in real-time.

async async_do_handshake(timeout: Optional[float] = None)

Asynchronous handshake loop with flush/recv handling and EOF detection.

async async_recv(n: int = DEFAULT_BUFSIZE, timeout: float = None) bytes

Asynchronously receives encrypted data from the socket, decrypts and returns it.

async async_recv_more_encrypted_data(n: int = DEFAULT_BUFSIZE, timeout: Optional[float] = None) int

Asynchronously read encrypted bytes from the transport and feed them into ssl_inbio. Returns number of bytes written into ssl_inbio. Raises ConnectionResetError on EOF.

async async_send(data: bytes, timeout: float = None) int

Encrypts and asynchronously sends application data over the network.

Returns:

Total bytes sent.

Return type:

int

async async_send_pending_data(timeout: Optional[float] = None) int

Asynchronous send to flush outbio. Will loop until outbio is drained or socket stops accepting. Returns total bytes written to the transport socket (not the application bytes).

close(shutdown: bool = True, shutdown_reason: int = socket.SHUT_RDWR)
do_handshake(timeout: Optional[float] = None)

Blocking handshake loop with flush/recv handling and EOF detection.

handle_sock_close()

Decorator to handle socket close by raising ConnectionError if ssl_obj is set to None.

Notes:

  • The ssl_obj is set to None if close is called so this prevents operations on NoneType, by raising ConnectionError.

is_handshake_done() bool

Returns whether the handshake is complete.

recv(n: int = DEFAULT_BUFSIZE, timeout: float = None) bytes

Synchronously receives encrypted data from the socket, decrypts and returns it.

recv_more_encrypted_data(n: int = DEFAULT_BUFSIZE, timeout: Optional[float] = None) int

Read encrypted bytes from the transport and feed them into ssl_inbio. Returns number of bytes written into ssl_inbio. Raises ConnectionResetError on EOF.

send(data: bytes, timeout: float = None) int

Encrypts and synchronously sends application data over the network.

Returns:

Total bytes sent.

Return type:

int

send_pending_data(timeout: Optional[float] = None) int

Blocking send to flush outbio. Will loop until outbio is drained or socket stops accepting. Returns total bytes written to the transport socket (not the application bytes).

transport_readable(timeout: Optional[float]) bool

Returns True if the underlying transport has bytes available for reading. Uses select.select on the socket fileno. If timeout is None, select will block until readability (which preserves blocking behaviour when the caller intentionally passes None). If timeout is a number, it is used as the select timeout.

class duck.utils.xsocket.xsocket(raw_socket: Union[socket.socket, duck.utils.xsocket.xsocket])

Wrapper for raw sockets providing async support and transparent delegation of socket methods/attributes.

Initialization

__getattribute__(attr: str) Any

Returns attributes from the wrapper if present, else falls back to the wrapped raw_socket attributes.

Raises AttributeError if not found.

__repr__()
__setattr__(key: str, value: Any) None

Custom setattr to track attributes defined on this wrapper.

async async_connect(target=Tuple[str, int], timeout: float = None) None

Connect socket to a target.

async async_recv(n: int = DEFAULT_BUFSIZE, timeout: Optional[float] = None) bytes

Asynchronously receives data from the socket with optional timeout.

Parameters:
  • n – Maximum number of bytes to read.

  • timeout – Max seconds to wait before timing out.

Returns:

The received data.

Return type:

bytes

Raises:
  • xsocketError – If socket in blocking mode, this may block the event loop.

  • TimeoutError – If receiving takes too long.

  • OSError – If a socket error occurs.

async async_send(data: bytes, timeout: Optional[float] = None) int

Asynchronously sends data through the socket with optional timeout.

Parameters:
  • data – The data to send.

  • timeout – Max seconds to wait before timing out.

Returns:

Number of bytes sent.

Return type:

int

Raises:
  • xsocketError – If socket in blocking mode, this may block the event loop.

  • TimeoutError – If sending takes too long.

  • OSError – If a socket error occurs.

close(shutdown: bool = True, shutdown_reason: int = socket.SHUT_RDWR)

Closes the underlying socket.

Parameters:
  • sock – The underlying xsocket object.

  • shutdown – Whether to shutdown the socket using sock.shutdown.

  • shutdown_reason – Reason for shutdown.

connect(target=Tuple[str, int], timeout: float = None) None

Connect socket to a target.

property loop: asyncio.AbstractEventLoop

Returns the currently running event loop.

raise_if_blocking()

Checks whether socket is in or not in blocking mode, useful in async.

Raises:

AsyncViolationError – If socket is in blocking mode.

raise_if_in_async_context(message: str)

Checks whether we are not in async context else an error is raised.

Parameters:

message – Error message to display if in async context.

Raises:

AsyncViolationError – If we are in async context. Useful in cases a user is trying to use blocking methods like send, recv instead of async_send & async_recv.

recv(n: int = DEFAULT_BUFSIZE, timeout: float = None)

Custom recv method using recv_into with a reusable buffer and optional timeout.

Parameters:
  • n – Number of bytes to read.

  • timeout – Timeout in seconds. If None, blocking behavior depends on socket settings.

Returns:

Data received.

Return type:

bytes

Raises:

TimeoutError – If no data is received within the specified timeout.

send(data: bytes, timeout: float = None) int

Custom send method with optional timeout. This defaults to using sendall.

Parameters:
  • data – Data to send.

  • timeout – Timeout in seconds. If None, blocking behavior depends on socket settings.

Returns:

Number of bytes sent.

Return type:

int

Raises:
  • TimeoutError – If the send operation times out.

  • OSError – For other socket errors.

exception duck.utils.xsocket.xsocketError

Bases: Exception

Raised on xsocket related errors.

Initialization

Initialize self. See help(type(self)) for accurate signature.