aboutsummaryrefslogtreecommitdiff
path: root/sys/sys
diff options
context:
space:
mode:
authorAlexander V. Chernikov <melifaro@FreeBSD.org>2021-02-07 17:21:18 +0000
committerAlexander V. Chernikov <melifaro@FreeBSD.org>2021-02-08 21:42:20 +0000
commit4a01b854ca5c2e5124958363b3326708b913af71 (patch)
tree466705011527e1d00e89597d5d3b60854ca7d8c3 /sys/sys
parentd8c6d4c7321d4c969216bda8f792b45ed00afd64 (diff)
downloadsrc-4a01b854ca5c2e5124958363b3326708b913af71.tar.gz
src-4a01b854ca5c2e5124958363b3326708b913af71.zip
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. This is really really important for programs that use route(4) to keep in sync with the system. If we loose a message then we need to reload the full system state, otherwise the behaviour from that point is undefined and can lead to chasing bogus bug reports.
Diffstat (limited to 'sys/sys')
-rw-r--r--sys/sys/socket.h1
-rw-r--r--sys/sys/socketvar.h6
2 files changed, 6 insertions, 1 deletions
diff --git a/sys/sys/socket.h b/sys/sys/socket.h
index d9256fd7544a..2cb76f9c6d63 100644
--- a/sys/sys/socket.h
+++ b/sys/sys/socket.h
@@ -147,6 +147,7 @@ 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.
diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h
index 295a1cf3d37f..60a4dde7f0cb 100644
--- a/sys/sys/socketvar.h
+++ b/sys/sys/socketvar.h
@@ -100,6 +100,7 @@ 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 */
@@ -266,7 +267,8 @@ struct socket {
/* can we read something from so? */
#define soreadabledata(so) \
- (sbavail(&(so)->so_rcv) >= (so)->so_rcv.sb_lowat || (so)->so_error)
+ (sbavail(&(so)->so_rcv) >= (so)->so_rcv.sb_lowat || \
+ (so)->so_error || (so)->so_rerror)
#define soreadable(so) \
(soreadabledata(so) || ((so)->so_rcv.sb_state & SBS_CANTRCVMORE))
@@ -480,6 +482,8 @@ 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).