blob: 8cfa81d733af6fe1e5e58a46cb83043545bce12d [file] [log] [blame]
danzh599ce0e2020-10-20 15:30:23 -07001// Copyright (c) 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
5#ifndef QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_
6#define QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_
7
8#include <ostream>
9
10#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
11#include "net/third_party/quiche/src/quic/core/quic_alarm.h"
12#include "net/third_party/quiche/src/quic/core/quic_alarm_factory.h"
13#include "net/third_party/quiche/src/quic/core/quic_arena_scoped_ptr.h"
14#include "net/third_party/quiche/src/quic/core/quic_clock.h"
15#include "net/third_party/quiche/src/quic/core/quic_one_block_arena.h"
16#include "net/third_party/quiche/src/quic/core/quic_packet_writer.h"
17#include "net/third_party/quiche/src/quic/core/quic_types.h"
18#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
19#include "net/quic/platform/impl/quic_export_impl.h"
20
21namespace quic {
22
23namespace test {
24class QuicPathValidatorPeer;
25}
26
27class QuicConnection;
28
29// Interface to provide the information of the path to be validated.
30class QUIC_EXPORT_PRIVATE QuicPathValidationContext {
31 public:
32 QuicPathValidationContext(const QuicSocketAddress& self_address,
33 const QuicSocketAddress& peer_address)
34 : self_address_(self_address), peer_address_(peer_address) {}
35
36 virtual ~QuicPathValidationContext() = default;
37
38 virtual QuicPacketWriter* WriterToUse() = 0;
39
40 const QuicSocketAddress& self_address() const { return self_address_; }
41 const QuicSocketAddress& peer_address() const { return peer_address_; }
42
43 private:
44 QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
45 std::ostream& os,
46 const QuicPathValidationContext& context);
47
48 QuicSocketAddress self_address_;
49 QuicSocketAddress peer_address_;
50};
51
52// Used to validate a path by sending up to 3 PATH_CHALLENGE frames before
53// declaring a path validation failure.
54class QUIC_EXPORT_PRIVATE QuicPathValidator {
55 public:
56 static const uint16_t kMaxRetryTimes = 2;
57
58 // Used to write PATH_CHALLENGE on the path to be validated and to get retry
59 // timeout.
60 class QUIC_EXPORT_PRIVATE SendDelegate {
61 public:
62 virtual ~SendDelegate() = default;
63
64 // Send a PATH_CHALLENGE with |data_buffer| as the frame payload using given
65 // path information. Return false if the delegate doesn't want to continue
66 // the validation.
67 virtual bool SendPathChallenge(const QuicPathFrameBuffer& data_buffer,
68 const QuicSocketAddress& self_address,
69 const QuicSocketAddress& peer_address,
70 QuicPacketWriter* writer) = 0;
71 // Return the time to retry sending PATH_CHALLENGE again based on given peer
72 // address and writer.
73 virtual QuicTime GetRetryTimeout(const QuicSocketAddress& peer_address,
74 QuicPacketWriter* writer) const = 0;
75 };
76
77 // Handles the validation result.
78 class QUIC_EXPORT_PRIVATE ResultDelegate {
79 public:
80 virtual ~ResultDelegate() = default;
81
82 virtual void OnPathValidationSuccess(
83 std::unique_ptr<QuicPathValidationContext> context) = 0;
84
85 virtual void OnPathValidationFailure(
86 std::unique_ptr<QuicPathValidationContext> context) = 0;
87 };
88
89 QuicPathValidator(QuicAlarmFactory* alarm_factory,
90 QuicConnectionArena* arena,
91 SendDelegate* delegate,
92 QuicRandom* random);
93
94 // Send PATH_CHALLENGE and start the retry timer.
95 void StartValidingPath(std::unique_ptr<QuicPathValidationContext> context,
96 std::unique_ptr<ResultDelegate> result_delegate);
97
98 // Called when a PATH_RESPONSE frame has been received. Matches the received
99 // PATH_RESPONSE payload with the payloads previously sent in PATH_CHALLANGE
100 // frames and the self address on which it was sent.
101 void OnPathResponse(const QuicPathFrameBuffer& probing_data,
102 QuicSocketAddress self_address);
103
104 // Cancel the retry timer and reset the path and result delegate.
105 void CancelPathValidation();
106
107 bool HasPendingPathValidation() const;
108
109 // Send another PATH_CHALLENGE on the same path. After retrying
110 // |kMaxRetryTimes| times, fail the current path validation.
111 void OnRetryTimeout();
112
113 private:
114 friend class test::QuicPathValidatorPeer;
115
116 // Return the payload to be used in the next PATH_CHALLENGE frame.
117 const QuicPathFrameBuffer& GeneratePathChallengePayload();
118
119 void SendPathChallengeAndSetAlarm();
120
121 void ResetPathValidation();
122
123 // Has at most 3 entries due to validation timeout.
124 QuicInlinedVector<QuicPathFrameBuffer, 3> probing_data_;
125 SendDelegate* send_delegate_;
126 QuicRandom* random_;
127 std::unique_ptr<QuicPathValidationContext> path_context_;
128 std::unique_ptr<ResultDelegate> result_delegate_;
129 QuicArenaScopedPtr<QuicAlarm> retry_timer_;
130 size_t retry_count_;
131};
132
133} // namespace quic
134
135#endif // QUICHE_QUIC_CORE_QUIC_PATH_VALIDATOR_H_