1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // A UrlInfo object is used to store prediction related information about a host 6 // port and scheme triplet. When performing DNS pre-resolution of the host/port 7 // pair, its state is monitored as it is resolved. 8 // It includes progress, from placement in the Predictor's queue, to resolution 9 // by the DNS service as either FOUND or NO_SUCH_NAME. Each instance may also 10 // hold records of previous resolution times, which might later be shown to be 11 // savings relative to resolution time during a navigation. 12 // UrlInfo objects are also used to describe frames, and additional instances 13 // may describe associated subresources, for future speculative connections to 14 // those expected subresources. 15 16 #ifndef CHROME_BROWSER_NET_URL_INFO_H_ 17 #define CHROME_BROWSER_NET_URL_INFO_H_ 18 #pragma once 19 20 #include <string> 21 #include <vector> 22 23 #include "base/time.h" 24 #include "googleurl/src/gurl.h" 25 #include "net/base/host_port_pair.h" 26 27 namespace chrome_browser_net { 28 29 // Use command line switch to enable detailed logging. 30 void EnablePredictorDetailedLog(bool enable); 31 32 class UrlInfo { 33 public: 34 // Reasons for a domain to be resolved. 35 enum ResolutionMotivation { 36 MOUSE_OVER_MOTIVATED, // Mouse-over link induced resolution. 37 PAGE_SCAN_MOTIVATED, // Scan of rendered page induced resolution. 38 UNIT_TEST_MOTIVATED, 39 LINKED_MAX_MOTIVATED, // enum demarkation above motivation from links. 40 OMNIBOX_MOTIVATED, // Omni-box suggested resolving this. 41 STARTUP_LIST_MOTIVATED, // Startup list caused this resolution. 42 EARLY_LOAD_MOTIVATED, // In some cases we use the prefetcher to warm up 43 // the connection in advance of issuing the real 44 // request. 45 46 NO_PREFETCH_MOTIVATION, // Browser navigation info (not prefetch related). 47 48 // The following involve predictive prefetching, triggered by a navigation. 49 // The referrinrg_url_ is also set when these are used. 50 // TODO(jar): Support STATIC_REFERAL_MOTIVATED API and integration. 51 STATIC_REFERAL_MOTIVATED, // External database suggested this resolution. 52 LEARNED_REFERAL_MOTIVATED, // Prior navigation taught us this resolution. 53 SELF_REFERAL_MOTIVATED, // Guess about need for a second connection. 54 55 MAX_MOTIVATED // Beyond all enums, for use in histogram bounding. 56 }; 57 58 enum DnsProcessingState { 59 // When processed by our prefetching system, the states are: 60 PENDING, // Constructor has completed. 61 QUEUED, // In name queue but not yet being resolved. 62 ASSIGNED, // Being resolved (or being reset to earlier state) 63 ASSIGNED_BUT_MARKED, // Needs to be deleted as soon as it's resolved. 64 FOUND, // DNS resolution completed. 65 NO_SUCH_NAME, // DNS resolution completed. 66 }; 67 static const base::TimeDelta kMaxNonNetworkDnsLookupDuration; 68 // The number of OS cache entries we can guarantee(?) before cache eviction 69 // might likely take place. 70 static const int kMaxGuaranteedDnsCacheSize = 50; 71 72 typedef std::vector<UrlInfo> UrlInfoTable; 73 74 static const base::TimeDelta kNullDuration; 75 76 // UrlInfo are usually made by the default constructor during 77 // initializing of the Predictor's map (of info for Hostnames). 78 UrlInfo(); 79 80 ~UrlInfo(); 81 82 // NeedDnsUpdate decides, based on our internal info, 83 // if it would be valuable to attempt to update (prefectch) 84 // DNS data for hostname. This decision is based 85 // on how recently we've done DNS prefetching for hostname. 86 bool NeedsDnsUpdate(); 87 88 // FOR TEST ONLY: The following access the otherwise constant values. 89 static void set_cache_expiration(base::TimeDelta time); 90 static base::TimeDelta get_cache_expiration(); 91 92 // The prefetching lifecycle. 93 void SetQueuedState(ResolutionMotivation motivation); 94 void SetAssignedState(); 95 void RemoveFromQueue(); 96 void SetPendingDeleteState(); 97 void SetFoundState(); 98 void SetNoSuchNameState(); 99 100 // Finish initialization. Must only be called once. 101 void SetUrl(const GURL& url); 102 103 bool was_linked() const { return was_linked_; } 104 105 GURL referring_url() const { return referring_url_; } 106 void SetReferringHostname(const GURL& url) { 107 referring_url_ = url; 108 } 109 110 bool was_found() const { return FOUND == state_; } 111 bool was_nonexistent() const { return NO_SUCH_NAME == state_; } 112 bool is_assigned() const { 113 return ASSIGNED == state_ || ASSIGNED_BUT_MARKED == state_; 114 } 115 bool is_marked_to_delete() const { return ASSIGNED_BUT_MARKED == state_; } 116 const GURL url() const { return url_; } 117 118 bool HasUrl(const GURL& url) const { 119 return url_ == url; 120 } 121 122 base::TimeDelta resolve_duration() const { return resolve_duration_;} 123 base::TimeDelta queue_duration() const { return queue_duration_;} 124 125 void DLogResultsStats(const char* message) const; 126 127 static void GetHtmlTable(const UrlInfoTable& host_infos, 128 const char* description, 129 bool brief, 130 std::string* output); 131 132 // For testing, and use in printing tables of info, we sometimes need to 133 // adjust the time manually. Usually, this value is maintained by state 134 // transition, and this call is not made. 135 void set_time(const base::TimeTicks& time) { time_ = time; } 136 137 private: 138 base::TimeDelta GetDuration() { 139 base::TimeTicks old_time = time_; 140 time_ = base::TimeTicks::Now(); 141 return time_ - old_time; 142 } 143 144 // IsStillCached() guesses if the DNS cache still has IP data. 145 bool IsStillCached() const; 146 147 // Record why we created, or have updated (reqested pre-resolution) of this 148 // instance. 149 void SetMotivation(ResolutionMotivation motivation); 150 151 // Helper function for about:dns printing. 152 std::string GetAsciiMotivation() const; 153 154 // The next declaration is non-const to facilitate testing. 155 static base::TimeDelta cache_expiration_duration_; 156 157 // The current state of this instance. 158 DnsProcessingState state_; 159 160 // Record the state prior to going to a queued state, in case we have to back 161 // out of the queue. 162 DnsProcessingState old_prequeue_state_; 163 164 GURL url_; // Host, port and scheme for this info. 165 166 // When was last state changed (usually lookup completed). 167 base::TimeTicks time_; 168 // Time needed for DNS to resolve. 169 base::TimeDelta resolve_duration_; 170 // Time spent in queue. 171 base::TimeDelta queue_duration_; 172 173 int sequence_number_; // Used to calculate potential of cache eviction. 174 static int sequence_counter; // Used to allocate sequence_number_'s. 175 176 // Motivation for creation of this instance. 177 ResolutionMotivation motivation_; 178 179 // Record if the motivation for prefetching was ever a page-link-scan. 180 bool was_linked_; 181 182 // If this instance holds data about a navigation, we store the referrer. 183 // If this instance hold data about a prefetch, and the prefetch was 184 // instigated by a referrer, we store it here (for use in about:dns). 185 GURL referring_url_; 186 187 // We put these objects into a std::map, and hence we 188 // need some "evil" constructors. 189 // DISALLOW_COPY_AND_ASSIGN(UrlInfo); 190 }; 191 192 } // namespace chrome_browser_net 193 194 #endif // CHROME_BROWSER_NET_URL_INFO_H_ 195