blob: cb6d974496f71d9ef36d53b8ce9b6c0efe7e2e7a [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
Steve Anton10542f22019-01-11 09:11:00 -080011#ifndef P2P_BASE_PSEUDO_TCP_H_
12#define P2P_BASE_PSEUDO_TCP_H_
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000013
Yves Gerey3e707812018-11-28 16:47:49 +010014#include <stddef.h>
15#include <stdint.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020016
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000017#include <list>
18
Niels Möller13339482019-03-28 13:30:15 +010019#include "rtc_base/memory/fifo_buffer.h"
Mirko Bonadeiac194142018-10-22 17:08:37 +020020#include "rtc_base/system/rtc_export.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000021
22namespace cricket {
23
24//////////////////////////////////////////////////////////////////////
25// IPseudoTcpNotify
26//////////////////////////////////////////////////////////////////////
27
28class PseudoTcp;
29
30class IPseudoTcpNotify {
31 public:
32 // Notification of tcp events
33 virtual void OnTcpOpen(PseudoTcp* tcp) = 0;
34 virtual void OnTcpReadable(PseudoTcp* tcp) = 0;
35 virtual void OnTcpWriteable(PseudoTcp* tcp) = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +020036 virtual void OnTcpClosed(PseudoTcp* tcp, uint32_t error) = 0;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000037
38 // Write the packet onto the network
39 enum WriteResult { WR_SUCCESS, WR_TOO_LARGE, WR_FAIL };
40 virtual WriteResult TcpWritePacket(PseudoTcp* tcp,
Yves Gerey665174f2018-06-19 15:03:05 +020041 const char* buffer,
42 size_t len) = 0;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000043
44 protected:
45 virtual ~IPseudoTcpNotify() {}
46};
47
48//////////////////////////////////////////////////////////////////////
49// PseudoTcp
50//////////////////////////////////////////////////////////////////////
51
Mirko Bonadeiac194142018-10-22 17:08:37 +020052class RTC_EXPORT PseudoTcp {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000053 public:
Peter Boström0c4e06b2015-10-07 12:23:21 +020054 static uint32_t Now();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000055
Peter Boström0c4e06b2015-10-07 12:23:21 +020056 PseudoTcp(IPseudoTcpNotify* notify, uint32_t conv);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000057 virtual ~PseudoTcp();
58
59 int Connect();
60 int Recv(char* buffer, size_t len);
61 int Send(const char* buffer, size_t len);
62 void Close(bool force);
63 int GetError();
64
65 enum TcpState {
Yves Gerey665174f2018-06-19 15:03:05 +020066 TCP_LISTEN,
67 TCP_SYN_SENT,
68 TCP_SYN_RECEIVED,
69 TCP_ESTABLISHED,
70 TCP_CLOSED
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000071 };
72 TcpState State() const { return m_state; }
73
74 // Call this when the PMTU changes.
Peter Boström0c4e06b2015-10-07 12:23:21 +020075 void NotifyMTU(uint16_t mtu);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000076
77 // Call this based on timeout value returned from GetNextClock.
78 // It's ok to call this too frequently.
Peter Boström0c4e06b2015-10-07 12:23:21 +020079 void NotifyClock(uint32_t now);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000080
81 // Call this whenever a packet arrives.
82 // Returns true if the packet was processed successfully.
Yves Gerey665174f2018-06-19 15:03:05 +020083 bool NotifyPacket(const char* buffer, size_t len);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000084
85 // Call this to determine the next time NotifyClock should be called.
86 // Returns false if the socket is ready to be destroyed.
Peter Boström0c4e06b2015-10-07 12:23:21 +020087 bool GetNextClock(uint32_t now, long& timeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000088
89 // Call these to get/set option values to tailor this PseudoTcp
90 // instance's behaviour for the kind of data it will carry.
91 // If an unrecognized option is set or got, an assertion will fire.
92 //
93 // Setting options for OPT_RCVBUF or OPT_SNDBUF after Connect() is called
94 // will result in an assertion.
95 enum Option {
Yves Gerey665174f2018-06-19 15:03:05 +020096 OPT_NODELAY, // Whether to enable Nagle's algorithm (0 == off)
97 OPT_ACKDELAY, // The Delayed ACK timeout (0 == off).
98 OPT_RCVBUF, // Set the receive buffer size, in bytes.
99 OPT_SNDBUF, // Set the send buffer size, in bytes.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000100 };
101 void GetOption(Option opt, int* value);
102 void SetOption(Option opt, int value);
103
104 // Returns current congestion window in bytes.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200105 uint32_t GetCongestionWindow() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000106
107 // Returns amount of data in bytes that has been sent, but haven't
108 // been acknowledged.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200109 uint32_t GetBytesInFlight() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000110
111 // Returns number of bytes that were written in buffer and haven't
112 // been sent.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200113 uint32_t GetBytesBufferedNotSent() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000114
115 // Returns current round-trip time estimate in milliseconds.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200116 uint32_t GetRoundTripTimeEstimateMs() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000117
118 protected:
119 enum SendFlags { sfNone, sfDelayedAck, sfImmediateAck };
120
121 struct Segment {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200122 uint32_t conv, seq, ack;
123 uint8_t flags;
124 uint16_t wnd;
Yves Gerey665174f2018-06-19 15:03:05 +0200125 const char* data;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200126 uint32_t len;
127 uint32_t tsval, tsecr;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000128 };
129
130 struct SSegment {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200131 SSegment(uint32_t s, uint32_t l, bool c)
132 : seq(s), len(l), /*tstamp(0),*/ xmit(0), bCtrl(c) {}
133 uint32_t seq, len;
134 // uint32_t tstamp;
135 uint8_t xmit;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000136 bool bCtrl;
137 };
138 typedef std::list<SSegment> SList;
139
140 struct RSegment {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200141 uint32_t seq, len;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000142 };
143
Peter Boström0c4e06b2015-10-07 12:23:21 +0200144 uint32_t queue(const char* data, uint32_t len, bool bCtrl);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000145
146 // Creates a packet and submits it to the network. This method can either
147 // send payload or just an ACK packet.
148 //
149 // |seq| is the sequence number of this packet.
150 // |flags| is the flags for sending this packet.
151 // |offset| is the offset to read from |m_sbuf|.
152 // |len| is the number of bytes to read from |m_sbuf| as payload. If this
153 // value is 0 then this is an ACK packet, otherwise this packet has payload.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200154 IPseudoTcpNotify::WriteResult packet(uint32_t seq,
155 uint8_t flags,
156 uint32_t offset,
157 uint32_t len);
158 bool parse(const uint8_t* buffer, uint32_t size);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000159
160 void attemptSend(SendFlags sflags = sfNone);
161
Peter Boström0c4e06b2015-10-07 12:23:21 +0200162 void closedown(uint32_t err = 0);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000163
Peter Boström0c4e06b2015-10-07 12:23:21 +0200164 bool clock_check(uint32_t now, long& nTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000165
166 bool process(Segment& seg);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200167 bool transmit(const SList::iterator& seg, uint32_t now);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000168
169 void adjustMTU();
170
171 protected:
172 // This method is used in test only to query receive buffer state.
173 bool isReceiveBufferFull() const;
174
175 // This method is only used in tests, to disable window scaling
176 // support for testing backward compatibility.
177 void disableWindowScale();
178
179 private:
180 // Queue the connect message with TCP options.
181 void queueConnectMessage();
182
183 // Parse TCP options in the header.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200184 void parseOptions(const char* data, uint32_t len);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000185
186 // Apply a TCP option that has been read from the header.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200187 void applyOption(char kind, const char* data, uint32_t len);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000188
189 // Apply window scale option.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200190 void applyWindowScaleOption(uint8_t scale_factor);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000191
192 // Resize the send buffer with |new_size| in bytes.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200193 void resizeSendBuffer(uint32_t new_size);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000194
195 // Resize the receive buffer with |new_size| in bytes. This call adjusts
196 // window scale factor |m_swnd_scale| accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200197 void resizeReceiveBuffer(uint32_t new_size);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000198
199 IPseudoTcpNotify* m_notify;
200 enum Shutdown { SD_NONE, SD_GRACEFUL, SD_FORCEFUL } m_shutdown;
201 int m_error;
202
203 // TCB data
204 TcpState m_state;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200205 uint32_t m_conv;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000206 bool m_bReadEnable, m_bWriteEnable, m_bOutgoing;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200207 uint32_t m_lasttraffic;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000208
209 // Incoming data
210 typedef std::list<RSegment> RList;
211 RList m_rlist;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200212 uint32_t m_rbuf_len, m_rcv_nxt, m_rcv_wnd, m_lastrecv;
213 uint8_t m_rwnd_scale; // Window scale factor.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000214 rtc::FifoBuffer m_rbuf;
215
216 // Outgoing data
217 SList m_slist;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200218 uint32_t m_sbuf_len, m_snd_nxt, m_snd_wnd, m_lastsend, m_snd_una;
219 uint8_t m_swnd_scale; // Window scale factor.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000220 rtc::FifoBuffer m_sbuf;
221
222 // Maximum segment size, estimated protocol level, largest segment sent
Peter Boström0c4e06b2015-10-07 12:23:21 +0200223 uint32_t m_mss, m_msslevel, m_largest, m_mtu_advise;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000224 // Retransmit timer
Peter Boström0c4e06b2015-10-07 12:23:21 +0200225 uint32_t m_rto_base;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000226
227 // Timestamp tracking
Peter Boström0c4e06b2015-10-07 12:23:21 +0200228 uint32_t m_ts_recent, m_ts_lastack;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000229
230 // Round-trip calculation
Peter Boström0c4e06b2015-10-07 12:23:21 +0200231 uint32_t m_rx_rttvar, m_rx_srtt, m_rx_rto;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000232
233 // Congestion avoidance, Fast retransmit/recovery, Delayed ACKs
Peter Boström0c4e06b2015-10-07 12:23:21 +0200234 uint32_t m_ssthresh, m_cwnd;
235 uint8_t m_dup_acks;
236 uint32_t m_recover;
237 uint32_t m_t_ack;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000238
239 // Configuration options
240 bool m_use_nagling;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200241 uint32_t m_ack_delay;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000242
243 // This is used by unit tests to test backward compatibility of
244 // PseudoTcp implementations that don't support window scaling.
245 bool m_support_wnd_scale;
246};
247
248} // namespace cricket
249
Steve Anton10542f22019-01-11 09:11:00 -0800250#endif // P2P_BASE_PSEUDO_TCP_H_