summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2006-04-27 23:24:34 +0000
committerLennart Poettering <lennart@poettering.net>2006-04-27 23:24:34 +0000
commitf020c14e4f1eb6b643ff673d0b5c35bc41fd4595 (patch)
tree91529efd7bf64aea9e53bf7191a6eb92cb46e3f4
parentd2b78eef168894934102d0bb05623622c15700d9 (diff)
* implement a "minimal" mode
* add configure option to allow building of nss-mdns without legacy mDNS queries git-svn-id: file:///home/lennart/svn/public/nss-mdns/trunk@91 0ee8848e-81ea-0310-a63a-f631d1a40d77
-rw-r--r--configure.ac60
-rw-r--r--doc/Makefile.am7
-rw-r--r--src/Makefile.am65
-rw-r--r--src/nss.c164
-rw-r--r--src/util.c30
-rw-r--r--src/util.h7
6 files changed, 252 insertions, 81 deletions
diff --git a/configure.ac b/configure.ac
index 1b7034a..cafaa15 100644
--- a/configure.ac
+++ b/configure.ac
@@ -39,6 +39,32 @@ AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
+test_gcc_flag() {
+ AC_LANG_CONFTEST([int main() {}])
+ $CC -c conftest.c $CFLAGS $@ > /dev/null 2> /dev/null
+ ret=$?
+ rm -f conftest.o
+ return $ret
+}
+
+# If using GCC specify some additional parameters
+if test "x$GCC" = "xyes" ; then
+
+ # We use gnu99 instead of c99 because many have interpreted the standard
+ # in a way that int64_t isn't defined on non-64 bit platforms.
+ DESIRED_FLAGS="-std=gnu99 -Wall -W -Wextra -pedantic -pipe -Wformat -Wold-style-definition -Wdeclaration-after-statement -Wfloat-equal -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls -Wmissing-noreturn -Wshadow -Wendif-labels -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings -Winline -Wno-unused-parameter"
+
+ for flag in $DESIRED_FLAGS ; do
+ AC_MSG_CHECKING([whether $CC accepts $flag])
+ if test_gcc_flag $flag ; then
+ CFLAGS="$CFLAGS $flag"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ done
+fi
+
# libtool stuff
AC_DISABLE_STATIC
AC_PROG_LIBTOOL
@@ -79,14 +105,23 @@ if test x$lynx = xyes ; then
AC_CHECK_PROG(have_lynx, lynx, yes, no)
if test x$have_lynx = xno ; then
- AC_MSG_WARN([*** lynx not found, plain text README will not be built ***])
+ lynx=no
+ AC_CHECK_PROG(have_links, links, yes, no)
+ if test x$have_links = xno ; then
+ AC_MSG_WARN([*** neither lynx nor links found, plain text README will not be built ***])
+ else
+ links=yes
+ fi
fi
fi
AM_CONDITIONAL([USE_LYNX], [test "x$lynx" = xyes])
+AM_CONDITIONAL([USE_LINKS], [test "x$links" = xyes])
+
+### Enable avahi support?
AC_ARG_ENABLE(avahi,
- AC_HELP_STRING([--enable-avahi],[use Avahi (default=yes)]),
+ AC_HELP_STRING([--enable-avahi],[Enable lookups with Avahi (default=yes)]),
[case "${enableval}" in
yes) ENABLE_AVAHI=yes ;;
no) ENABLE_AVAHI=no ;;
@@ -94,13 +129,32 @@ AC_ARG_ENABLE(avahi,
esac],
[ENABLE_AVAHI=yes]) dnl Default value
-
AM_CONDITIONAL([ENABLE_AVAHI], [test "x$ENABLE_AVAHI" = "xyes"])
if test "x$ENABLE_AVAHI" = "xyes" ; then
AC_DEFINE(ENABLE_AVAHI, [1], [Try to make use of a running avahi mDNS server before resolving on our own behalf])
fi
+### Enable legacy support?
+
+AC_ARG_ENABLE(legacy,
+ AC_HELP_STRING([--enable-legacy],[Enable legacy lookups when Avahi isn't available (default=yes)]),
+ [case "${enableval}" in
+ yes) ENABLE_LEGACY=yes ;;
+ no) ENABLE_LEGACY=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-legacy) ;;
+ esac],
+ [ENABLE_LEGACY=yes]) dnl Default value
+
+if test "x$ENABLE_AVAHI" = "xno" -a "x$ENABLE_LEGACY" = "xno"; then
+ AC_MSG_ERROR(Can't disable legacy lookups if Avahi support is disabled)
+fi
+
+if test "x$ENABLE_LEGACY" = "xyes" ; then
+ AC_DEFINE(ENABLE_LEGACY, [1], [Enable legacy lookups when Avahi isn't available])
+fi
+
+AM_CONDITIONAL([ENABLE_LEGACY], [test "x$ENABLE_LEGACY" = "xyes"])
AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile doc/README.html ])
AC_OUTPUT
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 752b2d6..a122244 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -29,6 +29,13 @@ README: README.html
CLEANFILES += README
endif
+if USE_LINKS
+README: README.html
+ links -dump $^ | sed 's,file://localhost/.*/doc/README.html,README,' > $@
+
+CLEANFILES += README
+endif
+
tidy: README.html
tidy -qe < README.html ; true
diff --git a/src/Makefile.am b/src/Makefile.am
index e9d5f91..7633c37 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -27,38 +27,85 @@ AM_CFLAGS = \
# This cool debug trap works on i386/gcc only
AM_CFLAGS+='-DDEBUG_TRAP=__asm__("int $$3")'
-noinst_PROGRAMS = nss-test mdns-test
-lib_LTLIBRARIES = libnss_mdns.la libnss_mdns4.la libnss_mdns6.la
+lib_LTLIBRARIES= \
+ libnss_mdns.la \
+ libnss_mdns4.la \
+ libnss_mdns6.la \
+ libnss_mdns_minimal.la \
+ libnss_mdns4_minimal.la \
+ libnss_mdns6_minimal.la
-mdns_test_SOURCES = query.c dns.c util.c mdns-test.c \
- query.h dns.h util.h
+noinst_PROGRAMS= \
+ nss-test
-nss_test_SOURCES = nss-test.c
+libnss_mdns_la_SOURCES= \
+ nss.c \
+ util.c util.h
-libnss_mdns_la_SOURCES = query.c dns.c util.c nss.c query.h dns.h util.h
libnss_mdns_la_CFLAGS=$(AM_CFLAGS)
libnss_mdns_la_LDFLAGS=-avoid-version -module -export-dynamic -shrext .so.2
if ENABLE_AVAHI
+libnss_mdns_la_SOURCES += \
+ avahi.c avahi.h
+
noinst_PROGRAMS += avahi-test
-avahi_test_SOURCES = avahi.c util.c avahi.h util.h avahi-test.c
-libnss_mdns_la_SOURCES += avahi.c avahi.h
endif
+if ENABLE_LEGACY
+libnss_mdns_la_SOURCES += \
+ query.c query.h \
+ dns.c dns.h
+
+noinst_PROGRAMS += mdns-test
+endif
+
+libnss_mdns_minimal_la_SOURCES=$(libnss_mdns_la_SOURCES)
+libnss_mdns_minimal_la_CFLAGS=$(libnss_mdns_la_CFLAGS) -DMDNS_MINIMAL
+libnss_mdns_minimal_la_LDFLAGS=$(libnss_mdns_la_LDFLAGS)
+
libnss_mdns4_la_SOURCES=$(libnss_mdns_la_SOURCES)
libnss_mdns4_la_CFLAGS=$(libnss_mdns_la_CFLAGS) -DNSS_IPV4_ONLY=1
libnss_mdns4_la_LDFLAGS=$(libnss_mdns_la_LDFLAGS)
+libnss_mdns4_minimal_la_SOURCES=$(libnss_mdns_la_SOURCES)
+libnss_mdns4_minimal_la_CFLAGS=$(libnss_mdns_la_CFLAGS) -DNSS_IPV4_ONLY=1 -DMDNS_MINIMAL
+libnss_mdns4_minimal_la_LDFLAGS=$(libnss_mdns_la_LDFLAGS)
+
libnss_mdns6_la_SOURCES=$(libnss_mdns_la_SOURCES)
libnss_mdns6_la_CFLAGS=$(libnss_mdns_la_CFLAGS) -DNSS_IPV6_ONLY=1
libnss_mdns6_la_LDFLAGS=$(libnss_mdns_la_LDFLAGS)
+libnss_mdns6_minimal_la_SOURCES=$(libnss_mdns_la_SOURCES)
+libnss_mdns6_minimal_la_CFLAGS=$(libnss_mdns_la_CFLAGS) -DNSS_IPV6_ONLY=1 -DMDNS_MINIMAL
+libnss_mdns6_minimal_la_LDFLAGS=$(libnss_mdns_la_LDFLAGS)
+
+avahi_test_SOURCES = \
+ avahi.c avahi.h \
+ util.c util.h \
+ avahi-test.c
+
+mdns_test_SOURCES = \
+ query.c query.h \
+ dns.c dns.h \
+ util.c util.h \
+ mdns-test.c
+
+nss_test_SOURCES = \
+ nss-test.c
+
install-exec-hook:
rm -f $(DESTDIR)$(libdir)/libnss_mdns.la
+ rm -f $(DESTDIR)$(libdir)/libnss_mdns_minimal.la
rm -f $(DESTDIR)$(libdir)/libnss_mdns4.la
+ rm -f $(DESTDIR)$(libdir)/libnss_mdns4_minimal.la
rm -f $(DESTDIR)$(libdir)/libnss_mdns6.la
+ rm -f $(DESTDIR)$(libdir)/libnss_mdns6_minimal.la
uninstall-hook:
rm -f $(DESTDIR)$(libdir)/libnss_mdns.so.2
+ rm -f $(DESTDIR)$(libdir)/libnss_mdns_minimal.so.2
rm -f $(DESTDIR)$(libdir)/libnss_mdns4.so.2
- rm -f $(DESTDIR)$(libdir)/libnss_mdns6.so.2
+ rm -f $(DESTDIR)$(libdir)/libnss_mdns4_minimal.so.2
+ rm -f $(DESTDIR)$(libdir)/libnss_mdns6.so.2
+ rm -f $(DESTDIR)$(libdir)/libnss_mdns6_minimal.so.2
diff --git a/src/nss.c b/src/nss.c
index 5b5579a..50e710c 100644
--- a/src/nss.c
+++ b/src/nss.c
@@ -39,19 +39,32 @@
#include "avahi.h"
#endif
-#define MAX_ENTRIES 16
-
-#ifdef NSS_IPV4_ONLY
+#if defined(NSS_IPV4_ONLY) && ! defined(MDNS_MINIMAL)
#define _nss_mdns_gethostbyname2_r _nss_mdns4_gethostbyname2_r
-#define _nss_mdns_gethostbyname_r _nss_mdns4_gethostbyname_r
-#define _nss_mdns_gethostbyaddr_r _nss_mdns4_gethostbyaddr_r
-#elif NSS_IPV6_ONLY
+#define _nss_mdns_gethostbyname_r _nss_mdns4_gethostbyname_r
+#define _nss_mdns_gethostbyaddr_r _nss_mdns4_gethostbyaddr_r
+#elif defined(NSS_IPV4_ONLY) && defined(MDNS_MINIMAL)
+#define _nss_mdns_gethostbyname2_r _nss_mdns4_minimal_gethostbyname2_r
+#define _nss_mdns_gethostbyname_r _nss_mdns4_minimal_gethostbyname_r
+#define _nss_mdns_gethostbyaddr_r _nss_mdns4_minimal_gethostbyaddr_r
+#elif defined(NSS_IPV6_ONLY) && ! defined(MDNS_MINIMAL)
#define _nss_mdns_gethostbyname2_r _nss_mdns6_gethostbyname2_r
-#define _nss_mdns_gethostbyname_r _nss_mdns6_gethostbyname_r
-#define _nss_mdns_gethostbyaddr_r _nss_mdns6_gethostbyaddr_r
+#define _nss_mdns_gethostbyname_r _nss_mdns6_gethostbyname_r
+#define _nss_mdns_gethostbyaddr_r _nss_mdns6_gethostbyaddr_r
+#elif defined(NSS_IPV6_ONLY) && defined(MDNS_MINIMAL)
+#define _nss_mdns_gethostbyname2_r _nss_mdns6_minimal_gethostbyname2_r
+#define _nss_mdns_gethostbyname_r _nss_mdns6_minimal_gethostbyname_r
+#define _nss_mdns_gethostbyaddr_r _nss_mdns6_minimal_gethostbyaddr_r
+#elif defined(MDNS_MINIMAL)
+#define _nss_mdns_gethostbyname2_r _nss_mdns_minimal_gethostbyname2_r
+#define _nss_mdns_gethostbyname_r _nss_mdns_minimal_gethostbyname_r
+#define _nss_mdns_gethostbyaddr_r _nss_mdns_minimal_gethostbyaddr_r
#endif
-/* the resolv conf page states that they only support 6 domains */
+/* Maximum number of entries to return */
+#define MAX_ENTRIES 16
+
+/* The resolv.conf page states that they only support 6 domains */
#define MAX_SEARCH_DOMAINS 6
struct userdata {
@@ -113,44 +126,50 @@ static int ends_with(const char *name, const char* suffix) {
}
static int verify_name_allowed(const char *name) {
+#ifndef MDNS_MINIMAL
FILE *f;
- int valid = 0;
+#endif
assert(name);
- if (!(f = fopen(MDNS_ALLOW_FILE, "r")))
- return ends_with(name, ".local") || ends_with(name, ".local.");
-
- while (!feof(f)) {
- char ln[128], ln2[128], *t;
+#ifndef MDNS_MINIMAL
+ if ((f = fopen(MDNS_ALLOW_FILE, "r"))) {
+ int valid = 0;
- if (!fgets(ln, sizeof(ln), f))
- break;
-
- ln[strcspn(ln, "#\t\n\r ")] = 0;
-
- if (ln[0] == 0)
- continue;
-
- if (strcmp(ln, "*") == 0) {
- valid = 1;
- break;
- }
-
- if (ln[0] != '.')
- snprintf(t = ln2, sizeof(ln2), ".%s", ln);
- else
- t = ln;
-
- if (ends_with(name, t)) {
- valid = 1;
- break;
+
+ while (!feof(f)) {
+ char ln[128], ln2[128], *t;
+
+ if (!fgets(ln, sizeof(ln), f))
+ break;
+
+ ln[strcspn(ln, "#\t\n\r ")] = 0;
+
+ if (ln[0] == 0)
+ continue;
+
+ if (strcmp(ln, "*") == 0) {
+ valid = 1;
+ break;
+ }
+
+ if (ln[0] != '.')
+ snprintf(t = ln2, sizeof(ln2), ".%s", ln);
+ else
+ t = ln;
+
+ if (ends_with(name, t)) {
+ valid = 1;
+ break;
+ }
}
+
+ fclose(f);
+ return valid;
}
+#endif
- fclose(f);
-
- return valid;
+ return ends_with(name, ".local") || ends_with(name, ".local.");
}
static char **alloc_domains(unsigned ndomains) {
@@ -268,7 +287,7 @@ enum nss_status _nss_mdns_gethostbyname2_r(
struct userdata u;
enum nss_status status = NSS_STATUS_UNAVAIL;
- int fd = -1, i;
+ int i;
size_t address_length, l, idx, astart;
void (*ipv4_func)(const ipv4_address_t *ipv4, void *userdata);
void (*ipv6_func)(const ipv6_address_t *ipv6, void *userdata);
@@ -279,6 +298,10 @@ enum nss_status _nss_mdns_gethostbyname2_r(
uint8_t data[128];
#endif
+#ifdef ENABLE_LEGACY
+ int fd = -1;
+#endif
+
/* DEBUG_TRAP; */
#ifdef NSS_IPV4_ONLY
@@ -381,11 +404,14 @@ enum nss_status _nss_mdns_gethostbyname2_r(
free_domains(domains);
}
}
+#endif
-
- if (u.count == 0 && !avahi_works) {
+#if defined(ENABLE_LEGACY) && defined(ENABLE_AVAHI)
+ if (u.count == 0 && !avahi_works)
#endif
+#if defined(ENABLE_LEGACY)
+ {
if ((fd = mdns_open_socket()) < 0) {
*errnop = errno;
*h_errnop = NO_RECOVERY;
@@ -432,14 +458,13 @@ enum nss_status _nss_mdns_gethostbyname2_r(
free_domains(domains);
}
}
-
-#ifdef ENABLE_AVAHI
}
#endif
if (u.count == 0) {
*errnop = ETIMEDOUT;
*h_errnop = HOST_NOT_FOUND;
+ status = NSS_STATUS_NOTFOUND;
goto finish;
}
@@ -483,8 +508,10 @@ enum nss_status _nss_mdns_gethostbyname2_r(
status = NSS_STATUS_SUCCESS;
finish:
+#ifdef ENABLE_LEGACY
if (fd >= 0)
close(fd);
+#endif
return status;
}
@@ -523,18 +550,23 @@ enum nss_status _nss_mdns_gethostbyaddr_r(
struct userdata u;
enum nss_status status = NSS_STATUS_UNAVAIL;
- int fd = -1, r;
+ int r;
size_t address_length, idx, astart;
+
#ifdef ENABLE_AVAHI
char t[256];
#endif
+#ifdef ENABLE_LEGACY
+ int fd = -1;
+#endif
*errnop = EINVAL;
*h_errnop = NO_RECOVERY;
u.count = 0;
u.data_len = 0;
-
+
+ /* Check for address types */
address_length = af == AF_INET ? sizeof(ipv4_address_t) : sizeof(ipv6_address_t);
if (len != (int) address_length ||
@@ -551,6 +583,7 @@ enum nss_status _nss_mdns_gethostbyaddr_r(
goto finish;
}
+ /* Check for buffer space */
if (buflen <
sizeof(char*)+ /* alias names */
address_length) { /* address */
@@ -562,27 +595,45 @@ enum nss_status _nss_mdns_gethostbyaddr_r(
goto finish;
}
-#ifdef ENABLE_AVAHI
+#ifdef MDNS_MINIMAL
+ /* Only query for 169.254.0.0/16 IPv4 in minimal mode */
+ if ((af == AF_INET && ((*(uint32_t*) &addr) & 0xFFFF0000UL) != 0xA9FE0000UL) ||
+ (af == AF_INET6 && !(((uint8_t*) &addr)[0] == 0xFE && (((uint8_t*) &addr)[1] >> 6) == 2))) {
+
+ *errnop = EINVAL;
+ *h_errnop = NO_RECOVERY;
+ goto finish;
+ }
+#endif
+
+#ifdef ENABLE_AVAHI
+ /* Lookup using Avahi */
if ((r = avahi_resolve_address(af, addr, t, sizeof(t))) == 0) {
name_callback(t, &u);
} else if (r > 0) {
*errnop = ETIMEDOUT;
*h_errnop = HOST_NOT_FOUND;
+ status = NSS_STATUS_NOTFOUND;
goto finish;
- }
-
-#endif
-
- if (u.count == 0) {
+ }
+#endif
+#if defined(ENABLE_AVAHI) && defined(ENABLE_LEGACY)
+ else
+#endif
+
+#ifdef ENABLE_LEGACY
+ /* Lookup using legacy mDNS queries */
+ {
if ((fd = mdns_open_socket()) < 0) {
-
*errnop = errno;
*h_errnop = NO_RECOVERY;
goto finish;
}
-
+
+ r = -1;
+
#if ! defined(NSS_IPV6_ONLY) && ! defined(NSS_IPV4_ONLY)
if (af == AF_INET)
#endif
@@ -595,13 +646,14 @@ enum nss_status _nss_mdns_gethostbyaddr_r(
#ifndef NSS_IPV4_ONLY
r = mdns_query_ipv6(fd, (const ipv6_address_t*) addr, name_callback, &u);
#endif
-
if (r < 0) {
*errnop = ETIMEDOUT;
*h_errnop = HOST_NOT_FOUND;
+ status = NSS_STATUS_NOTFOUND;
goto finish;
}
}
+#endif /* ENABLE_LEGACY */
/* Alias names */
*((char**) buffer) = NULL;
@@ -642,8 +694,10 @@ enum nss_status _nss_mdns_gethostbyaddr_r(
status = NSS_STATUS_SUCCESS;
finish:
+#ifdef ENABLE_LEGACY
if (fd >= 0)
close(fd);
+#endif
return status;
}
diff --git a/src/util.c b/src/util.c
index bf37711..1d0cd90 100644
--- a/src/util.c
+++ b/src/util.c
@@ -31,6 +31,8 @@
#include "util.h"
+#ifdef ENABLE_LEGACY
+
/* Calculate the difference between the two specfified timeval
* timestamsps. */
usec_t timeval_diff(const struct timeval *a, const struct timeval *b) {
@@ -102,19 +104,6 @@ void timeval_add(struct timeval *tv, usec_t v) {
}
}
-int set_cloexec(int fd) {
- int n;
- assert(fd >= 0);
-
- if ((n = fcntl(fd, F_GETFD)) < 0)
- return -1;
-
- if (n & FD_CLOEXEC)
- return 0;
-
- return fcntl(fd, F_SETFD, n|FD_CLOEXEC);
-}
-
int set_nonblock(int fd) {
int n;
assert(fd >= 0);
@@ -203,3 +192,18 @@ int wait_for_read(int fd, struct timeval *end) {
}
}
+#endif
+
+int set_cloexec(int fd) {
+ int n;
+ assert(fd >= 0);
+
+ if ((n = fcntl(fd, F_GETFD)) < 0)
+ return -1;
+
+ if (n & FD_CLOEXEC)
+ return 0;
+
+ return fcntl(fd, F_SETFD, n|FD_CLOEXEC);
+}
+
diff --git a/src/util.h b/src/util.h
index b227ce0..e2334ad 100644
--- a/src/util.h
+++ b/src/util.h
@@ -26,6 +26,7 @@
#include <time.h>
#include <inttypes.h>
+#ifdef ENABLE_LEGACY
typedef uint64_t usec_t;
usec_t timeval_diff(const struct timeval *a, const struct timeval *b);
@@ -34,9 +35,13 @@ usec_t timeval_age(const struct timeval *tv);
void timeval_add(struct timeval *tv, usec_t v);
int set_nonblock(int fd);
-int set_cloexec(int fd);
int wait_for_write(int fd, struct timeval *end);
int wait_for_read(int fd, struct timeval *end);
#endif
+
+int set_cloexec(int fd);
+
+
+#endif