dns_udp_tracker.h 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef NET_DNS_DNS_UDP_TRACKER_H_
  5. #define NET_DNS_DNS_UDP_TRACKER_H_
  6. #include <stdint.h>
  7. #include "base/containers/circular_deque.h"
  8. #include "base/memory/raw_ptr.h"
  9. #include "base/time/default_tick_clock.h"
  10. #include "base/time/time.h"
  11. #include "net/base/net_export.h"
  12. namespace base {
  13. class TickClock;
  14. } // namespace base
  15. namespace net {
  16. // Data tracker for DNS UDP and its usage of local ports. Intended to be owned
  17. // by a DnsSession and thus keep track of the data session-wide. Responsible for
  18. // related metrics and used to inform behavior based on the stored data.
  19. //
  20. // TODO(ericorth@chromium.org): Add methods to access the stored data or
  21. // conclusions about it.
  22. class NET_EXPORT_PRIVATE DnsUdpTracker {
  23. public:
  24. static constexpr base::TimeDelta kMaxAge = base::Minutes(10);
  25. static constexpr size_t kMaxRecordedQueries = 256;
  26. // How recently an ID needs to be recorded in a recent query to be considered
  27. // "recognized".
  28. static constexpr base::TimeDelta kMaxRecognizedIdAge = base::Seconds(15);
  29. // Numbers of ID mismatches required to set the |low_entropy_| flag. Also
  30. // serves as the max number of mismatches to be recorded, as no more entries
  31. // are recorded after setting the flag.
  32. static constexpr size_t kUnrecognizedIdMismatchThreshold = 8;
  33. static constexpr size_t kRecognizedIdMismatchThreshold = 128;
  34. // Number of reuses of the same port required to set the |low_entropy_| flag.
  35. static constexpr int kPortReuseThreshold = 2;
  36. DnsUdpTracker();
  37. ~DnsUdpTracker();
  38. DnsUdpTracker(DnsUdpTracker&&);
  39. DnsUdpTracker& operator=(DnsUdpTracker&&);
  40. void RecordQuery(uint16_t port, uint16_t query_id);
  41. void RecordResponseId(uint16_t query_id, uint16_t response_id);
  42. void RecordConnectionError(int connection_error);
  43. // If true, the entropy from random UDP port and DNS ID has been detected to
  44. // potentially be low, e.g. due to exhaustion of the port pool or mismatches
  45. // on IDs.
  46. bool low_entropy() const { return low_entropy_; }
  47. void set_tick_clock_for_testing(base::TickClock* tick_clock) {
  48. tick_clock_ = tick_clock;
  49. }
  50. private:
  51. struct QueryData;
  52. void PurgeOldRecords();
  53. void SaveQuery(QueryData query);
  54. void SaveIdMismatch(uint16_t it);
  55. bool low_entropy_ = false;
  56. base::circular_deque<QueryData> recent_queries_;
  57. // Times of recent ID mismatches, separated by whether or not the ID was
  58. // recognized from recent queries.
  59. base::circular_deque<base::TimeTicks> recent_unrecognized_id_hits_;
  60. base::circular_deque<base::TimeTicks> recent_recognized_id_hits_;
  61. raw_ptr<const base::TickClock> tick_clock_ =
  62. base::DefaultTickClock::GetInstance();
  63. };
  64. } // namespace net
  65. #endif // NET_DNS_DNS_UDP_TRACKER_H_