diff --git a/sys/rpc/clnt_rc.c b/sys/rpc/clnt_rc.c --- a/sys/rpc/clnt_rc.c +++ b/sys/rpc/clnt_rc.c @@ -42,6 +42,8 @@ #include #include +#include + #include #include #include @@ -212,6 +214,12 @@ goto out; } } + if (newclient != NULL) { + int optval = 1; + + (void)so_setsockopt(so, IPPROTO_TCP, TCP_USE_DDP, + &optval, sizeof(optval)); + } if (newclient != NULL && rc->rc_reconcall != NULL) (*rc->rc_reconcall)(newclient, rc->rc_reconarg, rc->rc_ucred); diff --git a/sys/rpc/svc.h b/sys/rpc/svc.h --- a/sys/rpc/svc.h +++ b/sys/rpc/svc.h @@ -185,6 +185,7 @@ int xp_ngrps; /* Cred. from TLS cert. */ uid_t xp_uid; gid_t *xp_gidp; + int xp_doneddp; #else int xp_fd; u_short xp_port; /* associated port number */ diff --git a/sys/rpc/svc.c b/sys/rpc/svc.c --- a/sys/rpc/svc.c +++ b/sys/rpc/svc.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,8 @@ #include #include +#include + #include #include #include @@ -987,6 +990,23 @@ goto call_done; } + /* + * Defer enabling DDP until the first non-NULLPROC RPC + * is received to allow STARTTLS authentication to + * enable TLS offload first. + */ + if (xprt->xp_doneddp == 0 && r->rq_proc != NULLPROC && + atomic_cmpset_int(&xprt->xp_doneddp, 0, 1)) { + if (xprt->xp_socket->so_proto->pr_protocol == + IPPROTO_TCP) { + int optval = 1; + + (void)so_setsockopt(xprt->xp_socket, + IPPROTO_TCP, TCP_USE_DDP, &optval, + sizeof(optval)); + } + } + /* * Everything checks out, return request to caller. */