static void
dec_res_limited(void)
{
	res_limited_refcnt--;
	if (!res_limited_refcnt)
		mon_stop(MON_RES);
}
示例#2
0
文件: ntp_util.c 项目: sambuc/netbsd
/*
 * ntpd_time_stepped is called back by step_systime(), allowing ntpd
 * to do any one-time processing necessitated by the step.
 */
void
ntpd_time_stepped(void)
{
	u_int saved_mon_enabled;

	/*
	 * flush the monitor MRU list which contains l_fp timestamps
	 * which should not be compared across the step.
	 */
	if (MON_OFF != mon_enabled) {
		saved_mon_enabled = mon_enabled;
		mon_stop(MON_OFF);
		mon_start(saved_mon_enabled);
	}

	/* inform interpolating Windows code to allow time to go back */
#ifdef SYS_WINNT
	win_time_stepped();
#endif
}
示例#3
0
/*
 * hack_restrict - add/subtract/manipulate entries on the restrict list
 */
void
hack_restrict(
	int op,
	struct sockaddr_storage *resaddr,
	struct sockaddr_storage *resmask,
	int mflags,
	int flags
	)
{
	register u_int32 addr = 0;
	register u_int32 mask = 0;
	struct in6_addr addr6;
	struct in6_addr mask6;
	register struct restrictlist *rl = NULL;
	register struct restrictlist *rlprev = NULL;
	register struct restrictlist6 *rl6 = NULL;
	register struct restrictlist6 *rlprev6 = NULL;
	int i, addr_cmp, mask_cmp;
	memset(&addr6, 0, sizeof(struct in6_addr)); 
	memset(&mask6, 0, sizeof(struct in6_addr)); 

	if (resaddr->ss_family == AF_INET) {
		/*
		 * Get address and mask in host byte order
		 */
		addr = SRCADR(resaddr);
		mask = SRCADR(resmask);
		addr &= mask;		/* make sure low bits zero */

		/*
		 * If this is the default address, point at first on
		 * list. Else go searching for it.
		 */
		if (addr == 0) {
			rlprev = NULL;
			rl = restrictlist;
		} else {
			rlprev = restrictlist;
			rl = rlprev->next;
			while (rl != NULL) {
				if (rl->addr > addr) {
					rl = NULL;
					break;
				} else if (rl->addr == addr) {
					if (rl->mask == mask) {
						if ((mflags &
						    RESM_NTPONLY) ==
						    (rl->mflags &
						    RESM_NTPONLY))
							break;

						if (!(mflags &
						    RESM_NTPONLY)) {
							rl = NULL;
							break;
						}
					} else if (rl->mask > mask) {
						rl = NULL;
						break;
					}
				}
				rlprev = rl;
				rl = rl->next;
			}
		}
	}

	if (resaddr->ss_family == AF_INET6) {
		mask6 = GET_INADDR6(*resmask);
		SET_IPV6_ADDR_MASK(&addr6,
		    &GET_INADDR6(*resaddr), &mask6);
		if (IN6_IS_ADDR_UNSPECIFIED(&addr6)) {
			rlprev6 = NULL;
			rl6 = restrictlist6;
		} else {
			rlprev6 = restrictlist6;
			rl6 = rlprev6->next;
			while (rl6 != NULL) {
				addr_cmp = memcmp(&rl6->addr6, &addr6,
				    sizeof(addr6));
				if (addr_cmp > 0) {
					rl6 = NULL;
					break;
				} else if (addr_cmp == 0) {
					mask_cmp = memcmp(&rl6->mask6,
					    &mask6, sizeof(mask6));
					if (mask_cmp == 0) {
						if ((mflags &
						    RESM_NTPONLY) ==
						    (rl6->mflags &
						    RESM_NTPONLY))
							break;

						if (!(mflags &
						    RESM_NTPONLY)) {
							rl6 = NULL;
							break;
						}
					} else if (mask_cmp > 0) {
						rl6 = NULL;
						break;
					}
				}
				rlprev6 = rl6;
				rl6 = rl6->next;
			}
		}
	}

	/*
	 * In case the above wasn't clear :-), either rl now points
	 * at the entry this call refers to, or rl is zero and rlprev
	 * points to the entry prior to where this one should go in
	 * the sort.
	 */

	/*
	 * Switch based on operation
	 */
	if (resaddr->ss_family == AF_INET) {
		switch (op) {
		case RESTRICT_FLAGS:
			/*
			 * Here we add bits to the flags. If this is a
			 * new restriction add it.
			 */
			if (rl == NULL) {
				if (resfree == NULL) {
					rl = (struct restrictlist *)
					    emalloc(INCRESLIST *
					    sizeof(struct
					    restrictlist));
					memset((char *)rl, 0,
					    INCRESLIST * sizeof(struct
					    restrictlist));
					for (i = 0; i < INCRESLIST; i++) {
						rl->next = resfree;
						resfree = rl;
						rl++;
					}
					numresfree = INCRESLIST;
				}

				rl = resfree;
				resfree = rl->next;
				numresfree--;

				rl->addr = addr;
				rl->mask = mask;
				rl->mflags = (u_short)mflags;

				if (rlprev == NULL) {
					rl->next = restrictlist;
					restrictlist = rl;
				} else {
					rl->next = rlprev->next;
					rlprev->next = rl;
				}
				restrictcount++;
			}
			if ((rl->flags ^ (u_short)flags) &
			    RES_LIMITED) {
				res_limited_refcnt++;
				mon_start(MON_RES);
			}
			rl->flags |= (u_short)flags;
			break;

		case RESTRICT_UNFLAG:
			/*
			 * Remove some bits from the flags. If we didn't
			 * find this one, just return.
			 */
			if (rl != NULL) {
				if ((rl->flags ^ (u_short)flags) &
				    RES_LIMITED) {
					res_limited_refcnt--;
					if (res_limited_refcnt == 0)
						mon_stop(MON_RES);
				}
				rl->flags &= (u_short)~flags;
			}
			break;
	
		case RESTRICT_REMOVE:
		case RESTRICT_REMOVEIF:
			/*
			 * Remove an entry from the table entirely if we
			 * found one. Don't remove the default entry and
			 * don't remove an interface entry.
			 */
			if (rl != NULL
			    && rl->addr != htonl(INADDR_ANY)
			    && !(rl->mflags & RESM_INTERFACE && op != RESTRICT_REMOVEIF)) {
				if (rlprev != NULL) {
					rlprev->next = rl->next;
				} else {
					restrictlist = rl->next;
				}
				restrictcount--;
				if (rl->flags & RES_LIMITED) {
					res_limited_refcnt--;
					if (res_limited_refcnt == 0)
						mon_stop(MON_RES);
				}
				memset((char *)rl, 0,
				    sizeof(struct restrictlist));

				rl->next = resfree;
				resfree = rl;
				numresfree++;
			}
			break;

		default:
			break;
		}
	} else if (resaddr->ss_family == AF_INET6) {
		switch (op) {
		case RESTRICT_FLAGS:
			/*
			 * Here we add bits to the flags. If this is a
			 * new restriction add it.
			 */
			if (rl6 == NULL) {
				if (resfree6 == NULL) {
					rl6 = (struct
					    restrictlist6 *)emalloc(
					    INCRESLIST * sizeof(struct
					    restrictlist6));
					memset((char *)rl6, 0,
					    INCRESLIST * sizeof(struct
					    restrictlist6));

					for (i = 0; i < INCRESLIST;
					    i++) {
						rl6->next = resfree6;
						resfree6 = rl6;
						rl6++;
					}
					numresfree6 = INCRESLIST;
				}
				rl6 = resfree6;
				resfree6 = rl6->next;
				numresfree6--;
				rl6->addr6 = addr6;
				rl6->mask6 = mask6;
				rl6->mflags = (u_short)mflags;
				if (rlprev6 != NULL) {
					rl6->next = rlprev6->next;
					rlprev6->next = rl6;
				} else {
					rl6->next = restrictlist6;
					restrictlist6 = rl6;
				}
				restrictcount6++;
			}
			if ((rl6->flags ^ (u_short)flags) &
			    RES_LIMITED) {
				res_limited_refcnt6++;
				mon_start(MON_RES);
			}
			rl6->flags |= (u_short)flags;
			break;

		case RESTRICT_UNFLAG:
			/*
			 * Remove some bits from the flags. If we didn't
			 * find this one, just return.
			 */
			if (rl6 != NULL) {
				if ((rl6->flags ^ (u_short)flags) &
				    RES_LIMITED) {
					res_limited_refcnt6--;
					if (res_limited_refcnt6 == 0)
						mon_stop(MON_RES);
				}
				rl6->flags &= (u_short)~flags;
			}
			break;

		case RESTRICT_REMOVE:
		case RESTRICT_REMOVEIF:
			/*
			 * Remove an entry from the table entirely if we
			 * found one. Don't remove the default entry and
			 * don't remove an interface entry.
			 */
			if (rl6 != NULL &&
			    !IN6_IS_ADDR_UNSPECIFIED(&rl6->addr6)
			    && !(rl6->mflags & RESM_INTERFACE && op != RESTRICT_REMOVEIF)) {
				if (rlprev6 != NULL) {
					rlprev6->next = rl6->next;
				} else {
					restrictlist6 = rl6->next;
				}
				restrictcount6--;
				if (rl6->flags & RES_LIMITED) {
					res_limited_refcnt6--;
					if (res_limited_refcnt6 == 0)
						mon_stop(MON_RES);
				}
				memset((char *)rl6, 0,
				    sizeof(struct restrictlist6));
				rl6->next = resfree6;
				resfree6 = rl6;
				numresfree6++;
			}
			break;

		default:
			break;
		}
	}
}
/*
 * hack_restrict - add/subtract/manipulate entries on the restrict list
 */
void
hack_restrict(
	int op,
	struct sockaddr_in *resaddr,
	struct sockaddr_in *resmask,
	int mflags,
	int flags
	)
{
	register u_int32 addr;
	register u_int32 mask;
	register struct restrictlist *rl;
	register struct restrictlist *rlprev;
	int i;

	/*
	 * Get address and mask in host byte order
	 */
	addr = SRCADR(resaddr);
	mask = SRCADR(resmask);
	addr &= mask;		/* make sure low bits are zero */

	/*
	 * If this is the default address, point at first on list.  Else
	 * go searching for it.
	 */
	if (addr == htonl(INADDR_ANY)) {
		rlprev = 0;
		rl = restrictlist;
	} else {
		rlprev = restrictlist;
		rl = rlprev->next;
		while (rl != 0) {
			if (rl->addr > addr) {
				rl = 0;
				break;
			} else if (rl->addr == addr) {
				if (rl->mask == mask) {
					if ((mflags & RESM_NTPONLY)
					    == (rl->mflags & RESM_NTPONLY))
					    break;	/* exact match */
					if (!(mflags & RESM_NTPONLY)) {
						/*
						 * No flag fits before flag
						 */
						rl = 0;
						break;
					}
					/* continue on */
				} else if (rl->mask > mask) {
					rl = 0;
					break;
				}
			}
			rlprev = rl;
			rl = rl->next;
		}
	}
	/*
	 * In case the above wasn't clear :-), either rl now points
	 * at the entry this call refers to, or rl is zero and rlprev
	 * points to the entry prior to where this one should go in
	 * the sort.
	 */

	/*
	 * Switch based on operation
	 */
	switch (op) {
	    case RESTRICT_FLAGS:
		/*
		 * Here we add bits to the flags.  If this is a new
		 * restriction add it.
		 */
		if (rl == 0) {
			if (numresfree == 0) {
				rl = (struct restrictlist *) emalloc(
					INCRESLIST*sizeof(struct restrictlist));
				memset((char *)rl, 0,
				       INCRESLIST*sizeof(struct restrictlist));

				for (i = 0; i < INCRESLIST; i++) {
					rl->next = resfree;
					resfree = rl;
					rl++;
				}
				numresfree = INCRESLIST;
			}

			rl = resfree;
			resfree = rl->next;
			numresfree--;

			rl->addr = addr;
			rl->mask = mask;
			rl->mflags = (u_short)mflags;

			rl->next = rlprev->next;
			rlprev->next = rl;
			restrictcount++;
		}
		if ((rl->flags ^ (u_short)flags) & RES_LIMITED) {
			res_limited_refcnt++;
			mon_start(MON_RES); /* ensure data gets collected */
		}
		rl->flags |= (u_short)flags;
		break;
	
	    case RESTRICT_UNFLAG:
		/*
		 * Remove some bits from the flags.  If we didn't
		 * find this one, just return.
		 */
		if (rl != 0) {
			if ((rl->flags ^ (u_short)flags) & RES_LIMITED) {
				res_limited_refcnt--;
				if (res_limited_refcnt == 0)
				    mon_stop(MON_RES);
			}
			rl->flags &= (u_short)~flags;
		}
		break;
	
	    case RESTRICT_REMOVE:
		/*
		 * Remove an entry from the table entirely if we found one.
		 * Don't remove the default entry and don't remove an
		 * interface entry.
		 */
		if (rl != 0
		    && rl->addr != htonl(INADDR_ANY)
		    && !(rl->mflags & RESM_INTERFACE)) {
			rlprev->next = rl->next;
			restrictcount--;
			if (rl->flags & RES_LIMITED) {
				res_limited_refcnt--;
				if (res_limited_refcnt == 0)
				    mon_stop(MON_RES);
			}
			memset((char *)rl, 0, sizeof(struct restrictlist));

			rl->next = resfree;
			resfree = rl;
			numresfree++;
		}
		break;

	    default:
		/* Oh, well */
		break;
	}

	/* done! */
}