1 /** 2 * Copyright (c) 2019, 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 <utility> 23 24 #include <android-base/thread_annotations.h> 25 26 #include "base_metrics_listener.h" 27 28 enum ExpectNat64PrefixStatus : bool { 29 EXPECT_FOUND, 30 EXPECT_NOT_FOUND, 31 }; 32 33 namespace android::net::metrics { 34 35 // TODO: Perhaps create a queue to monitor the event changes. That improves the unit test which can 36 // verify the event count, the event change order, and so on. 37 class DnsMetricsListener : public BaseMetricsListener { 38 public: 39 struct DnsEvent { 40 int32_t netId; 41 int32_t eventType; 42 int32_t returnCode; 43 std::string hostname; 44 std::vector<std::string> ipAddresses; 45 int32_t ipAddressesCount; 46 47 bool operator==(const DnsEvent& o) const; 48 49 // Informative for debugging. 50 friend std::ostream& operator<<(std::ostream& os, const DnsEvent& data); 51 }; 52 53 DnsMetricsListener() = delete; DnsMetricsListener(int32_t netId)54 DnsMetricsListener(int32_t netId) : mNetId(netId){}; 55 56 // Override DNS metrics event(s). 57 ::ndk::ScopedAStatus onNat64PrefixEvent(int32_t netId, bool added, 58 const std::string& prefixString, 59 int32_t /*prefixLength*/) override; 60 61 ::ndk::ScopedAStatus onPrivateDnsValidationEvent(int32_t netId, const std::string& ipAddress, 62 const std::string& /*hostname*/, 63 bool validated) override; 64 65 ::ndk::ScopedAStatus onDnsEvent(int32_t netId, int32_t eventType, int32_t returnCode, 66 int32_t /*latencyMs*/, const std::string& hostname, 67 const std::vector<std::string>& ipAddresses, 68 int32_t ipAddressesCount, int32_t /*uid*/) override; 69 70 // Wait for expected NAT64 prefix status until timeout. 71 bool waitForNat64Prefix(ExpectNat64PrefixStatus status, std::chrono::milliseconds timeout) 72 EXCLUDES(mMutex); 73 74 // Returns the number of updates to the NAT64 prefix that have not yet been waited for. getUnexpectedNat64PrefixUpdates()75 int getUnexpectedNat64PrefixUpdates() const EXCLUDES(mMutex) { 76 std::lock_guard lock(mMutex); 77 return mUnexpectedNat64PrefixUpdates; 78 } 79 80 // Wait for the expected private DNS validation result until timeout. 81 bool waitForPrivateDnsValidation(const std::string& serverAddr, const bool validated); 82 83 // Return true if a validation result for |serverAddr| is found; otherwise, return false. 84 // Only exists for testing. findValidationRecord(const std::string & serverAddr)85 bool findValidationRecord(const std::string& serverAddr) const EXCLUDES(mMutex) { 86 std::lock_guard lock(mMutex); 87 return mValidationRecords.find({mNetId, serverAddr}) != mValidationRecords.end(); 88 } 89 90 std::optional<DnsEvent> popDnsEvent() EXCLUDES(mMutex); 91 reset()92 void reset() EXCLUDES(mMutex) { 93 std::lock_guard lock(mMutex); 94 mUnexpectedNat64PrefixUpdates = 0; 95 mValidationRecords.clear(); 96 97 std::queue<DnsEvent> emptyQueue; 98 std::swap(mDnsEventRecords, emptyQueue); 99 } 100 101 private: 102 typedef std::pair<int32_t, std::string> ServerKey; 103 104 // Search mValidationRecords. Return true if |key| exists and its value is equal to 105 // |value|, and then remove it; otherwise, return false. 106 bool findAndRemoveValidationRecord(const ServerKey& key, const bool value) REQUIRES(mMutex); 107 108 // Monitor the event which was fired on specific network id. 109 const int32_t mNetId; 110 111 // The NAT64 prefix of the network |mNetId|. It is updated by the event onNat64PrefixEvent(). 112 std::string mNat64Prefix GUARDED_BY(mMutex); 113 114 // The number of updates to the NAT64 prefix of network |mNetId| that have not yet been waited 115 // for. Increases by 1 every time onNat64PrefixEvent is called, and decreases by 1 every time 116 // waitForNat64Prefix returns true. 117 // This allows tests to check that no unexpected events have been received without having to 118 // resort to timeouts that make the tests slower and flakier. 119 int mUnexpectedNat64PrefixUpdates GUARDED_BY(mMutex); 120 121 // Used to store the data from onPrivateDnsValidationEvent. 122 std::map<ServerKey, bool> mValidationRecords GUARDED_BY(mMutex); 123 124 // Used to store the data from onDnsEvent. 125 std::queue<DnsEvent> mDnsEventRecords GUARDED_BY(mMutex); 126 127 mutable std::mutex mMutex; 128 std::condition_variable mCv; 129 }; 130 131 } // namespace android::net::metrics 132