summaryrefslogtreecommitdiff
path: root/services/mesh.c
diff options
context:
space:
mode:
Diffstat (limited to 'services/mesh.c')
-rw-r--r--services/mesh.c66
1 files changed, 52 insertions, 14 deletions
diff --git a/services/mesh.c b/services/mesh.c
index 286901047698..99361b17f964 100644
--- a/services/mesh.c
+++ b/services/mesh.c
@@ -467,6 +467,8 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
"incoming query.");
if(rep->c->use_h2)
http2_stream_remove_mesh_state(rep->c->h2_stream);
+ else if(rep->c->type == comm_doq && rep->doq_stream)
+ doq_stream_remove_mesh_state(rep->doq_stream);
comm_point_drop_reply(rep);
mesh->stats_dropped++;
return;
@@ -480,6 +482,8 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
"dropping incoming query.");
if(rep->c->use_h2)
http2_stream_remove_mesh_state(rep->c->h2_stream);
+ else if(rep->c->type == comm_doq && rep->doq_stream)
+ doq_stream_remove_mesh_state(rep->doq_stream);
comm_point_drop_reply(rep);
mesh->num_queries_replyaddr_limit++;
return;
@@ -552,6 +556,8 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
}
if(rep->c->use_h2) {
http2_stream_add_meshstate(rep->c->h2_stream, mesh, s);
+ } else if(rep->c->type == comm_doq && rep->doq_stream) {
+ doq_stream_add_meshstate(rep->doq_stream, mesh, s);
}
/* add serve expired timer if required and not already there */
if(timeout && !mesh_serve_expired_init(s, timeout)) {
@@ -605,6 +611,8 @@ servfail_mem:
qinfo, qid, qflags, edns);
if(rep->c->use_h2)
http2_stream_remove_mesh_state(rep->c->h2_stream);
+ else if(rep->c->type == comm_doq && rep->doq_stream)
+ doq_stream_remove_mesh_state(rep->doq_stream);
comm_point_send_reply(rep);
if(added)
mesh_state_delete(&s->s);
@@ -925,8 +933,7 @@ cfg_region_strlist_copy(struct regional* region, struct config_strlist* list)
return result;
}
-/** Copy the client info to the query region. */
-static struct respip_client_info*
+struct respip_client_info*
mesh_copy_client_info(struct regional* region, struct respip_client_info* cinfo)
{
size_t i;
@@ -971,6 +978,11 @@ mesh_copy_client_info(struct regional* region, struct respip_client_info* cinfo)
cinfo->view->name);
if(!client_info->view_name)
return NULL;
+ } else if(cinfo->view_name) {
+ client_info->view_name = regional_strdup(region,
+ cinfo->view_name);
+ if(!client_info->view_name)
+ return NULL;
}
return client_info;
}
@@ -1484,6 +1496,10 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
* for HTTP/2 stream to refer to mesh state, in case
* connection gets cleanup before HTTP/2 stream close. */
r->h2_stream->mesh_state = NULL;
+#ifdef HAVE_NGTCP2
+ } else if(r->query_reply.doq_stream) {
+ r->query_reply.doq_stream->mesh_state = NULL;
+#endif
}
/* send the reply */
/* We don't reuse the encoded answer if:
@@ -1638,9 +1654,9 @@ static void dns_error_reporting(struct module_qstate* qstate,
opt = edns_opt_list_find(qstate->edns_opts_back_in,
LDNS_EDNS_REPORT_CHANNEL);
if(!opt) return;
- agent_domain_len = opt->opt_len;
agent_domain = opt->opt_data;
- if(dname_valid(agent_domain, agent_domain_len) < 3) {
+ agent_domain_len = dname_valid(agent_domain, opt->opt_len);
+ if(agent_domain_len < 3) {
/* The agent domain needs to be a valid dname that is not the
* root; from RFC9567. */
return;
@@ -1777,6 +1793,8 @@ void mesh_query_done(struct mesh_state* mstate)
mstate->reply_list = NULL;
if(r->query_reply.c->use_h2)
http2_stream_remove_mesh_state(r->h2_stream);
+ else if(r->query_reply.doq_stream)
+ doq_stream_remove_mesh_state(r->query_reply.doq_stream);
comm_point_drop_reply(&r->query_reply);
mstate->reply_list = reply_list;
log_assert(mstate->s.env->mesh->num_reply_addrs > 0);
@@ -1814,6 +1832,8 @@ void mesh_query_done(struct mesh_state* mstate)
mstate->reply_list = NULL;
if(r->query_reply.c->use_h2) {
http2_stream_remove_mesh_state(r->h2_stream);
+ } else if(r->query_reply.doq_stream) {
+ doq_stream_remove_mesh_state(r->query_reply.doq_stream);
}
comm_point_drop_reply(&r->query_reply);
mstate->reply_list = reply_list;
@@ -2009,6 +2029,8 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
if(rep->c->use_h2)
r->h2_stream = rep->c->h2_stream;
else r->h2_stream = NULL;
+ if(rep->c->type != comm_doq)
+ r->query_reply.doq_stream = NULL;
/* Data related to local alias stored in 'qinfo' (if any) is ephemeral
* and can be different for different original queries (even if the
@@ -2366,7 +2388,7 @@ void mesh_list_remove(struct mesh_state* m, struct mesh_state** fp,
}
void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
- struct comm_point* cp)
+ struct comm_point* cp, struct doq_stream* doq_stream)
{
struct mesh_reply* n, *prev = NULL;
n = m->reply_list;
@@ -2374,7 +2396,8 @@ void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
* there is no accounting twice */
if(!n) return; /* nothing to remove, also no accounting needed */
while(n) {
- if(n->query_reply.c == cp) {
+ if(n->query_reply.c == cp
+ && (!doq_stream || n->query_reply.doq_stream == doq_stream)) {
/* unlink it */
if(prev) prev->next = n->next;
else m->reply_list = n->next;
@@ -2387,6 +2410,10 @@ void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
* share the same comm_point); make sure the streams
* don't point back. */
if(n->h2_stream) n->h2_stream->mesh_state = NULL;
+#ifdef HAVE_NGTCP2
+ if(n->query_reply.doq_stream)
+ n->query_reply.doq_stream->mesh_state = NULL;
+#endif
/* prev = prev; */
n = n->next;
@@ -2427,9 +2454,10 @@ apply_respip_action(struct module_qstate* qstate,
/* xxx_deny actions mean dropping the reply, unless the original reply
* was redirected to response-ip data. */
- if((actinfo->action == respip_deny ||
+ if(actinfo->action == respip_always_deny ||
+ ((actinfo->action == respip_deny ||
actinfo->action == respip_inform_deny) &&
- *encode_repp == rep)
+ *encode_repp == rep))
*encode_repp = NULL;
return 1;
@@ -2494,12 +2522,15 @@ mesh_serve_expired_callback(void* arg)
qstate->client_info, &actinfo, msg->rep, &alias_rrset, &encode_rep,
qstate->env->auth_zones)) {
return;
- } else if(partial_rep &&
- !respip_merge_cname(partial_rep, &qstate->qinfo, msg->rep,
+ } else if(partial_rep) {
+ if(!respip_merge_cname(partial_rep, &qstate->qinfo, msg->rep,
qstate->client_info, must_validate, &encode_rep, qstate->region,
qstate->env->auth_zones, qstate->env->views,
qstate->env->respip_set)) {
- return;
+ return;
+ }
+ /* merge succeeded; final reply, no further alias pass */
+ partial_rep = NULL;
}
if(!encode_rep || alias_rrset) {
if(!encode_rep) {
@@ -2510,6 +2541,7 @@ mesh_serve_expired_callback(void* arg)
partial_rep = encode_rep;
}
}
+ msg->rep = encode_rep;
/* We've found a partial reply ending with an
* alias. Replace the lookup qinfo for the
* alias target and lookup the cache again to
@@ -2536,9 +2568,10 @@ mesh_serve_expired_callback(void* arg)
log_dns_msg("Serve expired lookup", &qstate->qinfo, msg->rep);
for(r = mstate->reply_list; r; r = r->next) {
- struct timeval old;
- timeval_subtract(&old, mstate->s.env->now_tv, &r->start_time);
- if(mstate->s.env->cfg->discard_timeout != 0 &&
+ if(mesh_is_udp(r)) {
+ struct timeval old;
+ timeval_subtract(&old, mstate->s.env->now_tv, &r->start_time);
+ if(mstate->s.env->cfg->discard_timeout != 0 &&
((int)old.tv_sec)*1000+((int)old.tv_usec)/1000 >
mstate->s.env->cfg->discard_timeout) {
/* Drop the reply, it is too old */
@@ -2554,10 +2587,15 @@ mesh_serve_expired_callback(void* arg)
mstate->reply_list = NULL;
if(r->query_reply.c->use_h2)
http2_stream_remove_mesh_state(r->h2_stream);
+ else if(r->query_reply.doq_stream)
+ doq_stream_remove_mesh_state(r->query_reply.doq_stream);
comm_point_drop_reply(&r->query_reply);
mstate->reply_list = reply_list;
+ log_assert(mstate->s.env->mesh->num_reply_addrs > 0);
+ mstate->s.env->mesh->num_reply_addrs--;
mstate->s.env->mesh->num_queries_discard_timeout++;
continue;
+ }
}
i++;