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++; }
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; }
/* * 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 }
/* * 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; }
/* * 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); }
/* * 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); }
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; }
/* ** 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); }
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); }
/* * 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; }
/* * 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); }
/* * 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); }
/* * 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); }
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; }
/* * 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); }
/* * 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; } }
/* * 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); }
/* * 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); */ }
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; }
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; }
/* ** 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(); }
/* * 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); }
/* * 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); }
/* * 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); }
/* * 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); }
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; }
/* ** 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)); } }
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); }