fixes for range locking
[unix-history] / usr / src / sys / deprecated / bbnnet / rdp_subr.c
CommitLineData
17efd7fe
MK
1/*
2 $Log: rdp_subr.c,v $
3 * Revision 2.7 84/11/21 12:06:30 walsh
4 * *** empty log message ***
5 *
6 * Revision 2.6 84/11/08 16:12:53 walsh
7 * Added code to gather statistics on RDP traffic. This makes the RDPCB
8 * too big unles you make mbufs 512 bytes large. RDP_CS should be turned off
9 * unless you do.
10 *
11 * Revision 2.5 84/11/06 13:54:21 walsh
12 * *** empty log message ***
13 *
14 * Revision 2.4 84/11/05 16:25:18 walsh
15 * tied rdp to icmp source quenches. See icmp_quench and rdp_quench.
16 *
17 * Revision 2.3 84/11/05 15:55:13 walsh
18 * update_nulltimer() macro began to look inappropriate with recent
19 * changes, so its been stripped out and put in-line.
20 *
21 * Revision 2.2 84/11/02 18:25:47 walsh
22 * Protocol specifiers want NULL message to have own sequence number in
23 * case of slow (t>NULL msg timeout) packets. I don't see this as a problem,
24 * and even if happened (dubious) would only delay discovery, but I
25 * didn't win this one. Initially not designed for this, but fixes are
26 * in almost neatly.
27 *
28 * Revision 2.1 84/11/02 10:15:35 walsh
29 * Fixed to include RCS comments in checked out source.
30 *
31 *
32 * description:
33 * Some subroutines for manipulating the datagram q's for RDP.
34 *
35 * revision 1.11
36 * date: 84/07/20 10:30:42; author: walsh; state: Exp; lines added/del: 21/1
37 * Tied RDP acknowledgements to ping reduction, just like TCP.
38 *
39 * revision 1.10
40 * date: 84/07/19 10:22:33; author: walsh; state: Exp; lines added/del: 1/17
41 * Organized macros and classified their definitions in rdp_macros.h.
42 *
43 * revision 1.9
44 * date: 84/07/17 22:35:26; author: walsh; state: Exp; lines added/del: 3/0
45 * Ensure cannot bind port number greater than RDP_pMAX.
46 *
47 * revision 1.8
48 * date: 84/07/12 10:12:48; author: walsh; state: Exp; lines added/del: 14/18
49 * some small optimizations.
50 *
51 * revision 1.7
52 * date: 84/07/12 09:39:06; author: walsh; state: Exp; lines added/del: 2/4
53 * small optimizations. ( a = (a+1)%b quicker than a++; a %= b)
54 *
55 * revision 1.6
56 * date: 84/07/10 14:58:24; author: walsh; state: Exp; lines added/del: 10/3
57 * Now no unecessary wakeups of the user process are done.
58 *
59 * revision 1.5
60 * date: 84/07/10 10:38:24; author: walsh; state: Exp; lines added/del: 13/13
61 * added register declarations.
62 *
63 * revision 1.4
64 * date: 84/07/06 14:28:53; author: wjacobso; state: Exp; lines added/del: 6/6
65 * *** empty log message ***
66 *
67 * revision 1.3
68 * date: 84/07/06 14:17:02; author: wjacobso; state: Exp; lines added/del: 8/8
69 * added register var definitions
70 *
71 * revision 1.2
72 * date: 84/07/06 09:51:12; author: root; state: Exp; lines added/del: 2/1
73 * This version seems to run bug-free.
74 *
75 * revision 1.1
76 * date: 84/06/26 14:18:30; author: walsh; state: Exp;
77 * Initial revision
78 */
79
80
81#ifdef RDP
82#include "../h/param.h"
83#include "../h/dir.h"
84#include "../h/user.h"
85#include "../h/kernel.h"
86#include "../h/inode.h"
87#include "../h/mbuf.h"
88#include "../h/socket.h"
89#include "../h/socketvar.h"
90#include "../h/syslog.h"
91
92#include "../net/if.h"
93#include "../net/route.h"
94
95#include "../bbnnet/in.h"
96#include "../bbnnet/net.h"
97#include "../bbnnet/in_pcb.h"
98#include "../bbnnet/in_var.h"
99#include "../bbnnet/ip.h"
100#include "../bbnnet/icmp.h"
101#include "../bbnnet/rdp.h"
102#include "../bbnnet/seq.h"
103#include "../bbnnet/rdp_macros.h"
104
105/*
106 * Called on ACK of a message we sent.
107 */
108he_acked(rdpcb, msgnum)
109register RDPCB *rdpcb;
110rdpsequence msgnum;
111{
112 register int index;
113 register int i;
114 register MBUF *m;
115
116 index = msgnum - rdpcb->r_sendq.rq_baseseq;
117 if (index < 0 || index >= rdpcb->r_sendq.rq_maxqlen)
118 return;
119
120 /*
121 * an ACK is cumulative and may be for more than one message
122 */
123 for (i=0; i<=index; i++)
124 {
125 register int j;
126
127 j = (rdpcb->r_sendq.rq_front + i) % rdpcb->r_sendq.rq_maxqlen;
128 m = rdpcb->r_sendq.rq_msgs[j];
129 /*
130 * ignore redundant ACKs. May have been EACKed (RDP_DELIVERED).
131 */
132 if (m)
133 {
134 if (m == RDP_NULLMSG)
135 {
136 /* and restart connection loss detection */
137 rdpcb->r_nullsent = 0;
138 rdpcb->r_timers[RDP_tNULL] = rdpcb->r_tvnull;
139 }
140 else if (m != RDP_DELIVERED)
141 {
142#ifdef RDP_CS
143 /* count when acked, not queued */
144 rdpcb->r_sent.r_nbytes += (int) m->m_act;
145#endif
146 m_freem(m);
147 }
148 rdpcb->r_sendq.rq_msgs[j] = NULL;
149 }
150 clear_rxtimer (rdpcb, j);
151 }
152
153 /*
154 * Ensure front is always NULL or an undelivered (unacked) message.
155 */
156 rdpcb->r_sendq.rq_front += (index +1);
157 rdpcb->r_sendq.rq_front %= rdpcb->r_sendq.rq_maxqlen;
158 rdpcb->r_sendq.rq_baseseq += (index +1); /* bumps r_snduna */
159
160 /*
161 * and, did this ack allow us to measure current round trip time?
162 */
163 if (rdpcb->r_rttiming)
164 {
165 if (SEQ_GT(rdpcb->r_sendq.rq_baseseq, rdpcb->r_rttimed))
166 {
167 update_rttestimate(rdpcb);
168 update_rxmitime(rdpcb);
169 rdpcb->r_rttiming = FALSE;
170 }
171 }
172
173#ifdef BBNPING
174 /*
175 * We've sent him NEW data, perhaps by a gateway, that he
176 * has successfully received. If that's the case, then
177 * we know the route works and we don't have to ping that
178 * gateway.
179 *
180 * see check_ping()
181 */
182 {
183 register struct rtentry *rt;
184
185 if (rt = rdpcb->r_inpcb->inp_route.ro_rt)
186 if (rt->rt_flags & RTF_GATEWAY)
187 rt->irt_pings = (-1);
188 }
189#endif
190
191 /*
192 * and let sender send more pkts now that we have space.
193 */
194 sendbufhasspace(rdpcb);
195}
196
197/*
198 * Called on EACK of a message we sent.
199 */
200he_eacked(rdpcb, msgnum)
201register RDPCB *rdpcb;
202rdpsequence msgnum;
203{
204 register int index;
205 register MBUF *m;
206
207 index = msgnum - rdpcb->r_sendq.rq_baseseq;
208 if (index < 0 || index >= rdpcb->r_sendq.rq_maxqlen)
209 return;
210
211 index = (index + rdpcb->r_sendq.rq_front) % rdpcb->r_sendq.rq_maxqlen;
212 m = rdpcb->r_sendq.rq_msgs[index];
213 /*
214 * ignore redundant EACKs
215 */
216 if (m && (m != RDP_DELIVERED))
217 {
218 if (m == RDP_NULLMSG)
219 {
220 /* and restart connection loss detection */
221 rdpcb->r_nullsent = 0;
222 rdpcb->r_timers[RDP_tNULL] = rdpcb->r_tvnull;
8902c2d0 223 log(LOG_INFO, "Incorrect ACK strategy on rdpcb 0x%x\n", rdpcb);
17efd7fe
MK
224 }
225 else
226 {
227#ifdef RDP_CS
228 rdpcb->r_sent.r_nbytes += (int) m->m_act;
229#endif
230 m_freem(m);
231 }
232 rdpcb->r_sendq.rq_msgs[index] = RDP_DELIVERED;
233 clear_rxtimer(rdpcb, index);
234
235 /*
236 * did this eack allow us to measure current round trip time?
237 */
238 if (rdpcb->r_rttiming)
239 {
240 if (msgnum == rdpcb->r_rttimed)
241 {
242 update_rttestimate(rdpcb);
243 update_rxmitime(rdpcb);
244 rdpcb->r_rttiming = FALSE;
245 }
246 }
247 }
248}
249
250
251/*
252 * Grab a message for passing to the user. msgq is our rcvq.
253 * Called on net reception if user recv q is empty.
254 * Called on PRU_RECV after user picks up current packet on socket.
255 * Only one packet is attached to the socket at a time.
256 */
257MBUF *rdp_qremove(msgq, async)
258register RDP_MSGQ *msgq;
259{
260 MBUF *m;
261 int index;
262 int pass;
263
264 index = msgq->rq_front;
265 pass = msgq->rq_maxqlen;
266 do
267 {
268 m = msgq->rq_msgs[index];
269 if (m && m != RDP_DELIVERED)
270 {
271 msgq->rq_msgs[index] = RDP_DELIVERED;
272 return (m);
273 }
274 index = (index +1) % msgq->rq_maxqlen;
275 }
276 while (async && (--pass > 0));
277
278 return (NULL);
279}
280
281/*
282 * rdp_qremove() grabbed a message to pass to the user. When he picks it up,
283 * PRU_RCVD occurs. At that point, we bump front and we send an ACK.
284 */
285rdp_received(msgq)
286register RDP_MSGQ *msgq;
287{
288 register MBUF *m;
289 register int index;
290
291 do
292 {
293 index = msgq->rq_front;
294 m = msgq->rq_msgs[index];
295 if (m == RDP_DELIVERED)
296 {
297 msgq->rq_front = (msgq->rq_front +1) % msgq->rq_maxqlen;
298 msgq->rq_baseseq ++;
299 msgq->rq_msgs[index] = NULL;
300 }
301 }
302 while (m == RDP_DELIVERED);
303}
304
305/*
306 * Put a message on our send or rcv q.
307 *
308 * 0 internal error somewhere
309 * 1 new message
310 * -1 duplicate message
311 */
312rdp_qinsert(msgq, m, msgnum)
313register RDP_MSGQ *msgq;
314MBUF *m;
315rdpsequence msgnum;
316{
317 register int index;
318 int isdup;
319
320 index = msgnum - msgq->rq_baseseq;
321 if ((index < 0) || (index >= msgq->rq_maxqlen))
322 {
323 m_freem(m);
324 return(0);
325 }
326
327 index = (index + msgq->rq_front) % msgq->rq_maxqlen;
328 if (msgq->rq_msgs[index] == RDP_DELIVERED)
329 {
330 /* rcvd duplicate of a message the user already has on socket */
331 m_freem(m);
332 isdup = -1;
333 }
334 else
335 {
336 if (msgq->rq_msgs[index])
337 {
338 m_freem(msgq->rq_msgs[index]);
339 isdup = -1;
340 }
341 else
342 isdup = 1;
343 msgq->rq_msgs[index] = m;
344 }
345 return(isdup);
346}
347#endif