1 /* $NetBSD: uipc_socket2.c,v 1.38 2001/04/30 03:32:56 kml Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1986, 1988, 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)uipc_socket2.c 8.2 (Berkeley) 2/14/95 36 */ 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/proc.h> 41 #include <sys/file.h> 42 #include <sys/buf.h> 43 #include <sys/malloc.h> 44 #include <sys/mbuf.h> 45 #include <sys/protosw.h> 46 #include <sys/socket.h> 47 #include <sys/socketvar.h> 48 #include <sys/signalvar.h> 49 50 /* 51 * Primitive routines for operating on sockets and socket buffers 52 */ 53 54 /* strings for sleep message: */ 55 const char netio[] = "netio"; 56 const char netcon[] = "netcon"; 57 const char netcls[] = "netcls"; 58 59 /* 60 * Procedures to manipulate state flags of socket 61 * and do appropriate wakeups. Normal sequence from the 62 * active (originating) side is that soisconnecting() is 63 * called during processing of connect() call, 64 * resulting in an eventual call to soisconnected() if/when the 65 * connection is established. When the connection is torn down 66 * soisdisconnecting() is called during processing of disconnect() call, 67 * and soisdisconnected() is called when the connection to the peer 68 * is totally severed. The semantics of these routines are such that 69 * connectionless protocols can call soisconnected() and soisdisconnected() 70 * only, bypassing the in-progress calls when setting up a ``connection'' 71 * takes no time. 72 * 73 * From the passive side, a socket is created with 74 * two queues of sockets: so_q0 for connections in progress 75 * and so_q for connections already made and awaiting user acceptance. 76 * As a protocol is preparing incoming connections, it creates a socket 77 * structure queued on so_q0 by calling sonewconn(). When the connection 78 * is established, soisconnected() is called, and transfers the 79 * socket structure to so_q, making it available to accept(). 80 * 81 * If a socket is closed with sockets on either 82 * so_q0 or so_q, these sockets are dropped. 83 * 84 * If higher level protocols are implemented in 85 * the kernel, the wakeups done here will sometimes 86 * cause software-interrupt process scheduling. 87 */ 88 89 void 90 soisconnecting(struct socket *so) 91 { 92 93 so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING); 94 so->so_state |= SS_ISCONNECTING; 95 } 96 97 void 98 soisconnected(struct socket *so) 99 { 100 struct socket *head; 101 102 head = so->so_head; 103 so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING); 104 so->so_state |= SS_ISCONNECTED; 105 if (head && soqremque(so, 0)) { 106 soqinsque(head, so, 1); 107 sorwakeup(head); 108 wakeup((caddr_t)&head->so_timeo); 109 } else { 110 wakeup((caddr_t)&so->so_timeo); 111 sorwakeup(so); 112 sowwakeup(so); 113 } 114 } 115 116 void 117 soisdisconnecting(struct socket *so) 118 { 119 120 so->so_state &= ~SS_ISCONNECTING; 121 so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE); 122 wakeup((caddr_t)&so->so_timeo); 123 sowwakeup(so); 124 sorwakeup(so); 125 } 126 127 void 128 soisdisconnected(struct socket *so) 129 { 130 131 so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING); 132 so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED); 133 wakeup((caddr_t)&so->so_timeo); 134 sowwakeup(so); 135 sorwakeup(so); 136 } 137 138 /* 139 * When an attempt at a new connection is noted on a socket 140 * which accepts connections, sonewconn is called. If the 141 * connection is possible (subject to space constraints, etc.) 142 * then we allocate a new structure, propoerly linked into the 143 * data structure of the original socket, and return this. 144 * Connstatus may be 0, or SO_ISCONFIRMING, or SO_ISCONNECTED. 145 * 146 * Currently, sonewconn() is defined as sonewconn1() in socketvar.h 147 * to catch calls that are missing the (new) second parameter. 148 */ 149 struct socket * 150 sonewconn1(struct socket *head, int connstatus) 151 { 152 struct socket *so; 153 int soqueue; 154 155 soqueue = connstatus ? 1 : 0; 156 if (head->so_qlen + head->so_q0len > 3 * head->so_qlimit / 2) 157 return ((struct socket *)0); 158 so = pool_get(&socket_pool, PR_NOWAIT); 159 if (so == NULL) 160 return (NULL); 161 memset((caddr_t)so, 0, sizeof(*so)); 162 so->so_type = head->so_type; 163 so->so_options = head->so_options &~ SO_ACCEPTCONN; 164 so->so_linger = head->so_linger; 165 so->so_state = head->so_state | SS_NOFDREF; 166 so->so_proto = head->so_proto; 167 so->so_timeo = head->so_timeo; 168 so->so_pgid = head->so_pgid; 169 so->so_send = head->so_send; 170 so->so_receive = head->so_receive; 171 so->so_uid = head->so_uid; 172 (void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat); 173 soqinsque(head, so, soqueue); 174 if ((*so->so_proto->pr_usrreq)(so, PRU_ATTACH, 175 (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0, 176 (struct proc *)0)) { 177 (void) soqremque(so, soqueue); 178 pool_put(&socket_pool, so); 179 return (NULL); 180 } 181 if (connstatus) { 182 sorwakeup(head); 183 wakeup((caddr_t)&head->so_timeo); 184 so->so_state |= connstatus; 185 } 186 return (so); 187 } 188 189 void 190 soqinsque(struct socket *head, struct socket *so, int q) 191 { 192 193 #ifdef DIAGNOSTIC 194 if (so->so_onq != NULL) 195 panic("soqinsque"); 196 #endif 197 198 so->so_head = head; 199 if (q == 0) { 200 head->so_q0len++; 201 so->so_onq = &head->so_q0; 202 } else { 203 head->so_qlen++; 204 so->so_onq = &head->so_q; 205 } 206 TAILQ_INSERT_TAIL(so->so_onq, so, so_qe); 207 } 208 209 int 210 soqremque(struct socket *so, int q) 211 { 212 struct socket *head; 213 214 head = so->so_head; 215 if (q == 0) { 216 if (so->so_onq != &head->so_q0) 217 return (0); 218 head->so_q0len--; 219 } else { 220 if (so->so_onq != &head->so_q) 221 return (0); 222 head->so_qlen--; 223 } 224 TAILQ_REMOVE(so->so_onq, so, so_qe); 225 so->so_onq = NULL; 226 so->so_head = NULL; 227 return (1); 228 } 229 230 /* 231 * Socantsendmore indicates that no more data will be sent on the 232 * socket; it would normally be applied to a socket when the user 233 * informs the system that no more data is to be sent, by the protocol 234 * code (in case PRU_SHUTDOWN). Socantrcvmore indicates that no more data 235 * will be received, and will normally be applied to the socket by a 236 * protocol when it detects that the peer will send no more data. 237 * Data queued for reading in the socket may yet be read. 238 */ 239 240 void 241 socantsendmore(struct socket *so) 242 { 243 244 so->so_state |= SS_CANTSENDMORE; 245 sowwakeup(so); 246 } 247 248 void 249 socantrcvmore(struct socket *so) 250 { 251 252 so->so_state |= SS_CANTRCVMORE; 253 sorwakeup(so); 254 } 255 256 /* 257 * Wait for data to arrive at/drain from a socket buffer. 258 */ 259 int 260 sbwait(struct sockbuf *sb) 261 { 262 263 sb->sb_flags |= SB_WAIT; 264 return (tsleep((caddr_t)&sb->sb_cc, 265 (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH, netio, 266 sb->sb_timeo)); 267 } 268 269 /* 270 * Lock a sockbuf already known to be locked; 271 * return any error returned from sleep (EINTR). 272 */ 273 int 274 sb_lock(struct sockbuf *sb) 275 { 276 int error; 277 278 while (sb->sb_flags & SB_LOCK) { 279 sb->sb_flags |= SB_WANT; 280 error = tsleep((caddr_t)&sb->sb_flags, 281 (sb->sb_flags & SB_NOINTR) ? 282 PSOCK : PSOCK|PCATCH, netio, 0); 283 if (error) 284 return (error); 285 } 286 sb->sb_flags |= SB_LOCK; 287 return (0); 288 } 289 290 /* 291 * Wakeup processes waiting on a socket buffer. 292 * Do asynchronous notification via SIGIO 293 * if the socket has the SS_ASYNC flag set. 294 */ 295 void 296 sowakeup(struct socket *so, struct sockbuf *sb) 297 { 298 struct proc *p; 299 300 selwakeup(&sb->sb_sel); 301 sb->sb_flags &= ~SB_SEL; 302 if (sb->sb_flags & SB_WAIT) { 303 sb->sb_flags &= ~SB_WAIT; 304 wakeup((caddr_t)&sb->sb_cc); 305 } 306 if (so->so_state & SS_ASYNC) { 307 if (so->so_pgid < 0) 308 gsignal(-so->so_pgid, SIGIO); 309 else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0) 310 psignal(p, SIGIO); 311 } 312 if (sb->sb_flags & SB_UPCALL) 313 (*so->so_upcall)(so, so->so_upcallarg, M_DONTWAIT); 314 } 315 316 /* 317 * Socket buffer (struct sockbuf) utility routines. 318 * 319 * Each socket contains two socket buffers: one for sending data and 320 * one for receiving data. Each buffer contains a queue of mbufs, 321 * information about the number of mbufs and amount of data in the 322 * queue, and other fields allowing poll() statements and notification 323 * on data availability to be implemented. 324 * 325 * Data stored in a socket buffer is maintained as a list of records. 326 * Each record is a list of mbufs chained together with the m_next 327 * field. Records are chained together with the m_nextpkt field. The upper 328 * level routine soreceive() expects the following conventions to be 329 * observed when placing information in the receive buffer: 330 * 331 * 1. If the protocol requires each message be preceded by the sender's 332 * name, then a record containing that name must be present before 333 * any associated data (mbuf's must be of type MT_SONAME). 334 * 2. If the protocol supports the exchange of ``access rights'' (really 335 * just additional data associated with the message), and there are 336 * ``rights'' to be received, then a record containing this data 337 * should be present (mbuf's must be of type MT_CONTROL). 338 * 3. If a name or rights record exists, then it must be followed by 339 * a data record, perhaps of zero length. 340 * 341 * Before using a new socket structure it is first necessary to reserve 342 * buffer space to the socket, by calling sbreserve(). This should commit 343 * some of the available buffer space in the system buffer pool for the 344 * socket (currently, it does nothing but enforce limits). The space 345 * should be released by calling sbrelease() when the socket is destroyed. 346 */ 347 348 int 349 soreserve(struct socket *so, u_long sndcc, u_long rcvcc) 350 { 351 352 if (sbreserve(&so->so_snd, sndcc) == 0) 353 goto bad; 354 if (sbreserve(&so->so_rcv, rcvcc) == 0) 355 goto bad2; 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; 362 return (0); 363 bad2: 364 sbrelease(&so->so_snd); 365 bad: 366 return (ENOBUFS); 367 } 368 369 /* 370 * Allot mbufs to a sockbuf. 371 * Attempt to scale mbmax so that mbcnt doesn't become limiting 372 * if buffering efficiency is near the normal case. 373 */ 374 int 375 sbreserve(struct sockbuf *sb, u_long cc) 376 { 377 378 if (cc == 0 || 379 (u_quad_t) cc > (u_quad_t) sb_max * MCLBYTES / (MSIZE + MCLBYTES)) 380 return (0); 381 sb->sb_hiwat = cc; 382 sb->sb_mbmax = min(cc * 2, sb_max); 383 if (sb->sb_lowat > sb->sb_hiwat) 384 sb->sb_lowat = sb->sb_hiwat; 385 return (1); 386 } 387 388 /* 389 * Free mbufs held by a socket, and reserved mbuf space. 390 */ 391 void 392 sbrelease(struct sockbuf *sb) 393 { 394 395 sbflush(sb); 396 sb->sb_hiwat = sb->sb_mbmax = 0; 397 } 398 399 /* 400 * Routines to add and remove 401 * data from an mbuf queue. 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. 422 */ 423 424 /* 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. 429 */ 430 void 431 sbappend(struct sockbuf *sb, struct mbuf *m) 432 { 433 struct mbuf *n; 434 435 if (m == 0) 436 return; 437 if ((n = sb->sb_mb) != NULL) { 438 while (n->m_nextpkt) 439 n = n->m_nextpkt; 440 do { 441 if (n->m_flags & M_EOR) { 442 sbappendrecord(sb, m); /* XXXXXX!!!! */ 443 return; 444 } 445 } while (n->m_next && (n = n->m_next)); 446 } 447 sbcompress(sb, m, n); 448 } 449 450 #ifdef SOCKBUF_DEBUG 451 void 452 sbcheck(struct sockbuf *sb) 453 { 454 struct mbuf *m; 455 int len, mbcnt; 456 457 len = 0; 458 mbcnt = 0; 459 for (m = sb->sb_mb; m; m = m->m_next) { 460 len += m->m_len; 461 mbcnt += MSIZE; 462 if (m->m_flags & M_EXT) 463 mbcnt += m->m_ext.ext_size; 464 if (m->m_nextpkt) 465 panic("sbcheck nextpkt"); 466 } 467 if (len != sb->sb_cc || mbcnt != sb->sb_mbcnt) { 468 printf("cc %d != %d || mbcnt %d != %d\n", len, sb->sb_cc, 469 mbcnt, sb->sb_mbcnt); 470 panic("sbcheck"); 471 } 472 } 473 #endif 474 475 /* 476 * As above, except the mbuf chain 477 * begins a new record. 478 */ 479 void 480 sbappendrecord(struct sockbuf *sb, struct mbuf *m0) 481 { 482 struct mbuf *m; 483 484 if (m0 == 0) 485 return; 486 if ((m = sb->sb_mb) != NULL) 487 while (m->m_nextpkt) 488 m = m->m_nextpkt; 489 /* 490 * Put the first mbuf on the queue. 491 * Note this permits zero length records. 492 */ 493 sballoc(sb, m0); 494 if (m) 495 m->m_nextpkt = m0; 496 else 497 sb->sb_mb = m0; 498 m = m0->m_next; 499 m0->m_next = 0; 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 */ 512 void 513 sbinsertoob(struct sockbuf *sb, struct mbuf *m0) 514 { 515 struct mbuf *m, **mp; 516 517 if (m0 == 0) 518 return; 519 for (mp = &sb->sb_mb; (m = *mp) != NULL; mp = &((*mp)->m_nextpkt)) { 520 again: 521 switch (m->m_type) { 522 523 case MT_OOBDATA: 524 continue; /* WANT next train */ 525 526 case MT_CONTROL: 527 if ((m = m->m_next) != NULL) 528 goto again; /* inspect THIS train further */ 529 } 530 break; 531 } 532 /* 533 * Put the first mbuf on the queue. 534 * Note this permits zero length records. 535 */ 536 sballoc(sb, m0); 537 m0->m_nextpkt = *mp; 538 *mp = m0; 539 m = m0->m_next; 540 m0->m_next = 0; 541 if (m && (m0->m_flags & M_EOR)) { 542 m0->m_flags &= ~M_EOR; 543 m->m_flags |= M_EOR; 544 } 545 sbcompress(sb, m, m0); 546 } 547 548 /* 549 * Append address and data, and optionally, control (ancillary) data 550 * to the receive queue of a socket. If present, 551 * m0 must include a packet header with total length. 552 * Returns 0 if no space in sockbuf or insufficient mbufs. 553 */ 554 int 555 sbappendaddr(struct sockbuf *sb, struct sockaddr *asa, struct mbuf *m0, 556 struct mbuf *control) 557 { 558 struct mbuf *m, *n; 559 int space; 560 561 space = asa->sa_len; 562 563 if (m0 && (m0->m_flags & M_PKTHDR) == 0) 564 panic("sbappendaddr"); 565 if (m0) 566 space += m0->m_pkthdr.len; 567 for (n = control; n; n = n->m_next) { 568 space += n->m_len; 569 if (n->m_next == 0) /* keep pointer to last control buf */ 570 break; 571 } 572 if (space > sbspace(sb)) 573 return (0); 574 MGET(m, M_DONTWAIT, MT_SONAME); 575 if (m == 0) 576 return (0); 577 if (asa->sa_len > MLEN) { 578 MEXTMALLOC(m, asa->sa_len, M_NOWAIT); 579 if ((m->m_flags & M_EXT) == 0) { 580 m_free(m); 581 return (0); 582 } 583 } 584 m->m_len = asa->sa_len; 585 memcpy(mtod(m, caddr_t), (caddr_t)asa, asa->sa_len); 586 if (n) 587 n->m_next = m0; /* concatenate data to control */ 588 else 589 control = m0; 590 m->m_next = control; 591 for (n = m; n; n = n->m_next) 592 sballoc(sb, n); 593 if ((n = sb->sb_mb) != NULL) { 594 while (n->m_nextpkt) 595 n = n->m_nextpkt; 596 n->m_nextpkt = m; 597 } else 598 sb->sb_mb = m; 599 return (1); 600 } 601 602 int 603 sbappendcontrol(struct sockbuf *sb, struct mbuf *m0, struct mbuf *control) 604 { 605 struct mbuf *m, *n; 606 int space; 607 608 space = 0; 609 if (control == 0) 610 panic("sbappendcontrol"); 611 for (m = control; ; m = m->m_next) { 612 space += m->m_len; 613 if (m->m_next == 0) 614 break; 615 } 616 n = m; /* save pointer to last control buffer */ 617 for (m = m0; m; m = m->m_next) 618 space += m->m_len; 619 if (space > sbspace(sb)) 620 return (0); 621 n->m_next = m0; /* concatenate data to control */ 622 for (m = control; m; m = m->m_next) 623 sballoc(sb, m); 624 if ((n = sb->sb_mb) != NULL) { 625 while (n->m_nextpkt) 626 n = n->m_nextpkt; 627 n->m_nextpkt = control; 628 } else 629 sb->sb_mb = control; 630 return (1); 631 } 632 633 /* 634 * Compress mbuf chain m into the socket 635 * buffer sb following mbuf n. If n 636 * is null, the buffer is presumed empty. 637 */ 638 void 639 sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n) 640 { 641 int eor; 642 struct mbuf *o; 643 644 eor = 0; 645 while (m) { 646 eor |= m->m_flags & M_EOR; 647 if (m->m_len == 0 && 648 (eor == 0 || 649 (((o = m->m_next) || (o = n)) && 650 o->m_type == m->m_type))) { 651 m = m_free(m); 652 continue; 653 } 654 if (n && (n->m_flags & M_EOR) == 0 && n->m_type == m->m_type && 655 (((n->m_flags & M_EXT) == 0 && 656 n->m_data + n->m_len + m->m_len <= &n->m_dat[MLEN]) || 657 ((~n->m_flags & (M_EXT|M_CLUSTER)) == 0 && 658 !MCLISREFERENCED(n) && 659 n->m_data + n->m_len + m->m_len <= 660 &n->m_ext.ext_buf[MCLBYTES]))) { 661 memcpy(mtod(n, caddr_t) + n->m_len, mtod(m, caddr_t), 662 (unsigned)m->m_len); 663 n->m_len += m->m_len; 664 sb->sb_cc += m->m_len; 665 m = m_free(m); 666 continue; 667 } 668 if (n) 669 n->m_next = m; 670 else 671 sb->sb_mb = m; 672 sballoc(sb, m); 673 n = m; 674 m->m_flags &= ~M_EOR; 675 m = m->m_next; 676 n->m_next = 0; 677 } 678 if (eor) { 679 if (n) 680 n->m_flags |= eor; 681 else 682 printf("semi-panic: sbcompress\n"); 683 } 684 } 685 686 /* 687 * Free all mbufs in a sockbuf. 688 * Check that all resources are reclaimed. 689 */ 690 void 691 sbflush(struct sockbuf *sb) 692 { 693 694 if (sb->sb_flags & SB_LOCK) 695 panic("sbflush"); 696 while (sb->sb_mbcnt) 697 sbdrop(sb, (int)sb->sb_cc); 698 if (sb->sb_cc || sb->sb_mb) 699 panic("sbflush 2"); 700 } 701 702 /* 703 * Drop data from (the front of) a sockbuf. 704 */ 705 void 706 sbdrop(struct sockbuf *sb, int len) 707 { 708 struct mbuf *m, *mn, *next; 709 710 next = (m = sb->sb_mb) ? m->m_nextpkt : 0; 711 while (len > 0) { 712 if (m == 0) { 713 if (next == 0) 714 panic("sbdrop"); 715 m = next; 716 next = m->m_nextpkt; 717 continue; 718 } 719 if (m->m_len > len) { 720 m->m_len -= len; 721 m->m_data += len; 722 sb->sb_cc -= len; 723 break; 724 } 725 len -= m->m_len; 726 sbfree(sb, m); 727 MFREE(m, mn); 728 m = mn; 729 } 730 while (m && m->m_len == 0) { 731 sbfree(sb, m); 732 MFREE(m, mn); 733 m = mn; 734 } 735 if (m) { 736 sb->sb_mb = m; 737 m->m_nextpkt = next; 738 } else 739 sb->sb_mb = next; 740 } 741 742 /* 743 * Drop a record off the front of a sockbuf 744 * and move the next record to the front. 745 */ 746 void 747 sbdroprecord(struct sockbuf *sb) 748 { 749 struct mbuf *m, *mn; 750 751 m = sb->sb_mb; 752 if (m) { 753 sb->sb_mb = m->m_nextpkt; 754 do { 755 sbfree(sb, m); 756 MFREE(m, mn); 757 } while ((m = mn) != NULL); 758 } 759 } 760 761 /* 762 * Create a "control" mbuf containing the specified data 763 * with the specified type for presentation on a socket buffer. 764 */ 765 struct mbuf * 766 sbcreatecontrol(caddr_t p, int size, int type, int level) 767 { 768 struct cmsghdr *cp; 769 struct mbuf *m; 770 771 if (CMSG_SPACE(size) > MCLBYTES) { 772 printf("sbcreatecontrol: message too large %d\n", size); 773 return NULL; 774 } 775 776 if ((m = m_get(M_DONTWAIT, MT_CONTROL)) == NULL) 777 return ((struct mbuf *) NULL); 778 if (CMSG_SPACE(size) > MLEN) { 779 MCLGET(m, M_DONTWAIT); 780 if ((m->m_flags & M_EXT) == 0) { 781 m_free(m); 782 return NULL; 783 } 784 } 785 cp = mtod(m, struct cmsghdr *); 786 memcpy(CMSG_DATA(cp), p, size); 787 m->m_len = CMSG_SPACE(size); 788 cp->cmsg_len = CMSG_LEN(size); 789 cp->cmsg_level = level; 790 cp->cmsg_type = type; 791 return (m); 792 } 793