Separate receive socket errors from general socket errors.diff -r1.263 -r1.264 src/sys/kern/uipc_socket.c
(roy)
--- src/sys/kern/uipc_socket.c 2018/04/26 19:50:09 1.263
+++ src/sys/kern/uipc_socket.c 2018/06/06 09:46:46 1.264
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: uipc_socket.c,v 1.263 2018/04/26 19:50:09 maxv Exp $ */ | 1 | /* $NetBSD: uipc_socket.c,v 1.264 2018/06/06 09:46:46 roy Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2002, 2007, 2008, 2009 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2002, 2007, 2008, 2009 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Jason R. Thorpe of Wasabi Systems, Inc, and by Andrew Doran. | 8 | * by Jason R. Thorpe of Wasabi Systems, Inc, and by Andrew Doran. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -61,27 +61,27 @@ | @@ -61,27 +61,27 @@ | |||
61 | * | 61 | * | |
62 | * @(#)uipc_socket.c 8.6 (Berkeley) 5/2/95 | 62 | * @(#)uipc_socket.c 8.6 (Berkeley) 5/2/95 | |
63 | */ | 63 | */ | |
64 | 64 | |||
65 | /* | 65 | /* | |
66 | * Socket operation routines. | 66 | * Socket operation routines. | |
67 | * | 67 | * | |
68 | * These routines are called by the routines in sys_socket.c or from a | 68 | * These routines are called by the routines in sys_socket.c or from a | |
69 | * system process, and implement the semantics of socket operations by | 69 | * system process, and implement the semantics of socket operations by | |
70 | * switching out to the protocol specific routines. | 70 | * switching out to the protocol specific routines. | |
71 | */ | 71 | */ | |
72 | 72 | |||
73 | #include <sys/cdefs.h> | 73 | #include <sys/cdefs.h> | |
74 | __KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.263 2018/04/26 19:50:09 maxv Exp $"); | 74 | __KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.264 2018/06/06 09:46:46 roy Exp $"); | |
75 | 75 | |||
76 | #ifdef _KERNEL_OPT | 76 | #ifdef _KERNEL_OPT | |
77 | #include "opt_compat_netbsd.h" | 77 | #include "opt_compat_netbsd.h" | |
78 | #include "opt_sock_counters.h" | 78 | #include "opt_sock_counters.h" | |
79 | #include "opt_sosend_loan.h" | 79 | #include "opt_sosend_loan.h" | |
80 | #include "opt_mbuftrace.h" | 80 | #include "opt_mbuftrace.h" | |
81 | #include "opt_somaxkva.h" | 81 | #include "opt_somaxkva.h" | |
82 | #include "opt_multiprocessor.h" /* XXX */ | 82 | #include "opt_multiprocessor.h" /* XXX */ | |
83 | #include "opt_sctp.h" | 83 | #include "opt_sctp.h" | |
84 | #endif | 84 | #endif | |
85 | 85 | |||
86 | #include <sys/param.h> | 86 | #include <sys/param.h> | |
87 | #include <sys/systm.h> | 87 | #include <sys/systm.h> | |
@@ -1230,31 +1230,36 @@ soreceive(struct socket *so, struct mbuf | @@ -1230,31 +1230,36 @@ soreceive(struct socket *so, struct mbuf | |||
1230 | * a short count if a timeout or signal occurs after we start. | 1230 | * a short count if a timeout or signal occurs after we start. | |
1231 | */ | 1231 | */ | |
1232 | if (m == NULL || | 1232 | if (m == NULL || | |
1233 | ((flags & MSG_DONTWAIT) == 0 && | 1233 | ((flags & MSG_DONTWAIT) == 0 && | |
1234 | so->so_rcv.sb_cc < uio->uio_resid && | 1234 | so->so_rcv.sb_cc < uio->uio_resid && | |
1235 | (so->so_rcv.sb_cc < so->so_rcv.sb_lowat || | 1235 | (so->so_rcv.sb_cc < so->so_rcv.sb_lowat || | |
1236 | ((flags & MSG_WAITALL) && | 1236 | ((flags & MSG_WAITALL) && | |
1237 | uio->uio_resid <= so->so_rcv.sb_hiwat)) && | 1237 | uio->uio_resid <= so->so_rcv.sb_hiwat)) && | |
1238 | m->m_nextpkt == NULL && !atomic)) { | 1238 | m->m_nextpkt == NULL && !atomic)) { | |
1239 | #ifdef DIAGNOSTIC | 1239 | #ifdef DIAGNOSTIC | |
1240 | if (m == NULL && so->so_rcv.sb_cc) | 1240 | if (m == NULL && so->so_rcv.sb_cc) | |
1241 | panic("receive 1"); | 1241 | panic("receive 1"); | |
1242 | #endif | 1242 | #endif | |
1243 | if (so->so_error) { | 1243 | if (so->so_error || so->so_rerror) { | |
1244 | if (m != NULL) | 1244 | if (m != NULL) | |
1245 | goto dontblock; | 1245 | goto dontblock; | |
1246 | error = so->so_error; | 1246 | if (so->so_error) { | |
1247 | so->so_error = 0; | 1247 | error = so->so_error; | |
1248 | so->so_error = 0; | |||
1249 | } else { | |||
1250 | error = so->so_rerror; | |||
1251 | so->so_rerror = 0; | |||
1252 | } | |||
1248 | goto release; | 1253 | goto release; | |
1249 | } | 1254 | } | |
1250 | if (so->so_state & SS_CANTRCVMORE) { | 1255 | if (so->so_state & SS_CANTRCVMORE) { | |
1251 | if (m != NULL) | 1256 | if (m != NULL) | |
1252 | goto dontblock; | 1257 | goto dontblock; | |
1253 | else | 1258 | else | |
1254 | goto release; | 1259 | goto release; | |
1255 | } | 1260 | } | |
1256 | for (; m != NULL; m = m->m_next) | 1261 | for (; m != NULL; m = m->m_next) | |
1257 | if (m->m_type == MT_OOBDATA || (m->m_flags & M_EOR)) { | 1262 | if (m->m_type == MT_OOBDATA || (m->m_flags & M_EOR)) { | |
1258 | m = so->so_rcv.sb_mb; | 1263 | m = so->so_rcv.sb_mb; | |
1259 | goto dontblock; | 1264 | goto dontblock; | |
1260 | } | 1265 | } | |
@@ -1554,27 +1559,28 @@ soreceive(struct socket *so, struct mbuf | @@ -1554,27 +1559,28 @@ soreceive(struct socket *so, struct mbuf | |||
1554 | } | 1559 | } | |
1555 | } | 1560 | } | |
1556 | if (flags & MSG_EOR) | 1561 | if (flags & MSG_EOR) | |
1557 | break; | 1562 | break; | |
1558 | /* | 1563 | /* | |
1559 | * If the MSG_WAITALL flag is set (for non-atomic socket), | 1564 | * If the MSG_WAITALL flag is set (for non-atomic socket), | |
1560 | * we must not quit until "uio->uio_resid == 0" or an error | 1565 | * we must not quit until "uio->uio_resid == 0" or an error | |
1561 | * termination. If a signal/timeout occurs, return | 1566 | * termination. If a signal/timeout occurs, return | |
1562 | * with a short count but without error. | 1567 | * with a short count but without error. | |
1563 | * Keep sockbuf locked against other readers. | 1568 | * Keep sockbuf locked against other readers. | |
1564 | */ | 1569 | */ | |
1565 | while (flags & MSG_WAITALL && m == NULL && uio->uio_resid > 0 && | 1570 | while (flags & MSG_WAITALL && m == NULL && uio->uio_resid > 0 && | |
1566 | !sosendallatonce(so) && !nextrecord) { | 1571 | !sosendallatonce(so) && !nextrecord) { | |
1567 | if (so->so_error || so->so_state & SS_CANTRCVMORE) | 1572 | if (so->so_error || so->so_rerror || | |
1573 | so->so_state & SS_CANTRCVMORE) | |||
1568 | break; | 1574 | break; | |
1569 | /* | 1575 | /* | |
1570 | * If we are peeking and the socket receive buffer is | 1576 | * If we are peeking and the socket receive buffer is | |
1571 | * full, stop since we can't get more data to peek at. | 1577 | * full, stop since we can't get more data to peek at. | |
1572 | */ | 1578 | */ | |
1573 | if ((flags & MSG_PEEK) && sbspace(&so->so_rcv) <= 0) | 1579 | if ((flags & MSG_PEEK) && sbspace(&so->so_rcv) <= 0) | |
1574 | break; | 1580 | break; | |
1575 | /* | 1581 | /* | |
1576 | * If we've drained the socket buffer, tell the | 1582 | * If we've drained the socket buffer, tell the | |
1577 | * protocol in case it needs to do something to | 1583 | * protocol in case it needs to do something to | |
1578 | * get it filled again. | 1584 | * get it filled again. | |
1579 | */ | 1585 | */ | |
1580 | if ((pr->pr_flags & PR_WANTRCVD) && so->so_pcb) | 1586 | if ((pr->pr_flags & PR_WANTRCVD) && so->so_pcb) | |
@@ -2240,27 +2246,27 @@ static int | @@ -2240,27 +2246,27 @@ static int | |||
2240 | filt_soread(struct knote *kn, long hint) | 2246 | filt_soread(struct knote *kn, long hint) | |
2241 | { | 2247 | { | |
2242 | struct socket *so; | 2248 | struct socket *so; | |
2243 | int rv; | 2249 | int rv; | |
2244 | 2250 | |||
2245 | so = ((file_t *)kn->kn_obj)->f_socket; | 2251 | so = ((file_t *)kn->kn_obj)->f_socket; | |
2246 | if (hint != NOTE_SUBMIT) | 2252 | if (hint != NOTE_SUBMIT) | |
2247 | solock(so); | 2253 | solock(so); | |
2248 | kn->kn_data = so->so_rcv.sb_cc; | 2254 | kn->kn_data = so->so_rcv.sb_cc; | |
2249 | if (so->so_state & SS_CANTRCVMORE) { | 2255 | if (so->so_state & SS_CANTRCVMORE) { | |
2250 | kn->kn_flags |= EV_EOF; | 2256 | kn->kn_flags |= EV_EOF; | |
2251 | kn->kn_fflags = so->so_error; | 2257 | kn->kn_fflags = so->so_error; | |
2252 | rv = 1; | 2258 | rv = 1; | |
2253 | } else if (so->so_error) | 2259 | } else if (so->so_error || so->so_rerror) | |
2254 | rv = 1; | 2260 | rv = 1; | |
2255 | else if (kn->kn_sfflags & NOTE_LOWAT) | 2261 | else if (kn->kn_sfflags & NOTE_LOWAT) | |
2256 | rv = (kn->kn_data >= kn->kn_sdata); | 2262 | rv = (kn->kn_data >= kn->kn_sdata); | |
2257 | else | 2263 | else | |
2258 | rv = (kn->kn_data >= so->so_rcv.sb_lowat); | 2264 | rv = (kn->kn_data >= so->so_rcv.sb_lowat); | |
2259 | if (hint != NOTE_SUBMIT) | 2265 | if (hint != NOTE_SUBMIT) | |
2260 | sounlock(so); | 2266 | sounlock(so); | |
2261 | return rv; | 2267 | return rv; | |
2262 | } | 2268 | } | |
2263 | 2269 | |||
2264 | static void | 2270 | static void | |
2265 | filt_sowdetach(struct knote *kn) | 2271 | filt_sowdetach(struct knote *kn) | |
2266 | { | 2272 | { |
--- src/sys/kern/uipc_socket2.c 2018/04/29 07:13:10 1.129
+++ src/sys/kern/uipc_socket2.c 2018/06/06 09:46:46 1.130
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: uipc_socket2.c,v 1.129 2018/04/29 07:13:10 maxv Exp $ */ | 1 | /* $NetBSD: uipc_socket2.c,v 1.130 2018/06/06 09:46:46 roy Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2008 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2008 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -48,27 +48,27 @@ | @@ -48,27 +48,27 @@ | |||
48 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 48 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
49 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 49 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
50 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 50 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
51 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 51 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
54 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 54 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
55 | * SUCH DAMAGE. | 55 | * SUCH DAMAGE. | |
56 | * | 56 | * | |
57 | * @(#)uipc_socket2.c 8.2 (Berkeley) 2/14/95 | 57 | * @(#)uipc_socket2.c 8.2 (Berkeley) 2/14/95 | |
58 | */ | 58 | */ | |
59 | 59 | |||
60 | #include <sys/cdefs.h> | 60 | #include <sys/cdefs.h> | |
61 | __KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.129 2018/04/29 07:13:10 maxv Exp $"); | 61 | __KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.130 2018/06/06 09:46:46 roy Exp $"); | |
62 | 62 | |||
63 | #ifdef _KERNEL_OPT | 63 | #ifdef _KERNEL_OPT | |
64 | #include "opt_mbuftrace.h" | 64 | #include "opt_mbuftrace.h" | |
65 | #include "opt_sb_max.h" | 65 | #include "opt_sb_max.h" | |
66 | #endif | 66 | #endif | |
67 | 67 | |||
68 | #include <sys/param.h> | 68 | #include <sys/param.h> | |
69 | #include <sys/systm.h> | 69 | #include <sys/systm.h> | |
70 | #include <sys/proc.h> | 70 | #include <sys/proc.h> | |
71 | #include <sys/file.h> | 71 | #include <sys/file.h> | |
72 | #include <sys/buf.h> | 72 | #include <sys/buf.h> | |
73 | #include <sys/mbuf.h> | 73 | #include <sys/mbuf.h> | |
74 | #include <sys/protosw.h> | 74 | #include <sys/protosw.h> | |
@@ -494,27 +494,27 @@ socantrcvmore(struct socket *so) | @@ -494,27 +494,27 @@ socantrcvmore(struct socket *so) | |||
494 | sorwakeup(so); | 494 | sorwakeup(so); | |
495 | } | 495 | } | |
496 | 496 | |||
497 | /* | 497 | /* | |
498 | * soroverflow(): indicates that data was attempted to be sent | 498 | * soroverflow(): indicates that data was attempted to be sent | |
499 | * but the receiving buffer overflowed. | 499 | * but the receiving buffer overflowed. | |
500 | */ | 500 | */ | |
501 | void | 501 | void | |
502 | soroverflow(struct socket *so) | 502 | soroverflow(struct socket *so) | |
503 | { | 503 | { | |
504 | KASSERT(solocked(so)); | 504 | KASSERT(solocked(so)); | |
505 | 505 | |||
506 | so->so_rcv.sb_overflowed++; | 506 | so->so_rcv.sb_overflowed++; | |
507 | so->so_error = ENOBUFS; | 507 | so->so_rerror = ENOBUFS; | |
508 | sorwakeup(so); | 508 | sorwakeup(so); | |
509 | } | 509 | } | |
510 | 510 | |||
511 | /* | 511 | /* | |
512 | * Wait for data to arrive at/drain from a socket buffer. | 512 | * Wait for data to arrive at/drain from a socket buffer. | |
513 | */ | 513 | */ | |
514 | int | 514 | int | |
515 | sbwait(struct sockbuf *sb) | 515 | sbwait(struct sockbuf *sb) | |
516 | { | 516 | { | |
517 | struct socket *so; | 517 | struct socket *so; | |
518 | kmutex_t *lock; | 518 | kmutex_t *lock; | |
519 | int error; | 519 | int error; | |
520 | 520 |
--- src/sys/sys/socketvar.h 2018/05/04 08:35:07 1.155
+++ src/sys/sys/socketvar.h 2018/06/06 09:46:46 1.156
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: socketvar.h,v 1.155 2018/05/04 08:35:07 christos Exp $ */ | 1 | /* $NetBSD: socketvar.h,v 1.156 2018/06/06 09:46:46 roy Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Andrew Doran. | 8 | * by Andrew Doran. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -150,26 +150,27 @@ struct socket { | @@ -150,26 +150,27 @@ struct socket { | |||
150 | * We allow connections to queue up based on current queue lengths | 150 | * We allow connections to queue up based on current queue lengths | |
151 | * and limit on number of queued connections for this socket. | 151 | * and limit on number of queued connections for this socket. | |
152 | */ | 152 | */ | |
153 | struct socket *so_head; /* back pointer to accept socket */ | 153 | struct socket *so_head; /* back pointer to accept socket */ | |
154 | struct soqhead *so_onq; /* queue (q or q0) that we're on */ | 154 | struct soqhead *so_onq; /* queue (q or q0) that we're on */ | |
155 | struct soqhead so_q0; /* queue of partial connections */ | 155 | struct soqhead so_q0; /* queue of partial connections */ | |
156 | struct soqhead so_q; /* queue of incoming connections */ | 156 | struct soqhead so_q; /* queue of incoming connections */ | |
157 | TAILQ_ENTRY(socket) so_qe; /* our queue entry (q or q0) */ | 157 | TAILQ_ENTRY(socket) so_qe; /* our queue entry (q or q0) */ | |
158 | short so_q0len; /* partials on so_q0 */ | 158 | short so_q0len; /* partials on so_q0 */ | |
159 | short so_qlen; /* number of connections on so_q */ | 159 | short so_qlen; /* number of connections on so_q */ | |
160 | short so_qlimit; /* max number queued connections */ | 160 | short so_qlimit; /* max number queued connections */ | |
161 | short so_timeo; /* connection timeout */ | 161 | short so_timeo; /* connection timeout */ | |
162 | u_short so_error; /* error affecting connection */ | 162 | u_short so_error; /* error affecting connection */ | |
163 | u_short so_rerror; /* error affecting receiving */ | |||
163 | u_short so_aborting; /* references from soabort() */ | 164 | u_short so_aborting; /* references from soabort() */ | |
164 | pid_t so_pgid; /* pgid for signals */ | 165 | pid_t so_pgid; /* pgid for signals */ | |
165 | u_long so_oobmark; /* chars to oob mark */ | 166 | u_long so_oobmark; /* chars to oob mark */ | |
166 | struct sockbuf so_snd; /* send buffer */ | 167 | struct sockbuf so_snd; /* send buffer */ | |
167 | struct sockbuf so_rcv; /* receive buffer */ | 168 | struct sockbuf so_rcv; /* receive buffer */ | |
168 | 169 | |||
169 | void *so_internal; /* Space for svr4 stream data */ | 170 | void *so_internal; /* Space for svr4 stream data */ | |
170 | void (*so_upcall) (struct socket *, void *, int, int); | 171 | void (*so_upcall) (struct socket *, void *, int, int); | |
171 | void * so_upcallarg; /* Arg for above */ | 172 | void * so_upcallarg; /* Arg for above */ | |
172 | int (*so_send) (struct socket *, struct sockaddr *, | 173 | int (*so_send) (struct socket *, struct sockaddr *, | |
173 | struct uio *, struct mbuf *, | 174 | struct uio *, struct mbuf *, | |
174 | struct mbuf *, int, struct lwp *); | 175 | struct mbuf *, int, struct lwp *); | |
175 | int (*so_receive) (struct socket *, | 176 | int (*so_receive) (struct socket *, |