git: 9f48eea36607 - main - rpcbind: get contact addr from xprt members

From: Eric van Gyzen <vangyzen_at_FreeBSD.org>
Date: Mon, 13 Jun 2022 18:54:36 UTC
The branch main has been updated by vangyzen:

URL: https://cgit.FreeBSD.org/src/commit/?id=9f48eea36607cd89a88a38d4efa9f3b81d5e6e54

commit 9f48eea36607cd89a88a38d4efa9f3b81d5e6e54
Author:     Dmitry Ovsyannikov <Dmitry.Ovsyannikov@dell.com>
AuthorDate: 2022-06-13 13:34:44 +0000
Commit:     Eric van Gyzen <vangyzen@FreeBSD.org>
CommitDate: 2022-06-13 13:54:08 +0000

    rpcbind: get contact addr from xprt members
    
    Addition to D31491 in order to actually resolve the top root cause.
    
    Currently rpcbind gets contact address from connectionless xprt->xp_p2
    member of a transport and will fail to get it when working over
    connection oriented transport, leading to a guess game in terms of
    contact address on rpcinfo requests like RPCBPROC_GETVERSADDR or
    RPCBPROC_GETADDRLIST and poor returns which may influence a user
    of a call and specifically reported on OSX clients, which tend to
    not provide address hint from rpcinfo request to a server.
    
    MFC after:      1 week
    Sponsored by:   Dell EMC Isilon
    Differential Revision:  https://reviews.freebsd.org/D35220
---
 include/rpc/svc.h              |  4 ++++
 usr.sbin/rpcbind/check_bound.c | 11 +++++------
 usr.sbin/rpcbind/util.c        | 16 ++++++++--------
 3 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/include/rpc/svc.h b/include/rpc/svc.h
index 912d26ba4461..4cffd4070817 100644
--- a/include/rpc/svc.h
+++ b/include/rpc/svc.h
@@ -165,6 +165,10 @@ struct svc_req {
  *  Approved way of getting address of caller
  */
 #define svc_getrpccaller(x) (&(x)->xp_rtaddr)
+/*
+ *  Approved way of getting address of callee
+ */
+#define svc_getrpccallee(x) (&(x)->xp_ltaddr)
 
 /*
  * Operations defined on an SVCXPRT handle
diff --git a/usr.sbin/rpcbind/check_bound.c b/usr.sbin/rpcbind/check_bound.c
index cf0a029dad72..1f9382d33730 100644
--- a/usr.sbin/rpcbind/check_bound.c
+++ b/usr.sbin/rpcbind/check_bound.c
@@ -161,7 +161,7 @@ char *
 mergeaddr(SVCXPRT *xprt, char *netid, char *uaddr, char *saddr)
 {
 	struct fdlist *fdl;
-	struct svc_dg_data *dg_data;
+	struct netbuf *callee;
 	char *c_uaddr, *s_uaddr, *m_uaddr, *allocated_uaddr = NULL;
 
 	for (fdl = fdhead; fdl; fdl = fdl->next)
@@ -182,12 +182,11 @@ mergeaddr(SVCXPRT *xprt, char *netid, char *uaddr, char *saddr)
 	 * address by which it contacted us.  Use that for the "client" uaddr,
 	 * otherwise use the info from the SVCXPRT.
 	 */
-	dg_data = (struct svc_dg_data*)xprt->xp_p2;
-	if (dg_data != NULL && dg_data->su_srcaddr.buf != NULL) {
-		c_uaddr = taddr2uaddr(fdl->nconf, &dg_data->su_srcaddr);
+	callee = svc_getrpccallee(xprt);
+	if (callee != NULL && callee->buf != NULL) {
+		c_uaddr = taddr2uaddr(fdl->nconf, callee);
 		allocated_uaddr = c_uaddr;
-	}
-	else if (saddr != NULL) {
+	} else if (saddr != NULL) {
 		c_uaddr = saddr;
 	} else {
 		c_uaddr = taddr2uaddr(fdl->nconf, svc_getrpccaller(xprt));
diff --git a/usr.sbin/rpcbind/util.c b/usr.sbin/rpcbind/util.c
index e497e9227690..7662f2357d48 100644
--- a/usr.sbin/rpcbind/util.c
+++ b/usr.sbin/rpcbind/util.c
@@ -101,7 +101,7 @@ bitmaskcmp(struct sockaddr *dst, struct sockaddr *src, struct sockaddr *mask)
 
 /*
  * Find a server address that can be used by `caller' to contact
- * the local service specified by `serv_uaddr'. If `clnt_uaddr' is
+ * the local service specified by `serv_uaddr'. If `contct_uaddr' is
  * non-NULL, it is used instead of `caller' as a hint suggesting
  * the best address (e.g. the `r_addr' field of an rpc, which
  * contains the rpcbind server address that the caller used).
@@ -110,8 +110,8 @@ bitmaskcmp(struct sockaddr *dst, struct sockaddr *src, struct sockaddr *mask)
  * string which should be freed by the caller. On error, returns NULL.
  */
 char *
-addrmerge(struct netbuf *caller, const char *serv_uaddr, const char *clnt_uaddr,
-	  const char *netid)
+addrmerge(struct netbuf *caller, const char *serv_uaddr,
+    const char *contct_uaddr, const char *netid)
 {
 	struct ifaddrs *ifap, *ifp = NULL, *bestif;
 	struct netbuf *serv_nbp = NULL, *hint_nbp = NULL, tbuf;
@@ -128,7 +128,7 @@ addrmerge(struct netbuf *caller, const char *serv_uaddr, const char *clnt_uaddr,
 #ifdef ND_DEBUG
 	if (debugging)
 		fprintf(stderr, "addrmerge(caller, %s, %s, %s\n", serv_uaddr,
-		    clnt_uaddr == NULL ? "NULL" : clnt_uaddr, netid);
+		    contct_uaddr == NULL ? "NULL" : contct_uaddr, netid);
 #endif
 	caller_sa = caller->buf;
 	if ((nconf = rpcbind_get_conf(netid)) == NULL)
@@ -137,15 +137,15 @@ addrmerge(struct netbuf *caller, const char *serv_uaddr, const char *clnt_uaddr,
 		goto freeit;
 
 	/*
-	 * Use `clnt_uaddr' as the hint if non-NULL, but ignore it if its
+	 * Use `contct_uaddr' as the hint if non-NULL, but ignore it if its
 	 * address family is different from that of the caller.
 	 */
 	hint_sa = NULL;
-	if (clnt_uaddr != NULL) {
+	if (contct_uaddr != NULL) {
 #ifdef ND_DEBUG
-		hint_uaddr = clnt_uaddr;
+		hint_uaddr = contct_uaddr;
 #endif
-		if ((hint_nbp = uaddr2taddr(nconf, clnt_uaddr)) == NULL)
+		if ((hint_nbp = uaddr2taddr(nconf, contct_uaddr)) == NULL)
 			goto freeit;
 		hint_sa = hint_nbp->buf;
 	}