1/*
2 * IXDNSLookup.h
3 * Author: Benjamin Sergeant
4 * Copyright (c) 2018 Machine Zone, Inc. All rights reserved.
5 *
6 * Resolve a hostname+port to a struct addrinfo obtained with getaddrinfo
7 * Does this in a background thread so that it can be cancelled, since
8 * getaddrinfo is a blocking call, and we don't want to block the main thread on Mobile.
9 */
10
11#pragma once
12
13#include "IXCancellationRequest.h"
14#include <atomic>
15#include <memory>
16#include <mutex>
17#include <set>
18#include <string>
19
20struct addrinfo;
21
22namespace ix
23{
24 class DNSLookup : public std::enable_shared_from_this<DNSLookup>
25 {
26 public:
27 DNSLookup(const std::string& hostname, int port, int64_t wait = DNSLookup::kDefaultWait);
28 ~DNSLookup() = default;
29
30 struct addrinfo* resolve(std::string& errMsg,
31 const CancellationRequest& isCancellationRequested,
32 bool cancellable = true);
33
34 void release(struct addrinfo* addr);
35
36 private:
37 struct addrinfo* resolveCancellable(std::string& errMsg,
38 const CancellationRequest& isCancellationRequested);
39 struct addrinfo* resolveUnCancellable(std::string& errMsg,
40 const CancellationRequest& isCancellationRequested);
41
42 static struct addrinfo* getAddrInfo(const std::string& hostname,
43 int port,
44 std::string& errMsg);
45
46 void run(std::weak_ptr<DNSLookup> self, std::string hostname, int port); // thread runner
47
48 void setErrMsg(const std::string& errMsg);
49 const std::string& getErrMsg();
50
51 void setRes(struct addrinfo* addr);
52 struct addrinfo* getRes();
53
54 std::string _hostname;
55 int _port;
56 int64_t _wait;
57 const static int64_t kDefaultWait;
58
59 struct addrinfo* _res;
60 std::mutex _resMutex;
61
62 std::string _errMsg;
63 std::mutex _errMsgMutex;
64
65 std::atomic<bool> _done;
66 };
67} // namespace ix
68