aboutsummaryrefslogtreecommitdiffhomepage
path: root/tdnet/td/net/GetHostByNameActor.cpp
diff options
context:
space:
mode:
authorArseny Smirnov <arseny30@gmail.com>2019-01-24 13:47:54 +0400
committerArseny Smirnov <arseny30@gmail.com>2019-01-24 13:47:54 +0400
commitdd190c7d7932abfac6449f508312c67833b96f6a (patch)
tree1e2fbf1c9d69547e14e647e6b1b515239bc53128 /tdnet/td/net/GetHostByNameActor.cpp
parentfc3717109dfcaeb626435e8246e8af3df09f1827 (diff)
DnsOverHttps class with a test
GitOrigin-RevId: 4f8785377ddbe47a59fe6e03628685902503e1f6
Diffstat (limited to 'tdnet/td/net/GetHostByNameActor.cpp')
-rw-r--r--tdnet/td/net/GetHostByNameActor.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/tdnet/td/net/GetHostByNameActor.cpp b/tdnet/td/net/GetHostByNameActor.cpp
index c98d366d2..9cd33a5b8 100644
--- a/tdnet/td/net/GetHostByNameActor.cpp
+++ b/tdnet/td/net/GetHostByNameActor.cpp
@@ -8,8 +8,57 @@
#include "td/utils/logging.h"
#include "td/utils/Time.h"
+#include "td/utils/JsonBuilder.h"
+#include "td/net/Wget.h"
namespace td {
+namespace detail {
+class GoogleDnsResolver : public Actor {
+ public:
+ GoogleDnsResolver(std::string host, int port, bool prefer_ipv6, td::Promise<td::IPAddress> promise) {
+ const int timeout = 10;
+ const int ttl = 3;
+ wget_ = create_actor<Wget>(
+ "Wget", create_result_handler(std::move(promise), port),
+ PSTRING() << "https://www.google.com/resolve?name=" << url_encode(host) << "&type=" << (prefer_ipv6 ? 28 : 1),
+ std::vector<std::pair<string, string>>({{"Host", "dns.google.com"}}), timeout, ttl, prefer_ipv6,
+ SslStream::VerifyPeer::Off);
+ }
+
+ private:
+ ActorOwn<Wget> wget_;
+
+ Promise<HttpQueryPtr> create_result_handler(Promise<IPAddress> promise, int port) {
+ return PromiseCreator::lambda([promise = std::move(promise), port](Result<HttpQueryPtr> r_http_query) mutable {
+ promise.set_result([&]() -> Result<IPAddress> {
+ TRY_RESULT(http_query, std::move(r_http_query));
+ LOG(ERROR) << *http_query;
+ TRY_RESULT(json_value, json_decode(http_query->content_));
+ if (json_value.type() != JsonValue::Type::Object) {
+ return Status::Error("Failed to parse dns result: not an object");
+ }
+ TRY_RESULT(answer, get_json_object_field(json_value.get_object(), "Answer", JsonValue::Type::Array, false));
+ if (answer.get_array().size() == 0) {
+ return Status::Error("Failed to parse dns result: Answer is an empty array");
+ }
+ if (answer.get_array()[0].type() != JsonValue::Type::Object) {
+ return Status::Error("Failed to parse dns result: Answer[0] is not an object");
+ }
+ auto &answer_0 = answer.get_array()[0].get_object();
+ TRY_RESULT(ip_str, get_json_object_string_field(answer_0, "data", false));
+ IPAddress ip;
+ TRY_STATUS(ip.init_host_port(ip_str, port));
+ return ip;
+ }());
+ });
+ }
+};
+} // namespace detail
+
+ActorOwn<> DnsOverHttps::resolve(std::string host, int port, bool prefer_ipv6, td::Promise<td::IPAddress> promise) {
+ return ActorOwn<>(create_actor<detail::GoogleDnsResolver>("GoogleDnsResolver", std::move(host), port, prefer_ipv6,
+ std::move(promise)));
+}
GetHostByNameActor::GetHostByNameActor(int32 ok_timeout, int32 error_timeout)
: ok_timeout_(ok_timeout), error_timeout_(error_timeout) {