blob: 44483cb35b5a5cdd4f9aba2b81f426d94c9c9d05 [file] [log] [blame]
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +00001/* Socket module header file */
2
3/* Includes needed for the sockaddr_* symbols below */
4#ifndef MS_WINDOWS
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00005#ifdef __VMS
6# include <socket.h>
7# else
8# include <sys/socket.h>
9# endif
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000010# 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 */
Martin v. Löwis272cb402002-03-01 08:31:07 +000016# include <winsock2.h>
17# include <ws2tcpip.h>
Amaury Forgeot d'Arca4dd2e22008-06-13 00:42:22 +000018/* 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. I use IPPROTO_IPV6 to detect a decent SDK.
21 */
22# ifdef IPPROTO_IPV6
23# include <MSTcpIP.h> /* for SIO_RCVALL */
24# define HAVE_ADDRINFO
25# define HAVE_SOCKADDR_STORAGE
26# define HAVE_GETADDRINFO
27# define HAVE_GETNAMEINFO
28# define ENABLE_IPV6
29# else
30typedef int socklen_t;
31# endif /* IPPROTO_IPV6 */
32#endif /* MS_WINDOWS */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000033
34#ifdef HAVE_SYS_UN_H
35# include <sys/un.h>
36#else
37# undef AF_UNIX
38#endif
39
Martin v. Löwis11017b12006-01-14 18:12:57 +000040#ifdef HAVE_LINUX_NETLINK_H
Neal Norwitz65851662006-01-16 04:31:40 +000041# ifdef HAVE_ASM_TYPES_H
42# include <asm/types.h>
43# endif
Martin v. Löwis11017b12006-01-14 18:12:57 +000044# include <linux/netlink.h>
45#else
46# undef AF_NETLINK
47#endif
48
Martin v. Löwis12af0482004-01-31 12:34:17 +000049#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
50#include <bluetooth/bluetooth.h>
51#include <bluetooth/rfcomm.h>
52#include <bluetooth/l2cap.h>
53#include <bluetooth/sco.h>
Martin v. Löwis45423a72007-02-14 10:07:37 +000054#include <bluetooth/hci.h>
Martin v. Löwis12af0482004-01-31 12:34:17 +000055#endif
56
Hye-Shik Chang96c44652004-02-02 08:48:45 +000057#ifdef HAVE_BLUETOOTH_H
58#include <bluetooth.h>
59#endif
60
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000061#ifdef HAVE_NETPACKET_PACKET_H
62# include <sys/ioctl.h>
63# include <net/if.h>
64# include <netpacket/packet.h>
65#endif
66
Christian Heimesfb2d25a2008-01-07 16:12:44 +000067#ifdef HAVE_LINUX_TIPC_H
68# include <linux/tipc.h>
69#endif
70
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000071#ifndef Py__SOCKET_H
72#define Py__SOCKET_H
73#ifdef __cplusplus
74extern "C" {
75#endif
76
77/* Python module and C API name */
78#define PySocket_MODULE_NAME "_socket"
79#define PySocket_CAPI_NAME "CAPI"
80
81/* Abstract the socket file descriptor type */
82#ifdef MS_WINDOWS
83typedef SOCKET SOCKET_T;
84# ifdef MS_WIN64
85# define SIZEOF_SOCKET_T 8
86# else
87# define SIZEOF_SOCKET_T 4
88# endif
89#else
90typedef int SOCKET_T;
91# define SIZEOF_SOCKET_T SIZEOF_INT
92#endif
93
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +000094/* Socket address */
95typedef union sock_addr {
96 struct sockaddr_in in;
97#ifdef AF_UNIX
98 struct sockaddr_un un;
99#endif
Martin v. Löwis11017b12006-01-14 18:12:57 +0000100#ifdef AF_NETLINK
101 struct sockaddr_nl nl;
102#endif
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +0000103#ifdef ENABLE_IPV6
104 struct sockaddr_in6 in6;
105 struct sockaddr_storage storage;
106#endif
107#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
108 struct sockaddr_l2 bt_l2;
109 struct sockaddr_rc bt_rc;
110 struct sockaddr_sco bt_sco;
Martin v. Löwis45423a72007-02-14 10:07:37 +0000111 struct sockaddr_hci bt_hci;
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +0000112#endif
113#ifdef HAVE_NETPACKET_PACKET_H
114 struct sockaddr_ll ll;
115#endif
116} sock_addr_t;
117
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000118/* The object holding a socket. It holds some extra information,
119 like the address family, which is used to decode socket address
120 arguments properly. */
121
122typedef struct {
123 PyObject_HEAD
124 SOCKET_T sock_fd; /* Socket file descriptor */
125 int sock_family; /* Address family, e.g., AF_INET */
126 int sock_type; /* Socket type, e.g., SOCK_STREAM */
127 int sock_proto; /* Protocol type, usually 0 */
Tim Peters6f5505a2002-02-17 03:58:51 +0000128 PyObject *(*errorhandler)(void); /* Error handler; checks
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000129 errno, returns NULL and
130 sets a Python exception */
Guido van Rossum11ba0942002-06-13 15:07:44 +0000131 double sock_timeout; /* Operation timeout in seconds;
132 0.0 means non-blocking */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000133} PySocketSockObject;
134
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000135/* --- C API ----------------------------------------------------*/
136
Marc-André Lemburg666e70d2002-02-25 14:45:40 +0000137/* Short explanation of what this C API export mechanism does
138 and how it works:
139
140 The _ssl module needs access to the type object defined in
141 the _socket module. Since cross-DLL linking introduces a lot of
142 problems on many platforms, the "trick" is to wrap the
143 C API of a module in a struct which then gets exported to
144 other modules via a PyCObject.
145
146 The code in socketmodule.c defines this struct (which currently
147 only contains the type object reference, but could very
148 well also include other C APIs needed by other modules)
149 and exports it as PyCObject via the module dictionary
150 under the name "CAPI".
151
152 Other modules can now include the socketmodule.h file
153 which defines the needed C APIs to import and set up
154 a static copy of this struct in the importing module.
155
156 After initialization, the importing module can then
157 access the C APIs from the _socket module by simply
158 referring to the static struct, e.g.
159
160 Load _socket module and its C API; this sets up the global
161 PySocketModule:
162
163 if (PySocketModule_ImportModuleAndAPI())
164 return;
165
166
167 Now use the C API as if it were defined in the using
168 module:
169
170 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
171
172 PySocketModule.Sock_Type,
173
174 (PyObject*)&Sock,
175 &key_file, &cert_file))
176 return NULL;
177
178 Support could easily be extended to export more C APIs/symbols
179 this way. Currently, only the type object is exported,
180 other candidates would be socket constructors and socket
181 access functions.
182
183*/
184
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000185/* C API for usage by other Python modules */
186typedef struct {
Tim Peters6f5505a2002-02-17 03:58:51 +0000187 PyTypeObject *Sock_Type;
Brett Cannon06c34792004-03-23 23:16:54 +0000188 PyObject *error;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000189} PySocketModule_APIObject;
Tim Peters6f5505a2002-02-17 03:58:51 +0000190
191/* XXX The net effect of the following appears to be to define a function
192 XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't
Marc-André Lemburg666e70d2002-02-25 14:45:40 +0000193 XXX defined there directly.
194
195 >>> It's defined here because other modules might also want to use
196 >>> the C API.
197
198*/
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000199#ifndef PySocket_BUILDING_SOCKET
200
201/* --- C API ----------------------------------------------------*/
202
203/* Interfacestructure to C API for other modules.
Guido van Rossumbe8db072002-06-07 02:27:50 +0000204 Call PySocketModule_ImportModuleAndAPI() to initialize this
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000205 structure. After that usage is simple:
206
207 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
208 &PySocketModule.Sock_Type, (PyObject*)&Sock,
209 &key_file, &cert_file))
210 return NULL;
211 ...
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000212*/
213
Tim Peters6f5505a2002-02-17 03:58:51 +0000214static
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000215PySocketModule_APIObject PySocketModule;
216
217/* You *must* call this before using any of the functions in
218 PySocketModule and check its outcome; otherwise all accesses will
219 result in a segfault. Returns 0 on success. */
220
221#ifndef DPRINTF
222# define DPRINTF if (0) printf
223#endif
224
225static
226int PySocketModule_ImportModuleAndAPI(void)
227{
Tim Peters6f5505a2002-02-17 03:58:51 +0000228 PyObject *mod = 0, *v = 0;
229 char *apimodule = PySocket_MODULE_NAME;
230 char *apiname = PySocket_CAPI_NAME;
231 void *api;
232
233 DPRINTF("Importing the %s C API...\n", apimodule);
Christian Heimes000a0742008-01-03 22:16:32 +0000234 mod = PyImport_ImportModuleNoBlock(apimodule);
Tim Peters6f5505a2002-02-17 03:58:51 +0000235 if (mod == NULL)
236 goto onError;
237 DPRINTF(" %s package found\n", apimodule);
238 v = PyObject_GetAttrString(mod, apiname);
239 if (v == NULL)
240 goto onError;
241 Py_DECREF(mod);
242 DPRINTF(" API object %s found\n", apiname);
243 api = PyCObject_AsVoidPtr(v);
244 if (api == NULL)
245 goto onError;
246 Py_DECREF(v);
247 memcpy(&PySocketModule, api, sizeof(PySocketModule));
248 DPRINTF(" API object loaded and initialized.\n");
249 return 0;
250
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000251 onError:
Tim Peters6f5505a2002-02-17 03:58:51 +0000252 DPRINTF(" not found.\n");
253 Py_XDECREF(mod);
254 Py_XDECREF(v);
255 return -1;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000256}
257
Tim Peters6f5505a2002-02-17 03:58:51 +0000258#endif /* !PySocket_BUILDING_SOCKET */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000259
260#ifdef __cplusplus
261}
262#endif
263#endif /* !Py__SOCKET_H */