15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/at_exit.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/cancelable_callback.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/file_util.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 149ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/strings/string_split.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/address_list.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/ip_endpoint.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/dns/dns_client.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/dns/dns_config_service.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/dns/dns_protocol.h" 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/dns/host_cache.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/host_resolver_impl.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/gdig/file_net_log.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/scoped_nsautorelease_pool.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StringToIPEndPoint(const std::string& ip_address_and_port, 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPEndPoint* ip_end_point) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ip_end_point); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string ip; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int port; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ParseHostAndPort(ip_address_and_port, &ip, &port)) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (port == -1) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) port = dns_protocol::kDefaultPort; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::IPAddressNumber ip_number; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!net::ParseIPLiteralToNumber(ip, &ip_number)) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ip_end_point = net::IPEndPoint(ip_number, port); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convert DnsConfig to human readable text omitting the hosts member. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string DnsConfigToString(const DnsConfig& dns_config) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string output; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.append("search "); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < dns_config.search.size(); ++i) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.append(dns_config.search[i] + " "); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.append("\n"); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < dns_config.nameservers.size(); ++i) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.append("nameserver "); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.append(dns_config.nameservers[i].ToString()).append("\n"); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&output, "options ndots:%d\n", dns_config.ndots); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&output, "options timeout:%d\n", 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(dns_config.timeout.InMilliseconds())); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&output, "options attempts:%d\n", dns_config.attempts); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dns_config.rotate) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.append("options rotate\n"); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dns_config.edns0) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.append("options edns0\n"); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return output; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convert DnsConfig hosts member to a human readable text. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string DnsHostsToString(const DnsHosts& dns_hosts) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string output; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (DnsHosts::const_iterator i = dns_hosts.begin(); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != dns_hosts.end(); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DnsHostsKey& key = i->first; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string host_name = key.first; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.append(IPEndPoint(i->second, -1).ToStringWithoutPort()); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.append(" ").append(host_name).append("\n"); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return output; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ReplayLogEntry { 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta start_time; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string domain_name; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef std::vector<ReplayLogEntry> ReplayLog; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Loads and parses a replay log file and fills |replay_log| with a structured 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// representation. Returns whether the operation was successful. If not, the 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// contents of |replay_log| are undefined. 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The replay log is a text file where each line contains 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// timestamp_in_milliseconds domain_name 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The timestamp_in_milliseconds needs to be an integral delta from start of 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// resolution and is in milliseconds. domain_name is the name to be resolved. 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The file should be sorted by timestamp in ascending time. 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool LoadReplayLog(const base::FilePath& file_path, ReplayLog* replay_log) { 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string original_replay_log_contents; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!file_util::ReadFileToString(file_path, &original_replay_log_contents)) { 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fprintf(stderr, "Unable to open replay file %s\n", 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_path.MaybeAsASCII().c_str()); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Strip out \r characters for Windows files. This isn't as efficient as a 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // smarter line splitter, but this particular use does not need to target 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // efficiency. 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string replay_log_contents; 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RemoveChars(original_replay_log_contents, "\r", &replay_log_contents); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> lines; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SplitString(replay_log_contents, '\n', &lines); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta previous_delta; 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool bad_parse = false; 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned i = 0; i < lines.size(); ++i) { 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (lines[i].empty()) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> time_and_name; 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SplitString(lines[i], ' ', &time_and_name); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (time_and_name.size() != 2) { 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fprintf( 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stderr, 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "[%s %u] replay log should have format 'timestamp domain_name\\n'\n", 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_path.MaybeAsASCII().c_str(), 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) i + 1); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bad_parse = true; 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 delta_in_milliseconds; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!base::StringToInt64(time_and_name[0], &delta_in_milliseconds)) { 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fprintf( 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stderr, 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "[%s %u] replay log should have format 'timestamp domain_name\\n'\n", 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_path.MaybeAsASCII().c_str(), 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) i + 1); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bad_parse = true; 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta delta = 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromMilliseconds(delta_in_milliseconds); 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (delta < previous_delta) { 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fprintf( 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stderr, 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "[%s %u] replay log should be sorted by time\n", 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_path.MaybeAsASCII().c_str(), 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) i + 1); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bad_parse = true; 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) previous_delta = delta; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReplayLogEntry entry; 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry.start_time = delta; 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry.domain_name = time_and_name[1]; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) replay_log->push_back(entry); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return !bad_parse; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GDig { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GDig(); 185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ~GDig(); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum Result { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RESULT_NO_RESOLVE = -3, 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RESULT_NO_CONFIG = -2, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RESULT_WRONG_USAGE = -1, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RESULT_OK = 0, 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RESULT_PENDING = 1, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Result Main(int argc, const char* argv[]); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ParseCommandLine(int argc, const char* argv[]); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Start(); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Finish(Result); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnDnsConfig(const DnsConfig& dns_config_const); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void OnResolveComplete(unsigned index, AddressList* address_list, 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta time_since_start, int val); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnTimeout(); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ReplayNextEntry(); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta config_timeout_; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool print_config_; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool print_hosts_; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::IPEndPoint nameserver_; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta timeout_; 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int parallellism_; 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReplayLog replay_log_; 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned replay_log_index_; 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time start_time_; 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int active_resolves_; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Result result_; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::CancelableClosure timeout_closure_; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DnsConfigService> dns_config_service_; 223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<FileNetLogObserver> log_observer_; 224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<NetLog> log_; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HostResolver> resolver_; 226ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 227ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if defined(OS_MACOSX) 228ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Without this there will be a mem leak on osx. 229ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::mac::ScopedNSAutoreleasePool scoped_pool_; 230ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif 231ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 232ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Need AtExitManager to support AsWeakPtr (in NetLog). 233ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::AtExitManager exit_manager_; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GDig::GDig() 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : config_timeout_(base::TimeDelta::FromSeconds(5)), 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_config_(false), 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) print_hosts_(false), 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parallellism_(6), 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) replay_log_index_(0u), 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) active_resolves_(0) { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)GDig::~GDig() { 246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (log_) 247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) log_->RemoveThreadSafeObserver(log_observer_.get()); 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GDig::Result GDig::Main(int argc, const char* argv[]) { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ParseCommandLine(argc, argv)) { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "usage: %s [--net_log[=<basic|no_bytes|all>]]" 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " [--print_config] [--print_hosts]" 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " [--nameserver=<ip_address[:port]>]" 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " [--timeout=<milliseconds>]" 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " [--config_timeout=<seconds>]" 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " [--j=<parallel resolves>]" 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " [--replay_file=<path>]" 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " [domain_name]\n", 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) argv[0]); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return RESULT_WRONG_USAGE; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoopForIO loop; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_ = RESULT_PENDING; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result_ == RESULT_PENDING) 27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Run(); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Destroy it while MessageLoopForIO is alive. 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dns_config_service_.reset(); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result_; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GDig::ParseCommandLine(int argc, const char* argv[]) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine::Init(argc, argv); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_command_line.HasSwitch("config_timeout")) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int timeout_seconds = 0; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool parsed = base::StringToInt( 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_command_line.GetSwitchValueASCII("config_timeout"), 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &timeout_seconds); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed && timeout_seconds > 0) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_timeout_ = base::TimeDelta::FromSeconds(timeout_seconds); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "Invalid config_timeout parameter\n"); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_command_line.HasSwitch("net_log")) { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string log_param = parsed_command_line.GetSwitchValueASCII("net_log"); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog::LogLevel level = NetLog::LOG_ALL_BUT_BYTES; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (log_param.length() > 0) { 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, NetLog::LogLevel> log_levels; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_levels["all"] = NetLog::LOG_ALL; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_levels["no_bytes"] = NetLog::LOG_ALL_BUT_BYTES; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_levels["basic"] = NetLog::LOG_BASIC; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (log_levels.find(log_param) != log_levels.end()) { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level = log_levels[log_param]; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "Invalid net_log parameter\n"); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) log_.reset(new NetLog); 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) log_observer_.reset(new FileNetLogObserver(stderr)); 313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) log_->AddThreadSafeObserver(log_observer_.get(), level); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_config_ = parsed_command_line.HasSwitch("print_config"); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_hosts_ = parsed_command_line.HasSwitch("print_hosts"); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_command_line.HasSwitch("nameserver")) { 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string nameserver = 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_command_line.GetSwitchValueASCII("nameserver"); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!StringToIPEndPoint(nameserver, &nameserver_)) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Cannot parse the namerserver string into an IPEndPoint\n"); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_command_line.HasSwitch("timeout")) { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int timeout_millis = 0; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool parsed = base::StringToInt( 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_command_line.GetSwitchValueASCII("timeout"), 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &timeout_millis); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed && timeout_millis > 0) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_ = base::TimeDelta::FromMilliseconds(timeout_millis); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "Invalid timeout parameter\n"); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (parsed_command_line.HasSwitch("replay_file")) { 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath replay_path = 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parsed_command_line.GetSwitchValuePath("replay_file"); 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!LoadReplayLog(replay_path, &replay_log_)) 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (parsed_command_line.HasSwitch("j")) { 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int parallellism = 0; 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool parsed = base::StringToInt( 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parsed_command_line.GetSwitchValueASCII("j"), 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ¶llellism); 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (parsed && parallellism > 0) { 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parallellism_ = parallellism; 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fprintf(stderr, "Invalid parallellism parameter\n"); 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_command_line.GetArgs().size() == 1) { 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReplayLogEntry entry; 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry.start_time = base::TimeDelta(); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry.domain_name = WideToASCII(parsed_command_line.GetArgs()[0]); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry.domain_name = parsed_command_line.GetArgs()[0]; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) replay_log_.push_back(entry); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (parsed_command_line.GetArgs().size() != 0) { 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return print_config_ || print_hosts_ || !replay_log_.empty(); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GDig::Start() { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nameserver_.address().size() > 0) { 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DnsConfig dns_config; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dns_config.attempts = 1; 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dns_config.nameservers.push_back(nameserver_); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnDnsConfig(dns_config); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dns_config_service_ = DnsConfigService::CreateSystemService(); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dns_config_service_->ReadConfig(base::Bind(&GDig::OnDnsConfig, 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_closure_.Reset(base::Bind(&GDig::OnTimeout, 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 38890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 38990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, timeout_closure_.callback(), config_timeout_); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GDig::Finish(Result result) { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(RESULT_PENDING, result); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_ = result; 39690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (base::MessageLoop::current()) 39790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Quit(); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GDig::OnDnsConfig(const DnsConfig& dns_config_const) { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_closure_.Cancel(); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(dns_config_const.IsValid()); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DnsConfig dns_config = dns_config_const; 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (timeout_.InMilliseconds() > 0) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dns_config.timeout = timeout_; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (print_config_) { 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("# Dns Configuration\n" 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "%s", DnsConfigToString(dns_config).c_str()); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (print_hosts_) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("# Host Database\n" 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "%s", DnsHostsToString(dns_config.hosts).c_str()); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (replay_log_.empty()) { 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Finish(RESULT_OK); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DnsClient> dns_client(DnsClient::CreateClient(NULL)); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dns_client->SetConfig(dns_config); 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<HostResolverImpl> resolver( 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new HostResolverImpl( 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostCache::CreateDefaultCache(), 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrioritizedDispatcher::Limits(NUM_PRIORITIES, parallellism_), 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostResolverImpl::ProcTaskParams(NULL, 1), 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_.get())); 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resolver->SetDnsClient(dns_client.Pass()); 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resolver_ = resolver.Pass(); 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_time_ = base::Time::Now(); 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReplayNextEntry(); 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GDig::ReplayNextEntry() { 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_LT(replay_log_index_, replay_log_.size()); 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta time_since_start = base::Time::Now() - start_time_; 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (replay_log_index_ < replay_log_.size()) { 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ReplayLogEntry& entry = replay_log_[replay_log_index_]; 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (time_since_start < entry.start_time) { 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Delay call to next time and return. 44590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 44690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 44790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&GDig::ReplayNextEntry, base::Unretained(this)), 44890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry.start_time - time_since_start); 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HostResolver::RequestInfo info(HostPortPair(entry.domain_name.c_str(), 80)); 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddressList* addrlist = new AddressList(); 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned current_index = replay_log_index_; 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CompletionCallback callback = base::Bind(&GDig::OnResolveComplete, 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this), 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_index, 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Owned(addrlist), 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) time_since_start); 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++active_resolves_; 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++replay_log_index_; 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int ret = resolver_->Resolve( 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info, addrlist, callback, NULL, 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BoundNetLog::Make(log_.get(), net::NetLog::SOURCE_NONE)); 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ret != ERR_IO_PENDING) 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(ret); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GDig::OnResolveComplete(unsigned entry_index, 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddressList* address_list, 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta resolve_start_time, 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int val) { 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GT(active_resolves_, 0); 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(address_list); 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_LT(entry_index, replay_log_.size()); 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) --active_resolves_; 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta resolve_end_time = base::Time::Now() - start_time_; 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta resolve_time = resolve_end_time - resolve_start_time; 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) printf("%u %d %d %s %d ", 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry_index, 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<int>(resolve_end_time.InMilliseconds()), 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<int>(resolve_time.InMilliseconds()), 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) replay_log_[entry_index].domain_name.c_str(), val); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (val != OK) { 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) printf("%s", ErrorToString(val)); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < address_list->size(); ++i) { 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (i != 0) 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) printf(" "); 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) printf("%s", (*address_list)[i].ToStringWithoutPort().c_str()); 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) printf("\n"); 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (active_resolves_ == 0 && replay_log_index_ >= replay_log_.size()) 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Finish(RESULT_OK); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GDig::OnTimeout() { 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "Timed out waiting to load the dns config\n"); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Finish(RESULT_NO_CONFIG); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // empty namespace 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, const char* argv[]) { 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::GDig dig; 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dig.Main(argc, argv); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 512