void infra_delete(struct infra_cache* infra) { if(!infra) return; slabhash_delete(infra->hosts); slabhash_delete(infra->domain_rates); traverse_postorder(&infra->domain_limits, domain_limit_free, NULL); free(infra); }
void key_cache_delete(struct key_cache* kcache) { if(!kcache) return; slabhash_delete(kcache->slab); free(kcache); }
void infra_delete(struct infra_cache* infra) { if(!infra) return; slabhash_delete(infra->hosts); free(infra); }
void slabhash_test(void) { /* start very very small array, so it can do lots of table_grow() */ /* also small in size so that reclaim has to be done quickly. */ struct slabhash* table; unit_show_feature("slabhash"); table = slabhash_create(4, 2, 10400, test_slabhash_sizefunc, test_slabhash_compfunc, test_slabhash_delkey, test_slabhash_deldata, NULL); test_short_table(table); test_long_table(table); slabhash_delete(table); table = slabhash_create(4, 2, 10400, test_slabhash_sizefunc, test_slabhash_compfunc, test_slabhash_delkey, test_slabhash_deldata, NULL); test_threaded_table(table); slabhash_delete(table); }
void ub_ctx_delete(struct ub_ctx* ctx) { struct alloc_cache* a, *na; int do_stop = 1; if(!ctx) return; /* see if bg thread is created and if threads have been killed */ /* no locks, because those may be held by terminated threads */ /* for processes the read pipe is closed and we see that on read */ #ifdef HAVE_PTHREAD if(ctx->created_bg && ctx->dothread) { if(pthread_kill(ctx->bg_tid, 0) == ESRCH) { /* thread has been killed */ do_stop = 0; } } #endif /* HAVE_PTHREAD */ if(do_stop) ub_stop_bg(ctx); libworker_delete_event(ctx->event_worker); modstack_desetup(&ctx->mods, ctx->env); a = ctx->alloc_list; while(a) { na = a->super; a->super = &ctx->superalloc; alloc_clear(a); free(a); a = na; } local_zones_delete(ctx->local_zones); lock_basic_destroy(&ctx->qqpipe_lock); lock_basic_destroy(&ctx->rrpipe_lock); lock_basic_destroy(&ctx->cfglock); tube_delete(ctx->qq_pipe); tube_delete(ctx->rr_pipe); if(ctx->env) { slabhash_delete(ctx->env->msg_cache); rrset_cache_delete(ctx->env->rrset_cache); infra_delete(ctx->env->infra_cache); config_delete(ctx->env->cfg); edns_known_options_delete(ctx->env); auth_zones_delete(ctx->env->auth_zones); free(ctx->env); } ub_randfree(ctx->seed_rnd); alloc_clear(&ctx->superalloc); traverse_postorder(&ctx->queries, delq, NULL); free(ctx); #ifdef USE_WINSOCK WSACleanup(); #endif }
void daemon_apply_cfg(struct daemon* daemon, struct config_file* cfg) { daemon->cfg = cfg; config_apply(cfg); if(!slabhash_is_size(daemon->env->msg_cache, cfg->msg_cache_size, cfg->msg_cache_slabs)) { slabhash_delete(daemon->env->msg_cache); daemon->env->msg_cache = slabhash_create(cfg->msg_cache_slabs, HASH_DEFAULT_STARTARRAY, cfg->msg_cache_size, msgreply_sizefunc, query_info_compare, query_entry_delete, reply_info_delete, NULL); if(!daemon->env->msg_cache) { fatal_exit("malloc failure updating config settings"); } } if((daemon->env->rrset_cache = rrset_cache_adjust( daemon->env->rrset_cache, cfg, &daemon->superalloc)) == 0) fatal_exit("malloc failure updating config settings"); if((daemon->env->infra_cache = infra_adjust(daemon->env->infra_cache, cfg))==0) fatal_exit("malloc failure updating config settings"); }
struct slabhash* slabhash_create(size_t numtables, size_t start_size, size_t maxmem, lruhash_sizefunc_type sizefunc, lruhash_compfunc_type compfunc, lruhash_delkeyfunc_type delkeyfunc, lruhash_deldatafunc_type deldatafunc, void* arg) { size_t i; struct slabhash* sl = (struct slabhash*)calloc(1, sizeof(struct slabhash)); if(!sl) return NULL; sl->size = numtables; log_assert(sl->size > 0); sl->array = (struct lruhash**)calloc(sl->size, sizeof(struct lruhash*)); if(!sl->array) { free(sl); return NULL; } sl->mask = (uint32_t)(sl->size - 1); if(sl->mask == 0) { sl->shift = 0; } else { log_assert( (sl->size & sl->mask) == 0 /* size must be power of 2 */ ); sl->shift = 0; while(!(sl->mask & 0x80000000)) { sl->mask <<= 1; sl->shift ++; } } for(i=0; i<sl->size; i++) { sl->array[i] = lruhash_create(start_size, maxmem / sl->size, sizefunc, compfunc, delkeyfunc, deldatafunc, arg); if(!sl->array[i]) { slabhash_delete(sl); return NULL; } } return sl; }
int context_finalize(struct ub_ctx* ctx) { struct config_file* cfg = ctx->env->cfg; verbosity = cfg->verbosity; if(ctx->logfile_override) log_file(ctx->log_out); else log_init(cfg->logfile, cfg->use_syslog, NULL); config_apply(cfg); if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env)) return UB_INITFAIL; ctx->local_zones = local_zones_create(); if(!ctx->local_zones) return UB_NOMEM; if(!local_zones_apply_cfg(ctx->local_zones, cfg)) return UB_INITFAIL; if(!ctx->env->msg_cache || cfg->msg_cache_size != slabhash_get_size(ctx->env->msg_cache) || cfg->msg_cache_slabs != ctx->env->msg_cache->size) { slabhash_delete(ctx->env->msg_cache); ctx->env->msg_cache = slabhash_create(cfg->msg_cache_slabs, HASH_DEFAULT_STARTARRAY, cfg->msg_cache_size, msgreply_sizefunc, query_info_compare, query_entry_delete, reply_info_delete, NULL); if(!ctx->env->msg_cache) return UB_NOMEM; } ctx->env->rrset_cache = rrset_cache_adjust(ctx->env->rrset_cache, ctx->env->cfg, ctx->env->alloc); if(!ctx->env->rrset_cache) return UB_NOMEM; ctx->env->infra_cache = infra_adjust(ctx->env->infra_cache, cfg); if(!ctx->env->infra_cache) return UB_NOMEM; ctx->finalized = 1; return UB_NOERROR; }
void ub_ctx_delete(struct ub_ctx* ctx) { struct alloc_cache* a, *na; if(!ctx) return; /* stop the bg thread */ lock_basic_lock(&ctx->cfglock); if(ctx->created_bg) { uint8_t* msg; uint32_t len; uint32_t cmd = UB_LIBCMD_QUIT; lock_basic_unlock(&ctx->cfglock); lock_basic_lock(&ctx->qqpipe_lock); (void)tube_write_msg(ctx->qq_pipe, (uint8_t*)&cmd, (uint32_t)sizeof(cmd), 0); lock_basic_unlock(&ctx->qqpipe_lock); lock_basic_lock(&ctx->rrpipe_lock); while(tube_read_msg(ctx->rr_pipe, &msg, &len, 0)) { /* discard all results except a quit confirm */ if(context_serial_getcmd(msg, len) == UB_LIBCMD_QUIT) { free(msg); break; } free(msg); } lock_basic_unlock(&ctx->rrpipe_lock); /* if bg worker is a thread, wait for it to exit, so that all * resources are really gone. */ lock_basic_lock(&ctx->cfglock); if(ctx->dothread) { lock_basic_unlock(&ctx->cfglock); ub_thread_join(ctx->bg_tid); } else { lock_basic_unlock(&ctx->cfglock); } } else { lock_basic_unlock(&ctx->cfglock); } modstack_desetup(&ctx->mods, ctx->env); a = ctx->alloc_list; while(a) { na = a->super; a->super = &ctx->superalloc; alloc_clear(a); free(a); a = na; } local_zones_delete(ctx->local_zones); lock_basic_destroy(&ctx->qqpipe_lock); lock_basic_destroy(&ctx->rrpipe_lock); lock_basic_destroy(&ctx->cfglock); tube_delete(ctx->qq_pipe); tube_delete(ctx->rr_pipe); if(ctx->env) { slabhash_delete(ctx->env->msg_cache); rrset_cache_delete(ctx->env->rrset_cache); infra_delete(ctx->env->infra_cache); config_delete(ctx->env->cfg); free(ctx->env); } ub_randfree(ctx->seed_rnd); alloc_clear(&ctx->superalloc); traverse_postorder(&ctx->queries, delq, NULL); free(ctx); #ifdef USE_WINSOCK WSACleanup(); #endif }
void daemon_delete(struct daemon* daemon) { size_t i; if(!daemon) return; modstack_desetup(&daemon->mods, daemon->env); daemon_remote_delete(daemon->rc); for(i = 0; i < daemon->num_ports; i++) listening_ports_free(daemon->ports[i]); free(daemon->ports); listening_ports_free(daemon->rc_ports); if(daemon->env) { slabhash_delete(daemon->env->msg_cache); rrset_cache_delete(daemon->env->rrset_cache); infra_delete(daemon->env->infra_cache); edns_known_options_delete(daemon->env); auth_zones_delete(daemon->env->auth_zones); } ub_randfree(daemon->rand); alloc_clear(&daemon->superalloc); acl_list_delete(daemon->acl); free(daemon->chroot); free(daemon->pidfile); free(daemon->env); #ifdef HAVE_SSL SSL_CTX_free((SSL_CTX*)daemon->listen_sslctx); SSL_CTX_free((SSL_CTX*)daemon->connect_sslctx); #endif free(daemon); #ifdef LEX_HAS_YYLEX_DESTROY /* lex cleanup */ ub_c_lex_destroy(); #endif /* libcrypto cleanup */ #ifdef HAVE_SSL # if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST) sldns_key_EVP_unload_gost(); # endif # if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS && HAVE_DECL_SK_SSL_COMP_POP_FREE # ifndef S_SPLINT_S # if OPENSSL_VERSION_NUMBER < 0x10100000 sk_SSL_COMP_pop_free(comp_meth, (void(*)())CRYPTO_free); # endif # endif # endif # ifdef HAVE_OPENSSL_CONFIG EVP_cleanup(); # if OPENSSL_VERSION_NUMBER < 0x10100000 ENGINE_cleanup(); # endif CONF_modules_free(); # endif # ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA CRYPTO_cleanup_all_ex_data(); /* safe, no more threads right now */ # endif # ifdef HAVE_ERR_FREE_STRINGS ERR_free_strings(); # endif # if OPENSSL_VERSION_NUMBER < 0x10100000 RAND_cleanup(); # endif # if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) ub_openssl_lock_delete(); # endif #ifndef HAVE_ARC4RANDOM _ARC4_LOCK_DESTROY(); #endif #elif defined(HAVE_NSS) NSS_Shutdown(); #endif /* HAVE_SSL or HAVE_NSS */ checklock_stop(); #ifdef USE_WINSOCK if(WSACleanup() != 0) { log_err("Could not WSACleanup: %s", wsa_strerror(WSAGetLastError())); } #endif }