예제 #1
0
파일: recvbuff.c 프로젝트: coyizumi/cs111
static void
create_buffers(int nbufs)
{
	register recvbuf_t *bufp;
	int i, abuf;

	abuf = nbufs + buffer_shortfall;
	buffer_shortfall = 0;

#ifndef DEBUG
	bufp = emalloc_zero(abuf * sizeof(*bufp));
#endif

	for (i = 0; i < abuf; i++) {
#ifdef DEBUG
		/*
		 * Allocate each buffer individually so they can be
		 * free()d during ntpd shutdown on DEBUG builds to
		 * keep them out of heap leak reports.
		 */
		bufp = emalloc_zero(sizeof(*bufp));
#endif
		LINK_SLIST(free_recv_list, bufp, link);
		bufp++;
		free_recvbufs++;
		total_recvbufs++;
	}
	lowater_adds++;
}
예제 #2
0
static int rhizome_sync_with_peers(int mode, int peer_count, const struct config_rhizome_peer *const *peers)
{

  /* Get iterator capable of 64KB buffering.
     In future we should parse the sync URL and base the buffer size on the
     transport and allowable traffic volumes. */
  rhizome_direct_transport_state_http *state = emalloc_zero(sizeof(rhizome_direct_transport_state_http));
  /* XXX This code runs each sync in series, when we can probably do them in
     parallel.  But we can't really do them in parallel until we make the
     synchronisation process fully asynchronous, which probably won't happen
     for a while yet.
     Also, we don't currently parse the URI protocol field fully. */
  int peer_number;
  for (peer_number = 0; peer_number < peer_count; ++peer_number) {
    const struct config_rhizome_peer *peer = peers[peer_number];
    if (strcasecmp(peer->protocol, "http") != 0)
      return WHYF("Unsupported Rhizome Direct protocol %s", alloca_str_toprint(peer->protocol));
    strbuf h = strbuf_local(state->host, sizeof state->host);
    strbuf_puts(h, peer->host);
    if (strbuf_overrun(h))
      return WHYF("Rhizome Direct host name too long: %s", alloca_str_toprint(peer->host));
    state->port = peer->port;
    DEBUGF("Rhizome direct peer is %s://%s:%d", peer->protocol, state->host, state->port);
    rhizome_direct_sync_request *s = rhizome_direct_new_sync_request(rhizome_direct_http_dispatch, 65536, 0, mode, state);
    rhizome_direct_start_sync_request(s);
    if (rd_sync_handle_count > 0)
      while (fd_poll() && rd_sync_handle_count > 0)
	;
  }
  return 0;
}
예제 #3
0
/*
 * auth_moremem - get some more free key structures
 */
void
auth_moremem(
	int	keycount
	)
{
	symkey *	sk;
	int		i;
#ifdef DEBUG
	void *		base;
	symkey_alloc *	allocrec;
# define MOREMEM_EXTRA_ALLOC	(sizeof(*allocrec))
#else
# define MOREMEM_EXTRA_ALLOC	(0)
#endif

	i = (keycount > 0)
		? keycount
		: MEMINC;
	sk = emalloc_zero(i * sizeof(*sk) + MOREMEM_EXTRA_ALLOC);
#ifdef DEBUG
	base = sk;
#endif
	authnumfreekeys += i;

	for (; i > 0; i--, sk++) {
		LINK_SLIST(authfreekeys, sk, llink.f);
	}

#ifdef DEBUG
	allocrec = (void *)sk;
	allocrec->mem = base;
	LINK_SLIST(authallocs, allocrec, link);
#endif
}
예제 #4
0
/*
 * Allocate an info structure and attach it to a file.
 *
 * Note: When 'mode' is NULL, then the INFO block will be set up to
 * contain a NULL file pointer, as suited for remote config command
 * parsing. Otherwise having a NULL file pointer is considered an error,
 * and a NULL info block pointer is returned to indicate failure!
 *
 * Note: We use a variable-sized structure to hold a copy of the file
 * name (or, more proper, the input source description). This is more
 * secure than keeping a reference to some other storage that might go
 * out of scope.
 */
static struct FILE_INFO *
lex_open(
	const char *path,
	const char *mode
	)
{
	struct FILE_INFO *stream;
	size_t            nnambuf;

	nnambuf = strlen(path);
	stream = emalloc_zero(sizeof(*stream) + nnambuf);
	stream->curpos.nline = 1;
	stream->backch = EOF;
	/* copy name with memcpy -- trailing NUL already there! */
	memcpy(stream->fname, path, nnambuf);

	if (NULL != mode) {
		stream->fpi = fopen(path, mode);
		if (NULL == stream->fpi) {
			free(stream);
			stream = NULL;
		}
	}
	return stream;
}
예제 #5
0
/*
 * true_start - open the devices and initialize data for processing
 */
static int
true_start(
	int unit,
	struct peer *peer
	)
{
	register struct true_unit *up;
	struct refclockproc *pp;
	char device[40];
	int fd;

	/*
	 * Open serial port
	 */
	snprintf(device, sizeof(device), DEVICE, unit);
	fd = refclock_open(device, SPEED232, LDISC_CLK);
	if (fd <= 0)
		return 0;

	/*
	 * Allocate and initialize unit structure
	 */
	up = emalloc_zero(sizeof(*up));
	pp = peer->procptr;
	pp->io.clock_recv = true_receive;
	pp->io.srcclock = peer;
	pp->io.datalen = 0;
	pp->io.fd = fd;
	if (!io_addclock(&pp->io)) {
		close(fd);
		pp->io.fd = -1;
		free(up);
		return (0);
	}
	pp->unitptr = up;

	/*
	 * Initialize miscellaneous variables
	 */
	peer->precision = PRECISION;
	pp->clockdesc = DESCRIPTION;
	memcpy(&pp->refid, REFID, 4);
	up->pollcnt = 2;
	up->type = t_unknown;
	up->state = s_Base;

	/*
	 * Send a CTRL-C character at the start,
	 * just in case the clock is already
	 * sending timecodes
	 */
	true_send(peer, "\03\r");
	
	true_doevent(peer, e_Init);

	return (1);
}
예제 #6
0
/*
 * arb_start - open the devices and initialize data for processing
 */
static int
arb_start(
	int unit,
	struct peer *peer
	)
{
	register struct arbunit *up;
	struct refclockproc *pp;
	int fd;
	char device[20];

	/*
	 * Open serial port. Use CLK line discipline, if available.
	 */
	snprintf(device, sizeof(device), DEVICE, unit);
	fd = refclock_open(device, SPEED232, LDISC_CLK);
	if (fd <= 0)
		return (0);

	/*
	 * Allocate and initialize unit structure
	 */
	up = emalloc_zero(sizeof(*up));
	pp = peer->procptr;
	pp->io.clock_recv = arb_receive;
	pp->io.srcclock = peer;
	pp->io.datalen = 0;
	pp->io.fd = fd;
	if (!io_addclock(&pp->io)) {
		close(fd);
		pp->io.fd = -1;
		free(up);
		return (0);
	}
	pp->unitptr = up;

	/*
	 * Initialize miscellaneous variables
	 */
	peer->precision = PRECISION;
	pp->clockdesc = DESCRIPTION;
	memcpy((char *)&pp->refid, REFID, 4);
	if (peer->MODE > 1) {
		msyslog(LOG_NOTICE, "ARBITER: Invalid mode %d", peer->MODE);
		close(fd);
		pp->io.fd = -1;
		free(up);
		return (0);
	}
#ifdef DEBUG
	if(debug) { printf("arbiter: mode = %d.\n", peer->MODE); }
#endif
	write(pp->io.fd, COMMAND_HALT_BCAST, 2);
	return (1);
}
예제 #7
0
static int add_packet(struct msp_window *window, uint16_t seq, uint8_t flags, 
  const uint8_t *payload, size_t len)
{
  
  struct msp_packet **insert_pos=NULL;
  
  if (!window->_head){
    insert_pos = &window->_head;
  }else{
    if (window->_tail->seq == seq){
      // ignore duplicate packets
      return 0;
    }else if (compare_wrapped_uint16(window->_tail->seq, seq)<0){
      if (compare_wrapped_uint16(window->_head->seq, seq)>0){
	// this is ambiguous
	return WHYF("%04x is both < tail (%04x) and > head (%04x)", seq, window->_tail->seq, window->_head->seq);
      }
      insert_pos = &window->_tail->_next;
    }else{
      insert_pos = &window->_head;
      while(compare_wrapped_uint16((*insert_pos)->seq, seq)<0)
	insert_pos = &(*insert_pos)->_next;
      if ((*insert_pos)->seq == seq){
	// ignore duplicate packets
	return 0;
      }
    }
  }
  
  struct msp_packet *packet = emalloc_zero(sizeof(struct msp_packet));
  if (!packet)
    return -1;
    
  packet->_next = (*insert_pos);
  *insert_pos = packet;
  if (!packet->_next)
    window->_tail = packet;
  packet->added = gettime_ms();
  packet->seq = seq;
  packet->flags = flags;
  packet->len = len;
  
  if (payload && len){
    uint8_t *p = emalloc(len);
    if (!p){
      free(packet);
      return -1;
    }
    packet->payload = p;
    bcopy(payload, p, len);
  }
  window->packet_count++;
  return 1;
}
예제 #8
0
파일: main.c 프로젝트: kjopek/freebsd
/*
** handle_lookup
*/
void
handle_lookup(
	const char *name,
	int flags
	)
{
	struct addrinfo	hints;	/* Local copy is OK */
	struct dns_ctx *ctx;
	char *		name_copy;
	size_t		name_sz;
	size_t		octets;

	TRACE(1, ("handle_lookup(%s,%#x)\n", name, flags));

	ZERO(hints);
	hints.ai_family = ai_fam_pref;
	hints.ai_flags = AI_CANONNAME | Z_AI_NUMERICSERV;
	/*
	** Unless we specify a socktype, we'll get at least two
	** entries for each address: one for TCP and one for
	** UDP. That's not what we want.
	*/
	hints.ai_socktype = SOCK_DGRAM;
	hints.ai_protocol = IPPROTO_UDP;

	name_sz = 1 + strlen(name);
	octets = sizeof(*ctx) + name_sz;	// Space for a ctx and the name
	ctx = emalloc_zero(octets);		// ctx at ctx[0]
	name_copy = (char *)(ctx + 1);		// Put the name at ctx[1]
	memcpy(name_copy, name, name_sz);	// copy the name to ctx[1]
	ctx->name = name_copy;			// point to it...
	ctx->flags = flags;
	ctx->timeout = response_tv;
	ctx->key = NULL;

	/* The following should arguably be passed in... */
	if (ENABLED_OPT(AUTHENTICATION)) {
		ctx->key_id = OPT_VALUE_AUTHENTICATION;
		get_key(ctx->key_id, &ctx->key);
		if (NULL == ctx->key) {
			fprintf(stderr, "%s: Authentication with keyID %d requested, but no matching keyID found in <%s>!\n",
				progname, ctx->key_id, OPT_ARG(KEYFILE));
			exit(1);
		}
	} else {
		ctx->key_id = -1;
	}

	++n_pending_dns;
	getaddrinfo_sometime(name, "123", &hints, 0,
			     &sntp_name_resolved, ctx);
}
예제 #9
0
파일: ntp_worker.c 프로젝트: Hal-Murray/ntp
int
queue_blocking_request(
	blocking_work_req	rtype,
	void *			req,
	size_t			reqsize,
	blocking_work_callback	done_func,
	void *			context
	)
{
	static u_int		intres_slot = UINT_MAX;
	u_int			child_slot;
	blocking_child *	c;
	blocking_pipe_header	req_hdr;

	req_hdr.octets = sizeof(req_hdr) + reqsize;
	req_hdr.magic_sig = BLOCKING_REQ_MAGIC;
	req_hdr.rtype = rtype;
	req_hdr.done_func = done_func;
	req_hdr.context = context;

	child_slot = UINT_MAX;
	if (worker_per_query || UINT_MAX == intres_slot ||
	    blocking_children[intres_slot]->reusable)
		child_slot = available_blocking_child_slot();
	if (!worker_per_query) {
		if (UINT_MAX == intres_slot)
			intres_slot = child_slot;
		else
			child_slot = intres_slot;
		if (0 == intres_req_pending)
			intres_timeout_req(0);
	}
	intres_req_pending++;
	INSIST(UINT_MAX != child_slot);
	c = blocking_children[child_slot];
	if (NULL == c) {
		c = emalloc_zero(sizeof(*c));
#ifdef WORK_FORK
		c->req_read_pipe = -1;
		c->req_write_pipe = -1;
#endif
#ifdef WORK_PIPE
		c->resp_read_pipe = -1;
		c->resp_write_pipe = -1;
#endif
		blocking_children[child_slot] = c;
	}
	req_hdr.child_idx = child_slot;

	return send_blocking_req_internal(c, &req_hdr, req);
}
예제 #10
0
/*
 * getmorepeermem - add more peer structures to the free list
 */
static void
getmorepeermem(void)
{
	int i;
	struct peer *peers;

	peers = emalloc_zero(INC_PEER_ALLOC * sizeof(*peers));

	for (i = INC_PEER_ALLOC - 1; i >= 0; i--)
		LINK_SLIST(peer_free, &peers[i], p_link);

	total_peer_structs += INC_PEER_ALLOC;
	peer_free_count += INC_PEER_ALLOC;
}
예제 #11
0
/*
 * chronolog_start - open the devices and initialize data for processing
 */
static int
chronolog_start(
	int unit,
	struct peer *peer
	)
{
	register struct chronolog_unit *up;
	struct refclockproc *pp;
	int fd;
	char device[20];

	/*
	 * Open serial port. Don't bother with CLK line discipline, since
	 * it's not available.
	 */
	snprintf(device, sizeof(device), DEVICE, unit);
#ifdef DEBUG
	if (debug)
		printf ("starting Chronolog with device %s\n",device);
#endif
	fd = refclock_open(device, SPEED232, 0);
	if (fd <= 0)
		return (0);

	/*
	 * Allocate and initialize unit structure
	 */
	up = emalloc_zero(sizeof(*up));
	pp = peer->procptr;
	pp->unitptr = up;
	pp->io.clock_recv = chronolog_receive;
	pp->io.srcclock = peer;
	pp->io.datalen = 0;
	pp->io.fd = fd;
	if (!io_addclock(&pp->io)) {
		close(fd);
		pp->io.fd = -1;
		free(up);
		pp->unitptr = NULL;
		return (0);
	}

	/*
	 * Initialize miscellaneous variables
	 */
	peer->precision = PRECISION;
	pp->clockdesc = DESCRIPTION;
	memcpy((char *)&pp->refid, REFID, 4);
	return (1);
}
예제 #12
0
/*
 * as2201_start - open the devices and initialize data for processing
 */
static int
as2201_start(
	int unit,
	struct peer *peer
	)
{
	register struct as2201unit *up;
	struct refclockproc *pp;
	int fd;
	char gpsdev[20];

	/*
	 * Open serial port. Use CLK line discipline, if available.
	 */
	snprintf(gpsdev, sizeof(gpsdev), DEVICE, unit);
	fd = refclock_open(gpsdev, SPEED232, LDISC_CLK);
	if (fd <= 0)
		return (0);

	/*
	 * Allocate and initialize unit structure
	 */
	up = emalloc_zero(sizeof(*up));
	pp = peer->procptr;
	pp->io.clock_recv = as2201_receive;
	pp->io.srcclock = peer;
	pp->io.datalen = 0;
	pp->io.fd = fd;
	if (!io_addclock(&pp->io)) {
		close(fd);
		pp->io.fd = -1;
		free(up);
		return (0);
	}
	pp->unitptr = up;

	/*
	 * Initialize miscellaneous variables
	 */
	peer->precision = PRECISION;
	pp->clockdesc = DESCRIPTION;
	memcpy((char *)&pp->refid, REFID, 4);
	up->lastptr = up->stats;
	up->index = 0;
	return (1);
}
예제 #13
0
/*
 * hopfpci_start - attach to hopf PCI board 6039
 */
static int
hopfpci_start(
	int unit,
	struct peer *peer
	)
{
	struct refclockproc *pp;
	struct hopfclock_unit *up;

	/*
	 * Allocate and initialize unit structure
	 */
	up = emalloc_zero(sizeof(*up));

#ifndef SYS_WINNT

 	fd = open(DEVICE,O_RDWR); /* try to open hopf clock device */

#else
	if (!OpenHopfDevice()) {
		msyslog(LOG_ERR, "Start: %s unit: %d failed!", DEVICE, unit);
		free(up);
		return (0);
	}
#endif

	pp = peer->procptr;
	pp->io.clock_recv = noentry;
	pp->io.srcclock = peer;
	pp->io.datalen = 0;
	pp->io.fd = INVALID_SOCKET;
	pp->unitptr = up;

	get_systime(&pp->lastrec);

	/*
	 * Initialize miscellaneous peer variables
	 */
	memcpy((char *)&pp->refid, REFID, 4);
	peer->precision = PRECISION;
	pp->clockdesc = DESCRIPTION;
	up->leap_status = 0;
	up->unit = (short) unit;
	return (1);
}
예제 #14
0
struct msp_sock * msp_socket(int mdp_sock)
{
  struct msp_sock *ret = emalloc_zero(sizeof(struct msp_sock));
  ret->mdp_sock = mdp_sock;
  ret->state = MSP_STATE_UNINITIALISED;
  ret->_next = root;
  // TODO set base rtt to ensure that we send the first packet a few times before giving up
  ret->tx.base_rtt = ret->tx.rtt = 0xFFFFFFFF;
  ret->tx.last_activity = TIME_NEVER_HAS;
  ret->rx.last_activity = TIME_NEVER_HAS;
  ret->next_action = TIME_NEVER_WILL;
  ret->timeout = gettime_ms() + 10000;
  ret->previous_ack = 0x7FFF;
  if (root)
    root->_prev=ret;
  root = ret;
  return ret;
}
예제 #15
0
/*
 * tpro_start - open the TPRO device and initialize data for processing
 */
static int
tpro_start(
	int unit,
	struct peer *peer
	)
{
	register struct tprounit *up;
	struct refclockproc *pp;
	char device[20];
	int fd;

	/*
	 * Open TPRO device
	 */
	snprintf(device, sizeof(device), DEVICE, unit);
	fd = open(device, O_RDONLY | O_NDELAY, 0777);
	if (fd == -1) {
		msyslog(LOG_ERR, "tpro_start: open of %s: %m", device);
		return (0);
	}

	/*
	 * Allocate and initialize unit structure
	 */
	up = emalloc_zero(sizeof(*up));
	pp = peer->procptr;
	pp->io.clock_recv = noentry;
	pp->io.srcclock = peer;
	pp->io.datalen = 0;
	pp->io.fd = fd;
	pp->unitptr = up;

	/*
	 * Initialize miscellaneous peer variables
	 */
	peer->precision = PRECISION;
	pp->clockdesc = DESCRIPTION;
	memcpy((char *)&pp->refid, REFID, 4);
	return (1);
}
예제 #16
0
/*
 * shm_start - attach to shared memory
 */
static int
shm_start(
	int unit,
	struct peer *peer
	)
{
	struct refclockproc * const pp = peer->procptr;
	struct shmunit *      const up = emalloc_zero(sizeof(*up));

	pp->io.clock_recv = noentry;
	pp->io.srcclock = peer;
	pp->io.datalen = 0;
	pp->io.fd = -1;

	up->forall = (unit >= 2) && !(peer->ttl & SHM_MODE_PRIVATE);

	up->shm = getShmTime(unit, up->forall);

	/*
	 * Initialize miscellaneous peer variables
	 */
	memcpy((char *)&pp->refid, REFID, 4);
	if (up->shm != 0) {
		pp->unitptr = up;
		up->shm->precision = PRECISION;
		peer->precision = up->shm->precision;
		up->shm->valid = 0;
		up->shm->nsamples = NSAMPLES;
		pp->clockdesc = DESCRIPTION;
		/* items to be changed later in 'shm_control()': */
		up->max_delay = 5;
		up->max_delta = 4*3600;
		return 1;
	} else {
		free(up);
		pp->unitptr = NULL;
		return 0;
	}
}
예제 #17
0
/*
 * Initialize data for processing
 */
static int
acts_start(
	int	unit,
	struct peer *peer
	)
{
	struct actsunit *up;
	struct refclockproc *pp;
	const char *setup;

	/*
	 * Allocate and initialize unit structure
	 */
	up = emalloc_zero(sizeof(struct actsunit));
	up->unit = unit;
	pp = peer->procptr;
	pp->unitptr = up;
	pp->io.clock_recv = acts_receive;
	pp->io.srcclock = peer;
	pp->io.datalen = 0;
	pp->io.fd = -1;

	/*
	 * Initialize miscellaneous variables
	 */
	peer->precision = PRECISION;
	pp->clockdesc = DESCRIPTION;
	memcpy(&pp->refid, REFID, 4);
	peer->sstclktype = CTL_SST_TS_TELEPHONE;
	up->bufptr = up->buf;
	if (def_modem_setup == modem_setup) {
		setup = get_ext_sys_var("modemsetup");
		if (setup != NULL)
			modem_setup = estrdup(setup);
	}

	return (1);
}
예제 #18
0
파일: work_thread.c 프로젝트: ntpsec/ntpsec
/*
 * prepare_child_sems()
 *
 * create sync events (semaphores)
 * child_is_blocking initially unset
 * blocking_req_ready initially unset
 *
 * Child waits for blocking_req_ready to be set after
 * setting child_is_blocking.  blocking_req_ready and
 * blocking_response_ready are auto-reset, so wake one
 * waiter and become unset (unsignalled) in one operation.
 */
static void
prepare_child_sems(
	blocking_child *c
	)
{
	size_t	octets;

	if (NULL == c->blocking_req_ready) {
		octets = sizeof(*c->blocking_req_ready);
		octets += sizeof(*c->wake_scheduled_sleep);
		/* !!!! octets += sizeof(*c->child_is_blocking); */
		c->blocking_req_ready = emalloc_zero(octets);;
		c->wake_scheduled_sleep = 1 + c->blocking_req_ready;
		/* !!!! c->child_is_blocking = 1 + c->wake_scheduled_sleep; */
	} else {
		sem_destroy(c->blocking_req_ready);
		sem_destroy(c->wake_scheduled_sleep);
		/* !!!! sem_destroy(c->child_is_blocking); */
	}
	sem_init(c->blocking_req_ready, false, 0);
	sem_init(c->wake_scheduled_sleep, false, 0);
	/* !!!! sem_init(c->child_is_blocking, false, 0); */
}
예제 #19
0
static restrict_u *
alloc_res6(void)
{
	const size_t	cb = V6_SIZEOF_RESTRICT_U;
	const size_t	count = INC_RESLIST6;
	restrict_u *	rl;
	restrict_u *	res;
	int		i;

	UNLINK_HEAD_SLIST(res, resfree6, link);
	if (res != NULL)
		return res;

	rl = emalloc_zero(count * cb);
	/* link all but the first onto free list */
	res = (void *)((char *)rl + (count - 1) * cb);
	for (i = count - 1; i > 0; i--) {
		LINK_SLIST(resfree6, res, link);
		res = (void *)((char *)res - cb);
	}
	INSIST(rl == res);
	/* allocate the first */
	return res;
}
예제 #20
0
void
add_entry(
	const char *	hostname,
	const char *	type	/* 4 bytes not \0 terminated */
	)
{
	int n;
	struct kod_entry *pke;

	pke = emalloc_zero(sizeof(*pke));
	pke->timestamp = time(NULL);
	memcpy(pke->type, type, 4);
	pke->type[sizeof(pke->type) - 1] = '\0';
	strlcpy(pke->hostname, hostname, sizeof(pke->hostname));

	/*
	 * insert in address ("hostname") order to find duplicates
	 */
	for (n = 0; n < kod_db_cnt; n++)
		if (strcmp(kod_db[n]->hostname, pke->hostname) >= 0)
			break;

	if (n < kod_db_cnt &&
	    0 == strcmp(kod_db[n]->hostname, pke->hostname)) {
		kod_db[n]->timestamp = pke->timestamp;
		free(pke);
		return;
	}

	kod_db_cnt++;
	kod_db = erealloc(kod_db, kod_db_cnt * sizeof(kod_db[0]));
	if (n != kod_db_cnt - 1)
		memmove(&kod_db[n + 1], &kod_db[n],
			sizeof(kod_db[0]) * ((kod_db_cnt - 1) - n));
	kod_db[n] = pke;
}
예제 #21
0
/*
** DNS Callback:
** - For each IP:
** - - open a socket
** - - increment n_pending_ntp
** - - send a request if this is a Unicast callback
** - - queue wait for response
** - decrement n_pending_dns
*/
void
sntp_name_resolved(
	int			rescode,
	int			gai_errno,
	void *			context,
	const char *		name,
	const char *		service,
	const struct addrinfo *	hints,
	const struct addrinfo *	addr
	)
{
	struct dns_ctx *	dctx;
	sent_pkt *		spkt;
	const struct addrinfo *	ai;
	SOCKET			sock;
	u_int			xmt_delay_v4;
	u_int			xmt_delay_v6;
	u_int			xmt_delay;
	size_t			octets;

	xmt_delay_v4 = 0;
	xmt_delay_v6 = 0;
	dctx = context;
	if (rescode) {
#ifdef EAI_SYSTEM
		if (EAI_SYSTEM == rescode) {
			errno = gai_errno;
			mfprintf(stderr, "%s lookup error %m\n",
				 dctx->name);
		} else
#endif
			fprintf(stderr, "%s lookup error %s\n",
				dctx->name, gai_strerror(rescode));
	} else {
		TRACE(3, ("%s [%s]\n", dctx->name,
			  (addr->ai_canonname != NULL)
			      ? addr->ai_canonname
			      : ""));

		for (ai = addr; ai != NULL; ai = ai->ai_next) {

			if (check_kod(ai))
				continue;

			switch (ai->ai_family) {

			case AF_INET:
				sock = sock4;
				xmt_delay = xmt_delay_v4;
				xmt_delay_v4++;
				break;

			case AF_INET6:
				if (!ipv6_works)
					continue;

				sock = sock6;
				xmt_delay = xmt_delay_v6;
				xmt_delay_v6++;
				break;

			default:
				msyslog(LOG_ERR, "sntp_name_resolved: unexpected ai_family: %d",
					ai->ai_family);
				exit(1);
				break;
			}

			/*
			** We're waiting for a response for either unicast
			** or broadcast, so...
			*/
			++n_pending_ntp;

			/* If this is for a unicast IP, queue a request */
			if (dctx->flags & CTX_UCST) {
				spkt = emalloc_zero(sizeof(*spkt));
				spkt->dctx = dctx;
				octets = min(ai->ai_addrlen, sizeof(spkt->addr));
				memcpy(&spkt->addr, ai->ai_addr, octets);
				queue_xmt(sock, dctx, spkt, xmt_delay);
			}
		}
	}
	/* n_pending_dns really should be >0 here... */
	--n_pending_dns;
	check_exit_conditions();
}
예제 #22
0
/*
 * chu_start - open the devices and initialize data for processing
 */
static int
chu_start(
	int	unit,		/* instance number (not used) */
	struct peer *peer	/* peer structure pointer */
	)
{
	struct chuunit *up;
	struct refclockproc *pp;
	char device[20];	/* device name */
	int	fd;		/* file descriptor */
#ifdef ICOM
	int	temp;
#endif /* ICOM */
#ifdef HAVE_AUDIO
	int	fd_audio;	/* audio port file descriptor */
	int	i;		/* index */
	double	step;		/* codec adjustment */

	/*
	 * Open audio device. Don't complain if not there.
	 */
	fd_audio = audio_init(DEVICE_AUDIO, AUDIO_BUFSIZ, unit);

#ifdef DEBUG
	if (fd_audio >= 0 && debug)
		audio_show();
#endif

	/*
	 * If audio is unavailable, Open serial port in raw mode.
	 */
	if (fd_audio >= 0) {
		fd = fd_audio;
	} else {
		snprintf(device, sizeof(device), DEVICE, unit);
		fd = refclock_open(device, SPEED232, LDISC_RAW);
	}
#else /* HAVE_AUDIO */

	/*
	 * Open serial port in raw mode.
	 */
	snprintf(device, sizeof(device), DEVICE, unit);
	fd = refclock_open(device, SPEED232, LDISC_RAW);
#endif /* HAVE_AUDIO */

	if (fd < 0)
		return (0);

	/*
	 * Allocate and initialize unit structure
	 */
	up = emalloc_zero(sizeof(*up));
	pp = peer->procptr;
	pp->unitptr = up;
	pp->io.clock_recv = chu_receive;
	pp->io.srcclock = peer;
	pp->io.datalen = 0;
	pp->io.fd = fd;
	if (!io_addclock(&pp->io)) {
		close(fd);
		pp->io.fd = -1;
		free(up);
		pp->unitptr = NULL;
		return (0);
	}

	/*
	 * Initialize miscellaneous variables
	 */
	peer->precision = PRECISION;
	pp->clockdesc = DESCRIPTION;
	strlcpy(up->ident, "CHU", sizeof(up->ident));
	memcpy(&pp->refid, up->ident, 4); 
	DTOLFP(CHAR, &up->charstamp);
#ifdef HAVE_AUDIO

	/*
	 * The companded samples are encoded sign-magnitude. The table
	 * contains all the 256 values in the interest of speed. We do
	 * this even if the audio codec is not available. C'est la lazy.
	 */
	up->fd_audio = fd_audio;
	up->gain = 127;
	up->comp[0] = up->comp[OFFSET] = 0.;
	up->comp[1] = 1; up->comp[OFFSET + 1] = -1.;
	up->comp[2] = 3; up->comp[OFFSET + 2] = -3.;
	step = 2.;
	for (i = 3; i < OFFSET; i++) {
		up->comp[i] = up->comp[i - 1] + step;
		up->comp[OFFSET + i] = -up->comp[i];
                if (i % 16 == 0)
                	step *= 2.;
	}
	DTOLFP(1. / SECOND, &up->tick);
#endif /* HAVE_AUDIO */
#ifdef ICOM
	temp = 0;
#ifdef DEBUG
	if (debug > 1)
		temp = P_TRACE;
#endif
	if (peer->ttl > 0) {
		if (peer->ttl & 0x80)
			up->fd_icom = icom_init("/dev/icom", B1200,
			    temp);
		else
			up->fd_icom = icom_init("/dev/icom", B9600,
			    temp);
	}
	if (up->fd_icom > 0) {
		if (chu_newchan(peer, 0) != 0) {
			msyslog(LOG_NOTICE, "icom: radio not found");
			close(up->fd_icom);
			up->fd_icom = 0;
		} else {
			msyslog(LOG_NOTICE, "icom: autotune enabled");
		}
	}
#endif /* ICOM */
	return (1);
}
예제 #23
0
/*
 * refclock_newpeer - initialize and start a reference clock
 *
 * This routine allocates and initializes the interface structure which
 * supports a reference clock in the form of an ordinary NTP peer. A
 * driver-specific support routine completes the initialization, if
 * used. Default peer variables which identify the clock and establish
 * its reference ID and stratum are set here. It returns one if success
 * and zero if the clock address is invalid or already running,
 * insufficient resources are available or the driver declares a bum
 * rap.
 */
int
refclock_newpeer(
	struct peer *peer	/* peer structure pointer */
	)
{
	struct refclockproc *pp;
	u_char clktype;
	int unit;

	/*
	 * Check for valid clock address. If already running, shut it
	 * down first.
	 */
	if (!ISREFCLOCKADR(&peer->srcadr)) {
		msyslog(LOG_ERR,
			"refclock_newpeer: clock address %s invalid",
			stoa(&peer->srcadr));
		return (0);
	}
	clktype = (u_char)REFCLOCKTYPE(&peer->srcadr);
	unit = REFCLOCKUNIT(&peer->srcadr);
	if (clktype >= num_refclock_conf ||
		refclock_conf[clktype]->clock_start == noentry) {
		msyslog(LOG_ERR,
			"refclock_newpeer: clock type %d invalid\n",
			clktype);
		return (0);
	}

	/*
	 * Allocate and initialize interface structure
	 */
	pp = emalloc_zero(sizeof(*pp));
	peer->procptr = pp;

	/*
	 * Initialize structures
	 */
	peer->refclktype = clktype;
	peer->refclkunit = (u_char)unit;
	peer->flags |= FLAG_REFCLOCK;
	peer->leap = LEAP_NOTINSYNC;
	peer->stratum = STRATUM_REFCLOCK;
	peer->ppoll = peer->maxpoll;
	pp->type = clktype;
	pp->conf = refclock_conf[clktype];
	pp->timestarted = current_time;
	pp->io.fd = -1;

	/*
	 * Set peer.pmode based on the hmode. For appearances only.
	 */
	switch (peer->hmode) {
	case MODE_ACTIVE:
		peer->pmode = MODE_PASSIVE;
		break;

	default:
		peer->pmode = MODE_SERVER;
		break;
	}

	/*
	 * Do driver dependent initialization. The above defaults
	 * can be wiggled, then finish up for consistency.
	 */
	if (!((refclock_conf[clktype]->clock_start)(unit, peer))) {
		refclock_unpeer(peer);
		return (0);
	}
	peer->refid = pp->refid;
	return (1);
}
예제 #24
0
/*
 * arc_start - open the devices and initialize data for processing
 */
static int
arc_start(
	int unit,
	struct peer *peer
	)
{
	register struct arcunit *up;
	struct refclockproc *pp;
	int temp_fd;
	int fd;
	char device[20];
#ifdef HAVE_TERMIOS
	struct termios arg;
#endif

	msyslog(LOG_NOTICE, "MSF_ARCRON %s: opening unit %d",
		arc_version, unit);
	DPRINTF(1, ("arc: %s: attempt to open unit %d.\n", arc_version,
		unit));

	/*
	 * Open serial port. Use CLK line discipline, if available.
	 */
	snprintf(device, sizeof(device), DEVICE, unit);
	temp_fd = refclock_open(device, SPEED, LDISC_CLK);
	if (temp_fd <= 0)
		return 0;
	DPRINTF(1, ("arc: unit %d using tty_open().\n", unit));
	fd = tty_open(device, OPEN_FLAGS, 0777);
	if (fd < 0) {
		msyslog(LOG_ERR, "MSF_ARCRON(%d): failed second open(%s, 0777): %m.\n",
			unit, device);
		close(temp_fd);
		return 0;
	}
	close(temp_fd);
	temp_fd = -1;

#ifndef SYS_WINNT
	fcntl(fd, F_SETFL, 0); /* clear the descriptor flags */
#endif
	DPRINTF(1, ("arc: opened RS232 port with file descriptor %d.\n", fd));

#ifdef HAVE_TERMIOS

	if (tcgetattr(fd, &arg) < 0) {
		msyslog(LOG_ERR, "MSF_ARCRON(%d): tcgetattr(%s): %m.\n",
			unit, device);
		close(fd);
		return 0;
	}

	arg.c_iflag = IGNBRK | ISTRIP;
	arg.c_oflag = 0;
	arg.c_cflag = B300 | CS8 | CREAD | CLOCAL | CSTOPB;
	arg.c_lflag = 0;
	arg.c_cc[VMIN] = 1;
	arg.c_cc[VTIME] = 0;

	if (tcsetattr(fd, TCSANOW, &arg) < 0) {
		msyslog(LOG_ERR, "MSF_ARCRON(%d): tcsetattr(%s): %m.\n",
			unit, device);
		close(fd);
		return 0;
	}

#else

	msyslog(LOG_ERR, "ARCRON: termios required by this driver");
	(void)close(fd);

	return 0;

#endif

	/* Set structure to all zeros... */
	up = emalloc_zero(sizeof(*up));
	pp = peer->procptr;
	pp->io.clock_recv = arc_receive;
	pp->io.srcclock = (caddr_t)peer;
	pp->io.datalen = 0;
	pp->io.fd = fd;
	if (!io_addclock(&pp->io)) {
		close(fd);
		pp->io.fd = -1;
		free(up); 
		return(0); 
	}
	pp->unitptr = up;

	/*
	 * Initialize miscellaneous variables
	 */
	peer->precision = PRECISION;
	peer->stratum = 2;              /* Default to stratum 2 not 0. */
	pp->clockdesc = DESCRIPTION;
	if (peer->MODE > 3) {
		msyslog(LOG_NOTICE, "ARCRON: Invalid mode %d", peer->MODE);
		return 0;
	}
#ifdef DEBUG
	if(debug) { printf("arc: mode = %d.\n", peer->MODE); }
#endif
	switch (peer->MODE) {
	    case 1:
		memcpy((char *)&pp->refid, REFID_MSF, 4);
		break;
	    case 2:
		memcpy((char *)&pp->refid, REFID_DCF77, 4);
		break;
	    case 3:
		memcpy((char *)&pp->refid, REFID_WWVB, 4);
		break;
	    default:
		memcpy((char *)&pp->refid, REFID, 4);
		break;
	}
	/* Spread out resyncs so that they should remain separated. */
	up->next_resync = current_time + INITIAL_RESYNC_DELAY + (67*unit)%1009;

#if 0 /* Not needed because of zeroing of arcunit structure... */
	up->resyncing = 0;              /* Not resyncing yet. */
	up->saved_flags = 0;            /* Default is all flags off. */
	/* Clear send buffer out... */
	{
		int i;
		for(i = CMDQUEUELEN; i >= 0; --i) { up->cmdqueue[i] = '\0'; }
	}
#endif

#ifdef ARCRON_KEEN
	up->quality = QUALITY_UNKNOWN;  /* Trust the clock immediately. */
#else
	up->quality = MIN_CLOCK_QUALITY;/* Don't trust the clock yet. */
#endif

	peer->action = arc_event_handler;

	ENQUEUE(up);

	return(1);
}
예제 #25
0
/*
 * hpgps_start - open the devices and initialize data for processing
 */
static int
hpgps_start(
	int unit,
	struct peer *peer
	)
{
	register struct hpgpsunit *up;
	struct refclockproc *pp;
	int fd;
	int speed, ldisc;
	char device[20];

	/*
	 * Open serial port. Use CLK line discipline, if available.
	 * Default is HP 58503A, mode arg selects HP Z3801A
	 */
	snprintf(device, sizeof(device), DEVICE, unit);
	ldisc = LDISC_CLK;
	speed = SPEED232;
	/* mode parameter to server config line shares ttl slot */
	if (1 == peer->ttl) {
		ldisc |= LDISC_7O1;
		speed = SPEED232Z;
	}
	fd = refclock_open(device, speed, ldisc);
	if (fd <= 0)
		return (0);
	/*
	 * Allocate and initialize unit structure
	 */
	up = emalloc_zero(sizeof(*up));
	pp = peer->procptr;
	pp->io.clock_recv = hpgps_receive;
	pp->io.srcclock = peer;
	pp->io.datalen = 0;
	pp->io.fd = fd;
	if (!io_addclock(&pp->io)) {
		close(fd);
		pp->io.fd = -1;
		free(up);
		return (0);
	}
	pp->unitptr = up;

	/*
	 * Initialize miscellaneous variables
	 */
	peer->precision = PRECISION;
	pp->clockdesc = DESCRIPTION;
	memcpy((char *)&pp->refid, REFID, 4);
	up->tzhour = 0;
	up->tzminute = 0;

	*up->statscrn = '\0';
	up->lastptr = up->statscrn;
	up->pollcnt = 2;

	/*
	 * Get the identifier string, which is logged but otherwise ignored,
	 * and get the local timezone information
	 */
	up->linecnt = 1;
	if (write(pp->io.fd, "*IDN?\r:PTIME:TZONE?\r", 20) != 20)
	    refclock_report(peer, CEVNT_FAULT);

	return (1);
}
예제 #26
0
static int
gpsd_start(
	int     unit,
	peerT * peer)
{
	clockprocT * const pp = peer->procptr;
	gpsd_unitT * const up = emalloc_zero(sizeof(*up));

	struct stat sb;

	/* initialize the unit structure */
	up->fdt      = -1;
	up->addr     = s_gpsd_addr;
	up->tickpres = TICKOVER_LOW;

	/* setup refclock processing */
	up->unit    = unit;
	pp->unitptr = (caddr_t)up;
	pp->io.fd   = -1;
	pp->io.clock_recv = gpsd_receive;
	pp->io.srcclock   = peer;
	pp->io.datalen    = 0;
	pp->a_lastcode[0] = '\0';
	pp->lencode       = 0;
	pp->clockdesc     = DESCRIPTION;
	memcpy(&pp->refid, REFID, 4);

	/* Initialize miscellaneous variables */
	peer->precision = PRECISION;

	/* Create the device name and check for a Character Device. It's
	 * assumed that GPSD was started with the same link, so the
	 * names match. (If this is not practicable, we will have to
	 * read the symlink, if any, so we can get the true device
	 * file.)
	 */
	if (-1 == myasprintf(&up->device, "%s%u", s_dev_stem, unit)) {
	    msyslog(LOG_ERR, "%s clock device name too long",
		    refnumtoa(&peer->srcadr));
	    goto dev_fail;
	}
	if (-1 == stat(up->device, &sb) || !S_ISCHR(sb.st_mode)) {
		msyslog(LOG_ERR, "%s: '%s' is not a character device",
			refnumtoa(&peer->srcadr), up->device);
	    goto dev_fail;
	}
	LOGIF(CLOCKINFO,
	      (LOG_NOTICE, "%s: startup, device is '%s'",
	       refnumtoa(&peer->srcadr), up->device));
	return TRUE;

dev_fail:
	/* On failure, remove all UNIT ressources and declare defeat. */

	INSIST (up);
	free(up->device);
	free(up);

	pp->unitptr = (caddr_t)NULL;
	return FALSE;
}
예제 #27
0
/*
** queue_xmt
*/
void
queue_xmt(
	SOCKET			sock,
	struct dns_ctx *	dctx,
	sent_pkt *		spkt,
	u_int			xmt_delay
	)
{
	sockaddr_u *	dest;
	sent_pkt **	pkt_listp;
	sent_pkt *	match;
	xmt_ctx *	xctx;
	struct timeval	start_cb;
	struct timeval	delay;

	dest = &spkt->addr;
	if (IS_IPV6(dest))
		pkt_listp = &v6_pkts_list;
	else
		pkt_listp = &v4_pkts_list;

	/* reject attempts to add address already listed */
	for (match = *pkt_listp; match != NULL; match = match->link) {
		if (ADDR_PORT_EQ(&spkt->addr, &match->addr)) {
			if (strcasecmp(spkt->dctx->name,
				       match->dctx->name))
				printf("%s %s duplicate address from %s ignored.\n",
				       sptoa(&match->addr),
				       match->dctx->name,
				       spkt->dctx->name);
			else
				printf("%s %s, duplicate address ignored.\n",
				       sptoa(&match->addr),
				       match->dctx->name);
			dec_pending_ntp(spkt->dctx->name, &spkt->addr);
			free(spkt);
			return;
		}
	}

	LINK_SLIST(*pkt_listp, spkt, link);	

	xctx = emalloc_zero(sizeof(*xctx));
	xctx->sock = sock;
	xctx->spkt = spkt;
	gettimeofday_cached(base, &start_cb);
	xctx->sched = start_cb.tv_sec + (2 * xmt_delay);

	LINK_SORT_SLIST(xmt_q, xctx, (xctx->sched < L_S_S_CUR()->sched),
			link, xmt_ctx);
	if (xmt_q == xctx) {
		/*
		 * The new entry is the first scheduled.  The timer is
		 * either not active or is set for the second xmt
		 * context in xmt_q.
		 */
		if (NULL == ev_xmt_timer)
			ev_xmt_timer = event_new(base, INVALID_SOCKET,
						 EV_TIMEOUT,
						 &xmt_timer_cb, NULL);
		if (NULL == ev_xmt_timer) {
			msyslog(LOG_ERR,
				"queue_xmt: event_new(base, -1, EV_TIMEOUT) failed!");
			exit(1);
		}
		ZERO(delay);
		if (xctx->sched > start_cb.tv_sec)
			delay.tv_sec = xctx->sched - start_cb.tv_sec;
		event_add(ev_xmt_timer, &delay);
		TRACE(2, ("queue_xmt: xmt timer for %u usec\n",
			  (u_int)delay.tv_usec));
	}
}
예제 #28
0
파일: work_thread.c 프로젝트: ntpsec/ntpsec
static void
start_blocking_thread_internal(
	blocking_child *	c
	)
{
	pthread_attr_t	thr_attr;
	int		rc;
	int		pipe_ends[2];	/* read then write */
	bool		is_pipe;
	int		flags;
	size_t		stacksize;
	sigset_t	saved_sig_mask;

	rc = pipe_socketpair(&pipe_ends[0], &is_pipe);
	if (0 != rc) {
		msyslog(LOG_ERR, "start_blocking_thread: pipe_socketpair() %m");
		exit(1);
	}
	c->resp_read_pipe = move_fd(pipe_ends[0]);
	c->resp_write_pipe = move_fd(pipe_ends[1]);
	c->ispipe = is_pipe;
	flags = fcntl(c->resp_read_pipe, F_GETFL, 0);
	if (-1 == flags) {
		msyslog(LOG_ERR, "start_blocking_thread: fcntl(F_GETFL) %m");
		exit(1);
	}
	rc = fcntl(c->resp_read_pipe, F_SETFL, O_NONBLOCK | flags);
	if (-1 == rc) {
		msyslog(LOG_ERR,
			"start_blocking_thread: fcntl(F_SETFL, O_NONBLOCK) %m");
		exit(1);
	}
	(*addremove_io_fd)(c->resp_read_pipe, c->ispipe, false);
	pthread_attr_init(&thr_attr);
	pthread_attr_setdetachstate(&thr_attr, PTHREAD_CREATE_DETACHED);
	rc = pthread_attr_getstacksize(&thr_attr, &stacksize);
	if (0 != rc) {
		errno = rc;
		msyslog(LOG_ERR,
			"start_blocking_thread: pthread_attr_getstacksize %m");
	} else if (stacksize < THREAD_MINSTACKSIZE) {
		rc = pthread_attr_setstacksize(&thr_attr,
					       THREAD_MINSTACKSIZE);
		if (0 != rc) {
			errno = rc;
			msyslog(LOG_ERR,
				"start_blocking_thread: pthread_attr_setstacksize(0x%lx -> 0x%lx) %m",
				(u_long)stacksize,
				(u_long)THREAD_MINSTACKSIZE);
		}
	}
	pthread_attr_setscope(&thr_attr, PTHREAD_SCOPE_SYSTEM);
	c->thread_ref = emalloc_zero(sizeof(*c->thread_ref));
	block_thread_signals(&saved_sig_mask);
	rc = pthread_create(c->thread_ref, &thr_attr,
			    &blocking_thread, c);
	if (0 != rc) {
	    if (EAGAIN == errno) {
	        msyslog(LOG_ERR, "EAGAIN from pthread_create(), probably out of (locked) memory");
	    } else {
	        msyslog(LOG_ERR, "pthread_create() blocking child: %m");
	    }
	    exit(1);
	}
	pthread_sigmask(SIG_SETMASK, &saved_sig_mask, NULL);
	pthread_attr_destroy(&thr_attr);
}