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 <util/AutoLock.h>
22#include <util/DoublyLinkedList.h>
23#include <util/OpenHashTable.h>
24
25#include <stddef.h>
26
27
28class WaitList {
29public:
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
38private:
39	int32 fCondition;
40	sem_id fSem;
41};
42
43
44class TCPEndpoint : public net_protocol, public ProtocolSocket {
45public:
46						TCPEndpoint(net_socket* socket);
47						~TCPEndpoint();
48
49			status_t	InitCheck() const;
50
51			status_t	Open();
52			status_t	Close();
53			void		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
86private:
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
135private:
136	TCPEndpoint*	fConnectionHashLink;
137	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	bool			fFinishReceived;
174	tcp_sequence	fFinishReceivedAt;
175	tcp_sequence	fInitialReceiveSequence;
176
177	// round trip time and retransmit timeout computation
178	int32			fRoundTripTime;
179	int32			fRoundTripDeviation;
180	bigtime_t		fRetransmitTimeout;
181
182	uint32			fReceivedTimestamp;
183
184	uint32			fCongestionWindow;
185	uint32			fSlowStartThreshold;
186
187	tcp_state		fState;
188	uint32			fFlags;
189
190	// timer
191	net_timer		fRetransmitTimer;
192	net_timer		fPersistTimer;
193	net_timer		fDelayedAcknowledgeTimer;
194	net_timer		fTimeWaitTimer;
195};
196
197#endif	// TCP_ENDPOINT_H
198