Ejemplo n.º 1
0
/*
 * mon_start - start up the monitoring software
 */
void
mon_start(
    int mode
)
{
    size_t octets;
    u_int min_hash_slots;

    if (MON_OFF == mode)		/* MON_OFF is 0 */
        return;
    if (mon_enabled) {
        mon_enabled |= mode;
        return;
    }
    if (0 == mon_mem_increments)
        mon_getmoremem();
    /*
     * Select the MRU hash table size to limit the average count
     * per bucket at capacity (mru_maxdepth) to 8, if possible
     * given our hash is limited to 16 bits.
     */
    min_hash_slots = (mru_maxdepth / 8) + 1;
    mon_hash_bits = 0;
    while (min_hash_slots >>= 1)
        mon_hash_bits++;
    mon_hash_bits = max(4, mon_hash_bits);
    mon_hash_bits = min(16, mon_hash_bits);
    octets = sizeof(*mon_hash) * MON_HASH_SIZE;
    mon_hash = erealloc_zero(mon_hash, octets, 0);

    mon_enabled = mode;
}
Ejemplo n.º 2
0
u_int
available_blocking_child_slot(void)
{
	const size_t	each = sizeof(blocking_children[0]);
	u_int		slot;
	size_t		prev_alloc;
	size_t		new_alloc;
	size_t		prev_octets;
	size_t		octets;

	for (slot = 0; slot < blocking_children_alloc; slot++) {
		if (NULL == blocking_children[slot])
			return slot;
		if (blocking_children[slot]->reusable) {
			blocking_children[slot]->reusable = FALSE;
			return slot;
		}
	}

	prev_alloc = blocking_children_alloc;
	prev_octets = prev_alloc * each;
	new_alloc = blocking_children_alloc + 4;
	octets = new_alloc * each;
	blocking_children = erealloc_zero(blocking_children, octets,
					  prev_octets);
	blocking_children_alloc = new_alloc;

	return prev_alloc;
}
Ejemplo n.º 3
0
u_int
available_blocking_child_slot(void)
{
	const size_t	each = sizeof(blocking_children[0]);
	u_int		slot;
	size_t		prev_alloc;
	size_t		new_alloc;
	size_t		prev_octets;
	size_t		octets;

	for (slot = 0; slot < blocking_children_alloc; slot++) {
		if (NULL == blocking_children[slot])
			return slot;
		if (blocking_children[slot]->reusable) {
			blocking_children[slot]->reusable = FALSE;
			return slot;
		}
	}

	prev_alloc = blocking_children_alloc;
	prev_octets = prev_alloc * each;
	new_alloc = blocking_children_alloc + 4;
	octets = new_alloc * each;
	blocking_children = erealloc_zero(blocking_children, octets,
					  prev_octets);
	blocking_children_alloc = new_alloc;

	/* assume we'll never have enough workers to overflow u_int */
	return (u_int)prev_alloc;
}
Ejemplo n.º 4
0
static void
ensure_workresp_empty_slot(
	blocking_child *c
	)
{
	const size_t	each = sizeof(blocking_children[0]->responses[0]);
	size_t		new_alloc;
	size_t		old_octets;
	size_t		new_octets;
	void *		nonvol_responses;

	if (c->responses != NULL &&
	    NULL == c->responses[c->next_response])
		return;

	new_alloc = c->responses_alloc + RESPONSES_ALLOC_INC;
	old_octets = c->responses_alloc * each;
	new_octets = new_alloc * each;
	nonvol_responses = DEVOLATILE(void *, c->responses);
	c->responses = erealloc_zero(nonvol_responses, new_octets,
				     old_octets);
	if (0 == c->next_response)
		c->next_response = c->responses_alloc;
	c->responses_alloc = new_alloc;
}
Ejemplo n.º 5
0
static void
ensure_workitems_empty_slot(
	blocking_child *c
	)
{
	const size_t	each = sizeof(blocking_children[0]->workitems[0]);
	size_t		new_alloc;
	size_t		old_octets;
	size_t		new_octets;
	void *		nonvol_workitems;


	if (c->workitems != NULL &&
	    NULL == c->workitems[c->next_workitem])
		return;

	new_alloc = c->workitems_alloc + WORKITEMS_ALLOC_INC;
	old_octets = c->workitems_alloc * each;
	new_octets = new_alloc * each;
	nonvol_workitems = DEVOLATILE(void *, c->workitems);
	c->workitems = erealloc_zero(nonvol_workitems, new_octets,
				     old_octets);
	if (0 == c->next_workitem)
		c->next_workitem = c->workitems_alloc;
	c->workitems_alloc = new_alloc;
}
Ejemplo n.º 6
0
/*
 * growpktdata - grow the packet data area
 */
static void
growpktdata(void)
{
	size_t priorsz;

	priorsz = (size_t)pktdatasize;
	pktdatasize += INCDATASIZE;
	pktdata = erealloc_zero(pktdata, (size_t)pktdatasize, priorsz);
}
Ejemplo n.º 7
0
/*
 * common_serial_open ensures duplicate opens of the same port
 * work by duplicating the handle for the 2nd open, allowing
 * refclock_atom to share a GPS refclock's comm port.
 */
HANDLE
common_serial_open(
	const char *	dev,
	char **		pwindev
	)
{
	char *		windev;
	HANDLE		handle;
	size_t		unit;
	size_t		prev_c_hnds;
	size_t		opens;
	const char *	pch;

	/*
	 * This is odd, but we'll take any unix device path
	 * by looking for the initial '/' and strip off everything
	 * before the final digits, then translate that to COM__:
	 * maintaining backward compatibility with NTP practice of
	 * mapping unit 0 to the nonfunctional COM0:
	 *
	 * To ease the job of taking the windows COMx: device names
	 * out of reference clocks, we'll also work with those
	 * equanimously.
	 */

	TRACE(1, ("common_serial_open given %s\n", dev));

	pch = NULL;
	if ('/' == dev[0]) {
		pch = dev + strlen(dev) - 1;

		if (isdigit(pch[0])) {
			while (isdigit(pch[0])) {
				pch--;
			}
			pch++;
		}
		TRACE(1, ("common_serial_open skipped to ending digits leaving %s\n", pch));
	} else if ('c' == tolower(dev[0])
		   && 'o' == tolower(dev[1])
		   && 'm' == tolower(dev[2])) {
		pch = dev + 3;
		TRACE(1, ("common_serial_open skipped COM leaving %s\n", pch));
	}

	if (!pch || !isdigit(pch[0])) {
		TRACE(1, ("not a digit: %s\n", pch ? pch : "[NULL]"));
		return INVALID_HANDLE_VALUE;
	}

	if (1 != sscanf(pch, "%d", &unit) 
	    || unit > MAX_SERIAL
	    || unit < 0) {
		TRACE(1, ("sscanf failure of %s\n", pch));
		return INVALID_HANDLE_VALUE;
	}


	if (c_hnds < unit + 1) {
		prev_c_hnds = c_hnds;
		c_hnds = unit + 1;
		/* round up to closest multiple of 4 to avoid churn */
		c_hnds = (c_hnds + 3) & ~3;
		hnds = erealloc_zero(hnds, c_hnds * sizeof(hnds[0]),
				     prev_c_hnds * sizeof(hnds[0]));
	}

	if (NULL == hnds[unit].h) {
		INSIST(0 == hnds[unit].opens);
		LIB_GETBUF(windev);
		snprintf(windev, LIB_BUFLENGTH, "\\\\.\\COM%d", unit);
		TRACE(1, ("windows device %s\n", windev));
		*pwindev = windev;
		hnds[unit].h =
		    CreateFile(
			windev,
			GENERIC_READ | GENERIC_WRITE,
			0, /* sharing prohibited */
			NULL, /* default security */
			OPEN_EXISTING,
			FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
			NULL);
		if (INVALID_HANDLE_VALUE == hnds[unit].h)
			hnds[unit].h = NULL;
	}

	if (NULL != hnds[unit].h) {
		/* think handle = dup(hnds[unit].h); */
		DuplicateHandle(
			GetCurrentProcess(),
			hnds[unit].h,
			GetCurrentProcess(),
			&handle,
			0,
			FALSE,
			DUPLICATE_SAME_ACCESS
			);
		hnds[unit].opens++;
		opens = hnds[unit].opens;
		hnds[unit].dupes = erealloc(hnds[unit].dupes, opens *
					    sizeof(hnds[unit].dupes[0]));
		hnds[unit].dupes[opens - 1] = handle;
		return handle;
	}

	return INVALID_HANDLE_VALUE;
}
Ejemplo n.º 8
0
/*
 * openhost - open a socket to a host
 */
static int
openhost(
	const char *hname
	)
{
	char temphost[LENHOSTNAME];
	int a_info, i;
	struct addrinfo hints, *ai = NULL;
	sockaddr_u addr;
	size_t octets;
	register const char *cp;
	char name[LENHOSTNAME];
	char service[5];

	/*
	 * We need to get by the [] if they were entered 
	 */
	
	cp = hname;
	
	if (*cp == '[') {
		cp++;	
		for (i = 0; *cp && *cp != ']'; cp++, i++)
			name[i] = *cp;
		if (*cp == ']') {
			name[i] = '\0';
			hname = name;
		} else {
			return 0;
		}
	}	

	/*
	 * First try to resolve it as an ip address and if that fails,
	 * do a fullblown (dns) lookup. That way we only use the dns
	 * when it is needed and work around some implementations that
	 * will return an "IPv4-mapped IPv6 address" address if you
	 * give it an IPv4 address to lookup.
	 */
	strlcpy(service, "ntp", sizeof(service));
	ZERO(hints);
	hints.ai_family = ai_fam_templ;
	hints.ai_protocol = IPPROTO_UDP;
	hints.ai_socktype = SOCK_DGRAM;
	hints.ai_flags = Z_AI_NUMERICHOST;

	a_info = getaddrinfo(hname, service, &hints, &ai);
	if (a_info == EAI_NONAME
#ifdef EAI_NODATA
	    || a_info == EAI_NODATA
#endif
	   ) {
		hints.ai_flags = AI_CANONNAME;
#ifdef AI_ADDRCONFIG
		hints.ai_flags |= AI_ADDRCONFIG;
#endif
		a_info = getaddrinfo(hname, service, &hints, &ai);	
	}
	/* Some older implementations don't like AI_ADDRCONFIG. */
	if (a_info == EAI_BADFLAGS) {
		hints.ai_flags = AI_CANONNAME;
		a_info = getaddrinfo(hname, service, &hints, &ai);	
	}
	if (a_info != 0) {
		fprintf(stderr, "%s\n", gai_strerror(a_info));
		if (ai != NULL)
			freeaddrinfo(ai);
		return 0;
	}

	/* 
	 * getaddrinfo() has returned without error so ai should not 
	 * be NULL.
	 */
	INSIST(ai != NULL);
	ZERO(addr);
	octets = min(sizeof(addr), ai->ai_addrlen);
	memcpy(&addr, ai->ai_addr, octets);

	if (ai->ai_canonname == NULL)
		strlcpy(temphost, stoa(&addr), sizeof(temphost));
	else
		strlcpy(temphost, ai->ai_canonname, sizeof(temphost));

	if (debug > 2)
		printf("Opening host %s\n", temphost);

	if (havehost == 1) {
		if (debug > 2)
			printf("Closing old host %s\n", currenthost);
		closesocket(sockfd);
		havehost = 0;
	}
	strlcpy(currenthost, temphost, sizeof(currenthost));
	
	/* port maps to the same in both families */
	s_port = NSRCPORT(&addr);; 
#ifdef SYS_VXWORKS
	((struct sockaddr_in6 *)&hostaddr)->sin6_port = htons(SERVER_PORT_NUM);
	if (ai->ai_family == AF_INET)
		*(struct sockaddr_in *)&hostaddr= 
			*((struct sockaddr_in *)ai->ai_addr);
	else 
		*(struct sockaddr_in6 *)&hostaddr= 
			*((struct sockaddr_in6 *)ai->ai_addr);
#endif /* SYS_VXWORKS */

#ifdef SYS_WINNT
	{
		int optionValue = SO_SYNCHRONOUS_NONALERT;
		int err;

		err = setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&optionValue, sizeof(optionValue));
		if (err != NO_ERROR) {
			(void) fprintf(stderr, "cannot open nonoverlapped sockets\n");
			exit(1);
		}
	}
#endif /* SYS_WINNT */

	sockfd = socket(ai->ai_family, SOCK_DGRAM, 0);
	if (sockfd == INVALID_SOCKET) {
		error("socket");
		exit(-1);
	}
	
#ifdef NEED_RCVBUF_SLOP
# ifdef SO_RCVBUF
	{
		int rbufsize = INITDATASIZE + 2048; /* 2K for slop */

		if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,
			       &rbufsize, sizeof(int)) == -1)
		    error("setsockopt");
	}
# endif
#endif

#ifdef SYS_VXWORKS
	if (connect(sockfd, (struct sockaddr *)&hostaddr, 
		    sizeof(hostaddr)) == -1) {
#else
	if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) == -1) {
#endif /* SYS_VXWORKS */
		error("connect");
		exit(-1);
	}

	freeaddrinfo(ai);
	havehost = 1;
	req_pkt_size = REQ_LEN_NOMAC;
	impl_ver = IMPL_XNTPD;
	return 1;
}


/* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */
/*
 * sendpkt - send a packet to the remote host
 */
static int
sendpkt(
	void *	xdata,
	size_t	xdatalen
	)
{
	if (send(sockfd, xdata, xdatalen, 0) == -1) {
		warning("write to %s failed", currenthost);
		return -1;
	}

	return 0;
}


/*
 * growpktdata - grow the packet data area
 */
static void
growpktdata(void)
{
	size_t priorsz;

	priorsz = (size_t)pktdatasize;
	pktdatasize += INCDATASIZE;
	pktdata = erealloc_zero(pktdata, (size_t)pktdatasize, priorsz);
}