uipc_sockbuf.c revision 17675
11541Srgrimes/* 21541Srgrimes * Copyright (c) 1982, 1986, 1988, 1990, 1993 31541Srgrimes * The Regents of the University of California. All rights reserved. 41541Srgrimes * 51541Srgrimes * Redistribution and use in source and binary forms, with or without 61541Srgrimes * modification, are permitted provided that the following conditions 71541Srgrimes * are met: 81541Srgrimes * 1. Redistributions of source code must retain the above copyright 91541Srgrimes * notice, this list of conditions and the following disclaimer. 101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111541Srgrimes * notice, this list of conditions and the following disclaimer in the 121541Srgrimes * documentation and/or other materials provided with the distribution. 131541Srgrimes * 3. All advertising materials mentioning features or use of this software 141541Srgrimes * must display the following acknowledgement: 151541Srgrimes * This product includes software developed by the University of 161541Srgrimes * California, Berkeley and its contributors. 171541Srgrimes * 4. Neither the name of the University nor the names of its contributors 181541Srgrimes * may be used to endorse or promote products derived from this software 191541Srgrimes * without specific prior written permission. 201541Srgrimes * 211541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311541Srgrimes * SUCH DAMAGE. 321541Srgrimes * 331541Srgrimes * @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93 3417675Sjulian * $Id: uipc_socket2.c,v 1.12 1996/07/11 16:31:59 wollman Exp $ 351541Srgrimes */ 361541Srgrimes 371541Srgrimes#include <sys/param.h> 381541Srgrimes#include <sys/systm.h> 3912041Swollman#include <sys/kernel.h> 401541Srgrimes#include <sys/proc.h> 411541Srgrimes#include <sys/file.h> 421541Srgrimes#include <sys/buf.h> 431541Srgrimes#include <sys/malloc.h> 441541Srgrimes#include <sys/mbuf.h> 451541Srgrimes#include <sys/protosw.h> 463308Sphk#include <sys/stat.h> 471541Srgrimes#include <sys/socket.h> 481541Srgrimes#include <sys/socketvar.h> 493308Sphk#include <sys/signalvar.h> 5012041Swollman#include <sys/sysctl.h> 511541Srgrimes 521541Srgrimes/* 531541Srgrimes * Primitive routines for operating on sockets and socket buffers 541541Srgrimes */ 551541Srgrimes 5612041Swollmanu_long sb_max = SB_MAX; /* XXX should be static */ 5712041SwollmanSYSCTL_INT(_kern, KERN_MAXSOCKBUF, maxsockbuf, CTLFLAG_RW, &sb_max, 0, "") 581541Srgrimes 5913267Swollmanstatic u_long sb_efficiency = 8; /* parameter for sbreserve() */ 6013267SwollmanSYSCTL_INT(_kern, OID_AUTO, sockbuf_waste_factor, CTLFLAG_RW, &sb_efficiency, 6113267Swollman 0, ""); 6213267Swollman 631541Srgrimes/* 641541Srgrimes * Procedures to manipulate state flags of socket 651541Srgrimes * and do appropriate wakeups. Normal sequence from the 661541Srgrimes * active (originating) side is that soisconnecting() is 671541Srgrimes * called during processing of connect() call, 681541Srgrimes * resulting in an eventual call to soisconnected() if/when the 691541Srgrimes * connection is established. When the connection is torn down 701541Srgrimes * soisdisconnecting() is called during processing of disconnect() call, 711541Srgrimes * and soisdisconnected() is called when the connection to the peer 721541Srgrimes * is totally severed. The semantics of these routines are such that 731541Srgrimes * connectionless protocols can call soisconnected() and soisdisconnected() 741541Srgrimes * only, bypassing the in-progress calls when setting up a ``connection'' 751541Srgrimes * takes no time. 761541Srgrimes * 771541Srgrimes * From the passive side, a socket is created with 781541Srgrimes * two queues of sockets: so_q0 for connections in progress 791541Srgrimes * and so_q for connections already made and awaiting user acceptance. 801541Srgrimes * As a protocol is preparing incoming connections, it creates a socket 811541Srgrimes * structure queued on so_q0 by calling sonewconn(). When the connection 821541Srgrimes * is established, soisconnected() is called, and transfers the 831541Srgrimes * socket structure to so_q, making it available to accept(). 848876Srgrimes * 851541Srgrimes * If a socket is closed with sockets on either 861541Srgrimes * so_q0 or so_q, these sockets are dropped. 871541Srgrimes * 881541Srgrimes * If higher level protocols are implemented in 891541Srgrimes * the kernel, the wakeups done here will sometimes 901541Srgrimes * cause software-interrupt process scheduling. 911541Srgrimes */ 921541Srgrimes 931549Srgrimesvoid 941541Srgrimessoisconnecting(so) 951541Srgrimes register struct socket *so; 961541Srgrimes{ 971541Srgrimes 981541Srgrimes so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING); 991541Srgrimes so->so_state |= SS_ISCONNECTING; 1001541Srgrimes} 1011541Srgrimes 1021549Srgrimesvoid 1031541Srgrimessoisconnected(so) 1041541Srgrimes register struct socket *so; 1051541Srgrimes{ 1061541Srgrimes register struct socket *head = so->so_head; 1071541Srgrimes 1081541Srgrimes so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING); 1091541Srgrimes so->so_state |= SS_ISCONNECTED; 11014547Sdg if (head && (so->so_state & SS_INCOMP)) { 11114547Sdg TAILQ_REMOVE(&head->so_incomp, so, so_list); 11214547Sdg so->so_state &= ~SS_INCOMP; 11314547Sdg TAILQ_INSERT_TAIL(&head->so_comp, so, so_list); 11414547Sdg so->so_state |= SS_COMP; 1151541Srgrimes sorwakeup(head); 1161541Srgrimes wakeup((caddr_t)&head->so_timeo); 1171541Srgrimes } else { 1181541Srgrimes wakeup((caddr_t)&so->so_timeo); 1191541Srgrimes sorwakeup(so); 1201541Srgrimes sowwakeup(so); 1211541Srgrimes } 1221541Srgrimes} 1231541Srgrimes 1241549Srgrimesvoid 1251541Srgrimessoisdisconnecting(so) 1261541Srgrimes register struct socket *so; 1271541Srgrimes{ 1281541Srgrimes 1291541Srgrimes so->so_state &= ~SS_ISCONNECTING; 1301541Srgrimes so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE); 1311541Srgrimes wakeup((caddr_t)&so->so_timeo); 1321541Srgrimes sowwakeup(so); 1331541Srgrimes sorwakeup(so); 1341541Srgrimes} 1351541Srgrimes 1361549Srgrimesvoid 1371541Srgrimessoisdisconnected(so) 1381541Srgrimes register struct socket *so; 1391541Srgrimes{ 1401541Srgrimes 1411541Srgrimes so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING); 1421541Srgrimes so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE); 1431541Srgrimes wakeup((caddr_t)&so->so_timeo); 1441541Srgrimes sowwakeup(so); 1451541Srgrimes sorwakeup(so); 1461541Srgrimes} 1471541Srgrimes 1481541Srgrimes/* 1491541Srgrimes * When an attempt at a new connection is noted on a socket 1501541Srgrimes * which accepts connections, sonewconn is called. If the 1511541Srgrimes * connection is possible (subject to space constraints, etc.) 1521541Srgrimes * then we allocate a new structure, propoerly linked into the 1531541Srgrimes * data structure of the original socket, and return this. 1541541Srgrimes * Connstatus may be 0, or SO_ISCONFIRMING, or SO_ISCONNECTED. 1551541Srgrimes * 1561541Srgrimes * Currently, sonewconn() is defined as sonewconn1() in socketvar.h 1571541Srgrimes * to catch calls that are missing the (new) second parameter. 1581541Srgrimes */ 1591541Srgrimesstruct socket * 1601541Srgrimessonewconn1(head, connstatus) 1611541Srgrimes register struct socket *head; 1621541Srgrimes int connstatus; 1631541Srgrimes{ 1641541Srgrimes register struct socket *so; 1651541Srgrimes 16614547Sdg if (head->so_qlen > 3 * head->so_qlimit / 2) 1671541Srgrimes return ((struct socket *)0); 1681541Srgrimes MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_DONTWAIT); 1698876Srgrimes if (so == NULL) 1701541Srgrimes return ((struct socket *)0); 1711541Srgrimes bzero((caddr_t)so, sizeof(*so)); 17214547Sdg so->so_head = head; 1731541Srgrimes so->so_type = head->so_type; 1741541Srgrimes so->so_options = head->so_options &~ SO_ACCEPTCONN; 1751541Srgrimes so->so_linger = head->so_linger; 1761541Srgrimes so->so_state = head->so_state | SS_NOFDREF; 1771541Srgrimes so->so_proto = head->so_proto; 1781541Srgrimes so->so_timeo = head->so_timeo; 1791541Srgrimes so->so_pgid = head->so_pgid; 1801541Srgrimes (void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat); 18114547Sdg if (connstatus) { 18214547Sdg TAILQ_INSERT_TAIL(&head->so_comp, so, so_list); 18314547Sdg so->so_state |= SS_COMP; 18414547Sdg } else { 18514547Sdg TAILQ_INSERT_TAIL(&head->so_incomp, so, so_list); 18614547Sdg so->so_state |= SS_INCOMP; 18714547Sdg } 18814547Sdg head->so_qlen++; 18917096Swollman if ((*so->so_proto->pr_usrreqs->pru_attach)(so, 0)) { 19014547Sdg if (so->so_state & SS_COMP) { 19114547Sdg TAILQ_REMOVE(&head->so_comp, so, so_list); 19214547Sdg } else { 19314547Sdg TAILQ_REMOVE(&head->so_incomp, so, so_list); 19414547Sdg } 19514547Sdg head->so_qlen--; 1961541Srgrimes (void) free((caddr_t)so, M_SOCKET); 1971541Srgrimes return ((struct socket *)0); 1981541Srgrimes } 1991541Srgrimes if (connstatus) { 2001541Srgrimes sorwakeup(head); 2011541Srgrimes wakeup((caddr_t)&head->so_timeo); 2021541Srgrimes so->so_state |= connstatus; 2031541Srgrimes } 2041541Srgrimes return (so); 2051541Srgrimes} 2061541Srgrimes 2071541Srgrimes/* 2081541Srgrimes * Socantsendmore indicates that no more data will be sent on the 2091541Srgrimes * socket; it would normally be applied to a socket when the user 2101541Srgrimes * informs the system that no more data is to be sent, by the protocol 2111541Srgrimes * code (in case PRU_SHUTDOWN). Socantrcvmore indicates that no more data 2121541Srgrimes * will be received, and will normally be applied to the socket by a 2131541Srgrimes * protocol when it detects that the peer will send no more data. 2141541Srgrimes * Data queued for reading in the socket may yet be read. 2151541Srgrimes */ 2161541Srgrimes 2171549Srgrimesvoid 2181541Srgrimessocantsendmore(so) 2191541Srgrimes struct socket *so; 2201541Srgrimes{ 2211541Srgrimes 2221541Srgrimes so->so_state |= SS_CANTSENDMORE; 2231541Srgrimes sowwakeup(so); 2241541Srgrimes} 2251541Srgrimes 2261549Srgrimesvoid 2271541Srgrimessocantrcvmore(so) 2281541Srgrimes struct socket *so; 2291541Srgrimes{ 2301541Srgrimes 2311541Srgrimes so->so_state |= SS_CANTRCVMORE; 2321541Srgrimes sorwakeup(so); 2331541Srgrimes} 2341541Srgrimes 2351541Srgrimes/* 2361541Srgrimes * Wait for data to arrive at/drain from a socket buffer. 2371541Srgrimes */ 2381549Srgrimesint 2391541Srgrimessbwait(sb) 2401541Srgrimes struct sockbuf *sb; 2411541Srgrimes{ 2421541Srgrimes 2431541Srgrimes sb->sb_flags |= SB_WAIT; 2441541Srgrimes return (tsleep((caddr_t)&sb->sb_cc, 24512843Sbde (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH, "sbwait", 2461541Srgrimes sb->sb_timeo)); 2471541Srgrimes} 2481541Srgrimes 2498876Srgrimes/* 2501541Srgrimes * Lock a sockbuf already known to be locked; 2511541Srgrimes * return any error returned from sleep (EINTR). 2521541Srgrimes */ 2531549Srgrimesint 2541541Srgrimessb_lock(sb) 2551541Srgrimes register struct sockbuf *sb; 2561541Srgrimes{ 2571541Srgrimes int error; 2581541Srgrimes 2591541Srgrimes while (sb->sb_flags & SB_LOCK) { 2601541Srgrimes sb->sb_flags |= SB_WANT; 2618876Srgrimes error = tsleep((caddr_t)&sb->sb_flags, 2621541Srgrimes (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK|PCATCH, 26312843Sbde "sblock", 0); 2643308Sphk if (error) 2651541Srgrimes return (error); 2661541Srgrimes } 2671541Srgrimes sb->sb_flags |= SB_LOCK; 2681541Srgrimes return (0); 2691541Srgrimes} 2701541Srgrimes 2711541Srgrimes/* 2721541Srgrimes * Wakeup processes waiting on a socket buffer. 2731541Srgrimes * Do asynchronous notification via SIGIO 2741541Srgrimes * if the socket has the SS_ASYNC flag set. 2751541Srgrimes */ 2761549Srgrimesvoid 2771541Srgrimessowakeup(so, sb) 2781541Srgrimes register struct socket *so; 2791541Srgrimes register struct sockbuf *sb; 2801541Srgrimes{ 2811541Srgrimes struct proc *p; 2821541Srgrimes 2831541Srgrimes selwakeup(&sb->sb_sel); 2841541Srgrimes sb->sb_flags &= ~SB_SEL; 2851541Srgrimes if (sb->sb_flags & SB_WAIT) { 2861541Srgrimes sb->sb_flags &= ~SB_WAIT; 2871541Srgrimes wakeup((caddr_t)&sb->sb_cc); 2881541Srgrimes } 2891541Srgrimes if (so->so_state & SS_ASYNC) { 2901541Srgrimes if (so->so_pgid < 0) 2911541Srgrimes gsignal(-so->so_pgid, SIGIO); 2921541Srgrimes else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0) 2931541Srgrimes psignal(p, SIGIO); 2941541Srgrimes } 2951541Srgrimes} 2961541Srgrimes 2971541Srgrimes/* 2981541Srgrimes * Socket buffer (struct sockbuf) utility routines. 2991541Srgrimes * 3001541Srgrimes * Each socket contains two socket buffers: one for sending data and 3011541Srgrimes * one for receiving data. Each buffer contains a queue of mbufs, 3021541Srgrimes * information about the number of mbufs and amount of data in the 3031541Srgrimes * queue, and other fields allowing select() statements and notification 3041541Srgrimes * on data availability to be implemented. 3051541Srgrimes * 3061541Srgrimes * Data stored in a socket buffer is maintained as a list of records. 3071541Srgrimes * Each record is a list of mbufs chained together with the m_next 3081541Srgrimes * field. Records are chained together with the m_nextpkt field. The upper 3091541Srgrimes * level routine soreceive() expects the following conventions to be 3101541Srgrimes * observed when placing information in the receive buffer: 3111541Srgrimes * 3121541Srgrimes * 1. If the protocol requires each message be preceded by the sender's 3131541Srgrimes * name, then a record containing that name must be present before 3141541Srgrimes * any associated data (mbuf's must be of type MT_SONAME). 3151541Srgrimes * 2. If the protocol supports the exchange of ``access rights'' (really 3161541Srgrimes * just additional data associated with the message), and there are 3171541Srgrimes * ``rights'' to be received, then a record containing this data 3181541Srgrimes * should be present (mbuf's must be of type MT_RIGHTS). 3191541Srgrimes * 3. If a name or rights record exists, then it must be followed by 3201541Srgrimes * a data record, perhaps of zero length. 3211541Srgrimes * 3221541Srgrimes * Before using a new socket structure it is first necessary to reserve 3231541Srgrimes * buffer space to the socket, by calling sbreserve(). This should commit 3241541Srgrimes * some of the available buffer space in the system buffer pool for the 3251541Srgrimes * socket (currently, it does nothing but enforce limits). The space 3261541Srgrimes * should be released by calling sbrelease() when the socket is destroyed. 3271541Srgrimes */ 3281541Srgrimes 3291549Srgrimesint 3301541Srgrimessoreserve(so, sndcc, rcvcc) 3311541Srgrimes register struct socket *so; 3321541Srgrimes u_long sndcc, rcvcc; 3331541Srgrimes{ 3341541Srgrimes 3351541Srgrimes if (sbreserve(&so->so_snd, sndcc) == 0) 3361541Srgrimes goto bad; 3371541Srgrimes if (sbreserve(&so->so_rcv, rcvcc) == 0) 3381541Srgrimes goto bad2; 3391541Srgrimes if (so->so_rcv.sb_lowat == 0) 3401541Srgrimes so->so_rcv.sb_lowat = 1; 3411541Srgrimes if (so->so_snd.sb_lowat == 0) 3421541Srgrimes so->so_snd.sb_lowat = MCLBYTES; 3431541Srgrimes if (so->so_snd.sb_lowat > so->so_snd.sb_hiwat) 3441541Srgrimes so->so_snd.sb_lowat = so->so_snd.sb_hiwat; 3451541Srgrimes return (0); 3461541Srgrimesbad2: 3471541Srgrimes sbrelease(&so->so_snd); 3481541Srgrimesbad: 3491541Srgrimes return (ENOBUFS); 3501541Srgrimes} 3511541Srgrimes 3521541Srgrimes/* 3531541Srgrimes * Allot mbufs to a sockbuf. 3541541Srgrimes * Attempt to scale mbmax so that mbcnt doesn't become limiting 3551541Srgrimes * if buffering efficiency is near the normal case. 3561541Srgrimes */ 3571549Srgrimesint 3581541Srgrimessbreserve(sb, cc) 3591541Srgrimes struct sockbuf *sb; 3601541Srgrimes u_long cc; 3611541Srgrimes{ 3621541Srgrimes 3631541Srgrimes if (cc > sb_max * MCLBYTES / (MSIZE + MCLBYTES)) 3641541Srgrimes return (0); 3651541Srgrimes sb->sb_hiwat = cc; 36613267Swollman sb->sb_mbmax = min(cc * sb_efficiency, sb_max); 3671541Srgrimes if (sb->sb_lowat > sb->sb_hiwat) 3681541Srgrimes sb->sb_lowat = sb->sb_hiwat; 3691541Srgrimes return (1); 3701541Srgrimes} 3711541Srgrimes 3721541Srgrimes/* 3731541Srgrimes * Free mbufs held by a socket, and reserved mbuf space. 3741541Srgrimes */ 3751549Srgrimesvoid 3761541Srgrimessbrelease(sb) 3771541Srgrimes struct sockbuf *sb; 3781541Srgrimes{ 3791541Srgrimes 3801541Srgrimes sbflush(sb); 3811541Srgrimes sb->sb_hiwat = sb->sb_mbmax = 0; 3821541Srgrimes} 3831541Srgrimes 3841541Srgrimes/* 3851541Srgrimes * Routines to add and remove 3861541Srgrimes * data from an mbuf queue. 3871541Srgrimes * 3881541Srgrimes * The routines sbappend() or sbappendrecord() are normally called to 3891541Srgrimes * append new mbufs to a socket buffer, after checking that adequate 3901541Srgrimes * space is available, comparing the function sbspace() with the amount 3911541Srgrimes * of data to be added. sbappendrecord() differs from sbappend() in 3921541Srgrimes * that data supplied is treated as the beginning of a new record. 3931541Srgrimes * To place a sender's address, optional access rights, and data in a 3941541Srgrimes * socket receive buffer, sbappendaddr() should be used. To place 3951541Srgrimes * access rights and data in a socket receive buffer, sbappendrights() 3961541Srgrimes * should be used. In either case, the new data begins a new record. 3971541Srgrimes * Note that unlike sbappend() and sbappendrecord(), these routines check 3981541Srgrimes * for the caller that there will be enough space to store the data. 3991541Srgrimes * Each fails if there is not enough space, or if it cannot find mbufs 4001541Srgrimes * to store additional information in. 4011541Srgrimes * 4021541Srgrimes * Reliable protocols may use the socket send buffer to hold data 4031541Srgrimes * awaiting acknowledgement. Data is normally copied from a socket 4041541Srgrimes * send buffer in a protocol with m_copy for output to a peer, 4051541Srgrimes * and then removing the data from the socket buffer with sbdrop() 4061541Srgrimes * or sbdroprecord() when the data is acknowledged by the peer. 4071541Srgrimes */ 4081541Srgrimes 4091541Srgrimes/* 4101541Srgrimes * Append mbuf chain m to the last record in the 4111541Srgrimes * socket buffer sb. The additional space associated 4121541Srgrimes * the mbuf chain is recorded in sb. Empty mbufs are 4131541Srgrimes * discarded and mbufs are compacted where possible. 4141541Srgrimes */ 4151549Srgrimesvoid 4161541Srgrimessbappend(sb, m) 4171541Srgrimes struct sockbuf *sb; 4181541Srgrimes struct mbuf *m; 4191541Srgrimes{ 4201541Srgrimes register struct mbuf *n; 4211541Srgrimes 4221541Srgrimes if (m == 0) 4231541Srgrimes return; 4243308Sphk n = sb->sb_mb; 4253308Sphk if (n) { 4261541Srgrimes while (n->m_nextpkt) 4271541Srgrimes n = n->m_nextpkt; 4281541Srgrimes do { 4291541Srgrimes if (n->m_flags & M_EOR) { 4301541Srgrimes sbappendrecord(sb, m); /* XXXXXX!!!! */ 4311541Srgrimes return; 4321541Srgrimes } 4331541Srgrimes } while (n->m_next && (n = n->m_next)); 4341541Srgrimes } 4351541Srgrimes sbcompress(sb, m, n); 4361541Srgrimes} 4371541Srgrimes 4381541Srgrimes#ifdef SOCKBUF_DEBUG 4391549Srgrimesvoid 4401541Srgrimessbcheck(sb) 4411541Srgrimes register struct sockbuf *sb; 4421541Srgrimes{ 4431541Srgrimes register struct mbuf *m; 4441541Srgrimes register int len = 0, mbcnt = 0; 4451541Srgrimes 4461541Srgrimes for (m = sb->sb_mb; m; m = m->m_next) { 4471541Srgrimes len += m->m_len; 4481541Srgrimes mbcnt += MSIZE; 44917675Sjulian if (m->m_flags & M_EXT) /*XXX*/ /* pretty sure this is bogus */ 4501541Srgrimes mbcnt += m->m_ext.ext_size; 4511541Srgrimes if (m->m_nextpkt) 4521541Srgrimes panic("sbcheck nextpkt"); 4531541Srgrimes } 4541541Srgrimes if (len != sb->sb_cc || mbcnt != sb->sb_mbcnt) { 4551541Srgrimes printf("cc %d != %d || mbcnt %d != %d\n", len, sb->sb_cc, 4561541Srgrimes mbcnt, sb->sb_mbcnt); 4571541Srgrimes panic("sbcheck"); 4581541Srgrimes } 4591541Srgrimes} 4601541Srgrimes#endif 4611541Srgrimes 4621541Srgrimes/* 4631541Srgrimes * As above, except the mbuf chain 4641541Srgrimes * begins a new record. 4651541Srgrimes */ 4661549Srgrimesvoid 4671541Srgrimessbappendrecord(sb, m0) 4681541Srgrimes register struct sockbuf *sb; 4691541Srgrimes register struct mbuf *m0; 4701541Srgrimes{ 4711541Srgrimes register struct mbuf *m; 4721541Srgrimes 4731541Srgrimes if (m0 == 0) 4741541Srgrimes return; 4753308Sphk m = sb->sb_mb; 4763308Sphk if (m) 4771541Srgrimes while (m->m_nextpkt) 4781541Srgrimes m = m->m_nextpkt; 4791541Srgrimes /* 4801541Srgrimes * Put the first mbuf on the queue. 4811541Srgrimes * Note this permits zero length records. 4821541Srgrimes */ 4831541Srgrimes sballoc(sb, m0); 4841541Srgrimes if (m) 4851541Srgrimes m->m_nextpkt = m0; 4861541Srgrimes else 4871541Srgrimes sb->sb_mb = m0; 4881541Srgrimes m = m0->m_next; 4891541Srgrimes m0->m_next = 0; 4901541Srgrimes if (m && (m0->m_flags & M_EOR)) { 4911541Srgrimes m0->m_flags &= ~M_EOR; 4921541Srgrimes m->m_flags |= M_EOR; 4931541Srgrimes } 4941541Srgrimes sbcompress(sb, m, m0); 4951541Srgrimes} 4961541Srgrimes 4971541Srgrimes/* 4981541Srgrimes * As above except that OOB data 4991541Srgrimes * is inserted at the beginning of the sockbuf, 5001541Srgrimes * but after any other OOB data. 5011541Srgrimes */ 5021549Srgrimesvoid 5031541Srgrimessbinsertoob(sb, m0) 5041541Srgrimes register struct sockbuf *sb; 5051541Srgrimes register struct mbuf *m0; 5061541Srgrimes{ 5071541Srgrimes register struct mbuf *m; 5081541Srgrimes register struct mbuf **mp; 5091541Srgrimes 5101541Srgrimes if (m0 == 0) 5111541Srgrimes return; 5123308Sphk for (mp = &sb->sb_mb; *mp ; mp = &((*mp)->m_nextpkt)) { 5133308Sphk m = *mp; 5141541Srgrimes again: 5151541Srgrimes switch (m->m_type) { 5161541Srgrimes 5171541Srgrimes case MT_OOBDATA: 5181541Srgrimes continue; /* WANT next train */ 5191541Srgrimes 5201541Srgrimes case MT_CONTROL: 5213308Sphk m = m->m_next; 5223308Sphk if (m) 5231541Srgrimes goto again; /* inspect THIS train further */ 5241541Srgrimes } 5251541Srgrimes break; 5261541Srgrimes } 5271541Srgrimes /* 5281541Srgrimes * Put the first mbuf on the queue. 5291541Srgrimes * Note this permits zero length records. 5301541Srgrimes */ 5311541Srgrimes sballoc(sb, m0); 5321541Srgrimes m0->m_nextpkt = *mp; 5331541Srgrimes *mp = m0; 5341541Srgrimes m = m0->m_next; 5351541Srgrimes m0->m_next = 0; 5361541Srgrimes if (m && (m0->m_flags & M_EOR)) { 5371541Srgrimes m0->m_flags &= ~M_EOR; 5381541Srgrimes m->m_flags |= M_EOR; 5391541Srgrimes } 5401541Srgrimes sbcompress(sb, m, m0); 5411541Srgrimes} 5421541Srgrimes 5431541Srgrimes/* 5441541Srgrimes * Append address and data, and optionally, control (ancillary) data 5451541Srgrimes * to the receive queue of a socket. If present, 5461541Srgrimes * m0 must include a packet header with total length. 5471541Srgrimes * Returns 0 if no space in sockbuf or insufficient mbufs. 5481541Srgrimes */ 5491549Srgrimesint 5501541Srgrimessbappendaddr(sb, asa, m0, control) 5511541Srgrimes register struct sockbuf *sb; 5521541Srgrimes struct sockaddr *asa; 5531541Srgrimes struct mbuf *m0, *control; 5541541Srgrimes{ 5551541Srgrimes register struct mbuf *m, *n; 5561541Srgrimes int space = asa->sa_len; 5571541Srgrimes 5581541Srgrimesif (m0 && (m0->m_flags & M_PKTHDR) == 0) 5591541Srgrimespanic("sbappendaddr"); 5601541Srgrimes if (m0) 5611541Srgrimes space += m0->m_pkthdr.len; 5621541Srgrimes for (n = control; n; n = n->m_next) { 5631541Srgrimes space += n->m_len; 5641541Srgrimes if (n->m_next == 0) /* keep pointer to last control buf */ 5651541Srgrimes break; 5661541Srgrimes } 5671541Srgrimes if (space > sbspace(sb)) 5681541Srgrimes return (0); 5691541Srgrimes if (asa->sa_len > MLEN) 5701541Srgrimes return (0); 5711541Srgrimes MGET(m, M_DONTWAIT, MT_SONAME); 5721541Srgrimes if (m == 0) 5731541Srgrimes return (0); 5741541Srgrimes m->m_len = asa->sa_len; 5751541Srgrimes bcopy((caddr_t)asa, mtod(m, caddr_t), asa->sa_len); 5761541Srgrimes if (n) 5771541Srgrimes n->m_next = m0; /* concatenate data to control */ 5781541Srgrimes else 5791541Srgrimes control = m0; 5801541Srgrimes m->m_next = control; 5811541Srgrimes for (n = m; n; n = n->m_next) 5821541Srgrimes sballoc(sb, n); 5833308Sphk n = sb->sb_mb; 5843308Sphk if (n) { 5851541Srgrimes while (n->m_nextpkt) 5861541Srgrimes n = n->m_nextpkt; 5871541Srgrimes n->m_nextpkt = m; 5881541Srgrimes } else 5891541Srgrimes sb->sb_mb = m; 5901541Srgrimes return (1); 5911541Srgrimes} 5921541Srgrimes 5931549Srgrimesint 5941541Srgrimessbappendcontrol(sb, m0, control) 5951541Srgrimes struct sockbuf *sb; 5961541Srgrimes struct mbuf *control, *m0; 5971541Srgrimes{ 5981541Srgrimes register struct mbuf *m, *n; 5991541Srgrimes int space = 0; 6001541Srgrimes 6011541Srgrimes if (control == 0) 6021541Srgrimes panic("sbappendcontrol"); 6031541Srgrimes for (m = control; ; m = m->m_next) { 6041541Srgrimes space += m->m_len; 6051541Srgrimes if (m->m_next == 0) 6061541Srgrimes break; 6071541Srgrimes } 6081541Srgrimes n = m; /* save pointer to last control buffer */ 6091541Srgrimes for (m = m0; m; m = m->m_next) 6101541Srgrimes space += m->m_len; 6111541Srgrimes if (space > sbspace(sb)) 6121541Srgrimes return (0); 6131541Srgrimes n->m_next = m0; /* concatenate data to control */ 6141541Srgrimes for (m = control; m; m = m->m_next) 6151541Srgrimes sballoc(sb, m); 6163308Sphk n = sb->sb_mb; 6173308Sphk if (n) { 6181541Srgrimes while (n->m_nextpkt) 6191541Srgrimes n = n->m_nextpkt; 6201541Srgrimes n->m_nextpkt = control; 6211541Srgrimes } else 6221541Srgrimes sb->sb_mb = control; 6231541Srgrimes return (1); 6241541Srgrimes} 6251541Srgrimes 6261541Srgrimes/* 6271541Srgrimes * Compress mbuf chain m into the socket 6281541Srgrimes * buffer sb following mbuf n. If n 6291541Srgrimes * is null, the buffer is presumed empty. 6301541Srgrimes */ 6311549Srgrimesvoid 6321541Srgrimessbcompress(sb, m, n) 6331541Srgrimes register struct sockbuf *sb; 6341541Srgrimes register struct mbuf *m, *n; 6351541Srgrimes{ 6361541Srgrimes register int eor = 0; 6371541Srgrimes register struct mbuf *o; 6381541Srgrimes 6391541Srgrimes while (m) { 6401541Srgrimes eor |= m->m_flags & M_EOR; 6411541Srgrimes if (m->m_len == 0 && 6421541Srgrimes (eor == 0 || 6431541Srgrimes (((o = m->m_next) || (o = n)) && 6441541Srgrimes o->m_type == m->m_type))) { 6451541Srgrimes m = m_free(m); 6461541Srgrimes continue; 6471541Srgrimes } 6481541Srgrimes if (n && (n->m_flags & (M_EXT | M_EOR)) == 0 && 6491541Srgrimes (n->m_data + n->m_len + m->m_len) < &n->m_dat[MLEN] && 6501541Srgrimes n->m_type == m->m_type) { 6511541Srgrimes bcopy(mtod(m, caddr_t), mtod(n, caddr_t) + n->m_len, 6521541Srgrimes (unsigned)m->m_len); 6531541Srgrimes n->m_len += m->m_len; 6541541Srgrimes sb->sb_cc += m->m_len; 6551541Srgrimes m = m_free(m); 6561541Srgrimes continue; 6571541Srgrimes } 6581541Srgrimes if (n) 6591541Srgrimes n->m_next = m; 6601541Srgrimes else 6611541Srgrimes sb->sb_mb = m; 6621541Srgrimes sballoc(sb, m); 6631541Srgrimes n = m; 6641541Srgrimes m->m_flags &= ~M_EOR; 6651541Srgrimes m = m->m_next; 6661541Srgrimes n->m_next = 0; 6671541Srgrimes } 6681541Srgrimes if (eor) { 6691541Srgrimes if (n) 6701541Srgrimes n->m_flags |= eor; 6711541Srgrimes else 6721541Srgrimes printf("semi-panic: sbcompress\n"); 6731541Srgrimes } 6741541Srgrimes} 6751541Srgrimes 6761541Srgrimes/* 6771541Srgrimes * Free all mbufs in a sockbuf. 6781541Srgrimes * Check that all resources are reclaimed. 6791541Srgrimes */ 6801549Srgrimesvoid 6811541Srgrimessbflush(sb) 6821541Srgrimes register struct sockbuf *sb; 6831541Srgrimes{ 6841541Srgrimes 6851541Srgrimes if (sb->sb_flags & SB_LOCK) 6861541Srgrimes panic("sbflush"); 6871541Srgrimes while (sb->sb_mbcnt) 6881541Srgrimes sbdrop(sb, (int)sb->sb_cc); 6891541Srgrimes if (sb->sb_cc || sb->sb_mb) 6901541Srgrimes panic("sbflush 2"); 6911541Srgrimes} 6921541Srgrimes 6931541Srgrimes/* 6941541Srgrimes * Drop data from (the front of) a sockbuf. 6951541Srgrimes */ 6961549Srgrimesvoid 6971541Srgrimessbdrop(sb, len) 6981541Srgrimes register struct sockbuf *sb; 6991541Srgrimes register int len; 7001541Srgrimes{ 7011541Srgrimes register struct mbuf *m, *mn; 7021541Srgrimes struct mbuf *next; 7031541Srgrimes 7041541Srgrimes next = (m = sb->sb_mb) ? m->m_nextpkt : 0; 7051541Srgrimes while (len > 0) { 7061541Srgrimes if (m == 0) { 7071541Srgrimes if (next == 0) 7081541Srgrimes panic("sbdrop"); 7091541Srgrimes m = next; 7101541Srgrimes next = m->m_nextpkt; 7111541Srgrimes continue; 7121541Srgrimes } 7131541Srgrimes if (m->m_len > len) { 7141541Srgrimes m->m_len -= len; 7151541Srgrimes m->m_data += len; 7161541Srgrimes sb->sb_cc -= len; 7171541Srgrimes break; 7181541Srgrimes } 7191541Srgrimes len -= m->m_len; 7201541Srgrimes sbfree(sb, m); 7211541Srgrimes MFREE(m, mn); 7221541Srgrimes m = mn; 7231541Srgrimes } 7241541Srgrimes while (m && m->m_len == 0) { 7251541Srgrimes sbfree(sb, m); 7261541Srgrimes MFREE(m, mn); 7271541Srgrimes m = mn; 7281541Srgrimes } 7291541Srgrimes if (m) { 7301541Srgrimes sb->sb_mb = m; 7311541Srgrimes m->m_nextpkt = next; 7321541Srgrimes } else 7331541Srgrimes sb->sb_mb = next; 7341541Srgrimes} 7351541Srgrimes 7361541Srgrimes/* 7371541Srgrimes * Drop a record off the front of a sockbuf 7381541Srgrimes * and move the next record to the front. 7391541Srgrimes */ 7401549Srgrimesvoid 7411541Srgrimessbdroprecord(sb) 7421541Srgrimes register struct sockbuf *sb; 7431541Srgrimes{ 7441541Srgrimes register struct mbuf *m, *mn; 7451541Srgrimes 7461541Srgrimes m = sb->sb_mb; 7471541Srgrimes if (m) { 7481541Srgrimes sb->sb_mb = m->m_nextpkt; 7491541Srgrimes do { 7501541Srgrimes sbfree(sb, m); 7511541Srgrimes MFREE(m, mn); 7523308Sphk m = mn; 7533308Sphk } while (m); 7541541Srgrimes } 7551541Srgrimes} 75617047Swollman 75717047Swollman#ifdef PRU_OLDSTYLE 75817047Swollman/* 75917047Swollman * The following routines mediate between the old-style `pr_usrreq' 76017047Swollman * protocol implementations and the new-style `struct pr_usrreqs' 76117047Swollman * calling convention. 76217047Swollman */ 76317047Swollman 76417047Swollman/* syntactic sugar */ 76517047Swollman#define nomb (struct mbuf *)0 76617047Swollman 76717047Swollmanstatic int 76817047Swollmanold_abort(struct socket *so) 76917047Swollman{ 77017096Swollman return so->so_proto->pr_ousrreq(so, PRU_ABORT, nomb, nomb, nomb); 77117047Swollman} 77217047Swollman 77317047Swollmanstatic int 77417047Swollmanold_accept(struct socket *so, struct mbuf *nam) 77517047Swollman{ 77617096Swollman return so->so_proto->pr_ousrreq(so, PRU_ACCEPT, nomb, nam, nomb); 77717047Swollman} 77817047Swollman 77917047Swollmanstatic int 78017047Swollmanold_attach(struct socket *so, int proto) 78117047Swollman{ 78217096Swollman return so->so_proto->pr_ousrreq(so, PRU_ATTACH, nomb, 78317047Swollman (struct mbuf *)proto, /* XXX */ 78417047Swollman nomb); 78517047Swollman} 78617047Swollman 78717047Swollmanstatic int 78817047Swollmanold_bind(struct socket *so, struct mbuf *nam) 78917047Swollman{ 79017096Swollman return so->so_proto->pr_ousrreq(so, PRU_BIND, nomb, nam, nomb); 79117047Swollman} 79217047Swollman 79317047Swollmanstatic int 79417047Swollmanold_connect(struct socket *so, struct mbuf *nam) 79517047Swollman{ 79617096Swollman return so->so_proto->pr_ousrreq(so, PRU_CONNECT, nomb, nam, nomb); 79717047Swollman} 79817047Swollman 79917047Swollmanstatic int 80017047Swollmanold_connect2(struct socket *so1, struct socket *so2) 80117047Swollman{ 80217096Swollman return so1->so_proto->pr_ousrreq(so1, PRU_CONNECT2, nomb, 80317047Swollman (struct mbuf *)so2, nomb); 80417047Swollman} 80517047Swollman 80617047Swollmanstatic int 80717096Swollmanold_control(struct socket *so, int cmd, caddr_t data, struct ifnet *ifp) 80817047Swollman{ 80917096Swollman return so->so_proto->pr_ousrreq(so, PRU_CONTROL, (struct mbuf *)cmd, 81017096Swollman (struct mbuf *)data, 81117096Swollman (struct mbuf *)ifp); 81217047Swollman} 81317047Swollman 81417047Swollmanstatic int 81517047Swollmanold_detach(struct socket *so) 81617047Swollman{ 81717096Swollman return so->so_proto->pr_ousrreq(so, PRU_DETACH, nomb, nomb, nomb); 81817047Swollman} 81917047Swollman 82017047Swollmanstatic int 82117047Swollmanold_disconnect(struct socket *so) 82217047Swollman{ 82317096Swollman return so->so_proto->pr_ousrreq(so, PRU_DISCONNECT, nomb, nomb, nomb); 82417047Swollman} 82517047Swollman 82617047Swollmanstatic int 82717047Swollmanold_listen(struct socket *so) 82817047Swollman{ 82917096Swollman return so->so_proto->pr_ousrreq(so, PRU_LISTEN, nomb, nomb, nomb); 83017047Swollman} 83117047Swollman 83217047Swollmanstatic int 83317047Swollmanold_peeraddr(struct socket *so, struct mbuf *nam) 83417047Swollman{ 83517096Swollman return so->so_proto->pr_ousrreq(so, PRU_PEERADDR, nomb, nam, nomb); 83617047Swollman} 83717047Swollman 83817047Swollmanstatic int 83917047Swollmanold_rcvd(struct socket *so, int flags) 84017047Swollman{ 84117096Swollman return so->so_proto->pr_ousrreq(so, PRU_RCVD, nomb, 84217047Swollman (struct mbuf *)flags, /* XXX */ 84317047Swollman nomb); 84417047Swollman} 84517047Swollman 84617047Swollmanstatic int 84717047Swollmanold_rcvoob(struct socket *so, struct mbuf *m, int flags) 84817047Swollman{ 84917096Swollman return so->so_proto->pr_ousrreq(so, PRU_RCVOOB, m, 85017047Swollman (struct mbuf *)flags, /* XXX */ 85117047Swollman nomb); 85217047Swollman} 85317047Swollman 85417047Swollmanstatic int 85517047Swollmanold_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *addr, 85617047Swollman struct mbuf *control) 85717047Swollman{ 85817047Swollman int req; 85917047Swollman 86017047Swollman if (flags & PRUS_OOB) { 86117047Swollman req = PRU_SENDOOB; 86217047Swollman } else if(flags & PRUS_EOF) { 86317047Swollman req = PRU_SEND_EOF; 86417047Swollman } else { 86517047Swollman req = PRU_SEND; 86617047Swollman } 86717096Swollman return so->so_proto->pr_ousrreq(so, req, m, addr, control); 86817047Swollman} 86917047Swollman 87017047Swollmanstatic int 87117047Swollmanold_sense(struct socket *so, struct stat *sb) 87217047Swollman{ 87317096Swollman return so->so_proto->pr_ousrreq(so, PRU_SENSE, (struct mbuf *)sb, 87417047Swollman nomb, nomb); 87517047Swollman} 87617047Swollman 87717047Swollmanstatic int 87817047Swollmanold_shutdown(struct socket *so) 87917047Swollman{ 88017096Swollman return so->so_proto->pr_ousrreq(so, PRU_SHUTDOWN, nomb, nomb, nomb); 88117047Swollman} 88217047Swollman 88317047Swollmanstatic int 88417047Swollmanold_sockaddr(struct socket *so, struct mbuf *nam) 88517047Swollman{ 88617096Swollman return so->so_proto->pr_ousrreq(so, PRU_SOCKADDR, nomb, nam, nomb); 88717047Swollman} 88817047Swollman 88917047Swollmanstruct pr_usrreqs pru_oldstyle = { 89017047Swollman old_abort, old_accept, old_attach, old_bind, old_connect, 89117047Swollman old_connect2, old_control, old_detach, old_disconnect, 89217047Swollman old_listen, old_peeraddr, old_rcvd, old_rcvoob, old_send, 89317047Swollman old_sense, old_shutdown, old_sockaddr 89417047Swollman}; 89517047Swollman 89617096Swollman#endif /* PRU_OLDSTYLE */ 89717096Swollman 89817047Swollman/* 89917096Swollman * Some routines that return EOPNOTSUPP for entry points that are not 90017096Swollman * supported by a protocol. Fill in as needed. 90117047Swollman */ 90217047Swollmanint 90317096Swollmanpru_connect2_notsupp(struct socket *so1, struct socket *so2) 90417047Swollman{ 90517096Swollman return EOPNOTSUPP; 90617047Swollman} 907