summaryrefslogtreecommitdiff
path: root/chromium/net/quic/core/quic_packet_generator.h
blob: f1cfd7978e903a993ba5d3328aeb68cf04418092 (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
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
// Copyright (c) 2012 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.
//
// Responsible for generating packets on behalf of a QuicConnection.
// Packets are serialized just-in-time.  Control frames are queued.
// Ack and Feedback frames will be requested from the Connection
// just-in-time.  When a packet needs to be sent, the Generator
// will serialize a packet and pass it to QuicConnection::SendOrQueuePacket()
//
// The Generator's mode of operation is controlled by two conditions:
//
// 1) Is the Delegate writable?
//
// If the Delegate is not writable, then no operations will cause
// a packet to be serialized.  In particular:
// * SetShouldSendAck will simply record that an ack is to be sent.
// * AddControlFrame will enqueue the control frame.
// * ConsumeData will do nothing.
//
// If the Delegate is writable, then the behavior depends on the second
// condition:
//
// 2) Is the Generator in batch mode?
//
// If the Generator is NOT in batch mode, then each call to a write
// operation will serialize one or more packets.  The contents will
// include any previous queued frames.  If an ack should be sent
// but has not been sent, then the Delegate will be asked to create
// an Ack frame which will then be included in the packet.  When
// the write call completes, the current packet will be serialized
// and sent to the Delegate, even if it is not full.
//
// If the Generator is in batch mode, then each write operation will
// add data to the "current" packet.  When the current packet becomes
// full, it will be serialized and sent to the packet.  When batch
// mode is ended via |FinishBatchOperations|, the current packet
// will be serialzied, even if it is not full.

#ifndef NET_QUIC_CORE_QUIC_PACKET_GENERATOR_H_
#define NET_QUIC_CORE_QUIC_PACKET_GENERATOR_H_

#include <cstddef>
#include <cstdint>
#include <list>

#include "base/macros.h"
#include "net/quic/core/quic_packet_creator.h"
#include "net/quic/core/quic_pending_retransmission.h"
#include "net/quic/core/quic_sent_packet_manager.h"
#include "net/quic/core/quic_types.h"
#include "net/quic/platform/api/quic_export.h"

namespace net {

namespace test {
class QuicPacketGeneratorPeer;
}  // namespace test

class QUIC_EXPORT_PRIVATE QuicPacketGenerator {
 public:
  class QUIC_EXPORT_PRIVATE DelegateInterface
      : public QuicPacketCreator::DelegateInterface {
   public:
    ~DelegateInterface() override {}
    // Consults delegate whether a packet should be generated.
    virtual bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
                                      IsHandshake handshake) = 0;
    virtual const QuicFrame GetUpdatedAckFrame() = 0;
    virtual void PopulateStopWaitingFrame(
        QuicStopWaitingFrame* stop_waiting) = 0;
  };

  QuicPacketGenerator(QuicConnectionId connection_id,
                      QuicFramer* framer,
                      QuicRandom* random_generator,
                      DelegateInterface* delegate);

  ~QuicPacketGenerator();

  // Indicates that an ACK frame should be sent.
  // If |also_send_stop_waiting| is true, then it also indicates that a
  // STOP_WAITING frame should be sent as well.
  // The contents of the frame(s) will be generated via a call to the delegate
  // CreateAckFrame() when the packet is serialized.
  void SetShouldSendAck(bool also_send_stop_waiting);

  void AddControlFrame(const QuicFrame& frame);

  // Given some data, may consume part or all of it and pass it to the
  // packet creator to be serialized into packets. If not in batch
  // mode, these packets will also be sent during this call.
  // When |state| is FIN_AND_PADDING, random padding of size [1, 256] will be
  // added after stream frames. If current constructed packet cannot
  // accommodate, the padding will overflow to the next packet(s).
  QuicConsumedData ConsumeData(QuicStreamId id,
                               size_t write_length,
                               QuicStreamOffset offset,
                               StreamSendingState state);

  // Sends as many data only packets as allowed by the send algorithm and the
  // available iov.
  // This path does not support padding, or bundling pending frames.
  // In case we access this method from ConsumeData, total_bytes_consumed
  // keeps track of how many bytes have already been consumed.
  QuicConsumedData ConsumeDataFastPath(QuicStreamId id,
                                       size_t write_length,
                                       QuicStreamOffset offset,
                                       bool fin,
                                       size_t total_bytes_consumed);

  // Generates an MTU discovery packet of specified size.
  void GenerateMtuDiscoveryPacket(QuicByteCount target_mtu);

  // Indicates whether packet flusher is currently attached.
  bool PacketFlusherAttached() const;
  // Attaches packet flusher.
  void AttachPacketFlusher();
  // Flushes everything, including all queued frames and pending padding.
  void Flush();

  // Flushes all queued frames, even frames which are not sendable.
  void FlushAllQueuedFrames();

  bool HasQueuedFrames() const;

  // Whether the pending packet has no frames in it at the moment.
  bool IsPendingPacketEmpty() const;

  // Makes the framer not serialize the protocol version in sent packets.
  void StopSendingVersion();

  // SetDiversificationNonce sets the nonce that will be sent in each public
  // header of packets encrypted at the initial encryption level. Should only
  // be called by servers.
  void SetDiversificationNonce(const DiversificationNonce& nonce);

  // Creates a version negotiation packet which supports |supported_versions|.
  std::unique_ptr<QuicEncryptedPacket> SerializeVersionNegotiationPacket(
      const ParsedQuicVersionVector& supported_versions);

  // Creates a connectivity probing packet.
  OwningSerializedPacketPointer SerializeConnectivityProbingPacket();

  // Re-serializes frames with the original packet's packet number length.
  // Used for retransmitting packets to ensure they aren't too long.
  void ReserializeAllFrames(const QuicPendingRetransmission& retransmission,
                            char* buffer,
                            size_t buffer_len);

  // Update the packet number length to use in future packets as soon as it
  // can be safely changed.
  void UpdatePacketNumberLength(QuicPacketNumber least_packet_awaited_by_peer,
                                QuicPacketCount max_packets_in_flight);

  // Set the minimum number of bytes for the connection id length;
  void SetConnectionIdLength(uint32_t length);

  // Sets the encrypter to use for the encryption level.
  void SetEncrypter(EncryptionLevel level, QuicEncrypter* encrypter);

  // Returns true if there are control frames or current constructed packet has
  // pending retransmittable frames.
  bool HasRetransmittableFrames() const;

  // Returns true if current constructed packet has pending stream frames for
  // stream |id|.
  bool HasPendingStreamFramesOfStream(QuicStreamId id) const;

  // Sets the encryption level that will be applied to new packets.
  void set_encryption_level(EncryptionLevel level);

  // packet number of the last created packet, or 0 if no packets have been
  // created.
  QuicPacketNumber packet_number() const;

  // Returns the maximum length a current packet can actually have.
  QuicByteCount GetCurrentMaxPacketLength() const;

  // Set maximum packet length in the creator immediately.  May not be called
  // when there are frames queued in the creator.
  void SetMaxPacketLength(QuicByteCount length);

  // Set transmission type of next constructed packets.
  void SetTransmissionType(TransmissionType type);

  // Allow/Disallow setting transmission type of next constructed packets.
  void SetCanSetTransmissionType(bool can_set_transmission_type);

  void set_debug_delegate(QuicPacketCreator::DebugDelegate* debug_delegate) {
    packet_creator_.set_debug_delegate(debug_delegate);
  }

 private:
  friend class test::QuicPacketGeneratorPeer;

  void SendQueuedFrames(bool flush);

  // Test to see if we have pending ack, or control frames.
  bool HasPendingFrames() const;
  // Returns true if addition of a pending frame (which might be
  // retransmittable) would still allow the resulting packet to be sent now.
  bool CanSendWithNextPendingFrameAddition() const;
  // Add exactly one pending frame, preferring ack frames over control frames.
  // Returns true if a pending frame is successfully added.
  // Returns false and flushes current open packet if the pending frame cannot
  // fit into current open packet.
  bool AddNextPendingFrame();

  // Adds a random amount of padding (between 1 to 256 bytes).
  void AddRandomPadding();

  // Sends remaining pending padding.
  // Pending paddings should only be sent when there is nothing else to send.
  void SendRemainingPendingPadding();

  DelegateInterface* delegate_;

  QuicPacketCreator packet_creator_;
  QuicFrames queued_control_frames_;

  // True if packet flusher is currently attached.
  bool flusher_attached_;

  // Flags to indicate the need for just-in-time construction of a frame.
  bool should_send_ack_;
  bool should_send_stop_waiting_;
  // If we put a non-retransmittable frame in this packet, then we have to hold
  // a reference to it until we flush (and serialize it). Retransmittable frames
  // are referenced elsewhere so that they can later be (optionally)
  // retransmitted.
  QuicStopWaitingFrame pending_stop_waiting_frame_;

  QuicRandom* random_generator_;

  DISALLOW_COPY_AND_ASSIGN(QuicPacketGenerator);
};

}  // namespace net

#endif  // NET_QUIC_CORE_QUIC_PACKET_GENERATOR_H_