/** check if type is OK for the lock given */ static void checktype(enum check_lock_type type, struct checked_lock* lock, const char* func, const char* file, int line) { if(!lock) fatal_exit("use of null/deleted lock at %s %s:%d", func, file, line); if(type != lock->type) { lock_error(lock, func, file, line, "wrong lock type"); } }
struct comm_base* comm_base_create(int ATTR_UNUSED(sigs)) { /* we return the runtime structure instead. */ struct replay_runtime* runtime = (struct replay_runtime*) calloc(1, sizeof(struct replay_runtime)); runtime->scenario = saved_scenario; runtime->vars = macro_store_create(); if(!runtime->vars) fatal_exit("out of memory"); return (struct comm_base*)runtime; }
/** add protected region */ void lock_protect(void *p, void* area, size_t size) { struct checked_lock* lock = *(struct checked_lock**)p; struct protected_area* e = (struct protected_area*)malloc( sizeof(struct protected_area)); if(!e) fatal_exit("lock_protect: out of memory"); e->region = area; e->size = size; e->hold = malloc(size); if(!e->hold) fatal_exit("lock_protect: out of memory"); memcpy(e->hold, e->region, e->size); acquire_locklock(lock, __func__, __FILE__, __LINE__); e->next = lock->prot; lock->prot = e; LOCKRET(pthread_mutex_unlock(&lock->lock)); }
/** helper function that logs a sldns_pkt packet to logfile */ static void log_pkt(const char* desc, uint8_t* pkt, size_t len) { char* str = sldns_wire2str_pkt(pkt, len); if(!str) fatal_exit("%s: (failed out of memory wire2str_pkt)", desc); else { log_info("%s%s", desc, str); free(str); } }
void png_start(struct cached_image *cimg) { png_structp png_ptr; png_infop info_ptr; struct png_decoder *decoder; retry1: #ifdef PNG_USER_MEM_SUPPORTED png_ptr=png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL, img_my_png_error, img_my_png_warning, NULL, my_png_alloc, my_png_free); #else png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, img_my_png_error, img_my_png_warning); #endif if (!png_ptr) { if (out_of_memory(0, NULL, 0)) goto retry1; fatal_exit("png_create_read_struct failed"); } retry2: info_ptr=png_create_info_struct(png_ptr); if (!info_ptr) { if (out_of_memory(0, NULL, 0)) goto retry2; fatal_exit("png_create_info_struct failed"); } if (setjmp(png_jmpbuf(png_ptr))){ error: png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); img_end(cimg); return; } png_set_progressive_read_fn(png_ptr, NULL, png_info_callback, &png_row_callback, png_end_callback); if (setjmp(png_jmpbuf(png_ptr))) goto error; decoder=mem_alloc(sizeof(*decoder)); decoder->png_ptr=png_ptr; decoder->info_ptr=info_ptr; cimg->decoder=decoder; }
/** fillup fetch policy array */ static void fetch_fill(struct iter_env* ie, const char* str) { char* s = (char*)str, *e; int i; for(i=0; i<ie->max_dependency_depth+1; i++) { ie->target_fetch_policy[i] = strtol(s, &e, 10); if(s == e) fatal_exit("cannot parse fetch policy number %s", s); s = e; } }
array_t * init_array (int initial_number, int elem_size) { array_t * a = (array_t *)malloc (sizeof (array_t)); if (a) *a = (array_t){elem_size, initial_number, -1, calloc(initial_number, elem_size)}; if (!a || !a->array) fatal_exit ("unable to allocate array."); return a; }
/** * Setup modules. setup module stack. * @param daemon: the daemon */ static void daemon_setup_modules(struct daemon* daemon) { daemon->env->cfg = daemon->cfg; daemon->env->alloc = &daemon->superalloc; daemon->env->worker = NULL; daemon->env->need_to_validate = 0; /* set by module init below */ if(!modstack_setup(&daemon->mods, daemon->cfg->module_conf, daemon->env)) { fatal_exit("failed to setup modules"); } log_edns_known_options(VERB_ALGO, daemon->env); }
void fatal (char const *format, ...) { va_list args; fprintf (stderr, "%s: **** ", program_name); va_start (args, format); vfprintf (stderr, format, args); va_end (args); putc ('\n', stderr); fflush (stderr); fatal_exit (0); }
int get_input_handle(void) { static int h = -1; if (h >= 0) return h; if (be_pipe(ihpipe) < 0) return -1; if ((inth = start_thr(input_handle_th, NULL, "input_thread")) < 0) { closesocket(ihpipe[0]); closesocket(ihpipe[1]); fatal_exit("Can't spawn input thread"); } return h = ihpipe[0]; }
/** recv new waiting packets */ static void service_recv(int s, struct ringbuf* ring, sldns_buffer* pkt, fd_set* rorig, int* max, struct proxy** proxies, struct sockaddr_storage* srv_addr, socklen_t srv_len, struct timeval* now, struct timeval* delay, struct timeval* reuse) { int i; struct sockaddr_storage from; socklen_t from_len; ssize_t len; struct proxy* p; for(i=0; i<TRIES_PER_SELECT; i++) { from_len = (socklen_t)sizeof(from); len = recvfrom(s, (void*)sldns_buffer_begin(pkt), sldns_buffer_capacity(pkt), 0, (struct sockaddr*)&from, &from_len); if(len < 0) { #ifndef USE_WINSOCK if(errno == EAGAIN || errno == EINTR) return; fatal_exit("recvfrom: %s", strerror(errno)); #else if(WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINPROGRESS) return; fatal_exit("recvfrom: %s", wsa_strerror(WSAGetLastError())); #endif } sldns_buffer_set_limit(pkt, (size_t)len); /* find its proxy element */ p = find_create_proxy(&from, from_len, rorig, max, proxies, addr_is_ip6(srv_addr, srv_len), now, reuse); if(!p) fatal_exit("error: cannot find or create proxy"); p->lastuse = *now; ring_add(ring, pkt, now, delay, p); p->numwait++; log_addr(1, "recv from client", &p->addr, p->addr_len); } }
char * get_set_var_name_int (char * s, int index, char * file, int line) { char var_buf [VAR_SIZE+1]; char fmt_buf [VAR_SIZE+1]; char * p; char * fmt; int index_found = 0; if (strlen (s) >= VAR_SIZE) { fatal_exit ("Variable name too long\n"); } for (p = fmt_buf, fmt=s; *fmt; fmt++) { *p++ = *fmt; if (*fmt == '%') { if (!index_found) { index_found = 1; *p++ = 'd'; } else { *p++ = '%'; } } } *p = '\0'; sprintf (var_buf, fmt_buf, index); if (strlen (var_buf) >= VAR_SIZE) { fatal_exit ("Variable name too long\n"); } return strsave (var_buf); }
/** wait for new events for performance test */ static void perfselect(struct perfinfo* info) { fd_set rset = info->rset; struct timeval timeout, now; int num; size_t i; if(gettimeofday(&now, NULL) < 0) fatal_exit("gettimeofday: %s", strerror(errno)); /* time to exit? */ if(info->duration > 0) { timeout = now; perf_tv_subtract(&timeout, &info->start); if((int)timeout.tv_sec >= info->duration) { info->exit = 1; return; } } /* time for stats printout? */ timeout = now; perf_tv_subtract(&timeout, &info->since); if(timeout.tv_sec > 0) { stat_printout(info, &now, &timeout); } /* see what is closest port to timeout; or if there is a timeout */ timeout = info->io[0].timeout; for(i=0; i<info->io_num; i++) { if(perf_tv_smaller(&info->io[i].timeout, &now)) { perftimeout(info, i, &now); return; } if(perf_tv_smaller(&info->io[i].timeout, &timeout)) { timeout = info->io[i].timeout; } } perf_tv_subtract(&timeout, &now); num = select(info->maxfd+1, &rset, NULL, NULL, &timeout); if(num == -1) { if(errno == EAGAIN || errno == EINTR) return; log_err("select: %s", strerror(errno)); } /* handle new events */ for(i=0; num && i<info->io_num; i++) { if(FD_ISSET(info->io[i].fd, &rset)) { perfreply(info, i, &now); num--; } } }
/* method model_base#MVisibility#to_s for (self: MVisibility): String */ val* nitc___nitc__MVisibility___core__abstract_text__Object__to_s(val* self) { val* var /* : String */; val* var1 /* : String */; var1 = self->attrs[COLOR_nitc__model_base__MVisibility___to_s].val; /* _to_s on <self:MVisibility> */ if (unlikely(var1 == NULL)) { PRINT_ERROR("Runtime error: %s", "Uninitialized attribute _to_s"); PRINT_ERROR(" (%s:%d)\n", FILE_nitc__model_base, 114); fatal_exit(1); } var = var1; RET_LABEL:; return var; }
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"); }
char * parse_get_variable_comment (char * name, char * package, int line) { char * content; content = get_variable_comment (convert_to_upper (name)); if (!content) { fatal_exit ("unknown variable '%s' in %s, line %d\n", name, package, line); } return content; }
/** read playback file */ static struct replay_scenario* setup_playback(const char* filename, int* pass_argc, char* pass_argv[]) { struct replay_scenario* scen = NULL; int lineno = 0; if(filename) { FILE *in = fopen(filename, "rb"); if(!in) { perror(filename); exit(1); } setup_config(in, &lineno, pass_argc, pass_argv); scen = replay_scenario_read(in, filename, &lineno); fclose(in); if(!scen) fatal_exit("Could not read: %s", filename); } else fatal_exit("need a playback file (-p)"); log_info("Scenario: %s", scen->title); return scen; }
struct waiting_tcp* pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet, struct sockaddr_storage* addr, socklen_t addrlen, int timeout, comm_point_callback_t* callback, void* callback_arg) { struct replay_runtime* runtime = (struct replay_runtime*)outnet->base; struct fake_pending* pend = (struct fake_pending*)calloc(1, sizeof(struct fake_pending)); ldns_status status; log_assert(pend); pend->buffer = ldns_buffer_new(ldns_buffer_capacity(packet)); log_assert(pend->buffer); ldns_buffer_write(pend->buffer, ldns_buffer_begin(packet), ldns_buffer_limit(packet)); ldns_buffer_flip(pend->buffer); memcpy(&pend->addr, addr, addrlen); pend->addrlen = addrlen; pend->callback = callback; pend->cb_arg = callback_arg; pend->timeout = timeout; pend->transport = transport_tcp; pend->pkt = NULL; pend->runtime = runtime; pend->serviced = 0; status = ldns_buffer2pkt_wire(&pend->pkt, packet); if(status != LDNS_STATUS_OK) { log_err("ldns error parsing tcp output packet: %s", ldns_get_errorstr_by_id(status)); fatal_exit("Sending unparseable DNS packets to servers!"); } log_pkt("pending tcp pkt: ", pend->pkt); /* see if it matches the current moment */ if(runtime->now && runtime->now->evt_type == repevt_back_query && (runtime->now->addrlen == 0 || sockaddr_cmp( &runtime->now->addr, runtime->now->addrlen, &pend->addr, pend->addrlen) == 0) && find_match(runtime->now->match, pend->pkt, pend->transport)) { log_info("testbound: matched pending to event. " "advance time between events."); log_info("testbound: do STEP %d %s", runtime->now->time_step, repevt_string(runtime->now->evt_type)); advance_moment(runtime); /* still create the pending, because we need it to callback */ } log_info("testbound: created fake pending"); /* add to list */ pend->next = runtime->pending_list; runtime->pending_list = pend; return (struct waiting_tcp*)pend; }
/** Read FILE match content */ static void read_file_content(FILE* in, int* lineno, struct replay_moment* mom) { char line[MAX_LINE_LEN]; char* remain = line; struct config_strlist** last = &mom->file_content; line[MAX_LINE_LEN-1]=0; if(!fgets(line, MAX_LINE_LEN-1, in)) fatal_exit("FILE_BEGIN expected at line %d", *lineno); if(!parse_keyword(&remain, "FILE_BEGIN")) fatal_exit("FILE_BEGIN expected at line %d", *lineno); while(fgets(line, MAX_LINE_LEN-1, in)) { (*lineno)++; if(strncmp(line, "FILE_END", 8) == 0) { return; } if(line[0]) line[strlen(line)-1] = 0; /* remove newline */ if(!cfg_strlist_insert(last, strdup(line))) fatal_exit("malloc failure"); last = &( (*last)->next ); } fatal_exit("no FILE_END in input file"); }
/** allocate debug info and create thread */ void checklock_thrcreate(pthread_t* id, void* (*func)(void*), void* arg) { struct thr_check* thr = (struct thr_check*)calloc(1, sizeof(struct thr_check)); if(!thr) fatal_exit("thrcreate: out of memory"); if(!key_created) { checklock_start(); } thr->func = func; thr->arg = arg; LOCKRET(pthread_create(id, NULL, checklock_main, thr)); }
struct waiting_tcp* pending_tcp_query(struct outside_network* outnet, sldns_buffer* packet, struct sockaddr_storage* addr, socklen_t addrlen, int timeout, comm_point_callback_t* callback, void* callback_arg, int ATTR_UNUSED(ssl_upstream)) { struct replay_runtime* runtime = (struct replay_runtime*)outnet->base; struct fake_pending* pend = (struct fake_pending*)calloc(1, sizeof(struct fake_pending)); log_assert(pend); pend->buffer = sldns_buffer_new(sldns_buffer_capacity(packet)); log_assert(pend->buffer); sldns_buffer_write(pend->buffer, sldns_buffer_begin(packet), sldns_buffer_limit(packet)); sldns_buffer_flip(pend->buffer); memcpy(&pend->addr, addr, addrlen); pend->addrlen = addrlen; pend->callback = callback; pend->cb_arg = callback_arg; pend->timeout = timeout; pend->transport = transport_tcp; pend->pkt = NULL; pend->zone = NULL; pend->runtime = runtime; pend->serviced = 0; pend->pkt_len = sldns_buffer_limit(packet); pend->pkt = memdup(sldns_buffer_begin(packet), pend->pkt_len); if(!pend->pkt) fatal_exit("out of memory"); log_pkt("pending tcp pkt: ", pend->pkt, pend->pkt_len); /* see if it matches the current moment */ if(runtime->now && runtime->now->evt_type == repevt_back_query && (runtime->now->addrlen == 0 || sockaddr_cmp( &runtime->now->addr, runtime->now->addrlen, &pend->addr, pend->addrlen) == 0) && find_match(runtime->now->match, pend->pkt, pend->pkt_len, pend->transport)) { log_info("testbound: matched pending to event. " "advance time between events."); log_info("testbound: do STEP %d %s", runtime->now->time_step, repevt_string(runtime->now->evt_type)); advance_moment(runtime); /* still create the pending, because we need it to callback */ } log_info("testbound: created fake pending"); /* add to list */ pend->next = runtime->pending_list; runtime->pending_list = pend; return (struct waiting_tcp*)pend; }
/** put dname into buffer */ static sldns_buffer* dname_to_buf(sldns_buffer* b, const char* str) { int e; size_t len = sldns_buffer_capacity(b); sldns_buffer_clear(b); e = sldns_str2wire_dname_buf(str, sldns_buffer_begin(b), &len); if(e != 0) fatal_exit("%s ldns: %s", __func__, sldns_get_errorstr_parse(e)); sldns_buffer_set_position(b, len); sldns_buffer_flip(b); return b; }
/** main program for pktview */ int main(int argc, char* argv[]) { ldns_buffer* pkt = ldns_buffer_new(65553); if(argc != 1) { usage(argv); } if(!pkt) fatal_exit("out of memory"); read_input(pkt, stdin); analyze(pkt); ldns_buffer_free(pkt); return 0; }
static void dt_apply_identity(struct dt_env *env, struct config_file *cfg) { char buf[MAXHOSTNAMELEN+1]; if (!cfg->dnstap_send_identity) return; free(env->identity); if (cfg->dnstap_identity == NULL || cfg->dnstap_identity[0] == 0) { if (gethostname(buf, MAXHOSTNAMELEN) == 0) { buf[MAXHOSTNAMELEN] = 0; env->identity = strdup(buf); } else { fatal_exit("dt_apply_identity: gethostname() failed"); } } else { env->identity = strdup(cfg->dnstap_identity); } if (env->identity == NULL) fatal_exit("dt_apply_identity: strdup() failed"); env->len_identity = (unsigned int)strlen(env->identity); verbose(VERB_OPS, "dnstap identity field set to \"%s\"", env->identity); }
/** read up the malloc stats */ static void read_malloc_stat(char* line, rbtree_t* tree) { char codeline[10240]; char name[10240]; int skip = 0; long num = 0; struct codeline* cl = 0; line = strstr(line, "info: ")+6; if(sscanf(line, "%s %s %n", codeline, name, &skip) != 2) { printf("%s\n", line); fatal_exit("unhandled malloc"); } if(sscanf(line+skip+7, "%ld", &num) != 1) { printf("%s\n%s\n", line, line+skip+7); fatal_exit("unhandled malloc"); } cl = get_codeline(tree, codeline, name); if(!cl) fatal_exit("alloc failure"); cl->alloc += num; cl->calls ++; }
/** go ahead and read config, contact server and perform command and display */ static int go(const char* cfgfile, char* svr, int quiet, int argc, char* argv[]) { struct config_file* cfg; int fd, ret; SSL_CTX* ctx; SSL* ssl; /* read config */ if(!(cfg = config_create())) fatal_exit("out of memory"); if(!config_read(cfg, cfgfile, NULL)) fatal_exit("could not read config file"); if(!cfg->remote_control_enable) log_warn("control-enable is 'no' in the config file."); #ifdef UB_ON_WINDOWS w_config_adjust_directory(cfg); #endif ctx = setup_ctx(cfg); /* contact server */ fd = contact_server(svr, cfg, argc>0&&strcmp(argv[0],"status")==0); ssl = setup_ssl(ctx, fd, cfg); /* send command */ ret = go_cmd(ssl, quiet, argc, argv); SSL_free(ssl); #ifndef USE_WINSOCK close(fd); #else closesocket(fd); #endif SSL_CTX_free(ctx); config_delete(cfg); return ret; }
int parse_check_file (char * name, char * check_dir) { char buf[256]; FILE * fp; int ret; if (! get_file_name (buf, check_dir, name, def_extcheck_ext)) { log_info (VERBOSE, "no extended check file for package %s\n", name); return 0; } fp = fopen (buf, "r"); if (!fp) { fatal_exit ("Error opening extended check file %s: %s\n", buf, strerror (errno)); } log_info (T_EXEC|INFO, "reading extended check file %s\n", buf); yyrestart(fp); yyline = 1; inc_log_indent_level (); parse_set_current (name, buf); ret = yyparse (); dec_log_indent_level (); fclose (fp); if (ret != 0) { fatal_exit ("error while parsing check file %s\n", buf); return ERR; } return OK; }
/** setup SSL context */ static SSL_CTX* setup_ctx(struct config_file* cfg) { char* s_cert=NULL, *c_key=NULL, *c_cert=NULL; SSL_CTX* ctx; if(cfg->remote_control_use_cert) { s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1); c_key = fname_after_chroot(cfg->control_key_file, cfg, 1); c_cert = fname_after_chroot(cfg->control_cert_file, cfg, 1); if(!s_cert || !c_key || !c_cert) fatal_exit("out of memory"); } ctx = SSL_CTX_new(SSLv23_client_method()); if(!ctx) ssl_err("could not allocate SSL_CTX pointer"); if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2) != SSL_OP_NO_SSLv2) ssl_err("could not set SSL_OP_NO_SSLv2"); if(cfg->remote_control_use_cert) { if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3) != SSL_OP_NO_SSLv3) ssl_err("could not set SSL_OP_NO_SSLv3"); if(!SSL_CTX_use_certificate_chain_file(ctx,c_cert) || !SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM) || !SSL_CTX_check_private_key(ctx)) ssl_err("Error setting up SSL_CTX client key and cert"); if (SSL_CTX_load_verify_locations(ctx, s_cert, NULL) != 1) ssl_err("Error setting up SSL_CTX verify, server cert"); SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); free(s_cert); free(c_key); free(c_cert); } else { /* Use ciphers that don't require authentication */ #if defined(SSL_OP_NO_TLSv1_3) /* in openssl 1.1.1, negotiation code for tls 1.3 does * not allow the unauthenticated aNULL and eNULL ciphers */ SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_3); #endif #ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL SSL_CTX_set_security_level(ctx, 0); #endif if(!SSL_CTX_set_cipher_list(ctx, "aNULL:eNULL")) ssl_err("Error setting NULL cipher!"); } return ctx; }
/** read all key files, exit on error */ static ldns_key_list* read_keys(int num, char* names[], struct keysets* set) { int i; ldns_key_list* keys = ldns_key_list_new(); ldns_key* k; ldns_rdf* rdf; ldns_status s; int b; FILE* in; if(!keys) fatal_exit("alloc failure"); for(i=0; i<num; i++) { printf("read keyfile %s\n", names[i]); in = fopen(names[i], "r"); if(!in) fatal_exit("could not open %s: %s", names[i], strerror(errno)); s = ldns_key_new_frm_fp(&k, in); fclose(in); if(s != LDNS_STATUS_OK) fatal_exit("bad keyfile %s: %s", names[i], ldns_get_errorstr_by_id(s)); ldns_key_set_expiration(k, set->expi); ldns_key_set_inception(k, set->incep); s = ldns_str2rdf_dname(&rdf, set->owner); if(s != LDNS_STATUS_OK) fatal_exit("bad owner name %s: %s", set->owner, ldns_get_errorstr_by_id(s)); ldns_key_set_pubkey_owner(k, rdf); ldns_key_set_flags(k, set->flags); ldns_key_set_keytag(k, set->keytag); b = ldns_key_list_push_key(keys, k); log_assert(b); } return keys; }
/** process nsec3 params and perform hashing */ static void process_nsec3(int argc, char* argv[]) { char line[10240]; ldns_rdf* salt; ldns_rdf* in, *out; ldns_status status; status = ldns_str2rdf_nsec3_salt(&salt, argv[5]); if(status != LDNS_STATUS_OK) fatal_exit("Could not parse salt %s: %s", argv[5], ldns_get_errorstr_by_id(status)); log_assert(argc == 6); while(fgets(line, (int)sizeof(line), stdin)) { if(strlen(line) > 0) line[strlen(line)-1] = 0; /* remove trailing newline */ if(line[0]==0) continue; status = ldns_str2rdf_dname(&in, line); if(status != LDNS_STATUS_OK) fatal_exit("Could not parse name %s: %s", line, ldns_get_errorstr_by_id(status)); ldns_rdf_print(stdout, in); printf(" -> "); /* arg 3 is flags, unused */ out = ldns_nsec3_hash_name(in, (uint8_t)atoi(argv[2]), (uint16_t)atoi(argv[4]), ldns_rdf_data(salt)[0], ldns_rdf_data(salt)+1); if(!out) fatal_exit("Could not hash %s", line); ldns_rdf_print(stdout, out); printf("\n"); ldns_rdf_deep_free(in); ldns_rdf_deep_free(out); } ldns_rdf_deep_free(salt); }