Revert "SO_RERROR indicates that receive buffer overflows should be handled as errors."
Wrong version of the change was pushed inadvertenly.
This reverts commit 4a01b854ca
.
This commit is contained in:
parent
db2f512381
commit
924d1c9a05
@ -28,7 +28,7 @@
|
||||
.\" @(#)getsockopt.2 8.4 (Berkeley) 5/2/95
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd Feb 07, 2020
|
||||
.Dd June 3, 2020
|
||||
.Dt GETSOCKOPT 2
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -177,7 +177,6 @@ for the socket
|
||||
.It Dv SO_PROTOCOL Ta "get the protocol number for the socket (get only)"
|
||||
.It Dv SO_PROTOTYPE Ta "SunOS alias for the Linux SO_PROTOCOL (get only)"
|
||||
.It Dv SO_ERROR Ta "get and clear error on the socket (get only)"
|
||||
.It Dv SO_RERROR Ta "enables receive error reporting"
|
||||
.It Dv SO_SETFIB Ta "set the associated FIB (routing table) for the socket (set only)"
|
||||
.El
|
||||
.Pp
|
||||
@ -515,13 +514,6 @@ returns any pending error on the socket and clears
|
||||
the error status.
|
||||
It may be used to check for asynchronous errors on connected
|
||||
datagram sockets or for other asynchronous errors.
|
||||
.Dv SO_RERROR
|
||||
indicates that receive buffer overflows should be handled as errors.
|
||||
Historically receive buffer overflows have been ignored and programs
|
||||
could not tell if they missed messages or messages had been truncated
|
||||
because of overflows.
|
||||
Since programs historically do not expect to get receive overflow errors,
|
||||
this behavior is not the default.
|
||||
.Pp
|
||||
.Dv SO_LABEL
|
||||
returns the MAC label of the socket.
|
||||
|
@ -1444,20 +1444,9 @@ monitor(int argc, char *argv[])
|
||||
interfaces();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#ifdef SO_RERROR
|
||||
n = 1;
|
||||
if (setsockopt(s, SOL_SOCKET, SO_RERROR, &n, sizeof(n)) == -1)
|
||||
warn("SO_RERROR");
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
time_t now;
|
||||
n = read(s, msg, sizeof(msg));
|
||||
if (n == -1) {
|
||||
warn("read");
|
||||
continue;
|
||||
}
|
||||
n = read(s, msg, 2048);
|
||||
now = time(NULL);
|
||||
(void)printf("\ngot message of size %d on %s", n, ctime(&now));
|
||||
print_rtmsg((struct rt_msghdr *)(void *)msg, n);
|
||||
|
@ -436,30 +436,6 @@ socantrcvmore(struct socket *so)
|
||||
mtx_assert(SOCKBUF_MTX(&so->so_rcv), MA_NOTOWNED);
|
||||
}
|
||||
|
||||
void
|
||||
soroverflow_locked(struct socket *so)
|
||||
{
|
||||
|
||||
SOCKBUF_LOCK_ASSERT(&so->so_rcv);
|
||||
|
||||
if (so->so_options & SO_RERROR) {
|
||||
so->so_rerror = ENOBUFS;
|
||||
sorwakeup_locked(so);
|
||||
} else
|
||||
SOCKBUF_UNLOCK(&so->so_rcv);
|
||||
|
||||
mtx_assert(SOCKBUF_MTX(&so->so_rcv), MA_NOTOWNED);
|
||||
}
|
||||
|
||||
void
|
||||
soroverflow(struct socket *so)
|
||||
{
|
||||
|
||||
SOCKBUF_LOCK(&so->so_rcv);
|
||||
soroverflow_locked(so);
|
||||
mtx_assert(SOCKBUF_MTX(&so->so_rcv), MA_NOTOWNED);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for data to arrive at/drain from a socket buffer.
|
||||
*/
|
||||
|
@ -1953,19 +1953,12 @@ soreceive_generic(struct socket *so, struct sockaddr **psa, struct uio *uio,
|
||||
KASSERT(m != NULL || !sbavail(&so->so_rcv),
|
||||
("receive: m == %p sbavail == %u",
|
||||
m, sbavail(&so->so_rcv)));
|
||||
if (so->so_error || so->so_rerror) {
|
||||
if (so->so_error) {
|
||||
if (m != NULL)
|
||||
goto dontblock;
|
||||
if (so->so_error)
|
||||
error = so->so_error;
|
||||
else
|
||||
error = so->so_rerror;
|
||||
if ((flags & MSG_PEEK) == 0) {
|
||||
if (so->so_error)
|
||||
so->so_error = 0;
|
||||
else
|
||||
so->so_rerror = 0;
|
||||
}
|
||||
error = so->so_error;
|
||||
if ((flags & MSG_PEEK) == 0)
|
||||
so->so_error = 0;
|
||||
SOCKBUF_UNLOCK(&so->so_rcv);
|
||||
goto release;
|
||||
}
|
||||
@ -2309,7 +2302,7 @@ soreceive_generic(struct socket *so, struct sockaddr **psa, struct uio *uio,
|
||||
while (flags & MSG_WAITALL && m == NULL && uio->uio_resid > 0 &&
|
||||
!sosendallatonce(so) && nextrecord == NULL) {
|
||||
SOCKBUF_LOCK_ASSERT(&so->so_rcv);
|
||||
if (so->so_error || so->so_rerror ||
|
||||
if (so->so_error ||
|
||||
so->so_rcv.sb_state & SBS_CANTRCVMORE)
|
||||
break;
|
||||
/*
|
||||
@ -3050,7 +3043,6 @@ sosetopt(struct socket *so, struct sockopt *sopt)
|
||||
case SO_NOSIGPIPE:
|
||||
case SO_NO_DDP:
|
||||
case SO_NO_OFFLOAD:
|
||||
case SO_RERROR:
|
||||
error = sooptcopyin(sopt, &optval, sizeof optval,
|
||||
sizeof optval);
|
||||
if (error)
|
||||
@ -3272,7 +3264,6 @@ sogetopt(struct socket *so, struct sockopt *sopt)
|
||||
case SO_NOSIGPIPE:
|
||||
case SO_NO_DDP:
|
||||
case SO_NO_OFFLOAD:
|
||||
case SO_RERROR:
|
||||
optval = so->so_options & sopt->sopt_name;
|
||||
integer:
|
||||
error = sooptcopyout(sopt, &optval, sizeof optval);
|
||||
@ -3292,13 +3283,8 @@ sogetopt(struct socket *so, struct sockopt *sopt)
|
||||
|
||||
case SO_ERROR:
|
||||
SOCK_LOCK(so);
|
||||
if (so->so_error) {
|
||||
optval = so->so_error;
|
||||
so->so_error = 0;
|
||||
} else {
|
||||
optval = so->so_rerror;
|
||||
so->so_rerror = 0;
|
||||
}
|
||||
optval = so->so_error;
|
||||
so->so_error = 0;
|
||||
SOCK_UNLOCK(so);
|
||||
goto integer;
|
||||
|
||||
@ -3847,7 +3833,7 @@ filt_soread(struct knote *kn, long hint)
|
||||
kn->kn_flags |= EV_EOF;
|
||||
kn->kn_fflags = so->so_error;
|
||||
return (1);
|
||||
} else if (so->so_error || so->so_rerror)
|
||||
} else if (so->so_error) /* temporary udp error */
|
||||
return (1);
|
||||
|
||||
if (kn->kn_sfflags & NOTE_LOWAT) {
|
||||
|
@ -1058,7 +1058,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
|
||||
m = NULL;
|
||||
control = NULL;
|
||||
} else {
|
||||
soroverflow_locked(so2);
|
||||
SOCKBUF_UNLOCK(&so2->so_rcv);
|
||||
error = ENOBUFS;
|
||||
}
|
||||
if (nam != NULL)
|
||||
|
@ -100,10 +100,10 @@ raw_input_ext(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src,
|
||||
n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
|
||||
if (n) {
|
||||
if (sbappendaddr(&last->so_rcv, src,
|
||||
n, (struct mbuf *)0) == 0) {
|
||||
soroverflow(last);
|
||||
n, (struct mbuf *)0) == 0)
|
||||
/* should notify about lost packet */
|
||||
m_freem(n);
|
||||
} else
|
||||
else
|
||||
sorwakeup(last);
|
||||
}
|
||||
}
|
||||
@ -111,10 +111,9 @@ raw_input_ext(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src,
|
||||
}
|
||||
if (last) {
|
||||
if (sbappendaddr(&last->so_rcv, src,
|
||||
m, (struct mbuf *)0) == 0) {
|
||||
soroverflow(last);
|
||||
m, (struct mbuf *)0) == 0)
|
||||
m_freem(m);
|
||||
} else
|
||||
else
|
||||
sorwakeup(last);
|
||||
} else
|
||||
m_freem(m);
|
||||
|
@ -539,7 +539,6 @@ ng_btsocket_hci_raw_data_input(struct mbuf *nam)
|
||||
|
||||
NG_FREE_M(m);
|
||||
NG_FREE_M(ctl);
|
||||
soroverflow(pcb->so);
|
||||
}
|
||||
}
|
||||
next:
|
||||
|
@ -982,7 +982,7 @@ ngs_rcvmsg(node_p node, item_p item, hook_p lasthook)
|
||||
/* Send it up to the socket. */
|
||||
if (sbappendaddr_locked(&so->so_rcv, (struct sockaddr *)&addr, m,
|
||||
NULL) == 0) {
|
||||
soroverflow_locked(so);
|
||||
SOCKBUF_UNLOCK(&so->so_rcv);
|
||||
TRAP_ERROR;
|
||||
m_freem(m);
|
||||
return (ENOBUFS);
|
||||
|
@ -285,7 +285,7 @@ divert_packet(struct mbuf *m, bool incoming)
|
||||
if (sbappendaddr_locked(&sa->so_rcv,
|
||||
(struct sockaddr *)&divsrc, m,
|
||||
(struct mbuf *)0) == 0) {
|
||||
soroverflow_locked(sa);
|
||||
SOCKBUF_UNLOCK(&sa->so_rcv);
|
||||
sa = NULL; /* force mbuf reclaim below */
|
||||
} else
|
||||
sorwakeup_locked(sa);
|
||||
|
@ -1199,7 +1199,7 @@ socket_send(struct socket *s, struct mbuf *mm, struct sockaddr_in *src)
|
||||
sorwakeup_locked(s);
|
||||
return 0;
|
||||
}
|
||||
soroverflow_locked(s);
|
||||
SOCKBUF_UNLOCK(&s->so_rcv);
|
||||
}
|
||||
m_freem(mm);
|
||||
return -1;
|
||||
|
@ -263,10 +263,11 @@ rip_append(struct inpcb *last, struct ip *ip, struct mbuf *n,
|
||||
SOCKBUF_LOCK(&so->so_rcv);
|
||||
if (sbappendaddr_locked(&so->so_rcv,
|
||||
(struct sockaddr *)ripsrc, n, opts) == 0) {
|
||||
soroverflow_locked(so);
|
||||
/* should notify about lost packet */
|
||||
m_freem(n);
|
||||
if (opts)
|
||||
m_freem(opts);
|
||||
SOCKBUF_UNLOCK(&so->so_rcv);
|
||||
} else
|
||||
sorwakeup_locked(so);
|
||||
} else
|
||||
|
@ -379,7 +379,7 @@ udp_append(struct inpcb *inp, struct ip *ip, struct mbuf *n, int off,
|
||||
so = inp->inp_socket;
|
||||
SOCKBUF_LOCK(&so->so_rcv);
|
||||
if (sbappendaddr_locked(&so->so_rcv, append_sa, n, opts) == 0) {
|
||||
soroverflow(so);
|
||||
SOCKBUF_UNLOCK(&so->so_rcv);
|
||||
m_freem(n);
|
||||
if (opts)
|
||||
m_freem(opts);
|
||||
|
@ -1973,11 +1973,13 @@ icmp6_rip6_input(struct mbuf **mp, int off)
|
||||
&last->inp_socket->so_rcv,
|
||||
(struct sockaddr *)&fromsa, n, opts)
|
||||
== 0) {
|
||||
soroverflow_locked(last->inp_socket);
|
||||
/* should notify about lost packet */
|
||||
m_freem(n);
|
||||
if (opts) {
|
||||
m_freem(opts);
|
||||
}
|
||||
SOCKBUF_UNLOCK(
|
||||
&last->inp_socket->so_rcv);
|
||||
} else
|
||||
sorwakeup_locked(last->inp_socket);
|
||||
opts = NULL;
|
||||
@ -2017,7 +2019,7 @@ icmp6_rip6_input(struct mbuf **mp, int off)
|
||||
m_freem(m);
|
||||
if (opts)
|
||||
m_freem(opts);
|
||||
soroverflow_locked(last->inp_socket);
|
||||
SOCKBUF_UNLOCK(&last->inp_socket->so_rcv);
|
||||
} else
|
||||
sorwakeup_locked(last->inp_socket);
|
||||
INP_RUNLOCK(last);
|
||||
|
@ -1576,7 +1576,6 @@ ip6_notify_pmtu(struct inpcb *inp, struct sockaddr_in6 *dst, u_int32_t mtu)
|
||||
so = inp->inp_socket;
|
||||
if (sbappendaddr(&so->so_rcv, (struct sockaddr *)dst, NULL, m_mtu)
|
||||
== 0) {
|
||||
soroverflow(so);
|
||||
m_freem(m_mtu);
|
||||
/* XXX: should count statistics */
|
||||
} else
|
||||
|
@ -1038,8 +1038,7 @@ socket_send(struct socket *s, struct mbuf *mm, struct sockaddr_in6 *src)
|
||||
mm, (struct mbuf *)0) != 0) {
|
||||
sorwakeup(s);
|
||||
return (0);
|
||||
} else
|
||||
soroverflow(s);
|
||||
}
|
||||
}
|
||||
m_freem(mm);
|
||||
return (-1);
|
||||
|
@ -214,7 +214,6 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
|
||||
if (sbappendaddr(&last->inp_socket->so_rcv,
|
||||
(struct sockaddr *)&fromsa,
|
||||
n, opts) == 0) {
|
||||
soroverflow(last->inp_socket);
|
||||
m_freem(n);
|
||||
if (opts)
|
||||
m_freem(opts);
|
||||
@ -326,7 +325,6 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
|
||||
m_adj(m, *offp);
|
||||
if (sbappendaddr(&last->inp_socket->so_rcv,
|
||||
(struct sockaddr *)&fromsa, m, opts) == 0) {
|
||||
soroverflow(last->inp_socket);
|
||||
m_freem(m);
|
||||
if (opts)
|
||||
m_freem(opts);
|
||||
|
@ -291,7 +291,7 @@ send_input(struct mbuf *m, struct ifnet *ifp, int direction, int msglen __unused
|
||||
SOCKBUF_LOCK(&V_send_so->so_rcv);
|
||||
if (sbappendaddr_locked(&V_send_so->so_rcv,
|
||||
(struct sockaddr *)&sendsrc, m, NULL) == 0) {
|
||||
soroverflow_locked(V_send_so);
|
||||
SOCKBUF_UNLOCK(&V_send_so->so_rcv);
|
||||
/* XXX stats. */
|
||||
m_freem(m);
|
||||
} else {
|
||||
|
@ -197,7 +197,7 @@ udp6_append(struct inpcb *inp, struct mbuf *n, int off,
|
||||
SOCKBUF_LOCK(&so->so_rcv);
|
||||
if (sbappendaddr_locked(&so->so_rcv, (struct sockaddr *)&fromsa[0], n,
|
||||
opts) == 0) {
|
||||
soroverflow_locked(so);
|
||||
SOCKBUF_UNLOCK(&so->so_rcv);
|
||||
m_freem(n);
|
||||
if (opts)
|
||||
m_freem(opts);
|
||||
|
@ -141,6 +141,7 @@ key_output(struct mbuf *m, struct socket *so, ...)
|
||||
static int
|
||||
key_sendup0(struct rawcb *rp, struct mbuf *m, int promisc)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (promisc) {
|
||||
struct sadb_msg *pmsg;
|
||||
@ -164,12 +165,11 @@ key_sendup0(struct rawcb *rp, struct mbuf *m, int promisc)
|
||||
m, NULL)) {
|
||||
PFKEYSTAT_INC(in_nomem);
|
||||
m_freem(m);
|
||||
soroverflow(rp->rcb_socket);
|
||||
return ENOBUFS;
|
||||
}
|
||||
|
||||
error = ENOBUFS;
|
||||
} else
|
||||
error = 0;
|
||||
sorwakeup(rp->rcb_socket);
|
||||
return 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
/* so can be NULL if target != KEY_SENDUP_ONE */
|
||||
|
@ -147,7 +147,6 @@ typedef __uintptr_t uintptr_t;
|
||||
#define SO_NO_OFFLOAD 0x00004000 /* socket cannot be offloaded */
|
||||
#define SO_NO_DDP 0x00008000 /* disable direct data placement */
|
||||
#define SO_REUSEPORT_LB 0x00010000 /* reuse with load balancing */
|
||||
#define SO_RERROR 0x00020000 /* keep track of receive errors */
|
||||
|
||||
/*
|
||||
* Additional options, not kept in so_options.
|
||||
|
@ -100,7 +100,6 @@ struct socket {
|
||||
struct protosw *so_proto; /* (a) protocol handle */
|
||||
short so_timeo; /* (g) connection timeout */
|
||||
u_short so_error; /* (f) error affecting connection */
|
||||
u_short so_rerror; /* (f) error affecting connection */
|
||||
struct sigio *so_sigio; /* [sg] information for async I/O or
|
||||
out of band data (SIGURG) */
|
||||
struct ucred *so_cred; /* (a) user credentials */
|
||||
@ -267,8 +266,7 @@ struct socket {
|
||||
|
||||
/* can we read something from so? */
|
||||
#define soreadabledata(so) \
|
||||
(sbavail(&(so)->so_rcv) >= (so)->so_rcv.sb_lowat || \
|
||||
(so)->so_error || (so)->so_rerror)
|
||||
(sbavail(&(so)->so_rcv) >= (so)->so_rcv.sb_lowat || (so)->so_error)
|
||||
#define soreadable(so) \
|
||||
(soreadabledata(so) || ((so)->so_rcv.sb_state & SBS_CANTRCVMORE))
|
||||
|
||||
@ -482,8 +480,6 @@ void socantrcvmore(struct socket *so);
|
||||
void socantrcvmore_locked(struct socket *so);
|
||||
void socantsendmore(struct socket *so);
|
||||
void socantsendmore_locked(struct socket *so);
|
||||
void soroverflow(struct socket *so);
|
||||
void soroverflow_locked(struct socket *so);
|
||||
|
||||
/*
|
||||
* Accept filter functions (duh).
|
||||
|
Loading…
Reference in New Issue
Block a user