xref: /original-bsd/sys/deprecated/bbnnet/rdp.h (revision 2c497c00)
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