123431Smckusick /* 240706Skarels * Copyright (c) 1982, 1986, 1988, 1990 Regents of the University of California. 333187Sbostic * All rights reserved. 423431Smckusick * 544451Sbostic * %sccs.include.redist.c% 633187Sbostic * 7*46480Ssklower * @(#)uipc_socket2.c 7.16 (Berkeley) 02/19/91 823431Smckusick */ 94903Swnj 1017103Sbloom #include "param.h" 1117103Sbloom #include "systm.h" 1217103Sbloom #include "user.h" 1317103Sbloom #include "proc.h" 1417103Sbloom #include "file.h" 1517103Sbloom #include "buf.h" 1635385Skarels #include "malloc.h" 1717103Sbloom #include "mbuf.h" 1817103Sbloom #include "protosw.h" 1917103Sbloom #include "socket.h" 2017103Sbloom #include "socketvar.h" 214903Swnj 224903Swnj /* 234903Swnj * Primitive routines for operating on sockets and socket buffers 244903Swnj */ 254903Swnj 2640706Skarels /* strings for sleep message: */ 2740706Skarels char netio[] = "netio"; 2840706Skarels char netcon[] = "netcon"; 2940706Skarels char netcls[] = "netcls"; 3040706Skarels 3140706Skarels u_long sb_max = SB_MAX; /* patchable */ 3240706Skarels 334903Swnj /* 344903Swnj * Procedures to manipulate state flags of socket 357509Sroot * and do appropriate wakeups. Normal sequence from the 367509Sroot * active (originating) side is that soisconnecting() is 377509Sroot * called during processing of connect() call, 385169Swnj * resulting in an eventual call to soisconnected() if/when the 395169Swnj * connection is established. When the connection is torn down 405169Swnj * soisdisconnecting() is called during processing of disconnect() call, 415169Swnj * and soisdisconnected() is called when the connection to the peer 425169Swnj * is totally severed. The semantics of these routines are such that 435169Swnj * connectionless protocols can call soisconnected() and soisdisconnected() 445169Swnj * only, bypassing the in-progress calls when setting up a ``connection'' 455169Swnj * takes no time. 465169Swnj * 4712758Ssam * From the passive side, a socket is created with 4812758Ssam * two queues of sockets: so_q0 for connections in progress 497509Sroot * and so_q for connections already made and awaiting user acceptance. 507509Sroot * As a protocol is preparing incoming connections, it creates a socket 517509Sroot * structure queued on so_q0 by calling sonewconn(). When the connection 527509Sroot * is established, soisconnected() is called, and transfers the 537509Sroot * socket structure to so_q, making it available to accept(). 547509Sroot * 5512758Ssam * If a socket is closed with sockets on either 567509Sroot * so_q0 or so_q, these sockets are dropped. 577509Sroot * 5812758Ssam * If higher level protocols are implemented in 595169Swnj * the kernel, the wakeups done here will sometimes 6012758Ssam * cause software-interrupt process scheduling. 614903Swnj */ 625169Swnj 634903Swnj soisconnecting(so) 6412758Ssam register struct socket *so; 654903Swnj { 664903Swnj 674903Swnj so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING); 684903Swnj so->so_state |= SS_ISCONNECTING; 694903Swnj } 704903Swnj 714903Swnj soisconnected(so) 7212758Ssam register struct socket *so; 734903Swnj { 747509Sroot register struct socket *head = so->so_head; 754903Swnj 7640633Skarels so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING); 7740633Skarels so->so_state |= SS_ISCONNECTED; 7840633Skarels if (head && soqremque(so, 0)) { 797509Sroot soqinsque(head, so, 1); 8012758Ssam sorwakeup(head); 817509Sroot wakeup((caddr_t)&head->so_timeo); 8240633Skarels } else { 8340633Skarels wakeup((caddr_t)&so->so_timeo); 8440633Skarels sorwakeup(so); 8540633Skarels sowwakeup(so); 867509Sroot } 874903Swnj } 884903Swnj 894903Swnj soisdisconnecting(so) 9012758Ssam register struct socket *so; 914903Swnj { 924903Swnj 935248Sroot so->so_state &= ~SS_ISCONNECTING; 944903Swnj so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE); 954903Swnj wakeup((caddr_t)&so->so_timeo); 965170Swnj sowwakeup(so); 975169Swnj sorwakeup(so); 984903Swnj } 994903Swnj 1004903Swnj soisdisconnected(so) 10112758Ssam register struct socket *so; 1024903Swnj { 1034903Swnj 1044903Swnj so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING); 1054903Swnj so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE); 1064903Swnj wakeup((caddr_t)&so->so_timeo); 1074903Swnj sowwakeup(so); 1084903Swnj sorwakeup(so); 1094903Swnj } 1104903Swnj 1115169Swnj /* 1127509Sroot * When an attempt at a new connection is noted on a socket 1137509Sroot * which accepts connections, sonewconn is called. If the 1147509Sroot * connection is possible (subject to space constraints, etc.) 1157509Sroot * then we allocate a new structure, propoerly linked into the 1167509Sroot * data structure of the original socket, and return this. 11740633Skarels * Connstatus may be 0, or SO_ISCONFIRMING, or SO_ISCONNECTED. 11840706Skarels * 11940706Skarels * Currently, sonewconn() is defined as sonewconn1() in socketvar.h 12040706Skarels * to catch calls that are missing the (new) second parameter. 1217509Sroot */ 1227509Sroot struct socket * 12340706Skarels sonewconn1(head, connstatus) 1247509Sroot register struct socket *head; 12540633Skarels int connstatus; 1267509Sroot { 1277509Sroot register struct socket *so; 12840633Skarels int soqueue = connstatus ? 1 : 0; 1297509Sroot 1307509Sroot if (head->so_qlen + head->so_q0len > 3 * head->so_qlimit / 2) 13137329Skarels return ((struct socket *)0); 13237329Skarels MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_DONTWAIT); 13337329Skarels if (so == NULL) 13437329Skarels return ((struct socket *)0); 13537329Skarels bzero((caddr_t)so, sizeof(*so)); 1367509Sroot so->so_type = head->so_type; 1377509Sroot so->so_options = head->so_options &~ SO_ACCEPTCONN; 1387509Sroot so->so_linger = head->so_linger; 13910204Ssam so->so_state = head->so_state | SS_NOFDREF; 1407509Sroot so->so_proto = head->so_proto; 1417509Sroot so->so_timeo = head->so_timeo; 14235804Smarc so->so_pgid = head->so_pgid; 14335385Skarels (void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat); 14440633Skarels soqinsque(head, so, soqueue); 14512758Ssam if ((*so->so_proto->pr_usrreq)(so, PRU_ATTACH, 14612758Ssam (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0)) { 14740633Skarels (void) soqremque(so, soqueue); 14837329Skarels (void) free((caddr_t)so, M_SOCKET); 14937329Skarels return ((struct socket *)0); 1507509Sroot } 15140633Skarels if (connstatus) { 15240633Skarels sorwakeup(head); 15340633Skarels wakeup((caddr_t)&head->so_timeo); 15440633Skarels so->so_state |= connstatus; 15540633Skarels } 1567509Sroot return (so); 1577509Sroot } 1587509Sroot 1597509Sroot soqinsque(head, so, q) 1607509Sroot register struct socket *head, *so; 1617509Sroot int q; 1627509Sroot { 16340706Skarels 16440633Skarels register struct socket **prev; 1657509Sroot so->so_head = head; 1667509Sroot if (q == 0) { 1677509Sroot head->so_q0len++; 16840633Skarels so->so_q0 = 0; 16940633Skarels for (prev = &(head->so_q0); *prev; ) 17040633Skarels prev = &((*prev)->so_q0); 1717509Sroot } else { 1727509Sroot head->so_qlen++; 17340633Skarels so->so_q = 0; 17440633Skarels for (prev = &(head->so_q); *prev; ) 17540633Skarels prev = &((*prev)->so_q); 1767509Sroot } 17740633Skarels *prev = so; 1787509Sroot } 1797509Sroot 1807509Sroot soqremque(so, q) 1817509Sroot register struct socket *so; 1827509Sroot int q; 1837509Sroot { 1847509Sroot register struct socket *head, *prev, *next; 1857509Sroot 1867509Sroot head = so->so_head; 1877509Sroot prev = head; 1887509Sroot for (;;) { 1897509Sroot next = q ? prev->so_q : prev->so_q0; 1907509Sroot if (next == so) 1917509Sroot break; 19240633Skarels if (next == 0) 1937509Sroot return (0); 1947509Sroot prev = next; 1957509Sroot } 1967509Sroot if (q == 0) { 1977509Sroot prev->so_q0 = next->so_q0; 1987509Sroot head->so_q0len--; 1997509Sroot } else { 2007509Sroot prev->so_q = next->so_q; 2017509Sroot head->so_qlen--; 2027509Sroot } 2037509Sroot next->so_q0 = next->so_q = 0; 2047509Sroot next->so_head = 0; 2057509Sroot return (1); 2067509Sroot } 2077509Sroot 2087509Sroot /* 2095169Swnj * Socantsendmore indicates that no more data will be sent on the 2105169Swnj * socket; it would normally be applied to a socket when the user 2115169Swnj * informs the system that no more data is to be sent, by the protocol 2125169Swnj * code (in case PRU_SHUTDOWN). Socantrcvmore indicates that no more data 2135169Swnj * will be received, and will normally be applied to the socket by a 2145169Swnj * protocol when it detects that the peer will send no more data. 2155169Swnj * Data queued for reading in the socket may yet be read. 2165169Swnj */ 2175169Swnj 2184917Swnj socantsendmore(so) 2194917Swnj struct socket *so; 2204917Swnj { 2214917Swnj 2224917Swnj so->so_state |= SS_CANTSENDMORE; 2234917Swnj sowwakeup(so); 2244917Swnj } 2254917Swnj 2264917Swnj socantrcvmore(so) 2274917Swnj struct socket *so; 2284917Swnj { 2294917Swnj 2304917Swnj so->so_state |= SS_CANTRCVMORE; 2314917Swnj sorwakeup(so); 2324917Swnj } 2334917Swnj 2344903Swnj /* 2355169Swnj * Socket select/wakeup routines. 2364903Swnj */ 2375169Swnj 2385169Swnj /* 2394903Swnj * Queue a process for a select on a socket buffer. 2404903Swnj */ 2414903Swnj sbselqueue(sb) 2424903Swnj struct sockbuf *sb; 2434903Swnj { 24435385Skarels struct proc *p; 2454903Swnj 2464917Swnj if ((p = sb->sb_sel) && p->p_wchan == (caddr_t)&selwait) 2474903Swnj sb->sb_flags |= SB_COLL; 24844228Skarels else { 2494903Swnj sb->sb_sel = u.u_procp; 25044228Skarels sb->sb_flags |= SB_SEL; 25144228Skarels } 2524903Swnj } 2534903Swnj 2544903Swnj /* 2554917Swnj * Wait for data to arrive at/drain from a socket buffer. 2564917Swnj */ 2574917Swnj sbwait(sb) 2584917Swnj struct sockbuf *sb; 2594917Swnj { 2604917Swnj 2614917Swnj sb->sb_flags |= SB_WAIT; 26240706Skarels return (tsleep((caddr_t)&sb->sb_cc, 26340706Skarels (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH, netio, 26440706Skarels sb->sb_timeo)); 2654917Swnj } 2664917Swnj 26740706Skarels /* 26840706Skarels * Lock a sockbuf already known to be locked; 26940706Skarels * return any error returned from sleep (EINTR). 27040706Skarels */ 27140706Skarels sb_lock(sb) 27240706Skarels register struct sockbuf *sb; 27340706Skarels { 27440706Skarels int error; 27540706Skarels 27640706Skarels while (sb->sb_flags & SB_LOCK) { 27740706Skarels sb->sb_flags |= SB_WANT; 27840706Skarels if (error = tsleep((caddr_t)&sb->sb_flags, 27940706Skarels (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK|PCATCH, 28040706Skarels netio, 0)) 28140706Skarels return (error); 28240706Skarels } 28340706Skarels sb->sb_flags |= SB_LOCK; 28440706Skarels return (0); 28540706Skarels } 28640706Skarels 2874917Swnj /* 2884903Swnj * Wakeup processes waiting on a socket buffer. 28935385Skarels * Do asynchronous notification via SIGIO 29035385Skarels * if the socket has the SS_ASYNC flag set. 2914903Swnj */ 29235385Skarels sowakeup(so, sb) 29335385Skarels register struct socket *so; 29412758Ssam register struct sockbuf *sb; 2954903Swnj { 29637329Skarels struct proc *p; 2974903Swnj 2984903Swnj if (sb->sb_sel) { 2994903Swnj selwakeup(sb->sb_sel, sb->sb_flags & SB_COLL); 3004903Swnj sb->sb_sel = 0; 30144228Skarels sb->sb_flags &= ~(SB_SEL|SB_COLL); 3024903Swnj } 3034903Swnj if (sb->sb_flags & SB_WAIT) { 3044903Swnj sb->sb_flags &= ~SB_WAIT; 3055013Swnj wakeup((caddr_t)&sb->sb_cc); 3064903Swnj } 30715829Scooper if (so->so_state & SS_ASYNC) { 30835804Smarc if (so->so_pgid < 0) 30935804Smarc gsignal(-so->so_pgid, SIGIO); 31035804Smarc else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0) 31115829Scooper psignal(p, SIGIO); 31215829Scooper } 31315829Scooper } 31415829Scooper 31515829Scooper /* 3165169Swnj * Socket buffer (struct sockbuf) utility routines. 3175169Swnj * 3185169Swnj * Each socket contains two socket buffers: one for sending data and 3195169Swnj * one for receiving data. Each buffer contains a queue of mbufs, 3205169Swnj * information about the number of mbufs and amount of data in the 3215169Swnj * queue, and other fields allowing select() statements and notification 3225169Swnj * on data availability to be implemented. 3235169Swnj * 32416994Skarels * Data stored in a socket buffer is maintained as a list of records. 32516994Skarels * Each record is a list of mbufs chained together with the m_next 32635385Skarels * field. Records are chained together with the m_nextpkt field. The upper 32716994Skarels * level routine soreceive() expects the following conventions to be 32816994Skarels * observed when placing information in the receive buffer: 32916994Skarels * 33016994Skarels * 1. If the protocol requires each message be preceded by the sender's 33116994Skarels * name, then a record containing that name must be present before 33216994Skarels * any associated data (mbuf's must be of type MT_SONAME). 33316994Skarels * 2. If the protocol supports the exchange of ``access rights'' (really 33416994Skarels * just additional data associated with the message), and there are 33516994Skarels * ``rights'' to be received, then a record containing this data 33616994Skarels * should be present (mbuf's must be of type MT_RIGHTS). 33716994Skarels * 3. If a name or rights record exists, then it must be followed by 33816994Skarels * a data record, perhaps of zero length. 33916994Skarels * 3405169Swnj * Before using a new socket structure it is first necessary to reserve 34133406Skarels * buffer space to the socket, by calling sbreserve(). This should commit 3425169Swnj * some of the available buffer space in the system buffer pool for the 34333406Skarels * socket (currently, it does nothing but enforce limits). The space 34433406Skarels * should be released by calling sbrelease() when the socket is destroyed. 3455169Swnj */ 3465169Swnj 3479027Sroot soreserve(so, sndcc, rcvcc) 34812758Ssam register struct socket *so; 34933406Skarels u_long sndcc, rcvcc; 3509027Sroot { 3519027Sroot 3529027Sroot if (sbreserve(&so->so_snd, sndcc) == 0) 3539027Sroot goto bad; 3549027Sroot if (sbreserve(&so->so_rcv, rcvcc) == 0) 3559027Sroot goto bad2; 35640706Skarels if (so->so_rcv.sb_lowat == 0) 35740706Skarels so->so_rcv.sb_lowat = 1; 35840706Skarels if (so->so_snd.sb_lowat == 0) 35940706Skarels so->so_snd.sb_lowat = MCLBYTES; 36040706Skarels if (so->so_snd.sb_lowat > so->so_snd.sb_hiwat) 36140706Skarels so->so_snd.sb_lowat = so->so_snd.sb_hiwat; 3629027Sroot return (0); 3639027Sroot bad2: 3649027Sroot sbrelease(&so->so_snd); 3659027Sroot bad: 3669027Sroot return (ENOBUFS); 3679027Sroot } 3689027Sroot 3695169Swnj /* 3704903Swnj * Allot mbufs to a sockbuf. 37140706Skarels * Attempt to scale mbmax so that mbcnt doesn't become limiting 37226830Skarels * if buffering efficiency is near the normal case. 3734903Swnj */ 3744903Swnj sbreserve(sb, cc) 3754903Swnj struct sockbuf *sb; 37633406Skarels u_long cc; 3774903Swnj { 3784903Swnj 37940706Skarels if (cc > sb_max * MCLBYTES / (MSIZE + MCLBYTES)) 38017355Skarels return (0); 3814980Swnj sb->sb_hiwat = cc; 38240706Skarels sb->sb_mbmax = min(cc * 2, sb_max); 38340706Skarels if (sb->sb_lowat > sb->sb_hiwat) 38440706Skarels sb->sb_lowat = sb->sb_hiwat; 3854917Swnj return (1); 3864903Swnj } 3874903Swnj 3884903Swnj /* 3894903Swnj * Free mbufs held by a socket, and reserved mbuf space. 3904903Swnj */ 3914903Swnj sbrelease(sb) 3924903Swnj struct sockbuf *sb; 3934903Swnj { 3944903Swnj 3954903Swnj sbflush(sb); 3964980Swnj sb->sb_hiwat = sb->sb_mbmax = 0; 3974903Swnj } 3984903Swnj 3994903Swnj /* 40016994Skarels * Routines to add and remove 40116994Skarels * data from an mbuf queue. 40225630Skarels * 40325630Skarels * The routines sbappend() or sbappendrecord() are normally called to 40425630Skarels * append new mbufs to a socket buffer, after checking that adequate 40525630Skarels * space is available, comparing the function sbspace() with the amount 40625630Skarels * of data to be added. sbappendrecord() differs from sbappend() in 40725630Skarels * that data supplied is treated as the beginning of a new record. 40825630Skarels * To place a sender's address, optional access rights, and data in a 40925630Skarels * socket receive buffer, sbappendaddr() should be used. To place 41025630Skarels * access rights and data in a socket receive buffer, sbappendrights() 41125630Skarels * should be used. In either case, the new data begins a new record. 41225630Skarels * Note that unlike sbappend() and sbappendrecord(), these routines check 41325630Skarels * for the caller that there will be enough space to store the data. 41425630Skarels * Each fails if there is not enough space, or if it cannot find mbufs 41525630Skarels * to store additional information in. 41625630Skarels * 41725630Skarels * Reliable protocols may use the socket send buffer to hold data 41825630Skarels * awaiting acknowledgement. Data is normally copied from a socket 41925630Skarels * send buffer in a protocol with m_copy for output to a peer, 42025630Skarels * and then removing the data from the socket buffer with sbdrop() 42125630Skarels * or sbdroprecord() when the data is acknowledged by the peer. 4224903Swnj */ 4234903Swnj 4244903Swnj /* 42516994Skarels * Append mbuf chain m to the last record in the 42616994Skarels * socket buffer sb. The additional space associated 42716994Skarels * the mbuf chain is recorded in sb. Empty mbufs are 42816994Skarels * discarded and mbufs are compacted where possible. 4294903Swnj */ 4304903Swnj sbappend(sb, m) 43116994Skarels struct sockbuf *sb; 43216994Skarels struct mbuf *m; 4334903Swnj { 4346092Sroot register struct mbuf *n; 4354903Swnj 43616994Skarels if (m == 0) 43716994Skarels return; 43816994Skarels if (n = sb->sb_mb) { 43935385Skarels while (n->m_nextpkt) 44035385Skarels n = n->m_nextpkt; 441*46480Ssklower do { 44240633Skarels if (n->m_flags & M_EOR) { 44340633Skarels sbappendrecord(sb, m); /* XXXXXX!!!! */ 44440633Skarels return; 445*46480Ssklower } 446*46480Ssklower } while (n->m_next && (n = n->m_next)); 4474903Swnj } 44816994Skarels sbcompress(sb, m, n); 4494903Swnj } 4504903Swnj 45144384Skarels #ifdef SOCKBUF_DEBUG 45244384Skarels sbcheck(sb) 45344384Skarels register struct sockbuf *sb; 45444384Skarels { 45544384Skarels register struct mbuf *m; 45644384Skarels register int len = 0, mbcnt = 0; 45744384Skarels 45844384Skarels for (m = sb->sb_mb; m; m = m->m_next) { 45944384Skarels len += m->m_len; 46044384Skarels mbcnt += MSIZE; 46144384Skarels if (m->m_flags & M_EXT) 46244384Skarels mbcnt += m->m_ext.ext_size; 46344384Skarels if (m->m_nextpkt) 46444384Skarels panic("sbcheck nextpkt"); 46544384Skarels } 46644384Skarels if (len != sb->sb_cc || mbcnt != sb->sb_mbcnt) { 46744384Skarels printf("cc %d != %d || mbcnt %d != %d\n", len, sb->sb_cc, 46844384Skarels mbcnt, sb->sb_mbcnt); 46944384Skarels panic("sbcheck"); 47044384Skarels } 47144384Skarels } 47244384Skarels #endif 47344384Skarels 4745169Swnj /* 47516994Skarels * As above, except the mbuf chain 47616994Skarels * begins a new record. 4775169Swnj */ 47816994Skarels sbappendrecord(sb, m0) 47916994Skarels register struct sockbuf *sb; 48016994Skarels register struct mbuf *m0; 4814928Swnj { 4824928Swnj register struct mbuf *m; 4834928Swnj 48416994Skarels if (m0 == 0) 48516994Skarels return; 48616994Skarels if (m = sb->sb_mb) 48735385Skarels while (m->m_nextpkt) 48835385Skarels m = m->m_nextpkt; 48916994Skarels /* 49016994Skarels * Put the first mbuf on the queue. 49116994Skarels * Note this permits zero length records. 49216994Skarels */ 49316994Skarels sballoc(sb, m0); 49416994Skarels if (m) 49535385Skarels m->m_nextpkt = m0; 49616994Skarels else 49716994Skarels sb->sb_mb = m0; 49816994Skarels m = m0->m_next; 49916994Skarels m0->m_next = 0; 50037329Skarels if (m && (m0->m_flags & M_EOR)) { 50137329Skarels m0->m_flags &= ~M_EOR; 50237329Skarels m->m_flags |= M_EOR; 50337329Skarels } 50416994Skarels sbcompress(sb, m, m0); 50516994Skarels } 50616994Skarels 50716994Skarels /* 50837329Skarels * As above except that OOB data 50937329Skarels * is inserted at the beginning of the sockbuf, 51037329Skarels * but after any other OOB data. 51137329Skarels */ 51237329Skarels sbinsertoob(sb, m0) 51337329Skarels register struct sockbuf *sb; 51437329Skarels register struct mbuf *m0; 51537329Skarels { 51637329Skarels register struct mbuf *m; 51737329Skarels register struct mbuf **mp; 51837329Skarels 51937329Skarels if (m0 == 0) 52037329Skarels return; 52137329Skarels for (mp = &sb->sb_mb; m = *mp; mp = &((*mp)->m_nextpkt)) { 52237329Skarels again: 52337329Skarels switch (m->m_type) { 52437329Skarels 52537329Skarels case MT_OOBDATA: 52637329Skarels continue; /* WANT next train */ 52737329Skarels 52837329Skarels case MT_CONTROL: 52937329Skarels if (m = m->m_next) 53037329Skarels goto again; /* inspect THIS train further */ 53137329Skarels } 53237329Skarels break; 53337329Skarels } 53437329Skarels /* 53537329Skarels * Put the first mbuf on the queue. 53637329Skarels * Note this permits zero length records. 53737329Skarels */ 53837329Skarels sballoc(sb, m0); 53937329Skarels m0->m_nextpkt = *mp; 54037329Skarels *mp = m0; 54137329Skarels m = m0->m_next; 54237329Skarels m0->m_next = 0; 54337329Skarels if (m && (m0->m_flags & M_EOR)) { 54437329Skarels m0->m_flags &= ~M_EOR; 54537329Skarels m->m_flags |= M_EOR; 54637329Skarels } 54737329Skarels sbcompress(sb, m, m0); 54837329Skarels } 54937329Skarels 55037329Skarels /* 55142259Skarels * Append address and data, and optionally, control (ancillary) data 55235385Skarels * to the receive queue of a socket. If present, 55342259Skarels * m0 must include a packet header with total length. 55442259Skarels * Returns 0 if no space in sockbuf or insufficient mbufs. 55516994Skarels */ 55642259Skarels sbappendaddr(sb, asa, m0, control) 55716994Skarels register struct sockbuf *sb; 55816994Skarels struct sockaddr *asa; 55942259Skarels struct mbuf *m0, *control; 56016994Skarels { 56116994Skarels register struct mbuf *m, *n; 56237329Skarels int space = asa->sa_len; 56316994Skarels 56435385Skarels if (m0 && (m0->m_flags & M_PKTHDR) == 0) 56535385Skarels panic("sbappendaddr"); 56635385Skarels if (m0) 56735385Skarels space += m0->m_pkthdr.len; 56842259Skarels for (n = control; n; n = n->m_next) { 56942259Skarels space += n->m_len; 57042259Skarels if (n->m_next == 0) /* keep pointer to last control buf */ 57142259Skarels break; 57242259Skarels } 57316994Skarels if (space > sbspace(sb)) 5744928Swnj return (0); 57542259Skarels if (asa->sa_len > MLEN) 57642259Skarels return (0); 57725630Skarels MGET(m, M_DONTWAIT, MT_SONAME); 57816994Skarels if (m == 0) 5794928Swnj return (0); 58037329Skarels m->m_len = asa->sa_len; 58137329Skarels bcopy((caddr_t)asa, mtod(m, caddr_t), asa->sa_len); 58242259Skarels if (n) 58342259Skarels n->m_next = m0; /* concatenate data to control */ 58442259Skarels else 58542259Skarels control = m0; 58642259Skarels m->m_next = control; 58742259Skarels for (n = m; n; n = n->m_next) 58842259Skarels sballoc(sb, n); 58916994Skarels if (n = sb->sb_mb) { 59035385Skarels while (n->m_nextpkt) 59135385Skarels n = n->m_nextpkt; 59235385Skarels n->m_nextpkt = m; 59316994Skarels } else 59416994Skarels sb->sb_mb = m; 59516994Skarels return (1); 59616994Skarels } 59716994Skarels 59842259Skarels sbappendcontrol(sb, m0, control) 59916994Skarels struct sockbuf *sb; 60042259Skarels struct mbuf *control, *m0; 60116994Skarels { 60216994Skarels register struct mbuf *m, *n; 60316994Skarels int space = 0; 60416994Skarels 60542259Skarels if (control == 0) 60642259Skarels panic("sbappendcontrol"); 60742259Skarels for (m = control; ; m = m->m_next) { 60842259Skarels space += m->m_len; 60942259Skarels if (m->m_next == 0) 61042259Skarels break; 61142259Skarels } 61242259Skarels n = m; /* save pointer to last control buffer */ 61325630Skarels for (m = m0; m; m = m->m_next) 61416994Skarels space += m->m_len; 61516994Skarels if (space > sbspace(sb)) 61612758Ssam return (0); 61742259Skarels n->m_next = m0; /* concatenate data to control */ 61842259Skarels for (m = control; m; m = m->m_next) 61942259Skarels sballoc(sb, m); 62016994Skarels if (n = sb->sb_mb) { 62135385Skarels while (n->m_nextpkt) 62235385Skarels n = n->m_nextpkt; 62342259Skarels n->m_nextpkt = control; 62416994Skarels } else 62542259Skarels sb->sb_mb = control; 6264928Swnj return (1); 6274928Swnj } 6284928Swnj 6294903Swnj /* 63016994Skarels * Compress mbuf chain m into the socket 63116994Skarels * buffer sb following mbuf n. If n 63216994Skarels * is null, the buffer is presumed empty. 6334903Swnj */ 63416994Skarels sbcompress(sb, m, n) 63516994Skarels register struct sockbuf *sb; 63616994Skarels register struct mbuf *m, *n; 63716994Skarels { 63842259Skarels register int eor = 0; 639*46480Ssklower register struct mbuf *o; 64016994Skarels 64116994Skarels while (m) { 64237329Skarels eor |= m->m_flags & M_EOR; 643*46480Ssklower if (m->m_len == 0 && 644*46480Ssklower (eor == 0 || 645*46480Ssklower (((o = m->m_next) || (o = n)) && 646*46480Ssklower o->m_type == m->m_type))) { 64716994Skarels m = m_free(m); 64816994Skarels continue; 64916994Skarels } 65037329Skarels if (n && (n->m_flags & (M_EXT | M_EOR)) == 0 && 65135385Skarels (n->m_data + n->m_len + m->m_len) < &n->m_dat[MLEN] && 65225630Skarels n->m_type == m->m_type) { 65316994Skarels bcopy(mtod(m, caddr_t), mtod(n, caddr_t) + n->m_len, 65416994Skarels (unsigned)m->m_len); 65516994Skarels n->m_len += m->m_len; 65616994Skarels sb->sb_cc += m->m_len; 65716994Skarels m = m_free(m); 65816994Skarels continue; 65916994Skarels } 66016994Skarels if (n) 66116994Skarels n->m_next = m; 66216994Skarels else 66316994Skarels sb->sb_mb = m; 66437329Skarels sballoc(sb, m); 66516994Skarels n = m; 66637329Skarels m->m_flags &= ~M_EOR; 66716994Skarels m = m->m_next; 66816994Skarels n->m_next = 0; 66916994Skarels } 670*46480Ssklower if (eor) { 671*46480Ssklower if (n) 672*46480Ssklower n->m_flags |= eor; 673*46480Ssklower else 674*46480Ssklower printf("semi-panic: sbcompress\n"); 675*46480Ssklower } 67616994Skarels } 67716994Skarels 67816994Skarels /* 67916994Skarels * Free all mbufs in a sockbuf. 68016994Skarels * Check that all resources are reclaimed. 68116994Skarels */ 6824903Swnj sbflush(sb) 68312758Ssam register struct sockbuf *sb; 6844903Swnj { 6854903Swnj 6864903Swnj if (sb->sb_flags & SB_LOCK) 6874903Swnj panic("sbflush"); 68826105Skarels while (sb->sb_mbcnt) 68926363Skarels sbdrop(sb, (int)sb->sb_cc); 69042259Skarels if (sb->sb_cc || sb->sb_mb) 6914903Swnj panic("sbflush 2"); 6924903Swnj } 6934903Swnj 6944903Swnj /* 69516994Skarels * Drop data from (the front of) a sockbuf. 6964903Swnj */ 6974903Swnj sbdrop(sb, len) 6984903Swnj register struct sockbuf *sb; 6994903Swnj register int len; 7004903Swnj { 70116994Skarels register struct mbuf *m, *mn; 70216994Skarels struct mbuf *next; 7034903Swnj 70435385Skarels next = (m = sb->sb_mb) ? m->m_nextpkt : 0; 7054903Swnj while (len > 0) { 70616994Skarels if (m == 0) { 70716994Skarels if (next == 0) 70816994Skarels panic("sbdrop"); 70916994Skarels m = next; 71035385Skarels next = m->m_nextpkt; 71116994Skarels continue; 71216994Skarels } 7135064Swnj if (m->m_len > len) { 7144903Swnj m->m_len -= len; 71535385Skarels m->m_data += len; 7164903Swnj sb->sb_cc -= len; 7174903Swnj break; 7184903Swnj } 7195064Swnj len -= m->m_len; 7205064Swnj sbfree(sb, m); 7215064Swnj MFREE(m, mn); 7225064Swnj m = mn; 7234903Swnj } 72417331Skarels while (m && m->m_len == 0) { 72517417Skarels sbfree(sb, m); 72617331Skarels MFREE(m, mn); 72717331Skarels m = mn; 72817331Skarels } 72916994Skarels if (m) { 73016994Skarels sb->sb_mb = m; 73135385Skarels m->m_nextpkt = next; 73216994Skarels } else 73316994Skarels sb->sb_mb = next; 7344903Swnj } 73516994Skarels 73616994Skarels /* 73716994Skarels * Drop a record off the front of a sockbuf 73816994Skarels * and move the next record to the front. 73916994Skarels */ 74016994Skarels sbdroprecord(sb) 74116994Skarels register struct sockbuf *sb; 74216994Skarels { 74316994Skarels register struct mbuf *m, *mn; 74416994Skarels 74516994Skarels m = sb->sb_mb; 74616994Skarels if (m) { 74735385Skarels sb->sb_mb = m->m_nextpkt; 74816994Skarels do { 74916994Skarels sbfree(sb, m); 75016994Skarels MFREE(m, mn); 75116994Skarels } while (m = mn); 75216994Skarels } 75316994Skarels } 754