parameterize max proc id
[unix-history] / usr / src / sys / kern / uipc_socket2.c
CommitLineData
da7c5cc6 1/*
83866636 2 * Copyright (c) 1982, 1986, 1988, 1990 Regents of the University of California.
5b519e94 3 * All rights reserved.
da7c5cc6 4 *
dbf0c423 5 * %sccs.include.redist.c%
5b519e94 6 *
dbf0c423 7 * @(#)uipc_socket2.c 7.15 (Berkeley) %G%
da7c5cc6 8 */
681ebb17 9
94368568
JB
10#include "param.h"
11#include "systm.h"
94368568
JB
12#include "user.h"
13#include "proc.h"
14#include "file.h"
94368568 15#include "buf.h"
a8a7f6b3 16#include "malloc.h"
94368568
JB
17#include "mbuf.h"
18#include "protosw.h"
19#include "socket.h"
20#include "socketvar.h"
681ebb17
BJ
21
22/*
23 * Primitive routines for operating on sockets and socket buffers
24 */
25
83866636
MK
26/* strings for sleep message: */
27char netio[] = "netio";
28char netcon[] = "netcon";
29char netcls[] = "netcls";
30
31u_long sb_max = SB_MAX; /* patchable */
32
681ebb17
BJ
33/*
34 * Procedures to manipulate state flags of socket
2deddea9
BJ
35 * and do appropriate wakeups. Normal sequence from the
36 * active (originating) side is that soisconnecting() is
37 * called during processing of connect() call,
4c078bb2
BJ
38 * resulting in an eventual call to soisconnected() if/when the
39 * connection is established. When the connection is torn down
40 * soisdisconnecting() is called during processing of disconnect() call,
41 * and soisdisconnected() is called when the connection to the peer
42 * is totally severed. The semantics of these routines are such that
43 * connectionless protocols can call soisconnected() and soisdisconnected()
44 * only, bypassing the in-progress calls when setting up a ``connection''
45 * takes no time.
46 *
88a7a62a
SL
47 * From the passive side, a socket is created with
48 * two queues of sockets: so_q0 for connections in progress
2deddea9
BJ
49 * and so_q for connections already made and awaiting user acceptance.
50 * As a protocol is preparing incoming connections, it creates a socket
51 * structure queued on so_q0 by calling sonewconn(). When the connection
52 * is established, soisconnected() is called, and transfers the
53 * socket structure to so_q, making it available to accept().
54 *
88a7a62a 55 * If a socket is closed with sockets on either
2deddea9
BJ
56 * so_q0 or so_q, these sockets are dropped.
57 *
88a7a62a 58 * If higher level protocols are implemented in
4c078bb2 59 * the kernel, the wakeups done here will sometimes
88a7a62a 60 * cause software-interrupt process scheduling.
681ebb17 61 */
4c078bb2 62
681ebb17 63soisconnecting(so)
88a7a62a 64 register struct socket *so;
681ebb17
BJ
65{
66
67 so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING);
68 so->so_state |= SS_ISCONNECTING;
681ebb17
BJ
69}
70
71soisconnected(so)
88a7a62a 72 register struct socket *so;
681ebb17 73{
2deddea9 74 register struct socket *head = so->so_head;
681ebb17 75
3b61a902
MK
76 so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING);
77 so->so_state |= SS_ISCONNECTED;
78 if (head && soqremque(so, 0)) {
2deddea9 79 soqinsque(head, so, 1);
ab303321 80 sorwakeup(head);
88a7a62a 81 wakeup((caddr_t)&head->so_timeo);
3b61a902
MK
82 } else {
83 wakeup((caddr_t)&so->so_timeo);
84 sorwakeup(so);
85 sowwakeup(so);
2deddea9 86 }
681ebb17
BJ
87}
88
89soisdisconnecting(so)
88a7a62a 90 register struct socket *so;
681ebb17
BJ
91{
92
72857acf 93 so->so_state &= ~SS_ISCONNECTING;
681ebb17
BJ
94 so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE);
95 wakeup((caddr_t)&so->so_timeo);
4c078bb2 96 sowwakeup(so);
b454c3ea 97 sorwakeup(so);
681ebb17
BJ
98}
99
100soisdisconnected(so)
88a7a62a 101 register struct socket *so;
681ebb17
BJ
102{
103
104 so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
105 so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE);
106 wakeup((caddr_t)&so->so_timeo);
107 sowwakeup(so);
108 sorwakeup(so);
109}
110
2deddea9
BJ
111/*
112 * When an attempt at a new connection is noted on a socket
113 * which accepts connections, sonewconn is called. If the
114 * connection is possible (subject to space constraints, etc.)
115 * then we allocate a new structure, propoerly linked into the
116 * data structure of the original socket, and return this.
3b61a902 117 * Connstatus may be 0, or SO_ISCONFIRMING, or SO_ISCONNECTED.
83866636
MK
118 *
119 * Currently, sonewconn() is defined as sonewconn1() in socketvar.h
120 * to catch calls that are missing the (new) second parameter.
2deddea9
BJ
121 */
122struct socket *
83866636 123sonewconn1(head, connstatus)
2deddea9 124 register struct socket *head;
3b61a902 125 int connstatus;
2deddea9
BJ
126{
127 register struct socket *so;
3b61a902 128 int soqueue = connstatus ? 1 : 0;
2deddea9
BJ
129
130 if (head->so_qlen + head->so_q0len > 3 * head->so_qlimit / 2)
0402489b
MK
131 return ((struct socket *)0);
132 MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_DONTWAIT);
133 if (so == NULL)
134 return ((struct socket *)0);
135 bzero((caddr_t)so, sizeof(*so));
2deddea9
BJ
136 so->so_type = head->so_type;
137 so->so_options = head->so_options &~ SO_ACCEPTCONN;
138 so->so_linger = head->so_linger;
f7428e88 139 so->so_state = head->so_state | SS_NOFDREF;
2deddea9
BJ
140 so->so_proto = head->so_proto;
141 so->so_timeo = head->so_timeo;
6868eb98 142 so->so_pgid = head->so_pgid;
a8a7f6b3 143 (void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat);
3b61a902 144 soqinsque(head, so, soqueue);
88a7a62a
SL
145 if ((*so->so_proto->pr_usrreq)(so, PRU_ATTACH,
146 (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0)) {
3b61a902 147 (void) soqremque(so, soqueue);
0402489b
MK
148 (void) free((caddr_t)so, M_SOCKET);
149 return ((struct socket *)0);
2deddea9 150 }
3b61a902
MK
151 if (connstatus) {
152 sorwakeup(head);
153 wakeup((caddr_t)&head->so_timeo);
154 so->so_state |= connstatus;
155 }
2deddea9 156 return (so);
2deddea9
BJ
157}
158
159soqinsque(head, so, q)
160 register struct socket *head, *so;
161 int q;
162{
163
83866636 164 register struct socket **prev;
2deddea9
BJ
165 so->so_head = head;
166 if (q == 0) {
167 head->so_q0len++;
3b61a902
MK
168 so->so_q0 = 0;
169 for (prev = &(head->so_q0); *prev; )
170 prev = &((*prev)->so_q0);
2deddea9
BJ
171 } else {
172 head->so_qlen++;
3b61a902
MK
173 so->so_q = 0;
174 for (prev = &(head->so_q); *prev; )
175 prev = &((*prev)->so_q);
2deddea9 176 }
3b61a902 177 *prev = so;
2deddea9
BJ
178}
179
180soqremque(so, q)
181 register struct socket *so;
182 int q;
183{
184 register struct socket *head, *prev, *next;
185
186 head = so->so_head;
187 prev = head;
188 for (;;) {
189 next = q ? prev->so_q : prev->so_q0;
190 if (next == so)
191 break;
3b61a902 192 if (next == 0)
2deddea9
BJ
193 return (0);
194 prev = next;
195 }
196 if (q == 0) {
197 prev->so_q0 = next->so_q0;
198 head->so_q0len--;
199 } else {
200 prev->so_q = next->so_q;
201 head->so_qlen--;
202 }
203 next->so_q0 = next->so_q = 0;
204 next->so_head = 0;
205 return (1);
206}
207
4c078bb2
BJ
208/*
209 * Socantsendmore indicates that no more data will be sent on the
210 * socket; it would normally be applied to a socket when the user
211 * informs the system that no more data is to be sent, by the protocol
212 * code (in case PRU_SHUTDOWN). Socantrcvmore indicates that no more data
213 * will be received, and will normally be applied to the socket by a
214 * protocol when it detects that the peer will send no more data.
215 * Data queued for reading in the socket may yet be read.
216 */
217
ae921915
BJ
218socantsendmore(so)
219 struct socket *so;
220{
221
222 so->so_state |= SS_CANTSENDMORE;
223 sowwakeup(so);
224}
225
226socantrcvmore(so)
227 struct socket *so;
228{
229
230 so->so_state |= SS_CANTRCVMORE;
231 sorwakeup(so);
232}
233
681ebb17 234/*
4c078bb2
BJ
235 * Socket select/wakeup routines.
236 */
237
681ebb17
BJ
238/*
239 * Queue a process for a select on a socket buffer.
240 */
241sbselqueue(sb)
242 struct sockbuf *sb;
243{
a8a7f6b3 244 struct proc *p;
681ebb17 245
ae921915 246 if ((p = sb->sb_sel) && p->p_wchan == (caddr_t)&selwait)
681ebb17 247 sb->sb_flags |= SB_COLL;
9b3acfb4 248 else {
681ebb17 249 sb->sb_sel = u.u_procp;
9b3acfb4
MK
250 sb->sb_flags |= SB_SEL;
251 }
681ebb17
BJ
252}
253
ae921915
BJ
254/*
255 * Wait for data to arrive at/drain from a socket buffer.
256 */
257sbwait(sb)
258 struct sockbuf *sb;
259{
260
261 sb->sb_flags |= SB_WAIT;
83866636
MK
262 return (tsleep((caddr_t)&sb->sb_cc,
263 (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH, netio,
264 sb->sb_timeo));
265}
266
267/*
268 * Lock a sockbuf already known to be locked;
269 * return any error returned from sleep (EINTR).
270 */
271sb_lock(sb)
272 register struct sockbuf *sb;
273{
274 int error;
275
276 while (sb->sb_flags & SB_LOCK) {
277 sb->sb_flags |= SB_WANT;
278 if (error = tsleep((caddr_t)&sb->sb_flags,
279 (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK|PCATCH,
280 netio, 0))
281 return (error);
282 }
283 sb->sb_flags |= SB_LOCK;
284 return (0);
ae921915
BJ
285}
286
681ebb17
BJ
287/*
288 * Wakeup processes waiting on a socket buffer.
a8a7f6b3
MK
289 * Do asynchronous notification via SIGIO
290 * if the socket has the SS_ASYNC flag set.
681ebb17 291 */
a8a7f6b3
MK
292sowakeup(so, sb)
293 register struct socket *so;
88a7a62a 294 register struct sockbuf *sb;
681ebb17 295{
0402489b 296 struct proc *p;
681ebb17
BJ
297
298 if (sb->sb_sel) {
299 selwakeup(sb->sb_sel, sb->sb_flags & SB_COLL);
300 sb->sb_sel = 0;
9b3acfb4 301 sb->sb_flags &= ~(SB_SEL|SB_COLL);
681ebb17
BJ
302 }
303 if (sb->sb_flags & SB_WAIT) {
304 sb->sb_flags &= ~SB_WAIT;
388ca8bd 305 wakeup((caddr_t)&sb->sb_cc);
681ebb17 306 }
8f7109aa 307 if (so->so_state & SS_ASYNC) {
6868eb98
MT
308 if (so->so_pgid < 0)
309 gsignal(-so->so_pgid, SIGIO);
310 else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0)
8f7109aa
EC
311 psignal(p, SIGIO);
312 }
313}
314
4c078bb2
BJ
315/*
316 * Socket buffer (struct sockbuf) utility routines.
317 *
318 * Each socket contains two socket buffers: one for sending data and
319 * one for receiving data. Each buffer contains a queue of mbufs,
320 * information about the number of mbufs and amount of data in the
321 * queue, and other fields allowing select() statements and notification
322 * on data availability to be implemented.
323 *
261a8548
MK
324 * Data stored in a socket buffer is maintained as a list of records.
325 * Each record is a list of mbufs chained together with the m_next
a8a7f6b3 326 * field. Records are chained together with the m_nextpkt field. The upper
261a8548
MK
327 * level routine soreceive() expects the following conventions to be
328 * observed when placing information in the receive buffer:
329 *
330 * 1. If the protocol requires each message be preceded by the sender's
331 * name, then a record containing that name must be present before
332 * any associated data (mbuf's must be of type MT_SONAME).
333 * 2. If the protocol supports the exchange of ``access rights'' (really
334 * just additional data associated with the message), and there are
335 * ``rights'' to be received, then a record containing this data
336 * should be present (mbuf's must be of type MT_RIGHTS).
337 * 3. If a name or rights record exists, then it must be followed by
338 * a data record, perhaps of zero length.
339 *
4c078bb2 340 * Before using a new socket structure it is first necessary to reserve
07680231 341 * buffer space to the socket, by calling sbreserve(). This should commit
4c078bb2 342 * some of the available buffer space in the system buffer pool for the
07680231
MK
343 * socket (currently, it does nothing but enforce limits). The space
344 * should be released by calling sbrelease() when the socket is destroyed.
4c078bb2
BJ
345 */
346
0e18ec4a 347soreserve(so, sndcc, rcvcc)
88a7a62a 348 register struct socket *so;
07680231 349 u_long sndcc, rcvcc;
0e18ec4a
BJ
350{
351
352 if (sbreserve(&so->so_snd, sndcc) == 0)
353 goto bad;
354 if (sbreserve(&so->so_rcv, rcvcc) == 0)
355 goto bad2;
83866636
MK
356 if (so->so_rcv.sb_lowat == 0)
357 so->so_rcv.sb_lowat = 1;
358 if (so->so_snd.sb_lowat == 0)
359 so->so_snd.sb_lowat = MCLBYTES;
360 if (so->so_snd.sb_lowat > so->so_snd.sb_hiwat)
361 so->so_snd.sb_lowat = so->so_snd.sb_hiwat;
0e18ec4a
BJ
362 return (0);
363bad2:
364 sbrelease(&so->so_snd);
365bad:
366 return (ENOBUFS);
367}
368
681ebb17
BJ
369/*
370 * Allot mbufs to a sockbuf.
83866636 371 * Attempt to scale mbmax so that mbcnt doesn't become limiting
bbfd9898 372 * if buffering efficiency is near the normal case.
681ebb17
BJ
373 */
374sbreserve(sb, cc)
375 struct sockbuf *sb;
07680231 376 u_long cc;
681ebb17
BJ
377{
378
83866636 379 if (cc > sb_max * MCLBYTES / (MSIZE + MCLBYTES))
1ceef2d8 380 return (0);
d028a086 381 sb->sb_hiwat = cc;
83866636
MK
382 sb->sb_mbmax = min(cc * 2, sb_max);
383 if (sb->sb_lowat > sb->sb_hiwat)
384 sb->sb_lowat = sb->sb_hiwat;
ae921915 385 return (1);
681ebb17
BJ
386}
387
388/*
389 * Free mbufs held by a socket, and reserved mbuf space.
390 */
391sbrelease(sb)
392 struct sockbuf *sb;
393{
394
395 sbflush(sb);
d028a086 396 sb->sb_hiwat = sb->sb_mbmax = 0;
681ebb17
BJ
397}
398
399/*
261a8548
MK
400 * Routines to add and remove
401 * data from an mbuf queue.
c34d38f4
MK
402 *
403 * The routines sbappend() or sbappendrecord() are normally called to
404 * append new mbufs to a socket buffer, after checking that adequate
405 * space is available, comparing the function sbspace() with the amount
406 * of data to be added. sbappendrecord() differs from sbappend() in
407 * that data supplied is treated as the beginning of a new record.
408 * To place a sender's address, optional access rights, and data in a
409 * socket receive buffer, sbappendaddr() should be used. To place
410 * access rights and data in a socket receive buffer, sbappendrights()
411 * should be used. In either case, the new data begins a new record.
412 * Note that unlike sbappend() and sbappendrecord(), these routines check
413 * for the caller that there will be enough space to store the data.
414 * Each fails if there is not enough space, or if it cannot find mbufs
415 * to store additional information in.
416 *
417 * Reliable protocols may use the socket send buffer to hold data
418 * awaiting acknowledgement. Data is normally copied from a socket
419 * send buffer in a protocol with m_copy for output to a peer,
420 * and then removing the data from the socket buffer with sbdrop()
421 * or sbdroprecord() when the data is acknowledged by the peer.
681ebb17
BJ
422 */
423
424/*
261a8548
MK
425 * Append mbuf chain m to the last record in the
426 * socket buffer sb. The additional space associated
427 * the mbuf chain is recorded in sb. Empty mbufs are
428 * discarded and mbufs are compacted where possible.
681ebb17
BJ
429 */
430sbappend(sb, m)
261a8548
MK
431 struct sockbuf *sb;
432 struct mbuf *m;
681ebb17 433{
e495e1cc 434 register struct mbuf *n;
681ebb17 435
261a8548
MK
436 if (m == 0)
437 return;
438 if (n = sb->sb_mb) {
a8a7f6b3
MK
439 while (n->m_nextpkt)
440 n = n->m_nextpkt;
e495e1cc 441 while (n->m_next)
3b61a902
MK
442 if (n->m_flags & M_EOR) {
443 sbappendrecord(sb, m); /* XXXXXX!!!! */
444 return;
445 } else
446 n = n->m_next;
681ebb17 447 }
261a8548 448 sbcompress(sb, m, n);
681ebb17
BJ
449}
450
ea97b0c7
MK
451#ifdef SOCKBUF_DEBUG
452sbcheck(sb)
453 register struct sockbuf *sb;
454{
455 register struct mbuf *m;
456 register int len = 0, mbcnt = 0;
457
458 for (m = sb->sb_mb; m; m = m->m_next) {
459 len += m->m_len;
460 mbcnt += MSIZE;
461 if (m->m_flags & M_EXT)
462 mbcnt += m->m_ext.ext_size;
463 if (m->m_nextpkt)
464 panic("sbcheck nextpkt");
465 }
466 if (len != sb->sb_cc || mbcnt != sb->sb_mbcnt) {
467 printf("cc %d != %d || mbcnt %d != %d\n", len, sb->sb_cc,
468 mbcnt, sb->sb_mbcnt);
469 panic("sbcheck");
470 }
471}
472#endif
473
4c078bb2 474/*
261a8548
MK
475 * As above, except the mbuf chain
476 * begins a new record.
4c078bb2 477 */
261a8548
MK
478sbappendrecord(sb, m0)
479 register struct sockbuf *sb;
480 register struct mbuf *m0;
2b4b57cd 481{
2b4b57cd 482 register struct mbuf *m;
2b4b57cd 483
261a8548
MK
484 if (m0 == 0)
485 return;
486 if (m = sb->sb_mb)
a8a7f6b3
MK
487 while (m->m_nextpkt)
488 m = m->m_nextpkt;
261a8548
MK
489 /*
490 * Put the first mbuf on the queue.
491 * Note this permits zero length records.
492 */
493 sballoc(sb, m0);
494 if (m)
a8a7f6b3 495 m->m_nextpkt = m0;
261a8548
MK
496 else
497 sb->sb_mb = m0;
498 m = m0->m_next;
499 m0->m_next = 0;
0402489b
MK
500 if (m && (m0->m_flags & M_EOR)) {
501 m0->m_flags &= ~M_EOR;
502 m->m_flags |= M_EOR;
503 }
504 sbcompress(sb, m, m0);
505}
506
507/*
508 * As above except that OOB data
509 * is inserted at the beginning of the sockbuf,
510 * but after any other OOB data.
511 */
512sbinsertoob(sb, m0)
513 register struct sockbuf *sb;
514 register struct mbuf *m0;
515{
516 register struct mbuf *m;
517 register struct mbuf **mp;
518
519 if (m0 == 0)
520 return;
521 for (mp = &sb->sb_mb; m = *mp; mp = &((*mp)->m_nextpkt)) {
522 again:
523 switch (m->m_type) {
524
525 case MT_OOBDATA:
526 continue; /* WANT next train */
527
528 case MT_CONTROL:
529 if (m = m->m_next)
530 goto again; /* inspect THIS train further */
531 }
532 break;
533 }
534 /*
535 * Put the first mbuf on the queue.
536 * Note this permits zero length records.
537 */
538 sballoc(sb, m0);
539 m0->m_nextpkt = *mp;
540 *mp = m0;
541 m = m0->m_next;
542 m0->m_next = 0;
543 if (m && (m0->m_flags & M_EOR)) {
544 m0->m_flags &= ~M_EOR;
545 m->m_flags |= M_EOR;
546 }
261a8548
MK
547 sbcompress(sb, m, m0);
548}
549
550/*
c1aac372 551 * Append address and data, and optionally, control (ancillary) data
a8a7f6b3 552 * to the receive queue of a socket. If present,
c1aac372
MK
553 * m0 must include a packet header with total length.
554 * Returns 0 if no space in sockbuf or insufficient mbufs.
261a8548 555 */
c1aac372 556sbappendaddr(sb, asa, m0, control)
261a8548
MK
557 register struct sockbuf *sb;
558 struct sockaddr *asa;
c1aac372 559 struct mbuf *m0, *control;
261a8548
MK
560{
561 register struct mbuf *m, *n;
0402489b 562 int space = asa->sa_len;
261a8548 563
a8a7f6b3
MK
564if (m0 && (m0->m_flags & M_PKTHDR) == 0)
565panic("sbappendaddr");
566 if (m0)
567 space += m0->m_pkthdr.len;
c1aac372
MK
568 for (n = control; n; n = n->m_next) {
569 space += n->m_len;
570 if (n->m_next == 0) /* keep pointer to last control buf */
571 break;
572 }
261a8548 573 if (space > sbspace(sb))
2b4b57cd 574 return (0);
c1aac372
MK
575 if (asa->sa_len > MLEN)
576 return (0);
c34d38f4 577 MGET(m, M_DONTWAIT, MT_SONAME);
261a8548 578 if (m == 0)
2b4b57cd 579 return (0);
0402489b
MK
580 m->m_len = asa->sa_len;
581 bcopy((caddr_t)asa, mtod(m, caddr_t), asa->sa_len);
c1aac372
MK
582 if (n)
583 n->m_next = m0; /* concatenate data to control */
584 else
585 control = m0;
586 m->m_next = control;
587 for (n = m; n; n = n->m_next)
588 sballoc(sb, n);
261a8548 589 if (n = sb->sb_mb) {
a8a7f6b3
MK
590 while (n->m_nextpkt)
591 n = n->m_nextpkt;
592 n->m_nextpkt = m;
88a7a62a 593 } else
261a8548 594 sb->sb_mb = m;
261a8548
MK
595 return (1);
596}
597
c1aac372 598sbappendcontrol(sb, m0, control)
261a8548 599 struct sockbuf *sb;
c1aac372 600 struct mbuf *control, *m0;
261a8548
MK
601{
602 register struct mbuf *m, *n;
603 int space = 0;
604
c1aac372
MK
605 if (control == 0)
606 panic("sbappendcontrol");
607 for (m = control; ; m = m->m_next) {
608 space += m->m_len;
609 if (m->m_next == 0)
610 break;
611 }
612 n = m; /* save pointer to last control buffer */
c34d38f4 613 for (m = m0; m; m = m->m_next)
261a8548 614 space += m->m_len;
261a8548 615 if (space > sbspace(sb))
88a7a62a 616 return (0);
c1aac372
MK
617 n->m_next = m0; /* concatenate data to control */
618 for (m = control; m; m = m->m_next)
619 sballoc(sb, m);
261a8548 620 if (n = sb->sb_mb) {
a8a7f6b3
MK
621 while (n->m_nextpkt)
622 n = n->m_nextpkt;
c1aac372 623 n->m_nextpkt = control;
261a8548 624 } else
c1aac372 625 sb->sb_mb = control;
2b4b57cd
BJ
626 return (1);
627}
261a8548
MK
628
629/*
630 * Compress mbuf chain m into the socket
631 * buffer sb following mbuf n. If n
632 * is null, the buffer is presumed empty.
633 */
634sbcompress(sb, m, n)
635 register struct sockbuf *sb;
636 register struct mbuf *m, *n;
637{
0402489b 638 register int eor = 0;
c1aac372 639
261a8548 640 while (m) {
0402489b 641 eor |= m->m_flags & M_EOR;
261a8548
MK
642 if (m->m_len == 0) {
643 m = m_free(m);
644 continue;
645 }
0402489b 646 if (n && (n->m_flags & (M_EXT | M_EOR)) == 0 &&
a8a7f6b3 647 (n->m_data + n->m_len + m->m_len) < &n->m_dat[MLEN] &&
c34d38f4 648 n->m_type == m->m_type) {
261a8548
MK
649 bcopy(mtod(m, caddr_t), mtod(n, caddr_t) + n->m_len,
650 (unsigned)m->m_len);
651 n->m_len += m->m_len;
652 sb->sb_cc += m->m_len;
653 m = m_free(m);
654 continue;
655 }
261a8548
MK
656 if (n)
657 n->m_next = m;
658 else
659 sb->sb_mb = m;
0402489b 660 sballoc(sb, m);
261a8548 661 n = m;
0402489b 662 m->m_flags &= ~M_EOR;
261a8548
MK
663 m = m->m_next;
664 n->m_next = 0;
665 }
0402489b
MK
666 if (n)
667 n->m_flags |= eor;
261a8548 668}
2b4b57cd 669
681ebb17 670/*
261a8548
MK
671 * Free all mbufs in a sockbuf.
672 * Check that all resources are reclaimed.
681ebb17
BJ
673 */
674sbflush(sb)
88a7a62a 675 register struct sockbuf *sb;
681ebb17
BJ
676{
677
678 if (sb->sb_flags & SB_LOCK)
679 panic("sbflush");
acb7839f 680 while (sb->sb_mbcnt)
8011f5df 681 sbdrop(sb, (int)sb->sb_cc);
c1aac372 682 if (sb->sb_cc || sb->sb_mb)
681ebb17
BJ
683 panic("sbflush 2");
684}
685
686/*
261a8548 687 * Drop data from (the front of) a sockbuf.
681ebb17
BJ
688 */
689sbdrop(sb, len)
690 register struct sockbuf *sb;
691 register int len;
692{
261a8548
MK
693 register struct mbuf *m, *mn;
694 struct mbuf *next;
681ebb17 695
a8a7f6b3 696 next = (m = sb->sb_mb) ? m->m_nextpkt : 0;
681ebb17 697 while (len > 0) {
261a8548
MK
698 if (m == 0) {
699 if (next == 0)
700 panic("sbdrop");
701 m = next;
a8a7f6b3 702 next = m->m_nextpkt;
261a8548
MK
703 continue;
704 }
b9f0d37f 705 if (m->m_len > len) {
681ebb17 706 m->m_len -= len;
a8a7f6b3 707 m->m_data += len;
681ebb17
BJ
708 sb->sb_cc -= len;
709 break;
710 }
b9f0d37f
BJ
711 len -= m->m_len;
712 sbfree(sb, m);
713 MFREE(m, mn);
714 m = mn;
681ebb17 715 }
082e4f86 716 while (m && m->m_len == 0) {
453677da 717 sbfree(sb, m);
082e4f86
MK
718 MFREE(m, mn);
719 m = mn;
720 }
261a8548
MK
721 if (m) {
722 sb->sb_mb = m;
a8a7f6b3 723 m->m_nextpkt = next;
261a8548
MK
724 } else
725 sb->sb_mb = next;
261a8548
MK
726}
727
728/*
729 * Drop a record off the front of a sockbuf
730 * and move the next record to the front.
731 */
261a8548
MK
732sbdroprecord(sb)
733 register struct sockbuf *sb;
734{
735 register struct mbuf *m, *mn;
736
737 m = sb->sb_mb;
738 if (m) {
a8a7f6b3 739 sb->sb_mb = m->m_nextpkt;
261a8548
MK
740 do {
741 sbfree(sb, m);
742 MFREE(m, mn);
743 } while (m = mn);
744 }
681ebb17 745}