blob: a4382abd91d31d680c1d3cb715ae0e125c8e67bb [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#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
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000025# include <winsock.h>
26#endif
Martin v. Löwis272cb402002-03-01 08:31:07 +000027#endif
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000028
29#ifdef HAVE_SYS_UN_H
30# include <sys/un.h>
31#else
32# undef AF_UNIX
33#endif
34
Martin v. Löwis11017b12006-01-14 18:12:57 +000035#ifdef HAVE_LINUX_NETLINK_H
Neal Norwitz65851662006-01-16 04:31:40 +000036# ifdef HAVE_ASM_TYPES_H
37# include <asm/types.h>
38# endif
Martin v. Löwis11017b12006-01-14 18:12:57 +000039# include <linux/netlink.h>
40#else
41# undef AF_NETLINK
42#endif
43
Martin v. Löwis12af0482004-01-31 12:34:17 +000044#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
45#include <bluetooth/bluetooth.h>
46#include <bluetooth/rfcomm.h>
47#include <bluetooth/l2cap.h>
48#include <bluetooth/sco.h>
Thomas Wouterscf297e42007-02-23 15:07:44 +000049#include <bluetooth/hci.h>
Martin v. Löwis12af0482004-01-31 12:34:17 +000050#endif
51
Hye-Shik Chang96c446582004-02-02 08:48:45 +000052#ifdef HAVE_BLUETOOTH_H
53#include <bluetooth.h>
54#endif
55
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000056#ifdef HAVE_NETPACKET_PACKET_H
57# include <sys/ioctl.h>
58# include <net/if.h>
59# include <netpacket/packet.h>
60#endif
61
62#ifndef Py__SOCKET_H
63#define Py__SOCKET_H
64#ifdef __cplusplus
65extern "C" {
66#endif
67
68/* Python module and C API name */
69#define PySocket_MODULE_NAME "_socket"
70#define PySocket_CAPI_NAME "CAPI"
71
72/* Abstract the socket file descriptor type */
73#ifdef MS_WINDOWS
74typedef SOCKET SOCKET_T;
75# ifdef MS_WIN64
76# define SIZEOF_SOCKET_T 8
77# else
78# define SIZEOF_SOCKET_T 4
79# endif
80#else
81typedef int SOCKET_T;
82# define SIZEOF_SOCKET_T SIZEOF_INT
83#endif
84
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +000085/* Socket address */
86typedef union sock_addr {
87 struct sockaddr_in in;
88#ifdef AF_UNIX
89 struct sockaddr_un un;
90#endif
Martin v. Löwis11017b12006-01-14 18:12:57 +000091#ifdef AF_NETLINK
92 struct sockaddr_nl nl;
93#endif
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +000094#ifdef ENABLE_IPV6
95 struct sockaddr_in6 in6;
96 struct sockaddr_storage storage;
97#endif
98#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
99 struct sockaddr_l2 bt_l2;
100 struct sockaddr_rc bt_rc;
101 struct sockaddr_sco bt_sco;
Thomas Wouterscf297e42007-02-23 15:07:44 +0000102 struct sockaddr_hci bt_hci;
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +0000103#endif
104#ifdef HAVE_NETPACKET_PACKET_H
105 struct sockaddr_ll ll;
106#endif
107} sock_addr_t;
108
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000109/* The object holding a socket. It holds some extra information,
110 like the address family, which is used to decode socket address
111 arguments properly. */
112
113typedef struct {
114 PyObject_HEAD
115 SOCKET_T sock_fd; /* Socket file descriptor */
116 int sock_family; /* Address family, e.g., AF_INET */
117 int sock_type; /* Socket type, e.g., SOCK_STREAM */
118 int sock_proto; /* Protocol type, usually 0 */
Tim Peters6f5505a2002-02-17 03:58:51 +0000119 PyObject *(*errorhandler)(void); /* Error handler; checks
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000120 errno, returns NULL and
121 sets a Python exception */
Guido van Rossum11ba0942002-06-13 15:07:44 +0000122 double sock_timeout; /* Operation timeout in seconds;
123 0.0 means non-blocking */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000124} PySocketSockObject;
125
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000126/* --- C API ----------------------------------------------------*/
127
Marc-André Lemburg666e70d2002-02-25 14:45:40 +0000128/* Short explanation of what this C API export mechanism does
129 and how it works:
130
131 The _ssl module needs access to the type object defined in
132 the _socket module. Since cross-DLL linking introduces a lot of
133 problems on many platforms, the "trick" is to wrap the
134 C API of a module in a struct which then gets exported to
135 other modules via a PyCObject.
136
137 The code in socketmodule.c defines this struct (which currently
138 only contains the type object reference, but could very
139 well also include other C APIs needed by other modules)
140 and exports it as PyCObject via the module dictionary
141 under the name "CAPI".
142
143 Other modules can now include the socketmodule.h file
144 which defines the needed C APIs to import and set up
145 a static copy of this struct in the importing module.
146
147 After initialization, the importing module can then
148 access the C APIs from the _socket module by simply
149 referring to the static struct, e.g.
150
151 Load _socket module and its C API; this sets up the global
152 PySocketModule:
153
154 if (PySocketModule_ImportModuleAndAPI())
155 return;
156
157
158 Now use the C API as if it were defined in the using
159 module:
160
161 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
162
163 PySocketModule.Sock_Type,
164
165 (PyObject*)&Sock,
166 &key_file, &cert_file))
167 return NULL;
168
169 Support could easily be extended to export more C APIs/symbols
170 this way. Currently, only the type object is exported,
171 other candidates would be socket constructors and socket
172 access functions.
173
174*/
175
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000176/* C API for usage by other Python modules */
177typedef struct {
Tim Peters6f5505a2002-02-17 03:58:51 +0000178 PyTypeObject *Sock_Type;
Brett Cannon06c34792004-03-23 23:16:54 +0000179 PyObject *error;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000180} PySocketModule_APIObject;
Tim Peters6f5505a2002-02-17 03:58:51 +0000181
182/* XXX The net effect of the following appears to be to define a function
183 XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't
Marc-André Lemburg666e70d2002-02-25 14:45:40 +0000184 XXX defined there directly.
185
186 >>> It's defined here because other modules might also want to use
187 >>> the C API.
188
189*/
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000190#ifndef PySocket_BUILDING_SOCKET
191
192/* --- C API ----------------------------------------------------*/
193
194/* Interfacestructure to C API for other modules.
Guido van Rossumbe8db072002-06-07 02:27:50 +0000195 Call PySocketModule_ImportModuleAndAPI() to initialize this
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000196 structure. After that usage is simple:
197
198 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
199 &PySocketModule.Sock_Type, (PyObject*)&Sock,
200 &key_file, &cert_file))
201 return NULL;
202 ...
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000203*/
204
Tim Peters6f5505a2002-02-17 03:58:51 +0000205static
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000206PySocketModule_APIObject PySocketModule;
207
208/* You *must* call this before using any of the functions in
209 PySocketModule and check its outcome; otherwise all accesses will
210 result in a segfault. Returns 0 on success. */
211
212#ifndef DPRINTF
213# define DPRINTF if (0) printf
214#endif
215
216static
217int PySocketModule_ImportModuleAndAPI(void)
218{
Tim Peters6f5505a2002-02-17 03:58:51 +0000219 PyObject *mod = 0, *v = 0;
220 char *apimodule = PySocket_MODULE_NAME;
221 char *apiname = PySocket_CAPI_NAME;
222 void *api;
223
224 DPRINTF("Importing the %s C API...\n", apimodule);
225 mod = PyImport_ImportModule(apimodule);
226 if (mod == NULL)
227 goto onError;
228 DPRINTF(" %s package found\n", apimodule);
229 v = PyObject_GetAttrString(mod, apiname);
230 if (v == NULL)
231 goto onError;
232 Py_DECREF(mod);
233 DPRINTF(" API object %s found\n", apiname);
234 api = PyCObject_AsVoidPtr(v);
235 if (api == NULL)
236 goto onError;
237 Py_DECREF(v);
238 memcpy(&PySocketModule, api, sizeof(PySocketModule));
239 DPRINTF(" API object loaded and initialized.\n");
240 return 0;
241
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000242 onError:
Tim Peters6f5505a2002-02-17 03:58:51 +0000243 DPRINTF(" not found.\n");
244 Py_XDECREF(mod);
245 Py_XDECREF(v);
246 return -1;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000247}
248
Tim Peters6f5505a2002-02-17 03:58:51 +0000249#endif /* !PySocket_BUILDING_SOCKET */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000250
251#ifdef __cplusplus
252}
253#endif
254#endif /* !Py__SOCKET_H */