| 
									
										
										
										
											2002-02-16 18:23:30 +00:00
										 |  |  | /* Socket module header file */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Includes needed for the sockaddr_* symbols below */ | 
					
						
							|  |  |  | #ifndef MS_WINDOWS
 | 
					
						
							| 
									
										
										
										
											2003-05-03 09:14:54 +00:00
										 |  |  | #ifdef __VMS
 | 
					
						
							|  |  |  | #   include <socket.h>
 | 
					
						
							|  |  |  | # else
 | 
					
						
							|  |  |  | #   include <sys/socket.h>
 | 
					
						
							|  |  |  | # endif
 | 
					
						
							| 
									
										
										
										
											2002-02-16 18:23:30 +00:00
										 |  |  | # include <netinet/in.h>
 | 
					
						
							|  |  |  | # if !(defined(__BEOS__) || defined(__CYGWIN__) || (defined(PYOS_OS2) && defined(PYCC_VACPP)))
 | 
					
						
							|  |  |  | #  include <netinet/tcp.h>
 | 
					
						
							|  |  |  | # endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else /* MS_WINDOWS */
 | 
					
						
							| 
									
										
										
										
											2002-03-01 08:31:07 +00:00
										 |  |  | #if _MSC_VER >= 1300
 | 
					
						
							|  |  |  | # include <winsock2.h>
 | 
					
						
							|  |  |  | # include <ws2tcpip.h>
 | 
					
						
							|  |  |  | # define HAVE_ADDRINFO
 | 
					
						
							|  |  |  | # define HAVE_SOCKADDR_STORAGE
 | 
					
						
							|  |  |  | # define HAVE_GETADDRINFO
 | 
					
						
							|  |  |  | # define HAVE_GETNAMEINFO
 | 
					
						
							|  |  |  | # define ENABLE_IPV6
 | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2002-02-16 18:23:30 +00:00
										 |  |  | # include <winsock.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2002-03-01 08:31:07 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2002-02-16 18:23:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_SYS_UN_H
 | 
					
						
							|  |  |  | # include <sys/un.h>
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | # undef AF_UNIX
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-14 18:12:57 +00:00
										 |  |  | #ifdef HAVE_LINUX_NETLINK_H
 | 
					
						
							| 
									
										
										
										
											2006-01-16 04:31:40 +00:00
										 |  |  | # ifdef HAVE_ASM_TYPES_H
 | 
					
						
							|  |  |  | #  include <asm/types.h>
 | 
					
						
							|  |  |  | # endif
 | 
					
						
							| 
									
										
										
										
											2006-01-14 18:12:57 +00:00
										 |  |  | # include <linux/netlink.h>
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #  undef AF_NETLINK
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-31 12:34:17 +00:00
										 |  |  | #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
 | 
					
						
							|  |  |  | #include <bluetooth/bluetooth.h>
 | 
					
						
							|  |  |  | #include <bluetooth/rfcomm.h>
 | 
					
						
							|  |  |  | #include <bluetooth/l2cap.h>
 | 
					
						
							|  |  |  | #include <bluetooth/sco.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-02 08:48:45 +00:00
										 |  |  | #ifdef HAVE_BLUETOOTH_H
 | 
					
						
							|  |  |  | #include <bluetooth.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-02-16 18:23:30 +00:00
										 |  |  | #ifdef HAVE_NETPACKET_PACKET_H
 | 
					
						
							|  |  |  | # include <sys/ioctl.h>
 | 
					
						
							|  |  |  | # include <net/if.h>
 | 
					
						
							|  |  |  | # include <netpacket/packet.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef Py__SOCKET_H
 | 
					
						
							|  |  |  | #define Py__SOCKET_H
 | 
					
						
							|  |  |  | #ifdef __cplusplus
 | 
					
						
							|  |  |  | extern "C" { | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Python module and C API name */ | 
					
						
							|  |  |  | #define PySocket_MODULE_NAME	"_socket"
 | 
					
						
							|  |  |  | #define PySocket_CAPI_NAME	"CAPI"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Abstract the socket file descriptor type */ | 
					
						
							|  |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  | typedef SOCKET SOCKET_T; | 
					
						
							|  |  |  | #	ifdef MS_WIN64
 | 
					
						
							|  |  |  | #		define SIZEOF_SOCKET_T 8
 | 
					
						
							|  |  |  | #	else
 | 
					
						
							|  |  |  | #		define SIZEOF_SOCKET_T 4
 | 
					
						
							|  |  |  | #	endif
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | typedef int SOCKET_T; | 
					
						
							|  |  |  | #	define SIZEOF_SOCKET_T SIZEOF_INT
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-14 18:09:42 +00:00
										 |  |  | /* Socket address */ | 
					
						
							|  |  |  | typedef union sock_addr { | 
					
						
							|  |  |  | 	struct sockaddr_in in; | 
					
						
							|  |  |  | #ifdef AF_UNIX
 | 
					
						
							|  |  |  | 	struct sockaddr_un un; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2006-01-14 18:12:57 +00:00
										 |  |  | #ifdef AF_NETLINK
 | 
					
						
							|  |  |  | 	struct sockaddr_nl nl; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-09-14 18:09:42 +00:00
										 |  |  | #ifdef ENABLE_IPV6
 | 
					
						
							|  |  |  | 	struct sockaddr_in6 in6; | 
					
						
							|  |  |  | 	struct sockaddr_storage storage; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
 | 
					
						
							|  |  |  | 	struct sockaddr_l2 bt_l2; | 
					
						
							|  |  |  | 	struct sockaddr_rc bt_rc; | 
					
						
							|  |  |  | 	struct sockaddr_sco bt_sco; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef HAVE_NETPACKET_PACKET_H
 | 
					
						
							|  |  |  | 	struct sockaddr_ll ll; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } sock_addr_t; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-02-16 18:23:30 +00:00
										 |  |  | /* The object holding a socket.  It holds some extra information,
 | 
					
						
							|  |  |  |    like the address family, which is used to decode socket address | 
					
						
							|  |  |  |    arguments properly. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	PyObject_HEAD | 
					
						
							|  |  |  | 	SOCKET_T sock_fd;	/* Socket file descriptor */ | 
					
						
							|  |  |  | 	int sock_family;	/* Address family, e.g., AF_INET */ | 
					
						
							|  |  |  | 	int sock_type;		/* Socket type, e.g., SOCK_STREAM */ | 
					
						
							|  |  |  | 	int sock_proto;		/* Protocol type, usually 0 */ | 
					
						
							| 
									
										
										
										
											2002-02-17 03:58:51 +00:00
										 |  |  | 	PyObject *(*errorhandler)(void); /* Error handler; checks
 | 
					
						
							| 
									
										
										
										
											2002-02-16 18:23:30 +00:00
										 |  |  | 					    errno, returns NULL and | 
					
						
							|  |  |  | 					    sets a Python exception */ | 
					
						
							| 
									
										
										
										
											2002-06-13 15:07:44 +00:00
										 |  |  | 	double sock_timeout;		 /* Operation timeout in seconds;
 | 
					
						
							|  |  |  | 					    0.0 means non-blocking */ | 
					
						
							| 
									
										
										
										
											2002-02-16 18:23:30 +00:00
										 |  |  | } PySocketSockObject; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --- C API ----------------------------------------------------*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-02-25 14:45:40 +00:00
										 |  |  | /* Short explanation of what this C API export mechanism does
 | 
					
						
							|  |  |  |    and how it works: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     The _ssl module needs access to the type object defined in  | 
					
						
							|  |  |  |     the _socket module. Since cross-DLL linking introduces a lot of | 
					
						
							|  |  |  |     problems on many platforms, the "trick" is to wrap the | 
					
						
							|  |  |  |     C API of a module in a struct which then gets exported to | 
					
						
							|  |  |  |     other modules via a PyCObject. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     The code in socketmodule.c defines this struct (which currently | 
					
						
							|  |  |  |     only contains the type object reference, but could very | 
					
						
							|  |  |  |     well also include other C APIs needed by other modules) | 
					
						
							|  |  |  |     and exports it as PyCObject via the module dictionary | 
					
						
							|  |  |  |     under the name "CAPI". | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Other modules can now include the socketmodule.h file | 
					
						
							|  |  |  |     which defines the needed C APIs to import and set up | 
					
						
							|  |  |  |     a static copy of this struct in the importing module. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     After initialization, the importing module can then | 
					
						
							|  |  |  |     access the C APIs from the _socket module by simply | 
					
						
							|  |  |  |     referring to the static struct, e.g. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Load _socket module and its C API; this sets up the global | 
					
						
							|  |  |  |     PySocketModule: | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  | 	if (PySocketModule_ImportModuleAndAPI()) | 
					
						
							|  |  |  | 	    return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Now use the C API as if it were defined in the using | 
					
						
							|  |  |  |     module: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!PyArg_ParseTuple(args, "O!|zz:ssl", | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			      PySocketModule.Sock_Type, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			      (PyObject*)&Sock, | 
					
						
							|  |  |  | 			      &key_file, &cert_file)) | 
					
						
							|  |  |  | 	    return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Support could easily be extended to export more C APIs/symbols | 
					
						
							|  |  |  |     this way. Currently, only the type object is exported,  | 
					
						
							|  |  |  |     other candidates would be socket constructors and socket | 
					
						
							|  |  |  |     access functions. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-02-16 18:23:30 +00:00
										 |  |  | /* C API for usage by other Python modules */ | 
					
						
							|  |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2002-02-17 03:58:51 +00:00
										 |  |  | 	PyTypeObject *Sock_Type; | 
					
						
							| 
									
										
										
										
											2004-03-23 23:16:54 +00:00
										 |  |  |         PyObject *error; | 
					
						
							| 
									
										
										
										
											2002-02-16 18:23:30 +00:00
										 |  |  | } PySocketModule_APIObject; | 
					
						
							| 
									
										
										
										
											2002-02-17 03:58:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* XXX The net effect of the following appears to be to define a function
 | 
					
						
							|  |  |  |    XXX named PySocketModule_APIObject in _ssl.c.  It's unclear why it isn't | 
					
						
							| 
									
										
										
										
											2002-02-25 14:45:40 +00:00
										 |  |  |    XXX defined there directly.  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    >>> It's defined here because other modules might also want to use | 
					
						
							|  |  |  |    >>> the C API. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2002-02-16 18:23:30 +00:00
										 |  |  | #ifndef PySocket_BUILDING_SOCKET
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* --- C API ----------------------------------------------------*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Interfacestructure to C API for other modules.
 | 
					
						
							| 
									
										
										
										
											2002-06-07 02:27:50 +00:00
										 |  |  |    Call PySocketModule_ImportModuleAndAPI() to initialize this | 
					
						
							| 
									
										
										
										
											2002-02-16 18:23:30 +00:00
										 |  |  |    structure. After that usage is simple: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    if (!PyArg_ParseTuple(args, "O!|zz:ssl", | 
					
						
							|  |  |  |                          &PySocketModule.Sock_Type, (PyObject*)&Sock, | 
					
						
							|  |  |  | 	 		 &key_file, &cert_file)) | 
					
						
							|  |  |  |  	 return NULL; | 
					
						
							|  |  |  |    ... | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-02-17 03:58:51 +00:00
										 |  |  | static | 
					
						
							| 
									
										
										
										
											2002-02-16 18:23:30 +00:00
										 |  |  | PySocketModule_APIObject PySocketModule; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* You *must* call this before using any of the functions in
 | 
					
						
							|  |  |  |    PySocketModule and check its outcome; otherwise all accesses will | 
					
						
							|  |  |  |    result in a segfault. Returns 0 on success. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef DPRINTF
 | 
					
						
							|  |  |  | # define DPRINTF if (0) printf
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static | 
					
						
							|  |  |  | int PySocketModule_ImportModuleAndAPI(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2002-02-17 03:58:51 +00:00
										 |  |  | 	PyObject *mod = 0, *v = 0; | 
					
						
							|  |  |  | 	char *apimodule = PySocket_MODULE_NAME; | 
					
						
							|  |  |  | 	char *apiname = PySocket_CAPI_NAME; | 
					
						
							|  |  |  | 	void *api; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	DPRINTF("Importing the %s C API...\n", apimodule); | 
					
						
							|  |  |  | 	mod = PyImport_ImportModule(apimodule); | 
					
						
							|  |  |  | 	if (mod == NULL) | 
					
						
							|  |  |  | 		goto onError; | 
					
						
							|  |  |  | 	DPRINTF(" %s package found\n", apimodule); | 
					
						
							|  |  |  | 	v = PyObject_GetAttrString(mod, apiname); | 
					
						
							|  |  |  | 	if (v == NULL) | 
					
						
							|  |  |  | 		goto onError; | 
					
						
							|  |  |  | 	Py_DECREF(mod); | 
					
						
							|  |  |  | 	DPRINTF(" API object %s found\n", apiname); | 
					
						
							|  |  |  | 	api = PyCObject_AsVoidPtr(v); | 
					
						
							|  |  |  | 	if (api == NULL) | 
					
						
							|  |  |  | 		goto onError; | 
					
						
							|  |  |  | 	Py_DECREF(v); | 
					
						
							|  |  |  | 	memcpy(&PySocketModule, api, sizeof(PySocketModule)); | 
					
						
							|  |  |  | 	DPRINTF(" API object loaded and initialized.\n"); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-02-16 18:23:30 +00:00
										 |  |  |  onError: | 
					
						
							| 
									
										
										
										
											2002-02-17 03:58:51 +00:00
										 |  |  | 	DPRINTF(" not found.\n"); | 
					
						
							|  |  |  | 	Py_XDECREF(mod); | 
					
						
							|  |  |  | 	Py_XDECREF(v); | 
					
						
							|  |  |  | 	return -1; | 
					
						
							| 
									
										
										
										
											2002-02-16 18:23:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-02-17 03:58:51 +00:00
										 |  |  | #endif /* !PySocket_BUILDING_SOCKET */
 | 
					
						
							| 
									
										
										
										
											2002-02-16 18:23:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef __cplusplus
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #endif /* !Py__SOCKET_H */
 |