summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Modules/socketmodule.c
diff options
context:
space:
mode:
authorshadchin <[email protected]>2022-04-18 12:39:32 +0300
committershadchin <[email protected]>2022-04-18 12:39:32 +0300
commitd4be68e361f4258cf0848fc70018dfe37a2acc24 (patch)
tree153e294cd97ac8b5d7a989612704a0c1f58e8ad4 /contrib/tools/python3/src/Modules/socketmodule.c
parent260c02f5ccf242d9d9b8a873afaf6588c00237d6 (diff)
IGNIETFERRO-1816 Update Python 3 from 3.9.12 to 3.10.4
ref:9f96be6d02ee8044fdd6f124b799b270c20ce641
Diffstat (limited to 'contrib/tools/python3/src/Modules/socketmodule.c')
-rw-r--r--contrib/tools/python3/src/Modules/socketmodule.c207
1 files changed, 89 insertions, 118 deletions
diff --git a/contrib/tools/python3/src/Modules/socketmodule.c b/contrib/tools/python3/src/Modules/socketmodule.c
index 5ac2ee510f6..e1b8b13d883 100644
--- a/contrib/tools/python3/src/Modules/socketmodule.c
+++ b/contrib/tools/python3/src/Modules/socketmodule.c
@@ -45,7 +45,7 @@ Module interface:
- socket.if_nameindex() -> list of tuples (if_index, if_name)
- socket.if_nametoindex(name) -> corresponding interface index
- socket.if_indextoname(index) -> corresponding interface name
-- an Internet socket address is a pair (hostname, port)
+- an internet socket address is a pair (hostname, port)
where hostname can be anything recognized by gethostbyname()
(including the dd.dd.dd.dd notation) and port is in host byte order
- where a hostname is returned, the dd.dd.dd.dd notation is used
@@ -201,43 +201,6 @@ shutdown(how) -- shut down traffic in one or both directions\n\
# define USE_GETHOSTBYNAME_LOCK
#endif
-/* To use __FreeBSD_version, __OpenBSD__, and __NetBSD_Version__ */
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-/* On systems on which getaddrinfo() is believed to not be thread-safe,
- (this includes the getaddrinfo emulation) protect access with a lock.
-
- getaddrinfo is thread-safe on Mac OS X 10.5 and later. Originally it was
- a mix of code including an unsafe implementation from an old BSD's
- libresolv. In 10.5 Apple reimplemented it as a safe IPC call to the
- mDNSResponder process. 10.5 is the first be UNIX '03 certified, which
- includes the requirement that getaddrinfo be thread-safe. See issue #25924.
-
- It's thread-safe in OpenBSD starting with 5.4, released Nov 2013:
- http://www.openbsd.org/plus54.html
-
- It's thread-safe in NetBSD starting with 4.0, released Dec 2007:
-
-http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/net/getaddrinfo.c.diff?r1=1.82&r2=1.83
- */
-#if ((defined(__APPLE__) && \
- MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) || \
- (defined(__FreeBSD__) && __FreeBSD_version+0 < 503000) || \
- (defined(__OpenBSD__) && OpenBSD+0 < 201311) || \
- (defined(__NetBSD__) && __NetBSD_Version__+0 < 400000000) || \
- !defined(HAVE_GETADDRINFO))
-#define USE_GETADDRINFO_LOCK
-#endif
-
-#ifdef USE_GETADDRINFO_LOCK
-#define ACQUIRE_GETADDRINFO_LOCK PyThread_acquire_lock(netdb_lock, 1);
-#define RELEASE_GETADDRINFO_LOCK PyThread_release_lock(netdb_lock);
-#else
-#define ACQUIRE_GETADDRINFO_LOCK
-#define RELEASE_GETADDRINFO_LOCK
-#endif
-
#if defined(__APPLE__) || defined(__CYGWIN__) || defined(__NetBSD__)
# include <sys/ioctl.h>
#endif
@@ -365,7 +328,7 @@ static FlagRuntimeInfo win_runtime_flags[] = {
{14393, "TCP_FASTOPEN"}
};
-static void
+static int
remove_unusable_flags(PyObject *m)
{
PyObject *dict;
@@ -374,7 +337,7 @@ remove_unusable_flags(PyObject *m)
dict = PyModule_GetDict(m);
if (dict == NULL) {
- return;
+ return -1;
}
/* set to Windows 10, except BuildNumber. */
@@ -400,19 +363,19 @@ remove_unusable_flags(PyObject *m)
break;
}
else {
- if (PyDict_GetItemString(
- dict,
- win_runtime_flags[i].flag_name) != NULL)
- {
- if (PyDict_DelItemString(
- dict,
- win_runtime_flags[i].flag_name))
- {
- PyErr_Clear();
- }
+ PyObject *flag_name = PyUnicode_FromString(win_runtime_flags[i].flag_name);
+ if (flag_name == NULL) {
+ return -1;
+ }
+ PyObject *v = _PyDict_Pop(dict, flag_name, Py_None);
+ Py_DECREF(flag_name);
+ if (v == NULL) {
+ return -1;
}
+ Py_DECREF(v);
}
}
+ return 0;
}
#endif
@@ -555,7 +518,6 @@ remove_unusable_flags(PyObject *m)
by this module (but not argument type or memory errors, etc.). */
static PyObject *socket_herror;
static PyObject *socket_gaierror;
-static PyObject *socket_timeout;
/* A forward reference to the socket type object.
The sock_type variable contains pointers to various functions,
@@ -927,7 +889,7 @@ sock_call_ex(PySocketSockObject *s,
if (err)
*err = SOCK_TIMEOUT_ERR;
else
- PyErr_SetString(socket_timeout, "timed out");
+ PyErr_SetString(PyExc_TimeoutError, "timed out");
return -1;
}
@@ -1064,7 +1026,7 @@ new_sockobject(SOCKET_T fd, int family, int type, int proto)
/* Lock to allow python interpreter to continue, but only allow one
thread to be in gethostbyname or getaddrinfo */
-#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK)
+#if defined(USE_GETHOSTBYNAME_LOCK)
static PyThread_type_lock netdb_lock;
#endif
@@ -1089,14 +1051,12 @@ setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
hints.ai_flags = AI_PASSIVE;
Py_BEGIN_ALLOW_THREADS
- ACQUIRE_GETADDRINFO_LOCK
error = getaddrinfo(NULL, "0", &hints, &res);
Py_END_ALLOW_THREADS
/* We assume that those thread-unsafe getaddrinfo() versions
*are* safe regarding their return value, ie. that a
subsequent call to getaddrinfo() does not destroy the
outcome of the first call. */
- RELEASE_GETADDRINFO_LOCK
if (error) {
set_gaierror(error);
return -1;
@@ -1197,7 +1157,6 @@ setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int
memset(&hints, 0, sizeof(hints));
hints.ai_family = af;
Py_BEGIN_ALLOW_THREADS
- ACQUIRE_GETADDRINFO_LOCK
error = getaddrinfo(name, NULL, &hints, &res);
#if defined(__digital__) && defined(__unix__)
if (error == EAI_NONAME && af == AF_UNSPEC) {
@@ -1208,7 +1167,6 @@ setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int
}
#endif
Py_END_ALLOW_THREADS
- RELEASE_GETADDRINFO_LOCK /* see comment in setipaddr() */
if (error) {
set_gaierror(error);
return -1;
@@ -2925,7 +2883,7 @@ sock_settimeout(PySocketSockObject *s, PyObject *arg)
/* Blocking mode for a Python socket object means that operations
like :meth:`recv` or :meth:`sendall` will block the execution of
the current thread until they are complete or aborted with a
- `socket.timeout` or `socket.error` errors. When timeout is `None`,
+ `TimeoutError` or `socket.error` errors. When timeout is `None`,
the underlying FD is in a blocking mode. When timeout is a positive
number, the FD is in a non-blocking mode, and socket ops are
implemented with a `select()` call.
@@ -4252,7 +4210,7 @@ sock_sendall(PySocketSockObject *s, PyObject *args)
}
if (interval <= 0) {
- PyErr_SetString(socket_timeout, "timed out");
+ PyErr_SetString(PyExc_TimeoutError, "timed out");
goto done;
}
}
@@ -5200,13 +5158,6 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwds)
else
#endif
{
-
- if (PyFloat_Check(fdobj)) {
- PyErr_SetString(PyExc_TypeError,
- "integer argument expected, got float");
- return -1;
- }
-
fd = PyLong_AsSocket_t(fdobj);
if (fd == (SOCKET_T)(-1) && PyErr_Occurred())
return -1;
@@ -6155,13 +6106,10 @@ socket_ntohs(PyObject *self, PyObject *args)
return NULL;
}
if (x > 0xffff) {
- if (PyErr_WarnEx(PyExc_DeprecationWarning,
- "ntohs: Python int too large to convert to C "
- "16-bit unsigned integer (The silent truncation "
- "is deprecated)",
- 1)) {
- return NULL;
- }
+ PyErr_SetString(PyExc_OverflowError,
+ "ntohs: Python int too large to convert to C "
+ "16-bit unsigned integer");
+ return NULL;
}
return PyLong_FromUnsignedLong(ntohs((unsigned short)x));
}
@@ -6169,12 +6117,7 @@ socket_ntohs(PyObject *self, PyObject *args)
PyDoc_STRVAR(ntohs_doc,
"ntohs(integer) -> integer\n\
\n\
-Convert a 16-bit unsigned integer from network to host byte order.\n\
-Note that in case the received integer does not fit in 16-bit unsigned\n\
-integer, but does fit in a positive C int, it is silently truncated to\n\
-16-bit unsigned integer.\n\
-However, this silent truncation feature is deprecated, and will raise an\n\
-exception in future versions of Python.");
+Convert a 16-bit unsigned integer from network to host byte order.");
static PyObject *
@@ -6226,13 +6169,10 @@ socket_htons(PyObject *self, PyObject *args)
return NULL;
}
if (x > 0xffff) {
- if (PyErr_WarnEx(PyExc_DeprecationWarning,
- "htons: Python int too large to convert to C "
- "16-bit unsigned integer (The silent truncation "
- "is deprecated)",
- 1)) {
- return NULL;
- }
+ PyErr_SetString(PyExc_OverflowError,
+ "htons: Python int too large to convert to C "
+ "16-bit unsigned integer");
+ return NULL;
}
return PyLong_FromUnsignedLong(htons((unsigned short)x));
}
@@ -6240,12 +6180,7 @@ socket_htons(PyObject *self, PyObject *args)
PyDoc_STRVAR(htons_doc,
"htons(integer) -> integer\n\
\n\
-Convert a 16-bit unsigned integer from host to network byte order.\n\
-Note that in case the received integer does not fit in 16-bit unsigned\n\
-integer, but does fit in a positive C int, it is silently truncated to\n\
-16-bit unsigned integer.\n\
-However, this silent truncation feature is deprecated, and will raise an\n\
-exception in future versions of Python.");
+Convert a 16-bit unsigned integer from host to network byte order.");
static PyObject *
@@ -6574,10 +6509,8 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs)
hints.ai_protocol = protocol;
hints.ai_flags = flags;
Py_BEGIN_ALLOW_THREADS
- ACQUIRE_GETADDRINFO_LOCK
error = getaddrinfo(hptr, pptr, &hints, &res0);
Py_END_ALLOW_THREADS
- RELEASE_GETADDRINFO_LOCK /* see comment in setipaddr() */
if (error) {
set_gaierror(error);
goto err;
@@ -6670,10 +6603,8 @@ socket_getnameinfo(PyObject *self, PyObject *args)
hints.ai_socktype = SOCK_DGRAM; /* make numeric port happy */
hints.ai_flags = AI_NUMERICHOST; /* don't do any name resolution */
Py_BEGIN_ALLOW_THREADS
- ACQUIRE_GETADDRINFO_LOCK
error = getaddrinfo(hostp, pbuf, &hints, &res);
Py_END_ALLOW_THREADS
- RELEASE_GETADDRINFO_LOCK /* see comment in setipaddr() */
if (error) {
set_gaierror(error);
goto fail;
@@ -7106,16 +7037,36 @@ os_init(void)
}
#endif
+static void
+sock_free_api(PySocketModule_APIObject *capi)
+{
+ Py_DECREF(capi->Sock_Type);
+ Py_DECREF(capi->error);
+ Py_DECREF(capi->timeout_error);
+ PyMem_Free(capi);
+}
+
+static void
+sock_destroy_api(PyObject *capsule)
+{
+ void *capi = PyCapsule_GetPointer(capsule, PySocket_CAPSULE_NAME);
+ sock_free_api(capi);
+}
-/* C API table - always add new things to the end for binary
- compatibility. */
-static
-PySocketModule_APIObject PySocketModuleAPI =
+static PySocketModule_APIObject *
+sock_get_api(void)
{
- &sock_type,
- NULL,
- NULL
-};
+ PySocketModule_APIObject *capi = PyMem_Malloc(sizeof(PySocketModule_APIObject));
+ if (capi == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ capi->Sock_Type = (PyTypeObject *)Py_NewRef(&sock_type);
+ capi->error = Py_NewRef(PyExc_OSError);
+ capi->timeout_error = Py_NewRef(PyExc_TimeoutError);
+ return capi;
+}
/* Initialize the _socket module.
@@ -7165,8 +7116,6 @@ PyInit__socket(void)
return NULL;
Py_INCREF(PyExc_OSError);
- PySocketModuleAPI.error = PyExc_OSError;
- Py_INCREF(PyExc_OSError);
PyModule_AddObject(m, "error", PyExc_OSError);
socket_herror = PyErr_NewException("socket.herror",
PyExc_OSError, NULL);
@@ -7180,13 +7129,8 @@ PyInit__socket(void)
return NULL;
Py_INCREF(socket_gaierror);
PyModule_AddObject(m, "gaierror", socket_gaierror);
- socket_timeout = PyErr_NewException("socket.timeout",
- PyExc_OSError, NULL);
- if (socket_timeout == NULL)
- return NULL;
- PySocketModuleAPI.timeout_error = socket_timeout;
- Py_INCREF(socket_timeout);
- PyModule_AddObject(m, "timeout", socket_timeout);
+ PyModule_AddObjectRef(m, "timeout", PyExc_TimeoutError);
+
Py_INCREF((PyObject *)&sock_type);
if (PyModule_AddObject(m, "SocketType",
(PyObject *)&sock_type) != 0)
@@ -7205,10 +7149,24 @@ PyInit__socket(void)
PyModule_AddObject(m, "has_ipv6", has_ipv6);
/* Export C API */
- if (PyModule_AddObject(m, PySocket_CAPI_NAME,
- PyCapsule_New(&PySocketModuleAPI, PySocket_CAPSULE_NAME, NULL)
- ) != 0)
+ PySocketModule_APIObject *capi = sock_get_api();
+ if (capi == NULL) {
+ Py_DECREF(m);
+ return NULL;
+ }
+ PyObject *capsule = PyCapsule_New(capi,
+ PySocket_CAPSULE_NAME,
+ sock_destroy_api);
+ if (capsule == NULL) {
+ sock_free_api(capi);
+ Py_DECREF(m);
return NULL;
+ }
+ if (PyModule_AddObject(m, PySocket_CAPI_NAME, capsule) < 0) {
+ Py_DECREF(capsule);
+ Py_DECREF(m);
+ return NULL;
+ }
/* Address families (we only support AF_INET and AF_UNIX) */
#ifdef AF_UNSPEC
@@ -7974,6 +7932,9 @@ PyInit__socket(void)
#ifdef IPPROTO_BIP
PyModule_AddIntMacro(m, IPPROTO_BIP);
#endif
+#ifdef IPPROTO_MPTCP
+ PyModule_AddIntMacro(m, IPPROTO_MPTCP);
+#endif
/**/
#ifdef IPPROTO_RAW
PyModule_AddIntMacro(m, IPPROTO_RAW);
@@ -8068,6 +8029,9 @@ PyInit__socket(void)
#ifdef IP_RECVRETOPTS
PyModule_AddIntMacro(m, IP_RECVRETOPTS);
#endif
+#ifdef IP_RECVTOS
+ PyModule_AddIntMacro(m, IP_RECVTOS);
+#endif
#ifdef IP_RECVDSTADDR
PyModule_AddIntMacro(m, IP_RECVDSTADDR);
#endif
@@ -8200,6 +8164,10 @@ PyInit__socket(void)
#ifdef TCP_KEEPIDLE
PyModule_AddIntMacro(m, TCP_KEEPIDLE);
#endif
+ /* TCP_KEEPALIVE is OSX's TCP_KEEPIDLE equivalent */
+#if defined(__APPLE__) && defined(TCP_KEEPALIVE)
+ PyModule_AddIntMacro(m, TCP_KEEPALIVE);
+#endif
#ifdef TCP_KEEPINTVL
PyModule_AddIntMacro(m, TCP_KEEPINTVL);
#endif
@@ -8434,13 +8402,16 @@ PyInit__socket(void)
#endif /* _MSTCPIP_ */
/* Initialize gethostbyname lock */
-#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK)
+#if defined(USE_GETHOSTBYNAME_LOCK)
netdb_lock = PyThread_allocate_lock();
#endif
#ifdef MS_WINDOWS
/* remove some flags on older version Windows during run-time */
- remove_unusable_flags(m);
+ if (remove_unusable_flags(m) < 0) {
+ Py_DECREF(m);
+ return NULL;
+ }
#endif
return m;