summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quiche/quic/core/quic_path_validator.h
blob: 32758a9fba4080d03540fae14d681c352e6818d8 (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
// Copyright (c) 2020 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.

#ifndef QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_
#define QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_

#include <ostream>

#include "absl/container/inlined_vector.h"
#include "quiche/quic/core/crypto/quic_random.h"
#include "quiche/quic/core/quic_alarm.h"
#include "quiche/quic/core/quic_alarm_factory.h"
#include "quiche/quic/core/quic_arena_scoped_ptr.h"
#include "quiche/quic/core/quic_clock.h"
#include "quiche/quic/core/quic_connection_context.h"
#include "quiche/quic/core/quic_one_block_arena.h"
#include "quiche/quic/core/quic_packet_writer.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/quic/platform/api/quic_socket_address.h"

namespace quic {

namespace test {
class QuicPathValidatorPeer;
}

class QuicConnection;

// Interface to provide the information of the path to be validated.
class QUIC_EXPORT_PRIVATE QuicPathValidationContext {
 public:
  QuicPathValidationContext(const QuicSocketAddress& self_address,
                            const QuicSocketAddress& peer_address)
      : self_address_(self_address),
        peer_address_(peer_address),
        effective_peer_address_(peer_address) {}

  QuicPathValidationContext(const QuicSocketAddress& self_address,
                            const QuicSocketAddress& peer_address,
                            const QuicSocketAddress& effective_peer_address)
      : self_address_(self_address),
        peer_address_(peer_address),
        effective_peer_address_(effective_peer_address) {}

  virtual ~QuicPathValidationContext() = default;

  virtual QuicPacketWriter* WriterToUse() = 0;

  const QuicSocketAddress& self_address() const { return self_address_; }
  const QuicSocketAddress& peer_address() const { return peer_address_; }
  const QuicSocketAddress& effective_peer_address() const {
    return effective_peer_address_;
  }

 private:
  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
      std::ostream& os, const QuicPathValidationContext& context);

  QuicSocketAddress self_address_;
  // The address to send PATH_CHALLENGE.
  QuicSocketAddress peer_address_;
  // The actual peer address which is different from |peer_address_| if the peer
  // is behind a proxy.
  QuicSocketAddress effective_peer_address_;
};

// Used to validate a path by sending up to 3 PATH_CHALLENGE frames before
// declaring a path validation failure.
class QUIC_EXPORT_PRIVATE QuicPathValidator {
 public:
  static const uint16_t kMaxRetryTimes = 2;

  // Used to write PATH_CHALLENGE on the path to be validated and to get retry
  // timeout.
  class QUIC_EXPORT_PRIVATE SendDelegate {
   public:
    virtual ~SendDelegate() = default;

    // Send a PATH_CHALLENGE with |data_buffer| as the frame payload using given
    // path information. Return false if the delegate doesn't want to continue
    // the validation.
    virtual bool SendPathChallenge(
        const QuicPathFrameBuffer& data_buffer,
        const QuicSocketAddress& self_address,
        const QuicSocketAddress& peer_address,
        const QuicSocketAddress& effective_peer_address,
        QuicPacketWriter* writer) = 0;
    // Return the time to retry sending PATH_CHALLENGE again based on given peer
    // address and writer.
    virtual QuicTime GetRetryTimeout(const QuicSocketAddress& peer_address,
                                     QuicPacketWriter* writer) const = 0;
  };

  // Handles the validation result.
  // TODO(danzh) consider to simplify this interface and its life time to
  // outlive a validation.
  class QUIC_EXPORT_PRIVATE ResultDelegate {
   public:
    virtual ~ResultDelegate() = default;

    virtual void OnPathValidationSuccess(
        std::unique_ptr<QuicPathValidationContext> context) = 0;

    virtual void OnPathValidationFailure(
        std::unique_ptr<QuicPathValidationContext> context) = 0;
  };

  QuicPathValidator(QuicAlarmFactory* alarm_factory, QuicConnectionArena* arena,
                    SendDelegate* delegate, QuicRandom* random,
                    QuicConnectionContext* context);

  // Send PATH_CHALLENGE and start the retry timer.
  void StartPathValidation(std::unique_ptr<QuicPathValidationContext> context,
                           std::unique_ptr<ResultDelegate> result_delegate);

  // Called when a PATH_RESPONSE frame has been received. Matches the received
  // PATH_RESPONSE payload with the payloads previously sent in PATH_CHALLANGE
  // frames and the self address on which it was sent.
  void OnPathResponse(const QuicPathFrameBuffer& probing_data,
                      QuicSocketAddress self_address);

  // Cancel the retry timer and reset the path and result delegate.
  void CancelPathValidation();

  bool HasPendingPathValidation() const;

  QuicPathValidationContext* GetContext() const;

  // Send another PATH_CHALLENGE on the same path. After retrying
  // |kMaxRetryTimes| times, fail the current path validation.
  void OnRetryTimeout();

  bool IsValidatingPeerAddress(const QuicSocketAddress& effective_peer_address);

 private:
  friend class test::QuicPathValidatorPeer;

  // Return the payload to be used in the next PATH_CHALLENGE frame.
  const QuicPathFrameBuffer& GeneratePathChallengePayload();

  void SendPathChallengeAndSetAlarm();

  void ResetPathValidation();

  // Has at most 3 entries due to validation timeout.
  absl::InlinedVector<QuicPathFrameBuffer, 3> probing_data_;
  SendDelegate* send_delegate_;
  QuicRandom* random_;
  std::unique_ptr<QuicPathValidationContext> path_context_;
  std::unique_ptr<ResultDelegate> result_delegate_;
  QuicArenaScopedPtr<QuicAlarm> retry_timer_;
  size_t retry_count_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_