示例#1
0
static void resolv_result(GResolvResultStatus status, char **results,
				gpointer user_data)
{
	int i;

	DBG("status %d", status);

	if (status == G_RESOLV_RESULT_STATUS_SUCCESS) {
		if (results) {
			for (i = 0; results[i]; i++) {
				DBG("result[%d]: %s", i, results[i]);
				if (i == 0)
					continue;

				ts_list = __connman_timeserver_add_list(
							ts_list, results[i]);
			}

			DBG("Using timeserver %s", results[0]);

			__connman_ntp_start(results[0]);

			return;
		}
	}

	/* If resolving fails, move to the next server */
	__connman_timeserver_sync_next();
}
示例#2
0
static void next_server(void)
{
	if (timeserver) {
		g_free(timeserver);
		timeserver = NULL;
	}

	__connman_timeserver_sync_next();
}
示例#3
0
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);
}
示例#4
0
/*
 * This function must be called everytime the default service changes, the
 * service timeserver(s) or gatway changes or the global timeserver(s) changes.
 */
int __connman_timeserver_sync(struct connman_service *default_service)
{
	struct connman_service *service;

	if (default_service)
		service = default_service;
	else
		service = __connman_service_get_default();

	if (!service)
		return -EINVAL;

	if (!resolv)
		return 0;
	/*
	 * Before we start creating the new timeserver list we must stop
	 * any ongoing ntp query and server resolution.
	 */

	__connman_ntp_stop();

	ts_recheck_disable();

	if (resolv_id > 0)
		g_resolv_cancel_lookup(resolv, resolv_id);

	g_slist_free_full(ts_list, g_free);

	ts_list = __connman_timeserver_get_all(service);

	__connman_service_timeserver_changed(service, ts_list);

	if (!ts_list) {
		DBG("No timeservers set.");
		return 0;
	}

	ts_recheck_enable();

	__connman_timeserver_sync_next();

	return 0;
}