From e1f934bbe96fd8e7f3f5212b783c0d3a434d4789 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 23 May 2005 16:15:12 +0000 Subject: [PATCH] * add the first bits of a mDNS reflector git-svn-id: file:///home/lennart/svn/public/avahi/trunk@90 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-core/Makefile.am | 9 +++++- avahi-core/avahi-reflector.c | 56 ++++++++++++++++++++++++++++++++++++ avahi-core/avahi-test.c | 4 +-- avahi-core/core.h | 35 +++++++++++++++++++--- avahi-core/server.c | 53 +++++++++++++++++++++++++++++++++- avahi-core/socket.c | 4 +++ todo | 7 ++++- 7 files changed, 159 insertions(+), 9 deletions(-) create mode 100644 avahi-core/avahi-reflector.c diff --git a/avahi-core/Makefile.am b/avahi-core/Makefile.am index 6fe184a..afc958c 100644 --- a/avahi-core/Makefile.am +++ b/avahi-core/Makefile.am @@ -45,7 +45,8 @@ noinst_PROGRAMS = \ strlst-test \ avahi-test \ alternative-test \ - conformance-test + conformance-test \ + avahi-reflector libavahi_core_la_SOURCES = \ timeeventq.c timeeventq.h\ @@ -119,6 +120,12 @@ conformance_test_SOURCES = \ conformance_test_CFLAGS = $(AM_CFLAGS) conformance_test_LDADD = $(AM_LDADD) +avahi_reflector_SOURCES = \ + avahi-reflector.c \ + $(libavahi_core_la_SOURCES) +avahi_reflector_CFLAGS = $(AM_CFLAGS) +avahi_reflector_LDADD = $(AM_LDADD) + valgrind: avahi-test libtool --mode=execute valgrind ./avahi-test diff --git a/avahi-core/avahi-reflector.c b/avahi-core/avahi-reflector.c new file mode 100644 index 0000000..0079afc --- /dev/null +++ b/avahi-core/avahi-reflector.c @@ -0,0 +1,56 @@ +/* $Id$ */ + +/*** + This file is part of avahi. + + avahi 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. + + avahi 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 avahi; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include +#include + +int main(int argc, char*argv[]) { + AvahiServer *server; + AvahiServerConfig config; + GMainLoop *loop; + + + avahi_server_config_init(&config); + config.register_hinfo = FALSE; + config.register_addresses = FALSE; + config.announce_domain = FALSE; + config.use_ipv6 = FALSE; + config.enable_reflector = TRUE; + + server = avahi_server_new(NULL, &config, NULL, NULL); + avahi_server_config_free(&config); + + loop = g_main_loop_new(NULL, FALSE); + + g_main_loop_run(loop); + g_main_loop_unref(loop); + + avahi_server_free(server); +} diff --git a/avahi-core/avahi-test.c b/avahi-core/avahi-test.c index 1c3dc57..48db6d7 100644 --- a/avahi-core/avahi-test.c +++ b/avahi-core/avahi-test.c @@ -28,8 +28,8 @@ #include #include -#include "core.h" -#include "alternative.h" +#include +#include static AvahiEntryGroup *group = NULL; static AvahiServer *server = NULL; diff --git a/avahi-core/core.h b/avahi-core/core.h index c832e03..addfebe 100644 --- a/avahi-core/core.h +++ b/avahi-core/core.h @@ -79,24 +79,51 @@ typedef struct AvahiServerConfig { gboolean check_response_ttl; /**< If enabled the server ignores all incoming responses with IP TTL != 255 */ gboolean announce_domain; /**< Announce the local domain for browsing */ gboolean use_iff_running; /**< Require IFF_RUNNING on local network interfaces. This is the official way to check for link beat. Unfortunately this doesn't work with all drivers. So bettere leave this off. */ + gboolean enable_reflector; /**< Reflect incoming mDNS traffic to all local networks. This allows mDNS based network browsing beyond ethernet borders */ } AvahiServerConfig; /** Allocate a new mDNS responder object. */ AvahiServer *avahi_server_new( GMainContext *c, /**< The GLIB main loop context to attach to */ - const AvahiServerConfig *sc, /**< If non-NULL a pointer to a configuration structure for the server */ + const AvahiServerConfig *sc, /**< If non-NULL a pointer to a configuration structure for the server. The server makes an internal deep copy of this structure, so you may free it using avahi_server_config_done() immediately after calling this function. */ AvahiServerCallback callback, /**< A callback which is called whenever the state of the server changes */ gpointer userdata /**< An opaque pointer which is passed to the callback function */); /** Free an mDNS responder object */ void avahi_server_free(AvahiServer* s); -AvahiServerConfig* avahi_server_config_init(AvahiServerConfig *c); -AvahiServerConfig* avahi_server_config_copy(AvahiServerConfig *ret, const AvahiServerConfig *c); +/** Fill in default values for a server configuration structure. If you + * make use of an AvahiServerConfig structure be sure to initialize + * it with this function for the sake of upwards library + * compatibility. This call may allocate strings on the heap. To + * release this memory make sure to call + * avahi_server_config_done(). If you want to replace any strings in + * the structure be sure to free the strings filled in by this + * function with g_free() first and allocate the replacements with + * g_malloc() (or g_strdup()).*/ +AvahiServerConfig* avahi_server_config_init( + AvahiServerConfig *c /**< A structure which shall be filled in */ ); + +/** Make a deep copy of the configuration structure *c to *ret. */ +AvahiServerConfig* avahi_server_config_copy( + AvahiServerConfig *ret /**< destination */, + const AvahiServerConfig *c /**< source */); + +/** Free the data in a server configuration structure. */ void avahi_server_config_free(AvahiServerConfig *c); - + +/** Return the currently chosen domain name of the server object. The + * return value points to an internally allocated string. Be sure to + * make a copy of the string before calling any other library + * functions. */ const gchar* avahi_server_get_domain_name(AvahiServer *s); + +/** Return the currently chosen host name. The return value points to a internally allocated string. */ const gchar* avahi_server_get_host_name(AvahiServer *s); + +/** Return the currently chosen host name as a FQDN ("fully qualified + * domain name", i.e. the concatenation of the host and domain + * name). The return value points to a internally allocated string. */ const gchar* avahi_server_get_host_name_fqdn(AvahiServer *s); void avahi_server_set_host_name(AvahiServer *s, const gchar *host_name); diff --git a/avahi-core/server.c b/avahi-core/server.c index fe2c5f8..e95fcca 100644 --- a/avahi-core/server.c +++ b/avahi-core/server.c @@ -465,6 +465,52 @@ void avahi_server_generate_response(AvahiServer *s, AvahiInterface *i, AvahiDnsP avahi_record_list_flush(s->record_list); } + +static void reflect_response(AvahiServer *s, AvahiInterface *i, AvahiRecord *r, gboolean flush_cache) { + AvahiInterface *j; + + g_assert(s); + g_assert(i); + g_assert(r); + + if (!s->config.enable_reflector) + return; + + for (j = s->monitor->interfaces; j; j = j->interface_next) + if (j != i) + avahi_interface_post_response(j, r, flush_cache, NULL, TRUE); +} + +static void reflect_query(AvahiServer *s, AvahiInterface *i, AvahiKey *k) { + AvahiInterface *j; + + g_assert(s); + g_assert(i); + g_assert(k); + + if (!s->config.enable_reflector) + return; + + for (j = s->monitor->interfaces; j; j = j->interface_next) + if (j != i) + avahi_interface_post_query(j, k, TRUE); +} + +static void reflect_probe(AvahiServer *s, AvahiInterface *i, AvahiRecord *r) { + AvahiInterface *j; + + g_assert(s); + g_assert(i); + g_assert(r); + + if (!s->config.enable_reflector) + return; + + for (j = s->monitor->interfaces; j; j = j->interface_next) + if (j != i) + avahi_interface_post_probe(j, r, TRUE); +} + static void handle_query(AvahiServer *s, AvahiDnsPacket *p, AvahiInterface *i, const AvahiAddress *a, guint16 port, gboolean legacy_unicast) { guint n; @@ -487,6 +533,7 @@ static void handle_query(AvahiServer *s, AvahiDnsPacket *p, AvahiInterface *i, c goto fail; } + reflect_query(s, i, key); avahi_query_scheduler_incoming(i->query_scheduler, key); avahi_server_prepare_matching_responses(s, i, key, unicast_response); avahi_key_unref(key); @@ -520,8 +567,10 @@ static void handle_query(AvahiServer *s, AvahiDnsPacket *p, AvahiInterface *i, c goto fail; } - if (record->key->type != AVAHI_DNS_TYPE_ANY) + if (record->key->type != AVAHI_DNS_TYPE_ANY) { + reflect_probe(s, i, record); incoming_probe(s, record, i); + } avahi_record_unref(record); } @@ -563,6 +612,7 @@ static void handle_response(AvahiServer *s, AvahiDnsPacket *p, AvahiInterface *i /* g_free(txt); */ if (handle_conflict(s, i, record, cache_flush, a)) { + reflect_response(s, i, record, cache_flush); avahi_cache_update(i->cache, record, cache_flush, a); avahi_response_scheduler_incoming(i->response_scheduler, record, cache_flush); } @@ -1511,6 +1561,7 @@ AvahiServerConfig* avahi_server_config_init(AvahiServerConfig *c) { c->check_response_ttl = TRUE; c->announce_domain = TRUE; c->use_iff_running = FALSE; + c->enable_reflector = FALSE; return c; } diff --git a/avahi-core/socket.c b/avahi-core/socket.c index b9e1b71..2833d27 100644 --- a/avahi-core/socket.c +++ b/avahi-core/socket.c @@ -451,6 +451,10 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in *ret_sa, if (ret_sa->sin_addr.s_addr == INADDR_ANY) { /* Linux 2.4 behaves very strangely sometimes! */ + + avahi_hexdump(AVAHI_DNS_PACKET_DATA(p), l); + + goto fail; } diff --git a/todo b/todo index fa31683..a24dc54 100644 --- a/todo +++ b/todo @@ -1,5 +1,10 @@ todo: -* Add some APIs to get the clean service name from RR for browsing +* reflector: + - handle legacy unicast + - handle unicast reply + - handle known answer + +* debug linux 2.4 spurious packet * test against apple test suite -- 2.39.5