1*2c497c00Skarels /* 2*2c497c00Skarels $Log: rdp.h,v $ 3*2c497c00Skarels * Revision 2.13 85/06/18 14:33:36 walsh 4*2c497c00Skarels * added extern decl. 5*2c497c00Skarels * 6*2c497c00Skarels * Revision 2.12 84/11/29 12:50:15 walsh 7*2c497c00Skarels * changed references to currentrtt into references to srtt, a better 8*2c497c00Skarels * and less misleading mnemonic. 9*2c497c00Skarels * 10*2c497c00Skarels * Revision 2.11 84/11/15 09:55:15 walsh 11*2c497c00Skarels * redid how we deal with compiler padding in the RDP header structure. 12*2c497c00Skarels * 13*2c497c00Skarels * Revision 2.10 84/11/08 16:09:21 walsh 14*2c497c00Skarels * Added code to gather statistics on RDP traffic. This makes the RDPCB 15*2c497c00Skarels * too big unles you make mbufs 512 bytes large. RDP_CS should be turned off 16*2c497c00Skarels * unless you do. 17*2c497c00Skarels * 18*2c497c00Skarels * Revision 2.9 84/11/06 15:24:02 walsh 19*2c497c00Skarels * *** empty log message *** 20*2c497c00Skarels * 21*2c497c00Skarels * Revision 2.8 84/11/06 14:29:44 walsh 22*2c497c00Skarels * intorduced RDP_HLSHIFT 23*2c497c00Skarels * 24*2c497c00Skarels * Revision 2.7 84/11/05 12:42:04 walsh 25*2c497c00Skarels * Set things up so can debug RDP connections just like can debug TCP 26*2c497c00Skarels * connections. 27*2c497c00Skarels * 28*2c497c00Skarels * Revision 2.6 84/11/05 11:14:03 walsh 29*2c497c00Skarels * *** empty log message *** 30*2c497c00Skarels * 31*2c497c00Skarels * Revision 2.5 84/11/05 11:03:55 walsh 32*2c497c00Skarels * comment and adjust number for rdp_iss in a mathematically correct way 33*2c497c00Skarels * as a result of benchmarks (cf. operationally correct). 34*2c497c00Skarels * 35*2c497c00Skarels * Revision 2.4 84/11/02 18:21:13 walsh 36*2c497c00Skarels * Protocol specifiers want NULL message to have own sequence number in 37*2c497c00Skarels * case of slow (t>NULL msg timeout) packets. I don't see this as a problem, 38*2c497c00Skarels * and even if happened (dubious) would only delay discovery, but I 39*2c497c00Skarels * didn't win this one. Initially not designed for this, but fixes are 40*2c497c00Skarels * in almost neatly. 41*2c497c00Skarels * 42*2c497c00Skarels * Revision 2.3 84/11/02 15:26:42 walsh 43*2c497c00Skarels * Allow for RDP header fields not on natural boundries. (Protocol 44*2c497c00Skarels * specifiers say will be part of next version in 6-12 months). 45*2c497c00Skarels * Until then, there goes the speed... Yucho modifications. 46*2c497c00Skarels * 47*2c497c00Skarels * Revision 2.2 84/11/02 13:12:29 walsh 48*2c497c00Skarels * use rdp typedefs for packet header fields to reduce lint errors. 49*2c497c00Skarels * 50*2c497c00Skarels * Revision 2.1 84/11/02 10:10:49 walsh 51*2c497c00Skarels * Fixed to include RCS comments in checked out source. 52*2c497c00Skarels * 53*2c497c00Skarels 54*2c497c00Skarels * description: 55*2c497c00Skarels * Reliable Datagram Protocol definitions. 56*2c497c00Skarels * 57*2c497c00Skarels * revision 1.10 58*2c497c00Skarels * date: 84/07/25 09:45:36; author: walsh; state: Exp; lines added/del: 1/1 59*2c497c00Skarels * RDP finally has an official protocol number assigned by Postel. 60*2c497c00Skarels * 61*2c497c00Skarels * revision 1.9 62*2c497c00Skarels * date: 84/07/19 10:20:37; author: walsh; state: Exp; lines added/del: 1/31 63*2c497c00Skarels * Organized macros and classified their definitions in rdp_macros.h. 64*2c497c00Skarels * 65*2c497c00Skarels * revision 1.8 66*2c497c00Skarels * date: 84/07/18 18:49:39; author: walsh; state: Exp; lines added/del: 7/1 67*2c497c00Skarels * Added provision for sending of NULL messages. These are sent on an idle 68*2c497c00Skarels * connection to determine that the other side still exists. 69*2c497c00Skarels * 70*2c497c00Skarels * revision 1.7 71*2c497c00Skarels * date: 84/07/18 13:51:54; author: walsh; state: Exp; lines added/del: 1/0 72*2c497c00Skarels * constant RDP_MAXTIMERVAL to go with type rdptimerval. 73*2c497c00Skarels * 74*2c497c00Skarels * revision 1.6 75*2c497c00Skarels * date: 84/07/18 13:27:06; author: walsh; state: Exp; lines added/del: 11/4 76*2c497c00Skarels * Bouncing datagrams off goonhilly-echo eventually causes RTTL timeout. So, 77*2c497c00Skarels * have re-worked: 78*2c497c00Skarels * 1. rxtime = 1.5 srtt, not factor of 2 used before 79*2c497c00Skarels * 2. max rxtime now 20 sec, not 30 seconds 80*2c497c00Skarels * 3. provisions for user definition of RTTL period. 81*2c497c00Skarels * 82*2c497c00Skarels * revision 1.5 83*2c497c00Skarels * date: 84/07/12 13:44:12; author: walsh; state: Exp; lines added/del: 26/19 84*2c497c00Skarels * Rather than in-line stuffing of IP/RDP headers, at least half of which are 85*2c497c00Skarels * constant, copy headers in from a template of what the headers are like. The 86*2c497c00Skarels * bcopy() call is turned into a movc3 instruction on the VAX by a sed script 87*2c497c00Skarels * run over the assembler output of the C compiler. Marginal speed-up. 88*2c497c00Skarels * 89*2c497c00Skarels * revision 1.4 90*2c497c00Skarels * date: 84/07/10 14:42:34; author: walsh; state: Exp; lines added/del: 20/23 91*2c497c00Skarels * simplified check for if debugging on in RDP_ACTION, since rdpcb, inpcb, 92*2c497c00Skarels * and socket structure all last equally as long. 93*2c497c00Skarels * 94*2c497c00Skarels * revision 1.3 95*2c497c00Skarels * date: 84/07/09 14:23:00; author: walsh; state: Exp; lines added/del: 2/1 96*2c497c00Skarels * Added ACK-delay timer. 97*2c497c00Skarels * 98*2c497c00Skarels * revision 1.2 99*2c497c00Skarels * date: 84/07/06 09:46:45; author: walsh; state: Exp; lines added/del: 36/1 100*2c497c00Skarels * This version seems to run bug-free. 101*2c497c00Skarels * 102*2c497c00Skarels * revision 1.1 103*2c497c00Skarels * date: 84/06/26 14:16:27; author: walsh; state: Exp; 104*2c497c00Skarels * Initial revision 105*2c497c00Skarels * 106*2c497c00Skarels */ 107*2c497c00Skarels 108*2c497c00Skarels 109*2c497c00Skarels /* 110*2c497c00Skarels * Here's how I've tried to name things to keep them consistent. 111*2c497c00Skarels * For RDP_?..., the ? means: 112*2c497c00Skarels * 113*2c497c00Skarels * f flag (in packet header) 114*2c497c00Skarels * i input event 115*2c497c00Skarels * o option (in syn packet header) 116*2c497c00Skarels * p port number 117*2c497c00Skarels * s state (of connection in rdpcb) 118*2c497c00Skarels * t timer 119*2c497c00Skarels * tv timer value 120*2c497c00Skarels */ 121*2c497c00Skarels 122*2c497c00Skarels typedef char boolean; 123*2c497c00Skarels typedef u_char rdpstate; 124*2c497c00Skarels typedef u_long rdpsequence; /* sequence # or ack # */ 125*2c497c00Skarels typedef u_long rdpchecksum; 126*2c497c00Skarels typedef u_char rdptimerval; 127*2c497c00Skarels #define RDP_MAXTIMERVAL 255 128*2c497c00Skarels typedef u_char rdpportnum; 129*2c497c00Skarels 130*2c497c00Skarels typedef struct inpcb INPCB; /* belongs in in_pcb.h */ 131*2c497c00Skarels typedef struct mbuf MBUF; /* belongs in mbuf.h */ 132*2c497c00Skarels 133*2c497c00Skarels 134*2c497c00Skarels typedef struct rdphdr { 135*2c497c00Skarels char rh_ver:2, /* version of packet header */ 136*2c497c00Skarels rh_flags:6; 137*2c497c00Skarels u_char rh_hdrlen; /* in units of 2 bytes */ 138*2c497c00Skarels rdpportnum rh_sport; /* source port */ 139*2c497c00Skarels rdpportnum rh_dport; /* destination port */ 140*2c497c00Skarels u_short rh_dlen; /* amount of data following the header */ 141*2c497c00Skarels rdpsequence rh_seqno; 142*2c497c00Skarels rdpsequence rh_ackno; /* valid iff ACK set */ 143*2c497c00Skarels rdpchecksum rh_cksum; 144*2c497c00Skarels } RDPHDR; 145*2c497c00Skarels 146*2c497c00Skarels #define RDP_VERSION 1 /* rh_ver */ 147*2c497c00Skarels 148*2c497c00Skarels #define RDP_fNULL 0x02 /* rh_flags */ 149*2c497c00Skarels #define RDP_fRST 0x04 150*2c497c00Skarels #define RDP_fEACK 0x08 151*2c497c00Skarels #define RDP_fACK 0x10 152*2c497c00Skarels #define RDP_fSYN 0x20 153*2c497c00Skarels 154*2c497c00Skarels #define RDP_HLSHIFT 1 /* Header Length SHIFT */ 155*2c497c00Skarels #define hdrlen(x) ((x)->rh_hdrlen << RDP_HLSHIFT) 156*2c497c00Skarels 157*2c497c00Skarels /* 158*2c497c00Skarels * RDP port numbers 1-63 for servers, 64-255 assigned to clients 159*2c497c00Skarels */ 160*2c497c00Skarels 161*2c497c00Skarels #define RDP_pANY 0 162*2c497c00Skarels #define RDP_RESERVED 63 163*2c497c00Skarels #define RDP_USERRESERVED 63 164*2c497c00Skarels #define RDP_MAXPORT 255 165*2c497c00Skarels 166*2c497c00Skarels /* 167*2c497c00Skarels * Due to the compiler aligning header fields on natural boundries, 168*2c497c00Skarels * the rdp header is 18 bytes on the network, but sizeof(RDPHDR) = 20 169*2c497c00Skarels * So, skip sizeof and define macros to access fields after the gap. 170*2c497c00Skarels */ 171*2c497c00Skarels #define RDPHDRSZ 18 /* on the network */ 172*2c497c00Skarels 173*2c497c00Skarels #define RDP_SEQNO(pkt) (* ((u_long *) (&((char *) (pkt))[6]))) 174*2c497c00Skarels #define RDP_ACKNO(pkt) (* ((u_long *) (&((char *) (pkt))[10]))) 175*2c497c00Skarels #define RDP_CKSUM(pkt) (* ((u_long *) (&((char *) (pkt))[14]))) 176*2c497c00Skarels #define RDP_OPT(pkt, type) ((type) (&((char *) (pkt))[RDPHDRSZ])) 177*2c497c00Skarels 178*2c497c00Skarels /* 179*2c497c00Skarels * In a SYN packet, this will immediately follow the rdphdr 180*2c497c00Skarels */ 181*2c497c00Skarels typedef struct synoptions { 182*2c497c00Skarels short rh_nbuf; /* # dgrams he can buffer */ 183*2c497c00Skarels u_short rh_maxlen; /* max length of a dgram */ 184*2c497c00Skarels short rh_options; 185*2c497c00Skarels #define RDP_oSEQUENTIAL 1 186*2c497c00Skarels } SYNOPTIONS; 187*2c497c00Skarels 188*2c497c00Skarels /* 189*2c497c00Skarels * For an established connection, a variable length array of these 190*2c497c00Skarels * may immediately follow the rdphdr 191*2c497c00Skarels */ 192*2c497c00Skarels typedef struct eackoptions { 193*2c497c00Skarels rdpsequence rh_eackno; 194*2c497c00Skarels } EACKOPTIONS; 195*2c497c00Skarels 196*2c497c00Skarels 197*2c497c00Skarels 198*2c497c00Skarels /* 199*2c497c00Skarels * RDP connection states 200*2c497c00Skarels */ 201*2c497c00Skarels #define RDP_sSAME 0 /* no state transition for this input to fsm */ 202*2c497c00Skarels #define RDP_sUNOPENED 1 /* after socket(2), before listen or connect */ 203*2c497c00Skarels #define RDP_sLISTEN 2 /* after listen(2) */ 204*2c497c00Skarels #define RDP_sSYNSENT 3 /* after connect(2) */ 205*2c497c00Skarels #define RDP_sLSYNRCVD 4 /* child socket after SYN gets to LISTENer */ 206*2c497c00Skarels #define RDP_sSYNRCVD 5 /* after SYN gets to SYNSENT */ 207*2c497c00Skarels #define RDP_sESTAB 6 /* after get both SYN and ACK */ 208*2c497c00Skarels #define RDP_sCLOSEWAIT 7 /* after send or receive RST */ 209*2c497c00Skarels #define RDP_sCLOSED 8 /* after CLOSEWAIT timeout */ 210*2c497c00Skarels 211*2c497c00Skarels #define RDP_NSTATES 9 212*2c497c00Skarels 213*2c497c00Skarels /* 214*2c497c00Skarels * Inputs that (possibly) cause state transition 215*2c497c00Skarels */ 216*2c497c00Skarels #define RDP_iCONNECT 0 /* user connect(2) request == active open */ 217*2c497c00Skarels #define RDP_iLISTEN 1 /* user listen(2) request == passive open */ 218*2c497c00Skarels #define RDP_iNETR 2 /* network reception of packet */ 219*2c497c00Skarels #define RDP_iUCLOSE 3 /* user close(2) request */ 220*2c497c00Skarels #define RDP_iTIMER 4 /* a timer went off */ 221*2c497c00Skarels #define RDP_iRCV 5 /* user has picked up a packet */ 222*2c497c00Skarels #define RDP_iSEND 6 /* user send request */ 223*2c497c00Skarels #define RDP_NINPUTS 7 224*2c497c00Skarels 225*2c497c00Skarels 226*2c497c00Skarels 227*2c497c00Skarels /* 228*2c497c00Skarels * rq_maxqlen = MIN(desired, RDP_MAXDGRAMS) 229*2c497c00Skarels */ 230*2c497c00Skarels #define RDP_MAXDGRAMS 40 231*2c497c00Skarels 232*2c497c00Skarels /* 233*2c497c00Skarels * In rq_msgs, pointers follow: 234*2c497c00Skarels * sendq:: NULL x PRU_SEND -> 235*2c497c00Skarels * ptr x (E)ACK -> 236*2c497c00Skarels * RDP_DELIVERED x move front -> NULL 237*2c497c00Skarels * 238*2c497c00Skarels * rcvq:: NULL x net reception -> 239*2c497c00Skarels * ptr x pass to user -> 240*2c497c00Skarels * RDP_DELIVERED x (PRU_RECV + move front) -> NULL 241*2c497c00Skarels * 242*2c497c00Skarels * on last transition, we also (E)ACK the packet. 243*2c497c00Skarels */ 244*2c497c00Skarels #define RDP_DELIVERED ((struct mbuf *) (-1)) 245*2c497c00Skarels #define RDP_NULLMSG ((struct mbuf *) (-2)) 246*2c497c00Skarels 247*2c497c00Skarels /* 248*2c497c00Skarels * rq_msgs points into an mbuf that we use for an array of pointers to 249*2c497c00Skarels * mbuf chains. On input, each mbuf chain holds an RDP packet (header and 250*2c497c00Skarels * data). On output, each mbuf chain holds the data portion of the packet 251*2c497c00Skarels * in case it is needed for re-transmission. 252*2c497c00Skarels * +---------------+ 253*2c497c00Skarels * rq_msgs --> | | 254*2c497c00Skarels * | o-----------|---> mbuf chain (== packet or data) 255*2c497c00Skarels * | RDP_DELIVERED | 256*2c497c00Skarels * | RDP_NULLMSG | 257*2c497c00Skarels * | | 258*2c497c00Skarels * +---------------+ 259*2c497c00Skarels * array in mbuf 260*2c497c00Skarels */ 261*2c497c00Skarels typedef struct rdp_msgq { 262*2c497c00Skarels int rq_maxqlen; /* 1...RDP_MAXDGRAMS inclusive */ 263*2c497c00Skarels int rq_maxiplen; /* max IP length of dgram can put on q*/ 264*2c497c00Skarels int rq_front; /* 0...(rq_maxqlen-1) inclusive */ 265*2c497c00Skarels rdpsequence rq_baseseq; /* RDP seq # of rq_msgs[rq_front] */ 266*2c497c00Skarels MBUF **rq_msgs; /* -> into mbuf holding array of ptrs*/ 267*2c497c00Skarels } RDP_MSGQ; 268*2c497c00Skarels 269*2c497c00Skarels 270*2c497c00Skarels typedef struct rdpcb { 271*2c497c00Skarels struct inpcb *r_inpcb; 272*2c497c00Skarels 273*2c497c00Skarels rdpstate r_state; /* state of connection */ 274*2c497c00Skarels rdpsequence r_iss; /* initial sequence # sent (in SYN) */ 275*2c497c00Skarels rdpsequence r_irs; /* initial sequence # rcvd (in SYN) */ 276*2c497c00Skarels rdpsequence r_sndnxt; /* seq # for next datagram we send */ 277*2c497c00Skarels 278*2c497c00Skarels struct rdp_msgq r_sendq, r_rcvq; 279*2c497c00Skarels 280*2c497c00Skarels #define r_hisnbuf r_sendq.rq_maxqlen /* # RDP messages he can buffer */ 281*2c497c00Skarels #define r_hismaxlen r_sendq.rq_maxiplen /* biggest IP datagram he'll take */ 282*2c497c00Skarels #define r_snduna r_sendq.rq_baseseq /* seq # of oldest unacked dgram sent */ 283*2c497c00Skarels #define r_ournbuf r_rcvq.rq_maxqlen /* # RDP messages we can buffer */ 284*2c497c00Skarels #define r_ourmaxlen r_rcvq.rq_maxiplen /* biggest RDP data length we'll take */ 285*2c497c00Skarels 286*2c497c00Skarels boolean r_synrcvd; /* have we rcvd his SYN? */ 287*2c497c00Skarels boolean r_synacked; /* has he ACKed our SYN? */ 288*2c497c00Skarels boolean r_usrclosed; /* has user process close(2)ed yet? */ 289*2c497c00Skarels boolean r_sendrst; /* set reset in outgoing packet */ 290*2c497c00Skarels boolean r_sendnull; /* set null in outgoing packet */ 291*2c497c00Skarels boolean r_sequential; /* sequential delivery? */ 292*2c497c00Skarels boolean r_rttiming; /* are we measuring rtt? */ 293*2c497c00Skarels 294*2c497c00Skarels rdptimerval r_closewait; /* # 0.5 sec units before destroy *cb */ 295*2c497c00Skarels #define RDP_tvCLOSEWAIT 120 /* default idea of CLOSEWAIT timer */ 296*2c497c00Skarels rdptimerval r_rttl; /* error if dgram unacked in this time*/ 297*2c497c00Skarels #define RDP_tvRTTL 120 /* default idea of RTTL timer */ 298*2c497c00Skarels rdptimerval r_tvnull; /* for testing connection existence */ 299*2c497c00Skarels #define RDP_tvNULL 240 /* default idea time to 1st NULL */ 300*2c497c00Skarels char r_nullsent; /* # successive null messages sent */ 301*2c497c00Skarels #define RDP_MAXNULL 5 302*2c497c00Skarels 303*2c497c00Skarels /* 304*2c497c00Skarels * For now, each retransmission of a packet will take the same 305*2c497c00Skarels * amount of time. 306*2c497c00Skarels */ 307*2c497c00Skarels rdptimerval r_rxmitime; /* current idea of re-xmission time */ 308*2c497c00Skarels #define RDP_tvRXMAX 40 /* max value of re-xmit timer (20 sec)*/ 309*2c497c00Skarels #define RDP_tvRXMIN 4 /* min value of re-xmit timer ( 2 sec)*/ 310*2c497c00Skarels /* 311*2c497c00Skarels * (3 * (RDP_tvRXMIN = 4)) / 2 = 6 312*2c497c00Skarels * So, allows AT LEAST one second of variance from srtt until 313*2c497c00Skarels * hits RDP_tvRXMAX ceiling. 314*2c497c00Skarels */ 315*2c497c00Skarels #define update_rxmitime(r) \ 316*2c497c00Skarels (r)->r_rxmitime = MAX(RDP_tvRXMIN, \ 317*2c497c00Skarels MIN(RDP_tvRXMAX, (3 * (r)->r_srtt) / 2)); 318*2c497c00Skarels 319*2c497c00Skarels /* 320*2c497c00Skarels * if we're measuring the round trip time, (r_rttiming == TRUE), 321*2c497c00Skarels * then r_rtt counts time til get ack of dgram # r_rttimed. 322*2c497c00Skarels * r_rtt starts at 0 when send packet # r_rttimed, and is incremented 323*2c497c00Skarels * each 0.5 second. r_srtt is updated when r_rttimed is acked. 324*2c497c00Skarels * At that time, r_rxmitime should also be updated. srtt represents 325*2c497c00Skarels * a weighted average of the recent round trip times. 326*2c497c00Skarels */ 327*2c497c00Skarels rdpsequence r_rttimed; /* seq # of dgram finding rtt for */ 328*2c497c00Skarels rdptimerval r_rtt; /* round trip time (in 0.5 sec units)*/ 329*2c497c00Skarels rdptimerval r_srtt; /* smoothed round trip time */ 330*2c497c00Skarels #define ALPHA 4 331*2c497c00Skarels #define BETA 1 332*2c497c00Skarels #ifdef RDP_CS 333*2c497c00Skarels #define update_rttestimate(r) \ 334*2c497c00Skarels { \ 335*2c497c00Skarels (r)->r_srtt = (ALPHA*(r)->r_srtt + BETA*(r)->r_rtt) / (ALPHA+BETA) \ 336*2c497c00Skarels (r)->r_nrtt ++; \ 337*2c497c00Skarels (r)->r_totalrtt += (r)->r_rtt; \ 338*2c497c00Skarels if ((r)->r_nrtt == 1) \ 339*2c497c00Skarels (r)->r_minrtt = (r)->r_maxrtt = (r)->r_rtt; \ 340*2c497c00Skarels else if ((r)->r_rtt < (r)->r_minrtt) \ 341*2c497c00Skarels (r)->r_minrtt = (r)->r_rtt; \ 342*2c497c00Skarels else if ((r)->r_rtt > (r)->r_maxrtt) \ 343*2c497c00Skarels (r)->r_maxrtt = (r)->r_rtt; \ 344*2c497c00Skarels } 345*2c497c00Skarels #else 346*2c497c00Skarels #define update_rttestimate(r) \ 347*2c497c00Skarels (r)->r_srtt = (ALPHA*(r)->r_srtt + BETA*(r)->r_rtt) / (ALPHA+BETA) 348*2c497c00Skarels #endif 349*2c497c00Skarels 350*2c497c00Skarels /* 351*2c497c00Skarels * if we have at least one packet being timed for re-transmission, 352*2c497c00Skarels * then we have a "retransmit took too long" timer also set. One such 353*2c497c00Skarels * timer suffices. This timer is associated with rxtimers[rttlindex] 354*2c497c00Skarels * and r_sendq.rq_msgs[rttlindex] 355*2c497c00Skarels */ 356*2c497c00Skarels int r_rttlindex; 357*2c497c00Skarels 358*2c497c00Skarels #define RDP_tCLOSEWAIT 0 359*2c497c00Skarels #define RDP_tRTTL 1 /* retransmit took too long (not in spec) */ 360*2c497c00Skarels #define RDP_tRXMIT 2 /* if set, check rxtimers */ 361*2c497c00Skarels #define RDP_tACKDELAY 3 362*2c497c00Skarels #define RDP_tNULL 4 363*2c497c00Skarels #define RDP_NTIMERS 5 364*2c497c00Skarels rdptimerval r_timers[RDP_NTIMERS]; 365*2c497c00Skarels 366*2c497c00Skarels /* 367*2c497c00Skarels * The re-transmission timer array is parallel to r_sendq.rq_msgs 368*2c497c00Skarels */ 369*2c497c00Skarels rdptimerval r_rxtimers[RDP_MAXDGRAMS]; /* send retransmit timers */ 370*2c497c00Skarels #define RDP_tvRXCHECK 1 /* check per-pkt rxmit timers every 0.5 sec */ 371*2c497c00Skarels 372*2c497c00Skarels /* 373*2c497c00Skarels * and for a (minor) speedup, just byte copy the constant header fields 374*2c497c00Skarels */ 375*2c497c00Skarels #define RDP_TEMPLSIZE (sizeof(struct ip) + RDPHDRSZ) 376*2c497c00Skarels char r_template[RDP_TEMPLSIZE]; 377*2c497c00Skarels 378*2c497c00Skarels #ifdef RDP_CS 379*2c497c00Skarels rdptimerval r_minrtt; /* minimum rtt observed */ 380*2c497c00Skarels rdptimerval r_maxrtt; /* maximum rtt observed */ 381*2c497c00Skarels int r_totalrtt; /* total of all rtt packets */ 382*2c497c00Skarels int r_nrtt; /* # rtt packets measured */ 383*2c497c00Skarels 384*2c497c00Skarels u_long r_entered[RDP_NSTATES]; /* .001 sec */ 385*2c497c00Skarels 386*2c497c00Skarels struct { 387*2c497c00Skarels int r_total; 388*2c497c00Skarels int r_nullpkts; 389*2c497c00Skarels int r_synpkts; 390*2c497c00Skarels int r_rstpkts; 391*2c497c00Skarels int r_retrans; 392*2c497c00Skarels int r_nbytes; /* to/from user */ 393*2c497c00Skarels } r_sent, r_rcvd; 394*2c497c00Skarels #endif 395*2c497c00Skarels } RDPCB; 396*2c497c00Skarels 397*2c497c00Skarels #define rdpcbtoso(r) ((r)->r_inpcb->inp_socket) 398*2c497c00Skarels 399*2c497c00Skarels /* 400*2c497c00Skarels * RDP desires control over the IP length. We really only have good 401*2c497c00Skarels * control on the RDP data length in the UNIX socket code. Use the following 402*2c497c00Skarels * as the difference between the two. 403*2c497c00Skarels * 404*2c497c00Skarels * Allow how much space for eacks? 405*2c497c00Skarels * (Don't care on input. Can drop eack options on output.) 406*2c497c00Skarels */ 407*2c497c00Skarels #define HDRSLOP (RDPHDRSZ + sizeof(struct ip)) 408*2c497c00Skarels 409*2c497c00Skarels /* 410*2c497c00Skarels * Active opens (connect) and children of listener can time out via RDP_tRTTL. 411*2c497c00Skarels * Is a timeout for passive opens (LISTEN state) desireable? Prob not 412*2c497c00Skarels * since user can always use alarm(2) system call. 413*2c497c00Skarels */ 414*2c497c00Skarels 415*2c497c00Skarels 416*2c497c00Skarels 417*2c497c00Skarels typedef struct r_debug { 418*2c497c00Skarels u_long rd_iptime; /* 0.001 second units */ 419*2c497c00Skarels int rd_input; 420*2c497c00Skarels rdpstate rd_newstate; 421*2c497c00Skarels RDPCB rd_rdpcb; 422*2c497c00Skarels 423*2c497c00Skarels int rd_timer; /* iff input == RDP_iTIMER */ 424*2c497c00Skarels struct ip rd_iphdr; /* iff input == RDP_iNETR */ 425*2c497c00Skarels RDPHDR rd_rdphdr; /* iff input == RDP_iNETR */ 426*2c497c00Skarels } R_DEBUG; 427*2c497c00Skarels 428*2c497c00Skarels #define RCDBLEN ((CLBYTES/sizeof(R_DEBUG)) * sizeof(R_DEBUG)) 429*2c497c00Skarels #define RDBLEN ((MLEN /sizeof(R_DEBUG)) * sizeof(R_DEBUG)) 430*2c497c00Skarels 431*2c497c00Skarels #define inptordpcb(i) ((RDPCB *) ((i)->inp_ppcb)) 432*2c497c00Skarels 433*2c497c00Skarels struct rdp_stat { 434*2c497c00Skarels struct in_stat r_in; 435*2c497c00Skarels #define r_total r_in.in_total 436*2c497c00Skarels #define r_badsum r_in.in_badsum 437*2c497c00Skarels #define r_tooshort r_in.in_tooshort 438*2c497c00Skarels #define r_drops r_in.in_drops 439*2c497c00Skarels }; 440*2c497c00Skarels 441*2c497c00Skarels 442*2c497c00Skarels #ifdef KERNEL 443*2c497c00Skarels /* 444*2c497c00Skarels * Each host chooses the starting point of the packet numbering for a 445*2c497c00Skarels * connection so that datagrams from different incarnations of a 446*2c497c00Skarels * connection have no sequence numbers in common. SYN packets are used 447*2c497c00Skarels * by each side to make the other aware of the starting point. If we 448*2c497c00Skarels * can send N packets per slow timeout, then if we update rdp_iss 449*2c497c00Skarels * by RDP_ISSINCR > N every slow timeout (one connection bangs away 450*2c497c00Skarels * all timeout period) and by RDP_ISSINCR every time we make a connection 451*2c497c00Skarels * (many incarnations of same connection per timeout period), then we're 452*2c497c00Skarels * o.k. 453*2c497c00Skarels */ 454*2c497c00Skarels extern rdpsequence rdp_iss; 455*2c497c00Skarels 456*2c497c00Skarels /* vax can send 180 packets/second */ 457*2c497c00Skarels #define RDP_ISSINCR ((200/PR_SLOWHZ) +1) 458*2c497c00Skarels 459*2c497c00Skarels extern struct dfilter rdp_dfilter; 460*2c497c00Skarels extern struct inpcb rdp; 461*2c497c00Skarels extern struct rdp_stat rdpstat; 462*2c497c00Skarels extern rdp_pcbdisconnect(); 463*2c497c00Skarels extern struct mbuf *rdp_qremove(); 464*2c497c00Skarels extern rdpchecksum rdp_cksum(); 465*2c497c00Skarels extern char *rdp_conn_used(); 466*2c497c00Skarels 467*2c497c00Skarels #define rdp_action(input, rdpcb, arg) rdpaction(input, rdpcb, (int) arg) 468*2c497c00Skarels 469*2c497c00Skarels 470*2c497c00Skarels /* 471*2c497c00Skarels * RDP finite state machine 472*2c497c00Skarels */ 473*2c497c00Skarels #ifdef RDPDEBUG 474*2c497c00Skarels extern char *rdpstates[RDP_NSTATES]; /* rdpstate -> string */ 475*2c497c00Skarels extern char *rdpinputs[RDP_NINPUTS]; 476*2c497c00Skarels extern char *rdptimers[RDP_NTIMERS]; 477*2c497c00Skarels #endif 478*2c497c00Skarels extern int (*rdp_action_table[RDP_NSTATES][RDP_NINPUTS])(); 479*2c497c00Skarels #endif 480