diff options
author | Коренберг Марк <socketpair@gmail.com> | 2018-02-12 19:47:42 (GMT) |
---|---|---|
committer | Yury Selivanov <yury@magic.io> | 2018-02-12 19:47:42 (GMT) |
commit | 7766b96ab80b04509bbac708ee5ecf3c1c5934fc (patch) | |
tree | fd14d59599e60bbc67dc723ce0d2b9a0eda2e66d /Modules | |
parent | 3c34aad4e7a95913ec7db8e5e948a8fc69047bf7 (diff) | |
download | cpython-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.c | 59 |
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) { |