void unbound_ctx_free(void) { if (dns_ctx != NULL) { ub_ctx_delete(dns_ctx); dns_ctx = NULL; } }
static int mod_detach(void *instance) { rlm_unbound_t *inst = instance; if (inst->log_fd >= 0) { fr_event_fd_delete(inst->el, inst->log_fd, FR_EVENT_FILTER_IO); if (inst->ub) { ub_process(inst->ub); /* This can hang/leave zombies currently * see upstream bug #519 * ...so expect valgrind to complain with -m */ #if 0 ub_ctx_delete(inst->ub); #endif } } if (inst->log_pipe_stream[1]) { fclose(inst->log_pipe_stream[1]); } if (inst->log_pipe_stream[0]) { if (inst->log_pipe_in_use) { fr_event_fd_delete(inst->el, inst->log_pipe[0], FR_EVENT_FILTER_IO); } fclose(inst->log_pipe_stream[0]); } if (inst->log_stream) { fclose(inst->log_stream); } return 0; }
/** perform extended threaded test */ static int ext_test(struct ub_ctx* ctx, int argc, char** argv) { struct ext_thr_info inf[NUMTHR]; int i; if(argc == 1 && strcmp(argv[0], "localhost") == 0) q_is_localhost = 1; printf("extended test start (%d threads)\n", NUMTHR); for(i=0; i<NUMTHR; i++) { /* 0 = this, 1 = library bg worker */ inf[i].thread_num = i+2; inf[i].ctx = ctx; inf[i].argc = argc; inf[i].argv = argv; inf[i].numq = 100; ub_thread_create(&inf[i].tid, ext_thread, &inf[i]); } /* the work happens here */ for(i=0; i<NUMTHR; i++) { ub_thread_join(inf[i].tid); } printf("extended test end\n"); ub_ctx_delete(ctx); checklock_stop(); return 0; }
DNSResolver::~DNSResolver() { if (m_data) { if (m_data->m_ub_context != NULL) { ub_ctx_delete(m_data->m_ub_context); } delete m_data; } }
/** update domain to file */ static int do_update(char* domain, char* file) { struct ub_ctx* ctx; struct ub_result* result; int r; printf("updating %s to %s\n", domain, file); ctx = ub_ctx_create(); if(!ctx) fatal("ub_ctx_create failed"); if((r=ub_ctx_add_ta_file(ctx, file))) { printf("%s\n", ub_strerror(r)); fatal("ub_ctx_add_ta_file failed"); } if(!(result=do_lookup(ctx, domain))) { ub_ctx_delete(ctx); return 1; } ub_ctx_delete(ctx); do_print(result, file); ub_resolve_free(result); return 0; }
struct ub_ctx* ub_ctx_create_event(struct event_base* eb) { struct ub_ctx* ctx = ub_ctx_create_nopipe(); if(!ctx) return NULL; /* no pipes, but we have the locks to make sure everything works */ ctx->created_bg = 0; ctx->dothread = 1; /* the processing is in the same process, makes ub_cancel and ub_ctx_delete do the right thing */ ctx->event_base = ub_libevent_event_base(eb); if (!ctx->event_base) { ub_ctx_delete(ctx); return NULL; } return ctx; }
/** perform host lookup */ static void lookup(struct ub_ctx* ctx, const char* nm, const char* qt, const char* qc) { /* massage input into a query name, type and class */ int multi = 0; /* no type, so do A, AAAA, MX */ int reverse = 0; /* we are doing a reverse lookup */ char* realq = massage_qname(nm, &reverse); int t = massage_type(qt, reverse, &multi); int c = massage_class(qc); /* perform the query */ if(multi) { if(!dnslook(ctx, realq, LDNS_RR_TYPE_A, c, 1)) { /* domain exists, lookup more */ (void)dnslook(ctx, realq, LDNS_RR_TYPE_AAAA, c, 0); (void)dnslook(ctx, realq, LDNS_RR_TYPE_MX, c, 0); } } else { (void)dnslook(ctx, realq, t, c, 1); } ub_ctx_delete(ctx); free(realq); }
struct ub_result * unbify_resolve(const char *hostname) { /*@only@*/ static struct ub_ctx * u = NULL; struct ub_result * r = NULL; int ub_err; assert(hostname != NULL); if ( u == NULL ) { if ( (u = ub_ctx_create()) == NULL ) { unbify_log_error("ub_ctx_create() error"); return NULL; } if ( (ub_err = ub_ctx_config(u, UNBOUND_CONFIG_FILE)) != 0 ) { /*@-mustfreefresh@*/ unbify_log_error(ub_strerror(ub_err)); /*@=mustfreefresh@*/ ub_ctx_delete(u); u = NULL; return NULL; } } /*@-unrecog@*/ if ( (ub_err = ub_resolve(u, (char*)hostname, LDNS_RR_TYPE_A, LDNS_RR_CLASS_IN, &r)) != 0 ) { /*@=unrecog -mustfreefresh@*/ unbify_log_error(ub_strerror(ub_err)); /*@=mustfreefresh@*/ if (r) { ub_resolve_free(r); return NULL; } } return r; }
int main(void) { struct ub_ctx* ctx; volatile int qlen = 0; int retval; char qname[QNAME_MAX]; char *moredata, *nl; /* basic checks */ if(QUEUE_MAX < 1) { printf("error: queue length must be >0\n"); return 1; } /* create context */ ctx = ub_ctx_create(); if(!ctx) { printf("error: could not create unbound context\n"); return 1; } fprintf(stderr, "HOST;ERR;RCODE;DATA;NXDOMAIN\n"); /* we keep running, lets do something while waiting */ moredata = (char*)-1; do { /* queue has room && more data on stdin? */ if(qlen < QUEUE_MAX && moredata) { /* read and prepare qname from stdin */ moredata = fgets(qname, QNAME_MAX, stdin); if(moredata != NULL) { nl = strrchr(qname, '\n'); if(nl) *nl = '\0'; if((int)nl == (int)&qname) { printf("empty input\n"); continue; } /* add async query to queue */ retval = ub_resolve_async(ctx, qname, 1, 1, (void*)&qlen, mycallback, NULL); if(retval != 0) { printf("resolve error for %s: %s\n", qname, ub_strerror(retval)); continue; } qlen++; } usleep(50000); /* wait 1/50 of a second */ } else { /* queue is full || eof stdin reached */ usleep(100000); /* wait 1/10 of a second */ retval = ub_process(ctx); if(retval != 0) { printf("resolve error: %s\n", ub_strerror(retval)); return 1; } } } while(qlen || moredata); ub_ctx_delete(ctx); return 0; }
/** main program for asynclook */ int main(int argc, char** argv) { int c; struct ub_ctx* ctx; struct lookinfo* lookups; int i, r, cancel=0, blocking=0, ext=0; /* init log now because solaris thr_key_create() is not threadsafe */ log_init(0,0,0); /* lock debug start (if any) */ checklock_start(); /* create context */ ctx = ub_ctx_create(); if(!ctx) { printf("could not create context, %s\n", strerror(errno)); return 1; } /* command line options */ if(argc == 1) { usage(argv); } while( (c=getopt(argc, argv, "bcdf:hH:r:tx")) != -1) { switch(c) { case 'd': r = ub_ctx_debuglevel(ctx, 3); checkerr("ub_ctx_debuglevel", r); break; case 't': r = ub_ctx_async(ctx, 1); checkerr("ub_ctx_async", r); break; case 'c': cancel = 1; break; case 'b': blocking = 1; break; case 'r': r = ub_ctx_resolvconf(ctx, optarg); if(r != 0) { printf("ub_ctx_resolvconf " "error: %s : %s\n", ub_strerror(r), strerror(errno)); return 1; } break; case 'H': r = ub_ctx_hosts(ctx, optarg); if(r != 0) { printf("ub_ctx_hosts " "error: %s : %s\n", ub_strerror(r), strerror(errno)); return 1; } break; case 'f': r = ub_ctx_set_fwd(ctx, optarg); checkerr("ub_ctx_set_fwd", r); break; case 'x': ext = 1; break; case 'h': case '?': default: usage(argv); } } argc -= optind; argv += optind; if(ext) return ext_test(ctx, argc, argv); /* allocate array for results. */ lookups = (struct lookinfo*)calloc((size_t)argc, sizeof(struct lookinfo)); if(!lookups) { printf("out of memory\n"); return 1; } /* perform asynchronous calls */ num_wait = argc; for(i=0; i<argc; i++) { lookups[i].name = argv[i]; if(blocking) { fprintf(stderr, "lookup %s\n", argv[i]); r = ub_resolve(ctx, argv[i], LDNS_RR_TYPE_A, LDNS_RR_CLASS_IN, &lookups[i].result); checkerr("ub_resolve", r); } else { fprintf(stderr, "start async lookup %s\n", argv[i]); r = ub_resolve_async(ctx, argv[i], LDNS_RR_TYPE_A, LDNS_RR_CLASS_IN, &lookups[i], &lookup_is_done, &lookups[i].async_id); checkerr("ub_resolve_async", r); } } if(blocking) num_wait = 0; else if(cancel) { for(i=0; i<argc; i++) { fprintf(stderr, "cancel %s\n", argv[i]); r = ub_cancel(ctx, lookups[i].async_id); if(r != UB_NOID) checkerr("ub_cancel", r); } num_wait = 0; } /* wait while the hostnames are looked up. Do something useful here */ if(num_wait > 0) for(i=0; i<1000; i++) { usleep(100000); fprintf(stderr, "%g seconds passed\n", 0.1*(double)i); r = ub_process(ctx); checkerr("ub_process", r); if(num_wait == 0) break; } if(i>=999) { printf("timed out\n"); return 0; } printf("lookup complete\n"); /* print lookup results */ for(i=0; i<argc; i++) { print_result(&lookups[i]); ub_resolve_free(lookups[i].result); } ub_ctx_delete(ctx); free(lookups); checklock_stop(); return 0; }
int ifconf_acquire_addresses(const char *name, struct address **_list, unsigned *_n_list) { struct { struct nlmsghdr hdr; struct rtgenmsg gen; } req; struct rtgenmsg *gen; int fd, r, on = 1; uint32_t seq = 4711; struct address *list = NULL; unsigned n_list = 0; struct ub_ctx* ctx; struct ub_result* result; int retval, i; char *server = "127.0.0.1:8080"; char url[3000]; fprintf(stderr, "ifconf_acquire_addresses \n"); URL *curl; CURLcode res; curl = curl_easy_init(); if(curl) { sprintf(url, "http://%s/address/%s", server, name); curl_easy_setopt(curl, CURLOPT_URL,url); /* send all data to this function */ //curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data); fprintf(stderr, "Sending http request\n"); res = curl_easy_perform(curl); //printf("read:%s\n", reply); /* always cleanup */ curl_easy_cleanup(curl); } ctx = ub_ctx_create(); if(!ctx) { printf("error: could not create unbound context\n"); retval = -1; goto finish; } //ub_ctx_debuglevel(ctx, 10); //requesting ip address from signpost /* read /etc/resolv.conf for DNS proxy settings (from DHCP) */ if( (retval=ub_ctx_resolvconf(ctx, "/etc/resolv.conf")) != 0) { fprintf(stderr, "error reading resolv.conf: %s. errno says: %s\n", ub_strerror(retval), strerror(errno)); //retval = errno; //goto finish; } /* read /etc/hosts for locally supplied host addresses */ if( (retval=ub_ctx_hosts(ctx, "/etc/hosts")) != 0) { fprintf(stderr, "error reading hosts: %s. errno says: %s\n", ub_strerror(retval), strerror(errno)); //retval = errno; //goto finish; } /* query for webserver */ retval = ub_resolve(ctx, name, 1 /* TYPE A (IPv4 address) */, 1 /* CLASS IN (internet) */, &result); if(retval != 0) { fprintf(stderr, "error resolving: %s. errno says: %s\n", ub_strerror(retval), strerror(errno)); retval = -ENOENT; goto finish; } if(!result->havedata) { //fprintf(stderr, "no response found\n"); retval = -ENOENT; goto finish; } while(result->data[n_list]) { list = realloc(list, (n_list+1) * sizeof(struct address)); if (!list) { retval = -ENOMEM; goto finish; } struct in_addr in; in.s_addr = *(uint32_t *)result->data[n_list]; fprintf(stderr, "found ip %s\n", inet_ntoa(in)); list[n_list].family = AF_INET; list[n_list].scope = 1; //ifaddrmsg->ifa_scope; memcpy(list[n_list].address, result->data[n_list], 4); list[n_list].ifindex = 1; //ifaddrmsg->ifa_index; n_list++; } r= n_list; goto finish; finish: close(fd); ub_resolve_free(result); ub_ctx_delete(ctx); if (r < 0) free(list); else { qsort(list, n_list, sizeof(struct address), address_compare); *_list = list; *_n_list = n_list; } //fprintf(stderr, "returned %d addr\n", n_list); return r; }
nss_ubdns_finish(void) { ub_ctx_delete(ctx); ctx = NULL; }
struct starter_config *confread_load(const char *file, err_t *perr, bool resolvip, const char *ctlbase, bool setuponly) { bool err = FALSE; /** * Load file */ struct config_parsed *cfgp = parser_load_conf(file, perr); if (cfgp == NULL) return NULL; struct starter_config *cfg = alloc_thing(struct starter_config, "starter_config cfg"); /** * Set default values */ ipsecconf_default_values(cfg); if (ctlbase != NULL) { pfree(cfg->ctlbase); cfg->ctlbase = clone_str(ctlbase, "control socket"); } /** * Load setup */ err |= load_setup(cfg, cfgp); if (err) { parser_free_conf(cfgp); confread_free(cfg); return NULL; } #ifdef DNSSEC struct ub_ctx *dnsctx = unbound_init(); if (dnsctx == NULL) return NULL; #endif if (!setuponly) { /** * Find %default * */ struct section_list *sconn; for (sconn = cfgp->sections.tqh_first; (!err) && sconn != NULL; sconn = sconn->link.tqe_next) { if (streq(sconn->name, "%default")) { starter_log(LOG_LEVEL_DEBUG, "Loading default conn"); err |= load_conn( #ifdef DNSSEC dnsctx, #endif &cfg->conn_default, cfgp, sconn, FALSE, /*default conn*/ TRUE, resolvip, perr); } } /** * Load other conns */ for (sconn = cfgp->sections.tqh_first; sconn != NULL; sconn = sconn->link.tqe_next) { if (streq(sconn->name, "%default")) continue; err |= init_load_conn( #ifdef DNSSEC dnsctx, #endif cfg, cfgp, sconn, FALSE, resolvip, perr); } } parser_free_conf(cfgp); #ifdef DNSSEC ub_ctx_delete(dnsctx); #endif return cfg; }
int main(int argc, char **argv) { struct ub_ctx* ctx; struct ub_result* result; int retval; int i; struct timeval starttime, endtime; int number = 100000; if (argc > 1) { number = atoi(argv[1]); } /* create context */ ctx = ub_ctx_create(); if(!ctx) { printf("error: could not create unbound context\n"); return 1; } /* read /etc/resolv.conf for DNS proxy settings (from DHCP) */ if( (retval=ub_ctx_resolvconf(ctx, "resolv.conf")) != 0) { printf("error reading resolv.conf: %s. errno says: %s\n", ub_strerror(retval), strerror(errno)); return 1; } /* read /etc/hosts for locally supplied host addresses */ if( (retval=ub_ctx_hosts(ctx, "hosts")) != 0) { printf("error reading hosts: %s. errno says: %s\n", ub_strerror(retval), strerror(errno)); return 1; } /* read public keys for DNSSEC verification */ if( (retval=ub_ctx_add_ta_file(ctx, "keys")) != 0) { printf("error adding keys: %s\n", ub_strerror(retval)); return 1; } /* query for webserver */ retval = ub_resolve(ctx, LOOKUP_NAME, 1, 1, &result); if(retval != 0) { printf("resolve error: %s\n", ub_strerror(retval)); return 1; } /* show first result */ if(result->havedata) printf("The address is %s\n", inet_ntoa(*(struct in_addr*)result->data[0])); /* show security status */ if(!result->secure) { fprintf(stderr, "something very wrong; not validated response returned\n"); exit(1); } fprintf(stderr, "validated response returned\n"); // Note: this is without proper memory freeing fprintf(stderr, "starting %d queries without context....\n", number); gettimeofday(&starttime, NULL); for (i = 0; i < number; i++) { retval = ub_resolve(ctx, LOOKUP_NAME, 1, 1, &result); } gettimeofday(&endtime, NULL); fprintf(stderr, "time elapsed (ms) for %d queries: %d\n", number, timeofday_diff(&starttime, &endtime)); ub_resolve_free(result); ub_ctx_delete(ctx); return 0; }