blob: c363ef64b74af9b1223ff7ca533179ae82c1acb4 [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"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000017
18namespace cricket {
19
20//////////////////////////////////////////////////////////////////////
21// IPseudoTcpNotify
22//////////////////////////////////////////////////////////////////////
23
24class PseudoTcp;
25
26class IPseudoTcpNotify {
27 public:
28 // Notification of tcp events
29 virtual void OnTcpOpen(PseudoTcp* tcp) = 0;
30 virtual void OnTcpReadable(PseudoTcp* tcp) = 0;
31 virtual void OnTcpWriteable(PseudoTcp* tcp) = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +020032 virtual void OnTcpClosed(PseudoTcp* tcp, uint32_t error) = 0;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000033
34 // Write the packet onto the network
35 enum WriteResult { WR_SUCCESS, WR_TOO_LARGE, WR_FAIL };
36 virtual WriteResult TcpWritePacket(PseudoTcp* tcp,
Yves Gerey665174f2018-06-19 15:03:05 +020037 const char* buffer,
38 size_t len) = 0;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000039
40 protected:
41 virtual ~IPseudoTcpNotify() {}
42};
43
44//////////////////////////////////////////////////////////////////////
45// PseudoTcp
46//////////////////////////////////////////////////////////////////////
47
48class PseudoTcp {
49 public:
Peter Boström0c4e06b2015-10-07 12:23:21 +020050 static uint32_t Now();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000051
Peter Boström0c4e06b2015-10-07 12:23:21 +020052 PseudoTcp(IPseudoTcpNotify* notify, uint32_t conv);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000053 virtual ~PseudoTcp();
54
55 int Connect();
56 int Recv(char* buffer, size_t len);
57 int Send(const char* buffer, size_t len);
58 void Close(bool force);
59 int GetError();
60
61 enum TcpState {
Yves Gerey665174f2018-06-19 15:03:05 +020062 TCP_LISTEN,
63 TCP_SYN_SENT,
64 TCP_SYN_RECEIVED,
65 TCP_ESTABLISHED,
66 TCP_CLOSED
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000067 };
68 TcpState State() const { return m_state; }
69
70 // Call this when the PMTU changes.
Peter Boström0c4e06b2015-10-07 12:23:21 +020071 void NotifyMTU(uint16_t mtu);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000072
73 // Call this based on timeout value returned from GetNextClock.
74 // It's ok to call this too frequently.
Peter Boström0c4e06b2015-10-07 12:23:21 +020075 void NotifyClock(uint32_t now);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000076
77 // Call this whenever a packet arrives.
78 // Returns true if the packet was processed successfully.
Yves Gerey665174f2018-06-19 15:03:05 +020079 bool NotifyPacket(const char* buffer, size_t len);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000080
81 // Call this to determine the next time NotifyClock should be called.
82 // Returns false if the socket is ready to be destroyed.
Peter Boström0c4e06b2015-10-07 12:23:21 +020083 bool GetNextClock(uint32_t now, long& timeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000084
85 // Call these to get/set option values to tailor this PseudoTcp
86 // instance's behaviour for the kind of data it will carry.
87 // If an unrecognized option is set or got, an assertion will fire.
88 //
89 // Setting options for OPT_RCVBUF or OPT_SNDBUF after Connect() is called
90 // will result in an assertion.
91 enum Option {
Yves Gerey665174f2018-06-19 15:03:05 +020092 OPT_NODELAY, // Whether to enable Nagle's algorithm (0 == off)
93 OPT_ACKDELAY, // The Delayed ACK timeout (0 == off).
94 OPT_RCVBUF, // Set the receive buffer size, in bytes.
95 OPT_SNDBUF, // Set the send buffer size, in bytes.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000096 };
97 void GetOption(Option opt, int* value);
98 void SetOption(Option opt, int value);
99
100 // Returns current congestion window in bytes.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200101 uint32_t GetCongestionWindow() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000102
103 // Returns amount of data in bytes that has been sent, but haven't
104 // been acknowledged.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200105 uint32_t GetBytesInFlight() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000106
107 // Returns number of bytes that were written in buffer and haven't
108 // been sent.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200109 uint32_t GetBytesBufferedNotSent() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000110
111 // Returns current round-trip time estimate in milliseconds.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200112 uint32_t GetRoundTripTimeEstimateMs() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000113
114 protected:
115 enum SendFlags { sfNone, sfDelayedAck, sfImmediateAck };
116
117 struct Segment {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200118 uint32_t conv, seq, ack;
119 uint8_t flags;
120 uint16_t wnd;
Yves Gerey665174f2018-06-19 15:03:05 +0200121 const char* data;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200122 uint32_t len;
123 uint32_t tsval, tsecr;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000124 };
125
126 struct SSegment {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200127 SSegment(uint32_t s, uint32_t l, bool c)
128 : seq(s), len(l), /*tstamp(0),*/ xmit(0), bCtrl(c) {}
129 uint32_t seq, len;
130 // uint32_t tstamp;
131 uint8_t xmit;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000132 bool bCtrl;
133 };
134 typedef std::list<SSegment> SList;
135
136 struct RSegment {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200137 uint32_t seq, len;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000138 };
139
Peter Boström0c4e06b2015-10-07 12:23:21 +0200140 uint32_t queue(const char* data, uint32_t len, bool bCtrl);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000141
142 // Creates a packet and submits it to the network. This method can either
143 // send payload or just an ACK packet.
144 //
145 // |seq| is the sequence number of this packet.
146 // |flags| is the flags for sending this packet.
147 // |offset| is the offset to read from |m_sbuf|.
148 // |len| is the number of bytes to read from |m_sbuf| as payload. If this
149 // value is 0 then this is an ACK packet, otherwise this packet has payload.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200150 IPseudoTcpNotify::WriteResult packet(uint32_t seq,
151 uint8_t flags,
152 uint32_t offset,
153 uint32_t len);
154 bool parse(const uint8_t* buffer, uint32_t size);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000155
156 void attemptSend(SendFlags sflags = sfNone);
157
Peter Boström0c4e06b2015-10-07 12:23:21 +0200158 void closedown(uint32_t err = 0);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000159
Peter Boström0c4e06b2015-10-07 12:23:21 +0200160 bool clock_check(uint32_t now, long& nTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000161
162 bool process(Segment& seg);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200163 bool transmit(const SList::iterator& seg, uint32_t now);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000164
165 void adjustMTU();
166
167 protected:
168 // This method is used in test only to query receive buffer state.
169 bool isReceiveBufferFull() const;
170
171 // This method is only used in tests, to disable window scaling
172 // support for testing backward compatibility.
173 void disableWindowScale();
174
175 private:
176 // Queue the connect message with TCP options.
177 void queueConnectMessage();
178
179 // Parse TCP options in the header.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200180 void parseOptions(const char* data, uint32_t len);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000181
182 // Apply a TCP option that has been read from the header.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200183 void applyOption(char kind, const char* data, uint32_t len);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000184
185 // Apply window scale option.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200186 void applyWindowScaleOption(uint8_t scale_factor);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000187
188 // Resize the send buffer with |new_size| in bytes.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200189 void resizeSendBuffer(uint32_t new_size);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000190
191 // Resize the receive buffer with |new_size| in bytes. This call adjusts
192 // window scale factor |m_swnd_scale| accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200193 void resizeReceiveBuffer(uint32_t new_size);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000194
195 IPseudoTcpNotify* m_notify;
196 enum Shutdown { SD_NONE, SD_GRACEFUL, SD_FORCEFUL } m_shutdown;
197 int m_error;
198
199 // TCB data
200 TcpState m_state;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200201 uint32_t m_conv;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000202 bool m_bReadEnable, m_bWriteEnable, m_bOutgoing;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200203 uint32_t m_lasttraffic;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000204
205 // Incoming data
206 typedef std::list<RSegment> RList;
207 RList m_rlist;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200208 uint32_t m_rbuf_len, m_rcv_nxt, m_rcv_wnd, m_lastrecv;
209 uint8_t m_rwnd_scale; // Window scale factor.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000210 rtc::FifoBuffer m_rbuf;
211
212 // Outgoing data
213 SList m_slist;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200214 uint32_t m_sbuf_len, m_snd_nxt, m_snd_wnd, m_lastsend, m_snd_una;
215 uint8_t m_swnd_scale; // Window scale factor.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000216 rtc::FifoBuffer m_sbuf;
217
218 // Maximum segment size, estimated protocol level, largest segment sent
Peter Boström0c4e06b2015-10-07 12:23:21 +0200219 uint32_t m_mss, m_msslevel, m_largest, m_mtu_advise;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000220 // Retransmit timer
Peter Boström0c4e06b2015-10-07 12:23:21 +0200221 uint32_t m_rto_base;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000222
223 // Timestamp tracking
Peter Boström0c4e06b2015-10-07 12:23:21 +0200224 uint32_t m_ts_recent, m_ts_lastack;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000225
226 // Round-trip calculation
Peter Boström0c4e06b2015-10-07 12:23:21 +0200227 uint32_t m_rx_rttvar, m_rx_srtt, m_rx_rto;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000228
229 // Congestion avoidance, Fast retransmit/recovery, Delayed ACKs
Peter Boström0c4e06b2015-10-07 12:23:21 +0200230 uint32_t m_ssthresh, m_cwnd;
231 uint8_t m_dup_acks;
232 uint32_t m_recover;
233 uint32_t m_t_ack;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000234
235 // Configuration options
236 bool m_use_nagling;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200237 uint32_t m_ack_delay;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000238
239 // This is used by unit tests to test backward compatibility of
240 // PseudoTcp implementations that don't support window scaling.
241 bool m_support_wnd_scale;
242};
243
244} // namespace cricket
245
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200246#endif // P2P_BASE_PSEUDOTCP_H_