1/*
2 * Copyright (c) 1982, 1986, 1988, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
--- 20 unchanged lines hidden (view full) ---
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
34 */
35
36#include <sys/cdefs.h>
37__FBSDID("$FreeBSD: head/sys/kern/uipc_socket.c 121628 2003-10-28 05:47:40Z sam $");
38
39#include "opt_inet.h"
40#include "opt_mac.h"
41#include "opt_zero.h"
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/fcntl.h>
--- 837 unchanged lines hidden (view full) ---
883 goto release;
884 }
885 if (uio->uio_resid == 0)
886 goto release;
887 if ((so->so_state & SS_NBIO) || (flags & MSG_DONTWAIT)) {
888 error = EWOULDBLOCK;
889 goto release;
890 }
891 SBLASTRECORDCHK(&so->so_rcv);
892 SBLASTMBUFCHK(&so->so_rcv);
893 sbunlock(&so->so_rcv);
894 error = sbwait(&so->so_rcv);
895 splx(s);
896 if (error)
897 return (error);
898 goto restart;
899 }
900dontblock:
901 if (uio->uio_td)
902 uio->uio_td->td_proc->p_stats->p_ru.ru_msgrcv++;
903 SBLASTRECORDCHK(&so->so_rcv);
904 SBLASTMBUFCHK(&so->so_rcv);
905 nextrecord = m->m_nextpkt;
906 if (pr->pr_flags & PR_ADDR) {
907 KASSERT(m->m_type == MT_SONAME,
908 ("m->m_type == %d", m->m_type));
909 orig_resid = 0;
910 if (psa)
911 *psa = dup_sockaddr(mtod(m, struct sockaddr *),
912 mp0 == 0);
--- 25 unchanged lines hidden (view full) ---
938 }
939 if (controlp) {
940 orig_resid = 0;
941 while (*controlp != NULL)
942 controlp = &(*controlp)->m_next;
943 }
944 }
945 if (m) {
946 if ((flags & MSG_PEEK) == 0) {
947 m->m_nextpkt = nextrecord;
948 /*
949 * If nextrecord == NULL (this is a single chain),
950 * then sb_lastrecord may not be valid here if m
951 * was changed earlier.
952 */
953 if (nextrecord == NULL) {
954 KASSERT(so->so_rcv.sb_mb == m,
955 ("receive tailq 1"));
956 so->so_rcv.sb_lastrecord = m;
957 }
958 }
959 type = m->m_type;
960 if (type == MT_OOBDATA)
961 flags |= MSG_OOB;
962 } else {
963 if ((flags & MSG_PEEK) == 0) {
964 KASSERT(so->so_rcv.sb_mb == m,("receive tailq 2"));
965 so->so_rcv.sb_mb = nextrecord;
966 SB_EMPTY_FIXUP(&so->so_rcv);
967 }
968 }
969 SBLASTRECORDCHK(&so->so_rcv);
970 SBLASTMBUFCHK(&so->so_rcv);
971
972 moff = 0;
973 offset = 0;
974 while (m && uio->uio_resid > 0 && error == 0) {
975 if (m->m_type == MT_OOBDATA) {
976 if (type != MT_OOBDATA)
977 break;
978 } else if (type == MT_OOBDATA)
979 break;
--- 10 unchanged lines hidden (view full) ---
990 * If mp is set, just pass back the mbufs.
991 * Otherwise copy them out via the uio, then free.
992 * Sockbuf must be consistent here (points to current mbuf,
993 * it points to next record) when we drop priority;
994 * we must note any additions to the sockbuf when we
995 * block interrupts again.
996 */
997 if (mp == 0) {
998 SBLASTRECORDCHK(&so->so_rcv);
999 SBLASTMBUFCHK(&so->so_rcv);
1000 splx(s);
1001#ifdef ZERO_COPY_SOCKETS
1002 if (so_zero_copy_receive) {
1003 vm_page_t pg;
1004 int disposable;
1005
1006 if ((m->m_flags & M_EXT)
1007 && (m->m_ext.ext_type == EXT_DISPOSABLE))
--- 31 unchanged lines hidden (view full) ---
1039 *mp = m;
1040 mp = &m->m_next;
1041 so->so_rcv.sb_mb = m = m->m_next;
1042 *mp = (struct mbuf *)0;
1043 } else {
1044 so->so_rcv.sb_mb = m_free(m);
1045 m = so->so_rcv.sb_mb;
1046 }
1047 if (m) {
1048 m->m_nextpkt = nextrecord;
1049 if (nextrecord == NULL)
1050 so->so_rcv.sb_lastrecord = m;
1051 } else {
1052 so->so_rcv.sb_mb = nextrecord;
1053 SB_EMPTY_FIXUP(&so->so_rcv);
1054 }
1055 SBLASTRECORDCHK(&so->so_rcv);
1056 SBLASTMBUFCHK(&so->so_rcv);
1057 }
1058 } else {
1059 if (flags & MSG_PEEK)
1060 moff += len;
1061 else {
1062 if (mp)
1063 *mp = m_copym(m, 0, len, M_TRYWAIT);
1064 m->m_data += len;
--- 28 unchanged lines hidden (view full) ---
1093 if (so->so_error || so->so_state & SS_CANTRCVMORE)
1094 break;
1095 /*
1096 * Notify the protocol that some data has been
1097 * drained before blocking.
1098 */
1099 if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
1100 (*pr->pr_usrreqs->pru_rcvd)(so, flags);
1101 SBLASTRECORDCHK(&so->so_rcv);
1102 SBLASTMBUFCHK(&so->so_rcv);
1103 error = sbwait(&so->so_rcv);
1104 if (error) {
1105 sbunlock(&so->so_rcv);
1106 splx(s);
1107 return (0);
1108 }
1109 m = so->so_rcv.sb_mb;
1110 if (m)
1111 nextrecord = m->m_nextpkt;
1112 }
1113 }
1114
1115 if (m && pr->pr_flags & PR_ATOMIC) {
1116 flags |= MSG_TRUNC;
1117 if ((flags & MSG_PEEK) == 0)
1118 (void) sbdroprecord(&so->so_rcv);
1119 }
1120 if ((flags & MSG_PEEK) == 0) {
1121 if (m == 0) {
1122 /*
1123 * First part is an inline SB_EMPTY_FIXUP(). Second
1124 * part makes sure sb_lastrecord is up-to-date if
1125 * there is still data in the socket buffer.
1126 */
1127 so->so_rcv.sb_mb = nextrecord;
1128 if (so->so_rcv.sb_mb == NULL) {
1129 so->so_rcv.sb_mbtail = NULL;
1130 so->so_rcv.sb_lastrecord = NULL;
1131 } else if (nextrecord->m_nextpkt == NULL)
1132 so->so_rcv.sb_lastrecord = nextrecord;
1133 }
1134 SBLASTRECORDCHK(&so->so_rcv);
1135 SBLASTMBUFCHK(&so->so_rcv);
1136 if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
1137 (*pr->pr_usrreqs->pru_rcvd)(so, flags);
1138 }
1139 if (orig_resid == uio->uio_resid && orig_resid &&
1140 (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
1141 sbunlock(&so->so_rcv);
1142 splx(s);
1143 goto restart;
--- 763 unchanged lines hidden ---
2 * Copyright (c) 1982, 1986, 1988, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
--- 20 unchanged lines hidden (view full) ---
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
34 */
35
36#include <sys/cdefs.h>
37__FBSDID("$FreeBSD: head/sys/kern/uipc_socket.c 121628 2003-10-28 05:47:40Z sam $");
38
39#include "opt_inet.h"
40#include "opt_mac.h"
41#include "opt_zero.h"
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/fcntl.h>
--- 837 unchanged lines hidden (view full) ---
883 goto release;
884 }
885 if (uio->uio_resid == 0)
886 goto release;
887 if ((so->so_state & SS_NBIO) || (flags & MSG_DONTWAIT)) {
888 error = EWOULDBLOCK;
889 goto release;
890 }
891 SBLASTRECORDCHK(&so->so_rcv);
892 SBLASTMBUFCHK(&so->so_rcv);
893 sbunlock(&so->so_rcv);
894 error = sbwait(&so->so_rcv);
895 splx(s);
896 if (error)
897 return (error);
898 goto restart;
899 }
900dontblock:
901 if (uio->uio_td)
902 uio->uio_td->td_proc->p_stats->p_ru.ru_msgrcv++;
903 SBLASTRECORDCHK(&so->so_rcv);
904 SBLASTMBUFCHK(&so->so_rcv);
905 nextrecord = m->m_nextpkt;
906 if (pr->pr_flags & PR_ADDR) {
907 KASSERT(m->m_type == MT_SONAME,
908 ("m->m_type == %d", m->m_type));
909 orig_resid = 0;
910 if (psa)
911 *psa = dup_sockaddr(mtod(m, struct sockaddr *),
912 mp0 == 0);
--- 25 unchanged lines hidden (view full) ---
938 }
939 if (controlp) {
940 orig_resid = 0;
941 while (*controlp != NULL)
942 controlp = &(*controlp)->m_next;
943 }
944 }
945 if (m) {
946 if ((flags & MSG_PEEK) == 0) {
947 m->m_nextpkt = nextrecord;
948 /*
949 * If nextrecord == NULL (this is a single chain),
950 * then sb_lastrecord may not be valid here if m
951 * was changed earlier.
952 */
953 if (nextrecord == NULL) {
954 KASSERT(so->so_rcv.sb_mb == m,
955 ("receive tailq 1"));
956 so->so_rcv.sb_lastrecord = m;
957 }
958 }
959 type = m->m_type;
960 if (type == MT_OOBDATA)
961 flags |= MSG_OOB;
962 } else {
963 if ((flags & MSG_PEEK) == 0) {
964 KASSERT(so->so_rcv.sb_mb == m,("receive tailq 2"));
965 so->so_rcv.sb_mb = nextrecord;
966 SB_EMPTY_FIXUP(&so->so_rcv);
967 }
968 }
969 SBLASTRECORDCHK(&so->so_rcv);
970 SBLASTMBUFCHK(&so->so_rcv);
971
972 moff = 0;
973 offset = 0;
974 while (m && uio->uio_resid > 0 && error == 0) {
975 if (m->m_type == MT_OOBDATA) {
976 if (type != MT_OOBDATA)
977 break;
978 } else if (type == MT_OOBDATA)
979 break;
--- 10 unchanged lines hidden (view full) ---
990 * If mp is set, just pass back the mbufs.
991 * Otherwise copy them out via the uio, then free.
992 * Sockbuf must be consistent here (points to current mbuf,
993 * it points to next record) when we drop priority;
994 * we must note any additions to the sockbuf when we
995 * block interrupts again.
996 */
997 if (mp == 0) {
998 SBLASTRECORDCHK(&so->so_rcv);
999 SBLASTMBUFCHK(&so->so_rcv);
1000 splx(s);
1001#ifdef ZERO_COPY_SOCKETS
1002 if (so_zero_copy_receive) {
1003 vm_page_t pg;
1004 int disposable;
1005
1006 if ((m->m_flags & M_EXT)
1007 && (m->m_ext.ext_type == EXT_DISPOSABLE))
--- 31 unchanged lines hidden (view full) ---
1039 *mp = m;
1040 mp = &m->m_next;
1041 so->so_rcv.sb_mb = m = m->m_next;
1042 *mp = (struct mbuf *)0;
1043 } else {
1044 so->so_rcv.sb_mb = m_free(m);
1045 m = so->so_rcv.sb_mb;
1046 }
1047 if (m) {
1048 m->m_nextpkt = nextrecord;
1049 if (nextrecord == NULL)
1050 so->so_rcv.sb_lastrecord = m;
1051 } else {
1052 so->so_rcv.sb_mb = nextrecord;
1053 SB_EMPTY_FIXUP(&so->so_rcv);
1054 }
1055 SBLASTRECORDCHK(&so->so_rcv);
1056 SBLASTMBUFCHK(&so->so_rcv);
1057 }
1058 } else {
1059 if (flags & MSG_PEEK)
1060 moff += len;
1061 else {
1062 if (mp)
1063 *mp = m_copym(m, 0, len, M_TRYWAIT);
1064 m->m_data += len;
--- 28 unchanged lines hidden (view full) ---
1093 if (so->so_error || so->so_state & SS_CANTRCVMORE)
1094 break;
1095 /*
1096 * Notify the protocol that some data has been
1097 * drained before blocking.
1098 */
1099 if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
1100 (*pr->pr_usrreqs->pru_rcvd)(so, flags);
1101 SBLASTRECORDCHK(&so->so_rcv);
1102 SBLASTMBUFCHK(&so->so_rcv);
1103 error = sbwait(&so->so_rcv);
1104 if (error) {
1105 sbunlock(&so->so_rcv);
1106 splx(s);
1107 return (0);
1108 }
1109 m = so->so_rcv.sb_mb;
1110 if (m)
1111 nextrecord = m->m_nextpkt;
1112 }
1113 }
1114
1115 if (m && pr->pr_flags & PR_ATOMIC) {
1116 flags |= MSG_TRUNC;
1117 if ((flags & MSG_PEEK) == 0)
1118 (void) sbdroprecord(&so->so_rcv);
1119 }
1120 if ((flags & MSG_PEEK) == 0) {
1121 if (m == 0) {
1122 /*
1123 * First part is an inline SB_EMPTY_FIXUP(). Second
1124 * part makes sure sb_lastrecord is up-to-date if
1125 * there is still data in the socket buffer.
1126 */
1127 so->so_rcv.sb_mb = nextrecord;
1128 if (so->so_rcv.sb_mb == NULL) {
1129 so->so_rcv.sb_mbtail = NULL;
1130 so->so_rcv.sb_lastrecord = NULL;
1131 } else if (nextrecord->m_nextpkt == NULL)
1132 so->so_rcv.sb_lastrecord = nextrecord;
1133 }
1134 SBLASTRECORDCHK(&so->so_rcv);
1135 SBLASTMBUFCHK(&so->so_rcv);
1136 if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
1137 (*pr->pr_usrreqs->pru_rcvd)(so, flags);
1138 }
1139 if (orig_resid == uio->uio_resid && orig_resid &&
1140 (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
1141 sbunlock(&so->so_rcv);
1142 splx(s);
1143 goto restart;
--- 763 unchanged lines hidden ---