]> git.meshlink.io Git - catta/commitdiff
Merge pull request #2 from everbase/feature/windows
authorNiklas <niklas.hofmann@everbase.net>
Mon, 20 Oct 2014 12:08:11 +0000 (14:08 +0200)
committerNiklas <niklas.hofmann@everbase.net>
Mon, 20 Oct 2014 12:08:11 +0000 (14:08 +0200)
Port the library to Windows

62 files changed:
.gitignore
configure.ac
examples/core-browse-services.c
examples/core-publish-service.c
include/catta/address.h
include/catta/llist.h
include/catta/lookup.h
include/catta/publish.h
m4/acx_pthread.m4
src/Makefile.am
src/address.c
src/announce.c
src/announce.h
src/browse-dns-server.c
src/browse-domain.c
src/browse-service-type.c
src/browse-service.c
src/browse.c
src/browse.h
src/cache.c
src/cache.h
src/compat/windows/include/arpa/inet.h [new file with mode: 0644]
src/compat/windows/include/net/if.h [new file with mode: 0644]
src/compat/windows/include/netinet/in.h [new file with mode: 0644]
src/compat/windows/include/sys/ioctl.h [new file with mode: 0644]
src/compat/windows/include/sys/poll.h [new file with mode: 0644]
src/compat/windows/include/sys/select.h [new file with mode: 0644]
src/compat/windows/include/sys/socket.h [new file with mode: 0644]
src/compat/windows/include/sys/uio.h [new file with mode: 0644]
src/compat/windows/include/sys/utsname.h [new file with mode: 0644]
src/compat/windows/wincompat.c [new file with mode: 0644]
src/compat/windows/wincompat.h [new file with mode: 0644]
src/dns-srv-rr.h
src/entry.c
src/error.c
src/fdutil.c
src/iface-none.c
src/iface-windows.c [new file with mode: 0644]
src/iface-windows.h [new file with mode: 0644]
src/iface.c
src/iface.h
src/internal.h
src/multicast-lookup.c
src/probe-sched.c
src/querier.c
src/query-sched.c
src/resolve-address.c
src/resolve-host-name.c
src/resolve-service.c
src/response-sched.c
src/rr.c
src/server.c
src/simple-watch.c
src/socket.c
src/socket.h
src/thread-watch.c
src/wide-area.c
tests/Makefile.am
tests/catta-test.c
tests/prioq-test.c
tests/strlst-test.c
tests/timeval-test.c

index 2059c267991609a07af644896a727bab2e514fba..fb0a069c21c68a7ee1d653e418bd998c4f0944e7 100644 (file)
@@ -26,4 +26,7 @@ ltmain.sh
 missing
 stamp-h1
 .*.swp
+.*.swo
 test-driver
+*.exe
+.dirstamp
index 59255603f0872c7344aa66bf0fe38d284f0e602e..cabd87bfdb8f48c0e7b6414c61a7e42662a22e87 100644 (file)
@@ -23,7 +23,7 @@ AC_INIT([catta],[0.1],[])
 AC_CONFIG_SRCDIR([src/server.c])
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_HEADERS([config.h])
-AM_INIT_AUTOMAKE([foreign 1.11 -Wall -Wno-portability silent-rules tar-pax])
+AM_INIT_AUTOMAKE([foreign 1.11 -Wall -Wno-portability silent-rules tar-pax subdir-objects])
 
 AC_SUBST(PACKAGE_URL, [http://github.com/everbase/catta/])
 
@@ -55,6 +55,17 @@ if test x"$ac_cv_prog_cc_c99" = x"no"; then
     AC_MSG_ERROR([C99 support is required])
 fi
 
+# Windows stuff
+AC_CHECK_DECL(_WIN32)
+AM_CONDITIONAL([WINDOWS], [ test "x$ac_cv_have_decl__WIN32" = "xyes" ])
+if test "x$ac_cv_have_decl__WIN32" = "xyes" ; then
+    CPPFLAGS="$CPPFLAGS -I`pwd`/src/compat/windows/include"
+fi
+AC_CHECK_MEMBER([struct in_pktinfo.ipi_spec_dst],
+    AC_DEFINE([HAVE_IPI_SPEC_DST], [], [struct in_pktinfo has ipi_spec_dst member]),
+    [],
+    [[#include <netinet/in.h>]])
+
 # -fstack-protector
 AC_ARG_ENABLE([stack-protector],
     [AS_HELP_STRING([--disable-stack-protector],
@@ -121,15 +132,10 @@ fi
 if test x"$enable_ssp" = x"yes"; then
     # Do this the long way so we don't call GCC_STACK_PROTECT_LIB twice
     GCC_STACK_PROTECT_CC
-
-    AC_LANG_PUSH([C++])
-    GCC_STACK_PROTECT_CXX
-    AC_LANG_POP([C++])
-    # XXX: Update the enable_ssp value now for output later?
 fi
 
 # libtool stuff
-AC_PROG_LIBTOOL
+LT_INIT([win32-dll])
 
 ACX_PTHREAD(,AC_MSG_ERROR([Missing POSIX Threads support]))
 
@@ -248,7 +254,13 @@ test_gcc_flag() {
 # If using GCC specify some additional parameters
 if test "x$GCC" = "xyes" ; then
 
-    DESIRED_FLAGS="-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 -fdiagnostics-show-option -Wno-cast-qual -fno-strict-aliasing"
+    DESIRED_FLAGS="-Wall -W -Wextra -pedantic -pipe -Wformat -Wold-style-definition -Wdeclaration-after-statement -Wfloat-equal -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls -Wshadow -Wendif-labels -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings -fdiagnostics-show-option -Wno-cast-qual -fno-strict-aliasing"
+
+    # when compiling for MingW, -Wmissing-noreturn is triggered a bunch of
+    # times from autogenerated libtool wrappers, so leave it out on Windows.
+    if test "x$ac_cv_have_decl__WIN32" != "xyes" ; then
+        DESIRED_FLAGS="$DESIRED_FLAGS -Wmissing-noreturn"
+    fi
 
     for flag in $DESIRED_FLAGS ; do
         AC_MSG_CHECKING([whether $CC accepts $flag])
@@ -271,7 +283,7 @@ AC_CHECK_HEADERS([arpa/inet.h fcntl.h netinet/in.h sys/ioctl.h sys/socket.h sys/
 
 # Checks for library functions.
 AC_FUNC_SELECT_ARGTYPES
-AC_CHECK_FUNCS([gethostname select socket uname strcasecmp gettimeofday strncasecmp strlcpy])
+AC_CHECK_FUNCS([gethostname select socket uname strcasecmp gettimeofday strncasecmp strlcpy fcntl])
 
 AC_FUNC_CHOWN
 AC_FUNC_STAT
@@ -335,14 +347,11 @@ AC_OUTPUT
 echo "
  ---{ $PACKAGE_NAME $VERSION }---
 
-    prefix:                                    ${prefix}
-    sysconfdir:                                ${sysconfdir}
-    localstatedir:                             ${localstatedir}
-    C Compiler:                                ${CC}
-    CFLAGS:                                    ${CFLAGS}
-    Enable stack-smashing protection:          ${enable_ssp}
-"
-
-echo "\
+    prefix:                             ${prefix}
+    sysconfdir:                         ${sysconfdir}
+    localstatedir:                      ${localstatedir}
+    C Compiler:                         ${CC}
+    CFLAGS:                             ${CFLAGS}
+    Enable stack-smashing protection:   ${enable_ssp}
     Building tests:                     ${ENABLE_TESTS}
 "
index 44f8ece0f48fb8d346d52f2f73d18538cec89d8b..e8f4aad0a72d6f22855fa50f21cc2380c696fd51 100644 (file)
@@ -48,7 +48,7 @@ static CattaServer *server = NULL;
 
 static void resolve_callback(
     CattaSServiceResolver *r,
-    CATTA_GCC_UNUSED CattaIfIndex interface,
+    CATTA_GCC_UNUSED CattaIfIndex iface,
     CATTA_GCC_UNUSED CattaProtocol protocol,
     CattaResolverEvent event,
     const char *name,
@@ -101,7 +101,7 @@ static void resolve_callback(
 
 static void browse_callback(
     CattaSServiceBrowser *b,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaBrowserEvent event,
     const char *name,
@@ -131,7 +131,7 @@ static void browse_callback(
                the callback function is called the server will free
                the resolver for us. */
 
-            if (!(catta_s_service_resolver_new(s, interface, protocol, name, type, domain, CATTA_PROTO_UNSPEC, 0, resolve_callback, s)))
+            if (!(catta_s_service_resolver_new(s, iface, protocol, name, type, domain, CATTA_PROTO_UNSPEC, 0, resolve_callback, s)))
                 fprintf(stderr, "Failed to resolve service '%s': %s\n", name, catta_strerror(catta_server_errno(s)));
 
             break;
index 8d6377e6b70becd99ab37487d09fa44061ccf411..1d5ce9d317b9df34ff91ad8df70d7d60694c8f7e 100644 (file)
@@ -24,6 +24,8 @@
 #include <time.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <signal.h>
+#include <errno.h>
 #include <assert.h>
 
 #include <catta/core.h>
@@ -189,6 +191,14 @@ static void server_callback(CattaServer *s, CattaServerState state, CATTA_GCC_UN
     }
 }
 
+static void signal_exit(int signum) {
+    int errnosave = errno;
+    catta_simple_poll_quit(simple_poll);
+    errno = errnosave;
+
+    (void)signum; // ignore
+}
+
 int main(CATTA_GCC_UNUSED int argc, CATTA_GCC_UNUSED char*argv[]) {
     CattaServerConfig config;
     CattaServer *server = NULL;
@@ -224,6 +234,10 @@ int main(CATTA_GCC_UNUSED int argc, CATTA_GCC_UNUSED char*argv[]) {
         goto fail;
     }
 
+    /* exit cleanly on signals */
+    signal(SIGINT, signal_exit);
+    signal(SIGTERM, signal_exit);
+
     /* Run the main loop */
     catta_simple_poll_loop(simple_poll);
 
index f10f33b1026764f61b3f9e535612560f9190b8ec..ad8e93b94db91fc5375b1312fc4424d2c9b381ab 100644 (file)
@@ -51,7 +51,7 @@ enum {
 #define CATTA_ADDRESS_STR_MAX 40 /* IPv6 Max = 4*8 + 7 + 1 for NUL */
 
 /** Return TRUE if the specified interface index is valid */
-#define CATTA_IF_VALID(ifindex) (((ifindex) >= 0) || ((ifindex) == CATTA_IF_UNSPEC))
+#define CATTA_IF_VALID(iface) (((iface) >= 0) || ((iface) == CATTA_IF_UNSPEC))
 
 /** Return TRUE if the specified protocol is valid */
 #define CATTA_PROTO_VALID(protocol) (((protocol) == CATTA_PROTO_INET) || ((protocol) == CATTA_PROTO_INET6) || ((protocol) == CATTA_PROTO_UNSPEC))
index a2321b6a551a591bb92264a224359410c71ad720..59a72742d3219dfa03b72e8c7d0588b80c858be9 100644 (file)
@@ -55,6 +55,17 @@ CATTA_C_DECL_BEGIN
                                         *_head = _item; \
                                         } while (0)
 
+/** Append an item to the list */
+#define CATTA_LLIST_APPEND(t,name,head,item) do { \
+        t **_cur = &(head), *_prev, *_item = (item); \
+        assert(_item); \
+        while ((_prev = *_cur)) \
+            _cur = &_prev->name##_next; \
+        _item->name##_prev = _prev; \
+        _item->name##_next = NULL; \
+        *_cur = _item; \
+    } while (0)
+
 /** Remove an item from the list */
 #define CATTA_LLIST_REMOVE(t,name,head,item) do { \
                                     t **_head = &(head), *_item = (item); \
index ebdc92ab3f06fad92892ed5dd0e0f9554f7e4d0c..c6d69dbf8c72a59809411b4abab71ab9569568eb 100644 (file)
@@ -55,7 +55,7 @@ CATTA_C_DECL_BEGIN
 /** Callback prototype for CattaSRecordBrowser events */
 typedef void (*CattaSRecordBrowserCallback)(
     CattaSRecordBrowser *b,          /**< The CattaSRecordBrowser object that is emitting this callback */
-    CattaIfIndex interface,          /**< Logical OS network interface number the record was found on */
+    CattaIfIndex iface,          /**< Logical OS network interface number the record was found on */
     CattaProtocol protocol,          /**< Protocol number the record was found. */
     CattaBrowserEvent event,         /**< Browsing event, either CATTA_BROWSER_NEW or CATTA_BROWSER_REMOVE */
     CattaRecord *record,             /**< The record that was found */
@@ -65,7 +65,7 @@ typedef void (*CattaSRecordBrowserCallback)(
 /** Create a new browsing object for arbitrary RRs */
 CattaSRecordBrowser *catta_s_record_browser_new(
     CattaServer *server,                    /**< The server object to which attach this query */
-    CattaIfIndex interface,                 /**< Logical OS interface number where to look for the records, or CATTA_IF_UNSPEC to look on interfaces */
+    CattaIfIndex iface,                 /**< Logical OS interface number where to look for the records, or CATTA_IF_UNSPEC to look on interfaces */
     CattaProtocol protocol,                 /**< Protocol number to use when looking for the record, or CATTA_PROTO_UNSPEC to look on all protocols */
     CattaKey *key,                          /**< The search key */
     CattaLookupFlags flags,                 /**< Lookup flags. Must have set either CATTA_LOOKUP_FORCE_WIDE_AREA or CATTA_LOOKUP_FORCE_MULTICAST, since domain based detection is not available here. */
@@ -78,7 +78,7 @@ void catta_s_record_browser_free(CattaSRecordBrowser *b);
 /** Callback prototype for CattaSHostNameResolver events */
 typedef void (*CattaSHostNameResolverCallback)(
     CattaSHostNameResolver *r,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaResolverEvent event, /**< Resolving event */
     const char *host_name,   /**< Host name which should be resolved. May differ in case from the query */
@@ -89,7 +89,7 @@ typedef void (*CattaSHostNameResolverCallback)(
 /** Create an CattaSHostNameResolver object for resolving a host name to an adddress. See CattaSRecordBrowser for more info on the paramters. */
 CattaSHostNameResolver *catta_s_host_name_resolver_new(
     CattaServer *server,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     const char *host_name,                  /**< The host name to look for */
     CattaProtocol aprotocol,                /**< The address family of the desired address or CATTA_PROTO_UNSPEC if doesn't matter. */
@@ -103,7 +103,7 @@ void catta_s_host_name_resolver_free(CattaSHostNameResolver *r);
 /** Callback prototype for CattaSAddressResolver events */
 typedef void (*CattaSAddressResolverCallback)(
     CattaSAddressResolver *r,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaResolverEvent event,
     const CattaAddress *a,
@@ -114,7 +114,7 @@ typedef void (*CattaSAddressResolverCallback)(
 /** Create an CattaSAddressResolver object. See CattaSRecordBrowser for more info on the paramters. */
 CattaSAddressResolver *catta_s_address_resolver_new(
     CattaServer *server,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     const CattaAddress *address,
     CattaLookupFlags flags,                 /**< Lookup flags. */
@@ -127,7 +127,7 @@ void catta_s_address_resolver_free(CattaSAddressResolver *r);
 /** Callback prototype for CattaSDomainBrowser events */
 typedef void (*CattaSDomainBrowserCallback)(
     CattaSDomainBrowser *b,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaBrowserEvent event,
     const char *domain,
@@ -137,7 +137,7 @@ typedef void (*CattaSDomainBrowserCallback)(
 /** Create a new CattaSDomainBrowser object */
 CattaSDomainBrowser *catta_s_domain_browser_new(
     CattaServer *server,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     const char *domain,
     CattaDomainBrowserType type,
@@ -151,7 +151,7 @@ void catta_s_domain_browser_free(CattaSDomainBrowser *b);
 /** Callback prototype for CattaSServiceTypeBrowser events */
 typedef void (*CattaSServiceTypeBrowserCallback)(
     CattaSServiceTypeBrowser *b,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaBrowserEvent event,
     const char *type,
@@ -162,7 +162,7 @@ typedef void (*CattaSServiceTypeBrowserCallback)(
 /** Create a new CattaSServiceTypeBrowser object. */
 CattaSServiceTypeBrowser *catta_s_service_type_browser_new(
     CattaServer *server,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     const char *domain,
     CattaLookupFlags flags,                 /**< Lookup flags. */
@@ -175,7 +175,7 @@ void catta_s_service_type_browser_free(CattaSServiceTypeBrowser *b);
 /** Callback prototype for CattaSServiceBrowser events */
 typedef void (*CattaSServiceBrowserCallback)(
     CattaSServiceBrowser *b,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaBrowserEvent event,
     const char *name     /**< Service name, e.g. "Lennart's Files" */,
@@ -187,7 +187,7 @@ typedef void (*CattaSServiceBrowserCallback)(
 /** Create a new CattaSServiceBrowser object. */
 CattaSServiceBrowser *catta_s_service_browser_new(
     CattaServer *server,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     const char *service_type /** DNS-SD service type, e.g. "_http._tcp" */,
     const char *domain,
@@ -201,7 +201,7 @@ void catta_s_service_browser_free(CattaSServiceBrowser *b);
 /** Callback prototype for CattaSServiceResolver events */
 typedef void (*CattaSServiceResolverCallback)(
     CattaSServiceResolver *r,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaResolverEvent event,  /**< Is CATTA_RESOLVER_FOUND when the service was resolved successfully, and everytime it changes. Is CATTA_RESOLVER_TIMOUT when the service failed to resolve or disappeared. */
     const char *name,       /**< Service name */
@@ -217,7 +217,7 @@ typedef void (*CattaSServiceResolverCallback)(
 /** Create a new CattaSServiceResolver object. The specified callback function will be called with the resolved service data. */
 CattaSServiceResolver *catta_s_service_resolver_new(
     CattaServer *server,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     const char *name,
     const char *type,
index 1176b1fabb3166a4573c29d112c4bea9b6b62050..ac39c9642b7ae31e8c03e37f0e45491f9902960b 100644 (file)
@@ -77,7 +77,7 @@ void* catta_s_entry_group_get_data(CattaSEntryGroup *g);
 int catta_server_add(
     CattaServer *s,           /**< The server object to add this record to */
     CattaSEntryGroup *g,       /**< An entry group object if this new record shall be attached to one, or NULL. If you plan to remove the record sometime later you a required to pass an entry group object here. */
-    CattaIfIndex interface,   /**< A numeric index of a network interface to attach this record to, or CATTA_IF_UNSPEC to attach this record to all interfaces */
+    CattaIfIndex iface,   /**< A numeric index of a network interface to attach this record to, or CATTA_IF_UNSPEC to attach this record to all interfaces */
     CattaProtocol protocol,   /**< A protocol family to attach this record to. One of the CATTA_PROTO_xxx constants. Use CATTA_PROTO_UNSPEC to make this record available on all protocols (wich means on both IPv4 and IPv6). */
     CattaPublishFlags flags,    /**< Special flags for this record */
     CattaRecord *r            /**< The record to add. This function increases the reference counter of this object. */);
@@ -92,7 +92,7 @@ int catta_server_add(
 int catta_server_add_address(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     const char *name,
@@ -107,7 +107,7 @@ int catta_server_add_address(
 int catta_server_add_service(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     const char *name,         /**< Service name, e.g. "Lennart's Files" */
@@ -121,7 +121,7 @@ int catta_server_add_service(
 int catta_server_add_service_strlst(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     const char *name,
@@ -135,7 +135,7 @@ int catta_server_add_service_strlst(
 int catta_server_add_service_subtype(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     const char *name,         /**< Specify the name of main service you already added here */
@@ -147,7 +147,7 @@ int catta_server_add_service_subtype(
 int catta_server_update_service_txt_strlst(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     const char *name,
@@ -159,7 +159,7 @@ int catta_server_update_service_txt_strlst(
 int catta_server_update_service_txt(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     const char *name,
@@ -168,7 +168,7 @@ int catta_server_update_service_txt(
     ...) CATTA_GCC_SENTINEL;
 
 /** Check if there is a service locally defined and return the entry group it is attached to. Returns NULL if the service isn't local*/
-int catta_server_get_group_of_service(CattaServer *s, CattaIfIndex interface, CattaProtocol protocol, const char *name, const char *type, const char *domain, CattaSEntryGroup** ret_group);
+int catta_server_get_group_of_service(CattaServer *s, CattaIfIndex iface, CattaProtocol protocol, const char *name, const char *type, const char *domain, CattaSEntryGroup** ret_group);
 
 CATTA_C_DECL_END
 
index dcf633229216186dd50fbc21bbabacf35c3902aa..1cada4d81208178be4f2c0a7e9b4a89969b2249f 100644 (file)
@@ -256,11 +256,16 @@ if test "x$acx_pthread_ok" = xyes; then
       #
       # -Wl,-z,defs forces link-time symbol resolution, so that the
       # linking checks with -shared actually have any value
+      # The Mingw32 equivalent to -z defs seems to be --error-unresolved-symbols.
       #
       # FIXME: -fPIC is required for -shared on many architectures,
       # so we specify it here, but the right way would probably be to
       # properly detect whether it is actually required.
-      CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS"
+      zdefs="-z,defs"
+      case "${host_os}" in
+        *mingw32*) zdefs="--unresolved-symbols=report-all,--error-unresolved-symbols"
+      esac
+      CFLAGS="-shared -fPIC -Wl,$zdefs $CFLAGS $PTHREAD_CFLAGS"
       LIBS="$PTHREAD_LIBS $LIBS"
       CC="$PTHREAD_CC"
 
index 236f9517a5ae32f7ed84ee1c4a9681246818382f..3b3a058cbaa5638dc5b7accfdcb5e4b2896e97e1 100644 (file)
@@ -75,11 +75,25 @@ if HAVE_PF_ROUTE
 libcatta_la_SOURCES += \
        iface-pfroute.c iface-pfroute.h
 else
+if WINDOWS
+libcatta_la_SOURCES += \
+       iface-windows.c iface-windows.h
+else
 libcatta_la_SOURCES += \
        iface-none.c
 endif
 endif
+endif
 
 libcatta_la_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS)
-libcatta_la_LIBADD = $(AM_LDADD) $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) $(INTLLIBS)
-libcatta_la_LDFLAGS = $(AM_LDFLAGS)  -version-info $(LIBCATTA_VERSION_INFO)
+libcatta_la_LIBADD = $(AM_LDADD) $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
+libcatta_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(LIBCATTA_VERSION_INFO)
+
+if WINDOWS
+libcatta_la_SOURCES += \
+       compat/windows/wincompat.c \
+       compat/windows/wincompat.h
+libcatta_la_LIBADD += -lws2_32 -liphlpapi
+libcatta_la_LDFLAGS += -no-undefined
+endif
+
index c207fdc28445d2542d66af3546b2019524060c2d..7eced15ed523c64fbcd27c639509b5ce62016498 100644 (file)
@@ -58,7 +58,7 @@ char *catta_address_snprint(char *s, size_t length, const CattaAddress *a) {
     assert(length);
     assert(a);
 
-    if (!(inet_ntop(catta_proto_to_af(a->proto), a->data.data, s, length)))
+    if (!(inet_ntop(catta_proto_to_af(a->proto), (void *)a->data.data, s, length)))
         return NULL;
 
     return s;
index 06e96e7c9413e74e191c621958b8167ab6ff02d8..e2b0757f38ca5c453f117b43b94c353fe5c1f7b4 100644 (file)
@@ -41,7 +41,7 @@ static void remove_announcer(CattaServer *s, CattaAnnouncer *a) {
     if (a->time_event)
         catta_time_event_free(a->time_event);
 
-    CATTA_LLIST_REMOVE(CattaAnnouncer, by_interface, a->interface->announcers, a);
+    CATTA_LLIST_REMOVE(CattaAnnouncer, by_interface, a->iface->announcers, a);
     CATTA_LLIST_REMOVE(CattaAnnouncer, by_entry, a->entry->announcers, a);
 
     catta_free(a);
@@ -139,7 +139,7 @@ static void next_state(CattaAnnouncer *a) {
         } else {
             struct timeval tv;
 
-            catta_interface_post_probe(a->interface, a->entry->record, 0);
+            catta_interface_post_probe(a->iface, a->entry->record, 0);
 
             catta_elapse_time(&tv, CATTA_PROBE_INTERVAL_MSEC, 0);
             set_timeout(a, &tv);
@@ -151,11 +151,11 @@ static void next_state(CattaAnnouncer *a) {
 
         if (a->entry->flags & CATTA_PUBLISH_UNIQUE)
             /* Send the whole rrset at once */
-            catta_server_prepare_matching_responses(a->server, a->interface, a->entry->record->key, 0);
+            catta_server_prepare_matching_responses(a->server, a->iface, a->entry->record->key, 0);
         else
-            catta_server_prepare_response(a->server, a->interface, a->entry, 0, 0);
+            catta_server_prepare_response(a->server, a->iface, a->entry, 0, 0);
 
-        catta_server_generate_response(a->server, a->interface, NULL, NULL, 0, 0, 0);
+        catta_server_generate_response(a->server, a->iface, NULL, NULL, 0, 0, 0);
 
         if (++a->n_iteration >= 4) {
             /* Announcing done */
@@ -189,7 +189,7 @@ static CattaAnnouncer *get_announcer(CattaServer *s, CattaEntry *e, CattaInterfa
     assert(i);
 
     for (a = e->announcers; a; a = a->by_entry_next)
-        if (a->interface == i)
+        if (a->iface == i)
             return a;
 
     return NULL;
@@ -236,7 +236,7 @@ static void new_announcer(CattaServer *s, CattaInterface *i, CattaEntry *e) {
     assert(e);
     assert(!e->dead);
 
-    if (!catta_interface_match(i, e->interface, e->protocol) || !i->announcing || !catta_entry_is_commited(e))
+    if (!catta_interface_match(i, e->iface, e->protocol) || !i->announcing || !catta_entry_is_commited(e))
         return;
 
     /* We don't want duplicate announcers */
@@ -249,7 +249,7 @@ static void new_announcer(CattaServer *s, CattaInterface *i, CattaEntry *e) {
     }
 
     a->server = s;
-    a->interface = i;
+    a->iface = i;
     a->entry = e;
     a->time_event = NULL;
 
@@ -289,7 +289,7 @@ void catta_announce_entry(CattaServer *s, CattaEntry *e) {
     assert(e);
     assert(!e->dead);
 
-    catta_interface_monitor_walk(s->monitor, e->interface, e->protocol, announce_walk_callback, e);
+    catta_interface_monitor_walk(s->monitor, e->iface, e->protocol, announce_walk_callback, e);
 }
 
 void catta_announce_group(CattaServer *s, CattaSEntryGroup *g) {
@@ -395,7 +395,7 @@ static void send_goodbye_callback(CattaInterfaceMonitor *m, CattaInterface *i, v
     assert(e);
     assert(!e->dead);
 
-    if (!catta_interface_match(i, e->interface, e->protocol))
+    if (!catta_interface_match(i, e->iface, e->protocol))
         return;
 
     if (e->flags & CATTA_PUBLISH_NO_ANNOUNCE)
@@ -488,7 +488,7 @@ void catta_reannounce_entry(CattaServer *s, CattaEntry *e) {
     assert(e);
     assert(!e->dead);
 
-    catta_interface_monitor_walk(s->monitor, e->interface, e->protocol, reannounce_walk_callback, e);
+    catta_interface_monitor_walk(s->monitor, e->iface, e->protocol, reannounce_walk_callback, e);
 }
 
 void catta_goodbye_interface(CattaServer *s, CattaInterface *i, int send_goodbye, int remove) {
index e8e62dc87f0b6a2eabf50b2e3913eaf058c0e2ae..3a2a4005810f60715c5f9f682ebab8fc873d0567 100644 (file)
@@ -37,7 +37,7 @@ typedef enum {
 
 struct CattaAnnouncer {
     CattaServer *server;
-    CattaInterface *interface;
+    CattaInterface *iface;
     CattaEntry *entry;
 
     CattaTimeEvent *time_event;
index 640ec517d6e4b1a6a93227686a1ea0e4b611101d..12b529f99d706c76a7ec287625200871fa94a1ed 100644 (file)
@@ -36,7 +36,7 @@ typedef struct CattaDNSServerInfo CattaDNSServerInfo;
 struct CattaDNSServerInfo {
     CattaSDNSServerBrowser *browser;
 
-    CattaIfIndex interface;
+    CattaIfIndex iface;
     CattaProtocol protocol;
     CattaRecord *srv_record;
     CattaSHostNameResolver *host_name_resolver;
@@ -61,14 +61,14 @@ struct CattaSDNSServerBrowser {
     CATTA_LLIST_HEAD(CattaDNSServerInfo, info);
 };
 
-static CattaDNSServerInfo* get_server_info(CattaSDNSServerBrowser *b, CattaIfIndex interface, CattaProtocol protocol, CattaRecord *r) {
+static CattaDNSServerInfo* get_server_info(CattaSDNSServerBrowser *b, CattaIfIndex iface, CattaProtocol protocol, CattaRecord *r) {
     CattaDNSServerInfo *i;
 
     assert(b);
     assert(r);
 
     for (i = b->info; i; i = i->info_next)
-        if (i->interface == interface &&
+        if (i->iface == iface &&
             i->protocol == protocol &&
             catta_record_equal_no_ttl(r, i->srv_record))
             return i;
@@ -94,7 +94,7 @@ static void server_info_free(CattaSDNSServerBrowser *b, CattaDNSServerInfo *i) {
 
 static void host_name_resolver_callback(
     CattaSHostNameResolver *r,
-    CATTA_GCC_UNUSED CattaIfIndex interface,
+    CATTA_GCC_UNUSED CattaIfIndex iface,
     CATTA_GCC_UNUSED CattaProtocol protocol,
     CattaResolverEvent event,
     const char *host_name,
@@ -114,7 +114,7 @@ static void host_name_resolver_callback(
 
             i->browser->callback(
                 i->browser,
-                i->interface,
+                i->iface,
                 i->protocol,
                 CATTA_BROWSER_NEW,
                 i->srv_record->data.srv.name,
@@ -137,7 +137,7 @@ static void host_name_resolver_callback(
 
 static void record_browser_callback(
     CattaSRecordBrowser*rr,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaBrowserEvent event,
     CattaRecord *record,
@@ -159,7 +159,7 @@ static void record_browser_callback(
             assert(record);
             assert(record->key->type == CATTA_DNS_TYPE_SRV);
 
-            if (get_server_info(b, interface, protocol, record))
+            if (get_server_info(b, iface, protocol, record))
                 return;
 
             if (b->n_info >= 10)
@@ -169,12 +169,12 @@ static void record_browser_callback(
                 return; /* OOM */
 
             i->browser = b;
-            i->interface = interface;
+            i->iface = iface;
             i->protocol = protocol;
             i->srv_record = catta_record_ref(record);
             i->host_name_resolver = catta_s_host_name_resolver_new(
                 b->server,
-                interface, protocol,
+                iface, protocol,
                 record->data.srv.name,
                 b->aprotocol,
                 b->user_flags,
@@ -193,13 +193,13 @@ static void record_browser_callback(
             assert(record);
             assert(record->key->type == CATTA_DNS_TYPE_SRV);
 
-            if (!(i = get_server_info(b, interface, protocol, record)))
+            if (!(i = get_server_info(b, iface, protocol, record)))
                 return;
 
             if (!i->host_name_resolver)
                 b->callback(
                     b,
-                    interface,
+                    iface,
                     protocol,
                     event,
                     i->srv_record->data.srv.name,
@@ -218,7 +218,7 @@ static void record_browser_callback(
 
             b->callback(
                 b,
-                interface,
+                iface,
                 protocol,
                 event,
                 NULL,
@@ -233,7 +233,7 @@ static void record_browser_callback(
 
 CattaSDNSServerBrowser *catta_s_dns_server_browser_new(
     CattaServer *server,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     const char *domain,
     CattaDNSServerType type,
@@ -255,7 +255,7 @@ CattaSDNSServerBrowser *catta_s_dns_server_browser_new(
     assert(server);
     assert(callback);
 
-    CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_IF_VALID(interface), CATTA_ERR_INVALID_INTERFACE);
+    CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_IF_VALID(iface), CATTA_ERR_INVALID_INTERFACE);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_PROTO_VALID(protocol), CATTA_ERR_INVALID_PROTOCOL);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_PROTO_VALID(aprotocol), CATTA_ERR_INVALID_PROTOCOL);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, !domain || catta_is_valid_domain_name(domain), CATTA_ERR_INVALID_DOMAIN_NAME);
@@ -290,7 +290,7 @@ CattaSDNSServerBrowser *catta_s_dns_server_browser_new(
         goto fail;
     }
 
-    if (!(b->record_browser = catta_s_record_browser_new(server, interface, protocol, k, flags, record_browser_callback, b)))
+    if (!(b->record_browser = catta_s_record_browser_new(server, iface, protocol, k, flags, record_browser_callback, b)))
         goto fail;
 
     catta_key_unref(k);
index 8ae99e49383c8bd14b9d5bee4754445fdac58b50..691cfba2c44d9367c47a4cfb44fe85a676162a80 100644 (file)
@@ -57,7 +57,7 @@ static void inc_ref(CattaSDomainBrowser *b) {
 
 static void record_browser_callback(
     CattaSRecordBrowser*rr,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaBrowserEvent event,
     CattaRecord *record,
@@ -96,7 +96,7 @@ static void record_browser_callback(
 
     }
 
-    b->callback(b, interface, protocol, event, n, flags, b->userdata);
+    b->callback(b, iface, protocol, event, n, flags, b->userdata);
 }
 
 static void defer_callback(CattaTimeEvent *e, void *userdata) {
@@ -137,7 +137,7 @@ static void defer_callback(CattaTimeEvent *e, void *userdata) {
 
 CattaSDomainBrowser *catta_s_domain_browser_new(
     CattaServer *server,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     const char *domain,
     CattaDomainBrowserType type,
@@ -161,7 +161,7 @@ CattaSDomainBrowser *catta_s_domain_browser_new(
     assert(server);
     assert(callback);
 
-    CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_IF_VALID(interface), CATTA_ERR_INVALID_INTERFACE);
+    CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_IF_VALID(iface), CATTA_ERR_INVALID_INTERFACE);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_PROTO_VALID(protocol), CATTA_ERR_INVALID_PROTOCOL);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, type < CATTA_DOMAIN_BROWSER_MAX, CATTA_ERR_INVALID_FLAGS);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, !domain || catta_is_valid_domain_name(domain), CATTA_ERR_INVALID_DOMAIN_NAME);
@@ -196,7 +196,7 @@ CattaSDomainBrowser *catta_s_domain_browser_new(
         goto fail;
     }
 
-    if (!(b->record_browser = catta_s_record_browser_new(server, interface, protocol, k, flags, record_browser_callback, b)))
+    if (!(b->record_browser = catta_s_record_browser_new(server, iface, protocol, k, flags, record_browser_callback, b)))
         goto fail;
 
     catta_key_unref(k);
index 4d40a82afda4f4f794ef34b9d9d39599fc1b5130..41c171e19f5fdbbaf7d867b840aa25a085b09128 100644 (file)
@@ -44,7 +44,7 @@ struct CattaSServiceTypeBrowser {
 
 static void record_browser_callback(
     CattaSRecordBrowser*rr,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaBrowserEvent event,
     CattaRecord *record,
@@ -69,14 +69,14 @@ static void record_browser_callback(
             return;
         }
 
-        b->callback(b, interface, protocol, event, type, domain, flags, b->userdata);
+        b->callback(b, iface, protocol, event, type, domain, flags, b->userdata);
     } else
-        b->callback(b, interface, protocol, event, NULL, b->domain_name, flags, b->userdata);
+        b->callback(b, iface, protocol, event, NULL, b->domain_name, flags, b->userdata);
 }
 
 CattaSServiceTypeBrowser *catta_s_service_type_browser_new(
     CattaServer *server,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     const char *domain,
     CattaLookupFlags flags,
@@ -91,7 +91,7 @@ CattaSServiceTypeBrowser *catta_s_service_type_browser_new(
     assert(server);
     assert(callback);
 
-    CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_IF_VALID(interface), CATTA_ERR_INVALID_INTERFACE);
+    CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_IF_VALID(iface), CATTA_ERR_INVALID_INTERFACE);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_PROTO_VALID(protocol), CATTA_ERR_INVALID_PROTOCOL);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, !domain || catta_is_valid_domain_name(domain), CATTA_ERR_INVALID_DOMAIN_NAME);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_FLAGS_VALID(flags, CATTA_LOOKUP_USE_WIDE_AREA|CATTA_LOOKUP_USE_MULTICAST), CATTA_ERR_INVALID_FLAGS);
@@ -126,7 +126,7 @@ CattaSServiceTypeBrowser *catta_s_service_type_browser_new(
         goto fail;
     }
 
-    if (!(b->record_browser = catta_s_record_browser_new(server, interface, protocol, k, flags, record_browser_callback, b)))
+    if (!(b->record_browser = catta_s_record_browser_new(server, iface, protocol, k, flags, record_browser_callback, b)))
         goto fail;
 
     catta_key_unref(k);
index 4a4c8df618387915cc6928e1a25955752d659d07..3b09695c98860f06772939f06c9430053e1faf96 100644 (file)
@@ -45,7 +45,7 @@ struct CattaSServiceBrowser {
 
 static void record_browser_callback(
     CattaSRecordBrowser*rr,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaBrowserEvent event,
     CattaRecord *record,
@@ -65,7 +65,7 @@ static void record_browser_callback(
 
         assert(record->key->type == CATTA_DNS_TYPE_PTR);
 
-        if (event == CATTA_BROWSER_NEW && catta_server_is_service_local(b->server, interface, protocol, record->data.ptr.name))
+        if (event == CATTA_BROWSER_NEW && catta_server_is_service_local(b->server, iface, protocol, record->data.ptr.name))
             flags |= CATTA_LOOKUP_RESULT_LOCAL;
 
         if (catta_service_name_split(record->data.ptr.name, service, sizeof(service), type, sizeof(type), domain, sizeof(domain)) < 0) {
@@ -73,16 +73,16 @@ static void record_browser_callback(
             return;
         }
 
-        b->callback(b, interface, protocol, event, service, type, domain, flags, b->userdata);
+        b->callback(b, iface, protocol, event, service, type, domain, flags, b->userdata);
 
     } else
-        b->callback(b, interface, protocol, event, NULL, b->service_type, b->domain_name, flags, b->userdata);
+        b->callback(b, iface, protocol, event, NULL, b->service_type, b->domain_name, flags, b->userdata);
 
 }
 
 CattaSServiceBrowser *catta_s_service_browser_new(
     CattaServer *server,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     const char *service_type,
     const char *domain,
@@ -99,7 +99,7 @@ CattaSServiceBrowser *catta_s_service_browser_new(
     assert(callback);
     assert(service_type);
 
-    CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_IF_VALID(interface), CATTA_ERR_INVALID_INTERFACE);
+    CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_IF_VALID(iface), CATTA_ERR_INVALID_INTERFACE);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_PROTO_VALID(protocol), CATTA_ERR_INVALID_PROTOCOL);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, !domain || catta_is_valid_domain_name(domain), CATTA_ERR_INVALID_DOMAIN_NAME);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_FLAGS_VALID(flags, CATTA_LOOKUP_USE_WIDE_AREA|CATTA_LOOKUP_USE_MULTICAST), CATTA_ERR_INVALID_FLAGS);
@@ -137,7 +137,7 @@ CattaSServiceBrowser *catta_s_service_browser_new(
         goto fail;
     }
 
-    if (!(b->record_browser = catta_s_record_browser_new(server, interface, protocol, k, flags, record_browser_callback, b)))
+    if (!(b->record_browser = catta_s_record_browser_new(server, iface, protocol, k, flags, record_browser_callback, b)))
         goto fail;
 
     catta_key_unref(k);
index 0324499767cc8907284b1775b633cd8e7cf2c259..d8f70e6a9ff492af4550003388b2c4cca857e89b 100644 (file)
@@ -43,7 +43,7 @@ struct CattaSRBLookup {
 
     unsigned ref;
 
-    CattaIfIndex interface;
+    CattaIfIndex iface;
     CattaProtocol protocol;
     CattaLookupFlags flags;
 
@@ -57,8 +57,8 @@ struct CattaSRBLookup {
     CATTA_LLIST_FIELDS(CattaSRBLookup, lookups);
 };
 
-static void lookup_handle_cname(CattaSRBLookup *l, CattaIfIndex interface, CattaProtocol protocol, CattaLookupFlags flags, CattaRecord *r);
-static void lookup_drop_cname(CattaSRBLookup *l, CattaIfIndex interface, CattaProtocol protocol, CattaLookupFlags flags, CattaRecord *r);
+static void lookup_handle_cname(CattaSRBLookup *l, CattaIfIndex iface, CattaProtocol protocol, CattaLookupFlags flags, CattaRecord *r);
+static void lookup_drop_cname(CattaSRBLookup *l, CattaIfIndex iface, CattaProtocol protocol, CattaLookupFlags flags, CattaRecord *r);
 
 static void transport_flags_from_domain(CattaServer *s, CattaLookupFlags *flags, const char *domain) {
     assert(flags);
@@ -81,7 +81,7 @@ static void transport_flags_from_domain(CattaServer *s, CattaLookupFlags *flags,
 
 static CattaSRBLookup* lookup_new(
     CattaSRecordBrowser *b,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaLookupFlags flags,
     CattaKey *key) {
@@ -89,7 +89,7 @@ static CattaSRBLookup* lookup_new(
     CattaSRBLookup *l;
 
     assert(b);
-    assert(CATTA_IF_VALID(interface));
+    assert(CATTA_IF_VALID(iface));
     assert(CATTA_PROTO_VALID(protocol));
 
     if (b->n_lookups >= CATTA_LOOKUPS_PER_BROWSER_MAX)
@@ -101,7 +101,7 @@ static CattaSRBLookup* lookup_new(
 
     l->ref = 1;
     l->record_browser = b;
-    l->interface = interface;
+    l->iface = iface;
     l->protocol = protocol;
     l->key = catta_key_ref(key);
     l->wide_area = NULL;
@@ -157,7 +157,7 @@ static CattaSRBLookup* lookup_ref(CattaSRBLookup *l) {
 
 static CattaSRBLookup *lookup_find(
     CattaSRecordBrowser *b,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaLookupFlags flags,
     CattaKey *key) {
@@ -168,8 +168,8 @@ static CattaSRBLookup *lookup_find(
 
     for (l = b->lookups; l; l = l->lookups_next) {
 
-        if ((l->interface == CATTA_IF_UNSPEC || l->interface == interface) &&
-            (l->interface == CATTA_PROTO_UNSPEC || l->protocol == protocol) &&
+        if ((l->iface == CATTA_IF_UNSPEC || l->iface == iface) &&
+            (l->iface == CATTA_PROTO_UNSPEC || l->protocol == protocol) &&
             l->flags == flags &&
             catta_key_equal(l->key, key))
 
@@ -248,7 +248,7 @@ static void lookup_wide_area_callback(
 
 static void lookup_multicast_callback(
     CattaMulticastLookupEngine *e,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaBrowserEvent event,
     CattaLookupResultFlags flags,
@@ -275,14 +275,14 @@ static void lookup_multicast_callback(
             if (r->key->clazz == CATTA_DNS_CLASS_IN &&
                 r->key->type == CATTA_DNS_TYPE_CNAME)
                 /* It's a CNAME record, so let's follow it. We allow browsing on both multicast and wide area. */
-                lookup_handle_cname(l, interface, protocol, b->flags, r);
+                lookup_handle_cname(l, iface, protocol, b->flags, r);
             else {
                 /* It's a normal record, so let's call the user callback */
 
-                if (catta_server_is_record_local(b->server, interface, protocol, r))
+                if (catta_server_is_record_local(b->server, iface, protocol, r))
                     flags |= CATTA_LOOKUP_RESULT_LOCAL;
 
-                b->callback(b, interface, protocol, event, r, flags, b->userdata);
+                b->callback(b, iface, protocol, event, r, flags, b->userdata);
             }
             break;
 
@@ -292,12 +292,12 @@ static void lookup_multicast_callback(
             if (r->key->clazz == CATTA_DNS_CLASS_IN &&
                 r->key->type == CATTA_DNS_TYPE_CNAME)
                 /* It's a CNAME record, so let's drop that query! */
-                lookup_drop_cname(l, interface, protocol, 0, r);
+                lookup_drop_cname(l, iface, protocol, 0, r);
             else {
                 /* It's a normal record, so let's call the user callback */
                 assert(catta_key_equal(b->key, l->key));
 
-                b->callback(b, interface, protocol, event, r, flags, b->userdata);
+                b->callback(b, iface, protocol, event, r, flags, b->userdata);
             }
             break;
 
@@ -330,7 +330,7 @@ static int lookup_start(CattaSRBLookup *l) {
     } else {
         assert(l->flags & CATTA_LOOKUP_USE_MULTICAST);
 
-        if (!(l->multicast = catta_multicast_lookup_new(l->record_browser->server->multicast_lookup_engine, l->interface, l->protocol, l->key, lookup_multicast_callback, l)))
+        if (!(l->multicast = catta_multicast_lookup_new(l->record_browser->server->multicast_lookup_engine, l->iface, l->protocol, l->key, lookup_multicast_callback, l)))
             return -1;
     }
 
@@ -350,22 +350,22 @@ static int lookup_scan_cache(CattaSRBLookup *l) {
 
     } else {
         assert(l->flags & CATTA_LOOKUP_USE_MULTICAST);
-        n = (int) catta_multicast_lookup_engine_scan_cache(l->record_browser->server->multicast_lookup_engine, l->interface, l->protocol, l->key, lookup_multicast_callback, l);
+        n = (int) catta_multicast_lookup_engine_scan_cache(l->record_browser->server->multicast_lookup_engine, l->iface, l->protocol, l->key, lookup_multicast_callback, l);
     }
 
     return n;
 }
 
-static CattaSRBLookup* lookup_add(CattaSRecordBrowser *b, CattaIfIndex interface, CattaProtocol protocol, CattaLookupFlags flags, CattaKey *key) {
+static CattaSRBLookup* lookup_add(CattaSRecordBrowser *b, CattaIfIndex iface, CattaProtocol protocol, CattaLookupFlags flags, CattaKey *key) {
     CattaSRBLookup *l;
 
     assert(b);
     assert(!b->dead);
 
-    if ((l = lookup_find(b, interface, protocol, flags, key)))
+    if ((l = lookup_find(b, iface, protocol, flags, key)))
         return lookup_ref(l);
 
-    if (!(l = lookup_new(b, interface, protocol, flags, key)))
+    if (!(l = lookup_new(b, iface, protocol, flags, key)))
         return NULL;
 
     return l;
@@ -398,7 +398,7 @@ static int lookup_go(CattaSRBLookup *l) {
     return n;
 }
 
-static void lookup_handle_cname(CattaSRBLookup *l, CattaIfIndex interface, CattaProtocol protocol, CattaLookupFlags flags, CattaRecord *r) {
+static void lookup_handle_cname(CattaSRBLookup *l, CattaIfIndex iface, CattaProtocol protocol, CattaLookupFlags flags, CattaRecord *r) {
     CattaKey *k;
     CattaSRBLookup *n;
 
@@ -409,7 +409,7 @@ static void lookup_handle_cname(CattaSRBLookup *l, CattaIfIndex interface, Catta
     assert(r->key->type == CATTA_DNS_TYPE_CNAME);
 
     k = catta_key_new(r->data.ptr.name, l->record_browser->key->clazz, l->record_browser->key->type);
-    n = lookup_add(l->record_browser, interface, protocol, flags, k);
+    n = lookup_add(l->record_browser, iface, protocol, flags, k);
     catta_key_unref(k);
 
     if (!n) {
@@ -423,7 +423,7 @@ static void lookup_handle_cname(CattaSRBLookup *l, CattaIfIndex interface, Catta
     lookup_unref(n);
 }
 
-static void lookup_drop_cname(CattaSRBLookup *l, CattaIfIndex interface, CattaProtocol protocol, CattaLookupFlags flags, CattaRecord *r) {
+static void lookup_drop_cname(CattaSRBLookup *l, CattaIfIndex iface, CattaProtocol protocol, CattaLookupFlags flags, CattaRecord *r) {
     CattaKey *k;
     CattaSRBLookup *n = NULL;
     CattaRList *rl;
@@ -438,8 +438,8 @@ static void lookup_drop_cname(CattaSRBLookup *l, CattaIfIndex interface, CattaPr
 
         assert(n);
 
-        if ((n->interface == CATTA_IF_UNSPEC || n->interface == interface) &&
-            (n->interface == CATTA_PROTO_UNSPEC || n->protocol == protocol) &&
+        if ((n->iface == CATTA_IF_UNSPEC || n->iface == iface) &&
+            (n->iface == CATTA_PROTO_UNSPEC || n->protocol == protocol) &&
             n->flags == flags &&
             catta_key_equal(n->key, k))
             break;
@@ -468,7 +468,7 @@ static void defer_callback(CATTA_GCC_UNUSED CattaTimeEvent *e, void *userdata) {
 
     /* Create initial query */
     assert(!b->root_lookup);
-    b->root_lookup = lookup_add(b, b->interface, b->protocol, b->flags, b->key);
+    b->root_lookup = lookup_add(b, b->iface, b->protocol, b->flags, b->key);
     assert(b->root_lookup);
 
     n = lookup_go(b->root_lookup);
@@ -482,7 +482,7 @@ static void defer_callback(CATTA_GCC_UNUSED CattaTimeEvent *e, void *userdata) {
         catta_server_set_errno(b->server, CATTA_ERR_FAILURE);
 
         b->callback(
-            b, b->interface, b->protocol, CATTA_BROWSER_FAILURE, NULL,
+            b, b->iface, b->protocol, CATTA_BROWSER_FAILURE, NULL,
             b->flags & CATTA_LOOKUP_USE_WIDE_AREA ? CATTA_LOOKUP_RESULT_WIDE_AREA : CATTA_LOOKUP_RESULT_MULTICAST,
             b->userdata);
 
@@ -492,7 +492,7 @@ static void defer_callback(CATTA_GCC_UNUSED CattaTimeEvent *e, void *userdata) {
 
     /* Tell the client that we're done with the cache */
     b->callback(
-        b, b->interface, b->protocol, CATTA_BROWSER_CACHE_EXHAUSTED, NULL,
+        b, b->iface, b->protocol, CATTA_BROWSER_CACHE_EXHAUSTED, NULL,
         b->flags & CATTA_LOOKUP_USE_WIDE_AREA ? CATTA_LOOKUP_RESULT_WIDE_AREA : CATTA_LOOKUP_RESULT_MULTICAST,
         b->userdata);
 
@@ -502,7 +502,7 @@ static void defer_callback(CATTA_GCC_UNUSED CattaTimeEvent *e, void *userdata) {
          * entries, we assume that it is complete, and tell the user
          * so by firing ALL_FOR_NOW. */
 
-        b->callback(b, b->interface, b->protocol, CATTA_BROWSER_ALL_FOR_NOW, NULL, CATTA_LOOKUP_RESULT_WIDE_AREA, b->userdata);
+        b->callback(b, b->iface, b->protocol, CATTA_BROWSER_ALL_FOR_NOW, NULL, CATTA_LOOKUP_RESULT_WIDE_AREA, b->userdata);
     }
 }
 
@@ -521,7 +521,7 @@ void catta_s_record_browser_restart(CattaSRecordBrowser *b) {
 
 CattaSRecordBrowser *catta_s_record_browser_new(
     CattaServer *server,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaKey *key,
     CattaLookupFlags flags,
@@ -534,7 +534,7 @@ CattaSRecordBrowser *catta_s_record_browser_new(
     assert(key);
     assert(callback);
 
-    CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_IF_VALID(interface), CATTA_ERR_INVALID_INTERFACE);
+    CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_IF_VALID(iface), CATTA_ERR_INVALID_INTERFACE);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_PROTO_VALID(protocol), CATTA_ERR_INVALID_PROTOCOL);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, !catta_key_is_pattern(key), CATTA_ERR_IS_PATTERN);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, catta_key_is_valid(key), CATTA_ERR_INVALID_KEY);
@@ -548,7 +548,7 @@ CattaSRecordBrowser *catta_s_record_browser_new(
 
     b->dead = 0;
     b->server = server;
-    b->interface = interface;
+    b->iface = iface;
     b->protocol = protocol;
     b->key = catta_key_ref(key);
     b->flags = flags;
index 76b7a6d545b01340aff8ea5314cab14c4f2438ab..1fccf2369135cf6773b2026551a2e5a50b944b0a 100644 (file)
@@ -36,7 +36,7 @@ struct CattaSRecordBrowser {
     CattaServer *server;
 
     CattaKey *key;
-    CattaIfIndex interface;
+    CattaIfIndex iface;
     CattaProtocol protocol;
     CattaLookupFlags flags;
 
index f4203ebffe8efed0dec35a1f6e526345b3b4ee78..de7b369b5f3e69b3ca03af9cda59cf16ca317262 100644 (file)
@@ -54,7 +54,7 @@ static void remove_entry(CattaCache *c, CattaCacheEntry *e) {
     if (e->time_event)
         catta_time_event_free(e->time_event);
 
-    catta_multicast_lookup_engine_notify(c->server->multicast_lookup_engine, c->interface, e->record, CATTA_BROWSER_REMOVE);
+    catta_multicast_lookup_engine_notify(c->server->multicast_lookup_engine, c->iface, e->record, CATTA_BROWSER_REMOVE);
 
     catta_record_unref(e->record);
 
@@ -74,7 +74,7 @@ CattaCache *catta_cache_new(CattaServer *server, CattaInterface *iface) {
     }
 
     c->server = server;
-    c->interface = iface;
+    c->iface = iface;
 
     if (!(c->hashmap = catta_hashmap_new((CattaHashFunc) catta_key_hash, (CattaEqualFunc) catta_key_equal, NULL, NULL))) {
         catta_log_error(__FILE__": Out of memory.");
@@ -212,8 +212,8 @@ static void elapse_func(CattaTimeEvent *t, void *userdata) {
         assert(percent > 0);
 
         /* Request a cache update if we are subscribed to this entry */
-        if (catta_querier_shall_refresh_cache(e->cache->interface, e->record->key))
-            catta_interface_post_query(e->cache->interface, e->record->key, 0, NULL);
+        if (catta_querier_shall_refresh_cache(e->cache->iface, e->record->key))
+            catta_interface_post_query(e->cache->iface, e->record->key, 0, NULL);
 
         /* Check again later */
         next_expiry(e->cache, e, percent);
@@ -360,7 +360,7 @@ void catta_cache_update(CattaCache *c, CattaRecord *r, int cache_flush, const Ca
             c->n_entries++;
 
             /* Notify subscribers */
-            catta_multicast_lookup_engine_notify(c->server->multicast_lookup_engine, c->interface, e->record, CATTA_BROWSER_NEW);
+            catta_multicast_lookup_engine_notify(c->server->multicast_lookup_engine, c->iface, e->record, CATTA_BROWSER_NEW);
         }
 
         e->origin = *a;
index a205b705d44f75d7d2916ddd8dae6dbacadb3f0c..c3741e1a90bb39b066260095c195cdb2ed7b16da 100644 (file)
@@ -65,7 +65,7 @@ struct CattaCacheEntry {
 struct CattaCache {
     CattaServer *server;
 
-    CattaInterface *interface;
+    CattaInterface *iface;
 
     CattaHashmap *hashmap;
 
@@ -77,7 +77,7 @@ struct CattaCache {
     time_t last_rand_timestamp;
 };
 
-CattaCache *catta_cache_new(CattaServer *server, CattaInterface *interface);
+CattaCache *catta_cache_new(CattaServer *server, CattaInterface *iface);
 void catta_cache_free(CattaCache *c);
 
 void catta_cache_update(CattaCache *c, CattaRecord *r, int cache_flush, const CattaAddress *a);
diff --git a/src/compat/windows/include/arpa/inet.h b/src/compat/windows/include/arpa/inet.h
new file mode 100644 (file)
index 0000000..cc77ee8
--- /dev/null
@@ -0,0 +1 @@
+#include "../../wincompat.h"
diff --git a/src/compat/windows/include/net/if.h b/src/compat/windows/include/net/if.h
new file mode 100644 (file)
index 0000000..cc77ee8
--- /dev/null
@@ -0,0 +1 @@
+#include "../../wincompat.h"
diff --git a/src/compat/windows/include/netinet/in.h b/src/compat/windows/include/netinet/in.h
new file mode 100644 (file)
index 0000000..cc77ee8
--- /dev/null
@@ -0,0 +1 @@
+#include "../../wincompat.h"
diff --git a/src/compat/windows/include/sys/ioctl.h b/src/compat/windows/include/sys/ioctl.h
new file mode 100644 (file)
index 0000000..cc77ee8
--- /dev/null
@@ -0,0 +1 @@
+#include "../../wincompat.h"
diff --git a/src/compat/windows/include/sys/poll.h b/src/compat/windows/include/sys/poll.h
new file mode 100644 (file)
index 0000000..cc77ee8
--- /dev/null
@@ -0,0 +1 @@
+#include "../../wincompat.h"
diff --git a/src/compat/windows/include/sys/select.h b/src/compat/windows/include/sys/select.h
new file mode 100644 (file)
index 0000000..cc77ee8
--- /dev/null
@@ -0,0 +1 @@
+#include "../../wincompat.h"
diff --git a/src/compat/windows/include/sys/socket.h b/src/compat/windows/include/sys/socket.h
new file mode 100644 (file)
index 0000000..cc77ee8
--- /dev/null
@@ -0,0 +1 @@
+#include "../../wincompat.h"
diff --git a/src/compat/windows/include/sys/uio.h b/src/compat/windows/include/sys/uio.h
new file mode 100644 (file)
index 0000000..cc77ee8
--- /dev/null
@@ -0,0 +1 @@
+#include "../../wincompat.h"
diff --git a/src/compat/windows/include/sys/utsname.h b/src/compat/windows/include/sys/utsname.h
new file mode 100644 (file)
index 0000000..cc77ee8
--- /dev/null
@@ -0,0 +1 @@
+#include "../../wincompat.h"
diff --git a/src/compat/windows/wincompat.c b/src/compat/windows/wincompat.c
new file mode 100644 (file)
index 0000000..d56e0a6
--- /dev/null
@@ -0,0 +1,314 @@
+#include "wincompat.h"
+#include <errno.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <stdint.h>
+
+#include <catta/log.h>
+
+// helper: convert WSAGetLastError() to an errno constant
+static int wsa_errno(void)
+{
+    switch(WSAGetLastError()) {
+        case WSAEACCES:         return EACCES;
+        case WSAECONNRESET:     return ECONNRESET;
+        case WSAEFAULT:         return EFAULT;
+        case WSAEINPROGRESS:    return EINPROGRESS;
+        case WSAEINTR:          return EINTR;
+        case WSAEINVAL:         return EINVAL;
+        case WSAEMSGSIZE:       return EMSGSIZE;
+        case WSAENETDOWN:       return ENETDOWN;
+        case WSAENETRESET:      return ENETRESET;
+        case WSAENOBUFS:        return ENOBUFS;
+        case WSAENOTCONN:       return ENOTCONN;
+        case WSAENOTSOCK:       return ENOTSOCK;
+        case WSAEOPNOTSUPP:     return EOPNOTSUPP;
+        case WSAESHUTDOWN:      return ESHUTDOWN;
+        case WSAETIMEDOUT:      return ETIMEDOUT;
+        case WSAEWOULDBLOCK:    return EWOULDBLOCK;
+        default:
+            return EINVAL;
+    }
+}
+
+void winsock_init(void)
+{
+    WSADATA wsa;
+    int error;
+
+    if((error = WSAStartup(MAKEWORD(2,2), &wsa)) != 0)
+        catta_log_error("WSAStartup() failed: %d", error);
+}
+
+void winsock_exit(void)
+{
+    if(WSACleanup() == SOCKET_ERROR)
+        catta_log_warn("WSACleanup() failed: %d", WSAGetLastError());
+}
+
+char *errnostrsocket(void)
+{
+    static char buf[256];
+
+    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+                  NULL, WSAGetLastError(), 0, buf, sizeof(buf), NULL);
+
+    return buf;
+}
+
+ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
+{
+    LPFN_WSARECVMSG WSARecvMsg = NULL;
+    GUID wsaid = WSAID_WSARECVMSG;
+    DWORD b;
+
+    DWORD bytesrcvd;
+    WSAMSG wsamsg;
+    size_t i;
+    int r;
+
+    // size_t is larger than DWORD on 64bit
+    if(msg->msg_iovlen > UINT32_MAX) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    // obtain the function pointer to WSARecvMsg
+    r = WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER,
+                 &wsaid, sizeof(wsaid), &WSARecvMsg, sizeof(WSARecvMsg),
+                 &b, NULL, NULL);
+    if(r == SOCKET_ERROR) {
+        errno = wsa_errno();
+        return -1;
+    }
+    assert(b == sizeof(WSARecvMsg));
+    assert(WSARecvMsg != NULL);
+
+    // convert msghdr to WSAMSG structure
+    wsamsg.name = msg->msg_name;
+    wsamsg.namelen = msg->msg_namelen;
+    wsamsg.lpBuffers = malloc(msg->msg_iovlen * sizeof(WSABUF));
+    wsamsg.dwBufferCount = msg->msg_iovlen;
+    wsamsg.Control.len = msg->msg_controllen;
+    wsamsg.Control.buf = msg->msg_control;
+    wsamsg.dwFlags = (DWORD)flags;
+
+    // all flags that fit into dwFlags also fit through the flags argument
+    assert(sizeof(DWORD) <= sizeof(flags));
+
+    if(wsamsg.lpBuffers == NULL) {
+        // malloc will have set errno
+        return -1;
+    }
+
+    // re-wrap iovecs as WSABUFs
+    for(i=0; i<msg->msg_iovlen; i++) {
+        // size_t vs. u_long
+        if(msg->msg_iov[i].iov_len > ULONG_MAX) {
+            free(wsamsg.lpBuffers);
+            errno = EINVAL;
+            return -1;
+        }
+
+        wsamsg.lpBuffers[i].len = msg->msg_iov[i].iov_len;
+        wsamsg.lpBuffers[i].buf = msg->msg_iov[i].iov_base;
+    }
+
+    r = WSARecvMsg(sockfd, &wsamsg, &bytesrcvd, NULL, NULL);
+
+    // the allocated WSABUF wrappers are no longer needed
+    free(wsamsg.lpBuffers);
+
+    if(r == SOCKET_ERROR) {
+        // XXX do we need special handling for ENETRESET, EMSGSIZE, ETIMEDOUT?
+        errno = wsa_errno();
+        return -1;
+    }
+
+    // DWORD has one bit more than ssize_t on 32bit
+    // XXX check for this condition before the WSARecvMsg call
+    if(bytesrcvd > SSIZE_MAX) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    // transfer results from wsamsg to msg
+    // NB: the data and control buffers are shared
+    msg->msg_controllen = wsamsg.Control.len;
+    msg->msg_flags = (int)wsamsg.dwFlags;
+        // all flags that fit into dwFlags also fit into msg_flags (see above)
+
+    return bytesrcvd;
+}
+
+ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags)
+{
+    LPFN_WSASENDMSG WSASendMsg = NULL;
+    GUID wsaid = WSAID_WSASENDMSG;
+    DWORD b;
+
+    DWORD bytessent;
+    WSAMSG wsamsg;
+    size_t i;
+    int r;
+
+    // size_t is larger than DWORD on 64bit
+    if(msg->msg_iovlen > UINT32_MAX) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    // obtain the function pointer to WSASendMsg
+    r = WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER,
+                 &wsaid, sizeof(wsaid), &WSASendMsg, sizeof(WSASendMsg),
+                 &b, NULL, NULL);
+    if(r == SOCKET_ERROR) {
+        errno = wsa_errno();
+        return -1;
+    }
+    assert(b == sizeof(WSASendMsg));
+    assert(WSASendMsg != NULL);
+
+    // convert msghdr to WSAMSG structure
+    wsamsg.name = msg->msg_name;
+    wsamsg.namelen = msg->msg_namelen;
+    wsamsg.lpBuffers = malloc(msg->msg_iovlen * sizeof(WSABUF));
+    wsamsg.dwBufferCount = msg->msg_iovlen;
+    wsamsg.Control.len = msg->msg_controllen;
+    wsamsg.Control.buf = msg->msg_control;
+    wsamsg.dwFlags = 0; // ignored
+
+    if(wsamsg.lpBuffers == NULL) {
+        // malloc will have set errno
+        return -1;
+    }
+
+    // re-wrap iovecs as WSABUFs
+    for(i=0; i<msg->msg_iovlen; i++) {
+        // size_t vs. u_long
+        if(msg->msg_iov[i].iov_len > ULONG_MAX) {
+            free(wsamsg.lpBuffers);
+            errno = EINVAL;
+            return -1;
+        }
+
+        wsamsg.lpBuffers[i].len = msg->msg_iov[i].iov_len;
+        wsamsg.lpBuffers[i].buf = msg->msg_iov[i].iov_base;
+    }
+
+    r = WSASendMsg(sockfd, &wsamsg, flags, &bytessent, NULL, NULL);
+
+    // the allocated WSABUF wrappers are no longer needed
+    free(wsamsg.lpBuffers);
+
+    if(r == SOCKET_ERROR) {
+        // XXX do we need special handling for ENETRESET, ETIMEDOUT?
+        errno = wsa_errno();
+        return -1;
+    }
+
+    // DWORD has one bit more than ssize_t on 32bit
+    // XXX check for this condition before sending anything
+    if(bytessent > SSIZE_MAX) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    return bytessent;
+}
+
+int ioctl(int d, unsigned long request, int *p)
+{
+    u_long arg = *p;
+
+    if(ioctlsocket(d, request, &arg) == SOCKET_ERROR) {
+        errno = wsa_errno();
+        return -1;
+    }
+
+    if(arg > INT_MAX) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    *p = arg;
+    return 0;
+}
+
+int pipe(int pipefd[2])
+{
+    int lsock = INVALID_SOCKET;
+    struct sockaddr_in laddr;
+    socklen_t laddrlen = sizeof(laddr);
+
+    pipefd[0] = pipefd[1] = INVALID_SOCKET;
+
+    // bind a listening socket to a TCP port on localhost
+    laddr.sin_family = AF_INET;
+    laddr.sin_port = 0;
+    laddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    if((lsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == SOCKET_ERROR)
+        goto fail;
+    if(bind(lsock, (struct sockaddr *)&laddr, sizeof(laddr)) == SOCKET_ERROR)
+        goto fail;
+    if(listen(lsock, 1) == SOCKET_ERROR)
+        goto fail;
+
+    // determine which address (i.e. port) we got bound to
+    if(getsockname(lsock, (struct sockaddr *)&laddr, &laddrlen) == SOCKET_ERROR)
+        goto fail;
+    assert(laddrlen == sizeof(laddr));
+    laddr.sin_family = AF_INET;
+    laddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+    // connect and accept
+    if((pipefd[0] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == SOCKET_ERROR)
+        goto fail;
+    if(connect(pipefd[0], (const struct sockaddr *)&laddr, sizeof(laddr)) == SOCKET_ERROR)
+        goto fail;
+    if((pipefd[1] = accept(lsock, NULL, NULL)) == SOCKET_ERROR)
+        goto fail;
+
+    // close the listener
+    closesocket(lsock);
+
+    return 0;
+
+fail:
+    errno = wsa_errno();
+    closesocket(pipefd[0]);
+    closesocket(lsock);
+    return -1;
+}
+
+int uname(struct utsname *buf)
+{
+    SYSTEM_INFO si;
+    const char *arch = "unknown";
+
+    memset(buf, 0, sizeof(struct utsname));
+
+    // operating system
+    strncpy(buf->sysname, "Windows", sizeof(buf->sysname)-1);
+    strncpy(buf->release, "unknown", sizeof(buf->sysname)-1);   // we don't need it
+    strncpy(buf->version, "unknown", sizeof(buf->sysname)-1);   // we don't need it
+
+    // computer (node) name
+    if(GetComputerName(buf->nodename, sizeof(buf->nodename)-1) == 0) {
+        errno = EFAULT;
+        return -1;
+    }
+
+    // hardware type
+    GetSystemInfo(&si);
+    switch(si.wProcessorArchitecture) {
+        case PROCESSOR_ARCHITECTURE_AMD64: arch = "amd64"; break;
+        case PROCESSOR_ARCHITECTURE_ARM:   arch = "arm";   break;
+        case PROCESSOR_ARCHITECTURE_IA64:  arch = "ia64";  break;
+        case PROCESSOR_ARCHITECTURE_INTEL: arch = "x86";   break;
+        default: arch = "unknown";
+    }
+    strncpy(buf->machine, arch, sizeof(buf->machine)-1);
+
+    return 0;
+}
diff --git a/src/compat/windows/wincompat.h b/src/compat/windows/wincompat.h
new file mode 100644 (file)
index 0000000..f611e33
--- /dev/null
@@ -0,0 +1,122 @@
+#ifndef foowincompatfoo
+#define foowincompatfoo
+
+// This file and its companion wincompat.c provide some Posix interfaces to
+// Windows APIs so the rest of the code can keep using them.
+
+
+// require at least Windows Vista
+#undef WINVER
+#undef _WIN32_WINNT
+#define WINVER 0x0600
+#define _WIN32_WINNT WINVER
+
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <mswsock.h>
+
+
+// wrappers around WSAStartup/WSACleanup to avoid clutter
+void winsock_init(void);
+void winsock_exit(void);
+
+
+// the equivalent of strerror(errno) for Windows sockets
+char *errnostrsocket(void);
+
+
+// Winsock doesn't have recvmsg/sendmsg but offers the same functionality
+// with WSARecvMsg/WSASendMsg, so we implement the former in terms of the
+// latter.
+
+struct iovec {                   /* Scatter/gather array items */
+   void  *iov_base;              /* Starting address */
+   size_t iov_len;               /* Number of bytes to transfer */
+};
+
+struct msghdr {
+   void         *msg_name;       /* optional address */
+   socklen_t     msg_namelen;    /* size of address */
+   struct iovec *msg_iov;        /* scatter/gather array */
+   size_t        msg_iovlen;     /* # elements in msg_iov */
+   void         *msg_control;    /* ancillary data, see below */
+   size_t        msg_controllen; /* ancillary data buffer len */
+   int           msg_flags;      /* flags on received message */
+};
+
+// MSDN says this struct is called wsacmsghdr but MingW uses _WSACMSGHDR.
+// TODO: Verify what it is on actual Windows.
+// cf. http://msdn.microsoft.com/en-us/library/ms741645(v=vs.85).aspx
+#ifdef __MINGW32__
+#define cmsghdr _WSACMSGHDR     // as in 'struct cmsghdr'
+#else
+#define cmsghdr wsacmsghdr      // as in 'struct cmsghdr'
+#endif
+
+static inline struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *m) {
+    WSAMSG wm;
+    wm.Control.len = m->msg_controllen;
+    wm.Control.buf = m->msg_control;
+    return WSA_CMSG_FIRSTHDR(&wm);
+}
+
+static inline struct cmsghdr *CMSG_NXTHDR(struct msghdr *m, struct cmsghdr *c) {
+    WSAMSG wm;
+    wm.Control.len = m->msg_controllen;
+    wm.Control.buf = m->msg_control;
+    return WSA_CMSG_NXTHDR(&wm, c);
+}
+
+#define CMSG_SPACE(len) WSA_CMSG_SPACE(len)
+#define CMSG_LEN(len) WSA_CMSG_LEN(len)
+
+// we're going to be naughty and redefine CMSG_DATA as an alias even though it
+// is also a constant defined in wincrypt.h which we don't care about.
+#undef CMSG_DATA
+#define CMSG_DATA(c) WSA_CMSG_DATA(c)
+
+ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
+ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
+
+// ESHUTDOWN does not seem to exist on Windows, even though WSAESHUTDOWN does.
+// MingW doesn't define it and MSDN doesn't list it, so we alias it to EBADF.
+// cf. http://msdn.microsoft.com/en-us/library/5814770t.aspx
+#ifndef ESHUTDOWN
+#define ESHUTDOWN EBADF
+#endif
+
+
+// Windows doesn't have ioctl but offers ioctlsocket for some socket-related
+// functions. Unfortunately, argument types differ, so we implement a
+// (restricted) wrapper.
+int ioctl(int d, unsigned long request, int *p);
+
+
+// Windows lacks poll, but WSAPoll is good enough for us.
+#define poll(fds, nfds, timeout) WSAPoll(fds, nfds, timeout)
+
+// Windows lacks pipe. It has an equivalent CreatePipe but we really need
+// something to give to WSAPoll, so we fake it with a local TCP socket. (ugh)
+int pipe(int pipefd[2]);
+
+// pipe(socket)-specific read/write/close equivalents
+#define closepipe closesocket
+#define writepipe(s,buf,len) send(s, buf, len, 0)
+#define readpipe(s,buf,len) recv(s, buf, len, 0)
+
+
+// Windows logically doesn't have uname, so we supply a replacement.
+
+struct utsname {
+   char sysname[9];    /* Operating system name (e.g., "Linux") */
+   char nodename[MAX_COMPUTERNAME_LENGTH+1];
+                       /* Name within "some implementation-defined network" */
+   char release[9];    /* Operating system release (e.g., "2.6.28") */
+   char version[9];    /* Operating system version */
+   char machine[9];    /* Hardware identifier */
+};
+
+int uname(struct utsname *buf);
+
+
+#endif
index e028f2b5a4b5b234aba1ccf6ac3c2078d647584e..d2c0dbf85dbccc83a19ee247f2e8d0ca27aedc85 100644 (file)
@@ -47,7 +47,7 @@ typedef enum {
 int catta_server_add_dns_server_address(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     const char *domain,
@@ -58,7 +58,7 @@ int catta_server_add_dns_server_address(
 /** Callback prototype for CattaSDNSServerBrowser events */
 typedef void (*CattaSDNSServerBrowserCallback)(
     CattaSDNSServerBrowser *b,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaBrowserEvent event,
     const char *host_name,       /**< Host name of the DNS server, probably useless */
@@ -70,7 +70,7 @@ typedef void (*CattaSDNSServerBrowserCallback)(
 /** Create a new CattaSDNSServerBrowser object */
 CattaSDNSServerBrowser *catta_s_dns_server_browser_new(
     CattaServer *server,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     const char *domain,
     CattaDNSServerType type,
index a56e0bd6407c8571c93a98195a506760d6a5f80d..afa972adb4bc5d1dbc56766e6042575af6cc7a84 100644 (file)
@@ -30,7 +30,6 @@
 
 #include <arpa/inet.h>
 
-#include <sys/utsname.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 
@@ -148,7 +147,7 @@ void catta_cleanup_dead_entries(CattaServer *s) {
     }
 }
 
-static int check_record_conflict(CattaServer *s, CattaIfIndex interface, CattaProtocol protocol, CattaRecord *r, CattaPublishFlags flags) {
+static int check_record_conflict(CattaServer *s, CattaIfIndex iface, CattaProtocol protocol, CattaRecord *r, CattaPublishFlags flags) {
     CattaEntry *e;
 
     assert(s);
@@ -169,9 +168,9 @@ static int check_record_conflict(CattaServer *s, CattaIfIndex interface, CattaPr
             continue;
         }
 
-        if ((interface <= 0 ||
-             e->interface <= 0 ||
-             e->interface == interface) &&
+        if ((iface <= 0 ||
+             e->iface <= 0 ||
+             e->iface == iface) &&
             (protocol == CATTA_PROTO_UNSPEC ||
              e->protocol == CATTA_PROTO_UNSPEC ||
              e->protocol == protocol))
@@ -185,7 +184,7 @@ static int check_record_conflict(CattaServer *s, CattaIfIndex interface, CattaPr
 static CattaEntry * server_add_internal(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     CattaRecord *r) {
@@ -196,7 +195,7 @@ static CattaEntry * server_add_internal(
     assert(r);
 
     CATTA_CHECK_VALIDITY_RETURN_NULL(s, s->state != CATTA_SERVER_FAILURE && s->state != CATTA_SERVER_INVALID, CATTA_ERR_BAD_STATE);
-    CATTA_CHECK_VALIDITY_RETURN_NULL(s, CATTA_IF_VALID(interface), CATTA_ERR_INVALID_INTERFACE);
+    CATTA_CHECK_VALIDITY_RETURN_NULL(s, CATTA_IF_VALID(iface), CATTA_ERR_INVALID_INTERFACE);
     CATTA_CHECK_VALIDITY_RETURN_NULL(s, CATTA_PROTO_VALID(protocol), CATTA_ERR_INVALID_PROTOCOL);
     CATTA_CHECK_VALIDITY_RETURN_NULL(s, CATTA_FLAGS_VALID(
                                          flags,
@@ -237,7 +236,7 @@ static CattaEntry * server_add_internal(
 
         /* Find the first matching entry */
         for (e = catta_hashmap_lookup(s->entries_by_key, r->key); e; e = e->by_key_next) {
-            if (!e->dead && e->group == g && e->interface == interface && e->protocol == protocol)
+            if (!e->dead && e->group == g && e->iface == iface && e->protocol == protocol)
                 break;
 
             is_first = 0;
@@ -276,7 +275,7 @@ static CattaEntry * server_add_internal(
 
         /* Add a new record */
 
-        if (check_record_conflict(s, interface, protocol, r, flags) < 0) {
+        if (check_record_conflict(s, iface, protocol, r, flags) < 0) {
             catta_server_set_errno(s, CATTA_ERR_COLLISION);
             return NULL;
         }
@@ -289,7 +288,7 @@ static CattaEntry * server_add_internal(
         e->server = s;
         e->record = catta_record_ref(r);
         e->group = g;
-        e->interface = interface;
+        e->iface = iface;
         e->protocol = protocol;
         e->flags = flags;
         e->dead = 0;
@@ -316,12 +315,12 @@ static CattaEntry * server_add_internal(
 int catta_server_add(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     CattaRecord *r) {
 
-    if (!server_add_internal(s, g, interface, protocol, flags, r))
+    if (!server_add_internal(s, g, iface, protocol, flags, r))
         return catta_server_errno(s);
 
     return CATTA_OK;
@@ -362,7 +361,7 @@ int catta_server_dump(CattaServer *s, CattaDumpCallback callback, void* userdata
         if (!(t = catta_record_to_string(e->record)))
             return catta_server_set_errno(s, CATTA_ERR_NO_MEMORY);
 
-        snprintf(ln, sizeof(ln), "%s ; iface=%i proto=%i", t, e->interface, e->protocol);
+        snprintf(ln, sizeof(ln), "%s ; iface=%i proto=%i", t, e->iface, e->protocol);
         catta_free(t);
 
         callback(ln, userdata);
@@ -378,7 +377,7 @@ int catta_server_dump(CattaServer *s, CattaDumpCallback callback, void* userdata
 static CattaEntry *server_add_ptr_internal(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     uint32_t ttl,
@@ -403,7 +402,7 @@ static CattaEntry *server_add_ptr_internal(
     }
 
     r->data.ptr.name = catta_normalize_name_strdup(dest);
-    e = server_add_internal(s, g, interface, protocol, flags, r);
+    e = server_add_internal(s, g, iface, protocol, flags, r);
     catta_record_unref(r);
     return e;
 }
@@ -411,7 +410,7 @@ static CattaEntry *server_add_ptr_internal(
 int catta_server_add_ptr(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     uint32_t ttl,
@@ -422,7 +421,7 @@ int catta_server_add_ptr(
 
     assert(s);
 
-    if (!(e = server_add_ptr_internal(s, g, interface, protocol, flags, ttl, name, dest)))
+    if (!(e = server_add_ptr_internal(s, g, iface, protocol, flags, ttl, name, dest)))
         return catta_server_errno(s);
 
     return CATTA_OK;
@@ -431,7 +430,7 @@ int catta_server_add_ptr(
 int catta_server_add_address(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     const char *name,
@@ -445,7 +444,7 @@ int catta_server_add_address(
     assert(s);
     assert(a);
 
-    CATTA_CHECK_VALIDITY(s, CATTA_IF_VALID(interface), CATTA_ERR_INVALID_INTERFACE);
+    CATTA_CHECK_VALIDITY(s, CATTA_IF_VALID(iface), CATTA_ERR_INVALID_INTERFACE);
     CATTA_CHECK_VALIDITY(s, CATTA_PROTO_VALID(protocol) && CATTA_PROTO_VALID(a->proto), CATTA_ERR_INVALID_PROTOCOL);
     CATTA_CHECK_VALIDITY(s, CATTA_FLAGS_VALID(flags,
                                               CATTA_PUBLISH_NO_REVERSE|
@@ -490,7 +489,7 @@ int catta_server_add_address(
         r->data.aaaa.address = a->data.ipv6;
     }
 
-    entry = server_add_internal(s, g, interface, protocol, (flags & ~ CATTA_PUBLISH_NO_REVERSE) | CATTA_PUBLISH_UNIQUE | CATTA_PUBLISH_ALLOW_MULTIPLE, r);
+    entry = server_add_internal(s, g, iface, protocol, (flags & ~ CATTA_PUBLISH_NO_REVERSE) | CATTA_PUBLISH_UNIQUE | CATTA_PUBLISH_ALLOW_MULTIPLE, r);
     catta_record_unref(r);
 
     if (!entry) {
@@ -504,7 +503,7 @@ int catta_server_add_address(
         char reverse_n[CATTA_DOMAIN_NAME_MAX];
         catta_reverse_lookup_name(a, reverse_n, sizeof(reverse_n));
 
-        if (!(reverse = server_add_ptr_internal(s, g, interface, protocol, flags | CATTA_PUBLISH_UNIQUE, CATTA_DEFAULT_TTL_HOST_NAME, reverse_n, name))) {
+        if (!(reverse = server_add_ptr_internal(s, g, iface, protocol, flags | CATTA_PUBLISH_UNIQUE, CATTA_DEFAULT_TTL_HOST_NAME, reverse_n, name))) {
             ret = catta_server_errno(s);
             goto finish;
         }
@@ -525,7 +524,7 @@ finish:
 static CattaEntry *server_add_txt_strlst_nocopy(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     uint32_t ttl,
@@ -544,7 +543,7 @@ static CattaEntry *server_add_txt_strlst_nocopy(
     }
 
     r->data.txt.string_list = strlst;
-    e = server_add_internal(s, g, interface, protocol, flags, r);
+    e = server_add_internal(s, g, iface, protocol, flags, r);
     catta_record_unref(r);
 
     return e;
@@ -569,7 +568,7 @@ static CattaStringList *add_magic_cookie(
 static int server_add_service_strlst_nocopy(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     const char *name,
@@ -588,7 +587,7 @@ static int server_add_service_strlst_nocopy(
     assert(type);
     assert(name);
 
-    CATTA_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, CATTA_IF_VALID(interface), CATTA_ERR_INVALID_INTERFACE);
+    CATTA_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, CATTA_IF_VALID(iface), CATTA_ERR_INVALID_INTERFACE);
     CATTA_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, CATTA_PROTO_VALID(protocol), CATTA_ERR_INVALID_PROTOCOL);
     CATTA_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, CATTA_FLAGS_VALID(flags,
                                                                 CATTA_PUBLISH_NO_COOKIE|
@@ -623,7 +622,7 @@ static int server_add_service_strlst_nocopy(
 
     /* Add service enumeration PTR record */
 
-    if (!(ptr_entry = server_add_ptr_internal(s, g, interface, protocol, 0, CATTA_DEFAULT_TTL, ptr_name, svc_name))) {
+    if (!(ptr_entry = server_add_ptr_internal(s, g, iface, protocol, 0, CATTA_DEFAULT_TTL, ptr_name, svc_name))) {
         ret = catta_server_errno(s);
         goto fail;
     }
@@ -640,7 +639,7 @@ static int server_add_service_strlst_nocopy(
     r->data.srv.port = port;
     r->data.srv.name = h;
     h = NULL;
-    srv_entry = server_add_internal(s, g, interface, protocol, CATTA_PUBLISH_UNIQUE, r);
+    srv_entry = server_add_internal(s, g, iface, protocol, CATTA_PUBLISH_UNIQUE, r);
     catta_record_unref(r);
 
     if (!srv_entry) {
@@ -653,7 +652,7 @@ static int server_add_service_strlst_nocopy(
     if (!(flags & CATTA_PUBLISH_NO_COOKIE))
         strlst = add_magic_cookie(s, strlst);
 
-    txt_entry = server_add_txt_strlst_nocopy(s, g, interface, protocol, CATTA_PUBLISH_UNIQUE, CATTA_DEFAULT_TTL, svc_name, strlst);
+    txt_entry = server_add_txt_strlst_nocopy(s, g, iface, protocol, CATTA_PUBLISH_UNIQUE, CATTA_DEFAULT_TTL, svc_name, strlst);
     strlst = NULL;
 
     if (!txt_entry) {
@@ -663,7 +662,7 @@ static int server_add_service_strlst_nocopy(
 
     /* Add service type enumeration record */
 
-    if (!(enum_entry = server_add_ptr_internal(s, g, interface, protocol, 0, CATTA_DEFAULT_TTL, enum_ptr, ptr_name))) {
+    if (!(enum_entry = server_add_ptr_internal(s, g, iface, protocol, 0, CATTA_DEFAULT_TTL, enum_ptr, ptr_name))) {
         ret = catta_server_errno(s);
         goto fail;
     }
@@ -689,7 +688,7 @@ fail:
 int catta_server_add_service_strlst(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     const char *name,
@@ -703,13 +702,13 @@ int catta_server_add_service_strlst(
     assert(type);
     assert(name);
 
-    return server_add_service_strlst_nocopy(s, g, interface, protocol, flags, name, type, domain, host, port, catta_string_list_copy(strlst));
+    return server_add_service_strlst_nocopy(s, g, iface, protocol, flags, name, type, domain, host, port, catta_string_list_copy(strlst));
 }
 
 int catta_server_add_service(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     const char *name,
@@ -723,7 +722,7 @@ int catta_server_add_service(
     int ret;
 
     va_start(va, port);
-    ret = server_add_service_strlst_nocopy(s, g, interface, protocol, flags, name, type, domain, host, port, catta_string_list_new_va(va));
+    ret = server_add_service_strlst_nocopy(s, g, iface, protocol, flags, name, type, domain, host, port, catta_string_list_new_va(va));
     va_end(va);
 
     return ret;
@@ -732,7 +731,7 @@ int catta_server_add_service(
 static int server_update_service_txt_strlst_nocopy(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     const char *name,
@@ -748,7 +747,7 @@ static int server_update_service_txt_strlst_nocopy(
     assert(type);
     assert(name);
 
-    CATTA_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, CATTA_IF_VALID(interface), CATTA_ERR_INVALID_INTERFACE);
+    CATTA_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, CATTA_IF_VALID(iface), CATTA_ERR_INVALID_INTERFACE);
     CATTA_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, CATTA_PROTO_VALID(protocol), CATTA_ERR_INVALID_PROTOCOL);
     CATTA_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, CATTA_FLAGS_VALID(flags,
                                                                 CATTA_PUBLISH_NO_COOKIE|
@@ -773,7 +772,7 @@ static int server_update_service_txt_strlst_nocopy(
     if (!(flags & CATTA_PUBLISH_NO_COOKIE))
         strlst = add_magic_cookie(s, strlst);
 
-    e = server_add_txt_strlst_nocopy(s, g, interface, protocol, CATTA_PUBLISH_UNIQUE | CATTA_PUBLISH_UPDATE, CATTA_DEFAULT_TTL, svc_name, strlst);
+    e = server_add_txt_strlst_nocopy(s, g, iface, protocol, CATTA_PUBLISH_UNIQUE | CATTA_PUBLISH_UPDATE, CATTA_DEFAULT_TTL, svc_name, strlst);
     strlst = NULL;
 
     if (!e)
@@ -789,7 +788,7 @@ fail:
 int catta_server_update_service_txt_strlst(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     const char *name,
@@ -797,14 +796,14 @@ int catta_server_update_service_txt_strlst(
     const char *domain,
     CattaStringList *strlst) {
 
-    return server_update_service_txt_strlst_nocopy(s, g, interface, protocol, flags, name, type, domain, catta_string_list_copy(strlst));
+    return server_update_service_txt_strlst_nocopy(s, g, iface, protocol, flags, name, type, domain, catta_string_list_copy(strlst));
 }
 
 /** Update the TXT record for a service with the NULL termonate list of strings */
 int catta_server_update_service_txt(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     const char *name,
@@ -816,7 +815,7 @@ int catta_server_update_service_txt(
     int ret;
 
     va_start(va, domain);
-    ret = server_update_service_txt_strlst_nocopy(s, g, interface, protocol, flags, name, type, domain, catta_string_list_new_va(va));
+    ret = server_update_service_txt_strlst_nocopy(s, g, iface, protocol, flags, name, type, domain, catta_string_list_new_va(va));
     va_end(va);
 
     return ret;
@@ -825,7 +824,7 @@ int catta_server_update_service_txt(
 int catta_server_add_service_subtype(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     const char *name,
@@ -840,7 +839,7 @@ int catta_server_add_service_subtype(
     assert(type);
     assert(subtype);
 
-    CATTA_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, CATTA_IF_VALID(interface), CATTA_ERR_INVALID_INTERFACE);
+    CATTA_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, CATTA_IF_VALID(iface), CATTA_ERR_INVALID_INTERFACE);
     CATTA_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, CATTA_PROTO_VALID(protocol), CATTA_ERR_INVALID_PROTOCOL);
     CATTA_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, CATTA_FLAGS_VALID(flags, CATTA_PUBLISH_USE_MULTICAST|CATTA_PUBLISH_USE_WIDE_AREA), CATTA_ERR_INVALID_FLAGS);
     CATTA_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, catta_is_valid_service_name(name), CATTA_ERR_INVALID_SERVICE_NAME);
@@ -860,7 +859,7 @@ int catta_server_add_service_subtype(
         goto fail;
     }
 
-    if ((ret = catta_server_add_ptr(s, g, interface, protocol, 0, CATTA_DEFAULT_TTL, ptr_name, svc_name)) < 0)
+    if ((ret = catta_server_add_ptr(s, g, iface, protocol, 0, CATTA_DEFAULT_TTL, ptr_name, svc_name)) < 0)
         goto fail;
 
 fail:
@@ -893,7 +892,7 @@ static void hexstring(char *s, size_t sl, const void *p, size_t pl) {
 static CattaEntry *server_add_dns_server_name(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     const char *domain,
@@ -940,7 +939,7 @@ static CattaEntry *server_add_dns_server_name(
     r->data.srv.weight = 0;
     r->data.srv.port = port;
     r->data.srv.name = n;
-    e = server_add_internal(s, g, interface, protocol, 0, r);
+    e = server_add_internal(s, g, iface, protocol, 0, r);
     catta_record_unref(r);
 
     return e;
@@ -949,7 +948,7 @@ static CattaEntry *server_add_dns_server_name(
 int catta_server_add_dns_server_address(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     const char *domain,
@@ -964,7 +963,7 @@ int catta_server_add_dns_server_address(
     assert(s);
     assert(address);
 
-    CATTA_CHECK_VALIDITY(s, CATTA_IF_VALID(interface), CATTA_ERR_INVALID_INTERFACE);
+    CATTA_CHECK_VALIDITY(s, CATTA_IF_VALID(iface), CATTA_ERR_INVALID_INTERFACE);
     CATTA_CHECK_VALIDITY(s, CATTA_PROTO_VALID(protocol) && CATTA_PROTO_VALID(address->proto), CATTA_ERR_INVALID_PROTOCOL);
     CATTA_CHECK_VALIDITY(s, CATTA_FLAGS_VALID(flags, CATTA_PUBLISH_USE_MULTICAST|CATTA_PUBLISH_USE_WIDE_AREA), CATTA_ERR_INVALID_FLAGS);
     CATTA_CHECK_VALIDITY(s, type == CATTA_DNS_SERVER_UPDATE || type == CATTA_DNS_SERVER_RESOLVE, CATTA_ERR_INVALID_FLAGS);
@@ -992,13 +991,13 @@ int catta_server_add_dns_server_address(
     if (!r)
         return catta_server_set_errno(s, CATTA_ERR_NO_MEMORY);
 
-    a_entry = server_add_internal(s, g, interface, protocol, CATTA_PUBLISH_UNIQUE | CATTA_PUBLISH_ALLOW_MULTIPLE, r);
+    a_entry = server_add_internal(s, g, iface, protocol, CATTA_PUBLISH_UNIQUE | CATTA_PUBLISH_ALLOW_MULTIPLE, r);
     catta_record_unref(r);
 
     if (!a_entry)
         return catta_server_errno(s);
 
-    if (!(s_entry = server_add_dns_server_name(s, g, interface, protocol, flags, domain, type, n, port))) {
+    if (!(s_entry = server_add_dns_server_name(s, g, iface, protocol, flags, domain, type, n, port))) {
         if (!(flags & CATTA_PUBLISH_UPDATE))
             catta_entry_free(s, a_entry);
         return catta_server_errno(s);
index 543d1b1ad1e7607f7544ed1572a1c748c57d40dd..c4199edf3f579e9298a3c7feada533dedb46ffd0 100644 (file)
@@ -55,7 +55,7 @@ const char *catta_strerror(int error) {
         "Memory exhausted",
         "The object passed in was not valid",
         "Daemon not running",
-        "Invalid interface index",
+        "Invalid iface index",
         "Invalid protocol specification",
         "Invalid flags",
 
index c483ce8de1e4859a7d2c366246d938ed0dc8d393..ca5f65b8f2bed79f12393ae513bc9716e48f3269 100644 (file)
 
 #include <sys/select.h>
 #include <unistd.h>
-#include <fcntl.h>
 #include <assert.h>
 
+#ifdef HAVE_FCNTL
+#include <fcntl.h>
+#else
+#include <sys/ioctl.h>
+#endif
+
 #include "fdutil.h"
 
 int catta_set_cloexec(int fd) {
@@ -33,6 +38,7 @@ int catta_set_cloexec(int fd) {
 
     assert(fd >= 0);
 
+#if defined(HAVE_FCNTL)
     if ((n = fcntl(fd, F_GETFD)) < 0)
         return -1;
 
@@ -40,6 +46,15 @@ int catta_set_cloexec(int fd) {
         return 0;
 
     return fcntl(fd, F_SETFD, n|FD_CLOEXEC);
+#elif defined(_WIN32)
+    (void)n;
+    if(!SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0))
+        return -1;
+    return 0;
+#else
+    (void)n;
+    return -1;
+#endif
 }
 
 int catta_set_nonblock(int fd) {
@@ -47,6 +62,7 @@ int catta_set_nonblock(int fd) {
 
     assert(fd >= 0);
 
+#ifdef HAVE_FCNTL
     if ((n = fcntl(fd, F_GETFL)) < 0)
         return -1;
 
@@ -54,6 +70,10 @@ int catta_set_nonblock(int fd) {
         return 0;
 
     return fcntl(fd, F_SETFL, n|O_NONBLOCK);
+#else
+    n = 1;
+    return ioctl(fd, FIONBIO, &n);
+#endif
 }
 
 int catta_wait_for_write(int fd) {
index 5dda5822091762f663dcc04da7f156b00868c50d..7f2840a1c0200b7721d118ba74f200b32d098a21 100644 (file)
 #include "iface.h"
 
 int catta_interface_monitor_init_osdep(CattaInterfaceMonitor *m) {
+    (void)m;    // silence "unused parameter" warning
+
     return 0;
 }
 
 void catta_interface_monitor_free_osdep(CattaInterfaceMonitor *m) {
+    (void)m;    // silence "unused parameter" warning
 }
 
 void catta_interface_monitor_sync(CattaInterfaceMonitor *m) {
+    (void)m;    // silence "unused parameter" warning
 }
diff --git a/src/iface-windows.c b/src/iface-windows.c
new file mode 100644 (file)
index 0000000..1d8d0f3
--- /dev/null
@@ -0,0 +1,583 @@
+/***
+  This file is part of catta.
+
+  catta is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.1 of the
+  License, or (at your option) any later version.
+
+  catta is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+  Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with catta; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include "iface.h"
+#include "iface-windows.h"
+
+#include <stdlib.h> // wcstombs
+#include <catta/malloc.h>
+#include <catta/log.h>
+#include <iphlpapi.h>
+#include <assert.h>
+#include "hashmap.h"
+#include "util.h"   // catta_format_mac_address
+#include "fdutil.h" // catta_set_nonblock
+
+
+typedef enum {
+    INTERFACE_CHANGE_EVENT,
+    ADDRESS_CHANGE_EVENT
+} ChangeEventType;
+
+struct ChangeEvent {
+    CATTA_LLIST_FIELDS(ChangeEvent, event);
+    ChangeEventType type;
+    MIB_NOTIFICATION_TYPE notification_type;
+    union {
+        MIB_IPINTERFACE_ROW iface;
+        MIB_UNICASTIPADDRESS_ROW addr;
+    } data;
+};
+
+
+// helper: determine the global_scope flag for an address
+static void set_global_scope_flag(CattaInterfaceAddress *ifaddr, const CattaAddress *addr)
+{
+    if(addr->proto == CATTA_PROTO_INET6) {
+        const struct in6_addr *ia = (struct in6_addr *)addr->data.ipv6.address;
+        ifaddr->global_scope = !(IN6_IS_ADDR_LINKLOCAL(ia) || IN6_IS_ADDR_MULTICAST(ia));
+    } else {
+        ifaddr->global_scope = 1;
+    }
+}
+
+// integrate the information from an IP_ADAPTER_UNICAST_ADDRESS structure for
+// given CattaHwInterface into the CattaInterfaceMonitor
+static void ip_adapter_unicast_address(CattaInterfaceMonitor *m,
+                                       CattaHwInterface *hw,
+                                       IP_ADAPTER_UNICAST_ADDRESS *a)
+{
+    CattaInterface *iface;
+    CattaAddress addr;
+    CattaInterfaceAddress *ifaddr;
+    struct sockaddr *sa = a->Address.lpSockaddr;
+
+    // skip transient addresses; to quote MSDN: "The IP address is a cluster
+    // address and should not be used by most applications."
+    // http://msdn.microsoft.com/en-us/library/windows/desktop/aa366066(v=vs.85).aspx
+    if(a->Flags & IP_ADAPTER_ADDRESS_TRANSIENT)
+        return;
+
+    // fill addr struct for address lookup
+    switch(sa->sa_family) {
+    case AF_INET:
+        memcpy(addr.data.data, &((struct sockaddr_in *)sa)->sin_addr, sizeof(struct in_addr));
+        break;
+    case AF_INET6:
+        memcpy(addr.data.data, &((struct sockaddr_in6 *)sa)->sin6_addr, sizeof(struct in6_addr));
+        break;
+    default:
+        catta_log_debug("unexpected address family on interface %d: %u", hw->index, sa->sa_family);
+        return;
+    }
+    addr.proto = catta_af_to_proto(sa->sa_family);
+
+    // get protocol-specific CattaInterface object
+    if(!(iface = catta_interface_monitor_get_interface(m, hw->index, addr.proto))) {
+        catta_log_error("CattaInterface (index %d, proto %d) not found", hw->index, addr.proto);
+        return;
+    }
+
+    // find or allocate a CattaInterfaceAddress struct for this address
+    if(!(ifaddr = catta_interface_monitor_get_address(m, iface, &addr))) {
+        if(!(ifaddr = catta_interface_address_new(m, iface, &addr, a->OnLinkPrefixLength))) {
+            catta_log_error("out of memory in ip_adapter_unicast_address");
+            return;
+        }
+    }
+
+    set_global_scope_flag(ifaddr, &addr);
+}
+
+// integrate the information from an IP_ADAPTER_ADDRESSES structure
+// as returned by GetAdaptersAddresses into the CattaInterfaceMonitor
+static void ip_adapter(CattaInterfaceMonitor *m, IP_ADAPTER_ADDRESSES *p)
+{
+    IP_ADAPTER_UNICAST_ADDRESS *a;
+    CattaIfIndex idx;
+    CattaHwInterface *hw;
+    size_t n;
+
+    // we want an index specific to the hardware interface, but Windows
+    // has one for IPv4 and one for IPv6. it seems like these are always the
+    // same unless one of the protocols is not available. let's have a bunch of
+    // checks...
+    if(!p->IfIndex && !p->Ipv6IfIndex) {
+        return; // no usable protocols
+    } else if(!p->IfIndex) {
+        idx = p->Ipv6IfIndex;   // IPv6 but no IPv4 (huh!)
+    } else if(!p->Ipv6IfIndex) {
+        idx = p->IfIndex;       // IPv4 but no IPv6
+    } else if(p->IfIndex == p->Ipv6IfIndex) {
+        idx = p->IfIndex;       // same index for both protocols
+    } else {
+        // both indexes valid but not equal
+        catta_log_error("unsupported interface: %ls (IfIndex and Ipv6IfIndex differ: %u/%u)",
+            p->FriendlyName, (unsigned int)p->IfIndex, (unsigned int)p->Ipv6IfIndex);
+        return;
+    }
+
+    // find the CattaHwInterface by index or allocate a new one
+    if((hw = catta_interface_monitor_get_hw_interface(m, idx)) == NULL) {
+        if((hw = catta_hw_interface_new(m, idx)) == NULL) {
+            catta_log_error("catta_hw_interface_new failed in ip_adapter_address");
+            return;
+        }
+    }
+
+    // fill the CattaHwInterface struct with data
+    // notice: this code is essentially duplicated in update_hw_interface()
+    hw->flags_ok =
+        (p->OperStatus == IfOperStatusUp) &&
+        !(p->IfType == IF_TYPE_SOFTWARE_LOOPBACK) &&
+        !(p->Flags & IP_ADAPTER_NO_MULTICAST) &&
+        (m->server->config.allow_point_to_point || !(p->IfType == IF_TYPE_PPP));
+            // XXX what about IF_TYPE_TUNNEL?
+
+    n = wcstombs(NULL, p->FriendlyName, 0) + 1;
+    catta_free(hw->name);
+    hw->name = catta_new(char, n);
+    wcstombs(hw->name, p->FriendlyName, n);
+
+    hw->mtu = p->Mtu;
+
+    hw->mac_address_size = p->PhysicalAddressLength;
+    if(hw->mac_address_size > CATTA_MAC_ADDRESS_MAX)
+        hw->mac_address_size = CATTA_MAC_ADDRESS_MAX;
+    memcpy(hw->mac_address, p->PhysicalAddress, hw->mac_address_size);
+
+    // process addresses
+    // XXX remove addresses that are no longer in the list
+    for(a=p->FirstUnicastAddress; a; a=a->Next)
+        ip_adapter_unicast_address(m, hw, a);
+}
+
+
+// place the event into the queue to be handled (by the main thread)
+// and wake the event handler if necessary
+static void queue_event(CattaInterfaceMonitor *m, ChangeEvent *ev)
+{
+    char c = 'X';
+
+    if(!ev)
+        return;
+
+    if(!pthread_mutex_lock(&m->osdep.mutex)) {
+        // queue the event
+        CATTA_LLIST_APPEND(ChangeEvent, event, m->osdep.events, ev);
+
+        // wake the handler
+        writepipe(m->osdep.pipefd[1], &c, sizeof(c));
+
+        pthread_mutex_unlock(&m->osdep.mutex);
+    } else {
+        catta_log_debug(__FILE__": queue_event: could not lock mutex");
+        catta_free(ev);
+    }
+}
+
+// copy the given data row into an appropriate change event struct
+static ChangeEvent *new_event(ChangeEventType type, MIB_NOTIFICATION_TYPE ntype, void *row, size_t n)
+{
+    ChangeEvent *ev;
+
+    if(!row)
+        return NULL;
+
+    if(!(ev = catta_new(ChangeEvent, 1)))
+        return NULL;
+
+    ev->type = type;
+    ev->notification_type = ntype;
+    memcpy(&ev->data, row, n);
+
+    return ev;
+}
+
+static void WINAPI icn_callback(void *m, MIB_IPINTERFACE_ROW *row, MIB_NOTIFICATION_TYPE type)
+{
+    queue_event(m, new_event(INTERFACE_CHANGE_EVENT, type, row, sizeof(*row)));
+}
+
+static void WINAPI acn_callback(void *m, MIB_UNICASTIPADDRESS_ROW *row, MIB_NOTIFICATION_TYPE type)
+{
+    queue_event(m, new_event(ADDRESS_CHANGE_EVENT, type, row, sizeof(*row)));
+}
+
+static void update_hw_interface(CattaHwInterface *hw)
+{
+    MIB_IF_ROW2 row;
+    DWORD r;
+    size_t n;
+    int multicast;  // synthetic flag
+
+    row.InterfaceLuid.Value = 0;
+    row.InterfaceIndex = hw->index;
+    if((r = GetIfEntry2(&row)) != NO_ERROR) {
+        catta_log_error("GetIfEntry2 failed for iface %d (error %u)", hw->index, (unsigned int)r);
+        return;
+    }
+
+    // fill the CattaHwInterface struct with data
+    // notice: this code is essentially duplicated from ip_adapter()
+    // notice: not sure where to find the IP_ADAPTER_NO_MULTICAST flag from an
+    //         MIB_IF_ROW2 struct, so try to deduce it otherwise
+    //         cf. http://msdn.microsoft.com/en-us/windows/desktop/ff568739(v=vs.100).aspx
+    multicast = row.AccessType == NET_IF_ACCESS_BROADCAST ||
+                row.AccessType == NET_IF_ACCESS_POINT_TO_POINT;
+    hw->flags_ok =
+        (row.OperStatus == IfOperStatusUp) &&
+        !(row.Type == IF_TYPE_SOFTWARE_LOOPBACK) &&
+        multicast &&
+        (hw->monitor->server->config.allow_point_to_point || !(row.Type == IF_TYPE_PPP));
+            // XXX what about IF_TYPE_TUNNEL?
+
+    n = wcstombs(NULL, row.Alias, 0) + 1;
+    catta_free(hw->name);
+    hw->name = catta_new(char, n);
+    wcstombs(hw->name, row.Alias, n);
+
+    hw->mtu = row.Mtu;
+
+    hw->mac_address_size = row.PhysicalAddressLength;
+    if(hw->mac_address_size > CATTA_MAC_ADDRESS_MAX)
+        hw->mac_address_size = CATTA_MAC_ADDRESS_MAX;
+    memcpy(hw->mac_address, row.PhysicalAddress, hw->mac_address_size);
+
+    catta_hw_interface_check_relevant(hw);
+    catta_hw_interface_update_rrs(hw, 0);
+}
+
+static void handle_iface_event(CattaInterfaceMonitor *m, MIB_IPINTERFACE_ROW *row, MIB_NOTIFICATION_TYPE type)
+{
+    CattaIfIndex idx = row->InterfaceIndex;
+    CattaProtocol proto = catta_af_to_proto(row->Family);
+    const char *protostr = catta_proto_to_string(proto);
+    CattaInterface *iface;
+    CattaHwInterface *hw;
+
+    // see if we know this interface
+    iface = catta_interface_monitor_get_interface(m, idx, proto);
+    hw = iface ? iface->hardware : catta_interface_monitor_get_hw_interface(m, idx);
+
+    // print debug messages for some unexpected cases
+    if(type==MibParameterNotification && !iface)
+        catta_log_debug("ParameterNotification received for unknown interface %d (%s)", idx, protostr);
+    if(type==MibDeleteInstance && !iface)
+        catta_log_debug("DeleteInstance received for unknown interface %d (%s)", idx, protostr);
+    if(type==MibAddInstance && iface)
+        catta_log_debug("AddInstance received for existing interface %d (%s)", idx, protostr);
+    if(iface && !hw)
+        catta_log_debug("missing CattaHwInterface for interface %d (%s)", idx, protostr);
+
+    switch(type) {
+    case MibParameterNotification:
+    case MibAddInstance:
+        // create the physical interface if it is missing
+        if(!hw) {
+            if((hw = catta_hw_interface_new(m, idx)) == NULL) {
+                catta_log_error("catta_hw_interface_new failed in handle_iface_event");
+                return;
+            }
+        }
+
+        // create the protocol-specific interface if it is missing
+        if(!iface) {
+            if((iface = catta_interface_new(m, hw, proto)) == NULL) {
+                catta_log_error("catta_interface_new failed in handle_iface_event");
+                return;
+            }
+        }
+
+        assert(iface != NULL);
+        assert(hw != NULL);
+        assert(iface->hardware == hw);
+
+        update_hw_interface(hw);
+        break;
+    case MibDeleteInstance:
+        if(iface)
+            catta_interface_free(iface, 0);
+
+        // free the hardware interface when there are no more protocol-specific interfaces
+        if(hw && !hw->interfaces)
+            catta_hw_interface_free(hw, 0);
+        break;
+    default:
+        catta_log_debug("unexpected type (%d) of interface change notification received", type);
+    }
+}
+
+static void handle_addr_event(CattaInterfaceMonitor *m, MIB_UNICASTIPADDRESS_ROW *row, MIB_NOTIFICATION_TYPE type)
+{
+    CattaIfIndex idx = row->InterfaceIndex;
+    CattaInterfaceAddress *ifaddr;
+    CattaInterface *iface;
+    CattaAddress addr;
+    const char *protostr;
+
+    // fill addr struct for address lookup
+    switch(row->Address.si_family) {
+    case AF_INET:
+        memcpy(addr.data.data, &row->Address.Ipv4.sin_addr, sizeof(struct in_addr));
+        break;
+    case AF_INET6:
+        memcpy(addr.data.data, &row->Address.Ipv6.sin6_addr, sizeof(struct in6_addr));
+        break;
+    default:
+        catta_log_debug("unexpected address family on interface %d: %u", idx, row->Address.si_family);
+        return;
+    }
+    addr.proto = catta_af_to_proto(row->Address.si_family);
+    protostr = catta_proto_to_string(addr.proto);
+
+    // see if we know this address/interface
+    iface = catta_interface_monitor_get_interface(m, idx, addr.proto);
+    ifaddr = iface ? catta_interface_monitor_get_address(m, iface, &addr) : NULL;
+
+    // print debug messages for some unexpected cases
+    if(type==MibParameterNotification && !ifaddr)
+        catta_log_debug("ParameterNotification received for unknown address on interface %d (%s)", idx, protostr);
+    if(type==MibDeleteInstance && !ifaddr)
+        catta_log_debug("DeleteInstance received for unknown address on interface %d (%s)", idx, protostr);
+    if(type==MibAddInstance && ifaddr)
+        catta_log_debug("AddInstance received for existing address on interface %d (%s)", idx, protostr);
+    if(ifaddr && !iface)
+        catta_log_debug("missing CattaInterface for address on interface %d (%s)", idx, protostr);
+
+    switch(type) {
+    case MibParameterNotification:
+    case MibAddInstance:
+        // fetch the full event data
+        if(GetUnicastIpAddressEntry(row) != NO_ERROR) {
+            catta_log_error("GetUnicastIpAddressEntry failed in handle_addr_event");
+            return;
+        }
+
+        // skip addresses that are not suitable as source addresses
+        if(row->SkipAsSource)
+            return;
+
+        // create the interface if it is missing
+        if(!iface) {
+            CattaHwInterface *hw;
+
+            if((hw = catta_interface_monitor_get_hw_interface(m, idx)) == NULL) {
+                catta_log_error("interface %d not found in handle_addr_event", idx);
+                return;
+            }
+
+            if((iface = catta_interface_new(m, hw, addr.proto)) == NULL) {
+                catta_log_error("catta_interface_new failed in handle_addr_event");
+                return;
+            }
+        }
+        assert(iface != NULL);
+
+        // create the interface-associated address if it is missing
+        if(!ifaddr) {
+            unsigned prefixlen = row->OnLinkPrefixLength;
+
+            if((ifaddr = catta_interface_address_new(m, iface, &addr, prefixlen)) == NULL) {
+                catta_log_error("catta_interface_address_new failed in handle_addr_event");
+                return;
+            }
+        }
+        assert(ifaddr != NULL);
+
+        set_global_scope_flag(ifaddr, &addr);
+        break;
+    case MibDeleteInstance:
+        if(ifaddr)
+            catta_interface_address_free(ifaddr);
+        break;
+    default:
+        catta_log_debug("unexpected type (%d) of address change notification received", type);
+    }
+
+    if(iface) {
+        catta_interface_check_relevant(iface);
+        catta_interface_update_rrs(iface, 0);
+    }
+}
+
+static void handle_events(CattaInterfaceMonitor *m)
+{
+    char buf[16];
+    ChangeEvent *ev;
+
+    if(!pthread_mutex_lock(&m->osdep.mutex)) {
+        // clear the pipe
+        while(readpipe(m->osdep.pipefd[0], buf, sizeof(buf)) == sizeof(buf)) {}
+
+        while((ev = m->osdep.events) != NULL) {
+            CATTA_LLIST_REMOVE(ChangeEvent, event, m->osdep.events, ev);
+
+            // dispatch to the appropriate handler
+            switch(ev->type) {
+            case INTERFACE_CHANGE_EVENT:
+                handle_iface_event(m, &ev->data.iface, ev->notification_type);
+                break;
+            case ADDRESS_CHANGE_EVENT:
+                handle_addr_event(m, &ev->data.addr, ev->notification_type);
+                break;
+            default:
+                catta_log_debug("unhandled change event type in handle_events");
+            }
+
+            catta_free(ev);
+        }
+
+        pthread_mutex_unlock(&m->osdep.mutex);
+    }
+}
+
+static void pipe_callback(CattaWatch *w, int fd, CattaWatchEvent event, void *m)
+{
+    // silence "unused parameter" warnings
+    (void)w;
+    (void)fd;
+    (void)event;
+
+    handle_events(m);
+}
+
+
+int catta_interface_monitor_init_osdep(CattaInterfaceMonitor *m)
+{
+    DWORD r;
+
+    pthread_mutex_init(&m->osdep.mutex, NULL);
+
+    CATTA_LLIST_HEAD_INIT(ChangeEvent, m->osdep.events);
+
+    if(pipe(m->osdep.pipefd) < 0) {
+        catta_log_error("pipe() in catta_interface_monitor_init_osdep failed");
+        return -1;
+    }
+    if(catta_set_nonblock(m->osdep.pipefd[0]) < 0 ||
+       catta_set_nonblock(m->osdep.pipefd[1]) < 0)
+    {
+        catta_log_error(__FILE__": catta_set_nonblock failed: %s", errnostrsocket());
+        goto fail;
+    }
+
+    m->osdep.icnhandle = NULL;
+    m->osdep.acnhandle = NULL;
+
+    // register handler for change events
+    m->osdep.watch = m->server->poll_api->watch_new(m->server->poll_api,
+                                                    m->osdep.pipefd[0],
+                                                    CATTA_WATCH_IN,
+                                                    pipe_callback,
+                                                    m);
+    if(!m->osdep.watch) {
+        catta_log_error(__FILE__": Failed to create watch.");
+        goto fail;
+    }
+
+    // request async notification on interface changes
+    r = NotifyIpInterfaceChange(AF_UNSPEC,
+                                // icn_callback needs to be WINAPI but
+                                // MingW up to 3.1.0 erroneously defines
+                                // PIPINTERFACE_CHANGE_CALLBACK without it
+                                (PIPINTERFACE_CHANGE_CALLBACK)icn_callback,
+                                m, FALSE, &m->osdep.icnhandle);
+    if(r != NO_ERROR)
+        catta_log_error("NotifyIpInterfaceChange failed: %u", (unsigned int)r);
+
+    // request async notification on address changes
+    r = NotifyUnicastIpAddressChange(AF_UNSPEC, acn_callback, m, FALSE,
+                                     &m->osdep.acnhandle);
+    if(r != NO_ERROR)
+        catta_log_error("NotifyUnicastIpAddressChange failed: %u", (unsigned int)r);
+
+    return 0;
+
+fail:
+    closesocket(m->osdep.pipefd[0]);
+    closesocket(m->osdep.pipefd[1]);
+    return -1;
+}
+
+void catta_interface_monitor_free_osdep(CattaInterfaceMonitor *m)
+{
+    ChangeEvent *ev;
+
+    // unregister callbacks
+    if(m->osdep.icnhandle) CancelMibChangeNotify2(m->osdep.icnhandle);
+    if(m->osdep.acnhandle) CancelMibChangeNotify2(m->osdep.acnhandle);
+
+    // unregister event handler
+    m->server->poll_api->watch_free(m->osdep.watch);
+
+    // close pipe
+    closepipe(m->osdep.pipefd[0]);
+    closepipe(m->osdep.pipefd[1]);
+
+    // make sure no stray events can come in during destruction
+    pthread_mutex_lock(&m->osdep.mutex);
+
+    // free all events that are still in the queue
+    while((ev = m->osdep.events) != NULL) {
+        CATTA_LLIST_REMOVE(ChangeEvent, event, m->osdep.events, ev);
+        catta_free(ev);
+    }
+
+    pthread_mutex_unlock(&m->osdep.mutex);
+    pthread_mutex_destroy(&m->osdep.mutex);
+}
+
+void catta_interface_monitor_sync(CattaInterfaceMonitor *m)
+{
+    IP_ADAPTER_ADDRESSES *buf = NULL;
+    IP_ADAPTER_ADDRESSES *p;
+    ULONG bufsize = 15000;
+    ULONG r;
+
+    // allocate a buffer and call GetAdaptersAddresses
+    // retry with the correct size if the buffer was too small
+    do {
+        catta_free(buf);    // no-op on first iteration
+        if((buf = catta_malloc(bufsize)) == NULL) {
+            catta_log_error("malloc failed in catta_interface_monitor_sync");
+            return;
+        }
+
+        r = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, buf, &bufsize);
+    } while(r == ERROR_BUFFER_OVERFLOW);
+
+    if(r != NO_ERROR) {
+        catta_log_error("GetAdaptersAddresses failed: %u", (unsigned int)r);
+        return;
+    }
+
+    // XXX remove interfaces for adapters that are no longer in the list
+
+    // create 'CattaInterface's for every adapter
+    for(p=buf; p; p=p->Next)
+        ip_adapter(m, p);
+
+    catta_free(buf);
+
+    m->list_complete = 1;
+    catta_interface_monitor_check_relevant(m);
+    catta_interface_monitor_update_rrs(m, 0);
+    catta_log_info("Network interface enumeration completed.");
+}
diff --git a/src/iface-windows.h b/src/iface-windows.h
new file mode 100644 (file)
index 0000000..f7be1f7
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef fooifacewindowshfoo
+#define fooifacewindowshfoo
+
+#include <catta/llist.h>
+#include <pthread.h>
+
+// we register with Windows to receive callbacks when IP interfaces change.
+// we save these events in the structures below and pick them up from our
+// own mainloop which we wake via a pipe.
+
+typedef struct ChangeEvent ChangeEvent;
+
+typedef struct CattaInterfaceMonitorOSDep {
+    pthread_mutex_t mutex;  // guards access to event queues and the pipe
+
+    CATTA_LLIST_HEAD(ChangeEvent, events);
+
+    int pipefd[2];      // used to wake up the mainloop and check for events
+
+    // handles for deregistering the handler and notification callbacks
+    HANDLE icnhandle;   // interface change notification handle
+    HANDLE acnhandle;   // address change notification handle
+    CattaWatch *watch;
+} CattaInterfaceMonitorOSDep;
+
+#endif
index 0940d63060f5ccd20916dea1a2fb49c8a2a90dd3..8ab84a41a7e64c56df209b27956536b312f12aff 100644 (file)
@@ -50,7 +50,7 @@ void catta_interface_address_update_rrs(CattaInterfaceAddress *a, int remove_rrs
 
     if (m->list_complete &&
         catta_interface_address_is_relevant(a) &&
-        catta_interface_is_relevant(a->interface) &&
+        catta_interface_is_relevant(a->iface) &&
         !remove_rrs &&
         m->server->config.publish_addresses &&
         (m->server->state == CATTA_SERVER_RUNNING ||
@@ -67,13 +67,13 @@ void catta_interface_address_update_rrs(CattaInterfaceAddress *a, int remove_rrs
             char t[CATTA_ADDRESS_STR_MAX];
             CattaProtocol p;
 
-            p = (a->interface->protocol == CATTA_PROTO_INET && m->server->config.publish_a_on_ipv6) ||
-                (a->interface->protocol == CATTA_PROTO_INET6 && m->server->config.publish_aaaa_on_ipv4) ? CATTA_PROTO_UNSPEC : a->interface->protocol;
+            p = (a->iface->protocol == CATTA_PROTO_INET && m->server->config.publish_a_on_ipv6) ||
+                (a->iface->protocol == CATTA_PROTO_INET6 && m->server->config.publish_aaaa_on_ipv4) ? CATTA_PROTO_UNSPEC : a->iface->protocol;
 
             catta_address_snprint(t, sizeof(t), &a->address);
-            catta_log_info("Registering new address record for %s on %s.%s.", t, a->interface->hardware->name, p == CATTA_PROTO_UNSPEC ? "*" : catta_proto_to_string(p));
+            catta_log_info("Registering new address record for %s on %s.%s.", t, a->iface->hardware->name, p == CATTA_PROTO_UNSPEC ? "*" : catta_proto_to_string(p));
 
-            if (catta_server_add_address(m->server, a->entry_group, a->interface->hardware->index, p, m->server->config.publish_no_reverse ? CATTA_PUBLISH_NO_REVERSE : 0, NULL, &a->address) < 0) {
+            if (catta_server_add_address(m->server, a->entry_group, a->iface->hardware->index, p, m->server->config.publish_no_reverse ? CATTA_PUBLISH_NO_REVERSE : 0, NULL, &a->address) < 0) {
                 catta_log_warn(__FILE__": catta_server_add_address() failed: %s", catta_strerror(m->server->error));
                 catta_s_entry_group_free(a->entry_group);
                 a->entry_group = NULL;
@@ -90,7 +90,7 @@ void catta_interface_address_update_rrs(CattaInterfaceAddress *a, int remove_rrs
             char t[CATTA_ADDRESS_STR_MAX];
             catta_address_snprint(t, sizeof(t), &a->address);
 
-            catta_log_info("Withdrawing address record for %s on %s.", t, a->interface->hardware->name);
+            catta_log_info("Withdrawing address record for %s on %s.", t, a->iface->hardware->name);
 
             if (catta_s_entry_group_get_state(a->entry_group) == CATTA_ENTRY_GROUP_REGISTERING &&
                 m->server->state == CATTA_SERVER_REGISTERING)
@@ -260,15 +260,15 @@ static int interface_mdns_mcast_rejoin(CattaInterface *i) {
 
 void catta_interface_address_free(CattaInterfaceAddress *a) {
     assert(a);
-    assert(a->interface);
+    assert(a->iface);
 
     catta_interface_address_update_rrs(a, 1);
-    CATTA_LLIST_REMOVE(CattaInterfaceAddress, address, a->interface->addresses, a);
+    CATTA_LLIST_REMOVE(CattaInterfaceAddress, address, a->iface->addresses, a);
 
     if (a->entry_group)
         catta_s_entry_group_free(a->entry_group);
 
-    interface_mdns_mcast_rejoin(a->interface);
+    interface_mdns_mcast_rejoin(a->iface);
 
     catta_free(a);
 }
@@ -299,7 +299,7 @@ void catta_interface_free(CattaInterface *i, int send_goodbye) {
     catta_probe_scheduler_free(i->probe_scheduler);
     catta_cache_free(i->cache);
 
-    CATTA_LLIST_REMOVE(CattaInterface, interface, i->monitor->interfaces, i);
+    CATTA_LLIST_REMOVE(CattaInterface, iface, i->monitor->interfaces, i);
     CATTA_LLIST_REMOVE(CattaInterface, by_hardware, i->hardware->interfaces, i);
 
     catta_free(i);
@@ -354,7 +354,7 @@ CattaInterface* catta_interface_new(CattaInterfaceMonitor *m, CattaHwInterface *
         goto fail; /* OOM */
 
     CATTA_LLIST_PREPEND(CattaInterface, by_hardware, hw->interfaces, i);
-    CATTA_LLIST_PREPEND(CattaInterface, interface, m->interfaces, i);
+    CATTA_LLIST_PREPEND(CattaInterface, iface, m->interfaces, i);
 
     return i;
 
@@ -416,7 +416,7 @@ CattaInterfaceAddress *catta_interface_address_new(CattaInterfaceMonitor *m, Cat
     if (!(a = catta_new(CattaInterfaceAddress, 1)))
         return NULL;
 
-    a->interface = i;
+    a->iface = i;
     a->monitor = m;
     a->address = *addr;
     a->prefix_len = prefix_len;
@@ -482,7 +482,7 @@ void catta_interface_monitor_check_relevant(CattaInterfaceMonitor *m) {
 
     assert(m);
 
-    for (i = m->interfaces; i; i = i->interface_next)
+    for (i = m->interfaces; i; i = i->iface_next)
         catta_interface_check_relevant(i);
 }
 
@@ -647,7 +647,7 @@ int catta_dump_caches(CattaInterfaceMonitor *m, CattaDumpCallback callback, void
     CattaInterface *i;
     assert(m);
 
-    for (i = m->interfaces; i; i = i->interface_next) {
+    for (i = m->interfaces; i; i = i->iface_next) {
         if (catta_interface_is_relevant(i)) {
             char ln[256];
             snprintf(ln, sizeof(ln), ";;; INTERFACE %s.%s ;;;", i->hardware->name, catta_proto_to_string(i->protocol));
@@ -706,7 +706,7 @@ int catta_interface_address_is_relevant(CattaInterfaceAddress *a) {
 
     /* Publish link-local and deprecated IP addresses only if they are
      * the only ones on the link */
-    for (b = a->interface->addresses; b; b = b->address_next) {
+    for (b = a->iface->addresses; b; b = b->address_next) {
         if (b == a)
             continue;
 
@@ -729,32 +729,32 @@ int catta_interface_match(CattaInterface *i, CattaIfIndex idx, CattaProtocol pro
     return 1;
 }
 
-void catta_interface_monitor_walk(CattaInterfaceMonitor *m, CattaIfIndex interface, CattaProtocol protocol, CattaInterfaceMonitorWalkCallback callback, void* userdata) {
+void catta_interface_monitor_walk(CattaInterfaceMonitor *m, CattaIfIndex iface, CattaProtocol protocol, CattaInterfaceMonitorWalkCallback callback, void* userdata) {
     assert(m);
     assert(callback);
 
-    if (interface != CATTA_IF_UNSPEC) {
+    if (iface != CATTA_IF_UNSPEC) {
         if (protocol != CATTA_PROTO_UNSPEC) {
             CattaInterface *i;
 
-            if ((i = catta_interface_monitor_get_interface(m, interface, protocol)))
+            if ((i = catta_interface_monitor_get_interface(m, iface, protocol)))
                 callback(m, i, userdata);
 
         } else {
             CattaHwInterface *hw;
             CattaInterface *i;
 
-            if ((hw = catta_interface_monitor_get_hw_interface(m, interface)))
+            if ((hw = catta_interface_monitor_get_hw_interface(m, iface)))
                 for (i = hw->interfaces; i; i = i->by_hardware_next)
-                    if (catta_interface_match(i, interface, protocol))
+                    if (catta_interface_match(i, iface, protocol))
                         callback(m, i, userdata);
         }
 
     } else {
         CattaInterface *i;
 
-        for (i = m->interfaces; i; i = i->interface_next)
-            if (catta_interface_match(i, interface, protocol))
+        for (i = m->interfaces; i; i = i->iface_next)
+            if (catta_interface_match(i, iface, protocol))
                 callback(m, i, userdata);
     }
 }
@@ -766,7 +766,7 @@ int catta_address_is_local(CattaInterfaceMonitor *m, const CattaAddress *a) {
     assert(m);
     assert(a);
 
-    for (i = m->interfaces; i; i = i->interface_next)
+    for (i = m->interfaces; i; i = i->iface_next)
         for (ia = i->addresses; ia; ia = ia->address_next)
             if (catta_address_cmp(a, &ia->address) == 0)
                 return 1;
@@ -850,7 +850,7 @@ CattaIfIndex catta_find_interface_for_address(CattaInterfaceMonitor *m, const Ca
      * attached. This is sometimes ambiguous, but we have to live with
      * it. */
 
-    for (i = m->interfaces; i; i = i->interface_next) {
+    for (i = m->interfaces; i; i = i->iface_next) {
         CattaInterfaceAddress *ai;
 
         if (i->protocol != a->proto)
index 22d225ee9acdfb80906ea5584716457b810f3dfd..303d230cac0524b934cf36490c856906a627d40c 100644 (file)
@@ -42,6 +42,8 @@ typedef struct CattaHwInterface CattaHwInterface;
 #include "iface-linux.h"
 #elif defined(HAVE_PF_ROUTE)
 #include "iface-pfroute.h"
+#elif defined(_WIN32)
+#include "iface-windows.h"
 #else
 typedef struct CattaInterfaceMonitorOSDep CattaInterfaceMonitorOSDep;
 struct CattaInterfaceMonitorOSDep {
@@ -96,7 +98,7 @@ struct CattaInterface {
     CattaInterfaceMonitor *monitor;
     CattaHwInterface *hardware;
 
-    CATTA_LLIST_FIELDS(CattaInterface, interface);
+    CATTA_LLIST_FIELDS(CattaInterface, iface);
     CATTA_LLIST_FIELDS(CattaInterface, by_hardware);
 
     CattaProtocol protocol;
@@ -119,7 +121,7 @@ struct CattaInterface {
 
 struct CattaInterfaceAddress {
     CattaInterfaceMonitor *monitor;
-    CattaInterface *interface;
+    CattaInterface *iface;
 
     CATTA_LLIST_FIELDS(CattaInterfaceAddress, address);
 
@@ -155,7 +157,7 @@ void catta_hw_interface_free(CattaHwInterface *hw, int send_goodbye);
 void catta_hw_interface_update_rrs(CattaHwInterface *hw, int remove_rrs);
 void catta_hw_interface_check_relevant(CattaHwInterface *hw);
 
-CattaHwInterface* catta_interface_monitor_get_hw_interface(CattaInterfaceMonitor *m, int idx);
+CattaHwInterface* catta_interface_monitor_get_hw_interface(CattaInterfaceMonitor *m, CattaIfIndex idx);
 
 /* CattaInterface */
 
index a7ee95e816ac758a6221df81c03c0270a6ccec80..59eca2ad34ed70a54ebc30aadb05c17b87a62e8f 100644 (file)
@@ -48,6 +48,16 @@ typedef struct CattaEntry CattaEntry;
 #define CATTA_RR_HOLDOFF_MSEC_RATE_LIMIT 20000
 #define CATTA_RR_RATE_LIMIT_COUNT 15
 
+#ifndef _WIN32
+#define closesocket close
+#define closepipe close
+#define writepipe write
+#define readpipe read
+#define winsock_init()
+#define winsock_exit()
+#define errnostrsocket() strerror(errno)
+#endif
+
 typedef struct CattaLegacyUnicastReflectSlot CattaLegacyUnicastReflectSlot;
 
 struct CattaLegacyUnicastReflectSlot {
@@ -56,7 +66,7 @@ struct CattaLegacyUnicastReflectSlot {
     uint16_t id, original_id;
     CattaAddress address;
     uint16_t port;
-    int interface;
+    CattaIfIndex iface;
     struct timeval elapse_time;
     CattaTimeEvent *time_event;
 };
@@ -69,7 +79,7 @@ struct CattaEntry {
 
     CattaPublishFlags flags;
     CattaRecord *record;
-    CattaIfIndex interface;
+    CattaIfIndex iface;
     CattaProtocol protocol;
 
     CATTA_LLIST_FIELDS(CattaEntry, entries);
@@ -182,13 +192,13 @@ void catta_server_decrease_host_rr_pending(CattaServer *s);
 
 int catta_server_set_errno(CattaServer *s, int error);
 
-int catta_server_is_service_local(CattaServer *s, CattaIfIndex interface, CattaProtocol protocol, const char *name);
-int catta_server_is_record_local(CattaServer *s, CattaIfIndex interface, CattaProtocol protocol, CattaRecord *record);
+int catta_server_is_service_local(CattaServer *s, CattaIfIndex iface, CattaProtocol protocol, const char *name);
+int catta_server_is_record_local(CattaServer *s, CattaIfIndex iface, CattaProtocol protocol, CattaRecord *record);
 
 int catta_server_add_ptr(
     CattaServer *s,
     CattaSEntryGroup *g,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaPublishFlags flags,
     uint32_t ttl,
index 85a13671b03c3bfbdffd71009a972ee94f2d722d..213b7b9f0732e0fe5d5c49e8520bf272f0a4fc45 100644 (file)
@@ -43,7 +43,7 @@ struct CattaMulticastLookup {
     CattaMulticastLookupCallback callback;
     void *userdata;
 
-    CattaIfIndex interface;
+    CattaIfIndex iface;
     CattaProtocol protocol;
 
     int queriers_added;
@@ -73,12 +73,12 @@ static void all_for_now_callback(CattaTimeEvent *e, void* userdata) {
     catta_time_event_free(l->all_for_now_event);
     l->all_for_now_event = NULL;
 
-    l->callback(l->engine, l->interface, l->protocol, CATTA_BROWSER_ALL_FOR_NOW, CATTA_LOOKUP_RESULT_MULTICAST, NULL, l->userdata);
+    l->callback(l->engine, l->iface, l->protocol, CATTA_BROWSER_ALL_FOR_NOW, CATTA_LOOKUP_RESULT_MULTICAST, NULL, l->userdata);
 }
 
 CattaMulticastLookup *catta_multicast_lookup_new(
     CattaMulticastLookupEngine *e,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaKey *key,
     CattaMulticastLookupCallback callback,
@@ -88,7 +88,7 @@ CattaMulticastLookup *catta_multicast_lookup_new(
     struct timeval tv;
 
     assert(e);
-    assert(CATTA_IF_VALID(interface));
+    assert(CATTA_IF_VALID(iface));
     assert(CATTA_PROTO_VALID(protocol));
     assert(key);
     assert(callback);
@@ -100,7 +100,7 @@ CattaMulticastLookup *catta_multicast_lookup_new(
     l->cname_key = catta_key_new_cname(l->key);
     l->callback = callback;
     l->userdata = userdata;
-    l->interface = interface;
+    l->iface = iface;
     l->protocol = protocol;
     l->all_for_now_event = NULL;
     l->queriers_added = 0;
@@ -111,7 +111,7 @@ CattaMulticastLookup *catta_multicast_lookup_new(
 
     CATTA_LLIST_PREPEND(CattaMulticastLookup, lookups, e->lookups, l);
 
-    catta_querier_add_for_all(e->server, interface, protocol, l->key, &tv);
+    catta_querier_add_for_all(e->server, iface, protocol, l->key, &tv);
     l->queriers_added = 1;
 
     /* Add a second */
@@ -129,7 +129,7 @@ static void lookup_stop(CattaMulticastLookup *l) {
     l->callback = NULL;
 
     if (l->queriers_added) {
-        catta_querier_remove_for_all(l->engine->server, l->interface, l->protocol, l->key);
+        catta_querier_remove_for_all(l->engine->server, l->iface, l->protocol, l->key);
         l->queriers_added = 0;
     }
 
@@ -195,7 +195,7 @@ struct cbdata {
     CattaMulticastLookupCallback callback;
     void *userdata;
     CattaKey *key, *cname_key;
-    CattaInterface *interface;
+    CattaInterface *iface;
     unsigned n_found;
 };
 
@@ -209,8 +209,8 @@ static void* scan_cache_callback(CattaCache *c, CattaKey *pattern, CattaCacheEnt
 
     cbdata->callback(
         cbdata->engine,
-        cbdata->interface->hardware->index,
-        cbdata->interface->protocol,
+        cbdata->iface->hardware->index,
+        cbdata->iface->protocol,
         CATTA_BROWSER_NEW,
         CATTA_LOOKUP_RESULT_CACHED|CATTA_LOOKUP_RESULT_MULTICAST,
         e->record,
@@ -228,19 +228,19 @@ static void scan_interface_callback(CattaInterfaceMonitor *m, CattaInterface *i,
     assert(i);
     assert(cbdata);
 
-    cbdata->interface = i;
+    cbdata->iface = i;
 
     catta_cache_walk(i->cache, cbdata->key, scan_cache_callback, cbdata);
 
     if (cbdata->cname_key)
         catta_cache_walk(i->cache, cbdata->cname_key, scan_cache_callback, cbdata);
 
-    cbdata->interface = NULL;
+    cbdata->iface = NULL;
 }
 
 unsigned catta_multicast_lookup_engine_scan_cache(
     CattaMulticastLookupEngine *e,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaKey *key,
     CattaMulticastLookupCallback callback,
@@ -252,7 +252,7 @@ unsigned catta_multicast_lookup_engine_scan_cache(
     assert(key);
     assert(callback);
 
-    assert(CATTA_IF_VALID(interface));
+    assert(CATTA_IF_VALID(iface));
     assert(CATTA_PROTO_VALID(protocol));
 
     cbdata.engine = e;
@@ -260,10 +260,10 @@ unsigned catta_multicast_lookup_engine_scan_cache(
     cbdata.cname_key = catta_key_new_cname(key);
     cbdata.callback = callback;
     cbdata.userdata = userdata;
-    cbdata.interface = NULL;
+    cbdata.iface = NULL;
     cbdata.n_found = 0;
 
-    catta_interface_monitor_walk(e->server->monitor, interface, protocol, scan_interface_callback, &cbdata);
+    catta_interface_monitor_walk(e->server->monitor, iface, protocol, scan_interface_callback, &cbdata);
 
     if (cbdata.cname_key)
         catta_key_unref(cbdata.cname_key);
@@ -282,7 +282,7 @@ void catta_multicast_lookup_engine_new_interface(CattaMulticastLookupEngine *e,
         if (l->dead || !l->callback)
             continue;
 
-        if (l->queriers_added && catta_interface_match(i, l->interface, l->protocol))
+        if (l->queriers_added && catta_interface_match(i, l->iface, l->protocol))
             catta_querier_add(i, l->key, NULL);
     }
 }
@@ -298,7 +298,7 @@ void catta_multicast_lookup_engine_notify(CattaMulticastLookupEngine *e, CattaIn
         if (l->dead || !l->callback)
             continue;
 
-        if (catta_interface_match(i, l->interface, l->protocol))
+        if (catta_interface_match(i, l->iface, l->protocol))
             l->callback(e, i->hardware->index, i->protocol, event, CATTA_LOOKUP_RESULT_MULTICAST, record, l->userdata);
     }
 
index f59229a66dfbb378b58d0cc3f47644200542ee50..7d417ade595937ae0e49252889ed0348fa80c132 100644 (file)
@@ -50,7 +50,7 @@ struct CattaProbeJob {
 };
 
 struct CattaProbeScheduler {
-    CattaInterface *interface;
+    CattaInterface *iface;
     CattaTimeEventQueue *time_event_queue;
 
     CATTA_LLIST_HEAD(CattaProbeJob, jobs);
@@ -137,7 +137,7 @@ CattaProbeScheduler *catta_probe_scheduler_new(CattaInterface *i) {
         return NULL;
     }
 
-    s->interface = i;
+    s->iface = i;
     s->time_event_queue = i->monitor->server->time_event_queue;
 
     CATTA_LLIST_HEAD_INIT(CattaProbeJob, s->jobs);
@@ -229,7 +229,7 @@ static void elapse_callback(CATTA_GCC_UNUSED CattaTimeEvent *e, void* data) {
         return;
     }
 
-    if (!(p = catta_dns_packet_new_query(s->interface->hardware->mtu)))
+    if (!(p = catta_dns_packet_new_query(s->iface->hardware->mtu)))
         return; /* OOM */
     n = 1;
 
@@ -262,7 +262,7 @@ static void elapse_callback(CATTA_GCC_UNUSED CattaTimeEvent *e, void* data) {
         if (b) {
             catta_dns_packet_set_field(p, CATTA_DNS_FIELD_NSCOUNT, 1);
             catta_dns_packet_set_field(p, CATTA_DNS_FIELD_QDCOUNT, 1);
-            catta_interface_send_packet(s->interface, p);
+            catta_interface_send_packet(s->iface, p);
         } else
             catta_log_warn("Probe record too large, cannot send");
 
@@ -314,7 +314,7 @@ static void elapse_callback(CATTA_GCC_UNUSED CattaTimeEvent *e, void* data) {
     catta_dns_packet_set_field(p, CATTA_DNS_FIELD_NSCOUNT, n);
 
     /* Send it now */
-    catta_interface_send_packet(s->interface, p);
+    catta_interface_send_packet(s->iface, p);
     catta_dns_packet_free(p);
 }
 
index dea1aa41c4e4495a1a7532f12412592b52670fcd..084bc42705f215ec3af15c064095ee6ead9b3d69 100644 (file)
@@ -32,7 +32,7 @@
 #include <catta/log.h>
 
 struct CattaQuerier {
-    CattaInterface *interface;
+    CattaInterface *iface;
 
     CattaKey *key;
     int n_used;
@@ -52,8 +52,8 @@ struct CattaQuerier {
 void catta_querier_free(CattaQuerier *q) {
     assert(q);
 
-    CATTA_LLIST_REMOVE(CattaQuerier, queriers, q->interface->queriers, q);
-    catta_hashmap_remove(q->interface->queriers_by_key, q->key);
+    CATTA_LLIST_REMOVE(CattaQuerier, queriers, q->iface->queriers, q);
+    catta_hashmap_remove(q->iface->queriers_by_key, q->key);
 
     catta_key_unref(q->key);
     catta_time_event_free(q->time_event);
@@ -77,7 +77,7 @@ static void querier_elapse_callback(CATTA_GCC_UNUSED CattaTimeEvent *e, void *us
         return;
     }
 
-    if (catta_interface_post_query(q->interface, q->key, 0, &q->post_id)) {
+    if (catta_interface_post_query(q->iface, q->key, 0, &q->post_id)) {
 
         /* The queue accepted our query. We store the query id here,
          * that allows us to drop the query at a later point if the
@@ -120,7 +120,7 @@ void catta_querier_add(CattaInterface *i, CattaKey *key, struct timeval *ret_cti
         return; /* OOM */
 
     q->key = catta_key_ref(key);
-    q->interface = i;
+    q->iface = i;
     q->n_used = 1;
     q->sec_delay = 1;
     q->post_id_valid = 0;
index 18c89719c8039e3657e79812573e9edbda739818..f1bdd127c36215a52cdec0599a7ee2d72be1cb77 100644 (file)
@@ -66,7 +66,7 @@ struct CattaKnownAnswer {
 };
 
 struct CattaQueryScheduler {
-    CattaInterface *interface;
+    CattaInterface *iface;
     CattaTimeEventQueue *time_event_queue;
 
     unsigned next_id;
@@ -157,7 +157,7 @@ CattaQueryScheduler *catta_query_scheduler_new(CattaInterface *i) {
         return NULL; /* OOM */
     }
 
-    s->interface = i;
+    s->iface = i;
     s->time_event_queue = i->monitor->server->time_event_queue;
     s->next_id = 0;
 
@@ -218,7 +218,7 @@ static int packet_add_query_job(CattaQueryScheduler *s, CattaDnsPacket *p, Catta
         return 0;
 
     /* Add all matching known answers to the list */
-    catta_cache_walk(s->interface->cache, qj->key, known_answer_walk_callback, s);
+    catta_cache_walk(s->iface->cache, qj->key, known_answer_walk_callback, s);
 
     job_mark_done(s, qj);
 
@@ -250,10 +250,10 @@ static void append_known_answers_and_send(CattaQueryScheduler *s, CattaDnsPacket
 
             catta_dns_packet_set_field(p, CATTA_DNS_FIELD_FLAGS, catta_dns_packet_get_field(p, CATTA_DNS_FIELD_FLAGS) | CATTA_DNS_FLAG_TC);
             catta_dns_packet_set_field(p, CATTA_DNS_FIELD_ANCOUNT, n);
-            catta_interface_send_packet(s->interface, p);
+            catta_interface_send_packet(s->iface, p);
             catta_dns_packet_free(p);
 
-            p = catta_dns_packet_new_query(s->interface->hardware->mtu);
+            p = catta_dns_packet_new_query(s->iface->hardware->mtu);
             n = 0;
         }
 
@@ -266,7 +266,7 @@ static void append_known_answers_and_send(CattaQueryScheduler *s, CattaDnsPacket
     }
 
     catta_dns_packet_set_field(p, CATTA_DNS_FIELD_ANCOUNT, n);
-    catta_interface_send_packet(s->interface, p);
+    catta_interface_send_packet(s->iface, p);
     catta_dns_packet_free(p);
 }
 
@@ -288,7 +288,7 @@ static void elapse_callback(CATTA_GCC_UNUSED CattaTimeEvent *e, void* data) {
 
     assert(!s->known_answers);
 
-    if (!(p = catta_dns_packet_new_query(s->interface->hardware->mtu)))
+    if (!(p = catta_dns_packet_new_query(s->iface->hardware->mtu)))
         return; /* OOM */
 
     b = packet_add_query_job(s, p, qj);
index 48dba8d0da488eb4e4f97c1c6ddbc5597ce399be..04e988e304fdafef1732a7f7cecb9a578d29ab62 100644 (file)
@@ -42,7 +42,7 @@ struct CattaSAddressResolver {
     void* userdata;
 
     CattaRecord *ptr_record;
-    CattaIfIndex interface;
+    CattaIfIndex iface;
     CattaProtocol protocol;
     CattaLookupResultFlags flags;
 
@@ -64,12 +64,12 @@ static void finish(CattaSAddressResolver *r, CattaResolverEvent event) {
 
     switch (event) {
         case CATTA_RESOLVER_FAILURE:
-            r->callback(r, r->interface, r->protocol, event, &r->address, NULL, r->flags, r->userdata);
+            r->callback(r, r->iface, r->protocol, event, &r->address, NULL, r->flags, r->userdata);
             break;
 
         case CATTA_RESOLVER_FOUND:
             assert(r->ptr_record);
-            r->callback(r, r->interface, r->protocol, event, &r->address, r->ptr_record->data.ptr.name, r->flags, r->userdata);
+            r->callback(r, r->iface, r->protocol, event, &r->address, r->ptr_record->data.ptr.name, r->flags, r->userdata);
             break;
     }
 }
@@ -97,7 +97,7 @@ static void start_timeout(CattaSAddressResolver *r) {
 
 static void record_browser_callback(
     CattaSRecordBrowser*rr,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaBrowserEvent event,
     CattaRecord *record,
@@ -114,14 +114,14 @@ static void record_browser_callback(
             assert(record);
             assert(record->key->type == CATTA_DNS_TYPE_PTR);
 
-            if (r->interface > 0 && interface != r->interface)
+            if (r->iface > 0 && iface != r->iface)
                 return;
 
             if (r->protocol != CATTA_PROTO_UNSPEC && protocol != r->protocol)
                 return;
 
-            if (r->interface <= 0)
-                r->interface = interface;
+            if (r->iface <= 0)
+                r->iface = iface;
 
             if (r->protocol == CATTA_PROTO_UNSPEC)
                 r->protocol = protocol;
@@ -160,7 +160,7 @@ static void record_browser_callback(
                 r->retry_with_multicast = 0;
 
                 catta_s_record_browser_free(r->record_browser);
-                r->record_browser = catta_s_record_browser_new(r->server, r->interface, r->protocol, r->key, CATTA_LOOKUP_USE_MULTICAST, record_browser_callback, r);
+                r->record_browser = catta_s_record_browser_new(r->server, r->iface, r->protocol, r->key, CATTA_LOOKUP_USE_MULTICAST, record_browser_callback, r);
 
                 if (r->record_browser) {
                     start_timeout(r);
@@ -176,7 +176,7 @@ static void record_browser_callback(
 
 CattaSAddressResolver *catta_s_address_resolver_new(
     CattaServer *server,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     const CattaAddress *address,
     CattaLookupFlags flags,
@@ -191,7 +191,7 @@ CattaSAddressResolver *catta_s_address_resolver_new(
     assert(address);
     assert(callback);
 
-    CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_IF_VALID(interface), CATTA_ERR_INVALID_INTERFACE);
+    CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_IF_VALID(iface), CATTA_ERR_INVALID_INTERFACE);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_PROTO_VALID(protocol), CATTA_ERR_INVALID_PROTOCOL);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, address->proto == CATTA_PROTO_INET || address->proto == CATTA_PROTO_INET6, CATTA_ERR_INVALID_PROTOCOL);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_FLAGS_VALID(flags, CATTA_LOOKUP_USE_WIDE_AREA|CATTA_LOOKUP_USE_MULTICAST), CATTA_ERR_INVALID_FLAGS);
@@ -214,7 +214,7 @@ CattaSAddressResolver *catta_s_address_resolver_new(
     r->callback = callback;
     r->userdata = userdata;
     r->ptr_record = NULL;
-    r->interface = interface;
+    r->iface = iface;
     r->protocol = protocol;
     r->flags = 0;
     r->retry_with_multicast = 0;
@@ -235,7 +235,7 @@ CattaSAddressResolver *catta_s_address_resolver_new(
         }
     }
 
-    r->record_browser = catta_s_record_browser_new(server, interface, protocol, k, flags, record_browser_callback, r);
+    r->record_browser = catta_s_record_browser_new(server, iface, protocol, k, flags, record_browser_callback, r);
 
     if (!r->record_browser) {
         catta_s_address_resolver_free(r);
index 24629bcc180e4d54723f43a72b9dafc32f75ecfc..c9fca471f14045be88a63ac34562beb44dcffdc0 100644 (file)
@@ -44,7 +44,7 @@ struct CattaSHostNameResolver {
     void* userdata;
 
     CattaRecord *address_record;
-    CattaIfIndex interface;
+    CattaIfIndex iface;
     CattaProtocol protocol;
     CattaLookupResultFlags flags;
 
@@ -82,14 +82,14 @@ static void finish(CattaSHostNameResolver *r, CattaResolverEvent event) {
                     abort();
             }
 
-            r->callback(r, r->interface, r->protocol, CATTA_RESOLVER_FOUND, r->address_record->key->name, &a, r->flags, r->userdata);
+            r->callback(r, r->iface, r->protocol, CATTA_RESOLVER_FOUND, r->address_record->key->name, &a, r->flags, r->userdata);
             break;
 
         }
 
         case CATTA_RESOLVER_FAILURE:
 
-            r->callback(r, r->interface, r->protocol, event, r->host_name, NULL, r->flags, r->userdata);
+            r->callback(r, r->iface, r->protocol, event, r->host_name, NULL, r->flags, r->userdata);
             break;
     }
 }
@@ -118,7 +118,7 @@ static void start_timeout(CattaSHostNameResolver *r) {
 
 static void record_browser_callback(
     CattaSRecordBrowser*rr,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaBrowserEvent event,
     CattaRecord *record,
@@ -136,14 +136,14 @@ static void record_browser_callback(
             assert(record);
             assert(record->key->type == CATTA_DNS_TYPE_A || record->key->type == CATTA_DNS_TYPE_AAAA);
 
-            if (r->interface > 0 && interface != r->interface)
+            if (r->iface > 0 && iface != r->iface)
                 return;
 
             if (r->protocol != CATTA_PROTO_UNSPEC && protocol != r->protocol)
                 return;
 
-            if (r->interface <= 0)
-                r->interface = interface;
+            if (r->iface <= 0)
+                r->iface = iface;
 
             if (r->protocol == CATTA_PROTO_UNSPEC)
                 r->protocol = protocol;
@@ -203,7 +203,7 @@ static void record_browser_callback(
 
 CattaSHostNameResolver *catta_s_host_name_resolver_new(
     CattaServer *server,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     const char *host_name,
     CattaProtocol aprotocol,
@@ -218,7 +218,7 @@ CattaSHostNameResolver *catta_s_host_name_resolver_new(
     assert(host_name);
     assert(callback);
 
-    CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_IF_VALID(interface), CATTA_ERR_INVALID_INTERFACE);
+    CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_IF_VALID(iface), CATTA_ERR_INVALID_INTERFACE);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_PROTO_VALID(protocol), CATTA_ERR_INVALID_PROTOCOL);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, catta_is_valid_fqdn(host_name), CATTA_ERR_INVALID_HOST_NAME);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_PROTO_VALID(aprotocol), CATTA_ERR_INVALID_PROTOCOL);
@@ -234,7 +234,7 @@ CattaSHostNameResolver *catta_s_host_name_resolver_new(
     r->callback = callback;
     r->userdata = userdata;
     r->address_record = NULL;
-    r->interface = interface;
+    r->iface = iface;
     r->protocol = protocol;
     r->flags = 0;
 
@@ -248,7 +248,7 @@ CattaSHostNameResolver *catta_s_host_name_resolver_new(
 
     if (aprotocol == CATTA_PROTO_INET || aprotocol == CATTA_PROTO_UNSPEC) {
         k = catta_key_new(host_name, CATTA_DNS_CLASS_IN, CATTA_DNS_TYPE_A);
-        r->record_browser_a = catta_s_record_browser_new(server, interface, protocol, k, flags, record_browser_callback, r);
+        r->record_browser_a = catta_s_record_browser_new(server, iface, protocol, k, flags, record_browser_callback, r);
         catta_key_unref(k);
 
         if (!r->record_browser_a)
@@ -257,7 +257,7 @@ CattaSHostNameResolver *catta_s_host_name_resolver_new(
 
     if (aprotocol == CATTA_PROTO_INET6 || aprotocol == CATTA_PROTO_UNSPEC) {
         k = catta_key_new(host_name, CATTA_DNS_CLASS_IN, CATTA_DNS_TYPE_AAAA);
-        r->record_browser_aaaa = catta_s_record_browser_new(server, interface, protocol, k, flags, record_browser_callback, r);
+        r->record_browser_aaaa = catta_s_record_browser_new(server, iface, protocol, k, flags, record_browser_callback, r);
         catta_key_unref(k);
 
         if (!r->record_browser_aaaa)
index 683c85d124b6d60e73a6c677961622f7e53ae6ea..0f6177ad95aebffadda5d0ec523bc867ef8f5a24 100644 (file)
@@ -42,7 +42,7 @@ struct CattaSServiceResolver {
     char *domain_name;
     CattaProtocol address_protocol;
 
-    CattaIfIndex interface;
+    CattaIfIndex iface;
     CattaProtocol protocol;
 
     CattaSRecordBrowser *record_browser_srv;
@@ -82,7 +82,7 @@ static void finish(CattaSServiceResolver *r, CattaResolverEvent event) {
 
             r->callback(
                 r,
-                r->interface,
+                r->iface,
                 r->protocol,
                 event,
                 r->service_name,
@@ -123,7 +123,7 @@ static void finish(CattaSServiceResolver *r, CattaResolverEvent event) {
 
             r->callback(
                 r,
-                r->interface,
+                r->iface,
                 r->protocol,
                 event,
                 r->service_name,
@@ -165,7 +165,7 @@ static void start_timeout(CattaSServiceResolver *r) {
 
 static void record_browser_callback(
     CattaSRecordBrowser*rr,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaBrowserEvent event,
     CattaRecord *record,
@@ -190,14 +190,14 @@ static void record_browser_callback(
             int changed = 0;
             assert(record);
 
-            if (r->interface > 0 && interface > 0 &&  interface != r->interface)
+            if (r->iface > 0 && iface > 0 &&  iface != r->iface)
                 return;
 
             if (r->protocol != CATTA_PROTO_UNSPEC && protocol != CATTA_PROTO_UNSPEC && protocol != r->protocol)
                 return;
 
-            if (r->interface <= 0)
-                r->interface = interface;
+            if (r->iface <= 0)
+                r->iface = iface;
 
             if (r->protocol == CATTA_PROTO_UNSPEC)
                 r->protocol = protocol;
@@ -222,13 +222,13 @@ static void record_browser_callback(
 
                             if (r->address_protocol == CATTA_PROTO_INET || r->address_protocol == CATTA_PROTO_UNSPEC) {
                                 CattaKey *k = catta_key_new(r->srv_record->data.srv.name, CATTA_DNS_CLASS_IN, CATTA_DNS_TYPE_A);
-                                r->record_browser_a = catta_s_record_browser_new(r->server, r->interface, r->protocol, k, r->user_flags & ~(CATTA_LOOKUP_NO_TXT|CATTA_LOOKUP_NO_ADDRESS), record_browser_callback, r);
+                                r->record_browser_a = catta_s_record_browser_new(r->server, r->iface, r->protocol, k, r->user_flags & ~(CATTA_LOOKUP_NO_TXT|CATTA_LOOKUP_NO_ADDRESS), record_browser_callback, r);
                                 catta_key_unref(k);
                             }
 
                             if (r->address_protocol == CATTA_PROTO_INET6 || r->address_protocol == CATTA_PROTO_UNSPEC) {
                                 CattaKey *k = catta_key_new(r->srv_record->data.srv.name, CATTA_DNS_CLASS_IN, CATTA_DNS_TYPE_AAAA);
-                                r->record_browser_aaaa = catta_s_record_browser_new(r->server, r->interface, r->protocol, k, r->user_flags & ~(CATTA_LOOKUP_NO_TXT|CATTA_LOOKUP_NO_ADDRESS), record_browser_callback, r);
+                                r->record_browser_aaaa = catta_s_record_browser_new(r->server, r->iface, r->protocol, k, r->user_flags & ~(CATTA_LOOKUP_NO_TXT|CATTA_LOOKUP_NO_ADDRESS), record_browser_callback, r);
                                 catta_key_unref(k);
                             }
                         }
@@ -377,7 +377,7 @@ static void record_browser_callback(
 
 CattaSServiceResolver *catta_s_service_resolver_new(
     CattaServer *server,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     const char *name,
     const char *type,
@@ -396,7 +396,7 @@ CattaSServiceResolver *catta_s_service_resolver_new(
     assert(type);
     assert(callback);
 
-    CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_IF_VALID(interface), CATTA_ERR_INVALID_INTERFACE);
+    CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_IF_VALID(iface), CATTA_ERR_INVALID_INTERFACE);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_PROTO_VALID(protocol), CATTA_ERR_INVALID_PROTOCOL);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, CATTA_PROTO_VALID(aprotocol), CATTA_ERR_INVALID_PROTOCOL);
     CATTA_CHECK_VALIDITY_RETURN_NULL(server, !domain || catta_is_valid_domain_name(domain), CATTA_ERR_INVALID_DOMAIN_NAME);
@@ -426,7 +426,7 @@ CattaSServiceResolver *catta_s_service_resolver_new(
     r->address_protocol = aprotocol;
     r->srv_record = r->txt_record = r->address_record = NULL;
     r->srv_flags = r->txt_flags = r->address_flags = 0;
-    r->interface = interface;
+    r->iface = iface;
     r->protocol = protocol;
     r->user_flags = flags;
     r->record_browser_a = r->record_browser_aaaa = r->record_browser_srv = r->record_browser_txt = NULL;
@@ -434,7 +434,7 @@ CattaSServiceResolver *catta_s_service_resolver_new(
     CATTA_LLIST_PREPEND(CattaSServiceResolver, resolver, server->service_resolvers, r);
 
     k = catta_key_new(n, CATTA_DNS_CLASS_IN, CATTA_DNS_TYPE_SRV);
-    r->record_browser_srv = catta_s_record_browser_new(server, interface, protocol, k, flags & ~(CATTA_LOOKUP_NO_TXT|CATTA_LOOKUP_NO_ADDRESS), record_browser_callback, r);
+    r->record_browser_srv = catta_s_record_browser_new(server, iface, protocol, k, flags & ~(CATTA_LOOKUP_NO_TXT|CATTA_LOOKUP_NO_ADDRESS), record_browser_callback, r);
     catta_key_unref(k);
 
     if (!r->record_browser_srv) {
@@ -444,7 +444,7 @@ CattaSServiceResolver *catta_s_service_resolver_new(
 
     if (!(flags & CATTA_LOOKUP_NO_TXT)) {
         k = catta_key_new(n, CATTA_DNS_CLASS_IN, CATTA_DNS_TYPE_TXT);
-        r->record_browser_txt = catta_s_record_browser_new(server, interface, protocol, k, flags & ~(CATTA_LOOKUP_NO_TXT|CATTA_LOOKUP_NO_ADDRESS),  record_browser_callback, r);
+        r->record_browser_txt = catta_s_record_browser_new(server, iface, protocol, k, flags & ~(CATTA_LOOKUP_NO_TXT|CATTA_LOOKUP_NO_ADDRESS),  record_browser_callback, r);
         catta_key_unref(k);
 
         if (!r->record_browser_txt) {
index fc3630d0413be9719ba1001d01f584bf56490db7..c6fd13c9702dc799fa2d5fe2061fcdb891f654e2 100644 (file)
@@ -66,7 +66,7 @@ struct CattaResponseJob {
 };
 
 struct CattaResponseScheduler {
-    CattaInterface *interface;
+    CattaInterface *iface;
     CattaTimeEventQueue *time_event_queue;
 
     CATTA_LLIST_HEAD(CattaResponseJob, jobs);
@@ -160,7 +160,7 @@ CattaResponseScheduler *catta_response_scheduler_new(CattaInterface *i) {
         return NULL;
     }
 
-    s->interface = i;
+    s->iface = i;
     s->time_event_queue = i->monitor->server->time_event_queue;
 
     CATTA_LLIST_HEAD_INIT(CattaResponseJob, s->jobs);
@@ -208,7 +208,7 @@ static int packet_add_response_job(CattaResponseScheduler *s, CattaDnsPacket *p,
 
     /* Ok, this record will definitely be sent, so schedule the
      * auxilliary packets, too */
-    catta_server_enumerate_aux_records(s->interface->monitor->server, s->interface, rj->record, enumerate_aux_records_callback, rj);
+    catta_server_enumerate_aux_records(s->iface->monitor->server, s->iface, rj->record, enumerate_aux_records_callback, rj);
     job_mark_done(s, rj);
 
     return 1;
@@ -221,7 +221,7 @@ static void send_response_packet(CattaResponseScheduler *s, CattaResponseJob *rj
     assert(s);
     assert(rj);
 
-    if (!(p = catta_dns_packet_new_response(s->interface->hardware->mtu, 1)))
+    if (!(p = catta_dns_packet_new_response(s->iface->hardware->mtu, 1)))
         return; /* OOM */
     n = 1;
 
@@ -258,7 +258,7 @@ static void send_response_packet(CattaResponseScheduler *s, CattaResponseJob *rj
     }
 
     catta_dns_packet_set_field(p, CATTA_DNS_FIELD_ANCOUNT, n);
-    catta_interface_send_packet(s->interface, p);
+    catta_interface_send_packet(s->iface, p);
     catta_dns_packet_free(p);
 }
 
index eeab99a208cd1196a0310344557cdc192e536317..6d9fb8ed72ee0f9eba88c8bbf80405bbeae4f04e 100644 (file)
--- a/src/rr.c
+++ b/src/rr.c
@@ -254,11 +254,11 @@ char *catta_record_to_string(const CattaRecord *r) {
 
     switch (r->key->type) {
         case CATTA_DNS_TYPE_A:
-            inet_ntop(AF_INET, &r->data.a.address.address, t = buf, sizeof(buf));
+            inet_ntop(AF_INET, (void *)&r->data.a.address.address, t = buf, sizeof(buf));
             break;
 
         case CATTA_DNS_TYPE_AAAA:
-            inet_ntop(AF_INET6, &r->data.aaaa.address.address, t = buf, sizeof(buf));
+            inet_ntop(AF_INET6, (void *)&r->data.aaaa.address.address, t = buf, sizeof(buf));
             break;
 
         case CATTA_DNS_TYPE_PTR:
index 4dc0dd0a90229883cffdf47be0c65fe22a9a96e5..fffbfdfdad85506dce2979af0518e29809fc063a 100644 (file)
@@ -506,7 +506,7 @@ static void reflect_response(CattaServer *s, CattaInterface *i, CattaRecord *r,
     if (!s->config.enable_reflector)
         return;
 
-    for (j = s->monitor->interfaces; j; j = j->interface_next)
+    for (j = s->monitor->interfaces; j; j = j->iface_next)
         if (j != i && (s->config.reflect_ipv || j->protocol == i->protocol))
             catta_interface_post_response(j, r, flush_cache, NULL, 1);
 }
@@ -541,7 +541,7 @@ static void reflect_query(CattaServer *s, CattaInterface *i, CattaKey *k) {
     if (!s->config.enable_reflector)
         return;
 
-    for (j = s->monitor->interfaces; j; j = j->interface_next)
+    for (j = s->monitor->interfaces; j; j = j->iface_next)
         if (j != i && (s->config.reflect_ipv || j->protocol == i->protocol)) {
             /* Post the query to other networks */
             catta_interface_post_query(j, k, 1, NULL);
@@ -563,7 +563,7 @@ static void reflect_probe(CattaServer *s, CattaInterface *i, CattaRecord *r) {
     if (!s->config.enable_reflector)
         return;
 
-    for (j = s->monitor->interfaces; j; j = j->interface_next)
+    for (j = s->monitor->interfaces; j; j = j->iface_next)
         if (j != i && (s->config.reflect_ipv || j->protocol == i->protocol))
             catta_interface_post_probe(j, r, 1);
 }
@@ -810,7 +810,7 @@ static void reflect_legacy_unicast_query_packet(CattaServer *s, CattaDnsPacket *
     slot->original_id = catta_dns_packet_get_field(p, CATTA_DNS_FIELD_ID);
     slot->address = *a;
     slot->port = port;
-    slot->interface = i->hardware->index;
+    slot->iface = i->hardware->index;
 
     catta_elapse_time(&slot->elapse_time, 2000, 0);
     slot->time_event = catta_time_event_new(s->time_event_queue, &slot->elapse_time, legacy_unicast_reflect_slot_timeout, slot);
@@ -818,7 +818,7 @@ static void reflect_legacy_unicast_query_packet(CattaServer *s, CattaDnsPacket *
     /* Patch the packet with our new locally generatet id */
     catta_dns_packet_set_field(p, CATTA_DNS_FIELD_ID, slot->id);
 
-    for (j = s->monitor->interfaces; j; j = j->interface_next)
+    for (j = s->monitor->interfaces; j; j = j->iface_next)
         if (j->announcing &&
             j != i &&
             (s->config.reflect_ipv || j->protocol == i->protocol)) {
@@ -849,7 +849,7 @@ static int originates_from_local_legacy_unicast_socket(CattaServer *s, const Cat
         socklen_t l = sizeof(lsa);
 
         if (getsockname(s->fd_legacy_unicast_ipv4, (struct sockaddr*) &lsa, &l) != 0)
-            catta_log_warn("getsockname(): %s", strerror(errno));
+            catta_log_warn("getsockname(): %s", errnostrsocket());
         else
             return catta_port_from_sockaddr((struct sockaddr*) &lsa) == port;
 
@@ -860,7 +860,7 @@ static int originates_from_local_legacy_unicast_socket(CattaServer *s, const Cat
         socklen_t l = sizeof(lsa);
 
         if (getsockname(s->fd_legacy_unicast_ipv6, (struct sockaddr*) &lsa, &l) != 0)
-            catta_log_warn("getsockname(): %s", strerror(errno));
+            catta_log_warn("getsockname(): %s", errnostrsocket());
         else
             return catta_port_from_sockaddr((struct sockaddr*) &lsa) == port;
     }
@@ -899,9 +899,12 @@ static void dispatch_packet(CattaServer *s, CattaDnsPacket *p, const CattaAddres
     assert(iface > 0);
     assert(src_address->proto == dst_address->proto);
 
-    if (!(i = catta_interface_monitor_get_interface(s->monitor, iface, src_address->proto)) ||
-        !i->announcing) {
-        catta_log_warn("Received packet from invalid interface.");
+    if (!(i = catta_interface_monitor_get_interface(s->monitor, iface, src_address->proto))) {
+        catta_log_warn("Received packet from unrecognized interface (%d).", iface);
+        return;
+    }
+    if (!i->announcing) {
+        catta_log_warn("Received packet from invalid interface %d (not announcing).", iface);
         return;
     }
 
@@ -1001,7 +1004,7 @@ static void dispatch_legacy_unicast_packet(CattaServer *s, CattaDnsPacket *p) {
         return;
     }
 
-    if (!(j = catta_interface_monitor_get_interface(s->monitor, slot->interface, slot->address.proto)) ||
+    if (!(j = catta_interface_monitor_get_interface(s->monitor, slot->iface, slot->address.proto)) ||
         !j->announcing)
         return;
 
@@ -1381,12 +1384,14 @@ CattaServer *catta_server_new(const CattaPoll *poll_api, const CattaServerConfig
     else
         catta_server_config_init(&s->config);
 
+    winsock_init();  // on Windows, call WSAStartup; no-op on other platforms
     if ((e = setup_sockets(s)) < 0) {
         if (error)
             *error = e;
 
         catta_server_config_free(&s->config);
         catta_free(s);
+        winsock_exit();
 
         return NULL;
     }
@@ -1515,14 +1520,14 @@ void catta_server_free(CattaServer* s) {
     /* Free sockets */
 
     if (s->fd_ipv4 >= 0)
-        close(s->fd_ipv4);
+        closesocket(s->fd_ipv4);
     if (s->fd_ipv6 >= 0)
-        close(s->fd_ipv6);
+        closesocket(s->fd_ipv6);
 
     if (s->fd_legacy_unicast_ipv4 >= 0)
-        close(s->fd_legacy_unicast_ipv4);
+        closesocket(s->fd_legacy_unicast_ipv4);
     if (s->fd_legacy_unicast_ipv6 >= 0)
-        close(s->fd_legacy_unicast_ipv6);
+        closesocket(s->fd_legacy_unicast_ipv6);
 
     /* Free other stuff */
 
@@ -1533,6 +1538,7 @@ void catta_server_free(CattaServer* s) {
     catta_server_config_free(&s->config);
 
     catta_free(s);
+    winsock_exit();  // on Windows, call WSACleanup(); no-op on other platforms
 }
 
 const char* catta_server_get_domain_name(CattaServer *s) {
@@ -1682,7 +1688,7 @@ uint32_t catta_server_get_local_service_cookie(CattaServer *s) {
     return s->local_service_cookie;
 }
 
-static CattaEntry *find_entry(CattaServer *s, CattaIfIndex interface, CattaProtocol protocol, CattaKey *key) {
+static CattaEntry *find_entry(CattaServer *s, CattaIfIndex iface, CattaProtocol protocol, CattaKey *key) {
     CattaEntry *e;
 
     assert(s);
@@ -1690,7 +1696,7 @@ static CattaEntry *find_entry(CattaServer *s, CattaIfIndex interface, CattaProto
 
     for (e = catta_hashmap_lookup(s->entries_by_key, key); e; e = e->by_key_next)
 
-        if ((e->interface == interface || e->interface <= 0 || interface <= 0) &&
+        if ((e->iface == iface || e->iface <= 0 || iface <= 0) &&
             (e->protocol == protocol || e->protocol == CATTA_PROTO_UNSPEC || protocol == CATTA_PROTO_UNSPEC) &&
             (!e->group || e->group->state == CATTA_ENTRY_GROUP_ESTABLISHED || e->group->state == CATTA_ENTRY_GROUP_REGISTERING))
 
@@ -1699,7 +1705,7 @@ static CattaEntry *find_entry(CattaServer *s, CattaIfIndex interface, CattaProto
     return NULL;
 }
 
-int catta_server_get_group_of_service(CattaServer *s, CattaIfIndex interface, CattaProtocol protocol, const char *name, const char *type, const char *domain, CattaSEntryGroup** ret_group) {
+int catta_server_get_group_of_service(CattaServer *s, CattaIfIndex iface, CattaProtocol protocol, const char *name, const char *type, const char *domain, CattaSEntryGroup** ret_group) {
     CattaKey *key = NULL;
     CattaEntry *e;
     int ret;
@@ -1710,7 +1716,7 @@ int catta_server_get_group_of_service(CattaServer *s, CattaIfIndex interface, Ca
     assert(type);
     assert(ret_group);
 
-    CATTA_CHECK_VALIDITY(s, CATTA_IF_VALID(interface), CATTA_ERR_INVALID_INTERFACE);
+    CATTA_CHECK_VALIDITY(s, CATTA_IF_VALID(iface), CATTA_ERR_INVALID_INTERFACE);
     CATTA_CHECK_VALIDITY(s, CATTA_PROTO_VALID(protocol), CATTA_ERR_INVALID_PROTOCOL);
     CATTA_CHECK_VALIDITY(s, catta_is_valid_service_name(name), CATTA_ERR_INVALID_SERVICE_NAME);
     CATTA_CHECK_VALIDITY(s, catta_is_valid_service_type_strict(type), CATTA_ERR_INVALID_SERVICE_TYPE);
@@ -1722,7 +1728,7 @@ int catta_server_get_group_of_service(CattaServer *s, CattaIfIndex interface, Ca
     if (!(key = catta_key_new(n, CATTA_DNS_CLASS_IN, CATTA_DNS_TYPE_SRV)))
         return catta_server_set_errno(s, CATTA_ERR_NO_MEMORY);
 
-    e = find_entry(s, interface, protocol, key);
+    e = find_entry(s, iface, protocol, key);
     catta_key_unref(key);
 
     if (e) {
@@ -1733,7 +1739,7 @@ int catta_server_get_group_of_service(CattaServer *s, CattaIfIndex interface, Ca
     return catta_server_set_errno(s, CATTA_ERR_NOT_FOUND);
 }
 
-int catta_server_is_service_local(CattaServer *s, CattaIfIndex interface, CattaProtocol protocol, const char *name) {
+int catta_server_is_service_local(CattaServer *s, CattaIfIndex iface, CattaProtocol protocol, const char *name) {
     CattaKey *key = NULL;
     CattaEntry *e;
 
@@ -1746,7 +1752,7 @@ int catta_server_is_service_local(CattaServer *s, CattaIfIndex interface, CattaP
     if (!(key = catta_key_new(name, CATTA_DNS_CLASS_IN, CATTA_DNS_TYPE_SRV)))
         return 0;
 
-    e = find_entry(s, interface, protocol, key);
+    e = find_entry(s, iface, protocol, key);
     catta_key_unref(key);
 
     if (!e)
@@ -1755,7 +1761,7 @@ int catta_server_is_service_local(CattaServer *s, CattaIfIndex interface, CattaP
     return catta_domain_equal(s->host_name_fqdn, e->record->data.srv.name);
 }
 
-int catta_server_is_record_local(CattaServer *s, CattaIfIndex interface, CattaProtocol protocol, CattaRecord *record) {
+int catta_server_is_record_local(CattaServer *s, CattaIfIndex iface, CattaProtocol protocol, CattaRecord *record) {
     CattaEntry *e;
 
     assert(s);
@@ -1763,7 +1769,7 @@ int catta_server_is_record_local(CattaServer *s, CattaIfIndex interface, CattaPr
 
     for (e = catta_hashmap_lookup(s->entries_by_key, record->key); e; e = e->by_key_next)
 
-        if ((e->interface == interface || e->interface <= 0 || interface <= 0) &&
+        if ((e->iface == iface || e->iface <= 0 || iface <= 0) &&
             (e->protocol == protocol || e->protocol == CATTA_PROTO_UNSPEC || protocol == CATTA_PROTO_UNSPEC) &&
             (!e->group || e->group->state == CATTA_ENTRY_GROUP_ESTABLISHED || e->group->state == CATTA_ENTRY_GROUP_REGISTERING) &&
             catta_record_equal_no_ttl(record, e->record))
index 253ad501533282b0c8b48db64d31340d426fba77..06be1d6f8eb28baf6f14261ae5609da919708430 100644 (file)
@@ -33,6 +33,9 @@
 #include <catta/malloc.h>
 #include <catta/timeval.h>
 #include <catta/simple-watch.h>
+#include <catta/log.h>
+#include "fdutil.h"                 // catta_set_nonblock
+#include "internal.h"               // closesocket
 
 struct CattaWatch {
     CattaSimplePoll *simple_poll;
@@ -98,7 +101,7 @@ void catta_simple_poll_wakeup(CattaSimplePoll *s) {
     char c = 'W';
     assert(s);
 
-    write(s->wakeup_pipe[1], &c, sizeof(c));
+    (void)writepipe(s->wakeup_pipe[1], &c, sizeof(c));
     s->wakeup_issued = 1;
 }
 
@@ -110,23 +113,10 @@ static void clear_wakeup(CattaSimplePoll *s) {
 
     s->wakeup_issued = 0;
 
-    for(;;)
-        if (read(s->wakeup_pipe[0], &c, sizeof(c)) != sizeof(c))
+    for(;;) {
+        if (readpipe(s->wakeup_pipe[0], c, sizeof(c)) != sizeof(c))
             break;
-}
-
-static int set_nonblock(int fd) {
-    int n;
-
-    assert(fd >= 0);
-
-    if ((n = fcntl(fd, F_GETFL)) < 0)
-        return -1;
-
-    if (n & O_NONBLOCK)
-        return 0;
-
-    return fcntl(fd, F_SETFL, n|O_NONBLOCK);
+    }
 }
 
 static CattaWatch* watch_new(const CattaPoll *api, int fd, CattaWatchEvent event, CattaWatchCallback callback, void *userdata) {
@@ -321,13 +311,18 @@ CattaSimplePoll *catta_simple_poll_new(void) {
     if (!(s = catta_new(CattaSimplePoll, 1)))
         return NULL;
 
+    winsock_init();  // on Windows, pipe uses sockets; no-op on other platforms
     if (pipe(s->wakeup_pipe) < 0) {
-        catta_free(s);
-        return NULL;
+        catta_log_error(__FILE__": pipe() failed: %s", errnostrsocket());
+        goto fail;
     }
 
-    set_nonblock(s->wakeup_pipe[0]);
-    set_nonblock(s->wakeup_pipe[1]);
+    if (catta_set_nonblock(s->wakeup_pipe[0]) < 0 ||
+        catta_set_nonblock(s->wakeup_pipe[1]) < 0)
+    {
+        catta_log_error(__FILE__": O_NONBLOCK failed: %s", errnostrsocket());
+        goto fail;
+    }
 
     s->api.userdata = s;
 
@@ -362,6 +357,11 @@ CattaSimplePoll *catta_simple_poll_new(void) {
     CATTA_LLIST_HEAD_INIT(CattaTimeout, s->timeouts);
 
     return s;
+
+fail:
+    catta_free(s);
+    winsock_exit();
+    return NULL;
 }
 
 void catta_simple_poll_free(CattaSimplePoll *s) {
@@ -374,12 +374,13 @@ void catta_simple_poll_free(CattaSimplePoll *s) {
     catta_free(s->pollfds);
 
     if (s->wakeup_pipe[0] >= 0)
-        close(s->wakeup_pipe[0]);
+        closepipe(s->wakeup_pipe[0]);
 
     if (s->wakeup_pipe[1] >= 0)
-        close(s->wakeup_pipe[1]);
+        closepipe(s->wakeup_pipe[1]);
 
     catta_free(s);
+    winsock_exit();  // match the winsock_init in catta_simple_poll_new
 }
 
 static int rebuild(CattaSimplePoll *s) {
@@ -552,7 +553,7 @@ int catta_simple_poll_dispatch(CattaSimplePoll *s) {
     assert(s->state == STATE_RAN);
     s->state = STATE_DISPATCHING;
 
-    /* We execute only on callback in every iteration */
+    /* We execute only one callback in every iteration */
 
     /* Check whether the wakeup time has been reached now */
     if ((next_timeout = find_next_timeout(s))) {
index a6dd588c7052416f06d391b910c6c454f48a2b66..c6b670bc0c15401ac76acda1b20a693af0e4294d 100644 (file)
@@ -50,6 +50,7 @@
 #include "fdutil.h"
 #include "socket.h"
 #include "addr-util.h"
+#include "internal.h"
 
 /* this is a portability hack */
 #ifndef IPV6_ADD_MEMBERSHIP
@@ -104,7 +105,7 @@ static void ipv6_address_to_sockaddr(struct sockaddr_in6 *ret_sa, const CattaIPv
     memcpy(&ret_sa->sin6_addr, a, sizeof(CattaIPv6Address));
 }
 
-int catta_mdns_mcast_join_ipv4(int fd, const CattaIPv4Address *a, int idx, int join) {
+int catta_mdns_mcast_join_ipv4(int fd, const CattaIPv4Address *a, CattaIfIndex idx, int join) {
 #ifdef HAVE_STRUCT_IP_MREQN
     struct ip_mreqn mreq;
 #else
@@ -130,17 +131,17 @@ int catta_mdns_mcast_join_ipv4(int fd, const CattaIPv4Address *a, int idx, int j
      * mcast groups when the iface is down, but don't allow rejoining
      * when it comes back up. This is an ugly workaround */
     if (join)
-        setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));
+        setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (void *)&mreq, sizeof(mreq));
 
-    if (setsockopt(fd, IPPROTO_IP, join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
-        catta_log_warn("%s failed: %s", join ? "IP_ADD_MEMBERSHIP" : "IP_DROP_MEMBERSHIP", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IP, join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, (void *)&mreq, sizeof(mreq)) < 0) {
+        catta_log_warn("%s failed: %s", join ? "IP_ADD_MEMBERSHIP" : "IP_DROP_MEMBERSHIP", errnostrsocket());
         return -1;
     }
 
     return 0;
 }
 
-int catta_mdns_mcast_join_ipv6(int fd, const CattaIPv6Address *a, int idx, int join) {
+int catta_mdns_mcast_join_ipv6(int fd, const CattaIPv6Address *a, CattaIfIndex idx, int join) {
     struct ipv6_mreq mreq6;
     struct sockaddr_in6 sa6;
 
@@ -154,10 +155,10 @@ int catta_mdns_mcast_join_ipv6(int fd, const CattaIPv6Address *a, int idx, int j
     mreq6.ipv6mr_interface = idx;
 
     if (join)
-        setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6));
+        setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, (void *)&mreq6, sizeof(mreq6));
 
-    if (setsockopt(fd, IPPROTO_IPV6, join ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) {
-        catta_log_warn("%s failed: %s", join ? "IPV6_ADD_MEMBERSHIP" : "IPV6_DROP_MEMBERSHIP", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, join ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP, (void *)&mreq6, sizeof(mreq6)) < 0) {
+        catta_log_warn("%s failed: %s", join ? "IPV6_ADD_MEMBERSHIP" : "IPV6_DROP_MEMBERSHIP", errnostrsocket());
         return -1;
     }
 
@@ -168,15 +169,15 @@ static int reuseaddr(int fd) {
     int yes;
 
     yes = 1;
-    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("SO_REUSEADDR failed: %s", strerror(errno));
+    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("SO_REUSEADDR failed: %s", errnostrsocket());
         return -1;
     }
 
 #ifdef SO_REUSEPORT
     yes = 1;
-    if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("SO_REUSEPORT failed: %s", strerror(errno));
+    if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("SO_REUSEPORT failed: %s", errnostrsocket());
         return -1;
     }
 #endif
@@ -190,10 +191,20 @@ static int bind_with_warn(int fd, const struct sockaddr *sa, socklen_t l) {
     assert(sa);
     assert(l > 0);
 
+#ifdef _WIN32
+    // Windows does not allow address reuse when SO_REUSEADDR was set after
+    // bind() on the first socket, so we must set it before.
+    // Note that this spoils the detection trickery below and the warning will
+    // not be logged.
+
+    if (reuseaddr(fd) < 0)
+        return -1;
+#endif
+
     if (bind(fd, sa, l) < 0) {
 
         if (errno != EADDRINUSE) {
-            catta_log_warn("bind() failed: %s", strerror(errno));
+            catta_log_warn("bind() failed: %s", errnostrsocket());
             return -1;
         }
 
@@ -205,7 +216,7 @@ static int bind_with_warn(int fd, const struct sockaddr *sa, socklen_t l) {
             return -1;
 
         if (bind(fd, sa, l) < 0) {
-            catta_log_warn("bind() failed: %s", strerror(errno));
+            catta_log_warn("bind() failed: %s", errnostrsocket());
             return -1;
         }
     } else {
@@ -226,30 +237,30 @@ static int ipv4_pktinfo(int fd) {
 
 #ifdef IP_PKTINFO
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IP_PKTINFO failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IP_PKTINFO failed: %s", errnostrsocket());
         return -1;
     }
 #else
 
 #ifdef IP_RECVINTERFACE
     yes = 1;
-    if (setsockopt (fd, IPPROTO_IP, IP_RECVINTERFACE, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IP_RECVINTERFACE failed: %s", strerror(errno));
+    if (setsockopt (fd, IPPROTO_IP, IP_RECVINTERFACE, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IP_RECVINTERFACE failed: %s", errnostrsocket());
         return -1;
     }
 #elif defined(IP_RECVIF)
     yes = 1;
-    if (setsockopt (fd, IPPROTO_IP, IP_RECVIF, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IP_RECVIF failed: %s", strerror(errno));
+    if (setsockopt (fd, IPPROTO_IP, IP_RECVIF, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IP_RECVIF failed: %s", errnostrsocket());
         return -1;
     }
 #endif
 
 #ifdef IP_RECVDSTADDR
     yes = 1;
-    if (setsockopt (fd, IPPROTO_IP, IP_RECVDSTADDR, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IP_RECVDSTADDR failed: %s", strerror(errno));
+    if (setsockopt (fd, IPPROTO_IP, IP_RECVDSTADDR, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IP_RECVDSTADDR failed: %s", errnostrsocket());
         return -1;
     }
 #endif
@@ -258,8 +269,8 @@ static int ipv4_pktinfo(int fd) {
 
 #ifdef IP_RECVTTL
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IP_RECVTTL failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IP, IP_RECVTTL, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IP_RECVTTL failed: %s", errnostrsocket());
         return -1;
     }
 #endif
@@ -272,34 +283,34 @@ static int ipv6_pktinfo(int fd) {
 
 #ifdef IPV6_RECVPKTINFO
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IPV6_RECVPKTINFO failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IPV6_RECVPKTINFO failed: %s", errnostrsocket());
         return -1;
     }
 #elif defined(IPV6_PKTINFO)
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IPV6_PKTINFO failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IPV6_PKTINFO failed: %s", errnostrsocket());
         return -1;
     }
 #endif
 
 #ifdef IPV6_RECVHOPS
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPS, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IPV6_RECVHOPS failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPS, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IPV6_RECVHOPS failed: %s", errnostrsocket());
         return -1;
     }
 #elif defined(IPV6_RECVHOPLIMIT)
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IPV6_RECVHOPLIMIT failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IPV6_RECVHOPLIMIT failed: %s", errnostrsocket());
         return -1;
     }
 #elif defined(IPV6_HOPLIMIT)
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_HOPLIMIT, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IPV6_HOPLIMIT failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_HOPLIMIT, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IPV6_HOPLIMIT failed: %s", errnostrsocket());
         return -1;
     }
 #endif
@@ -313,25 +324,25 @@ int catta_open_socket_ipv4(int no_reuse) {
     uint8_t ttl, cyes;
 
     if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-        catta_log_warn("socket() failed: %s", strerror(errno));
+        catta_log_warn("socket() failed: %s", errnostrsocket());
         goto fail;
     }
 
     ttl = 255;
-    if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) {
-        catta_log_warn("IP_MULTICAST_TTL failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&ttl, sizeof(ttl)) < 0) {
+        catta_log_warn("IP_MULTICAST_TTL failed: %s", errnostrsocket());
         goto fail;
     }
 
     ittl = 255;
-    if (setsockopt(fd, IPPROTO_IP, IP_TTL, &ittl, sizeof(ittl)) < 0) {
-        catta_log_warn("IP_TTL failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IP, IP_TTL, (void *)&ittl, sizeof(ittl)) < 0) {
+        catta_log_warn("IP_TTL failed: %s", errnostrsocket());
         goto fail;
     }
 
     cyes = 1;
-    if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &cyes, sizeof(cyes)) < 0) {
-        catta_log_warn("IP_MULTICAST_LOOP failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (void *)&cyes, sizeof(cyes)) < 0) {
+        catta_log_warn("IP_MULTICAST_LOOP failed: %s", errnostrsocket());
         goto fail;
     }
 
@@ -351,12 +362,12 @@ int catta_open_socket_ipv4(int no_reuse) {
          goto fail;
 
     if (catta_set_cloexec(fd) < 0) {
-        catta_log_warn("FD_CLOEXEC failed: %s", strerror(errno));
+        catta_log_warn("FD_CLOEXEC failed: %s", errnostrsocket());
         goto fail;
     }
 
     if (catta_set_nonblock(fd) < 0) {
-        catta_log_warn("O_NONBLOCK failed: %s", strerror(errno));
+        catta_log_warn("O_NONBLOCK failed: %s", errnostrsocket());
         goto fail;
     }
 
@@ -364,7 +375,7 @@ int catta_open_socket_ipv4(int no_reuse) {
 
 fail:
     if (fd >= 0)
-        close(fd);
+        closesocket(fd);
 
     return -1;
 }
@@ -377,31 +388,31 @@ int catta_open_socket_ipv6(int no_reuse) {
     mdns_mcast_group_ipv6(&sa);
 
     if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
-        catta_log_warn("socket() failed: %s", strerror(errno));
+        catta_log_warn("socket() failed: %s", errnostrsocket());
         goto fail;
     }
 
     ttl = 255;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl)) < 0) {
-        catta_log_warn("IPV6_MULTICAST_HOPS failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (void *)&ttl, sizeof(ttl)) < 0) {
+        catta_log_warn("IPV6_MULTICAST_HOPS failed: %s", errnostrsocket());
         goto fail;
     }
 
     ttl = 255;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)) < 0) {
-        catta_log_warn("IPV6_UNICAST_HOPS failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (void *)&ttl, sizeof(ttl)) < 0) {
+        catta_log_warn("IPV6_UNICAST_HOPS failed: %s", errnostrsocket());
         goto fail;
     }
 
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IPV6_V6ONLY failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IPV6_V6ONLY failed: %s", errnostrsocket());
         goto fail;
     }
 
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IPV6_MULTICAST_LOOP failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IPV6_MULTICAST_LOOP failed: %s", errnostrsocket());
         goto fail;
     }
 
@@ -421,12 +432,12 @@ int catta_open_socket_ipv6(int no_reuse) {
         goto fail;
 
     if (catta_set_cloexec(fd) < 0) {
-        catta_log_warn("FD_CLOEXEC failed: %s", strerror(errno));
+        catta_log_warn("FD_CLOEXEC failed: %s", errnostrsocket());
         goto fail;
     }
 
     if (catta_set_nonblock(fd) < 0) {
-        catta_log_warn("O_NONBLOCK failed: %s", strerror(errno));
+        catta_log_warn("O_NONBLOCK failed: %s", errnostrsocket());
         goto fail;
     }
 
@@ -434,7 +445,7 @@ int catta_open_socket_ipv6(int no_reuse) {
 
 fail:
     if (fd >= 0)
-        close(fd);
+        closesocket(fd);
 
     return -1;
 }
@@ -451,12 +462,15 @@ static int sendmsg_loop(int fd, struct msghdr *msg, int flags) {
         if (errno == EINTR)
             continue;
 
-        if (errno != EAGAIN) {
+        if (errno != EAGAIN && errno != EWOULDBLOCK) {
             char where[64];
-            struct sockaddr_in *sin = msg->msg_name;
+            struct sockaddr *sa = msg->msg_name;
 
-            inet_ntop(sin->sin_family, &sin->sin_addr, where, sizeof(where));
-            catta_log_debug("sendmsg() to %s failed: %s", where, strerror(errno));
+            if(sa->sa_family == AF_INET)
+                inet_ntop(sa->sa_family, &((struct sockaddr_in *)sa)->sin_addr, where, sizeof(where));
+            else
+                inet_ntop(sa->sa_family, &((struct sockaddr_in6 *)sa)->sin6_addr, where, sizeof(where));
+            catta_log_debug("sendmsg() to %s failed: %s", where, errnostrsocket());
             return -1;
         }
 
@@ -469,7 +483,7 @@ static int sendmsg_loop(int fd, struct msghdr *msg, int flags) {
 
 int catta_send_dns_packet_ipv4(
         int fd,
-        CattaIfIndex interface,
+        CattaIfIndex iface,
         CattaDnsPacket *p,
         const CattaIPv4Address *src_address,
         const CattaIPv4Address *dst_address,
@@ -510,7 +524,7 @@ int catta_send_dns_packet_ipv4(
     msg.msg_controllen = 0;
 
 #ifdef IP_PKTINFO
-    if (interface > 0 || src_address) {
+    if (iface > 0 || src_address) {
         struct in_pktinfo *pkti;
 
         memset(cmsg_data, 0, sizeof(cmsg_data));
@@ -524,17 +538,22 @@ int catta_send_dns_packet_ipv4(
 
         pkti = (struct in_pktinfo*) CMSG_DATA(cmsg);
 
-        if (interface > 0)
-            pkti->ipi_ifindex = interface;
+        if (iface > 0)
+            pkti->ipi_ifindex = iface;
 
+#ifdef HAVE_IPI_SPEC_DST
         if (src_address)
             pkti->ipi_spec_dst.s_addr = src_address->address;
+#else
+        if (src_address)
+            pkti->ipi_addr.s_addr = src_address->address;
+#endif
     }
 #elif defined(IP_MULTICAST_IF)
     if (src_address) {
         struct in_addr any = { INADDR_ANY };
-        if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, src_address ? &src_address->address : &any, sizeof(struct in_addr)) < 0) {
-            catta_log_warn("IP_MULTICAST_IF failed: %s", strerror(errno));
+        if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (void *)(src_address ? &src_address->address : &any), sizeof(struct in_addr)) < 0) {
+            catta_log_warn("IP_MULTICAST_IF failed: %s", errnostrsocket());
             return -1;
         }
     }
@@ -563,7 +582,7 @@ int catta_send_dns_packet_ipv4(
 
 int catta_send_dns_packet_ipv6(
         int fd,
-        CattaIfIndex interface,
+        CattaIfIndex iface,
         CattaDnsPacket *p,
         const CattaIPv6Address *src_address,
         const CattaIPv6Address *dst_address,
@@ -596,7 +615,7 @@ int catta_send_dns_packet_ipv6(
     msg.msg_iovlen = 1;
     msg.msg_flags = 0;
 
-    if (interface > 0 || src_address) {
+    if (iface > 0 || src_address) {
         struct in6_pktinfo *pkti;
 
         memset(cmsg_data, 0, sizeof(cmsg_data));
@@ -610,8 +629,8 @@ int catta_send_dns_packet_ipv6(
 
         pkti = (struct in6_pktinfo*) CMSG_DATA(cmsg);
 
-        if (interface > 0)
-            pkti->ipi6_ifindex = interface;
+        if (iface > 0)
+            pkti->ipi6_ifindex = iface;
 
         if (src_address)
             memcpy(&pkti->ipi6_addr, src_address->address, sizeof(src_address->address));
@@ -644,7 +663,7 @@ CattaDnsPacket *catta_recv_dns_packet_ipv4(
     assert(fd >= 0);
 
     if (ioctl(fd, FIONREAD, &ms) < 0) {
-        catta_log_warn("ioctl(): %s", strerror(errno));
+        catta_log_warn("ioctl(): %s", errnostrsocket());
         goto fail;
     }
 
@@ -674,7 +693,7 @@ CattaDnsPacket *catta_recv_dns_packet_ipv4(
         links. (See #60) */
 
         if (errno != EAGAIN)
-            catta_log_warn("recvmsg(): %s", strerror(errno));
+            catta_log_warn("recvmsg(): %s", errnostrsocket());
 
         goto fail;
     }
@@ -805,7 +824,7 @@ CattaDnsPacket *catta_recv_dns_packet_ipv6(
     assert(fd >= 0);
 
     if (ioctl(fd, FIONREAD, &ms) < 0) {
-        catta_log_warn("ioctl(): %s", strerror(errno));
+        catta_log_warn("ioctl(): %s", errnostrsocket());
         goto fail;
     }
 
@@ -836,7 +855,7 @@ CattaDnsPacket *catta_recv_dns_packet_ipv6(
         links. (See #60) */
 
         if (errno != EAGAIN)
-            catta_log_warn("recvmsg(): %s", strerror(errno));
+            catta_log_warn("recvmsg(): %s", errnostrsocket());
 
         goto fail;
     }
@@ -912,7 +931,7 @@ int catta_open_unicast_socket_ipv4(void) {
     int fd = -1;
 
     if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-        catta_log_warn("socket() failed: %s", strerror(errno));
+        catta_log_warn("socket() failed: %s", errnostrsocket());
         goto fail;
     }
 
@@ -920,7 +939,7 @@ int catta_open_unicast_socket_ipv4(void) {
     local.sin_family = AF_INET;
 
     if (bind(fd, (struct sockaddr*) &local, sizeof(local)) < 0) {
-        catta_log_warn("bind() failed: %s", strerror(errno));
+        catta_log_warn("bind() failed: %s", errnostrsocket());
         goto fail;
     }
 
@@ -929,12 +948,12 @@ int catta_open_unicast_socket_ipv4(void) {
     }
 
     if (catta_set_cloexec(fd) < 0) {
-        catta_log_warn("FD_CLOEXEC failed: %s", strerror(errno));
+        catta_log_warn("FD_CLOEXEC failed: %s", errnostrsocket());
         goto fail;
     }
 
     if (catta_set_nonblock(fd) < 0) {
-        catta_log_warn("O_NONBLOCK failed: %s", strerror(errno));
+        catta_log_warn("O_NONBLOCK failed: %s", errnostrsocket());
         goto fail;
     }
 
@@ -942,7 +961,7 @@ int catta_open_unicast_socket_ipv4(void) {
 
 fail:
     if (fd >= 0)
-        close(fd);
+        closesocket(fd);
 
     return -1;
 }
@@ -952,13 +971,13 @@ int catta_open_unicast_socket_ipv6(void) {
     int fd = -1, yes;
 
     if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
-        catta_log_warn("socket() failed: %s", strerror(errno));
+        catta_log_warn("socket() failed: %s", errnostrsocket());
         goto fail;
     }
 
     yes = 1;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes)) < 0) {
-        catta_log_warn("IPV6_V6ONLY failed: %s", strerror(errno));
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&yes, sizeof(yes)) < 0) {
+        catta_log_warn("IPV6_V6ONLY failed: %s", errnostrsocket());
         goto fail;
     }
 
@@ -966,7 +985,7 @@ int catta_open_unicast_socket_ipv6(void) {
     local.sin6_family = AF_INET6;
 
     if (bind(fd, (struct sockaddr*) &local, sizeof(local)) < 0) {
-        catta_log_warn("bind() failed: %s", strerror(errno));
+        catta_log_warn("bind() failed: %s", errnostrsocket());
         goto fail;
     }
 
@@ -974,12 +993,12 @@ int catta_open_unicast_socket_ipv6(void) {
         goto fail;
 
     if (catta_set_cloexec(fd) < 0) {
-        catta_log_warn("FD_CLOEXEC failed: %s", strerror(errno));
+        catta_log_warn("FD_CLOEXEC failed: %s", errnostrsocket());
         goto fail;
     }
 
     if (catta_set_nonblock(fd) < 0) {
-        catta_log_warn("O_NONBLOCK failed: %s", strerror(errno));
+        catta_log_warn("O_NONBLOCK failed: %s", errnostrsocket());
         goto fail;
     }
 
@@ -987,7 +1006,7 @@ int catta_open_unicast_socket_ipv6(void) {
 
 fail:
     if (fd >= 0)
-        close(fd);
+        closesocket(fd);
 
     return -1;
 }
index 59da2a8441d572d2cd8aaa3efa2b1e551d8b60e8..dab7220e7ba840c84122c86474bf8f56cd075951 100644 (file)
@@ -41,7 +41,7 @@ int catta_send_dns_packet_ipv6(int fd, CattaIfIndex iface, CattaDnsPacket *p, co
 CattaDnsPacket *catta_recv_dns_packet_ipv4(int fd, CattaIPv4Address *ret_src_address, uint16_t *ret_src_port, CattaIPv4Address *ret_dst_address, CattaIfIndex *ret_iface, uint8_t *ret_ttl);
 CattaDnsPacket *catta_recv_dns_packet_ipv6(int fd, CattaIPv6Address *ret_src_address, uint16_t *ret_src_port, CattaIPv6Address *ret_dst_address, CattaIfIndex *ret_iface, uint8_t *ret_ttl);
 
-int catta_mdns_mcast_join_ipv4(int fd, const CattaIPv4Address *local_address, int iface, int join);
-int catta_mdns_mcast_join_ipv6(int fd, const CattaIPv6Address *local_address, int iface, int join);
+int catta_mdns_mcast_join_ipv4(int fd, const CattaIPv4Address *local_address, CattaIfIndex iface, int join);
+int catta_mdns_mcast_join_ipv6(int fd, const CattaIPv6Address *local_address, CattaIfIndex iface, int join);
 
 #endif
index aa22bf993205c065747a559866c4fdc706c0b6af..b20b8979aa1b91e8595b4bd71e227b866402a837 100644 (file)
@@ -61,11 +61,14 @@ static int poll_func(struct pollfd *ufds, unsigned int nfds, int timeout, void *
 
 static void* thread(void *userdata){
     CattaThreadedPoll *p = userdata;
+
+#ifndef _WIN32
     sigset_t mask;
 
     /* Make sure that signals are delivered to the main thread */
     sigfillset(&mask);
     pthread_sigmask(SIG_BLOCK, &mask, NULL);
+#endif
 
     pthread_mutex_lock(&p->mutex);
     p->retval = catta_simple_poll_loop(p->simple_poll);
index 2ae6d2d655dd691ef41ab0d43bdbf52f6e4bcf2e..d5237d32142333aae6333ff0a7f5842167e89686 100644 (file)
@@ -581,13 +581,13 @@ CattaWideAreaLookupEngine *catta_wide_area_engine_new(CattaServer *s) {
     e->fd_ipv6 = s->config.use_ipv6 ? catta_open_unicast_socket_ipv6() : -1;
 
     if (e->fd_ipv4 < 0 && e->fd_ipv6 < 0) {
-        catta_log_error(__FILE__": Failed to create wide area sockets: %s", strerror(errno));
+        catta_log_error(__FILE__": Failed to create wide area sockets: %s", errnostrsocket());
 
         if (e->fd_ipv6 >= 0)
-            close(e->fd_ipv6);
+            closesocket(e->fd_ipv6);
 
         if (e->fd_ipv4 >= 0)
-            close(e->fd_ipv4);
+            closesocket(e->fd_ipv4);
 
         catta_free(e);
         return NULL;
@@ -637,10 +637,10 @@ void catta_wide_area_engine_free(CattaWideAreaLookupEngine *e) {
         e->server->poll_api->watch_free(e->watch_ipv6);
 
     if (e->fd_ipv6 >= 0)
-        close(e->fd_ipv6);
+        closesocket(e->fd_ipv6);
 
     if (e->fd_ipv4 >= 0)
-        close(e->fd_ipv4);
+        closesocket(e->fd_ipv4);
 
     catta_free(e);
 }
index 8cd35c3b5db552db7019e5ce4f1186eb05cc965e..5b144658c8b892e5965c7af767926d8e8c50ccc4 100644 (file)
@@ -35,16 +35,20 @@ noinst_PROGRAMS = \
        conformance-test \
        catta-reflector \
        dns-test \
-       dns-spin-test \
        timeeventq-test \
        hashmap-test \
        querier-test \
        update-test
 
 TESTS = \
-       dns-spin-test \
        dns-test \
        hashmap-test
+
+# disable the dns-spin-test on Windows (needs setitimer)
+if !WINDOWS
+noinst_PROGRAMS += dns-spin-test
+TESTS += dns-spin-test
+endif
 endif
 
 
index 000828239de72c62202493ae6d9b3b6b27a97824..359df9e86b084f478d3bd61b29abf532600ad806 100644 (file)
@@ -89,7 +89,7 @@ static const char *resolver_event_to_string(CattaResolverEvent event) {
 
 static void record_browser_callback(
     CattaSRecordBrowser *r,
-    CattaIfIndex interface,
+    CattaIfIndex iface,
     CattaProtocol protocol,
     CattaBrowserEvent event,
     CattaRecord *record,
@@ -100,7 +100,7 @@ static void record_browser_callback(
     assert(r);
 
     if (record) {
-        catta_log_debug("RB: record [%s] on %i.%i is %s", t = catta_record_to_string(record), interface, protocol, browser_event_to_string(event));
+        catta_log_debug("RB: record [%s] on %i.%i is %s", t = catta_record_to_string(record), iface, protocol, browser_event_to_string(event));
         catta_free(t);
     } else
         catta_log_debug("RB: [%s]", browser_event_to_string(event));
index b01068cf9a192b4d7c684a0b42052b6d58f0f2ac..d9f9f19546dcc85a152df0cb56b175ec8a40b5f8 100644 (file)
@@ -90,7 +90,7 @@ int main(CATTA_GCC_UNUSED int argc, CATTA_GCC_UNUSED char *argv[]) {
     srand(time(NULL));
 
     for (i = 0; i < 10000; i++)
-        catta_prio_queue_put(q2, catta_prio_queue_put(q, INT_TO_POINTER(random() & 0xFFFF)));
+        catta_prio_queue_put(q2, catta_prio_queue_put(q, INT_TO_POINTER(rand() & 0xFFFF)));
 
     while (q2->root) {
         rec(q->root);
index 496f80a6f460f7fc32a5c7c80b778ff6fc95dc9a..0c74e8858013b0312e9146f9b96c379fc2cab8e6 100644 (file)
@@ -59,7 +59,7 @@ int main(CATTA_GCC_UNUSED int argc, CATTA_GCC_UNUSED char *argv[]) {
     size = catta_string_list_serialize(a, data, sizeof(data));
     assert(size == n);
 
-    printf("%zu\n", size);
+    printf("%lu\n", (unsigned long)size);
 
     for (t = (char*) data, n = 0; n < size; n++, t++) {
         if (*t <= 32)
index 75f50d4e3a77db81e4bfadc6b5a8234e3ed40507..56b0a34838e7d53e6f2c67de0bafe1a8687cf7ae 100644 (file)
@@ -37,7 +37,7 @@ int main(CATTA_GCC_UNUSED int argc, CATTA_GCC_UNUSED char *argv[]) {
 
     printf("%li.%li\n", a.tv_sec, a.tv_usec);
 
-    printf("%lli\n", (long long) catta_timeval_diff(&a, &b));
+    printf("%li\n", (long) catta_timeval_diff(&a, &b));
 
     return 0;
 }