diff --git a/daemon/worker.c b/daemon/worker.c index 8ae05eb67..33289ebb9 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -2160,7 +2160,10 @@ worker_init(struct worker* worker, struct config_file *cfg, if(cfg->dnstap) { log_assert(worker->daemon->dtenv != NULL); memcpy(&worker->dtenv, worker->daemon->dtenv, sizeof(struct dt_env)); - if(!dt_init(&worker->dtenv, worker->base)) + struct timeval tv; + tv.tv_sec = (time_t)(cfg->dnstap_wakeup_delay / 1000); + tv.tv_usec = (time_t)((cfg->dnstap_wakeup_delay % 1000) * 1000); + if(!dt_init(&worker->dtenv, worker->base, &tv)) fatal_exit("dt_init failed"); } #endif diff --git a/dnstap/dnstap.c b/dnstap/dnstap.c index d15eb9b00..efe7379a1 100644 --- a/dnstap/dnstap.c +++ b/dnstap/dnstap.c @@ -244,9 +244,10 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg) } int -dt_init(struct dt_env *env, struct comm_base* base) +dt_init(struct dt_env *env, struct comm_base* base, + struct timeval* wakeup_delay) { - env->msgqueue = dt_msg_queue_create(base); + env->msgqueue = dt_msg_queue_create(base, wakeup_delay); if(!env->msgqueue) { log_err("malloc failure"); return 0; diff --git a/dnstap/dnstap.h b/dnstap/dnstap.h index 169bdc2c6..ee7615e68 100644 --- a/dnstap/dnstap.h +++ b/dnstap/dnstap.h @@ -105,7 +105,8 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg); * @return: true on success, false on failure. */ int -dt_init(struct dt_env *env, struct comm_base* base); +dt_init(struct dt_env *env, struct comm_base* base, + struct timeval* wakeup_delay); /** * Deletes the per-worker state created by dt_init diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 69c951276..bfb62fa4d 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -101,7 +101,7 @@ static int dtio_enable_brief_write(struct dt_io_thread* dtio); #endif struct dt_msg_queue* -dt_msg_queue_create(struct comm_base* base) +dt_msg_queue_create(struct comm_base* base, struct timeval* wakeup_delay) { struct dt_msg_queue* mq = calloc(1, sizeof(*mq)); if(!mq) return NULL; @@ -109,6 +109,7 @@ dt_msg_queue_create(struct comm_base* base) about 1 M should contain 64K messages with some overhead, or a whole bunch smaller ones */ mq->wakeup_timer = comm_timer_create(base, mq_wakeup_cb, mq); + mq->wakeup_delay = *wakeup_delay; if(!mq->wakeup_timer) { free(mq); return NULL; @@ -219,8 +220,7 @@ dt_msg_queue_start_timer(struct dt_msg_queue* mq, int wakeupnow) /* start the timer, in mq, in the event base of our worker */ if(!wakeupnow) { - tv.tv_sec = 1; - tv.tv_usec = 0; + tv = mq->wakeup_delay; } comm_timer_set(mq->wakeup_timer, &tv); lock_basic_unlock(&mq->dtio->wakeup_timer_lock); diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index f87d6dc8d..c2b544ee2 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -78,6 +78,8 @@ struct dt_msg_queue { struct dt_io_thread* dtio; /** the wakeup timer for dtio, on worker event base */ struct comm_timer* wakeup_timer; + /** the wakeup delay to use when waking up the worker */ + struct timeval wakeup_delay; }; /** @@ -245,7 +247,8 @@ struct dt_io_list_item { * @param base: event base for wakeup timer. * @return NULL on malloc failure or a new queue (not locked). */ -struct dt_msg_queue* dt_msg_queue_create(struct comm_base* base); +struct dt_msg_queue* dt_msg_queue_create(struct comm_base* base, + struct timeval* wakeup_delay); /** * Delete a worker message queue. It has to be unlinked from access, diff --git a/doc/example.conf.in b/doc/example.conf.in index 6bf1c668e..2f1287f43 100644 --- a/doc/example.conf.in +++ b/doc/example.conf.in @@ -1286,6 +1286,7 @@ remote-control: # dnstap-identity: "" # # if "" it uses the package version. # dnstap-version: "" +# dnstap-wakeup-delay: 1000 # dnstap-log-resolver-query-messages: no # dnstap-log-resolver-response-messages: no # dnstap-log-client-query-messages: no diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in index 76cfa2383..8b58db596 100644 --- a/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in @@ -2797,6 +2797,11 @@ Default is "". The version to send with messages, if "" the package version is used. Default is "". .TP +.B dnstap-wakeup-delay: \fI +Delay before the dnstap message queue worker will handle incoming +messages. This reduces performance overhead, but increases latency. +Default is 1000 milliseconds. +.TP .B dnstap-log-resolver-query-messages: \fI Enable to log resolver query messages. Default is no. These are messages from Unbound to upstream servers. diff --git a/util/config_file.c b/util/config_file.c index 31ae8c808..e2ca7b95e 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -329,6 +329,7 @@ config_create(void) goto error_exit; #endif cfg->dnstap_bidirectional = 1; + cfg->dnstap_wakeup_delay = 1000; cfg->dnstap_tls = 1; cfg->disable_dnssec_lame_check = 0; cfg->ip_ratelimit_cookie = 0; @@ -755,6 +756,7 @@ int config_set_option(struct config_file* cfg, const char* opt, else S_YNO("dnstap-send-version:", dnstap_send_version) else S_STR("dnstap-identity:", dnstap_identity) else S_STR("dnstap-version:", dnstap_version) + else S_SIZET_OR_ZERO("dnstap-wakeup-delay:", dnstap_wakeup_delay) else S_YNO("dnstap-log-resolver-query-messages:", dnstap_log_resolver_query_messages) else S_YNO("dnstap-log-resolver-response-messages:", @@ -1226,6 +1228,7 @@ config_get_option(struct config_file* cfg, const char* opt, else O_YNO(opt, "dnstap-send-version", dnstap_send_version) else O_STR(opt, "dnstap-identity", dnstap_identity) else O_STR(opt, "dnstap-version", dnstap_version) + else O_UNS(opt, "dnstap-wakeup-delay", dnstap_wakeup_delay) else O_YNO(opt, "dnstap-log-resolver-query-messages", dnstap_log_resolver_query_messages) else O_YNO(opt, "dnstap-log-resolver-response-messages", diff --git a/util/config_file.h b/util/config_file.h index ad22b8330..71cb6eb54 100644 --- a/util/config_file.h +++ b/util/config_file.h @@ -573,6 +573,8 @@ struct config_file { char* dnstap_identity; /** dnstap "version", package version is used if "". */ char* dnstap_version; + /** dnstap worker wakeup delay */ + size_t dnstap_wakeup_delay; /** true to log dnstap RESOLVER_QUERY message events */ int dnstap_log_resolver_query_messages; diff --git a/util/configlexer.lex b/util/configlexer.lex index fdc267434..3add6d48b 100644 --- a/util/configlexer.lex +++ b/util/configlexer.lex @@ -494,6 +494,7 @@ dnstap-send-identity{COLON} { YDVAR(1, VAR_DNSTAP_SEND_IDENTITY) } dnstap-send-version{COLON} { YDVAR(1, VAR_DNSTAP_SEND_VERSION) } dnstap-identity{COLON} { YDVAR(1, VAR_DNSTAP_IDENTITY) } dnstap-version{COLON} { YDVAR(1, VAR_DNSTAP_VERSION) } +dnstap-wakeup-delay{COLON} { YDVAR(1, VAR_DNSTAP_WAKEUP_DELAY) } dnstap-log-resolver-query-messages{COLON} { YDVAR(1, VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES) } dnstap-log-resolver-response-messages{COLON} { diff --git a/util/configparser.y b/util/configparser.y index da5d6608f..c687c99c2 100644 --- a/util/configparser.y +++ b/util/configparser.y @@ -130,7 +130,7 @@ extern struct config_parser_state* cfg_parser; %token VAR_DNSTAP_TLS VAR_DNSTAP_TLS_SERVER_NAME VAR_DNSTAP_TLS_CERT_BUNDLE %token VAR_DNSTAP_TLS_CLIENT_KEY_FILE VAR_DNSTAP_TLS_CLIENT_CERT_FILE %token VAR_DNSTAP_SEND_IDENTITY VAR_DNSTAP_SEND_VERSION VAR_DNSTAP_BIDIRECTIONAL -%token VAR_DNSTAP_IDENTITY VAR_DNSTAP_VERSION +%token VAR_DNSTAP_IDENTITY VAR_DNSTAP_VERSION VAR_DNSTAP_WAKEUP_DELAY %token VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES %token VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES %token VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES @@ -3354,7 +3354,7 @@ content_dt: dt_dnstap_enable | dt_dnstap_socket_path | dt_dnstap_bidirectional | dt_dnstap_tls_cert_bundle | dt_dnstap_tls_client_key_file | dt_dnstap_tls_client_cert_file | dt_dnstap_send_identity | dt_dnstap_send_version | - dt_dnstap_identity | dt_dnstap_version | + dt_dnstap_identity | dt_dnstap_version | dt_dnstap_wakeup_delay | dt_dnstap_log_resolver_query_messages | dt_dnstap_log_resolver_response_messages | dt_dnstap_log_client_query_messages | @@ -3464,6 +3464,15 @@ dt_dnstap_version: VAR_DNSTAP_VERSION STRING_ARG cfg_parser->cfg->dnstap_version = $2; } ; +dt_dnstap_wakeup_delay: VAR_DNSTAP_WAKEUP_DELAY STRING_ARG + { + OUTYY(("P(dt_dnstap_wakeup_delay:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2, "0") != 0) + yyerror("number expected"); + else cfg_parser->cfg->dnstap_wakeup_delay = atoi($2); + free($2); + } + ; dt_dnstap_log_resolver_query_messages: VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES STRING_ARG { OUTYY(("P(dt_dnstap_log_resolver_query_messages:%s)\n", $2));