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

📄 ntp_io.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 5 页
字号:
			stoa(addr));		exit(1);		/*NOTREACHED*/	}#elif defined(FNDELAY)	if (fcntl(fd, F_SETFL, FNDELAY) < 0)	{		netsyslog(LOG_ERR, "fcntl(FNDELAY) fails on address %s: %m",			stoa(addr));		exit(1);		/*NOTREACHED*/	}#elif defined(O_NDELAY) /* generally the same as FNDELAY */	if (fcntl(fd, F_SETFL, O_NDELAY) < 0)	{		netsyslog(LOG_ERR, "fcntl(O_NDELAY) fails on address %s: %m",			stoa(addr));		exit(1);		/*NOTREACHED*/	}#elif defined(FIONBIO)# if defined(SYS_WINNT)		if (ioctlsocket(fd,FIONBIO,(u_long *) &on) == SOCKET_ERROR)# else		if (ioctl(fd,FIONBIO,&on) < 0)# endif	{		netsyslog(LOG_ERR, "ioctl(FIONBIO) fails on address %s: %m",			stoa(addr));		exit(1);		/*NOTREACHED*/	}#elif defined(FIOSNBIO)	if (ioctl(fd,FIOSNBIO,&on) < 0)	{		netsyslog(LOG_ERR, "ioctl(FIOSNBIO) fails on address %s: %m",			stoa(addr));		exit(1);		/*NOTREACHED*/	}#else# include "Bletch: Need non-blocking I/O!"#endif#ifdef HAVE_SIGNALED_IO	init_socket_sig(fd);#endif /* not HAVE_SIGNALED_IO */	/*	 *	Turn off the SO_REUSEADDR socket option.  It apparently	 *	causes heartburn on systems with multicast IP installed.	 *	On normal systems it only gets looked at when the address	 *	is being bound anyway..	 */	if (turn_off_reuse)	    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,			   (char *)&off, sizeof(off)))	    {		    netsyslog(LOG_ERR, "setsockopt SO_REUSEADDR off fails on address %s: %m",			    stoa(addr));	    }#if !defined(SYS_WINNT) && !defined(VMS)# ifdef DEBUG	if (debug > 1)	    printf("flags for fd %d: 0%o\n", fd,		   fcntl(fd, F_GETFL, 0));# endif#endif /* SYS_WINNT || VMS */#if defined (HAVE_IO_COMPLETION_PORT)/* * Add the socket to the completion port */	io_completion_port_add_socket(fd, interf);#endif	return fd;}/* * close_socket - close a socket and remove from the activefd list */static voidclose_socket(	     SOCKET fd	){	SOCKET i, newmax;	if (fd < 0)		return;	(void) closesocket(fd);	/*	 * I/O Completion Ports don't care about select and fd_set	 */#ifndef HAVE_IO_COMPLETION_PORT	FD_CLR( (u_int) fd, &activefds);	if (fd == maxactivefd) {		newmax = 0;		for (i = 0; i < maxactivefd; i++)			if (FD_ISSET(i, &activefds))				newmax = i;		maxactivefd = newmax;	}#endif	delete_socket_from_list(fd);}/* * close_file - close a file and remove from the activefd list * added 1/31/1997 Greg Schueman for Windows NT portability */#ifdef REFCLOCKstatic voidclose_file(	SOCKET fd	){	int i, newmax;	if (fd < 0)		return;	(void) close(fd);#ifndef HAVE_IO_COMPLETION_PORT	/*	 * I/O Completion Ports don't care about select and fd_set	 */	FD_CLR( (u_int) fd, &activefds);	if (fd == maxactivefd) {		newmax = 0;		for (i = 0; i < maxactivefd; i++)			if (FD_ISSET(i, &activefds))				newmax = i;		maxactivefd = newmax;	}#endif	delete_socket_from_list(fd);}#endif/* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c *//* * sendpkt - send a packet to the specified destination. Maintain a * send error cache so that only the first consecutive error for a * destination is logged. */voidsendpkt(	struct sockaddr_storage *dest,	struct interface *inter,	int ttl,	struct pkt *pkt,	int len	){	int cc, slot;#ifdef SYS_WINNT	DWORD err;#endif /* SYS_WINNT */	/*	 * Send error caches. Empty slots have port == 0	 * Set ERRORCACHESIZE to 0 to disable	 */	struct cache {		u_short port;		struct	in_addr addr;	};#ifdef INCLUDE_IPV6_SUPPORT	struct cache6 {		u_short port;		struct in6_addr addr;	};#endif /* INCLUDE_IPV6_SUPPORT */#ifndef ERRORCACHESIZE#define ERRORCACHESIZE 8#endif#if ERRORCACHESIZE > 0	static struct cache badaddrs[ERRORCACHESIZE];#ifdef INCLUDE_IPV6_SUPPORT	static struct cache6 badaddrs6[ERRORCACHESIZE];#endif /* INCLUDE_IPV6_SUPPORT */#else#define badaddrs ((struct cache *)0)		/* Only used in empty loops! */#ifdef INCLUDE_IPV6_SUPPORT#define badaddrs6 ((struct cache6 *)0)		/* Only used in empty loops! */#endif /* INCLUDE_IPV6_SUPPORT */#endif#ifdef DEBUG	if (debug > 1)	    printf("%ssendpkt(fd=%d dst=%s, src=%s, ttl=%d, len=%d)\n",		   (ttl > 0) ? "\tMCAST\t*****" : "",		   inter->fd, stoa(dest),		   stoa(&inter->sin), ttl, len);#endif#ifdef MCAST	switch (inter->sin.ss_family) {	case AF_INET :		/*		* for the moment we use the bcast option to set multicast ttl		*/		if (ttl > 0 && ttl != inter->last_ttl) {			/*			* set the multicast ttl for outgoing packets			*/			u_char mttl = (u_char) ttl;			if (setsockopt(inter->fd, IPPROTO_IP, IP_MULTICAST_TTL,				(const void *) &mttl, sizeof(mttl)) != 0) {				netsyslog(LOG_ERR, "setsockopt IP_MULTICAST_TTL fails on address %s: %m",					stoa(&inter->sin));			}			else   				inter->last_ttl = ttl;		}		break;#ifdef INCLUDE_IPV6_SUPPORT	case AF_INET6 :	 	/*		 * for the moment we use the bcast option to set		 * multicast max hops		 */        	if (ttl > 0 && ttl != inter->last_ttl) {                	/*                 	* set the multicast ttl for outgoing packets                 	*/			u_int ittl = (u_int) ttl;                	if (setsockopt(inter->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,                    	(const void *) &ittl, sizeof(ittl)) == -1)	                        netsyslog(LOG_ERR, "setsockopt IP_MULTICAST_TTL fails on address %s: %m",					stoa(&inter->sin));                	else	                        inter->last_ttl = ttl;	        }	        break;#endif /* INCLUDE_IPV6_SUPPORT */	default :		exit(1);	}#endif /* MCAST */	for (slot = ERRORCACHESIZE; --slot >= 0; )		if(dest->ss_family == AF_INET) {			if (badaddrs[slot].port == ((struct sockaddr_in*)dest)->sin_port &&				badaddrs[slot].addr.s_addr == ((struct sockaddr_in*)dest)->sin_addr.s_addr)			break;		}#ifdef INCLUDE_IPV6_SUPPORT		else if (dest->ss_family == AF_INET6) {			if (badaddrs6[slot].port == ((struct sockaddr_in6*)dest)->sin6_port &&				badaddrs6[slot].addr.s6_addr == ((struct sockaddr_in6*)dest)->sin6_addr.s6_addr)			break;		}#endif /* INCLUDE_IPV6_SUPPORT */		else exit(1);  /* address family not supported yet */#if defined(HAVE_IO_COMPLETION_PORT)        err = io_completion_port_sendto(inter, pkt, len, dest);	if (err != ERROR_SUCCESS)#else#ifdef SIM        cc = srvr_rply(&ntp_node,  dest, inter, pkt);#else /* SIM */	cc = sendto(inter->fd, (char *)pkt, (unsigned int)len, 0, (struct sockaddr *)dest,		    SOCKLEN(dest));#endif /* SIM */	if (cc == -1)#endif	{		inter->notsent++;		packets_notsent++;#if defined(HAVE_IO_COMPLETION_PORT)		err = WSAGetLastError();		if (err != WSAEWOULDBLOCK && err != WSAENOBUFS && slot < 0)#else		if (errno != EWOULDBLOCK && errno != ENOBUFS && slot < 0)#endif		{			/*			 * Remember this, if there's an empty slot			 */			switch (dest->ss_family) {			case AF_INET :				for (slot = ERRORCACHESIZE; --slot >= 0; )					if (badaddrs[slot].port == 0)					{						badaddrs[slot].port = SRCPORT(dest);						badaddrs[slot].addr = ((struct sockaddr_in*)dest)->sin_addr;						break;					}				break;#ifdef INCLUDE_IPV6_SUPPORT			case AF_INET6 :				for (slot = ERRORCACHESIZE; --slot >= 0; )        				if (badaddrs6[slot].port == 0)            				{                                    		badaddrs6[slot].port = SRCPORT(dest);                                    		badaddrs6[slot].addr = ((struct sockaddr_in6*)dest)->sin6_addr;                                    		break;                            		}                		break;#endif /* INCLUDE_IPV6_SUPPORT */			default :				exit(1);			}			netsyslog(LOG_ERR, "sendto(%s) (fd=%d): %m",				  stoa(dest), inter->fd);		}	}	else	{		inter->sent++;		packets_sent++;		/*		 * He's not bad any more		 */		if (slot >= 0)		{			netsyslog(LOG_INFO, "Connection re-established to %s", stoa(dest));			switch (dest->ss_family) {			case AF_INET :				badaddrs[slot].port = 0;				break;#ifdef INCLUDE_IPV6_SUPPORT			case AF_INET6 :				badaddrs6[slot].port = 0;				break;#endif /* INCLUDE_IPV6_SUPPORT */			}		}	}}#if !defined(HAVE_IO_COMPLETION_PORT)/* * fdbits - generate ascii representation of fd_set (FAU debug support) * HFDF format - highest fd first. */static char *fdbits(	int count,	fd_set *set	){	static char buffer[256];	char * buf = buffer;	count = (count < 256) ? count : 255;	while (count >= 0)	{		*buf++ = FD_ISSET(count, set) ? '#' : '-';		count--;	}	*buf = '\0';	return buffer;}/* * Routine to read the refclock packets for a specific interface * Return the number of bytes read. That way we know if we should * read it again or go on to the next one if no bytes returned */static inline intread_refclock_packet(SOCKET fd, struct refclockio *rp, l_fp ts){	int i;	int buflen;	register struct recvbuf *rb;	if (free_recvbuffs() == 0)	{		char buf[RX_BUFF_SIZE];		buflen = read(fd, buf, sizeof buf);		packets_dropped++;		return (buflen);	/* Return what we found */	}	rb = get_free_recv_buffer();	i = (rp->datalen == 0	    || rp->datalen > sizeof(rb->recv_space))	    ? sizeof(rb->recv_space) : rp->datalen;	buflen = read(fd, (char *)&rb->recv_space, (unsigned)i);	if (buflen < 0)	{		if (errno != EINTR && errno != EAGAIN) {			netsyslog(LOG_ERR, "clock read fd %d: %m", fd);		}		freerecvbuf(rb);		return (0);	}	/*	 * Got one. Mark how and when it got here,	 * put it on the full list and do bookkeeping.	 */	rb->recv_length = buflen;	rb->recv_srcclock = rp->srcclock;	rb->dstadr = 0;	rb->fd = fd;	rb->recv_time = ts;	rb->receiver = rp->clock_recv;	if (rp->io_input)	{		/*		 * have direct input routine for refclocks		 */		if (rp->io_input(rb) == 0)		{			/*			 * data was consumed - nothing to pass up			 * into block input machine			 */			freerecvbuf(rb);			return (buflen);		}	}		add_full_recv_buffer(rb);	rp->recvcount++;	packets_received++;	return (buflen);}/* * Routine to read the network NTP packets for a specific interface * Return the number of bytes read. That way we know if we should * read it again or go on to the next one if no bytes returned */static inline intread_network_packet(SOCKET fd, struct interface *itf, l_fp ts){	int fromlen;	int buflen;	register struct recvbuf *rb;	/*	 * Get a buffer and read the frame.  If we	 * haven't got a buffer, or this is received	 * on a disallowed socket, just dump the	 * packet.	 */	if (free_recvbuffs() == 0 || itf->ignore_packets == ISC_TRUE)	{		char buf[RX_BUFF_SIZE];		struct sockaddr_storage from;		fromlen = sizeof from;		buflen = recvfrom(fd, buf, sizeof(buf), 0,				(struct sockaddr*)&from, &fromlen);#ifdef DEBUG		if (debug > 3)			printf("%s on (%lu) fd=%d from %s\n",			(itf->ignore_packets == ISC_TRUE) ? "ignore" : "drop",			free_recvbuffs(), fd,			stoa(&from));#endif		if (itf->ignore_packets == ISC_TRUE)			packets_ignored++;		else			packets_dropped++;		return (buflen);	}	rb = get_free_recv_buffer();	fromlen = sizeof(struct sockaddr_storage);	rb->recv_length = recvfrom(fd,			  (char *)&rb->recv_space,			   sizeof(rb->recv_space), 0,			   (struct sockaddr *)&rb->recv_srcadr,			   &fromlen);	if (rb->recv_length == 0|| (rb->recv_length == -1 && 	    (errno==EWOULDBLOCK#ifdef EAGAIN	   || errno==EAGAIN#endif	 ))) {		freerecvbuf(rb);		return (rb->recv_length);	}	else if (rb->recv_length < 0)	{		netsyslog(LOG_ERR, "recvfrom(%s) fd=%d: %m",		stoa(&rb->recv_srcadr), fd);#ifdef DEBUG		if (debug)			printf("input_handler: fd=%d dropped (bad recvfrom)\n", fd);#endif		freerecvbuf(rb);

⌨️ 快捷键说明

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