Deleted Added
full compact
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 ---