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