blob: 84f2422f418283c57d5a82e473431982705e1f08 [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>
49#endif
50
Hye-Shik Chang96c44652004-02-02 08:48:45 +000051#ifdef HAVE_BLUETOOTH_H
52#include <bluetooth.h>
53#endif
54
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000055#ifdef HAVE_NETPACKET_PACKET_H
56# include <sys/ioctl.h>
57# include <net/if.h>
58# include <netpacket/packet.h>
59#endif
60
61#ifndef Py__SOCKET_H
62#define Py__SOCKET_H
63#ifdef __cplusplus
64extern "C" {
65#endif
66
67/* Python module and C API name */
68#define PySocket_MODULE_NAME "_socket"
69#define PySocket_CAPI_NAME "CAPI"
70
71/* Abstract the socket file descriptor type */
72#ifdef MS_WINDOWS
73typedef SOCKET SOCKET_T;
74# ifdef MS_WIN64
75# define SIZEOF_SOCKET_T 8
76# else
77# define SIZEOF_SOCKET_T 4
78# endif
79#else
80typedef int SOCKET_T;
81# define SIZEOF_SOCKET_T SIZEOF_INT
82#endif
83
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +000084/* Socket address */
85typedef union sock_addr {
86 struct sockaddr_in in;
87#ifdef AF_UNIX
88 struct sockaddr_un un;
89#endif
Martin v. Löwis11017b12006-01-14 18:12:57 +000090#ifdef AF_NETLINK
91 struct sockaddr_nl nl;
92#endif
Guido van Rossum8ee3e5a2005-09-14 18:09:42 +000093#ifdef ENABLE_IPV6
94 struct sockaddr_in6 in6;
95 struct sockaddr_storage storage;
96#endif
97#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
98 struct sockaddr_l2 bt_l2;
99 struct sockaddr_rc bt_rc;
100 struct sockaddr_sco bt_sco;
101#endif
102#ifdef HAVE_NETPACKET_PACKET_H
103 struct sockaddr_ll ll;
104#endif
105} sock_addr_t;
106
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000107/* The object holding a socket. It holds some extra information,
108 like the address family, which is used to decode socket address
109 arguments properly. */
110
111typedef struct {
112 PyObject_HEAD
113 SOCKET_T sock_fd; /* Socket file descriptor */
114 int sock_family; /* Address family, e.g., AF_INET */
115 int sock_type; /* Socket type, e.g., SOCK_STREAM */
116 int sock_proto; /* Protocol type, usually 0 */
Tim Peters6f5505a2002-02-17 03:58:51 +0000117 PyObject *(*errorhandler)(void); /* Error handler; checks
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000118 errno, returns NULL and
119 sets a Python exception */
Guido van Rossum11ba0942002-06-13 15:07:44 +0000120 double sock_timeout; /* Operation timeout in seconds;
121 0.0 means non-blocking */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000122} PySocketSockObject;
123
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000124/* --- C API ----------------------------------------------------*/
125
Marc-André Lemburg666e70d2002-02-25 14:45:40 +0000126/* Short explanation of what this C API export mechanism does
127 and how it works:
128
129 The _ssl module needs access to the type object defined in
130 the _socket module. Since cross-DLL linking introduces a lot of
131 problems on many platforms, the "trick" is to wrap the
132 C API of a module in a struct which then gets exported to
133 other modules via a PyCObject.
134
135 The code in socketmodule.c defines this struct (which currently
136 only contains the type object reference, but could very
137 well also include other C APIs needed by other modules)
138 and exports it as PyCObject via the module dictionary
139 under the name "CAPI".
140
141 Other modules can now include the socketmodule.h file
142 which defines the needed C APIs to import and set up
143 a static copy of this struct in the importing module.
144
145 After initialization, the importing module can then
146 access the C APIs from the _socket module by simply
147 referring to the static struct, e.g.
148
149 Load _socket module and its C API; this sets up the global
150 PySocketModule:
151
152 if (PySocketModule_ImportModuleAndAPI())
153 return;
154
155
156 Now use the C API as if it were defined in the using
157 module:
158
159 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
160
161 PySocketModule.Sock_Type,
162
163 (PyObject*)&Sock,
164 &key_file, &cert_file))
165 return NULL;
166
167 Support could easily be extended to export more C APIs/symbols
168 this way. Currently, only the type object is exported,
169 other candidates would be socket constructors and socket
170 access functions.
171
172*/
173
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000174/* C API for usage by other Python modules */
175typedef struct {
Tim Peters6f5505a2002-02-17 03:58:51 +0000176 PyTypeObject *Sock_Type;
Brett Cannon06c34792004-03-23 23:16:54 +0000177 PyObject *error;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000178} PySocketModule_APIObject;
Tim Peters6f5505a2002-02-17 03:58:51 +0000179
180/* XXX The net effect of the following appears to be to define a function
181 XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't
Marc-André Lemburg666e70d2002-02-25 14:45:40 +0000182 XXX defined there directly.
183
184 >>> It's defined here because other modules might also want to use
185 >>> the C API.
186
187*/
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000188#ifndef PySocket_BUILDING_SOCKET
189
190/* --- C API ----------------------------------------------------*/
191
192/* Interfacestructure to C API for other modules.
Guido van Rossumbe8db072002-06-07 02:27:50 +0000193 Call PySocketModule_ImportModuleAndAPI() to initialize this
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000194 structure. After that usage is simple:
195
196 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
197 &PySocketModule.Sock_Type, (PyObject*)&Sock,
198 &key_file, &cert_file))
199 return NULL;
200 ...
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000201*/
202
Tim Peters6f5505a2002-02-17 03:58:51 +0000203static
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000204PySocketModule_APIObject PySocketModule;
205
206/* You *must* call this before using any of the functions in
207 PySocketModule and check its outcome; otherwise all accesses will
208 result in a segfault. Returns 0 on success. */
209
210#ifndef DPRINTF
211# define DPRINTF if (0) printf
212#endif
213
214static
215int PySocketModule_ImportModuleAndAPI(void)
216{
Tim Peters6f5505a2002-02-17 03:58:51 +0000217 PyObject *mod = 0, *v = 0;
218 char *apimodule = PySocket_MODULE_NAME;
219 char *apiname = PySocket_CAPI_NAME;
220 void *api;
221
222 DPRINTF("Importing the %s C API...\n", apimodule);
223 mod = PyImport_ImportModule(apimodule);
224 if (mod == NULL)
225 goto onError;
226 DPRINTF(" %s package found\n", apimodule);
227 v = PyObject_GetAttrString(mod, apiname);
228 if (v == NULL)
229 goto onError;
230 Py_DECREF(mod);
231 DPRINTF(" API object %s found\n", apiname);
232 api = PyCObject_AsVoidPtr(v);
233 if (api == NULL)
234 goto onError;
235 Py_DECREF(v);
236 memcpy(&PySocketModule, api, sizeof(PySocketModule));
237 DPRINTF(" API object loaded and initialized.\n");
238 return 0;
239
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000240 onError:
Tim Peters6f5505a2002-02-17 03:58:51 +0000241 DPRINTF(" not found.\n");
242 Py_XDECREF(mod);
243 Py_XDECREF(v);
244 return -1;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000245}
246
Tim Peters6f5505a2002-02-17 03:58:51 +0000247#endif /* !PySocket_BUILDING_SOCKET */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000248
249#ifdef __cplusplus
250}
251#endif
252#endif /* !Py__SOCKET_H */