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