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