xfer.c

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

C
1,802
字号
				return XFER_FAIL;			}		}		#else#ifdef ULTRIXFUNC		if ((n = res_mkquery(QUERY, zp->z_origin, C_ANY,		    T_SOA, (char *)NULL, 0, NULL, buf, bufsize)) < 0) {			if (!quiet)			    syslog(LOG_ERR, "zone %s: res_mkquery T_SOA failed",				zp->z_origin);			(void) close(s);			(void) sigvec(SIGALRM, &osv, (struct sigvec *)0);			return XFER_FAIL;		}#else ULTRIXFUNC		if ((n = res_mkquery(QUERY, zp->z_origin, C_IN,		    T_SOA, (char *)NULL, 0, NULL, buf, bufsize)) < 0) {			if (!quiet)			    syslog(LOG_ERR, "zone %s: res_mkquery T_SOA failed",				zp->z_origin);			(void) close(s);			(void) sigvec(SIGALRM, &osv, (struct sigvec *)0);			return XFER_FAIL;		}#endif ULTRIXFUNC#endif AUTHEN		/*		 * Send length & message for zone transfer		 */		if (writemsg(s, buf, n) < 0) {			(void) close(s);			error++;#ifdef DEBUG			if (debug >= 2)				(void)fprintf(ddt,"writemsg failed\n");#endif			continue;			}		/*		 * Get out your butterfly net and catch the SOA		 */		cp = buf;		l = sizeof(u_short);		read_interrupted = 0;		while (l > 0) {#ifdef DEBUG			if (debug > 10) (void)fprintf(ddt,"Before setitimer\n");#endif			(void) setitimer(ITIMER_REAL, &ival,			    (struct itimerval *)NULL);#ifdef DEBUG			if (debug > 10) (void)fprintf(ddt,"Before recv(l = %d)\n",n);#endif			errno = 0;			if ((n = recv(s, (char *)cp, l, 0)) > 0) {				cp += n;				l -= n;			} else {#ifdef DEBUG				if (debug > 10)				    (void)fprintf(ddt,"bad recv->%d, errno= %d, read_interrupt=%d\n", n, errno, read_interrupted);#endif#ifdef ULTRIXFUNC				(void) close(s);#endif ULTRIXFUNC				if (n == -1 && errno == EINTR 				    && !read_interrupted)					continue;				error++;#ifdef DEBUG				if(errno && debug)				    (void)fprintf(ddt,"bad recv->%d, errno= %d, read_interrupt=%d\n", n, errno, read_interrupted);				else if (debug)				    (void)fprintf(ddt,"recv timeout occurred, read_interrupt=%d\n", read_interrupted);#endif				break;			}		}		(void) setitimer(ITIMER_REAL, &zeroival,		    (struct itimerval *)NULL);		if (error) {			(void) close(s);			continue;		}		if ((len = htons(*(u_short *)buf)) == 0) {			(void) close(s);			continue;		}		if (len > bufsize) {			if ((buf = (u_char *)realloc(buf, len)) == NULL) {				syslog(LOG_ERR,			  "malloc(%u) failed for SOA from server %s, zone %s\n",				    len, inet_ntoa(sin.sin_addr), zp->z_origin);				(void) close(s);				continue;			}			bufsize = len;		}		l = len;		cp = buf;		while (l > 0) {			(void) setitimer(ITIMER_REAL, &ival,			    (struct itimerval *)NULL);			errno = 0;			if ((n = recv(s, (char *)cp, l, 0)) > 0) {				cp += n;				l -= n;			} else {#ifdef ULTRIXFUNC				(void) close(s);#endif ULTRIXFUNC				if (errno == EINTR && !read_interrupted)					continue;				error++;#ifdef DEBUG				if (debug > 10)				    (void)fprintf(ddt,					    "recv failed: n= %d, errno = %d\n",					    n, errno);#endif#ifdef DEBUG				if(errno && debug)				    (void)fprintf(ddt,"bad recv->%d, errno= %d, read_interrupt=%d\n", n, errno, read_interrupted);				else if (debug)				    (void)fprintf(ddt,"recv timeout occurred, read_interrupt=%d\n", read_interrupted);#endif				break;			}		}		(void) setitimer(ITIMER_REAL, &zeroival,		    (struct itimerval *)NULL);		if (error) {			(void) close(s);			continue;		}#ifdef DEBUG		if (debug >= 3) {			(void)fprintf(ddt,"len = %d\n", len);			fp_query(buf, ddt);		}#endif DEBUG		hp = (HEADER *) buf;		ancount = ntohs(hp->ancount);		aucount = ntohs(hp->nscount);		/*		 * close socket if:		 *  1) rcode != NOERROR		 *  2) not an authority response		 *  3) both the number of answers and authority count < 1)		 *//*		if (hp->rcode != NOERROR || !(hp->aa) || 		    (ancount < 1 && aucount < 1)) { */		/* None of the additional conditions above can be met with		   a C_ANY query */		if (hp->rcode != NOERROR ) {			if (!quiet)				syslog(LOG_ERR,	    "%s from %s, zone %s: rcode %d, aa %d, ancount %d, aucount %d\n",				    "bad response to SOA query",				    inet_ntoa(sin.sin_addr), zp->z_origin,				    hp->rcode, hp->aa, ancount, aucount);#ifdef DEBUG			if (debug)				fprintf(ddt,	    "%s from %s, zone %s: rcode %d, aa %d, ancount %d, aucount %d\n",				    "bad response to SOA query",				    inet_ntoa(sin.sin_addr), zp->z_origin,				    hp->rcode, hp->aa, ancount, aucount);#endif DEBUG			(void) close(s);			error++;			continue;		}		zp_start = *zp;#ifdef AUTHEN		if (len < sizeof(HEADER) + 			((hp->opcode == AQUERY) ? AQFIXEDSZ : QFIXEDSZ)) {#else AUTHEN		if (len < sizeof(HEADER) + QFIXEDSZ) {#endif AUTHEN	badsoa:			if (!quiet)				syslog(LOG_ERR,				  "malformed SOA from %s, zone %s: too short\n",				    inet_ntoa(sin.sin_addr), zp->z_origin);#ifdef DEBUG			if (debug)				fprintf(ddt,				    "malformed SOA from %s: too short\n",				    inet_ntoa(sin.sin_addr));#endif DEBUG			(void) close(s);			error++;			continue;		}		tmp = buf + sizeof(HEADER);		eom = buf + len;#ifdef AUTHEN		if ((n = dn_skipname(tmp, eom)) == -1)			goto badsoa;		tmp += n + ((hp->opcode == AQUERY) ? AQFIXEDSZ : QFIXEDSZ);		if ((n = dn_skipname(tmp, eom)) == -1)			goto badsoa;		tmp += n;		if((authen_len = soa_zinfo(&zp_start, tmp, eom)) == -1)			goto badsoa;		authen_len += tmp - buf;#else AUTHEN		if ((n = dn_skipname(tmp, eom)) == -1)			goto badsoa;		tmp += n + QFIXEDSZ;		if ((n = dn_skipname(tmp, eom)) == -1)			goto badsoa;		tmp += n;		if (soa_zinfo(&zp_start, tmp, eom) == -1)			goto badsoa;#endif AUTHEN#ifdef AUTHEN		if(hp->opcode == AQUERY && defauthentype == AUTH_KRB &&		   defauthenver==ONE) {			if(res_rds_krbcred(ONE, "named",zp->z_dname[cnt],					   &cred, buf, buf + authen_len,					   eom - (buf + authen_len),					   zp->z_origin, T_SOA,					   zp_start.z_class)			   < RET_OK) {#ifdef DEBUG				if (debug)					fprintf(ddt,					    "Authentication error on T_ SOA from %s\n",					    inet_ntoa(sin.sin_addr));#endif DEBUG				(void) close(s);				error++;				continue;			}		} else if(netsafe) {#ifdef DEBUG			if (debug)				fprintf(ddt,				    "Authenitcation nonexistent on T_ SOA from %s\n",				    inet_ntoa(sin.sin_addr));#endif DEBUG			(void) close(s);			error++;			continue;		}#endif AUTHEN#ifdef ULTRIXFUNC		if(zp->z_class == C_ANY)			zp->z_class = zp_start.z_class;#endif ULTRIXFUNC		if (zp_start.z_serial > serial_no || serial_no == 0) {#ifdef DEBUG		    if (debug)			(void)fprintf(ddt, "need update, serial %d\n",			    zp_start.z_serial);#endif DEBUG		    hp = (HEADER *) buf;		    soacnt = 0;		    for (;;) {			if (soacnt == 0) {#ifdef AUTHEN						    if(netsafe) {				    /* switch of auth type */					    if ((n = res_mkquery(AQUERY, zp->z_origin,						     zp->z_class,						     T_AXFR,(char *)NULL,						     0, NULL, buf,						     bufsize)) < 0) {					if (!quiet)					    syslog(LOG_ERR,					     "zone %s: res_mkquery T_AXFR failed",						zp->z_origin);					(void) close(s);					(void) sigvec(SIGALRM, &osv,					    (struct sigvec *)0);					return XFER_FAIL;				    }				    krbnameptr = res_dotname_head(					zp->z_dname[cnt]);				    if((authen_len = res_mkl_krbcred(ONE,						"named", krbnameptr, &cred,						buf, buf + n, bufsize - n,						zp->z_origin, T_AXFR,						zp->z_class)) < RET_OK) {					if (!quiet)					    syslog(LOG_ERR,						"zone %s: res_mkl_krbcred T_AXFR failed",						zp->z_origin);					free(krbnameptr);					(void) close(s);					(void) sigvec(SIGALRM, &osv,						  (struct sigvec *)0);					return XFER_FAIL;				    }				    free(krbnameptr);				    n += authen_len;			    } else {				    if ((n = res_mkquery(QUERY, zp->z_origin,							 zp->z_class,							 T_AXFR, (char *)NULL,							 0, NULL,							 buf,							 bufsize)) < 0) {					if (!quiet)					    syslog(LOG_ERR,						"zone %s: res_mkquery T_AXFR failed",						zp->z_origin);					(void) close(s);					(void) sigvec(SIGALRM, &osv,					    (struct sigvec *)0);					return XFER_FAIL;				    }			    }#else AUTHEN#ifdef ULTRIXFUNC			    if ((n = res_mkquery(QUERY, zp->z_origin, C_ANY,			      T_AXFR, (char *)NULL, 0, NULL,			      buf, bufsize)) < 0) {				if (!quiet)				    syslog(LOG_ERR,					"zone %s: res_mkquery T_AXFR failed",					zp->z_origin);				(void) close(s);				(void) sigvec(SIGALRM, &osv, (struct sigvec *)0);				return XFER_FAIL;			    }#else ULTRIXFUNC			    if ((n = res_mkquery(QUERY, zp->z_origin, C_IN,			      T_AXFR, (char *)NULL, 0, NULL,			      buf, bufsize)) < 0) {				if (!quiet)				    syslog(LOG_ERR,					"zone %s: res_mkquery T_AXFR failed",					zp->z_origin);				(void) close(s);				(void) sigvec(SIGALRM, &osv,				    (struct sigvec *)0);				return XFER_FAIL;			    }#endif ULTRIXFUNC#endif AUTHEN			    /*			     * Send length & message for zone transfer			     */			    if (writemsg(s, buf, n) < 0) {				    (void) close(s);				    error++;#ifdef DEBUG				    if (debug >= 2)					    (void)fprintf(ddt,"writemsg failed\n");#endif				    break;				    }			}			/*			 * Receive length & response			 */			cp = buf;			l = sizeof(u_short);			while (l > 0) {				(void) setitimer(ITIMER_REAL, &ival,				    (struct itimerval *)NULL);				errno = 0;				if ((n = recv(s, (char *)cp, l, 0)) > 0) {					cp += n;					l -= n;				} else {					if (errno == EINTR && !read_interrupted)						continue;					error++;#ifdef DEBUG					if (debug >= 2)					  (void)fprintf(ddt,					    "recv failed: n= %d, errno = %d\n",					    n, errno);#endif#ifdef DEBUG					if(errno && debug)					    (void)fprintf(ddt,"bad recv->%d, errno= %d, read_interrupt=%d\n", n, errno, read_interrupted);					else if (debug)					    (void)fprintf(ddt,"recv timeout occurred, read_interrupt=%d\n", read_interrupted);#endif					break;				}			}			(void) setitimer(ITIMER_REAL, &zeroival,			    (struct itimerval *)NULL);			if (error)				break;			if ((len = htons(*(u_short *)buf)) == 0)				break;			l = len;			cp = buf;			eom = buf + len;			while (l > 0) {				(void) setitimer(ITIMER_REAL, &ival,				    (struct itimerval *)NULL);				errno = 0;				if ((n = recv(s, (char *)cp, l, 0)) > 0) {					cp += n;					l -= n;				} else {					if (errno == EINTR && !read_interrupted)						continue;					error++;#ifdef DEBUG					if (debug >= 2)						(void)fprintf(ddt,"recv failed\n");#endif#ifdef DEBUG					if(errno && debug)					    (void)fprintf(ddt,"bad recv->%d, errno= %d, read_interrupt=%d\n", n, errno, read_interrupted);					else if (debug)					    (void)fprintf(ddt,"recv timeout occurred, read_interrupt=%d\n", read_interrupted);#endif					break;				}			}			(void) setitimer(ITIMER_REAL, &zeroival,			    (struct itimerval *)NULL);			if (error)				break;#ifdef DEBUG			if (debug >= 3) {				(void)fprintf(ddt,"len = %d\n", len);				fp_query(buf, ddt);			}			if (fp) fp_query(buf,fp);#endif#ifdef AUTHEN			authen = 0;#endif AUTHEN			if (len < sizeof(HEADER)) {		badrec:				error++;				if (!quiet)					syslog(LOG_ERR, "record too short from %s, zone %s\n", inet_ntoa(sin.sin_addr), zp->z_source);#ifdef DEBUG				if (debug)					fprintf(ddt,					    "record too short from %s\n",				    inet_ntoa(sin.sin_addr));#endif DEBUG				break;			}			cp = buf + sizeof(HEADER);#ifdef AUTHEN			if(netsafe && hp->opcode != AQUERY) {				syslog(LOG_ERR, "zoneref: res_mkquery non authenticated zone transfer message");				error++;error = 9;				break;							}			if (hp->qdcount) {				if ((n = dn_skipname(cp, eom)) == -1 ||				    n + ((hp->opcode == AQUERY) ? AQFIXEDSZ :				    QFIXEDSZ) >= eom - cp)					goto badrec;				cp += n + ((hp->opcode == AQUERY) ? AQFIXEDSZ :				    QFIXEDSZ);			}			nmp = cp;			if((authen_len = dn_expand(hp, eom, cp, name2, sizeof(name2))) < 0) {				syslog(LOG_ERR, "zoneref: res_mkquery failed bad dn_expand");				goto badrec;			}			tmp = cp + authen_len;#else AUTHEN			if (hp->qdcount) {				if ((n = dn_skipname(cp, eom)) == -1 ||				    n + QFIXEDSZ >= eom - cp)					goto badrec;				cp += n + QFIXEDSZ;			}			nmp = cp;			if ((n = dn_skipname(cp, eom)) == -1)				goto badrec;			tmp = cp + n;#endif AUTHEN#ifdef AUTHEN			authen = 0;			authen_tmp = tmp;			GETSHORT(authen_answtype, authen_tmp);			GETSHORT(authen_answclass, authen_tmp);			authen_tmp += sizeof(u_long);			GETSHORT(authen_len, authen_tmp);			authen_tmp += authen_len;			namptr = name2;			if(authen_answtype != T_SOA && authen_answtype!=T_AXFR)				res_dotname_rmhead(&namptr);			if(netsafe) {				krbnameptr = res_dotname_head(					zp->z_dname[cnt]);				if((authen_len = res_rds_krbcred(ONE,						   "named", 						   krbnameptr,						   &cred, hp, authen_tmp,						   eom - authen_tmp,						   namptr,						   authen_answtype,						   authen_answclass))				   < RET_OK) {					if (!quiet)					    syslog(LOG_ERR,						   "zoneref: res_rds_krbcred failed.");					free(krbnameptr);					error++;					break;				} else {					authen = 1;					free(krbnameptr);					n = print_output(buf, bufsize, cp);					n += authen_len;				}			} else {				authen = 1;				n = print_output(buf, bufsize, cp);			}#else AUTHEN				n = print_output(buf, bufsize, cp);#endif AUTHEN			if (cp + n != eom) {#ifdef DEBUG			   if (debug)			   (void)fprintf(ddt,				     "getzone: print_update failed (%d, %d)\n",					cp - buf, n);#endif				error++;				break;			}			GETSHORT(n, tmp);#ifdef AUTHEN			if (n == T_SOA && authen) {#else AUTHEN			if (n == T_SOA) {#endif AUTHEN				if (soacnt == 0) {					soacnt++;					if (dn_expand(buf, buf + 512, nmp,					    name, sizeof(name)) == -1)						goto badsoa;					if (eom - tmp <= 2 * sizeof(u_short) +					    sizeof(u_long))						goto badsoa;					tmp += 2 * sizeof(u_short)						+ sizeof(u_long);					if ((n = dn_skipname(tmp, eom)) == -1)						goto badsoa;					tmp += n;					if ((n = dn_skipname(tmp, eom)) == -1)						goto badsoa;					tmp += n;					if (eom - tmp <= sizeof(u_long))						goto badsoa;					GETLONG(serial, tmp);#ifdef DEBUG					if (debug > 2)					    (void)fprintf(ddt,					        "first SOA for %s, serial %d\n",					        name, serial);#endif DEBUG

⌨️ 快捷键说明

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