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