Re: git: d195b3783fa4 - main - sctp: fix socket type created by sctp_peeloff()

From: Gleb Smirnoff <glebius_at_freebsd.org>
Date: Mon, 02 Feb 2026 19:28:07 UTC
  Michael,

On Sat, Jan 31, 2026 at 06:16:09PM +0000, Michael Tuexen wrote:
M> commit d195b3783fa4de5c1a95f6d95eb9444abce6778b
M> Author:     Michael Tuexen <tuexen@FreeBSD.org>
M> AuthorDate: 2026-01-31 18:11:08 +0000
M> Commit:     Michael Tuexen <tuexen@FreeBSD.org>
M> CommitDate: 2026-01-31 18:11:08 +0000
M> 
M>     sctp: fix socket type created by sctp_peeloff()
M>     
M>     When calling sctp_peeloff() on a SOCK_SEQPACKET socket, the created
M>     and returned socket has the type SOCK_STREAM.
M>     This is specified in section 9.2 of RFC 6458.
M>     
M>     Reported by:    Xin Long
M>     MFC after:      3 days
M> ---
M>  sys/kern/uipc_socket.c | 6 ++++--
M>  1 file changed, 4 insertions(+), 2 deletions(-)
M> 
M> diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
M> index efc8ebfcece2..4014006ce2e5 100644
M> --- a/sys/kern/uipc_socket.c
M> +++ b/sys/kern/uipc_socket.c
M> @@ -1292,7 +1292,7 @@ solisten_enqueue(struct socket *so, int connstatus)
M>  
M>  #if defined(SCTP) || defined(SCTP_SUPPORT)
M>  /*
M> - * Socket part of sctp_peeloff().  Detach a new socket from an
M> + * Socket part of sctp_peeloff().  Create a new socket for an
M>   * association.  The new socket is returned with a reference.
M>   *
M>   * XXXGL: reduce copy-paste with solisten_clone().
M> @@ -1304,6 +1304,8 @@ sopeeloff(struct socket *head)
M>  
M>  	VNET_ASSERT(head->so_vnet != NULL, ("%s:%d so_vnet is NULL, head=%p",
M>  	    __func__, __LINE__, head));
M> +	KASSERT(head->so_type == SOCK_SEQPACKET,
M> +	    ("%s: unexpecte so_type: %d", __func__, head->so_type));
M>  	so = soalloc(head->so_vnet);
M>  	if (so == NULL) {
M>  		log(LOG_DEBUG, "%s: pcb %p: New socket allocation failure: "
M> @@ -1311,7 +1313,7 @@ sopeeloff(struct socket *head)
M>  		    __func__, head->so_pcb);
M>  		return (NULL);
M>  	}
M> -	so->so_type = head->so_type;
M> +	so->so_type = SOCK_STREAM;
M>  	so->so_options = head->so_options;
M>  	so->so_linger = head->so_linger;
M>  	so->so_state = (head->so_state & SS_NBIO) | SS_ISCONNECTED;

This creates a socket where:

so->so_type != so->so_proto->pr_type.

I'm not sure this is a good idea.  I was actually looking into removing so_type
at all.  What does SCTP idea is about this peel-off thing?  If the resulting
socket is a stream one, shouldn't its so_proto point at sctp_stream_protosw?

-- 
Gleb Smirnoff