Skip to content

Commit 5bb65d7

Browse files
committed
Add support for DNS names
1 parent 164dcc3 commit 5bb65d7

File tree

4 files changed

+28
-2
lines changed

4 files changed

+28
-2
lines changed

multiaddr/codec.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22
import base64
33
import binascii
44

5+
import idna
56
from netaddr import IPAddress
67

78
from .protocols import code_to_varint
9+
from .protocols import P_DNS
10+
from .protocols import P_DNS4
11+
from .protocols import P_DNS6
812
from .protocols import P_DCCP
913
from .protocols import P_IP4
1014
from .protocols import P_IP6
@@ -159,6 +163,10 @@ def address_string_to_bytes(proto, addr_string):
159163
addr_string_bytes = addr_string.encode("ascii")
160164
size = code_to_varint(len(addr_string_bytes))
161165
return b''.join([size, binascii.hexlify(addr_string_bytes)])
166+
elif proto.code in (P_DNS, P_DNS4, P_DNS6):
167+
addr_string_bytes = idna.encode(addr_string, uts46=True)
168+
size = code_to_varint(len(addr_string_bytes))
169+
return b''.join([size, binascii.hexlify(addr_string_bytes)])
162170
else:
163171
raise ValueError("failed to parse %s addr: unknown" % proto.name)
164172

@@ -193,6 +201,10 @@ def address_bytes_to_string(proto, buf):
193201
buf = binascii.unhexlify(buf)
194202
size, num_bytes_read = read_varint_code(buf)
195203
return buf[num_bytes_read:].decode('ascii')
204+
elif proto.code in (P_DNS, P_DNS4, P_DNS6):
205+
buf = binascii.unhexlify(buf)
206+
size, num_bytes_read = read_varint_code(buf)
207+
return idna.decode(buf[num_bytes_read:])
196208
raise ValueError("unknown protocol")
197209

198210

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ varint
22
six
33
base58
44
netaddr
5+
idna

tests/test_codec.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@
2323
(_names_to_protocols['p2p'],
2424
b'221220d52ebb89d85b02a284948203a62ff28389c57c9f42beec4ec20db76a68911c0b',
2525
'QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC'),
26+
27+
# Additional test data
28+
(_names_to_protocols['dns4'],
29+
b'30786e2d2d34676272696d2e786e2d2d2d2d796d63626161616a6c6336646a3762786e6532632e786e2d2d776762683163',
30+
u'موقع.وزارة-الاتصالات.مصر'), # Explicietly mark as unicode to force it LTR
31+
(_names_to_protocols['dns4'],
32+
b'16786e2d2d667562616c6c2d6374612e6578616d706c65',
33+
'fußball.example'), # This will fail if IDNA-2003/NamePrep is used
2634
]
2735

2836
BYTES_MAP_STR_TEST_DATA = [

tests/test_multiaddr.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@
4545
"/ip4/127.0.0.1/p2p/tcp",
4646
"/unix",
4747
"/ip4/1.2.3.4/tcp/80/unix",
48-
"/ip4/127.0.0.1/tcp/9090/http/p2p-webcrt-direct"])
48+
"/ip4/127.0.0.1/tcp/9090/http/p2p-webcrt-direct",
49+
"/dns",
50+
"/dns4",
51+
"/dns6"])
4952
def test_invalid(addr_str):
5053
with pytest.raises(ValueError):
5154
Multiaddr(addr_str)
@@ -80,7 +83,9 @@ def test_invalid(addr_str):
8083
"/unix/stdio",
8184
"/ip4/1.2.3.4/tcp/80/unix/a/b/c/d/e/f",
8285
"/ip4/127.0.0.1/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234/unix/stdio",
83-
"/ip4/127.0.0.1/tcp/9090/http/p2p-webrtc-direct"]) # nopep8
86+
"/ip4/127.0.0.1/tcp/9090/http/p2p-webrtc-direct",
87+
"/dns/example.com",
88+
"/dns4/موقع.وزارة-الاتصالات.مصر"]) # nopep8
8489
def test_valid(addr_str):
8590
ma = Multiaddr(addr_str)
8691
assert str(ma) == addr_str.rstrip("/")

0 commit comments

Comments
 (0)