From 8e0eb02df52d15dd4317abeddec427cdbac4da3c Mon Sep 17 00:00:00 2001 From: huyan Date: Mon, 8 Jul 2019 02:10:44 +0000 Subject: [PATCH] backport bugfix rpcbind GETADDR return client ip --- src/util.c | 45 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/src/util.c b/src/util.c index 74b0284..d722d4f 100644 --- a/src/util.c +++ b/src/util.c @@ -103,7 +103,7 @@ char * addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr, char *netid) { - struct ifaddrs *ifap, *ifp = NULL, *bestif; + struct ifaddrs *ifap, *ifp = NULL, *bestif, *exactif; struct netbuf *serv_nbp = NULL, *hint_nbp = NULL, tbuf; struct sockaddr *caller_sa, *hint_sa, *ifsa, *ifmasksa, *serv_sa; struct sockaddr_storage ss; @@ -157,7 +157,12 @@ addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr, * network portion of its address is equal to that of the client. * If so, we have found the interface that we want to use. */ - bestif = NULL; + bestif = NULL; /* first interface UP with same network & family */ + exactif = NULL; /* the interface requested by the client */ + u_int8_t maskAllBits[16] = { /* 16 bytes for IPv6 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) { ifsa = ifap->ifa_addr; ifmasksa = ifap->ifa_netmask; @@ -175,8 +180,21 @@ addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr, if (!bitmaskcmp(&SA2SINADDR(ifsa), &SA2SINADDR(hint_sa), &SA2SINADDR(ifmasksa), sizeof(struct in_addr))) { - bestif = ifap; - goto found; + if (getenv("RPCBIND_GETADDR_RETURN_CLIENT_IP") == NULL) { + bestif = ifap; + goto found; + } + + if(!bestif) /* for compatibility with previous code */ + bestif = ifap; + /* Is this an exact match? */ + if (!bitmaskcmp(&SA2SINADDR(ifsa), + &SA2SINADDR(hint_sa), maskAllBits, + sizeof(struct in_addr))) { + exactif = ifap; + goto found; + } + /* else go-on looking for an exact match */ } break; #ifdef INET6 @@ -197,8 +215,21 @@ addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr, } else if (!bitmaskcmp(&SA2SIN6ADDR(ifsa), &SA2SIN6ADDR(hint_sa), &SA2SIN6ADDR(ifmasksa), sizeof(struct in6_addr))) { - bestif = ifap; - goto found; + if (getenv("RPCBIND_GETADDR_RETURN_CLIENT_IP") == NULL) { + bestif = ifap; + goto found; + } + + if(!bestif) /* for compatibility with previous code */ + bestif = ifap; + /* Is this an exact match? */ + if (!bitmaskcmp(&SA2SIN6ADDR(ifsa), + &SA2SIN6ADDR(hint_sa), maskAllBits, + sizeof(struct in6_addr))) { + exactif = ifap; + goto found; + } + /* else go-on looking for an exact match */ } break; #endif @@ -219,6 +250,8 @@ addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr, goto freeit; found: + if(exactif) + bestif = exactif; /* * Construct the new address using the the address from * `bestif', and the port number from `serv_uaddr'. -- 1.7.12.4