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

📄 ns_main.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	syslog(LOG_NOTICE, "Ready to answer queries.\n");	prime_cache();	nfds = getdtablesize();       /* get the number of file descriptors */	if (nfds > FD_SETSIZE) {		nfds = FD_SETSIZE;	/* Bulletproofing */		syslog(LOG_ERR, "Return from getdtablesize() > FD_SETSIZE");#ifdef DEBUG		if (debug)		      fprintf(ddt,"Return from getdtablesize() > FD_SETSIZE\n");#endif	}	FD_ZERO(&mask);	FD_SET(vs, &mask);	for (dqp = datagramq; dqp != QDATAGRAM_NULL; dqp = dqp->dq_next)		FD_SET(dqp->dq_dfd, &mask);	for (;;) {#ifdef DEBUG		if (ddt && debug == 0) {			fprintf(ddt,"Debug turned OFF\n");			(void) my_fclose(ddt);			ddt = 0;		}#endif#ifdef ALLOW_UPDATES                if (needToExit) {			struct zoneinfo *zp;			sigblock(~0);   /*					 * Block all blockable signals					 * to ensure a consistant					 * state during final dump					 */#ifdef DEBUG			if (debug)				fprintf(ddt, "Received shutdown signal\n");                     #endif			for (zp = zones; zp < &zones[nzones]; zp++) {				if (zp->z_state & Z_CHANGED)					zonedump(zp);                        }                        exit(0);                }#endif /* ALLOW_UPDATES */		if (needreload) {			needreload = 0;			db_reload();		}		if (needStatsDump) {			needStatsDump = 0;			ns_stats();		}		if (needzoneload) {			needzoneload = 0;			loadxfer();		}		if (needmaint) {                        needmaint = 0;                        ns_maint();                }	        if(needToChkpt) {                        needToChkpt = 0;                        doachkpt();	        }                if(needToDoadump) {                        needToDoadump = 0;                        doadump();                }		/*		** Wait until a query arrives		*/		if (retryqp != NULL) {			gettime(&tt);			/*			** The tv_sec field might be unsigned 			** and thus cannot be negative.			*/			if ((int32_t) retryqp->q_time <= tt.tv_sec) {				retry(retryqp);				continue;			}			t.tv_sec = (int32_t) retryqp->q_time - tt.tv_sec;			tp = &t;		} else			tp = NULL;		tmpmask = mask;		n = select(nfds, &tmpmask, (fd_set *)NULL, (fd_set *)NULL, tp);		if (n < 0) {			if (errno == EINTR)				continue;			syslog(LOG_ERR, "select: %m");#ifdef DEBUG			if (debug)				fprintf(ddt,"select error\n");#endif			;		}		if (n == 0)			continue;		for (dqp = datagramq;		     dqp != QDATAGRAM_NULL;		     dqp = dqp->dq_next) {		    if (FD_ISSET(dqp->dq_dfd, &tmpmask))		        for(udpcnt = 0; udpcnt < 25; udpcnt++) {			    from_len = sizeof(from_addr);			    if ((n = recvfrom(dqp->dq_dfd, buf, sizeof(buf), 0,				(struct sockaddr *)&from_addr, &from_len)) < 0)			    {				if ((n < 0) && (errno == PORT_WOULDBLK))					break;				syslog(LOG_WARNING, "recvfrom: %m");				break;			    }			    if (n == 0)				break;			    stats[S_INPKTS].cnt++;			    gettime(&tt);			    dprintf(1, (ddt,				 "\ndatagram from [%s].%d, fd %d, len %d; now %s",					inet_ntoa(from_addr.sin_addr),					ntohs(from_addr.sin_port),					dqp->dq_dfd, n,				        ctime(&tt.tv_sec)));#ifdef DEBUG			    if (debug >= 10)				fp_query((char *)buf, ddt);#endif			    /*			     * Consult database to get the answer.			     */			    gettime(&tt);			    ns_req(buf, n, PACKETSZ, QSTREAM_NULL, &from_addr,				    dqp->dq_dfd);		        }		}		/*		** Process stream connection		*/		if (FD_ISSET(vs, &tmpmask)) {			from_len = sizeof(from_addr);			rfd = accept(vs,				     (struct sockaddr *)&from_addr,				     &from_len);			gettime(&tt);			if (rfd < 0 && errno == EMFILE && streamq != NULL) {				maxctime = 0;				candidate = QSTREAM_NULL;				for (sp = streamq; sp != QSTREAM_NULL;				   sp = nextsp) {					nextsp = sp->s_next;					if (sp->s_refcnt != 0)					    continue;					lasttime = tt.tv_sec - sp->s_time;					if (lasttime >= 900)					    sqrm(sp);					else if (lasttime > maxctime) {					    candidate = sp;					    maxctime = lasttime;					}				}				rfd = accept(vs,					     (struct sockaddr *)&from_addr,					     &from_len);				if ((rfd < 0) && (errno == EMFILE) &&				    candidate != QSTREAM_NULL) {					sqrm(candidate);					rfd = accept(vs,						     (struct sockaddr *)							&from_addr,						     &from_len);				}			}			if (rfd < 0) {				syslog(LOG_WARNING, "accept: %m");				continue;			}			if ((n = fcntl(rfd, F_GETFL, 0)) < 0) {				syslog(LOG_ERR,				       "fcntl(rfd, F_GETFL): %m");				(void) my_close(rfd);				continue;			}			if (fcntl(rfd, F_SETFL, n|PORT_NONBLOCK) != 0) {				syslog(LOG_ERR,				       "fcntl(rfd, non-blocking): %m");				(void) my_close(rfd);				continue;			}			if (setsockopt(rfd, SOL_SOCKET, SO_KEEPALIVE,				(char *)&on, sizeof(on)) != 0)			{				syslog(LOG_ERR,				       "setsockopt(rfd, keepalive): %m");				(void) my_close(rfd);				continue;			}			if ((sp = sqadd()) == QSTREAM_NULL) {				(void) my_close(rfd);				continue;			}			sp->s_rfd = rfd;	/* stream file descriptor */			sp->s_size = -1;	/* amount of data to receive */			gettime(&tt);			sp->s_time = tt.tv_sec;	/* last transaction time */			sp->s_from = from_addr;	/* address to respond to */			sp->s_bufp = (u_char *)&sp->s_tempsize;			FD_SET(rfd, &mask);			FD_SET(rfd, &tmpmask);			dprintf(1, (ddt,				  "\nTCP connection from [%s].%d (fd %d)\n",				    inet_ntoa(sp->s_from.sin_addr),				    ntohs(sp->s_from.sin_port), rfd));		}		if (streamq) {			dprintf(3, (ddt, "streamq  = x%x\n",streamq));		}		for (sp = streamq;  sp != QSTREAM_NULL;  sp = nextsp) {			nextsp = sp->s_next;			if (!FD_ISSET(sp->s_rfd, &tmpmask))				continue;			dprintf(5, (ddt,				    "sp x%x rfd %d size %d time %d next x%x\n",				    sp, sp->s_rfd, sp->s_size,				    sp->s_time, sp->s_next));			dprintf(5, (ddt,				    "\tbufsize %d buf x%x bufp x%x\n",				    sp->s_bufsize, sp->s_buf, sp->s_bufp));			if (sp->s_size < 0) {				size = sizeof(u_int16_t)				    - (sp->s_bufp - (u_char *)&sp->s_tempsize);			        while (size > 0 &&			           (n = read(sp->s_rfd, sp->s_bufp, size)) > 0				       ) {					sp->s_bufp += n;					size -= n;			        }				if ((n < 0) && (errno == PORT_WOULDBLK))					continue;				if (n <= 0) {					sqrm(sp);					continue;			        }			        if ((sp->s_bufp - (u_char *)&sp->s_tempsize) ==					sizeof(u_int16_t)) {					sp->s_size = htons(sp->s_tempsize);					if (sp->s_bufsize == 0) {					    if ( (sp->s_buf = (u_char *)						  malloc(BUFSIZ))						== NULL) {						    sp->s_buf = buf;						    sp->s_size  = sizeof(buf);					    } else {						    sp->s_bufsize = BUFSIZ;					    }					}					if (sp->s_size > sp->s_bufsize &&					    sp->s_bufsize != 0					) {					    sp->s_buf = (u_char *)						realloc((char *)sp->s_buf,							(unsigned)sp->s_size);					    if (sp->s_buf == NULL) {						sp->s_buf = buf;						sp->s_bufsize = 0;						sp->s_size  = sizeof(buf);					    } else {						sp->s_bufsize = sp->s_size;					    }					}					sp->s_bufp = sp->s_buf;					}			}			gettime(&tt);			sp->s_time = tt.tv_sec;			while (sp->s_size > 0 &&			      (n = read(sp->s_rfd,					sp->s_bufp,					sp->s_size)			       ) > 0			) {				sp->s_bufp += n;				sp->s_size -= n;			}			/*			 * we don't have enough memory for the query.			 * if we have a query id, then we will send an			 * error back to the user.			 */			if (sp->s_bufsize == 0 &&			    (sp->s_bufp - sp->s_buf > sizeof(u_int16_t))) {				HEADER *hp;				hp = (HEADER *)sp->s_buf;				hp->qr = 1;				hp->ra = 1;				hp->ancount = 0;				hp->qdcount = 0;				hp->nscount = 0;				hp->arcount = 0;				hp->rcode = SERVFAIL;				(void) writemsg(sp->s_rfd, sp->s_buf,						sizeof(HEADER));				continue;			}			if ((n == -1) && (errno == PORT_WOULDBLK))				continue;			if (n <= 0) {				sqrm(sp);				continue;			}			/*			 * Consult database to get the answer.			 */			if (sp->s_size == 0) {				sq_query(sp);				ns_req(sp->s_buf,				       sp->s_bufp - sp->s_buf,				       sp->s_bufsize, sp,				       &sp->s_from, -1);				/* ns_req() can call sqrm() - check for it */				if (sq_here(sp)) {					sp->s_bufp = (u_char *)&sp->s_tempsize;					sp->s_size = -1;				}				continue;			}		}	}	/* NOTREACHED */}voidgetnetconf(){	register struct netinfo *ntp;	struct netinfo *ontp;	struct ifconf ifc;	struct ifreq ifreq, *ifr;	struct	qdatagram *dqp, *pqp, *nqp;	static int first = 1;	char buf[BUFSIZ], *cp, *cplim;	u_int32_t nm;	time_t my_generation = time(NULL);	ifc.ifc_len = sizeof(buf);	ifc.ifc_buf = buf;	if (ioctl(vs, SIOCGIFCONF, (char *)&ifc) < 0) {		syslog(LOG_ERR, "get interface configuration: %m - exiting");		exit(1);	}	ntp = NULL;#if defined(AF_LINK) && !defined(RISCOS_BSD)#define my_max(a, b) (a > b ? a : b)#define my_size(p)	my_max((p).sa_len, sizeof(p))#else#define my_size(p) (sizeof (p))#endif	cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */	for (cp = buf;	     cp < cplim;	     cp += sizeof (ifr->ifr_name) + my_size(ifr->ifr_addr)) {#undef my_size		ifr = (struct ifreq *)cp;		if (ifr->ifr_addr.sa_family != AF_INET ||		   ((struct sockaddr_in *)		    &ifr->ifr_addr)->sin_addr.s_addr == 0) {			continue;		}		ifreq = *ifr;		/*		 * Don't test IFF_UP, packets may still be received at this		 * address if any other interface is up.		 */#if !defined(BSD) || (BSD < 199103)		if (ioctl(vs, SIOCGIFADDR, (char *)&ifreq) < 0) {			syslog(LOG_ERR, "get interface addr: %m");			continue;		}#endif		dprintf(1, (ddt, "considering [%s]\n",			    inet_ntoa(((struct sockaddr_in *)				       &ifreq.ifr_addr)->sin_addr)));		/* build datagram queue */		/* 		 * look for an already existing source interface address.		 * This happens mostly when reinitializing.  Also, if		 * the machine has multiple point to point interfaces, then 		 * the local address may appear more than once.		 */		if (dqp = aIsUs(((struct sockaddr_in *)&ifreq.ifr_addr)				->sin_addr)) {			dprintf(1, (ddt,				    "dup interface address %s on %s\n",				    inet_ntoa(((struct sockaddr_in *)					       &ifreq.ifr_addr)->sin_addr),				    ifreq.ifr_name));			dqp->dq_gen = my_generation;			continue;		}		/*		 * Skip over address 0.0.0.0 since this will conflict		 * with binding to wildcard address later.  Interfaces		 * which are not completely configured can have this addr.		 */		if (((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr		    == 0x00000000) {	/* XXX */			dprintf(1, (ddt, "skipping address 0.0.0.0 on %s\n",				    ifreq.ifr_name));			continue;		}		if ((dqp = (struct qdatagram *)			   calloc(1, sizeof(struct qdatagram))		     ) == NULL) {			dprintf(5, (ddt, "getnetconf: malloc error\n"));			syslog(LOG_ERR, "getnetconf: Out Of Memory");			exit(12);		}		dqp->dq_next = datagramq;		datagramq = dqp;		dqp->dq_addr = ((struct sockaddr_in *)				&ifreq.ifr_addr)->sin_addr;		dqp->dq_gen = my_generation;		opensocket(dqp);		dprintf(1, (ddt, "listening [%s]\n",			    inet_ntoa(((struct sockaddr_in *)				       &ifreq.ifr_addr)->sin_addr)));		/*		 * Add interface to list of directly-attached (sub)nets		 * for use in sorting addresses.		 */		if (ntp == NULL) {			ntp = (struct netinfo *)malloc(sizeof(struct netinfo));		}		ntp->my_addr = ((struct sockaddr_in *)				&ifreq.ifr_addr)->sin_addr;#ifdef SIOCGIFNETMASK		if (ioctl(vs, SIOCGIFNETMASK, (char *)&ifreq) < 0) {			syslog(LOG_ERR, "get netmask: %m");			ntp->mask = net_mask(ntp->my_addr);		} else			ntp->mask = ((struct sockaddr_in *)			    &ifreq.ifr_addr)->sin_addr.s_addr;#else		/* 4.2 does not support subnets */		ntp->mask = net_mask(ntp->my_addr);#endif		if (ioctl(vs, SIOCGIFFLAGS, (char *)&ifreq) < 0) {			syslog(LOG_ERR, "get interface flags: %m");			continue;		}#ifdef IFF_LOOPBACK		if (ifreq.ifr_flags & IFF_LOOPBACK)#else		/* test against 127.0.0.1 (yuck!!) */		if (ntp->my_addr.s_addr == inet_addr("127.0.0.1"))  /* XXX */#endif		{			if (netloop.my_addr.s_addr == 0) {				netloop.my_addr = ntp->my_addr;				netloop.mask = 0xffffffff;				netloop.net = ntp->my_addr.s_addr;				dprintf(1, (ddt, "loopback address: x%lx\n",					    netloop.my_addr.s_addr));			}			continue;		} else if ((ifreq.ifr_flags & IFF_POINTOPOINT)) {			if (ioctl(vs, SIOCGIFDSTADDR, (char *)&ifreq) < 0) {				syslog(LOG_ERR, "get dst addr: %m");				continue;			}			ntp->mask = 0xffffffff;			ntp->net = ((struct sockaddr_in *)				    &ifreq.ifr_addr)->sin_addr.s_addr;		} else {			ntp->net = ntp->mask & ntp->my_addr.s_addr;		}		/*		 * Place on end of list of locally-attached (sub)nets,		 * but before logical nets for subnetted nets.		 */		ntp->next = *elocal;		*elocal = ntp;		if (elocal == enettab)			enettab = &ntp->next;		elocal = &ntp->next;		ntp = NULL;	}	if (ntp)		(void) free((char *)ntp);	/*	 * now go through the datagramq and delete anything that	 * does not have the current generation number.  this is	 * how we catch interfaces that go away or change their	 * addresses.  note that 0.0.0.0 is the wildcard element	 * and should never be deleted by this code.	 *	 * XXX - need to update enettab/elocal as well.	 */	for (pqp = NULL, dqp = datagramq;	     dqp != NULL;	     pqp = dqp, dqp = nqp) {		nqp = dqp->dq_next;		if ((dqp->dq_addr.s_addr != INADDR_ANY)		    && (dqp->dq_gen != my_generation)		    ) {

⌨️ 快捷键说明

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