classification
Title: Converting ipv6 address to string representation using getnameinfo() is wrong.
Type: performance Stage: patch review
Components: Library (Lib) Versions: Python 3.8, Python 3.7, Python 3.6
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: socketpair
Priority: normal Keywords: patch

Created on 2017-12-05 09:54 by socketpair, last changed 2017-12-05 09:55 by socketpair.

Pull Requests
URL Status Linked Edit
PR 4724 open socketpair, 2017-12-05 09:55
Messages (1)
msg307651 - (view) Author: Марк Коренберг (socketpair) * Date: 2017-12-05 09:54
https://github.com/python/cpython/pull/4724


`recvfrom` from multicast socket is painfull slow. In fact, it returns sender address in form:

`('fe80::941f:f6ff:fe04:c560%qwe', 42133, 0, 78)`
which is superfluous, since interface-name part (`%qwe`) is not actually used. Actually, scopeid (`78`) signify interface/scope/zone_id. This tuple can be used for `.sendto()` either with this interface-name-part or without.

The problem is in the performance. For each `recvrfom()`, `getnameinfo()` internally converts interface index to interface name using three syscalls, i.e. `socket(), getsockopt()?, close()` , which slows down receiving (I have not measured result, but see additional syscalls in `strace`).

In order to convert from tuple to string-based full address one may use `getnameinfo()`:
As you can see, initial interface is ignored (but without my patch it is also validated uselessly):
```
In[1]: socket.getnameinfo(('fe80::941f:f6ff:fe04:c560%qwe', 42133, 0, 78), socket.NI_NUMERICHOST)
Out[1]: ('fe80::941f:f6ff:fe04:c560%qwe', '42133')
In[2]: socket.getnameinfo(('fe80::941f:f6ff:fe04:c560', 42133, 0, 78), socket.NI_NUMERICHOST)
Out[2]: ('fe80::941f:f6ff:fe04:c560%qwe', '42133')
```
History
Date User Action Args
2017-12-05 09:55:04socketpairsetkeywords: + patch
stage: patch review
pull_requests: + pull_request4631
2017-12-05 09:54:54socketpaircreate