summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorКоренберг Марк <socketpair@gmail.com>2018-02-12 19:47:42 (GMT)
committerYury Selivanov <yury@magic.io>2018-02-12 19:47:42 (GMT)
commit7766b96ab80b04509bbac708ee5ecf3c1c5934fc (patch)
treefd14d59599e60bbc67dc723ce0d2b9a0eda2e66d /Modules
parent3c34aad4e7a95913ec7db8e5e948a8fc69047bf7 (diff)
downloadcpython-7766b96ab80b04509bbac708ee5ecf3c1c5934fc.zip
cpython-7766b96ab80b04509bbac708ee5ecf3c1c5934fc.tar.gz
cpython-7766b96ab80b04509bbac708ee5ecf3c1c5934fc.tar.bz2
bpo-32221: makeipaddr(): remove interface part + speedup (GH-5449) (#5449)
Diffstat (limited to 'Modules')
-rw-r--r--Modules/socketmodule.c59
1 files changed, 31 insertions, 28 deletions
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 23061be..aa715bf 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -1099,25 +1099,33 @@ setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int
}
-/* Create a string object representing an IP address.
- This is always a string of the form 'dd.dd.dd.dd' (with variable
- size numbers). */
+/* Convert IPv4 sockaddr to a Python str. */
static PyObject *
-makeipaddr(struct sockaddr *addr, int addrlen)
+make_ipv4_addr(const struct sockaddr_in *addr)
{
- char buf[NI_MAXHOST];
- int error;
-
- error = getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0,
- NI_NUMERICHOST);
- if (error) {
- set_gaierror(error);
+ char buf[INET_ADDRSTRLEN];
+ if (inet_ntop(AF_INET, &addr->sin_addr, buf, sizeof(buf)) == NULL) {
+ PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
return PyUnicode_FromString(buf);
}
+#ifdef ENABLE_IPV6
+/* Convert IPv6 sockaddr to a Python str. */
+
+static PyObject *
+make_ipv6_addr(const struct sockaddr_in6 *addr)
+{
+ char buf[INET6_ADDRSTRLEN];
+ if (inet_ntop(AF_INET6, &addr->sin6_addr, buf, sizeof(buf)) == NULL) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return NULL;
+ }
+ return PyUnicode_FromString(buf);
+}
+#endif
#ifdef USE_BLUETOOTH
/* Convert a string representation of a Bluetooth address into a numeric
@@ -1182,11 +1190,10 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
case AF_INET:
{
- struct sockaddr_in *a;
- PyObject *addrobj = makeipaddr(addr, sizeof(*a));
+ const struct sockaddr_in *a = (const struct sockaddr_in *)addr;
+ PyObject *addrobj = make_ipv4_addr(a);
PyObject *ret = NULL;
if (addrobj) {
- a = (struct sockaddr_in *)addr;
ret = Py_BuildValue("Oi", addrobj, ntohs(a->sin_port));
Py_DECREF(addrobj);
}
@@ -1230,11 +1237,10 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
#ifdef ENABLE_IPV6
case AF_INET6:
{
- struct sockaddr_in6 *a;
- PyObject *addrobj = makeipaddr(addr, sizeof(*a));
+ const struct sockaddr_in6 *a = (const struct sockaddr_in6 *)addr;
+ PyObject *addrobj = make_ipv6_addr(a);
PyObject *ret = NULL;
if (addrobj) {
- a = (struct sockaddr_in6 *)addr;
ret = Py_BuildValue("OiII",
addrobj,
ntohs(a->sin6_port),
@@ -5154,14 +5160,14 @@ static PyObject *
socket_gethostbyname(PyObject *self, PyObject *args)
{
char *name;
- sock_addr_t addrbuf;
+ struct sockaddr_in addrbuf;
PyObject *ret = NULL;
if (!PyArg_ParseTuple(args, "et:gethostbyname", "idna", &name))
return NULL;
- if (setipaddr(name, SAS2SA(&addrbuf), sizeof(addrbuf), AF_INET) < 0)
+ if (setipaddr(name, (struct sockaddr *)&addrbuf, sizeof(addrbuf), AF_INET) < 0)
goto finally;
- ret = makeipaddr(SAS2SA(&addrbuf), sizeof(struct sockaddr_in));
+ ret = make_ipv4_addr(&addrbuf);
finally:
PyMem_Free(name);
return ret;
@@ -5263,7 +5269,7 @@ gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af)
sin.sin_len = sizeof(sin);
#endif
memcpy(&sin.sin_addr, *pch, sizeof(sin.sin_addr));
- tmp = makeipaddr((struct sockaddr *)&sin, sizeof(sin));
+ tmp = make_ipv4_addr(&sin);
if (pch == h->h_addr_list && alen >= sizeof(sin))
memcpy((char *) addr, &sin, sizeof(sin));
@@ -5280,8 +5286,7 @@ gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af)
sin6.sin6_len = sizeof(sin6);
#endif
memcpy(&sin6.sin6_addr, *pch, sizeof(sin6.sin6_addr));
- tmp = makeipaddr((struct sockaddr *)&sin6,
- sizeof(sin6));
+ tmp = make_ipv6_addr(&sin6);
if (pch == h->h_addr_list && alen >= sizeof(sin6))
memcpy((char *) addr, &sin6, sizeof(sin6));
@@ -6052,14 +6057,11 @@ socket_inet_ntop(PyObject *self, PyObject *args)
Py_buffer packed_ip;
const char* retval;
#ifdef ENABLE_IPV6
- char ip[Py_MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) + 1];
+ char ip[Py_MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)];
#else
- char ip[INET_ADDRSTRLEN + 1];
+ char ip[INET_ADDRSTRLEN];
#endif
- /* Guarantee NUL-termination for PyUnicode_FromString() below */
- memset((void *) &ip[0], '\0', sizeof(ip));
-
if (!PyArg_ParseTuple(args, "iy*:inet_ntop", &af, &packed_ip)) {
return NULL;
}
@@ -6087,6 +6089,7 @@ socket_inet_ntop(PyObject *self, PyObject *args)
return NULL;
}
+ /* inet_ntop guarantee NUL-termination of resulting string. */
retval = inet_ntop(af, packed_ip.buf, ip, sizeof(ip));
PyBuffer_Release(&packed_ip);
if (!retval) {