1 /* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * Definitions for the TCP module. 7 * 8 * Version: @(#)tcp.h 1.0.5 05/23/93 9 * 10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 12 * 13 * This program is free software; you can redistribute it and/or 14 * modify it under the terms of the GNU General Public License 15 * as published by the Free Software Foundation; either version 16 * 2 of the License, or (at your option) any later version. 17 */ 18 #ifndef_TCP_H 19 #define_TCP_H 20
21 #include <linux/tcp.h>
22 #include <net/checksum.h>
23
24 /* 25 * 40 is maximal IP options size 26 * 4 is TCP option size (MSS) 27 */ 28 #defineMAX_SYN_SIZE (sizeof(structiphdr) + 40 + sizeof(structtcphdr) + 4 + MAX_HEADER + 15)
29 #define MAX_FIN_SIZE (sizeof(structiphdr) + 40 + sizeof(structtcphdr) + MAX_HEADER + 15)
30 #defineMAX_ACK_SIZE (sizeof(structiphdr) + 40 + sizeof(structtcphdr) + MAX_HEADER + 15)
31 #defineMAX_RESET_SIZE (sizeof(structiphdr) + 40 + sizeof(structtcphdr) + MAX_HEADER + 15)
32
33 #defineMAX_WINDOW 32767 /* Never offer a window over 32767 without using 34 window scaling (not yet supported). Some poor 35 stacks do signed 16bit maths! */ 36 #defineMIN_WINDOW 2048
37 #define MAX_ACK_BACKLOG 2
38 #defineMAX_DUP_ACKS 2
39 #defineMIN_WRITE_SPACE 2048
40 #defineTCP_WINDOW_DIFF 2048
41
42 /* urg_data states */ 43 #defineURG_VALID 0x0100
44 #defineURG_NOTYET 0x0200
45 #defineURG_READ 0x0400
46
47 #defineTCP_RETR1 7 /* 48 * This is how many retries it does before it 49 * tries to figure out if the gateway is 50 * down. 51 */ 52
53 #defineTCP_RETR2 15 /* 54 * This should take at least 55 * 90 minutes to time out. 56 */ 57
58 #defineTCP_TIMEOUT_LEN (15*60*HZ) /* should be about 15 mins */ 59 #defineTCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to successfully 60 * close the socket, about 60 seconds */ 61 #defineTCP_FIN_TIMEOUT (3*60*HZ) /* BSD style FIN_WAIT2 deadlock breaker */ 62 #define TCP_ACK_TIME (3*HZ) /* time to delay before sending an ACK */ 63 #defineTCP_DONE_TIME (5*HZ/2)/* maximum time to wait before actually 64 * destroying a socket */ 65 #define TCP_WRITE_TIME (30*HZ) /* initial time to wait for an ACK, 66 * after last transmit */ 67 #defineTCP_TIMEOUT_INIT (3*HZ) /* RFC 1122 initial timeout value */ 68 #defineTCP_SYN_RETRIES 10 /* number of times to retry opening a 69 * connection (TCP_RETR2-....) */ 70 #define TCP_PROBEWAIT_LEN (1*HZ)/* time to wait between probes when 71 * I've got something to write and 72 * there is no window */ 73
74 #defineTCP_NO_CHECK 0 /* turn to one if you want the default 75 * to be no checksum */ 76
77
78 /* 79 * TCP option 80 */ 81
82 #defineTCPOPT_NOP 1 /* Padding */ 83 #defineTCPOPT_EOL 0 /* End of options */ 84 #defineTCPOPT_MSS 2 /* Segment size negotiating */ 85 /* 86 * We don't use these yet, but they are for PAWS and big windows 87 */ 88 #define TCPOPT_WINDOW 3 /* Window scaling */ 89 #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ 90
91
92 /* 93 * The next routines deal with comparing 32 bit unsigned ints 94 * and worry about wraparound (automatic with unsigned arithmetic). 95 */ 96
97 extern__inlineintbefore(__u32seq1, __u32seq2)
/* */ 98 { 99 return (__s32)(seq1-seq2) < 0;
100 } 101
102 extern__inlineintafter(__u32seq1, __u32seq2)
/* */ 103 { 104 return (__s32)(seq2-seq1) < 0;
105 } 106
107
108 /* is s2<=s1<=s3 ? */ 109 extern__inlineint between(__u32seq1, __u32seq2, __u32seq3)
/* */ 110 { 111 return (after(seq1+1, seq2) && before(seq1, seq3+1));
112 } 113
114 static__inline__intmin(unsignedinta, unsignedintb)
/* */ 115 { 116 if (a > b)
117 a = b;
118 returna;
119 } 120
121 static__inline__intmax(unsignedinta, unsignedintb)
/* */ 122 { 123 if (a < b)
124 a = b;
125 returna;
126 } 127
128 externstructprototcp_prot;
129 externstructtcp_mibtcp_statistics;
130
131 externvoidtcp_err(inttype, intcode, unsignedchar *header, __u32daddr,
132 __u32, structinet_protocol *protocol);
133 externvoidtcp_shutdown (structsock *sk, inthow);
134 externinttcp_rcv(structsk_buff *skb, structdevice *dev,
135 structoptions *opt, __u32daddr,
136 unsignedshortlen, __u32saddr, intredo,
137 structinet_protocol *protocol);
138
139 externinttcp_ioctl(structsock *sk, intcmd, unsignedlongarg);
140
141 externvoidtcp_read_wakeup(structsock *);
142 externvoidtcp_write_xmit(structsock *);
143 externvoidtcp_time_wait(structsock *);
144 externvoidtcp_retransmit(structsock *, int);
145 externvoidtcp_do_retransmit(structsock *, int);
146 externvoidtcp_send_check(structtcphdr *th, unsignedlongsaddr,
147 unsignedlongdaddr, intlen, structsk_buff *skb);
148
149 /* tcp_output.c */ 150
151 externvoidtcp_send_probe0(structsock *);
152 externvoidtcp_send_partial(structsock *);
153 externvoidtcp_write_wakeup(structsock *);
154 externvoidtcp_send_fin(structsock *sk);
155 externvoidtcp_send_synack(structsock *, structsock *, structsk_buff *);
156 externvoidtcp_send_skb(structsock *, structsk_buff *);
157 externvoidtcp_send_ack(structsock *sk);
158 externvoidtcp_send_delayed_ack(structsock *sk, inttimeout);
159 externvoidtcp_send_reset(unsignedlongsaddr, unsignedlongdaddr, structtcphdr *th,
160 structproto *prot, structoptions *opt, structdevice *dev, inttos, intttl);
161
162 externvoidtcp_enqueue_partial(structsk_buff *, structsock *);
163 externstructsk_buff * tcp_dequeue_partial(structsock *);
164
165 /* tcp_input.c */ 166 externvoidtcp_cache_zap(void);
167
168 /* tcp_timer.c */ 169 #definetcp_reset_msl_timer(x,y,z) reset_timer(x,y,z)
170 externvoidtcp_reset_xmit_timer(structsock *, int, unsignedlong);
171 externvoidtcp_delack_timer(unsignedlong);
172 externvoidtcp_retransmit_timer(unsignedlong);
173
174 /* 175 * Default sequence number picking algorithm. 176 * As close as possible to RFC 793, which 177 * suggests using a 250kHz clock. 178 * Further reading shows this assumes 2MB/s networks. 179 * For 10MB/s ethernet, a 1MHz clock is appropriate. 180 * That's funny, Linux has one built in! Use it! 181 */ 182
183 staticinlineu32tcp_init_seq(void)
/* */ 184 { 185 structtimevaltv;
186 do_gettimeofday(&tv);
187 returntv.tv_usec+tv.tv_sec*1000000;
188 } 189
190 static__inline__inttcp_old_window(structsock * sk)
/* */ 191 { 192 returnsk->window - (sk->acked_seq - sk->lastwin_seq);
193 } 194
195 static__inline__inttcp_new_window(structsock * sk)
/* */ 196 { 197 intwindow = sock_rspace(sk);
198
199 if (window > 1024)
200 window &= ~0x3FF; /* make free space a multiple of 1024 */ 201
202 if (sk->window_clamp && sk->window_clamp < window)
203 window = sk->window_clamp;
204
205 /* 206 * RFC 1122 says: 207 * 208 * "the suggested [SWS] avoidance algorithm for the receiver is to keep 209 * RECV.NEXT + RCV.WIN fixed until: 210 * RCV.BUFF - RCV.USER - RCV.WINDOW >= min(1/2 RCV.BUFF, MSS)" 211 * 212 * Experiments against BSD and Solaris machines show that following 213 * these rules results in the BSD and Solaris machines making very 214 * bad guesses about how much data they can have in flight. 215 * 216 * Instead we follow the BSD lead and offer a window that gives 217 * the size of the current free space, truncated to a multiple 218 * of 1024 bytes. If the window is smaller than 219 * min(sk->mss, MAX_WINDOW/2) 220 * then we advertise the window as having size 0, unless this 221 * would shrink the window we offered last time. 222 * This results in as much as double the throughput as the original 223 * implementation. 224 */ 225
226 if (sk->mss == 0)
227 sk->mss = sk->mtu;
228
229 /* BSD style SWS avoidance 230 * Note that RFC1122 only says we must do silly window avoidance, 231 * it does not require that we use the suggested algorithm. 232 */ 233
234 if (window < min(sk->mss, MAX_WINDOW/2))
235 window = 0;
236
237 returnwindow;
238 } 239
240 /* 241 * Return true if we should raise the window when we 242 * have cleaned up the receive queue. We don't want to 243 * do this normally, only if it makes sense to avoid 244 * zero window probes.. 245 * 246 * We do this only if we can raise the window noticeably. 247 */ 248 static__inline__inttcp_raise_window(structsock * sk)
/* */ 249 { 250 returntcp_new_window(sk) >= 2*tcp_old_window(sk);
251 } 252
253 static__inline__unsignedshorttcp_select_window(structsock *sk)
/* */ 254 { 255 intwindow = tcp_new_window(sk);
256
257 /* Don't allow a shrinking window */ 258 if (window > tcp_old_window(sk)) { 259 sk->window = window;
260 sk->lastwin_seq = sk->acked_seq;
261 } 262 returnsk->window;
263 } 264
265 /* 266 * List all states of a TCP socket that can be viewed as a "connected" 267 * state. This now includes TCP_SYN_RECV, although I am not yet fully 268 * convinced that this is the solution for the 'getpeername(2)' 269 * problem. Thanks to Stephen A. Wood <saw@cebaf.gov> -FvK 270 */ 271
272 extern__inlineconstinttcp_connected(constintstate)
/* */ 273 { 274 return(state == TCP_ESTABLISHED || state == TCP_CLOSE_WAIT ||
275 state == TCP_FIN_WAIT1 || state == TCP_FIN_WAIT2 ||
276 state == TCP_SYN_RECV);
277 } 278
279 /* 280 * Calculate(/check) TCP checksum 281 */ 282 static__inline__u16tcp_check(structtcphdr *th, intlen,
/* */ 283 unsignedlongsaddr, unsignedlongdaddr, unsignedlongbase)
284 { 285 returncsum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base);
286 } 287
288 #undefSTATE_TRACE 289
290 #ifdefSTATE_TRACE 291 staticchar *statename[]={ 292 "Unused","Established","Syn Sent","Syn Recv",
293 "Fin Wait 1","Fin Wait 2","Time Wait", "Close",
294 "Close Wait","Last ACK","Listen","Closing"
295 };
296 #endif 297
298 static__inline__voidtcp_set_state(structsock *sk, intstate)
/* */ 299 { 300 intoldstate = sk->state;
301
302 sk->state = state;
303
304 #ifdefSTATE_TRACE 305 if(sk->debug)
306 printk("TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]);
307 #endif 308
309 switch (state) { 310 caseTCP_ESTABLISHED:
311 if (oldstate != TCP_ESTABLISHED) { 312 tcp_statistics.TcpCurrEstab++;
313 } 314 break;
315
316 caseTCP_CLOSE:
317 tcp_cache_zap();
318 /* Should be about 2 rtt's */ 319 reset_timer(sk, TIME_DONE, min(sk->rtt * 2, TCP_DONE_TIME));
320 /* fall through */ 321 default:
322 if (oldstate==TCP_ESTABLISHED)
323 tcp_statistics.TcpCurrEstab--;
324 } 325 } 326
327 #endif/* _TCP_H */