Skip to content

Commit 2c23ef1

Browse files
authored
Fix DNS and IPFS for Multiaddr (#43)
* Add DNS processing to multiaddr * Fix IPFS resolution in multiaddr * Fix comment about IPFS/P2P in multiaddr
1 parent 67c7518 commit 2c23ef1

File tree

9 files changed

+91
-12
lines changed

9 files changed

+91
-12
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#ifndef LIBP2P_DNS_CONVERTER_HPP
7+
#define LIBP2P_DNS_CONVERTER_HPP
8+
9+
#include <libp2p/outcome/outcome.hpp>
10+
11+
namespace libp2p::multi::converters {
12+
13+
/**
14+
* Converts a DNS part of a multiaddress (a hostname)
15+
* to bytes representation as a hex string
16+
*/
17+
class DnsConverter {
18+
public:
19+
static auto addressToHex(std::string_view addr)
20+
-> outcome::result<std::string>;
21+
};
22+
23+
} // namespace libp2p::multi::converters
24+
25+
#endif // LIBP2P_DNS_CONVERTER_HPP

include/libp2p/multi/multiaddress_protocol_list.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ namespace libp2p::multi {
7878
* otherwise
7979
*/
8080
static constexpr auto get(std::string_view name) -> Protocol const * {
81+
if(name == "ipfs") {
82+
name = "p2p"; // IPFS is a legacy name, P2P is the preferred one
83+
}
8184
for (Protocol const &protocol : protocols_) {
8285
if (protocol.name == name) {
8386
return &protocol;
@@ -120,15 +123,15 @@ namespace libp2p::multi {
120123
{Protocol::Code::IP6, 128, "ip6"},
121124
{Protocol::Code::IP6_ZONE, Protocol::kVarLen, "ip6zone"},
122125
{Protocol::Code::DNS, Protocol::kVarLen, "dns"},
123-
{Protocol::Code::DNS4, Protocol::kVarLen, "dns64"},
126+
{Protocol::Code::DNS4, Protocol::kVarLen, "dns4"},
124127
{Protocol::Code::DNS6, Protocol::kVarLen, "dns6"},
125128
{Protocol::Code::DNS_ADDR, Protocol::kVarLen, "dnsaddr"},
126129
{Protocol::Code::SCTP, 16, "sctp"},
127130
{Protocol::Code::UDT, 0, "udt"},
128131
{Protocol::Code::UTP, 0, "utp"},
129132
{Protocol::Code::UNIX, Protocol::kVarLen, "unix"},
130-
// {Protocol::Code::P2P, Protocol::kVarLen, "p2p"},
131-
{Protocol::Code::P2P, Protocol::kVarLen, "ipfs"},
133+
{Protocol::Code::P2P, Protocol::kVarLen, "p2p"},
134+
// Also P2P protocol may have a legacy name "ipfs"
132135
{Protocol::Code::ONION, 96, "onion"},
133136
{Protocol::Code::ONION3, 296, "onion3"},
134137
{Protocol::Code::GARLIC64, Protocol::kVarLen, "garlic64"},

src/multi/converters/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ libp2p_add_library(p2p_converters
1111
tcp_converter.cpp
1212
udp_converter.cpp
1313
ipfs_converter.cpp
14+
dns_converter.cpp
1415
)
1516
target_link_libraries(p2p_converters
1617
Boost::boost

src/multi/converters/converter_utils.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <libp2p/multi/converters/ip_v4_converter.hpp>
1515
#include <libp2p/multi/converters/ip_v6_converter.hpp>
1616
#include <libp2p/multi/converters/ipfs_converter.hpp>
17+
#include <libp2p/multi/converters/dns_converter.hpp>
1718
#include <libp2p/multi/converters/tcp_converter.hpp>
1819
#include <libp2p/multi/converters/udp_converter.hpp>
1920
#include <libp2p/multi/multiaddress_protocol_list.hpp>
@@ -89,12 +90,14 @@ namespace libp2p::multi::converters {
8990
case Protocol::Code::P2P:
9091
return IpfsConverter::addressToHex(addr);
9192

92-
case Protocol::Code::IP6_ZONE:
9393
case Protocol::Code::DNS:
9494
case Protocol::Code::DNS4:
9595
case Protocol::Code::DNS6:
9696
case Protocol::Code::DNS_ADDR:
9797
case Protocol::Code::UNIX:
98+
return DnsConverter::addressToHex(addr);
99+
100+
case Protocol::Code::IP6_ZONE:
98101
case Protocol::Code::ONION3:
99102
case Protocol::Code::GARLIC64:
100103
case Protocol::Code::QUIC:
@@ -127,7 +130,7 @@ namespace libp2p::multi::converters {
127130
return ConversionError::NO_SUCH_PROTOCOL;
128131
}
129132

130-
if (protocol->name != "ipfs") {
133+
if (protocol->name != "ipfs" and protocol->name != "p2p") {
131134
lastpos = lastpos
132135
+ UVarint::calculateSize(pid_bytes.subspan(lastpos / 2)) * 2;
133136
std::string address;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include <libp2p/multi/converters/dns_converter.hpp>
7+
8+
#include <libp2p/common/hexutil.hpp>
9+
#include <libp2p/multi/uvarint.hpp>
10+
11+
namespace libp2p::multi::converters {
12+
13+
auto DnsConverter::addressToHex(std::string_view addr)
14+
-> outcome::result<std::string> {
15+
std::vector<uint8_t> bytes(addr.size());
16+
std::copy(addr.begin(), addr.end(), bytes.begin());
17+
auto hex = common::hex_lower(bytes);
18+
return UVarint{bytes.size()}.toHex() + hex;
19+
}
20+
}

src/multi/multiaddress.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,17 @@ namespace libp2p::multi {
127127
bool Multiaddress::decapsulateStringFromAddress(std::string_view proto,
128128
const ByteBuffer &bytes) {
129129
auto str_pos = stringified_address_.rfind(proto);
130+
if (proto == "/p2p" or proto == "/ipfs") {
131+
auto alt_pos =
132+
stringified_address_.rfind(proto == "/ipfs" ? "/p2p" : "/ipfs");
133+
if (alt_pos != std::string::npos) {
134+
if(str_pos == std::string::npos) {
135+
str_pos = alt_pos;
136+
} else {
137+
str_pos = std::max(str_pos, alt_pos);
138+
}
139+
}
140+
}
130141
if (str_pos == std::string::npos) {
131142
return false;
132143
}
@@ -167,6 +178,12 @@ namespace libp2p::multi {
167178
auto proto_str = "/"s + std::string(protocol->name);
168179
auto proto_positions =
169180
findSubstringOccurrences(stringified_address_, proto_str);
181+
if (proto == Protocol::Code::P2P) { // ipfs and p2p are equivalent
182+
auto ipfs_occurences =
183+
findSubstringOccurrences(stringified_address_, "/ipfs"s);
184+
proto_positions.insert(proto_positions.end(), ipfs_occurences.begin(),
185+
ipfs_occurences.end());
186+
}
170187

171188
for (const auto &pos : proto_positions) {
172189
auto value_pos = stringified_address_.find_first_of('/', pos + 1) + 1;

test/libp2p/multi/multiaddress_test.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,7 @@ class MultiaddressTest : public ::testing::Test {
3838
* @then creation succeeds
3939
*/
4040
TEST_F(MultiaddressTest, CreateFromStringValid) {
41-
auto result = Multiaddress::create(valid_ip_udp);
42-
ASSERT_TRUE(result);
43-
auto &&address = result.value();
41+
EXPECT_OUTCOME_TRUE(address, Multiaddress::create(valid_ip_udp));
4442
ASSERT_EQ(address.getStringAddress(), valid_ip_udp);
4543
ASSERT_EQ(address.getBytesAddress(), valid_ip_udp_bytes);
4644
}
@@ -245,3 +243,15 @@ TEST_F(MultiaddressTest, GetProtocolsWithValues) {
245243
std::make_pair(*ProtocolList::get("ip4"), "127.0.0.1"),
246244
std::make_pair(*ProtocolList::get("udp"), "3232")));
247245
}
246+
247+
/**
248+
* @given a multiaddr containing DNS and P2P entries
249+
* @when parsing it
250+
* @then it is accepted
251+
*/
252+
TEST_F(MultiaddressTest, DnsAndIpfs) {
253+
auto addr = "/dns4/kusama-bootnode-1.paritytech.net/tcp/30333/p2p/QmV32G18YzenpNFmhqg2n7TtdjYRK7oU6FhLbDL4oRgsbe"s;
254+
EXPECT_OUTCOME_TRUE(address, Multiaddress::create(addr));
255+
ASSERT_EQ(address.getStringAddress(), addr);
256+
257+
}

test/libp2p/multi/utils/string_from_to_bytes_test.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,19 +79,19 @@ TEST(AddressConverter, BytesToString) {
7979
VALID_BYTES_TO_STR("/udp/1234", "910204D2")
8080
VALID_BYTES_TO_STR("/tcp/1234", "0604D2")
8181
VALID_BYTES_TO_STR(
82-
"/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234",
82+
"/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234",
8383
"A503221220D52EBB89D85B02A284948203A62FF28389C57C9F42BEEC4EC20DB76A68911C"
8484
"0B0604D2")
8585
VALID_BYTES_TO_STR("/ip4/127.0.0.1/udp/1234", "047F000001910204D2")
8686
VALID_BYTES_TO_STR("/ip4/127.0.0.1/udp/0", "047F00000191020000")
8787
VALID_BYTES_TO_STR("/ip4/127.0.0.1/tcp/1234/udp/0/udp/1234",
8888
"047F0000010604D291020000910204D2")
8989
VALID_BYTES_TO_STR(
90-
"/ip4/127.0.0.1/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC",
90+
"/ip4/127.0.0.1/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC",
9191
"047F000001A503221220D52EBB89D85B02A284948203A62FF28389C57C9F42BEEC4EC20D"
9292
"B76A68911C0B")
9393
VALID_BYTES_TO_STR(
94-
"/ip4/127.0.0.1/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/"
94+
"/ip4/127.0.0.1/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/"
9595
"1234",
9696
"047F000001A503221220D52EBB89D85B02A284948203A62FF28389C57C9F42BEEC4EC20D"
9797
"B76A68911C0B0604D2")

test/libp2p/peer/peer_address_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class PeerAddressTest : public ::testing::Test {
3636
Multiaddress::create("/ip4/192.168.0.1/tcp/228").value();
3737

3838
const std::string kaddressString =
39-
std::string{kDefaultAddress.getStringAddress()} + "/ipfs/"
39+
std::string{kDefaultAddress.getStringAddress()} + "/p2p/"
4040
+ kEncodedDefaultPeerId;
4141
};
4242

0 commit comments

Comments
 (0)