Skip to content

Commit 1c5764c

Browse files
authored
Add proper dns-resolving (#73)
* Add proper dns-resolving Signed-off-by: kamilsa <[email protected]>
1 parent 69d4ec5 commit 1c5764c

File tree

4 files changed

+97
-27
lines changed

4 files changed

+97
-27
lines changed

include/libp2p/transport/tcp/tcp_connection.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,23 @@ namespace libp2p::transport {
4444
*/
4545
void resolve(const Tcp::endpoint &endpoint, ResolveCallbackFunc cb);
4646

47+
/**
48+
* @brief Resolve service name (DNS).
49+
* @param host_name host name to resolve
50+
* @param cb callback executed on operation completion.
51+
*/
52+
void resolve(const std::string &host_name, const std::string &port,
53+
ResolveCallbackFunc cb);
54+
55+
/**
56+
* @brief Resolve service name (DNS).
57+
* @param protocol is either Tcp::ip4 or Tcp::ip6 protocol
58+
* @param host_name host name to resolve
59+
* @param cb callback executed on operation completion.
60+
*/
61+
void resolve(const Tcp &protocol, const std::string &host_name,
62+
const std::string &port, ResolveCallbackFunc cb);
63+
4764
/**
4865
* @brief Connect to a remote service.
4966
* @param iterator list of resolved IP addresses of remote service.

include/libp2p/transport/tcp/tcp_util.hpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
#include <boost/asio.hpp>
1313
#include <boost/lexical_cast.hpp>
1414
#include <gsl/span>
15-
#include <libp2p/outcome/outcome.hpp>
1615
#include <libp2p/multi/multiaddress.hpp>
16+
#include <libp2p/outcome/outcome.hpp>
1717

1818
namespace libp2p::transport::detail {
1919
template <typename T>
@@ -56,10 +56,33 @@ namespace libp2p::transport::detail {
5656

5757
inline bool supportsIpTcp(const multi::Multiaddress &ma) {
5858
using P = multi::Protocol::Code;
59-
return (ma.hasProtocol(P::IP4) || ma.hasProtocol(P::IP6))
59+
return (ma.hasProtocol(P::IP4) || ma.hasProtocol(P::IP6)
60+
|| ma.hasProtocol(P::DNS4) || ma.hasProtocol(P::DNS6)
61+
|| ma.hasProtocol(P::DNS))
6062
&& ma.hasProtocol(P::TCP);
6163
}
6264

65+
inline auto getFirstProtocol(const multi::Multiaddress &ma) {
66+
return ma.getProtocolsWithValues().front().first.code;
67+
}
68+
69+
// Obtain host and port strings from provided address
70+
inline std::pair<std::string, std::string> getHostAndTcpPort(
71+
const multi::Multiaddress &address) {
72+
auto v = address.getProtocolsWithValues();
73+
74+
// get host
75+
auto it = v.begin();
76+
auto host = it->second;
77+
78+
// get port
79+
it++;
80+
BOOST_ASSERT(it->first.code == multi::Protocol::Code::TCP);
81+
auto port = it->second;
82+
83+
return {host, port};
84+
}
85+
6386
inline outcome::result<boost::asio::ip::tcp::endpoint> makeEndpoint(
6487
const multi::Multiaddress &ma) {
6588
using P = multi::Protocol::Code;

src/transport/tcp/tcp_connection.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,29 @@ namespace libp2p::transport {
6464
});
6565
}
6666

67+
void TcpConnection::resolve(const std::string &host_name,
68+
const std::string &port,
69+
TcpConnection::ResolveCallbackFunc cb) {
70+
auto resolver = std::make_shared<Tcp::resolver>(context_);
71+
resolver->async_resolve(
72+
host_name, port,
73+
[resolver, cb{std::move(cb)}](const ErrorCode &ec, auto &&iterator) {
74+
cb(ec, std::forward<decltype(iterator)>(iterator));
75+
});
76+
}
77+
78+
void TcpConnection::resolve(const TcpConnection::Tcp &protocol,
79+
const std::string &host_name,
80+
const std::string &port,
81+
TcpConnection::ResolveCallbackFunc cb) {
82+
auto resolver = std::make_shared<Tcp::resolver>(context_);
83+
resolver->async_resolve(
84+
protocol, host_name, port,
85+
[resolver, cb{std::move(cb)}](const ErrorCode &ec, auto &&iterator) {
86+
cb(ec, std::forward<decltype(iterator)>(iterator));
87+
});
88+
}
89+
6790
void TcpConnection::connect(
6891
const TcpConnection::ResolverResultsType &iterator,
6992
TcpConnection::ConnectCallbackFunc cb) {

src/transport/tcp/tcp_transport.cpp

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,32 +17,39 @@ namespace libp2p::transport {
1717
}
1818

1919
auto conn = std::make_shared<TcpConnection>(*context_);
20-
auto rendpoint = detail::makeEndpoint(address);
21-
if (!rendpoint) {
22-
return handler(rendpoint.error());
23-
}
2420

25-
conn->resolve(rendpoint.value(),
26-
[self{shared_from_this()}, conn, handler{std::move(handler)},
27-
remoteId](auto ec, auto r) mutable {
28-
if (ec) {
29-
return handler(ec);
30-
}
31-
32-
conn->connect(
33-
r,
34-
[self, conn, handler{std::move(handler)}, remoteId](
35-
auto ec, auto &e) mutable {
36-
if (ec) {
37-
return handler(ec);
38-
}
39-
40-
auto session = std::make_shared<UpgraderSession>(
41-
self->upgrader_, std::move(conn), handler);
42-
43-
session->secureOutbound(remoteId);
44-
});
45-
});
21+
auto [host, port] = detail::getHostAndTcpPort(address);
22+
23+
auto connect = [self{shared_from_this()}, conn, handler{std::move(handler)},
24+
remoteId](auto ec, auto r) mutable {
25+
if (ec) {
26+
return handler(ec);
27+
}
28+
29+
conn->connect(r,
30+
[self, conn, handler{std::move(handler)}, remoteId](
31+
auto ec, auto &e) mutable {
32+
if (ec) {
33+
return handler(ec);
34+
}
35+
36+
auto session = std::make_shared<UpgraderSession>(
37+
self->upgrader_, std::move(conn), handler);
38+
39+
session->secureOutbound(remoteId);
40+
});
41+
};
42+
43+
using P = multi::Protocol::Code;
44+
switch (detail::getFirstProtocol(address)) {
45+
case P::DNS4:
46+
return conn->resolve(boost::asio::ip::tcp::v4(), host, port, connect);
47+
case P::DNS6:
48+
return conn->resolve(boost::asio::ip::tcp::v6(), host, port, connect);
49+
default: // Could be only DNS, IP6 or IP4 as canDial already checked for
50+
// that in the beginning of the method
51+
return conn->resolve(host, port, connect);
52+
}
4653
}
4754

4855
std::shared_ptr<TransportListener> TcpTransport::createListener(

0 commit comments

Comments
 (0)