aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Evans <kevans@FreeBSD.org>2021-01-20 17:53:05 +0000
committerKyle Evans <kevans@FreeBSD.org>2021-02-24 04:48:42 +0000
commit7f73db6d04d0fcfe52dde537ba1495886f34762d (patch)
tree3f2e6bf109a63d9dde282ca6a1286a9e1f188be1
parent8cf559d6b9b4782bf67eb868ea480f47fc8c64a4 (diff)
downloadsrc-7f73db6d04d0fcfe52dde537ba1495886f34762d.tar.gz
src-7f73db6d04d0fcfe52dde537ba1495886f34762d.zip
504ebd612ec: kern: sonewconn: set so_options before pru_attach()
Protocol attachment has historically been able to observe and modify so->so_options as needed, and it still can for newly created sockets. 779f106aa169 moved this to after pru_attach() when we re-acquire the lock on the listening socket. Restore the historical behavior so that pru_attach implementations can consistently use it. Note that some pru_attach() do currently rely on this, though that may change in the future. D28265 contains a change to remove the use in TCP and IB/SDP bits, as resetting the requested linger time on incoming connections seems questionable at best. This does move the assignment out from under the head's listen lock, but glebius notes that head won't be going away and applications cannot assume any specific ordering with a race between a connection coming in and the application changing socket options anyways. 4c0bef07be0: kern: net: remove TCP_LINGERTIME TCP_LINGERTIME can be traced back to BSD 4.4 Lite and perhaps beyond, in exactly the same form that it appears here modulo slightly different context. It used to be the case that there was a single pr_usrreq method with requests dispatched to it; these exact two lines appeared in tcp_usrreq's PRU_ATTACH handling. The only purpose of this that I can find is to cause surprising behavior on accepted connections. Newly-created sockets will never hit these paths as one cannot set SO_LINGER prior to socket(2). If SO_LINGER is set on a listening socket and inherited, one would expect the timeout to be inherited rather than changed arbitrarily like this -- noting that SO_LINGER is nonsense on a listening socket beyond inheritance, since they cannot be 'connected' by definition. Neither Illumos nor Linux reset the timer like this based on testing and inspection of Illumos, and testing of Linux. (cherry picked from commit 504ebd612ec61165bb949cfce3a348b0d6f37008) (cherry picked from commit 4c0bef07be071a1633ebc86a653f9bd59d40796e)
-rw-r--r--sys/kern/uipc_socket.c2
-rw-r--r--sys/netinet/tcp_timer.h2
-rw-r--r--sys/netinet/tcp_usrreq.c2
-rw-r--r--sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c2
4 files changed, 1 insertions, 7 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 7b16401b7071..7f06b51cf096 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -718,6 +718,7 @@ sonewconn(struct socket *head, int connstatus)
}
so->so_listen = head;
so->so_type = head->so_type;
+ so->so_options = head->so_options & ~SO_ACCEPTCONN;
so->so_linger = head->so_linger;
so->so_state = head->so_state | SS_NOFDREF;
so->so_fibnum = head->so_fibnum;
@@ -754,7 +755,6 @@ sonewconn(struct socket *head, int connstatus)
if (head->sol_accept_filter != NULL)
connstatus = 0;
so->so_state |= connstatus;
- so->so_options = head->so_options & ~SO_ACCEPTCONN;
soref(head); /* A socket on (in)complete queue refs head. */
if (connstatus) {
TAILQ_INSERT_TAIL(&head->sol_comp, so, so_list);
diff --git a/sys/netinet/tcp_timer.h b/sys/netinet/tcp_timer.h
index 6f0c3a46605a..9a711d173386 100644
--- a/sys/netinet/tcp_timer.h
+++ b/sys/netinet/tcp_timer.h
@@ -115,8 +115,6 @@
#define TCPTV_TWTRUNC 8 /* RTO factor to truncate TW */
-#define TCP_LINGERTIME 120 /* linger at most 2 minutes */
-
#define TCP_MAXRXTSHIFT 12 /* maximum retransmits */
#define TCPTV_DELACK ( hz/25 ) /* 40ms timeout */
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index bfa96ce093b5..31b580bfafcc 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -204,8 +204,6 @@ tcp_usr_attach(struct socket *so, int proto, struct thread *td)
tp->t_state = TCPS_CLOSED;
INP_WUNLOCK(inp);
TCPSTATES_INC(TCPS_CLOSED);
- if ((so->so_options & SO_LINGER) && so->so_linger == 0)
- so->so_linger = TCP_LINGERTIME;
out:
TCPDEBUG2(PRU_ATTACH);
TCP_PROBE2(debug__user, tp, PRU_ATTACH);
diff --git a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c
index 46a43e1b8e3b..e7ae4e03365e 100644
--- a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c
+++ b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c
@@ -482,8 +482,6 @@ sdp_attach(struct socket *so, int proto, struct thread *td)
LIST_INSERT_HEAD(&sdp_list, ssk, list);
sdp_count++;
SDP_LIST_WUNLOCK();
- if ((so->so_options & SO_LINGER) && so->so_linger == 0)
- so->so_linger = TCP_LINGERTIME;
return (0);
}