16bfaab8aSAndrew Galante/*
2e572c323SAxel Dörfler * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
36bfaab8aSAndrew Galante * Distributed under the terms of the MIT License.
46bfaab8aSAndrew Galante *
56bfaab8aSAndrew Galante * Authors:
66bfaab8aSAndrew Galante *		Andrew Galante, haiku.galante@gmail.com
7c35b04deSAxel Dörfler *		Axel D��rfler, axeld@pinc-software.de
884052230SAxel Dörfler *		Hugo Santos, hugosantos@gmail.com
96bfaab8aSAndrew Galante */
10442c0979SAxel Dörfler#ifndef TCP_ENDPOINT_H
11442c0979SAxel Dörfler#define TCP_ENDPOINT_H
126bfaab8aSAndrew Galante
13171ee972SAndrew Galante
145fcf0448SAxel Dörfler#include "BufferQueue.h"
154b55736dSHugo Santos#include "EndpointManager.h"
164b55736dSHugo Santos#include "tcp.h"
177bfdb02eSAndrew Galante
184b55736dSHugo Santos#include <ProtocolUtilities.h>
19c35b04deSAxel Dörfler#include <net_protocol.h>
20c35b04deSAxel Dörfler#include <net_stack.h>
217664bcb5SHugo Santos#include <util/AutoLock.h>
225fcf0448SAxel Dörfler#include <util/DoublyLinkedList.h>
232586c25eSHugo Santos#include <util/OpenHashTable.h>
246bfaab8aSAndrew Galante
25c35b04deSAxel Dörfler#include <stddef.h>
266bfaab8aSAndrew Galante
276bfaab8aSAndrew Galante
284b55736dSHugo Santosclass TCPEndpoint : public net_protocol, public ProtocolSocket {
2905849428SIngo Weinholdpublic:
30db4b6bc4SAxel Dörfler						TCPEndpoint(net_socket* socket);
31db4b6bc4SAxel Dörfler						~TCPEndpoint();
3205849428SIngo Weinhold
33db4b6bc4SAxel Dörfler			status_t	InitCheck() const;
3405849428SIngo Weinhold
35db4b6bc4SAxel Dörfler			status_t	Open();
36db4b6bc4SAxel Dörfler			status_t	Close();
3711112327SAxel Dörfler			void		Free();
38db4b6bc4SAxel Dörfler			status_t	Connect(const struct sockaddr* address);
39db4b6bc4SAxel Dörfler			status_t	Accept(struct net_socket** _acceptedSocket);
40db4b6bc4SAxel Dörfler			status_t	Bind(const sockaddr* address);
41db4b6bc4SAxel Dörfler			status_t	Unbind(struct sockaddr* address);
42db4b6bc4SAxel Dörfler			status_t	Listen(int count);
43db4b6bc4SAxel Dörfler			status_t	Shutdown(int direction);
44db4b6bc4SAxel Dörfler			status_t	SendData(net_buffer* buffer);
45db4b6bc4SAxel Dörfler			ssize_t		SendAvailable();
46db4b6bc4SAxel Dörfler			status_t	ReadData(size_t numBytes, uint32 flags,
47db4b6bc4SAxel Dörfler							net_buffer** _buffer);
48db4b6bc4SAxel Dörfler			ssize_t		ReadAvailable();
4905849428SIngo Weinhold
50db4b6bc4SAxel Dörfler			status_t	FillStat(struct net_stat* stat);
5105849428SIngo Weinhold
52db4b6bc4SAxel Dörfler			status_t	SetSendBufferSize(size_t length);
53db4b6bc4SAxel Dörfler			status_t	SetReceiveBufferSize(size_t length);
5405849428SIngo Weinhold
55895d7215SAxel Dörfler			status_t	GetOption(int option, void* value, int* _length);
56db4b6bc4SAxel Dörfler			status_t	SetOption(int option, const void* value, int length);
5705849428SIngo Weinhold
58db4b6bc4SAxel Dörfler			tcp_state	State() const { return fState; }
59db4b6bc4SAxel Dörfler			bool		IsBound() const;
6030a396abSAxel Dörfler			bool		IsLocal() const;
6105849428SIngo Weinhold
62db4b6bc4SAxel Dörfler			status_t	DelayedAcknowledge();
63db4b6bc4SAxel Dörfler			status_t	SendAcknowledge(bool force);
6405849428SIngo Weinhold
65db4b6bc4SAxel Dörfler			int32		SegmentReceived(tcp_segment_header& segment,
66db4b6bc4SAxel Dörfler							net_buffer* buffer);
6705849428SIngo Weinhold
68db4b6bc4SAxel Dörfler			void		Dump() const;
6905849428SIngo Weinhold
7005849428SIngo Weinholdprivate:
71db4b6bc4SAxel Dörfler			void		_StartPersistTimer();
72db4b6bc4SAxel Dörfler			void		_EnterTimeWait();
730cadc931SAxel Dörfler			void		_UpdateTimeWait();
7462895789SAxel Dörfler			void		_Close();
75db4b6bc4SAxel Dörfler			void		_CancelConnectionTimers();
76db4b6bc4SAxel Dörfler			uint8		_CurrentFlags();
77db4b6bc4SAxel Dörfler			bool		_ShouldSendSegment(tcp_segment_header& segment,
78db4b6bc4SAxel Dörfler							uint32 length, uint32 segmentMaxSize,
79db4b6bc4SAxel Dörfler							uint32 flightSize);
80db4b6bc4SAxel Dörfler			status_t	_SendQueued(bool force = false);
81db4b6bc4SAxel Dörfler			status_t	_SendQueued(bool force, uint32 sendWindow);
82db4b6bc4SAxel Dörfler			int			_MaxSegmentSize(const struct sockaddr* address) const;
83db4b6bc4SAxel Dörfler			status_t	_Disconnect(bool closing);
84db4b6bc4SAxel Dörfler			ssize_t		_AvailableData() const;
85db4b6bc4SAxel Dörfler			void		_NotifyReader();
86db4b6bc4SAxel Dörfler			bool		_ShouldReceive() const;
87db4b6bc4SAxel Dörfler			void		_HandleReset(status_t error);
88db4b6bc4SAxel Dörfler			int32		_Spawn(TCPEndpoint* parent, tcp_segment_header& segment,
89db4b6bc4SAxel Dörfler							net_buffer* buffer);
90db4b6bc4SAxel Dörfler			int32		_ListenReceive(tcp_segment_header& segment,
91db4b6bc4SAxel Dörfler							net_buffer* buffer);
92db4b6bc4SAxel Dörfler			int32		_SynchronizeSentReceive(tcp_segment_header& segment,
93db4b6bc4SAxel Dörfler							net_buffer* buffer);
94db4b6bc4SAxel Dörfler			int32		_SegmentReceived(tcp_segment_header& segment,
95db4b6bc4SAxel Dörfler							net_buffer* buffer);
96db4b6bc4SAxel Dörfler			int32		_Receive(tcp_segment_header& segment,
97db4b6bc4SAxel Dörfler							net_buffer* buffer);
98db4b6bc4SAxel Dörfler			void		_UpdateTimestamps(tcp_segment_header& segment,
99db4b6bc4SAxel Dörfler							size_t segmentLength);
100db4b6bc4SAxel Dörfler			void		_MarkEstablished();
101db4b6bc4SAxel Dörfler			status_t	_WaitForEstablished(MutexLocker& lock,
102db4b6bc4SAxel Dörfler							bigtime_t timeout);
103db4b6bc4SAxel Dörfler			bool		_AddData(tcp_segment_header& segment,
104db4b6bc4SAxel Dörfler							net_buffer* buffer);
105db4b6bc4SAxel Dörfler			void		_PrepareReceivePath(tcp_segment_header& segment);
106db4b6bc4SAxel Dörfler			status_t	_PrepareSendPath(const sockaddr* peer);
107db4b6bc4SAxel Dörfler			void		_Acknowledged(tcp_segment_header& segment);
108db4b6bc4SAxel Dörfler			void		_Retransmit();
109bf1a86c1SA-star-ayush			void		_UpdateRoundTripTime(int32 roundTripTime, int32 expectedSamples);
110db4b6bc4SAxel Dörfler			void		_ResetSlowStart();
111db4b6bc4SAxel Dörfler			void		_DuplicateAcknowledge(tcp_segment_header& segment);
112db4b6bc4SAxel Dörfler
113db4b6bc4SAxel Dörfler	static	void		_TimeWaitTimer(net_timer* timer, void* _endpoint);
114db4b6bc4SAxel Dörfler	static	void		_RetransmitTimer(net_timer* timer, void* _endpoint);
115db4b6bc4SAxel Dörfler	static	void		_PersistTimer(net_timer* timer, void* _endpoint);
116db4b6bc4SAxel Dörfler	static	void		_DelayedAcknowledgeTimer(net_timer* timer,
117db4b6bc4SAxel Dörfler							void* _endpoint);
11805849428SIngo Weinhold
119da8fbe0eSMichael Lotz	static	status_t	_WaitForCondition(ConditionVariable& condition,
120da8fbe0eSMichael Lotz							MutexLocker& locker, bigtime_t timeout);
121da8fbe0eSMichael Lotz
122db4b6bc4SAxel Dörflerprivate:
1235147963dSStephan Aßmus	TCPEndpoint*	fConnectionHashLink;
1245147963dSStephan Aßmus	TCPEndpoint*	fEndpointHashLink;
125db4b6bc4SAxel Dörfler	friend class EndpointManager;
12605849428SIngo Weinhold	friend class ConnectionHashDefinition;
12705849428SIngo Weinhold	friend class EndpointHashDefinition;
12805849428SIngo Weinhold
12905849428SIngo Weinhold	mutex			fLock;
130db4b6bc4SAxel Dörfler	EndpointManager* fManager;
131da8fbe0eSMichael Lotz	ConditionVariable
132da8fbe0eSMichael Lotz					fReceiveCondition;
133da8fbe0eSMichael Lotz	ConditionVariable
134da8fbe0eSMichael Lotz					fSendCondition;
13505849428SIngo Weinhold	sem_id			fAcceptSemaphore;
13605849428SIngo Weinhold	uint8			fOptions;
13705849428SIngo Weinhold
13805849428SIngo Weinhold	uint8			fSendWindowShift;
13905849428SIngo Weinhold	uint8			fReceiveWindowShift;
14005849428SIngo Weinhold
14105849428SIngo Weinhold	tcp_sequence	fSendUnacknowledged;
14205849428SIngo Weinhold	tcp_sequence	fSendNext;
14305849428SIngo Weinhold	tcp_sequence	fSendMax;
1448e0a418bSAxel Dörfler	tcp_sequence	fSendUrgentOffset;
14505849428SIngo Weinhold	uint32			fSendWindow;
14605849428SIngo Weinhold	uint32			fSendMaxWindow;
14705849428SIngo Weinhold	uint32			fSendMaxSegmentSize;
148272e1a2fSA-star-ayush	uint32			fSendMaxSegments;
14905849428SIngo Weinhold	BufferQueue		fSendQueue;
15005849428SIngo Weinhold	tcp_sequence	fLastAcknowledgeSent;
15105849428SIngo Weinhold	tcp_sequence	fInitialSendSequence;
152515cda72SA-star-ayush	tcp_sequence	fPreviousHighestAcknowledge;
15305849428SIngo Weinhold	uint32			fDuplicateAcknowledgeCount;
154ec63a329SA-star-ayush	uint32			fPreviousFlightSize;
155515cda72SA-star-ayush	uint32			fRecover;
15605849428SIngo Weinhold
15789822930SMichael Lotz	net_route		*fRoute;
15805849428SIngo Weinhold		// TODO: don't use a net_route, but a net_route_info!!!
15930a396abSAxel Dörfler		// (the latter will automatically adapt to routing changes)
16005849428SIngo Weinhold
16105849428SIngo Weinhold	tcp_sequence	fReceiveNext;
16205849428SIngo Weinhold	tcp_sequence	fReceiveMaxAdvertised;
16305849428SIngo Weinhold	uint32			fReceiveWindow;
16405849428SIngo Weinhold	uint32			fReceiveMaxSegmentSize;
16505849428SIngo Weinhold	BufferQueue		fReceiveQueue;
166e572c323SAxel Dörfler	bool			fFinishReceived;
167e572c323SAxel Dörfler	tcp_sequence	fFinishReceivedAt;
16805849428SIngo Weinhold	tcp_sequence	fInitialReceiveSequence;
16905849428SIngo Weinhold
17005849428SIngo Weinhold	// round trip time and retransmit timeout computation
17130982ed7SA-star-ayush	int32			fSmoothedRoundTripTime;
17230982ed7SA-star-ayush	int32			fRoundTripVariation;
17330982ed7SA-star-ayush	uint32			fSendTime;
174bf1a86c1SA-star-ayush	tcp_sequence	fRoundTripStartSequence;
17505849428SIngo Weinhold	bigtime_t		fRetransmitTimeout;
17605849428SIngo Weinhold
17705849428SIngo Weinhold	uint32			fReceivedTimestamp;
17805849428SIngo Weinhold
17905849428SIngo Weinhold	uint32			fCongestionWindow;
18005849428SIngo Weinhold	uint32			fSlowStartThreshold;
18105849428SIngo Weinhold
18205849428SIngo Weinhold	tcp_state		fState;
18305849428SIngo Weinhold	uint32			fFlags;
18405849428SIngo Weinhold
18505849428SIngo Weinhold	// timer
18605849428SIngo Weinhold	net_timer		fRetransmitTimer;
18705849428SIngo Weinhold	net_timer		fPersistTimer;
18805849428SIngo Weinhold	net_timer		fDelayedAcknowledgeTimer;
18905849428SIngo Weinhold	net_timer		fTimeWaitTimer;
1906bfaab8aSAndrew Galante};
1916bfaab8aSAndrew Galante
192442c0979SAxel Dörfler#endif	// TCP_ENDPOINT_H
193