mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-06-11 09:31:28 -04:00
distribute can send out responses tsig signed
This commit is contained in:
parent
c86c267b8b
commit
7977ef28f5
8 changed files with 89 additions and 16 deletions
|
|
@ -2440,7 +2440,8 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
|||
worker->daemon->connect_dot_sslctx, cfg->delay_close,
|
||||
cfg->tls_use_sni, dtenv, cfg->udp_connect,
|
||||
cfg->max_reuse_tcp_queries, cfg->tcp_reuse_timeout,
|
||||
cfg->tcp_auth_query_timeout, cfg->dist, cfg->num_dist);
|
||||
cfg->tcp_auth_query_timeout, (const char**)cfg->dist,
|
||||
(const char**)cfg->dist_tsig, cfg->num_dist);
|
||||
if(!worker->back) {
|
||||
log_err("could not create outgoing sockets");
|
||||
worker_delete(worker);
|
||||
|
|
|
|||
|
|
@ -229,7 +229,9 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
|
|||
cfg->do_udp || cfg->udp_upstream_without_downstream, w->sslctx,
|
||||
cfg->delay_close, cfg->tls_use_sni, NULL, cfg->udp_connect,
|
||||
cfg->max_reuse_tcp_queries, cfg->tcp_reuse_timeout,
|
||||
cfg->tcp_auth_query_timeout, cfg->dist, cfg->num_dist);
|
||||
cfg->tcp_auth_query_timeout, (const char**)cfg->dist,
|
||||
(const char**)cfg->dist_tsig,
|
||||
cfg->num_dist);
|
||||
w->env->outnet = w->back;
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
#include "util/alloc.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/edns.h"
|
||||
#include "sldns/parseutil.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/wire2str.h"
|
||||
#include "services/localzone.h"
|
||||
|
|
@ -66,6 +67,8 @@
|
|||
#include "respip/respip.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "util/timeval_func.h"
|
||||
#include "util/allow_response_list.h"
|
||||
#include "util/tsig.h"
|
||||
|
||||
#ifdef CLIENT_SUBNET
|
||||
#include "edns-subnet/subnetmod.h"
|
||||
|
|
@ -1748,14 +1751,56 @@ void mesh_query_done(struct mesh_state* mstate)
|
|||
1 /* cached */, mstate->s.env->scratch,
|
||||
sizeof(data) /* udpsize */, NULL /* edns */,
|
||||
1 /* dnssec */, 0 /* secure */);
|
||||
log_err("Answer to be send to other unbounds, size: %d",
|
||||
log_err("Answer to be send to %d other unbounds, size: %d",
|
||||
mstate->s.env->outnet->num_dist,
|
||||
(int)sldns_buffer_limit(&dest));
|
||||
for(i = 0; i < mstate->s.env->outnet->num_dist; i++) {
|
||||
if(mstate->s.env->outnet->dist[i] != -1)
|
||||
struct tsig_key* key;
|
||||
int r;
|
||||
uint8_t data_signed[8192];
|
||||
struct sldns_buffer dest_signed;
|
||||
|
||||
if(mstate->s.env->outnet->dist[i] == -1
|
||||
|| mstate->s.env->outnet->dist_tsig[i] == NULL)
|
||||
continue;
|
||||
if(mstate->s.env->outnet->dist_tsig[i] == TSIG_NOKEY) {
|
||||
send(mstate->s.env->outnet->dist[i],
|
||||
data, sldns_buffer_limit(&dest), 0);
|
||||
continue;
|
||||
}
|
||||
lock_rw_rdlock(&mstate->s.env->tsig_key_table->lock);
|
||||
key = tsig_key_table_search_fromstr(
|
||||
mstate->s.env->tsig_key_table,
|
||||
mstate->s.env->outnet->dist_tsig[i]);
|
||||
if(!key) {
|
||||
lock_rw_unlock(
|
||||
&mstate->s.env->tsig_key_table->lock);
|
||||
log_err("tsig key \"%s\" not found when "
|
||||
"distributing responses",
|
||||
mstate->s.env->outnet->dist_tsig[i]);
|
||||
continue;
|
||||
}
|
||||
sldns_buffer_init_frm_data(&dest_signed,
|
||||
data_signed, sizeof(data_signed));
|
||||
sldns_buffer_write(&dest_signed,
|
||||
data, sldns_buffer_limit(&dest));
|
||||
if((r = tsig_sign_shared(&dest_signed, key->name,
|
||||
key->algo->wireformat_name,
|
||||
key->data, key->data_len,
|
||||
*mstate->s.env->now))) {
|
||||
lock_rw_unlock(
|
||||
&mstate->s.env->tsig_key_table->lock);
|
||||
log_err("tsig key \"%s\" failed to sign"
|
||||
"distributing response: %s",
|
||||
key->name_str,
|
||||
sldns_lookup_by_id(sldns_tsig_errors, r)?
|
||||
sldns_lookup_by_id(sldns_tsig_errors, r)->name:"??");
|
||||
continue;
|
||||
}
|
||||
lock_rw_unlock(&mstate->s.env->tsig_key_table->lock);
|
||||
send(mstate->s.env->outnet->dist[i], data_signed,
|
||||
sldns_buffer_position(&dest_signed), 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for(r = mstate->reply_list; r; r = r->next) {
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
#include "util/random.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/edns.h"
|
||||
#include "util/allow_response_list.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "dnstap/dnstap.h"
|
||||
#ifdef HAVE_OPENSSL_SSL_H
|
||||
|
|
@ -1678,7 +1679,8 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
|||
void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
|
||||
void* sslctx, int delayclose, int tls_use_sni, struct dt_env* dtenv,
|
||||
int udp_connect, int max_reuse_tcp_queries, int tcp_reuse_timeout,
|
||||
int tcp_auth_query_timeout, char** dist, int num_dist)
|
||||
int tcp_auth_query_timeout, const char** dist, const char** dist_tsig,
|
||||
int num_dist)
|
||||
{
|
||||
struct outside_network* outnet = (struct outside_network*)
|
||||
calloc(1, sizeof(struct outside_network));
|
||||
|
|
@ -1821,7 +1823,8 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
|||
}
|
||||
if (!(outnet->num_dist = num_dist))
|
||||
outnet->dist = NULL;
|
||||
else if ((outnet->dist = calloc(num_dist, sizeof(int)))) {
|
||||
else if ((outnet->dist = calloc(num_dist, sizeof(int))) &&
|
||||
(outnet->dist_tsig = calloc(num_dist, sizeof(const char*)))) {
|
||||
int i;
|
||||
|
||||
for(i = 0; i < num_dist; i++) {
|
||||
|
|
@ -1838,6 +1841,10 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
|||
s = -1;
|
||||
}
|
||||
outnet->dist[i] = s;
|
||||
outnet->dist_tsig[i] = dist_tsig[i] == NULL ? NULL
|
||||
: strcmp(dist_tsig[i], TSIG_NOKEY)
|
||||
? strdup(dist_tsig[i])
|
||||
: TSIG_NOKEY;
|
||||
}
|
||||
}
|
||||
return outnet;
|
||||
|
|
@ -1970,6 +1977,8 @@ outside_network_delete(struct outside_network* outnet)
|
|||
p = np;
|
||||
}
|
||||
}
|
||||
if(outnet->num_dist > 0 && outnet->dist != NULL)
|
||||
free(outnet->dist);
|
||||
free(outnet);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -194,6 +194,8 @@ struct outside_network {
|
|||
int num_dist;
|
||||
/** udp sockets to the addresses to send to be cached responses to */
|
||||
int* dist;
|
||||
/** names of TSIG keys with which to sign the outgoing responses */
|
||||
const char** dist_tsig;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -574,7 +576,8 @@ struct outside_network* outside_network_create(struct comm_base* base,
|
|||
void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
|
||||
void* sslctx, int delayclose, int tls_use_sni, struct dt_env *dtenv,
|
||||
int udp_connect, int max_reuse_tcp_queries, int tcp_reuse_timeout,
|
||||
int tcp_auth_query_timeout, char** dist, int num_dist);
|
||||
int tcp_auth_query_timeout, const char** dist, const char** dist_tsig,
|
||||
int num_dist);
|
||||
|
||||
/**
|
||||
* Delete outside_network structure.
|
||||
|
|
|
|||
|
|
@ -251,6 +251,8 @@ struct config_file {
|
|||
int num_dist;
|
||||
/** distribute description strings (IP addresses) */
|
||||
char **dist;
|
||||
/** distribute description strings (IP addresses) */
|
||||
char **dist_tsig;
|
||||
|
||||
/** list of allowed responses, linked list */
|
||||
struct config_str2list* allow_response_list;
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ use-systemd{COLON} { YDVAR(1, VAR_USE_SYSTEMD) }
|
|||
do-daemonize{COLON} { YDVAR(1, VAR_DO_DAEMONIZE) }
|
||||
interface{COLON} { YDVAR(1, VAR_INTERFACE) }
|
||||
ip-address{COLON} { YDVAR(1, VAR_INTERFACE) }
|
||||
distribute{COLON} { YDVAR(1, VAR_DISTRIBUTE ) }
|
||||
distribute{COLON} { YDVAR(2, VAR_DISTRIBUTE ) }
|
||||
allow-response{COLON} { YDVAR(2, VAR_ALLOW_RESPONSE) }
|
||||
outgoing-interface{COLON} { YDVAR(1, VAR_OUTGOING_INTERFACE) }
|
||||
interface-automatic{COLON} { YDVAR(1, VAR_INTERFACE_AUTOMATIC) }
|
||||
|
|
|
|||
|
|
@ -822,17 +822,28 @@ server_interface: VAR_INTERFACE STRING_ARG
|
|||
cfg_parser->cfg->ifs[cfg_parser->cfg->num_ifs++] = $2;
|
||||
}
|
||||
;
|
||||
server_distribute: VAR_DISTRIBUTE STRING_ARG
|
||||
server_distribute: VAR_DISTRIBUTE STRING_ARG STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_distribute:%s)\n", $2));
|
||||
if(cfg_parser->cfg->num_dist == 0)
|
||||
OUTYY(("P(server_distribute: %s %s)\n", $2, $3));
|
||||
if(cfg_parser->cfg->num_dist == 0) {
|
||||
cfg_parser->cfg->dist = calloc(1, sizeof(char*));
|
||||
else cfg_parser->cfg->dist = realloc(cfg_parser->cfg->dist,
|
||||
cfg_parser->cfg->dist_tsig = calloc(1, sizeof(char*));
|
||||
}
|
||||
else {
|
||||
cfg_parser->cfg->dist = realloc(cfg_parser->cfg->dist,
|
||||
(cfg_parser->cfg->num_dist+1)*sizeof(char*));
|
||||
if(!cfg_parser->cfg->dist)
|
||||
cfg_parser->cfg->dist_tsig = realloc(
|
||||
cfg_parser->cfg->dist_tsig,
|
||||
(cfg_parser->cfg->num_dist+1)*sizeof(char*));
|
||||
}
|
||||
if(!cfg_parser->cfg->dist || !cfg_parser->cfg->dist_tsig)
|
||||
yyerror("out of memory");
|
||||
else
|
||||
cfg_parser->cfg->dist[cfg_parser->cfg->num_dist++] = $2;
|
||||
else {
|
||||
cfg_parser->cfg->dist[cfg_parser->cfg->num_dist] = $2;
|
||||
cfg_parser->cfg->dist_tsig[cfg_parser->cfg->num_dist]
|
||||
= $3;
|
||||
cfg_parser->cfg->num_dist += 1;
|
||||
}
|
||||
}
|
||||
;
|
||||
server_allow_response: VAR_ALLOW_RESPONSE STRING_ARG STRING_ARG
|
||||
|
|
|
|||
Loading…
Reference in a new issue