blob: 1df1ae62b9e962822aecb91a972d8f66a1a3aa80 [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>
Christian Heimesb5daaed2007-11-30 23:34:21 +000011# if !(defined(__CYGWIN__) || (defined(PYOS_OS2) && defined(PYCC_VACPP)))
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000012# include <netinet/tcp.h>
13# endif
14
15#else /* MS_WINDOWS */
Martin v. Löwis272cb402002-03-01 08:31:07 +000016#if _MSC_VER >= 1300
17# include <winsock2.h>
18# include <ws2tcpip.h>
19# define HAVE_ADDRINFO
20# define HAVE_SOCKADDR_STORAGE
21# define HAVE_GETADDRINFO
22# define HAVE_GETNAMEINFO
23# define ENABLE_IPV6
24#else
Christian Heimesc36625b2008-01-04 13:33:00 +000025# define WIN32_LEAN_AND_MEAN
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000026# include <winsock.h>
27#endif
Martin v. Löwis272cb402002-03-01 08:31:07 +000028#endif
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000029
30#ifdef HAVE_SYS_UN_H
31# include <sys/un.h>
32#else
33# undef AF_UNIX
34#endif
35
Martin v. Löwis11017b12006-01-14 18:12:57 +000036#ifdef HAVE_LINUX_NETLINK_H
Neal Norwitz65851662006-01-16 04:31:40 +000037# ifdef HAVE_ASM_TYPES_H
38# include <asm/types.h>
39# endif
Martin v. Löwis11017b12006-01-14 18:12:57 +000040# include <linux/netlink.h>
41#else
42# undef AF_NETLINK
43#endif
44
Martin v. Löwis12af0482004-01-31 12:34:17 +000045#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
46#include <bluetooth/bluetooth.h>
47#include <bluetooth/rfcomm.h>
48#include <bluetooth/l2cap.h>
49#include <bluetooth/sco.h>
Thomas Wouterscf297e42007-02-23 15:07:44 +000050#include <bluetooth/hci.h>
Martin v. Löwis12af0482004-01-31 12:34:17 +000051#endif
52
Hye-Shik Chang96c44652004-02-02 08:48:45 +000053#ifdef HAVE_BLUETOOTH_H
54#include <bluetooth.h>
55#endif
56
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000057#ifdef HAVE_NETPACKET_PACKET_H
58# include <sys/ioctl.h>
59# include <net/if.h>
60# include <netpacket/packet.h>
61#endif
62
63#ifndef Py__SOCKET_H
64#define Py__SOCKET_H
65#ifdef __cplusplus
66extern "C" {
67#endif
68
69/* Python module and C API name */
70#define PySocket_MODULE_NAME "_socket"
71#define PySocket_CAPI_NAME "CAPI"
72
73/* Abstract the socket file descriptor type */
74#ifdef MS_WINDOWS
75typedef SOCKET SOCKET_T;
76# ifdef MS_WIN64
77# define SIZEOF_SOCKET_T 8
78# else
79# define SIZEOF_SOCKET_T 4
80# endif
81#else
82typedef int SOCKET_T;
83# define SIZEOF_SOCKET_T SIZEOF_INT
84#endif
85
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +000086/* Socket address */
87typedef union sock_addr {
88 struct sockaddr_in in;
89#ifdef AF_UNIX
90 struct sockaddr_un un;
91#endif
Martin v. Löwis11017b12006-01-14 18:12:57 +000092#ifdef AF_NETLINK
93 struct sockaddr_nl nl;
94#endif
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +000095#ifdef ENABLE_IPV6
96 struct sockaddr_in6 in6;
97 struct sockaddr_storage storage;
98#endif
99#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
100 struct sockaddr_l2 bt_l2;
101 struct sockaddr_rc bt_rc;
102 struct sockaddr_sco bt_sco;
Thomas Wouterscf297e42007-02-23 15:07:44 +0000103 struct sockaddr_hci bt_hci;
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +0000104#endif
105#ifdef HAVE_NETPACKET_PACKET_H
106 struct sockaddr_ll ll;
107#endif
108} sock_addr_t;
109
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000110/* The object holding a socket. It holds some extra information,
111 like the address family, which is used to decode socket address
112 arguments properly. */
113
114typedef struct {
115 PyObject_HEAD
116 SOCKET_T sock_fd; /* Socket file descriptor */
117 int sock_family; /* Address family, e.g., AF_INET */
118 int sock_type; /* Socket type, e.g., SOCK_STREAM */
119 int sock_proto; /* Protocol type, usually 0 */
Tim Peters6f5505a2002-02-17 03:58:51 +0000120 PyObject *(*errorhandler)(void); /* Error handler; checks
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000121 errno, returns NULL and
122 sets a Python exception */
Guido van Rossum11ba0942002-06-13 15:07:44 +0000123 double sock_timeout; /* Operation timeout in seconds;
124 0.0 means non-blocking */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000125} PySocketSockObject;
126
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000127/* --- C API ----------------------------------------------------*/
128
Marc-André Lemburg666e70d2002-02-25 14:45:40 +0000129/* Short explanation of what this C API export mechanism does
130 and how it works:
131
132 The _ssl module needs access to the type object defined in
133 the _socket module. Since cross-DLL linking introduces a lot of
134 problems on many platforms, the "trick" is to wrap the
135 C API of a module in a struct which then gets exported to
136 other modules via a PyCObject.
137
138 The code in socketmodule.c defines this struct (which currently
139 only contains the type object reference, but could very
140 well also include other C APIs needed by other modules)
141 and exports it as PyCObject via the module dictionary
142 under the name "CAPI".
143
144 Other modules can now include the socketmodule.h file
145 which defines the needed C APIs to import and set up
146 a static copy of this struct in the importing module.
147
148 After initialization, the importing module can then
149 access the C APIs from the _socket module by simply
150 referring to the static struct, e.g.
151
152 Load _socket module and its C API; this sets up the global
153 PySocketModule:
154
155 if (PySocketModule_ImportModuleAndAPI())
156 return;
157
158
159 Now use the C API as if it were defined in the using
160 module:
161
162 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
163
164 PySocketModule.Sock_Type,
165
166 (PyObject*)&Sock,
167 &key_file, &cert_file))
168 return NULL;
169
170 Support could easily be extended to export more C APIs/symbols
171 this way. Currently, only the type object is exported,
172 other candidates would be socket constructors and socket
173 access functions.
174
175*/
176
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000177/* C API for usage by other Python modules */
178typedef struct {
Tim Peters6f5505a2002-02-17 03:58:51 +0000179 PyTypeObject *Sock_Type;
Brett Cannon06c34792004-03-23 23:16:54 +0000180 PyObject *error;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000181} PySocketModule_APIObject;
Tim Peters6f5505a2002-02-17 03:58:51 +0000182
183/* XXX The net effect of the following appears to be to define a function
184 XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't
Marc-André Lemburg666e70d2002-02-25 14:45:40 +0000185 XXX defined there directly.
186
187 >>> It's defined here because other modules might also want to use
188 >>> the C API.
189
190*/
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000191#ifndef PySocket_BUILDING_SOCKET
192
193/* --- C API ----------------------------------------------------*/
194
195/* Interfacestructure to C API for other modules.
Guido van Rossumbe8db072002-06-07 02:27:50 +0000196 Call PySocketModule_ImportModuleAndAPI() to initialize this
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000197 structure. After that usage is simple:
198
199 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
200 &PySocketModule.Sock_Type, (PyObject*)&Sock,
201 &key_file, &cert_file))
202 return NULL;
203 ...
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000204*/
205
Tim Peters6f5505a2002-02-17 03:58:51 +0000206static
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000207PySocketModule_APIObject PySocketModule;
208
209/* You *must* call this before using any of the functions in
210 PySocketModule and check its outcome; otherwise all accesses will
211 result in a segfault. Returns 0 on success. */
212
213#ifndef DPRINTF
214# define DPRINTF if (0) printf
215#endif
216
217static
218int PySocketModule_ImportModuleAndAPI(void)
219{
Tim Peters6f5505a2002-02-17 03:58:51 +0000220 PyObject *mod = 0, *v = 0;
221 char *apimodule = PySocket_MODULE_NAME;
222 char *apiname = PySocket_CAPI_NAME;
223 void *api;
224
225 DPRINTF("Importing the %s C API...\n", apimodule);
Christian Heimes072c0f12008-01-03 23:01:04 +0000226 mod = PyImport_ImportModuleNoBlock(apimodule);
Tim Peters6f5505a2002-02-17 03:58:51 +0000227 if (mod == NULL)
228 goto onError;
229 DPRINTF(" %s package found\n", apimodule);
230 v = PyObject_GetAttrString(mod, apiname);
231 if (v == NULL)
232 goto onError;
233 Py_DECREF(mod);
234 DPRINTF(" API object %s found\n", apiname);
235 api = PyCObject_AsVoidPtr(v);
236 if (api == NULL)
237 goto onError;
238 Py_DECREF(v);
239 memcpy(&PySocketModule, api, sizeof(PySocketModule));
240 DPRINTF(" API object loaded and initialized.\n");
241 return 0;
242
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000243 onError:
Tim Peters6f5505a2002-02-17 03:58:51 +0000244 DPRINTF(" not found.\n");
245 Py_XDECREF(mod);
246 Py_XDECREF(v);
247 return -1;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000248}
249
Tim Peters6f5505a2002-02-17 03:58:51 +0000250#endif /* !PySocket_BUILDING_SOCKET */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000251
252#ifdef __cplusplus
253}
254#endif
255#endif /* !Py__SOCKET_H */