Lines Matching defs:mesh

2  * services/mesh.c - deal with mesh of query states and handle events for that.
39 * This file contains functions to assist in dealing with a mesh of
40 * query states. This mesh is supposed to be thread-specific.
46 #include "services/mesh.h"
81 * Compare two response-ip client info entries for the purpose of mesh state
85 * We cannot share the mesh state for two queries if different response-ip
193 struct mesh_area* mesh = calloc(1, sizeof(struct mesh_area));
194 if(!mesh) {
195 log_err("mesh area alloc: out of memory");
198 mesh->histogram = timehist_setup();
199 mesh->qbuf_bak = sldns_buffer_new(env->cfg->msg_buffer_size);
200 if(!mesh->histogram || !mesh->qbuf_bak) {
201 free(mesh);
202 log_err("mesh area alloc: out of memory");
205 mesh->mods = *stack;
206 mesh->env = env;
207 rbtree_init(&mesh->run, &mesh_state_compare);
208 rbtree_init(&mesh->all, &mesh_state_compare);
209 mesh->num_reply_addrs = 0;
210 mesh->num_reply_states = 0;
211 mesh->num_detached_states = 0;
212 mesh->num_forever_states = 0;
213 mesh->stats_jostled = 0;
214 mesh->stats_dropped = 0;
215 mesh->ans_expired = 0;
216 mesh->ans_cachedb = 0;
217 mesh->max_reply_states = env->cfg->num_queries_per_thread;
218 mesh->max_forever_states = (mesh->max_reply_states+1)/2;
220 mesh->jostle_max.tv_sec = (time_t)(env->cfg->jostle_time / 1000);
221 mesh->jostle_max.tv_usec = (time_t)((env->cfg->jostle_time % 1000)
224 return mesh;
227 /** help mesh delete delete mesh states */
233 * because other callbacks expect a clean state in the mesh.
241 mesh_delete(struct mesh_area* mesh)
243 if(!mesh)
246 while(mesh->all.count)
247 mesh_delete_helper(mesh->all.root);
248 timehist_delete(mesh->histogram);
249 sldns_buffer_free(mesh->qbuf_bak);
250 free(mesh);
254 mesh_delete_all(struct mesh_area* mesh)
257 while(mesh->all.count)
258 mesh_delete_helper(mesh->all.root);
259 mesh->stats_dropped += mesh->num_reply_addrs;
260 /* clear mesh area references */
261 rbtree_init(&mesh->run, &mesh_state_compare);
262 rbtree_init(&mesh->all, &mesh_state_compare);
263 mesh->num_reply_addrs = 0;
264 mesh->num_reply_states = 0;
265 mesh->num_detached_states = 0;
266 mesh->num_forever_states = 0;
267 mesh->forever_first = NULL;
268 mesh->forever_last = NULL;
269 mesh->jostle_first = NULL;
270 mesh->jostle_last = NULL;
273 int mesh_make_new_space(struct mesh_area* mesh, sldns_buffer* qbuf)
275 struct mesh_state* m = mesh->jostle_first;
277 if(mesh->num_reply_states < mesh->max_reply_states)
283 timeval_subtract(&age, mesh->env->now_tv,
285 if(timeval_smaller(&mesh->jostle_max, &age)) {
292 if(qbuf) sldns_buffer_copy(mesh->qbuf_bak, qbuf);
298 mesh_walk_supers(mesh, m);
300 mesh->stats_jostled ++;
304 if(qbuf) sldns_buffer_copy(qbuf, mesh->qbuf_bak);
403 void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
409 int unique = unique_mesh_state(edns->opt_list_in, mesh->env);
413 int timeout = mesh->env->cfg->serve_expired?
414 mesh->env->cfg->serve_expired_client_timeout:0;
420 if(!infra_wait_limit_allowed(mesh->env->infra_cache, rep,
421 edns->cookie_valid, mesh->env->cfg)) {
425 mesh->stats_dropped++;
429 s = mesh_area_find(mesh, cinfo, qinfo, mesh_flags, 0, 0);
432 if(!mesh_make_new_space(mesh, rep->c->buffer)) {
436 mesh->stats_dropped++;
443 if(mesh->num_reply_addrs > mesh->max_reply_states*16) {
447 mesh->stats_dropped++;
456 s = mesh_state_create(mesh->env, qinfo, cinfo,
460 if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL,
461 LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch, mesh->env->now_tv))
469 mesh->num_detached_states++;
479 if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL,
480 NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch, mesh->env->now_tv))
495 rbtree_insert(&mesh->all, &s->node);
511 if(!tcp_req_info_add_meshstate(rep->c->tcp_req_info, mesh, s)) {
517 http2_stream_add_meshstate(rep->c->h2_stream, mesh, s);
525 if(!timeout && mesh->env->cfg->serve_expired &&
526 !mesh->env->cfg->serve_expired_client_timeout &&
527 (mesh->env->cachedb_enabled &&
528 mesh->env->cfg->cachedb_check_when_serve_expired)) {
535 infra_wait_limit_inc(mesh->env->infra_cache, rep, *mesh->env->now,
536 mesh->env->cfg);
539 log_assert(mesh->num_detached_states > 0);
540 mesh->num_detached_states--;
543 mesh->num_reply_states ++;
545 mesh->num_reply_addrs++;
548 if(mesh->num_forever_states < mesh->max_forever_states) {
549 mesh->num_forever_states ++;
550 mesh_list_insert(s, &mesh->forever_first,
551 &mesh->forever_last);
554 mesh_list_insert(s, &mesh->jostle_first,
555 &mesh->jostle_last);
560 mesh_run(mesh, s, module_event_new, NULL);
564 if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, &s->s,
565 NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch, mesh->env->now_tv))
578 mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
583 int unique = unique_mesh_state(edns->opt_list_in, mesh->env);
584 int timeout = mesh->env->cfg->serve_expired?
585 mesh->env->cfg->serve_expired_client_timeout:0;
591 s = mesh_area_find(mesh, NULL, qinfo, mesh_flags, 0, 0);
600 s = mesh_state_create(mesh->env, qinfo, NULL,
606 mesh->num_detached_states++;
623 rbtree_insert(&mesh->all, &s->node);
646 if(!timeout && mesh->env->cfg->serve_expired &&
647 !mesh->env->cfg->serve_expired_client_timeout &&
648 (mesh->env->cachedb_enabled &&
649 mesh->env->cfg->cachedb_check_when_serve_expired)) {
659 log_assert(mesh->num_detached_states > 0);
660 mesh->num_detached_states--;
663 mesh->num_reply_states ++;
665 mesh->num_reply_addrs++;
667 mesh_run(mesh, s, module_event_new, NULL);
676 static void mesh_schedule_prefetch(struct mesh_area* mesh,
684 struct mesh_state* s = mesh_area_find(mesh, NULL, qinfo,
699 if(!mesh_make_new_space(mesh, NULL)) {
701 mesh->stats_dropped ++;
705 s = mesh_state_create(mesh->env, qinfo, NULL, mesh_flags, 0, 0);
715 rbtree_insert(&mesh->all, &s->node);
718 mesh->num_detached_states++;
725 if(mesh->num_forever_states < mesh->max_forever_states) {
726 mesh->num_forever_states ++;
727 mesh_list_insert(s, &mesh->forever_first,
728 &mesh->forever_last);
731 mesh_list_insert(s, &mesh->jostle_first,
732 &mesh->jostle_last);
744 rbtree_insert(&mesh->run, &s->run_node);
749 mesh_run(mesh, s, module_event_new, NULL);
757 static void mesh_schedule_prefetch_subnet(struct mesh_area* mesh,
770 if(!mesh_make_new_space(mesh, NULL)) {
772 mesh->stats_dropped ++;
776 s = mesh_state_create(mesh->env, qinfo, NULL, mesh_flags, 0, 0);
783 opt = edns_opt_list_find(edns_list, mesh->env->cfg->client_subnet_opcode);
802 rbtree_insert(&mesh->all, &s->node);
805 mesh->num_detached_states++;
812 if(mesh->num_forever_states < mesh->max_forever_states) {
813 mesh->num_forever_states ++;
814 mesh_list_insert(s, &mesh->forever_first,
815 &mesh->forever_last);
818 mesh_list_insert(s, &mesh->jostle_first,
819 &mesh->jostle_last);
831 rbtree_insert(&mesh->run, &s->run_node);
836 mesh_run(mesh, s, module_event_new, NULL);
840 void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
848 mesh_schedule_prefetch_subnet(mesh, qinfo, qflags, leeway, 1,
852 mesh_schedule_prefetch(mesh, qinfo, qflags, leeway, 1,
856 void mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e,
866 mesh_run(mesh, e->qstate->mesh_info, event, e);
936 for(i=0; i<env->mesh->mods.num; i++) {
958 struct mesh_area* mesh;
962 mesh = mstate->s.env->mesh;
974 * takes no time and also it does not do the mesh accounting */
977 infra_wait_limit_dec(mesh->env->infra_cache,
978 &rep->query_reply, mesh->env->cfg);
982 log_assert(mesh->num_reply_addrs > 0);
983 mesh->num_reply_addrs--;
990 log_assert(mesh->num_reply_addrs > 0);
991 mesh->num_reply_addrs--;
996 for(i=0; i<mesh->mods.num; i++) {
997 fptr_ok(fptr_whitelist_mod_clear(mesh->mods.mod[i]->clear));
998 (*mesh->mods.mod[i]->clear)(&mstate->s, i);
1008 struct mesh_area* mesh;
1014 mesh = mstate->s.env->mesh;
1017 mesh->num_forever_states --;
1018 mesh_list_remove(mstate, &mesh->forever_first,
1019 &mesh->forever_last);
1021 mesh_list_remove(mstate, &mesh->jostle_first,
1022 &mesh->jostle_last);
1026 log_assert(mesh->num_detached_states > 0);
1027 mesh->num_detached_states--;
1030 log_assert(mesh->num_reply_states > 0);
1031 mesh->num_reply_states--;
1038 (void)rbtree_delete(&mesh->run, mstate);
1039 (void)rbtree_delete(&mesh->all, mstate);
1075 struct mesh_area* mesh = qstate->env->mesh;
1092 mesh->num_detached_states++;
1093 log_assert(mesh->num_detached_states +
1094 mesh->num_reply_states <= mesh->all.count);
1105 struct mesh_area* mesh = qstate->env->mesh;
1106 *sub = mesh_area_find(mesh, NULL, qinfo, qflags,
1128 rbtree_insert(&mesh->all, &(*sub)->node);
1131 mesh->num_detached_states++;
1138 rbtree_insert(&mesh->run, &(*sub)->run_node);
1149 struct mesh_area* mesh = qstate->env->mesh;
1161 log_assert(mesh->num_detached_states > 0);
1162 mesh->num_detached_states--;
1206 * callback results to mesh cb entry
1207 * @param m: mesh state to send it for.
1212 * a value from one of the packets if the mesh state had packets.
1275 log_assert(m->s.env->mesh->num_reply_addrs > 0);
1276 m->s.env->mesh->num_reply_addrs--;
1323 * Send reply to mesh reply entry
1324 * @param m: mesh state to send it for.
1343 * null stops the mesh state remove and thus
1358 m->s.env->mesh->ans_bogus++;
1368 * for HTTP/2 stream to refer to mesh state, in case
1467 log_assert(m->s.env->mesh->num_reply_addrs > 0);
1468 m->s.env->mesh->num_reply_addrs--;
1473 m->s.env->mesh->replies_sent++;
1474 timeval_add(&m->s.env->mesh->replies_sum_wait, &duration);
1475 timehist_insert(m->s.env->mesh->histogram, &duration);
1479 if(secure) m->s.env->mesh->ans_secure++;
1480 m->s.env->mesh->ans_rcode[ rc ] ++;
1482 m->s.env->mesh->ans_nodata++;
1528 * tcp req info cleanup routine that calls the mesh
1541 mstate->s.env->mesh->stats_dropped++;
1560 * mesh processing, this is the point to take that action. */
1563 * tcp req info cleanup routine that calls the mesh
1588 /* mesh_send_reply removed mesh state from
1600 mstate->s.env->mesh->rpz_action[RPZ_DISABLED_ACTION] += i;
1602 mstate->s.env->mesh->rpz_action[RPZ_CNAME_OVERRIDE_ACTION] += i;
1604 mstate->s.env->mesh->rpz_action[respip_action_to_rpz_action(
1610 mstate->s.env->mesh->ans_cachedb += i;
1619 log_assert(mstate->s.env->mesh->num_reply_states > 0);
1620 mstate->s.env->mesh->num_reply_states--;
1624 mstate->s.env->mesh->num_detached_states++;
1633 log_assert(mstate->s.env->mesh->num_reply_states > 0);
1634 mstate->s.env->mesh->num_reply_states--;
1639 mstate->s.env->mesh->num_detached_states++;
1644 void mesh_walk_supers(struct mesh_area* mesh, struct mesh_state* mstate)
1650 (void)rbtree_insert(&mesh->run, &ref->s->run_node);
1653 mesh->mods.mod[ref->s->s.curmod]->inform_super));
1654 (*mesh->mods.mod[ref->s->s.curmod]->inform_super)(&mstate->s,
1661 struct mesh_state* mesh_area_find(struct mesh_area* mesh,
1673 /* We are searching for a similar mesh state when we DO want to
1679 result = (struct mesh_state*)rbtree_search(&mesh->all, &key);
1815 * Continue processing the mesh state at another module.
1818 * @param mesh: the mesh area.
1819 * @param mstate: currently active mesh state.
1821 * send replies to clients and inform other mesh states.
1822 * This in turn may create additional runnable mesh states.
1830 mesh_continue(struct mesh_area* mesh, struct mesh_state* mstate,
1837 mesh->mods.mod[mstate->s.curmod]->name);
1845 if(mesh->mods.num == mstate->s.curmod) {
1850 return mesh_continue(mesh, mstate, module_error, ev);
1854 for(; mstate->s.curmod < mesh->mods.num;
1857 mesh->mods.mod[mstate->s.curmod]->clear));
1858 (*mesh->mods.mod[mstate->s.curmod]->clear)
1879 mesh_walk_supers(mesh, mstate);
1894 modstack_find(&mesh->mods, "subnetcache") != -1 &&
1902 mesh_walk_supers(mesh, mstate);
1926 mesh_new_prefetch(mesh, qinfo, qflags, 0,
1943 void mesh_run(struct mesh_area* mesh, struct mesh_state* mstate,
1951 mesh->mods.mod[mstate->s.curmod]->operate));
1952 (*mesh->mods.mod[mstate->s.curmod]->operate)
1960 mesh->mods.mod[mstate->s.curmod]->name, strextstate(s));
1962 if(mesh_continue(mesh, mstate, s, &ev))
1967 if(mesh->run.count > 0) {
1969 mstate = (struct mesh_state*)mesh->run.root->key;
1970 (void)rbtree_delete(&mesh->run, mstate);
1974 mesh_stats(mesh, "mesh_run: end");
1975 mesh_log_list(mesh);
1980 mesh_log_list(struct mesh_area* mesh)
1985 RBTREE_FOR(m, struct mesh_state*, &mesh->all) {
2001 mesh_stats(struct mesh_area* mesh, const char* str)
2006 str, (unsigned)mesh->all.count,
2007 (unsigned)mesh->num_reply_states,
2008 (unsigned)mesh->num_detached_states,
2009 (unsigned)mesh->num_reply_addrs,
2010 (unsigned)mesh->replies_sent,
2011 (unsigned)mesh->stats_dropped,
2012 (unsigned)mesh->stats_jostled);
2013 if(mesh->replies_sent > 0) {
2015 timeval_divide(&avg, &mesh->replies_sum_wait,
2016 mesh->replies_sent);
2021 timehist_log(mesh->histogram, "recursions");
2026 mesh_stats_clear(struct mesh_area* mesh)
2028 if(!mesh)
2030 mesh->replies_sent = 0;
2031 mesh->replies_sum_wait.tv_sec = 0;
2032 mesh->replies_sum_wait.tv_usec = 0;
2033 mesh->stats_jostled = 0;
2034 mesh->stats_dropped = 0;
2035 timehist_clear(mesh->histogram);
2036 mesh->ans_secure = 0;
2037 mesh->ans_bogus = 0;
2038 mesh->ans_expired = 0;
2039 mesh->ans_cachedb = 0;
2040 memset(&mesh->ans_rcode[0], 0, sizeof(size_t)*UB_STATS_RCODE_NUM);
2041 memset(&mesh->rpz_action[0], 0, sizeof(size_t)*UB_STATS_RPZ_ACTION_NUM);
2042 mesh->ans_nodata = 0;
2046 mesh_get_mem(struct mesh_area* mesh)
2049 size_t s = sizeof(*mesh) + sizeof(struct timehist) +
2050 sizeof(struct th_buck)*mesh->histogram->num +
2051 sizeof(sldns_buffer) + sldns_buffer_capacity(mesh->qbuf_bak);
2052 RBTREE_FOR(m, struct mesh_state*, &mesh->all) {
2063 struct mesh_area* mesh = qstate->env->mesh;
2065 dep_m = mesh_area_find(mesh, NULL, qinfo, flags, prime, valrec);
2092 void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
2106 log_assert(mesh->num_reply_addrs > 0);
2107 mesh->num_reply_addrs--;
2108 infra_wait_limit_dec(mesh->env->infra_cache,
2109 &n->query_reply, mesh->env->cfg);
2121 mesh->num_detached_states++;
2125 log_assert(mesh->num_reply_states > 0);
2126 mesh->num_reply_states--;
2163 struct mesh_area* mesh = qstate->env->mesh;
2204 if((mesh->use_response_ip || mesh->use_rpz) &&
2257 * tcp req info cleanup routine that calls the mesh
2270 mstate->s.env->mesh->stats_dropped++;
2301 /* mesh_send_reply removed mesh state from http2_stream. */
2309 mesh->ans_expired += i;
2313 qstate->env->mesh->rpz_action[RPZ_DISABLED_ACTION] += i;
2315 qstate->env->mesh->rpz_action[RPZ_CNAME_OVERRIDE_ACTION] += i;
2317 qstate->env->mesh->rpz_action[
2326 log_assert(mesh->num_reply_states > 0);
2327 mesh->num_reply_states--;
2329 mesh->num_detached_states++;
2339 log_assert(qstate->env->mesh->num_reply_states > 0);
2340 qstate->env->mesh->num_reply_states--;
2345 qstate->env->mesh->num_detached_states++;
2358 int mesh_jostle_exceeded(struct mesh_area* mesh)
2360 if(mesh->all.count < mesh->max_reply_states)