|
|
1.1 ! root 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, <[email protected]> ! 11: * Fred N. van Kempen, <[email protected]> ! 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: #define MAX_SYN_SIZE 44 + MAX_HEADER + 15 ! 25: #define MAX_FIN_SIZE 40 + MAX_HEADER + 15 ! 26: #define MAX_ACK_SIZE 40 + MAX_HEADER + 15 ! 27: #define MAX_RESET_SIZE 40 + MAX_HEADER + 15 ! 28: #define MAX_WINDOW 32767 /* Never offer a window over 32767 without using ! 29: window scaling (not yet supported). Some poor ! 30: stacks do signed 16bit maths! */ ! 31: #define MIN_WINDOW 2048 ! 32: #define MAX_ACK_BACKLOG 2 ! 33: #define MIN_WRITE_SPACE 2048 ! 34: #define TCP_WINDOW_DIFF 2048 ! 35: ! 36: /* urg_data states */ ! 37: #define URG_VALID 0x0100 ! 38: #define URG_NOTYET 0x0200 ! 39: #define URG_READ 0x0400 ! 40: ! 41: #define TCP_RETR1 7 /* ! 42: * This is how many retries it does before it ! 43: * tries to figure out if the gateway is ! 44: * down. ! 45: */ ! 46: ! 47: #define TCP_RETR2 15 /* ! 48: * This should take at least ! 49: * 90 minutes to time out. ! 50: */ ! 51: ! 52: #define TCP_TIMEOUT_LEN (15*60*HZ) /* should be about 15 mins */ ! 53: #define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to successfully ! 54: * close the socket, about 60 seconds */ ! 55: #define TCP_FIN_TIMEOUT (3*60*HZ) /* BSD style FIN_WAIT2 deadlock breaker */ ! 56: #define TCP_ACK_TIME (3*HZ) /* time to delay before sending an ACK */ ! 57: #define TCP_DONE_TIME (5*HZ/2)/* maximum time to wait before actually ! 58: * destroying a socket */ ! 59: #define TCP_WRITE_TIME (30*HZ) /* initial time to wait for an ACK, ! 60: * after last transmit */ ! 61: #define TCP_TIMEOUT_INIT (3*HZ) /* RFC 1122 initial timeout value */ ! 62: #define TCP_SYN_RETRIES 10 /* number of times to retry opening a ! 63: * connection (TCP_RETR2-....) */ ! 64: #define TCP_PROBEWAIT_LEN (1*HZ)/* time to wait between probes when ! 65: * I've got something to write and ! 66: * there is no window */ ! 67: ! 68: #define TCP_NO_CHECK 0 /* turn to one if you want the default ! 69: * to be no checksum */ ! 70: ! 71: ! 72: /* ! 73: * TCP option ! 74: */ ! 75: ! 76: #define TCPOPT_NOP 1 /* Padding */ ! 77: #define TCPOPT_EOL 0 /* End of options */ ! 78: #define TCPOPT_MSS 2 /* Segment size negotiating */ ! 79: /* ! 80: * We don't use these yet, but they are for PAWS and big windows ! 81: */ ! 82: #define TCPOPT_WINDOW 3 /* Window scaling */ ! 83: #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ ! 84: ! 85: ! 86: /* ! 87: * The next routines deal with comparing 32 bit unsigned ints ! 88: * and worry about wraparound (automatic with unsigned arithmetic). ! 89: */ ! 90: ! 91: extern __inline int before(__u32 seq1, __u32 seq2) ! 92: { ! 93: return (__s32)(seq1-seq2) < 0; ! 94: } ! 95: ! 96: extern __inline int after(__u32 seq1, __u32 seq2) ! 97: { ! 98: return (__s32)(seq2-seq1) < 0; ! 99: } ! 100: ! 101: ! 102: /* is s2<=s1<=s3 ? */ ! 103: extern __inline int between(__u32 seq1, __u32 seq2, __u32 seq3) ! 104: { ! 105: return (after(seq1+1, seq2) && before(seq1, seq3+1)); ! 106: } ! 107: ! 108: static __inline__ int min(unsigned int a, unsigned int b) ! 109: { ! 110: if (a < b) ! 111: return(a); ! 112: return(b); ! 113: } ! 114: ! 115: extern struct proto tcp_prot; ! 116: extern struct tcp_mib tcp_statistics; ! 117: extern struct wait_queue *master_select_wakeup; ! 118: ! 119: extern void tcp_err(int type, int code, unsigned char *header, __u32 daddr, ! 120: __u32, struct inet_protocol *protocol); ! 121: extern void tcp_shutdown (struct sock *sk, int how); ! 122: extern int tcp_rcv(struct sk_buff *skb, struct device *dev, ! 123: struct options *opt, __u32 daddr, ! 124: unsigned short len, __u32 saddr, int redo, ! 125: struct inet_protocol *protocol); ! 126: ! 127: extern int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg); ! 128: ! 129: extern void tcp_read_wakeup(struct sock *); ! 130: extern void tcp_write_xmit(struct sock *); ! 131: extern void tcp_time_wait(struct sock *); ! 132: extern void tcp_retransmit(struct sock *, int); ! 133: extern void tcp_do_retransmit(struct sock *, int); ! 134: extern void tcp_send_check(struct tcphdr *th, unsigned long saddr, ! 135: unsigned long daddr, int len, struct sk_buff *skb); ! 136: ! 137: /* tcp_output.c */ ! 138: ! 139: extern void tcp_send_probe0(struct sock *); ! 140: extern void tcp_send_partial(struct sock *); ! 141: extern void tcp_write_wakeup(struct sock *); ! 142: extern void tcp_send_fin(struct sock *sk); ! 143: extern void tcp_send_synack(struct sock *, struct sock *, struct sk_buff *); ! 144: extern void tcp_send_skb(struct sock *, struct sk_buff *); ! 145: extern void tcp_send_ack(u32, u32, struct sock *sk, struct tcphdr *th, u32); ! 146: extern void tcp_send_reset(unsigned long saddr, unsigned long daddr, struct tcphdr *th, ! 147: struct proto *prot, struct options *opt, struct device *dev, int tos, int ttl); ! 148: ! 149: extern void tcp_enqueue_partial(struct sk_buff *, struct sock *); ! 150: extern struct sk_buff * tcp_dequeue_partial(struct sock *); ! 151: ! 152: /* tcp_input.c */ ! 153: extern void tcp_cache_zap(void); ! 154: ! 155: /* tcp_timer.c */ ! 156: #define tcp_reset_msl_timer(x,y,z) reset_timer(x,y,z) ! 157: extern void tcp_reset_xmit_timer(struct sock *, int, unsigned long); ! 158: extern void tcp_retransmit_timer(unsigned long); ! 159: ! 160: /* ! 161: * Default sequence number picking algorithm. ! 162: * As close as possible to RFC 793, which ! 163: * suggests using a 250kHz clock. ! 164: * Further reading shows this assumes 2MB/s networks. ! 165: * For 10MB/s ethernet, a 1MHz clock is appropriate. ! 166: * That's funny, Linux has one built in! Use it! ! 167: */ ! 168: ! 169: static inline u32 tcp_init_seq(void) ! 170: { ! 171: struct timeval tv; ! 172: do_gettimeofday(&tv); ! 173: return tv.tv_usec+tv.tv_sec*1000000; ! 174: } ! 175: ! 176: /* ! 177: * This function returns the amount that we can raise the ! 178: * usable window based on the following constraints ! 179: * ! 180: * 1. The window can never be shrunk once it is offered (RFC 793) ! 181: * 2. We limit memory per socket ! 182: */ ! 183: ! 184: static __inline__ unsigned short tcp_raise_window(struct sock *sk) ! 185: { ! 186: long free_space = sock_rspace(sk); ! 187: long window; ! 188: ! 189: if (free_space > 1024) ! 190: free_space &= ~0x3FF; /* make free space a multiple of 1024 */ ! 191: ! 192: if(sk->window_clamp) ! 193: free_space = min(sk->window_clamp, free_space); ! 194: ! 195: /* ! 196: * compute the actual window i.e. ! 197: * old_window - received_bytes_on_that_win ! 198: */ ! 199: ! 200: window = sk->window - (sk->acked_seq - sk->lastwin_seq); ! 201: ! 202: if (sk->mss == 0) ! 203: sk->mss = sk->mtu; ! 204: ! 205: if ( window < 0 ) { ! 206: window = 0; ! 207: printk(KERN_DEBUG "TRW: win < 0 w=%d 1=%u 2=%u\n", ! 208: sk->window, sk->acked_seq, sk->lastwin_seq); ! 209: } ! 210: ! 211: if ( (free_space - window) >= min(sk->mss, MAX_WINDOW/2) ) ! 212: return ((free_space - window) / sk->mss) * sk->mss; ! 213: ! 214: return 0; ! 215: } ! 216: ! 217: static __inline__ unsigned short tcp_select_window(struct sock *sk) ! 218: { ! 219: long free_space = sock_rspace(sk); ! 220: long window; ! 221: ! 222: if (free_space > 1024) ! 223: free_space &= ~0x3FF; /* make free space a multiple of 1024 */ ! 224: ! 225: if (sk->window_clamp) ! 226: free_space = min(sk->window_clamp, free_space); ! 227: ! 228: /* ! 229: * compute the actual window i.e. ! 230: * old_window - received_bytes_on_that_win ! 231: */ ! 232: ! 233: if (sk->mss == 0) ! 234: sk->mss = sk->mtu; ! 235: ! 236: window = sk->window - (sk->acked_seq - sk->lastwin_seq); ! 237: ! 238: if ( window < 0 ) { ! 239: window = 0; ! 240: printk(KERN_DEBUG "TSW: win < 0 w=%d 1=%u 2=%u\n", ! 241: sk->window, sk->acked_seq, sk->lastwin_seq); ! 242: } ! 243: ! 244: /* ! 245: * RFC 1122: ! 246: * "the suggested [SWS] avoidance algoritm for the receiver is to keep ! 247: * RECV.NEXT + RCV.WIN fixed until: ! 248: * RCV.BUFF - RCV.USER - RCV.WINDOW >= min(1/2 RCV.BUFF, MSS)" ! 249: * ! 250: * i.e. don't raise the right edge of the window until you can't raise ! 251: * it MSS bytes ! 252: */ ! 253: ! 254: if ( (free_space - window) >= min(sk->mss, MAX_WINDOW/2) ) ! 255: window += ((free_space - window) / sk->mss) * sk->mss; ! 256: ! 257: sk->window = window; ! 258: sk->lastwin_seq = sk->acked_seq; ! 259: ! 260: return sk->window; ! 261: } ! 262: ! 263: /* ! 264: * List all states of a TCP socket that can be viewed as a "connected" ! 265: * state. This now includes TCP_SYN_RECV, although I am not yet fully ! 266: * convinced that this is the solution for the 'getpeername(2)' ! 267: * problem. Thanks to Stephen A. Wood <[email protected]> -FvK ! 268: */ ! 269: ! 270: extern __inline const int tcp_connected(const int state) ! 271: { ! 272: return(state == TCP_ESTABLISHED || state == TCP_CLOSE_WAIT || ! 273: state == TCP_FIN_WAIT1 || state == TCP_FIN_WAIT2 || ! 274: state == TCP_SYN_RECV); ! 275: } ! 276: ! 277: /* ! 278: * Calculate(/check) TCP checksum ! 279: */ ! 280: static __inline__ u16 tcp_check(struct tcphdr *th, int len, ! 281: unsigned long saddr, unsigned long daddr, unsigned long base) ! 282: { ! 283: return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base); ! 284: } ! 285: ! 286: #undef STATE_TRACE ! 287: ! 288: #ifdef STATE_TRACE ! 289: static char *statename[]={ ! 290: "Unused","Established","Syn Sent","Syn Recv", ! 291: "Fin Wait 1","Fin Wait 2","Time Wait", "Close", ! 292: "Close Wait","Last ACK","Listen","Closing" ! 293: }; ! 294: #endif ! 295: ! 296: static __inline__ void tcp_set_state(struct sock *sk, int state) ! 297: { ! 298: int oldstate = sk->state; ! 299: ! 300: sk->state = state; ! 301: ! 302: #ifdef STATE_TRACE ! 303: if(sk->debug) ! 304: printk("TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]); ! 305: #endif ! 306: ! 307: switch (state) { ! 308: case TCP_ESTABLISHED: ! 309: if (oldstate != TCP_ESTABLISHED) { ! 310: tcp_statistics.TcpCurrEstab++; ! 311: /* This is a hack but it doesn't occur often and it's going to ! 312: be a real to fix nicely */ ! 313: if (oldstate == TCP_SYN_RECV) ! 314: wake_up_interruptible(&master_select_wakeup); ! 315: } ! 316: break; ! 317: ! 318: case TCP_CLOSE: ! 319: tcp_cache_zap(); ! 320: /* Should be about 2 rtt's */ ! 321: reset_timer(sk, TIME_DONE, min(sk->rtt * 2, TCP_DONE_TIME)); ! 322: /* fall through */ ! 323: default: ! 324: if (oldstate==TCP_ESTABLISHED) ! 325: tcp_statistics.TcpCurrEstab--; ! 326: } ! 327: } ! 328: ! 329: #endif /* _TCP_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.