1 /**
2  * Copyright (c) 2021, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <condition_variable>
20 #include <map>
21 #include <queue>
22 #include <string>
23 #include <utility>
24 
25 #include <aidl/android/net/resolv/aidl/BnDnsResolverUnsolicitedEventListener.h>
26 #include <android-base/result.h>
27 #include <android-base/thread_annotations.h>
28 
29 namespace android::net::resolv::aidl {
30 
31 class UnsolicitedEventListener
32     : public ::aidl::android::net::resolv::aidl::BnDnsResolverUnsolicitedEventListener {
33   public:
34     UnsolicitedEventListener() = delete;
UnsolicitedEventListener(int32_t netId)35     UnsolicitedEventListener(int32_t netId) : mNetId(netId){};
36     ~UnsolicitedEventListener() = default;
37 
38     ::ndk::ScopedAStatus onDnsHealthEvent(
39             const ::aidl::android::net::resolv::aidl::DnsHealthEventParcel&) override;
40     ::ndk::ScopedAStatus onNat64PrefixEvent(
41             const ::aidl::android::net::resolv::aidl::Nat64PrefixEventParcel&) override;
42     ::ndk::ScopedAStatus onPrivateDnsValidationEvent(
43             const ::aidl::android::net::resolv::aidl::PrivateDnsValidationEventParcel&) override;
44 
45     // Wait for the expected private DNS validation result until timeout.
46     bool waitForPrivateDnsValidation(const std::string& serverAddr, int validation, int protocol);
47 
48     // Wait for expected NAT64 prefix operation until timeout.
49     bool waitForNat64Prefix(int operation, const std::chrono::milliseconds& timeout)
50             EXCLUDES(mMutex);
51 
52     // Pop up last receiving dns health result.
53     android::base::Result<int> popDnsHealthResult() EXCLUDES(mMutex);
54 
55     // Return true if a validation result for |serverAddr| is found; otherwise, return false.
findValidationRecord(const std::string & serverAddr,int protocol)56     bool findValidationRecord(const std::string& serverAddr, int protocol) const EXCLUDES(mMutex) {
57         std::lock_guard lock(mMutex);
58         return mValidationRecords.find({mNetId, serverAddr, protocol}) != mValidationRecords.end();
59     }
60 
61     // Returns the number of updates to the NAT64 prefix that have not yet been waited for.
getUnexpectedNat64PrefixUpdates()62     int getUnexpectedNat64PrefixUpdates() const EXCLUDES(mMutex) {
63         std::lock_guard lock(mMutex);
64         return mUnexpectedNat64PrefixUpdates;
65     }
66 
reset()67     void reset() EXCLUDES(mMutex) {
68         std::lock_guard lock(mMutex);
69         mValidationRecords.clear();
70         mUnexpectedNat64PrefixUpdates = 0;
71 
72         std::queue<int> emptyQueue;
73         std::swap(mDnsHealthResultRecords, emptyQueue);
74     }
75 
76   private:
77     //  Stores (netId, ipAddress, protocol) from onPrivateDnsValidationEvent.
78     using ServerKey = std::tuple<int, std::string, int>;
79 
80     // Search mValidationRecords. Return true if |key| exists and its value is equal to
81     // |value|, and then remove it; otherwise, return false.
82     bool findAndRemoveValidationRecord(const ServerKey& key, int value) REQUIRES(mMutex);
83 
84     // Monitor the event which was fired on specific network id.
85     const int32_t mNetId;
86 
87     // Used to store the data from onPrivateDnsValidationEvent.
88     std::map<ServerKey, int> mValidationRecords GUARDED_BY(mMutex);
89 
90     // The NAT64 prefix address of the network |mNetId|. It is updated by onNat64PrefixEvent().
91     std::string mNat64PrefixAddress GUARDED_BY(mMutex);
92 
93     // The number of updates to the NAT64 prefix of network |mNetId| that have not yet been waited
94     // for. Increases by 1 every time onNat64PrefixEvent is called, and decreases by 1 every time
95     // waitForNat64Prefix returns true.
96     // This allows tests to check that no unexpected events have been received without having to
97     // resort to timeouts that make the tests slower and flakier.
98     int mUnexpectedNat64PrefixUpdates GUARDED_BY(mMutex);
99 
100     // Used to store the dns health result from onDnsHealthEvent().
101     std::queue<int> mDnsHealthResultRecords GUARDED_BY(mMutex);
102 
103     mutable std::mutex mMutex;
104     std::condition_variable mCv;
105 };
106 
107 }  // namespace android::net::resolv::aidl
108