123431Smckusick /* 235385Skarels * Copyright (c) 1982, 1986, 1988 Regents of the University of California. 333187Sbostic * All rights reserved. 423431Smckusick * 533187Sbostic * Redistribution and use in source and binary forms are permitted 634858Sbostic * provided that the above copyright notice and this paragraph are 734858Sbostic * duplicated in all such forms and that any documentation, 834858Sbostic * advertising materials, and other materials related to such 934858Sbostic * distribution and use acknowledge that the software was developed 1034858Sbostic * by the University of California, Berkeley. The name of the 1134858Sbostic * University may not be used to endorse or promote products derived 1234858Sbostic * from this software without specific prior written permission. 1334858Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434858Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1534858Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1633187Sbostic * 17*37329Skarels * @(#)uipc_socket2.c 7.8 (Berkeley) 04/08/89 1823431Smckusick */ 194903Swnj 2017103Sbloom #include "param.h" 2117103Sbloom #include "systm.h" 2217103Sbloom #include "dir.h" 2317103Sbloom #include "user.h" 2417103Sbloom #include "proc.h" 2517103Sbloom #include "file.h" 2617103Sbloom #include "inode.h" 2717103Sbloom #include "buf.h" 2835385Skarels #include "malloc.h" 2917103Sbloom #include "mbuf.h" 3017103Sbloom #include "protosw.h" 3117103Sbloom #include "socket.h" 3217103Sbloom #include "socketvar.h" 334903Swnj 344903Swnj /* 354903Swnj * Primitive routines for operating on sockets and socket buffers 364903Swnj */ 374903Swnj 384903Swnj /* 394903Swnj * Procedures to manipulate state flags of socket 407509Sroot * and do appropriate wakeups. Normal sequence from the 417509Sroot * active (originating) side is that soisconnecting() is 427509Sroot * called during processing of connect() call, 435169Swnj * resulting in an eventual call to soisconnected() if/when the 445169Swnj * connection is established. When the connection is torn down 455169Swnj * soisdisconnecting() is called during processing of disconnect() call, 465169Swnj * and soisdisconnected() is called when the connection to the peer 475169Swnj * is totally severed. The semantics of these routines are such that 485169Swnj * connectionless protocols can call soisconnected() and soisdisconnected() 495169Swnj * only, bypassing the in-progress calls when setting up a ``connection'' 505169Swnj * takes no time. 515169Swnj * 5212758Ssam * From the passive side, a socket is created with 5312758Ssam * two queues of sockets: so_q0 for connections in progress 547509Sroot * and so_q for connections already made and awaiting user acceptance. 557509Sroot * As a protocol is preparing incoming connections, it creates a socket 567509Sroot * structure queued on so_q0 by calling sonewconn(). When the connection 577509Sroot * is established, soisconnected() is called, and transfers the 587509Sroot * socket structure to so_q, making it available to accept(). 597509Sroot * 6012758Ssam * If a socket is closed with sockets on either 617509Sroot * so_q0 or so_q, these sockets are dropped. 627509Sroot * 6312758Ssam * If higher level protocols are implemented in 645169Swnj * the kernel, the wakeups done here will sometimes 6512758Ssam * cause software-interrupt process scheduling. 664903Swnj */ 675169Swnj 684903Swnj soisconnecting(so) 6912758Ssam register struct socket *so; 704903Swnj { 714903Swnj 724903Swnj so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING); 734903Swnj so->so_state |= SS_ISCONNECTING; 744903Swnj wakeup((caddr_t)&so->so_timeo); 754903Swnj } 764903Swnj 774903Swnj soisconnected(so) 7812758Ssam register struct socket *so; 794903Swnj { 807509Sroot register struct socket *head = so->so_head; 814903Swnj 827509Sroot if (head) { 837509Sroot if (soqremque(so, 0) == 0) 847509Sroot panic("soisconnected"); 857509Sroot soqinsque(head, so, 1); 8612758Ssam sorwakeup(head); 877509Sroot wakeup((caddr_t)&head->so_timeo); 887509Sroot } 894903Swnj so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING); 904903Swnj so->so_state |= SS_ISCONNECTED; 914903Swnj wakeup((caddr_t)&so->so_timeo); 925578Swnj sorwakeup(so); 935578Swnj sowwakeup(so); 944903Swnj } 954903Swnj 964903Swnj soisdisconnecting(so) 9712758Ssam register struct socket *so; 984903Swnj { 994903Swnj 1005248Sroot so->so_state &= ~SS_ISCONNECTING; 1014903Swnj so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE); 1024903Swnj wakeup((caddr_t)&so->so_timeo); 1035170Swnj sowwakeup(so); 1045169Swnj sorwakeup(so); 1054903Swnj } 1064903Swnj 1074903Swnj soisdisconnected(so) 10812758Ssam register struct socket *so; 1094903Swnj { 1104903Swnj 1114903Swnj so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING); 1124903Swnj so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE); 1134903Swnj wakeup((caddr_t)&so->so_timeo); 1144903Swnj sowwakeup(so); 1154903Swnj sorwakeup(so); 1164903Swnj } 1174903Swnj 1185169Swnj /* 1197509Sroot * When an attempt at a new connection is noted on a socket 1207509Sroot * which accepts connections, sonewconn is called. If the 1217509Sroot * connection is possible (subject to space constraints, etc.) 1227509Sroot * then we allocate a new structure, propoerly linked into the 1237509Sroot * data structure of the original socket, and return this. 1247509Sroot */ 1257509Sroot struct socket * 1267509Sroot sonewconn(head) 1277509Sroot register struct socket *head; 1287509Sroot { 1297509Sroot register struct socket *so; 1307509Sroot 1317509Sroot if (head->so_qlen + head->so_q0len > 3 * head->so_qlimit / 2) 132*37329Skarels return ((struct socket *)0); 133*37329Skarels MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_DONTWAIT); 134*37329Skarels if (so == NULL) 135*37329Skarels return ((struct socket *)0); 136*37329Skarels bzero((caddr_t)so, sizeof(*so)); 1377509Sroot so->so_type = head->so_type; 1387509Sroot so->so_options = head->so_options &~ SO_ACCEPTCONN; 1397509Sroot so->so_linger = head->so_linger; 14010204Ssam so->so_state = head->so_state | SS_NOFDREF; 1417509Sroot so->so_proto = head->so_proto; 1427509Sroot so->so_timeo = head->so_timeo; 14335804Smarc so->so_pgid = head->so_pgid; 14435385Skarels (void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat); 1457509Sroot soqinsque(head, so, 0); 14612758Ssam if ((*so->so_proto->pr_usrreq)(so, PRU_ATTACH, 14712758Ssam (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0)) { 1487509Sroot (void) soqremque(so, 0); 149*37329Skarels (void) free((caddr_t)so, M_SOCKET); 150*37329Skarels return ((struct socket *)0); 1517509Sroot } 1527509Sroot return (so); 1537509Sroot } 1547509Sroot 1557509Sroot soqinsque(head, so, q) 1567509Sroot register struct socket *head, *so; 1577509Sroot int q; 1587509Sroot { 1597509Sroot 1607509Sroot so->so_head = head; 1617509Sroot if (q == 0) { 1627509Sroot head->so_q0len++; 1637509Sroot so->so_q0 = head->so_q0; 1647509Sroot head->so_q0 = so; 1657509Sroot } else { 1667509Sroot head->so_qlen++; 1677509Sroot so->so_q = head->so_q; 1687509Sroot head->so_q = so; 1697509Sroot } 1707509Sroot } 1717509Sroot 1727509Sroot soqremque(so, q) 1737509Sroot register struct socket *so; 1747509Sroot int q; 1757509Sroot { 1767509Sroot register struct socket *head, *prev, *next; 1777509Sroot 1787509Sroot head = so->so_head; 1797509Sroot prev = head; 1807509Sroot for (;;) { 1817509Sroot next = q ? prev->so_q : prev->so_q0; 1827509Sroot if (next == so) 1837509Sroot break; 1847509Sroot if (next == head) 1857509Sroot return (0); 1867509Sroot prev = next; 1877509Sroot } 1887509Sroot if (q == 0) { 1897509Sroot prev->so_q0 = next->so_q0; 1907509Sroot head->so_q0len--; 1917509Sroot } else { 1927509Sroot prev->so_q = next->so_q; 1937509Sroot head->so_qlen--; 1947509Sroot } 1957509Sroot next->so_q0 = next->so_q = 0; 1967509Sroot next->so_head = 0; 1977509Sroot return (1); 1987509Sroot } 1997509Sroot 2007509Sroot /* 2015169Swnj * Socantsendmore indicates that no more data will be sent on the 2025169Swnj * socket; it would normally be applied to a socket when the user 2035169Swnj * informs the system that no more data is to be sent, by the protocol 2045169Swnj * code (in case PRU_SHUTDOWN). Socantrcvmore indicates that no more data 2055169Swnj * will be received, and will normally be applied to the socket by a 2065169Swnj * protocol when it detects that the peer will send no more data. 2075169Swnj * Data queued for reading in the socket may yet be read. 2085169Swnj */ 2095169Swnj 2104917Swnj socantsendmore(so) 2114917Swnj struct socket *so; 2124917Swnj { 2134917Swnj 2144917Swnj so->so_state |= SS_CANTSENDMORE; 2154917Swnj sowwakeup(so); 2164917Swnj } 2174917Swnj 2184917Swnj socantrcvmore(so) 2194917Swnj struct socket *so; 2204917Swnj { 2214917Swnj 2224917Swnj so->so_state |= SS_CANTRCVMORE; 2234917Swnj sorwakeup(so); 2244917Swnj } 2254917Swnj 2264903Swnj /* 2275169Swnj * Socket select/wakeup routines. 2284903Swnj */ 2295169Swnj 2305169Swnj /* 2314903Swnj * Queue a process for a select on a socket buffer. 2324903Swnj */ 2334903Swnj sbselqueue(sb) 2344903Swnj struct sockbuf *sb; 2354903Swnj { 23635385Skarels struct proc *p; 2374903Swnj 2384917Swnj if ((p = sb->sb_sel) && p->p_wchan == (caddr_t)&selwait) 2394903Swnj sb->sb_flags |= SB_COLL; 2404903Swnj else 2414903Swnj sb->sb_sel = u.u_procp; 2424903Swnj } 2434903Swnj 2444903Swnj /* 2454917Swnj * Wait for data to arrive at/drain from a socket buffer. 2464917Swnj */ 2474917Swnj sbwait(sb) 2484917Swnj struct sockbuf *sb; 2494917Swnj { 2504917Swnj 2514917Swnj sb->sb_flags |= SB_WAIT; 2524917Swnj sleep((caddr_t)&sb->sb_cc, PZERO+1); 2534917Swnj } 2544917Swnj 2554917Swnj /* 2564903Swnj * Wakeup processes waiting on a socket buffer. 25735385Skarels * Do asynchronous notification via SIGIO 25835385Skarels * if the socket has the SS_ASYNC flag set. 2594903Swnj */ 26035385Skarels sowakeup(so, sb) 26135385Skarels register struct socket *so; 26212758Ssam register struct sockbuf *sb; 2634903Swnj { 264*37329Skarels struct proc *p; 2654903Swnj 2664903Swnj if (sb->sb_sel) { 2674903Swnj selwakeup(sb->sb_sel, sb->sb_flags & SB_COLL); 2684903Swnj sb->sb_sel = 0; 2694903Swnj sb->sb_flags &= ~SB_COLL; 2704903Swnj } 2714903Swnj if (sb->sb_flags & SB_WAIT) { 2724903Swnj sb->sb_flags &= ~SB_WAIT; 2735013Swnj wakeup((caddr_t)&sb->sb_cc); 2744903Swnj } 27515829Scooper if (so->so_state & SS_ASYNC) { 27635804Smarc if (so->so_pgid < 0) 27735804Smarc gsignal(-so->so_pgid, SIGIO); 27835804Smarc else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0) 27915829Scooper psignal(p, SIGIO); 28015829Scooper } 28115829Scooper } 28215829Scooper 28315829Scooper /* 2845169Swnj * Socket buffer (struct sockbuf) utility routines. 2855169Swnj * 2865169Swnj * Each socket contains two socket buffers: one for sending data and 2875169Swnj * one for receiving data. Each buffer contains a queue of mbufs, 2885169Swnj * information about the number of mbufs and amount of data in the 2895169Swnj * queue, and other fields allowing select() statements and notification 2905169Swnj * on data availability to be implemented. 2915169Swnj * 29216994Skarels * Data stored in a socket buffer is maintained as a list of records. 29316994Skarels * Each record is a list of mbufs chained together with the m_next 29435385Skarels * field. Records are chained together with the m_nextpkt field. The upper 29516994Skarels * level routine soreceive() expects the following conventions to be 29616994Skarels * observed when placing information in the receive buffer: 29716994Skarels * 29816994Skarels * 1. If the protocol requires each message be preceded by the sender's 29916994Skarels * name, then a record containing that name must be present before 30016994Skarels * any associated data (mbuf's must be of type MT_SONAME). 30116994Skarels * 2. If the protocol supports the exchange of ``access rights'' (really 30216994Skarels * just additional data associated with the message), and there are 30316994Skarels * ``rights'' to be received, then a record containing this data 30416994Skarels * should be present (mbuf's must be of type MT_RIGHTS). 30516994Skarels * 3. If a name or rights record exists, then it must be followed by 30616994Skarels * a data record, perhaps of zero length. 30716994Skarels * 3085169Swnj * Before using a new socket structure it is first necessary to reserve 30933406Skarels * buffer space to the socket, by calling sbreserve(). This should commit 3105169Swnj * some of the available buffer space in the system buffer pool for the 31133406Skarels * socket (currently, it does nothing but enforce limits). The space 31233406Skarels * should be released by calling sbrelease() when the socket is destroyed. 3135169Swnj */ 3145169Swnj 3159027Sroot soreserve(so, sndcc, rcvcc) 31612758Ssam register struct socket *so; 31733406Skarels u_long sndcc, rcvcc; 3189027Sroot { 3199027Sroot 3209027Sroot if (sbreserve(&so->so_snd, sndcc) == 0) 3219027Sroot goto bad; 3229027Sroot if (sbreserve(&so->so_rcv, rcvcc) == 0) 3239027Sroot goto bad2; 3249027Sroot return (0); 3259027Sroot bad2: 3269027Sroot sbrelease(&so->so_snd); 3279027Sroot bad: 3289027Sroot return (ENOBUFS); 3299027Sroot } 3309027Sroot 3315169Swnj /* 3324903Swnj * Allot mbufs to a sockbuf. 33326830Skarels * Attempt to scale cc so that mbcnt doesn't become limiting 33426830Skarels * if buffering efficiency is near the normal case. 3354903Swnj */ 3364903Swnj sbreserve(sb, cc) 3374903Swnj struct sockbuf *sb; 33833406Skarels u_long cc; 3394903Swnj { 3404903Swnj 34135385Skarels if (cc > (u_long)SB_MAX * MCLBYTES / (2 * MSIZE + MCLBYTES)) 34217355Skarels return (0); 3434980Swnj sb->sb_hiwat = cc; 34417417Skarels sb->sb_mbmax = MIN(cc * 2, SB_MAX); 3454917Swnj return (1); 3464903Swnj } 3474903Swnj 3484903Swnj /* 3494903Swnj * Free mbufs held by a socket, and reserved mbuf space. 3504903Swnj */ 3514903Swnj sbrelease(sb) 3524903Swnj struct sockbuf *sb; 3534903Swnj { 3544903Swnj 3554903Swnj sbflush(sb); 3564980Swnj sb->sb_hiwat = sb->sb_mbmax = 0; 3574903Swnj } 3584903Swnj 3594903Swnj /* 36016994Skarels * Routines to add and remove 36116994Skarels * data from an mbuf queue. 36225630Skarels * 36325630Skarels * The routines sbappend() or sbappendrecord() are normally called to 36425630Skarels * append new mbufs to a socket buffer, after checking that adequate 36525630Skarels * space is available, comparing the function sbspace() with the amount 36625630Skarels * of data to be added. sbappendrecord() differs from sbappend() in 36725630Skarels * that data supplied is treated as the beginning of a new record. 36825630Skarels * To place a sender's address, optional access rights, and data in a 36925630Skarels * socket receive buffer, sbappendaddr() should be used. To place 37025630Skarels * access rights and data in a socket receive buffer, sbappendrights() 37125630Skarels * should be used. In either case, the new data begins a new record. 37225630Skarels * Note that unlike sbappend() and sbappendrecord(), these routines check 37325630Skarels * for the caller that there will be enough space to store the data. 37425630Skarels * Each fails if there is not enough space, or if it cannot find mbufs 37525630Skarels * to store additional information in. 37625630Skarels * 37725630Skarels * Reliable protocols may use the socket send buffer to hold data 37825630Skarels * awaiting acknowledgement. Data is normally copied from a socket 37925630Skarels * send buffer in a protocol with m_copy for output to a peer, 38025630Skarels * and then removing the data from the socket buffer with sbdrop() 38125630Skarels * or sbdroprecord() when the data is acknowledged by the peer. 3824903Swnj */ 3834903Swnj 3844903Swnj /* 38516994Skarels * Append mbuf chain m to the last record in the 38616994Skarels * socket buffer sb. The additional space associated 38716994Skarels * the mbuf chain is recorded in sb. Empty mbufs are 38816994Skarels * discarded and mbufs are compacted where possible. 3894903Swnj */ 3904903Swnj sbappend(sb, m) 39116994Skarels struct sockbuf *sb; 39216994Skarels struct mbuf *m; 3934903Swnj { 3946092Sroot register struct mbuf *n; 3954903Swnj 39616994Skarels if (m == 0) 39716994Skarels return; 39816994Skarels if (n = sb->sb_mb) { 39935385Skarels while (n->m_nextpkt) 40035385Skarels n = n->m_nextpkt; 4016092Sroot while (n->m_next) 4026092Sroot n = n->m_next; 4034903Swnj } 40416994Skarels sbcompress(sb, m, n); 4054903Swnj } 4064903Swnj 4075169Swnj /* 40816994Skarels * As above, except the mbuf chain 40916994Skarels * begins a new record. 4105169Swnj */ 41116994Skarels sbappendrecord(sb, m0) 41216994Skarels register struct sockbuf *sb; 41316994Skarels register struct mbuf *m0; 4144928Swnj { 4154928Swnj register struct mbuf *m; 4164928Swnj 41716994Skarels if (m0 == 0) 41816994Skarels return; 41916994Skarels if (m = sb->sb_mb) 42035385Skarels while (m->m_nextpkt) 42135385Skarels m = m->m_nextpkt; 42216994Skarels /* 42316994Skarels * Put the first mbuf on the queue. 42416994Skarels * Note this permits zero length records. 42516994Skarels */ 42616994Skarels sballoc(sb, m0); 42716994Skarels if (m) 42835385Skarels m->m_nextpkt = m0; 42916994Skarels else 43016994Skarels sb->sb_mb = m0; 43116994Skarels m = m0->m_next; 43216994Skarels m0->m_next = 0; 433*37329Skarels if (m && (m0->m_flags & M_EOR)) { 434*37329Skarels m0->m_flags &= ~M_EOR; 435*37329Skarels m->m_flags |= M_EOR; 436*37329Skarels } 43716994Skarels sbcompress(sb, m, m0); 43816994Skarels } 43916994Skarels 44016994Skarels /* 441*37329Skarels * As above except that OOB data 442*37329Skarels * is inserted at the beginning of the sockbuf, 443*37329Skarels * but after any other OOB data. 444*37329Skarels */ 445*37329Skarels sbinsertoob(sb, m0) 446*37329Skarels register struct sockbuf *sb; 447*37329Skarels register struct mbuf *m0; 448*37329Skarels { 449*37329Skarels register struct mbuf *m; 450*37329Skarels register struct mbuf **mp; 451*37329Skarels 452*37329Skarels if (m0 == 0) 453*37329Skarels return; 454*37329Skarels for (mp = &sb->sb_mb; m = *mp; mp = &((*mp)->m_nextpkt)) { 455*37329Skarels again: 456*37329Skarels switch (m->m_type) { 457*37329Skarels 458*37329Skarels case MT_OOBDATA: 459*37329Skarels continue; /* WANT next train */ 460*37329Skarels 461*37329Skarels case MT_CONTROL: 462*37329Skarels if (m = m->m_next) 463*37329Skarels goto again; /* inspect THIS train further */ 464*37329Skarels } 465*37329Skarels break; 466*37329Skarels } 467*37329Skarels /* 468*37329Skarels * Put the first mbuf on the queue. 469*37329Skarels * Note this permits zero length records. 470*37329Skarels */ 471*37329Skarels sballoc(sb, m0); 472*37329Skarels m0->m_nextpkt = *mp; 473*37329Skarels *mp = m0; 474*37329Skarels m = m0->m_next; 475*37329Skarels m0->m_next = 0; 476*37329Skarels if (m && (m0->m_flags & M_EOR)) { 477*37329Skarels m0->m_flags &= ~M_EOR; 478*37329Skarels m->m_flags |= M_EOR; 479*37329Skarels } 480*37329Skarels sbcompress(sb, m, m0); 481*37329Skarels } 482*37329Skarels 483*37329Skarels /* 48416994Skarels * Append address and data, and optionally, rights 48535385Skarels * to the receive queue of a socket. If present, 48635385Skarels * m0 Return 0 if 48716994Skarels * no space in sockbuf or insufficient mbufs. 48816994Skarels */ 48925630Skarels sbappendaddr(sb, asa, m0, rights0) 49016994Skarels register struct sockbuf *sb; 49116994Skarels struct sockaddr *asa; 49235385Skarels struct mbuf *m0, *rights0; 49316994Skarels { 49416994Skarels register struct mbuf *m, *n; 495*37329Skarels int space = asa->sa_len; 49616994Skarels 49735385Skarels if (m0 && (m0->m_flags & M_PKTHDR) == 0) 49835385Skarels panic("sbappendaddr"); 49935385Skarels if (m0) 50035385Skarels space += m0->m_pkthdr.len; 50116994Skarels if (rights0) 50216994Skarels space += rights0->m_len; 50316994Skarels if (space > sbspace(sb)) 5044928Swnj return (0); 50525630Skarels MGET(m, M_DONTWAIT, MT_SONAME); 50616994Skarels if (m == 0) 5074928Swnj return (0); 508*37329Skarels if (asa->sa_len > MLEN) { 509*37329Skarels (void) m_free(m); 510*37329Skarels return (0); 511*37329Skarels } 512*37329Skarels m->m_len = asa->sa_len; 513*37329Skarels bcopy((caddr_t)asa, mtod(m, caddr_t), asa->sa_len); 51425921Skarels if (rights0 && rights0->m_len) { 51525630Skarels m->m_next = m_copy(rights0, 0, rights0->m_len); 51625630Skarels if (m->m_next == 0) { 51716994Skarels m_freem(m); 51816994Skarels return (0); 51916994Skarels } 52025630Skarels sballoc(sb, m->m_next); 52121765Skarels } 52225938Skarels sballoc(sb, m); 52316994Skarels if (n = sb->sb_mb) { 52435385Skarels while (n->m_nextpkt) 52535385Skarels n = n->m_nextpkt; 52635385Skarels n->m_nextpkt = m; 52716994Skarels } else 52816994Skarels sb->sb_mb = m; 52925630Skarels if (m->m_next) 53025630Skarels m = m->m_next; 53125630Skarels if (m0) 53225630Skarels sbcompress(sb, m0, m); 53316994Skarels return (1); 53416994Skarels } 53516994Skarels 53625630Skarels sbappendrights(sb, m0, rights) 53716994Skarels struct sockbuf *sb; 53825630Skarels struct mbuf *rights, *m0; 53916994Skarels { 54016994Skarels register struct mbuf *m, *n; 54116994Skarels int space = 0; 54216994Skarels 54325630Skarels if (rights == 0) 54416994Skarels panic("sbappendrights"); 54525630Skarels for (m = m0; m; m = m->m_next) 54616994Skarels space += m->m_len; 54716994Skarels space += rights->m_len; 54816994Skarels if (space > sbspace(sb)) 54912758Ssam return (0); 55016994Skarels m = m_copy(rights, 0, rights->m_len); 55116994Skarels if (m == 0) 55216994Skarels return (0); 55316994Skarels sballoc(sb, m); 55416994Skarels if (n = sb->sb_mb) { 55535385Skarels while (n->m_nextpkt) 55635385Skarels n = n->m_nextpkt; 55735385Skarels n->m_nextpkt = m; 55816994Skarels } else 55925630Skarels sb->sb_mb = m; 56025630Skarels if (m0) 56125630Skarels sbcompress(sb, m0, m); 5624928Swnj return (1); 5634928Swnj } 5644928Swnj 5654903Swnj /* 56616994Skarels * Compress mbuf chain m into the socket 56716994Skarels * buffer sb following mbuf n. If n 56816994Skarels * is null, the buffer is presumed empty. 5694903Swnj */ 57016994Skarels sbcompress(sb, m, n) 57116994Skarels register struct sockbuf *sb; 57216994Skarels register struct mbuf *m, *n; 57316994Skarels { 57416994Skarels 575*37329Skarels register int eor = 0; 57616994Skarels while (m) { 577*37329Skarels eor |= m->m_flags & M_EOR; 57816994Skarels if (m->m_len == 0) { 57916994Skarels m = m_free(m); 58016994Skarels continue; 58116994Skarels } 582*37329Skarels if (n && (n->m_flags & (M_EXT | M_EOR)) == 0 && 58335385Skarels (n->m_data + n->m_len + m->m_len) < &n->m_dat[MLEN] && 58425630Skarels n->m_type == m->m_type) { 58516994Skarels bcopy(mtod(m, caddr_t), mtod(n, caddr_t) + n->m_len, 58616994Skarels (unsigned)m->m_len); 58716994Skarels n->m_len += m->m_len; 58816994Skarels sb->sb_cc += m->m_len; 58916994Skarels m = m_free(m); 59016994Skarels continue; 59116994Skarels } 59216994Skarels if (n) 59316994Skarels n->m_next = m; 59416994Skarels else 59516994Skarels sb->sb_mb = m; 596*37329Skarels sballoc(sb, m); 59716994Skarels n = m; 598*37329Skarels m->m_flags &= ~M_EOR; 59916994Skarels m = m->m_next; 60016994Skarels n->m_next = 0; 60116994Skarels } 602*37329Skarels if (n) 603*37329Skarels n->m_flags |= eor; 60416994Skarels } 60516994Skarels 60616994Skarels /* 60716994Skarels * Free all mbufs in a sockbuf. 60816994Skarels * Check that all resources are reclaimed. 60916994Skarels */ 6104903Swnj sbflush(sb) 61112758Ssam register struct sockbuf *sb; 6124903Swnj { 6134903Swnj 6144903Swnj if (sb->sb_flags & SB_LOCK) 6154903Swnj panic("sbflush"); 61626105Skarels while (sb->sb_mbcnt) 61726363Skarels sbdrop(sb, (int)sb->sb_cc); 6184903Swnj if (sb->sb_cc || sb->sb_mbcnt || sb->sb_mb) 6194903Swnj panic("sbflush 2"); 6204903Swnj } 6214903Swnj 6224903Swnj /* 62316994Skarels * Drop data from (the front of) a sockbuf. 6244903Swnj */ 6254903Swnj sbdrop(sb, len) 6264903Swnj register struct sockbuf *sb; 6274903Swnj register int len; 6284903Swnj { 62916994Skarels register struct mbuf *m, *mn; 63016994Skarels struct mbuf *next; 6314903Swnj 63235385Skarels next = (m = sb->sb_mb) ? m->m_nextpkt : 0; 6334903Swnj while (len > 0) { 63416994Skarels if (m == 0) { 63516994Skarels if (next == 0) 63616994Skarels panic("sbdrop"); 63716994Skarels m = next; 63835385Skarels next = m->m_nextpkt; 63916994Skarels continue; 64016994Skarels } 6415064Swnj if (m->m_len > len) { 6424903Swnj m->m_len -= len; 64335385Skarels m->m_data += len; 6444903Swnj sb->sb_cc -= len; 6454903Swnj break; 6464903Swnj } 6475064Swnj len -= m->m_len; 6485064Swnj sbfree(sb, m); 6495064Swnj MFREE(m, mn); 6505064Swnj m = mn; 6514903Swnj } 65217331Skarels while (m && m->m_len == 0) { 65317417Skarels sbfree(sb, m); 65417331Skarels MFREE(m, mn); 65517331Skarels m = mn; 65617331Skarels } 65716994Skarels if (m) { 65816994Skarels sb->sb_mb = m; 65935385Skarels m->m_nextpkt = next; 66016994Skarels } else 66116994Skarels sb->sb_mb = next; 6624903Swnj } 66316994Skarels 66416994Skarels /* 66516994Skarels * Drop a record off the front of a sockbuf 66616994Skarels * and move the next record to the front. 66716994Skarels */ 66816994Skarels sbdroprecord(sb) 66916994Skarels register struct sockbuf *sb; 67016994Skarels { 67116994Skarels register struct mbuf *m, *mn; 67216994Skarels 67316994Skarels m = sb->sb_mb; 67416994Skarels if (m) { 67535385Skarels sb->sb_mb = m->m_nextpkt; 67616994Skarels do { 67716994Skarels sbfree(sb, m); 67816994Skarels MFREE(m, mn); 67916994Skarels } while (m = mn); 68016994Skarels } 68116994Skarels } 682