⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socketmodule.c

📁 python s60 1.4.5版本的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef AF_UNIX
		struct sockaddr_un un;
#endif
#ifdef ENABLE_IPV6
		struct sockaddr_in6 in6;
		struct sockaddr_storage storage;
#endif
#ifdef HAVE_NETPACKET_PACKET_H
		struct sockaddr_ll ll;
#endif
	} sock_addr;
} PySocketSockObject;

#ifdef USE_SSL

#define X509_NAME_MAXLEN 256

typedef struct {
	PyObject_HEAD
	PySocketSockObject *Socket;	/* Socket on which we're layered */
	SSL_CTX* 	ctx;
	SSL*     	ssl;
	X509*    	server_cert;
	BIO*		sbio;
	char    	server[X509_NAME_MAXLEN];
	char		issuer[X509_NAME_MAXLEN];

} PySSLObject;

staticforward PyTypeObject PySSL_Type;
staticforward PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args);
staticforward PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args);

#define PySSLObject_Check(v)	((v)->ob_type == &PySSL_Type)

#endif /* USE_SSL */

/* A forward reference to the Socktype type object.
   The Socktype variable contains pointers to various functions,
   some of which call newsockobject(), which uses Socktype, so
   there has to be a circular reference. */

staticforward PyTypeObject PySocketSock_Type;


/* Initialize a new socket object. */

static void
init_sockobject(PySocketSockObject *s,
		SOCKET_T fd, int family, int type, int proto)
{
#ifdef RISCOS
	int block = 1;
#endif
	s->sock_fd = fd;
	s->sock_family = family;
	s->sock_type = type;
	s->sock_proto = proto;
#ifdef RISCOS
	if(taskwindow) {
		socketioctl(s->sock_fd, 0x80046679, (u_long*)&block);
	}
#endif
}


/* Create a new socket object.
   This just creates the object and initializes it.
   If the creation fails, return NULL and set an exception (implicit
   in NEWOBJ()). */

static PySocketSockObject *
PySocketSock_New(SOCKET_T fd, int family, int type, int proto)
{
	PySocketSockObject *s;
	s = (PySocketSockObject *)
		PyType_GenericNew(&PySocketSock_Type, NULL, NULL);
	if (s != NULL)
		init_sockobject(s, fd, family, type, proto);
	return s;
}


/* Lock to allow python interpreter to continue, but only allow one
   thread to be in gethostbyname */
#ifdef USE_GETHOSTBYNAME_LOCK
PyThread_type_lock gethostbyname_lock;
#endif


/* Convert a string specifying a host name or one of a few symbolic
   names to a numeric IP address.  This usually calls gethostbyname()
   to do the work; the names "" and "<broadcast>" are special.
   Return the length (IPv4 should be 4 bytes), or negative if
   an error occurred; then an exception is raised. */

static int
setipaddr(char* name, struct sockaddr * addr_ret, size_t addr_ret_size, int af)
{
	struct addrinfo hints, *res;
	int error;

	memset((void *) addr_ret, '\0', sizeof(*addr_ret));
	if (name[0] == '\0') {
		int siz;
		memset(&hints, 0, sizeof(hints));
		hints.ai_family = af;
		hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
		hints.ai_flags = AI_PASSIVE;
		error = getaddrinfo(NULL, "0", &hints, &res);
		if (error) {
			PyGAI_Err(error);
			return -1;
		}
		switch (res->ai_family) {
		case AF_INET:
			siz = 4;
			break;
#ifdef ENABLE_IPV6
		case AF_INET6:
			siz = 16;
			break;
#endif
		default:
			freeaddrinfo(res);
			PyErr_SetString(PySocket_Error,
				"unsupported address family");
			return -1;
		}
		if (res->ai_next) {
			freeaddrinfo(res);
			PyErr_SetString(PySocket_Error,
				"wildcard resolved to multiple address");
			return -1;
		}
		if (res->ai_addrlen < addr_ret_size)
			addr_ret_size = res->ai_addrlen;
		memcpy(addr_ret, res->ai_addr, addr_ret_size);
		freeaddrinfo(res);
		return siz;
	}
	if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) {
		struct sockaddr_in *sin;
		if (af != PF_INET && af != PF_UNSPEC) {
			PyErr_SetString(PySocket_Error,
				"address family mismatched");
			return -1;
		}
		sin = (struct sockaddr_in *)addr_ret;
		memset((void *) sin, '\0', sizeof(*sin));
		sin->sin_family = AF_INET;
#ifdef HAVE_SOCKADDR_SA_LEN
		sin->sin_len = sizeof(*sin);
#endif
		sin->sin_addr.s_addr = INADDR_BROADCAST;
		return sizeof(sin->sin_addr);
	}
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = af;
	error = getaddrinfo(name, NULL, &hints, &res);
#if defined(__digital__) && defined(__unix__)
        if (error == EAI_NONAME && af == AF_UNSPEC) {
          /* On Tru64 V5.1, numeric-to-addr conversion
             fails if no address family is given. Assume IPv4 for now.*/
          hints.ai_family = AF_INET;
          error = getaddrinfo(name, NULL, &hints, &res);
        }
#endif
	if (error) {
		PyGAI_Err(error);
		return -1;
	}
	if (res->ai_addrlen < addr_ret_size)
		addr_ret_size = res->ai_addrlen;
	memcpy((char *) addr_ret, res->ai_addr, addr_ret_size);
	freeaddrinfo(res);
	switch (addr_ret->sa_family) {
	case AF_INET:
		return 4;
#ifdef ENABLE_IPV6
	case AF_INET6:
		return 16;
#endif
	default:
		PyErr_SetString(PySocket_Error, "unknown address family");
		return -1;
	}
}


/* Create a string object representing an IP address.
   This is always a string of the form 'dd.dd.dd.dd' (with variable
   size numbers). */

static PyObject *
makeipaddr(struct sockaddr *addr, int addrlen)
{
	char buf[NI_MAXHOST];
	int error;

	error = getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0,
		NI_NUMERICHOST);
	if (error) {
		PyGAI_Err(error);
		return NULL;
	}
	return PyString_FromString(buf);
}


/* Create an object representing the given socket address,
   suitable for passing it back to bind(), connect() etc.
   The family field of the sockaddr structure is inspected
   to determine what kind of address it really is. */

/*ARGSUSED*/
static PyObject *
makesockaddr(int sockfd, struct sockaddr *addr, int addrlen)
{
	if (addrlen == 0) {
		/* No address -- may be recvfrom() from known socket */
		Py_INCREF(Py_None);
		return Py_None;
	}

#ifdef __BEOS__
	/* XXX: BeOS version of accept() doesn't set family correctly */
	addr->sa_family = AF_INET;
#endif

	switch (addr->sa_family) {

	case AF_INET:
	{
		struct sockaddr_in *a;
		PyObject *addrobj = makeipaddr(addr, sizeof(*a));
		PyObject *ret = NULL;
		if (addrobj) {
			a = (struct sockaddr_in *)addr;
			ret = Py_BuildValue("Oi", addrobj, ntohs(a->sin_port));
			Py_DECREF(addrobj);
		}
		return ret;
	}

#ifdef AF_UNIX
	case AF_UNIX:
	{
		struct sockaddr_un *a = (struct sockaddr_un *) addr;
		return PyString_FromString(a->sun_path);
	}
#endif /* AF_UNIX */

#ifdef ENABLE_IPV6
	case AF_INET6:
	{
		struct sockaddr_in6 *a;
		PyObject *addrobj = makeipaddr(addr, sizeof(*a));
		PyObject *ret = NULL;
		if (addrobj) {
			a = (struct sockaddr_in6 *)addr;
			ret = Py_BuildValue("Oiii", addrobj, ntohs(a->sin6_port),
				a->sin6_flowinfo, a->sin6_scope_id);
			Py_DECREF(addrobj);
		}
		return ret;
	}
#endif

#ifdef HAVE_NETPACKET_PACKET_H
	case AF_PACKET:
	{
		struct sockaddr_ll *a = (struct sockaddr_ll *)addr;
		char *ifname = "";
		struct ifreq ifr;
		/* need to look up interface name give index */
		if (a->sll_ifindex) {
			ifr.ifr_ifindex = a->sll_ifindex;
			if (ioctl(sockfd, SIOCGIFNAME, &ifr) == 0)
				ifname = ifr.ifr_name;
		}
		return Py_BuildValue("shbhs#", ifname, ntohs(a->sll_protocol),
				     a->sll_pkttype, a->sll_hatype,
				     a->sll_addr, a->sll_halen);
	}
#endif

	/* More cases here... */

	default:
		/* If we don't know the address family, don't raise an
		   exception -- return it as a tuple. */
		return Py_BuildValue("is#",
				     addr->sa_family,
				     addr->sa_data,
				     sizeof(addr->sa_data));

	}
}


/* Parse a socket address argument according to the socket object's
   address family.  Return 1 if the address was in the proper format,
   0 of not.  The address is returned through addr_ret, its length
   through len_ret. */

static int
getsockaddrarg(PySocketSockObject *s, PyObject *args,
	       struct sockaddr **addr_ret, int *len_ret)
{
	switch (s->sock_family) {

#ifdef AF_UNIX
	case AF_UNIX:
	{
		struct sockaddr_un* addr;
		char *path;
		int len;
		addr = (struct sockaddr_un* )&(s->sock_addr).un;
		if (!PyArg_Parse(args, "t#", &path, &len))
			return 0;
		if (len > sizeof addr->sun_path) {
			PyErr_SetString(PySocket_Error,
					"AF_UNIX path too long");
			return 0;
		}
		addr->sun_family = s->sock_family;
		memcpy(addr->sun_path, path, len);
		addr->sun_path[len] = 0;
		*addr_ret = (struct sockaddr *) addr;
		*len_ret = len + sizeof(*addr) - sizeof(addr->sun_path);
		return 1;
	}
#endif /* AF_UNIX */

	case AF_INET:
	{
		struct sockaddr_in* addr;
		char *host;
		int port;
 		addr=(struct sockaddr_in*)&(s->sock_addr).in;
		if (!PyTuple_Check(args)) {
			PyErr_Format(PyExc_TypeError,
		  "getsockaddrarg: AF_INET address must be tuple, not %.500s",
				     args->ob_type->tp_name);
			return 0;
		}
		if (!PyArg_ParseTuple(args, "si:getsockaddrarg", &host, &port))
			return 0;
		if (setipaddr(host, (struct sockaddr *)addr, sizeof(*addr),  AF_INET) < 0)
			return 0;
		addr->sin_family = AF_INET;
		addr->sin_port = htons((short)port);
		*addr_ret = (struct sockaddr *) addr;
		*len_ret = sizeof *addr;
		return 1;
	}

#ifdef ENABLE_IPV6
	case AF_INET6:
	{
		struct sockaddr_in6* addr;
		char *host;
		int port, flowinfo, scope_id;
 		addr = (struct sockaddr_in6*)&(s->sock_addr).in6;
		flowinfo = scope_id = 0;
		if (!PyArg_ParseTuple(args, "si|ii", &host, &port, &flowinfo,
				&scope_id)) {
			return 0;
		}
		if (setipaddr(host, (struct sockaddr *)addr,  sizeof(*addr), AF_INET6) < 0)
			return 0;
		addr->sin6_family = s->sock_family;
		addr->sin6_port = htons((short)port);
		addr->sin6_flowinfo = flowinfo;
		addr->sin6_scope_id = scope_id;
		*addr_ret = (struct sockaddr *) addr;
		*len_ret = sizeof *addr;
		return 1;
	}
#endif

#ifdef HAVE_NETPACKET_PACKET_H
	case AF_PACKET:
	{
		struct sockaddr_ll* addr;
		struct ifreq ifr;
		char *interfaceName;
		int protoNumber;
		int hatype = 0;
		int pkttype = 0;
		char *haddr;

		if (!PyArg_ParseTuple(args, "si|iis", &interfaceName,
				      &protoNumber, &pkttype, &hatype, &haddr))
			return 0;
		strncpy(ifr.ifr_name, interfaceName, sizeof(ifr.ifr_name));
		ifr.ifr_name[(sizeof(ifr.ifr_name))-1] = '\0';
		if (ioctl(s->sock_fd, SIOCGIFINDEX, &ifr) < 0) {
			PySocket_Err();
			return 0;
		}
		addr = &(s->sock_addr.ll);
		addr->sll_family = AF_PACKET;
		addr->sll_protocol = htons((short)protoNumber);
		addr->sll_ifindex = ifr.ifr_ifindex;
		addr->sll_pkttype = pkttype;
		addr->sll_hatype = hatype;
		*addr_ret = (struct sockaddr *) addr;
		*len_ret = sizeof *addr;
		return 1;
	}
#endif

	/* More cases here... */

	default:
		PyErr_SetString(PySocket_Error, "getsockaddrarg: bad family");
		return 0;

	}
}


/* Get the address length according to the socket object's address family.
   Return 1 if the family is known, 0 otherwise.  The length is returned
   through len_ret. */

static int
getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
{
	switch (s->sock_family) {

#ifdef AF_UNIX
	case AF_UNIX:
	{
		*len_ret = sizeof (struct sockaddr_un);
		return 1;
	}
#endif /* AF_UNIX */

	case AF_INET:
	{
		*len_ret = sizeof (struct sockaddr_in);
		return 1;
	}

#ifdef ENABLE_IPV6
	case AF_INET6:
	{
		*len_ret = sizeof (struct sockaddr_in6);
		return 1;
	}
#endif

#ifdef HAVE_NETPACKET_PACKET_H
	case AF_PACKET:
	{
		*len_ret = sizeof (struct sockaddr_ll);
		return 1;
	}
#endif

	/* More cases here... */

	default:
		PyErr_SetString(PySocket_Error, "getsockaddrlen: bad family");
		return 0;

	}
}


/* s.accept() method */

static PyObject *
PySocketSock_accept(PySocketSockObject *s)
{
	char addrbuf[256];
	SOCKET_T newfd;
	socklen_t addrlen;
	PyObject *sock = NULL;
	PyObject *addr = NULL;
	PyObject *res = NULL;

	if (!getsockaddrlen(s, &addrlen))
		return NULL;
	memset(addrbuf, 0, addrlen);
	Py_BEGIN_ALLOW_THREADS
	newfd = accept(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen);
	Py_END_ALLOW_THREADS
#ifdef MS_WINDOWS
	if (newfd == INVALID_SOCKET)
#else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -