|
1 |
| -import base58 |
2 |
| -import base64 |
3 |
| -import os |
| 1 | +from __future__ import absolute_import |
4 | 2 |
|
5 |
| -import idna |
6 |
| -from netaddr import IPAddress |
7 |
| -import six |
8 |
| -import struct |
9 | 3 | import varint
|
10 | 4 |
|
11 | 5 | from .protocols import P_DNS
|
|
25 | 19 | from .protocols import read_varint_code
|
26 | 20 |
|
27 | 21 |
|
28 |
| -if hasattr(os, "fsencode") and hasattr(os, "fsdecode"): |
29 |
| - fsencode = os.fsencode |
30 |
| - fsdecode = os.fsdecode |
31 |
| -else: # PY2 |
32 |
| - import sys |
33 |
| - |
34 |
| - def fsencode(path): |
35 |
| - if not isinstance(path, six.binary_type): |
36 |
| - path = path.encode(sys.getfilesystemencoding()) |
37 |
| - return path |
38 |
| - |
39 |
| - def fsdecode(path): |
40 |
| - if not isinstance(path, six.text_type): |
41 |
| - path = path.decode(sys.getfilesystemencoding()) |
42 |
| - return path |
43 |
| - |
44 |
| - |
45 | 22 | def string_to_bytes(string):
|
46 | 23 | if not string:
|
47 | 24 | return b''
|
@@ -90,117 +67,53 @@ def bytes_to_string(buf):
|
90 | 67 |
|
91 | 68 | def address_string_to_bytes(proto, addr_string):
|
92 | 69 | if proto.code == P_IP4: # ipv4
|
93 |
| - try: |
94 |
| - return IPAddress(addr_string, version=4).packed |
95 |
| - except Exception: |
96 |
| - raise ValueError("failed to parse ip4 addr: %s" % addr_string) |
| 70 | + from .codecs import ip4 |
| 71 | + return ip4.to_bytes(proto, addr_string) |
97 | 72 | elif proto.code == P_IP6: # ipv6
|
98 |
| - try: |
99 |
| - return IPAddress(addr_string, version=6).packed |
100 |
| - except Exception: |
101 |
| - raise ValueError("failed to parse ip6 addr: %s" % addr_string) |
| 73 | + from .codecs import ip6 |
| 74 | + return ip6.to_bytes(proto, addr_string) |
102 | 75 | # tcp udp dccp sctp
|
103 | 76 | elif proto.code in [P_TCP, P_UDP, P_DCCP, P_SCTP]:
|
104 |
| - try: |
105 |
| - return struct.pack('>H', int(addr_string, 10)) |
106 |
| - except ValueError as ex: |
107 |
| - raise ValueError("failed to parse %s addr: %s" |
108 |
| - % (proto.name, str(ex))) |
109 |
| - except struct.error: |
110 |
| - raise ValueError("failed to parse %s addr: %s" % |
111 |
| - (proto.name, "greater than 65536")) |
| 77 | + from .codecs import uint16be |
| 78 | + return uint16be.to_bytes(proto, addr_string) |
112 | 79 | elif proto.code == P_ONION:
|
113 |
| - addr = addr_string.split(":") |
114 |
| - if len(addr) != 2: |
115 |
| - raise ValueError( |
116 |
| - "failed to parse %s addr: %s does not contain a port number." |
117 |
| - % (proto.name, addr_string)) |
118 |
| - |
119 |
| - # onion address without the ".onion" substring |
120 |
| - if len(addr[0]) != 16: |
121 |
| - raise ValueError( |
122 |
| - "failed to parse %s addr: %s not a Tor onion address." |
123 |
| - % (proto.name, addr_string)) |
124 |
| - try: |
125 |
| - onion_host_bytes = base64.b32decode(addr[0].upper()) |
126 |
| - except Exception as ex: |
127 |
| - raise ValueError( |
128 |
| - "failed to decode base32 %s addr: %s %s" |
129 |
| - % (proto.name, addr_string, str(ex))) |
130 |
| - |
131 |
| - # onion port number |
132 |
| - try: |
133 |
| - port = int(addr[1]) |
134 |
| - except Exception as ex: |
135 |
| - raise ValueError("failed to parse %s addr: %s" |
136 |
| - % (proto.name, str(ex))) |
137 |
| - if port >= 65536: |
138 |
| - raise ValueError("failed to parse %s addr: %s" |
139 |
| - % (proto.name, "port greater than 65536")) |
140 |
| - if port < 1: |
141 |
| - raise ValueError("failed to parse %s addr: %s" |
142 |
| - % (proto.name, "port less than 1")) |
143 |
| - |
144 |
| - return b''.join([onion_host_bytes, struct.pack('>H', port)]) |
| 80 | + from .codecs import onion |
| 81 | + return onion.to_bytes(proto, addr_string) |
145 | 82 | elif proto.code == P_P2P: # ipfs
|
146 |
| - # the address is a varint prefixed multihash string representation |
147 |
| - try: |
148 |
| - if six.PY2 and isinstance(addr_string, unicode): |
149 |
| - addr_string = addr_string.encode("ascii") |
150 |
| - mm = base58.b58decode(addr_string) |
151 |
| - except Exception as ex: |
152 |
| - raise ValueError("failed to parse p2p addr: %s %s" |
153 |
| - % (addr_string, str(ex))) |
154 |
| - size = varint.encode(len(mm)) |
155 |
| - if len(mm) < 5: |
156 |
| - # TODO - port go-multihash so we can do this correctly |
157 |
| - raise ValueError("invalid P2P multihash: %s" % mm) |
158 |
| - return b''.join([size, mm]) |
| 83 | + from .codecs import multihash |
| 84 | + return multihash.to_bytes(proto, addr_string) |
159 | 85 | elif proto.code == P_UNIX:
|
160 |
| - addr_string_bytes = fsencode(addr_string) |
161 |
| - size = varint.encode(len(addr_string_bytes)) |
162 |
| - return b''.join([size, addr_string_bytes]) |
| 86 | + from .codecs import fspath |
| 87 | + return fspath.to_bytes(proto, addr_string) |
163 | 88 | elif proto.code in (P_DNS, P_DNS4, P_DNS6):
|
164 |
| - addr_string_bytes = idna.encode(addr_string, uts46=True) |
165 |
| - size = varint.encode(len(addr_string_bytes)) |
166 |
| - return b''.join([size, addr_string_bytes]) |
| 89 | + from .codecs import idna |
| 90 | + return idna.to_bytes(proto, addr_string) |
167 | 91 | else:
|
168 | 92 | raise ValueError("failed to parse %s addr: unknown" % proto.name)
|
169 | 93 |
|
170 | 94 |
|
171 |
| -packed_net_bytes_to_int = None |
172 |
| - |
173 |
| - |
174 | 95 | def address_bytes_to_string(proto, buf):
|
175 |
| - global packed_net_bytes_to_int |
176 |
| - if packed_net_bytes_to_int is None: |
177 |
| - from .util import packed_net_bytes_to_int |
178 |
| - |
179 | 96 | if proto.code == P_IP4:
|
180 |
| - return six.text_type(IPAddress(packed_net_bytes_to_int(buf), 4)) |
| 97 | + from .codecs import ip4 |
| 98 | + return ip4.to_string(proto, buf) |
181 | 99 | elif proto.code == P_IP6:
|
182 |
| - return six.text_type(IPAddress(packed_net_bytes_to_int(buf), 6)) |
| 100 | + from .codecs import ip6 |
| 101 | + return ip6.to_string(proto, buf) |
183 | 102 | elif proto.code in [P_TCP, P_UDP, P_DCCP, P_SCTP]:
|
184 |
| - if len(buf) != 2: |
185 |
| - raise ValueError("Not a uint16") |
186 |
| - return six.text_type(struct.unpack('>H', buf)[0]) |
| 103 | + from .codecs import uint16be |
| 104 | + return uint16be.to_string(proto, buf) |
187 | 105 | elif proto.code == P_ONION:
|
188 |
| - addr_bytes, port_bytes = (buf[:-2], buf[-2:]) |
189 |
| - addr = base64.b32encode(addr_bytes).decode('ascii').lower() |
190 |
| - port = six.text_type(struct.unpack('>H', port_bytes)[0]) |
191 |
| - return u':'.join([addr, port]) |
| 106 | + from .codecs import onion |
| 107 | + return onion.to_string(proto, buf) |
192 | 108 | elif proto.code == P_P2P:
|
193 |
| - size, num_bytes_read = read_varint_code(buf) |
194 |
| - buf = buf[num_bytes_read:] |
195 |
| - if len(buf) != size: |
196 |
| - raise ValueError("inconsistent lengths") |
197 |
| - return base58.b58encode(buf).decode('ascii') |
| 109 | + from .codecs import multihash |
| 110 | + return multihash.to_string(proto, buf) |
198 | 111 | elif proto.code == P_UNIX:
|
199 |
| - size, num_bytes_read = read_varint_code(buf) |
200 |
| - return fsdecode(buf[num_bytes_read:]) |
| 112 | + from .codecs import fspath |
| 113 | + return fspath.to_string(proto, buf) |
201 | 114 | elif proto.code in (P_DNS, P_DNS4, P_DNS6):
|
202 |
| - size, num_bytes_read = read_varint_code(buf) |
203 |
| - return idna.decode(buf[num_bytes_read:]) |
| 115 | + from .codecs import idna |
| 116 | + return idna.to_string(proto, buf) |
204 | 117 | raise ValueError("unknown protocol")
|
205 | 118 |
|
206 | 119 |
|
|
0 commit comments