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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
|
// Copyright 2013 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 NET_QUIC_QUIC_SENT_PACKET_MANAGER_H_
#define NET_QUIC_QUIC_SENT_PACKET_MANAGER_H_
#include <deque>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <utility>
#include <vector>
#include "base/containers/hash_tables.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/linked_hash_map.h"
#include "net/quic/congestion_control/loss_detection_interface.h"
#include "net/quic/congestion_control/rtt_stats.h"
#include "net/quic/congestion_control/send_algorithm_interface.h"
#include "net/quic/quic_ack_notifier_manager.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_unacked_packet_map.h"
namespace net {
namespace test {
class QuicConnectionPeer;
class QuicSentPacketManagerPeer;
} // namespace test
class QuicClock;
class QuicConfig;
struct QuicConnectionStats;
// Class which tracks the set of packets sent on a QUIC connection and contains
// a send algorithm to decide when to send new packets. It keeps track of any
// retransmittable data associated with each packet. If a packet is
// retransmitted, it will keep track of each version of a packet so that if a
// previous transmission is acked, the data will not be retransmitted.
class NET_EXPORT_PRIVATE QuicSentPacketManager {
public:
// Struct to store the pending retransmission information.
struct PendingRetransmission {
PendingRetransmission(QuicPacketSequenceNumber sequence_number,
TransmissionType transmission_type,
const RetransmittableFrames& retransmittable_frames,
QuicSequenceNumberLength sequence_number_length)
: sequence_number(sequence_number),
transmission_type(transmission_type),
retransmittable_frames(retransmittable_frames),
sequence_number_length(sequence_number_length) {
}
QuicPacketSequenceNumber sequence_number;
TransmissionType transmission_type;
const RetransmittableFrames& retransmittable_frames;
QuicSequenceNumberLength sequence_number_length;
};
QuicSentPacketManager(bool is_server,
const QuicClock* clock,
QuicConnectionStats* stats,
CongestionFeedbackType congestion_type,
LossDetectionType loss_type);
virtual ~QuicSentPacketManager();
virtual void SetFromConfig(const QuicConfig& config);
// Called when a new packet is serialized. If the packet contains
// retransmittable data, it will be added to the unacked packet map.
void OnSerializedPacket(const SerializedPacket& serialized_packet);
// Called when a packet is retransmitted with a new sequence number.
// Replaces the old entry in the unacked packet map with the new
// sequence number.
void OnRetransmittedPacket(QuicPacketSequenceNumber old_sequence_number,
QuicPacketSequenceNumber new_sequence_number);
// Processes the incoming ack.
void OnIncomingAck(const ReceivedPacketInfo& received_info,
QuicTime ack_receive_time);
// Returns true if the non-FEC packet |sequence_number| is unacked.
bool IsUnacked(QuicPacketSequenceNumber sequence_number) const;
// Requests retransmission of all unacked packets of |retransmission_type|.
void RetransmitUnackedPackets(RetransmissionType retransmission_type);
// Removes the retransmittable frames from all unencrypted packets to ensure
// they don't get retransmitted.
void NeuterUnencryptedPackets();
// Returns true if the unacked packet |sequence_number| has retransmittable
// frames. This will only return false if the packet has been acked, if a
// previous transmission of this packet was ACK'd, or if this packet has been
// retransmitted as with different sequence number.
bool HasRetransmittableFrames(QuicPacketSequenceNumber sequence_number) const;
// Returns true if there are pending retransmissions.
bool HasPendingRetransmissions() const;
// Retrieves the next pending retransmission.
PendingRetransmission NextPendingRetransmission();
bool HasUnackedPackets() const;
// Returns the smallest sequence number of a serialized packet which has not
// been acked by the peer. If there are no unacked packets, returns 0.
QuicPacketSequenceNumber GetLeastUnackedSentPacket() const;
// Called when a congestion feedback frame is received from peer.
virtual void OnIncomingQuicCongestionFeedbackFrame(
const QuicCongestionFeedbackFrame& frame,
const QuicTime& feedback_receive_time);
// Called when we have sent bytes to the peer. This informs the manager both
// the number of bytes sent and if they were retransmitted. Returns true if
// the sender should reset the retransmission timer.
virtual bool OnPacketSent(QuicPacketSequenceNumber sequence_number,
QuicTime sent_time,
QuicByteCount bytes,
TransmissionType transmission_type,
HasRetransmittableData has_retransmittable_data);
// Called when the retransmission timer expires.
virtual void OnRetransmissionTimeout();
// Calculate the time until we can send the next packet to the wire.
// Note 1: When kUnknownWaitTime is returned, there is no need to poll
// TimeUntilSend again until we receive an OnIncomingAckFrame event.
// Note 2: Send algorithms may or may not use |retransmit| in their
// calculations.
virtual QuicTime::Delta TimeUntilSend(QuicTime now,
HasRetransmittableData retransmittable);
// Returns amount of time for delayed ack timer.
const QuicTime::Delta DelayedAckTime() const;
// Returns the current delay for the retransmission timer, which may send
// either a tail loss probe or do a full RTO. Returns QuicTime::Zero() if
// there are no retransmittable packets.
const QuicTime GetRetransmissionTime() const;
const RttStats* GetRttStats() const;
// Returns the estimated bandwidth calculated by the congestion algorithm.
QuicBandwidth BandwidthEstimate() const;
// Returns the size of the current congestion window in bytes. Note, this is
// not the *available* window. Some send algorithms may not use a congestion
// window and will return 0.
QuicByteCount GetCongestionWindow() const;
// Enables pacing if it has not already been enabled, and if
// FLAGS_enable_quic_pacing is set.
void MaybeEnablePacing();
bool using_pacing() const { return using_pacing_; }
private:
friend class test::QuicConnectionPeer;
friend class test::QuicSentPacketManagerPeer;
// The retransmission timer is a single timer which switches modes depending
// upon connection state.
enum RetransmissionTimeoutMode {
// A conventional TCP style RTO.
RTO_MODE,
// A tail loss probe. By default, QUIC sends up to two before RTOing.
TLP_MODE,
// Retransmission of handshake packets prior to handshake completion.
HANDSHAKE_MODE,
// Re-invoke the loss detection when a packet is not acked before the
// loss detection algorithm expects.
LOSS_MODE,
};
typedef linked_hash_map<QuicPacketSequenceNumber,
TransmissionType> PendingRetransmissionMap;
// Process the incoming ack looking for newly ack'd data packets.
void HandleAckForSentPackets(const ReceivedPacketInfo& received_info);
// Returns the current retransmission mode.
RetransmissionTimeoutMode GetRetransmissionMode() const;
// Retransmits all crypto stream packets.
void RetransmitCryptoPackets();
// Retransmits the oldest pending packet.
void RetransmitOldestPacket();
// Retransmits all the packets and abandons by invoking a full RTO.
void RetransmitAllPackets();
// Returns the timer for retransmitting crypto handshake packets.
const QuicTime::Delta GetCryptoRetransmissionDelay() const;
// Returns the timer for a new tail loss probe.
const QuicTime::Delta GetTailLossProbeDelay() const;
// Returns the retransmission timeout, after which a full RTO occurs.
const QuicTime::Delta GetRetransmissionDelay() const;
// Update the RTT if the ack is for the largest acked sequence number.
// Returns true if the rtt was updated.
bool MaybeUpdateRTT(const ReceivedPacketInfo& received_info,
const QuicTime& ack_receive_time);
// Invokes the loss detection algorithm and loses and retransmits packets if
// necessary.
void InvokeLossDetection(QuicTime time);
// Invokes OnCongestionEvent if |rtt_updated| is true, there are pending acks,
// or pending losses. Clears pending acks and pending losses afterwards.
// |bytes_in_flight| is the number of bytes in flight before the losses or
// acks.
void MaybeInvokeCongestionEvent(bool rtt_updated,
QuicByteCount bytes_in_flight);
// Marks |sequence_number| as having been revived by the peer, but not
// received, so the packet remains pending if it is and the congestion control
// does not consider the packet acked.
void MarkPacketRevived(QuicPacketSequenceNumber sequence_number,
QuicTime::Delta delta_largest_observed);
// Removes the retransmittability and pending properties from the packet at
// |it| due to receipt by the peer. Returns an iterator to the next remaining
// unacked packet.
QuicUnackedPacketMap::const_iterator MarkPacketHandled(
QuicUnackedPacketMap::const_iterator it,
QuicTime::Delta delta_largest_observed);
// Request that |sequence_number| be retransmitted after the other pending
// retransmissions. Does not add it to the retransmissions if it's already
// a pending retransmission.
void MarkForRetransmission(QuicPacketSequenceNumber sequence_number,
TransmissionType transmission_type);
// Newly serialized retransmittable and fec packets are added to this map,
// which contains owning pointers to any contained frames. If a packet is
// retransmitted, this map will contain entries for both the old and the new
// packet. The old packet's retransmittable frames entry will be NULL, while
// the new packet's entry will contain the frames to retransmit.
// If the old packet is acked before the new packet, then the old entry will
// be removed from the map and the new entry's retransmittable frames will be
// set to NULL.
QuicUnackedPacketMap unacked_packets_;
// Pending retransmissions which have not been packetized and sent yet.
PendingRetransmissionMap pending_retransmissions_;
// Tracks if the connection was created by the server.
bool is_server_;
// An AckNotifier can register to be informed when ACKs have been received for
// all packets that a given block of data was sent in. The AckNotifierManager
// maintains the currently active notifiers.
AckNotifierManager ack_notifier_manager_;
const QuicClock* clock_;
QuicConnectionStats* stats_;
RttStats rtt_stats_;
scoped_ptr<SendAlgorithmInterface> send_algorithm_;
scoped_ptr<LossDetectionInterface> loss_algorithm_;
QuicPacketSequenceNumber largest_observed_; // From the most recent ACK.
// Number of times the RTO timer has fired in a row without receiving an ack.
size_t consecutive_rto_count_;
// Number of times the tail loss probe has been sent.
size_t consecutive_tlp_count_;
// Number of times the crypto handshake has been retransmitted.
size_t consecutive_crypto_retransmission_count_;
// Whether a tlp packet can be sent even if the send algorithm says not to.
bool pending_tlp_transmission_;
// Maximum number of tail loss probes to send before firing an RTO.
size_t max_tail_loss_probes_;
bool using_pacing_;
// Sets of packets acked and lost as a result of the last congestion event.
SendAlgorithmInterface::CongestionMap packets_acked_;
SendAlgorithmInterface::CongestionMap packets_lost_;
DISALLOW_COPY_AND_ASSIGN(QuicSentPacketManager);
};
} // namespace net
#endif // NET_QUIC_QUIC_SENT_PACKET_MANAGER_H_
|