|
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 |
|
82 /* Abstract the socket file descriptor type */ |
|
83 #ifdef MS_WINDOWS |
|
84 typedef SOCKET SOCKET_T; |
|
85 # ifdef MS_WIN64 |
|
86 # define SIZEOF_SOCKET_T 8 |
|
87 # else |
|
88 # define SIZEOF_SOCKET_T 4 |
|
89 # endif |
|
90 #else |
|
91 typedef int SOCKET_T; |
|
92 # define SIZEOF_SOCKET_T SIZEOF_INT |
|
93 #endif |
|
94 |
|
95 /* Socket address */ |
|
96 typedef union sock_addr { |
|
97 struct sockaddr_in in; |
|
98 #ifdef AF_UNIX |
|
99 struct sockaddr_un un; |
|
100 #endif |
|
101 #ifdef AF_NETLINK |
|
102 struct sockaddr_nl nl; |
|
103 #endif |
|
104 #ifdef ENABLE_IPV6 |
|
105 struct sockaddr_in6 in6; |
|
106 struct sockaddr_storage storage; |
|
107 #endif |
|
108 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H |
|
109 struct sockaddr_l2 bt_l2; |
|
110 struct sockaddr_rc bt_rc; |
|
111 struct sockaddr_sco bt_sco; |
|
112 struct sockaddr_hci bt_hci; |
|
113 #endif |
|
114 #ifdef HAVE_NETPACKET_PACKET_H |
|
115 struct sockaddr_ll ll; |
|
116 #endif |
|
117 } sock_addr_t; |
|
118 |
|
119 /* The object holding a socket. It holds some extra information, |
|
120 like the address family, which is used to decode socket address |
|
121 arguments properly. */ |
|
122 |
|
123 typedef struct { |
|
124 PyObject_HEAD |
|
125 SOCKET_T sock_fd; /* Socket file descriptor */ |
|
126 int sock_family; /* Address family, e.g., AF_INET */ |
|
127 int sock_type; /* Socket type, e.g., SOCK_STREAM */ |
|
128 int sock_proto; /* Protocol type, usually 0 */ |
|
129 PyObject *(*errorhandler)(void); /* Error handler; checks |
|
130 errno, returns NULL and |
|
131 sets a Python exception */ |
|
132 double sock_timeout; /* Operation timeout in seconds; |
|
133 0.0 means non-blocking */ |
|
134 } PySocketSockObject; |
|
135 |
|
136 /* --- C API ----------------------------------------------------*/ |
|
137 |
|
138 /* Short explanation of what this C API export mechanism does |
|
139 and how it works: |
|
140 |
|
141 The _ssl module needs access to the type object defined in |
|
142 the _socket module. Since cross-DLL linking introduces a lot of |
|
143 problems on many platforms, the "trick" is to wrap the |
|
144 C API of a module in a struct which then gets exported to |
|
145 other modules via a PyCObject. |
|
146 |
|
147 The code in socketmodule.c defines this struct (which currently |
|
148 only contains the type object reference, but could very |
|
149 well also include other C APIs needed by other modules) |
|
150 and exports it as PyCObject via the module dictionary |
|
151 under the name "CAPI". |
|
152 |
|
153 Other modules can now include the socketmodule.h file |
|
154 which defines the needed C APIs to import and set up |
|
155 a static copy of this struct in the importing module. |
|
156 |
|
157 After initialization, the importing module can then |
|
158 access the C APIs from the _socket module by simply |
|
159 referring to the static struct, e.g. |
|
160 |
|
161 Load _socket module and its C API; this sets up the global |
|
162 PySocketModule: |
|
163 |
|
164 if (PySocketModule_ImportModuleAndAPI()) |
|
165 return; |
|
166 |
|
167 |
|
168 Now use the C API as if it were defined in the using |
|
169 module: |
|
170 |
|
171 if (!PyArg_ParseTuple(args, "O!|zz:ssl", |
|
172 |
|
173 PySocketModule.Sock_Type, |
|
174 |
|
175 (PyObject*)&Sock, |
|
176 &key_file, &cert_file)) |
|
177 return NULL; |
|
178 |
|
179 Support could easily be extended to export more C APIs/symbols |
|
180 this way. Currently, only the type object is exported, |
|
181 other candidates would be socket constructors and socket |
|
182 access functions. |
|
183 |
|
184 */ |
|
185 |
|
186 /* C API for usage by other Python modules */ |
|
187 typedef struct { |
|
188 PyTypeObject *Sock_Type; |
|
189 PyObject *error; |
|
190 } PySocketModule_APIObject; |
|
191 |
|
192 /* XXX The net effect of the following appears to be to define a function |
|
193 XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't |
|
194 XXX defined there directly. |
|
195 |
|
196 >>> It's defined here because other modules might also want to use |
|
197 >>> the C API. |
|
198 |
|
199 */ |
|
200 #ifndef PySocket_BUILDING_SOCKET |
|
201 |
|
202 /* --- C API ----------------------------------------------------*/ |
|
203 |
|
204 /* Interfacestructure to C API for other modules. |
|
205 Call PySocketModule_ImportModuleAndAPI() to initialize this |
|
206 structure. After that usage is simple: |
|
207 |
|
208 if (!PyArg_ParseTuple(args, "O!|zz:ssl", |
|
209 &PySocketModule.Sock_Type, (PyObject*)&Sock, |
|
210 &key_file, &cert_file)) |
|
211 return NULL; |
|
212 ... |
|
213 */ |
|
214 |
|
215 static |
|
216 PySocketModule_APIObject PySocketModule; |
|
217 |
|
218 /* You *must* call this before using any of the functions in |
|
219 PySocketModule and check its outcome; otherwise all accesses will |
|
220 result in a segfault. Returns 0 on success. */ |
|
221 |
|
222 #ifndef DPRINTF |
|
223 # define DPRINTF if (0) printf |
|
224 #endif |
|
225 |
|
226 static |
|
227 int PySocketModule_ImportModuleAndAPI(void) |
|
228 { |
|
229 PyObject *mod = 0, *v = 0; |
|
230 char *apimodule = PySocket_MODULE_NAME; |
|
231 char *apiname = PySocket_CAPI_NAME; |
|
232 void *api; |
|
233 |
|
234 DPRINTF("Importing the %s C API...\n", apimodule); |
|
235 mod = PyImport_ImportModuleNoBlock(apimodule); |
|
236 if (mod == NULL) |
|
237 goto onError; |
|
238 DPRINTF(" %s package found\n", apimodule); |
|
239 v = PyObject_GetAttrString(mod, apiname); |
|
240 if (v == NULL) |
|
241 goto onError; |
|
242 Py_DECREF(mod); |
|
243 DPRINTF(" API object %s found\n", apiname); |
|
244 api = PyCObject_AsVoidPtr(v); |
|
245 if (api == NULL) |
|
246 goto onError; |
|
247 Py_DECREF(v); |
|
248 memcpy(&PySocketModule, api, sizeof(PySocketModule)); |
|
249 DPRINTF(" API object loaded and initialized.\n"); |
|
250 return 0; |
|
251 |
|
252 onError: |
|
253 DPRINTF(" not found.\n"); |
|
254 Py_XDECREF(mod); |
|
255 Py_XDECREF(v); |
|
256 return -1; |
|
257 } |
|
258 |
|
259 #endif /* !PySocket_BUILDING_SOCKET */ |
|
260 |
|
261 #ifdef __cplusplus |
|
262 } |
|
263 #endif |
|
264 #endif /* !Py__SOCKET_H */ |