示例#1
0
int
main(int argc, char *argv[]) {
	int i, ch, error;
	struct addrinfo hints, *res;
	isc_result_t result;
	isc_sockaddr_t sa;
	isc_sockaddrlist_t servers;
	isc_taskmgr_t *taskmgr = NULL;
	isc_socketmgr_t *socketmgr = NULL;
	isc_timermgr_t *timermgr = NULL;

	while ((ch = getopt(argc, argv, "c:dhv")) != -1) {
		switch (ch) {
		case 'c':
			cacheserver = optarg;
			break;
		case 'd':
			debug_mode = ISC_TRUE;
			break;
		case 'h':
			usage();
			break;
		case 'v':
			verbose_level++;
			break;
		default:
			usage();
			break;
		}
	}

	argc -= optind;
	argv += optind;

	/* Common set up */
	isc_lib_register();
	result = dns_lib_init();
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "dns_lib_init failed: %d\n", result);
		exit(1);
	}

	result = ctxs_init(&mctx, &actx, &taskmgr, &socketmgr,
			   &timermgr);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "ctx create failed: %d\n", result);
		exit(1);
	}

	isc_app_ctxstart(actx);

	result = dns_client_createx(mctx, actx, taskmgr, socketmgr,
				    timermgr, 0, &client);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "dns_client_createx failed: %d\n", result);
		exit(1);
	}

	/* Set local cache server */
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_DGRAM;
	error = getaddrinfo(cacheserver, "53", &hints, &res);
	if (error != 0) {
		fprintf(stderr, "failed to convert server name (%s): %s\n",
			cacheserver, gai_strerror(error));
		exit(1);
	}

	if (res->ai_addrlen > sizeof(sa.type)) {
		fprintf(stderr,
			"assumption failure: addrlen is too long: %ld\n",
			(long)res->ai_addrlen);
		exit(1);
	}
	memcpy(&sa.type.sa, res->ai_addr, res->ai_addrlen);
	sa.length = res->ai_addrlen;
	freeaddrinfo(res);
	ISC_LINK_INIT(&sa, link);
	ISC_LIST_INIT(servers);
	ISC_LIST_APPEND(servers, &sa, link);
	result = dns_client_setservers(client, dns_rdataclass_in, NULL,
				       &servers);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "failed to set server: %d\n", result);
		exit(1);
	}

	/* Create the main task */
	probe_task = NULL;
	result = isc_task_create(taskmgr, 0, &probe_task);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "failed to create task: %d\n", result);
		exit(1);
	}

	/* Open input file */
	if (argc == 0)
		fp = stdin;
	else {
		fp = fopen(argv[0], "r");
		if (fp == NULL) {
			fprintf(stderr, "failed to open input file: %s\n",
				argv[0]);
			exit(1);
		}
	}

	/* Set up and start probe */
	for (i = 0; i < MAX_PROBES; i++) {
		probes[i].inuse = ISC_FALSE;
		probes[i].domain = NULL;
		dns_fixedname_init(&probes[i].fixedname);
		probes[i].qname = NULL;
		probes[i].qlabel = qlabels;
		probes[i].qname_found = ISC_FALSE;
		probes[i].resid = NULL;
		ISC_LIST_INIT(probes[i].nslist);
		probes[i].reqid = NULL;

		probes[i].qmessage = NULL;
		result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER,
					    &probes[i].qmessage);
		if (result == ISC_R_SUCCESS) {
			result = dns_message_create(mctx,
						    DNS_MESSAGE_INTENTPARSE,
						    &probes[i].rmessage);
		}
		if (result != ISC_R_SUCCESS) {
			fprintf(stderr, "initialization failure\n");
			exit(1);
		}
	}
	for (i = 0; i < MAX_PROBES; i++) {
		result = probe_domain(&probes[i]);
		if (result == ISC_R_NOMORE)
			break;
		else if (result != ISC_R_SUCCESS) {
			fprintf(stderr, "failed to issue an initial probe\n");
			exit(1);
		}
	}

	/* Start event loop */
	isc_app_ctxrun(actx);

	/* Dump results */
	printf("Per domain results (out of %lu domains):\n",
	       number_of_domains);
	printf("  valid: %lu\n"
	       "  ignore: %lu\n"
	       "  nxdomain: %lu\n"
	       "  othererr: %lu\n"
	       "  multiplesoa: %lu\n"
	       "  multiplecname: %lu\n"
	       "  brokenanswer: %lu\n"
	       "  lame: %lu\n"
	       "  unknown: %lu\n"
	       "  multiple errors: %lu\n",
	       domain_stat.valid, domain_stat.ignore, domain_stat.nxdomain,
	       domain_stat.othererr, domain_stat.multiplesoa,
	       domain_stat.multiplecname, domain_stat.brokenanswer,
	       domain_stat.lame, domain_stat.unknown, multiple_error_domains);
	printf("Per server results (out of %lu servers):\n",
	       number_of_servers);
	printf("  valid: %lu\n"
	       "  ignore: %lu\n"
	       "  nxdomain: %lu\n"
	       "  othererr: %lu\n"
	       "  multiplesoa: %lu\n"
	       "  multiplecname: %lu\n"
	       "  brokenanswer: %lu\n"
	       "  lame: %lu\n"
	       "  unknown: %lu\n",
	       server_stat.valid, server_stat.ignore, server_stat.nxdomain,
	       server_stat.othererr, server_stat.multiplesoa,
	       server_stat.multiplecname, server_stat.brokenanswer,
	       server_stat.lame, server_stat.unknown);

	/* Cleanup */
	for (i = 0; i < MAX_PROBES; i++) {
		dns_message_destroy(&probes[i].qmessage);
		dns_message_destroy(&probes[i].rmessage);
	}
	isc_task_detach(&probe_task);
	dns_client_destroy(&client);
	dns_lib_shutdown();
	isc_app_ctxfinish(actx);
	ctxs_destroy(&mctx, &actx, &taskmgr, &socketmgr, &timermgr);

	exit(0);
}
示例#2
0
int
main(int argc, char *argv[]) {
	int ch;
	struct addrinfo hints, *res;
	int gai_error;
	dns_client_t *client = NULL;
	char *zonenamestr = NULL;
	char *keyfilename = NULL;
	char *prereqstr = NULL;
	isc_sockaddrlist_t auth_servers;
	char *auth_server = NULL;
	char *recursive_server = NULL;
	isc_sockaddr_t sa_auth, sa_recursive;
	isc_sockaddrlist_t rec_servers;
	isc_result_t result;
	isc_boolean_t isdelete;
	isc_buffer_t b, *buf;
	dns_fixedname_t zname0, pname0, uname0;
	size_t namelen;
	dns_name_t *zname = NULL, *uname, *pname;
	dns_rdataset_t *rdataset;
	dns_rdatalist_t *rdatalist;
	dns_rdata_t *rdata;
	dns_namelist_t updatelist, prereqlist, *prereqlistp = NULL;
	isc_mem_t *umctx = NULL;

	while ((ch = getopt(argc, argv, "a:k:p:r:z:")) != -1) {
		switch (ch) {
		case 'k':
			keyfilename = optarg;
			break;
		case 'a':
			auth_server = optarg;
			break;
		case 'p':
			prereqstr = optarg;
			break;
		case 'r':
			recursive_server = optarg;
			break;
		case 'z':
			zonenamestr = optarg;
			break;
		default:
			usage();
		}
	}

	argc -= optind;
	argv += optind;
	if (argc < 2)
		usage();

	/* command line argument validation */
	if (strcmp(argv[0], "delete") == 0)
		isdelete = ISC_TRUE;
	else if (strcmp(argv[0], "add") == 0)
		isdelete = ISC_FALSE;
	else {
		fprintf(stderr, "invalid update command: %s\n", argv[0]);
		exit(1);
	}

	if (auth_server == NULL && recursive_server == NULL) {
		fprintf(stderr, "authoritative or recursive server "
			"must be specified\n");
		usage();
	}

	/* Initialization */
	ISC_LIST_INIT(usedbuffers);
	ISC_LIST_INIT(usedrdatalists);
	ISC_LIST_INIT(prereqlist);
	ISC_LIST_INIT(auth_servers);
	isc_lib_register();
	result = dns_lib_init();
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "dns_lib_init failed: %d\n", result);
		exit(1);
	}
	result = isc_mem_create(0, 0, &umctx);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "failed to crate mctx\n");
		exit(1);
	}

	result = dns_client_create(&client, 0);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "dns_client_create failed: %d\n", result);
		exit(1);
	}

	/* Set the authoritative server */
	if (auth_server != NULL) {
		memset(&hints, 0, sizeof(hints));
		hints.ai_family = AF_UNSPEC;
		hints.ai_socktype = SOCK_DGRAM;
		hints.ai_protocol = IPPROTO_UDP;
		hints.ai_flags = AI_NUMERICHOST;
		gai_error = getaddrinfo(auth_server, "53", &hints, &res);
		if (gai_error != 0) {
			fprintf(stderr, "getaddrinfo failed: %s\n",
				gai_strerror(gai_error));
			exit(1);
		}
		INSIST(res->ai_addrlen <= sizeof(sa_auth.type));
		memmove(&sa_auth.type, res->ai_addr, res->ai_addrlen);
		freeaddrinfo(res);
		sa_auth.length = res->ai_addrlen;
		ISC_LINK_INIT(&sa_auth, link);

		ISC_LIST_APPEND(auth_servers, &sa_auth, link);
	}

	/* Set the recursive server */
	if (recursive_server != NULL) {
		memset(&hints, 0, sizeof(hints));
		hints.ai_family = AF_UNSPEC;
		hints.ai_socktype = SOCK_DGRAM;
		hints.ai_protocol = IPPROTO_UDP;
		hints.ai_flags = AI_NUMERICHOST;
		gai_error = getaddrinfo(recursive_server, "53", &hints, &res);
		if (gai_error != 0) {
			fprintf(stderr, "getaddrinfo failed: %s\n",
				gai_strerror(gai_error));
			exit(1);
		}
		INSIST(res->ai_addrlen <= sizeof(sa_recursive.type));
		memmove(&sa_recursive.type, res->ai_addr, res->ai_addrlen);
		freeaddrinfo(res);
		sa_recursive.length = res->ai_addrlen;
		ISC_LINK_INIT(&sa_recursive, link);
		ISC_LIST_INIT(rec_servers);
		ISC_LIST_APPEND(rec_servers, &sa_recursive, link);
		result = dns_client_setservers(client, dns_rdataclass_in,
					       NULL, &rec_servers);
		if (result != ISC_R_SUCCESS) {
			fprintf(stderr, "set server failed: %d\n", result);
			exit(1);
		}
	}

	/* Construct zone name */
	zname = NULL;
	if (zonenamestr != NULL) {
		namelen = strlen(zonenamestr);
		isc_buffer_init(&b, zonenamestr, namelen);
		isc_buffer_add(&b, namelen);
		dns_fixedname_init(&zname0);
		zname = dns_fixedname_name(&zname0);
		result = dns_name_fromtext(zname, &b, dns_rootname, 0, NULL);
		if (result != ISC_R_SUCCESS)
			fprintf(stderr, "failed to convert zone name: %d\n",
				result);
	}

	/* Construct prerequisite name (if given) */
	if (prereqstr != NULL) {
		dns_fixedname_init(&pname0);
		pname = dns_fixedname_name(&pname0);
		evaluate_prereq(umctx, prereqstr, pname);
		ISC_LIST_APPEND(prereqlist, pname, link);
		prereqlistp = &prereqlist;
	}

	/* Construct update name */
	ISC_LIST_INIT(updatelist);
	dns_fixedname_init(&uname0);
	uname = dns_fixedname_name(&uname0);
	update_addordelete(umctx, argv[1], isdelete, uname);
	ISC_LIST_APPEND(updatelist, uname, link);

	/* Set up TSIG/SIG(0) key (if given) */
	if (keyfilename != NULL)
		setup_tsec(keyfilename, umctx);

	/* Perform update */
	result = dns_client_update(client,
				   default_rdataclass, /* XXX: fixed */
				   zname, prereqlistp, &updatelist,
				   (auth_server == NULL) ? NULL :
				   &auth_servers, tsec, 0);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr,
			"update failed: %s\n", dns_result_totext(result));
	} else
		fprintf(stderr, "update succeeded\n");

	/* Cleanup */
	while ((pname = ISC_LIST_HEAD(prereqlist)) != NULL) {
		while ((rdataset = ISC_LIST_HEAD(pname->list)) != NULL) {
			ISC_LIST_UNLINK(pname->list, rdataset, link);
			dns_rdataset_disassociate(rdataset);
			isc_mem_put(umctx, rdataset, sizeof(*rdataset));
		}
		ISC_LIST_UNLINK(prereqlist, pname, link);
	}
	while ((uname = ISC_LIST_HEAD(updatelist)) != NULL) {
		while ((rdataset = ISC_LIST_HEAD(uname->list)) != NULL) {
			ISC_LIST_UNLINK(uname->list, rdataset, link);
			dns_rdataset_disassociate(rdataset);
			isc_mem_put(umctx, rdataset, sizeof(*rdataset));
		}
		ISC_LIST_UNLINK(updatelist, uname, link);
	}
	while ((rdatalist = ISC_LIST_HEAD(usedrdatalists)) != NULL) {
		while ((rdata = ISC_LIST_HEAD(rdatalist->rdata)) != NULL) {
			ISC_LIST_UNLINK(rdatalist->rdata, rdata, link);
			isc_mem_put(umctx, rdata, sizeof(*rdata));
		}
		ISC_LIST_UNLINK(usedrdatalists, rdatalist, link);
		isc_mem_put(umctx, rdatalist, sizeof(*rdatalist));
	}
	while ((buf = ISC_LIST_HEAD(usedbuffers)) != NULL) {
		ISC_LIST_UNLINK(usedbuffers, buf, link);
		isc_buffer_free(&buf);
	}
	if (tsec != NULL)
		dns_tsec_destroy(&tsec);
	isc_mem_destroy(&umctx);
	dns_client_destroy(&client);
	dns_lib_shutdown();

	return (0);
}
示例#3
0
文件: context.c 项目: JeanCaron/bind9
isc_result_t
irs_context_create(irs_context_t **contextp) {
	isc_result_t result;
	irs_context_t *context;
	isc_appctx_t *actx = NULL;
	isc_mem_t *mctx = NULL;
	isc_taskmgr_t *taskmgr = NULL;
	isc_socketmgr_t *socketmgr = NULL;
	isc_timermgr_t *timermgr = NULL;
	dns_client_t *client = NULL;
	isc_sockaddrlist_t *nameservers;
	irs_dnsconf_dnskeylist_t *trustedkeys;
	irs_dnsconf_dnskey_t *trustedkey;

	isc_lib_register();
	result = dns_lib_init();
	if (result != ISC_R_SUCCESS)
		return (result);

	result = ctxs_init(&mctx, &actx, &taskmgr, &socketmgr, &timermgr);
	if (result != ISC_R_SUCCESS)
		return (result);

	result = isc_app_ctxstart(actx);
	if (result != ISC_R_SUCCESS) {
		ctxs_destroy(&mctx, &actx, &taskmgr, &socketmgr, &timermgr);
		return (result);
	}

	context = isc_mem_get(mctx, sizeof(*context));
	if (context == NULL) {
		ctxs_destroy(&mctx, &actx, &taskmgr, &socketmgr, &timermgr);
		return (ISC_R_NOMEMORY);
	}

	context->mctx = mctx;
	context->actx = actx;
	context->taskmgr = taskmgr;
	context->socketmgr = socketmgr;
	context->timermgr = timermgr;
	context->resconf = NULL;
	context->dnsconf = NULL;
	context->task = NULL;
	result = isc_task_create(taskmgr, 0, &context->task);
	if (result != ISC_R_SUCCESS)
		goto fail;

	/* Create a DNS client object */
	result = dns_client_createx(mctx, actx, taskmgr, socketmgr, timermgr,
				    0, &client);
	if (result != ISC_R_SUCCESS)
		goto fail;
	context->dnsclient = client;

	/* Read resolver configuration file */
	result = irs_resconf_load(mctx, RESOLV_CONF, &context->resconf);
	if (result != ISC_R_SUCCESS)
		goto fail;
	/* Set nameservers */
	nameservers = irs_resconf_getnameservers(context->resconf);
	result = dns_client_setservers(client, dns_rdataclass_in, NULL,
				       nameservers);
	if (result != ISC_R_SUCCESS)
		goto fail;

	/* Read advanced DNS configuration (if any) */
	result = irs_dnsconf_load(mctx, DNS_CONF, &context->dnsconf);
	if (result != ISC_R_SUCCESS)
		goto fail;
	trustedkeys = irs_dnsconf_gettrustedkeys(context->dnsconf);
	for (trustedkey = ISC_LIST_HEAD(*trustedkeys);
	     trustedkey != NULL;
	     trustedkey = ISC_LIST_NEXT(trustedkey, link)) {
		result = dns_client_addtrustedkey(client, dns_rdataclass_in,
						  trustedkey->keyname,
						  trustedkey->keydatabuf);
		if (result != ISC_R_SUCCESS)
			goto fail;
	}

	context->magic = IRS_CONTEXT_MAGIC;
	*contextp = context;

	return (ISC_R_SUCCESS);

  fail:
	if (context->task != NULL)
		isc_task_detach(&context->task);
	if (context->resconf != NULL)
		irs_resconf_destroy(&context->resconf);
	if (context->dnsconf != NULL)
		irs_dnsconf_destroy(&context->dnsconf);
	if (client != NULL)
		dns_client_destroy(&client);
	ctxs_destroy(NULL, &actx, &taskmgr, &socketmgr, &timermgr);
	isc_mem_putanddetach(&mctx, context, sizeof(*context));

	return (result);
}
示例#4
0
int
main(int argc, char *argv[]) {
	int ch;
	isc_textregion_t tr;
	isc_mem_t *mctx = NULL;
	isc_taskmgr_t *taskmgr = NULL;
	isc_socketmgr_t *socketmgr = NULL;
	isc_timermgr_t *timermgr = NULL;
	int nservers = 0;
	const char *serveraddr[MAX_SERVERS];
	isc_sockaddr_t sa[MAX_SERVERS];
	isc_sockaddrlist_t servers;
	dns_rdatatype_t type = dns_rdatatype_a;
	struct in_addr inaddr;
	isc_result_t result;
	int i;

	while ((ch = getopt(argc, argv, "s:t:")) != -1) {
		switch (ch) {
		case 't':
			tr.base = optarg;
			tr.length = strlen(optarg);
			result = dns_rdatatype_fromtext(&type, &tr);
			if (result != ISC_R_SUCCESS) {
				fprintf(stderr,
					"invalid RRtype: %s\n", optarg);
				exit(1);
			}
			break;
		case 's':
			if (nservers == MAX_SERVERS) {
				fprintf(stderr,
					"too many servers (up to %d)\n",
					MAX_SERVERS);
				exit(1);
			}
			serveraddr[nservers++] = (const char *)optarg;
			break;
		default:
			usage();
		}
	}

	argc -= optind;
	argv += optind;
	if (argc < 1)
		usage();

	if (nservers == 0) {
		nservers = 1;
		serveraddr[0] = def_server;
	}

	for (i = 0; i < MAX_QUERIES; i++) {
		query_array[i].id = i;
		query_array[i].inuse = ISC_FALSE;
		query_array[i].type = type;
		dns_fixedname_init(&query_array[i].fixedname);
		query_array[i].qname = NULL;
		ISC_LIST_INIT(query_array[i].answerlist);
		query_array[i].xid = NULL;
	}

	isc_lib_register();
	result = dns_lib_init();
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "dns_lib_init failed: %d\n", result);
		exit(1);
	}

	result = ctxs_init(&mctx, &query_actx, &taskmgr, &socketmgr,
			   &timermgr);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "ctx create failed: %d\n", result);
		exit(1);
	}

	isc_app_ctxstart(query_actx);

	result = dns_client_createx(mctx, query_actx, taskmgr, socketmgr,
				    timermgr, 0, &client);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "dns_client_createx failed: %d\n", result);
		exit(1);
	}

	/* Set nameservers */
	ISC_LIST_INIT(servers);
	for (i = 0; i < nservers; i++) {
		if (inet_pton(AF_INET, serveraddr[i], &inaddr) != 1) {
			fprintf(stderr, "failed to parse IPv4 address %s\n",
				serveraddr[i]);
			exit(1);
		}
		isc_sockaddr_fromin(&sa[i], &inaddr, 53);
		ISC_LIST_APPEND(servers, &sa[i], link);
	}
	result = dns_client_setservers(client, dns_rdataclass_in, NULL,
				       &servers);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "set server failed: %d\n", result);
		exit(1);
	}

	/* Create the main task */
	query_task = NULL;
	result = isc_task_create(taskmgr, 0, &query_task);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "failed to create task: %d\n", result);
		exit(1);
	}

	/* Open input file */
	fp = fopen(argv[0], "r");
	if (fp == NULL) {
		fprintf(stderr, "failed to open input file: %s\n", argv[1]);
		exit(1);
	}

	/* Dispatch initial queries */
	for (i = 0; i < MAX_QUERIES; i++) {
		result = dispatch_query(&query_array[i]);
		if (result == ISC_R_NOMORE)
			break;
	}

	/* Start event loop */
	isc_app_ctxrun(query_actx);

	/* Sanity check */
	for (i = 0; i < MAX_QUERIES; i++)
		INSIST(query_array[i].inuse == ISC_FALSE);

	/* Cleanup */
	isc_task_detach(&query_task);
	dns_client_destroy(&client);
	dns_lib_shutdown();
	isc_app_ctxfinish(query_actx);
	ctxs_destroy(&mctx, &query_actx, &taskmgr, &socketmgr, &timermgr);

	return (0);
}
示例#5
0
static isc_result_t
findserver(dns_client_t *client) {
	isc_result_t result;
	irs_resconf_t *resconf = NULL;
	isc_sockaddrlist_t *nameservers;
	isc_sockaddr_t *sa, *next;
	isc_uint32_t destport;

	result = parse_uint(&destport, port, 0xffff, "port");
	if (result != ISC_R_SUCCESS)
		fatal("Couldn't parse port number");

	result = irs_resconf_load(mctx, "/etc/resolv.conf", &resconf);
	if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) {
		delv_log(ISC_LOG_ERROR, "irs_resconf_load: %s",
			  isc_result_totext(result));
		goto cleanup;
	}

	/* Get nameservers from resolv.conf */
	nameservers = irs_resconf_getnameservers(resconf);
	for (sa = ISC_LIST_HEAD(*nameservers); sa != NULL; sa = next) {
		next = ISC_LIST_NEXT(sa, link);

		/* Set destination port */
		if (sa->type.sa.sa_family == AF_INET && use_ipv4) {
			sa->type.sin.sin_port = htons(destport);
			continue;
		}
		if (sa->type.sa.sa_family == AF_INET6 && use_ipv6) {
			sa->type.sin6.sin6_port = htons(destport);
			continue;
		}

		/* Incompatible protocol family */
		ISC_LIST_UNLINK(*nameservers, sa, link);
		isc_mem_put(mctx, sa, sizeof(*sa));
	}

	/* None found, use localhost */
	if (ISC_LIST_EMPTY(*nameservers)) {
		if (use_ipv4) {
			struct in_addr localhost;
			localhost.s_addr = htonl(INADDR_LOOPBACK);
			sa = isc_mem_get(mctx, sizeof(*sa));
			if (sa == NULL) {
				result = ISC_R_NOMEMORY;
				goto cleanup;
			}
			isc_sockaddr_fromin(sa, &localhost, destport);

			ISC_LINK_INIT(sa, link);
			ISC_LIST_APPEND(*nameservers, sa, link);
		}

		if (use_ipv6) {
			sa = isc_mem_get(mctx, sizeof(*sa));
			if (sa == NULL) {
				result = ISC_R_NOMEMORY;
				goto cleanup;
			}
			isc_sockaddr_fromin6(sa, &in6addr_loopback, destport);

			ISC_LINK_INIT(sa, link);
			ISC_LIST_APPEND(*nameservers, sa, link);
		}
	}

	result = dns_client_setservers(client, dns_rdataclass_in, NULL,
				       nameservers);
	if (result != ISC_R_SUCCESS)
		delv_log(ISC_LOG_ERROR, "dns_client_setservers: %s",
			  isc_result_totext(result));

cleanup:
	if (resconf != NULL)
		irs_resconf_destroy(&resconf);
	return (result);
}
示例#6
0
static isc_result_t
addserver(dns_client_t *client) {
	struct addrinfo hints, *res, *cur;
	int gaierror;
	struct in_addr in4;
	struct in6_addr in6;
	isc_sockaddr_t *sa;
	isc_sockaddrlist_t servers;
	isc_uint32_t destport;
	isc_result_t result;
	dns_name_t *name = NULL;

	result = parse_uint(&destport, port, 0xffff, "port");
	if (result != ISC_R_SUCCESS)
		fatal("Couldn't parse port number");

	ISC_LIST_INIT(servers);

	if (inet_pton(AF_INET, server, &in4) == 1) {
		if (!use_ipv4) {
			fatal("Use of IPv4 disabled by -6");
		}
		sa = isc_mem_get(mctx, sizeof(*sa));
		if (sa == NULL)
			return (ISC_R_NOMEMORY);
		ISC_LINK_INIT(sa, link);
		isc_sockaddr_fromin(sa, &in4, destport);
		ISC_LIST_APPEND(servers, sa, link);
	} else if (inet_pton(AF_INET6, server, &in6) == 1) {
		if (!use_ipv6) {
			fatal("Use of IPv6 disabled by -4");
		}
		sa = isc_mem_get(mctx, sizeof(*sa));
		if (sa == NULL)
			return (ISC_R_NOMEMORY);
		ISC_LINK_INIT(sa, link);
		isc_sockaddr_fromin6(sa, &in6, destport);
		ISC_LIST_APPEND(servers, sa, link);
	} else {
		memset(&hints, 0, sizeof(hints));
		if (!use_ipv6)
			hints.ai_family = AF_INET;
		else if (!use_ipv4)
			hints.ai_family = AF_INET6;
		else
			hints.ai_family = AF_UNSPEC;
		hints.ai_socktype = SOCK_DGRAM;
		hints.ai_protocol = IPPROTO_UDP;
		gaierror = getaddrinfo(server, port, &hints, &res);
		if (gaierror != 0) {
			delv_log(ISC_LOG_ERROR,
				  "getaddrinfo failed: %s",
				  gai_strerror(gaierror));
			return (ISC_R_FAILURE);
		}

		result = ISC_R_SUCCESS;
		for (cur = res; cur != NULL; cur = cur->ai_next) {
			if (cur->ai_family != AF_INET &&
			    cur->ai_family != AF_INET6)
				continue;
			sa = isc_mem_get(mctx, sizeof(*sa));
			if (sa == NULL) {
				result = ISC_R_NOMEMORY;
				break;
			}
			memset(sa, 0, sizeof(*sa));
			ISC_LINK_INIT(sa, link);
			memmove(&sa->type, cur->ai_addr, cur->ai_addrlen);
			sa->length = (unsigned int)cur->ai_addrlen;
			ISC_LIST_APPEND(servers, sa, link);
		}
		freeaddrinfo(res);
		CHECK(result);
	}


	CHECK(dns_client_setservers(client, dns_rdataclass_in, name, &servers));

 cleanup:
	while (!ISC_LIST_EMPTY(servers)) {
		sa = ISC_LIST_HEAD(servers);
		ISC_LIST_UNLINK(servers, sa, link);
		isc_mem_put(mctx, sa, sizeof(*sa));
	}

	if (result != ISC_R_SUCCESS)
		delv_log(ISC_LOG_ERROR, "addserver: %s",
			  isc_result_totext(result));

	return (result);
}