resolve: stop timer event source and detach from browser when a dnssd service is removed
Otherwise, if the timer event source is enabled, a new query may be
invoked by the already removed service.
This also renames dns_remove_service() to dnssd_discovered_service_detach(),
and drops unused DnssdDiscoveredService.query.
(cherry picked from commit 02f65ebead)
This commit is contained in:
committed by
Luca Boccassi
parent
3e0080355b
commit
7898414837
@@ -108,6 +108,8 @@ static int mdns_maintenance_query(sd_event_source *s, uint64_t usec, void *userd
|
||||
_cleanup_(dns_query_freep) DnsQuery *q = NULL;
|
||||
int r;
|
||||
|
||||
assert(service->service_browser);
|
||||
|
||||
/* Check if the TTL state has reached the maximum value, then revisit
|
||||
* cache */
|
||||
if (service->rr_ttl_state++ == DNS_RECORD_TTL_STATE_100_PERCENT)
|
||||
@@ -171,12 +173,10 @@ int dns_add_new_service(DnsServiceBrowser *sb, DnsResourceRecord *rr, int owner_
|
||||
|
||||
*s = (DnssdDiscoveredService) {
|
||||
.n_ref = 1,
|
||||
.service_browser = sb,
|
||||
.rr = dns_resource_record_copy(rr),
|
||||
.family = owner_family,
|
||||
.ifindex = ifindex,
|
||||
.until = until,
|
||||
.query = NULL,
|
||||
.rr_ttl_state = DNS_RECORD_TTL_STATE_80_PERCENT,
|
||||
};
|
||||
if (!s->rr)
|
||||
@@ -221,34 +221,39 @@ int dns_add_new_service(DnsServiceBrowser *sb, DnsResourceRecord *rr, int owner_
|
||||
"Failed to schedule mDNS maintenance query for DNS service: %m");
|
||||
|
||||
LIST_PREPEND(dns_services, sb->dns_services, s);
|
||||
|
||||
s->service_browser = sb;
|
||||
TAKE_PTR(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dns_remove_service(DnsServiceBrowser *sb, DnssdDiscoveredService *service) {
|
||||
assert(sb);
|
||||
static DnssdDiscoveredService* dnssd_discovered_service_detach_impl(DnssdDiscoveredService *service) {
|
||||
assert(service);
|
||||
|
||||
LIST_REMOVE(dns_services, sb->dns_services, service);
|
||||
dnssd_discovered_service_unref(service);
|
||||
}
|
||||
|
||||
DnssdDiscoveredService *dns_service_free(DnssdDiscoveredService *service) {
|
||||
if (!service)
|
||||
return NULL;
|
||||
|
||||
service->schedule_event = sd_event_source_disable_unref(service->schedule_event);
|
||||
|
||||
if (service->query && DNS_TRANSACTION_IS_LIVE(service->query->state))
|
||||
dns_query_complete(service->query, DNS_TRANSACTION_ABORTED);
|
||||
if (!service->service_browser)
|
||||
return NULL; /* already detached */
|
||||
|
||||
LIST_REMOVE(dns_services, service->service_browser->dns_services, service);
|
||||
service->service_browser = NULL;
|
||||
return service; /* indicate that the service is detached. */
|
||||
}
|
||||
|
||||
static void dnssd_discovered_service_detach(DnssdDiscoveredService *service) {
|
||||
dnssd_discovered_service_unref(dnssd_discovered_service_detach_impl(service));
|
||||
}
|
||||
|
||||
static DnssdDiscoveredService* dnssd_discovered_service_free(DnssdDiscoveredService *service) {
|
||||
if (!service)
|
||||
return NULL;
|
||||
|
||||
dnssd_discovered_service_detach_impl(service);
|
||||
service->rr = dns_resource_record_unref(service->rr);
|
||||
|
||||
return mfree(service);
|
||||
}
|
||||
|
||||
DEFINE_TRIVIAL_REF_UNREF_FUNC(DnssdDiscoveredService, dnssd_discovered_service, dns_service_free);
|
||||
DEFINE_TRIVIAL_REF_UNREF_FUNC(DnssdDiscoveredService, dnssd_discovered_service, dnssd_discovered_service_free);
|
||||
|
||||
int mdns_service_update(DnssdDiscoveredService *service, DnsResourceRecord *rr, usec_t t, usec_t until) {
|
||||
assert(service);
|
||||
@@ -498,7 +503,7 @@ int mdns_manage_services_answer(DnsServiceBrowser *sb, DnsAnswer *answer, int ow
|
||||
/* Capture ifindex before removing the service */
|
||||
ifindex = service->ifindex;
|
||||
|
||||
dns_remove_service(sb, service);
|
||||
dnssd_discovered_service_detach(service);
|
||||
|
||||
log_debug("Remove from the list %s, %s, %s, %s, %d",
|
||||
strna(name),
|
||||
@@ -904,7 +909,7 @@ static DnsServiceBrowser* dns_service_browser_detach_impl(DnsServiceBrowser *sb)
|
||||
assert(!sb->manager == !sb->link);
|
||||
|
||||
while (sb->dns_services)
|
||||
dns_remove_service(sb, sb->dns_services);
|
||||
dnssd_discovered_service_detach(sb->dns_services);
|
||||
|
||||
sb->schedule_event = sd_event_source_disable_unref(sb->schedule_event);
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ struct DnssdDiscoveredService {
|
||||
int ifindex;
|
||||
usec_t until;
|
||||
DnsRecordTTLState rr_ttl_state;
|
||||
DnsQuery *query;
|
||||
LIST_FIELDS(DnssdDiscoveredService, dns_services);
|
||||
};
|
||||
|
||||
@@ -52,9 +51,6 @@ struct DnsServiceBrowser {
|
||||
LIST_HEAD(DnssdDiscoveredService, dns_services);
|
||||
};
|
||||
|
||||
void dns_remove_service(DnsServiceBrowser *sb, DnssdDiscoveredService *service);
|
||||
DnssdDiscoveredService *dns_service_free(DnssdDiscoveredService *service);
|
||||
|
||||
void dns_service_browser_detach(DnsServiceBrowser *sb);
|
||||
DECLARE_TRIVIAL_REF_UNREF_FUNC(DnsServiceBrowser, dns_service_browser);
|
||||
DECLARE_TRIVIAL_REF_UNREF_FUNC(DnssdDiscoveredService, dnssd_discovered_service);
|
||||
|
||||
Reference in New Issue
Block a user