1 /* 2 * Copyright 2006, 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 */ 9 #ifndef TCP_ENDPOINT_H 10 #define TCP_ENDPOINT_H 11 12 13 #include "BufferQueue.h" 14 #include "EndpointManager.h" 15 #include "tcp.h" 16 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 &, bigtime_t timeout, bool wakeNext = true); 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, net_buffer **_buffer); 63 ssize_t ReadAvailable(); 64 65 status_t FillStat(struct net_stat *stat); 66 67 status_t SetSendBufferSize(size_t length); 68 status_t SetReceiveBufferSize(size_t length); 69 70 status_t SetOption(int option, const void *value, int length); 71 72 tcp_state State() const { return fState; } 73 bool IsBound() const; 74 75 void DeleteSocket(); 76 77 status_t DelayedAcknowledge(); 78 status_t SendAcknowledge(bool force); 79 status_t UpdateTimeWait(); 80 81 int32 SegmentReceived(tcp_segment_header& segment, net_buffer *buffer); 82 int32 Spawn(TCPEndpoint *parent, tcp_segment_header& segment, 83 net_buffer *buffer); 84 85 void DumpInternalState() const; 86 87 private: 88 friend class EndpointManager; 89 90 void _StartPersistTimer(); 91 void _EnterTimeWait(); 92 uint8 _CurrentFlags(); 93 bool _ShouldSendSegment(tcp_segment_header &segment, uint32 length, 94 uint32 segmentMaxSize, uint32 flightSize); 95 status_t _SendQueued(bool force = false); 96 status_t _SendQueued(bool force, uint32 sendWindow); 97 int _GetMSS(const struct sockaddr *) const; 98 status_t _ShutdownEgress(bool closing); 99 ssize_t _AvailableData() const; 100 void _NotifyReader(); 101 bool _ShouldReceive() const; 102 int32 _ListenReceive(tcp_segment_header& segment, net_buffer *buffer); 103 int32 _SynchronizeSentReceive(tcp_segment_header& segment, 104 net_buffer *buffer); 105 int32 _SegmentReceived(tcp_segment_header& segment, net_buffer *buffer); 106 int32 _Receive(tcp_segment_header& segment, net_buffer *buffer); 107 void _UpdateTimestamps(tcp_segment_header& segment, 108 size_t segmentLength); 109 void _MarkEstablished(); 110 status_t _WaitForEstablished(MutexLocker &lock, bigtime_t timeout); 111 void _AddData(tcp_segment_header &segment, net_buffer *buffer); 112 void _PrepareReceivePath(tcp_segment_header &segment); 113 status_t _PrepareSendPath(const sockaddr *peer); 114 void _Acknowledged(tcp_segment_header &segment); 115 void _Retransmit(); 116 void _UpdateSRTT(int32 roundTripTime); 117 void _ResetSlowStart(); 118 void _DuplicateAcknowledge(tcp_segment_header &segment); 119 120 static void _TimeWaitTimer(net_timer *timer, void *data); 121 static void _RetransmitTimer(net_timer *timer, void *data); 122 static void _PersistTimer(net_timer *timer, void *data); 123 static void _DelayedAcknowledgeTimer(net_timer *timer, void *data); 124 125 EndpointManager *fManager; 126 127 HashTableLink<TCPEndpoint> fConnectionHashLink; 128 HashTableLink<TCPEndpoint> fEndpointHashLink; 129 130 friend class ConnectionHashDefinition; 131 friend class EndpointHashDefinition; 132 133 mutex fLock; 134 WaitList fReceiveList; 135 WaitList fSendList; 136 sem_id fAcceptSemaphore; 137 uint8 fOptions; 138 139 uint8 fSendWindowShift; 140 uint8 fReceiveWindowShift; 141 142 tcp_sequence fSendUnacknowledged; 143 tcp_sequence fSendNext; 144 tcp_sequence fSendMax; 145 uint32 fSendWindow; 146 uint32 fSendMaxWindow; 147 uint32 fSendMaxSegmentSize; 148 BufferQueue fSendQueue; 149 tcp_sequence fLastAcknowledgeSent; 150 tcp_sequence fInitialSendSequence; 151 uint32 fDuplicateAcknowledgeCount; 152 153 net_route *fRoute; 154 // TODO: don't use a net_route, but a net_route_info!!! 155 156 tcp_sequence fReceiveNext; 157 tcp_sequence fReceiveMaxAdvertised; 158 uint32 fReceiveWindow; 159 uint32 fReceiveMaxSegmentSize; 160 BufferQueue fReceiveQueue; 161 tcp_sequence fInitialReceiveSequence; 162 163 // round trip time and retransmit timeout computation 164 int32 fRoundTripTime; 165 int32 fRoundTripDeviation; 166 bigtime_t fRetransmitTimeout; 167 168 uint32 fReceivedTimestamp; 169 170 uint32 fCongestionWindow; 171 uint32 fSlowStartThreshold; 172 173 tcp_state fState; 174 uint32 fFlags; 175 status_t fError; 176 177 // timer 178 net_timer fRetransmitTimer; 179 net_timer fPersistTimer; 180 net_timer fDelayedAcknowledgeTimer; 181 net_timer fTimeWaitTimer; 182 }; 183 184 #endif // TCP_ENDPOINT_H 185