xref: /haiku/src/add-ons/kernel/network/protocols/tcp/tcp.h (revision 1acbe440b8dd798953bec31d18ee589aa3f71b73)
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  */
8 #ifndef TCP_H
9 #define TCP_H
10 
11 
12 #include <net_buffer.h>
13 #include <net_datalink.h>
14 #include <net_socket.h>
15 #include <net_stack.h>
16 
17 #include <util/khash.h>
18 
19 #include <ByteOrder.h>
20 
21 #include <sys/socket.h>
22 
23 
24 class EndpointManager;
25 
26 typedef enum {
27 	// establishing a connection
28 	CLOSED,
29 	LISTEN,
30 	SYNCHRONIZE_SENT,
31 	SYNCHRONIZE_RECEIVED,
32 	ESTABLISHED,
33 
34 	// peer closes the connection
35 	FINISH_RECEIVED,
36 	WAIT_FOR_FINISH_ACKNOWLEDGE,
37 
38 	// we close the connection
39 	FINISH_SENT,
40 	FINISH_ACKNOWLEDGED,
41 	CLOSING,
42 	TIME_WAIT
43 } tcp_state;
44 
45 struct tcp_header {
46 	uint16 source_port;
47 	uint16 destination_port;
48 	uint32 sequence;
49 	uint32 acknowledge;
50 	struct {
51 #if B_HOST_IS_LENDIAN == 1
52 		uint8 reserved : 4;
53 		uint8 header_length : 4;
54 #else
55 		uint8 header_length : 4;
56 		uint8 reserved : 4;
57 #endif
58 	};
59 	uint8  flags;
60 	uint16 advertised_window;
61 	uint16 checksum;
62 	uint16 urgent_offset;
63 
64 	uint32 HeaderLength() const { return (uint32)header_length << 2; }
65 	uint32 Sequence() const { return ntohl(sequence); }
66 	uint32 Acknowledge() const { return ntohl(acknowledge); }
67 	uint16 AdvertisedWindow() const { return ntohs(advertised_window); }
68 	uint16 Checksum() const { return ntohs(checksum); }
69 	uint16 UrgentOffset() const { return ntohs(urgent_offset); }
70 } _PACKED;
71 
72 class tcp_sequence {
73 	public:
74 		tcp_sequence() {}
75 		tcp_sequence(uint32 sequence) : number(sequence) {}
76 
77 		operator uint32() const { return number; }
78 
79 		void operator=(uint32 sequence) { number = sequence; }
80 		bool operator>(uint32 sequence) const { return (int32)(number - sequence) > 0; }
81 		bool operator>=(uint32 sequence) const { return (int32)(number - sequence) >= 0; }
82 		bool operator<(uint32 sequence) const { return (int32)(number - sequence) < 0; }
83 		bool operator<=(uint32 sequence) const { return (int32)(number - sequence) <= 0; }
84 
85 		uint32& operator+=(uint32 sequence) { return number += sequence; }
86 		uint32& operator++() { return ++number; }
87 		uint32 operator++(int _) { return number++; }
88 
89 	private:
90 		uint32 number;
91 };
92 
93 // TCP flag constants
94 #define TCP_FLAG_FINISH					0x01
95 #define TCP_FLAG_SYNCHRONIZE			0x02
96 #define TCP_FLAG_RESET					0x04
97 #define TCP_FLAG_PUSH					0x08
98 #define TCP_FLAG_ACKNOWLEDGE			0x10
99 #define TCP_FLAG_URGENT					0x20
100 #define TCP_FLAG_CONGESTION_NOTIFICATION_ECHO	0x40
101 #define TCP_FLAG_CONGESTION_WINDOW_REDUCED		0x80
102 
103 #define TCP_CONNECTION_TIMEOUT			75000000	// 75 secs
104 #define TCP_DELAYED_ACKNOWLEDGE_TIMEOUT	100000		// 100 msecs
105 #define TCP_DEFAULT_MAX_SEGMENT_SIZE	536
106 #define TCP_MAX_WINDOW					65535
107 #define TCP_MAX_SEGMENT_LIFETIME		60000000	// 60 secs
108 
109 struct tcp_option {
110 	uint8	kind;
111 	uint8	length;
112 	union {
113 		uint8	window_shift;
114 		uint16	max_segment_size;
115 		uint32	timestamp;
116 	};
117 	uint32	timestamp_reply;
118 } _PACKED;
119 
120 enum tcp_option_kind {
121 	TCP_OPTION_END				= 0,
122 	TCP_OPTION_NOP				= 1,
123 	TCP_OPTION_MAX_SEGMENT_SIZE	= 2,
124 	TCP_OPTION_WINDOW_SHIFT		= 3,
125 	TCP_OPTION_TIMESTAMP		= 8,
126 };
127 
128 #define TCP_MAX_WINDOW_SHIFT	14
129 
130 struct tcp_segment_header {
131 	tcp_segment_header() : has_window_shift(false), window_shift(0), max_segment_size(0) {}
132 		// constructor zeros options
133 
134 	uint32	sequence;
135 	uint32	acknowledge;
136 	uint16	advertised_window;
137 	uint16	urgent_offset;
138 	uint8	flags;
139 	uint8	has_window_shift : 1;
140 	uint8	window_shift : 7;
141 	uint16	max_segment_size;
142 
143 	bool AcknowledgeOnly() const
144 	{
145 		return (flags & (TCP_FLAG_SYNCHRONIZE | TCP_FLAG_FINISH | TCP_FLAG_RESET
146 			| TCP_FLAG_URGENT | TCP_FLAG_ACKNOWLEDGE)) == TCP_FLAG_ACKNOWLEDGE;
147 	}
148 };
149 
150 enum tcp_segment_action {
151 	KEEP		= 0x00,
152 	DROP		= 0x01,
153 	RESET		= 0x02,
154 	ACKNOWLEDGE	= 0x04,
155 	IMMEDIATE_ACKNOWLEDGE = 0x08,
156 	DELETE		= 0x10,
157 };
158 
159 
160 extern net_domain *gDomain;
161 extern net_address_module_info *gAddressModule;
162 extern net_buffer_module_info *gBufferModule;
163 extern net_datalink_module_info *gDatalinkModule;
164 extern net_socket_module_info *gSocketModule;
165 extern net_stack_module_info *gStackModule;
166 extern EndpointManager *gEndpointManager;
167 
168 
169 status_t add_tcp_header(tcp_segment_header &segment, net_buffer *buffer);
170 
171 #endif	// TCP_H
172