1*5577Swnj /* uipc_socket2.c 4.18 82/01/19 */ 24903Swnj 34903Swnj #include "../h/param.h" 44903Swnj #include "../h/systm.h" 54903Swnj #include "../h/dir.h" 64903Swnj #include "../h/user.h" 74903Swnj #include "../h/proc.h" 84903Swnj #include "../h/file.h" 94903Swnj #include "../h/inode.h" 104903Swnj #include "../h/buf.h" 114903Swnj #include "../h/mbuf.h" 124903Swnj #include "../h/protosw.h" 134903Swnj #include "../h/socket.h" 144903Swnj #include "../h/socketvar.h" 155096Swnj #include "../net/in.h" 165096Swnj #include "../net/in_systm.h" 174903Swnj 184903Swnj /* 194903Swnj * Primitive routines for operating on sockets and socket buffers 204903Swnj */ 214903Swnj 224903Swnj /* 234903Swnj * Procedures to manipulate state flags of socket 245169Swnj * and do appropriate wakeups. Normal sequence is that 255169Swnj * soisconnecting() is called during processing of connect() call, 265169Swnj * resulting in an eventual call to soisconnected() if/when the 275169Swnj * connection is established. When the connection is torn down 285169Swnj * soisdisconnecting() is called during processing of disconnect() call, 295169Swnj * and soisdisconnected() is called when the connection to the peer 305169Swnj * is totally severed. The semantics of these routines are such that 315169Swnj * connectionless protocols can call soisconnected() and soisdisconnected() 325169Swnj * only, bypassing the in-progress calls when setting up a ``connection'' 335169Swnj * takes no time. 345169Swnj * 355169Swnj * When higher level protocols are implemented in 365169Swnj * the kernel, the wakeups done here will sometimes 375169Swnj * be implemented as software-interrupt process scheduling. 384903Swnj */ 395169Swnj 404903Swnj soisconnecting(so) 414903Swnj struct socket *so; 424903Swnj { 434903Swnj 444903Swnj so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING); 454903Swnj so->so_state |= SS_ISCONNECTING; 464903Swnj wakeup((caddr_t)&so->so_timeo); 474903Swnj } 484903Swnj 494903Swnj soisconnected(so) 504903Swnj struct socket *so; 514903Swnj { 524903Swnj 534903Swnj so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING); 544903Swnj so->so_state |= SS_ISCONNECTED; 554903Swnj wakeup((caddr_t)&so->so_timeo); 564903Swnj } 574903Swnj 584903Swnj soisdisconnecting(so) 594903Swnj struct socket *so; 604903Swnj { 614903Swnj 625248Sroot so->so_state &= ~SS_ISCONNECTING; 634903Swnj so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE); 644903Swnj wakeup((caddr_t)&so->so_timeo); 655170Swnj sowwakeup(so); 665169Swnj sorwakeup(so); 674903Swnj } 684903Swnj 694903Swnj soisdisconnected(so) 704903Swnj struct socket *so; 714903Swnj { 724903Swnj 734903Swnj so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING); 744903Swnj so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE); 754903Swnj wakeup((caddr_t)&so->so_timeo); 764903Swnj sowwakeup(so); 774903Swnj sorwakeup(so); 784903Swnj } 794903Swnj 805169Swnj /* 815169Swnj * Socantsendmore indicates that no more data will be sent on the 825169Swnj * socket; it would normally be applied to a socket when the user 835169Swnj * informs the system that no more data is to be sent, by the protocol 845169Swnj * code (in case PRU_SHUTDOWN). Socantrcvmore indicates that no more data 855169Swnj * will be received, and will normally be applied to the socket by a 865169Swnj * protocol when it detects that the peer will send no more data. 875169Swnj * Data queued for reading in the socket may yet be read. 885169Swnj */ 895169Swnj 904917Swnj socantsendmore(so) 914917Swnj struct socket *so; 924917Swnj { 934917Swnj 944917Swnj so->so_state |= SS_CANTSENDMORE; 954917Swnj sowwakeup(so); 964917Swnj } 974917Swnj 984917Swnj socantrcvmore(so) 994917Swnj struct socket *so; 1004917Swnj { 1014917Swnj 1024917Swnj so->so_state |= SS_CANTRCVMORE; 1034917Swnj sorwakeup(so); 1044917Swnj } 1054917Swnj 1064903Swnj /* 1075169Swnj * Socket select/wakeup routines. 1084903Swnj */ 1095169Swnj 1105169Swnj /* 1115169Swnj * Interface routine to select() system 1125169Swnj * call for sockets. 1135169Swnj */ 114*5577Swnj soselect(so, rw) 1154903Swnj register struct socket *so; 116*5577Swnj int rw; 1174903Swnj { 1184903Swnj 119*5577Swnj switch (rw) { 120*5577Swnj 121*5577Swnj case FREAD: 1224903Swnj if (soreadable(so)) 1234903Swnj return (1); 1244903Swnj sbselqueue(&so->so_rcv); 125*5577Swnj break; 126*5577Swnj 127*5577Swnj case FWRITE: 1284903Swnj if (sowriteable(so)) 1294903Swnj return (1); 1304903Swnj sbselqueue(&so->so_snd); 131*5577Swnj break; 1324903Swnj } 1334903Swnj return (0); 1344903Swnj } 1354903Swnj 1364903Swnj /* 1374903Swnj * Queue a process for a select on a socket buffer. 1384903Swnj */ 1394903Swnj sbselqueue(sb) 1404903Swnj struct sockbuf *sb; 1414903Swnj { 1424903Swnj register struct proc *p; 1434903Swnj 1444917Swnj if ((p = sb->sb_sel) && p->p_wchan == (caddr_t)&selwait) 1454903Swnj sb->sb_flags |= SB_COLL; 1464903Swnj else 1474903Swnj sb->sb_sel = u.u_procp; 1484903Swnj } 1494903Swnj 1504903Swnj /* 1514917Swnj * Wait for data to arrive at/drain from a socket buffer. 1524917Swnj */ 1534917Swnj sbwait(sb) 1544917Swnj struct sockbuf *sb; 1554917Swnj { 1564917Swnj 1574917Swnj sb->sb_flags |= SB_WAIT; 1584917Swnj sleep((caddr_t)&sb->sb_cc, PZERO+1); 1594917Swnj } 1604917Swnj 1614917Swnj /* 1624903Swnj * Wakeup processes waiting on a socket buffer. 1634903Swnj */ 1644903Swnj sbwakeup(sb) 1654903Swnj struct sockbuf *sb; 1664903Swnj { 1674903Swnj 1684903Swnj if (sb->sb_sel) { 1694903Swnj selwakeup(sb->sb_sel, sb->sb_flags & SB_COLL); 1704903Swnj sb->sb_sel = 0; 1714903Swnj sb->sb_flags &= ~SB_COLL; 1724903Swnj } 1734903Swnj if (sb->sb_flags & SB_WAIT) { 1744903Swnj sb->sb_flags &= ~SB_WAIT; 1755013Swnj wakeup((caddr_t)&sb->sb_cc); 1764903Swnj } 1774903Swnj } 1784903Swnj 1794903Swnj /* 1805169Swnj * Socket buffer (struct sockbuf) utility routines. 1815169Swnj * 1825169Swnj * Each socket contains two socket buffers: one for sending data and 1835169Swnj * one for receiving data. Each buffer contains a queue of mbufs, 1845169Swnj * information about the number of mbufs and amount of data in the 1855169Swnj * queue, and other fields allowing select() statements and notification 1865169Swnj * on data availability to be implemented. 1875169Swnj * 1885169Swnj * Before using a new socket structure it is first necessary to reserve 1895169Swnj * buffer space to the socket, by calling sbreserve. This commits 1905169Swnj * some of the available buffer space in the system buffer pool for the 1915169Swnj * socket. The space should be released by calling sbrelease when the 1925169Swnj * socket is destroyed. 1935169Swnj * 1945169Swnj * The routine sbappend() is normally called to append new mbufs 1955169Swnj * to a socket buffer, after checking that adequate space is available 1965169Swnj * comparing the function spspace() with the amount of data to be added. 1975169Swnj * Data is normally removed from a socket buffer in a protocol by 1985169Swnj * first calling m_copy on the socket buffer mbuf chain and sending this 1995169Swnj * to a peer, and then removing the data from the socket buffer with 2005169Swnj * sbdrop when the data is acknowledged by the peer (or immediately 2015170Swnj * in the case of unreliable protocols.) 2025169Swnj * 2035169Swnj * Protocols which do not require connections place both source address 2045169Swnj * and data information in socket buffer queues. The source addresses 2055169Swnj * are stored in single mbufs after each data item, and are easily found 2065169Swnj * as the data items are all marked with end of record markers. The 2075169Swnj * sbappendaddr() routine stores a datum and associated address in 2085169Swnj * a socket buffer. Note that, unlike sbappend(), this routine checks 2095169Swnj * for the caller that there will be enough space to store the data. 2105169Swnj * It fails if there is not enough space, or if it cannot find 2115169Swnj * a mbuf to store the address in. 2125169Swnj * 2135169Swnj * The higher-level routines sosend and soreceive (in socket.c) 2145170Swnj * also add data to, and remove data from socket buffers repectively. 2155169Swnj */ 2165169Swnj 2175169Swnj /* 2184903Swnj * Allot mbufs to a sockbuf. 2194903Swnj */ 2204903Swnj sbreserve(sb, cc) 2214903Swnj struct sockbuf *sb; 2224903Swnj { 2234903Swnj 2245015Sroot if (m_reserve((cc*2)/MSIZE) == 0) 2254903Swnj return (0); 2264980Swnj sb->sb_hiwat = cc; 2275042Swnj sb->sb_mbmax = cc*2; 2284917Swnj return (1); 2294903Swnj } 2304903Swnj 2314903Swnj /* 2324903Swnj * Free mbufs held by a socket, and reserved mbuf space. 2334903Swnj */ 2344903Swnj sbrelease(sb) 2354903Swnj struct sockbuf *sb; 2364903Swnj { 2374903Swnj 2384903Swnj sbflush(sb); 2395019Swnj m_release(sb->sb_mbmax/MSIZE); 2404980Swnj sb->sb_hiwat = sb->sb_mbmax = 0; 2414903Swnj } 2424903Swnj 2434903Swnj /* 2444903Swnj * Routines to add (at the end) and remove (from the beginning) 2454903Swnj * data from a mbuf queue. 2464903Swnj */ 2474903Swnj 2484903Swnj /* 2494903Swnj * Append mbuf queue m to sockbuf sb. 2504903Swnj */ 2514903Swnj sbappend(sb, m) 2524903Swnj register struct mbuf *m; 2534903Swnj register struct sockbuf *sb; 2544903Swnj { 2554903Swnj register struct mbuf **np, *n; 2564903Swnj 2574903Swnj np = &sb->sb_mb; 2585013Swnj n = 0; 2595013Swnj while (*np) { 2605013Swnj n = *np; 2614903Swnj np = &n->m_next; 2625013Swnj } 2634903Swnj while (m) { 2645266Swnj if (m->m_len == 0 && (int)m->m_act == 0) { 2655304Sroot m = m_free(m); 2665266Swnj continue; 2675266Swnj } 2684903Swnj if (n && n->m_off <= MMAXOFF && m->m_off <= MMAXOFF && 2694903Swnj (int)n->m_act == 0 && (int)m->m_act == 0 && 2705042Swnj (n->m_off + n->m_len + m->m_len) <= MMAXOFF) { 2715042Swnj bcopy(mtod(m, caddr_t), mtod(n, caddr_t) + n->m_len, 2724917Swnj (unsigned)m->m_len); 2734903Swnj n->m_len += m->m_len; 2744903Swnj sb->sb_cc += m->m_len; 2754903Swnj m = m_free(m); 2764903Swnj continue; 2774903Swnj } 2784903Swnj sballoc(sb, m); 2794903Swnj *np = m; 2804903Swnj n = m; 2814903Swnj np = &n->m_next; 2824903Swnj m = m->m_next; 2834903Swnj } 2844903Swnj } 2854903Swnj 2865169Swnj /* 2875169Swnj * Append data and address. 2885169Swnj * Return 0 if no space in sockbuf or if 2895169Swnj * can't get mbuf to stuff address in. 2905169Swnj */ 2914928Swnj sbappendaddr(sb, asa, m0) 2924928Swnj struct sockbuf *sb; 2934928Swnj struct sockaddr *asa; 2944928Swnj struct mbuf *m0; 2954928Swnj { 2964928Swnj struct sockaddr *msa; 2974928Swnj register struct mbuf *m; 2984928Swnj register int len = sizeof (struct sockaddr); 2994928Swnj 3005042Swnj m = m0; 3015042Swnj if (m == 0) 3025042Swnj panic("sbappendaddr"); 3035042Swnj for (;;) { 3044928Swnj len += m->m_len; 3055042Swnj if (m->m_next == 0) { 3065042Swnj m->m_act = (struct mbuf *)1; 3075042Swnj break; 3085042Swnj } 3095042Swnj m = m->m_next; 3105042Swnj } 3115043Swnj if (len > sbspace(sb)) 3124928Swnj return (0); 3134928Swnj m = m_get(0); 3145043Swnj if (m == 0) 3154928Swnj return (0); 3164928Swnj m->m_off = MMINOFF; 3174928Swnj m->m_len = sizeof (struct sockaddr); 3184928Swnj msa = mtod(m, struct sockaddr *); 3194928Swnj *msa = *asa; 3204928Swnj m->m_act = (struct mbuf *)1; 3214928Swnj sbappend(sb, m); 3224928Swnj sbappend(sb, m0); 3234928Swnj return (1); 3244928Swnj } 3254928Swnj 3264903Swnj /* 3274903Swnj * Free all mbufs on a sockbuf mbuf chain. 3284903Swnj * Check that resource allocations return to 0. 3294903Swnj */ 3304903Swnj sbflush(sb) 3314903Swnj struct sockbuf *sb; 3324903Swnj { 3334903Swnj 3344903Swnj if (sb->sb_flags & SB_LOCK) 3354903Swnj panic("sbflush"); 3365266Swnj if (sb->sb_cc) 3375266Swnj sbdrop(sb, sb->sb_cc); 3384903Swnj if (sb->sb_cc || sb->sb_mbcnt || sb->sb_mb) 3394903Swnj panic("sbflush 2"); 3404903Swnj } 3414903Swnj 3424903Swnj /* 3434903Swnj * Drop data from (the front of) a sockbuf chain. 3444903Swnj */ 3454903Swnj sbdrop(sb, len) 3464903Swnj register struct sockbuf *sb; 3474903Swnj register int len; 3484903Swnj { 3494903Swnj register struct mbuf *m = sb->sb_mb, *mn; 3504903Swnj 3514903Swnj while (len > 0) { 3524903Swnj if (m == 0) 3534903Swnj panic("sbdrop"); 3545064Swnj if (m->m_len > len) { 3554903Swnj m->m_len -= len; 3564903Swnj m->m_off += len; 3574903Swnj sb->sb_cc -= len; 3584903Swnj break; 3594903Swnj } 3605064Swnj len -= m->m_len; 3615064Swnj sbfree(sb, m); 3625064Swnj MFREE(m, mn); 3635064Swnj m = mn; 3644903Swnj } 3654903Swnj sb->sb_mb = m; 3664903Swnj } 3675266Swnj 3685266Swnj /* 3695266Swnj printm(m) 3705266Swnj struct mbuf *m; 3715266Swnj { 3725266Swnj 3735266Swnj printf("<"); 3745266Swnj while (m) { 3755266Swnj printf("%d,", m->m_len); 3765266Swnj m = m->m_next; 3775266Swnj } 3785266Swnj printf(">"); 3795266Swnj printf("\n"); 3805266Swnj } 3815266Swnj */ 382