uipc_socket.c (178888) | uipc_socket.c (180198) |
---|---|
1/*- 2 * Copyright (c) 1982, 1986, 1988, 1990, 1993 3 * The Regents of the University of California. 4 * Copyright (c) 2004 The FreeBSD Foundation 5 * Copyright (c) 2004-2007 Robert N. M. Watson 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 81 unchanged lines hidden (view full) --- 90 * calls to explicitly manage socket references, soref(), and sorele(). 91 * Currently, these are generally required only when transitioning a socket 92 * from a listen queue to a file descriptor, in order to prevent garbage 93 * collection of the socket at an untimely moment. For a number of reasons, 94 * these interfaces are not preferred, and should be avoided. 95 */ 96 97#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1982, 1986, 1988, 1990, 1993 3 * The Regents of the University of California. 4 * Copyright (c) 2004 The FreeBSD Foundation 5 * Copyright (c) 2004-2007 Robert N. M. Watson 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 81 unchanged lines hidden (view full) --- 90 * calls to explicitly manage socket references, soref(), and sorele(). 91 * Currently, these are generally required only when transitioning a socket 92 * from a listen queue to a file descriptor, in order to prevent garbage 93 * collection of the socket at an untimely moment. For a number of reasons, 94 * these interfaces are not preferred, and should be avoided. 95 */ 96 97#include <sys/cdefs.h> |
98__FBSDID("$FreeBSD: head/sys/kern/uipc_socket.c 178888 2008-05-09 23:03:00Z julian $"); | 98__FBSDID("$FreeBSD: head/sys/kern/uipc_socket.c 180198 2008-07-02 23:23:27Z rwatson $"); |
99 100#include "opt_inet.h" 101#include "opt_mac.h" 102#include "opt_zero.h" 103#include "opt_compat.h" 104 105#include <sys/param.h> 106#include <sys/systm.h> --- 1733 unchanged lines hidden (view full) --- 1840 1841 if (flagsp != NULL) 1842 *flagsp |= flags; 1843release: 1844 sbunlock(&so->so_rcv); 1845 return (error); 1846} 1847 | 99 100#include "opt_inet.h" 101#include "opt_mac.h" 102#include "opt_zero.h" 103#include "opt_compat.h" 104 105#include <sys/param.h> 106#include <sys/systm.h> --- 1733 unchanged lines hidden (view full) --- 1840 1841 if (flagsp != NULL) 1842 *flagsp |= flags; 1843release: 1844 sbunlock(&so->so_rcv); 1845 return (error); 1846} 1847 |
1848/* 1849 * Optimized version of soreceive() for simple datagram cases from userspace; 1850 * this is experimental, and while heavily tested, may contain errors. 1851 */ |
|
1848int | 1852int |
1853soreceive_dgram(struct socket *so, struct sockaddr **psa, struct uio *uio, 1854 struct mbuf **mp0, struct mbuf **controlp, int *flagsp) 1855{ 1856 struct mbuf *m, *m2; 1857 int flags, len, error, offset; 1858 struct protosw *pr = so->so_proto; 1859 struct mbuf *nextrecord; 1860 int orig_resid = uio->uio_resid; 1861 1862 if (psa != NULL) 1863 *psa = NULL; 1864 if (controlp != NULL) 1865 *controlp = NULL; 1866 if (flagsp != NULL) 1867 flags = *flagsp &~ MSG_EOR; 1868 else 1869 flags = 0; 1870 1871 /* 1872 * For any complicated cases, fall back to the full 1873 * soreceive_generic(). 1874 */ 1875 if (mp0 != NULL || (flags & MSG_PEEK) || (flags & MSG_OOB)) 1876 return (soreceive_generic(so, psa, uio, mp0, controlp, 1877 flagsp)); 1878 1879 /* 1880 * Enforce restrictions on use. 1881 */ 1882 KASSERT((pr->pr_flags & PR_WANTRCVD) == 0, 1883 ("soreceive_dgram: wantrcvd")); 1884 KASSERT(pr->pr_flags & PR_ATOMIC, ("soreceive_dgram: !atomic")); 1885 KASSERT((so->so_rcv.sb_state & SBS_RCVATMARK) == 0, 1886 ("soreceive_dgram: SBS_RCVATMARK")); 1887 KASSERT((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0, 1888 ("soreceive_dgram: P_CONNREQUIRED")); 1889 1890restart: 1891 SOCKBUF_LOCK(&so->so_rcv); 1892 m = so->so_rcv.sb_mb; 1893 1894 /* 1895 * If we have less data than requested, block awaiting more (subject 1896 * to any timeout) if: 1897 * 1. the current count is less than the low water mark, or 1898 * 2. MSG_WAITALL is set, and it is possible to do the entire 1899 * receive operation at once if we block (resid <= hiwat). 1900 * 3. MSG_DONTWAIT is not set 1901 * If MSG_WAITALL is set but resid is larger than the receive buffer, 1902 * we have to do the receive in sections, and thus risk returning a 1903 * short count if a timeout or signal occurs after we start. 1904 */ 1905 if (m == NULL) { 1906 KASSERT(m != NULL || !so->so_rcv.sb_cc, 1907 ("receive: m == %p so->so_rcv.sb_cc == %u", 1908 m, so->so_rcv.sb_cc)); 1909 if (so->so_error) { 1910 if (m != NULL) 1911 goto dontblock; 1912 error = so->so_error; 1913 so->so_error = 0; 1914 SOCKBUF_UNLOCK(&so->so_rcv); 1915 return (error); 1916 } 1917 SOCKBUF_LOCK_ASSERT(&so->so_rcv); 1918 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { 1919 if (m == NULL) { 1920 SOCKBUF_UNLOCK(&so->so_rcv); 1921 return (0); 1922 } else 1923 goto dontblock; 1924 } 1925 if (uio->uio_resid == 0) { 1926 SOCKBUF_UNLOCK(&so->so_rcv); 1927 return (0); 1928 } 1929 if ((so->so_state & SS_NBIO) || 1930 (flags & (MSG_DONTWAIT|MSG_NBIO))) { 1931 SOCKBUF_UNLOCK(&so->so_rcv); 1932 error = EWOULDBLOCK; 1933 return (error); 1934 } 1935 SBLASTRECORDCHK(&so->so_rcv); 1936 SBLASTMBUFCHK(&so->so_rcv); 1937 1938 /* XXXRW: sbwait() may not be as happy without sblock(). */ 1939 error = sbwait(&so->so_rcv); 1940 SOCKBUF_UNLOCK(&so->so_rcv); 1941 if (error) 1942 return (error); 1943 goto restart; 1944 } 1945dontblock: 1946 /* 1947 * From this point onward, we maintain 'nextrecord' as a cache of the 1948 * pointer to the next record in the socket buffer. We must keep the 1949 * various socket buffer pointers and local stack versions of the 1950 * pointers in sync, pushing out modifications before dropping the 1951 * socket buffer mutex, and re-reading them when picking it up. 1952 * 1953 * Otherwise, we will race with the network stack appending new data 1954 * or records onto the socket buffer by using inconsistent/stale 1955 * versions of the field, possibly resulting in socket buffer 1956 * corruption. 1957 * 1958 * By holding the high-level sblock(), we prevent simultaneous 1959 * readers from pulling off the front of the socket buffer. 1960 */ 1961 SOCKBUF_LOCK_ASSERT(&so->so_rcv); 1962 if (uio->uio_td) 1963 uio->uio_td->td_ru.ru_msgrcv++; 1964 KASSERT(m == so->so_rcv.sb_mb, ("soreceive: m != so->so_rcv.sb_mb")); 1965 SBLASTRECORDCHK(&so->so_rcv); 1966 SBLASTMBUFCHK(&so->so_rcv); 1967 nextrecord = m->m_nextpkt; 1968 if (pr->pr_flags & PR_ADDR) { 1969 KASSERT(m->m_type == MT_SONAME, 1970 ("m->m_type == %d", m->m_type)); 1971 orig_resid = 0; 1972 if (psa != NULL) 1973 *psa = sodupsockaddr(mtod(m, struct sockaddr *), 1974 M_NOWAIT); 1975 sbfree(&so->so_rcv, m); 1976 so->so_rcv.sb_mb = m_free(m); 1977 m = so->so_rcv.sb_mb; 1978 sockbuf_pushsync(&so->so_rcv, nextrecord); 1979 } 1980 if (m == NULL) { 1981 /* XXXRW: Can this happen? */ 1982 SOCKBUF_UNLOCK(&so->so_rcv); 1983 return (0); 1984 } 1985 KASSERT(m->m_nextpkt == nextrecord, 1986 ("soreceive: post-control, nextrecord !sync")); 1987 if (nextrecord == NULL) { 1988 KASSERT(so->so_rcv.sb_mb == m, 1989 ("soreceive: post-control, sb_mb!=m")); 1990 KASSERT(so->so_rcv.sb_lastrecord == m, 1991 ("soreceive: post-control, lastrecord!=m")); 1992 } 1993 1994 SOCKBUF_LOCK_ASSERT(&so->so_rcv); 1995 SBLASTRECORDCHK(&so->so_rcv); 1996 SBLASTMBUFCHK(&so->so_rcv); 1997 KASSERT(m == so->so_rcv.sb_mb, ("soreceive_dgram: m not sb_mb")); 1998 KASSERT(so->so_rcv.sb_mb->m_nextpkt == nextrecord, 1999 ("soreceive_dgram: m_nextpkt != nextrecord")); 2000 2001 /* 2002 * Pull 'm' and its chain off the front of the packet queue. 2003 */ 2004 so->so_rcv.sb_mb = NULL; 2005 sockbuf_pushsync(&so->so_rcv, nextrecord); 2006 2007 /* 2008 * Walk 'm's chain and free that many bytes from the socket buffer. 2009 */ 2010 for (m2 = m; m2 != NULL; m2 = m2->m_next) 2011 sbfree(&so->so_rcv, m2); 2012 2013 /* 2014 * Do a few last checks before we let go of the lock. 2015 */ 2016 SBLASTRECORDCHK(&so->so_rcv); 2017 SBLASTMBUFCHK(&so->so_rcv); 2018 SOCKBUF_UNLOCK(&so->so_rcv); 2019 2020 /* 2021 * Packet to copyout() is now in 'm' and it is disconnected from the 2022 * queue. 2023 * 2024 * Process one or more MT_CONTROL mbufs present before any data mbufs 2025 * in the first mbuf chain on the socket buffer. If MSG_PEEK, we 2026 * just copy the data; if !MSG_PEEK, we call into the protocol to 2027 * perform externalization (or freeing if controlp == NULL). 2028 */ 2029 if (m->m_type == MT_CONTROL) { 2030 struct mbuf *cm = NULL, *cmn; 2031 struct mbuf **cme = &cm; 2032 2033 do { 2034 m2 = m->m_next; 2035 m->m_next = NULL; 2036 *cme = m; 2037 cme = &(*cme)->m_next; 2038 m = m2; 2039 } while (m != NULL && m->m_type == MT_CONTROL); 2040 while (cm != NULL) { 2041 cmn = cm->m_next; 2042 cm->m_next = NULL; 2043 if (pr->pr_domain->dom_externalize != NULL) { 2044 error = (*pr->pr_domain->dom_externalize) 2045 (cm, controlp); 2046 } else if (controlp != NULL) 2047 *controlp = cm; 2048 else 2049 m_freem(cm); 2050 if (controlp != NULL) { 2051 orig_resid = 0; 2052 while (*controlp != NULL) 2053 controlp = &(*controlp)->m_next; 2054 } 2055 cm = cmn; 2056 } 2057 orig_resid = 0; /* XXXRW: why this? */ 2058 } 2059 2060 KASSERT(m->m_type == MT_DATA, ("soreceive_dgram: !data")); 2061 2062 offset = 0; 2063 while (m != NULL && uio->uio_resid > 0) { 2064 len = uio->uio_resid; 2065 if (len > m->m_len) 2066 len = m->m_len; 2067 error = uiomove(mtod(m, char *), (int)len, uio); 2068 if (error) { 2069 m_freem(m); 2070 return (error); 2071 } 2072 m = m_free(m); 2073 } 2074 if (m != NULL && pr->pr_flags & PR_ATOMIC) 2075 flags |= MSG_TRUNC; 2076 m_freem(m); 2077 if (flagsp != NULL) 2078 *flagsp |= flags; 2079 return (0); 2080} 2081 2082int |
|
1849soreceive(struct socket *so, struct sockaddr **psa, struct uio *uio, 1850 struct mbuf **mp0, struct mbuf **controlp, int *flagsp) 1851{ 1852 1853 /* XXXRW: Temporary debugging. */ 1854 KASSERT(so->so_proto->pr_usrreqs->pru_soreceive != soreceive, 1855 ("soreceive: protocol calls soreceive")); 1856 --- 1121 unchanged lines hidden --- | 2083soreceive(struct socket *so, struct sockaddr **psa, struct uio *uio, 2084 struct mbuf **mp0, struct mbuf **controlp, int *flagsp) 2085{ 2086 2087 /* XXXRW: Temporary debugging. */ 2088 KASSERT(so->so_proto->pr_usrreqs->pru_soreceive != soreceive, 2089 ("soreceive: protocol calls soreceive")); 2090 --- 1121 unchanged lines hidden --- |