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); }
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); }