int main(int argc, char *argv[]) { lwres_context_t *ctx; const char *file = "/etc/resolv.conf"; int ret; #ifdef USE_ISC_MEM isc_mem_t *mem; isc_result_t result; #endif isc__mem_register(); isc__task_register(); isc__timer_register(); isc__socket_register(); if (argc > 1) { file = argv[1]; } #ifdef USE_ISC_MEM mem = NULL; result = isc_mem_create(0, 0, &mem); INSIST(result == ISC_R_SUCCESS); #endif ctx = NULL; #ifdef USE_ISC_MEM ret = lwres_context_create(&ctx, mem, mem_alloc, mem_free, 0); #else ret = lwres_context_create(&ctx, NULL, NULL, NULL, 0); #endif CHECK(ret, "lwres_context_create"); lwres_conf_init(ctx); if (lwres_conf_parse(ctx, file) == 0) { lwres_conf_print(ctx, stderr); } else { perror("lwres_conf_parse"); } lwres_conf_clear(ctx); lwres_context_destroy(&ctx); #ifdef USE_ISC_MEM isc_mem_stats(mem, stdout); isc_mem_destroy(&mem); #endif return (0); }
void do_queries () { iplist tIP; lwres_context_t *ctx = NULL; lwres_grbnresponse_t *response = NULL; int n, i; pthread_mutex_lock(mutexp); tIP = IPs; if (IPs != NULL) { IPs = tIP->next; } pthread_mutex_unlock(mutexp); while (tIP != NULL) { //fprintf (stderr, "making query %s\n", tIP->IP); fflush(stderr); if (lwres_context_create(&ctx, NULL, NULL, NULL, 0) != 0) { fprintf (stderr, "Couldn't create context\n"); return; } else { lwres_conf_parse(ctx, lwres_resolv_conf); //pthread_mutex_lock(mutexoutput); n = lwres_getrdatabyname(ctx, tIP->IP, ns_c_in, ns_t_a, 0, &response); //pthread_mutex_unlock(mutexoutput); if (n == LWRES_R_SUCCESS) { printf ("%s,%d.%d.%d.%d,%d\n", tIP->IP, response->rdatas[0][0], response->rdatas[0][1], response->rdatas[0][2], response->rdatas[0][3], response->ttl); //fprintf (stderr, "freeing response\n"); fflush(stderr); lwres_grbnresponse_free(ctx, &response); } else { //fprintf (stderr, "Nothing found\n"); printf ("%s, %s, %d\n", tIP->IP, tIP->IP, defttl); } //fprintf (stderr, "freeing context\n"); fflush(stderr); lwres_context_destroy(&ctx); //fprintf (stderr, "done freeing\n"); fflush(stderr); } pthread_mutex_lock(mutexp); tIP = IPs; if (IPs != NULL) { IPs = tIP->next; } pthread_mutex_unlock(mutexp); } }
static void lwdclientmgr_destroy(ns_lwdclientmgr_t *cm) { ns_lwdclient_t *client; ns_lwreslistener_t *listener; LOCK(&cm->lock); if (!SHUTTINGDOWN(cm)) { UNLOCK(&cm->lock); return; } /* * Run through the idle list and free the clients there. Idle * clients do not have a recv running nor do they have any finds * or similar running. */ client = ISC_LIST_HEAD(cm->idle); while (client != NULL) { ns_lwdclient_log(50, "destroying client %p, manager %p", client, cm); ISC_LIST_UNLINK(cm->idle, client, link); isc_mem_put(cm->mctx, client, sizeof(*client)); client = ISC_LIST_HEAD(cm->idle); } if (!ISC_LIST_EMPTY(cm->running)) { UNLOCK(&cm->lock); return; } UNLOCK(&cm->lock); lwres_context_destroy(&cm->lwctx); cm->view = NULL; isc_socket_detach(&cm->sock); isc_task_detach(&cm->task); DESTROYLOCK(&cm->lock); listener = cm->listener; ns_lwreslistener_unlinkcm(listener, cm); ns_lwdclient_log(50, "destroying manager %p", cm); isc_mem_put(cm->mctx, cm, sizeof(*cm)); ns_lwreslistener_detach(&listener); }
ATF_TC_BODY(parse_linklocal, tc) { lwres_result_t result; lwres_context_t *ctx = NULL; unsigned char addr[16] = { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; UNUSED(tc); setup_test(); lwres_context_create(&ctx, NULL, NULL, NULL, LWRES_CONTEXT_USEIPV4 | LWRES_CONTEXT_USEIPV6); ATF_CHECK_EQ(ctx->confdata.nsnext, 0); ATF_CHECK_EQ(ctx->confdata.nameservers[0].zone, 0); result = lwres_conf_parse(ctx, "testdata/link-local.conf"); ATF_CHECK_EQ(result, LWRES_R_SUCCESS); ATF_CHECK_EQ(ctx->confdata.nsnext, 1); ATF_CHECK_EQ(ctx->confdata.nameservers[0].zone, 1); ATF_CHECK_EQ(memcmp(ctx->confdata.nameservers[0].address, addr, 16), 0); lwres_context_destroy(&ctx); }
/* * Convert a resolv.conf file into a config structure. */ isc_result_t ns_lwresd_parseeresolvconf(isc_mem_t *mctx, cfg_parser_t *pctx, cfg_obj_t **configp) { char text[4096]; char str[16]; isc_buffer_t b; lwres_context_t *lwctx = NULL; lwres_conf_t *lwc = NULL; isc_sockaddr_t sa; isc_netaddr_t na; int i; isc_result_t result; lwres_result_t lwresult; lwctx = NULL; lwresult = lwres_context_create(&lwctx, mctx, ns__lwresd_memalloc, ns__lwresd_memfree, LWRES_CONTEXT_SERVERMODE); if (lwresult != LWRES_R_SUCCESS) { result = ISC_R_NOMEMORY; goto cleanup; } lwresult = lwres_conf_parse(lwctx, lwresd_g_resolvconffile); if (lwresult != LWRES_R_SUCCESS) { result = DNS_R_SYNTAX; goto cleanup; } lwc = lwres_conf_get(lwctx); INSIST(lwc != NULL); isc_buffer_init(&b, text, sizeof(text)); CHECK(buffer_putstr(&b, "options {\n")); /* * Build the list of forwarders. */ if (lwc->nsnext > 0) { CHECK(buffer_putstr(&b, "\tforwarders {\n")); for (i = 0; i < lwc->nsnext; i++) { CHECK(lwaddr_sockaddr_fromlwresaddr( &sa, &lwc->nameservers[i], ns_g_port)); isc_netaddr_fromsockaddr(&na, &sa); CHECK(buffer_putstr(&b, "\t\t")); CHECK(isc_netaddr_totext(&na, &b)); CHECK(buffer_putstr(&b, ";\n")); } CHECK(buffer_putstr(&b, "\t};\n")); } /* * Build the sortlist */ if (lwc->sortlistnxt > 0) { CHECK(buffer_putstr(&b, "\tsortlist {\n")); CHECK(buffer_putstr(&b, "\t\t{\n")); CHECK(buffer_putstr(&b, "\t\t\tany;\n")); CHECK(buffer_putstr(&b, "\t\t\t{\n")); for (i = 0; i < lwc->sortlistnxt; i++) { lwres_addr_t *lwaddr = &lwc->sortlist[i].addr; lwres_addr_t *lwmask = &lwc->sortlist[i].mask; unsigned int mask; CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, lwmask, 0)); isc_netaddr_fromsockaddr(&na, &sa); result = isc_netaddr_masktoprefixlen(&na, &mask); if (result != ISC_R_SUCCESS) { char addrtext[ISC_NETADDR_FORMATSIZE]; isc_netaddr_format(&na, addrtext, sizeof(addrtext)); isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_LWRESD, ISC_LOG_ERROR, "processing sortlist: '%s' is " "not a valid netmask", addrtext); goto cleanup; } CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, lwaddr, 0)); isc_netaddr_fromsockaddr(&na, &sa); CHECK(buffer_putstr(&b, "\t\t\t\t")); CHECK(isc_netaddr_totext(&na, &b)); snprintf(str, sizeof(str), "%u", mask); CHECK(buffer_putstr(&b, "/")); CHECK(buffer_putstr(&b, str)); CHECK(buffer_putstr(&b, ";\n")); } CHECK(buffer_putstr(&b, "\t\t\t};\n")); CHECK(buffer_putstr(&b, "\t\t};\n")); CHECK(buffer_putstr(&b, "\t};\n")); } CHECK(buffer_putstr(&b, "};\n\n")); CHECK(buffer_putstr(&b, "lwres {\n")); /* * Build the search path */ if (lwc->searchnxt > 0) { if (lwc->searchnxt > 0) { CHECK(buffer_putstr(&b, "\tsearch {\n")); for (i = 0; i < lwc->searchnxt; i++) { CHECK(buffer_putstr(&b, "\t\t\"")); CHECK(buffer_putstr(&b, lwc->search[i])); CHECK(buffer_putstr(&b, "\";\n")); } CHECK(buffer_putstr(&b, "\t};\n")); } } /* * Build the ndots line */ if (lwc->ndots != 1) { CHECK(buffer_putstr(&b, "\tndots ")); snprintf(str, sizeof(str), "%u", lwc->ndots); CHECK(buffer_putstr(&b, str)); CHECK(buffer_putstr(&b, ";\n")); } /* * Build the listen-on line */ if (lwc->lwnext > 0) { CHECK(buffer_putstr(&b, "\tlisten-on {\n")); for (i = 0; i < lwc->lwnext; i++) { CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, &lwc->lwservers[i], 0)); isc_netaddr_fromsockaddr(&na, &sa); CHECK(buffer_putstr(&b, "\t\t")); CHECK(isc_netaddr_totext(&na, &b)); CHECK(buffer_putstr(&b, ";\n")); } CHECK(buffer_putstr(&b, "\t};\n")); } CHECK(buffer_putstr(&b, "};\n")); #if 0 printf("%.*s\n", (int)isc_buffer_usedlength(&b), (char *)isc_buffer_base(&b)); #endif lwres_conf_clear(lwctx); lwres_context_destroy(&lwctx); return (cfg_parse_buffer(pctx, &b, &cfg_type_namedconf, configp)); cleanup: if (lwctx != NULL) { lwres_conf_clear(lwctx); lwres_context_destroy(&lwctx); } return (result); }
int main(int argc, char *argv[]) { int ret; #ifdef USE_ISC_MEM isc_mem_t *mem; isc_result_t result; #endif (void)argc; (void)argv; #ifdef USE_ISC_MEM mem = NULL; result = isc_mem_create(0, 0, &mem); INSIST(result == ISC_R_SUCCESS); #endif ctx = NULL; #ifdef USE_ISC_MEM ret = lwres_context_create(&ctx, mem, mem_alloc, mem_free, 0); #else ret = lwres_context_create(&ctx, NULL, NULL, NULL, 0); #endif CHECK(ret, "lwres_context_create"); ret = lwres_conf_parse(ctx, "/etc/resolv.conf"); CHECK(ret, "lwres_conf_parse"); lwres_conf_print(ctx, stdout); test_noop(); /* * The following comments about tests all assume your search path is * nominum.com isc.org flame.org * and ndots is the default of 1. */ test_gabn("alias-05.test"); /* exact, then search. */ test_gabn("f.root-servers.net."); test_gabn("poofball.flame.org."); test_gabn("foo.ip6.int."); test_gabn("notthereatall.flame.org"); /* exact, then search (!found)*/ test_gabn("shell"); /* search (found in nominum.com), then exact */ test_gabn("kechara"); /* search (found in flame.org), then exact */ test_gabn("lkasdjlaksjdlkasjdlkasjdlkasjd"); /* search, exact(!found)*/ test_gnba("198.133.199.1", LWRES_ADDRTYPE_V4); test_gnba("204.152.184.79", LWRES_ADDRTYPE_V4); test_gnba("3ffe:8050:201:1860:42::1", LWRES_ADDRTYPE_V6); lwres_conf_clear(ctx); lwres_context_destroy(&ctx); #ifdef USE_ISC_MEM isc_mem_stats(mem, stdout); isc_mem_destroy(&mem); #endif return (0); }
/*% performs a reverse lookup of address src which is len bytes long. af denotes the protocol family, typically #PF_INET or PF_INET6. */ struct hostent * lwres_getipnodebyaddr(const void *src, size_t len, int af, int *error_num) { struct hostent *he1, *he2; lwres_context_t *lwrctx = NULL; lwres_gnbaresponse_t *by = NULL; lwres_result_t n; union { const void *konst; struct in6_addr *in6; } u; /* * Sanity checks. */ if (src == NULL) { *error_num = NO_RECOVERY; return (NULL); } switch (af) { case AF_INET: if (len != (unsigned int)INADDRSZ) { *error_num = NO_RECOVERY; return (NULL); } break; case AF_INET6: if (len != (unsigned int)IN6ADDRSZ) { *error_num = NO_RECOVERY; return (NULL); } break; default: *error_num = NO_RECOVERY; return (NULL); } /* * The de-"const"-ing game is done because at least one * vendor's system (RedHat 6.0) defines the IN6_IS_ADDR_* * macros in such a way that they discard the const with * internal casting, and gcc ends up complaining. Rather * than replacing their own (possibly optimized) definitions * with our own, cleanly discarding the const is the easiest * thing to do. */ u.konst = src; /* * Look up IPv4 and IPv4 mapped/compatible addresses. */ if ((af == AF_INET6 && IN6_IS_ADDR_V4COMPAT(u.in6)) || (af == AF_INET6 && IN6_IS_ADDR_V4MAPPED(u.in6)) || (af == AF_INET)) { const unsigned char *cp = src; if (af == AF_INET6) cp += 12; n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0); if (n == LWRES_R_SUCCESS) (void) lwres_conf_parse(lwrctx, lwres_resolv_conf); if (n == LWRES_R_SUCCESS) n = lwres_getnamebyaddr(lwrctx, LWRES_ADDRTYPE_V4, INADDRSZ, cp, &by); if (n != LWRES_R_SUCCESS) { lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); if (n == LWRES_R_NOTFOUND) *error_num = HOST_NOT_FOUND; else *error_num = NO_RECOVERY; return (NULL); } he1 = hostfromaddr(by, AF_INET, cp); lwres_gnbaresponse_free(lwrctx, &by); lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); if (af != AF_INET6) return (he1); /* * Convert from AF_INET to AF_INET6. */ he2 = copyandmerge(he1, NULL, af, error_num); lwres_freehostent(he1); if (he2 == NULL) return (NULL); /* * Restore original address. */ memcpy(he2->h_addr, src, len); return (he2); } /* * Lookup IPv6 address. */ if (memcmp(src, &in6addr_any, IN6ADDRSZ) == 0) { *error_num = HOST_NOT_FOUND; return (NULL); } n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0); if (n == LWRES_R_SUCCESS) (void) lwres_conf_parse(lwrctx, lwres_resolv_conf); if (n == LWRES_R_SUCCESS) n = lwres_getnamebyaddr(lwrctx, LWRES_ADDRTYPE_V6, IN6ADDRSZ, src, &by); if (n != 0) { lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); if (n == LWRES_R_NOTFOUND) *error_num = HOST_NOT_FOUND; else *error_num = NO_RECOVERY; return (NULL); } he1 = hostfromaddr(by, AF_INET6, src); lwres_gnbaresponse_free(lwrctx, &by); if (he1 == NULL) *error_num = NO_RECOVERY; lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); return (he1); }
struct hostent * lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) { int have_v4 = 1, have_v6 = 1; struct in_addr in4; struct in6_addr in6; struct hostent he, *he1 = NULL, *he2 = NULL, *he3 = NULL; int v4 = 0, v6 = 0; int tmp_err = 0; lwres_context_t *lwrctx = NULL; lwres_gabnresponse_t *by = NULL; int n; /* * If we care about active interfaces then check. */ if ((flags & AI_ADDRCONFIG) != 0) if (scan_interfaces(&have_v4, &have_v6) == -1) { *error_num = NO_RECOVERY; return (NULL); } /* Check for literal address. */ if ((v4 = lwres_net_pton(AF_INET, name, &in4)) != 1) v6 = lwres_net_pton(AF_INET6, name, &in6); /* * Impossible combination? */ if ((af == AF_INET6 && (flags & AI_V4MAPPED) == 0 && v4 == 1) || (af == AF_INET && v6 == 1) || (have_v4 == 0 && v4 == 1) || (have_v6 == 0 && v6 == 1) || (have_v4 == 0 && af == AF_INET) || (have_v6 == 0 && af == AF_INET6 && (((flags & AI_V4MAPPED) != 0 && have_v4) || (flags & AI_V4MAPPED) == 0))) { *error_num = HOST_NOT_FOUND; return (NULL); } /* * Literal address? */ if (v4 == 1 || v6 == 1) { char *addr_list[2]; char *aliases[1]; char mappedname[sizeof("::ffff:123.123.123.123")]; union { const char *const_name; char *deconst_name; } u; u.const_name = name; if (v4 == 1 && af == AF_INET6) { strcpy(mappedname, "::ffff:"); lwres_net_ntop(AF_INET, (char *)&in4, mappedname + sizeof("::ffff:") - 1, sizeof(mappedname) - sizeof("::ffff:") + 1); he.h_name = mappedname; } else he.h_name = u.deconst_name; he.h_addr_list = addr_list; he.h_addr_list[0] = (v4 == 1) ? (char *)&in4 : (char *)&in6; he.h_addr_list[1] = NULL; he.h_aliases = aliases; he.h_aliases[0] = NULL; he.h_length = (v4 == 1) ? INADDRSZ : IN6ADDRSZ; he.h_addrtype = (v4 == 1) ? AF_INET : AF_INET6; return (copyandmerge(&he, NULL, af, error_num)); } n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0); if (n != 0) { *error_num = NO_RECOVERY; goto cleanup; } (void) lwres_conf_parse(lwrctx, lwres_resolv_conf); tmp_err = NO_RECOVERY; if (have_v6 && af == AF_INET6) { n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V6, &by); if (n == 0) { he1 = hostfromname(by, AF_INET6); lwres_gabnresponse_free(lwrctx, &by); if (he1 == NULL) { *error_num = NO_RECOVERY; goto cleanup; } } else { if (n == LWRES_R_NOTFOUND) tmp_err = HOST_NOT_FOUND; else { *error_num = NO_RECOVERY; goto cleanup; } } } if (have_v4 && ((af == AF_INET) || (af == AF_INET6 && (flags & AI_V4MAPPED) != 0 && (he1 == NULL || (flags & AI_ALL) != 0)))) { n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V4, &by); if (n == 0) { he2 = hostfromname(by, AF_INET); lwres_gabnresponse_free(lwrctx, &by); if (he2 == NULL) { *error_num = NO_RECOVERY; goto cleanup; } } else if (he1 == NULL) { if (n == LWRES_R_NOTFOUND) *error_num = HOST_NOT_FOUND; else *error_num = NO_RECOVERY; goto cleanup; } } else *error_num = tmp_err; he3 = copyandmerge(he1, he2, af, error_num); cleanup: if (he1 != NULL) lwres_freehostent(he1); if (he2 != NULL) lwres_freehostent(he2); if (lwrctx != NULL) { lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); } return (he3); }
/*% Returns a set of resource records associated with a hostname, class, and type. hostname is a pointer a to null-terminated string. */ int lwres_getrrsetbyname(const char *hostname, unsigned int rdclass, unsigned int rdtype, unsigned int flags, struct rrsetinfo **res) { lwres_context_t *lwrctx = NULL; lwres_result_t lwresult; lwres_grbnresponse_t *response = NULL; struct rrsetinfo *rrset = NULL; unsigned int i; unsigned int lwflags; unsigned int result; if (rdclass > 0xffff || rdtype > 0xffff) { result = ERRSET_INVAL; goto fail; } /* * Don't allow queries of class or type ANY */ if (rdclass == 0xff || rdtype == 0xff) { result = ERRSET_INVAL; goto fail; } lwresult = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0); if (lwresult != LWRES_R_SUCCESS) { result = lwresult_to_result(lwresult); goto fail; } (void) lwres_conf_parse(lwrctx, lwres_resolv_conf); /* * If any input flags were defined, lwflags would be set here * based on them */ UNUSED(flags); lwflags = 0; lwresult = lwres_getrdatabyname(lwrctx, hostname, (lwres_uint16_t)rdclass, (lwres_uint16_t)rdtype, lwflags, &response); if (lwresult != LWRES_R_SUCCESS) { result = lwresult_to_result(lwresult); goto fail; } rrset = sane_malloc(sizeof(struct rrsetinfo)); if (rrset == NULL) { result = ERRSET_NOMEMORY; goto fail; } rrset->rri_name = NULL; rrset->rri_rdclass = response->rdclass; rrset->rri_rdtype = response->rdtype; rrset->rri_ttl = response->ttl; rrset->rri_flags = 0; rrset->rri_nrdatas = 0; rrset->rri_rdatas = NULL; rrset->rri_nsigs = 0; rrset->rri_sigs = NULL; rrset->rri_name = sane_malloc(response->realnamelen + 1); if (rrset->rri_name == NULL) { result = ERRSET_NOMEMORY; goto fail; } strncpy(rrset->rri_name, response->realname, response->realnamelen); rrset->rri_name[response->realnamelen] = 0; if ((response->flags & LWRDATA_VALIDATED) != 0) rrset->rri_flags |= RRSET_VALIDATED; rrset->rri_nrdatas = response->nrdatas; rrset->rri_rdatas = sane_calloc(rrset->rri_nrdatas, sizeof(struct rdatainfo)); if (rrset->rri_rdatas == NULL) { result = ERRSET_NOMEMORY; goto fail; } for (i = 0; i < rrset->rri_nrdatas; i++) { rrset->rri_rdatas[i].rdi_length = response->rdatalen[i]; rrset->rri_rdatas[i].rdi_data = sane_malloc(rrset->rri_rdatas[i].rdi_length); if (rrset->rri_rdatas[i].rdi_data == NULL) { result = ERRSET_NOMEMORY; goto fail; } memcpy(rrset->rri_rdatas[i].rdi_data, response->rdatas[i], rrset->rri_rdatas[i].rdi_length); } rrset->rri_nsigs = response->nsigs; rrset->rri_sigs = sane_calloc(rrset->rri_nsigs, sizeof(struct rdatainfo)); if (rrset->rri_sigs == NULL) { result = ERRSET_NOMEMORY; goto fail; } for (i = 0; i < rrset->rri_nsigs; i++) { rrset->rri_sigs[i].rdi_length = response->siglen[i]; rrset->rri_sigs[i].rdi_data = sane_malloc(rrset->rri_sigs[i].rdi_length); if (rrset->rri_sigs[i].rdi_data == NULL) { result = ERRSET_NOMEMORY; goto fail; } memcpy(rrset->rri_sigs[i].rdi_data, response->sigs[i], rrset->rri_sigs[i].rdi_length); } lwres_grbnresponse_free(lwrctx, &response); lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); *res = rrset; return (ERRSET_SUCCESS); fail: if (rrset != NULL) lwres_freerrset(rrset); if (response != NULL) lwres_grbnresponse_free(lwrctx, &response); if (lwrctx != NULL) { lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); } return (result); }
isc_result_t ns_lwdclientmgr_create(ns_lwreslistener_t *listener, unsigned int nclients, isc_taskmgr_t *taskmgr) { ns_lwresd_t *lwresd = listener->manager; ns_lwdclientmgr_t *cm; ns_lwdclient_t *client; unsigned int i; isc_result_t result = ISC_R_FAILURE; cm = isc_mem_get(lwresd->mctx, sizeof(ns_lwdclientmgr_t)); if (cm == NULL) return (ISC_R_NOMEMORY); cm->listener = NULL; ns_lwreslistener_attach(listener, &cm->listener); cm->mctx = lwresd->mctx; cm->sock = NULL; isc_socket_attach(listener->sock, &cm->sock); cm->view = lwresd->view; cm->lwctx = NULL; cm->task = NULL; cm->flags = 0; ISC_LINK_INIT(cm, link); ISC_LIST_INIT(cm->idle); ISC_LIST_INIT(cm->running); if (lwres_context_create(&cm->lwctx, cm->mctx, ns__lwresd_memalloc, ns__lwresd_memfree, LWRES_CONTEXT_SERVERMODE) != ISC_R_SUCCESS) goto errout; for (i = 0; i < nclients; i++) { client = isc_mem_get(lwresd->mctx, sizeof(ns_lwdclient_t)); if (client != NULL) { ns_lwdclient_log(50, "created client %p, manager %p", client, cm); ns_lwdclient_initialize(client, cm); } } /* * If we could create no clients, clean up and return. */ if (ISC_LIST_EMPTY(cm->idle)) goto errout; result = isc_task_create(taskmgr, 0, &cm->task); if (result != ISC_R_SUCCESS) goto errout; /* * This MUST be last, since there is no way to cancel an onshutdown... */ result = isc_task_onshutdown(cm->task, lwdclientmgr_shutdown_callback, cm); if (result != ISC_R_SUCCESS) goto errout; ns_lwreslistener_linkcm(listener, cm); return (ISC_R_SUCCESS); errout: client = ISC_LIST_HEAD(cm->idle); while (client != NULL) { ISC_LIST_UNLINK(cm->idle, client, link); isc_mem_put(lwresd->mctx, client, sizeof(*client)); client = ISC_LIST_HEAD(cm->idle); } if (cm->task != NULL) isc_task_detach(&cm->task); if (cm->lwctx != NULL) lwres_context_destroy(&cm->lwctx); isc_mem_put(lwresd->mctx, cm, sizeof(*cm)); return (result); }
static int add_ipv6(const char *hostname, int flags, struct addrinfo **aip, int socktype, int port) { struct addrinfo *ai; lwres_context_t *lwrctx = NULL; lwres_gabnresponse_t *by = NULL; lwres_addr_t *addr; lwres_result_t lwres; int result = 0; lwres = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0); if (lwres != LWRES_R_SUCCESS) ERR(EAI_FAIL); (void) lwres_conf_parse(lwrctx, lwres_resolv_conf); if (hostname == NULL && (flags & AI_PASSIVE) == 0) { ai = ai_clone(*aip, AF_INET6); if (ai == NULL) { lwres_freeaddrinfo(*aip); ERR(EAI_MEMORY); } *aip = ai; ai->ai_socktype = socktype; SIN6(ai->ai_addr)->sin6_port = port; memcpy(&SIN6(ai->ai_addr)->sin6_addr, v6_loop, 16); } else { lwres = lwres_getaddrsbyname(lwrctx, hostname, LWRES_ADDRTYPE_V6, &by); if (lwres != LWRES_R_SUCCESS) { if (lwres == LWRES_R_NOTFOUND) goto cleanup; else ERR(EAI_FAIL); } addr = LWRES_LIST_HEAD(by->addrs); while (addr != NULL) { ai = ai_clone(*aip, AF_INET6); if (ai == NULL) { lwres_freeaddrinfo(*aip); ERR(EAI_MEMORY); } *aip = ai; ai->ai_socktype = socktype; SIN6(ai->ai_addr)->sin6_port = port; memcpy(&SIN6(ai->ai_addr)->sin6_addr, addr->address, 16); if (flags & AI_CANONNAME) { ai->ai_canonname = strdup(by->realname); if (ai->ai_canonname == NULL) ERR(EAI_MEMORY); } addr = LWRES_LIST_NEXT(addr, link); } } cleanup: if (by != NULL) lwres_gabnresponse_free(lwrctx, &by); if (lwrctx != NULL) { lwres_conf_clear(lwrctx); lwres_context_destroy(&lwrctx); } return (result); }