ns_resp.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 2,318 行 · 第 1/4 页

C
2,318
字号
		hp->arcount = htons((u_short)1);		tmplen -= authen_rrlen;		if((authenlen = res_mks_krbcred(ONE, "", "",					&qp->q_ad,					tmpmsg, tmpmsg + tmplen,					BUFSIZ - tmplen,					dnameptr,					type_authenrr, class_authenrr))		    < RET_OK)			goto servfail;		tmplen += authenlen;	}	(void) send_msg(tmpmsg, tmplen, qp);	hp->arcount = 0;	qremove(qp);	return;#else AUTHENreturn_msg:#ifdef STATS	stats[S_RESPOK].cnt++;#endif	/* The "standard" return code */	hp->qr = 1;	hp->id = qp->q_id;	hp->rd = 1;	hp->ra = 1;	(void) send_msg(msg, msglen, qp);	qremove(qp);	return;return_newmsg:#ifdef STATS	stats[S_RESPOK].cnt++;#endif	if (addcount) {		n = doaddinfo(hp, cp, buflen);		cp += n;		buflen -= n;	}	hp->id = qp->q_id;	hp->rd = 1;	hp->ra = 1;	hp->qr = 1;	(void) send_msg(newmsg, cp - newmsg, qp);	qremove(qp);	return;servfail:#ifdef STATS	stats[S_RESPFAIL].cnt++;#endif	hp = (HEADER *)(cname ? qp->q_cmsg : qp->q_msg);	hp->rcode = SERVFAIL;	hp->id = qp->q_id;	hp->rd = 1;	hp->ra = 1;	hp->qr = 1;	(void) send_msg((char *)hp, (cname ? qp->q_cmsglen : qp->q_msglen), qp);	qremove(qp);	return;#endif AUTHEN}/* * Decode the resource record 'rrp' and update the database. * If savens is true, record pointer for forwarding queries a second time. */#ifdef AUTHENdoupdate(msg, msglen, rrp, zone, savens, authen_type, authen_ver, flags)	char *msg ;	u_char *rrp;	struct databuf **savens;	int  msglen, zone, flags;	int authen_type;	int authen_ver;{#else AUTHENdoupdate(msg, msglen, rrp, zone, savens, flags)	char *msg ;	u_char *rrp;	struct databuf **savens;	int  msglen, zone, flags;{#endif AUTHEN	register u_char *cp;	register int n;	int class, type, dlen, n1;	u_long ttl;	struct databuf *dp;	char dname[MAXDNAME];	u_char *cp1;	u_char data[BUFSIZ];	register HEADER *hp = (HEADER *) msg;#ifdef DEBUG	if (debug > 2)		fprintf(ddt,"doupdate(zone %d, savens %x, flags %x)\n",			zone, savens, flags);#endif	cp = rrp;	if ((n = dn_expand(msg, msg + msglen, cp, dname, sizeof(dname))) < 0) {		hp->rcode = FORMERR;		return (-1);	}	cp += n;	GETSHORT(type, cp);	GETSHORT(class, cp);	GETLONG(ttl, cp);/*	KLUDGE ALERT This kludge sponsored in part by John Williams and	brought to you by Bill Brown and a tight field test schedule.	If this named is running as a slave and the data being placed	in the database is auth or password info, then set the ttl to two	minutes.  This will allow a slave to pick up new password info 	from the database at two minute intervals.*/	{ /* begin KLUDGE */		char *kld_head;		if((forward_only && fwdtab)) {			/* We are a slave */			kld_head = dname;			res_dotname_rmhead(&kld_head);			kld_head = res_dotname_head(kld_head);			if( !strcmp(kld_head, "auth") ||					!strcmp(kld_head, "passwd"))				/* this is auth or passwd info */				ttl = 120;				}	} /* end KLUDGE */	GETSHORT(dlen, cp);#ifdef DEBUG	if (debug > 2)		fprintf(ddt,"doupdate: dname %s type %d class %d ttl %d\n",			dname, type, class, ttl);#endif	/*	 * Convert the resource record data into the internal	 * database format.	 */	switch (type) {	case T_A:	case T_WKS:	case T_HINFO:	case T_UINFO:	case T_UID:	case T_GID:	case T_TXT:#ifdef ALLOW_T_UNSPEC	case T_UNSPEC:#endif ALLOW_T_UNSPEC		cp1 = cp;		n = dlen;		cp += n;		break;	case T_CNAME:	case T_MB:	case T_MG:	case T_MR:	case T_NS:	case T_PTR:		if ((n = dn_expand(msg, msg + msglen, cp, data,		   sizeof(data))) < 0) {			hp->rcode = FORMERR;			return (-1);		}		cp += n;		cp1 = data;		n = strlen(data) + 1;		break;	case T_MINFO:	case T_SOA:		if ((n = dn_expand(msg, msg + msglen, cp, data,		    sizeof(data))) < 0) {			hp->rcode = FORMERR;			return (-1);		}		cp += n;		cp1 = data + (n = strlen(data) + 1);		n1 = sizeof(data) - n;		if (type == T_SOA)			n1 -= 5 * sizeof(u_long);		if ((n = dn_expand(msg, msg + msglen, cp, cp1, n1)) < 0) {			hp->rcode = FORMERR;			return (-1);		}		cp += n;		cp1 += strlen(cp1) + 1;		if (type == T_SOA) {			bcopy(cp, cp1, n = 5 * sizeof(u_long));			cp += n;			cp1 += n;		}		n = cp1 - data;		cp1 = data;		break;	case T_MX:		/* grab preference */		bcopy(cp,data,sizeof(u_short));		cp1 = data + sizeof(u_short);		cp += sizeof(u_short);		/* get name */		if ((n = dn_expand(msg, msg + msglen, cp, cp1,		    sizeof(data)-sizeof(u_short))) < 0)			return(-1);		cp += n;		/* compute end of data */		cp1 += strlen(cp1) + 1;		/* compute size of data */		n = cp1 - data;		cp1 = data;		break;	default:#ifdef DEBUG		if (debug >= 3)			fprintf(ddt,"unknown type %d\n", type);#endif		return ((cp - rrp) + dlen);	}	if (n > MAXDATA) {#ifdef DEBUG		if (debug)		    fprintf(ddt,			"update type %d: %d bytes is too much data\n",			type, n);#endif		hp->rcode = NOCHANGE;	/* XXX - FORMERR ??? */		return(-1);	}#ifdef ALLOW_UPDATES	/*	 * If this is a dynamic update request, process it specially; else,	 * execute normal update code.	 */	switch(opcode) {	/* For UPDATEM and UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA */	case UPDATEM:	case UPDATEMA:	/*	 * The named code for UPDATED and UPDATEDA is the same except that for	 * UPDATEDA we we ignore any data that was passed: we just delete all	 * RRs whose name, type, and class matches	 */	case UPDATED:	case UPDATEDA:		if (type == T_SOA) {	/* Not allowed */#ifdef DEBUG			if (debug)			   fprintf(ddt, "UDPATE: REFUSED - SOA delete\n");#endif			hp->rcode = REFUSED;			return(-1);		}		/*		 * Don't check message length if doing UPDATEM/UPDATEMA,		 * since the whole message wont have been demarshalled until		 * we reach the code for UPDATEA		 */		if ( (opcode == UPDATED) || (opcode == UPDATEDA) ) {			if (cp != msg + msglen) {#ifdef DEBUG			    if (debug)			        fprintf(ddt,"FORMERR UPDATE message length off\n");#endif			    hp->rcode = FORMERR;			    return(-1);			}		}		if ((zonenum = findzone(dname, class)) == 0) { 			hp->rcode = NXDOMAIN;			return(-1);		}		if ( (opcode == UPDATED) || (opcode == UPDATEM) ) {			/* Make a dp for use in db_update, as old dp */			dp = savedata(class, type, 0, cp1, n);			dp->d_zone = zonenum;			n = db_update(dname, dp, NULL, DB_MEXIST | DB_DELETE,				      hashtab);			if (n != OK) {#ifdef DEBUG				if (debug)				    fprintf(ddt,"UPDATE: db_update failed\n");#endif DEBUG				free( (struct databuf *) dp);				hp->rcode = NOCHANGE;				return(-1);			}		} else {	/* UPDATEDA or UPDATEMA */			int DeletedOne = 0;			/* Make a dp for use in db_update, as old dp */			dp = savedata(class, type, 0, NULL, 0);			dp->d_zone = zonenum;			do {	/* Loop and delete all matching RR(s) */				n = db_update(dname, dp, NULL, DB_DELETE,					      hashtab);				if (n != OK)					break;				DeletedOne++;			} while (1);			free( (struct databuf *) dp);			/* Ok for UPDATEMA not to have deleted any RRs */			if (!DeletedOne && opcode == UPDATEDA) {#ifdef DEBUG				if (debug)					fprintf(ddt,"UPDATE: db_update failed\n");#endif DEBUG				hp->rcode = NOCHANGE;				return(-1);			}		}		if ( (opcode == UPDATED) || (opcode == UPDATEDA) )			return (cp - rrp);;		/*		 * Else unmarshal the RR to be added and continue on to		 * UPDATEA code for UPDATEM/UPDATEMA		 */		if ((n =		   dn_expand(msg, msg+msglen, cp, dname, sizeof(dname))) < 0) {#ifdef DEBUG			if (debug)			    fprintf(ddt,"FORMERR UPDATE expand name failed\n");#endif			hp->rcode = FORMERR;			return(-1);		}		cp += n;		GETSHORT(type, cp);		GETSHORT(class, cp);		GETLONG(ttl, cp);		GETSHORT(n, cp);		cp1 = cp;/**** XXX - need bounds checking here ****/		cp += n;	case UPDATEA:		if (n > MAXDATA) {#ifdef DEBUG			if (debug)			    fprintf(ddt,"UPDATE: too much data\n");#endif			hp->rcode = NOCHANGE;			return(-1);		}		if (cp != msg + msglen) {#ifdef DEBUG			if (debug)			    fprintf(ddt,"FORMERR UPDATE message length off\n");#endif			hp->rcode = FORMERR;			return(-1);		}		if ((zonenum = findzone(dname, class)) == 0) { 			hp->rcode = NXDOMAIN;			return(-1);		}		dp = savedata(class, type, ttl, cp1, n);		dp->d_zone = zonenum;		if ((n = db_update(dname, NULL, dp, DB_NODATA,				   hashtab)) != OK) {#ifdef DEBUG			if (debug)				fprintf(ddt,"UPDATE: db_update failed\n");#endif			hp->rcode = NOCHANGE;			return (-1);		}		else			return (cp - rrp);	}#endif ALLOW_UPDATES	if (zone == 0)		ttl += tt.tv_sec;#ifdef AUTHEN	dp = savedata(class, type, ttl, authen_type, authen_ver, cp1, n);#else AUTHEN	dp = savedata(class, type, ttl, cp1, n);#endif AUTHEN	dp->d_zone = zone;	if ((n = db_update(dname, dp, dp, flags, hashtab)) < 0) {#ifdef DEBUG		if (debug && (n != DATAEXISTS))			fprintf(ddt,"update failed (%d)\n", n);		else if (debug >= 3)			fprintf(ddt,"update failed (DATAEXISTS)\n");#endif		(void) free((char *)dp);	} else if (type == T_NS && savens != NULL)		*savens = dp;	return (cp - rrp);}send_msg(msg, msglen, qp)	char *msg;	int msglen;	struct qinfo *qp;{	extern struct qinfo *qhead;#ifdef DEBUG	struct qinfo *tqp;#endif DEBUG	if (qp->q_system)		return(1);#ifdef DEBUG	if (debug) {		fprintf(ddt,"send_msg -> %s (%s %d %d) id=%d\n",			inet_ntoa(qp->q_from.sin_addr), 			qp->q_stream == QSTREAM_NULL ? "UDP" : "TCP", qp->q_dfd,			ntohs(qp->q_from.sin_port),			ntohs(qp->q_id));	}	if (debug>4)		for (tqp = qhead; tqp!=QINFO_NULL; tqp = tqp->q_link) {		    fprintf(ddt, "qp %x q_id: %d  q_nsid: %d q_msglen: %d ",		    	tqp, tqp->q_id,tqp->q_nsid,tqp->q_msglen);	            fprintf(ddt,"q_naddr: %d q_curaddr: %d\n", tqp->q_naddr,			tqp->q_curaddr);	            fprintf(ddt,"q_next: %x q_link: %x\n", qp->q_next,		   	 qp->q_link);		}	if (debug >= 10)		fp_query(msg, ddt);#endif DEBUG	if (qp->q_stream == QSTREAM_NULL) {		if (sendto(qp->q_dfd, msg, msglen, 0,		    (struct sockaddr *)&qp->q_from, sizeof(qp->q_from)) < 0) {#ifdef DEBUG			if (debug)				fprintf(ddt, "sendto error errno= %d\n",errno);#endif			return(1);		}#ifdef STATS		stats[S_OUTPKTS].cnt++;#endif	} else {		(void) writemsg(qp->q_stream->s_rfd, msg, msglen);		qp->q_stream->s_time = tt.tv_sec;		qp->q_stream->s_refcnt--;	}	return(0);}prime(class, type, oqp)	int class, type;	register struct qinfo *oqp;{	char	dname[BUFSIZ];	if (oqp->q_msg == NULL)		return;	if (dn_expand(oqp->q_msg, oqp->q_msg + oqp->q_msglen,	    oqp->q_msg + sizeof(HEADER), dname, sizeof(dname)) < 0)		return;#ifdef DEBUG	if (debug >= 2)	       fprintf(ddt,"prime: %s\n", dname);#endif	(void) sysquery(dname, class, type);}prime_cache(){	register struct qinfo *qp;#ifdef DEBUG	if (debug)		fprintf(ddt,"prime_cache: priming = %d\n", priming);#endif#ifdef STATS	stats[S_PRIMECACHE].cnt++;#endif	if (!priming && fcachetab->h_tab[0] != NULL) {		priming++;		if ((qp = sysquery("", C_IN, T_NS)) == NULL)			priming = 0;		else			qp->q_system = PRIMING_CACHE;	}	needs_prime_cache = 0;	return;}struct qinfo *sysquery(dname, class, type)	char *dname;	int class, type;{	extern struct qinfo *qhead;	extern int nsid;	register struct qinfo *qp, *oqp;	register HEADER *hp;	struct namebuf *np;	struct databuf *nsp[NSMAX];	struct hashbuf *htp;	char *fname;	int count;#ifdef AUTHEN	char *krbnameptr;	char *dnameptr;	int authenlen;	int msglen;#endif AUTHEN#ifdef DEBUG	if (debug > 2)	       fprintf(ddt,"sysquery(%s, %d, %d)\n", dname, class, type);#endif#ifdef STATS	stats[S_SYSQUERIES].cnt++;#endif	htp = hashtab;	if (priming && dname[0] == '\0')		np = NULL;	else if ((np = nlookup(dname, &htp, &fname, 1)) == NULL) {#ifdef DEBUG		if (debug)			fprintf(ddt,"sysquery: nlookup error on %s?\n", dname);#endif		return(0);	}	switch (findns(&np, class, nsp, &count)) {	case NXDOMAIN:	case SERVFAIL:#ifdef DEBUG		if (debug)			fprintf(ddt,"sysquery: findns error on %s?\n", dname);#endif		return(0);	}	/* build new qinfo struct */	qp = qnew();	qp->q_cmsg = qp->q_msg = NULL;	qp->q_dfd = ds;	qp->q_fwd = fwdtab;	qp->q_addr[0].stime = tt;	qp->q_system++;#ifdef AUTHEN	strcpy(qp->q_dname, dname);	qp->q_type = type;	qp->q_class = class;	strcpy(qp->q_dname_curr, dname);	qp->q_type_curr = type;	qp->q_class_curr = class;	if(netsafe && class == C_HS) {		qp->q_type_in = AQUERY;		qp->q_type_out = AQUERY;		qp->q_authentype_in = AUTH_KRB;		qp->q_authenver_in = ONE;		qp->q_authentype_out = AUTH_KRB;		qp->q_authenver_out = ONE;	} else {		qp->q_type_in = QUERY;		qp->q_type_out = QUERY;		qp->q_authentype_in = AUTH_NONE;		qp->q_authenver_in = ZERO;		qp->q_authentype_out = AUTH_NONE;		qp->q_authenver_out = ZERO;	}		#endif AUTHEN	if ((qp->q_msg = malloc(BUFSIZ)) == NULL) {		qfree(qp);

⌨️ 快捷键说明

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