1*5248Sroot /* uipc_socket2.c 4.14 81/12/12 */ 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 44*5248Sroot printf("soisconnecting %x\n", so); 454903Swnj so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING); 464903Swnj so->so_state |= SS_ISCONNECTING; 474903Swnj wakeup((caddr_t)&so->so_timeo); 484903Swnj } 494903Swnj 504903Swnj soisconnected(so) 514903Swnj struct socket *so; 524903Swnj { 534903Swnj 54*5248Sroot printf("soisconnected %x\n", so); 554903Swnj so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING); 564903Swnj so->so_state |= SS_ISCONNECTED; 574903Swnj wakeup((caddr_t)&so->so_timeo); 584903Swnj } 594903Swnj 604903Swnj soisdisconnecting(so) 614903Swnj struct socket *so; 624903Swnj { 634903Swnj 64*5248Sroot printf("soisdisconnecting %x\n", so); 65*5248Sroot so->so_state &= ~SS_ISCONNECTING; 664903Swnj so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE); 674903Swnj wakeup((caddr_t)&so->so_timeo); 685170Swnj sowwakeup(so); 695169Swnj sorwakeup(so); 704903Swnj } 714903Swnj 724903Swnj soisdisconnected(so) 734903Swnj struct socket *so; 744903Swnj { 754903Swnj 76*5248Sroot printf("soisdisconnected %x\n", so); 774903Swnj so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING); 784903Swnj so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE); 794903Swnj wakeup((caddr_t)&so->so_timeo); 804903Swnj sowwakeup(so); 814903Swnj sorwakeup(so); 824903Swnj } 834903Swnj 845169Swnj /* 855169Swnj * Socantsendmore indicates that no more data will be sent on the 865169Swnj * socket; it would normally be applied to a socket when the user 875169Swnj * informs the system that no more data is to be sent, by the protocol 885169Swnj * code (in case PRU_SHUTDOWN). Socantrcvmore indicates that no more data 895169Swnj * will be received, and will normally be applied to the socket by a 905169Swnj * protocol when it detects that the peer will send no more data. 915169Swnj * Data queued for reading in the socket may yet be read. 925169Swnj */ 935169Swnj 944917Swnj socantsendmore(so) 954917Swnj struct socket *so; 964917Swnj { 974917Swnj 984917Swnj so->so_state |= SS_CANTSENDMORE; 994917Swnj sowwakeup(so); 1004917Swnj } 1014917Swnj 1024917Swnj socantrcvmore(so) 1034917Swnj struct socket *so; 1044917Swnj { 1054917Swnj 1064917Swnj so->so_state |= SS_CANTRCVMORE; 1074917Swnj sorwakeup(so); 1084917Swnj } 1094917Swnj 1104903Swnj /* 1115169Swnj * Socket select/wakeup routines. 1124903Swnj */ 1135169Swnj 1145169Swnj /* 1155169Swnj * Interface routine to select() system 1165169Swnj * call for sockets. 1175169Swnj */ 1184903Swnj soselect(so, flag) 1194903Swnj register struct socket *so; 1204903Swnj int flag; 1214903Swnj { 1224903Swnj 1234903Swnj if (flag & FREAD) { 1244903Swnj if (soreadable(so)) 1254903Swnj return (1); 1264903Swnj sbselqueue(&so->so_rcv); 1274903Swnj } 1284903Swnj if (flag & FWRITE) { 1294903Swnj if (sowriteable(so)) 1304903Swnj return (1); 1314903Swnj sbselqueue(&so->so_snd); 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) { 2644903Swnj if (n && n->m_off <= MMAXOFF && m->m_off <= MMAXOFF && 2654903Swnj (int)n->m_act == 0 && (int)m->m_act == 0 && 2665042Swnj (n->m_off + n->m_len + m->m_len) <= MMAXOFF) { 2675042Swnj bcopy(mtod(m, caddr_t), mtod(n, caddr_t) + n->m_len, 2684917Swnj (unsigned)m->m_len); 2694903Swnj n->m_len += m->m_len; 2704903Swnj sb->sb_cc += m->m_len; 2714903Swnj m = m_free(m); 2724903Swnj continue; 2734903Swnj } 2744903Swnj sballoc(sb, m); 2754903Swnj *np = m; 2764903Swnj n = m; 2774903Swnj np = &n->m_next; 2784903Swnj m = m->m_next; 2794903Swnj } 2804903Swnj } 2814903Swnj 2825169Swnj /* 2835169Swnj * Append data and address. 2845169Swnj * Return 0 if no space in sockbuf or if 2855169Swnj * can't get mbuf to stuff address in. 2865169Swnj */ 2874928Swnj sbappendaddr(sb, asa, m0) 2884928Swnj struct sockbuf *sb; 2894928Swnj struct sockaddr *asa; 2904928Swnj struct mbuf *m0; 2914928Swnj { 2924928Swnj struct sockaddr *msa; 2934928Swnj register struct mbuf *m; 2944928Swnj register int len = sizeof (struct sockaddr); 2954928Swnj 2965042Swnj m = m0; 2975042Swnj if (m == 0) 2985042Swnj panic("sbappendaddr"); 2995042Swnj for (;;) { 3004928Swnj len += m->m_len; 3015042Swnj if (m->m_next == 0) { 3025042Swnj m->m_act = (struct mbuf *)1; 3035042Swnj break; 3045042Swnj } 3055042Swnj m = m->m_next; 3065042Swnj } 3075043Swnj if (len > sbspace(sb)) 3084928Swnj return (0); 3094928Swnj m = m_get(0); 3105043Swnj if (m == 0) 3114928Swnj return (0); 3124928Swnj m->m_off = MMINOFF; 3134928Swnj m->m_len = sizeof (struct sockaddr); 3144928Swnj msa = mtod(m, struct sockaddr *); 3154928Swnj *msa = *asa; 3164928Swnj m->m_act = (struct mbuf *)1; 3174928Swnj sbappend(sb, m); 3184928Swnj sbappend(sb, m0); 3194928Swnj return (1); 3204928Swnj } 3214928Swnj 3224903Swnj /* 3234903Swnj * Free all mbufs on a sockbuf mbuf chain. 3244903Swnj * Check that resource allocations return to 0. 3254903Swnj */ 3264903Swnj sbflush(sb) 3274903Swnj struct sockbuf *sb; 3284903Swnj { 3294903Swnj 3304903Swnj if (sb->sb_flags & SB_LOCK) 3314903Swnj panic("sbflush"); 3324903Swnj sbdrop(sb, sb->sb_cc); 3334903Swnj if (sb->sb_cc || sb->sb_mbcnt || sb->sb_mb) 3344903Swnj panic("sbflush 2"); 3354903Swnj } 3364903Swnj 3374903Swnj /* 3384903Swnj * Drop data from (the front of) a sockbuf chain. 3394903Swnj */ 3404903Swnj sbdrop(sb, len) 3414903Swnj register struct sockbuf *sb; 3424903Swnj register int len; 3434903Swnj { 3444903Swnj register struct mbuf *m = sb->sb_mb, *mn; 3454903Swnj 3464903Swnj while (len > 0) { 3474903Swnj if (m == 0) 3484903Swnj panic("sbdrop"); 3495064Swnj if (m->m_len > len) { 3504903Swnj m->m_len -= len; 3514903Swnj m->m_off += len; 3524903Swnj sb->sb_cc -= len; 3534903Swnj break; 3544903Swnj } 3555064Swnj len -= m->m_len; 3565064Swnj sbfree(sb, m); 3575064Swnj MFREE(m, mn); 3585064Swnj m = mn; 3594903Swnj } 3604903Swnj sb->sb_mb = m; 3614903Swnj } 362