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