1b7e825d6SAndreas Färber/*
2b7e825d6SAndreas Färber * Copyright 2010 Andreas F��rber <andreas.faerber@web.de>
3b7e825d6SAndreas Färber * All rights reserved. Distributed under the terms of the MIT License.
4b7e825d6SAndreas Färber */
5b7e825d6SAndreas Färber#ifndef BOOT_NET_TCP_H
6b7e825d6SAndreas Färber#define BOOT_NET_TCP_H
7b7e825d6SAndreas Färber
8b7e825d6SAndreas Färber
9b7e825d6SAndreas Färber#include <boot/net/IP.h>
10b7e825d6SAndreas Färber
11b7e825d6SAndreas Färber
12b7e825d6SAndreas Färberclass TCPPacket {
13b7e825d6SAndreas Färberpublic:
14b7e825d6SAndreas Färber	TCPPacket();
15b7e825d6SAndreas Färber	~TCPPacket();
16b7e825d6SAndreas Färber
17b7e825d6SAndreas Färber	status_t SetTo(const void* data, size_t size, ip_addr_t sourceAddress,
18b7e825d6SAndreas Färber		uint16 sourcePort, ip_addr_t destinationAddress,
19b7e825d6SAndreas Färber		uint16 destinationPort, uint32 sequenceNumber,
20b7e825d6SAndreas Färber		uint32 acknowledgmentNumber, uint8 flags);
21b7e825d6SAndreas Färber
22b7e825d6SAndreas Färber	ip_addr_t SourceAddress() const;
23b7e825d6SAndreas Färber	ip_addr_t DestinationAddress() const;
24b7e825d6SAndreas Färber	uint16 SourcePort() const;
25b7e825d6SAndreas Färber	uint16 DestinationPort() const;
26b7e825d6SAndreas Färber	uint32 SequenceNumber() const;
27b7e825d6SAndreas Färber	uint32 AcknowledgmentNumber() const;
28b7e825d6SAndreas Färber	const void* Data() const { return fData; }
29b7e825d6SAndreas Färber	size_t DataSize() const { return fSize; }
30b7e825d6SAndreas Färber	uint8 Flags() const { return fFlags; }
31b7e825d6SAndreas Färber
32b7e825d6SAndreas Färber	bool ProvidesSequenceNumber(uint32 sequenceNo) const;
33b7e825d6SAndreas Färber
34b7e825d6SAndreas Färber	TCPPacket* Next() const;
35b7e825d6SAndreas Färber	void SetNext(TCPPacket* packet);
36b7e825d6SAndreas Färber
37b7e825d6SAndreas Färberprivate:
38b7e825d6SAndreas Färber	ip_addr_t	fSourceAddress;
39b7e825d6SAndreas Färber	ip_addr_t	fDestinationAddress;
40b7e825d6SAndreas Färber	uint16		fSourcePort;
41b7e825d6SAndreas Färber	uint16		fDestinationPort;
42b7e825d6SAndreas Färber	uint32		fSequenceNumber;
43b7e825d6SAndreas Färber	uint32		fAcknowledgmentNumber;
44b7e825d6SAndreas Färber	void*		fData;
45b7e825d6SAndreas Färber	size_t		fSize;
46b7e825d6SAndreas Färber	uint8		fFlags;
47b7e825d6SAndreas Färber	TCPPacket*	fNext;
48b7e825d6SAndreas Färber};
49b7e825d6SAndreas Färber
50b7e825d6SAndreas Färberclass TCPService;
51b7e825d6SAndreas Färber
52b7e825d6SAndreas Färberenum TCPSocketState {
53b7e825d6SAndreas Färber	TCP_SOCKET_STATE_INITIAL,
54b7e825d6SAndreas Färber	TCP_SOCKET_STATE_SYN_SENT,
55b7e825d6SAndreas Färber	TCP_SOCKET_STATE_SYN_RECEIVED,
56b7e825d6SAndreas Färber	TCP_SOCKET_STATE_OPEN,
57b7e825d6SAndreas Färber	TCP_SOCKET_STATE_FIN_SENT,
58b7e825d6SAndreas Färber	TCP_SOCKET_STATE_CLOSED
59b7e825d6SAndreas Färber};
60b7e825d6SAndreas Färber
61b7e825d6SAndreas Färberclass TCPSocket {
62b7e825d6SAndreas Färberpublic:
63b7e825d6SAndreas Färber	TCPSocket();
64b7e825d6SAndreas Färber	~TCPSocket();
65b7e825d6SAndreas Färber
66b7e825d6SAndreas Färber	ip_addr_t Address() const	{ return fAddress; }
67b7e825d6SAndreas Färber	uint16 Port() const			{ return fPort; }
68040b3398SAndreas Färber	uint16 WindowSize() const;
69b7e825d6SAndreas Färber
70b7e825d6SAndreas Färber	status_t Connect(ip_addr_t address, uint16 port);
71b7e825d6SAndreas Färber	status_t Close();
72b7e825d6SAndreas Färber	status_t Read(void* buffer, size_t bufferSize, size_t* bytesRead, bigtime_t timeout = 0);
73b7e825d6SAndreas Färber	status_t Write(const void* buffer, size_t bufferSize);
74b7e825d6SAndreas Färber
75b7e825d6SAndreas Färber	void Acknowledge(uint32 number);
76b7e825d6SAndreas Färber	void ProcessPacket(TCPPacket* packet);
77b7e825d6SAndreas Färber
78b7e825d6SAndreas Färberprivate:
79b7e825d6SAndreas Färber	TCPPacket* _PeekPacket();
80b7e825d6SAndreas Färber	TCPPacket* _DequeuePacket();
81b7e825d6SAndreas Färber	status_t _Send(TCPPacket* packet, bool enqueue = true);
82b7e825d6SAndreas Färber	status_t _ResendQueue();
83b7e825d6SAndreas Färber	void _EnqueueOutgoingPacket(TCPPacket* packet);
84b7e825d6SAndreas Färber	inline void	_DumpQueue();
85b7e825d6SAndreas Färber	status_t _WaitForState(TCPSocketState state, bigtime_t timeout = 0);
86b7e825d6SAndreas Färber	status_t _Ack();
87b7e825d6SAndreas Färber
88b7e825d6SAndreas Färber	TCPService*	fTCPService;
89b7e825d6SAndreas Färber	ip_addr_t	fAddress;
90b7e825d6SAndreas Färber	uint16		fPort;
91b7e825d6SAndreas Färber	ip_addr_t	fRemoteAddress;
92b7e825d6SAndreas Färber	uint16		fRemotePort;
93b7e825d6SAndreas Färber	uint32		fSequenceNumber;
94b7e825d6SAndreas Färber	uint32		fAcknowledgeNumber;
95b7e825d6SAndreas Färber	uint32		fNextSequence;
96b7e825d6SAndreas Färber	TCPPacket*	fFirstPacket;
97b7e825d6SAndreas Färber	TCPPacket*	fLastPacket;
98b7e825d6SAndreas Färber	TCPPacket*	fFirstSentPacket;
99b7e825d6SAndreas Färber	TCPPacket*	fLastSentPacket;
100b7e825d6SAndreas Färber	TCPSocketState fState;
101b7e825d6SAndreas Färber	TCPSocketState fRemoteState;
102b7e825d6SAndreas Färber};
103b7e825d6SAndreas Färber
104b7e825d6SAndreas Färberclass TCPService : public IPSubService {
105b7e825d6SAndreas Färberpublic:
106b7e825d6SAndreas Färber	TCPService(IPService* ipService);
107b7e825d6SAndreas Färber	virtual ~TCPService();
108b7e825d6SAndreas Färber
109b7e825d6SAndreas Färber	status_t Init();
110b7e825d6SAndreas Färber
111b7e825d6SAndreas Färber	virtual uint8 IPProtocol() const;
112b7e825d6SAndreas Färber
113b7e825d6SAndreas Färber	virtual void HandleIPPacket(IPService* ipService, ip_addr_t sourceIP,
114b7e825d6SAndreas Färber		ip_addr_t destinationIP, const void* data, size_t size);
115b7e825d6SAndreas Färber
116b7e825d6SAndreas Färber	status_t Send(uint16 sourcePort, ip_addr_t destinationAddress,
117b7e825d6SAndreas Färber		uint16 destinationPort, uint32 sequenceNumber,
118040b3398SAndreas Färber		uint32 acknowledgmentNumber, uint8 flags, uint16 windowSize,
119040b3398SAndreas Färber		ChainBuffer* buffer);
120b7e825d6SAndreas Färber
121b7e825d6SAndreas Färber	void ProcessIncomingPackets();
122b7e825d6SAndreas Färber
123b7e825d6SAndreas Färber	status_t BindSocket(TCPSocket* socket);
124b7e825d6SAndreas Färber	void UnbindSocket(TCPSocket* socket);
125b7e825d6SAndreas Färber
126b7e825d6SAndreas Färberprivate:
127b7e825d6SAndreas Färber	uint16 _ChecksumBuffer(ChainBuffer* buffer, ip_addr_t source,
128b7e825d6SAndreas Färber		ip_addr_t destination, uint16 length);
129b7e825d6SAndreas Färber	uint16 _ChecksumData(const void* data, uint16 length, ip_addr_t source,
130b7e825d6SAndreas Färber		ip_addr_t destination);
131b7e825d6SAndreas Färber
132b7e825d6SAndreas Färber	TCPSocket* _FindSocket(ip_addr_t address, uint16 port);
133b7e825d6SAndreas Färber
134b7e825d6SAndreas Färber	IPService*			fIPService;
135b7e825d6SAndreas Färber	Vector<TCPSocket*>	fSockets;
136b7e825d6SAndreas Färber};
137b7e825d6SAndreas Färber
138b7e825d6SAndreas Färber
139b7e825d6SAndreas Färber#endif
140