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);
405 void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
411 int unique = unique_mesh_state(edns->opt_list_in, mesh->env);
415 int timeout = mesh->env->cfg->serve_expired?
416 mesh->env->cfg->serve_expired_client_timeout:0;
422 if(!infra_wait_limit_allowed(mesh->env->infra_cache, rep,
423 edns->cookie_valid, mesh->env->cfg)) {
427 mesh->stats_dropped++;
431 s = mesh_area_find(mesh, cinfo, qinfo, mesh_flags, 0, 0);
434 if(!mesh_make_new_space(mesh, rep->c->buffer)) {
438 mesh->stats_dropped++;
445 if(mesh->num_reply_addrs > mesh->max_reply_states*16) {
449 mesh->stats_dropped++;
458 s = mesh_state_create(mesh->env, qinfo, cinfo,
462 if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL,
463 LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch, mesh->env->now_tv))
471 mesh->num_detached_states++;
481 if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL,
482 NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch, mesh->env->now_tv))
497 rbtree_insert(&mesh->all, &s->node);
513 if(!tcp_req_info_add_meshstate(rep->c->tcp_req_info, mesh, s)) {
519 http2_stream_add_meshstate(rep->c->h2_stream, mesh, s);
527 if(!timeout && mesh->env->cfg->serve_expired &&
528 !mesh->env->cfg->serve_expired_client_timeout &&
529 (mesh->env->cachedb_enabled &&
530 mesh->env->cfg->cachedb_check_when_serve_expired)) {
537 infra_wait_limit_inc(mesh->env->infra_cache, rep, *mesh->env->now,
538 mesh->env->cfg);
541 log_assert(mesh->num_detached_states > 0);
542 mesh->num_detached_states--;
545 mesh->num_reply_states ++;
547 mesh->num_reply_addrs++;
550 if(mesh->num_forever_states < mesh->max_forever_states) {
551 mesh->num_forever_states ++;
552 mesh_list_insert(s, &mesh->forever_first,
553 &mesh->forever_last);
556 mesh_list_insert(s, &mesh->jostle_first,
557 &mesh->jostle_last);
562 mesh_run(mesh, s, module_event_new, NULL);
566 if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, &s->s,
567 NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch, mesh->env->now_tv))
580 mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
585 int unique = unique_mesh_state(edns->opt_list_in, mesh->env);
586 int timeout = mesh->env->cfg->serve_expired?
587 mesh->env->cfg->serve_expired_client_timeout:0;
593 s = mesh_area_find(mesh, NULL, qinfo, mesh_flags, 0, 0);
602 s = mesh_state_create(mesh->env, qinfo, NULL,
608 mesh->num_detached_states++;
625 rbtree_insert(&mesh->all, &s->node);
648 if(!timeout && mesh->env->cfg->serve_expired &&
649 !mesh->env->cfg->serve_expired_client_timeout &&
650 (mesh->env->cachedb_enabled &&
651 mesh->env->cfg->cachedb_check_when_serve_expired)) {
661 log_assert(mesh->num_detached_states > 0);
662 mesh->num_detached_states--;
665 mesh->num_reply_states ++;
667 mesh->num_reply_addrs++;
669 mesh_run(mesh, s, module_event_new, NULL);
678 static void mesh_schedule_prefetch(struct mesh_area* mesh,
686 struct mesh_state* s = mesh_area_find(mesh, NULL, qinfo,
701 if(!mesh_make_new_space(mesh, NULL)) {
703 mesh->stats_dropped ++;
707 s = mesh_state_create(mesh->env, qinfo, NULL, mesh_flags, 0, 0);
717 rbtree_insert(&mesh->all, &s->node);
720 mesh->num_detached_states++;
727 if(mesh->num_forever_states < mesh->max_forever_states) {
728 mesh->num_forever_states ++;
729 mesh_list_insert(s, &mesh->forever_first,
730 &mesh->forever_last);
733 mesh_list_insert(s, &mesh->jostle_first,
734 &mesh->jostle_last);
746 rbtree_insert(&mesh->run, &s->run_node);
751 mesh_run(mesh, s, module_event_new, NULL);
759 static void mesh_schedule_prefetch_subnet(struct mesh_area* mesh,
772 if(!mesh_make_new_space(mesh, NULL)) {
774 mesh->stats_dropped ++;
778 s = mesh_state_create(mesh->env, qinfo, NULL, mesh_flags, 0, 0);
785 opt = edns_opt_list_find(edns_list, mesh->env->cfg->client_subnet_opcode);
804 rbtree_insert(&mesh->all, &s->node);
807 mesh->num_detached_states++;
814 if(mesh->num_forever_states < mesh->max_forever_states) {
815 mesh->num_forever_states ++;
816 mesh_list_insert(s, &mesh->forever_first,
817 &mesh->forever_last);
820 mesh_list_insert(s, &mesh->jostle_first,
821 &mesh->jostle_last);
833 rbtree_insert(&mesh->run, &s->run_node);
838 mesh_run(mesh, s, module_event_new, NULL);
842 void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
850 mesh_schedule_prefetch_subnet(mesh, qinfo, qflags, leeway, 1,
854 mesh_schedule_prefetch(mesh, qinfo, qflags, leeway, 1,
858 void mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e,
868 mesh_run(mesh, e->qstate->mesh_info, event, e);
938 for(i=0; i<env->mesh->mods.num; i++) {
960 struct mesh_area* mesh;
964 mesh = mstate->s.env->mesh;
976 * takes no time and also it does not do the mesh accounting */
979 infra_wait_limit_dec(mesh->env->infra_cache,
980 &rep->query_reply, mesh->env->cfg);
984 log_assert(mesh->num_reply_addrs > 0);
985 mesh->num_reply_addrs--;
992 log_assert(mesh->num_reply_addrs > 0);
993 mesh->num_reply_addrs--;
998 for(i=0; i<mesh->mods.num; i++) {
999 fptr_ok(fptr_whitelist_mod_clear(mesh->mods.mod[i]->clear));
1000 (*mesh->mods.mod[i]->clear)(&mstate->s, i);
1010 struct mesh_area* mesh;
1016 mesh = mstate->s.env->mesh;
1019 mesh->num_forever_states --;
1020 mesh_list_remove(mstate, &mesh->forever_first,
1021 &mesh->forever_last);
1023 mesh_list_remove(mstate, &mesh->jostle_first,
1024 &mesh->jostle_last);
1028 log_assert(mesh->num_detached_states > 0);
1029 mesh->num_detached_states--;
1032 log_assert(mesh->num_reply_states > 0);
1033 mesh->num_reply_states--;
1040 (void)rbtree_delete(&mesh->run, mstate);
1041 (void)rbtree_delete(&mesh->all, mstate);
1077 struct mesh_area* mesh = qstate->env->mesh;
1094 mesh->num_detached_states++;
1095 log_assert(mesh->num_detached_states +
1096 mesh->num_reply_states <= mesh->all.count);
1107 struct mesh_area* mesh = qstate->env->mesh;
1108 *sub = mesh_area_find(mesh, NULL, qinfo, qflags,
1130 rbtree_insert(&mesh->all, &(*sub)->node);
1133 mesh->num_detached_states++;
1140 rbtree_insert(&mesh->run, &(*sub)->run_node);
1151 struct mesh_area* mesh = qstate->env->mesh;
1163 log_assert(mesh->num_detached_states > 0);
1164 mesh->num_detached_states--;
1208 * callback results to mesh cb entry
1209 * @param m: mesh state to send it for.
1214 * a value from one of the packets if the mesh state had packets.
1277 log_assert(m->s.env->mesh->num_reply_addrs > 0);
1278 m->s.env->mesh->num_reply_addrs--;
1325 * Send reply to mesh reply entry
1326 * @param m: mesh state to send it for.
1345 * null stops the mesh state remove and thus
1360 m->s.env->mesh->ans_bogus++;
1370 * for HTTP/2 stream to refer to mesh state, in case
1469 log_assert(m->s.env->mesh->num_reply_addrs > 0);
1470 m->s.env->mesh->num_reply_addrs--;
1475 m->s.env->mesh->replies_sent++;
1476 timeval_add(&m->s.env->mesh->replies_sum_wait, &duration);
1477 timehist_insert(m->s.env->mesh->histogram, &duration);
1481 if(secure) m->s.env->mesh->ans_secure++;
1482 m->s.env->mesh->ans_rcode[ rc ] ++;
1484 m->s.env->mesh->ans_nodata++;
1530 * tcp req info cleanup routine that calls the mesh
1543 mstate->s.env->mesh->stats_dropped++;
1562 * mesh processing, this is the point to take that action. */
1565 * tcp req info cleanup routine that calls the mesh
1590 /* mesh_send_reply removed mesh state from
1602 mstate->s.env->mesh->rpz_action[RPZ_DISABLED_ACTION] += i;
1604 mstate->s.env->mesh->rpz_action[RPZ_CNAME_OVERRIDE_ACTION] += i;
1606 mstate->s.env->mesh->rpz_action[respip_action_to_rpz_action(
1612 mstate->s.env->mesh->ans_cachedb += i;
1621 log_assert(mstate->s.env->mesh->num_reply_states > 0);
1622 mstate->s.env->mesh->num_reply_states--;
1626 mstate->s.env->mesh->num_detached_states++;
1635 log_assert(mstate->s.env->mesh->num_reply_states > 0);
1636 mstate->s.env->mesh->num_reply_states--;
1641 mstate->s.env->mesh->num_detached_states++;
1646 void mesh_walk_supers(struct mesh_area* mesh, struct mesh_state* mstate)
1652 (void)rbtree_insert(&mesh->run, &ref->s->run_node);
1655 mesh->mods.mod[ref->s->s.curmod]->inform_super));
1656 (*mesh->mods.mod[ref->s->s.curmod]->inform_super)(&mstate->s,
1663 struct mesh_state* mesh_area_find(struct mesh_area* mesh,
1675 /* We are searching for a similar mesh state when we DO want to
1681 result = (struct mesh_state*)rbtree_search(&mesh->all, &key);
1817 * Continue processing the mesh state at another module.
1820 * @param mesh: the mesh area.
1821 * @param mstate: currently active mesh state.
1823 * send replies to clients and inform other mesh states.
1824 * This in turn may create additional runnable mesh states.
1832 mesh_continue(struct mesh_area* mesh, struct mesh_state* mstate,
1839 mesh->mods.mod[mstate->s.curmod]->name);
1847 if(mesh->mods.num == mstate->s.curmod) {
1852 return mesh_continue(mesh, mstate, module_error, ev);
1856 for(; mstate->s.curmod < mesh->mods.num;
1859 mesh->mods.mod[mstate->s.curmod]->clear));
1860 (*mesh->mods.mod[mstate->s.curmod]->clear)
1881 mesh_walk_supers(mesh, mstate);
1896 modstack_find(&mesh->mods, "subnetcache") != -1 &&
1904 mesh_walk_supers(mesh, mstate);
1928 mesh_new_prefetch(mesh, qinfo, qflags, 0,
1945 void mesh_run(struct mesh_area* mesh, struct mesh_state* mstate,
1953 mesh->mods.mod[mstate->s.curmod]->operate));
1954 (*mesh->mods.mod[mstate->s.curmod]->operate)
1962 mesh->mods.mod[mstate->s.curmod]->name, strextstate(s));
1964 if(mesh_continue(mesh, mstate, s, &ev))
1969 if(mesh->run.count > 0) {
1971 mstate = (struct mesh_state*)mesh->run.root->key;
1972 (void)rbtree_delete(&mesh->run, mstate);
1976 mesh_stats(mesh, "mesh_run: end");
1977 mesh_log_list(mesh);
1982 mesh_log_list(struct mesh_area* mesh)
1987 RBTREE_FOR(m, struct mesh_state*, &mesh->all) {
2003 mesh_stats(struct mesh_area* mesh, const char* str)
2008 str, (unsigned)mesh->all.count,
2009 (unsigned)mesh->num_reply_states,
2010 (unsigned)mesh->num_detached_states,
2011 (unsigned)mesh->num_reply_addrs,
2012 (unsigned)mesh->replies_sent,
2013 (unsigned)mesh->stats_dropped,
2014 (unsigned)mesh->stats_jostled);
2015 if(mesh->replies_sent > 0) {
2017 timeval_divide(&avg, &mesh->replies_sum_wait,
2018 mesh->replies_sent);
2023 timehist_log(mesh->histogram, "recursions");
2028 mesh_stats_clear(struct mesh_area* mesh)
2030 if(!mesh)
2032 mesh->replies_sent = 0;
2033 mesh->replies_sum_wait.tv_sec = 0;
2034 mesh->replies_sum_wait.tv_usec = 0;
2035 mesh->stats_jostled = 0;
2036 mesh->stats_dropped = 0;
2037 timehist_clear(mesh->histogram);
2038 mesh->ans_secure = 0;
2039 mesh->ans_bogus = 0;
2040 mesh->ans_expired = 0;
2041 mesh->ans_cachedb = 0;
2042 memset(&mesh->ans_rcode[0], 0, sizeof(size_t)*UB_STATS_RCODE_NUM);
2043 memset(&mesh->rpz_action[0], 0, sizeof(size_t)*UB_STATS_RPZ_ACTION_NUM);
2044 mesh->ans_nodata = 0;
2048 mesh_get_mem(struct mesh_area* mesh)
2051 size_t s = sizeof(*mesh) + sizeof(struct timehist) +
2052 sizeof(struct th_buck)*mesh->histogram->num +
2053 sizeof(sldns_buffer) + sldns_buffer_capacity(mesh->qbuf_bak);
2054 RBTREE_FOR(m, struct mesh_state*, &mesh->all) {
2065 struct mesh_area* mesh = qstate->env->mesh;
2067 dep_m = mesh_area_find(mesh, NULL, qinfo, flags, prime, valrec);
2094 void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
2108 log_assert(mesh->num_reply_addrs > 0);
2109 mesh->num_reply_addrs--;
2110 infra_wait_limit_dec(mesh->env->infra_cache,
2111 &n->query_reply, mesh->env->cfg);
2123 mesh->num_detached_states++;
2127 log_assert(mesh->num_reply_states > 0);
2128 mesh->num_reply_states--;
2165 struct mesh_area* mesh = qstate->env->mesh;
2207 if((mesh->use_response_ip || mesh->use_rpz) &&
2260 * tcp req info cleanup routine that calls the mesh
2273 mstate->s.env->mesh->stats_dropped++;
2306 /* mesh_send_reply removed mesh state from http2_stream. */
2314 mesh->ans_expired += i;
2318 qstate->env->mesh->rpz_action[RPZ_DISABLED_ACTION] += i;
2320 qstate->env->mesh->rpz_action[RPZ_CNAME_OVERRIDE_ACTION] += i;
2322 qstate->env->mesh->rpz_action[
2331 log_assert(mesh->num_reply_states > 0);
2332 mesh->num_reply_states--;
2334 mesh->num_detached_states++;
2344 log_assert(qstate->env->mesh->num_reply_states > 0);
2345 qstate->env->mesh->num_reply_states--;
2350 qstate->env->mesh->num_detached_states++;
2363 int mesh_jostle_exceeded(struct mesh_area* mesh)
2365 if(mesh->all.count < mesh->max_reply_states)