blob: 5b26aeb21a5bce435a19857ca7d051fadd91370a [file] [log] [blame]
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001/*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef P2P_BASE_PSEUDOTCP_H_
12#define P2P_BASE_PSEUDOTCP_H_
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000013
14#include <list>
15
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "rtc_base/stream.h"
Mirko Bonadeiac194142018-10-22 17:08:37 +020017#include "rtc_base/system/rtc_export.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000018
19namespace cricket {
20
21//////////////////////////////////////////////////////////////////////
22// IPseudoTcpNotify
23//////////////////////////////////////////////////////////////////////
24
25class PseudoTcp;
26
27class IPseudoTcpNotify {
28 public:
29 // Notification of tcp events
30 virtual void OnTcpOpen(PseudoTcp* tcp) = 0;
31 virtual void OnTcpReadable(PseudoTcp* tcp) = 0;
32 virtual void OnTcpWriteable(PseudoTcp* tcp) = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +020033 virtual void OnTcpClosed(PseudoTcp* tcp, uint32_t error) = 0;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000034
35 // Write the packet onto the network
36 enum WriteResult { WR_SUCCESS, WR_TOO_LARGE, WR_FAIL };
37 virtual WriteResult TcpWritePacket(PseudoTcp* tcp,
Yves Gerey665174f2018-06-19 15:03:05 +020038 const char* buffer,
39 size_t len) = 0;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000040
41 protected:
42 virtual ~IPseudoTcpNotify() {}
43};
44
45//////////////////////////////////////////////////////////////////////
46// PseudoTcp
47//////////////////////////////////////////////////////////////////////
48
Mirko Bonadeiac194142018-10-22 17:08:37 +020049class RTC_EXPORT PseudoTcp {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000050 public:
Peter Boström0c4e06b2015-10-07 12:23:21 +020051 static uint32_t Now();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000052
Peter Boström0c4e06b2015-10-07 12:23:21 +020053 PseudoTcp(IPseudoTcpNotify* notify, uint32_t conv);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000054 virtual ~PseudoTcp();
55
56 int Connect();
57 int Recv(char* buffer, size_t len);
58 int Send(const char* buffer, size_t len);
59 void Close(bool force);
60 int GetError();
61
62 enum TcpState {
Yves Gerey665174f2018-06-19 15:03:05 +020063 TCP_LISTEN,
64 TCP_SYN_SENT,
65 TCP_SYN_RECEIVED,
66 TCP_ESTABLISHED,
67 TCP_CLOSED
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000068 };
69 TcpState State() const { return m_state; }
70
71 // Call this when the PMTU changes.
Peter Boström0c4e06b2015-10-07 12:23:21 +020072 void NotifyMTU(uint16_t mtu);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000073
74 // Call this based on timeout value returned from GetNextClock.
75 // It's ok to call this too frequently.
Peter Boström0c4e06b2015-10-07 12:23:21 +020076 void NotifyClock(uint32_t now);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000077
78 // Call this whenever a packet arrives.
79 // Returns true if the packet was processed successfully.
Yves Gerey665174f2018-06-19 15:03:05 +020080 bool NotifyPacket(const char* buffer, size_t len);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000081
82 // Call this to determine the next time NotifyClock should be called.
83 // Returns false if the socket is ready to be destroyed.
Peter Boström0c4e06b2015-10-07 12:23:21 +020084 bool GetNextClock(uint32_t now, long& timeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000085
86 // Call these to get/set option values to tailor this PseudoTcp
87 // instance's behaviour for the kind of data it will carry.
88 // If an unrecognized option is set or got, an assertion will fire.
89 //
90 // Setting options for OPT_RCVBUF or OPT_SNDBUF after Connect() is called
91 // will result in an assertion.
92 enum Option {
Yves Gerey665174f2018-06-19 15:03:05 +020093 OPT_NODELAY, // Whether to enable Nagle's algorithm (0 == off)
94 OPT_ACKDELAY, // The Delayed ACK timeout (0 == off).
95 OPT_RCVBUF, // Set the receive buffer size, in bytes.
96 OPT_SNDBUF, // Set the send buffer size, in bytes.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000097 };
98 void GetOption(Option opt, int* value);
99 void SetOption(Option opt, int value);
100
101 // Returns current congestion window in bytes.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200102 uint32_t GetCongestionWindow() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000103
104 // Returns amount of data in bytes that has been sent, but haven't
105 // been acknowledged.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200106 uint32_t GetBytesInFlight() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000107
108 // Returns number of bytes that were written in buffer and haven't
109 // been sent.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200110 uint32_t GetBytesBufferedNotSent() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000111
112 // Returns current round-trip time estimate in milliseconds.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200113 uint32_t GetRoundTripTimeEstimateMs() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000114
115 protected:
116 enum SendFlags { sfNone, sfDelayedAck, sfImmediateAck };
117
118 struct Segment {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200119 uint32_t conv, seq, ack;
120 uint8_t flags;
121 uint16_t wnd;
Yves Gerey665174f2018-06-19 15:03:05 +0200122 const char* data;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200123 uint32_t len;
124 uint32_t tsval, tsecr;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000125 };
126
127 struct SSegment {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200128 SSegment(uint32_t s, uint32_t l, bool c)
129 : seq(s), len(l), /*tstamp(0),*/ xmit(0), bCtrl(c) {}
130 uint32_t seq, len;
131 // uint32_t tstamp;
132 uint8_t xmit;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000133 bool bCtrl;
134 };
135 typedef std::list<SSegment> SList;
136
137 struct RSegment {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200138 uint32_t seq, len;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000139 };
140
Peter Boström0c4e06b2015-10-07 12:23:21 +0200141 uint32_t queue(const char* data, uint32_t len, bool bCtrl);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000142
143 // Creates a packet and submits it to the network. This method can either
144 // send payload or just an ACK packet.
145 //
146 // |seq| is the sequence number of this packet.
147 // |flags| is the flags for sending this packet.
148 // |offset| is the offset to read from |m_sbuf|.
149 // |len| is the number of bytes to read from |m_sbuf| as payload. If this
150 // value is 0 then this is an ACK packet, otherwise this packet has payload.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200151 IPseudoTcpNotify::WriteResult packet(uint32_t seq,
152 uint8_t flags,
153 uint32_t offset,
154 uint32_t len);
155 bool parse(const uint8_t* buffer, uint32_t size);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000156
157 void attemptSend(SendFlags sflags = sfNone);
158
Peter Boström0c4e06b2015-10-07 12:23:21 +0200159 void closedown(uint32_t err = 0);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000160
Peter Boström0c4e06b2015-10-07 12:23:21 +0200161 bool clock_check(uint32_t now, long& nTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000162
163 bool process(Segment& seg);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200164 bool transmit(const SList::iterator& seg, uint32_t now);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000165
166 void adjustMTU();
167
168 protected:
169 // This method is used in test only to query receive buffer state.
170 bool isReceiveBufferFull() const;
171
172 // This method is only used in tests, to disable window scaling
173 // support for testing backward compatibility.
174 void disableWindowScale();
175
176 private:
177 // Queue the connect message with TCP options.
178 void queueConnectMessage();
179
180 // Parse TCP options in the header.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200181 void parseOptions(const char* data, uint32_t len);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000182
183 // Apply a TCP option that has been read from the header.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200184 void applyOption(char kind, const char* data, uint32_t len);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000185
186 // Apply window scale option.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200187 void applyWindowScaleOption(uint8_t scale_factor);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000188
189 // Resize the send buffer with |new_size| in bytes.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200190 void resizeSendBuffer(uint32_t new_size);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000191
192 // Resize the receive buffer with |new_size| in bytes. This call adjusts
193 // window scale factor |m_swnd_scale| accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200194 void resizeReceiveBuffer(uint32_t new_size);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000195
196 IPseudoTcpNotify* m_notify;
197 enum Shutdown { SD_NONE, SD_GRACEFUL, SD_FORCEFUL } m_shutdown;
198 int m_error;
199
200 // TCB data
201 TcpState m_state;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200202 uint32_t m_conv;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000203 bool m_bReadEnable, m_bWriteEnable, m_bOutgoing;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200204 uint32_t m_lasttraffic;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000205
206 // Incoming data
207 typedef std::list<RSegment> RList;
208 RList m_rlist;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200209 uint32_t m_rbuf_len, m_rcv_nxt, m_rcv_wnd, m_lastrecv;
210 uint8_t m_rwnd_scale; // Window scale factor.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000211 rtc::FifoBuffer m_rbuf;
212
213 // Outgoing data
214 SList m_slist;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200215 uint32_t m_sbuf_len, m_snd_nxt, m_snd_wnd, m_lastsend, m_snd_una;
216 uint8_t m_swnd_scale; // Window scale factor.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000217 rtc::FifoBuffer m_sbuf;
218
219 // Maximum segment size, estimated protocol level, largest segment sent
Peter Boström0c4e06b2015-10-07 12:23:21 +0200220 uint32_t m_mss, m_msslevel, m_largest, m_mtu_advise;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000221 // Retransmit timer
Peter Boström0c4e06b2015-10-07 12:23:21 +0200222 uint32_t m_rto_base;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000223
224 // Timestamp tracking
Peter Boström0c4e06b2015-10-07 12:23:21 +0200225 uint32_t m_ts_recent, m_ts_lastack;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000226
227 // Round-trip calculation
Peter Boström0c4e06b2015-10-07 12:23:21 +0200228 uint32_t m_rx_rttvar, m_rx_srtt, m_rx_rto;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000229
230 // Congestion avoidance, Fast retransmit/recovery, Delayed ACKs
Peter Boström0c4e06b2015-10-07 12:23:21 +0200231 uint32_t m_ssthresh, m_cwnd;
232 uint8_t m_dup_acks;
233 uint32_t m_recover;
234 uint32_t m_t_ack;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000235
236 // Configuration options
237 bool m_use_nagling;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200238 uint32_t m_ack_delay;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000239
240 // This is used by unit tests to test backward compatibility of
241 // PseudoTcp implementations that don't support window scaling.
242 bool m_support_wnd_scale;
243};
244
245} // namespace cricket
246
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200247#endif // P2P_BASE_PSEUDOTCP_H_