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 18 #include "DnsQueryLog.h" 19 20 #include "util.h" 21 22 namespace android::net { 23 24 namespace { 25 26 std::string maskHostname(const std::string& hostname) { 27 // Boundary issue is handled in substr(). 28 return hostname.substr(0, 1) + "***"; 29 } 30 31 // Return the string of masked addresses of the first v4 address and the first v6 address. 32 std::string maskIps(const std::vector<std::string>& ips) { 33 std::string ret; 34 bool v4Found = false, v6Found = false; 35 for (const auto& ip : ips) { 36 if (auto pos = ip.find_first_of(':'); pos != ip.npos && !v6Found) { 37 ret += ip.substr(0, pos + 1) + "***, "; 38 v6Found = true; 39 } else if (auto pos = ip.find_first_of('.'); pos != ip.npos && !v4Found) { 40 ret += ip.substr(0, pos + 1) + "***, "; 41 v4Found = true; 42 } 43 if (v6Found && v4Found) break; 44 } 45 return ret.empty() ? "" : ret.substr(0, ret.length() - 2); 46 } 47 48 } // namespace 49 50 void DnsQueryLog::push(Record&& record) { 51 mQueue.push(std::move(record)); 52 } 53 54 void DnsQueryLog::dump(netdutils::DumpWriter& dw) const { 55 dw.println("DNS query log (last %lld minutes):", (mValidityTimeMs / 60000).count()); 56 netdutils::ScopedIndent indentStats(dw); 57 const auto now = std::chrono::system_clock::now(); 58 59 for (const auto& record : mQueue.copy()) { 60 if (now - record.timestamp > mValidityTimeMs) continue; 61 62 const std::string maskedHostname = maskHostname(record.hostname); 63 const std::string maskedIpsStr = maskIps(record.addrs); 64 const std::string time = timestampToString(record.timestamp); 65 dw.println("time=%s netId=%u uid=%u pid=%d hostname=%s answer=[%s] (%dms)", time.c_str(), 66 record.netId, record.uid, record.pid, maskedHostname.c_str(), 67 maskedIpsStr.c_str(), record.timeTaken); 68 } 69 } 70 71 } // namespace android::net 72