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*40633Skarels * @(#)uipc_socket2.c 7.10 (Berkeley) 03/25/90 1823431Smckusick */ 194903Swnj 2017103Sbloom #include "param.h" 2117103Sbloom #include "systm.h" 2217103Sbloom #include "user.h" 2317103Sbloom #include "proc.h" 2417103Sbloom #include "file.h" 2517103Sbloom #include "buf.h" 2635385Skarels #include "malloc.h" 2717103Sbloom #include "mbuf.h" 2817103Sbloom #include "protosw.h" 2917103Sbloom #include "socket.h" 3017103Sbloom #include "socketvar.h" 31*40633Skarels #include "tsleep.h" 324903Swnj 334903Swnj /* 344903Swnj * Primitive routines for operating on sockets and socket buffers 354903Swnj */ 364903Swnj 374903Swnj /* 384903Swnj * Procedures to manipulate state flags of socket 397509Sroot * and do appropriate wakeups. Normal sequence from the 407509Sroot * active (originating) side is that soisconnecting() is 417509Sroot * called during processing of connect() call, 425169Swnj * resulting in an eventual call to soisconnected() if/when the 435169Swnj * connection is established. When the connection is torn down 445169Swnj * soisdisconnecting() is called during processing of disconnect() call, 455169Swnj * and soisdisconnected() is called when the connection to the peer 465169Swnj * is totally severed. The semantics of these routines are such that 475169Swnj * connectionless protocols can call soisconnected() and soisdisconnected() 485169Swnj * only, bypassing the in-progress calls when setting up a ``connection'' 495169Swnj * takes no time. 505169Swnj * 5112758Ssam * From the passive side, a socket is created with 5212758Ssam * two queues of sockets: so_q0 for connections in progress 537509Sroot * and so_q for connections already made and awaiting user acceptance. 547509Sroot * As a protocol is preparing incoming connections, it creates a socket 557509Sroot * structure queued on so_q0 by calling sonewconn(). When the connection 567509Sroot * is established, soisconnected() is called, and transfers the 577509Sroot * socket structure to so_q, making it available to accept(). 587509Sroot * 5912758Ssam * If a socket is closed with sockets on either 607509Sroot * so_q0 or so_q, these sockets are dropped. 617509Sroot * 6212758Ssam * If higher level protocols are implemented in 635169Swnj * the kernel, the wakeups done here will sometimes 6412758Ssam * cause software-interrupt process scheduling. 654903Swnj */ 665169Swnj 674903Swnj soisconnecting(so) 6812758Ssam register struct socket *so; 694903Swnj { 704903Swnj 714903Swnj so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING); 724903Swnj so->so_state |= SS_ISCONNECTING; 734903Swnj } 744903Swnj 754903Swnj soisconnected(so) 7612758Ssam register struct socket *so; 774903Swnj { 787509Sroot register struct socket *head = so->so_head; 794903Swnj 80*40633Skarels so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING); 81*40633Skarels so->so_state |= SS_ISCONNECTED; 82*40633Skarels if (head && soqremque(so, 0)) { 837509Sroot soqinsque(head, so, 1); 8412758Ssam sorwakeup(head); 857509Sroot wakeup((caddr_t)&head->so_timeo); 86*40633Skarels } else { 87*40633Skarels wakeup((caddr_t)&so->so_timeo); 88*40633Skarels sorwakeup(so); 89*40633Skarels sowwakeup(so); 907509Sroot } 914903Swnj } 924903Swnj 934903Swnj soisdisconnecting(so) 9412758Ssam register struct socket *so; 954903Swnj { 964903Swnj 975248Sroot so->so_state &= ~SS_ISCONNECTING; 984903Swnj so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE); 994903Swnj wakeup((caddr_t)&so->so_timeo); 1005170Swnj sowwakeup(so); 1015169Swnj sorwakeup(so); 1024903Swnj } 1034903Swnj 1044903Swnj soisdisconnected(so) 10512758Ssam register struct socket *so; 1064903Swnj { 1074903Swnj 1084903Swnj so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING); 1094903Swnj so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE); 1104903Swnj wakeup((caddr_t)&so->so_timeo); 1114903Swnj sowwakeup(so); 1124903Swnj sorwakeup(so); 1134903Swnj } 1144903Swnj 1155169Swnj /* 1167509Sroot * When an attempt at a new connection is noted on a socket 1177509Sroot * which accepts connections, sonewconn is called. If the 1187509Sroot * connection is possible (subject to space constraints, etc.) 1197509Sroot * then we allocate a new structure, propoerly linked into the 1207509Sroot * data structure of the original socket, and return this. 121*40633Skarels * Connstatus may be 0, or SO_ISCONFIRMING, or SO_ISCONNECTED. 1227509Sroot */ 1237509Sroot struct socket * 124*40633Skarels sonewsock(head, connstatus) 1257509Sroot register struct socket *head; 126*40633Skarels int connstatus; 1277509Sroot { 1287509Sroot register struct socket *so; 129*40633Skarels int soqueue = connstatus ? 1 : 0; 1307509Sroot 1317509Sroot if (head->so_qlen + head->so_q0len > 3 * head->so_qlimit / 2) 13237329Skarels return ((struct socket *)0); 13337329Skarels MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_DONTWAIT); 13437329Skarels if (so == NULL) 13537329Skarels return ((struct socket *)0); 13637329Skarels 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); 145*40633Skarels soqinsque(head, so, soqueue); 14612758Ssam if ((*so->so_proto->pr_usrreq)(so, PRU_ATTACH, 14712758Ssam (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0)) { 148*40633Skarels (void) soqremque(so, soqueue); 14937329Skarels (void) free((caddr_t)so, M_SOCKET); 15037329Skarels return ((struct socket *)0); 1517509Sroot } 152*40633Skarels if (connstatus) { 153*40633Skarels sorwakeup(head); 154*40633Skarels wakeup((caddr_t)&head->so_timeo); 155*40633Skarels so->so_state |= connstatus; 156*40633Skarels } 1577509Sroot return (so); 1587509Sroot } 1597509Sroot 1607509Sroot soqinsque(head, so, q) 1617509Sroot register struct socket *head, *so; 1627509Sroot int q; 1637509Sroot { 164*40633Skarels register struct socket **prev; 1657509Sroot 1667509Sroot so->so_head = head; 1677509Sroot if (q == 0) { 1687509Sroot head->so_q0len++; 169*40633Skarels so->so_q0 = 0; 170*40633Skarels for (prev = &(head->so_q0); *prev; ) 171*40633Skarels prev = &((*prev)->so_q0); 1727509Sroot } else { 1737509Sroot head->so_qlen++; 174*40633Skarels so->so_q = 0; 175*40633Skarels for (prev = &(head->so_q); *prev; ) 176*40633Skarels prev = &((*prev)->so_q); 1777509Sroot } 178*40633Skarels *prev = so; 1797509Sroot } 1807509Sroot 1817509Sroot soqremque(so, q) 1827509Sroot register struct socket *so; 1837509Sroot int q; 1847509Sroot { 1857509Sroot register struct socket *head, *prev, *next; 1867509Sroot 1877509Sroot head = so->so_head; 1887509Sroot prev = head; 1897509Sroot for (;;) { 1907509Sroot next = q ? prev->so_q : prev->so_q0; 1917509Sroot if (next == so) 1927509Sroot break; 193*40633Skarels if (next == 0) 1947509Sroot return (0); 1957509Sroot prev = next; 1967509Sroot } 1977509Sroot if (q == 0) { 1987509Sroot prev->so_q0 = next->so_q0; 1997509Sroot head->so_q0len--; 2007509Sroot } else { 2017509Sroot prev->so_q = next->so_q; 2027509Sroot head->so_qlen--; 2037509Sroot } 2047509Sroot next->so_q0 = next->so_q = 0; 2057509Sroot next->so_head = 0; 2067509Sroot return (1); 2077509Sroot } 2087509Sroot 2097509Sroot /* 2105169Swnj * Socantsendmore indicates that no more data will be sent on the 2115169Swnj * socket; it would normally be applied to a socket when the user 2125169Swnj * informs the system that no more data is to be sent, by the protocol 2135169Swnj * code (in case PRU_SHUTDOWN). Socantrcvmore indicates that no more data 2145169Swnj * will be received, and will normally be applied to the socket by a 2155169Swnj * protocol when it detects that the peer will send no more data. 2165169Swnj * Data queued for reading in the socket may yet be read. 2175169Swnj */ 2185169Swnj 2194917Swnj socantsendmore(so) 2204917Swnj struct socket *so; 2214917Swnj { 2224917Swnj 2234917Swnj so->so_state |= SS_CANTSENDMORE; 2244917Swnj sowwakeup(so); 2254917Swnj } 2264917Swnj 2274917Swnj socantrcvmore(so) 2284917Swnj struct socket *so; 2294917Swnj { 2304917Swnj 2314917Swnj so->so_state |= SS_CANTRCVMORE; 2324917Swnj sorwakeup(so); 2334917Swnj } 2344917Swnj 2354903Swnj /* 2365169Swnj * Socket select/wakeup routines. 2374903Swnj */ 2385169Swnj 2395169Swnj /* 2404903Swnj * Queue a process for a select on a socket buffer. 2414903Swnj */ 2424903Swnj sbselqueue(sb) 2434903Swnj struct sockbuf *sb; 2444903Swnj { 24535385Skarels struct proc *p; 2464903Swnj 2474917Swnj if ((p = sb->sb_sel) && p->p_wchan == (caddr_t)&selwait) 2484903Swnj sb->sb_flags |= SB_COLL; 2494903Swnj else 2504903Swnj sb->sb_sel = u.u_procp; 2514903Swnj } 2524903Swnj 2534903Swnj /* 2544917Swnj * Wait for data to arrive at/drain from a socket buffer. 2554917Swnj */ 2564917Swnj sbwait(sb) 2574917Swnj struct sockbuf *sb; 2584917Swnj { 2594917Swnj 2604917Swnj sb->sb_flags |= SB_WAIT; 261*40633Skarels tsleep((caddr_t)&sb->sb_cc, PZERO+1, SLP_SO_SBWAIT, 0); 2624917Swnj } 2634917Swnj 2644917Swnj /* 2654903Swnj * Wakeup processes waiting on a socket buffer. 26635385Skarels * Do asynchronous notification via SIGIO 26735385Skarels * if the socket has the SS_ASYNC flag set. 2684903Swnj */ 26935385Skarels sowakeup(so, sb) 27035385Skarels register struct socket *so; 27112758Ssam register struct sockbuf *sb; 2724903Swnj { 27337329Skarels struct proc *p; 2744903Swnj 2754903Swnj if (sb->sb_sel) { 2764903Swnj selwakeup(sb->sb_sel, sb->sb_flags & SB_COLL); 2774903Swnj sb->sb_sel = 0; 2784903Swnj sb->sb_flags &= ~SB_COLL; 2794903Swnj } 2804903Swnj if (sb->sb_flags & SB_WAIT) { 2814903Swnj sb->sb_flags &= ~SB_WAIT; 2825013Swnj wakeup((caddr_t)&sb->sb_cc); 2834903Swnj } 28415829Scooper if (so->so_state & SS_ASYNC) { 28535804Smarc if (so->so_pgid < 0) 28635804Smarc gsignal(-so->so_pgid, SIGIO); 28735804Smarc else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0) 28815829Scooper psignal(p, SIGIO); 28915829Scooper } 29015829Scooper } 29115829Scooper 29215829Scooper /* 2935169Swnj * Socket buffer (struct sockbuf) utility routines. 2945169Swnj * 2955169Swnj * Each socket contains two socket buffers: one for sending data and 2965169Swnj * one for receiving data. Each buffer contains a queue of mbufs, 2975169Swnj * information about the number of mbufs and amount of data in the 2985169Swnj * queue, and other fields allowing select() statements and notification 2995169Swnj * on data availability to be implemented. 3005169Swnj * 30116994Skarels * Data stored in a socket buffer is maintained as a list of records. 30216994Skarels * Each record is a list of mbufs chained together with the m_next 30335385Skarels * field. Records are chained together with the m_nextpkt field. The upper 30416994Skarels * level routine soreceive() expects the following conventions to be 30516994Skarels * observed when placing information in the receive buffer: 30616994Skarels * 30716994Skarels * 1. If the protocol requires each message be preceded by the sender's 30816994Skarels * name, then a record containing that name must be present before 30916994Skarels * any associated data (mbuf's must be of type MT_SONAME). 31016994Skarels * 2. If the protocol supports the exchange of ``access rights'' (really 31116994Skarels * just additional data associated with the message), and there are 31216994Skarels * ``rights'' to be received, then a record containing this data 31316994Skarels * should be present (mbuf's must be of type MT_RIGHTS). 31416994Skarels * 3. If a name or rights record exists, then it must be followed by 31516994Skarels * a data record, perhaps of zero length. 31616994Skarels * 3175169Swnj * Before using a new socket structure it is first necessary to reserve 31833406Skarels * buffer space to the socket, by calling sbreserve(). This should commit 3195169Swnj * some of the available buffer space in the system buffer pool for the 32033406Skarels * socket (currently, it does nothing but enforce limits). The space 32133406Skarels * should be released by calling sbrelease() when the socket is destroyed. 3225169Swnj */ 3235169Swnj 3249027Sroot soreserve(so, sndcc, rcvcc) 32512758Ssam register struct socket *so; 32633406Skarels u_long sndcc, rcvcc; 3279027Sroot { 3289027Sroot 3299027Sroot if (sbreserve(&so->so_snd, sndcc) == 0) 3309027Sroot goto bad; 3319027Sroot if (sbreserve(&so->so_rcv, rcvcc) == 0) 3329027Sroot goto bad2; 3339027Sroot return (0); 3349027Sroot bad2: 3359027Sroot sbrelease(&so->so_snd); 3369027Sroot bad: 3379027Sroot return (ENOBUFS); 3389027Sroot } 3399027Sroot 3405169Swnj /* 3414903Swnj * Allot mbufs to a sockbuf. 34226830Skarels * Attempt to scale cc so that mbcnt doesn't become limiting 34326830Skarels * if buffering efficiency is near the normal case. 3444903Swnj */ 3454903Swnj sbreserve(sb, cc) 3464903Swnj struct sockbuf *sb; 34733406Skarels u_long cc; 3484903Swnj { 3494903Swnj 35035385Skarels if (cc > (u_long)SB_MAX * MCLBYTES / (2 * MSIZE + MCLBYTES)) 35117355Skarels return (0); 3524980Swnj sb->sb_hiwat = cc; 35317417Skarels sb->sb_mbmax = MIN(cc * 2, SB_MAX); 3544917Swnj return (1); 3554903Swnj } 3564903Swnj 3574903Swnj /* 3584903Swnj * Free mbufs held by a socket, and reserved mbuf space. 3594903Swnj */ 3604903Swnj sbrelease(sb) 3614903Swnj struct sockbuf *sb; 3624903Swnj { 3634903Swnj 3644903Swnj sbflush(sb); 3654980Swnj sb->sb_hiwat = sb->sb_mbmax = 0; 3664903Swnj } 3674903Swnj 3684903Swnj /* 36916994Skarels * Routines to add and remove 37016994Skarels * data from an mbuf queue. 37125630Skarels * 37225630Skarels * The routines sbappend() or sbappendrecord() are normally called to 37325630Skarels * append new mbufs to a socket buffer, after checking that adequate 37425630Skarels * space is available, comparing the function sbspace() with the amount 37525630Skarels * of data to be added. sbappendrecord() differs from sbappend() in 37625630Skarels * that data supplied is treated as the beginning of a new record. 37725630Skarels * To place a sender's address, optional access rights, and data in a 37825630Skarels * socket receive buffer, sbappendaddr() should be used. To place 37925630Skarels * access rights and data in a socket receive buffer, sbappendrights() 38025630Skarels * should be used. In either case, the new data begins a new record. 38125630Skarels * Note that unlike sbappend() and sbappendrecord(), these routines check 38225630Skarels * for the caller that there will be enough space to store the data. 38325630Skarels * Each fails if there is not enough space, or if it cannot find mbufs 38425630Skarels * to store additional information in. 38525630Skarels * 38625630Skarels * Reliable protocols may use the socket send buffer to hold data 38725630Skarels * awaiting acknowledgement. Data is normally copied from a socket 38825630Skarels * send buffer in a protocol with m_copy for output to a peer, 38925630Skarels * and then removing the data from the socket buffer with sbdrop() 39025630Skarels * or sbdroprecord() when the data is acknowledged by the peer. 3914903Swnj */ 3924903Swnj 3934903Swnj /* 39416994Skarels * Append mbuf chain m to the last record in the 39516994Skarels * socket buffer sb. The additional space associated 39616994Skarels * the mbuf chain is recorded in sb. Empty mbufs are 39716994Skarels * discarded and mbufs are compacted where possible. 3984903Swnj */ 3994903Swnj sbappend(sb, m) 40016994Skarels struct sockbuf *sb; 40116994Skarels struct mbuf *m; 4024903Swnj { 4036092Sroot register struct mbuf *n; 4044903Swnj 40516994Skarels if (m == 0) 40616994Skarels return; 40716994Skarels if (n = sb->sb_mb) { 40835385Skarels while (n->m_nextpkt) 40935385Skarels n = n->m_nextpkt; 4106092Sroot while (n->m_next) 411*40633Skarels if (n->m_flags & M_EOR) { 412*40633Skarels sbappendrecord(sb, m); /* XXXXXX!!!! */ 413*40633Skarels return; 414*40633Skarels } else 415*40633Skarels n = n->m_next; 4164903Swnj } 41716994Skarels sbcompress(sb, m, n); 4184903Swnj } 4194903Swnj 4205169Swnj /* 42116994Skarels * As above, except the mbuf chain 42216994Skarels * begins a new record. 4235169Swnj */ 42416994Skarels sbappendrecord(sb, m0) 42516994Skarels register struct sockbuf *sb; 42616994Skarels register struct mbuf *m0; 4274928Swnj { 4284928Swnj register struct mbuf *m; 4294928Swnj 43016994Skarels if (m0 == 0) 43116994Skarels return; 43216994Skarels if (m = sb->sb_mb) 43335385Skarels while (m->m_nextpkt) 43435385Skarels m = m->m_nextpkt; 43516994Skarels /* 43616994Skarels * Put the first mbuf on the queue. 43716994Skarels * Note this permits zero length records. 43816994Skarels */ 43916994Skarels sballoc(sb, m0); 44016994Skarels if (m) 44135385Skarels m->m_nextpkt = m0; 44216994Skarels else 44316994Skarels sb->sb_mb = m0; 44416994Skarels m = m0->m_next; 44516994Skarels m0->m_next = 0; 44637329Skarels if (m && (m0->m_flags & M_EOR)) { 44737329Skarels m0->m_flags &= ~M_EOR; 44837329Skarels m->m_flags |= M_EOR; 44937329Skarels } 45016994Skarels sbcompress(sb, m, m0); 45116994Skarels } 45216994Skarels 45316994Skarels /* 45437329Skarels * As above except that OOB data 45537329Skarels * is inserted at the beginning of the sockbuf, 45637329Skarels * but after any other OOB data. 45737329Skarels */ 45837329Skarels sbinsertoob(sb, m0) 45937329Skarels register struct sockbuf *sb; 46037329Skarels register struct mbuf *m0; 46137329Skarels { 46237329Skarels register struct mbuf *m; 46337329Skarels register struct mbuf **mp; 46437329Skarels 46537329Skarels if (m0 == 0) 46637329Skarels return; 46737329Skarels for (mp = &sb->sb_mb; m = *mp; mp = &((*mp)->m_nextpkt)) { 46837329Skarels again: 46937329Skarels switch (m->m_type) { 47037329Skarels 47137329Skarels case MT_OOBDATA: 47237329Skarels continue; /* WANT next train */ 47337329Skarels 47437329Skarels case MT_CONTROL: 47537329Skarels if (m = m->m_next) 47637329Skarels goto again; /* inspect THIS train further */ 47737329Skarels } 47837329Skarels break; 47937329Skarels } 48037329Skarels /* 48137329Skarels * Put the first mbuf on the queue. 48237329Skarels * Note this permits zero length records. 48337329Skarels */ 48437329Skarels sballoc(sb, m0); 48537329Skarels m0->m_nextpkt = *mp; 48637329Skarels *mp = m0; 48737329Skarels m = m0->m_next; 48837329Skarels m0->m_next = 0; 48937329Skarels if (m && (m0->m_flags & M_EOR)) { 49037329Skarels m0->m_flags &= ~M_EOR; 49137329Skarels m->m_flags |= M_EOR; 49237329Skarels } 49337329Skarels sbcompress(sb, m, m0); 49437329Skarels } 49537329Skarels 49637329Skarels /* 49716994Skarels * Append address and data, and optionally, rights 49835385Skarels * to the receive queue of a socket. If present, 49935385Skarels * m0 Return 0 if 50016994Skarels * no space in sockbuf or insufficient mbufs. 50116994Skarels */ 50225630Skarels sbappendaddr(sb, asa, m0, rights0) 50316994Skarels register struct sockbuf *sb; 50416994Skarels struct sockaddr *asa; 50535385Skarels struct mbuf *m0, *rights0; 50616994Skarels { 50716994Skarels register struct mbuf *m, *n; 50837329Skarels int space = asa->sa_len; 50916994Skarels 51035385Skarels if (m0 && (m0->m_flags & M_PKTHDR) == 0) 51135385Skarels panic("sbappendaddr"); 51235385Skarels if (m0) 51335385Skarels space += m0->m_pkthdr.len; 51416994Skarels if (rights0) 51516994Skarels space += rights0->m_len; 51616994Skarels if (space > sbspace(sb)) 5174928Swnj return (0); 51825630Skarels MGET(m, M_DONTWAIT, MT_SONAME); 51916994Skarels if (m == 0) 5204928Swnj return (0); 52137329Skarels if (asa->sa_len > MLEN) { 52237329Skarels (void) m_free(m); 52337329Skarels return (0); 52437329Skarels } 52537329Skarels m->m_len = asa->sa_len; 52637329Skarels bcopy((caddr_t)asa, mtod(m, caddr_t), asa->sa_len); 52725921Skarels if (rights0 && rights0->m_len) { 52825630Skarels m->m_next = m_copy(rights0, 0, rights0->m_len); 52925630Skarels if (m->m_next == 0) { 53016994Skarels m_freem(m); 53116994Skarels return (0); 53216994Skarels } 53325630Skarels sballoc(sb, m->m_next); 53421765Skarels } 53525938Skarels sballoc(sb, m); 53616994Skarels if (n = sb->sb_mb) { 53735385Skarels while (n->m_nextpkt) 53835385Skarels n = n->m_nextpkt; 53935385Skarels n->m_nextpkt = m; 54016994Skarels } else 54116994Skarels sb->sb_mb = m; 54225630Skarels if (m->m_next) 54325630Skarels m = m->m_next; 54425630Skarels if (m0) 54525630Skarels sbcompress(sb, m0, m); 54616994Skarels return (1); 54716994Skarels } 54816994Skarels 54925630Skarels sbappendrights(sb, m0, rights) 55016994Skarels struct sockbuf *sb; 55125630Skarels struct mbuf *rights, *m0; 55216994Skarels { 55316994Skarels register struct mbuf *m, *n; 55416994Skarels int space = 0; 55516994Skarels 55625630Skarels if (rights == 0) 55716994Skarels panic("sbappendrights"); 55825630Skarels for (m = m0; m; m = m->m_next) 55916994Skarels space += m->m_len; 56016994Skarels space += rights->m_len; 56116994Skarels if (space > sbspace(sb)) 56212758Ssam return (0); 56316994Skarels m = m_copy(rights, 0, rights->m_len); 56416994Skarels if (m == 0) 56516994Skarels return (0); 56616994Skarels sballoc(sb, m); 56716994Skarels if (n = sb->sb_mb) { 56835385Skarels while (n->m_nextpkt) 56935385Skarels n = n->m_nextpkt; 57035385Skarels n->m_nextpkt = m; 57116994Skarels } else 57225630Skarels sb->sb_mb = m; 57325630Skarels if (m0) 57425630Skarels sbcompress(sb, m0, m); 5754928Swnj return (1); 5764928Swnj } 5774928Swnj 5784903Swnj /* 57916994Skarels * Compress mbuf chain m into the socket 58016994Skarels * buffer sb following mbuf n. If n 58116994Skarels * is null, the buffer is presumed empty. 5824903Swnj */ 58316994Skarels sbcompress(sb, m, n) 58416994Skarels register struct sockbuf *sb; 58516994Skarels register struct mbuf *m, *n; 58616994Skarels { 58716994Skarels 58837329Skarels register int eor = 0; 58916994Skarels while (m) { 59037329Skarels eor |= m->m_flags & M_EOR; 59116994Skarels if (m->m_len == 0) { 59216994Skarels m = m_free(m); 59316994Skarels continue; 59416994Skarels } 59537329Skarels if (n && (n->m_flags & (M_EXT | M_EOR)) == 0 && 59635385Skarels (n->m_data + n->m_len + m->m_len) < &n->m_dat[MLEN] && 59725630Skarels n->m_type == m->m_type) { 59816994Skarels bcopy(mtod(m, caddr_t), mtod(n, caddr_t) + n->m_len, 59916994Skarels (unsigned)m->m_len); 60016994Skarels n->m_len += m->m_len; 60116994Skarels sb->sb_cc += m->m_len; 60216994Skarels m = m_free(m); 60316994Skarels continue; 60416994Skarels } 60516994Skarels if (n) 60616994Skarels n->m_next = m; 60716994Skarels else 60816994Skarels sb->sb_mb = m; 60937329Skarels sballoc(sb, m); 61016994Skarels n = m; 61137329Skarels m->m_flags &= ~M_EOR; 61216994Skarels m = m->m_next; 61316994Skarels n->m_next = 0; 61416994Skarels } 61537329Skarels if (n) 61637329Skarels n->m_flags |= eor; 61716994Skarels } 61816994Skarels 61916994Skarels /* 62016994Skarels * Free all mbufs in a sockbuf. 62116994Skarels * Check that all resources are reclaimed. 62216994Skarels */ 6234903Swnj sbflush(sb) 62412758Ssam register struct sockbuf *sb; 6254903Swnj { 6264903Swnj 6274903Swnj if (sb->sb_flags & SB_LOCK) 6284903Swnj panic("sbflush"); 62926105Skarels while (sb->sb_mbcnt) 63026363Skarels sbdrop(sb, (int)sb->sb_cc); 6314903Swnj if (sb->sb_cc || sb->sb_mbcnt || sb->sb_mb) 6324903Swnj panic("sbflush 2"); 6334903Swnj } 6344903Swnj 6354903Swnj /* 63616994Skarels * Drop data from (the front of) a sockbuf. 6374903Swnj */ 6384903Swnj sbdrop(sb, len) 6394903Swnj register struct sockbuf *sb; 6404903Swnj register int len; 6414903Swnj { 64216994Skarels register struct mbuf *m, *mn; 64316994Skarels struct mbuf *next; 6444903Swnj 64535385Skarels next = (m = sb->sb_mb) ? m->m_nextpkt : 0; 6464903Swnj while (len > 0) { 64716994Skarels if (m == 0) { 64816994Skarels if (next == 0) 64916994Skarels panic("sbdrop"); 65016994Skarels m = next; 65135385Skarels next = m->m_nextpkt; 65216994Skarels continue; 65316994Skarels } 6545064Swnj if (m->m_len > len) { 6554903Swnj m->m_len -= len; 65635385Skarels m->m_data += len; 6574903Swnj sb->sb_cc -= len; 6584903Swnj break; 6594903Swnj } 6605064Swnj len -= m->m_len; 6615064Swnj sbfree(sb, m); 6625064Swnj MFREE(m, mn); 6635064Swnj m = mn; 6644903Swnj } 66517331Skarels while (m && m->m_len == 0) { 66617417Skarels sbfree(sb, m); 66717331Skarels MFREE(m, mn); 66817331Skarels m = mn; 66917331Skarels } 67016994Skarels if (m) { 67116994Skarels sb->sb_mb = m; 67235385Skarels m->m_nextpkt = next; 67316994Skarels } else 67416994Skarels sb->sb_mb = next; 6754903Swnj } 67616994Skarels 67716994Skarels /* 67816994Skarels * Drop a record off the front of a sockbuf 67916994Skarels * and move the next record to the front. 68016994Skarels */ 68116994Skarels sbdroprecord(sb) 68216994Skarels register struct sockbuf *sb; 68316994Skarels { 68416994Skarels register struct mbuf *m, *mn; 68516994Skarels 68616994Skarels m = sb->sb_mb; 68716994Skarels if (m) { 68835385Skarels sb->sb_mb = m->m_nextpkt; 68916994Skarels do { 69016994Skarels sbfree(sb, m); 69116994Skarels MFREE(m, mn); 69216994Skarels } while (m = mn); 69316994Skarels } 69416994Skarels } 695