diff options
Diffstat (limited to 'sys/netinet/tcp_usrreq.c')
-rw-r--r-- | sys/netinet/tcp_usrreq.c | 61 |
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). |