dighost.c

来自「非常好的dns解析软件」· C语言 代码 · 共 2,368 行 · 第 1/5 页

C
2,368
字号
			r.base[r.length] = '\0';			strncpy(current_lookup->textname, (char*)r.base,				MXNAME);			isc_buffer_free(&b);			nameFromString(current_lookup->textnamesigchase,				       &chase_name);			dns_name_init(&chase_authority_name, NULL);		}	novalidation:#endif		setup_lookup(current_lookup);		do_lookup(current_lookup);	} else {		check_if_done();	}}/*% * If we can, clear the current lookup and start the next one running. * This calls try_clear_lookup, so may invalidate the lookup pointer. */static voidcheck_next_lookup(dig_lookup_t *lookup) {	INSIST(!free_now);	debug("check_next_lookup(%p)", lookup);	if (ISC_LIST_HEAD(lookup->q) != NULL) {		debug("still have a worker");		return;	}	if (try_clear_lookup(lookup)) {		current_lookup = NULL;		start_lookup();	}}/*% * Create and queue a new lookup as a followup to the current lookup, * based on the supplied message and section.  This is used in trace and * name server search modes to start a new lookup using servers from * NS records in a reply. Returns the number of followup lookups made. */static intfollowup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section){	dig_lookup_t *lookup = NULL;	dig_server_t *srv = NULL;	dns_rdataset_t *rdataset = NULL;	dns_rdata_t rdata = DNS_RDATA_INIT;	dns_name_t *name = NULL;	isc_result_t result;	isc_boolean_t success = ISC_FALSE;	int numLookups = 0;	dns_name_t *domain;	isc_boolean_t horizontal = ISC_FALSE, bad = ISC_FALSE;	INSIST(!free_now);	debug("following up %s", query->lookup->textname);		for (result = dns_message_firstname(msg, section);	     result == ISC_R_SUCCESS;	     result = dns_message_nextname(msg, section)) {		name = NULL;		dns_message_currentname(msg, section, &name);		if (section == DNS_SECTION_AUTHORITY) {			rdataset = NULL;			result = dns_message_findtype(name, dns_rdatatype_soa,						      0, &rdataset);			if (result == ISC_R_SUCCESS)				return (0);		}		rdataset = NULL;		result = dns_message_findtype(name, dns_rdatatype_ns, 0,					      &rdataset);		if (result != ISC_R_SUCCESS)			continue;		debug("found NS set");		if (query->lookup->trace && !query->lookup->trace_root) {			dns_namereln_t namereln;			unsigned int nlabels;			int order;			domain = dns_fixedname_name(&query->lookup->fdomain);			namereln = dns_name_fullcompare(name, domain,							&order, &nlabels);			if (namereln == dns_namereln_equal) {				if (!horizontal)					printf(";; BAD (HORIZONTAL) REFERRAL\n");				horizontal = ISC_TRUE;			} else if (namereln != dns_namereln_subdomain) {				if (!bad)					printf(";; BAD REFERRAL\n");				bad = ISC_TRUE;				continue;			}		}		for (result = dns_rdataset_first(rdataset);		     result == ISC_R_SUCCESS;		     result = dns_rdataset_next(rdataset)) {			char namestr[DNS_NAME_FORMATSIZE];			dns_rdata_ns_t ns;			if (query->lookup->trace_root &&			    query->lookup->nsfound >= MXSERV)				break;			dns_rdataset_current(rdataset, &rdata);			query->lookup->nsfound++;			(void)dns_rdata_tostruct(&rdata, &ns, NULL);			dns_name_format(&ns.name, namestr, sizeof(namestr));			dns_rdata_freestruct(&ns);			/* Initialize lookup if we've not yet */			debug("found NS %d %s", numLookups, namestr);			numLookups++;			if (!success) {				success = ISC_TRUE;				lookup_counter++;				lookup = requeue_lookup(query->lookup,							ISC_FALSE);				cancel_lookup(query->lookup);				lookup->doing_xfr = ISC_FALSE;				if (!lookup->trace_root &&				    section == DNS_SECTION_ANSWER)					lookup->trace = ISC_FALSE;				else					lookup->trace = query->lookup->trace;				lookup->ns_search_only =					query->lookup->ns_search_only;				lookup->trace_root = ISC_FALSE;				if (lookup->ns_search_only)					lookup->recurse = ISC_FALSE;				dns_fixedname_init(&lookup->fdomain);				domain = dns_fixedname_name(&lookup->fdomain);				dns_name_copy(name, domain, NULL);			}			srv = make_server(namestr, namestr);			debug("adding server %s", srv->servername);			ISC_LIST_APPEND(lookup->my_server_list, srv, link);			dns_rdata_reset(&rdata);		}	}	if (lookup == NULL &&	    section == DNS_SECTION_ANSWER &&	    (query->lookup->trace || query->lookup->ns_search_only))		return (followup_lookup(msg, query, DNS_SECTION_AUTHORITY));	/*	 * Randomize the order the nameserver will be tried.	 */	if (numLookups > 1) {		isc_uint32_t i, j;		dig_serverlist_t my_server_list;		ISC_LIST_INIT(my_server_list);		for (i = numLookups; i > 0; i--) {			isc_random_get(&j);			j %= i;			srv = ISC_LIST_HEAD(lookup->my_server_list);			while (j-- > 0)				srv = ISC_LIST_NEXT(srv, link);			ISC_LIST_DEQUEUE(lookup->my_server_list, srv, link);			ISC_LIST_APPEND(my_server_list, srv, link);		}		ISC_LIST_APPENDLIST(lookup->my_server_list,				    my_server_list, link);	}	return (numLookups);}/*% * Create and queue a new lookup using the next origin from the search * list, read in setup_system(). * * Return ISC_TRUE iff there was another searchlist entry. */static isc_boolean_tnext_origin(dns_message_t *msg, dig_query_t *query) {	dig_lookup_t *lookup;	dig_searchlist_t *search;	UNUSED(msg);	INSIST(!free_now);	debug("next_origin()");	debug("following up %s", query->lookup->textname);	if (!usesearch)		/*		 * We're not using a search list, so don't even think		 * about finding the next entry.		 */		return (ISC_FALSE);	if (query->lookup->origin == NULL && !query->lookup->need_search)		/*		 * Then we just did rootorg; there's nothing left.		 */		return (ISC_FALSE);	if (query->lookup->origin == NULL && query->lookup->need_search) {		lookup = requeue_lookup(query->lookup, ISC_TRUE);		lookup->origin = ISC_LIST_HEAD(search_list);		lookup->need_search = ISC_FALSE;	} else {		search = ISC_LIST_NEXT(query->lookup->origin, link);		if (search == NULL && query->lookup->done_as_is)			return (ISC_FALSE);		lookup = requeue_lookup(query->lookup, ISC_TRUE);		lookup->origin = search;	}	cancel_lookup(query->lookup);	return (ISC_TRUE);}/*% * Insert an SOA record into the sendmessage in a lookup.  Used for * creating IXFR queries. */static voidinsert_soa(dig_lookup_t *lookup) {	isc_result_t result;	dns_rdata_soa_t soa;	dns_rdata_t *rdata = NULL;	dns_rdatalist_t *rdatalist = NULL;	dns_rdataset_t *rdataset = NULL;	dns_name_t *soaname = NULL;	debug("insert_soa()");	soa.mctx = mctx;	soa.serial = lookup->ixfr_serial;	soa.refresh = 0;	soa.retry = 0;	soa.expire = 0;	soa.minimum = 0;	soa.common.rdclass = lookup->rdclass;	soa.common.rdtype = dns_rdatatype_soa;	dns_name_init(&soa.origin, NULL);	dns_name_init(&soa.contact, NULL);	dns_name_clone(dns_rootname, &soa.origin);	dns_name_clone(dns_rootname, &soa.contact);	isc_buffer_init(&lookup->rdatabuf, lookup->rdatastore,			sizeof(lookup->rdatastore));	result = dns_message_gettemprdata(lookup->sendmsg, &rdata);	check_result(result, "dns_message_gettemprdata");	result = dns_rdata_fromstruct(rdata, lookup->rdclass,				      dns_rdatatype_soa, &soa,				      &lookup->rdatabuf);	check_result(result, "isc_rdata_fromstruct");	result = dns_message_gettemprdatalist(lookup->sendmsg, &rdatalist);	check_result(result, "dns_message_gettemprdatalist");	result = dns_message_gettemprdataset(lookup->sendmsg, &rdataset);	check_result(result, "dns_message_gettemprdataset");	dns_rdatalist_init(rdatalist);	rdatalist->type = dns_rdatatype_soa;	rdatalist->rdclass = lookup->rdclass;	rdatalist->covers = 0;	rdatalist->ttl = 0;	ISC_LIST_INIT(rdatalist->rdata);	ISC_LIST_APPEND(rdatalist->rdata, rdata, link);	dns_rdataset_init(rdataset);	dns_rdatalist_tordataset(rdatalist, rdataset);	result = dns_message_gettempname(lookup->sendmsg, &soaname);	check_result(result, "dns_message_gettempname");	dns_name_init(soaname, NULL);	dns_name_clone(lookup->name, soaname);	ISC_LIST_INIT(soaname->list);	ISC_LIST_APPEND(soaname->list, rdataset, link);	dns_message_addname(lookup->sendmsg, soaname, DNS_SECTION_AUTHORITY);}/*% * Setup the supplied lookup structure, making it ready to start sending * queries to servers.  Create and initialize the message to be sent as * well as the query structures and buffer space for the replies.  If the * server list is empty, clone it from the system default list. */voidsetup_lookup(dig_lookup_t *lookup) {	isc_result_t result;	isc_uint32_t id;	int len;	dig_server_t *serv;	dig_query_t *query;	isc_buffer_t b;	dns_compress_t cctx;	char store[MXNAME];#ifdef WITH_IDN	idn_result_t mr;	char utf8_textname[MXNAME], utf8_origin[MXNAME], idn_textname[MXNAME];#endif#ifdef WITH_IDN	result = dns_name_settotextfilter(output_filter);	check_result(result, "dns_name_settotextfilter");#endif	REQUIRE(lookup != NULL);	INSIST(!free_now);	debug("setup_lookup(%p)", lookup);	result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER,				    &lookup->sendmsg);	check_result(result, "dns_message_create");	if (lookup->new_search) {		debug("resetting lookup counter.");		lookup_counter = 0;	}	if (ISC_LIST_EMPTY(lookup->my_server_list)) {		debug("cloning server list");		clone_server_list(server_list, &lookup->my_server_list);	}	result = dns_message_gettempname(lookup->sendmsg, &lookup->name);	check_result(result, "dns_message_gettempname");	dns_name_init(lookup->name, NULL);	isc_buffer_init(&lookup->namebuf, lookup->namespace,			sizeof(lookup->namespace));	isc_buffer_init(&lookup->onamebuf, lookup->onamespace,			sizeof(lookup->onamespace));#ifdef WITH_IDN	/*	 * We cannot convert `textname' and `origin' separately.	 * `textname' doesn't contain TLD, but local mapping needs	 * TLD.	 */	mr = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP, lookup->textname,			    utf8_textname, sizeof(utf8_textname));	idn_check_result(mr, "convert textname to UTF-8");#endif	/*	 * If the name has too many dots, force the origin to be NULL	 * (which produces an absolute lookup).  Otherwise, take the origin	 * we have if there's one in the struct already.  If it's NULL,	 * take the first entry in the searchlist iff either usesearch	 * is TRUE or we got a domain line in the resolv.conf file.	 */	if (lookup->new_search) {#ifdef WITH_IDN		if ((count_dots(utf8_textname) >= ndots) || !usesearch) {			lookup->origin = NULL; /* Force abs lookup */			lookup->done_as_is = ISC_TRUE;			lookup->need_search = usesearch;		} else if (lookup->origin == NULL && usesearch) {			lookup->origin = ISC_LIST_HEAD(search_list);			lookup->need_search = ISC_FALSE;		}#else		if ((count_dots(lookup->textname) >= ndots) || !usesearch) {			lookup->origin = NULL; /* Force abs lookup */			lookup->done_as_is = ISC_TRUE;			lookup->need_search = usesearch;		} else if (lookup->origin == NULL && usesearch) {			lookup->origin = ISC_LIST_HEAD(search_list);			lookup->need_search = ISC_FALSE;		}#endif	}#ifdef WITH_IDN	if (lookup->origin != NULL) {		mr = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP,				    lookup->origin->origin, utf8_origin,				    sizeof(utf8_origin));		idn_check_result(mr, "convert origin to UTF-8");		mr = append_textname(utf8_textname, utf8_origin,				     sizeof(utf8_textname));		idn_check_result(mr, "append origin to textname");	}	mr = idn_encodename(IDN_LOCALMAP | IDN_NAMEPREP | IDN_ASCCHECK |			    IDN_IDNCONV | IDN_LENCHECK, utf8_textname,			    idn_textname, sizeof(idn_textname));	idn_check_result(mr, "convert UTF-8 textname to IDN encoding");#else	if (lookup->origin != NULL) {		debug("trying origin %s", lookup->origin->origin);		result = dns_message_gettempname(lookup->sendmsg,						 &lookup->oname);		check_result(result, "dns_message_gettempname");		dns_name_init(lookup->oname, NULL);		/* XXX Helper funct to conv char* to name? */		len = strlen(lookup->origin->origin);		isc_buffer_init(&b, lookup->origin->origin, len);		isc_buffer_add(&b, len);		result = dns_name_fromtext(lookup->oname, &b, dns_rootname,					   ISC_FALSE, &lookup->onamebuf);		if (result != ISC_R_SUCCESS) {			dns_message_puttempname(lookup->sendmsg,						&lookup->name);			dns_message_puttempname(lookup->sendmsg,						&lookup->oname);			fatal("'%s' is not in legal name syntax (%s)",			      lookup->origin->origin,			      isc_result_totext(result));		}		if (lookup->trace && lookup->trace_root) {			dns_name_clone(dns_rootname, lookup->name);		} else {			len = strlen(lookup->textname);			isc_buffer_init(&b, lookup->textname, len);			isc_buffer_add(&b, len);			result = dns_name_fromtext(lookup->name, &b,						   lookup->oname, ISC_FALSE,						   &lookup->namebuf);		}		if (result != ISC_R_SUCCESS) {			dns_message_puttempname(lookup->sendmsg,						&lookup->name);			dns_message_puttempname(lookup->sendmsg,						&lookup->oname);			fatal("'%s' is not in legal name syntax (%s)",			      lookup->textname, isc_result_totext(result));		}		dns_message_puttempname(lookup->sendmsg, &lookup->oname);	} else#endif	{		debug("using root origin");		if (lookup->trace && lookup->trace_root)			dns_name_clone(dns_rootname, lookup->name);		else {#ifdef WITH_IDN			len = strlen(idn_textname);			isc_buffer_init(&b, idn_textname, len);			isc_buffer_add(&b, len);			result = dns_name_fromtext(lookup->name, &b,						   dns_rootname,						   ISC_FALSE,						   &lookup->namebuf);#else			len = strlen(lookup->textname);			isc_buffer_init(&b, lookup->textname, len);			isc_buffer_add(&b, len);			result = dns_name_fromtext(lookup->name, &b,						   dns_rootname,						   ISC_FALSE,						   &lookup->namebuf);#endif		}		if (result != ISC_R_SUCCESS) {			dns_message_puttempname(lookup->sendmsg,						&lookup->name);			isc_buffer_init(&b, store, MXNAME);			fatal("'%s' is not a legal name "			      "(%s)", lookup->textname,			      isc_result_totext(result));		}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?