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

📄 ntp_io.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 5 页
字号:
			netsyslog(LOG_ERR,			"setsockopt IPV6_LEAVE_GROUP failure: %m on socket %d, addr %s for %d(%s)",			iface->fd, stoa(&iface->sin),			mreq6.ipv6mr_interface, stoa(maddr));			return ISC_FALSE;		}		break;#else		return ISC_FALSE;#endif	/* INCLUDE_IPV6_MULTICAST_SUPPORT */	}	iface->num_mcast--;	if (iface->num_mcast <= 0) {		iface->flags &= ~INT_MCASTOPEN;		modify_addr_in_list(maddr, iface->flags);	}	return ISC_TRUE;}#endif	/* MCAST *//* * io_setbclient - open the broadcast client sockets */voidio_setbclient(void){#ifdef OPEN_BCAST_SOCKET 	int i;	int nif = 0;	isc_boolean_t jstatus; 	SOCKET fd;	set_reuseaddr(1);	for (i = nwilds; i < ninterfaces; i++) {		/* use only allowed addresses */		if (inter_list[i].ignore_packets == ISC_TRUE)			continue;		/* Only IPv4 addresses are valid for broadcast */		if (inter_list[i].sin.ss_family != AF_INET)			continue;		/* Is this a broadcast address? */		if (!(inter_list[i].flags & INT_BROADCAST))			continue;		/* Skip the loopback addresses */		if (inter_list[i].flags & INT_LOOPBACK)			continue;		/* Do we already have the broadcast address open? */		if (inter_list[i].flags & INT_BCASTOPEN)			continue;		/*		 * Try to open the broadcast address		 */		inter_list[i].family = AF_INET;		inter_list[i].bfd = open_socket(&inter_list[i].bcast,				    INT_BROADCAST, 1, &inter_list[i], i);		 /*		 * If we succeeded then we use it otherwise		 * enable the underlying address		 */		if (inter_list[i].bfd == INVALID_SOCKET) {			fd = inter_list[i].fd;		}		else {			fd = inter_list[i].bfd;		}		/* Enable Broadcast on socket */		jstatus = socket_broadcast_enable(&inter_list[i], fd, &inter_list[i].sin);		if (jstatus == ISC_TRUE)		{			nif++;			netsyslog(LOG_INFO,"io_setbclient: Opened broadcast client on interface %d, socket: %d",				i, fd);		}	}	set_reuseaddr(0);#ifdef DEBUG	if (debug)		if (nif > 0)			printf("io_setbclient: Opened broadcast clients\n");#endif		if (nif == 0)			netsyslog(LOG_ERR, "Unable to listen for broadcasts, no broadcast interfaces available");#else	netsyslog(LOG_ERR, "io_setbclient: Broadcast Client disabled by build");#endif}/* * io_unsetbclient - close the broadcast client sockets */voidio_unsetbclient(void){#ifdef OPEN_BCAST_SOCKET	int i;	isc_boolean_t lstatus;	for (i = nwilds; i < ninterfaces; i++)	{		if (!(inter_list[i].flags & INT_BCASTOPEN))		    continue;		lstatus = socket_broadcast_disable(&inter_list[i], i, &inter_list[i].sin);	}#endif}voidio_multicast_add(	struct sockaddr_storage addr	){#ifdef MCAST	int i;	isc_boolean_t jstatus;	int ind;	int lscope = 0;	/*	 * Check to see if this is a multicast address	 */	if (addr_ismulticast(&addr) == ISC_FALSE)		return;	/* If we already have it we can just return */	ind = find_flagged_addr_in_list(&addr, INT_MCASTOPEN);	if (ind >= 0)	{		netsyslog(LOG_INFO, "Duplicate request found for multicast address %s",			stoa(&addr));		return;	}#ifndef MULTICAST_NONEWSOCKET	/*	 * Find an empty slot to use	 */	ind = -1;	for (i = nwilds; i < ninterfaces; i++) {		/* found a free slot */		if (SOCKNUL(&inter_list[i].sin) &&		    inter_list[i].fd <= 0 && inter_list[i].bfd <= 0)		{			ind = i;			break;		}	}	/*	 * We didn't find a slot and nothing available. Log and return	 */	if (ind < 0 && ninterfaces >= MAXINTERFACES)	{		netsyslog(LOG_ERR,		"No interface available to use for address %s",		stoa(&addr));		return;	}	else	{		ind = ninterfaces;	}	/*	 * Open a new socket for the multicast address	 */	memset((char *)&inter_list[ind], 0, sizeof(struct interface));	inter_list[ind].sin.ss_family = addr.ss_family;	inter_list[ind].family = addr.ss_family;	switch(addr.ss_family) {	case AF_INET:		memcpy(&(((struct sockaddr_in *)&inter_list[ind].sin)->sin_addr),		       &(((struct sockaddr_in*)&addr)->sin_addr),		       sizeof(struct in_addr));		((struct sockaddr_in*)&inter_list[ind].sin)->sin_port = htons(NTP_PORT);		memset(&((struct sockaddr_in*)&inter_list[ind].mask)->sin_addr.s_addr, 0xff, sizeof(struct in_addr));		break;	case AF_INET6:#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT		memcpy(&(((struct sockaddr_in6 *)&inter_list[ind].sin)->sin6_addr),		       &((struct sockaddr_in6*)&addr)->sin6_addr,		       sizeof(struct in6_addr));		((struct sockaddr_in6*)&inter_list[ind].sin)->sin6_port = htons(NTP_PORT);#ifdef ISC_PLATFORM_HAVESCOPEID		((struct sockaddr_in6*)&inter_list[ind].sin)->sin6_scope_id = ((struct sockaddr_in6*)&addr)->sin6_scope_id;#endif		memset(&((struct sockaddr_in6*)&inter_list[ind].mask)->sin6_addr.s6_addr, 0xff, sizeof(struct in6_addr));#endif		i = findlocalcastinterface(&addr, INT_MULTICAST);# ifdef ISC_PLATFORM_HAVESCOPEID		if (i >= 0)			lscope = ((struct sockaddr_in6*)&inter_list[i].sin)->sin6_scope_id;# endif#ifdef DEBUG	if (debug > 1)		printf("Found interface index %d, scope: %d for address %s\n",			i, lscope, stoa(&addr));#endif		break;	}	set_reuseaddr(1);	inter_list[ind].bfd = INVALID_SOCKET;	inter_list[ind].fd = open_socket(&inter_list[ind].sin,			    INT_MULTICAST, 1, &inter_list[ind], ind);	set_reuseaddr(0);	if (inter_list[ind].fd != INVALID_SOCKET)	{		inter_list[ind].bfd = INVALID_SOCKET;		inter_list[ind].ignore_packets = ISC_FALSE;		(void) strncpy(inter_list[ind].name, "multicast",			sizeof(inter_list[ind].name));		((struct sockaddr_in*)&inter_list[ind].mask)->sin_addr.s_addr =						htonl(~(u_int32)0);		if (ind >= ninterfaces)			ninterfaces = ind + 1;#ifdef DEBUG		if(debug > 1)			print_interface(ind);#endif	}	else	{		memset((char *)&inter_list[ind], 0, sizeof(struct interface));		ind = -1;		if (addr.ss_family == AF_INET)			ind = wildipv4;		else if (addr.ss_family == AF_INET6)			ind = wildipv6;		if (ind >= 0) {			/* HACK ! -- stuff in an address */			inter_list[ind].bcast = addr;			netsyslog(LOG_ERR,			 "...multicast address %s using wildcard socket",			 stoa(&addr));		} else {			netsyslog(LOG_ERR,			"No multicast socket available to use for address %s",			stoa(&addr));			return;		}	}#else	/*	 * For the case where we can't use a separate socket	 */	ind = findlocalcastinterface(&addr, INT_MULTICAST);#endif	/*	 * If we don't have a valid socket, just return	 */	if (ind < 0)	{		netsyslog(LOG_ERR,		"Cannot add multicast address %s: Cannot find slot",		stoa(&addr));		return;	}	jstatus = socket_multicast_enable(&inter_list[ind], ind, lscope, &addr);	if (jstatus == ISC_TRUE)		netsyslog(LOG_INFO, "Added Multicast Listener %s on interface %d\n", stoa(&addr), ind);	else		netsyslog(LOG_ERR, "Failed to add Multicast Listener %s\n", stoa(&addr));#else /* MCAST */	netsyslog(LOG_ERR,	    "Cannot add multicast address %s: no Multicast support",	    stoa(&addr));#endif /* MCAST */	return;}/* * io_multicast_del() - delete multicast group address */voidio_multicast_del(	struct sockaddr_storage addr	){#ifdef MCAST	int i;	isc_boolean_t lstatus;	/*	 * Check to see if this is a multicast address	 */	if (addr_ismulticast(&addr) == ISC_FALSE)	{		netsyslog(LOG_ERR,			 "invalid multicast address %s", stoa(&addr));		return;	}	switch (addr.ss_family)	{	case AF_INET :		/*		 * Disable reception of multicast packets		 */		i = find_flagged_addr_in_list(&addr, INT_MCASTOPEN);		while ( i > 0) {			lstatus = socket_multicast_disable(&inter_list[i], i, &addr);			i = find_flagged_addr_in_list(&addr, INT_MCASTOPEN);		}		break;#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT	case AF_INET6 :		/*		* Disable reception of multicast packets		*/		for (i = 0; i < ninterfaces; i++)		{			/* Be sure it's the correct family */			if (inter_list[i].sin.ss_family != AF_INET6)				continue;			if (!(inter_list[i].flags & INT_MCASTOPEN))				continue;			if (!(inter_list[i].fd < 0))				continue;			if (!SOCKCMP(&addr, &inter_list[i].sin))				continue;			lstatus = socket_multicast_disable(&inter_list[i], i, &addr);		}		break;#endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */	}/* switch */        delete_addr_from_list(&addr);#else /* not MCAST */	netsyslog(LOG_ERR, "this function requires multicast kernel");#endif /* not MCAST */}/* * open_socket - open a socket, returning the file descriptor */static SOCKETopen_socket(	struct sockaddr_storage *addr,	int flags,	int turn_off_reuse,	struct interface *interf,	int ind	){	int errval;	SOCKET fd;	int on = 1, off = 0;#if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS)	int tos;#endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */	if ((addr->ss_family == AF_INET6) && (isc_net_probeipv6() != ISC_R_SUCCESS))		return (INVALID_SOCKET);	/* create a datagram (UDP) socket */#ifndef SYS_WINNT	if (  (fd = socket(addr->ss_family, SOCK_DGRAM, 0)) < 0) {		errval = errno;#else	if (  (fd = socket(addr->ss_family, SOCK_DGRAM, 0)) == INVALID_SOCKET) {		errval = WSAGetLastError();#endif		if(addr->ss_family == AF_INET)			netsyslog(LOG_ERR, "socket(AF_INET, SOCK_DGRAM, 0) failed on address %s: %m",				stoa(addr));		else if(addr->ss_family == AF_INET6)			netsyslog(LOG_ERR, "socket(AF_INET6, SOCK_DGRAM, 0) failed on address %s: %m",				stoa(addr));#ifndef SYS_WINNT		if (errval == EPROTONOSUPPORT || errval == EAFNOSUPPORT ||		    errval == EPFNOSUPPORT)#else		if (errval == WSAEPROTONOSUPPORT || errval == WSAEAFNOSUPPORT ||		    errval == WSAEPFNOSUPPORT)#endif			return (INVALID_SOCKET);		exit(1);		/*NOTREACHED*/	}#ifdef SYS_WINNT	if (connection_reset_fix(fd) != ISC_R_SUCCESS) {		netsyslog(LOG_ERR, "connection_reset_fix(fd) failed on address %s: %m",			stoa(addr));	}#endif /* SYS_WINNT */	/* set SO_REUSEADDR since we will be binding the same port	   number on each interface */	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,		       (char *)&on, sizeof(on)))	{		netsyslog(LOG_ERR, "setsockopt SO_REUSEADDR on fails on address %s: %m",			stoa(addr));	}	/*	 * IPv4 specific options go here	 */	if (addr->ss_family == AF_INET) {#if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS)	/* set IP_TOS to minimize packet delay */		tos = IPTOS_LOWDELAY;		if (setsockopt(fd, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(tos)) < 0)		{			netsyslog(LOG_ERR, "setsockopt IPTOS_LOWDELAY on fails on address %s: %m",				stoa(addr));		}#endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */	}	/*	 * IPv6 specific options go here	 */        if (addr->ss_family == AF_INET6) {#if defined(IPV6_V6ONLY)                if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,                	(char*)&on, sizeof(on)))                {                	netsyslog(LOG_ERR, "setsockopt IPV6_V6ONLY on fails on address %s: %m",				stoa(addr));		}#endif /* IPV6_V6ONLY */#if defined(IPV6_BINDV6ONLY)                if (setsockopt(fd, IPPROTO_IPV6, IPV6_BINDV6ONLY,                	(char*)&on, sizeof(on)))                {                	netsyslog(LOG_ERR,			    "setsockopt IPV6_BINDV6ONLY on fails on address %s: %m",			    stoa(addr));		}#endif /* IPV6_BINDV6ONLY */	}	/*	 * bind the local address.	 */	if (bind(fd, (struct sockaddr *)addr, SOCKLEN(addr)) < 0) {		char buff[160];		if(addr->ss_family == AF_INET)			sprintf(buff,				"bind() fd %d, family %d, port %d, addr %s, in_classd=%d flags=%d fails: %%m",				fd, addr->ss_family, (int)ntohs(((struct sockaddr_in*)addr)->sin_port),				stoa(addr),				IN_CLASSD(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr)), flags);#ifdef INCLUDE_IPV6_SUPPORT		else if(addr->ss_family == AF_INET6)		                sprintf(buff,                                "bind() fd %d, family %d, port %d, scope %d, addr %s, in6_is_addr_multicast=%d flags=%d fails: %%m",                                fd, addr->ss_family, (int)ntohs(((struct sockaddr_in6*)addr)->sin6_port),# ifdef ISC_PLATFORM_HAVESCOPEID                                ((struct sockaddr_in6*)addr)->sin6_scope_id# else                                -1# endif				, stoa(addr),                                IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)addr)->sin6_addr), flags);#endif		else 			return (INVALID_SOCKET);		/*		 * Don't log this under all conditions		 */		if (turn_off_reuse == 0 || debug > 1)			netsyslog(LOG_ERR, buff);		closesocket(fd);		return (INVALID_SOCKET);	}#ifdef DEBUG	if (debug)	    printf("bind() fd %d, family %d, port %d, addr %s, flags=%d\n",		   fd,		   addr->ss_family,		   (int)ntohs(((struct sockaddr_in*)addr)->sin_port),		   stoa(addr),		   flags);#endif	/*	 * I/O Completion Ports don't care about the select and FD_SET	 */#ifndef HAVE_IO_COMPLETION_PORT	if (fd > maxactivefd)	    maxactivefd = fd;	FD_SET(fd, &activefds);#endif	add_socket_to_list(fd);	add_addr_to_list(addr, ind, interf->flags);	/*	 * set non-blocking,	 */#ifdef USE_FIONBIO	/* in vxWorks we use FIONBIO, but the others are defined for old systems, so	 * all hell breaks loose if we leave them defined	 */#undef O_NONBLOCK#undef FNDELAY#undef O_NDELAY#endif#if defined(O_NONBLOCK) /* POSIX */	if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)	{		netsyslog(LOG_ERR, "fcntl(O_NONBLOCK) fails on address %s: %m",

⌨️ 快捷键说明

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