summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quic/test_tools/simple_session_notifier.h
blob: 7366ed8df12f4c358a83f314764ef299f3146126 (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) 2018 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_TEST_TOOLS_SIMPLE_SESSION_NOTIFIER_H_
#define QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_NOTIFIER_H_

#include "net/third_party/quiche/src/quic/core/quic_circular_deque.h"
#include "net/third_party/quiche/src/quic/core/quic_interval_set.h"
#include "net/third_party/quiche/src/quic/core/session_notifier_interface.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"

namespace quic {

class QuicConnection;

namespace test {

// SimpleSessionNotifier implements the basic functionalities of a session, and
// it manages stream data and control frames.
class SimpleSessionNotifier : public SessionNotifierInterface {
 public:
  explicit SimpleSessionNotifier(QuicConnection* connection);
  ~SimpleSessionNotifier() override;

  // Tries to write stream data and returns data consumed.
  QuicConsumedData WriteOrBufferData(QuicStreamId id,
                                     QuicByteCount data_length,
                                     StreamSendingState state);

  // Tries to write RST_STREAM_FRAME.
  void WriteOrBufferRstStream(QuicStreamId id,
                              QuicRstStreamErrorCode error,
                              QuicStreamOffset bytes_written);
  // Tries to write PING.
  void WriteOrBufferPing();

  // Tries to write CRYPTO data and returns the number of bytes written.
  size_t WriteCryptoData(EncryptionLevel level,
                         QuicByteCount data_length,
                         QuicStreamOffset offset);

  // Neuters unencrypted data of crypto stream.
  void NeuterUnencryptedData();

  // Called when connection_ becomes writable.
  void OnCanWrite();

  // Called to reset stream.
  void OnStreamReset(QuicStreamId id, QuicRstStreamErrorCode error);

  // Returns true if there are 1) unsent control frames and stream data, or 2)
  // lost control frames and stream data.
  bool WillingToWrite() const;

  // Number of sent stream bytes. Please note, this does not count
  // retransmissions.
  QuicByteCount StreamBytesSent() const;

  // Number of stream bytes waiting to be sent for the first time.
  QuicByteCount StreamBytesToSend() const;

  // Returns true if there is any stream data waiting to be sent for the first
  // time.
  bool HasBufferedStreamData() const;

  // Returns true if stream |id| has any outstanding data.
  bool StreamIsWaitingForAcks(QuicStreamId id) const;

  // SessionNotifierInterface methods:
  bool OnFrameAcked(const QuicFrame& frame,
                    QuicTime::Delta ack_delay_time,
                    QuicTime receive_timestamp) override;
  void OnStreamFrameRetransmitted(const QuicStreamFrame& /*frame*/) override {}
  void OnFrameLost(const QuicFrame& frame) override;
  void RetransmitFrames(const QuicFrames& frames,
                        TransmissionType type) override;
  bool IsFrameOutstanding(const QuicFrame& frame) const override;
  bool HasUnackedCryptoData() const override;
  bool HasUnackedStreamData() const override;

 private:
  struct StreamState {
    StreamState();
    ~StreamState();

    // Total number of bytes.
    QuicByteCount bytes_total;
    // Number of sent bytes.
    QuicByteCount bytes_sent;
    // Record of acked offsets.
    QuicIntervalSet<QuicStreamOffset> bytes_acked;
    // Data considered as lost and needs to be retransmitted.
    QuicIntervalSet<QuicStreamOffset> pending_retransmissions;

    bool fin_buffered;
    bool fin_sent;
    bool fin_outstanding;
    bool fin_lost;
  };

  friend std::ostream& operator<<(std::ostream& os, const StreamState& s);

  using StreamMap = QuicUnorderedMap<QuicStreamId, StreamState>;

  void OnStreamDataConsumed(QuicStreamId id,
                            QuicStreamOffset offset,
                            QuicByteCount data_length,
                            bool fin);

  bool OnControlFrameAcked(const QuicFrame& frame);

  void OnControlFrameLost(const QuicFrame& frame);

  bool RetransmitLostControlFrames();

  bool RetransmitLostCryptoData();

  bool RetransmitLostStreamData();

  bool WriteBufferedControlFrames();

  bool IsControlFrameOutstanding(const QuicFrame& frame) const;

  bool HasBufferedControlFrames() const;

  bool HasLostStreamData() const;

  bool StreamHasBufferedData(QuicStreamId id) const;

  QuicCircularDeque<QuicFrame> control_frames_;

  QuicLinkedHashMap<QuicControlFrameId, bool> lost_control_frames_;

  // Id of latest saved control frame. 0 if no control frame has been saved.
  QuicControlFrameId last_control_frame_id_;

  // The control frame at the 0th index of control_frames_.
  QuicControlFrameId least_unacked_;

  // ID of the least unsent control frame.
  QuicControlFrameId least_unsent_;

  StreamMap stream_map_;

  // Transferred crypto bytes according to encryption levels.
  QuicIntervalSet<QuicStreamOffset>
      crypto_bytes_transferred_[NUM_ENCRYPTION_LEVELS];

  StreamState crypto_state_[NUM_ENCRYPTION_LEVELS];

  QuicConnection* connection_;
};

}  // namespace test

}  // namespace quic

#endif  // QUICHE_QUIC_TEST_TOOLS_SIMPLE_SESSION_NOTIFIER_H_