| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // The tests in this file attempt to verify the following through simulation: | 5 // The tests in this file attempt to verify the following through simulation: |
| 6 // a) That a server experiencing overload will actually benefit from the | 6 // a) That a server experiencing overload will actually benefit from the |
| 7 // anti-DDoS throttling logic, i.e. that its traffic spike will subside | 7 // anti-DDoS throttling logic, i.e. that its traffic spike will subside |
| 8 // and be distributed over a longer period of time; | 8 // and be distributed over a longer period of time; |
| 9 // b) That "well-behaved" clients of a server under DDoS attack actually | 9 // b) That "well-behaved" clients of a server under DDoS attack actually |
| 10 // benefit from the anti-DDoS throttling logic; and | 10 // benefit from the anti-DDoS throttling logic; and |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 scoped_ptr<URLRequest> mock_request_; | 296 scoped_ptr<URLRequest> mock_request_; |
| 297 | 297 |
| 298 DISALLOW_COPY_AND_ASSIGN(Server); | 298 DISALLOW_COPY_AND_ASSIGN(Server); |
| 299 }; | 299 }; |
| 300 | 300 |
| 301 // Mock throttler entry used by Requester class. | 301 // Mock throttler entry used by Requester class. |
| 302 class MockURLRequestThrottlerEntry : public URLRequestThrottlerEntry { | 302 class MockURLRequestThrottlerEntry : public URLRequestThrottlerEntry { |
| 303 public: | 303 public: |
| 304 explicit MockURLRequestThrottlerEntry(URLRequestThrottlerManager* manager) | 304 explicit MockURLRequestThrottlerEntry(URLRequestThrottlerManager* manager) |
| 305 : URLRequestThrottlerEntry(manager, std::string()), | 305 : URLRequestThrottlerEntry(manager, std::string()), |
| 306 mock_backoff_entry_(&backoff_policy_) {} | 306 backoff_entry_(&backoff_policy_, &fake_clock_) {} |
| 307 | 307 |
| 308 const BackoffEntry* GetBackoffEntry() const override { | 308 const BackoffEntry* GetBackoffEntry() const override { |
| 309 return &mock_backoff_entry_; | 309 return &backoff_entry_; |
| 310 } | 310 } |
| 311 | 311 |
| 312 BackoffEntry* GetBackoffEntry() override { return &mock_backoff_entry_; } | 312 BackoffEntry* GetBackoffEntry() override { return &backoff_entry_; } |
| 313 | 313 |
| 314 TimeTicks ImplGetTimeNow() const override { return fake_now_; } | 314 TimeTicks ImplGetTimeNow() const override { return fake_clock_.NowTicks(); } |
| 315 | 315 |
| 316 void SetFakeNow(const TimeTicks& fake_time) { | 316 void SetFakeNow(const TimeTicks& fake_time) { |
| 317 fake_now_ = fake_time; | 317 fake_clock_.set_now(fake_time); |
| 318 mock_backoff_entry_.set_fake_now(fake_time); | |
| 319 } | |
| 320 | |
| 321 TimeTicks fake_now() const { | |
| 322 return fake_now_; | |
| 323 } | 318 } |
| 324 | 319 |
| 325 protected: | 320 protected: |
| 326 ~MockURLRequestThrottlerEntry() override {} | 321 ~MockURLRequestThrottlerEntry() override {} |
| 327 | 322 |
| 328 private: | 323 private: |
| 329 TimeTicks fake_now_; | 324 mutable TestTickClock fake_clock_; |
| 330 MockBackoffEntry mock_backoff_entry_; | 325 BackoffEntry backoff_entry_; |
| 331 }; | 326 }; |
| 332 | 327 |
| 333 // Registry of results for a class of |Requester| objects (e.g. attackers vs. | 328 // Registry of results for a class of |Requester| objects (e.g. attackers vs. |
| 334 // regular clients). | 329 // regular clients). |
| 335 class RequesterResults { | 330 class RequesterResults { |
| 336 public: | 331 public: |
| 337 RequesterResults() | 332 RequesterResults() |
| 338 : num_attempts_(0), num_successful_(0), num_failed_(0), num_blocked_(0) { | 333 : num_attempts_(0), num_successful_(0), num_failed_(0), num_blocked_(0) { |
| 339 } | 334 } |
| 340 | 335 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 void PerformAction() override { | 414 void PerformAction() override { |
| 420 TimeDelta effective_delay = time_between_requests_; | 415 TimeDelta effective_delay = time_between_requests_; |
| 421 TimeDelta current_jitter = TimeDelta::FromMilliseconds( | 416 TimeDelta current_jitter = TimeDelta::FromMilliseconds( |
| 422 request_jitter_.InMilliseconds() * base::RandDouble()); | 417 request_jitter_.InMilliseconds() * base::RandDouble()); |
| 423 if (base::RandInt(0, 1)) { | 418 if (base::RandInt(0, 1)) { |
| 424 effective_delay -= current_jitter; | 419 effective_delay -= current_jitter; |
| 425 } else { | 420 } else { |
| 426 effective_delay += current_jitter; | 421 effective_delay += current_jitter; |
| 427 } | 422 } |
| 428 | 423 |
| 429 if (throttler_entry_->fake_now() - time_of_last_attempt_ > | 424 if (throttler_entry_->ImplGetTimeNow() - time_of_last_attempt_ > |
| 430 effective_delay) { | 425 effective_delay) { |
| 431 if (!throttler_entry_->ShouldRejectRequest( | 426 if (!throttler_entry_->ShouldRejectRequest( |
| 432 server_->mock_request(), | 427 server_->mock_request(), |
| 433 server_->context().network_delegate())) { | 428 server_->context().network_delegate())) { |
| 434 int status_code = server_->HandleRequest(); | 429 int status_code = server_->HandleRequest(); |
| 435 MockURLRequestThrottlerHeaderAdapter response_headers(status_code); | 430 MockURLRequestThrottlerHeaderAdapter response_headers(status_code); |
| 436 throttler_entry_->UpdateWithResponse(std::string(), &response_headers); | 431 throttler_entry_->UpdateWithResponse(std::string(), &response_headers); |
| 437 | 432 |
| 438 if (status_code == 200) { | 433 if (status_code == 200) { |
| 439 if (results_) | 434 if (results_) |
| 440 results_->AddSuccess(); | 435 results_->AddSuccess(); |
| 441 | 436 |
| 442 if (last_attempt_was_failure_) { | 437 if (last_attempt_was_failure_) { |
| 443 last_downtime_duration_ = | 438 last_downtime_duration_ = |
| 444 throttler_entry_->fake_now() - time_of_last_success_; | 439 throttler_entry_->ImplGetTimeNow() - time_of_last_success_; |
| 445 } | 440 } |
| 446 | 441 |
| 447 time_of_last_success_ = throttler_entry_->fake_now(); | 442 time_of_last_success_ = throttler_entry_->ImplGetTimeNow(); |
| 448 last_attempt_was_failure_ = false; | 443 last_attempt_was_failure_ = false; |
| 449 } else { | 444 } else { |
| 450 if (results_) | 445 if (results_) |
| 451 results_->AddFailure(); | 446 results_->AddFailure(); |
| 452 last_attempt_was_failure_ = true; | 447 last_attempt_was_failure_ = true; |
| 453 } | 448 } |
| 454 } else { | 449 } else { |
| 455 if (results_) | 450 if (results_) |
| 456 results_->AddBlocked(); | 451 results_->AddBlocked(); |
| 457 last_attempt_was_failure_ = true; | 452 last_attempt_was_failure_ = true; |
| 458 } | 453 } |
| 459 | 454 |
| 460 time_of_last_attempt_ = throttler_entry_->fake_now(); | 455 time_of_last_attempt_ = throttler_entry_->ImplGetTimeNow(); |
| 461 } | 456 } |
| 462 } | 457 } |
| 463 | 458 |
| 464 // Adds a delay until the first request, equal to a uniformly distributed | 459 // Adds a delay until the first request, equal to a uniformly distributed |
| 465 // value between now and now + max_delay. | 460 // value between now and now + max_delay. |
| 466 void SetStartupJitter(const TimeDelta& max_delay) { | 461 void SetStartupJitter(const TimeDelta& max_delay) { |
| 467 int delay_ms = base::RandInt(0, max_delay.InMilliseconds()); | 462 int delay_ms = base::RandInt(0, max_delay.InMilliseconds()); |
| 468 time_of_last_attempt_ = TimeTicks() + | 463 time_of_last_attempt_ = TimeTicks() + |
| 469 TimeDelta::FromMilliseconds(delay_ms) - time_between_requests_; | 464 TimeDelta::FromMilliseconds(delay_ms) - time_between_requests_; |
| 470 } | 465 } |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 748 trials[i].PrintTrialDescription(); | 743 trials[i].PrintTrialDescription(); |
| 749 trials[i].stats.ReportTrialResult(increase_ratio); | 744 trials[i].stats.ReportTrialResult(increase_ratio); |
| 750 } | 745 } |
| 751 | 746 |
| 752 VerboseOut("Average increase ratio was %.4f\n", average_increase_ratio); | 747 VerboseOut("Average increase ratio was %.4f\n", average_increase_ratio); |
| 753 VerboseOut("Maximum increase ratio was %.4f\n", max_increase_ratio); | 748 VerboseOut("Maximum increase ratio was %.4f\n", max_increase_ratio); |
| 754 } | 749 } |
| 755 | 750 |
| 756 } // namespace | 751 } // namespace |
| 757 } // namespace net | 752 } // namespace net |
| OLD | NEW |