Skip to content

socket.connect - support custom family value #92658

Closed
@jborean93

Description

@jborean93

Feature or enhancement

Currently socket.connect() accepts a wide range of values when connecting to a socket with the code in socketmodule.c transforming it based on the family the socket was created with. Unfortunately there is a check that fails the connection if the family is unrecognized

cpython/Modules/socketmodule.c

Lines 2530 to 2534 in 9d85aba

default:
PyErr_SetString(PyExc_OSError, "getsockaddrlen: bad family");
return 0;
}
.

My proposal is to allow a caller to bypass this check if passing in a raw byte value to be used as the addr info on the native call.

Pitch

The reason why I am hoping for this feature is to support clients connecting to a Hyper-V socket. This uses the AF_HYPERV family which isn't known to Python so any attempts to connect to it won't work.

Currently I am using the following to work around this restriction by using ctypes to call the C API directly and using the fileno:

import ctypes import socket import uuid HV_GUID_VM_SESSION_SERVICE_ID = uuid.UUID("999e53d4-3d5c-4c3e-8779-bed06ec056e1") HV_GUID_VM_SESSION_SERVICE_ID_2 = uuid.UUID("a5201c21-2770-4c11-a68e-f182edb29220") AF_HYPERV = 34 HV_PROTOCOL_RAW = 1 # This is the GUID of the Win VM to connect to vm_id = uuid.UUID("...") win32sock = ctypes.WinDLL("Ws2_32.dll") raw_sock = win32sock.socket(AF_HYPERV, socket.SOCK_STREAM, HV_PROTOCOL_RAW) if raw_sock == -1: err = win32sock.WSAGetLastError() raise ctypes.WinError(code=err) try: sock_addr = b"\x22\x00\x00\x00" + vm_id.bytes_le + HV_GUID_VM_SESSION_SERVICE_ID.bytes_le res = win32sock.connect(raw_sock, sock_addr, len(sock_addr)) if res: err = win32sock.WSAGetLastError() raise ctypes.WinError(code=err) sock = socket.socket(fileno=raw_sock) except: win32sock.closesocket(raw_sock) raise ... sock.close()

It would be good to be able to do this instead

import socket sock = socket.socket(AF_HYPERV, socket.SOCK_STREAM, HV_PROTOCOL_RAW) sock_addr = b"\x22\x00\x00\x00" + vm_id.bytes_le + HV_GUID_VM_SESSION_SERVICE_ID.bytes_le sock.connect(sock_addr) ... sock.close()

Currently that fails due to the hardcoded check against unknown families

Traceback (most recent call last): File "<stdin>", line 1, in <module> OSError: connect(): bad family

Another option is to add support for AF_HYPERV on Windows and support a tuple of (vm_id, service_id) and have Python create the struct. This could be done as a separate feature request potentially.

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirtype-featureA feature request or enhancement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions