-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathsystem_resolver.h
93 lines (81 loc) · 3.01 KB
/
system_resolver.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#pragma once
#include "common/defs.h"
#include "common/error.h"
#include "common/coro.h"
#include "dns/common/event_loop.h"
#include <cassert>
#include <ldns/ldns.h>
#include <string_view>
namespace ag::dns {
enum class SystemResolverError {
AE_OK, // No error occurred
AE_RECORD_NOT_FOUND, // The specified record does not exist
AE_DOMAIN_NOT_FOUND, // The specified name does not exist
AE_SYSTEM_RESOLVE_ERROR, // Other errors from DNSService
AE_DECODE_ERROR, // Errors from ldns
AE_INIT_ERROR, // DNSServiceRef could not be created
AE_SHUTTING_DOWN, // Shutting down
AE_TIMED_OUT, // Timed out
};
/**
* The SystemResolver class is used for resolving DNS records using the system resolver.
*/
class SystemResolver {
struct ConstructorAccess {};
public:
/**
* Unique pointer to a list of ldns_rr_list resource records.
*/
using LdnsRrListPtr = ag::UniquePtr<ldns_rr_list, &ldns_rr_list_deep_free>;
/**
* Constructs a SystemResolver for a specific network interface.
* @param if_index Index of the network interface (default is 0, which means any interface).
*/
SystemResolver(ConstructorAccess, EventLoop *loop, Millis timeout, uint32_t if_index = 0);
static Result<std::unique_ptr<SystemResolver>, SystemResolverError> create(EventLoop *loop, Millis timeout, uint32_t if_index);
~SystemResolver();
/**
* Resolves a domain to a list of resource records.
* @param domain Domain to resolve.
* @param rr_type Type of the resource record to resolve.
* @return A unique pointer to a list of resource records.
*/
coro::Task<Result<LdnsRrListPtr, SystemResolverError>>
resolve(std::string_view domain, ldns_rr_type rr_type);
private:
class Impl;
std::unique_ptr<Impl> m_pimpl;
};
} // namespace ag::dns
namespace ag {
template <>
struct ErrorCodeToString<dns::SystemResolverError> {
const char *operator()(dns::SystemResolverError e) {
switch (e) {
case dns::SystemResolverError::AE_OK:
return "No error";
case dns::SystemResolverError::AE_RECORD_NOT_FOUND:
return "No such record";
case dns::SystemResolverError::AE_DOMAIN_NOT_FOUND:
return "No such name";
case dns::SystemResolverError::AE_DECODE_ERROR:
return "LDNS error";
case dns::SystemResolverError::AE_INIT_ERROR:
return "DNSServiceRef could not be created";
case dns::SystemResolverError::AE_SHUTTING_DOWN:
return "Shutting down";
case dns::SystemResolverError::AE_TIMED_OUT:
return "Timed out";
case dns::SystemResolverError::AE_SYSTEM_RESOLVE_ERROR:
return "Other errors from DNSService";
}
}
};
template<>
struct ErrorCodeToString<ldns_status> {
const char *operator()(ldns_status e) {
const char *error_str = ldns_get_errorstr_by_id(e);
return error_str ? error_str : "Unknown error";
}
};
} // namespace ag