From nobody Fri Jun 24 16:10:28 2022 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 976CC865449; Fri, 24 Jun 2022 16:10:29 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4LV2CS6ThLz3JL8; Fri, 24 Jun 2022 16:10:28 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1656087028; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=wlgFt56hMqnnzzDrqCKQ/zXFk5pgqz0GDni5MReu+H4=; b=k4PQz72bSUDWTTO3lbkroFX1ws7ZWYbaSEP3aN+kE4iasDZukbuurezUmmfiVLiD/yxB7w 4593TMRMgZFk9EmOLC4c8zMElksu+HWeun8lFvmRuJb66iyr3uft3kery3M8ot9VVhwD3u 9YMRCxT/DTIkpk+NqQoEAXgOsFsLry7KQd2HDD3BObU2WxeNBCp/Z5tbPmm3KipswKCu/H 9t1vCZNj8ZnAKh+7+USMxdQMTBj6GDa6Rs4js5CUDTUZhjXIeKcBfPRauq65kCJ79/AjGl g6qqRsFRByxzQn/4fxo+wrfiTXtpC0eaYxJE2FVZ8hl/Uh80sHWG68RQvS02FA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id ADBD312F41; Fri, 24 Jun 2022 16:10:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 25OGASrm006065; Fri, 24 Jun 2022 16:10:28 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 25OGASaj006064; Fri, 24 Jun 2022 16:10:28 GMT (envelope-from git) Date: Fri, 24 Jun 2022 16:10:28 GMT Message-Id: <202206241610.25OGASaj006064@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Gleb Smirnoff Subject: git: 346495824627 - main - unix/dgram: add a specific send method - uipc_sosend_dgram() List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: glebius X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 3464958246273971a7f1e8e56773a589032c3ee4 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1656087028; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=wlgFt56hMqnnzzDrqCKQ/zXFk5pgqz0GDni5MReu+H4=; b=spGIDGN9jXgW1kFNBUANwS1mnky/N2FHApQ3DOhdaGGzN+9zMRaVzHSRsvJDvoLXzGLZ4i NcJ/IF7n9P3Vvr2yxj+sizkVMIWTcr5FhLicOShEOGulS1jSmWAg+KZyIWkoBA29VlZkSC jo5HbF/aAXx3pLU0o7Vg9FuuAwXuJi2BkhHvOQNjUF57SFSJqBy8aW6xO83lQhbeP7+M9t JE2tIHk65Y3iig3EsdJQKuf8W90sFG0vIBpVc+FXi4HWL6gGIQAhBKy7A6cSNDYg4KZDQi WAf+rtSkAPqTWEjrVkO9dquB2QDldxk2QOwyviuMu0aLUVoY54wCfYEEZI6ayg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1656087028; a=rsa-sha256; cv=none; b=tqE5Ng9q5wkO879Rq4YcQ9w8v+NYmbMyG6O7kuPz02t2sFnxlLT/q7NyF3I1YcusH4I+vN BvYpQw5Cewoz4Xjtp9F+eMZw66tr2oXglOBVtU+Ix9wymz86LZEM1aHEvu2bpYMnXjxcdp SjGa1vtXsOTwuIe9t236tZ10DVAZwUxaKdQ5sCVZktd4MWPTHBX37Dd+jtmHZSf3w5iDPN 12IoogewjRb2nfS2D1sSgbrMglvBC2/6TQ+QI2gIrNySdSN7o/UXZp0BLMFYwnY4Q0NmGT ss2w17sOzvhnPX7OqoTpjAMSW3Kw/Nen8CpTZjwIY/EewAJ3xxpeAuUzg6iLsQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=3464958246273971a7f1e8e56773a589032c3ee4 commit 3464958246273971a7f1e8e56773a589032c3ee4 Author: Gleb Smirnoff AuthorDate: 2022-06-24 16:09:10 +0000 Commit: Gleb Smirnoff CommitDate: 2022-06-24 16:09:10 +0000 unix/dgram: add a specific send method - uipc_sosend_dgram() This is first step towards splitting classic BSD socket implementation into separate classes. The first to be split is PF_UNIX/SOCK_DGRAM as it has most differencies to SOCK_STREAM sockets and to PF_INET sockets. Historically a protocol shall provide two methods for sendmsg(2): pru_sosend and pru_send. The former is a generic send method, e.g. sosend_generic() which would internally call the latter, uipc_send() in our case. There is one important exception, though, the sendfile(2) code will call pru_send directly. But sendfile doesn't work on SOCK_DGRAM, so we can do the trick. We will create socket class specific uipc_sosend_dgram() which will carry only important bits from sosend_generic() and uipc_send(). Reviewed by: markj Differential revision: https://reviews.freebsd.org/D35293 --- sys/kern/uipc_usrreq.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 3 deletions(-) diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 16029e5c38c8..2e54ee827b8e 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -996,8 +996,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, unp = sotounpcb(so); KASSERT(unp != NULL, ("%s: unp == NULL", __func__)); - KASSERT(so->so_type == SOCK_STREAM || so->so_type == SOCK_DGRAM || - so->so_type == SOCK_SEQPACKET, + KASSERT(so->so_type == SOCK_STREAM || so->so_type == SOCK_SEQPACKET, ("%s: socktype %d", __func__, so->so_type)); error = 0; @@ -1173,6 +1172,146 @@ release: return (error); } +/* + * PF_UNIX/SOCK_DGRAM send + */ +static int +uipc_sosend_dgram(struct socket *so, struct sockaddr *addr, struct uio *uio, + struct mbuf *m, struct mbuf *c, int flags, struct thread *td) +{ + struct unpcb *unp, *unp2; + const struct sockaddr *from; + struct socket *so2; + int error; + + MPASS((uio != NULL && m == NULL) || (m != NULL && uio == NULL)); + + error = 0; + + if (__predict_false(flags & MSG_OOB)) { + error = EOPNOTSUPP; + goto out; + } + if (m == NULL) { + if (__predict_false(uio->uio_resid > unpdg_maxdgram)) { + error = EMSGSIZE; + goto out; + } + m = m_uiotombuf(uio, M_WAITOK, 0, max_hdr, M_PKTHDR); + if (__predict_false(m == NULL)) { + error = EFAULT; + goto out; + } + if (c != NULL && (error = unp_internalize(&c, td))) + goto out; + } else { + /* pru_sosend() with mbuf usually is a kernel thread. */ + + M_ASSERTPKTHDR(m); + if (__predict_false(c != NULL)) + panic("%s: control from a kernel thread", __func__); + + if (__predict_false(m->m_pkthdr.len > unpdg_maxdgram)) { + error = EMSGSIZE; + goto out; + } + /* Condition the foreign mbuf to our standards. */ + m_clrprotoflags(m); + m_tag_delete_chain(m, NULL); + m->m_pkthdr.rcvif = NULL; + m->m_pkthdr.flowid = 0; + m->m_pkthdr.csum_flags = 0; + m->m_pkthdr.fibnum = 0; + m->m_pkthdr.rsstype = 0; + } + + unp = sotounpcb(so); + MPASS(unp); + + /* + * XXXGL: would be cool to fully remove so_snd out of the equation + * and avoid this lock, which is not only extraneous, but also being + * released, thus still leaving possibility for a race. We can easily + * handle SBS_CANTSENDMORE/SS_ISCONNECTED complement in unpcb, but it + * is more difficult to invent something to handle so_error. + */ + error = SOCK_IO_SEND_LOCK(so, SBLOCKWAIT(flags)); + if (error) + goto out2; + SOCKBUF_LOCK(&so->so_snd); + if (so->so_snd.sb_state & SBS_CANTSENDMORE) { + SOCK_SENDBUF_UNLOCK(so); + error = EPIPE; + goto out3; + } + if (so->so_error != 0) { + error = so->so_error; + so->so_error = 0; + SOCKBUF_UNLOCK(&so->so_snd); + goto out3; + } + if (((so->so_state & SS_ISCONNECTED) == 0) && addr == NULL) { + SOCKBUF_UNLOCK(&so->so_snd); + error = EDESTADDRREQ; + goto out3; + } + SOCKBUF_UNLOCK(&so->so_snd); + + if (addr != NULL && (error = unp_connect(so, addr, td))) + goto out3; + + UNP_PCB_LOCK(unp); + /* + * Because connect() and send() are non-atomic in a sendto() with a + * target address, it's possible that the socket will have disconnected + * before the send() can run. In that case return the slightly + * counter-intuitive but otherwise correct error that the socket is not + * connected. + */ + unp2 = unp_pcb_lock_peer(unp); + if (unp2 == NULL) { + UNP_PCB_UNLOCK(unp); + error = ENOTCONN; + goto out3; + } + + if (unp2->unp_flags & UNP_WANTCRED_MASK) + c = unp_addsockcred(td, c, unp2->unp_flags); + if (unp->unp_addr != NULL) + from = (struct sockaddr *)unp->unp_addr; + else + from = &sun_noname; + so2 = unp2->unp_socket; + SOCKBUF_LOCK(&so2->so_rcv); + if (sbappendaddr_locked(&so2->so_rcv, from, m, c)) { + sorwakeup_locked(so2); + m = c = NULL; + } else { + soroverflow_locked(so2); + error = (so->so_state & SS_NBIO) ? EAGAIN : ENOBUFS; + } + + if (addr != NULL) + unp_disconnect(unp, unp2); + else + unp_pcb_unlock_pair(unp, unp2); + + td->td_ru.ru_msgsnd++; + +out3: + SOCK_IO_SEND_UNLOCK(so); +out2: + if (c) + unp_scan(c, unp_freerights); +out: + if (c) + m_freem(c); + if (m) + m_freem(m); + + return (error); +} + static bool uipc_ready_scan(struct socket *so, struct mbuf *m, int count, int *errorp) { @@ -1314,7 +1453,7 @@ static struct pr_usrreqs uipc_usrreqs_dgram = { .pru_detach = uipc_detach, .pru_disconnect = uipc_disconnect, .pru_peeraddr = uipc_peeraddr, - .pru_send = uipc_send, + .pru_sosend = uipc_sosend_dgram, .pru_sense = uipc_sense, .pru_shutdown = uipc_shutdown, .pru_sockaddr = uipc_sockaddr,