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

📄 named-xfer.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
				syslog(LOG_ERR, "malloc(%u) failed",				    2 * PACKETSZ);				error++;				break;			}			bufsize = 2 * PACKETSZ;		}		bzero((char *)&sin, sizeof(sin));		sin.sin_family = AF_INET;		sin.sin_port = port;		sin.sin_addr = zp->z_addr[cnt];		if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {			syslog(LOG_ERR, "socket: %m");			error++;			break;		}			dprintf(2, (ddt, "connecting to server #%d [%s].%d\n",			    cnt+1, inet_ntoa(sin.sin_addr),			    ntohs(sin.sin_port)));		if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {			(void) my_close(s);			error++;			dprintf(2, (ddt, "connect failed: %s\n",				    strerror(errno)));			continue;		}	tryagain:		if ((n = res_mkquery(QUERY, zp->z_origin, Class,		    T_SOA, (char *)NULL, 0, NULL, (char *)buf, bufsize)) < 0) {			if (!quiet)			    syslog(LOG_ERR,				   "zone %s: res_mkquery T_SOA failed",				   zp->z_origin);			(void) my_close(s);#ifdef POSIX_SIGNALS			(void) sigaction(SIGALRM, &osv, (struct sigaction *)0);#else			(void) sigvec(SIGALRM, &osv, (struct sigvec *)0);#endif			return XFER_FAIL;		}		/*		 * Send length & message for SOA query		 */		if (writemsg(s, buf, n) < 0) {			(void) my_close(s);			error++;			dprintf(2, (ddt, "writemsg failed\n"));			continue;			}		/*		 * Get out your butterfly net and catch the SOA		 */		cp = buf;		l = sizeof(u_int16_t);		read_interrupted = 0;		while (l > 0) {			dprintf(11, (ddt, "Before setitimer\n"));			(void) setitimer(ITIMER_REAL, &ival,			    (struct itimerval *)NULL);			dprintf(11, (ddt, "Before recv(l = %d)\n",n));			errno = 0;			if ((n = recv(s, (char *)cp, l, 0)) > 0) {				cp += n;				l -= n;			} else {				dprintf(11, (ddt,				"bad recv->%d, errno= %d, read_interrupt=%d\n",					     n, errno, read_interrupted));				if (n == -1 && errno == EINTR 				    && !read_interrupted)					continue;				error++;				break;			}		}		(void) setitimer(ITIMER_REAL, &zeroival,		    (struct itimerval *)NULL);		if (error) {			(void) my_close(s);			continue;		}		if ((len = htons(*(u_int16_t *)buf)) == 0) {			(void) my_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) my_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 {				if (errno == EINTR && !read_interrupted)					continue;				error++;				dprintf(11, (ddt,					    "recv failed: n= %d, errno = %d\n",					     n, errno));				break;			}		}		(void) setitimer(ITIMER_REAL, &zeroival,				 (struct itimerval *)NULL);		if (error) {			(void) my_close(s);			continue;		}#ifdef DEBUG		if (debug >= 3) {			(void)fprintf(ddt,"len = %d\n", len);			fp_query((char *)buf, ddt);		}#endif		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)) {#ifndef GEN_AXFR			if (Class == C_IN) {				dprintf(1, (ddt,"SOA failed, trying C_HS\n"));				Class = C_HS;				goto tryagain;			}#endif			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);			dprintf(1, (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));			(void) my_close(s);			error++;			continue;		}		zp_start = *zp;		if (len < sizeof(HEADER) + QFIXEDSZ) {	badsoa:			if (!quiet)				syslog(LOG_ERR,				 "malformed SOA from [%s], zone %s: too short\n",				       inet_ntoa(sin.sin_addr), zp->z_origin);			dprintf(1, (ddt,				    "malformed SOA from [%s]: too short\n",				    inet_ntoa(sin.sin_addr)));			(void) my_close(s);			error++;			continue;		}		tmp = buf + sizeof(HEADER);		eom = buf + len;		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;		/* compare using sequence space arithmetic */		if (SEQ_GT(zp_start.z_serial, serial_no) || serial_no == 0) {			dprintf(1, (ddt, "need update, serial %d\n",				    zp_start.z_serial));			hp = (HEADER *) buf;			soacnt = 0;			nscnt = 0;			for (;;) {				if ((soacnt == 0) || (zp->z_type == Z_STUB)) {					int type;#ifdef	STUBS					if (zp->z_type == Z_STUB) {						if (!soacnt)							type = T_SOA;						else if (!nscnt)							type = T_NS;						else 							type = T_SOA;					} else#endif						type = T_AXFR;					if ((n = res_mkquery(QUERY,							     zp->z_origin,							     Class,							     type,							     (char *)NULL,							     0,							     NULL,							     (char *)buf,							     bufsize							     )) < 0) {						if (!quiet) {#ifdef STUBS						    if (zp->z_type == Z_STUB)							syslog(LOG_ERR,							       (type == T_SOA)					? "zone %s: res_mkquery T_SOA failed"					: "zone %s: res_mkquery T_NS failed",							       zp->z_origin);						    else#endif							syslog(LOG_ERR,					  "zone %s: res_mkquery T_AXFR failed",							       zp->z_origin);						}						(void) my_close(s);#ifdef POSIX_SIGNALS						sigaction(SIGALRM, &osv,							(struct sigaction *)0);#else						sigvec(SIGALRM, &osv,						       (struct sigvec *)0);#endif						return XFER_FAIL;					}					/*					 * Send length & msg for zone transfer					 */					if (writemsg(s, buf, n) < 0) {						(void) my_close(s);						error++;						dprintf(2, (ddt,							    "writemsg failed\n"							    ));						break;						}				}				/*				 * Receive length & response				 */				cp = buf;				l = sizeof(u_int16_t);				/* allow extra time for fork on first read */				if (soacnt == 0)					ival.it_value.tv_sec = 300;				while (l > 0) {					(void) setitimer(ITIMER_REAL, &ival,							 (struct itimerval *)							     NULL							 );					errno = 0;					n = recv(s, (char *)cp, l, 0);					if (n > 0) {						cp += n;						l -= n;					} else {						if (errno == EINTR						    && !read_interrupted)							continue;						error++;						dprintf(2, (ddt,					    "recv failed: n= %d, errno = %d\n",							    n, errno));						break;					}				}				if (soacnt == 0)					ival.it_value.tv_sec = XFER_TIMER;				(void) setitimer(ITIMER_REAL, &zeroival,						 (struct itimerval *)NULL);				if (error)					break;				if ((len = htons(*(u_int16_t *)buf)) == 0)					break;				l = len;				cp = buf;				eom = buf + len;				while (l > 0) {					(void) setitimer(ITIMER_REAL, &ival,							 (struct itimerval *)							     NULL							 );					errno = 0;					n = recv(s, (char *)cp, l, 0);					if (n > 0) {						cp += n;						l -= n;					} else {						if (errno == EINTR						    && !read_interrupted)							continue;						error++;						dprintf(2, (ddt,							    "recv failed\n"));						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((char *)buf, ddt);				}				if (fp)					fp_query((char *)buf, fp);#endif				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);					dprintf(1, (ddt,						"record too short from [%s]\n",						    inet_ntoa(sin.sin_addr)));					break;				}				cp = buf + sizeof(HEADER);				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;#ifdef STUBS			if (zp->z_type == Z_STUB) {				ancount = ntohs(hp->ancount);				for (cnt = 0 ; cnt < ancount ; cnt++) {					n = print_output(buf, bufsize, cp);					cp += n;				}				if (hp->nscount) {					/* we should not get here */					ancount = ntohs(hp->nscount);					for (cnt = 0 ; cnt < ancount ; cnt++) {					    n = print_output(buf, bufsize, cp);						cp += n;					}				}				ancount = ntohs(hp->arcount);				for (cnt = 0 ; cnt < ancount ; cnt ++) {					n = print_output(buf, bufsize, cp);					cp += n;				}				if (cp != eom) {					dprintf(1, (ddt,				     "getzone: print_update failed (%d, %d)\n",						cp - buf, n));					error++;					break;				}					} else {#endif /*STUBS*/				n = print_output(buf, bufsize, cp);				if (cp + n != eom) {					dprintf(1, (ddt,				     "getzone: print_update failed (%d, %d)\n",					    cp - buf, n));					error++;					break;				}#ifdef STUBS			}#endif			GETSHORT(n, tmp);			if (n == T_SOA) {				if (soacnt == 0) {					soacnt++;					if (dn_expand(buf, buf + 512, nmp,					    name, sizeof(name)) == -1)						goto badsoa;					if (eom - tmp					    <= 2 * sizeof(u_int16_t)					       + sizeof(u_int32_t)) {						goto badsoa;					}					tmp += 2 * sizeof(u_int16_t)					       + sizeof(u_int32_t);					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_int32_t))						goto badsoa;					GETLONG(serial, tmp);					dprintf(3, (ddt,					       "first SOA for %s, serial %d\n",						    name, serial));					continue;				}				if (dn_expand(buf, buf + 512, nmp, name2, 				    sizeof(name2)) == -1)					goto badsoa;				if (strcasecmp((char *)name,					       (char *)name2) != 0) {					dprintf(2, (ddt,						    "extraneous SOA for %s\n",						    name2));					continue;				}				tmp -= sizeof(u_int16_t);				if (soa_zinfo(&zp_finish, tmp, eom) == -1)					goto badsoa;				dprintf(2, (ddt,					    "SOA, serial %d\n",					    zp_finish.z_serial));				if (serial != zp_finish.z_serial) {					soacnt = 0;					got_soa = 0;					minimum_ttl = 0;					strcpy(prev_origin, zp->z_origin);					prev_dname[0] = DEF_DNAME;					dprintf(1, (ddt,						    "serial changed, restart\n"						    ));					/*					 * Flush buffer, truncate file					 * and seek to beginning to restart.					 */					fflush(dbfp);					if (ftruncate(fileno(dbfp), 0) != 0) {						if (!quiet)						    syslog(LOG_ERR,							"ftruncate %s: %m\n",							tmpname);						return(XFER_FAIL);					}					fseek(dbfp, 0L, 0);				} else					break;#ifdef STUBS			} else if (zp->z_type == Z_STUB && n == T_NS) {				nscnt++;			} else if (zp->z_type == Z_STUB) {				break;#endif			}		}		(void) my_close(s);		if (error == 0) {#ifdef POSIX_SIGNALS			(void) sigaction(SIGALRM, &osv,					 (struct sigaction *)0);#else			(void) sigvec(SIGALRM, &osv, (struct sigvec *)0);#endif			return XFER_SUCCESS;		}		dprintf(2, (ddt, "error receiving zone transfer\n"));	    } else if (zp_start.z_serial == serial_no) {		(void) my_close(s);		dprintf(1, (ddt,			    "zone up-to-date, serial %u\n",			    zp_start.z_serial));		return XFER_UPTODATE;	    } else {		(void) my_close(s);		if (!quiet)		    syslog(LOG_ERR,		      "serial from [%s], zone %s: %u lower than current: %u\n",			   inet_ntoa(sin.sin_addr), zp->z_origin,			   zp_start.z_serial, serial_no);		dprintf(1, (ddt,

⌨️ 快捷键说明

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