Created attachment 213673 [details] Minimal test program send(2) manpage currently states "The send() function may be used only when the socket is in a connected state, while sendto(), sendmsg() and sendmmsg() may be used at any time." This seems inaccurate. Doing a sendto() on an unconnected SOCK_STREAM unix socket results in an ENOTCONN error. ENOTCONN is not a documented possible error from sendto. Small c testcase showing the behaviour attached. Suggested manpage patch submitted: https://reviews.freebsd.org/D24530
Hmm, I would expect this to work. Looking.
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?
A commit references this bug: Author: markj Date: Mon Apr 27 16:12:33 UTC 2020 New revision: 360384 URL: https://svnweb.freebsd.org/changeset/base/360384 Log: Document handling of connection-mode sockets by sendto(2). sendto(2), sendmsg(2) and sendmmsg(2) return ENOTCONN if a destination address is specified and the socket is not connected and the socket protocol does not automatically connect ("implied connect"). Document that. Also document the fact that the destination address is ignored for connection-mode sockets if the socket is already connected. PR: 245817 Submitted by: Erik Inge Bols? <knan-bfo@modirum.com> MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D24530 Changes: head/lib/libc/sys/send.2
(In reply to Mark Johnston from comment #2) PR_IMPLOPCL is the flag that the unix socket protocols should be setting, not PR_CONNREQUIRED. In any case, the documentation at least covers what is supposed to happen in this case. Thanks for the patch.
A commit references this bug: Author: markj Date: Mon May 4 12:27:46 UTC 2020 New revision: 360627 URL: https://svnweb.freebsd.org/changeset/base/360627 Log: MFC r360384: Document handling of connection-mode sockets by sendto(2). PR: 245817 Changes: _U stable/12/ stable/12/lib/libc/sys/send.2
Thanks for the report.