Date: Wed, 1 Jul 2020 02:11:16 +0000 (UTC) From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r362820 - projects/nfs-over-tls/sys/rpc Message-ID: <202007010211.0612BG0u098822@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rmacklem Date: Wed Jul 1 02:11:15 2020 New Revision: 362820 URL: https://svnweb.freebsd.org/changeset/base/362820 Log: Use a reserved value for ssl refno to indicate that a handshake is in progress. This is needed so clnt_vc_destroy() will not do a soclose() on the socket, since the daemon may still be in SSL_connect(). Modified: projects/nfs-over-tls/sys/rpc/clnt_rc.c projects/nfs-over-tls/sys/rpc/clnt_vc.c projects/nfs-over-tls/sys/rpc/rpcsec_tls.h Modified: projects/nfs-over-tls/sys/rpc/clnt_rc.c ============================================================================== --- projects/nfs-over-tls/sys/rpc/clnt_rc.c Wed Jul 1 01:12:23 2020 (r362819) +++ projects/nfs-over-tls/sys/rpc/clnt_rc.c Wed Jul 1 02:11:15 2020 (r362820) @@ -198,6 +198,16 @@ clnt_reconnect_connect(CLIENT *cl) (struct sockaddr *) &rc->rc_addr, rc->rc_prog, rc->rc_vers, rc->rc_sendsz, rc->rc_recvsz, rc->rc_intr); if (rc->rc_tls && newclient != NULL) { + /* + * Set ssl refno so that clnt_vc_destroy() will not + * close the socket and will leave that for the + * daemon to do. It is possible that the upcall + * will time out, so that closing the socket via + * the CLNT_CLOSE() below would happen too soon. + */ + ssl[0] = ssl[1] = 0; + ssl[2] = RPCTLS_REFNO_HANDSHAKE; + CLNT_CONTROL(newclient, CLSET_TLS, ssl); printf("at rpctls_connect\n"); stat = rpctls_connect(newclient, so, ssl, &reterr); printf("aft rpctls_connect=%d ssl=%jd\n", stat, (uintmax_t)ssl[2]); Modified: projects/nfs-over-tls/sys/rpc/clnt_vc.c ============================================================================== --- projects/nfs-over-tls/sys/rpc/clnt_vc.c Wed Jul 1 01:12:23 2020 (r362819) +++ projects/nfs-over-tls/sys/rpc/clnt_vc.c Wed Jul 1 02:11:15 2020 (r362820) @@ -775,12 +775,15 @@ printf("backch tls=0x%x xprt=%p\n", xprt->xp_tls, xprt ct->ct_sslsec = *p++; ct->ct_sslusec = *p++; ct->ct_sslrefno = *p; - mtx_unlock(&ct->ct_lock); - /* Start the kthread that handles upcalls. */ - error = kthread_add(clnt_vc_dotlsupcall, ct, - NULL, NULL, 0, 0, "krpctls%u", thrdnum++); - if (error != 0) - panic("Can't add KRPC thread error %d", error); + if (ct->ct_sslrefno != RPCTLS_REFNO_HANDSHAKE) { + mtx_unlock(&ct->ct_lock); + /* Start the kthread that handles upcalls. */ + error = kthread_add(clnt_vc_dotlsupcall, ct, + NULL, NULL, 0, 0, "krpctls%u", thrdnum++); + if (error != 0) + panic("Can't add KRPC thread error %d", error); + } else + mtx_unlock(&ct->ct_lock); return (TRUE); case CLSET_BLOCKRCV: @@ -892,24 +895,22 @@ clnt_vc_destroy(CLIENT *cl) if (so) { if (ct->ct_sslrefno != 0) { /* - * If the upcall fails, the socket has - * probably been closed via the rpctlscd - * daemon having crashed or been - * restarted, so ignore return stat. + * If the TLS handshake is in progress, the upcall + * will fail, but the socket should be closed by the + * daemon, since the connect upcall has just failed. */ - stat = rpctls_cl_disconnect(ct->ct_sslsec, - ct->ct_sslusec, ct->ct_sslrefno, - &reterr); - } else if ((ct->ct_rcvstate & RPCRCVSTATE_TLSHANDSHAKE) == 0) { - /* - * If the TLS handshake is in progress, leave the - * socket so that it will closed by the daemon. - * This can only occur if the daemon is waiting for - * an openssl call like SSL_connect() for a long - * time. The call will normally eventually fail and - * then the daemon will close the socket, so do not - * do it here. - */ + if (ct->ct_sslrefno != RPCTLS_REFNO_HANDSHAKE) { + /* + * If the upcall fails, the socket has + * probably been closed via the rpctlscd + * daemon having crashed or been + * restarted, so ignore return stat. + */ + stat = rpctls_cl_disconnect(ct->ct_sslsec, + ct->ct_sslusec, ct->ct_sslrefno, + &reterr); + } + } else { soshutdown(so, SHUT_WR); soclose(so); } @@ -1293,7 +1294,8 @@ clnt_vc_dotlsupcall(void *data) if ((ct->ct_rcvstate & RPCRCVSTATE_UPCALLNEEDED) != 0) { ct->ct_rcvstate &= ~RPCRCVSTATE_UPCALLNEEDED; ct->ct_rcvstate |= RPCRCVSTATE_UPCALLINPROG; - if (ct->ct_sslrefno != 0) { + if (ct->ct_sslrefno != 0 && ct->ct_sslrefno != + RPCTLS_REFNO_HANDSHAKE) { mtx_unlock(&ct->ct_lock); printf("at handlerecord\n"); ret = rpctls_cl_handlerecord(ct->ct_sslsec, Modified: projects/nfs-over-tls/sys/rpc/rpcsec_tls.h ============================================================================== --- projects/nfs-over-tls/sys/rpc/rpcsec_tls.h Wed Jul 1 01:12:23 2020 (r362819) +++ projects/nfs-over-tls/sys/rpc/rpcsec_tls.h Wed Jul 1 02:11:15 2020 (r362820) @@ -78,6 +78,9 @@ bool rpctls_getinfo(u_int *maxlen, bool rpctlscd_run, /* String for AUTH_TLS reply verifier. */ #define RPCTLS_START_STRING "STARTTLS" +/* ssl refno value to indicate TLS handshake being done. */ +#define RPCTLS_REFNO_HANDSHAKE 0xFFFFFFFFFFFFFFFFULL + #endif /* _KERNEL */ #endif /* _RPC_RPCSEC_TLS_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202007010211.0612BG0u098822>