Imported Upstream version 1.37
[platform/upstream/connman.git] / src / ntp.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2014  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/time.h>
32 #include <sys/timex.h>
33 #include <sys/socket.h>
34 #include <netinet/in.h>
35 #include <netinet/ip.h>
36 #include <arpa/inet.h>
37 #include <netdb.h>
38
39 #include <glib.h>
40
41 #include "connman.h"
42
43 struct ntp_short {
44         uint16_t seconds;
45         uint16_t fraction;
46 } __attribute__ ((packed));
47
48 struct ntp_time {
49         uint32_t seconds;
50         uint32_t fraction;
51 } __attribute__ ((packed));
52
53 struct ntp_msg {
54         uint8_t flags;                  /* Mode, version and leap indicator */
55         uint8_t stratum;                /* Stratum details */
56         int8_t poll;                    /* Maximum interval in log2 seconds */
57         int8_t precision;               /* Clock precision in log2 seconds */
58         struct ntp_short rootdelay;     /* Root delay */
59         struct ntp_short rootdisp;      /* Root dispersion */
60         uint32_t refid;                 /* Reference ID */
61         struct ntp_time reftime;        /* Reference timestamp */
62         struct ntp_time orgtime;        /* Origin timestamp */
63         struct ntp_time rectime;        /* Receive timestamp */
64         struct ntp_time xmttime;        /* Transmit timestamp */
65 } __attribute__ ((packed));
66
67 #define OFFSET_1900_1970  2208988800UL  /* 1970 - 1900 in seconds */
68
69 #define STEPTIME_MIN_OFFSET  0.4
70
71 #define LOGTOD(a)  ((a) < 0 ? 1. / (1L << -(a)) : 1L << (int)(a))
72 #define NSEC_PER_SEC  ((uint64_t)1000000000ULL)
73 #ifndef ADJ_SETOFFSET
74 #define ADJ_SETOFFSET           0x0100  /* add 'time' to current time */
75 #endif
76
77 #define NTP_SEND_TIMEOUT       2
78 #define NTP_SEND_RETRIES       3
79
80 #define NTP_FLAG_LI_SHIFT      6
81 #define NTP_FLAG_LI_MASK       0x3
82 #define NTP_FLAG_LI_NOWARNING  0x0
83 #define NTP_FLAG_LI_ADDSECOND  0x1
84 #define NTP_FLAG_LI_DELSECOND  0x2
85 #define NTP_FLAG_LI_NOTINSYNC  0x3
86
87 #define NTP_FLAG_VN_SHIFT      3
88 #define NTP_FLAG_VN_MASK       0x7
89
90 #define NTP_FLAG_MD_SHIFT      0
91 #define NTP_FLAG_MD_MASK       0x7
92 #define NTP_FLAG_MD_UNSPEC     0
93 #define NTP_FLAG_MD_ACTIVE     1
94 #define NTP_FLAG_MD_PASSIVE    2
95 #define NTP_FLAG_MD_CLIENT     3
96 #define NTP_FLAG_MD_SERVER     4
97 #define NTP_FLAG_MD_BROADCAST  5
98 #define NTP_FLAG_MD_CONTROL    6
99 #define NTP_FLAG_MD_PRIVATE    7
100
101 #define NTP_FLAG_VN_VER3       3
102 #define NTP_FLAG_VN_VER4       4
103
104 #define NTP_FLAGS_ENCODE(li, vn, md)  ((uint8_t)( \
105                       (((li) & NTP_FLAG_LI_MASK) << NTP_FLAG_LI_SHIFT) | \
106                       (((vn) & NTP_FLAG_VN_MASK) << NTP_FLAG_VN_SHIFT) | \
107                       (((md) & NTP_FLAG_MD_MASK) << NTP_FLAG_MD_SHIFT)))
108
109 #define NTP_FLAGS_LI_DECODE(flags)    ((uint8_t)(((flags) >> NTP_FLAG_LI_SHIFT) & NTP_FLAG_LI_MASK))
110 #define NTP_FLAGS_VN_DECODE(flags)    ((uint8_t)(((flags) >> NTP_FLAG_VN_SHIFT) & NTP_FLAG_VN_MASK))
111 #define NTP_FLAGS_MD_DECODE(flags)    ((uint8_t)(((flags) >> NTP_FLAG_MD_SHIFT) & NTP_FLAG_MD_MASK))
112
113 #define NTP_PRECISION_S    0
114 #define NTP_PRECISION_DS   -3
115 #define NTP_PRECISION_CS   -6
116 #define NTP_PRECISION_MS   -9
117 #define NTP_PRECISION_US   -19
118 #define NTP_PRECISION_NS   -29
119
120 struct ntp_data {
121         char *timeserver;
122         struct sockaddr_in6 timeserver_addr;
123         struct timespec mtx_time;
124         int transmit_fd;
125         gint timeout_id;
126         guint retries;
127         guint channel_watch;
128         gint poll_id;
129         uint32_t timeout;
130         __connman_ntp_cb_t cb;
131         void *user_data;
132 };
133
134 static struct ntp_data *ntp_data;
135
136 static void free_ntp_data(struct ntp_data *nd)
137 {
138         if (nd->poll_id)
139                 g_source_remove(nd->poll_id);
140         if (nd->timeout_id)
141                 g_source_remove(nd->timeout_id);
142         if (nd->channel_watch)
143                 g_source_remove(nd->channel_watch);
144         if (nd->timeserver)
145                 g_free(nd->timeserver);
146         g_free(nd);
147 }
148
149 static void send_packet(struct ntp_data *nd, struct sockaddr *server,
150                         uint32_t timeout);
151
152 static gboolean send_timeout(gpointer user_data)
153 {
154         struct ntp_data *nd = user_data;
155
156         DBG("send timeout %u (retries %d)", nd->timeout, nd->retries);
157
158         if (nd->retries++ == NTP_SEND_RETRIES)
159                 nd->cb(false, nd->user_data);
160         else
161                 send_packet(nd, (struct sockaddr *)&nd->timeserver_addr,
162                         nd->timeout << 1);
163
164         return FALSE;
165 }
166
167 static void send_packet(struct ntp_data *nd, struct sockaddr *server,
168                         uint32_t timeout)
169 {
170         struct ntp_msg msg;
171         struct timeval transmit_timeval;
172         ssize_t len;
173         void * addr;
174         int size;
175         char ipaddrstring[INET6_ADDRSTRLEN + 1];
176
177         /*
178          * At some point, we could specify the actual system precision with:
179          *
180          *   clock_getres(CLOCK_REALTIME, &ts);
181          *   msg.precision = (int)log2(ts.tv_sec + (ts.tv_nsec * 1.0e-9));
182          */
183         memset(&msg, 0, sizeof(msg));
184         msg.flags = NTP_FLAGS_ENCODE(NTP_FLAG_LI_NOTINSYNC, NTP_FLAG_VN_VER4,
185             NTP_FLAG_MD_CLIENT);
186         msg.poll = 10;
187         msg.precision = NTP_PRECISION_S;
188
189         if (server->sa_family == AF_INET) {
190                 size = sizeof(struct sockaddr_in);
191                 addr = (void *)&(((struct sockaddr_in *)&nd->timeserver_addr)->sin_addr);
192         } else if (server->sa_family == AF_INET6) {
193                 size = sizeof(struct sockaddr_in6);
194                 addr = (void *)&nd->timeserver_addr.sin6_addr;
195         } else {
196                 DBG("Family is neither ipv4 nor ipv6");
197                 nd->cb(false, nd->user_data);
198                 return;
199         }
200
201         gettimeofday(&transmit_timeval, NULL);
202         clock_gettime(CLOCK_MONOTONIC, &nd->mtx_time);
203
204         msg.xmttime.seconds = htonl(transmit_timeval.tv_sec + OFFSET_1900_1970);
205         msg.xmttime.fraction = htonl(transmit_timeval.tv_usec * 1000);
206
207         len = sendto(nd->transmit_fd, &msg, sizeof(msg), MSG_DONTWAIT,
208                                                 server, size);
209         if (len < 0 || len != sizeof(msg)) {
210                 DBG("Time request for server %s failed",
211                         inet_ntop(server->sa_family, addr, ipaddrstring, sizeof(ipaddrstring)));
212                 nd->cb(false, nd->user_data);
213                 return;
214         }
215
216         /*
217          * Add an exponential retry timeout to retry the existing
218          * request. After a set number of retries, we'll fallback to
219          * trying another server.
220          */
221
222         nd->timeout = timeout;
223         nd->timeout_id = g_timeout_add_seconds(timeout, send_timeout, nd);
224 }
225
226 static gboolean next_poll(gpointer user_data)
227 {
228         struct ntp_data *nd = user_data;
229         nd->poll_id = 0;
230
231         if (!nd->timeserver || nd->transmit_fd == 0)
232                 return FALSE;
233
234         send_packet(nd, (struct sockaddr *)&nd->timeserver_addr, NTP_SEND_TIMEOUT);
235
236         return FALSE;
237 }
238
239 static void reset_timeout(struct ntp_data *nd)
240 {
241         if (nd->timeout_id > 0) {
242                 g_source_remove(nd->timeout_id);
243                 nd->timeout_id = 0;
244         }
245
246         nd->retries = 0;
247 }
248
249 static void decode_msg(struct ntp_data *nd, void *base, size_t len,
250                 struct timeval *tv, struct timespec *mrx_time)
251 {
252         struct ntp_msg *msg = base;
253         double m_delta, org, rec, xmt, dst;
254         double delay, offset;
255         static guint transmit_delay;
256         struct timex tmx = {};
257
258         if (len < sizeof(*msg)) {
259                 connman_error("Invalid response from time server");
260                 return;
261         }
262
263         if (!tv) {
264                 connman_error("Invalid packet timestamp from time server");
265                 return;
266         }
267
268         DBG("flags      : 0x%02x", msg->flags);
269         DBG("stratum    : %u", msg->stratum);
270         DBG("poll       : %f seconds (%d)",
271                                 LOGTOD(msg->poll), msg->poll);
272         DBG("precision  : %f seconds (%d)",
273                                 LOGTOD(msg->precision), msg->precision);
274         DBG("root delay : %u seconds (fraction %u)",
275                         msg->rootdelay.seconds, msg->rootdelay.fraction);
276         DBG("root disp. : %u seconds (fraction %u)",
277                         msg->rootdisp.seconds, msg->rootdisp.fraction);
278         DBG("reference  : 0x%04x", msg->refid);
279
280         if (!msg->stratum) {
281                 /* RFC 4330 ch 8 Kiss-of-Death packet */
282                 uint32_t code = ntohl(msg->refid);
283
284                 connman_info("Skipping server %s KoD code %c%c%c%c",
285                         nd->timeserver, code >> 24, code >> 16 & 0xff,
286                         code >> 8 & 0xff, code & 0xff);
287                 nd->cb(false, nd->user_data);
288                 return;
289         }
290
291         transmit_delay = LOGTOD(msg->poll);
292
293         if (NTP_FLAGS_LI_DECODE(msg->flags) == NTP_FLAG_LI_NOTINSYNC) {
294                 DBG("ignoring unsynchronized peer");
295                 nd->cb(false, nd->user_data);
296                 return;
297         }
298
299
300         if (NTP_FLAGS_VN_DECODE(msg->flags) != NTP_FLAG_VN_VER4) {
301                 if (NTP_FLAGS_VN_DECODE(msg->flags) == NTP_FLAG_VN_VER3) {
302                         DBG("requested version %d, accepting version %d",
303                                 NTP_FLAG_VN_VER4, NTP_FLAGS_VN_DECODE(msg->flags));
304                 } else {
305                         DBG("unsupported version %d", NTP_FLAGS_VN_DECODE(msg->flags));
306                         nd->cb(false, nd->user_data);
307                         return;
308                 }
309         }
310
311         if (NTP_FLAGS_MD_DECODE(msg->flags) != NTP_FLAG_MD_SERVER) {
312                 DBG("unsupported mode %d", NTP_FLAGS_MD_DECODE(msg->flags));
313                 nd->cb(false, nd->user_data);
314                 return;
315         }
316
317         m_delta = mrx_time->tv_sec - nd->mtx_time.tv_sec +
318                 1.0e-9 * (mrx_time->tv_nsec - nd->mtx_time.tv_nsec);
319
320         org = tv->tv_sec + (1.0e-6 * tv->tv_usec) - m_delta + OFFSET_1900_1970;
321         rec = ntohl(msg->rectime.seconds) +
322                         ((double) ntohl(msg->rectime.fraction) / UINT_MAX);
323         xmt = ntohl(msg->xmttime.seconds) +
324                         ((double) ntohl(msg->xmttime.fraction) / UINT_MAX);
325         dst = tv->tv_sec + (1.0e-6 * tv->tv_usec) + OFFSET_1900_1970;
326
327         DBG("org=%f rec=%f xmt=%f dst=%f", org, rec, xmt, dst);
328
329         offset = ((rec - org) + (xmt - dst)) / 2;
330         delay = (dst - org) - (xmt - rec);
331
332         DBG("offset=%f delay=%f", offset, delay);
333
334         /* Remove the timeout, as timeserver has responded */
335
336         reset_timeout(nd);
337
338         /*
339          * Now poll the server every transmit_delay seconds
340          * for time correction.
341          */
342         if (nd->poll_id > 0)
343                 g_source_remove(nd->poll_id);
344
345         DBG("Timeserver %s, next sync in %d seconds", nd->timeserver,
346                 transmit_delay);
347
348         nd->poll_id = g_timeout_add_seconds(transmit_delay, next_poll, nd);
349
350         if (offset < STEPTIME_MIN_OFFSET && offset > -STEPTIME_MIN_OFFSET) {
351                 tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR | ADJ_ESTERROR;
352                 tmx.status = STA_PLL;
353                 tmx.offset = offset * NSEC_PER_SEC;
354                 tmx.constant = msg->poll - 4;
355                 tmx.maxerror = 0;
356                 tmx.esterror = 0;
357
358                 connman_info("ntp: adjust (slew): %+.6f sec", offset);
359         } else {
360                 tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_SETOFFSET | ADJ_MAXERROR | ADJ_ESTERROR;
361
362                 /* ADJ_NANO uses nanoseconds in the microseconds field */
363                 tmx.time.tv_sec = (long)offset;
364                 tmx.time.tv_usec = (offset - tmx.time.tv_sec) * NSEC_PER_SEC;
365                 tmx.maxerror = 0;
366                 tmx.esterror = 0;
367
368                 /* the kernel expects -0.3s as {-1, 7000.000.000} */
369                 if (tmx.time.tv_usec < 0) {
370                         tmx.time.tv_sec  -= 1;
371                         tmx.time.tv_usec += NSEC_PER_SEC;
372                 }
373
374                 connman_info("ntp: adjust (jump): %+.6f sec", offset);
375         }
376
377         if (NTP_FLAGS_LI_DECODE(msg->flags) & NTP_FLAG_LI_ADDSECOND)
378                 tmx.status |= STA_INS;
379         else if (NTP_FLAGS_LI_DECODE(msg->flags) & NTP_FLAG_LI_DELSECOND)
380                 tmx.status |= STA_DEL;
381
382         if (adjtimex(&tmx) < 0) {
383                 connman_error("Failed to adjust time: %s (%d)", strerror(errno), errno);
384                 nd->cb(false, nd->user_data);
385                 return;
386         }
387
388         DBG("interval/delta/delay/drift %fs/%+.3fs/%.3fs/%+ldppm",
389                 LOGTOD(msg->poll), offset, delay, tmx.freq / 65536);
390
391         nd->cb(true, nd->user_data);
392 }
393
394 static gboolean received_data(GIOChannel *channel, GIOCondition condition,
395                                                         gpointer user_data)
396 {
397         struct ntp_data *nd = user_data;
398         unsigned char buf[128];
399         struct sockaddr_in6 sender_addr;
400         struct msghdr msg;
401         struct iovec iov;
402         struct cmsghdr *cmsg;
403         struct timeval *tv;
404         struct timespec mrx_time;
405         char aux[128];
406         ssize_t len;
407         int fd;
408         int size;
409         void * addr_ptr;
410         void * src_ptr;
411
412         if (condition & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
413                 connman_error("Problem with timer server channel");
414                 nd->channel_watch = 0;
415                 return FALSE;
416         }
417
418         fd = g_io_channel_unix_get_fd(channel);
419
420         iov.iov_base = buf;
421         iov.iov_len = sizeof(buf);
422
423         memset(&msg, 0, sizeof(msg));
424         msg.msg_iov = &iov;
425         msg.msg_iovlen = 1;
426         msg.msg_control = aux;
427         msg.msg_controllen = sizeof(aux);
428         msg.msg_name = &sender_addr;
429         msg.msg_namelen = sizeof(sender_addr);
430
431         len = recvmsg(fd, &msg, MSG_DONTWAIT);
432         if (len < 0)
433                 return TRUE;
434
435         if (sender_addr.sin6_family == AF_INET) {
436                 size = 4;
437                 addr_ptr = &((struct sockaddr_in *)&nd->timeserver_addr)->sin_addr;
438                 src_ptr = &((struct sockaddr_in *)&sender_addr)->sin_addr;
439         } else if (sender_addr.sin6_family == AF_INET6) {
440                 size = 16;
441                 addr_ptr = &((struct sockaddr_in6 *)&nd->timeserver_addr)->sin6_addr;
442                 src_ptr = &((struct sockaddr_in6 *)&sender_addr)->sin6_addr;
443         } else {
444                 connman_error("Not a valid family type");
445                 return TRUE;
446         }
447
448         if(memcmp(addr_ptr, src_ptr, size) != 0)
449                 return TRUE;
450
451         tv = NULL;
452         clock_gettime(CLOCK_MONOTONIC, &mrx_time);
453
454         for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
455                 if (cmsg->cmsg_level != SOL_SOCKET)
456                         continue;
457
458                 switch (cmsg->cmsg_type) {
459                 case SCM_TIMESTAMP:
460                         tv = (struct timeval *) CMSG_DATA(cmsg);
461                         break;
462                 }
463         }
464
465         decode_msg(nd, iov.iov_base, iov.iov_len, tv, &mrx_time);
466
467         return TRUE;
468 }
469
470 static void start_ntp(struct ntp_data *nd)
471 {
472         GIOChannel *channel;
473         struct addrinfo hint;
474         struct addrinfo *info;
475         struct sockaddr * addr;
476         struct sockaddr_in  * in4addr;
477         struct sockaddr_in6 in6addr;
478         int size;
479         int family;
480         int tos = IPTOS_LOWDELAY, timestamp = 1;
481         int ret;
482
483         memset(&hint, 0, sizeof(hint));
484         hint.ai_family = AF_UNSPEC;
485         hint.ai_socktype = SOCK_DGRAM;
486         hint.ai_flags = AI_NUMERICHOST | AI_PASSIVE;
487         ret = getaddrinfo(nd->timeserver, NULL, &hint, &info);
488
489         if (ret) {
490                 connman_error("cannot get server info");
491                 return;
492         }
493
494         family = info->ai_family;
495
496         memcpy(&ntp_data->timeserver_addr, info->ai_addr, info->ai_addrlen);
497         freeaddrinfo(info);
498         memset(&in6addr, 0, sizeof(in6addr));
499
500         if (family == AF_INET) {
501                 ((struct sockaddr_in *)&ntp_data->timeserver_addr)->sin_port = htons(123);
502                 in4addr = (struct sockaddr_in *)&in6addr;
503                 in4addr->sin_family = family;
504                 addr = (struct sockaddr *)in4addr;
505                 size = sizeof(struct sockaddr_in);
506         } else if (family == AF_INET6) {
507                 ntp_data->timeserver_addr.sin6_port = htons(123);
508                 in6addr.sin6_family = family;
509                 addr = (struct sockaddr *)&in6addr;
510                 size = sizeof(in6addr);
511         } else {
512                 connman_error("Family is neither ipv4 nor ipv6");
513                 return;
514         }
515
516         DBG("server %s family %d", nd->timeserver, family);
517
518         if (nd->channel_watch > 0)
519                 goto send;
520
521         nd->transmit_fd = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
522
523         if (nd->transmit_fd <= 0) {
524                 if (errno != EAFNOSUPPORT)
525                         connman_error("Failed to open time server socket");
526         }
527
528         if (bind(nd->transmit_fd, (struct sockaddr *) addr, size) < 0) {
529                 connman_error("Failed to bind time server socket");
530                 goto err;
531         }
532
533         if (family == AF_INET) {
534                 if (setsockopt(nd->transmit_fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) {
535                         connman_error("Failed to set type of service option");
536                         goto err;
537                 }
538         }
539
540         if (setsockopt(nd->transmit_fd, SOL_SOCKET, SO_TIMESTAMP, &timestamp,
541                                                 sizeof(timestamp)) < 0) {
542                 connman_error("Failed to enable timestamp support");
543                 goto err;
544         }
545
546         channel = g_io_channel_unix_new(nd->transmit_fd);
547         if (!channel)
548                 goto err;
549
550         g_io_channel_set_encoding(channel, NULL, NULL);
551         g_io_channel_set_buffered(channel, FALSE);
552
553         g_io_channel_set_close_on_unref(channel, TRUE);
554
555         nd->channel_watch = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT,
556                                 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
557                                 received_data, nd, NULL);
558
559         g_io_channel_unref(channel);
560
561 send:
562         send_packet(nd, (struct sockaddr*)&ntp_data->timeserver_addr,
563                 NTP_SEND_TIMEOUT);
564         return;
565
566 err:
567         if (nd->transmit_fd > 0)
568                 close(nd->transmit_fd);
569
570         nd->cb(false, nd->user_data);
571 }
572
573 int __connman_ntp_start(char *server, __connman_ntp_cb_t callback,
574                         void *user_data)
575 {
576         if (!server)
577                 return -EINVAL;
578
579         if (ntp_data) {
580                 connman_warn("ntp_data is not NULL (timerserver %s)",
581                         ntp_data->timeserver);
582                 free_ntp_data(ntp_data);
583         }
584
585         ntp_data = g_new0(struct ntp_data, 1);
586
587         ntp_data->timeserver = g_strdup(server);
588         ntp_data->cb = callback;
589         ntp_data->user_data = user_data;
590
591         start_ntp(ntp_data);
592
593         return 0;
594 }
595
596 void __connman_ntp_stop()
597 {
598         if (ntp_data) {
599                 free_ntp_data(ntp_data);
600                 ntp_data = NULL;
601         }
602 }