예제 #1
0
static void
process_answer(isc_task_t *task, isc_event_t *event) {
	struct query_trans *trans = event->ev_arg;
	dns_clientresevent_t *rev = (dns_clientresevent_t *)event;
	dns_name_t *name;
	dns_rdataset_t *rdataset;
	isc_result_t result;

	REQUIRE(task == query_task);
	REQUIRE(trans->inuse == ISC_TRUE);
	REQUIRE(outstanding_queries > 0);

	printf("answer[%2d]\n", trans->id);

	if (rev->result != ISC_R_SUCCESS)
		printf("  failed: %d(%s)\n", rev->result,
		       dns_result_totext(rev->result));

	for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL;
	     name = ISC_LIST_NEXT(name, link)) {
		for (rdataset = ISC_LIST_HEAD(name->list);
		     rdataset != NULL;
		     rdataset = ISC_LIST_NEXT(rdataset, link)) {
			(void)printdata(rdataset, name);
		}
	}

	dns_client_freeresanswer(client, &rev->answerlist);
	dns_client_destroyrestrans(&trans->xid);

	isc_event_free(&event);

	trans->inuse = ISC_FALSE;
	dns_fixedname_invalidate(&trans->fixedname);
	trans->qname = NULL;
	outstanding_queries--;

	result = dispatch_query(trans);
#if 0				/* for cancel test */
	if (result == ISC_R_SUCCESS) {
		static int count = 0;

		if ((++count) % 10 == 0)
			dns_client_cancelresolve(trans->xid);
	}
#endif
	if (result == ISC_R_NOMORE && outstanding_queries == 0)
		isc_app_ctxshutdown(query_actx);
}
예제 #2
0
static void
resolve_ns(isc_task_t *task, isc_event_t *event) {
	struct probe_trans *trans = event->ev_arg;
	dns_clientresevent_t *rev = (dns_clientresevent_t *)event;
	dns_name_t *name;
	dns_rdataset_t *rdataset;
	isc_result_t result = ISC_R_SUCCESS;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	struct probe_ns *pns;

	REQUIRE(task == probe_task);
	REQUIRE(trans->inuse == ISC_TRUE);
	INSIST(outstanding_probes > 0);

	for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL;
	     name = ISC_LIST_NEXT(name, link)) {
		for (rdataset = ISC_LIST_HEAD(name->list);
		     rdataset != NULL;
		     rdataset = ISC_LIST_NEXT(rdataset, link)) {
			(void)print_rdataset(rdataset, name);

			if (rdataset->type != dns_rdatatype_ns)
				continue;

			for (result = dns_rdataset_first(rdataset);
			     result == ISC_R_SUCCESS;
			     result = dns_rdataset_next(rdataset)) {
				dns_rdata_ns_t ns;

				dns_rdataset_current(rdataset, &rdata);
				/*
				 * Extract the name from the NS record.
				 */
				result = dns_rdata_tostruct(&rdata, &ns, NULL);
				if (result != ISC_R_SUCCESS)
					continue;

				pns = isc_mem_get(mctx, sizeof(*pns));
				if (pns == NULL) {
					fprintf(stderr,
						"resolve_ns: mem_get failed");
					result = ISC_R_NOMEMORY;
					POST(result);
					/*
					 * XXX: should we continue with the
					 * available servers anyway?
					 */
					goto cleanup;
				}

				dns_fixedname_init(&pns->fixedname);
				pns->name =
					dns_fixedname_name(&pns->fixedname);
				ISC_LINK_INIT(pns, link);
				ISC_LIST_APPEND(trans->nslist, pns, link);
				ISC_LIST_INIT(pns->servers);

				dns_name_copy(&ns.name, pns->name, NULL);
				dns_rdata_reset(&rdata);
				dns_rdata_freestruct(&ns);
			}
		}
	}

 cleanup:
	dns_client_freeresanswer(client, &rev->answerlist);
	dns_client_destroyrestrans(&trans->resid);
	isc_event_free(&event);

	if (!ISC_LIST_EMPTY(trans->nslist)) {
		/* Go get addresses of NSes */
		trans->current_ns = ISC_LIST_HEAD(trans->nslist);
		result = fetch_nsaddress(trans);
	} else
		result = ISC_R_FAILURE;

	if (result == ISC_R_SUCCESS)
		return;

	reset_probe(trans);
}
예제 #3
0
static void
resolve_nsaddress(isc_task_t *task, isc_event_t *event) {
	struct probe_trans *trans = event->ev_arg;
	dns_clientresevent_t *rev = (dns_clientresevent_t *)event;
	dns_name_t *name;
	dns_rdataset_t *rdataset;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	struct probe_ns *pns = trans->current_ns;
	isc_result_t result;

	REQUIRE(task == probe_task);
	REQUIRE(trans->inuse == ISC_TRUE);
	REQUIRE(pns != NULL);
	INSIST(outstanding_probes > 0);

	for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL;
	     name = ISC_LIST_NEXT(name, link)) {
		for (rdataset = ISC_LIST_HEAD(name->list);
		     rdataset != NULL;
		     rdataset = ISC_LIST_NEXT(rdataset, link)) {
			(void)print_rdataset(rdataset, name);

			if (rdataset->type != dns_rdatatype_a)
				continue;

			for (result = dns_rdataset_first(rdataset);
			     result == ISC_R_SUCCESS;
			     result = dns_rdataset_next(rdataset)) {
				dns_rdata_in_a_t rdata_a;
				struct server *server;

				dns_rdataset_current(rdataset, &rdata);
				result = dns_rdata_tostruct(&rdata, &rdata_a,
							    NULL);
				if (result != ISC_R_SUCCESS)
					continue;

				server = isc_mem_get(mctx, sizeof(*server));
				if (server == NULL) {
					fprintf(stderr, "resolve_nsaddress: "
						"mem_get failed");
					result = ISC_R_NOMEMORY;
					POST(result);
					goto cleanup;
				}
				isc_sockaddr_fromin(&server->address,
						    &rdata_a.in_addr, 53);
				ISC_LINK_INIT(server, link);
				server->result_a = none;
				server->result_aaaa = none;
				ISC_LIST_APPEND(pns->servers, server, link);
			}
		}
	}

 cleanup:
	dns_client_freeresanswer(client, &rev->answerlist);
	dns_client_destroyrestrans(&trans->resid);
	isc_event_free(&event);

 next_ns:
	trans->current_ns = ISC_LIST_NEXT(pns, link);
	if (trans->current_ns == NULL) {
		trans->current_ns = ISC_LIST_HEAD(trans->nslist);
		dns_fixedname_invalidate(&trans->fixedname);
		trans->qname = NULL;
		result = set_nextqname(trans);
		if (result == ISC_R_SUCCESS)
			 result = probe_name(trans, dns_rdatatype_a);
	} else {
		result = fetch_nsaddress(trans);
		if (result != ISC_R_SUCCESS)
			goto next_ns; /* XXX: this is unlikely to succeed */
	}

	if (result != ISC_R_SUCCESS)
		reset_probe(trans);
}
예제 #4
0
int
main(int argc, char *argv[]) {
	dns_client_t *client = NULL;
	isc_result_t result;
	dns_fixedname_t qfn;
	dns_name_t *query_name, *response_name;
	dns_rdataset_t *rdataset;
	dns_namelist_t namelist;
	unsigned int resopt, clopt;
	isc_appctx_t *actx = NULL;
	isc_taskmgr_t *taskmgr = NULL;
	isc_socketmgr_t *socketmgr = NULL;
	isc_timermgr_t *timermgr = NULL;
	dns_master_style_t *style = NULL;
#ifndef WIN32
	struct sigaction sa;
#endif

	progname = argv[0];
	preparse_args(argc, argv);

	argc--;
	argv++;

	isc_lib_register();
	result = dns_lib_init();
	if (result != ISC_R_SUCCESS)
		fatal("dns_lib_init failed: %d", result);

	result = isc_mem_create(0, 0, &mctx);
	if (result != ISC_R_SUCCESS)
		fatal("failed to create mctx");

	CHECK(isc_appctx_create(mctx, &actx));
	CHECK(isc_taskmgr_createinctx(mctx, actx, 1, 0, &taskmgr));
	CHECK(isc_socketmgr_createinctx(mctx, actx, &socketmgr));
	CHECK(isc_timermgr_createinctx(mctx, actx, &timermgr));

	parse_args(argc, argv);

	CHECK(setup_style(&style));

	setup_logging(stderr);

	CHECK(isc_app_ctxstart(actx));

#ifndef WIN32
	/* Unblock SIGINT if it's been blocked by isc_app_ctxstart() */
	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = SIG_DFL;
	if (sigfillset(&sa.sa_mask) != 0 || sigaction(SIGINT, &sa, NULL) < 0)
		fatal("Couldn't set up signal handler");
#endif

	/* Create client */
	clopt = DNS_CLIENTCREATEOPT_USECACHE;
	result = dns_client_createx2(mctx, actx, taskmgr, socketmgr, timermgr,
				     clopt, &client, srcaddr4, srcaddr6);
	if (result != ISC_R_SUCCESS) {
		delv_log(ISC_LOG_ERROR, "dns_client_create: %s",
			  isc_result_totext(result));
		goto cleanup;
	}

	/* Set the nameserver */
	if (server != NULL)
		addserver(client);
	else
		findserver(client);

	CHECK(setup_dnsseckeys(client));

	/* Construct QNAME */
	CHECK(convert_name(&qfn, &query_name, qname));

	/* Set up resolution options */
	resopt = DNS_CLIENTRESOPT_ALLOWRUN | DNS_CLIENTRESOPT_NOCDFLAG;
	if (no_sigs)
		resopt |= DNS_CLIENTRESOPT_NODNSSEC;
	if (!root_validation && !dlv_validation)
		resopt |= DNS_CLIENTRESOPT_NOVALIDATE;
	if (cdflag)
		resopt &= ~DNS_CLIENTRESOPT_NOCDFLAG;

	/* Perform resolution */
	ISC_LIST_INIT(namelist);
	result = dns_client_resolve(client, query_name, dns_rdataclass_in,
				    qtype, resopt, &namelist);
	if (result != ISC_R_SUCCESS)
		delv_log(ISC_LOG_ERROR, "resolution failed: %s",
			  isc_result_totext(result));

	for (response_name = ISC_LIST_HEAD(namelist);
	     response_name != NULL;
	     response_name = ISC_LIST_NEXT(response_name, link)) {
		for (rdataset = ISC_LIST_HEAD(response_name->list);
		     rdataset != NULL;
		     rdataset = ISC_LIST_NEXT(rdataset, link)) {
			result = printdata(rdataset, response_name, style);
			if (result != ISC_R_SUCCESS)
				delv_log(ISC_LOG_ERROR, "print data failed");
		}
	}

	dns_client_freeresanswer(client, &namelist);

cleanup:
	if (dlv_anchor != NULL)
		isc_mem_free(mctx, dlv_anchor);
	if (trust_anchor != NULL)
		isc_mem_free(mctx, trust_anchor);
	if (anchorfile != NULL)
		isc_mem_free(mctx, anchorfile);
	if (qname != NULL)
		isc_mem_free(mctx, qname);
	if (style != NULL)
		dns_master_styledestroy(&style, mctx);
	if (client != NULL)
		dns_client_destroy(&client);
	if (taskmgr != NULL)
		isc_taskmgr_destroy(&taskmgr);
	if (timermgr != NULL)
		isc_timermgr_destroy(&timermgr);
	if (socketmgr != NULL)
		isc_socketmgr_destroy(&socketmgr);
	if (actx != NULL)
		isc_appctx_destroy(&actx);
	if (lctx != NULL)
		isc_log_destroy(&lctx);
	isc_mem_detach(&mctx);

	dns_lib_shutdown();

	return (0);
}