(root)/
Python-3.11.7/
Modules/
socketmodule.h
       1  /* Socket module header file */
       2  
       3  /* Includes needed for the sockaddr_* symbols below */
       4  #ifndef MS_WINDOWS
       5  #ifdef __VMS
       6  #   include <socket.h>
       7  # else
       8  #   include <sys/socket.h>
       9  # endif
      10  # include <netinet/in.h>
      11  # include <netinet/tcp.h>
      12  
      13  #else /* MS_WINDOWS */
      14  # include <winsock2.h>
      15  
      16  /*
      17   * If Windows has bluetooth support, include bluetooth constants.
      18   */
      19  #ifdef AF_BTH
      20  # include <ws2bth.h>
      21  # include <pshpack1.h>
      22  
      23  /*
      24   * The current implementation assumes the bdaddr in the sockaddr structs
      25   * will be a bdaddr_t. We treat this as an opaque type: on *nix systems, it
      26   * will be a struct with a single member (an array of six bytes). On windows,
      27   * we typedef this to ULONGLONG to match the Windows definition.
      28   */
      29  typedef ULONGLONG bdaddr_t;
      30  
      31  /*
      32   * Redefine SOCKADDR_BTH to provide names compatible with _BT_RC_MEMB() macros.
      33   */
      34  struct SOCKADDR_BTH_REDEF {
      35      union {
      36          USHORT    addressFamily;
      37          USHORT    family;
      38      };
      39  
      40      union {
      41          ULONGLONG btAddr;
      42          bdaddr_t  bdaddr;
      43      };
      44  
      45      GUID      serviceClassId;
      46  
      47      union {
      48          ULONG     port;
      49          ULONG     channel;
      50      };
      51  
      52  };
      53  # include <poppack.h>
      54  #endif
      55  
      56  /* Windows 'supports' CMSG_LEN, but does not follow the POSIX standard
      57   * interface at all, so there is no point including the code that
      58   * attempts to use it.
      59   */
      60  # ifdef PySocket_BUILDING_SOCKET
      61  #  undef CMSG_LEN
      62  # endif
      63  # include <ws2tcpip.h>
      64  /* VC6 is shipped with old platform headers, and does not have MSTcpIP.h
      65   * Separate SDKs have all the functions we want, but older ones don't have
      66   * any version information.
      67   * I use SIO_GET_MULTICAST_FILTER to detect a decent SDK.
      68   */
      69  # ifdef SIO_GET_MULTICAST_FILTER
      70  #  include <mstcpip.h> /* for SIO_RCVALL */
      71  #  define HAVE_ADDRINFO
      72  #  define HAVE_SOCKADDR_STORAGE
      73  #  define HAVE_GETADDRINFO
      74  #  define HAVE_GETNAMEINFO
      75  #  define ENABLE_IPV6
      76  # else
      77  typedef int socklen_t;
      78  # endif /* IPPROTO_IPV6 */
      79  #endif /* MS_WINDOWS */
      80  
      81  #ifdef HAVE_SYS_UN_H
      82  # include <sys/un.h>
      83  #else
      84  # undef AF_UNIX
      85  #endif
      86  
      87  #ifdef HAVE_LINUX_NETLINK_H
      88  # ifdef HAVE_ASM_TYPES_H
      89  #  include <asm/types.h>
      90  # endif
      91  # include <linux/netlink.h>
      92  #else
      93  #  undef AF_NETLINK
      94  #endif
      95  
      96  #ifdef HAVE_LINUX_QRTR_H
      97  # ifdef HAVE_ASM_TYPES_H
      98  #  include <asm/types.h>
      99  # endif
     100  # include <linux/qrtr.h>
     101  #else
     102  #  undef AF_QIPCRTR
     103  #endif
     104  
     105  #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
     106  #include <bluetooth/bluetooth.h>
     107  #include <bluetooth/rfcomm.h>
     108  #include <bluetooth/l2cap.h>
     109  #include <bluetooth/sco.h>
     110  #include <bluetooth/hci.h>
     111  #endif
     112  
     113  #ifdef HAVE_BLUETOOTH_H
     114  #include <bluetooth.h>
     115  #endif
     116  
     117  #ifdef HAVE_NET_IF_H
     118  # include <net/if.h>
     119  #endif
     120  
     121  #ifdef HAVE_NETPACKET_PACKET_H
     122  # include <sys/ioctl.h>
     123  # include <netpacket/packet.h>
     124  #endif
     125  
     126  #ifdef HAVE_LINUX_TIPC_H
     127  # include <linux/tipc.h>
     128  #endif
     129  
     130  #ifdef HAVE_LINUX_CAN_H
     131  # include <linux/can.h>
     132  #elif defined(HAVE_NETCAN_CAN_H)
     133  # include <netcan/can.h>
     134  #else
     135  # undef AF_CAN
     136  # undef PF_CAN
     137  #endif
     138  
     139  #ifdef HAVE_LINUX_CAN_RAW_H
     140  #include <linux/can/raw.h>
     141  #endif
     142  
     143  #ifdef HAVE_LINUX_CAN_BCM_H
     144  #include <linux/can/bcm.h>
     145  #endif
     146  
     147  #ifdef HAVE_LINUX_CAN_J1939_H
     148  #include <linux/can/j1939.h>
     149  #endif
     150  
     151  #ifdef HAVE_SYS_SYS_DOMAIN_H
     152  #include <sys/sys_domain.h>
     153  #endif
     154  #ifdef HAVE_SYS_KERN_CONTROL_H
     155  #include <sys/kern_control.h>
     156  #endif
     157  
     158  #ifdef HAVE_LINUX_VM_SOCKETS_H
     159  # include <linux/vm_sockets.h>
     160  #else
     161  # undef AF_VSOCK
     162  #endif
     163  
     164  #ifdef HAVE_SOCKADDR_ALG
     165  
     166  # include <linux/if_alg.h>
     167  # ifndef AF_ALG
     168  #  define AF_ALG 38
     169  # endif
     170  # ifndef SOL_ALG
     171  #  define SOL_ALG 279
     172  # endif
     173  
     174  /* Linux 3.19 */
     175  # ifndef ALG_SET_AEAD_ASSOCLEN
     176  #  define ALG_SET_AEAD_ASSOCLEN           4
     177  # endif
     178  # ifndef ALG_SET_AEAD_AUTHSIZE
     179  #  define ALG_SET_AEAD_AUTHSIZE           5
     180  # endif
     181  /* Linux 4.8 */
     182  # ifndef ALG_SET_PUBKEY
     183  #  define ALG_SET_PUBKEY                  6
     184  # endif
     185  
     186  # ifndef ALG_OP_SIGN
     187  #  define ALG_OP_SIGN                     2
     188  # endif
     189  # ifndef ALG_OP_VERIFY
     190  #  define ALG_OP_VERIFY                   3
     191  # endif
     192  
     193  #endif /* HAVE_SOCKADDR_ALG */
     194  
     195  #ifdef __EMSCRIPTEN__
     196  // wasm32-emscripten sockets only support subset of IPv4 and IPv6.
     197  // SCTP protocol crashes runtime.
     198  #ifdef IPPROTO_SCTP
     199  #  undef IPPROTO_SCTP
     200  #endif
     201  // setsockopt() fails with ENOPROTOOPT, getsockopt only supports SO_ERROR.
     202  // undef SO_REUSEADDR and SO_REUSEPORT so they cannot be used.
     203  #ifdef SO_REUSEADDR
     204  #  undef SO_REUSEADDR
     205  #endif
     206  #ifdef SO_REUSEPORT
     207  #  undef SO_REUSEPORT
     208  #endif
     209  #endif // __EMSCRIPTEN__
     210  
     211  #ifndef Py__SOCKET_H
     212  #define Py__SOCKET_H
     213  #ifdef __cplusplus
     214  extern "C" {
     215  #endif
     216  
     217  /* Python module and C API name */
     218  #define PySocket_MODULE_NAME    "_socket"
     219  #define PySocket_CAPI_NAME      "CAPI"
     220  #define PySocket_CAPSULE_NAME   PySocket_MODULE_NAME "." PySocket_CAPI_NAME
     221  
     222  /* Abstract the socket file descriptor type */
     223  #ifdef MS_WINDOWS
     224  typedef SOCKET SOCKET_T;
     225  #       ifdef MS_WIN64
     226  #               define SIZEOF_SOCKET_T 8
     227  #       else
     228  #               define SIZEOF_SOCKET_T 4
     229  #       endif
     230  #else
     231  typedef int SOCKET_T;
     232  #       define SIZEOF_SOCKET_T SIZEOF_INT
     233  #endif
     234  
     235  #if SIZEOF_SOCKET_T <= SIZEOF_LONG
     236  #define PyLong_FromSocket_t(fd) PyLong_FromLong((SOCKET_T)(fd))
     237  #define PyLong_AsSocket_t(fd) (SOCKET_T)PyLong_AsLong(fd)
     238  #else
     239  #define PyLong_FromSocket_t(fd) PyLong_FromLongLong((SOCKET_T)(fd))
     240  #define PyLong_AsSocket_t(fd) (SOCKET_T)PyLong_AsLongLong(fd)
     241  #endif
     242  
     243  /* Socket address */
     244  typedef union sock_addr {
     245      struct sockaddr_in in;
     246      struct sockaddr sa;
     247  #ifdef AF_UNIX
     248      struct sockaddr_un un;
     249  #endif
     250  #ifdef AF_NETLINK
     251      struct sockaddr_nl nl;
     252  #endif
     253  #ifdef ENABLE_IPV6
     254      struct sockaddr_in6 in6;
     255      struct sockaddr_storage storage;
     256  #endif
     257  #if defined(HAVE_BLUETOOTH_H) && defined(__FreeBSD__)
     258      struct sockaddr_l2cap bt_l2;
     259      struct sockaddr_rfcomm bt_rc;
     260      struct sockaddr_sco bt_sco;
     261      struct sockaddr_hci bt_hci;
     262  #elif defined(HAVE_BLUETOOTH_BLUETOOTH_H)
     263      struct sockaddr_l2 bt_l2;
     264      struct sockaddr_rc bt_rc;
     265      struct sockaddr_sco bt_sco;
     266      struct sockaddr_hci bt_hci;
     267  #elif defined(MS_WINDOWS)
     268      struct SOCKADDR_BTH_REDEF bt_rc;
     269  #endif
     270  #ifdef HAVE_NETPACKET_PACKET_H
     271      struct sockaddr_ll ll;
     272  #endif
     273  #if defined(HAVE_LINUX_CAN_H) || defined(HAVE_NETCAN_CAN_H)
     274      struct sockaddr_can can;
     275  #endif
     276  #ifdef HAVE_SYS_KERN_CONTROL_H
     277      struct sockaddr_ctl ctl;
     278  #endif
     279  #ifdef HAVE_SOCKADDR_ALG
     280      struct sockaddr_alg alg;
     281  #endif
     282  #ifdef AF_QIPCRTR
     283      struct sockaddr_qrtr sq;
     284  #endif
     285  #ifdef AF_VSOCK
     286      struct sockaddr_vm vm;
     287  #endif
     288  #ifdef HAVE_LINUX_TIPC_H
     289      struct sockaddr_tipc tipc;
     290  #endif
     291  } sock_addr_t;
     292  
     293  /* The object holding a socket.  It holds some extra information,
     294     like the address family, which is used to decode socket address
     295     arguments properly. */
     296  
     297  typedef struct {
     298      PyObject_HEAD
     299      SOCKET_T sock_fd;           /* Socket file descriptor */
     300      int sock_family;            /* Address family, e.g., AF_INET */
     301      int sock_type;              /* Socket type, e.g., SOCK_STREAM */
     302      int sock_proto;             /* Protocol type, usually 0 */
     303      PyObject *(*errorhandler)(void); /* Error handler; checks
     304                                          errno, returns NULL and
     305                                          sets a Python exception */
     306      _PyTime_t sock_timeout;     /* Operation timeout in seconds;
     307                                          0.0 means non-blocking */
     308  } PySocketSockObject;
     309  
     310  /* --- C API ----------------------------------------------------*/
     311  
     312  /* Short explanation of what this C API export mechanism does
     313     and how it works:
     314  
     315      The _ssl module needs access to the type object defined in
     316      the _socket module. Since cross-DLL linking introduces a lot of
     317      problems on many platforms, the "trick" is to wrap the
     318      C API of a module in a struct which then gets exported to
     319      other modules via a PyCapsule.
     320  
     321      The code in socketmodule.c defines this struct (which currently
     322      only contains the type object reference, but could very
     323      well also include other C APIs needed by other modules)
     324      and exports it as PyCapsule via the module dictionary
     325      under the name "CAPI".
     326  
     327      Other modules can now include the socketmodule.h file
     328      which defines the needed C APIs to import and set up
     329      a static copy of this struct in the importing module.
     330  
     331      After initialization, the importing module can then
     332      access the C APIs from the _socket module by simply
     333      referring to the static struct, e.g.
     334  
     335      Load _socket module and its C API; this sets up the global
     336      PySocketModule:
     337  
     338      if (PySocketModule_ImportModuleAndAPI())
     339          return;
     340  
     341  
     342      Now use the C API as if it were defined in the using
     343      module:
     344  
     345      if (!PyArg_ParseTuple(args, "O!|zz:ssl",
     346  
     347                            PySocketModule.Sock_Type,
     348  
     349                            (PyObject*)&Sock,
     350                            &key_file, &cert_file))
     351          return NULL;
     352  
     353      Support could easily be extended to export more C APIs/symbols
     354      this way. Currently, only the type object is exported,
     355      other candidates would be socket constructors and socket
     356      access functions.
     357  
     358  */
     359  
     360  /* C API for usage by other Python modules.
     361   * Always add new things to the end for binary compatibility. */
     362  typedef struct {
     363      PyTypeObject *Sock_Type;
     364      PyObject *error;
     365      PyObject *timeout_error;
     366  } PySocketModule_APIObject;
     367  
     368  #define PySocketModule_ImportModuleAndAPI() PyCapsule_Import(PySocket_CAPSULE_NAME, 1)
     369  
     370  #ifdef __cplusplus
     371  }
     372  #endif
     373  #endif /* !Py__SOCKET_H */