blob: 114084cea7d9e613e8c236edc8812bacd33fe5d2 [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>
Christian Heimesfaf2f632008-01-06 16:59:19 +000019# include <MSTcpIP.h> /* for SIO_RCVALL */
Martin v. Löwis272cb402002-03-01 08:31:07 +000020# define HAVE_ADDRINFO
21# define HAVE_SOCKADDR_STORAGE
22# define HAVE_GETADDRINFO
23# define HAVE_GETNAMEINFO
24# define ENABLE_IPV6
25#else
Christian Heimesc36625b2008-01-04 13:33:00 +000026# define WIN32_LEAN_AND_MEAN
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000027# include <winsock.h>
28#endif
Martin v. Löwis272cb402002-03-01 08:31:07 +000029#endif
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000030
31#ifdef HAVE_SYS_UN_H
32# include <sys/un.h>
33#else
34# undef AF_UNIX
35#endif
36
Martin v. Löwis11017b12006-01-14 18:12:57 +000037#ifdef HAVE_LINUX_NETLINK_H
Neal Norwitz65851662006-01-16 04:31:40 +000038# ifdef HAVE_ASM_TYPES_H
39# include <asm/types.h>
40# endif
Martin v. Löwis11017b12006-01-14 18:12:57 +000041# include <linux/netlink.h>
42#else
43# undef AF_NETLINK
44#endif
45
Martin v. Löwis12af0482004-01-31 12:34:17 +000046#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
47#include <bluetooth/bluetooth.h>
48#include <bluetooth/rfcomm.h>
49#include <bluetooth/l2cap.h>
50#include <bluetooth/sco.h>
Thomas Wouterscf297e42007-02-23 15:07:44 +000051#include <bluetooth/hci.h>
Martin v. Löwis12af0482004-01-31 12:34:17 +000052#endif
53
Hye-Shik Chang96c446582004-02-02 08:48:45 +000054#ifdef HAVE_BLUETOOTH_H
55#include <bluetooth.h>
56#endif
57
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000058#ifdef HAVE_NETPACKET_PACKET_H
59# include <sys/ioctl.h>
60# include <net/if.h>
61# include <netpacket/packet.h>
62#endif
63
Christian Heimes043d6f62008-01-07 17:19:16 +000064#ifdef HAVE_LINUX_TIPC_H
65# include <linux/tipc.h>
66#endif
67
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000068#ifndef Py__SOCKET_H
69#define Py__SOCKET_H
70#ifdef __cplusplus
71extern "C" {
72#endif
73
74/* Python module and C API name */
75#define PySocket_MODULE_NAME "_socket"
76#define PySocket_CAPI_NAME "CAPI"
77
78/* Abstract the socket file descriptor type */
79#ifdef MS_WINDOWS
80typedef SOCKET SOCKET_T;
81# ifdef MS_WIN64
82# define SIZEOF_SOCKET_T 8
83# else
84# define SIZEOF_SOCKET_T 4
85# endif
86#else
87typedef int SOCKET_T;
88# define SIZEOF_SOCKET_T SIZEOF_INT
89#endif
90
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +000091/* Socket address */
92typedef union sock_addr {
93 struct sockaddr_in in;
94#ifdef AF_UNIX
95 struct sockaddr_un un;
96#endif
Martin v. Löwis11017b12006-01-14 18:12:57 +000097#ifdef AF_NETLINK
98 struct sockaddr_nl nl;
99#endif
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +0000100#ifdef ENABLE_IPV6
101 struct sockaddr_in6 in6;
102 struct sockaddr_storage storage;
103#endif
104#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
105 struct sockaddr_l2 bt_l2;
106 struct sockaddr_rc bt_rc;
107 struct sockaddr_sco bt_sco;
Thomas Wouterscf297e42007-02-23 15:07:44 +0000108 struct sockaddr_hci bt_hci;
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +0000109#endif
110#ifdef HAVE_NETPACKET_PACKET_H
111 struct sockaddr_ll ll;
112#endif
113} sock_addr_t;
114
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000115/* The object holding a socket. It holds some extra information,
116 like the address family, which is used to decode socket address
117 arguments properly. */
118
119typedef struct {
120 PyObject_HEAD
121 SOCKET_T sock_fd; /* Socket file descriptor */
122 int sock_family; /* Address family, e.g., AF_INET */
123 int sock_type; /* Socket type, e.g., SOCK_STREAM */
124 int sock_proto; /* Protocol type, usually 0 */
Tim Peters6f5505a2002-02-17 03:58:51 +0000125 PyObject *(*errorhandler)(void); /* Error handler; checks
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000126 errno, returns NULL and
127 sets a Python exception */
Guido van Rossum11ba0942002-06-13 15:07:44 +0000128 double sock_timeout; /* Operation timeout in seconds;
129 0.0 means non-blocking */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000130} PySocketSockObject;
131
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000132/* --- C API ----------------------------------------------------*/
133
Marc-André Lemburg666e70d2002-02-25 14:45:40 +0000134/* Short explanation of what this C API export mechanism does
135 and how it works:
136
137 The _ssl module needs access to the type object defined in
138 the _socket module. Since cross-DLL linking introduces a lot of
139 problems on many platforms, the "trick" is to wrap the
140 C API of a module in a struct which then gets exported to
141 other modules via a PyCObject.
142
143 The code in socketmodule.c defines this struct (which currently
144 only contains the type object reference, but could very
145 well also include other C APIs needed by other modules)
146 and exports it as PyCObject via the module dictionary
147 under the name "CAPI".
148
149 Other modules can now include the socketmodule.h file
150 which defines the needed C APIs to import and set up
151 a static copy of this struct in the importing module.
152
153 After initialization, the importing module can then
154 access the C APIs from the _socket module by simply
155 referring to the static struct, e.g.
156
157 Load _socket module and its C API; this sets up the global
158 PySocketModule:
159
160 if (PySocketModule_ImportModuleAndAPI())
161 return;
162
163
164 Now use the C API as if it were defined in the using
165 module:
166
167 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
168
169 PySocketModule.Sock_Type,
170
171 (PyObject*)&Sock,
172 &key_file, &cert_file))
173 return NULL;
174
175 Support could easily be extended to export more C APIs/symbols
176 this way. Currently, only the type object is exported,
177 other candidates would be socket constructors and socket
178 access functions.
179
180*/
181
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000182/* C API for usage by other Python modules */
183typedef struct {
Tim Peters6f5505a2002-02-17 03:58:51 +0000184 PyTypeObject *Sock_Type;
Brett Cannon06c34792004-03-23 23:16:54 +0000185 PyObject *error;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000186} PySocketModule_APIObject;
Tim Peters6f5505a2002-02-17 03:58:51 +0000187
188/* XXX The net effect of the following appears to be to define a function
189 XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't
Marc-André Lemburg666e70d2002-02-25 14:45:40 +0000190 XXX defined there directly.
191
192 >>> It's defined here because other modules might also want to use
193 >>> the C API.
194
195*/
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000196#ifndef PySocket_BUILDING_SOCKET
197
198/* --- C API ----------------------------------------------------*/
199
200/* Interfacestructure to C API for other modules.
Guido van Rossumbe8db072002-06-07 02:27:50 +0000201 Call PySocketModule_ImportModuleAndAPI() to initialize this
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000202 structure. After that usage is simple:
203
204 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
205 &PySocketModule.Sock_Type, (PyObject*)&Sock,
206 &key_file, &cert_file))
207 return NULL;
208 ...
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000209*/
210
Tim Peters6f5505a2002-02-17 03:58:51 +0000211static
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000212PySocketModule_APIObject PySocketModule;
213
214/* You *must* call this before using any of the functions in
215 PySocketModule and check its outcome; otherwise all accesses will
216 result in a segfault. Returns 0 on success. */
217
218#ifndef DPRINTF
219# define DPRINTF if (0) printf
220#endif
221
222static
223int PySocketModule_ImportModuleAndAPI(void)
224{
Tim Peters6f5505a2002-02-17 03:58:51 +0000225 PyObject *mod = 0, *v = 0;
226 char *apimodule = PySocket_MODULE_NAME;
227 char *apiname = PySocket_CAPI_NAME;
228 void *api;
229
230 DPRINTF("Importing the %s C API...\n", apimodule);
Christian Heimes072c0f12008-01-03 23:01:04 +0000231 mod = PyImport_ImportModuleNoBlock(apimodule);
Tim Peters6f5505a2002-02-17 03:58:51 +0000232 if (mod == NULL)
233 goto onError;
234 DPRINTF(" %s package found\n", apimodule);
235 v = PyObject_GetAttrString(mod, apiname);
236 if (v == NULL)
237 goto onError;
238 Py_DECREF(mod);
239 DPRINTF(" API object %s found\n", apiname);
240 api = PyCObject_AsVoidPtr(v);
241 if (api == NULL)
242 goto onError;
243 Py_DECREF(v);
244 memcpy(&PySocketModule, api, sizeof(PySocketModule));
245 DPRINTF(" API object loaded and initialized.\n");
246 return 0;
247
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000248 onError:
Tim Peters6f5505a2002-02-17 03:58:51 +0000249 DPRINTF(" not found.\n");
250 Py_XDECREF(mod);
251 Py_XDECREF(v);
252 return -1;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000253}
254
Tim Peters6f5505a2002-02-17 03:58:51 +0000255#endif /* !PySocket_BUILDING_SOCKET */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000256
257#ifdef __cplusplus
258}
259#endif
260#endif /* !Py__SOCKET_H */