Description
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
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.