1 /* 2 * Copyright 2006-2008, 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 <util/AutoLock.h> 22 #include <util/DoublyLinkedList.h> 23 #include <util/OpenHashTable.h> 24 25 #include <stddef.h> 26 27 28 class WaitList { 29 public: 30 WaitList(const char* name); 31 ~WaitList(); 32 33 status_t InitCheck() const; 34 35 status_t Wait(MutexLocker& locker, bigtime_t timeout = B_INFINITE_TIMEOUT); 36 void Signal(); 37 38 private: 39 int32 fCondition; 40 sem_id fSem; 41 }; 42 43 44 class TCPEndpoint : public net_protocol, public ProtocolSocket { 45 public: 46 TCPEndpoint(net_socket* socket); 47 ~TCPEndpoint(); 48 49 status_t InitCheck() const; 50 51 status_t Open(); 52 status_t Close(); 53 status_t Free(); 54 status_t Connect(const struct sockaddr* address); 55 status_t Accept(struct net_socket** _acceptedSocket); 56 status_t Bind(const sockaddr* address); 57 status_t Unbind(struct sockaddr* address); 58 status_t Listen(int count); 59 status_t Shutdown(int direction); 60 status_t SendData(net_buffer* buffer); 61 ssize_t SendAvailable(); 62 status_t ReadData(size_t numBytes, uint32 flags, 63 net_buffer** _buffer); 64 ssize_t ReadAvailable(); 65 66 status_t FillStat(struct net_stat* stat); 67 68 status_t SetSendBufferSize(size_t length); 69 status_t SetReceiveBufferSize(size_t length); 70 71 status_t GetOption(int option, void* value, int* _length); 72 status_t SetOption(int option, const void* value, int length); 73 74 tcp_state State() const { return fState; } 75 bool IsBound() const; 76 bool IsLocal() const; 77 78 status_t DelayedAcknowledge(); 79 status_t SendAcknowledge(bool force); 80 81 int32 SegmentReceived(tcp_segment_header& segment, 82 net_buffer* buffer); 83 84 void Dump() const; 85 86 private: 87 void _StartPersistTimer(); 88 void _EnterTimeWait(); 89 void _UpdateTimeWait(); 90 void _Close(); 91 void _CancelConnectionTimers(); 92 uint8 _CurrentFlags(); 93 bool _ShouldSendSegment(tcp_segment_header& segment, 94 uint32 length, uint32 segmentMaxSize, 95 uint32 flightSize); 96 status_t _SendQueued(bool force = false); 97 status_t _SendQueued(bool force, uint32 sendWindow); 98 int _MaxSegmentSize(const struct sockaddr* address) const; 99 status_t _Disconnect(bool closing); 100 ssize_t _AvailableData() const; 101 void _NotifyReader(); 102 bool _ShouldReceive() const; 103 void _HandleReset(status_t error); 104 int32 _Spawn(TCPEndpoint* parent, tcp_segment_header& segment, 105 net_buffer* buffer); 106 int32 _ListenReceive(tcp_segment_header& segment, 107 net_buffer* buffer); 108 int32 _SynchronizeSentReceive(tcp_segment_header& segment, 109 net_buffer* buffer); 110 int32 _SegmentReceived(tcp_segment_header& segment, 111 net_buffer* buffer); 112 int32 _Receive(tcp_segment_header& segment, 113 net_buffer* buffer); 114 void _UpdateTimestamps(tcp_segment_header& segment, 115 size_t segmentLength); 116 void _MarkEstablished(); 117 status_t _WaitForEstablished(MutexLocker& lock, 118 bigtime_t timeout); 119 bool _AddData(tcp_segment_header& segment, 120 net_buffer* buffer); 121 void _PrepareReceivePath(tcp_segment_header& segment); 122 status_t _PrepareSendPath(const sockaddr* peer); 123 void _Acknowledged(tcp_segment_header& segment); 124 void _Retransmit(); 125 void _UpdateRoundTripTime(int32 roundTripTime); 126 void _ResetSlowStart(); 127 void _DuplicateAcknowledge(tcp_segment_header& segment); 128 129 static void _TimeWaitTimer(net_timer* timer, void* _endpoint); 130 static void _RetransmitTimer(net_timer* timer, void* _endpoint); 131 static void _PersistTimer(net_timer* timer, void* _endpoint); 132 static void _DelayedAcknowledgeTimer(net_timer* timer, 133 void* _endpoint); 134 135 private: 136 HashTableLink<TCPEndpoint> fConnectionHashLink; 137 HashTableLink<TCPEndpoint> fEndpointHashLink; 138 friend class EndpointManager; 139 friend class ConnectionHashDefinition; 140 friend class EndpointHashDefinition; 141 142 mutex fLock; 143 EndpointManager* fManager; 144 WaitList fReceiveList; 145 WaitList fSendList; 146 sem_id fAcceptSemaphore; 147 uint8 fOptions; 148 149 uint8 fSendWindowShift; 150 uint8 fReceiveWindowShift; 151 152 tcp_sequence fSendUnacknowledged; 153 tcp_sequence fSendNext; 154 tcp_sequence fSendMax; 155 tcp_sequence fSendUrgentOffset; 156 uint32 fSendWindow; 157 uint32 fSendMaxWindow; 158 uint32 fSendMaxSegmentSize; 159 BufferQueue fSendQueue; 160 tcp_sequence fLastAcknowledgeSent; 161 tcp_sequence fInitialSendSequence; 162 uint32 fDuplicateAcknowledgeCount; 163 164 net_route *fRoute; 165 // TODO: don't use a net_route, but a net_route_info!!! 166 // (the latter will automatically adapt to routing changes) 167 168 tcp_sequence fReceiveNext; 169 tcp_sequence fReceiveMaxAdvertised; 170 uint32 fReceiveWindow; 171 uint32 fReceiveMaxSegmentSize; 172 BufferQueue fReceiveQueue; 173 tcp_sequence fInitialReceiveSequence; 174 175 // round trip time and retransmit timeout computation 176 int32 fRoundTripTime; 177 int32 fRoundTripDeviation; 178 bigtime_t fRetransmitTimeout; 179 180 uint32 fReceivedTimestamp; 181 182 uint32 fCongestionWindow; 183 uint32 fSlowStartThreshold; 184 185 tcp_state fState; 186 uint32 fFlags; 187 188 // timer 189 net_timer fRetransmitTimer; 190 net_timer fPersistTimer; 191 net_timer fDelayedAcknowledgeTimer; 192 net_timer fTimeWaitTimer; 193 }; 194 195 #endif // TCP_ENDPOINT_H 196