]> git.meshlink.io Git - catta/commitdiff
some preliminary work for adding legacy unicast and unicast response support
authorLennart Poettering <lennart@poettering.net>
Fri, 6 May 2005 00:21:04 +0000 (00:21 +0000)
committerLennart Poettering <lennart@poettering.net>
Fri, 6 May 2005 00:21:04 +0000 (00:21 +0000)
git-svn-id: file:///home/lennart/svn/public/avahi/trunk@45 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe

address.c
address.h
dns.c
dns.h
main.c
psched.c
rr.h
server.c
socket.c
socket.h

index dffd3ee4a44a29aa33c5a69fbce71465c20a6ea5..d0fc10134ad98f7ab319f8eaff50ce084881c030 100644 (file)
--- a/address.c
+++ b/address.c
@@ -113,3 +113,14 @@ flxAddress *flx_address_from_sockaddr(const struct sockaddr* sa, flxAddress *ret
 
     return ret_addr;
 }
+
+guint16 flx_port_from_sockaddr(const struct sockaddr* sa) {
+    g_assert(sa);
+
+    g_assert(sa->sa_family == AF_INET || sa->sa_family == AF_INET6);
+
+    if (sa->sa_family == AF_INET)
+        return ntohs(((struct sockaddr_in*) sa)->sin_port);
+    else
+        return ntohs(((struct sockaddr_in6*) sa)->sin6_port);
+}
index 66b3b1f4f72f1ff8baf76bb4d9d4c6e604685fcb..8d8f2f67da4a03a83f35a240b80a043e8ee15aef 100644 (file)
--- a/address.h
+++ b/address.h
@@ -31,6 +31,7 @@ gchar *flx_address_snprint(char *ret_s, guint length, const flxAddress *a);
 flxAddress *flx_address_parse(const char *s, guchar family, flxAddress *ret_addr);
 
 flxAddress *flx_address_from_sockaddr(const struct sockaddr* sa, flxAddress *ret_addr);
+guint16 flx_port_from_sockaddr(const struct sockaddr* sa);
 
 gchar* flx_reverse_lookup_name_ipv4(const flxIPv4Address *a);
 gchar* flx_reverse_lookup_name_ipv6_arpa(const flxIPv6Address *a);
diff --git a/dns.c b/dns.c
index 3f508271672e19584fe1bbab230492d294ae8df5..55ae42a5dd56d110ef113c3ae862933aa6dff2ab 100644 (file)
--- a/dns.c
+++ b/dns.c
@@ -478,13 +478,12 @@ flxRecord* flx_dns_packet_consume_record(flxDnsPacket *p, gboolean *ret_cache_fl
         flx_dns_packet_consume_uint32(p, &ttl) < 0 ||
         flx_dns_packet_consume_uint16(p, &rdlength) < 0 ||
         p->rindex + rdlength > p->size)
-        
         goto fail;
 
 /*     g_message("name = %s, rdlength = %u", name, rdlength); */
 
     *ret_cache_flush = !!(class & FLX_DNS_CACHE_FLUSH);
-    class &= ~ FLX_DNS_CACHE_FLUSH;
+    class &= ~FLX_DNS_CACHE_FLUSH;
     
     start = flx_dns_packet_get_rptr(p);
     
@@ -595,23 +594,25 @@ fail:
     return NULL;
 }
 
-flxKey* flx_dns_packet_consume_key(flxDnsPacket *p) {
+flxKey* flx_dns_packet_consume_key(flxDnsPacket *p, gboolean *ret_unicast_response) {
     gchar name[256];
     guint16 type, class;
 
     g_assert(p);
+    g_assert(ret_unicast_response);
 
     if (flx_dns_packet_consume_name(p, name, sizeof(name)) < 0 ||
         flx_dns_packet_consume_uint16(p, &type) < 0 ||
         flx_dns_packet_consume_uint16(p, &class) < 0)
         return NULL;
 
-    class &= ~ FLX_DNS_CACHE_FLUSH;
+    *ret_unicast_response = !!(class & FLX_DNS_UNICAST_RESPONSE);
+    class &= ~FLX_DNS_UNICAST_RESPONSE;
 
     return flx_key_new(name, class, type);
 }
 
-guint8* flx_dns_packet_append_key(flxDnsPacket *p, flxKey *k) {
+guint8* flx_dns_packet_append_key(flxDnsPacket *p, flxKey *k, gboolean unicast_response) {
     guint8 *t;
     guint size;
     
@@ -622,7 +623,7 @@ guint8* flx_dns_packet_append_key(flxDnsPacket *p, flxKey *k) {
     
     if (!(t = flx_dns_packet_append_name(p, k->name)) ||
         !flx_dns_packet_append_uint16(p, k->type) ||
-        !flx_dns_packet_append_uint16(p, k->class)) {
+        !flx_dns_packet_append_uint16(p, k->class | (unicast_response ? FLX_DNS_UNICAST_RESPONSE : 0))) {
         p->size = size;
         return NULL;
     }
diff --git a/dns.h b/dns.h
index 9a692c48af8807b3f7d87674bab60b87d98e3d48..af9bd59202fad29a16e3f991632b5e6bf70f8184 100644 (file)
--- a/dns.h
+++ b/dns.h
@@ -30,7 +30,7 @@ guint8 *flx_dns_packet_append_uint16(flxDnsPacket *p, guint16 v);
 guint8 *flx_dns_packet_append_uint32(flxDnsPacket *p, guint32 v);
 guint8 *flx_dns_packet_append_name(flxDnsPacket *p, const gchar *name);
 guint8 *flx_dns_packet_append_bytes(flxDnsPacket  *p, gconstpointer, guint l);
-guint8* flx_dns_packet_append_key(flxDnsPacket *p, flxKey *k);
+guint8* flx_dns_packet_append_key(flxDnsPacket *p, flxKey *k, gboolean unicast_response);
 guint8* flx_dns_packet_append_record(flxDnsPacket *p, flxRecord *r, gboolean cache_flush);
 guint8* flx_dns_packet_append_string(flxDnsPacket *p, const gchar *s);
 
@@ -41,7 +41,7 @@ gint flx_dns_packet_consume_uint16(flxDnsPacket *p, guint16 *ret_v);
 gint flx_dns_packet_consume_uint32(flxDnsPacket *p, guint32 *ret_v);
 gint flx_dns_packet_consume_name(flxDnsPacket *p, gchar *ret_name, guint l);
 gint flx_dns_packet_consume_bytes(flxDnsPacket *p, gpointer ret_data, guint l);
-flxKey* flx_dns_packet_consume_key(flxDnsPacket *p);
+flxKey* flx_dns_packet_consume_key(flxDnsPacket *p, gboolean *ret_unicast_response);
 flxRecord* flx_dns_packet_consume_record(flxDnsPacket *p, gboolean *ret_cache_flush);
 gint flx_dns_packet_consume_string(flxDnsPacket *p, gchar *ret_string, guint l);
 
diff --git a/main.c b/main.c
index efb6172b14178e8b1a29f566d0ad4eb18a05481e..57251628af8d364e7fd32cdc2f39d4ebaec08454 100644 (file)
--- a/main.c
+++ b/main.c
@@ -67,7 +67,7 @@ int main(int argc, char *argv[]) {
     g_main_loop_unref(loop);
 
 /*     flx_subscription_free(s); */
-    flx_entry_group_free(g); 
+    /* flx_entry_group_free(g);  */
     flx_server_free(flx);
     
     return 0;
index 1c4316425f6ee8ebd65290095fdf3bae5511ad78..dcad5bbcf9b5ad835252a67c179e77c00d548731 100644 (file)
--- a/psched.c
+++ b/psched.c
@@ -111,7 +111,7 @@ static guint8* packet_add_query_job(flxPacketScheduler *s, flxDnsPacket *p, flxQ
     g_assert(p);
     g_assert(qj);
 
-    if ((d = flx_dns_packet_append_key(p, qj->key))) {
+    if ((d = flx_dns_packet_append_key(p, qj->key, FALSE))) {
         GTimeVal tv;
 
         qj->done = 1;
@@ -603,7 +603,7 @@ static guint8* packet_add_probe_query(flxPacketScheduler *s, flxDnsPacket *p, fl
 
     /* Create the probe query */
     k = flx_key_new(pj->record->key->name, pj->record->key->class, FLX_DNS_TYPE_ANY);
-    ret = flx_dns_packet_append_key(p, k);
+    ret = flx_dns_packet_append_key(p, k, FALSE);
     g_assert(ret);
 
     /* Mark this job for addition to the packet */
diff --git a/rr.h b/rr.h
index 465c3286de7972966b91d9965daedef615feb050..65219617f32e38493f4fa2adeb29c2eacacf88e0 100644 (file)
--- a/rr.h
+++ b/rr.h
@@ -22,7 +22,8 @@ enum {
 
 enum {
     FLX_DNS_CLASS_IN = 0x01,
-    FLX_DNS_CACHE_FLUSH = 0x8000
+    FLX_DNS_CACHE_FLUSH = 0x8000,
+    FLX_DNS_UNICAST_RESPONSE = 0x8000
 };
 
 #define FLX_DEFAULT_TTL (120*60)
index 5cdf56d9cc97de18020c927322b35aef30421e33..dff3968e55d4d7e7a87347fcf4d6f9a69dd0a3f8 100644 (file)
--- a/server.c
+++ b/server.c
@@ -77,7 +77,7 @@ static void cleanup_dead(flxServer *s) {
     }
 }
 
-static void handle_query_key(flxServer *s, flxKey *k, flxInterface *i, const flxAddress *a) {
+static void handle_query_key(flxServer *s, flxKey *k, flxInterface *i, const flxAddress *a, guint16 port, gboolean legacy_unicast, gboolean unicast_response) {
     flxEntry *e;
     gchar *txt;
     
@@ -141,7 +141,6 @@ static void incoming_probe(flxServer *s, flxRecord *record, flxInterface *i) {
     t = flx_record_to_string(record);
 
 /*     g_message("PROBE: [%s]", t); */
-
     
     for (e = g_hash_table_lookup(s->entries_by_key, record->key); e; e = n) {
         n = e->by_key_next;
@@ -164,7 +163,7 @@ static void incoming_probe(flxServer *s, flxRecord *record, flxInterface *i) {
     g_free(t);
 }
 
-static void handle_query(flxServer *s, flxDnsPacket *p, flxInterface *i, const flxAddress *a) {
+static void handle_query(flxServer *s, flxDnsPacket *p, flxInterface *i, const flxAddress *a, guint16 port, gboolean legacy_unicast) {
     guint n;
     
     g_assert(s);
@@ -175,17 +174,18 @@ static void handle_query(flxServer *s, flxDnsPacket *p, flxInterface *i, const f
     /* Handle the questions */
     for (n = flx_dns_packet_get_field(p, FLX_DNS_FIELD_QDCOUNT); n > 0; n --) {
         flxKey *key;
+        gboolean unicast_response = FALSE;
 
-        if (!(key = flx_dns_packet_consume_key(p))) {
+        if (!(key = flx_dns_packet_consume_key(p, &unicast_response))) {
             g_warning("Packet too short (1)");
             return;
         }
 
-        handle_query_key(s, key, i, a);
+        handle_query_key(s, key, i, a, port, legacy_unicast, unicast_response);
         flx_key_unref(key);
     }
 
-    /* Known Answer Suppresion */
+    /* Known Answer Suppression */
     for (n = flx_dns_packet_get_field(p, FLX_DNS_FIELD_ANCOUNT); n > 0; n --) {
         flxRecord *record;
         gboolean unique = FALSE;
@@ -320,36 +320,30 @@ static void handle_response(flxServer *s, flxDnsPacket *p, flxInterface *i, cons
 static void dispatch_packet(flxServer *s, flxDnsPacket *p, struct sockaddr *sa, gint iface, gint ttl) {
     flxInterface *i;
     flxAddress a;
+    guint16 port;
     
     g_assert(s);
     g_assert(p);
     g_assert(sa);
     g_assert(iface > 0);
 
-    g_message("new packet recieved.");
-
     if (!(i = flx_interface_monitor_get_interface(s->monitor, iface, sa->sa_family))) {
         g_warning("Recieved packet from invalid interface.");
         return;
     }
 
-    if (ttl != 255) {
-        g_warning("Recieved packet with invalid TTL on interface '%s.%i'.", i->hardware->name, i->protocol);
-        if (!s->ignore_bad_ttl)
-            return;
-    }
+    g_message("new packet recieved on interface '%s.%i'.", i->hardware->name, i->protocol);
 
     if (sa->sa_family == AF_INET6) {
-        static const unsigned char ipv4_in_ipv6[] = {
+        static const guint8 ipv4_in_ipv6[] = {
             0x00, 0x00, 0x00, 0x00,
             0x00, 0x00, 0x00, 0x00,
             0xFF, 0xFF, 0xFF, 0xFF };
 
-        if (memcmp(((struct sockaddr_in6*) sa)->sin6_addr.s6_addr, ipv4_in_ipv6, sizeof(ipv4_in_ipv6)) == 0) {
+        /* This is an IPv4 address encapsulated in IPv6, so let's ignore it. */
 
-            /* This is an IPv4 address encapsulated in IPv6, so let's ignore it. */
+        if (memcmp(((struct sockaddr_in6*) sa)->sin6_addr.s6_addr, ipv4_in_ipv6, sizeof(ipv4_in_ipv6)) == 0)
             return;
-        }
     }
 
     if (flx_dns_packet_check_valid(p) < 0) {
@@ -357,19 +351,46 @@ static void dispatch_packet(flxServer *s, flxDnsPacket *p, struct sockaddr *sa,
         return;
     }
 
+    port = flx_port_from_sockaddr(sa);
     flx_address_from_sockaddr(sa, &a);
 
     if (flx_dns_packet_is_query(p)) {
+        gboolean legacy_unicast = FALSE;
 
         if (flx_dns_packet_get_field(p, FLX_DNS_FIELD_QDCOUNT) == 0 ||
             flx_dns_packet_get_field(p, FLX_DNS_FIELD_ARCOUNT) != 0) {
             g_warning("Invalid query packet.");
             return;
         }
-                
-        handle_query(s, p, i, &a);    
+
+        if (port != FLX_MDNS_PORT) {
+            /* Legacy Unicast */
+
+            if ((flx_dns_packet_get_field(p, FLX_DNS_FIELD_ANCOUNT) != 0 ||
+                 flx_dns_packet_get_field(p, FLX_DNS_FIELD_NSCOUNT) != 0)) {
+                g_warning("Invalid legacy unicast query packet.");
+                return;
+            }
+        
+            legacy_unicast = TRUE;
+        }
+
+        handle_query(s, p, i, &a, port, legacy_unicast);
+        
         g_message("Handled query");
     } else {
+
+        if (port != FLX_MDNS_PORT) {
+            g_warning("Recieved repsonse with invalid source port %u on interface '%s.%i'", port, i->hardware->name, i->protocol);
+            return;
+        }
+
+        if (ttl != 255) {
+            g_warning("Recieved response with invalid TTL %u on interface '%s.%i'.", ttl, i->hardware->name, i->protocol);
+            if (!s->ignore_bad_ttl)
+                return;
+        }
+
         if (flx_dns_packet_get_field(p, FLX_DNS_FIELD_QDCOUNT) != 0 ||
             flx_dns_packet_get_field(p, FLX_DNS_FIELD_ANCOUNT) == 0 ||
             flx_dns_packet_get_field(p, FLX_DNS_FIELD_NSCOUNT) != 0) {
index 48a5d4b57d89d23c463e8ee8817d8e7e11cb5562..8f50291c170df12e62da3b733f34a29b5f0235a5 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -13,8 +13,7 @@
 
 #include "dns.h"
 #include "util.h"
-
-#define MDNS_PORT 5353
+#include "socket.h"
 
 static void mdns_mcast_group_ipv4(struct sockaddr_in *ret_sa) {
     g_assert(ret_sa);
@@ -22,7 +21,7 @@ static void mdns_mcast_group_ipv4(struct sockaddr_in *ret_sa) {
     memset(ret_sa, 0, sizeof(struct sockaddr_in));
     
     ret_sa->sin_family = AF_INET;
-    ret_sa->sin_port = htons(MDNS_PORT);
+    ret_sa->sin_port = htons(FLX_MDNS_PORT);
     inet_pton(AF_INET, "224.0.0.251", &ret_sa->sin_addr);
 }
 
@@ -33,7 +32,7 @@ static void mdns_mcast_group_ipv6(struct sockaddr_in6 *ret_sa) {
     memset(ret_sa, 0, sizeof(struct sockaddr_in6));
     
     ret_sa->sin6_family = AF_INET6;
-    ret_sa->sin6_port = htons(MDNS_PORT);
+    ret_sa->sin6_port = htons(FLX_MDNS_PORT);
     inet_pton(AF_INET6, "ff02::fb", &ret_sa->sin6_addr);
 }
 
@@ -149,7 +148,7 @@ gint flx_open_socket_ipv4(void) {
     
     memset(&local, 0, sizeof(local));
     local.sin_family = AF_INET;
-    local.sin_port = htons(MDNS_PORT);
+    local.sin_port = htons(FLX_MDNS_PORT);
     
     if (bind(fd, (struct sockaddr*) &local, sizeof(local)) < 0) {
         g_warning("bind() failed: %s\n", strerror(errno));
@@ -230,7 +229,7 @@ gint flx_open_socket_ipv6(void) {
 
     memset(&local, 0, sizeof(local));
     local.sin6_family = AF_INET6;
-    local.sin6_port = htons(MDNS_PORT);
+    local.sin6_port = htons(FLX_MDNS_PORT);
     
     if (bind(fd, (struct sockaddr*) &local, sizeof(local)) < 0) {
         g_warning("bind() failed: %s\n", strerror(errno));
index 61d17a532f966ac22aa2bfcef980637aaade72a8..5548a707045a2d08d2247c174cbeb85723ec3e11 100644 (file)
--- a/socket.h
+++ b/socket.h
@@ -5,6 +5,10 @@
 
 #include "dns.h"
 
+#define FLX_MDNS_PORT 5353
+
+
+
 gint flx_open_socket_ipv4(void);
 gint flx_open_socket_ipv6(void);