LDNS_QR_SET(ldns_buffer_begin(worker->query_reply.c->buffer));
LDNS_RCODE_SET(ldns_buffer_begin(worker->query_reply.c->buffer), r);
comm_point_send_reply(&worker->query_reply);
+ if(worker->num_requests == 1) {
+ /* no longer at max, start accepting again. */
+ listen_resume(worker->front);
+ }
worker->num_requests --;
}
struct comm_reply* ATTR_UNUSED(reply_info))
{
struct worker* worker = (struct worker*)arg;
+ log_info("reply to query with stored ID %d", worker->query_id);
LDNS_ID_SET(ldns_buffer_begin(worker->query_reply.c->buffer),
worker->query_id);
if(error != 0) {
LDNS_QR_SET(ldns_buffer_begin(worker->query_reply.c->buffer));
ldns_buffer_flip(worker->query_reply.c->buffer);
comm_point_send_reply(&worker->query_reply);
+ if(worker->num_requests == 1) {
+ /* no longer at max, start accepting again. */
+ listen_resume(worker->front);
+ }
worker->num_requests --;
return 0;
}
/* query the forwarding address */
worker->query_id = LDNS_ID_WIRE(ldns_buffer_begin(
worker->query_reply.c->buffer));
+ log_info("stored in process_query ID %d", worker->query_id);
pending_udp_query(worker->back, worker->query_reply.c->buffer,
&worker->fwd_addr, worker->fwd_addrlen, UDP_QUERY_TIMEOUT,
worker_handle_reply, worker, worker->rndstate);
return 0;
}
if(worker->num_requests > 0) {
+ /* we could get this due to a slow tcp incoming query,
+ that started before we performed listen_pushback */
verbose(VERB_DETAIL, "worker: too many incoming requests "
"active. dropping incoming query.");
comm_point_drop_reply(repinfo);
}
/* answer it */
worker->num_requests ++;
+ if(worker->num_requests >= 1) {
+ /* the max request number has been reached, stop accepting */
+ listen_pushback(worker->front);
+ }
memcpy(&worker->query_reply, repinfo, sizeof(struct comm_reply));
worker_process_query(worker);
return 0;
- During reloads the daemon will temporarily handle signals,
so that they do not result in problems.
- Also randomize the outgoing port range for tests.
+ - If query list is full, will stop selecting listening ports for read.
+ This makes all threads service incoming requests, instead of one.
+ No memory is leaking during reloads, service of queries, etc.
26 February 2007: Wouter
- ub_random code used to select ID and port.
free(front);
}
+void listen_pushback(struct listen_dnsport* listen)
+{
+ struct listen_list *p;
+ log_assert(listen);
+ for(p = listen->cps; p; p = p->next)
+ {
+ if(p->com->type != comm_udp &&
+ p->com->type != comm_tcp_accept)
+ continue;
+ comm_point_stop_listening(p->com);
+ }
+}
+
+void listen_resume(struct listen_dnsport* listen)
+{
+ struct listen_list *p;
+ log_assert(listen);
+ for(p = listen->cps; p; p = p->next)
+ {
+ if(p->com->type != comm_udp &&
+ p->com->type != comm_tcp_accept)
+ continue;
+ comm_point_start_listening(p->com, -1, -1);
+ }
+}
+
struct listen_port*
listening_ports_open(struct config_file* cfg)
{
struct listen_port* ports, size_t bufsize,
comm_point_callback_t* cb, void* cb_arg);
+/**
+ * Stop listening to the dnsports. Ports are still open but not checked
+ * for readability - performs pushback of the load.
+ * @param listen: the listening structs to stop listening on. Note that
+ * udp and tcp-accept handlers stop, but ongoing tcp-handlers are kept
+ * going, since its rude to 'reset connection by peer' them, instead,
+ * we keep them and the callback will be called when its ready. It can
+ * be dropped at that time. New tcp and udp queries can be served by
+ * other threads.
+ */
+void listen_pushback(struct listen_dnsport* listen);
+
+/**
+ * Start listening again to the dnsports.
+ * Call after the listen_pushback has been called.
+ * @param listen: the listening structs to stop listening on.
+ */
+void listen_resume(struct listen_dnsport* listen);
+
/**
* delete the listening structure
*/
free(list);
}
+void listen_pushback(struct listen_dnsport* ATTR_UNUSED(listen))
+{
+}
+
+void listen_resume(struct listen_dnsport* ATTR_UNUSED(listen))
+{
+}
+
struct comm_point* comm_point_create_local(struct comm_base* ATTR_UNUSED(base),
int ATTR_UNUSED(fd), size_t ATTR_UNUSED(bufsize),
comm_point_callback_t* ATTR_UNUSED(callback),
free(c->tcp_handlers);
}
free(c->timeout);
- if(c->type == comm_tcp)
+ if(c->type == comm_tcp || c->type == comm_local)
ldns_buffer_free(c->buffer);
free(c->ev);
free(c);