resolved: handle linked packet in dns_scope_emit()
authorDaniel Mack <daniel@zonque.org>
Wed, 9 Dec 2015 11:05:38 +0000 (12:05 +0100)
committerDaniel Mack <daniel@zonque.org>
Thu, 10 Dec 2015 09:20:55 +0000 (10:20 +0100)
In dns_scope_emit(), walk the list of additional packets and emit all of
them. Set the TC bit in all but the last of them.

This is specific to mDNS, so an assertion is triggered if used with other
protocols.

src/resolve/resolved-dns-scope.c

index 91e2353..11c3294 100644 (file)
@@ -161,7 +161,7 @@ void dns_scope_packet_lost(DnsScope *s, usec_t usec) {
                 s->resend_timeout = MIN(s->resend_timeout * 2, MULTICAST_RESEND_TIMEOUT_MAX_USEC);
 }
 
-int dns_scope_emit(DnsScope *s, int fd, DnsServer *server, DnsPacket *p) {
+static int dns_scope_emit_one(DnsScope *s, int fd, DnsServer *server, DnsPacket *p) {
         union in_addr_union addr;
         int ifindex = 0, r;
         int family;
@@ -278,6 +278,31 @@ int dns_scope_emit(DnsScope *s, int fd, DnsServer *server, DnsPacket *p) {
         return 1;
 }
 
+int dns_scope_emit(DnsScope *s, int fd, DnsServer *server, DnsPacket *p) {
+        int r;
+
+        assert(s);
+        assert(p);
+        assert(p->protocol == s->protocol);
+        assert((s->protocol == DNS_PROTOCOL_DNS) != (fd < 0));
+
+        do {
+                /* If there are multiple linked packets, set the TC bit in all but the last of them */
+                if (p->more) {
+                        assert(p->protocol == DNS_PROTOCOL_MDNS);
+                        dns_packet_set_truncated_flag(p, true);
+                }
+
+                r = dns_scope_emit_one(s, fd, server, p);
+                if (r < 0)
+                        return r;
+
+                p = p->more;
+        } while(p);
+
+        return 0;
+}
+
 static int dns_scope_socket(DnsScope *s, int type, int family, const union in_addr_union *address, uint16_t port, DnsServer **server) {
         DnsServer *srv = NULL;
         _cleanup_close_ int fd = -1;