pseudo_tcp.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*
  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. #ifndef P2P_BASE_PSEUDO_TCP_H_
  11. #define P2P_BASE_PSEUDO_TCP_H_
  12. #include <stddef.h>
  13. #include <stdint.h>
  14. #include <list>
  15. #include "rtc_base/memory/fifo_buffer.h"
  16. #include "rtc_base/system/rtc_export.h"
  17. namespace cricket {
  18. //////////////////////////////////////////////////////////////////////
  19. // IPseudoTcpNotify
  20. //////////////////////////////////////////////////////////////////////
  21. class PseudoTcp;
  22. class IPseudoTcpNotify {
  23. public:
  24. // Notification of tcp events
  25. virtual void OnTcpOpen(PseudoTcp* tcp) = 0;
  26. virtual void OnTcpReadable(PseudoTcp* tcp) = 0;
  27. virtual void OnTcpWriteable(PseudoTcp* tcp) = 0;
  28. virtual void OnTcpClosed(PseudoTcp* tcp, uint32_t error) = 0;
  29. // Write the packet onto the network
  30. enum WriteResult { WR_SUCCESS, WR_TOO_LARGE, WR_FAIL };
  31. virtual WriteResult TcpWritePacket(PseudoTcp* tcp,
  32. const char* buffer,
  33. size_t len) = 0;
  34. protected:
  35. virtual ~IPseudoTcpNotify() {}
  36. };
  37. //////////////////////////////////////////////////////////////////////
  38. // PseudoTcp
  39. //////////////////////////////////////////////////////////////////////
  40. class RTC_EXPORT PseudoTcp {
  41. public:
  42. static uint32_t Now();
  43. PseudoTcp(IPseudoTcpNotify* notify, uint32_t conv);
  44. virtual ~PseudoTcp();
  45. int Connect();
  46. int Recv(char* buffer, size_t len);
  47. int Send(const char* buffer, size_t len);
  48. void Close(bool force);
  49. int GetError();
  50. enum TcpState {
  51. TCP_LISTEN,
  52. TCP_SYN_SENT,
  53. TCP_SYN_RECEIVED,
  54. TCP_ESTABLISHED,
  55. TCP_CLOSED
  56. };
  57. TcpState State() const { return m_state; }
  58. // Call this when the PMTU changes.
  59. void NotifyMTU(uint16_t mtu);
  60. // Call this based on timeout value returned from GetNextClock.
  61. // It's ok to call this too frequently.
  62. void NotifyClock(uint32_t now);
  63. // Call this whenever a packet arrives.
  64. // Returns true if the packet was processed successfully.
  65. bool NotifyPacket(const char* buffer, size_t len);
  66. // Call this to determine the next time NotifyClock should be called.
  67. // Returns false if the socket is ready to be destroyed.
  68. bool GetNextClock(uint32_t now, long& timeout);
  69. // Call these to get/set option values to tailor this PseudoTcp
  70. // instance's behaviour for the kind of data it will carry.
  71. // If an unrecognized option is set or got, an assertion will fire.
  72. //
  73. // Setting options for OPT_RCVBUF or OPT_SNDBUF after Connect() is called
  74. // will result in an assertion.
  75. enum Option {
  76. OPT_NODELAY, // Whether to enable Nagle's algorithm (0 == off)
  77. OPT_ACKDELAY, // The Delayed ACK timeout (0 == off).
  78. OPT_RCVBUF, // Set the receive buffer size, in bytes.
  79. OPT_SNDBUF, // Set the send buffer size, in bytes.
  80. };
  81. void GetOption(Option opt, int* value);
  82. void SetOption(Option opt, int value);
  83. // Returns current congestion window in bytes.
  84. uint32_t GetCongestionWindow() const;
  85. // Returns amount of data in bytes that has been sent, but haven't
  86. // been acknowledged.
  87. uint32_t GetBytesInFlight() const;
  88. // Returns number of bytes that were written in buffer and haven't
  89. // been sent.
  90. uint32_t GetBytesBufferedNotSent() const;
  91. // Returns current round-trip time estimate in milliseconds.
  92. uint32_t GetRoundTripTimeEstimateMs() const;
  93. protected:
  94. enum SendFlags { sfNone, sfDelayedAck, sfImmediateAck };
  95. struct Segment {
  96. uint32_t conv, seq, ack;
  97. uint8_t flags;
  98. uint16_t wnd;
  99. const char* data;
  100. uint32_t len;
  101. uint32_t tsval, tsecr;
  102. };
  103. struct SSegment {
  104. SSegment(uint32_t s, uint32_t l, bool c)
  105. : seq(s), len(l), /*tstamp(0),*/ xmit(0), bCtrl(c) {}
  106. uint32_t seq, len;
  107. // uint32_t tstamp;
  108. uint8_t xmit;
  109. bool bCtrl;
  110. };
  111. typedef std::list<SSegment> SList;
  112. struct RSegment {
  113. uint32_t seq, len;
  114. };
  115. uint32_t queue(const char* data, uint32_t len, bool bCtrl);
  116. // Creates a packet and submits it to the network. This method can either
  117. // send payload or just an ACK packet.
  118. //
  119. // |seq| is the sequence number of this packet.
  120. // |flags| is the flags for sending this packet.
  121. // |offset| is the offset to read from |m_sbuf|.
  122. // |len| is the number of bytes to read from |m_sbuf| as payload. If this
  123. // value is 0 then this is an ACK packet, otherwise this packet has payload.
  124. IPseudoTcpNotify::WriteResult packet(uint32_t seq,
  125. uint8_t flags,
  126. uint32_t offset,
  127. uint32_t len);
  128. bool parse(const uint8_t* buffer, uint32_t size);
  129. void attemptSend(SendFlags sflags = sfNone);
  130. void closedown(uint32_t err = 0);
  131. bool clock_check(uint32_t now, long& nTimeout);
  132. bool process(Segment& seg);
  133. bool transmit(const SList::iterator& seg, uint32_t now);
  134. void adjustMTU();
  135. protected:
  136. // This method is used in test only to query receive buffer state.
  137. bool isReceiveBufferFull() const;
  138. // This method is only used in tests, to disable window scaling
  139. // support for testing backward compatibility.
  140. void disableWindowScale();
  141. private:
  142. // Queue the connect message with TCP options.
  143. void queueConnectMessage();
  144. // Parse TCP options in the header.
  145. void parseOptions(const char* data, uint32_t len);
  146. // Apply a TCP option that has been read from the header.
  147. void applyOption(char kind, const char* data, uint32_t len);
  148. // Apply window scale option.
  149. void applyWindowScaleOption(uint8_t scale_factor);
  150. // Resize the send buffer with |new_size| in bytes.
  151. void resizeSendBuffer(uint32_t new_size);
  152. // Resize the receive buffer with |new_size| in bytes. This call adjusts
  153. // window scale factor |m_swnd_scale| accordingly.
  154. void resizeReceiveBuffer(uint32_t new_size);
  155. IPseudoTcpNotify* m_notify;
  156. enum Shutdown { SD_NONE, SD_GRACEFUL, SD_FORCEFUL } m_shutdown;
  157. int m_error;
  158. // TCB data
  159. TcpState m_state;
  160. uint32_t m_conv;
  161. bool m_bReadEnable, m_bWriteEnable, m_bOutgoing;
  162. uint32_t m_lasttraffic;
  163. // Incoming data
  164. typedef std::list<RSegment> RList;
  165. RList m_rlist;
  166. uint32_t m_rbuf_len, m_rcv_nxt, m_rcv_wnd, m_lastrecv;
  167. uint8_t m_rwnd_scale; // Window scale factor.
  168. rtc::FifoBuffer m_rbuf;
  169. // Outgoing data
  170. SList m_slist;
  171. uint32_t m_sbuf_len, m_snd_nxt, m_snd_wnd, m_lastsend, m_snd_una;
  172. uint8_t m_swnd_scale; // Window scale factor.
  173. rtc::FifoBuffer m_sbuf;
  174. // Maximum segment size, estimated protocol level, largest segment sent
  175. uint32_t m_mss, m_msslevel, m_largest, m_mtu_advise;
  176. // Retransmit timer
  177. uint32_t m_rto_base;
  178. // Timestamp tracking
  179. uint32_t m_ts_recent, m_ts_lastack;
  180. // Round-trip calculation
  181. uint32_t m_rx_rttvar, m_rx_srtt, m_rx_rto;
  182. // Congestion avoidance, Fast retransmit/recovery, Delayed ACKs
  183. uint32_t m_ssthresh, m_cwnd;
  184. uint8_t m_dup_acks;
  185. uint32_t m_recover;
  186. uint32_t m_t_ack;
  187. // Configuration options
  188. bool m_use_nagling;
  189. uint32_t m_ack_delay;
  190. // This is used by unit tests to test backward compatibility of
  191. // PseudoTcp implementations that don't support window scaling.
  192. bool m_support_wnd_scale;
  193. };
  194. } // namespace cricket
  195. #endif // P2P_BASE_PSEUDO_TCP_H_