1 /* 2 * Copyright 2006-2010, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Andrew Galante, haiku.galante@gmail.com 7 * Axel Dörfler, axeld@pinc-software.de 8 * Hugo Santos, hugosantos@gmail.com 9 */ 10 #ifndef TCP_ENDPOINT_H 11 #define TCP_ENDPOINT_H 12 13 14 #include "BufferQueue.h" 15 #include "EndpointManager.h" 16 #include "tcp.h" 17 18 #include <ProtocolUtilities.h> 19 #include <net_protocol.h> 20 #include <net_stack.h> 21 #include <condition_variable.h> 22 #include <util/AutoLock.h> 23 #include <util/DoublyLinkedList.h> 24 #include <util/OpenHashTable.h> 25 26 #include <stddef.h> 27 28 29 class TCPEndpoint : public net_protocol, public ProtocolSocket { 30 public: 31 TCPEndpoint(net_socket* socket); 32 ~TCPEndpoint(); 33 34 status_t InitCheck() const; 35 36 status_t Open(); 37 status_t Close(); 38 void Free(); 39 status_t Connect(const struct sockaddr* address); 40 status_t Accept(struct net_socket** _acceptedSocket); 41 status_t Bind(const sockaddr* address); 42 status_t Unbind(struct sockaddr* address); 43 status_t Listen(int count); 44 status_t Shutdown(int direction); 45 status_t SendData(net_buffer* buffer); 46 ssize_t SendAvailable(); 47 status_t ReadData(size_t numBytes, uint32 flags, 48 net_buffer** _buffer); 49 ssize_t ReadAvailable(); 50 51 status_t FillStat(struct net_stat* stat); 52 53 status_t SetSendBufferSize(size_t length); 54 status_t SetReceiveBufferSize(size_t length); 55 56 status_t GetOption(int option, void* value, int* _length); 57 status_t SetOption(int option, const void* value, int length); 58 59 tcp_state State() const { return fState; } 60 bool IsBound() const; 61 bool IsLocal() const; 62 63 status_t DelayedAcknowledge(); 64 65 int32 SegmentReceived(tcp_segment_header& segment, 66 net_buffer* buffer); 67 68 void Dump() const; 69 70 private: 71 void _StartPersistTimer(); 72 void _EnterTimeWait(); 73 void _UpdateTimeWait(); 74 void _Close(); 75 void _CancelConnectionTimers(); 76 77 tcp_segment_header _PrepareSendSegment(); 78 bool _ShouldSendSegment(tcp_segment_header& segment, 79 uint32 length, uint32 segmentMaxSize, 80 uint32 flightSize); 81 status_t _PrepareAndSend(tcp_segment_header& segment, net_buffer* buffer, 82 bool isRetransmit); 83 status_t _SendAcknowledge(bool force = false); 84 status_t _SendQueued(bool force = false); 85 86 status_t _Disconnect(bool closing); 87 ssize_t _AvailableData() const; 88 void _NotifyReader(); 89 bool _ShouldReceive() const; 90 void _HandleReset(status_t error); 91 int32 _Spawn(TCPEndpoint* parent, tcp_segment_header& segment, 92 net_buffer* buffer); 93 int32 _ListenReceive(tcp_segment_header& segment, 94 net_buffer* buffer); 95 int32 _SynchronizeSentReceive(tcp_segment_header& segment, 96 net_buffer* buffer); 97 int32 _SegmentReceived(tcp_segment_header& segment, 98 net_buffer* buffer); 99 int32 _Receive(tcp_segment_header& segment, 100 net_buffer* buffer); 101 void _UpdateTimestamps(tcp_segment_header& segment, 102 size_t segmentLength); 103 void _MarkEstablished(); 104 status_t _WaitForEstablished(MutexLocker& lock, 105 bigtime_t timeout); 106 bool _AddData(tcp_segment_header& segment, 107 net_buffer* buffer); 108 int _MaxSegmentSize(const struct sockaddr* address) const; 109 void _PrepareReceivePath(tcp_segment_header& segment); 110 status_t _PrepareSendPath(const sockaddr* peer); 111 void _Acknowledged(tcp_segment_header& segment); 112 void _Retransmit(); 113 void _UpdateRoundTripTime(int32 roundTripTime, int32 expectedSamples); 114 void _ResetSlowStart(); 115 void _DuplicateAcknowledge(tcp_segment_header& segment); 116 117 static void _TimeWaitTimer(net_timer* timer, void* _endpoint); 118 static void _RetransmitTimer(net_timer* timer, void* _endpoint); 119 static void _PersistTimer(net_timer* timer, void* _endpoint); 120 static void _DelayedAcknowledgeTimer(net_timer* timer, 121 void* _endpoint); 122 123 static status_t _WaitForCondition(ConditionVariable& condition, 124 MutexLocker& locker, bigtime_t timeout); 125 126 private: 127 TCPEndpoint* fConnectionHashLink; 128 TCPEndpoint* fEndpointHashLink; 129 friend class EndpointManager; 130 friend struct ConnectionHashDefinition; 131 friend class EndpointHashDefinition; 132 133 mutex fLock; 134 EndpointManager* fManager; 135 ConditionVariable 136 fReceiveCondition; 137 ConditionVariable 138 fSendCondition; 139 sem_id fAcceptSemaphore; 140 uint8 fOptions; 141 142 uint8 fSendWindowShift; 143 uint8 fReceiveWindowShift; 144 145 tcp_sequence fSendUnacknowledged; 146 tcp_sequence fSendNext; 147 tcp_sequence fSendMax; 148 tcp_sequence fSendUrgentOffset; 149 uint32 fSendWindow; 150 uint32 fSendMaxWindow; 151 uint32 fSendMaxSegmentSize; 152 uint32 fSendMaxSegments; 153 BufferQueue fSendQueue; 154 tcp_sequence fLastAcknowledgeSent; 155 tcp_sequence fInitialSendSequence; 156 tcp_sequence fPreviousHighestAcknowledge; 157 uint32 fDuplicateAcknowledgeCount; 158 uint32 fPreviousFlightSize; 159 uint32 fRecover; 160 161 net_route *fRoute; 162 // TODO: don't use a net_route, but a net_route_info!!! 163 // (the latter will automatically adapt to routing changes) 164 165 tcp_sequence fReceiveNext; 166 tcp_sequence fReceiveMaxAdvertised; 167 uint32 fReceiveWindow; 168 uint32 fReceiveMaxSegmentSize; 169 BufferQueue fReceiveQueue; 170 bool fFinishReceived; 171 tcp_sequence fFinishReceivedAt; 172 tcp_sequence fInitialReceiveSequence; 173 174 // round trip time and retransmit timeout computation 175 int32 fSmoothedRoundTripTime; 176 int32 fRoundTripVariation; 177 uint32 fSendTime; 178 tcp_sequence fRoundTripStartSequence; 179 bigtime_t fRetransmitTimeout; 180 181 uint32 fReceivedTimestamp; 182 183 uint32 fCongestionWindow; 184 uint32 fSlowStartThreshold; 185 186 tcp_state fState; 187 uint32 fFlags; 188 189 // timer 190 net_timer fRetransmitTimer; 191 net_timer fPersistTimer; 192 net_timer fDelayedAcknowledgeTimer; 193 net_timer fTimeWaitTimer; 194 }; 195 196 #endif // TCP_ENDPOINT_H 197