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 State()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 _UpdateReceiveBuffer(); 104 void _MarkEstablished(); 105 status_t _WaitForEstablished(MutexLocker& lock, 106 bigtime_t timeout); 107 bool _AddData(tcp_segment_header& segment, 108 net_buffer* buffer); 109 int _MaxSegmentSize(const struct sockaddr* address) const; 110 void _PrepareReceivePath(tcp_segment_header& segment); 111 status_t _PrepareSendPath(const sockaddr* peer); 112 void _Acknowledged(tcp_segment_header& segment); 113 void _Retransmit(); 114 void _UpdateRoundTripTime(int32 roundTripTime, int32 expectedSamples); 115 void _ResetSlowStart(); 116 void _DuplicateAcknowledge(tcp_segment_header& segment); 117 118 static void _TimeWaitTimer(net_timer* timer, void* _endpoint); 119 static void _RetransmitTimer(net_timer* timer, void* _endpoint); 120 static void _PersistTimer(net_timer* timer, void* _endpoint); 121 static void _DelayedAcknowledgeTimer(net_timer* timer, 122 void* _endpoint); 123 124 static status_t _WaitForCondition(ConditionVariable& condition, 125 MutexLocker& locker, bigtime_t timeout); 126 127 private: 128 TCPEndpoint* fConnectionHashLink; 129 TCPEndpoint* fEndpointHashLink; 130 friend class EndpointManager; 131 friend struct ConnectionHashDefinition; 132 friend class EndpointHashDefinition; 133 134 mutex fLock; 135 EndpointManager* fManager; 136 ConditionVariable 137 fReceiveCondition; 138 ConditionVariable 139 fSendCondition; 140 sem_id fAcceptSemaphore; 141 uint8 fOptions; 142 143 uint8 fSendWindowShift; 144 uint8 fReceiveWindowShift; 145 146 tcp_sequence fSendUnacknowledged; 147 tcp_sequence fSendNext; 148 tcp_sequence fSendMax; 149 tcp_sequence fSendUrgentOffset; 150 uint32 fSendWindow; 151 uint32 fSendMaxWindow; 152 uint32 fSendMaxSegmentSize; 153 uint32 fSendMaxSegments; 154 BufferQueue fSendQueue; 155 tcp_sequence fLastAcknowledgeSent; 156 tcp_sequence fInitialSendSequence; 157 tcp_sequence fPreviousHighestAcknowledge; 158 uint32 fDuplicateAcknowledgeCount; 159 uint32 fPreviousFlightSize; 160 uint32 fRecover; 161 162 net_route *fRoute; 163 // TODO: don't use a net_route, but a net_route_info!!! 164 // (the latter will automatically adapt to routing changes) 165 166 tcp_sequence fReceiveNext; 167 tcp_sequence fReceiveMaxAdvertised; 168 uint32 fReceiveWindow; 169 uint32 fReceiveMaxSegmentSize; 170 BufferQueue fReceiveQueue; 171 bool fFinishReceived; 172 tcp_sequence fFinishReceivedAt; 173 tcp_sequence fInitialReceiveSequence; 174 175 // round trip time and retransmit timeout computation 176 int32 fSmoothedRoundTripTime; 177 int32 fRoundTripVariation; 178 uint32 fSendTime; 179 tcp_sequence fRoundTripStartSequence; 180 bigtime_t fRetransmitTimeout; 181 182 uint32 fReceivedTimestamp; 183 184 tcp_sequence fReceiveSizingReference; 185 uint32 fReceiveSizingTimestamp; 186 187 uint32 fCongestionWindow; 188 uint32 fSlowStartThreshold; 189 190 tcp_state fState; 191 uint32 fFlags; 192 193 // timer 194 net_timer fRetransmitTimer; 195 net_timer fPersistTimer; 196 net_timer fDelayedAcknowledgeTimer; 197 net_timer fTimeWaitTimer; 198 }; 199 200 #endif // TCP_ENDPOINT_H 201