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