summaryrefslogtreecommitdiff
path: root/sys/netinet/tcp_usrreq.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/tcp_usrreq.c')
-rw-r--r--sys/netinet/tcp_usrreq.c61
1 files changed, 49 insertions, 12 deletions
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index b4333507447..b6ab40112c2 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_usrreq.c,v 1.158 2017/10/25 12:38:21 job Exp $ */
+/* $OpenBSD: tcp_usrreq.c,v 1.159 2017/11/02 14:01:18 florian Exp $ */
/* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */
/*
@@ -182,17 +182,6 @@ tcp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
switch (req) {
/*
- * PRU_DETACH detaches the TCP protocol from the socket.
- * If the protocol state is non-embryonic, then can't
- * do this directly: have to initiate a PRU_DISCONNECT,
- * which may finish later; embryonic TCB's can just
- * be discarded here.
- */
- case PRU_DETACH:
- tp = tcp_disconnect(tp);
- break;
-
- /*
* Give the socket an address.
*/
case PRU_BIND:
@@ -618,6 +607,54 @@ tcp_attach(struct socket *so, int proto)
return (0);
}
+int
+tcp_detach(struct socket *so)
+{
+ struct inpcb *inp;
+ struct tcpcb *tp = NULL;
+ int error = 0;
+ short ostate;
+
+ soassertlocked(so);
+
+ inp = sotoinpcb(so);
+ /*
+ * When a TCP is attached to a socket, then there will be
+ * a (struct inpcb) pointed at by the socket, and this
+ * structure will point at a subsidiary (struct tcpcb).
+ */
+ if (inp == NULL) {
+ error = so->so_error;
+ if (error == 0)
+ error = EINVAL;
+
+ return (error);
+ }
+ if (inp) {
+ tp = intotcpcb(inp);
+ /* tp might get 0 when using socket splicing */
+ if (tp == NULL) {
+ return (0);
+ }
+#ifdef KPROF
+ tcp_acounts[tp->t_state][req]++;
+#endif
+ ostate = tp->t_state;
+ } else
+ ostate = 0;
+
+ /*
+ * Detache the TCP protocol from the socket.
+ * If the protocol state is non-embryonic, then can't
+ * do this directly: have to initiate a PRU_DISCONNECT,
+ * which may finish later; embryonic TCB's can just
+ * be discarded here.
+ */
+ tcp_disconnect(tp);
+
+ return (error);
+}
+
/*
* Initiate (or continue) disconnect.
* If embryonic state, just send reset (once).