From: Chuck Lever <chuck.lever@oracle.com>
To: steved@redhat.com
Cc: chris.mason@oracle.com, linux-nfs@vger.kernel.org
Subject: [PATCH 2/6] tcp_wrappers: Use getifaddrs(3) if it is available
Date: Fri, 15 Jan 2010 12:49:49 -0500 [thread overview]
Message-ID: <20100115174949.30104.94932.stgit@localhost.localdomain> (raw)
In-Reply-To: <20100115174426.30104.3492.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
After glibc 2.3.3, getifaddrs(3) can return AF_INET6 addresses for
local network interfaces. Using the library call is easier than
trying to update the open code in from_local(), and means we have
less to maintain in nfs-utils.
Since from_local() can now support IPv6, change its synopsis to take a
"struct sockaddr *" .
Note that the original code discovers local addresses once. These
days, with wifi, DHCP, and NetworkManager, the local network
configuration can change dynamically over time. So, call getifaddrs()
more often to ensure from_local() has up-to-date network configuration
information.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
aclocal/ipv6.m4 | 4 +-
configure.ac | 2 -
support/include/tcpwrapper.h | 2 -
support/misc/from_local.c | 87 +++++++++++++++++++++++++++++++++++++++---
support/misc/tcpwrapper.c | 2 -
5 files changed, 85 insertions(+), 12 deletions(-)
diff --git a/aclocal/ipv6.m4 b/aclocal/ipv6.m4
index 2490f3d..5ee8fb6 100644
--- a/aclocal/ipv6.m4
+++ b/aclocal/ipv6.m4
@@ -15,8 +15,8 @@ AC_DEFUN([AC_IPV6], [
fi
dnl IPv6-enabled networking functions required for IPv6
- AC_CHECK_FUNCS([getnameinfo bindresvport_sa], ,
- [AC_MSG_ERROR([Missing functions needed for IPv6.])])
+ AC_CHECK_FUNCS([getifaddrs getnameinfo bindresvport_sa], ,
+ [AC_MSG_ERROR([Missing library functions needed for IPv6.])])
dnl Need to detect presence of IPv6 networking at run time via
dnl getaddrinfo(3); old versions of glibc do not support ADDRCONFIG
diff --git a/configure.ac b/configure.ac
index c77c5ba..1dc4249 100644
--- a/configure.ac
+++ b/configure.ac
@@ -330,7 +330,7 @@ AC_FUNC_STAT
AC_FUNC_VPRINTF
AC_CHECK_FUNCS([alarm atexit dup2 fdatasync ftruncate getcwd \
gethostbyaddr gethostbyname gethostname getmntent \
- getnameinfo getrpcbyname \
+ getnameinfo getrpcbyname getifaddrs \
gettimeofday hasmntopt inet_ntoa innetgr memset mkdir pathconf \
realpath rmdir select socket strcasecmp strchr strdup \
strerror strrchr strtol strtoul sigprocmask])
diff --git a/support/include/tcpwrapper.h b/support/include/tcpwrapper.h
index 98cf806..f1145bd 100644
--- a/support/include/tcpwrapper.h
+++ b/support/include/tcpwrapper.h
@@ -11,7 +11,7 @@ extern int allow_severity;
extern int deny_severity;
extern int good_client(char *daemon, struct sockaddr_in *addr);
-extern int from_local (struct sockaddr_in *addr);
+extern int from_local(const struct sockaddr *sap);
extern int check_default(char *daemon, struct sockaddr_in *addr,
u_long proc, u_long prog);
diff --git a/support/misc/from_local.c b/support/misc/from_local.c
index 3f46b99..57529ad 100644
--- a/support/misc/from_local.c
+++ b/support/misc/from_local.c
@@ -43,6 +43,7 @@ static char sccsid[] = "@(#) from_local.c 1.3 96/05/31 15:52:57";
#include <sys/types.h>
#include <sys/socket.h>
+#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <netdb.h>
@@ -52,6 +53,7 @@ static char sccsid[] = "@(#) from_local.c 1.3 96/05/31 15:52:57";
#include <stdlib.h>
#include <string.h>
+#include "sockaddr.h"
#include "tcpwrapper.h"
#include "xlog.h"
@@ -60,11 +62,66 @@ static char sccsid[] = "@(#) from_local.c 1.3 96/05/31 15:52:57";
#define FALSE 0
#endif
- /*
- * With virtual hosting, each hardware network interface can have multiple
- * network addresses. On such machines the number of machine addresses can
- * be surprisingly large.
- */
+#ifdef HAVE_GETIFADDRS
+
+#include <ifaddrs.h>
+#include <time.h>
+
+/**
+ * from_local - determine whether request comes from the local system
+ * @sap: pointer to socket address to check
+ *
+ * With virtual hosting, each hardware network interface can have
+ * multiple network addresses. On such machines the number of machine
+ * addresses can be surprisingly large.
+ *
+ * We also expect the local network configuration to change over time,
+ * so call getifaddrs(3) more than once, but not too often.
+ *
+ * Returns TRUE if the sockaddr contains an address of one of the local
+ * network interfaces. Otherwise FALSE is returned.
+ */
+int
+from_local(const struct sockaddr *sap)
+{
+ static struct ifaddrs *ifaddr = NULL;
+ static time_t last_update = 0;
+ struct ifaddrs *ifa;
+ time_t now;
+
+ if (time(&now) == ((time_t)-1)) {
+ xlog(L_ERROR, "%s: time(2): %m", __func__);
+
+ /* If we don't know what time it is, use the
+ * existing ifaddr list, if one exists */
+ now = last_update;
+ if (ifaddr == NULL)
+ now++;
+ }
+ if (now != last_update) {
+ xlog(D_GENERAL, "%s: updating if addr list", __func__);
+
+ if (ifaddr)
+ freeifaddrs(ifaddr);
+
+ if (getifaddrs(&ifaddr) == -1) {
+ xlog(L_ERROR, "%s: getifaddrs(3): %m", __func__);
+ return FALSE;
+ }
+
+ last_update = now;
+ }
+
+ for (ifa = ifaddr; ifa; ifa = ifa->ifa_next)
+ if ((ifa->ifa_flags & IFF_UP) &&
+ nfs_compare_sockaddr(sap, ifa->ifa_addr))
+ return TRUE;
+
+ return FALSE;
+}
+
+#else /* !HAVE_GETIFADDRS */
+
static int num_local;
static int num_addrs;
static struct in_addr *addrs;
@@ -155,12 +212,26 @@ find_local(void)
return (num_local);
}
-/* from_local - determine whether request comes from the local system */
+/**
+ * from_local - determine whether request comes from the local system
+ * @sap: pointer to socket address to check
+ *
+ * With virtual hosting, each hardware network interface can have
+ * multiple network addresses. On such machines the number of machine
+ * addresses can be surprisingly large.
+ *
+ * Returns TRUE if the sockaddr contains an address of one of the local
+ * network interfaces. Otherwise FALSE is returned.
+ */
int
-from_local(struct sockaddr_in *addr)
+from_local(const struct sockaddr *sap)
{
+ const struct sockaddr_in *addr = (const struct sockaddr_in *)sap;
int i;
+ if (sap->sa_family != AF_INET)
+ return (FALSE);
+
if (addrs == 0 && find_local() == 0)
xlog(L_ERROR, "Cannot find any active local network interfaces");
@@ -184,3 +255,5 @@ int main(void)
}
#endif /* TEST */
+
+#endif /* !HAVE_GETIFADDRS */
diff --git a/support/misc/tcpwrapper.c b/support/misc/tcpwrapper.c
index 1da6020..af626ad 100644
--- a/support/misc/tcpwrapper.c
+++ b/support/misc/tcpwrapper.c
@@ -202,7 +202,7 @@ u_long prog;
if (acc && changed == 0)
return (acc->access);
- if (!(from_local(addr) || good_client(daemon, addr))) {
+ if (!(from_local((struct sockaddr *)addr) || good_client(daemon, addr))) {
log_bad_host(addr, proc, prog);
if (acc)
acc->access = FALSE;
next prev parent reply other threads:[~2010-01-15 17:50 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-01-15 17:49 [PATCH 0/6] IPv6 support for nfs-utils tcpwrapper shim Chuck Lever
[not found] ` <20100115174426.30104.3492.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2010-01-15 17:49 ` [PATCH 1/6] tcpwrappers: Use xlog() instead of perror(3) and syslog(2) Chuck Lever
2010-01-15 17:49 ` Chuck Lever [this message]
2010-01-15 17:49 ` [PATCH 3/6] tcp_wrapper: Clean up logit() Chuck Lever
2010-01-15 17:50 ` [PATCH 4/6] tcpwrapper: Fix signage problems in the tcp_wrappers hash function Chuck Lever
2010-01-15 17:50 ` [PATCH 5/6] tcpwrapper: Eliminated shadowed declaration warnings Chuck Lever
2010-01-15 17:50 ` [PATCH 6/6] tcpwrapper: Add support for IPv6 Chuck Lever
2010-01-15 18:04 ` [PATCH 0/6] IPv6 support for nfs-utils tcpwrapper shim Steve Dickson
[not found] ` <4B50AE34.3020009-AfCzQyP5zfLQT0dZR+AlfA@public.gmane.org>
2010-01-15 18:27 ` Chuck Lever
2010-01-15 18:37 ` Steve Dickson
[not found] ` <4B50B5F0.6020202-AfCzQyP5zfLQT0dZR+AlfA@public.gmane.org>
2010-01-15 18:59 ` Chuck Lever
2010-01-15 19:32 ` Steve Dickson
-- strict thread matches above, loose matches on Subject: below --
2010-01-15 21:31 [PATCH 0/6] IPv6 support for nfs-utils tcpwrapper shim (take 2) Chuck Lever
[not found] ` <20100115212102.18214.19398.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2010-01-15 21:31 ` [PATCH 2/6] tcp_wrappers: Use getifaddrs(3) if it is available Chuck Lever
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100115174949.30104.94932.stgit@localhost.localdomain \
--to=chuck.lever@oracle.com \
--cc=chris.mason@oracle.com \
--cc=linux-nfs@vger.kernel.org \
--cc=steved@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox