Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(344)

Side by Side Diff: net/url_request/url_request_throttler_manager.cc

Issue 6966038: Anti-DDoS enhancements: Log to net log, UMA stats, improved policy. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Respond to review comments. Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/url_request/url_request_throttler_manager.h" 5 #include "net/url_request/url_request_throttler_manager.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/metrics/field_trial.h"
9 #include "base/metrics/histogram.h"
8 #include "base/string_util.h" 10 #include "base/string_util.h"
11 #include "net/base/net_log.h"
9 #include "net/base/net_util.h" 12 #include "net/base/net_util.h"
13 #include "net/base/network_change_notifier.h"
wtc 2011/05/25 23:12:06 Nit: This header is already included by url_reques
Jói 2011/05/26 14:53:42 Done.
10 14
11 namespace net { 15 namespace net {
12 16
13 const unsigned int URLRequestThrottlerManager::kMaximumNumberOfEntries = 1500; 17 const unsigned int URLRequestThrottlerManager::kMaximumNumberOfEntries = 1500;
14 const unsigned int URLRequestThrottlerManager::kRequestsBetweenCollecting = 200; 18 const unsigned int URLRequestThrottlerManager::kRequestsBetweenCollecting = 200;
15 19
16 URLRequestThrottlerManager* URLRequestThrottlerManager::GetInstance() { 20 URLRequestThrottlerManager* URLRequestThrottlerManager::GetInstance() {
17 return Singleton<URLRequestThrottlerManager>::get(); 21 return Singleton<URLRequestThrottlerManager>::get();
18 } 22 }
19 23
20 scoped_refptr<URLRequestThrottlerEntryInterface> 24 scoped_refptr<URLRequestThrottlerEntryInterface>
21 URLRequestThrottlerManager::RegisterRequestUrl(const GURL &url) { 25 URLRequestThrottlerManager::RegisterRequestUrl(const GURL &url) {
22 DCHECK(!enable_thread_checks_ || CalledOnValidThread()); 26 DCHECK(!enable_thread_checks_ || CalledOnValidThread());
23 27
24 // Normalize the url. 28 // Normalize the url.
25 std::string url_id = GetIdFromUrl(url); 29 std::string url_id = GetIdFromUrl(url);
26 30
27 // Periodically garbage collect old entries. 31 // Periodically garbage collect old entries.
28 GarbageCollectEntriesIfNecessary(); 32 GarbageCollectEntriesIfNecessary();
29 33
30 // Find the entry in the map or create it. 34 // Find the entry in the map or create a new NULL entry.
31 scoped_refptr<URLRequestThrottlerEntry>& entry = url_entries_[url_id]; 35 scoped_refptr<URLRequestThrottlerEntry>& entry = url_entries_[url_id];
36
37 // If the entry exists but could be garbage collected at this point, we
38 // start with a fresh entry so that we possibly back off a bit less
39 // aggressively (i.e. this resets the error count when the entry's URL
40 // hasn't been requested in long enough).
41 if (entry.get() && entry->IsEntryOutdated()) {
42 entry = NULL;
43 }
44
45 // Create the entry if needed.
32 if (entry.get() == NULL) { 46 if (entry.get() == NULL) {
33 entry = new URLRequestThrottlerEntry(this); 47 entry = new URLRequestThrottlerEntry(this, url_id);
34 48
35 // We only disable back-off throttling on an entry that we have 49 // We only disable back-off throttling on an entry that we have
36 // just constructed. This is to allow unit tests to explicitly override 50 // just constructed. This is to allow unit tests to explicitly override
37 // the entry for localhost URLs. Given that we do not attempt to 51 // the entry for localhost URLs. Given that we do not attempt to
38 // disable throttling for entries already handed out (see comment 52 // disable throttling for entries already handed out (see comment
39 // in AddToOptOutList), this is not a problem. 53 // in AddToOptOutList), this is not a problem.
40 std::string host = url.host(); 54 std::string host = url.host();
41 if (opt_out_hosts_.find(host) != opt_out_hosts_.end() || 55 if (opt_out_hosts_.find(host) != opt_out_hosts_.end() ||
42 IsLocalhost(host)) { 56 IsLocalhost(host)) {
57 if (!logged_for_localhost_disabled_ && IsLocalhost(host)) {
58 logged_for_localhost_disabled_ = true;
59 net_log_->AddEvent(
60 NetLog::TYPE_THROTTLING_DISABLED_FOR_HOST,
61 make_scoped_refptr(new NetLogStringParameter("host", host)));
62 }
63
43 // TODO(joi): Once sliding window is separate from back-off throttling, 64 // TODO(joi): Once sliding window is separate from back-off throttling,
44 // we can simply return a dummy implementation of 65 // we can simply return a dummy implementation of
45 // URLRequestThrottlerEntryInterface here that never blocks anything (and 66 // URLRequestThrottlerEntryInterface here that never blocks anything (and
46 // not keep entries in url_entries_ for opted-out sites). 67 // not keep entries in url_entries_ for opted-out sites).
47 entry->DisableBackoffThrottling(); 68 entry->DisableBackoffThrottling();
48 } 69 }
49 } 70 }
50 71
51 return entry; 72 return entry;
52 } 73 }
53 74
54 void URLRequestThrottlerManager::AddToOptOutList(const std::string& host) { 75 void URLRequestThrottlerManager::AddToOptOutList(const std::string& host) {
55 // There is an edge case here that we are not handling, to keep things 76 // There is an edge case here that we are not handling, to keep things
56 // simple. If a host starts adding the opt-out header to its responses 77 // simple. If a host starts adding the opt-out header to its responses
57 // after there are already one or more entries in url_entries_ for that 78 // after there are already one or more entries in url_entries_ for that
58 // host, the pre-existing entries may still perform back-off throttling. 79 // host, the pre-existing entries may still perform back-off throttling.
59 // In practice, this would almost never occur. 80 // In practice, this would almost never occur.
60 opt_out_hosts_.insert(host); 81 if (opt_out_hosts_.find(host) == opt_out_hosts_.end()) {
82 UMA_HISTOGRAM_COUNTS("Throttling.SiteOptedOut", 1);
83 if (base::FieldTrialList::TrialExists("ThrottlingEnabled")) {
84 UMA_HISTOGRAM_COUNTS(base::FieldTrial::MakeName(
85 "Throttling.SiteOptedOut", "ThrottlingEnabled"), 1);
86 }
87
88 net_log_->EndEvent(
89 NetLog::TYPE_THROTTLING_DISABLED_FOR_HOST,
90 make_scoped_refptr(new NetLogStringParameter("host", host)));
91 opt_out_hosts_.insert(host);
92 }
61 } 93 }
62 94
63 void URLRequestThrottlerManager::OverrideEntryForTests( 95 void URLRequestThrottlerManager::OverrideEntryForTests(
64 const GURL& url, 96 const GURL& url,
65 URLRequestThrottlerEntry* entry) { 97 URLRequestThrottlerEntry* entry) {
66 // Normalize the url. 98 // Normalize the url.
67 std::string url_id = GetIdFromUrl(url); 99 std::string url_id = GetIdFromUrl(url);
68 100
69 // Periodically garbage collect old entries. 101 // Periodically garbage collect old entries.
70 GarbageCollectEntriesIfNecessary(); 102 GarbageCollectEntriesIfNecessary();
(...skipping 16 matching lines...) Expand all
87 } 119 }
88 120
89 void URLRequestThrottlerManager::set_enforce_throttling(bool enforce) { 121 void URLRequestThrottlerManager::set_enforce_throttling(bool enforce) {
90 enforce_throttling_ = enforce; 122 enforce_throttling_ = enforce;
91 } 123 }
92 124
93 bool URLRequestThrottlerManager::enforce_throttling() { 125 bool URLRequestThrottlerManager::enforce_throttling() {
94 return enforce_throttling_; 126 return enforce_throttling_;
95 } 127 }
96 128
129 void URLRequestThrottlerManager::set_net_log(NetLog* net_log) {
130 DCHECK(net_log);
131 NetLog::Source source(NetLog::SOURCE_EXPONENTIAL_BACKOFF_THROTTLING,
132 net_log->NextID());
133 net_log_.reset(new BoundNetLog(source, net_log));
134 }
135
136 NetLog* URLRequestThrottlerManager::net_log() const {
137 return net_log_->net_log();
138 }
139
140 void URLRequestThrottlerManager::OnIPAddressChanged() {
141 OnNetworkChange();
142 }
143
144 void URLRequestThrottlerManager::OnOnlineStateChanged(bool online) {
145 OnNetworkChange();
146 }
147
97 // TODO(joi): Turn throttling on by default when appropriate. 148 // TODO(joi): Turn throttling on by default when appropriate.
98 URLRequestThrottlerManager::URLRequestThrottlerManager() 149 URLRequestThrottlerManager::URLRequestThrottlerManager()
99 : requests_since_last_gc_(0), 150 : requests_since_last_gc_(0),
100 enforce_throttling_(false), 151 enforce_throttling_(false),
101 enable_thread_checks_(false) { 152 enable_thread_checks_(false),
153 logged_for_localhost_disabled_(false) {
102 // Construction/destruction is on main thread (because BrowserMain 154 // Construction/destruction is on main thread (because BrowserMain
103 // retrieves an instance to call InitializeOptions), but is from then on 155 // retrieves an instance to call InitializeOptions), but is from then on
104 // used on I/O thread. 156 // used on I/O thread.
105 DetachFromThread(); 157 DetachFromThread();
106 158
107 url_id_replacements_.ClearPassword(); 159 url_id_replacements_.ClearPassword();
108 url_id_replacements_.ClearUsername(); 160 url_id_replacements_.ClearUsername();
109 url_id_replacements_.ClearQuery(); 161 url_id_replacements_.ClearQuery();
110 url_id_replacements_.ClearRef(); 162 url_id_replacements_.ClearRef();
163
164 // Make sure there is always a net_log_ instance, even if it logs to
165 // nowhere.
166 net_log_.reset(new BoundNetLog());
167
168 NetworkChangeNotifier::AddIPAddressObserver(this);
169 NetworkChangeNotifier::AddOnlineStateObserver(this);
111 } 170 }
112 171
113 URLRequestThrottlerManager::~URLRequestThrottlerManager() { 172 URLRequestThrottlerManager::~URLRequestThrottlerManager() {
114 // Destruction is on main thread (AtExit), but real use is on I/O thread. 173 // Destruction is on main thread (AtExit), but real use is on I/O thread.
115 DetachFromThread(); 174 DetachFromThread();
116 175
176 NetworkChangeNotifier::RemoveIPAddressObserver(this);
177 NetworkChangeNotifier::RemoveOnlineStateObserver(this);
178
117 // Since, for now, the manager object might conceivably go away before 179 // Since, for now, the manager object might conceivably go away before
118 // the entries, detach the entries' back-pointer to the manager. 180 // the entries, detach the entries' back-pointer to the manager.
119 // 181 //
120 // TODO(joi): Revisit whether to make entries non-refcounted. 182 // TODO(joi): Revisit whether to make entries non-refcounted.
121 UrlEntryMap::iterator i = url_entries_.begin(); 183 UrlEntryMap::iterator i = url_entries_.begin();
122 while (i != url_entries_.end()) { 184 while (i != url_entries_.end()) {
123 if (i->second != NULL) { 185 if (i->second != NULL) {
124 i->second->DetachManager(); 186 i->second->DetachManager();
125 } 187 }
126 ++i; 188 ++i;
(...skipping 29 matching lines...) Expand all
156 ++i; 218 ++i;
157 } 219 }
158 } 220 }
159 221
160 // In case something broke we want to make sure not to grow indefinitely. 222 // In case something broke we want to make sure not to grow indefinitely.
161 while (url_entries_.size() > kMaximumNumberOfEntries) { 223 while (url_entries_.size() > kMaximumNumberOfEntries) {
162 url_entries_.erase(url_entries_.begin()); 224 url_entries_.erase(url_entries_.begin());
163 } 225 }
164 } 226 }
165 227
228 void URLRequestThrottlerManager::OnNetworkChange() {
229 // Remove all entries. Any entries that in-flight requests have a reference
230 // to will live until those requests end, and these entries may be
231 // inconsistent with new entries for the same URLs, but since what we
232 // want is a clean slate for the new connection state, this is OK.
233 url_entries_.clear();
234 requests_since_last_gc_ = 0;
235 }
236
166 } // namespace net 237 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698