From d96fa07134c06472bfee6718b5cfd1679196fc99 Mon Sep 17 00:00:00 2001 From: thegeorg Date: Mon, 19 Feb 2024 02:38:52 +0300 Subject: Sync contrib/tools/python3 layout with upstream * Move src/ subdir contents to the top of the layout * Rename self-written lib -> lib2 to avoid CaseFolding warning from the VCS * Regenerate contrib/libs/python proxy-headers accordingly 4ccc62ac1511abcf0fed14ccade38e984e088f1e --- contrib/tools/python3/Modules/socketmodule.h | 391 +++++++++++++++++++++++++++ 1 file changed, 391 insertions(+) create mode 100644 contrib/tools/python3/Modules/socketmodule.h (limited to 'contrib/tools/python3/Modules/socketmodule.h') diff --git a/contrib/tools/python3/Modules/socketmodule.h b/contrib/tools/python3/Modules/socketmodule.h new file mode 100644 index 00000000000..d55c02fd156 --- /dev/null +++ b/contrib/tools/python3/Modules/socketmodule.h @@ -0,0 +1,391 @@ +/* Socket module header file */ + +/* Includes needed for the sockaddr_* symbols below */ +#ifndef MS_WINDOWS +#ifdef __VMS +# include +# else +# include +# endif +# include +# include + +#else /* MS_WINDOWS */ +# include + +/* + * If Windows has bluetooth support, include bluetooth constants. + */ +#ifdef AF_BTH +# include +# include + +/* + * The current implementation assumes the bdaddr in the sockaddr structs + * will be a bdaddr_t. We treat this as an opaque type: on *nix systems, it + * will be a struct with a single member (an array of six bytes). On windows, + * we typedef this to ULONGLONG to match the Windows definition. + */ +typedef ULONGLONG bdaddr_t; + +/* + * Redefine SOCKADDR_BTH to provide names compatible with _BT_RC_MEMB() macros. + */ +struct SOCKADDR_BTH_REDEF { + union { + USHORT addressFamily; + USHORT family; + }; + + union { + ULONGLONG btAddr; + bdaddr_t bdaddr; + }; + + GUID serviceClassId; + + union { + ULONG port; + ULONG channel; + }; + +}; +# include +#endif + +/* Windows 'supports' CMSG_LEN, but does not follow the POSIX standard + * interface at all, so there is no point including the code that + * attempts to use it. + */ +# ifdef PySocket_BUILDING_SOCKET +# undef CMSG_LEN +# endif +# include +/* VC6 is shipped with old platform headers, and does not have MSTcpIP.h + * Separate SDKs have all the functions we want, but older ones don't have + * any version information. + * I use SIO_GET_MULTICAST_FILTER to detect a decent SDK. + */ +# ifdef SIO_GET_MULTICAST_FILTER +# include /* for SIO_RCVALL */ +# define HAVE_ADDRINFO +# define HAVE_SOCKADDR_STORAGE +# define HAVE_GETADDRINFO +# define HAVE_GETNAMEINFO +# define ENABLE_IPV6 +# else +typedef int socklen_t; +# endif /* IPPROTO_IPV6 */ + +/* Remove ifdef once Py_WINVER >= 0x0604 + * socket.h only defines AF_HYPERV if _WIN32_WINNT is at that level or higher + * so for now it's just manually defined. + */ +# ifndef AF_HYPERV +# define AF_HYPERV 34 +# endif +# include +#endif /* MS_WINDOWS */ + +#ifdef HAVE_SYS_UN_H +# include +#else +# undef AF_UNIX +#endif + +#ifdef HAVE_LINUX_NETLINK_H +# ifdef HAVE_ASM_TYPES_H +# include +# endif +# include +#else +# undef AF_NETLINK +#endif + +#ifdef HAVE_LINUX_QRTR_H +# ifdef HAVE_ASM_TYPES_H +# include +# endif +# include +#else +# undef AF_QIPCRTR +#endif + +#ifdef HAVE_BLUETOOTH_BLUETOOTH_H +#error #include +#error #include +#error #include +#error #include +#error #include +#endif + +#ifdef HAVE_BLUETOOTH_H +#error #include +#endif + +#ifdef HAVE_NET_IF_H +# include +#endif + +#ifdef HAVE_NETPACKET_PACKET_H +# include +# include +#endif + +#ifdef HAVE_LINUX_TIPC_H +# include +#endif + +#ifdef HAVE_LINUX_CAN_H +# include +#elif defined(HAVE_NETCAN_CAN_H) +# error #include +#else +# undef AF_CAN +# undef PF_CAN +#endif + +#ifdef HAVE_LINUX_CAN_RAW_H +#include +#endif + +#ifdef HAVE_LINUX_CAN_BCM_H +#include +#endif + +#ifdef HAVE_LINUX_CAN_J1939_H +#include +#endif + +#ifdef HAVE_SYS_SYS_DOMAIN_H +#include +#endif +#ifdef HAVE_SYS_KERN_CONTROL_H +#include +#endif + +#ifdef HAVE_LINUX_VM_SOCKETS_H +# include +#else +# undef AF_VSOCK +#endif + +#ifdef HAVE_SOCKADDR_ALG + +# include +# ifndef AF_ALG +# define AF_ALG 38 +# endif +# ifndef SOL_ALG +# define SOL_ALG 279 +# endif + +/* Linux 3.19 */ +# ifndef ALG_SET_AEAD_ASSOCLEN +# define ALG_SET_AEAD_ASSOCLEN 4 +# endif +# ifndef ALG_SET_AEAD_AUTHSIZE +# define ALG_SET_AEAD_AUTHSIZE 5 +# endif +/* Linux 4.8 */ +# ifndef ALG_SET_PUBKEY +# define ALG_SET_PUBKEY 6 +# endif + +# ifndef ALG_OP_SIGN +# define ALG_OP_SIGN 2 +# endif +# ifndef ALG_OP_VERIFY +# define ALG_OP_VERIFY 3 +# endif + +#endif /* HAVE_SOCKADDR_ALG */ + +#ifdef __EMSCRIPTEN__ +// wasm32-emscripten sockets only support subset of IPv4 and IPv6. +// SCTP protocol crashes runtime. +#ifdef IPPROTO_SCTP +# undef IPPROTO_SCTP +#endif +// setsockopt() fails with ENOPROTOOPT, getsockopt only supports SO_ERROR. +// undef SO_REUSEADDR and SO_REUSEPORT so they cannot be used. +#ifdef SO_REUSEADDR +# undef SO_REUSEADDR +#endif +#ifdef SO_REUSEPORT +# undef SO_REUSEPORT +#endif +#endif // __EMSCRIPTEN__ + +#ifndef Py__SOCKET_H +#define Py__SOCKET_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Python module and C API name */ +#define PySocket_MODULE_NAME "_socket" +#define PySocket_CAPI_NAME "CAPI" +#define PySocket_CAPSULE_NAME PySocket_MODULE_NAME "." PySocket_CAPI_NAME + +/* Abstract the socket file descriptor type */ +#ifdef MS_WINDOWS +typedef SOCKET SOCKET_T; +# ifdef MS_WIN64 +# define SIZEOF_SOCKET_T 8 +# else +# define SIZEOF_SOCKET_T 4 +# endif +#else +typedef int SOCKET_T; +# define SIZEOF_SOCKET_T SIZEOF_INT +#endif + +#if SIZEOF_SOCKET_T <= SIZEOF_LONG +#define PyLong_FromSocket_t(fd) PyLong_FromLong((SOCKET_T)(fd)) +#define PyLong_AsSocket_t(fd) (SOCKET_T)PyLong_AsLong(fd) +#else +#define PyLong_FromSocket_t(fd) PyLong_FromLongLong((SOCKET_T)(fd)) +#define PyLong_AsSocket_t(fd) (SOCKET_T)PyLong_AsLongLong(fd) +#endif + +// AF_HYPERV is only supported on Windows +#if defined(AF_HYPERV) && defined(MS_WINDOWS) +# define HAVE_AF_HYPERV +#endif + +/* Socket address */ +typedef union sock_addr { + struct sockaddr_in in; + struct sockaddr sa; +#ifdef AF_UNIX + struct sockaddr_un un; +#endif +#ifdef AF_NETLINK + struct sockaddr_nl nl; +#endif +#ifdef ENABLE_IPV6 + struct sockaddr_in6 in6; + struct sockaddr_storage storage; +#endif +#if defined(HAVE_BLUETOOTH_H) && defined(__FreeBSD__) + struct sockaddr_l2cap bt_l2; + struct sockaddr_rfcomm bt_rc; + struct sockaddr_sco bt_sco; + struct sockaddr_hci bt_hci; +#elif defined(HAVE_BLUETOOTH_BLUETOOTH_H) + struct sockaddr_l2 bt_l2; + struct sockaddr_rc bt_rc; + struct sockaddr_sco bt_sco; + struct sockaddr_hci bt_hci; +#elif defined(MS_WINDOWS) + struct SOCKADDR_BTH_REDEF bt_rc; +#endif +#ifdef HAVE_NETPACKET_PACKET_H + struct sockaddr_ll ll; +#endif +#if defined(HAVE_LINUX_CAN_H) || defined(HAVE_NETCAN_CAN_H) + struct sockaddr_can can; +#endif +#ifdef HAVE_SYS_KERN_CONTROL_H + struct sockaddr_ctl ctl; +#endif +#ifdef HAVE_SOCKADDR_ALG + struct sockaddr_alg alg; +#endif +#ifdef AF_QIPCRTR + struct sockaddr_qrtr sq; +#endif +#ifdef AF_VSOCK + struct sockaddr_vm vm; +#endif +#ifdef HAVE_LINUX_TIPC_H + struct sockaddr_tipc tipc; +#endif +#ifdef HAVE_AF_HYPERV + SOCKADDR_HV hv; +#endif +} sock_addr_t; + +/* The object holding a socket. It holds some extra information, + like the address family, which is used to decode socket address + arguments properly. */ + +typedef struct { + PyObject_HEAD + SOCKET_T sock_fd; /* Socket file descriptor */ + int sock_family; /* Address family, e.g., AF_INET */ + int sock_type; /* Socket type, e.g., SOCK_STREAM */ + int sock_proto; /* Protocol type, usually 0 */ + PyObject *(*errorhandler)(void); /* Error handler; checks + errno, returns NULL and + sets a Python exception */ + _PyTime_t sock_timeout; /* Operation timeout in seconds; + 0.0 means non-blocking */ + struct _socket_state *state; +} PySocketSockObject; + +/* --- C API ----------------------------------------------------*/ + +/* Short explanation of what this C API export mechanism does + and how it works: + + The _ssl module needs access to the type object defined in + the _socket module. Since cross-DLL linking introduces a lot of + problems on many platforms, the "trick" is to wrap the + C API of a module in a struct which then gets exported to + other modules via a PyCapsule. + + The code in socketmodule.c defines this struct (which currently + only contains the type object reference, but could very + well also include other C APIs needed by other modules) + and exports it as PyCapsule via the module dictionary + under the name "CAPI". + + Other modules can now include the socketmodule.h file + which defines the needed C APIs to import and set up + a static copy of this struct in the importing module. + + After initialization, the importing module can then + access the C APIs from the _socket module by simply + referring to the static struct, e.g. + + Load _socket module and its C API; this sets up the global + PySocketModule: + + if (PySocketModule_ImportModuleAndAPI()) + return; + + + Now use the C API as if it were defined in the using + module: + + if (!PyArg_ParseTuple(args, "O!|zz:ssl", + + PySocketModule.Sock_Type, + + (PyObject*)&Sock, + &key_file, &cert_file)) + return NULL; + + Support could easily be extended to export more C APIs/symbols + this way. Currently, only the type object is exported, + other candidates would be socket constructors and socket + access functions. + +*/ + +/* C API for usage by other Python modules. + * Always add new things to the end for binary compatibility. */ +typedef struct { + PyTypeObject *Sock_Type; + PyObject *error; + PyObject *timeout_error; +} PySocketModule_APIObject; + +#define PySocketModule_ImportModuleAndAPI() PyCapsule_Import(PySocket_CAPSULE_NAME, 1) + +#ifdef __cplusplus +} +#endif +#endif /* !Py__SOCKET_H */ -- cgit v1.3