[Python-checkins] r52907 - in python/branches/release25-maint: Misc/NEWS Modules/socketmodule.c Modules/socketmodule.h

martin.v.loewis python-checkins at python.org
Sun Dec 3 12:24:00 CET 2006


Author: martin.v.loewis
Date: Sun Dec  3 12:24:00 2006
New Revision: 52907

Modified:
   python/branches/release25-maint/Misc/NEWS
   python/branches/release25-maint/Modules/socketmodule.c
   python/branches/release25-maint/Modules/socketmodule.h
Log:
Patch #1544279: Improve thread-safety of the socket module by moving
the sock_addr_t storage out of the socket object.


Modified: python/branches/release25-maint/Misc/NEWS
==============================================================================
--- python/branches/release25-maint/Misc/NEWS	(original)
+++ python/branches/release25-maint/Misc/NEWS	Sun Dec  3 12:24:00 2006
@@ -70,6 +70,9 @@
 Extension Modules
 -----------------
 
+- Patch #1544279: Improve thread-safety of the socket module by moving
+  the sock_addr_t storage out of the socket object.
+
 - Bug #1563807: _ctypes built on AIX fails with ld ffi error.
 
 - Bug #1598620: A ctypes Structure cannot contain itself.

Modified: python/branches/release25-maint/Modules/socketmodule.c
==============================================================================
--- python/branches/release25-maint/Modules/socketmodule.c	(original)
+++ python/branches/release25-maint/Modules/socketmodule.c	Sun Dec  3 12:24:00 2006
@@ -364,19 +364,16 @@
 #define BTPROTO_RFCOMM BLUETOOTH_PROTO_RFCOMM
 #define sockaddr_l2 sockaddr_l2cap
 #define sockaddr_rc sockaddr_rfcomm
-#define _BT_SOCKADDR_MEMB(s, proto) &((s)->sock_addr)
 #define _BT_L2_MEMB(sa, memb) ((sa)->l2cap_##memb)
 #define _BT_RC_MEMB(sa, memb) ((sa)->rfcomm_##memb)
 #elif defined(__NetBSD__)
 #define sockaddr_l2 sockaddr_bt
 #define sockaddr_rc sockaddr_bt
 #define sockaddr_sco sockaddr_bt
-#define _BT_SOCKADDR_MEMB(s, proto) &((s)->sock_addr)
 #define _BT_L2_MEMB(sa, memb) ((sa)->bt_##memb)
 #define _BT_RC_MEMB(sa, memb) ((sa)->bt_##memb)
 #define _BT_SCO_MEMB(sa, memb) ((sa)->bt_##memb)
 #else
-#define _BT_SOCKADDR_MEMB(s, proto) (&((s)->sock_addr).bt_##proto)
 #define _BT_L2_MEMB(sa, memb) ((sa)->l2_##memb)
 #define _BT_RC_MEMB(sa, memb) ((sa)->rc_##memb)
 #define _BT_SCO_MEMB(sa, memb) ((sa)->sco_##memb)
@@ -388,6 +385,8 @@
 #define SEGMENT_SIZE (32 * 1024 -1)
 #endif
 
+#define	SAS2SA(x)	((struct sockaddr *)(x))
+
 /*
  * Constants for getnameinfo()
  */
@@ -1174,7 +1173,7 @@
 
 static int
 getsockaddrarg(PySocketSockObject *s, PyObject *args,
-	       struct sockaddr **addr_ret, int *len_ret)
+	       struct sockaddr *addr_ret, int *len_ret)
 {
 	switch (s->sock_family) {
 
@@ -1184,9 +1183,10 @@
 		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;
+
+		addr = (struct sockaddr_un*)addr_ret;
 #ifdef linux
 		if (len > 0 && path[0] == 0) {
 			/* Linux abstract namespace extension */
@@ -1209,7 +1209,6 @@
 		}
 		addr->sun_family = s->sock_family;
 		memcpy(addr->sun_path, path, len);
-		*addr_ret = (struct sockaddr *) addr;
 #if defined(PYOS_OS2)
 		*len_ret = sizeof(*addr);
 #else
@@ -1224,7 +1223,7 @@
 	{
 		struct sockaddr_nl* addr;
 		int pid, groups;
-		addr = (struct sockaddr_nl *)&(s->sock_addr).nl;
+		addr = (struct sockaddr_nl *)addr_ret;
 		if (!PyTuple_Check(args)) {
 			PyErr_Format(
 				PyExc_TypeError,
@@ -1238,7 +1237,6 @@
 		addr->nl_family = AF_NETLINK;
 		addr->nl_pid = pid;
 		addr->nl_groups = groups;
-		*addr_ret = (struct sockaddr *) addr;
 		*len_ret = sizeof(*addr);
 		return 1;
 	}
@@ -1249,7 +1247,6 @@
 		struct sockaddr_in* addr;
 		char *host;
 		int port, result;
- 		addr=(struct sockaddr_in*)&(s->sock_addr).in;
 		if (!PyTuple_Check(args)) {
 			PyErr_Format(
 				PyExc_TypeError,
@@ -1261,6 +1258,7 @@
 		if (!PyArg_ParseTuple(args, "eti:getsockaddrarg",
 				      "idna", &host, &port))
 			return 0;
+		addr=(struct sockaddr_in*)addr_ret;
                 result = setipaddr(host, (struct sockaddr *)addr,
                                    sizeof(*addr),  AF_INET);
                 PyMem_Free(host);
@@ -1268,7 +1266,6 @@
 			return 0;
 		addr->sin_family = AF_INET;
 		addr->sin_port = htons((short)port);
-		*addr_ret = (struct sockaddr *) addr;
 		*len_ret = sizeof *addr;
 		return 1;
 	}
@@ -1279,7 +1276,6 @@
 		struct sockaddr_in6* addr;
 		char *host;
 		int port, flowinfo, scope_id, result;
- 		addr = (struct sockaddr_in6*)&(s->sock_addr).in6;
 		flowinfo = scope_id = 0;
 		if (!PyTuple_Check(args)) {
 			PyErr_Format(
@@ -1294,6 +1290,7 @@
 				      &scope_id)) {
 			return 0;
 		}
+		addr = (struct sockaddr_in6*)addr_ret;
                 result = setipaddr(host, (struct sockaddr *)addr,
                                    sizeof(*addr), AF_INET6);
                 PyMem_Free(host);
@@ -1303,7 +1300,6 @@
 		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;
 	}
@@ -1315,9 +1311,10 @@
 		switch (s->sock_proto) {
 		case BTPROTO_L2CAP:
 		{
-			struct sockaddr_l2 *addr = (struct sockaddr_l2 *) _BT_SOCKADDR_MEMB(s, l2);
+			struct sockaddr_l2 *addr;
 			char *straddr;
 
+			addr = (struct sockaddr_l2 *)addr_ret;
 			_BT_L2_MEMB(addr, family) = AF_BLUETOOTH;
 			if (!PyArg_ParseTuple(args, "si", &straddr,
 					      &_BT_L2_MEMB(addr, psm))) {
@@ -1328,15 +1325,15 @@
 			if (setbdaddr(straddr, &_BT_L2_MEMB(addr, bdaddr)) < 0)
 				return 0;
 
-			*addr_ret = (struct sockaddr *) addr;
 			*len_ret = sizeof *addr;
 			return 1;
 		}
 		case BTPROTO_RFCOMM:
 		{
-			struct sockaddr_rc *addr = (struct sockaddr_rc *) _BT_SOCKADDR_MEMB(s, rc);
+			struct sockaddr_rc *addr;
 			char *straddr;
 
+			addr = (struct sockaddr_rc *)addr_ret;
 			_BT_RC_MEMB(addr, family) = AF_BLUETOOTH;
 			if (!PyArg_ParseTuple(args, "si", &straddr,
 					      &_BT_RC_MEMB(addr, channel))) {
@@ -1347,16 +1344,16 @@
 			if (setbdaddr(straddr, &_BT_RC_MEMB(addr, bdaddr)) < 0)
 				return 0;
 
-			*addr_ret = (struct sockaddr *) addr;
 			*len_ret = sizeof *addr;
 			return 1;
 		}
 #if !defined(__FreeBSD__)
 		case BTPROTO_SCO:
 		{
-			struct sockaddr_sco *addr = (struct sockaddr_sco *) _BT_SOCKADDR_MEMB(s, sco);
+			struct sockaddr_sco *addr;
 			char *straddr;
 
+			addr = (struct sockaddr_sco *)addr_ret;
 			_BT_SCO_MEMB(addr, family) = AF_BLUETOOTH;
 			straddr = PyString_AsString(args);
 			if (straddr == NULL) {
@@ -1367,7 +1364,6 @@
 			if (setbdaddr(straddr, &_BT_SCO_MEMB(addr, bdaddr)) < 0)
 				return 0;
 
-			*addr_ret = (struct sockaddr *) addr;
 			*len_ret = sizeof *addr;
 			return 1;
 		}
@@ -1409,22 +1405,21 @@
 		        s->errorhandler();
 			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;
 		if (halen > 8) {
 		  PyErr_SetString(PyExc_ValueError,
 				  "Hardware address must be 8 bytes or less");
 		  return 0;
 		}
+		addr = (struct sockaddr_ll*)addr_ret;
+		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;
 		if (halen != 0) {
 		  memcpy(&addr->sll_addr, haddr, halen);
 		}
 		addr->sll_halen = halen;
-		*addr_ret = (struct sockaddr *) addr;
 		*len_ret = sizeof *addr;
 		return 1;
 	}
@@ -1551,8 +1546,7 @@
 	Py_BEGIN_ALLOW_THREADS
 	timeout = internal_select(s, 0);
 	if (!timeout)
-		newfd = accept(s->sock_fd, (struct sockaddr *) &addrbuf,
-			       &addrlen);
+		newfd = accept(s->sock_fd, SAS2SA(&addrbuf), &addrlen);
 	Py_END_ALLOW_THREADS
 
 	if (timeout == 1) {
@@ -1578,7 +1572,7 @@
 		SOCKETCLOSE(newfd);
 		goto finally;
 	}
-	addr = makesockaddr(s->sock_fd, (struct sockaddr *) &addrbuf,
+	addr = makesockaddr(s->sock_fd, SAS2SA(&addrbuf),
 			    addrlen, s->sock_proto);
 	if (addr == NULL)
 		goto finally;
@@ -1819,14 +1813,14 @@
 static PyObject *
 sock_bind(PySocketSockObject *s, PyObject *addro)
 {
-	struct sockaddr *addr;
+	sock_addr_t addrbuf;
 	int addrlen;
 	int res;
 
-	if (!getsockaddrarg(s, addro, &addr, &addrlen))
+	if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen))
 		return NULL;
 	Py_BEGIN_ALLOW_THREADS
-	res = bind(s->sock_fd, addr, addrlen);
+	res = bind(s->sock_fd, SAS2SA(&addrbuf), addrlen);
 	Py_END_ALLOW_THREADS
 	if (res < 0)
 		return s->errorhandler();
@@ -1952,16 +1946,16 @@
 static PyObject *
 sock_connect(PySocketSockObject *s, PyObject *addro)
 {
-	struct sockaddr *addr;
+	sock_addr_t addrbuf;
 	int addrlen;
 	int res;
 	int timeout;
 
-	if (!getsockaddrarg(s, addro, &addr, &addrlen))
+	if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen))
 		return NULL;
 
 	Py_BEGIN_ALLOW_THREADS
-	res = internal_connect(s, addr, addrlen, &timeout);
+	res = internal_connect(s, SAS2SA(&addrbuf), addrlen, &timeout);
 	Py_END_ALLOW_THREADS
 
 	if (timeout == 1) {
@@ -1986,16 +1980,16 @@
 static PyObject *
 sock_connect_ex(PySocketSockObject *s, PyObject *addro)
 {
-	struct sockaddr *addr;
+	sock_addr_t addrbuf;
 	int addrlen;
 	int res;
 	int timeout;
 
-	if (!getsockaddrarg(s, addro, &addr, &addrlen))
+	if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen))
 		return NULL;
 
 	Py_BEGIN_ALLOW_THREADS
-	res = internal_connect(s, addr, addrlen, &timeout);
+	res = internal_connect(s, SAS2SA(&addrbuf), addrlen, &timeout);
 	Py_END_ALLOW_THREADS
 
 	/* Signals are not errors (though they may raise exceptions).  Adapted
@@ -2075,11 +2069,11 @@
 		return NULL;
 	memset(&addrbuf, 0, addrlen);
 	Py_BEGIN_ALLOW_THREADS
-	res = getsockname(s->sock_fd, (struct sockaddr *) &addrbuf, &addrlen);
+	res = getsockname(s->sock_fd, SAS2SA(&addrbuf), &addrlen);
 	Py_END_ALLOW_THREADS
 	if (res < 0)
 		return s->errorhandler();
-	return makesockaddr(s->sock_fd, (struct sockaddr *) &addrbuf, addrlen,
+	return makesockaddr(s->sock_fd, SAS2SA(&addrbuf), addrlen,
 			    s->sock_proto);
 }
 
@@ -2104,11 +2098,11 @@
 		return NULL;
 	memset(&addrbuf, 0, addrlen);
 	Py_BEGIN_ALLOW_THREADS
-	res = getpeername(s->sock_fd, (struct sockaddr *) &addrbuf, &addrlen);
+	res = getpeername(s->sock_fd, SAS2SA(&addrbuf), &addrlen);
 	Py_END_ALLOW_THREADS
 	if (res < 0)
 		return s->errorhandler();
-	return makesockaddr(s->sock_fd, (struct sockaddr *) &addrbuf, addrlen,
+	return makesockaddr(s->sock_fd, SAS2SA(&addrbuf), addrlen,
 			    s->sock_proto);
 }
 
@@ -2443,14 +2437,14 @@
 #ifndef MS_WINDOWS
 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
 		n = recvfrom(s->sock_fd, cbuf, len, flags,
-			     (struct sockaddr *) &addrbuf, &addrlen);
+			     SAS2SA(&addrbuf), &addrlen);
 #else
 		n = recvfrom(s->sock_fd, cbuf, len, flags,
 			     (void *) &addrbuf, &addrlen);
 #endif
 #else
 		n = recvfrom(s->sock_fd, cbuf, len, flags,
-			     (struct sockaddr *) &addrbuf, &addrlen);
+			     SAS2SA(&addrbuf), &addrlen);
 #endif
 	}
 	Py_END_ALLOW_THREADS
@@ -2464,7 +2458,7 @@
                 return -1;
 	}
 
-	if (!(*addr = makesockaddr(s->sock_fd, (struct sockaddr *) &addrbuf,
+	if (!(*addr = makesockaddr(s->sock_fd, SAS2SA(&addrbuf),
 				   addrlen, s->sock_proto)))
 		return -1;
 
@@ -2664,7 +2658,7 @@
 {
 	PyObject *addro;
 	char *buf;
-	struct sockaddr *addr;
+	sock_addr_t addrbuf;
 	int addrlen, len, n = -1, flags, timeout;
 
 	flags = 0;
@@ -2675,16 +2669,16 @@
 			return NULL;
 	}
 
-	if (!getsockaddrarg(s, addro, &addr, &addrlen))
-		return NULL;
-
 	if (!IS_SELECTABLE(s))
 		return select_error();
 
+	if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen))
+		return NULL;
+
 	Py_BEGIN_ALLOW_THREADS
 	timeout = internal_select(s, 1);
 	if (!timeout)
-		n = sendto(s->sock_fd, buf, len, flags, addr, addrlen);
+		n = sendto(s->sock_fd, buf, len, flags, SAS2SA(&addrbuf), addrlen);
 	Py_END_ALLOW_THREADS
 
 	if (timeout == 1) {
@@ -2973,10 +2967,9 @@
 
 	if (!PyArg_ParseTuple(args, "s:gethostbyname", &name))
 		return NULL;
-	if (setipaddr(name, (struct sockaddr *)&addrbuf,  sizeof(addrbuf), AF_INET) < 0)
+	if (setipaddr(name, SAS2SA(&addrbuf),  sizeof(addrbuf), AF_INET) < 0)
 		return NULL;
-	return makeipaddr((struct sockaddr *)&addrbuf,
-		sizeof(struct sockaddr_in));
+	return makeipaddr(SAS2SA(&addrbuf), sizeof(struct sockaddr_in));
 }
 
 PyDoc_STRVAR(gethostbyname_doc,

Modified: python/branches/release25-maint/Modules/socketmodule.h
==============================================================================
--- python/branches/release25-maint/Modules/socketmodule.h	(original)
+++ python/branches/release25-maint/Modules/socketmodule.h	Sun Dec  3 12:24:00 2006
@@ -114,7 +114,6 @@
 	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 */
-	sock_addr_t sock_addr;	/* Socket address */
 	PyObject *(*errorhandler)(void); /* Error handler; checks
 					    errno, returns NULL and
 					    sets a Python exception */


More information about the Python-checkins mailing list