blob: e81b5b40e72b1f1d1b83cd221db21496b688888c [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öwis12af0482004-01-31 12:34:17 +000035#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
36#include <bluetooth/bluetooth.h>
37#include <bluetooth/rfcomm.h>
38#include <bluetooth/l2cap.h>
39#include <bluetooth/sco.h>
40#endif
41
Hye-Shik Chang96c446582004-02-02 08:48:45 +000042#ifdef HAVE_BLUETOOTH_H
43#include <bluetooth.h>
44#endif
45
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000046#ifdef HAVE_NETPACKET_PACKET_H
47# include <sys/ioctl.h>
48# include <net/if.h>
49# include <netpacket/packet.h>
50#endif
51
52#ifndef Py__SOCKET_H
53#define Py__SOCKET_H
54#ifdef __cplusplus
55extern "C" {
56#endif
57
58/* Python module and C API name */
59#define PySocket_MODULE_NAME "_socket"
60#define PySocket_CAPI_NAME "CAPI"
61
62/* Abstract the socket file descriptor type */
63#ifdef MS_WINDOWS
64typedef SOCKET SOCKET_T;
65# ifdef MS_WIN64
66# define SIZEOF_SOCKET_T 8
67# else
68# define SIZEOF_SOCKET_T 4
69# endif
70#else
71typedef int SOCKET_T;
72# define SIZEOF_SOCKET_T SIZEOF_INT
73#endif
74
75/* The object holding a socket. It holds some extra information,
76 like the address family, which is used to decode socket address
77 arguments properly. */
78
79typedef struct {
80 PyObject_HEAD
81 SOCKET_T sock_fd; /* Socket file descriptor */
82 int sock_family; /* Address family, e.g., AF_INET */
83 int sock_type; /* Socket type, e.g., SOCK_STREAM */
84 int sock_proto; /* Protocol type, usually 0 */
85 union sock_addr {
86 struct sockaddr_in in;
87#ifdef AF_UNIX
88 struct sockaddr_un un;
89#endif
90#ifdef ENABLE_IPV6
91 struct sockaddr_in6 in6;
92 struct sockaddr_storage storage;
93#endif
Martin v. Löwis12af0482004-01-31 12:34:17 +000094#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
95 struct sockaddr_l2 bt_l2;
96 struct sockaddr_rc bt_rc;
97 struct sockaddr_sco bt_sco;
98#endif
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000099#ifdef HAVE_NETPACKET_PACKET_H
100 struct sockaddr_ll ll;
101#endif
102 } sock_addr;
Tim Peters6f5505a2002-02-17 03:58:51 +0000103 PyObject *(*errorhandler)(void); /* Error handler; checks
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000104 errno, returns NULL and
105 sets a Python exception */
Guido van Rossum11ba0942002-06-13 15:07:44 +0000106 double sock_timeout; /* Operation timeout in seconds;
107 0.0 means non-blocking */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000108} PySocketSockObject;
109
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000110/* --- C API ----------------------------------------------------*/
111
Marc-André Lemburg666e70d2002-02-25 14:45:40 +0000112/* Short explanation of what this C API export mechanism does
113 and how it works:
114
115 The _ssl module needs access to the type object defined in
116 the _socket module. Since cross-DLL linking introduces a lot of
117 problems on many platforms, the "trick" is to wrap the
118 C API of a module in a struct which then gets exported to
119 other modules via a PyCObject.
120
121 The code in socketmodule.c defines this struct (which currently
122 only contains the type object reference, but could very
123 well also include other C APIs needed by other modules)
124 and exports it as PyCObject via the module dictionary
125 under the name "CAPI".
126
127 Other modules can now include the socketmodule.h file
128 which defines the needed C APIs to import and set up
129 a static copy of this struct in the importing module.
130
131 After initialization, the importing module can then
132 access the C APIs from the _socket module by simply
133 referring to the static struct, e.g.
134
135 Load _socket module and its C API; this sets up the global
136 PySocketModule:
137
138 if (PySocketModule_ImportModuleAndAPI())
139 return;
140
141
142 Now use the C API as if it were defined in the using
143 module:
144
145 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
146
147 PySocketModule.Sock_Type,
148
149 (PyObject*)&Sock,
150 &key_file, &cert_file))
151 return NULL;
152
153 Support could easily be extended to export more C APIs/symbols
154 this way. Currently, only the type object is exported,
155 other candidates would be socket constructors and socket
156 access functions.
157
158*/
159
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000160/* C API for usage by other Python modules */
161typedef struct {
Tim Peters6f5505a2002-02-17 03:58:51 +0000162 PyTypeObject *Sock_Type;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000163} PySocketModule_APIObject;
Tim Peters6f5505a2002-02-17 03:58:51 +0000164
165/* XXX The net effect of the following appears to be to define a function
166 XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't
Marc-André Lemburg666e70d2002-02-25 14:45:40 +0000167 XXX defined there directly.
168
169 >>> It's defined here because other modules might also want to use
170 >>> the C API.
171
172*/
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000173#ifndef PySocket_BUILDING_SOCKET
174
175/* --- C API ----------------------------------------------------*/
176
177/* Interfacestructure to C API for other modules.
Guido van Rossumbe8db072002-06-07 02:27:50 +0000178 Call PySocketModule_ImportModuleAndAPI() to initialize this
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000179 structure. After that usage is simple:
180
181 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
182 &PySocketModule.Sock_Type, (PyObject*)&Sock,
183 &key_file, &cert_file))
184 return NULL;
185 ...
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000186*/
187
Tim Peters6f5505a2002-02-17 03:58:51 +0000188static
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000189PySocketModule_APIObject PySocketModule;
190
191/* You *must* call this before using any of the functions in
192 PySocketModule and check its outcome; otherwise all accesses will
193 result in a segfault. Returns 0 on success. */
194
195#ifndef DPRINTF
196# define DPRINTF if (0) printf
197#endif
198
199static
200int PySocketModule_ImportModuleAndAPI(void)
201{
Tim Peters6f5505a2002-02-17 03:58:51 +0000202 PyObject *mod = 0, *v = 0;
203 char *apimodule = PySocket_MODULE_NAME;
204 char *apiname = PySocket_CAPI_NAME;
205 void *api;
206
207 DPRINTF("Importing the %s C API...\n", apimodule);
208 mod = PyImport_ImportModule(apimodule);
209 if (mod == NULL)
210 goto onError;
211 DPRINTF(" %s package found\n", apimodule);
212 v = PyObject_GetAttrString(mod, apiname);
213 if (v == NULL)
214 goto onError;
215 Py_DECREF(mod);
216 DPRINTF(" API object %s found\n", apiname);
217 api = PyCObject_AsVoidPtr(v);
218 if (api == NULL)
219 goto onError;
220 Py_DECREF(v);
221 memcpy(&PySocketModule, api, sizeof(PySocketModule));
222 DPRINTF(" API object loaded and initialized.\n");
223 return 0;
224
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000225 onError:
Tim Peters6f5505a2002-02-17 03:58:51 +0000226 DPRINTF(" not found.\n");
227 Py_XDECREF(mod);
228 Py_XDECREF(v);
229 return -1;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000230}
231
Tim Peters6f5505a2002-02-17 03:58:51 +0000232#endif /* !PySocket_BUILDING_SOCKET */
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000233
234#ifdef __cplusplus
235}
236#endif
237#endif /* !Py__SOCKET_H */