duplicate query callbacks work.

git-svn-id: file:///svn/unbound/trunk@408 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-06-20 14:01:58 +00:00
parent 133b65bc67
commit fed6a738de
5 changed files with 55 additions and 0 deletions

View file

@ -833,6 +833,8 @@ worker_init(struct worker* worker, struct config_file *cfg,
worker_delete(worker); worker_delete(worker);
return 0; return 0;
} }
outside_network_set_secondary_buffer(worker->back,
worker->front->udp_buff);
if(worker->thread_num != 0) { if(worker->thread_num != 0) {
/* start listening to commands */ /* start listening to commands */
if(!(worker->cmd_com=comm_point_create_local(worker->base, if(!(worker->cmd_com=comm_point_create_local(worker->base,

View file

@ -7,6 +7,7 @@
- typo in check caused subquery errors to be ignored, fixed. - typo in check caused subquery errors to be ignored, fixed.
- make lint happy about rlim_t. - make lint happy about rlim_t.
- freeup of modules after freeup of module-states. - freeup of modules after freeup of module-states.
- duplicate replies work, this uses secondary udp buffer in outnet.
19 June 2007: Wouter 19 June 2007: Wouter
- nicer layout in stats.c, review 0.3 change. - nicer layout in stats.c, review 0.3 change.

View file

@ -472,6 +472,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
outnet->num_tcp = num_tcp; outnet->num_tcp = num_tcp;
outnet->infra = infra; outnet->infra = infra;
outnet->rnd = rnd; outnet->rnd = rnd;
outnet->udp_second = 0;
#ifndef INET6 #ifndef INET6
do_ip6 = 0; do_ip6 = 0;
#endif #endif
@ -532,6 +533,13 @@ outside_network_create(struct comm_base *base, size_t bufsize,
return outnet; return outnet;
} }
void
outside_network_set_secondary_buffer(struct outside_network* outnet,
ldns_buffer* buf)
{
outnet->udp_second = buf;
}
/** helper pending delete */ /** helper pending delete */
static void static void
pending_node_del(rbnode_t* node, void* arg) pending_node_del(rbnode_t* node, void* arg)
@ -998,6 +1006,7 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c,
struct comm_reply* rep) struct comm_reply* rep)
{ {
struct service_callback* p = sq->cblist, *n; struct service_callback* p = sq->cblist, *n;
int dobackup = (sq->cblist && sq->cblist->next); /* >1 cb*/
rbnode_t* rem; rbnode_t* rem;
/* remove from tree, and schedule for deletion, so that callbacks /* remove from tree, and schedule for deletion, so that callbacks
* can safely deregister themselves and even create new serviced * can safely deregister themselves and even create new serviced
@ -1005,8 +1014,28 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c,
rem = rbtree_delete(sq->outnet->serviced, sq); rem = rbtree_delete(sq->outnet->serviced, sq);
log_assert(rem); /* should have been present */ log_assert(rem); /* should have been present */
sq->to_be_deleted = 1; sq->to_be_deleted = 1;
if(dobackup) {
/* make a backup of the query, since the querystate processing
* may send outgoing queries that overwrite the buffer.
* use secondary buffer to store the query.
* This is a data copy, but faster than packet to server */
log_assert(ldns_buffer_capacity(sq->outnet->udp_second) >=
ldns_buffer_limit(c->buffer));
ldns_buffer_clear(sq->outnet->udp_second);
ldns_buffer_write(sq->outnet->udp_second,
ldns_buffer_begin(c->buffer),
ldns_buffer_limit(c->buffer));
ldns_buffer_flip(sq->outnet->udp_second);
}
while(p) { while(p) {
n = p->next; n = p->next;
if(dobackup) {
ldns_buffer_clear(c->buffer);
ldns_buffer_write(c->buffer,
ldns_buffer_begin(sq->outnet->udp_second),
ldns_buffer_limit(sq->outnet->udp_second));
ldns_buffer_flip(c->buffer);
}
(void)(*p->cb)(c, p->cb_arg, error, rep); (void)(*p->cb)(c, p->cb_arg, error, rep);
p = n; p = n;
} }

View file

@ -65,6 +65,12 @@ struct outside_network {
datagram at any time. */ datagram at any time. */
ldns_buffer* udp_buff; ldns_buffer* udp_buff;
/** buffer for storage. (buffer for incoming connections, since
* either an event to outside or incoming happens, but not both
* This buffer is used during callbacks, so that the datagram
* that just arrived does not collide with new datagrams sent out. */
ldns_buffer* udp_second;
/** /**
* Array of udp comm point* that are used to listen to pending events. * Array of udp comm point* that are used to listen to pending events.
* Each is on a different port. This is for ip4 ports. * Each is on a different port. This is for ip4 ports.
@ -265,6 +271,16 @@ struct outside_network* outside_network_create(struct comm_base* base,
*/ */
void outside_network_delete(struct outside_network* outnet); void outside_network_delete(struct outside_network* outnet);
/**
* Set secondary UDP buffer. Make sure it is not used during outside network
* callbacks. Such as the incoming network UDP buffer. Caller responsible
* for deletion.
* @param outnet: outside network.
* @param buf: buffer to use as secondary buffer.
*/
void outside_network_set_secondary_buffer(struct outside_network* outnet,
ldns_buffer* buf);
/** /**
* Send UDP query, create pending answer. * Send UDP query, create pending answer.
* Changes the ID for the query to be random and unique for that destination. * Changes the ID for the query to be random and unique for that destination.

View file

@ -668,6 +668,13 @@ outside_network_delete(struct outside_network* outnet)
free(outnet); free(outnet);
} }
void
outside_network_set_secondary_buffer(struct outside_network*
ATTR_UNUSED(outnet), ldns_buffer* ATTR_UNUSED(buf))
{
/* nothing to do */
}
struct pending* struct pending*
pending_udp_query(struct outside_network* outnet, ldns_buffer* packet, pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
struct sockaddr_storage* addr, socklen_t addrlen, int timeout, struct sockaddr_storage* addr, socklen_t addrlen, int timeout,