blob: 09bc2cc56c3adeaf21df4893b2404ba7d8118ba5 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2016 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_BUFFERED_PACKET_STORE_H_
6#define QUICHE_QUIC_CORE_QUIC_BUFFERED_PACKET_STORE_H_
7
8#include <list>
vasilvv872e7a32019-03-12 16:42:44 -07009#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -050010
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_packets.h"
14#include "net/third_party/quiche/src/quic/core/quic_time.h"
15#include "net/third_party/quiche/src/quic/platform/api/quic_clock.h"
16#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h"
17#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
18#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050019
20namespace quic {
21
22namespace test {
23class QuicBufferedPacketStorePeer;
24} // namespace test
25
26// This class buffers packets for each connection until either
27// 1) They are requested to be delivered via
28// DeliverPacket()/DeliverPacketsForNextConnection(), or
29// 2) They expire after exceeding their lifetime in the store.
30//
31// It can only buffer packets on certain number of connections. It has two pools
32// of connections: connections with CHLO buffered and those without CHLO. The
33// latter has its own upper limit along with the max number of connections this
34// store can hold. The former pool can grow till this store is full.
35class QUIC_EXPORT_PRIVATE QuicBufferedPacketStore {
36 public:
37 enum EnqueuePacketResult {
38 SUCCESS = 0,
39 TOO_MANY_PACKETS, // Too many packets stored up for a certain connection.
40 TOO_MANY_CONNECTIONS // Too many connections stored up in the store.
41 };
42
43 struct QUIC_EXPORT_PRIVATE BufferedPacket {
44 BufferedPacket(std::unique_ptr<QuicReceivedPacket> packet,
45 QuicSocketAddress self_address,
46 QuicSocketAddress peer_address);
47 BufferedPacket(BufferedPacket&& other);
48
49 BufferedPacket& operator=(BufferedPacket&& other);
50
51 ~BufferedPacket();
52
53 std::unique_ptr<QuicReceivedPacket> packet;
54 QuicSocketAddress self_address;
55 QuicSocketAddress peer_address;
56 };
57
58 // A queue of BufferedPackets for a connection.
59 struct QUIC_EXPORT_PRIVATE BufferedPacketList {
60 BufferedPacketList();
61 BufferedPacketList(BufferedPacketList&& other);
62
63 BufferedPacketList& operator=(BufferedPacketList&& other);
64
65 ~BufferedPacketList();
66
67 std::list<BufferedPacket> buffered_packets;
68 QuicTime creation_time;
69 // The alpn from the CHLO, if one was found.
vasilvvc48c8712019-03-11 13:38:16 -070070 std::string alpn;
QUICHE teama6ef0a62019-03-07 20:34:33 -050071 // Indicating whether this is an IETF QUIC connection.
72 bool ietf_quic;
73 // If buffered_packets contains the CHLO, it is the version of the CHLO.
74 // Otherwise, it is the version of the first packet in |buffered_packets|.
75 ParsedQuicVersion version;
76 };
77
78 typedef QuicLinkedHashMap<QuicConnectionId,
79 BufferedPacketList,
80 QuicConnectionIdHash>
81 BufferedPacketMap;
82
83 class QUIC_EXPORT_PRIVATE VisitorInterface {
84 public:
85 virtual ~VisitorInterface() {}
86
87 // Called for each expired connection when alarm fires.
88 virtual void OnExpiredPackets(QuicConnectionId connection_id,
89 BufferedPacketList early_arrived_packets) = 0;
90 };
91
92 QuicBufferedPacketStore(VisitorInterface* vistor,
93 const QuicClock* clock,
94 QuicAlarmFactory* alarm_factory);
95
96 QuicBufferedPacketStore(const QuicBufferedPacketStore&) = delete;
97
98 ~QuicBufferedPacketStore();
99
100 QuicBufferedPacketStore& operator=(const QuicBufferedPacketStore&) = delete;
101
102 // Adds a copy of packet into packet queue for given connection.
103 // TODO(danzh): Consider to split this method to EnqueueChlo() and
104 // EnqueueDataPacket().
105 EnqueuePacketResult EnqueuePacket(QuicConnectionId connection_id,
106 bool ietf_quic,
107 const QuicReceivedPacket& packet,
108 QuicSocketAddress self_address,
109 QuicSocketAddress peer_address,
110 bool is_chlo,
vasilvvc48c8712019-03-11 13:38:16 -0700111 const std::string& alpn,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500112 const ParsedQuicVersion& version);
113
114 // Returns true if there are any packets buffered for |connection_id|.
115 bool HasBufferedPackets(QuicConnectionId connection_id) const;
116
117 // Returns the list of buffered packets for |connection_id| and removes them
118 // from the store. Returns an empty list if no early arrived packets for this
119 // connection are present.
120 BufferedPacketList DeliverPackets(QuicConnectionId connection_id);
121
122 // Discards packets buffered for |connection_id|, if any.
123 void DiscardPackets(QuicConnectionId connection_id);
124
125 // Examines how long packets have been buffered in the store for each
126 // connection. If they stay too long, removes them for new coming packets and
127 // calls |visitor_|'s OnPotentialConnectionExpire().
128 // Resets the alarm at the end.
129 void OnExpirationTimeout();
130
131 // Delivers buffered packets for next connection with CHLO to open.
132 // Return connection id for next connection in |connection_id|
133 // and all buffered packets including CHLO.
134 // The returned list should at least has one packet(CHLO) if
135 // store does have any connection to open. If no connection in the store has
136 // received CHLO yet, empty list will be returned.
137 BufferedPacketList DeliverPacketsForNextConnection(
138 QuicConnectionId* connection_id);
139
140 // Is given connection already buffered in the store?
141 bool HasChloForConnection(QuicConnectionId connection_id);
142
143 // Is there any CHLO buffered in the store?
144 bool HasChlosBuffered() const;
145
146 private:
147 friend class test::QuicBufferedPacketStorePeer;
148
149 // Set expiration alarm if it hasn't been set.
150 void MaybeSetExpirationAlarm();
151
152 // Return true if add an extra packet will go beyond allowed max connection
153 // limit. The limit for non-CHLO packet and CHLO packet is different.
154 bool ShouldBufferPacket(bool is_chlo);
155
156 // A map to store packet queues with creation time for each connection.
157 BufferedPacketMap undecryptable_packets_;
158
159 // The max time the packets of a connection can be buffer in the store.
160 const QuicTime::Delta connection_life_span_;
161
162 VisitorInterface* visitor_; // Unowned.
163
164 const QuicClock* clock_; // Unowned.
165
166 // This alarm fires every |connection_life_span_| to clean up
167 // packets staying in the store for too long.
168 std::unique_ptr<QuicAlarm> expiration_alarm_;
169
170 // Keeps track of connection with CHLO buffered up already and the order they
171 // arrive.
172 QuicLinkedHashMap<QuicConnectionId, bool, QuicConnectionIdHash>
173 connections_with_chlo_;
174};
175
176} // namespace quic
177
178#endif // QUICHE_QUIC_CORE_QUIC_BUFFERED_PACKET_STORE_H_