summaryrefslogtreecommitdiffstats
path: root/chrome/browser/net/dns_host_info.h
blob: d0a05bc89a4769e43c731b0da931fb0569941d71 (plain)
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
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// A DnsHostInfo object is used to store status of a Dns lookup of a specific
// hostname.
// It includes progress, from placement in the DnsMaster's queue, to assignment
// to a slave, to resolution by the (blocking) DNS service as either FOUND or
// NO_SUCH_NAME.

#ifndef CHROME_BROWSER_NET_DNS_HOST_INFO_H__
#define CHROME_BROWSER_NET_DNS_HOST_INFO_H__

#include <string>
#include <vector>

#include "base/logging.h"
#include "base/time.h"

namespace chrome_browser_net {

// Use command line switch to enable detailed logging.
void EnableDnsDetailedLog(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 DnsHostInfo {
 public:
  enum DnsProcessingState {
      // When processed by our prefetching system, there are 4 states:
      PENDING,       // Constructor has completed.
      QUEUED,        // In prefetch queue but not yet assigned to a slave.
      ASSIGNED,      // Currently being processed by a slave.
      ASSIGNED_BUT_MARKED,  // Needs to be deleted as soon as slave is done.
      FOUND,         // DNS prefetch search completed.
      NO_SUCH_NAME,  // DNS prefetch search completed.
      // When processed by the HTTP network stack, there are 3 states:
      STARTED,               // Resolution has begun.
      FINISHED,              // Resolution has completed.
      FINISHED_UNRESOLVED};  // No resolution found.
  static const TimeDelta kMaxNonNetworkDnsLookupDuration;
  // The number of OS cache entries we can guarantee(?) before cache eviction
  // might likely take place.
  static const int kMaxGuaranteedCacheSize = 50;

  typedef std::vector<const DnsHostInfo> DnsInfoTable;

  static const TimeDelta kNullDuration;

  // DnsHostInfo are usually made by the default constructor during
  // initializing of the DnsMaster's map (of info for Hostnames).
  DnsHostInfo()
      : state_(PENDING),
        resolve_duration_(kNullDuration),
        queue_duration_(kNullDuration),
        benefits_remaining_(),
        sequence_number_(0) {
  }

  ~DnsHostInfo() {}

  // 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(const std::string& hostname);

  static void set_cache_expiration(TimeDelta time);

  // The prefetching lifecycle.
  void SetQueuedState();
  void SetAssignedState();
  void SetPendingDeleteState();
  void SetFoundState();
  void SetNoSuchNameState();
  // The actual browsing resolution lifecycle.
  void SetStartedState();
  void SetFinishedState(bool was_resolved);

  void SetHostname(const std::string& hostname) {
    if (hostname != hostname_) {
      DCHECK(hostname_.size() == 0);  // Not yet initialized.
      hostname_ = hostname;
    }
  }

  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 std::string hostname() const { return hostname_; }

  bool HasHostname(const std::string& hostname) const {
    return (hostname == hostname_);
  }

  TimeDelta resolve_duration() const { return resolve_duration_;}
  TimeDelta queue_duration() const { return queue_duration_;}
  TimeDelta benefits_remaining() const { return benefits_remaining_; }

  DnsBenefit AcruePrefetchBenefits(DnsHostInfo* later_host_info);

  void DLogResultsStats(const char* message) const;

  static void GetHtmlTable(const DnsInfoTable host_infos,
                           const char* description,
                           const bool brief,
                           std::string* output);

 private:
  // The next declaration is non-const to facilitate testing.
  static TimeDelta kCacheExpirationDuration;

  DnsProcessingState state_;
  std::string hostname_;  // Hostname for this info.

  TimeTicks time_;  // When was last state changed (usually lookup completed).
  TimeDelta resolve_duration_;  // Time needed for DNS to resolve.
  TimeDelta queue_duration_;  // Time spent in queue.
  TimeDelta benefits_remaining_;  // Unused potential benefits of a prefetch.

  int sequence_number_;  // Used to calculate potential of cache eviction.
  static int sequence_counter;  // Used to allocate sequence_number_'s.

  TimeDelta GetDuration() {
    TimeTicks old_time = time_;
    time_ = TimeTicks::Now();
    return time_ - old_time;
  }

  // IsStillCached() guesses if the DNS cache still has IP data.
  bool IsStillCached() const;

  // We put these objects into a std::map, and hence we
  // need some "evil" constructors.
  // DISALLOW_EVIL_CONSTRUCTORS(DnsHostInfo);
};

}  // namespace chrome_browser_net

#endif  // CHROME_BROWSER_NET_DNS_HOST_INFO_H__