svn commit: r362820 - projects/nfs-over-tls/sys/rpc
Rick Macklem
rmacklem at FreeBSD.org
Wed Jul 1 02:11:17 UTC 2020
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_ */
More information about the svn-src-projects
mailing list