[Bug 245817] sendto() can return ENOTCONN on SOCK_STREAM unix socket, which is not documented

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Wed Apr 22 17:32:23 UTC 2020


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=245817

--- Comment #2 from Mark Johnston <markj at FreeBSD.org> ---
I see.  The SOCK_STREAM/SEQPACKET unix socket protocol descriptions set
PR_CONNREQUIRED, which effectively disables sendto()/sendmsg() on unconnected
unix sockets.  That is surprising since uipc_send() has explicit handling for
that:

1137         case SOCK_SEQPACKET:                                               
1138         case SOCK_STREAM:                                                  
1139                 if ((so->so_state & SS_ISCONNECTED) == 0) {                
1140                         if (nam != NULL) {                                 
1141                                 error = connect_internal(so, nam, td);     
1142                                 if (error != 0)                            
1143                                         break;                             
1144                         } else {                                           
1145                                 error = ENOTCONN;                          
1146                                 break;                                     
1147                         }                                                  
1148                 } else {                                                   
1149                         UNP_PCB_LOCK(unp);                                 
1150                 }

I think we can probably just clear PR_CONNREQUIRED for unix sockets.  Though, I
think we should indeed document ENOTCONN as a possible error for sendto() and
sendmsg().  It is documented here for instance:
https://pubs.opengroup.org/onlinepubs/009695399/functions/sendto.html

Also weird is this fragment in sosend_generic():

1626                         /*                                                 
1627                          * `sendto' and `sendmsg' is allowed on a
connection-                                                                     
1628                          * based socket if it supports implied connect.    
1629                          * Return ENOTCONN if not connected and no address
is                                                                            
1630                          * supplied.                                       
1631                          */                                                
1632                         if ((so->so_proto->pr_flags & PR_CONNREQUIRED) &&  
1633                             (so->so_proto->pr_flags & PR_IMPLOPCL) == 0) { 
1634                                 if ((so->so_state & SS_ISCONFIRMING) == 0
&&                                                                             
1635                                     !(resid == 0 && clen != 0)) {          
1636                                         SOCKBUF_UNLOCK(&so->so_snd);       
1637                                         error = ENOTCONN;                  
1638                                         goto release;                      
1639                                 }

Specifically, the !(resid == 0 && clen != 0) check: we only return an error if
we are trying to send data and there is no control message. So, we *can* send
control messages over unconnected stream sockets even if CONNREQUIRED is set.

Does any protocol except PF_LOCAL handle control messages to begin with?

-- 
You are receiving this mail because:
You are on the CC list for the bug.


More information about the freebsd-doc mailing list