Blame SOURCES/0004-avahi-core-reserve-space-for-record-data-when-size-e.patch

1a7c47
From 86e213fbd0d24b5b2e58d474d27d47b222011936 Mon Sep 17 00:00:00 2001
1a7c47
From: "Lee, Chun-Yi" <jlee at suse.com>
1a7c47
Date: Mon, 10 Sep 2012 10:27:56 +0800
1a7c47
Subject: [PATCH 4/4] avahi-core: reserve space for record data when size
1a7c47
 estimate
1a7c47
1a7c47
When we tested put a lot of airprint service files(have 45 to 60 flies), found
1a7c47
there have cpu loadinghigh problem when start avahi-daemon with those service
1a7c47
files.
1a7c47
1a7c47
After traced source code, there have problem in probe-sched.c::elapse_callback
1a7c47
causes doesn't have any probe job set to DONE so the daemon unlimited send out
1a7c47
DNS package.
1a7c47
1a7c47
The root cause is when compare with the free package space in
1a7c47
packet_add_probe_query before attach job key, the free package space doesn't
1a7c47
include any record data that will attached after all keys attached. This defect
1a7c47
causes whole DNS package is filled by job key, but doesn't remain enough space
1a7c47
for any rdata. Then, that means have no job set to DONE.
1a7c47
1a7c47
This patch add a new res_size member to AvahiDnsPacket, it used to sum the
1a7c47
reserve size for record data the will attached after all keys attached. It can
1a7c47
avoid keys consume whole size until p->size larger then p->max_size.
1a7c47
1a7c47
Resolves: #1081801
1a7c47
---
1a7c47
 avahi-core/dns.c         | 20 ++++++++++++++++++++
1a7c47
 avahi-core/dns.h         |  4 +++-
1a7c47
 avahi-core/probe-sched.c | 10 ++++++++--
1a7c47
 3 files changed, 31 insertions(+), 3 deletions(-)
1a7c47
1a7c47
diff --git a/avahi-core/dns.c b/avahi-core/dns.c
1a7c47
index 2fcd91f..523afdc 100644
1a7c47
--- a/avahi-core/dns.c
1a7c47
+++ b/avahi-core/dns.c
1a7c47
@@ -55,6 +55,7 @@ AvahiDnsPacket* avahi_dns_packet_new(unsigned mtu) {
1a7c47
 
1a7c47
     p->size = p->rindex = AVAHI_DNS_PACKET_HEADER_SIZE;
1a7c47
     p->max_size = max_size;
1a7c47
+    p->res_size = 0;
1a7c47
     p->name_table = NULL;
1a7c47
     p->data = NULL;
1a7c47
 
1a7c47
@@ -833,6 +834,25 @@ size_t avahi_dns_packet_space(AvahiDnsPacket *p) {
1a7c47
     return p->max_size - p->size;
1a7c47
 }
1a7c47
 
1a7c47
+size_t avahi_dns_packet_reserve_size(AvahiDnsPacket *p, size_t res_size) {
1a7c47
+    assert(p);
1a7c47
+
1a7c47
+    assert(p->size + p->res_size <= p->max_size);
1a7c47
+
1a7c47
+    if ((p->size + p->res_size + res_size) <= p->max_size)
1a7c47
+	p->res_size += res_size;
1a7c47
+
1a7c47
+    return p->res_size;
1a7c47
+}
1a7c47
+
1a7c47
+size_t avahi_dns_packet_reserved_space(AvahiDnsPacket *p) {
1a7c47
+    assert(p);
1a7c47
+
1a7c47
+    assert(p->size + p->res_size <= p->max_size);
1a7c47
+
1a7c47
+    return p->max_size - p->size - p->res_size;
1a7c47
+}
1a7c47
+
1a7c47
 int avahi_rdata_parse(AvahiRecord *record, const void* rdata, size_t size) {
1a7c47
     int ret;
1a7c47
     AvahiDnsPacket p;
1a7c47
diff --git a/avahi-core/dns.h b/avahi-core/dns.h
1a7c47
index 52e8d88..13b1ac2 100644
1a7c47
--- a/avahi-core/dns.h
1a7c47
+++ b/avahi-core/dns.h
1a7c47
@@ -30,7 +30,7 @@
1a7c47
 #define AVAHI_DNS_PACKET_SIZE_MAX (AVAHI_DNS_PACKET_HEADER_SIZE + 256 + 2 + 2 + 4 + 2 + AVAHI_DNS_RDATA_MAX)
1a7c47
 
1a7c47
 typedef struct AvahiDnsPacket {
1a7c47
-    size_t size, rindex, max_size;
1a7c47
+    size_t size, rindex, max_size, res_size;
1a7c47
     AvahiHashmap *name_table; /* for name compression */
1a7c47
     uint8_t *data;
1a7c47
 } AvahiDnsPacket;
1a7c47
@@ -78,6 +78,8 @@ int avahi_dns_packet_skip(AvahiDnsPacket *p, size_t length);
1a7c47
 
1a7c47
 int avahi_dns_packet_is_empty(AvahiDnsPacket *p);
1a7c47
 size_t avahi_dns_packet_space(AvahiDnsPacket *p);
1a7c47
+size_t avahi_dns_packet_reserve_size(AvahiDnsPacket *p, size_t res_size);
1a7c47
+size_t avahi_dns_packet_reserved_space(AvahiDnsPacket *p);
1a7c47
 
1a7c47
 #define AVAHI_DNS_FIELD_ID 0
1a7c47
 #define AVAHI_DNS_FIELD_FLAGS 1
1a7c47
diff --git a/avahi-core/probe-sched.c b/avahi-core/probe-sched.c
1a7c47
index 1e63411..63cb817 100644
1a7c47
--- a/avahi-core/probe-sched.c
1a7c47
+++ b/avahi-core/probe-sched.c
1a7c47
@@ -179,7 +179,7 @@ static int packet_add_probe_query(AvahiProbeScheduler *s, AvahiDnsPacket *p, Ava
1a7c47
         avahi_record_get_estimate_size(pj->record);
1a7c47
 
1a7c47
     /* Too large */
1a7c47
-    if (size > avahi_dns_packet_space(p))
1a7c47
+    if (size > avahi_dns_packet_reserved_space(p))
1a7c47
         return 0;
1a7c47
 
1a7c47
     /* Create the probe query */
1a7c47
@@ -189,6 +189,9 @@ static int packet_add_probe_query(AvahiProbeScheduler *s, AvahiDnsPacket *p, Ava
1a7c47
     b = !!avahi_dns_packet_append_key(p, k, 0);
1a7c47
     assert(b);
1a7c47
 
1a7c47
+    /* reserve size for record data */
1a7c47
+    avahi_dns_packet_reserve_size(p, avahi_record_get_estimate_size(pj->record));
1a7c47
+
1a7c47
     /* Mark this job for addition to the packet */
1a7c47
     pj->chosen = 1;
1a7c47
 
1a7c47
@@ -202,9 +205,12 @@ static int packet_add_probe_query(AvahiProbeScheduler *s, AvahiDnsPacket *p, Ava
1a7c47
             continue;
1a7c47
 
1a7c47
         /* This job wouldn't fit in */
1a7c47
-        if (avahi_record_get_estimate_size(pj->record) > avahi_dns_packet_space(p))
1a7c47
+        if (avahi_record_get_estimate_size(pj->record) > avahi_dns_packet_reserved_space(p))
1a7c47
             break;
1a7c47
 
1a7c47
+	/* reserve size for record data */
1a7c47
+	avahi_dns_packet_reserve_size(p, avahi_record_get_estimate_size(pj->record));
1a7c47
+
1a7c47
         /* Mark this job for addition to the packet */
1a7c47
         pj->chosen = 1;
1a7c47
     }
1a7c47
-- 
1a7c47
2.3.4
1a7c47