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.
131 lines
4.6 KiB
131 lines
4.6 KiB
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 |
|
|
|
|