From 605d2dd7511d18120b474f33af6fe654f37c29e9 Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Mon, 18 Jun 2007 10:27:54 +0000 Subject: [PATCH] fixup git-svn-id: file:///svn/unbound/trunk@392 be551aaa-1e26-0410-a405-d3ace91eadb9 --- daemon/worker.c | 14 +++++++++++++- doc/Changelog | 4 ++++ iterator/iterator.c | 4 ++++ services/outside_network.c | 10 ++++++---- services/outside_network.h | 5 ++++- testcode/fake_event.c | 4 +++- 6 files changed, 34 insertions(+), 7 deletions(-) diff --git a/daemon/worker.c b/daemon/worker.c index 011924fee..90801c615 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -878,6 +878,17 @@ worker_send_packet(ldns_buffer* pkt, struct sockaddr_storage* addr, worker->rndstate) != 0; } +/** compare outbound entry qstates */ +static int +outbound_entry_compare(void* a, void* b) +{ + struct outbound_entry* e1 = (struct outbound_entry*)a; + struct outbound_entry* e2 = (struct outbound_entry*)b; + if(e1->qstate == e2->qstate) + return 1; + return 0; +} + struct outbound_entry* worker_send_query(uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec, @@ -891,7 +902,8 @@ worker_send_query(uint8_t* qname, size_t qnamelen, uint16_t qtype, e->qstate = q; e->qsent = outnet_serviced_query(worker->back, qname, qnamelen, qtype, qclass, flags, dnssec, addr, addrlen, - worker_handle_service_reply, e, worker->back->udp_buff); + worker_handle_service_reply, e, worker->back->udp_buff, + &outbound_entry_compare); if(!e->qsent) { free(e); return NULL; diff --git a/doc/Changelog b/doc/Changelog index 475e15839..9923f7397 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,7 @@ +18 June 2007: Wouter + - same, move subqueries to slumber list when first has resolved. + - fixup last fix for duplicate callbacks. + 15 June 2007: Wouter - if a query asks to be notified of the same serviced query result multiple times, this will succeed. Only one callback will happen; diff --git a/iterator/iterator.c b/iterator/iterator.c index f895f99ba..97538f1d8 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -1072,6 +1072,10 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, iq->num_current_queries); return 0; } + /* move other targets to slumber list */ + if(iq->num_target_queries>0) { + (*qstate->env->remove_subqueries)(qstate); + } /* We have a valid target. */ log_nametypeclass(VERB_DETAIL, "sending query:", qstate->qinfo.qname, diff --git a/services/outside_network.c b/services/outside_network.c index 2e83417b7..e79a0f913 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -1132,11 +1132,12 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, /** find callback in list */ static struct service_callback* -callback_list_find(struct serviced_query* sq, void* cb_arg) +callback_list_find(struct serviced_query* sq, void* cb_arg, + int (*arg_compare)(void*,void*)) { struct service_callback* p; for(p = sq->cblist; p; p = p->next) { - if(p->cb_arg == cb_arg) + if(arg_compare(p->cb_arg, cb_arg)) return p; } return NULL; @@ -1147,7 +1148,8 @@ outnet_serviced_query(struct outside_network* outnet, uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec, struct sockaddr_storage* addr, socklen_t addrlen, comm_point_callback_t* callback, - void* callback_arg, ldns_buffer* buff) + void* callback_arg, ldns_buffer* buff, + int (*arg_compare)(void*,void*)) { struct serviced_query* sq; struct service_callback* cb; @@ -1155,7 +1157,7 @@ outnet_serviced_query(struct outside_network* outnet, sq = lookup_serviced(outnet, buff, dnssec, addr, addrlen); if(sq) { /* see if it is a duplicate notification request for cb_arg */ - if((cb = callback_list_find(sq, callback_arg))) { + if((cb = callback_list_find(sq, callback_arg, arg_compare))) { return sq; } } diff --git a/services/outside_network.h b/services/outside_network.h index 45d0d2dae..fb4f1a43d 100644 --- a/services/outside_network.h +++ b/services/outside_network.h @@ -324,6 +324,8 @@ void pending_delete(struct outside_network* outnet, struct pending* p); * @param addr: to which server to send the query. * @param addrlen: length of addr. * @param buff: scratch buffer to create query contents in. Empty on exit. + * @param arg_compare: function to compare callback args, return true if + * identical. It is given the callback_arg and args that are listed. * @return 0 on error, or pointer to serviced query that is used to answer * this serviced query may be shared with other callbacks as well. */ @@ -331,7 +333,8 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet, uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec, struct sockaddr_storage* addr, socklen_t addrlen, comm_point_callback_t* callback, - void* callback_arg, ldns_buffer* buff); + void* callback_arg, ldns_buffer* buff, + int (*arg_compare)(void*,void*)); /** * Remove service query callback. diff --git a/testcode/fake_event.c b/testcode/fake_event.c index b336deaba..ade1e1091 100644 --- a/testcode/fake_event.c +++ b/testcode/fake_event.c @@ -770,12 +770,14 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet, uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec, struct sockaddr_storage* addr, socklen_t addrlen, comm_point_callback_t* callback, - void* callback_arg, ldns_buffer* ATTR_UNUSED(buff)) + void* callback_arg, ldns_buffer* ATTR_UNUSED(buff), + int (*arg_compare)(void*,void*)) { struct replay_runtime* runtime = (struct replay_runtime*)outnet->base; struct fake_pending* pend = (struct fake_pending*)calloc(1, sizeof(struct fake_pending)); ldns_status status; + (void)arg_compare; log_assert(pend); /* create packet with EDNS */ -- 2.47.2