1 /* 2 * libjingle 3 * Copyright 2004--2005, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef TALK_P2P_BASE_PSEUDOTCP_H_ 29 #define TALK_P2P_BASE_PSEUDOTCP_H_ 30 31 #include <list> 32 33 #include "talk/base/basictypes.h" 34 35 namespace cricket { 36 37 ////////////////////////////////////////////////////////////////////// 38 // IPseudoTcpNotify 39 ////////////////////////////////////////////////////////////////////// 40 41 class PseudoTcp; 42 43 class IPseudoTcpNotify { 44 public: 45 virtual ~IPseudoTcpNotify() {} 46 // Notification of tcp events 47 virtual void OnTcpOpen(PseudoTcp* tcp) = 0; 48 virtual void OnTcpReadable(PseudoTcp* tcp) = 0; 49 virtual void OnTcpWriteable(PseudoTcp* tcp) = 0; 50 virtual void OnTcpClosed(PseudoTcp* tcp, uint32 error) = 0; 51 52 // Write the packet onto the network 53 enum WriteResult { WR_SUCCESS, WR_TOO_LARGE, WR_FAIL }; 54 virtual WriteResult TcpWritePacket(PseudoTcp* tcp, 55 const char* buffer, size_t len) = 0; 56 }; 57 58 ////////////////////////////////////////////////////////////////////// 59 // PseudoTcp 60 ////////////////////////////////////////////////////////////////////// 61 62 class PseudoTcp { 63 public: 64 static uint32 Now(); 65 66 PseudoTcp(IPseudoTcpNotify* notify, uint32 conv); 67 virtual ~PseudoTcp(); 68 69 int Connect(); 70 int Recv(char* buffer, size_t len); 71 int Send(const char* buffer, size_t len); 72 void Close(bool force); 73 int GetError(); 74 75 enum TcpState { 76 TCP_LISTEN, TCP_SYN_SENT, TCP_SYN_RECEIVED, TCP_ESTABLISHED, TCP_CLOSED 77 }; 78 TcpState State() const { return m_state; } 79 80 // Call this when the PMTU changes. 81 void NotifyMTU(uint16 mtu); 82 83 // Call this based on timeout value returned from GetNextClock. 84 // It's ok to call this too frequently. 85 void NotifyClock(uint32 now); 86 87 // Call this whenever a packet arrives. 88 // Returns true if the packet was processed successfully. 89 bool NotifyPacket(const char * buffer, size_t len); 90 91 // Call this to determine the next time NotifyClock should be called. 92 // Returns false if the socket is ready to be destroyed. 93 bool GetNextClock(uint32 now, long& timeout); 94 95 // Call these to get/set option values to tailor this PseudoTcp 96 // instance's behaviour for the kind of data it will carry. 97 // If an unrecognized option is set or got, an assertion will fire. 98 enum Option { 99 OPT_NODELAY, // Whether to enable Nagle's algorithm (0 == off) 100 OPT_ACKDELAY, // The Delayed ACK timeout (0 == off). 101 //kOptRcvBuf, // Set the receive buffer size, in bytes. 102 //kOptSndBuf, // Set the send buffer size, in bytes. 103 }; 104 void GetOption(Option opt, int* value); 105 void SetOption(Option opt, int value); 106 107 protected: 108 enum SendFlags { sfNone, sfDelayedAck, sfImmediateAck }; 109 enum { 110 // Note: can't go as high as 1024 * 64, because of uint16 precision 111 kRcvBufSize = 1024 * 60, 112 // Note: send buffer should be larger to make sure we can always fill the 113 // receiver window 114 kSndBufSize = 1024 * 90 115 }; 116 117 struct Segment { 118 uint32 conv, seq, ack; 119 uint8 flags; 120 uint16 wnd; 121 const char * data; 122 uint32 len; 123 uint32 tsval, tsecr; 124 }; 125 126 struct SSegment { 127 SSegment(uint32 s, uint32 l, bool c) 128 : seq(s), len(l), /*tstamp(0),*/ xmit(0), bCtrl(c) { 129 } 130 uint32 seq, len; 131 //uint32 tstamp; 132 uint8 xmit; 133 bool bCtrl; 134 }; 135 typedef std::list<SSegment> SList; 136 137 struct RSegment { 138 uint32 seq, len; 139 }; 140 141 uint32 queue(const char* data, uint32 len, bool bCtrl); 142 143 IPseudoTcpNotify::WriteResult packet(uint32 seq, uint8 flags, 144 const char* data, uint32 len); 145 bool parse(const uint8* buffer, uint32 size); 146 147 void attemptSend(SendFlags sflags = sfNone); 148 149 void closedown(uint32 err = 0); 150 151 bool clock_check(uint32 now, long& nTimeout); 152 153 bool process(Segment& seg); 154 bool transmit(const SList::iterator& seg, uint32 now); 155 156 void adjustMTU(); 157 158 private: 159 IPseudoTcpNotify* m_notify; 160 enum Shutdown { SD_NONE, SD_GRACEFUL, SD_FORCEFUL } m_shutdown; 161 int m_error; 162 163 // TCB data 164 TcpState m_state; 165 uint32 m_conv; 166 bool m_bReadEnable, m_bWriteEnable, m_bOutgoing; 167 uint32 m_lasttraffic; 168 169 // Incoming data 170 typedef std::list<RSegment> RList; 171 RList m_rlist; 172 char m_rbuf[kRcvBufSize]; 173 uint32 m_rcv_nxt, m_rcv_wnd, m_rlen, m_lastrecv; 174 175 // Outgoing data 176 SList m_slist; 177 char m_sbuf[kSndBufSize]; 178 uint32 m_snd_nxt, m_snd_wnd, m_slen, m_lastsend, m_snd_una; 179 // Maximum segment size, estimated protocol level, largest segment sent 180 uint32 m_mss, m_msslevel, m_largest, m_mtu_advise; 181 // Retransmit timer 182 uint32 m_rto_base; 183 184 // Timestamp tracking 185 uint32 m_ts_recent, m_ts_lastack; 186 187 // Round-trip calculation 188 uint32 m_rx_rttvar, m_rx_srtt, m_rx_rto; 189 190 // Congestion avoidance, Fast retransmit/recovery, Delayed ACKs 191 uint32 m_ssthresh, m_cwnd; 192 uint8 m_dup_acks; 193 uint32 m_recover; 194 uint32 m_t_ack; 195 196 // Configuration options 197 bool m_use_nagling; 198 uint32 m_ack_delay; 199 }; 200 201 } // namespace cricket 202 203 #endif // TALK_P2P_BASE_PSEUDOTCP_H_ 204