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 # if !(defined(__BEOS__) || defined(__CYGWIN__) || (defined(PYOS_OS2) && defined(PYCC_VACPP))) 12 # include <netinet/tcp.h> 13 # endif 14 15 #else /* MS_WINDOWS */ 16 # include <winsock2.h> 17 # include <ws2tcpip.h> 18 /* VC6 is shipped with old platform headers, and does not have MSTcpIP.h 19 * Separate SDKs have all the functions we want, but older ones don't have 20 * any version information. 21 * I use SIO_GET_MULTICAST_FILTER to detect a decent SDK. 22 */ 23 # ifdef SIO_GET_MULTICAST_FILTER 24 # include <MSTcpIP.h> /* for SIO_RCVALL */ 25 # define HAVE_ADDRINFO 26 # define HAVE_SOCKADDR_STORAGE 27 # define HAVE_GETADDRINFO 28 # define HAVE_GETNAMEINFO 29 # define ENABLE_IPV6 30 # else 31 typedef int socklen_t; 32 # endif /* IPPROTO_IPV6 */ 33 #endif /* MS_WINDOWS */ 34 35 #ifdef HAVE_SYS_UN_H 36 # include <sys/un.h> 37 #else 38 # undef AF_UNIX 39 #endif 40 41 #ifdef HAVE_LINUX_NETLINK_H 42 # ifdef HAVE_ASM_TYPES_H 43 # include <asm/types.h> 44 # endif 45 # include <linux/netlink.h> 46 #else 47 # undef AF_NETLINK 48 #endif 49 50 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H 51 #include <bluetooth/bluetooth.h> 52 #include <bluetooth/rfcomm.h> 53 #include <bluetooth/l2cap.h> 54 #include <bluetooth/sco.h> 55 #include <bluetooth/hci.h> 56 #endif 57 58 #ifdef HAVE_BLUETOOTH_H 59 #include <bluetooth.h> 60 #endif 61 62 #ifdef HAVE_NETPACKET_PACKET_H 63 # include <sys/ioctl.h> 64 # include <net/if.h> 65 # include <netpacket/packet.h> 66 #endif 67 68 #ifdef HAVE_LINUX_TIPC_H 69 # include <linux/tipc.h> 70 #endif 71 72 #ifndef Py__SOCKET_H 73 #define Py__SOCKET_H 74 #ifdef __cplusplus 75 extern "C" { 76 #endif 77 78 /* Python module and C API name */ 79 #define PySocket_MODULE_NAME "_socket" 80 #define PySocket_CAPI_NAME "CAPI" 81 #define PySocket_CAPSULE_NAME (PySocket_MODULE_NAME "." PySocket_CAPI_NAME) 82 83 /* Abstract the socket file descriptor type */ 84 #ifdef MS_WINDOWS 85 typedef SOCKET SOCKET_T; 86 # ifdef MS_WIN64 87 # define SIZEOF_SOCKET_T 8 88 # else 89 # define SIZEOF_SOCKET_T 4 90 # endif 91 #else 92 typedef int SOCKET_T; 93 # define SIZEOF_SOCKET_T SIZEOF_INT 94 #endif 95 96 /* Socket address */ 97 typedef union sock_addr { 98 struct sockaddr_in in; 99 #ifdef AF_UNIX 100 struct sockaddr_un un; 101 #endif 102 #ifdef AF_NETLINK 103 struct sockaddr_nl nl; 104 #endif 105 #ifdef ENABLE_IPV6 106 struct sockaddr_in6 in6; 107 struct sockaddr_storage storage; 108 #endif 109 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H 110 struct sockaddr_l2 bt_l2; 111 struct sockaddr_rc bt_rc; 112 struct sockaddr_sco bt_sco; 113 struct sockaddr_hci bt_hci; 114 #endif 115 #ifdef HAVE_NETPACKET_PACKET_H 116 struct sockaddr_ll ll; 117 #endif 118 } sock_addr_t; 119 120 /* The object holding a socket. It holds some extra information, 121 like the address family, which is used to decode socket address 122 arguments properly. */ 123 124 typedef struct { 125 PyObject_HEAD 126 SOCKET_T sock_fd; /* Socket file descriptor */ 127 int sock_family; /* Address family, e.g., AF_INET */ 128 int sock_type; /* Socket type, e.g., SOCK_STREAM */ 129 int sock_proto; /* Protocol type, usually 0 */ 130 PyObject *(*errorhandler)(void); /* Error handler; checks 131 errno, returns NULL and 132 sets a Python exception */ 133 double sock_timeout; /* Operation timeout in seconds; 134 0.0 means non-blocking */ 135 PyObject *weakreflist; 136 } PySocketSockObject; 137 138 /* --- C API ----------------------------------------------------*/ 139 140 /* Short explanation of what this C API export mechanism does 141 and how it works: 142 143 The _ssl module needs access to the type object defined in 144 the _socket module. Since cross-DLL linking introduces a lot of 145 problems on many platforms, the "trick" is to wrap the 146 C API of a module in a struct which then gets exported to 147 other modules via a PyCapsule. 148 149 The code in socketmodule.c defines this struct (which currently 150 only contains the type object reference, but could very 151 well also include other C APIs needed by other modules) 152 and exports it as PyCapsule via the module dictionary 153 under the name "CAPI". 154 155 Other modules can now include the socketmodule.h file 156 which defines the needed C APIs to import and set up 157 a static copy of this struct in the importing module. 158 159 After initialization, the importing module can then 160 access the C APIs from the _socket module by simply 161 referring to the static struct, e.g. 162 163 Load _socket module and its C API; this sets up the global 164 PySocketModule: 165 166 if (PySocketModule_ImportModuleAndAPI()) 167 return; 168 169 170 Now use the C API as if it were defined in the using 171 module: 172 173 if (!PyArg_ParseTuple(args, "O!|zz:ssl", 174 175 PySocketModule.Sock_Type, 176 177 (PyObject*)&Sock, 178 &key_file, &cert_file)) 179 return NULL; 180 181 Support could easily be extended to export more C APIs/symbols 182 this way. Currently, only the type object is exported, 183 other candidates would be socket constructors and socket 184 access functions. 185 186 */ 187 188 /* C API for usage by other Python modules */ 189 typedef struct { 190 PyTypeObject *Sock_Type; 191 PyObject *error; 192 } PySocketModule_APIObject; 193 194 /* XXX The net effect of the following appears to be to define a function 195 XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't 196 XXX defined there directly. 197 198 >>> It's defined here because other modules might also want to use 199 >>> the C API. 200 201 */ 202 #ifndef PySocket_BUILDING_SOCKET 203 204 /* --- C API ----------------------------------------------------*/ 205 206 /* Interfacestructure to C API for other modules. 207 Call PySocketModule_ImportModuleAndAPI() to initialize this 208 structure. After that usage is simple: 209 210 if (!PyArg_ParseTuple(args, "O!|zz:ssl", 211 &PySocketModule.Sock_Type, (PyObject*)&Sock, 212 &key_file, &cert_file)) 213 return NULL; 214 ... 215 */ 216 217 static 218 PySocketModule_APIObject PySocketModule; 219 220 /* You *must* call this before using any of the functions in 221 PySocketModule and check its outcome; otherwise all accesses will 222 result in a segfault. Returns 0 on success. */ 223 224 #ifndef DPRINTF 225 # define DPRINTF if (0) printf 226 #endif 227 228 static 229 int PySocketModule_ImportModuleAndAPI(void) 230 { 231 void *api; 232 233 DPRINTF(" Loading capsule %s\n", PySocket_CAPSULE_NAME); 234 api = PyCapsule_Import(PySocket_CAPSULE_NAME, 1); 235 if (api == NULL) 236 goto onError; 237 memcpy(&PySocketModule, api, sizeof(PySocketModule)); 238 DPRINTF(" API object loaded and initialized.\n"); 239 return 0; 240 241 onError: 242 DPRINTF(" not found.\n"); 243 return -1; 244 } 245 246 #endif /* !PySocket_BUILDING_SOCKET */ 247 248 #ifdef __cplusplus 249 } 250 #endif 251 #endif /* !Py__SOCKET_H */ 252