From: Niklas Date: Mon, 20 Oct 2014 12:08:11 +0000 (+0200) Subject: Merge pull request #2 from everbase/feature/windows X-Git-Url: http://git.meshlink.io/?p=catta;a=commitdiff_plain;h=ba51d86d35c7686fe64e861e14177bec0a993e42;hp=a4c3af8516b1384e2856904719e75cda5bf6d669 Merge pull request #2 from everbase/feature/windows Port the library to Windows --- diff --git a/.gitignore b/.gitignore index 2059c26..fb0a069 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,7 @@ ltmain.sh missing stamp-h1 .*.swp +.*.swo test-driver +*.exe +.dirstamp diff --git a/configure.ac b/configure.ac index 5925560..cabd87b 100644 --- a/configure.ac +++ b/configure.ac @@ -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 ]]) + # -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} " diff --git a/examples/core-browse-services.c b/examples/core-browse-services.c index 44f8ece..e8f4aad 100644 --- a/examples/core-browse-services.c +++ b/examples/core-browse-services.c @@ -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; diff --git a/examples/core-publish-service.c b/examples/core-publish-service.c index 8d6377e..1d5ce9d 100644 --- a/examples/core-publish-service.c +++ b/examples/core-publish-service.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include @@ -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); diff --git a/include/catta/address.h b/include/catta/address.h index f10f33b..ad8e93b 100644 --- a/include/catta/address.h +++ b/include/catta/address.h @@ -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)) diff --git a/include/catta/llist.h b/include/catta/llist.h index a2321b6..59a7274 100644 --- a/include/catta/llist.h +++ b/include/catta/llist.h @@ -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); \ diff --git a/include/catta/lookup.h b/include/catta/lookup.h index ebdc92a..c6d69db 100644 --- a/include/catta/lookup.h +++ b/include/catta/lookup.h @@ -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, diff --git a/include/catta/publish.h b/include/catta/publish.h index 1176b1f..ac39c96 100644 --- a/include/catta/publish.h +++ b/include/catta/publish.h @@ -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 diff --git a/m4/acx_pthread.m4 b/m4/acx_pthread.m4 index dcf6332..1cada4d 100644 --- a/m4/acx_pthread.m4 +++ b/m4/acx_pthread.m4 @@ -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" diff --git a/src/Makefile.am b/src/Makefile.am index 236f951..3b3a058 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 + diff --git a/src/address.c b/src/address.c index c207fdc..7eced15 100644 --- a/src/address.c +++ b/src/address.c @@ -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; diff --git a/src/announce.c b/src/announce.c index 06e96e7..e2b0757 100644 --- a/src/announce.c +++ b/src/announce.c @@ -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) { diff --git a/src/announce.h b/src/announce.h index e8e62dc..3a2a400 100644 --- a/src/announce.h +++ b/src/announce.h @@ -37,7 +37,7 @@ typedef enum { struct CattaAnnouncer { CattaServer *server; - CattaInterface *interface; + CattaInterface *iface; CattaEntry *entry; CattaTimeEvent *time_event; diff --git a/src/browse-dns-server.c b/src/browse-dns-server.c index 640ec51..12b529f 100644 --- a/src/browse-dns-server.c +++ b/src/browse-dns-server.c @@ -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); diff --git a/src/browse-domain.c b/src/browse-domain.c index 8ae99e4..691cfba 100644 --- a/src/browse-domain.c +++ b/src/browse-domain.c @@ -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); diff --git a/src/browse-service-type.c b/src/browse-service-type.c index 4d40a82..41c171e 100644 --- a/src/browse-service-type.c +++ b/src/browse-service-type.c @@ -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); diff --git a/src/browse-service.c b/src/browse-service.c index 4a4c8df..3b09695 100644 --- a/src/browse-service.c +++ b/src/browse-service.c @@ -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); diff --git a/src/browse.c b/src/browse.c index 0324499..d8f70e6 100644 --- a/src/browse.c +++ b/src/browse.c @@ -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; diff --git a/src/browse.h b/src/browse.h index 76b7a6d..1fccf23 100644 --- a/src/browse.h +++ b/src/browse.h @@ -36,7 +36,7 @@ struct CattaSRecordBrowser { CattaServer *server; CattaKey *key; - CattaIfIndex interface; + CattaIfIndex iface; CattaProtocol protocol; CattaLookupFlags flags; diff --git a/src/cache.c b/src/cache.c index f4203eb..de7b369 100644 --- a/src/cache.c +++ b/src/cache.c @@ -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; diff --git a/src/cache.h b/src/cache.h index a205b70..c3741e1 100644 --- a/src/cache.h +++ b/src/cache.h @@ -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 index 0000000..cc77ee8 --- /dev/null +++ b/src/compat/windows/include/arpa/inet.h @@ -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 index 0000000..cc77ee8 --- /dev/null +++ b/src/compat/windows/include/net/if.h @@ -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 index 0000000..cc77ee8 --- /dev/null +++ b/src/compat/windows/include/netinet/in.h @@ -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 index 0000000..cc77ee8 --- /dev/null +++ b/src/compat/windows/include/sys/ioctl.h @@ -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 index 0000000..cc77ee8 --- /dev/null +++ b/src/compat/windows/include/sys/poll.h @@ -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 index 0000000..cc77ee8 --- /dev/null +++ b/src/compat/windows/include/sys/select.h @@ -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 index 0000000..cc77ee8 --- /dev/null +++ b/src/compat/windows/include/sys/socket.h @@ -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 index 0000000..cc77ee8 --- /dev/null +++ b/src/compat/windows/include/sys/uio.h @@ -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 index 0000000..cc77ee8 --- /dev/null +++ b/src/compat/windows/include/sys/utsname.h @@ -0,0 +1 @@ +#include "../../wincompat.h" diff --git a/src/compat/windows/wincompat.c b/src/compat/windows/wincompat.c new file mode 100644 index 0000000..d56e0a6 --- /dev/null +++ b/src/compat/windows/wincompat.c @@ -0,0 +1,314 @@ +#include "wincompat.h" +#include +#include +#include +#include + +#include + +// 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; imsg_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; imsg_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 index 0000000..f611e33 --- /dev/null +++ b/src/compat/windows/wincompat.h @@ -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 +#include +#include + + +// 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 diff --git a/src/dns-srv-rr.h b/src/dns-srv-rr.h index e028f2b..d2c0dbf 100644 --- a/src/dns-srv-rr.h +++ b/src/dns-srv-rr.h @@ -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, diff --git a/src/entry.c b/src/entry.c index a56e0bd..afa972a 100644 --- a/src/entry.c +++ b/src/entry.c @@ -30,7 +30,6 @@ #include -#include #include #include @@ -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); diff --git a/src/error.c b/src/error.c index 543d1b1..c4199ed 100644 --- a/src/error.c +++ b/src/error.c @@ -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", diff --git a/src/fdutil.c b/src/fdutil.c index c483ce8..ca5f65b 100644 --- a/src/fdutil.c +++ b/src/fdutil.c @@ -23,9 +23,14 @@ #include #include -#include #include +#ifdef HAVE_FCNTL +#include +#else +#include +#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) { diff --git a/src/iface-none.c b/src/iface-none.c index 5dda582..7f2840a 100644 --- a/src/iface-none.c +++ b/src/iface-none.c @@ -20,11 +20,15 @@ #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 index 0000000..1d8d0f3 --- /dev/null +++ b/src/iface-windows.c @@ -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 // wcstombs +#include +#include +#include +#include +#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 index 0000000..f7be1f7 --- /dev/null +++ b/src/iface-windows.h @@ -0,0 +1,26 @@ +#ifndef fooifacewindowshfoo +#define fooifacewindowshfoo + +#include +#include + +// 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 diff --git a/src/iface.c b/src/iface.c index 0940d63..8ab84a4 100644 --- a/src/iface.c +++ b/src/iface.c @@ -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) diff --git a/src/iface.h b/src/iface.h index 22d225e..303d230 100644 --- a/src/iface.h +++ b/src/iface.h @@ -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 */ diff --git a/src/internal.h b/src/internal.h index a7ee95e..59eca2a 100644 --- a/src/internal.h +++ b/src/internal.h @@ -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, diff --git a/src/multicast-lookup.c b/src/multicast-lookup.c index 85a1367..213b7b9 100644 --- a/src/multicast-lookup.c +++ b/src/multicast-lookup.c @@ -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); } diff --git a/src/probe-sched.c b/src/probe-sched.c index f59229a..7d417ad 100644 --- a/src/probe-sched.c +++ b/src/probe-sched.c @@ -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); } diff --git a/src/querier.c b/src/querier.c index dea1aa4..084bc42 100644 --- a/src/querier.c +++ b/src/querier.c @@ -32,7 +32,7 @@ #include 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; diff --git a/src/query-sched.c b/src/query-sched.c index 18c8971..f1bdd12 100644 --- a/src/query-sched.c +++ b/src/query-sched.c @@ -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); diff --git a/src/resolve-address.c b/src/resolve-address.c index 48dba8d..04e988e 100644 --- a/src/resolve-address.c +++ b/src/resolve-address.c @@ -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); diff --git a/src/resolve-host-name.c b/src/resolve-host-name.c index 24629bc..c9fca47 100644 --- a/src/resolve-host-name.c +++ b/src/resolve-host-name.c @@ -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) diff --git a/src/resolve-service.c b/src/resolve-service.c index 683c85d..0f6177a 100644 --- a/src/resolve-service.c +++ b/src/resolve-service.c @@ -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) { diff --git a/src/response-sched.c b/src/response-sched.c index fc3630d..c6fd13c 100644 --- a/src/response-sched.c +++ b/src/response-sched.c @@ -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); } diff --git a/src/rr.c b/src/rr.c index eeab99a..6d9fb8e 100644 --- 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: diff --git a/src/server.c b/src/server.c index 4dc0dd0..fffbfdf 100644 --- a/src/server.c +++ b/src/server.c @@ -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)) diff --git a/src/simple-watch.c b/src/simple-watch.c index 253ad50..06be1d6 100644 --- a/src/simple-watch.c +++ b/src/simple-watch.c @@ -33,6 +33,9 @@ #include #include #include +#include +#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))) { diff --git a/src/socket.c b/src/socket.c index a6dd588..c6b670b 100644 --- a/src/socket.c +++ b/src/socket.c @@ -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; } diff --git a/src/socket.h b/src/socket.h index 59da2a8..dab7220 100644 --- a/src/socket.h +++ b/src/socket.h @@ -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 diff --git a/src/thread-watch.c b/src/thread-watch.c index aa22bf9..b20b897 100644 --- a/src/thread-watch.c +++ b/src/thread-watch.c @@ -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); diff --git a/src/wide-area.c b/src/wide-area.c index 2ae6d2d..d5237d3 100644 --- a/src/wide-area.c +++ b/src/wide-area.c @@ -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); } diff --git a/tests/Makefile.am b/tests/Makefile.am index 8cd35c3..5b14465 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 diff --git a/tests/catta-test.c b/tests/catta-test.c index 0008282..359df9e 100644 --- a/tests/catta-test.c +++ b/tests/catta-test.c @@ -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)); diff --git a/tests/prioq-test.c b/tests/prioq-test.c index b01068c..d9f9f19 100644 --- a/tests/prioq-test.c +++ b/tests/prioq-test.c @@ -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); diff --git a/tests/strlst-test.c b/tests/strlst-test.c index 496f80a..0c74e88 100644 --- a/tests/strlst-test.c +++ b/tests/strlst-test.c @@ -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) diff --git a/tests/timeval-test.c b/tests/timeval-test.c index 75f50d4..56b0a34 100644 --- a/tests/timeval-test.c +++ b/tests/timeval-test.c @@ -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; }