예제 #1
0
파일: ntp.c 프로젝트: igaw/connman
static void send_packet(struct ntp_data *nd, struct sockaddr *server,
			uint32_t timeout)
{
	struct ntp_msg msg;
	struct timeval transmit_timeval;
	ssize_t len;
	void * addr;
	int size;
	char ipaddrstring[INET6_ADDRSTRLEN + 1];

	/*
	 * At some point, we could specify the actual system precision with:
	 *
	 *   clock_getres(CLOCK_REALTIME, &ts);
	 *   msg.precision = (int)log2(ts.tv_sec + (ts.tv_nsec * 1.0e-9));
	 */
	memset(&msg, 0, sizeof(msg));
	msg.flags = NTP_FLAGS_ENCODE(NTP_FLAG_LI_NOTINSYNC, NTP_FLAG_VN_VER4,
	    NTP_FLAG_MD_CLIENT);
	msg.poll = 10;
	msg.precision = NTP_PRECISION_S;

	if (server->sa_family == AF_INET) {
		size = sizeof(struct sockaddr_in);
		addr = (void *)&(((struct sockaddr_in *)&nd->timeserver_addr)->sin_addr);
	} else if (server->sa_family == AF_INET6) {
		size = sizeof(struct sockaddr_in6);
		addr = (void *)&nd->timeserver_addr.sin6_addr;
	} else {
		DBG("Family is neither ipv4 nor ipv6");
		nd->cb(false, nd->user_data);
		return;
	}

	gettimeofday(&transmit_timeval, NULL);
	clock_gettime(CLOCK_MONOTONIC, &nd->mtx_time);

	msg.xmttime.seconds = htonl(transmit_timeval.tv_sec + OFFSET_1900_1970);
	msg.xmttime.fraction = htonl(transmit_timeval.tv_usec * 1000);

	len = sendto(nd->transmit_fd, &msg, sizeof(msg), MSG_DONTWAIT,
						server, size);
	if (len < 0 || len != sizeof(msg)) {
		DBG("Time request for server %s failed",
			inet_ntop(server->sa_family, addr, ipaddrstring, sizeof(ipaddrstring)));
		nd->cb(false, nd->user_data);
		return;
	}

	/*
	 * Add an exponential retry timeout to retry the existing
	 * request. After a set number of retries, we'll fallback to
	 * trying another server.
	 */

	nd->timeout = timeout;
	nd->timeout_id = g_timeout_add_seconds(timeout, send_timeout, nd);
}
예제 #2
0
파일: ntp.c 프로젝트: HoraceWeebler/connman
static void send_packet(int fd, const char *server)
{
	struct ntp_msg msg;
	struct sockaddr_in addr;
	struct timeval transmit_timeval;
	ssize_t len;

	/*
	 * At some point, we could specify the actual system precision with:
	 *
	 *   clock_getres(CLOCK_REALTIME, &ts);
	 *   msg.precision = (int)log2(ts.tv_sec + (ts.tv_nsec * 1.0e-9));
	 */
	memset(&msg, 0, sizeof(msg));
	msg.flags = NTP_FLAGS_ENCODE(NTP_FLAG_LI_NOTINSYNC, NTP_FLAG_VN_VER4,
	    NTP_FLAG_MD_CLIENT);
	msg.poll = 4;	// min
	msg.poll = 10;	// max
	msg.precision = NTP_PRECISION_S;

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(123);
	addr.sin_addr.s_addr = inet_addr(server);

	gettimeofday(&transmit_timeval, NULL);
	clock_gettime(CLOCK_MONOTONIC, &mtx_time);

	msg.xmttime.seconds = htonl(transmit_timeval.tv_sec + OFFSET_1900_1970);
	msg.xmttime.fraction = htonl(transmit_timeval.tv_usec * 1000);

	len = sendto(fd, &msg, sizeof(msg), MSG_DONTWAIT,
						&addr, sizeof(addr));
	if (len < 0) {
		connman_error("Time request for server %s failed (%d/%s)",
			server, errno, strerror(errno));

		if (errno == ENETUNREACH)
			__connman_timeserver_sync_next();

		return;
	}

	if (len != sizeof(msg)) {
		connman_error("Broken time request for server %s", server);
		return;
	}

	/*
	 * Add a retry timeout of two seconds to retry the existing
	 * request. After a set number of retries, we'll fallback to
	 * trying another server.
	 */

	timeout_id = g_timeout_add_seconds(NTP_SEND_TIMEOUT, send_timeout, NULL);
}