示例#1
0
/* Send a packet */
int
sendpkt (
	SOCKET rsock,
	sockaddr_u *dest,
	struct pkt *pkt,
	int len
	)
{
	int cc;

#ifdef DEBUG
	if (debug > 2) {
		printf("sntp sendpkt: Packet data:\n");
		pkt_output(pkt, len, stdout);
	}
#endif
	TRACE(1, ("sntp sendpkt: Sending packet to %s ...\n",
		  sptoa(dest)));

	cc = sendto(rsock, (void *)pkt, len, 0, &dest->sa, 
		    SOCKLEN(dest));
	if (cc == SOCKET_ERROR) {
		msyslog(LOG_ERR, "Send to %s failed, %m",
			sptoa(dest));
		return FALSE;
	}
	TRACE(1, ("Packet sent.\n"));

	return TRUE;
}
示例#2
0
static
struct peer *		
findexistingpeer_addr(
	sockaddr_u *	addr,
	struct peer *	start_peer,
	int		mode,
	u_char		cast_flags
	)
{
	struct peer *peer;

	DPRINTF(2, ("findexistingpeer_addr(%s, %s, %d, 0x%x)\n",
		sptoa(addr),
		(start_peer)
		    ? sptoa(&start_peer->srcadr)
		    : "NULL",
		mode, (u_int)cast_flags));

	/*
	 * start_peer is included so we can locate instances of the
	 * same peer through different interfaces in the hash table.
	 * Without MDF_BCLNT, a match requires the same mode and remote
	 * address.  MDF_BCLNT associations start out as MODE_CLIENT
	 * if broadcastdelay is not specified, and switch to
	 * MODE_BCLIENT after estimating the one-way delay.  Duplicate
	 * associations are expanded in definition to match any other
	 * MDF_BCLNT with the same srcadr (remote, unicast address).
	 */
	if (NULL == start_peer)
		peer = peer_hash[NTP_HASH_ADDR(addr)];
	else
		peer = start_peer->adr_link;
	
	while (peer != NULL) {
		DPRINTF(3, ("%s %s %d %d 0x%x 0x%x ", sptoa(addr),
			sptoa(&peer->srcadr), mode, peer->hmode,
			(u_int)cast_flags, (u_int)peer->cast_flags));
 		if ((-1 == mode || peer->hmode == mode ||
		     ((MDF_BCLNT & peer->cast_flags) &&
		      (MDF_BCLNT & cast_flags))) &&
		    ADDR_PORT_EQ(addr, &peer->srcadr)) {
			DPRINTF(3, ("found.\n"));
			break;
		}
		DPRINTF(3, ("\n"));
		peer = peer->adr_link;
	}

	return peer;
}
示例#3
0
/* Receive raw data */
int
recvdata(
	SOCKET		rsock,
	sockaddr_u *	sender,
	void *		rdata,
	int		rdata_length
	)
{
	GETSOCKNAME_SOCKLEN_TYPE slen;
	int recvc;

	slen = sizeof(*sender);
	recvc = recvfrom(rsock, rdata, rdata_length, 0,
			 &sender->sa, &slen);
	if (recvc < 0)
		return recvc;
#ifdef DEBUG
	if (debug > 2) {
		printf("Received %d bytes from %s:\n", recvc, sptoa(sender));
		pkt_output((struct pkt *)rdata, recvc, stdout);
	}
#endif
	return recvc;
}
示例#4
0
/*
** Socket readable/timeout Callback:
** Read in the packet
** Unicast:
** - close socket
** - decrement n_pending_ntp
** - If packet is good, set the time and "exit"
** Broadcast:
** - If packet is good, set the time and "exit"
*/
void
sock_cb(
	evutil_socket_t fd,
	short what,
	void *ptr
	)
{
	sockaddr_u	sender;
	sockaddr_u *	psau;
	sent_pkt **	p_pktlist;
	sent_pkt *	spkt;
	int		rpktl;
	int		rc;

	INSIST(sock4 == fd || sock6 == fd);

	TRACE(3, ("sock_cb: event on sock%s:%s%s%s%s\n",
		  (fd == sock6)
		      ? "6"
		      : "4",
		  (what & EV_TIMEOUT) ? " timeout" : "",
		  (what & EV_READ)    ? " read" : "",
		  (what & EV_WRITE)   ? " write" : "",
		  (what & EV_SIGNAL)  ? " signal" : ""));

	if (!(EV_READ & what)) {
		if (EV_TIMEOUT & what)
			timeout_queries();

		return;
	}

	/* Read in the packet */
	rpktl = recvdata(fd, &sender, &rbuf, sizeof(rbuf));
	if (rpktl < 0) {
		msyslog(LOG_DEBUG, "recvfrom error %m");
		return;
	}

	if (sock6 == fd)
		p_pktlist = &v6_pkts_list;
	else
		p_pktlist = &v4_pkts_list;

	for (spkt = *p_pktlist; spkt != NULL; spkt = spkt->link) {
		psau = &spkt->addr;
		if (SOCK_EQ(&sender, psau))
			break;
	}
	if (NULL == spkt) {
		msyslog(LOG_WARNING,
			"Packet from unexpected source %s dropped",
			sptoa(&sender));
		return;
	}

	TRACE(1, ("sock_cb: %s %s\n", spkt->dctx->name,
		  sptoa(&sender)));

	rpktl = process_pkt(&r_pkt, &sender, rpktl, MODE_SERVER,
			    &spkt->x_pkt, "sock_cb");

	TRACE(2, ("sock_cb: process_pkt returned %d\n", rpktl));

	/* If this is a Unicast packet, one down ... */
	if (!spkt->done && (CTX_UCST & spkt->dctx->flags)) {
		dec_pending_ntp(spkt->dctx->name, &spkt->addr);
		spkt->done = TRUE;
	}


	/* If the packet is good, set the time and we're all done */
	rc = handle_pkt(rpktl, &r_pkt, &spkt->addr, spkt->dctx->name);
	if (0 != rc)
		TRACE(1, ("sock_cb: handle_pkt() returned %d\n", rc));
	check_exit_conditions();
}
示例#5
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));
	}
}