⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 domain.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 3 页
字号:

	while(rrlp != NULL){

		*rrpp = copy_rr(rrlp);

		rrpp = &(*rrpp)->next;

		rrlp = rrlp->next;

	}

	*rrpp = NULL;

	return result_rrlp;

}



/* Free (list of) resource records */

void free_rr(rrlp)

register struct rr *rrlp;

{

	register struct rr *rrp;



	while((rrp = rrlp) != NULL){

		rrlp = rrlp->next;



		SysLfree(rrp->comment);

		SysLfree(rrp->name);

		if(rrp->rdlength > 0){

			switch(rrp->type){

			case TYPE_A:

				break;	/* Nothing allocated in rdata section */

			case TYPE_CNAME:

			case TYPE_MB:

			case TYPE_MG:

			case TYPE_MR:

			case TYPE_NS:

			case TYPE_PTR:

			case TYPE_TXT:

				SysLfree(rrp->rdata.name);

				break;

			case TYPE_HINFO:

				SysLfree(rrp->rdata.hinfo.cpu);

				SysLfree(rrp->rdata.hinfo.os);

				break;

			case TYPE_MX:

				SysLfree(rrp->rdata.mx.exch);

				break;

			case TYPE_SOA:

				SysLfree(rrp->rdata.soa.mname);

				SysLfree(rrp->rdata.soa.rname);

				break;

			}

		}

		SysLfree(rrp);

	}

}



static struct rr *make_rr(int source, char *dname, u_int16 dclass, 

							u_int16 dtype, int32 ttl, u_int16 rdl, void *data)

{

	register struct rr *newrr;



	newrr = (struct rr *)SysLcalloc(sizeof(struct rr));

	newrr->source = source;

	newrr->name = strdup(dname);

	newrr->class = dclass;

	newrr->type = dtype;

	newrr->ttl = ttl;

	if((newrr->rdlength = rdl) == 0)

		return newrr;



	switch(dtype){

	case TYPE_A:

	  {

		register int32 *ap = (int32 *)data;

		newrr->rdata.addr = *ap;

		break;

	  }

	case TYPE_CNAME:

	case TYPE_MB:

	case TYPE_MG:

	case TYPE_MR:

	case TYPE_NS:

	case TYPE_PTR:

	case TYPE_TXT:

	  {

		newrr->rdata.name = strdup((char *)data);

		break;

	  }

	case TYPE_HINFO:

	  {

		register struct hinfo *hinfop = (struct hinfo *)data;

		newrr->rdata.hinfo.cpu = strdup(hinfop->cpu);

		newrr->rdata.hinfo.os = strdup(hinfop->os);

		break;

	  }

	case TYPE_MX:

	  {

		register struct mx *mxp = (struct mx *)data;

		newrr->rdata.mx.pref = mxp->pref;

		newrr->rdata.mx.exch = strdup(mxp->exch);

		break;

	  }

	case TYPE_SOA:

	  {

		register struct soa *soap = (struct soa *)data;

		newrr->rdata.soa.mname = 	strdup(soap->mname);

		newrr->rdata.soa.rname = 	strdup(soap->rname);

		newrr->rdata.soa.serial = 	soap->serial;

		newrr->rdata.soa.refresh = 	soap->refresh;

		newrr->rdata.soa.retry = 	soap->retry;

		newrr->rdata.soa.expire = 	soap->expire;

		newrr->rdata.soa.minimum = 	soap->minimum;

		break;

	  }

	}

	return newrr;

}





/**

 **	Domain Cache Utilities

 **/



static void

dcache_add(rrlp)

register struct rr *rrlp;

{

	register struct rr *last_rrp;

	struct rr *save_rrp;



	if(rrlp == NULL)

		return;



	save_rrp = rrlp;

	last_rrp = NULL;

	while(rrlp != NULL){

		rrlp->last = last_rrp;

		last_rrp = rrlp;

		rrlp = rrlp->next;

	}

	last_rrp->next = Dcache;

	if(Dcache != NULL)

		Dcache->last = last_rrp;

	Dcache = save_rrp;

}



static void

dcache_drop(rrp)

register struct rr *rrp;

{

	if(rrp->last != NULL)

		rrp->last->next = rrp->next;

	else

		Dcache = rrp->next;

	if(rrp->next != NULL)

		rrp->next->last = rrp->last;

	rrp->last =

	rrp->next = NULL;

}



/* Search cache for resource records, removing them from the cache.

 * Also, timeout cache entries, and trim cache to size.

 * (Calling with NULL is legal -- will timeout & trim only.)

 * Note that an answer from the cache cannot be authoritative, because

 * we cannot guarantee that all the entries remain from a previous request.

 * Returns RR list, or NULL if no record found.

 */

static struct rr *dcache_search(struct rr *rrlp)

{

	register struct rr *rrp, *test_rrp;

	struct rr **rrpp, *result_rrlp;

	//int32 elapsed;                                              /*************已经修改********************/

	int count = 0;



	rrpp = &result_rrlp;

	for(rrp = Dcache; (test_rrp = rrp) != NULL;){

		rrp = rrp->next;

					/* timeout entries */

		if(test_rrp->ttl > 0L)

			test_rrp->ttl = 0L;



		if(compare_rr_list(rrlp,test_rrp) == 0){

			dcache_drop( *rrpp = test_rrp );

			rrpp = &(*rrpp)->next;

		} else if(test_rrp->source == RR_FILE && ++count > Dcache_size){

			dcache_drop(test_rrp);

			free_rr(test_rrp);

		}

	}

	*rrpp = NULL;

	return result_rrlp;

}



/* Move a list of resource records to the cache, removing duplicates. */

static void

dcache_update(rrlp)

register struct rr *rrlp;

{

	if(rrlp == NULL)

		return;



	free_rr(dcache_search(rrlp));	/* remove duplicates, first */

	dcache_add(rrlp);

}





/**

 **	File Utilities

 **	We do not use the real file access , so we empty this function and just return NULL

 **	Lingming 8/19/1999

 **/



static struct rr *get_rr(KFILE *fp, struct rr *lastrrp)

{

	return NULL;

}



/* Print a resource record */

/**	We do not use the real file access , so we empty this function and just return 

 **	Lingming 8/19/1999

 **/

static void

put_rr(KFILE *fp, struct rr *rrp)

{

	return;

}



/* Search local database for resource records.

 * Returns RR list, or NULL if no record found.

 * We do not use the real file access , so we empty this function and just return NULL

 * Lingming 8/19/1999

 */

static struct rr *dfile_search(struct rr *rrlp)

{

	return NULL;

}



/* Process which will add new resource records from the cache

 * to the local file, eliminating duplicates while it goes.

 * We do not use the real file access , so we empty this function and just return 

 * Lingming 8/19/1999

 */

static void

dfile_update(s,unused,p)

int s;

void *unused;

void *p;

{

	return;

}





/**

 **	Domain Server Utilities

 **/



static void

dumpdomain(dhp,rtt)

struct dhdr *dhp;

int32 rtt;

{

	//struct rr *rrp;                                      已经修改

	//char * stuff;                                        已经修改

	

}



static int

dns_makequery(op,srrp,buffer,buflen)

u_int16 op;	/* operation */

struct rr *srrp;/* Search RR */

u_int8 *buffer;	/* Area for query */

u_int16 buflen;	/* Length of same */

{

	u_int8 *cp;

	char *cp1;

	char *dname, *sname;

	u_int16 parameter;

	//u_int16 dlen,len;
	u_int16 len;
	unsigned long dlen;



	cp = buffer;

	/* Use millisecond clock for timestamping */

	cp = (u_int8 *)put16(cp,(u_int16)mtime());

	parameter = (op << 11)

			| 0x0100;	/* Recursion desired */

	cp = (u_int8 *)put16(cp,parameter);

	cp = (u_int8 *)put16(cp,1);

	cp = (u_int8 *)put16(cp,0);

	cp = (u_int8 *)put16(cp,0);

	cp = (u_int8 *)put16(cp,0);



	sname = strdup(srrp->name);

	dname = sname;

	dlen = strlen(dname);

	for(;;){

		/* Look for next dot */

		cp1 = (char*)strchr(dname,(int)'.');

		if(cp1 != NULL)

			len = cp1-dname;	/* More to come */

		else

			len =(unsigned short)dlen;	/* Last component */

		*cp++ =(unsigned char)len;		/* Write length of component */

		if(len == 0)

			break;

		/* Copy component up to (but not including) dot */

		strncpy((char *)cp,dname,len);

		cp += len;

		if(cp1 == NULL){

			*cp++ = 0;	/* Last one; write null and finish */

			break;

		}

		dname += len+1;

		dlen -= len+1;

	}

	SysLfree(sname);

	cp = (u_int8 *)put16(cp,srrp->type);

	cp = (u_int8 *)put16(cp,srrp->class);

	return cp - buffer;

}



/* domain server resolution loop

 * returns: any answers in cache.

 *	(future features)

 *	multiple queries.

 *	inverse queries.

 * return value: 0 if something added to cache, -1 if error

 */

static int dns_query(rrlp)
struct rr *rrlp;
{
	struct dhdr *dhp;
	struct dserver *dp;	/* server list */
	int32 rtt,abserr;
	int tried = 0;		/* server list has been retried (count) */
	u_int8 *buf;
	int n;
	

	if((dp = Dservers) == NULL)

		return -1;



	if ((buf = (u_int8 *)SysLcalloc(512)) == NULL) 

		return -1;

	

	for(;;){

		int len;

		struct sockaddr_in server_in;

		int s;

		int rval;


		n = 0;
		
		dp->queries++;



		//s = socket(AF_INET,SOCK_DGRAM,0);

		server_in.sin_family = AF_INET;

		server_in.sin_port = IPPORT_DOMAIN;

		server_in.sin_addr.s_addr = dp->address;
		//server_in.sin_port = htons(IPPORT_DOMAIN);
		//server_in.sin_addr.s_addr = htonl(dp->address);
	



		memset(buf, 0, 512);

		len = dns_makequery(0, rrlp, buf, 512);



		s = udpOpen();

    

	    udpConnect(s, &server_in, 0);



		//if(sendto(s,buf,len,0,(struct sockaddr *)&server_in,sizeof(server_in)) == -1)

			//perror("domain sendto");



		udpWrite(s, buf, len);

	//	delay(500);
		delay(3000);
		while(1) {
			memset(buf, 0, 512);
			rval = udpRead(s, buf, 512); //maybe read part data
			n++;

			if ((rval > 0) || (n == 100)) break;
			//if(rval > 0) break;

			}

		if(rval > 0) break;

		udpClose(s);

		

		if(rval > 12) break;	//no use 



		//if(errno == EABORT)

			//return -1;		/* Killed by "reset" command */



		/* Timeout; back off this one and try another server */

		dp->timeout <<= 1;

		if((dp = dp->next) == NULL){

			dp = Dservers;

			if(Dserver_retries > 0 && ++tried > Dserver_retries)

				return -1;

		}

	}



	/* got a response */

	dp->responses++;

	dhp = (struct dhdr *) SysLcalloc(sizeof(struct dhdr));

	memset(dhp, 0, sizeof(struct dhdr));

	

	//ntohdomain(dhp,&bp);	/* Convert to local format */



	if (getdnshdr(dhp, buf) < 0) return -1; 

	

	/* Compute and update the round trip time */

	rtt = (int32) ((u_int16)mtime() - dhp->id);

	abserr = rtt > dp->srtt ? rtt - dp->srtt : dp->srtt - rtt;

	dp->srtt = ((AGAIN-1) * dp->srtt + rtt + (AGAIN/2)) >> LAGAIN;

	dp->mdev = ((DGAIN-1) * dp->mdev + abserr + (DGAIN/2)) >> LDGAIN;

	dp->timeout = 4 * dp->mdev + dp->srtt;



	/* move to top of list for next time */

	if(dp->prev != NULL){

		dlist_drop(dp);

		dlist_add(dp);

	}



	if(Dtrace)

		dumpdomain(dhp,rtt);



	/* Add negative reply to answers.  This assumes that there was

	 * only one question, which is true for all questions we send.

	 */

	if(dhp->aa && (dhp->rcode == NAME_ERROR || dhp->ancount == 0)){

		register struct rr *rrp;

		long ttl = 600L; /* Default TTL for negative records */



		/* look for SOA ttl */

		for(rrp = dhp->authority; rrp != NULL; rrp = rrp->next){

			if(rrp->type == TYPE_SOA)

				ttl = rrp->ttl;

		}



		/* make the questions the negative answers */

		for(rrp = dhp->questions; rrp != NULL; rrp = rrp->next)

			rrp->ttl = ttl;

	} else {

		free_rr(dhp->questions);

		dhp->questions = NULL;

	}



	/* post in reverse order to maintain original order */

	dcache_update(dhp->additional);

	dcache_update(dhp->authority);

	dcache_update(dhp->answers);

	dcache_update(dhp->questions);



	Dfile_wait_absolute = mtime()/1000 + Dfile_wait_relative;

	if(Dfile_updater == NULL){

		//Dfile_updater = newproc("domain update",

		//	80,dfile_update,0,NULL,NULL,0);// the origin stk is 512 LM 2000/09/22

	}



	SysLfree(dhp);

	return 0;

}





/**

 **	Resolver Utilities

 **/



/* Return TRUE if string appears to be an IP address in dotted decimal;

 * return FALSE otherwise (i.e., if string is a domain name)

 */

static int isaddr(s)

register char *s;

{

	char c;



	if(s == NULL)

		return TRUE;	/* Can't happen */



	while((c = *s++) != '\0'){

		if(c != '[' && c != ']' && !isdigit(c) && c != '.')

			return FALSE;

	}

	return TRUE;

}



/* Return "normalized" domain name, with default suffix and trailing '.'

 */

static char *

checksuffix(dname)

char *dname;

{

	char *sname, *tname;



	sname = strdup(dname);

	if (strchr(sname,(int)'.') == NULL && Dsuffix != NULL){

		/* Append default suffix */

		tname = (char *)SysLcalloc(strlen(sname)+strlen(Dsuffix)+2);

		sprintf(tname,"%s.%s",sname,Dsuffix);

		SysLfree(sname);

		sname = tname;

	}

	if(sname[strlen(sname)-1] != '.'){

		/* Append trailing dot */

		tname = (char *)SysLcalloc(strlen(sname)+2);

		sprintf(tname,"%s.",sname);

		SysLfree(sname);

		sname = tname;

	}

	return sname;

}



/* Search for resource records.

 * Returns RR list, or NULL if no record found.

 */

 

static struct rr *resolver(struct rr *rrlp)

{

	register struct rr *result_rrlp;



	if((result_rrlp = dcache_search(rrlp)) == NULL){

		result_rrlp = dfile_search(rrlp);

	}

	if(result_rrlp == NULL || check_ttl(result_rrlp) != 0){

		dcache_add(result_rrlp); 	/* save any expired RRs */

		if(dns_query(rrlp) == -1)

			return NULL;

		result_rrlp = dcache_search(rrlp);

	}

	dcache_add(copy_rr_list(result_rrlp));

	return result_rrlp;

}



/* general entry point for address -> domain name resolution.

 * Returns RR list, or NULL if no record found.

 */

struct rr *inverse_a(int32 ip_address)

{

	struct rr *prrp;

	struct rr *result_rrlp;

	char pname[30];



	if(ip_address == 0L)

		return NULL;



	sprintf( pname, "%u.%u.%u.%u.IN-ADDR.ARPA.",

			lobyte(loword(ip_address)),

			hibyte(loword(ip_address)),

			lobyte(hiword(ip_address)),

			hibyte(hiword(ip_address)) );



	prrp = make_rr(RR_QUERY,pname,CLASS_IN,TYPE_PTR,0,0,NULL);



	prrp->next = 		/* make list to speed search */

		make_rr(RR_INQUERY,NULL,CLASS_IN,TYPE_A,0,4,&ip_address);



	result_rrlp = resolver(prrp);



	free_rr(prrp);

	return result_rrlp;

}



/* general entry point for domain name -> resource resolution.

 * Returns RR list, or NULL if no record found.

 */

struct rr *resolve_rr(char *dname, u_int16 dtype)

{

	struct rr *qrrp;

	struct rr *result_rrlp;

	char *sname;

	int looping = MAXCNAME;



	if(dname == NULL)

		return NULL;



	sname = checksuffix(dname);

⌨️ 快捷键说明

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