This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: socketmodule: fix/improve setipaddr() numeric addresses handling
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.4
process
Status: closed Resolution: duplicate
Dependencies: Superseder: socket.gethostbyname incorrectly parses ip
View: 16201
Assigned To: Nosy List: loewis, neologix
Priority: normal Keywords:

Created on 2013-08-22 05:44 by neologix, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (3)
msg195859 - (view) Author: Charles-François Natali (neologix) * (Python committer) Date: 2013-08-22 05:44
Currently, setipaddr() has this code to special-case numeric IPv4 addresses and avoid a name resolution:

"""
    if (sscanf(name, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 &&
        0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 &&
        0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) {
        struct sockaddr_in *sin;
        sin = (struct sockaddr_in *)addr_ret;
        sin->sin_addr.s_addr = htonl(
            ((long) d1 << 24) | ((long) d2 << 16) |
            ((long) d3 << 8) | ((long) d4 << 0));
        sin->sin_family = AF_INET;
#ifdef HAVE_SOCKADDR_SA_LEN
        sin->sin_len = sizeof(*sin);
#endif
        return 4;
    }
"""

- it's sub-optimal to hand-parse an IP address while we have inet_pton() and getaddrinfo()
- it doesn't work for IPv6 addresses
- it's also subject to integer overflow due to the scanf formatter

Wouldn't it be better getaddrinfo() with AI_NUMERICHOST instead?
msg195864 - (view) Author: Charles-François Natali (neologix) * (Python committer) Date: 2013-08-22 07:11
Hum...
Apparently, before this bug was fixed, glibc's getaddrinfo() would
retrieve the list of interfaces at every call, even if AI_ADDRCONFIG
was not set:
http://sourceware.org/git/?p=glibc.git;a=commitdiff;h=fa3fc0fe5f452d0aa7e435d8f32e992958683819

Which can mean a large overhead.
Also, from a quick look at the source, it will also retrieve the list
of interfaces if more than one address matches (e.g. for TCP, UDP, or
if AF_UNSPEC is passed).
So using getaddrinfo() could incur a non-negligible overhead.

So it might be better to just use inet_pton() instead.
msg195869 - (view) Author: Charles-François Natali (neologix) * (Python committer) Date: 2013-08-22 09:04
> So it might be better to just use inet_pton() instead.

But then it won't set the scope ID if the user doesn't provide it...
History
Date User Action Args
2022-04-11 14:57:49adminsetgithub: 63006
2013-08-29 09:34:06neologixsetstatus: open -> closed
superseder: socket.gethostbyname incorrectly parses ip
resolution: duplicate
stage: resolved
2013-08-22 09:04:10neologixsetmessages: + msg195869
2013-08-22 07:11:34neologixsetmessages: + msg195864
2013-08-22 05:44:15neologixcreate