From owner-svn-src-projects@freebsd.org Fri Jun 19 00:26:31 2020 Return-Path: Delivered-To: svn-src-projects@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 8EF7C339A8F for ; Fri, 19 Jun 2020 00:26:31 +0000 (UTC) (envelope-from rmacklem@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 "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 49p03W3DN6z4JH0; Fri, 19 Jun 2020 00:26:31 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 6A0C612906; Fri, 19 Jun 2020 00:26:31 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 05J0QVn0090265; Fri, 19 Jun 2020 00:26:31 GMT (envelope-from rmacklem@FreeBSD.org) Received: (from rmacklem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 05J0QVd0090264; Fri, 19 Jun 2020 00:26:31 GMT (envelope-from rmacklem@FreeBSD.org) Message-Id: <202006190026.05J0QVd0090264@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: rmacklem set sender to rmacklem@FreeBSD.org using -f From: Rick Macklem Date: Fri, 19 Jun 2020 00:26:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r362354 - projects/nfs-over-tls/sys/rpc X-SVN-Group: projects X-SVN-Commit-Author: rmacklem X-SVN-Commit-Paths: projects/nfs-over-tls/sys/rpc X-SVN-Commit-Revision: 362354 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 19 Jun 2020 00:26:31 -0000 Author: rmacklem Date: Fri Jun 19 00:26:30 2020 New Revision: 362354 URL: https://svnweb.freebsd.org/changeset/base/362354 Log: Modify handling of EOF on socket and m_split() returning NULL. This patch modifies the behaviour of the krpc TCP client side socket upcall function for certain failure scenarios. When the soreceive() returns a fatal error or EOF on the socket, the unpatched code would fail RPCs in progress immediately. This patch modifies the behaviour so that it processes the ct_raw mbuf list (data already received) before failing RPCs in progress, in case the reply for an RPC is already in ct_raw. For the case where m_split() returns NULL, the code now just returns instead of failing RPCs in progress. If the lack of mbufs is transient, a subsequent TCP segment might be received so that progress on parsing RPC messages from the ct_raw list can continue. If not, clnt_reconnect_call() will eventually time out and try to establish a new TCP connection to retry RPCs on. Hopefully the transient lack of mbufs will be resolved so that a new TCP connection can be established. Modified: projects/nfs-over-tls/sys/rpc/clnt_vc.c Modified: projects/nfs-over-tls/sys/rpc/clnt_vc.c ============================================================================== --- projects/nfs-over-tls/sys/rpc/clnt_vc.c Thu Jun 18 23:57:10 2020 (r362353) +++ projects/nfs-over-tls/sys/rpc/clnt_vc.c Fri Jun 19 00:26:30 2020 (r362354) @@ -941,8 +941,6 @@ clnt_vc_soupcall(struct socket *so, void *arg, int wai struct cmsghdr *cmsg; struct tls_get_record tgr; - CTASSERT(sizeof(xid_plus_direction) == 2 * sizeof(uint32_t)); - /* * RPC-over-TLS needs to block reception during * upcalls since the upcall will be doing I/O on @@ -998,6 +996,9 @@ clnt_vc_soupcall(struct socket *so, void *arg, int wai * after our call to soreceive fails with * EWOULDBLOCK. */ +if (so->so_rcv.sb_lowat > 1) +printf("lowat=%d\n", so->so_rcv.sb_lowat); + error = 0; if (!soreadable(so)) break; continue; @@ -1030,19 +1031,8 @@ clnt_vc_soupcall(struct socket *so, void *arg, int wai printf("Mark upcallneeded\n"); break; } - if (error != 0) { - wakeup_all: -printf("wakeup_all err=%d\n", error); - mtx_lock(&ct->ct_lock); - ct->ct_error.re_status = RPC_CANTRECV; - ct->ct_error.re_errno = error; - TAILQ_FOREACH(cr, &ct->ct_pending, cr_link) { - cr->cr_error = error; - wakeup(cr); - } - mtx_unlock(&ct->ct_lock); - goto out; - } + if (error != 0) + break; /* Process any record header(s). */ if (m2 != NULL) { @@ -1093,22 +1083,6 @@ printf("Got weird type=%d\n", tgr.tls_type); header = ntohl(header); ct->ct_record_resid = header & 0x7fffffff; ct->ct_record_eor = ((header & 0x80000000) != 0); - if (ct->ct_record_resid < 20 || - ct->ct_record_resid > 150000 || - !ct->ct_record_eor) { - printf("clnt_vc_soupcall: bogus record " - "mark recres=%zd eor=%d\n", - ct->ct_record_resid, ct->ct_record_eor); - /* - * Connection is messed up. All we can - * do now is shut it down and let - * clnt_reconnect_XXX establish a new - * connection. - * This should never happen, but?? - */ - error = ECONNRESET; - goto wakeup_all; - } m_adj(ct->ct_raw, sizeof(uint32_t)); rawlen -= sizeof(uint32_t); } else { @@ -1130,22 +1104,10 @@ printf("Got weird type=%d\n", tgr.tls_type); } else { m = m_split(ct->ct_raw, ct->ct_record_resid, M_NOWAIT); - if (m == NULL) { -printf("soup m_split returned NULL\n"); - /* - * What to do now? - * The system is out of mbufs. - * I think it best to close this - * connection and allow - * clnt_reconnect_XXX() to try - * and establish a new one. - * If we just return and there is - * no more data received, the - * connection will be hung. - */ - error = ECONNRESET; - goto wakeup_all; - } + if (m == NULL) +{ printf("soup m_split returned NULL\n"); + break; +} if (ct->ct_record != NULL) m_last(ct->ct_record)->m_next = ct->ct_raw; @@ -1266,7 +1228,24 @@ printf("backxprt=%p\n", xprt); } } } -out: + if (error != 0) { + wakeup_all: + /* + * This socket is broken, so mark that it cannot + * receive and fail all RPCs waiting for a reply + * on it, so that they will be retried on a new + * TCP connection created by clnt_reconnect_X(). + */ + mtx_lock(&ct->ct_lock); + ct->ct_error.re_status = RPC_CANTRECV; + ct->ct_error.re_errno = error; + TAILQ_FOREACH(cr, &ct->ct_pending, cr_link) { + cr->cr_error = error; + wakeup(cr); + } + mtx_unlock(&ct->ct_lock); + } + ct->ct_upcallrefs--; if (ct->ct_upcallrefs < 0) panic("rpcvc upcall refcnt");