-
Notifications
You must be signed in to change notification settings - Fork 0
/
Dns64Configuration.h
133 lines (108 loc) · 4.93 KB
/
Dns64Configuration.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DNS_DNS64CONFIGURATION_H_
#define DNS_DNS64CONFIGURATION_H_
#include <netinet/in.h>
#include <condition_variable>
#include <cstdlib>
#include <mutex>
#include <unordered_map>
#include <android-base/thread_annotations.h>
#include <netdutils/DumpWriter.h>
#include <netdutils/InternetAddresses.h>
struct android_net_context;
namespace android {
namespace net {
/**
* This class handles RFC 7050 -style DNS64 prefix discovery.
*
* The ResolverController starts DNS64 prefix discovery when it observes a
* a network with only IPv6 nameservers. (It stops discovery whenever an IPv4
* nameserver is added or the network is deleted.)
*
* Each time prefix discovery is started, a new discoveryId is generated so
* that running resolution threads can notice they are no longer the most
* recent resolution attempt. This results in the backoff schedule of resolution
* being reset.
*
* Thread-safety: All public methods in this class MUST be thread-safe.
* (In other words: this class handles all its locking privately.)
*/
class Dns64Configuration {
public:
// Simple data struct for passing back packet NAT64 prefix event information to the
// Dns64PrefixCallback callback.
struct Nat64PrefixInfo {
unsigned netId;
bool added;
std::string prefixString;
uint8_t prefixLength;
};
// Callback that is triggered for every NAT64 prefix event.
using Nat64PrefixCallback = std::function<void(const Nat64PrefixInfo&)>;
using GetNetworkContextCallback = std::function<void(uint32_t, uint32_t, android_net_context*)>;
// Parameters from RFC 7050 section 8.
static const char kIPv4OnlyHost[]; // "ipv4only.arpa."
static const char kIPv4Literal1[]; // 192.0.0.170
static const char kIPv4Literal2[]; // 192.0.0.171
Dns64Configuration() = delete;
Dns64Configuration(GetNetworkContextCallback getNetworkCallback,
Nat64PrefixCallback prefixCallback)
: mGetNetworkContextCallback(std::move(getNetworkCallback)),
mPrefixCallback(std::move(prefixCallback)) {}
Dns64Configuration(const Dns64Configuration&) = delete;
Dns64Configuration(Dns64Configuration&&) = delete;
Dns64Configuration& operator=(const Dns64Configuration&) = delete;
Dns64Configuration& operator=(Dns64Configuration&&) = delete;
void startPrefixDiscovery(unsigned netId);
void stopPrefixDiscovery(unsigned netId);
netdutils::IPPrefix getPrefix64(unsigned netId) const;
int setPrefix64(unsigned netId, const netdutils::IPPrefix& pfx) EXCLUDES(mMutex);
int clearPrefix64(unsigned netId) EXCLUDES(mMutex);
void dump(netdutils::DumpWriter& dw, unsigned netId);
private:
struct Dns64Config {
Dns64Config(unsigned pseudoRandomId, unsigned network)
: discoveryId(pseudoRandomId), netId(network) {}
// ID of the discovery operation, or kNoDiscoveryId if no discovery was performed (i.e., the
// prefix was discovered and passed in via setPrefix64).
const unsigned int discoveryId;
const unsigned int netId;
netdutils::IPPrefix prefix64{};
bool isFromPrefixDiscovery() const { return discoveryId != kNoDiscoveryId; }
};
static constexpr int kNoDiscoveryId = 0;
enum { PREFIX_REMOVED, PREFIX_ADDED };
static bool doRfc7050PrefixDiscovery(const android_net_context& netcontext, Dns64Config* cfg);
// Picks the next discovery ID. Never returns kNoDiscoveryId.
unsigned getNextId() REQUIRES(mMutex) { return ++mNextId ? mNextId : ++mNextId; }
netdutils::IPPrefix getPrefix64Locked(unsigned netId) const REQUIRES(mMutex);
bool isDiscoveryInProgress(const Dns64Config& cfg) const REQUIRES(mMutex);
bool reportNat64PrefixStatus(unsigned netId, bool added, const netdutils::IPPrefix& pfx)
REQUIRES(mMutex);
bool shouldContinueDiscovery(const Dns64Config& cfg);
void recordDns64Config(const Dns64Config& cfg);
void removeDns64Config(unsigned netId) REQUIRES(mMutex);
mutable std::mutex mMutex;
std::condition_variable mCv;
unsigned int mNextId GUARDED_BY(mMutex);
std::unordered_map<unsigned, Dns64Config> mDns64Configs GUARDED_BY(mMutex);
const GetNetworkContextCallback mGetNetworkContextCallback;
const Nat64PrefixCallback mPrefixCallback;
};
} // namespace net
} // namespace android
#endif // DNS_DNS64CONFIGURATION_H_