1*25202Skarels #define RCSTCPHDR "$Header: tcp.h,v 1.19 85/07/31 09:33:34 walsh Exp $" 2*25202Skarels 3*25202Skarels struct th { /* tcp header (fits over ip header) */ 4*25202Skarels struct th *t_next; /* -> next tcp on rcv chain */ 5*25202Skarels struct th *t_prev; /* -> prev tcp on rcv chain */ 6*25202Skarels u_char t_x1; /* (unused) */ 7*25202Skarels u_char t_pr; /* protocol */ 8*25202Skarels u_short t_len; /* seg length */ 9*25202Skarels struct in_addr t_s; /* source internet address */ 10*25202Skarels struct in_addr t_d; /* destination internet address */ 11*25202Skarels u_short t_src; /* source port */ 12*25202Skarels u_short t_dst; /* destination port */ 13*25202Skarels sequence t_seq; /* sequence number */ 14*25202Skarels sequence t_ackno; /* acknowledgement number */ 15*25202Skarels #define t_end(x) (x->t_seq + x->t_len - 1) 16*25202Skarels u_char 17*25202Skarels t_x2:4, /* (unused) */ 18*25202Skarels t_off:4; /* data offset */ 19*25202Skarels #define TCP_OFFSHIFT 2 20*25202Skarels u_char t_flags; 21*25202Skarels #define T_FIN 0x01 /* fin flag */ 22*25202Skarels #define T_SYN 0x02 /* syn flag */ 23*25202Skarels #define T_RST 0x04 /* reset flag */ 24*25202Skarels #define T_PUSH 0x08 /* push flag */ 25*25202Skarels #define T_ACK 0x10 /* ack flag */ 26*25202Skarels #define T_URG 0x20 /* urgent flag */ 27*25202Skarels u_short t_win; /* window */ 28*25202Skarels u_short t_sum; /* checksum */ 29*25202Skarels u_short t_urp; /* urgent pointer */ 30*25202Skarels }; 31*25202Skarels 32*25202Skarels #define TCP_END_OPT 0 /* end of option list */ 33*25202Skarels #define TCP_NOP_OPT 1 /* nop option */ 34*25202Skarels #define TCP_MAXSEG_OPT 2 /* maximum segment size option */ 35*25202Skarels #define TCP_MAXSEG_OPTLEN 4 /* max seg option length */ 36*25202Skarels #define TCP_MAXSEG_OPTHDR ((TCP_MAXSEG_OPT<<8)|TCP_MAXSEG_OPTLEN) 37*25202Skarels 38*25202Skarels typedef u_char tcptimerval; /* in 0.5 second units */ 39*25202Skarels #define MAX_TCPTIMERVAL 255 40*25202Skarels 41*25202Skarels struct tcpcb { /* tcp control block */ 42*25202Skarels 43*25202Skarels /* various pointers */ 44*25202Skarels 45*25202Skarels /* where store data until gets to socket */ 46*25202Skarels struct th *t_rcv_next; /* -> first el on rcv queue */ 47*25202Skarels struct th *t_rcv_prev; /* -> last el on rcv queue */ 48*25202Skarels int t_rcv_len; /* length of rcv queue */ 49*25202Skarels 50*25202Skarels struct inpcb *t_in_pcb; /* -> in_pcb */ 51*25202Skarels struct mbuf *t_rcv_unack; /* -> unacked message queue */ 52*25202Skarels /* ### how about a tail pointer */ 53*25202Skarels 54*25202Skarels /* sequence number variables */ 55*25202Skarels 56*25202Skarels sequence iss; /* initial send seq # */ 57*25202Skarels sequence irs; /* initial recv seq # */ 58*25202Skarels sequence rcv_urp; /* rcv urgent pointer */ 59*25202Skarels sequence rcv_nxt; /* next contiguous seq # to rcv */ 60*25202Skarels sequence seq_fin; /* seq # of FIN sent */ 61*25202Skarels sequence snd_end; /* send eol pointer. end of PUSH */ 62*25202Skarels sequence snd_urp; /* snd urgent pointer. end of URG */ 63*25202Skarels sequence snd_lst; /* seq # of last datum to send */ 64*25202Skarels sequence snd_nxt; /* seq # of next datum to send */ 65*25202Skarels sequence snd_una; /* seq # of first unacked datum */ 66*25202Skarels sequence snd_wl; /* seq # of last sent window */ 67*25202Skarels sequence snd_hi; /* highest seq # we sent */ 68*25202Skarels sequence t_xmt_val; /* seq # measuring round trip time of */ 69*25202Skarels 70*25202Skarels /* various flags and state variables 71*25202Skarels * At one time booleans were a bitfield, but since are using mbufs, 72*25202Skarels * have space and is quicker to test/set byte than bit. 73*25202Skarels */ 74*25202Skarels 75*25202Skarels char ack_due; /* must we send ACK */ 76*25202Skarels char cancelled; /* retransmit timer cancelled */ 77*25202Skarels char dropped_txt; /* dropped incoming data */ 78*25202Skarels char fin_rcvd; /* FIN received */ 79*25202Skarels char force_one; /* force sending of one byte */ 80*25202Skarels char new_window; /* received new window size */ 81*25202Skarels char rexmt; /* this msg is a retransmission */ 82*25202Skarels char snd_fin; /* FIN should be sent */ 83*25202Skarels char snd_rst; /* RST should be sent */ 84*25202Skarels char snd_urg; /* urgent data to send */ 85*25202Skarels char syn_acked; /* SYN has been ACKed */ 86*25202Skarels char syn_rcvd; /* SYN has been received */ 87*25202Skarels char usr_closed; /* user has closed connection */ 88*25202Skarels char waited_2_ml; /* wait time for FIN ACK is up */ 89*25202Skarels char usr_abort; /* user has closed and does not expect 90*25202Skarels to receive any more data */ 91*25202Skarels char sent_zero; /* sent zero window */ 92*25202Skarels char force_ack; /* force sending of ack */ 93*25202Skarels char t_push; 94*25202Skarels char t_urg; 95*25202Skarels char t_noactprobe; /* see tcp_newtcpcb() */ 96*25202Skarels char t_noactsig; 97*25202Skarels /* end booleans */ 98*25202Skarels 99*25202Skarels u_short snd_wnd; /* window he advertised */ 100*25202Skarels short t_maxseg; /* max seg size peer can handle */ 101*25202Skarels u_short t_maxfrag; /* max IP frag size received */ 102*25202Skarels u_short t_olddata; /* useless rexmts received */ 103*25202Skarels u_short t_preproc; /* #segs out of window rcvd */ 104*25202Skarels u_short t_rxtct; /* # of retransmissions */ 105*25202Skarels u_char t_state; /* state of this connection */ 106*25202Skarels 107*25202Skarels tcptimerval t_srtt; /* smoothed round trip time */ 108*25202Skarels /* 109*25202Skarels * Not used to limit t_srtt, but to estimate limits/values for the 110*25202Skarels * timers given the rxmitime = 1.5 srtt, and rxmitime doubles for 111*25202Skarels * each retransmission. 112*25202Skarels * This is the srtt on our slowest network connection. 113*25202Skarels */ 114*25202Skarels #define TCP_tvMAXSRTT 20 /* 10 seconds */ 115*25202Skarels 116*25202Skarels tcptimerval t_rxmitime; /* current rexmt time */ 117*25202Skarels /* 118*25202Skarels * Allow some slop for the maximum in case the network experiences 119*25202Skarels * a temporary peak loading 120*25202Skarels */ 121*25202Skarels #define TCP_tvRXMIN 4 122*25202Skarels #define TCP_tvRXMAX ((3 * TCP_tvMAXSRTT) / 2) 123*25202Skarels 124*25202Skarels tcptimerval t_itimeo; /* init timeout value */ 125*25202Skarels /* by default, try 3+ syns to get to the other side */ 126*25202Skarels #define TCP_tvINIT (TCP_tvMAXSRTT + 3 * TCP_tvRXMAX) 127*25202Skarels 128*25202Skarels tcptimerval t_rttltimeo; /* rxmit took too long timeout value */ 129*25202Skarels /* by default, try 4+ retransmissions before warn user */ 130*25202Skarels #define TCP_tvRTTL (TCP_tvMAXSRTT + 4 * TCP_tvRXMAX) 131*25202Skarels 132*25202Skarels tcptimerval t_noact; /* no activity timeout value (mins.) */ 133*25202Skarels #define TCP_tvNOACT 10 /* internal no activity timeout (min) */ 134*25202Skarels 135*25202Skarels tcptimerval t_timers[NTIMERS];/* the timers */ 136*25202Skarels #define TCP_tvMINPERSIST 10 137*25202Skarels #define TCP_tvMAXPERSIST 90 138*25202Skarels #define TCP_tv2ML 40 /* 2*maximum packet lifetime */ 139*25202Skarels 140*25202Skarels struct mbuf *oob_data; /* for 4.2 implementation of urgent */ 141*25202Skarels sequence rcv_urpend; /* (out-of-band) data */ 142*25202Skarels 143*25202Skarels short sws_qff; /* silly window syndrome and icmp 144*25202Skarels * source quench fudge factor */ 145*25202Skarels 146*25202Skarels short ack_skipped; 147*25202Skarels sequence lastack; /* with force_ack, for TDELACK */ 148*25202Skarels u_short rcv_wnd; /* window we advertised */ 149*25202Skarels 150*25202Skarels struct th *t_template; /* for send_pkt() */ 151*25202Skarels }; 152*25202Skarels 153*25202Skarels #if TCP_tvRXMAX > MAX_TCPTIMERVAL 154*25202Skarels whoops 155*25202Skarels #endif 156*25202Skarels #if TCP_tvINIT > MAX_TCPTIMERVAL 157*25202Skarels whoops 158*25202Skarels #endif 159*25202Skarels #if TCP_tvRTTL > MAX_TCPTIMERVAL 160*25202Skarels whoops 161*25202Skarels #endif 162*25202Skarels 163*25202Skarels struct t_debug { /* tcp debugging record */ 164*25202Skarels u_long t_iptime; 165*25202Skarels char t_oldstate; /* old state */ 166*25202Skarels char t_input; /* input */ 167*25202Skarels char t_timer; /* timer id */ 168*25202Skarels char t_newstate; /* new state */ 169*25202Skarels 170*25202Skarels struct tcpcb t_tcb; /* -> tcb */ 171*25202Skarels struct th t_hdr; /* valid iff input is INRECV */ 172*25202Skarels }; 173*25202Skarels 174*25202Skarels #define DB_PER_CHUNK(x) (((x)/sizeof(struct t_debug)) * sizeof(struct t_debug)) 175*25202Skarels #define TDBLEN DB_PER_CHUNK(MLEN) 176*25202Skarels #define TCDBLEN DB_PER_CHUNK(CLBYTES) 177*25202Skarels 178*25202Skarels /* 179*25202Skarels * tcp statistics 180*25202Skarels */ 181*25202Skarels 182*25202Skarels struct tcp_stat { 183*25202Skarels struct in_stat t_in; 184*25202Skarels #define t_total t_in.in_total 185*25202Skarels #define t_badsum t_in.in_badsum 186*25202Skarels #define t_tooshort t_in.in_tooshort 187*25202Skarels int t_badsegs; /* #bad tcp segments (to which we send RST) */ 188*25202Skarels int t_unack; /* #tcp segs placed on rcv_unack */ 189*25202Skarels int t_retransmit; /* #retransmissions we sent */ 190*25202Skarels int t_ackonly; /* #send_pkt just to send ack, no data */ 191*25202Skarels }; 192*25202Skarels 193*25202Skarels 194*25202Skarels /* size of TCP leader (bytes) */ 195*25202Skarels #define TCPSIZE (sizeof(struct th)-sizeof(struct ip)) 196*25202Skarels /* 197*25202Skarels * max size of TCP/IP leader. If start using options on tcp connections, 198*25202Skarels * increase TCPIPMAX accordingly. 199*25202Skarels */ 200*25202Skarels #define TCPIPMAX sizeof(struct th) 201*25202Skarels /* initial maximum segment size */ 202*25202Skarels #define TCPMAXSND (IPMAX - TCPIPMAX) 203*25202Skarels 204*25202Skarels /* get the tcpcb from the inpcb */ 205*25202Skarels #define inptotcpcb(inp) ((struct tcpcb *)((inp)->inp_ppcb)) 206*25202Skarels #define sototcpcb(so) (inptotcpcb((struct inpcb *)((so)->so_pcb))) 207*25202Skarels #define tcpcbtoso(tp) ((tp)->t_in_pcb->inp_socket) 208*25202Skarels 209*25202Skarels #define TCP_CTL 1 /* send/receive control call */ 210*25202Skarels #define TCP_DATA 0 /* send/receive data call */ 211*25202Skarels 212*25202Skarels #define T_LINGERTIME 120 /* two minutes of linger */ 213*25202Skarels 214*25202Skarels /* tcp machine predicates */ 215*25202Skarels 216*25202Skarels /* 217*25202Skarels * Is there unacked data on this TCP connection? 218*25202Skarels */ 219*25202Skarels #define is_unacked(t) (SEQ_LT((t)->snd_una, (t)->snd_hi)) 220*25202Skarels 221*25202Skarels /* ACK of local FIN */ 222*25202Skarels #define ack_fin(x, y) (SEQ_GT((x)->seq_fin, (x)->iss) && \ 223*25202Skarels SEQ_GT((y)->t_ackno, (x)->seq_fin)) 224*25202Skarels 225*25202Skarels /* receive buffer empty */ 226*25202Skarels #define rcv_empty(x) ((x)->usr_abort || \ 227*25202Skarels ((x)->t_in_pcb->inp_socket->so_rcv.sb_cc == 0 && \ 228*25202Skarels (x)->t_rcv_next == (struct th *)(x))) 229*25202Skarels 230*25202Skarels #define t_cancel(tp, timer) ((tp)->t_timers[timer] = 0) 231*25202Skarels 232*25202Skarels sequence firstempty(); 233*25202Skarels char *tcp_conn_used(); /* see note about return value */ 234*25202Skarels struct th *tcp_template(); 235*25202Skarels 236*25202Skarels /* 237*25202Skarels * If we have many incarnations of a connection in a time period, do not 238*25202Skarels * want the sequence number space of them to overlap and have packets for 239*25202Skarels * one be mistaken as from another. 240*25202Skarels * Assume max throughput of 1Mbit/sec == 125kbyte/sec for TCP 241*25202Skarels */ 242*25202Skarels #define ISSINCR ((125*1024) / PR_SLOWHZ) 243*25202Skarels 244*25202Skarels /* 245*25202Skarels * 512 is arbitrary. 246*25202Skarels */ 247*25202Skarels #define MAX_TCPOOB 512 248*25202Skarels 249*25202Skarels /* 250*25202Skarels * TCP port allocation 251*25202Skarels */ 252*25202Skarels 253*25202Skarels #define TCP_RESERVED 1023 /* <= for root only */ 254*25202Skarels #define TCP_USERRESERVED 5000 /* reserved for applications */ 255*25202Skarels #define TCP_MAXPORT 0xffff 256*25202Skarels 257*25202Skarels #ifdef KERNEL 258*25202Skarels extern struct tcp_stat tcpstat; 259*25202Skarels #endif 260