sockets: provide correct pr_shutdown for keysock and SDP

My failure to run all kinds of kernel builds lead to missing the keysock
and incorrectly assuming SDP as not having a shutdown method.

Fixes:	5bba272807
This commit is contained in:
Gleb Smirnoff 2024-01-16 12:00:36 -08:00
parent 61a0eaca0d
commit 296a4cb5c5
2 changed files with 56 additions and 15 deletions

View file

@ -310,9 +310,24 @@ key_detach(struct socket *so)
} }
static int static int
key_shutdown(struct socket *so) key_shutdown(struct socket *so, enum shutdown_how how)
{ {
socantsendmore(so); /*
* Note: key socket marks itself as connected through its lifetime.
*/
switch (how) {
case SHUT_RD:
socantrcvmore(so);
sbrelease(so, SO_RCV);
break;
case SHUT_RDWR:
socantrcvmore(so);
sbrelease(so, SO_RCV);
/* FALLTHROUGH */
case SHUT_WR:
socantsendmore(so);
}
return (0); return (0);
} }

View file

@ -787,24 +787,50 @@ sdp_accept(struct socket *so, struct sockaddr *sa)
* Mark the connection as being incapable of further output. * Mark the connection as being incapable of further output.
*/ */
static int static int
sdp_shutdown(struct socket *so) sdp_shutdown(struct socket *so, enum shutdown_how how)
{ {
struct sdp_sock *ssk = sdp_sk(so);
int error = 0; int error = 0;
struct sdp_sock *ssk;
ssk = sdp_sk(so); SOCK_LOCK(so);
SDP_WLOCK(ssk); if ((so->so_state &
if (ssk->flags & (SDP_TIMEWAIT | SDP_DROPPED)) { (SS_ISCONNECTED | SS_ISCONNECTING | SS_ISDISCONNECTING)) == 0) {
error = ECONNRESET; SOCK_UNLOCK(so);
goto out; return (ENOTCONN);
} }
socantsendmore(so); if (SOLISTENING(so)) {
sdp_usrclosed(ssk); if (how != SHUT_WR) {
if (!(ssk->flags & SDP_DROPPED)) so->so_error = ECONNABORTED;
sdp_output_disconnect(ssk); solisten_wakeup(so); /* unlocks so */
} else
SOCK_UNLOCK(so);
return (0);
}
SOCK_UNLOCK(so);
out: switch (how) {
SDP_WUNLOCK(ssk); case SHUT_RD:
socantrcvmore(so);
sbrelease(so, SO_RCV);
break;
case SHUT_RDWR:
socantrcvmore(so);
sbrelease(so, SO_RCV);
/* FALLTHROUGH */
case SHUT_WR:
SDP_WLOCK(ssk);
if (ssk->flags & (SDP_TIMEWAIT | SDP_DROPPED)) {
SDP_WUNLOCK(ssk);
error = ECONNRESET;
break;
}
socantsendmore(so);
sdp_usrclosed(ssk);
if (!(ssk->flags & SDP_DROPPED))
sdp_output_disconnect(ssk);
SDP_WUNLOCK(ssk);
}
wakeup(&so->so_timeo);
return (error); return (error);
} }