blob: 2522bdc96f667f5076bd597b829e4720abdaedb5 [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
Yves Gerey3e707812018-11-28 16:47:49 +010014#include <stddef.h>
15#include <stdint.h>
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000016#include <list>
17
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "rtc_base/stream.h"
Mirko Bonadeiac194142018-10-22 17:08:37 +020019#include "rtc_base/system/rtc_export.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000020
21namespace cricket {
22
23//////////////////////////////////////////////////////////////////////
24// IPseudoTcpNotify
25//////////////////////////////////////////////////////////////////////
26
27class PseudoTcp;
28
29class IPseudoTcpNotify {
30 public:
31 // Notification of tcp events
32 virtual void OnTcpOpen(PseudoTcp* tcp) = 0;
33 virtual void OnTcpReadable(PseudoTcp* tcp) = 0;
34 virtual void OnTcpWriteable(PseudoTcp* tcp) = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +020035 virtual void OnTcpClosed(PseudoTcp* tcp, uint32_t error) = 0;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000036
37 // Write the packet onto the network
38 enum WriteResult { WR_SUCCESS, WR_TOO_LARGE, WR_FAIL };
39 virtual WriteResult TcpWritePacket(PseudoTcp* tcp,
Yves Gerey665174f2018-06-19 15:03:05 +020040 const char* buffer,
41 size_t len) = 0;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000042
43 protected:
44 virtual ~IPseudoTcpNotify() {}
45};
46
47//////////////////////////////////////////////////////////////////////
48// PseudoTcp
49//////////////////////////////////////////////////////////////////////
50
Mirko Bonadeiac194142018-10-22 17:08:37 +020051class RTC_EXPORT PseudoTcp {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000052 public:
Peter Boström0c4e06b2015-10-07 12:23:21 +020053 static uint32_t Now();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000054
Peter Boström0c4e06b2015-10-07 12:23:21 +020055 PseudoTcp(IPseudoTcpNotify* notify, uint32_t conv);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000056 virtual ~PseudoTcp();
57
58 int Connect();
59 int Recv(char* buffer, size_t len);
60 int Send(const char* buffer, size_t len);
61 void Close(bool force);
62 int GetError();
63
64 enum TcpState {
Yves Gerey665174f2018-06-19 15:03:05 +020065 TCP_LISTEN,
66 TCP_SYN_SENT,
67 TCP_SYN_RECEIVED,
68 TCP_ESTABLISHED,
69 TCP_CLOSED
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000070 };
71 TcpState State() const { return m_state; }
72
73 // Call this when the PMTU changes.
Peter Boström0c4e06b2015-10-07 12:23:21 +020074 void NotifyMTU(uint16_t mtu);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000075
76 // Call this based on timeout value returned from GetNextClock.
77 // It's ok to call this too frequently.
Peter Boström0c4e06b2015-10-07 12:23:21 +020078 void NotifyClock(uint32_t now);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000079
80 // Call this whenever a packet arrives.
81 // Returns true if the packet was processed successfully.
Yves Gerey665174f2018-06-19 15:03:05 +020082 bool NotifyPacket(const char* buffer, size_t len);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000083
84 // Call this to determine the next time NotifyClock should be called.
85 // Returns false if the socket is ready to be destroyed.
Peter Boström0c4e06b2015-10-07 12:23:21 +020086 bool GetNextClock(uint32_t now, long& timeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000087
88 // Call these to get/set option values to tailor this PseudoTcp
89 // instance's behaviour for the kind of data it will carry.
90 // If an unrecognized option is set or got, an assertion will fire.
91 //
92 // Setting options for OPT_RCVBUF or OPT_SNDBUF after Connect() is called
93 // will result in an assertion.
94 enum Option {
Yves Gerey665174f2018-06-19 15:03:05 +020095 OPT_NODELAY, // Whether to enable Nagle's algorithm (0 == off)
96 OPT_ACKDELAY, // The Delayed ACK timeout (0 == off).
97 OPT_RCVBUF, // Set the receive buffer size, in bytes.
98 OPT_SNDBUF, // Set the send buffer size, in bytes.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000099 };
100 void GetOption(Option opt, int* value);
101 void SetOption(Option opt, int value);
102
103 // Returns current congestion window in bytes.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200104 uint32_t GetCongestionWindow() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000105
106 // Returns amount of data in bytes that has been sent, but haven't
107 // been acknowledged.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200108 uint32_t GetBytesInFlight() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000109
110 // Returns number of bytes that were written in buffer and haven't
111 // been sent.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200112 uint32_t GetBytesBufferedNotSent() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000113
114 // Returns current round-trip time estimate in milliseconds.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200115 uint32_t GetRoundTripTimeEstimateMs() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000116
117 protected:
118 enum SendFlags { sfNone, sfDelayedAck, sfImmediateAck };
119
120 struct Segment {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200121 uint32_t conv, seq, ack;
122 uint8_t flags;
123 uint16_t wnd;
Yves Gerey665174f2018-06-19 15:03:05 +0200124 const char* data;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200125 uint32_t len;
126 uint32_t tsval, tsecr;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000127 };
128
129 struct SSegment {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200130 SSegment(uint32_t s, uint32_t l, bool c)
131 : seq(s), len(l), /*tstamp(0),*/ xmit(0), bCtrl(c) {}
132 uint32_t seq, len;
133 // uint32_t tstamp;
134 uint8_t xmit;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000135 bool bCtrl;
136 };
137 typedef std::list<SSegment> SList;
138
139 struct RSegment {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200140 uint32_t seq, len;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000141 };
142
Peter Boström0c4e06b2015-10-07 12:23:21 +0200143 uint32_t queue(const char* data, uint32_t len, bool bCtrl);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000144
145 // Creates a packet and submits it to the network. This method can either
146 // send payload or just an ACK packet.
147 //
148 // |seq| is the sequence number of this packet.
149 // |flags| is the flags for sending this packet.
150 // |offset| is the offset to read from |m_sbuf|.
151 // |len| is the number of bytes to read from |m_sbuf| as payload. If this
152 // value is 0 then this is an ACK packet, otherwise this packet has payload.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200153 IPseudoTcpNotify::WriteResult packet(uint32_t seq,
154 uint8_t flags,
155 uint32_t offset,
156 uint32_t len);
157 bool parse(const uint8_t* buffer, uint32_t size);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000158
159 void attemptSend(SendFlags sflags = sfNone);
160
Peter Boström0c4e06b2015-10-07 12:23:21 +0200161 void closedown(uint32_t err = 0);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000162
Peter Boström0c4e06b2015-10-07 12:23:21 +0200163 bool clock_check(uint32_t now, long& nTimeout);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000164
165 bool process(Segment& seg);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200166 bool transmit(const SList::iterator& seg, uint32_t now);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000167
168 void adjustMTU();
169
170 protected:
171 // This method is used in test only to query receive buffer state.
172 bool isReceiveBufferFull() const;
173
174 // This method is only used in tests, to disable window scaling
175 // support for testing backward compatibility.
176 void disableWindowScale();
177
178 private:
179 // Queue the connect message with TCP options.
180 void queueConnectMessage();
181
182 // Parse TCP options in the header.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200183 void parseOptions(const char* data, uint32_t len);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000184
185 // Apply a TCP option that has been read from the header.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200186 void applyOption(char kind, const char* data, uint32_t len);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000187
188 // Apply window scale option.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200189 void applyWindowScaleOption(uint8_t scale_factor);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000190
191 // Resize the send buffer with |new_size| in bytes.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200192 void resizeSendBuffer(uint32_t new_size);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000193
194 // Resize the receive buffer with |new_size| in bytes. This call adjusts
195 // window scale factor |m_swnd_scale| accordingly.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200196 void resizeReceiveBuffer(uint32_t new_size);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000197
198 IPseudoTcpNotify* m_notify;
199 enum Shutdown { SD_NONE, SD_GRACEFUL, SD_FORCEFUL } m_shutdown;
200 int m_error;
201
202 // TCB data
203 TcpState m_state;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200204 uint32_t m_conv;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000205 bool m_bReadEnable, m_bWriteEnable, m_bOutgoing;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200206 uint32_t m_lasttraffic;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000207
208 // Incoming data
209 typedef std::list<RSegment> RList;
210 RList m_rlist;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200211 uint32_t m_rbuf_len, m_rcv_nxt, m_rcv_wnd, m_lastrecv;
212 uint8_t m_rwnd_scale; // Window scale factor.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000213 rtc::FifoBuffer m_rbuf;
214
215 // Outgoing data
216 SList m_slist;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200217 uint32_t m_sbuf_len, m_snd_nxt, m_snd_wnd, m_lastsend, m_snd_una;
218 uint8_t m_swnd_scale; // Window scale factor.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000219 rtc::FifoBuffer m_sbuf;
220
221 // Maximum segment size, estimated protocol level, largest segment sent
Peter Boström0c4e06b2015-10-07 12:23:21 +0200222 uint32_t m_mss, m_msslevel, m_largest, m_mtu_advise;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000223 // Retransmit timer
Peter Boström0c4e06b2015-10-07 12:23:21 +0200224 uint32_t m_rto_base;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000225
226 // Timestamp tracking
Peter Boström0c4e06b2015-10-07 12:23:21 +0200227 uint32_t m_ts_recent, m_ts_lastack;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000228
229 // Round-trip calculation
Peter Boström0c4e06b2015-10-07 12:23:21 +0200230 uint32_t m_rx_rttvar, m_rx_srtt, m_rx_rto;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000231
232 // Congestion avoidance, Fast retransmit/recovery, Delayed ACKs
Peter Boström0c4e06b2015-10-07 12:23:21 +0200233 uint32_t m_ssthresh, m_cwnd;
234 uint8_t m_dup_acks;
235 uint32_t m_recover;
236 uint32_t m_t_ack;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000237
238 // Configuration options
239 bool m_use_nagling;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200240 uint32_t m_ack_delay;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000241
242 // This is used by unit tests to test backward compatibility of
243 // PseudoTcp implementations that don't support window scaling.
244 bool m_support_wnd_scale;
245};
246
247} // namespace cricket
248
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200249#endif // P2P_BASE_PSEUDOTCP_H_