From 13fd8f76079e7e9a0529754eb834fd93549d5a6b Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Mon, 4 Nov 2013 11:19:30 +0100 Subject: add configuration file for pacredir This allows to ignore hosts on specified interfaces and add static hosts. --- Makefile | 2 ++ config.def.h | 5 +++ pacredir.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- pacredir.conf | 20 ++++++++++++ 4 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 pacredir.conf diff --git a/Makefile b/Makefile index ffba1c3..c29932e 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ CFLAGS += -O2 -Wall -Werror CFLAGS += $(shell pkg-config --libs --cflags libcurl) CFLAGS += $(shell pkg-config --libs --cflags avahi-client) CFLAGS += $(shell pkg-config --libs --cflags libmicrohttpd) +CFLAGS += -liniparser VERSION := $(shell git describe --tags --long 2>/dev/null) # this is just a fallback in case you do not use git but downloaded # a release tarball... @@ -39,6 +40,7 @@ install: install-bin install-doc install-bin: pacredir $(INSTALL) -D -m0755 pacredir $(DESTDIR)/usr/bin/pacredir + $(INSTALL) -D -m0644 pacredir.conf $(DESTDIR)/etc/pacredir.conf $(INSTALL) -D -m0644 pacman/paccache $(DESTDIR)/etc/pacman.d/paccache $(INSTALL) -D -m0644 avahi/pacserve.service $(DESTDIR)/etc/avahi/services/pacserve.service $(INSTALL) -D -m0644 avahi/pacdbserve.service $(DESTDIR)/etc/avahi/services/pacdbserve.service diff --git a/config.def.h b/config.def.h index 72bf6a8..c81672e 100644 --- a/config.def.h +++ b/config.def.h @@ -41,6 +41,11 @@ #define PACSERVE "_pacserve._tcp" #define PACDBSERVE "_pacdbserve_" ARCH "._tcp" +/* path to the config file */ +#define CONFIGFILE "/etc/pacredir.conf" +/* these characters are used as delimiter in config file */ +#define DELIMITER " ,;" + /* this is where pacman stores its local copy of db files */ #define SYNCPATH "/var/lib/pacman/sync" diff --git a/pacredir.c b/pacredir.c index aef0fba..d889309 100644 --- a/pacredir.c +++ b/pacredir.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -22,6 +23,7 @@ #include #include +#include #include #include @@ -46,8 +48,17 @@ struct hosts { struct hosts * next; }; +/* ignore interfaces */ +struct ignore_interfaces { + /* interface name */ + char * interface; + /* pointer to next struct element */ + struct ignore_interfaces * next; +}; + /* global variables */ struct hosts * hosts = NULL; +struct ignore_interfaces * ignore_interfaces = NULL; static AvahiSimplePoll *simple_poll = NULL; /*** write_log ***/ @@ -130,6 +141,8 @@ int remove_host(const char * host, const char * type) { static void browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, void* userdata) { char * host; + char intname[IFNAMSIZ]; + struct ignore_interfaces * tmp_ignore_interfaces = ignore_interfaces; assert(b); @@ -143,13 +156,23 @@ static void browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, Avah case AVAHI_BROWSER_NEW: host = get_fqdn(name, domain); + if (flags & AVAHI_LOOKUP_RESULT_LOCAL) + goto out; + + /* check whether to ignore the interface */ + if_indextoname(interface, intname); + while (tmp_ignore_interfaces->next != NULL) { + if (strcmp(intname, tmp_ignore_interfaces->interface) == 0) { + write_log(stdout, "Ignoring service '%s' of type '%s' in domain '%s' on interface '%s'\n", name, type, domain, intname); + goto out; + } + tmp_ignore_interfaces = tmp_ignore_interfaces->next; + } + # if defined DEBUG write_log(stdout, "NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain); # endif - if (flags & AVAHI_LOOKUP_RESULT_LOCAL) - goto out; - add_host(host, type); out: free(host); @@ -377,6 +400,8 @@ static int ahc_echo(void * cls, struct MHD_Connection * connection, const char * /*** sigterm_callback ***/ void sigterm_callback(int signal) { + write_log(stdout, "Received SIGTERM, quitting.\n"); + avahi_simple_poll_quit(simple_poll); } @@ -395,6 +420,9 @@ void sighup_callback(int signal) { /*** main ***/ int main(int argc, char ** argv) { + dictionary * ini; + char * values, * value; + struct ignore_interfaces * tmp_ignore_interfaces; AvahiClient *client = NULL; AvahiServiceBrowser *pacserve = NULL, *pacdbserve = NULL; int error; @@ -414,6 +442,62 @@ int main(int argc, char ** argv) { hosts->pacdbserve.bad = 0; hosts->next = NULL; + ignore_interfaces = malloc(sizeof(struct ignore_interfaces)); + ignore_interfaces->interface = NULL; + ignore_interfaces->next = NULL; + + + /* parse config file */ + if ((ini = iniparser_load(CONFIGFILE)) == NULL) { + write_log(stderr, "cannot parse file: " CONFIGFILE "\n"); + return EXIT_FAILURE ; + } + + /* store interfaces to ignore */ + if ((values = iniparser_getstring(ini, "general:ignore interfaces", NULL)) != NULL) { +# if defined DEBUG + write_log(stdout, "Ignore interface: [%s]\n", values); +# endif + tmp_ignore_interfaces = ignore_interfaces; + + value = strtok(values, DELIMITER); + while (value != NULL) { + tmp_ignore_interfaces->interface = strdup(value); + tmp_ignore_interfaces->next = malloc(sizeof(struct ignore_interfaces)); + tmp_ignore_interfaces = tmp_ignore_interfaces->next; + value = strtok(NULL, DELIMITER); + } + tmp_ignore_interfaces->interface = NULL; + tmp_ignore_interfaces->next = NULL; + } + + /* add static pacserve hosts */ + if ((values = iniparser_getstring(ini, "general:pacserve hosts", NULL)) != NULL) { +# if defined DEBUG + write_log(stdout, "pacserve hosts: [%s]\n", values); +# endif + value = strtok(values, DELIMITER); + while (value != NULL) { + add_host(value, PACSERVE); + value = strtok(NULL, DELIMITER); + } + } + + /* add static pacdbserve hosts */ + if ((values = iniparser_getstring(ini, "general:pacdbserve hosts", NULL)) != NULL) { +# if defined DEBUG + write_log(stdout, "pacdbserve hosts: [%s]\n", values); +# endif + value = strtok(values, DELIMITER); + while (value != NULL) { + add_host(value, PACDBSERVE); + value = strtok(NULL, DELIMITER); + } + } + + /* done reading config file, free */ + iniparser_freedict(ini); + /* allocate main loop object */ if (!(simple_poll = avahi_simple_poll_new())) { write_log(stderr, "Failed to create simple poll object.\n"); @@ -473,6 +557,13 @@ fail: hosts = tmphosts; } + while(ignore_interfaces->interface != NULL) { + free(ignore_interfaces->interface); + tmp_ignore_interfaces = ignore_interfaces->next; + free(ignore_interfaces); + ignore_interfaces = tmp_ignore_interfaces; + } + if (pacdbserve) avahi_service_browser_free(pacdbserve); diff --git a/pacredir.conf b/pacredir.conf new file mode 100644 index 0000000..e68393e --- /dev/null +++ b/pacredir.conf @@ -0,0 +1,20 @@ +# pacredir configuration file + +# We need a default section and call it 'general', so do not change this line. +[general] + +# Some people like to run avahi on network interfaces with low bandwidth or +# high cost, for example to use 'Bonjour' (Link-Local Messaging) on it. +# Add these interfaces here to ignore them by pacredir. Just give multiple +# interface if desired, separated by space, comma or semicolon. +#ignore interfaces = tap0 +#ignore interfaces = tun0 +#ignore interfaces = openvpn +#ignore interfaces = tap0 tun0 openvpn + +# You may want to add hosts that do not announce their services via avahi or +# are connected to a different network segment. Add them here. +# Please note that pacdbserve hosts depend on the servers architecture! +#pacserve hosts = test1.domain +#pacserve hosts = test1.domain test2.domain +#pacdbserve hosts = test3.domain test4.domain -- cgit v1.2.3-70-g09d2