blob: 73a0b2e139511a3d43d3e88a286ad61b1bf8264c [file] [log] [blame]
// Copyright (c) 2006-2008 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 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 resolution
// by the 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/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 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:
// 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 referring_hostport_ 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 kMaxGuaranteedCacheSize = 50;
typedef std::vector<DnsHostInfo> DnsInfoTable;
static const base::TimeDelta kNullDuration;
// DnsHostInfo are usually made by the default constructor during
// initializing of the DnsMaster's map (of info for Hostnames).
DnsHostInfo()
: state_(PENDING),
old_prequeue_state_(state_),
resolve_duration_(kNullDuration),
queue_duration_(kNullDuration),
benefits_remaining_(),
sequence_number_(0),
motivation_(NO_PREFETCH_MOTIVATION),
was_linked_(false) {
}
~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();
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 SetHostname(const net::HostPortPair& hostport);
bool was_linked() const { return was_linked_; }
net::HostPortPair referring_hostname() const { return referring_hostport_; }
void SetReferringHostname(const net::HostPortPair& hostport) {
referring_hostport_ = hostport;
}
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 net::HostPortPair hostport() const { return hostport_; }
bool HasHostname(const net::HostPortPair& hostport) const {
return (hostport.Equals(hostport_));
}
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(DnsHostInfo* 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_;
net::HostPortPair hostport_; // Hostname 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).
net::HostPortPair referring_hostport_;
// We put these objects into a std::map, and hence we
// need some "evil" constructors.
// DISALLOW_COPY_AND_ASSIGN(DnsHostInfo);
};
} // namespace chrome_browser_net
#endif // CHROME_BROWSER_NET_DNS_HOST_INFO_H_