]> git.meshlink.io Git - catta/commitdiff
* add new server state AVAHI_SERVER_SLEEPING to avoid conflicts by own responses
authorLennart Poettering <lennart@poettering.net>
Fri, 20 May 2005 21:35:40 +0000 (21:35 +0000)
committerLennart Poettering <lennart@poettering.net>
Fri, 20 May 2005 21:35:40 +0000 (21:35 +0000)
* Honour TC bit in incoming packets by responding immediately to packets
* publish browse domain
* Fix a structure size issue in iface.c revealed by running avahi on Linux 2.4
* Don't depend on IFF_RUNNING
* Require a global IP addresses to consider an interface relevant
* Linux 2.4 compatiblity
* fix parsing of TTL from recvmsg()

git-svn-id: file:///home/lennart/svn/public/avahi/trunk@79 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe

avahi-core/announce.c
avahi-core/avahi-test.c
avahi-core/cache.c
avahi-core/core.h
avahi-core/iface.c
avahi-core/server.c
avahi-core/server.h
avahi-core/socket.c
avahi-core/subscribe.c

index 75766a9ab5c950dfeb15220d000f841df7515f4c..6f94a74bab6bb1a1a751290b59e53c6bb319bb85 100644 (file)
@@ -120,7 +120,7 @@ static void next_state(AvahiAnnouncement *a) {
         if (a->n_iteration >= 4) {
             /* Probing done */
             
         if (a->n_iteration >= 4) {
             /* Probing done */
             
-            gchar *t;
+/*             gchar *t; */
 
 /*             g_message("Enough probes for record [%s]", t = avahi_record_to_string(a->entry->record)); */
 /*             g_free(t); */
 
 /*             g_message("Enough probes for record [%s]", t = avahi_record_to_string(a->entry->record)); */
 /*             g_free(t); */
index a090a126fb7bc6113f672bb2493390c44811aca3..fc1426fe52e0390ba4e24477cba5d30be047c0f8 100644 (file)
@@ -65,24 +65,31 @@ static void remove_entries(void);
 static void create_entries(gboolean new_name);
 
 static void entry_group_callback(AvahiServer *s, AvahiEntryGroup *g, AvahiEntryGroupState state, gpointer userdata) {
 static void create_entries(gboolean new_name);
 
 static void entry_group_callback(AvahiServer *s, AvahiEntryGroup *g, AvahiEntryGroupState state, gpointer userdata) {
-    g_message("=======> entry group state: %i", state);
+    g_message("entry group state: %i", state); 
 
     if (state == AVAHI_ENTRY_GROUP_COLLISION) {
         remove_entries();
         create_entries(TRUE);
 
     if (state == AVAHI_ENTRY_GROUP_COLLISION) {
         remove_entries();
         create_entries(TRUE);
+        g_message("Service name conflict, retrying with <%s>", service_name);
+    } else if (state == AVAHI_ENTRY_GROUP_ESTABLISHED) {
+        g_message("Service established under name <%s>", service_name);
     }
 }
 
 static void server_callback(AvahiServer *s, AvahiServerState state, gpointer userdata) {
     }
 }
 
 static void server_callback(AvahiServer *s, AvahiServerState state, gpointer userdata) {
-    g_message("=======> server state: %i", state);
 
 
-    if (state == AVAHI_SERVER_RUNNING)
+     g_message("server state: %i", state); 
+    
+    if (state == AVAHI_SERVER_RUNNING) {
+        g_message("Server startup complete.  Host name is <%s>", avahi_server_get_host_name_fqdn(s));
         create_entries(FALSE);
         create_entries(FALSE);
-    else if (state == AVAHI_SERVER_COLLISION) {
+    else if (state == AVAHI_SERVER_COLLISION) {
         gchar *n;
         remove_entries();
 
         n = avahi_alternative_host_name(avahi_server_get_host_name(s));
         gchar *n;
         remove_entries();
 
         n = avahi_alternative_host_name(avahi_server_get_host_name(s));
+
+        g_message("Host name conflict, retrying with <%s>", n);
         avahi_server_set_host_name(s, n);
         g_free(n);
     }
         avahi_server_set_host_name(s, n);
         g_free(n);
     }
@@ -103,7 +110,7 @@ static void create_entries(gboolean new_name) {
     if (!service_name)
         service_name = g_strdup("Test Service");
     else if (new_name) {
     if (!service_name)
         service_name = g_strdup("Test Service");
     else if (new_name) {
-        gchar *n = avahi_alternative_service_name(avahi_server_get_host_name(server));
+        gchar *n = avahi_alternative_service_name(service_name);
         g_free(service_name);
         service_name = n;
     }
         g_free(service_name);
         service_name = n;
     }
@@ -117,24 +124,28 @@ static void create_entries(gboolean new_name) {
 }
 int main(int argc, char *argv[]) {
     GMainLoop *loop = NULL;
 }
 int main(int argc, char *argv[]) {
     GMainLoop *loop = NULL;
-/*     AvahiSubscription *s; */
-/*     AvahiKey *k; */
-    
-    server = avahi_server_new(NULL, NULL, server_callback, NULL);
+    AvahiSubscription *s;
+    AvahiKey *k;
+    AvahiServerConfig config;
+
+    avahi_server_config_init(&config);
+    config.host_name = g_strdup("test");
+    server = avahi_server_new(NULL, &config, server_callback, NULL);
+    avahi_server_config_free(&config);
 
 
-/*     k = avahi_key_new("HALLO", AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_TXT); */
-/*     s = avahi_subscription_new(avahi, k, 0, AF_UNSPEC, subscription, NULL); */
-/*     avahi_key_unref(k); */
+    k = avahi_key_new("_http._tcp.local", AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR);
+    s = avahi_subscription_new(server, k, 0, AF_UNSPEC, subscription, NULL);
+    avahi_key_unref(k);
 
     loop = g_main_loop_new(NULL, FALSE);
     
 
     loop = g_main_loop_new(NULL, FALSE);
     
-    g_timeout_add(1000*5, dump_timeout, server); 
+/*      g_timeout_add(1000*5, dump_timeout, server);   */
 /*     g_timeout_add(1000*30, quit_timeout, loop);    */
     
     g_main_loop_run(loop);
     g_main_loop_unref(loop);
 
 /*     g_timeout_add(1000*30, quit_timeout, loop);    */
     
     g_main_loop_run(loop);
     g_main_loop_unref(loop);
 
-/*     avahi_subscription_free(s);  */
+     avahi_subscription_free(s);  
 
     if (group)
         avahi_entry_group_free(group);   
 
     if (group)
         avahi_entry_group_free(group);   
index 2f0c1667c70ca63a1fcd5950249a72acbc2a2d6b..12ee0e66a8e4cff12f88e67c038de77f57f87c0e 100644 (file)
@@ -151,7 +151,7 @@ static void elapse_func(AvahiTimeEvent *t, void *userdata) {
 
     if (e->state == AVAHI_CACHE_FINAL) {
         remove_entry(e->cache, e);
 
     if (e->state == AVAHI_CACHE_FINAL) {
         remove_entry(e->cache, e);
-        g_message("Removing entry from cache due to expiration");
+/*         g_message("Removing entry from cache due to expiration"); */
     } else {
         guint percent = 0;
     
     } else {
         guint percent = 0;
     
@@ -183,7 +183,7 @@ static void elapse_func(AvahiTimeEvent *t, void *userdata) {
 
         /* Request a cache update, if we are subscribed to this entry */
         if (avahi_is_subscribed(e->cache->server, e->record->key)) {
 
         /* Request a cache update, if we are subscribed to this entry */
         if (avahi_is_subscribed(e->cache->server, e->record->key)) {
-            g_message("Requesting cache entry update at %i%%.", percent);
+/*             g_message("Requesting cache entry update at %i%%.", percent); */
             avahi_interface_post_query(e->cache->interface, e->record->key, TRUE);
         }
 
             avahi_interface_post_query(e->cache->interface, e->record->key, TRUE);
         }
 
index d27f02ed6cc014b04f8511b2b27dad973cd476d7..e113f86b9ee57917016080f78a1f9691de03b607 100644 (file)
@@ -42,7 +42,8 @@ typedef enum {
     AVAHI_SERVER_INVALID = -1,     /**< Invalid state (initial) */ 
     AVAHI_SERVER_REGISTERING = 0,  /**< Host RRs are being registered */
     AVAHI_SERVER_RUNNING,          /**< All host RRs have been established */
     AVAHI_SERVER_INVALID = -1,     /**< Invalid state (initial) */ 
     AVAHI_SERVER_REGISTERING = 0,  /**< Host RRs are being registered */
     AVAHI_SERVER_RUNNING,          /**< All host RRs have been established */
-    AVAHI_SERVER_COLLISION         /**< There is a collision with a host RR. All host RRs have been withdrawn, the user should set a new host name via avahi_server_set_host_name() */
+    AVAHI_SERVER_COLLISION,        /**< There is a collision with a host RR. All host RRs have been withdrawn, the user should set a new host name via avahi_server_set_host_name() */
+    AVAHI_SERVER_SLEEPING          /**< The host or domain name has changed and the server waits for old entries to be expired */
 } AvahiServerState;
 
 /** Flags for server entries */
 } AvahiServerState;
 
 /** Flags for server entries */
@@ -76,6 +77,8 @@ typedef struct AvahiServerConfig {
     gboolean register_hinfo;               /**< Register a HINFO record for the host containing the local OS and CPU type */
     gboolean register_addresses;           /**< Register A, AAAA and PTR records for all local IP addresses */
     gboolean check_response_ttl;           /**< If enabled the server ignores all incoming responses with IP TTL != 255 */
     gboolean register_hinfo;               /**< Register a HINFO record for the host containing the local OS and CPU type */
     gboolean register_addresses;           /**< Register A, AAAA and PTR records for all local IP addresses */
     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. */
 } AvahiServerConfig;
 
 /** Allocate a new mDNS responder object. */
 } AvahiServerConfig;
 
 /** Allocate a new mDNS responder object. */
index b2c49f7f122d34ac531570a1a38aac214fc94d78..efd960a3b660b3a9cebbb8d055e993ea097df6bc 100644 (file)
@@ -41,13 +41,12 @@ static void update_address_rr(AvahiInterfaceMonitor *m, AvahiInterfaceAddress *a
     g_assert(m);
     g_assert(a);
 
     g_assert(m);
     g_assert(a);
 
-    
     if (avahi_interface_address_relevant(a) &&
         !remove &&
         m->server->config.register_addresses &&
         (m->server->state == AVAHI_SERVER_RUNNING ||
         m->server->state == AVAHI_SERVER_REGISTERING)) {
     if (avahi_interface_address_relevant(a) &&
         !remove &&
         m->server->config.register_addresses &&
         (m->server->state == AVAHI_SERVER_RUNNING ||
         m->server->state == AVAHI_SERVER_REGISTERING)) {
-        
+
         if (!a->entry_group) {
             a->entry_group = avahi_entry_group_new(m->server, avahi_host_rr_entry_group_callback, NULL);
             avahi_server_add_address(m->server, a->entry_group, a->interface->hardware->index, AF_UNSPEC, 0, NULL, &a->address); 
         if (!a->entry_group) {
             a->entry_group = avahi_entry_group_new(m->server, avahi_host_rr_entry_group_callback, NULL);
             avahi_server_add_address(m->server, a->entry_group, a->interface->hardware->index, AF_UNSPEC, 0, NULL, &a->address); 
@@ -68,6 +67,7 @@ static void update_address_rr(AvahiInterfaceMonitor *m, AvahiInterfaceAddress *a
 
 static void update_interface_rr(AvahiInterfaceMonitor *m, AvahiInterface *i, gboolean remove) {
     AvahiInterfaceAddress *a;
 
 static void update_interface_rr(AvahiInterfaceMonitor *m, AvahiInterface *i, gboolean remove) {
     AvahiInterfaceAddress *a;
+    
     g_assert(m);
     g_assert(i);
 
     g_assert(m);
     g_assert(i);
 
@@ -161,7 +161,7 @@ static int netlink_list_items(AvahiNetlink *nl, guint16 type, guint *ret_seq) {
     n = (struct nlmsghdr*) req;
     n->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
     n->nlmsg_type = type;
     n = (struct nlmsghdr*) req;
     n->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
     n->nlmsg_type = type;
-    n->nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
+    n->nlmsg_flags = NLM_F_ROOT/*|NLM_F_MATCH*/|NLM_F_REQUEST;
     n->nlmsg_pid = 0;
 
     gen = NLMSG_DATA(n);
     n->nlmsg_pid = 0;
 
     gen = NLMSG_DATA(n);
@@ -205,12 +205,12 @@ static void check_interface_relevant(AvahiInterfaceMonitor *m, AvahiInterface *i
     b = avahi_interface_relevant(i);
 
     if (b && !i->announcing) {
     b = avahi_interface_relevant(i);
 
     if (b && !i->announcing) {
-        g_message("New relevant interface %s.%i", i->hardware->name, i->protocol);
+        g_message("New relevant interface %s.%i (#%i)", i->hardware->name, i->protocol, i->hardware->index);
 
         if (i->protocol == AF_INET)
 
         if (i->protocol == AF_INET)
-            avahi_mdns_mcast_join_ipv4 (i->hardware->index, m->server->fd_ipv4);
+            avahi_mdns_mcast_join_ipv4(i->hardware->index, m->server->fd_ipv4);
         if (i->protocol == AF_INET6)
         if (i->protocol == AF_INET6)
-            avahi_mdns_mcast_join_ipv6 (i->hardware->index, m->server->fd_ipv6);
+            avahi_mdns_mcast_join_ipv6(i->hardware->index, m->server->fd_ipv6);
 
         i->announcing = TRUE;
         avahi_announce_interface(m->server, i);
 
         i->announcing = TRUE;
         avahi_announce_interface(m->server, i);
@@ -218,9 +218,9 @@ static void check_interface_relevant(AvahiInterfaceMonitor *m, AvahiInterface *i
         g_message("Interface %s.%i no longer relevant", i->hardware->name, i->protocol);
 
         if (i->protocol == AF_INET)
         g_message("Interface %s.%i no longer relevant", i->hardware->name, i->protocol);
 
         if (i->protocol == AF_INET)
-            avahi_mdns_mcast_leave_ipv4 (i->hardware->index, m->server->fd_ipv4);
+            avahi_mdns_mcast_leave_ipv4(i->hardware->index, m->server->fd_ipv4);
         if (i->protocol == AF_INET6)
         if (i->protocol == AF_INET6)
-            avahi_mdns_mcast_leave_ipv6 (i->hardware->index, m->server->fd_ipv6);
+            avahi_mdns_mcast_leave_ipv6(i->hardware->index, m->server->fd_ipv6);
 
         avahi_goodbye_interface(m->server, i, FALSE);
         avahi_response_scheduler_clear(i->response_scheduler);
 
         avahi_goodbye_interface(m->server, i, FALSE);
         avahi_response_scheduler_clear(i->response_scheduler);
@@ -324,7 +324,7 @@ static void callback(AvahiNetlink *nl, struct nlmsghdr *n, gpointer userdata) {
         struct rtattr *a = NULL;
         size_t l;
         AvahiAddress raddr;
         struct rtattr *a = NULL;
         size_t l;
         AvahiAddress raddr;
-        int raddr_valid = 0;
+        gboolean raddr_valid = FALSE;
 
         if (ifaddrmsg->ifa_family != AF_INET && ifaddrmsg->ifa_family != AF_INET6)
             return;
 
         if (ifaddrmsg->ifa_family != AF_INET && ifaddrmsg->ifa_family != AF_INET6)
             return;
@@ -334,10 +334,11 @@ static void callback(AvahiNetlink *nl, struct nlmsghdr *n, gpointer userdata) {
 
         raddr.family = ifaddrmsg->ifa_family;
 
 
         raddr.family = ifaddrmsg->ifa_family;
 
-        l = NLMSG_PAYLOAD(n, sizeof(struct ifinfomsg));
+        l = NLMSG_PAYLOAD(n, sizeof(struct ifaddrmsg));
         a = IFA_RTA(ifaddrmsg);
 
         while (RTA_OK(a, l)) {
         a = IFA_RTA(ifaddrmsg);
 
         while (RTA_OK(a, l)) {
+
             switch(a->rta_type) {
                 case IFA_ADDRESS:
                     if ((raddr.family == AF_INET6 && RTA_PAYLOAD(a) != 16) ||
             switch(a->rta_type) {
                 case IFA_ADDRESS:
                     if ((raddr.family == AF_INET6 && RTA_PAYLOAD(a) != 16) ||
@@ -345,7 +346,7 @@ static void callback(AvahiNetlink *nl, struct nlmsghdr *n, gpointer userdata) {
                         return;
 
                     memcpy(raddr.data.data, RTA_DATA(a), RTA_PAYLOAD(a));
                         return;
 
                     memcpy(raddr.data.data, RTA_DATA(a), RTA_PAYLOAD(a));
-                    raddr_valid = 1;
+                    raddr_valid = TRUE;
 
                     break;
                     
 
                     break;
                     
@@ -355,7 +356,6 @@ static void callback(AvahiNetlink *nl, struct nlmsghdr *n, gpointer userdata) {
             
             a = RTA_NEXT(a, l);
         }
             
             a = RTA_NEXT(a, l);
         }
-
         
         if (!raddr_valid)
             return;
         
         if (!raddr_valid)
             return;
@@ -563,14 +563,33 @@ void avahi_dump_caches(AvahiInterfaceMonitor *m, FILE *f) {
 }
 
 gboolean avahi_interface_relevant(AvahiInterface *i) {
 }
 
 gboolean avahi_interface_relevant(AvahiInterface *i) {
+    AvahiInterfaceAddress *a;
+    gboolean relevant_address;
+    
     g_assert(i);
 
     g_assert(i);
 
+    relevant_address = FALSE;
+    
+    for (a = i->addresses; a; a = a->address_next)
+        if (avahi_interface_address_relevant(a)) {
+            relevant_address = TRUE;
+            break;
+        }
+
+/*     g_message("%p. iface-relevant: %i %i %i %i %i %i", i, relevant_address, */
+/*               (i->hardware->flags & IFF_UP), */
+/*               (i->hardware->flags & IFF_RUNNING), */
+/*               !(i->hardware->flags & IFF_LOOPBACK), */
+/*               (i->hardware->flags & IFF_MULTICAST), */
+/*               !(i->hardware->flags & IFF_POINTOPOINT)); */
+    
     return
         (i->hardware->flags & IFF_UP) &&
     return
         (i->hardware->flags & IFF_UP) &&
-        (i->hardware->flags & IFF_RUNNING) &&
+        (!i->monitor->server->config.use_iff_running || (i->hardware->flags & IFF_RUNNING)) &&
         !(i->hardware->flags & IFF_LOOPBACK) &&
         (i->hardware->flags & IFF_MULTICAST) &&
         !(i->hardware->flags & IFF_LOOPBACK) &&
         (i->hardware->flags & IFF_MULTICAST) &&
-        i->addresses;
+        !(i->hardware->flags & IFF_POINTOPOINT) && 
+        relevant_address;
 }
 
 gboolean avahi_interface_address_relevant(AvahiInterfaceAddress *a) { 
 }
 
 gboolean avahi_interface_address_relevant(AvahiInterfaceAddress *a) { 
index f04ae6744ac49f57f5b07bdb6bcdac5a4e7aa81b..4085276598f03458d0fe93828b4e9f413d7acaf5 100644 (file)
@@ -35,6 +35,8 @@
 #include "socket.h"
 #include "subscribe.h"
 
 #include "socket.h"
 #include "subscribe.h"
 
+#define AVAHI_HOST_RR_HOLDOFF_MSEC 1000
+
 static void free_entry(AvahiServer*s, AvahiEntry *e) {
     AvahiEntry *t;
 
 static void free_entry(AvahiServer*s, AvahiEntry *e) {
     AvahiEntry *t;
 
@@ -378,11 +380,15 @@ void avahi_server_generate_response(AvahiServer *s, AvahiInterface *i, AvahiDnsP
         gboolean unicast_response, flush_cache, auxiliary;
         AvahiDnsPacket *reply = NULL;
         AvahiRecord *r;
         gboolean unicast_response, flush_cache, auxiliary;
         AvahiDnsPacket *reply = NULL;
         AvahiRecord *r;
+
+        /* In case the query packet was truncated never respond
+        immediately, because known answer suppression records might be
+        contained in later packets */
+        gboolean tc = p && !!(avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS) & AVAHI_DNS_FLAG_TC);
         
         while ((r = avahi_record_list_next(s->record_list, &flush_cache, &unicast_response, &auxiliary))) {
         
         while ((r = avahi_record_list_next(s->record_list, &flush_cache, &unicast_response, &auxiliary))) {
-
                         
                         
-            if (!avahi_interface_post_response(i, r, flush_cache, a, flush_cache && !auxiliary) && unicast_response) {
+            if (!avahi_interface_post_response(i, r, flush_cache, a, !tc && flush_cache && !auxiliary) && unicast_response) {
 
                 append_aux_records_to_list(s, i, r, unicast_response);
                 
 
                 append_aux_records_to_list(s, i, r, unicast_response);
                 
@@ -534,7 +540,7 @@ static void handle_response(AvahiServer *s, AvahiDnsPacket *p, AvahiInterface *i
              avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_ARCOUNT); n > 0; n--) {
         AvahiRecord *record;
         gboolean cache_flush = FALSE;
              avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_ARCOUNT); n > 0; n--) {
         AvahiRecord *record;
         gboolean cache_flush = FALSE;
-        gchar *txt;
+/*         gchar *txt; */
         
         if (!(record = avahi_dns_packet_consume_record(p, &cache_flush))) {
             g_warning("Packet too short (4)");
         
         if (!(record = avahi_dns_packet_consume_record(p, &cache_flush))) {
             g_warning("Packet too short (4)");
@@ -646,7 +652,7 @@ static void work(AvahiServer *s) {
     struct sockaddr_in6 sa6;
     struct sockaddr_in sa;
     AvahiDnsPacket *p;
     struct sockaddr_in6 sa6;
     struct sockaddr_in sa;
     AvahiDnsPacket *p;
-    gint iface = -1;
+    gint iface = 0;
     guint8 ttl;
         
     g_assert(s);
     guint8 ttl;
         
     g_assert(s);
@@ -717,6 +723,11 @@ static void withdraw_host_rrs(AvahiServer *s) {
         s->hinfo_entry_group = NULL;
     }
 
         s->hinfo_entry_group = NULL;
     }
 
+    if (s->browse_domain_entry_group) {
+        avahi_entry_group_free(s->browse_domain_entry_group);
+        s->browse_domain_entry_group = NULL;
+    }
+
     avahi_update_host_rrs(s->monitor, TRUE);
     s->n_host_rr_pending = 0;
 }
     avahi_update_host_rrs(s->monitor, TRUE);
     s->n_host_rr_pending = 0;
 }
@@ -743,7 +754,8 @@ void avahi_host_rr_entry_group_callback(AvahiServer *s, AvahiEntryGroup *g, Avah
     if (state == AVAHI_ENTRY_GROUP_REGISTERING &&
         s->state == AVAHI_SERVER_REGISTERING)
         avahi_server_increase_host_rr_pending(s);
     if (state == AVAHI_ENTRY_GROUP_REGISTERING &&
         s->state == AVAHI_SERVER_REGISTERING)
         avahi_server_increase_host_rr_pending(s);
-    else if (state == AVAHI_ENTRY_GROUP_COLLISION) {
+    else if (state == AVAHI_ENTRY_GROUP_COLLISION &&
+        (s->state == AVAHI_SERVER_REGISTERING || s->state == AVAHI_SERVER_RUNNING)) {
         withdraw_host_rrs(s);
         server_set_state(s, AVAHI_SERVER_COLLISION);
     } else if (state == AVAHI_ENTRY_GROUP_ESTABLISHED &&
         withdraw_host_rrs(s);
         server_set_state(s, AVAHI_SERVER_COLLISION);
     } else if (state == AVAHI_ENTRY_GROUP_ESTABLISHED &&
@@ -785,11 +797,23 @@ static void register_localhost(AvahiServer *s) {
     avahi_server_add_address(s, NULL, 0, AF_UNSPEC, AVAHI_ENTRY_NOPROBE|AVAHI_ENTRY_NOANNOUNCE, "ip6-localhost", &a);
 }
 
     avahi_server_add_address(s, NULL, 0, AF_UNSPEC, AVAHI_ENTRY_NOPROBE|AVAHI_ENTRY_NOANNOUNCE, "ip6-localhost", &a);
 }
 
+static void register_browse_domain(AvahiServer *s) {
+    g_assert(s);
+
+    if (!s->config.announce_domain || s->browse_domain_entry_group)
+        return;
+
+    s->browse_domain_entry_group = avahi_entry_group_new(s, NULL, NULL);
+    avahi_server_add_ptr(s, s->browse_domain_entry_group, 0, AF_UNSPEC, 0, "_browse._dns-sd._udp.local", s->domain_name);
+    avahi_entry_group_commit(s->browse_domain_entry_group);
+}
+
 static void register_stuff(AvahiServer *s) {
     g_assert(s);
 
     server_set_state(s, AVAHI_SERVER_REGISTERING);
     register_hinfo(s);
 static void register_stuff(AvahiServer *s) {
     g_assert(s);
 
     server_set_state(s, AVAHI_SERVER_REGISTERING);
     register_hinfo(s);
+    register_browse_domain(s);
     avahi_update_host_rrs(s->monitor, FALSE);
 
     if (s->n_host_rr_pending == 0)
     avahi_update_host_rrs(s->monitor, FALSE);
 
     if (s->n_host_rr_pending == 0)
@@ -806,10 +830,38 @@ static void update_fqdn(AvahiServer *s) {
     s->host_name_fqdn = g_strdup_printf("%s.%s", s->host_name, s->domain_name);
 }
 
     s->host_name_fqdn = g_strdup_printf("%s.%s", s->host_name, s->domain_name);
 }
 
+static void register_time_event_callback(AvahiTimeEvent *e, gpointer userdata) {
+    AvahiServer *s = userdata;
+    
+    g_assert(e);
+    g_assert(s);
+
+    g_assert(e == s->register_time_event);
+    avahi_time_event_queue_remove(s->time_event_queue, s->register_time_event);
+    s->register_time_event = NULL;
+
+    if (s->state == AVAHI_SERVER_SLEEPING)
+        register_stuff(s);
+}
+
+static void delayed_register_stuff(AvahiServer *s) {
+    GTimeVal tv;
+    
+    g_assert(s);
+
+    avahi_elapse_time(&tv, AVAHI_HOST_RR_HOLDOFF_MSEC, 0);
+
+    if (s->register_time_event)
+        avahi_time_event_queue_update(s->time_event_queue, s->register_time_event, &tv);
+    else
+        s->register_time_event = avahi_time_event_queue_add(s->time_event_queue, &tv, register_time_event_callback, s);
+}
+
 void avahi_server_set_host_name(AvahiServer *s, const gchar *host_name) {
     g_assert(s);
     g_assert(host_name);
 
 void avahi_server_set_host_name(AvahiServer *s, const gchar *host_name) {
     g_assert(s);
     g_assert(host_name);
 
+    server_set_state(s, AVAHI_SERVER_SLEEPING);
     withdraw_host_rrs(s);
 
     g_free(s->host_name);
     withdraw_host_rrs(s);
 
     g_free(s->host_name);
@@ -817,20 +869,21 @@ void avahi_server_set_host_name(AvahiServer *s, const gchar *host_name) {
     s->host_name[strcspn(s->host_name, ".")] = 0;
     update_fqdn(s);
 
     s->host_name[strcspn(s->host_name, ".")] = 0;
     update_fqdn(s);
 
-    register_stuff(s);
+    delayed_register_stuff(s);
 }
 
 void avahi_server_set_domain_name(AvahiServer *s, const gchar *domain_name) {
     g_assert(s);
     g_assert(domain_name);
 
 }
 
 void avahi_server_set_domain_name(AvahiServer *s, const gchar *domain_name) {
     g_assert(s);
     g_assert(domain_name);
 
+    server_set_state(s, AVAHI_SERVER_SLEEPING);
     withdraw_host_rrs(s);
 
     g_free(s->domain_name);
     s->domain_name = domain_name ? avahi_normalize_name(domain_name) : g_strdup("local.");
     update_fqdn(s);
 
     withdraw_host_rrs(s);
 
     g_free(s->domain_name);
     s->domain_name = domain_name ? avahi_normalize_name(domain_name) : g_strdup("local.");
     update_fqdn(s);
 
-    register_stuff(s);
+    delayed_register_stuff(s);
 }
 
 AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc, AvahiServerCallback callback, gpointer userdata) {
 }
 
 AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc, AvahiServerCallback callback, gpointer userdata) {
@@ -910,7 +963,8 @@ AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc, Avah
     s->record_list = avahi_record_list_new();
 
     s->time_event_queue = avahi_time_event_queue_new(s->context, G_PRIORITY_DEFAULT+10); /* Slightly less priority than the FDs */
     s->record_list = avahi_record_list_new();
 
     s->time_event_queue = avahi_time_event_queue_new(s->context, G_PRIORITY_DEFAULT+10); /* Slightly less priority than the FDs */
-
+    s->register_time_event = NULL;
+    
     s->state = AVAHI_SERVER_INVALID;
 
     s->monitor = avahi_interface_monitor_new(s);
     s->state = AVAHI_SERVER_INVALID;
 
     s->monitor = avahi_interface_monitor_new(s);
@@ -919,6 +973,7 @@ AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc, Avah
     register_localhost(s);
 
     s->hinfo_entry_group = NULL;
     register_localhost(s);
 
     s->hinfo_entry_group = NULL;
+    s->browse_domain_entry_group = NULL;
     register_stuff(s);
     
     return s;
     register_stuff(s);
     
     return s;
@@ -941,6 +996,8 @@ void avahi_server_free(AvahiServer* s) {
 
     g_hash_table_destroy(s->entries_by_key);
 
 
     g_hash_table_destroy(s->entries_by_key);
 
+    if (s->register_time_event)
+        avahi_time_event_queue_remove(s->time_event_queue, s->register_time_event);
     avahi_time_event_queue_free(s->time_event_queue);
 
     avahi_record_list_free(s->record_list);
     avahi_time_event_queue_free(s->time_event_queue);
 
     avahi_record_list_free(s->record_list);
@@ -1205,7 +1262,7 @@ void avahi_server_add_service_strlst(
         while (domain[0] == '.')
             domain++;
     } else
         while (domain[0] == '.')
             domain++;
     } else
-        domain = "local";
+        domain = s->domain_name;
 
     if (!host)
         host = s->host_name_fqdn;
 
     if (!host)
         host = s->host_name_fqdn;
@@ -1321,11 +1378,20 @@ AvahiEntryGroup *avahi_entry_group_new(AvahiServer *s, AvahiEntryGroupCallback c
 }
 
 void avahi_entry_group_free(AvahiEntryGroup *g) {
 }
 
 void avahi_entry_group_free(AvahiEntryGroup *g) {
+    AvahiEntry *e;
+    
     g_assert(g);
     g_assert(g->server);
 
     g_assert(g);
     g_assert(g->server);
 
+    for (e = g->entries; e; e = e->by_group_next) {
+        avahi_goodbye_entry(g->server, e, TRUE);
+        e->dead = TRUE;
+    }
+
     g->dead = TRUE;
     g->dead = TRUE;
+    
     g->server->need_group_cleanup = TRUE;
     g->server->need_group_cleanup = TRUE;
+    g->server->need_entry_cleanup = TRUE;
 }
 
 void avahi_entry_group_commit(AvahiEntryGroup *g) {
 }
 
 void avahi_entry_group_commit(AvahiEntryGroup *g) {
@@ -1415,16 +1481,17 @@ AvahiServerConfig* avahi_server_config_init(AvahiServerConfig *c) {
     c->host_name = NULL;
     c->domain_name = NULL;
     c->check_response_ttl = TRUE;
     c->host_name = NULL;
     c->domain_name = NULL;
     c->check_response_ttl = TRUE;
-
+    c->announce_domain = TRUE;
+    c->use_iff_running = FALSE;
+    
     return c;
 }
 
 void avahi_server_config_free(AvahiServerConfig *c) {
     g_assert(c);
 
     return c;
 }
 
 void avahi_server_config_free(AvahiServerConfig *c) {
     g_assert(c);
 
-    g_assert(c->host_name);
-    g_assert(c->domain_name);
-    g_free(c);
+    g_free(c->host_name);
+    g_free(c->domain_name);
 }
 
 AvahiServerConfig* avahi_server_config_copy(AvahiServerConfig *ret, const AvahiServerConfig *c) {
 }
 
 AvahiServerConfig* avahi_server_config_copy(AvahiServerConfig *ret, const AvahiServerConfig *c) {
index fddf17e00f88d105345852d7e637fe464b1686af..7ba4ad92371b9f729410f4988c2bf18b5ab5c049 100644 (file)
@@ -94,7 +94,10 @@ struct AvahiServer {
     gpointer userdata;
 
     AvahiEntryGroup *hinfo_entry_group;
     gpointer userdata;
 
     AvahiEntryGroup *hinfo_entry_group;
+    AvahiEntryGroup *browse_domain_entry_group;
     guint n_host_rr_pending;
     guint n_host_rr_pending;
+
+    AvahiTimeEvent *register_time_event;
     
     /* Used for assembling responses */
     AvahiRecordList *record_list;
     
     /* Used for assembling responses */
     AvahiRecordList *record_list;
index 86e2a6fc6df4b56b2c2ada280bec5b91c01f3505..b9e1b71ff3b385f4d2b1b55317ffcc191aa1e2dd 100644 (file)
@@ -420,7 +420,7 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in *ret_sa,
     AvahiDnsPacket *p= NULL;
     struct msghdr msg;
     struct iovec io;
     AvahiDnsPacket *p= NULL;
     struct msghdr msg;
     struct iovec io;
-    uint8_t aux[64];
+    uint8_t aux[1024];
     ssize_t l;
     struct cmsghdr *cmsg;
     gboolean found_ttl = FALSE, found_iface = FALSE;
     ssize_t l;
     struct cmsghdr *cmsg;
     gboolean found_ttl = FALSE, found_iface = FALSE;
@@ -444,25 +444,42 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in *ret_sa,
     msg.msg_controllen = sizeof(aux);
     msg.msg_flags = 0;
     
     msg.msg_controllen = sizeof(aux);
     msg.msg_flags = 0;
     
-    if ((l = recvmsg(fd, &msg, 0)) < 0)
+    if ((l = recvmsg(fd, &msg, 0)) < 0) {
+        g_warning("recvmsg(): %s\n", strerror(errno));
         goto fail;
         goto fail;
+    }
 
 
+    if (ret_sa->sin_addr.s_addr == INADDR_ANY) {
+        /* Linux 2.4 behaves very strangely sometimes! */
+        goto fail;
+    }
+    
+    g_assert(!(msg.msg_flags & MSG_CTRUNC));
+    g_assert(!(msg.msg_flags & MSG_TRUNC));
     p->size = (size_t) l;
     
     *ret_ttl = 0;
     p->size = (size_t) l;
     
     *ret_ttl = 0;
+
+/*     avahi_hexdump(msg.msg_control, msg.msg_controllen); */
         
         
-    for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg,cmsg)) {
-        if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_TTL) {
-            *ret_ttl = *(uint8_t *) CMSG_DATA(cmsg);
-            found_ttl = TRUE;
-        }
+    for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+
+/*         avahi_hexdump(CMSG_DATA(cmsg), cmsg->cmsg_len - sizeof(struct cmsghdr)); */
+        
+        if (cmsg->cmsg_level == SOL_IP) {
             
             
-        if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_PKTINFO) {
-            *ret_iface = ((struct in_pktinfo*) CMSG_DATA(cmsg))->ipi_ifindex;
-            found_iface = TRUE;
+            if (cmsg->cmsg_type == IP_TTL) {
+                *ret_ttl = (uint8_t) (*(int *) CMSG_DATA(cmsg));
+                found_ttl = TRUE;
+            } else if (cmsg->cmsg_type == IP_PKTINFO) {
+                *ret_iface = (gint) ((struct in_pktinfo*) CMSG_DATA(cmsg))->ipi_ifindex;
+                found_iface = TRUE;
+            }
         }
     }
 
         }
     }
 
+/*     g_message("ttl=%u iface=%i", *ret_ttl, *ret_iface); */
+
     g_assert(found_iface);
     g_assert(found_ttl);
 
     g_assert(found_iface);
     g_assert(found_ttl);
 
@@ -512,7 +529,7 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6 *ret_sa,
 
     for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
         if (cmsg->cmsg_level == SOL_IPV6 && cmsg->cmsg_type == IPV6_HOPLIMIT) {
 
     for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
         if (cmsg->cmsg_level == SOL_IPV6 && cmsg->cmsg_type == IPV6_HOPLIMIT) {
-            *ret_ttl = *(uint8_t *) CMSG_DATA(cmsg);
+            *ret_ttl = (uint8_t) (*(int *) CMSG_DATA(cmsg));
             found_ttl = TRUE;
         }
             
             found_ttl = TRUE;
         }
             
index 00d3385fd2b8e75246170765f254b1da1c24eabc..975fa1c14c828bd5d0501fcd11756f35001de541 100644 (file)
@@ -29,7 +29,7 @@
 static void elapse(AvahiTimeEvent *e, void *userdata) {
     AvahiSubscription *s = userdata;
     GTimeVal tv;
 static void elapse(AvahiTimeEvent *e, void *userdata) {
     AvahiSubscription *s = userdata;
     GTimeVal tv;
-    gchar *t;
+/*     gchar *t; */
     
     g_assert(s);
 
     
     g_assert(s);
 
@@ -38,8 +38,8 @@ static void elapse(AvahiTimeEvent *e, void *userdata) {
     if (s->n_query++ <= 8)
         s->sec_delay *= 2;
 
     if (s->n_query++ <= 8)
         s->sec_delay *= 2;
 
-    g_message("%i. Continuous querying for %s", s->n_query, t = avahi_key_to_string(s->key));
-    g_free(t);
+/*     g_message("%i. Continuous querying for %s", s->n_query, t = avahi_key_to_string(s->key)); */
+/*     g_free(t); */
     
     avahi_elapse_time(&tv, s->sec_delay*1000, 0);
     avahi_time_event_queue_update(s->server->time_event_queue, s->time_event, &tv);
     
     avahi_elapse_time(&tv, s->sec_delay*1000, 0);
     avahi_time_event_queue_update(s->server->time_event_queue, s->time_event, &tv);