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