Added support of WPA3-SAE security mode.
[platform/upstream/connman.git] / src / ntp.c
old mode 100644 (file)
new mode 100755 (executable)
index 1916a72..11512a0
--- a/src/ntp.c
+++ b/src/ntp.c
@@ -2,7 +2,7 @@
  *
  *  Connection Manager
  *
- *  Copyright (C) 2007-2012  Intel Corporation. All rights reserved.
+ *  Copyright (C) 2007-2014  Intel Corporation. All rights reserved.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 as
 #include <stdlib.h>
 #include <string.h>
 #include <sys/time.h>
+#include <sys/timex.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <netinet/ip.h>
 #include <arpa/inet.h>
+#include <netdb.h>
 
 #include <glib.h>
 
@@ -65,9 +67,16 @@ struct ntp_msg {
 
 #define OFFSET_1900_1970  2208988800UL /* 1970 - 1900 in seconds */
 
-#define STEPTIME_MIN_OFFSET  0.128
+#define STEPTIME_MIN_OFFSET  0.4
 
 #define LOGTOD(a)  ((a) < 0 ? 1. / (1L << -(a)) : 1L << (int)(a))
+#define NSEC_PER_SEC  ((uint64_t)1000000000ULL)
+#ifndef ADJ_SETOFFSET
+#define ADJ_SETOFFSET          0x0100  /* add 'time' to current time */
+#endif
+
+#define NTP_SEND_TIMEOUT       2
+#define NTP_SEND_RETRIES       3
 
 #define NTP_FLAG_LI_SHIFT      6
 #define NTP_FLAG_LI_MASK       0x3
@@ -90,6 +99,9 @@ struct ntp_msg {
 #define NTP_FLAG_MD_CONTROL    6
 #define NTP_FLAG_MD_PRIVATE    7
 
+#define NTP_FLAG_VN_VER3       3
+#define NTP_FLAG_VN_VER4       4
+
 #define NTP_FLAGS_ENCODE(li, vn, md)  ((uint8_t)( \
                       (((li) & NTP_FLAG_LI_MASK) << NTP_FLAG_LI_SHIFT) | \
                       (((vn) & NTP_FLAG_VN_MASK) << NTP_FLAG_VN_SHIFT) | \
@@ -99,40 +111,94 @@ struct ntp_msg {
 #define NTP_FLAGS_VN_DECODE(flags)    ((uint8_t)(((flags) >> NTP_FLAG_VN_SHIFT) & NTP_FLAG_VN_MASK))
 #define NTP_FLAGS_MD_DECODE(flags)    ((uint8_t)(((flags) >> NTP_FLAG_MD_SHIFT) & NTP_FLAG_MD_MASK))
 
+#define NTP_PRECISION_S    0
+#define NTP_PRECISION_DS   -3
+#define NTP_PRECISION_CS   -6
+#define NTP_PRECISION_MS   -9
+#define NTP_PRECISION_US   -19
+#define NTP_PRECISION_NS   -29
+
 static guint channel_watch = 0;
-static struct timeval transmit_timeval;
+static struct timespec mtx_time;
 static int transmit_fd = 0;
 
 static char *timeserver = NULL;
+static struct sockaddr_in6 timeserver_addr;
 static gint poll_id = 0;
 static gint timeout_id = 0;
+static guint retries = 0;
+
+static void send_packet(int fd, struct sockaddr *server, uint32_t timeout);
+
+static void next_server(void)
+{
+       if (timeserver) {
+               g_free(timeserver);
+               timeserver = NULL;
+       }
+
+       __connman_timeserver_sync_next();
+}
+
+static gboolean send_timeout(gpointer user_data)
+{
+       uint32_t timeout = GPOINTER_TO_UINT(user_data);
+
+       DBG("send timeout %u (retries %d)", timeout, retries);
 
-static void send_packet(int fd, const char *server)
+       if (retries++ == NTP_SEND_RETRIES)
+               next_server();
+       else
+               send_packet(transmit_fd, (struct sockaddr *)&timeserver_addr, timeout << 1);
+
+       return FALSE;
+}
+
+static void send_packet(int fd, struct sockaddr *server, uint32_t timeout)
 {
        struct ntp_msg msg;
-       struct sockaddr_in addr;
+       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_NOWARNING, 4, NTP_FLAG_MD_CLIENT);
-       msg.poll = 4;   // min
-       msg.poll = 10;  // max
-
-       memset(&addr, 0, sizeof(addr));
-       addr.sin_family = AF_INET;
-       addr.sin_port = htons(123);
-       addr.sin_addr.s_addr = inet_addr(server);
+       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 *)&timeserver_addr)->sin_addr);
+       } else if (server->sa_family == AF_INET6) {
+               size = sizeof(struct sockaddr_in6);
+               addr = (void *)&timeserver_addr.sin6_addr;
+       } else {
+               connman_error("Family is neither ipv4 nor ipv6");
+               return;
+       }
 
        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));
+                                               server, size);
+
        if (len < 0) {
                connman_error("Time request for server %s failed (%d/%s)",
-                       server, errno, strerror(errno));
+                       inet_ntop(server->sa_family, addr, ipaddrstring, sizeof(ipaddrstring)),
+                       errno, strerror(errno));
 
                if (errno == ENETUNREACH)
                        __connman_timeserver_sync_next();
@@ -141,46 +207,59 @@ static void send_packet(int fd, const char *server)
        }
 
        if (len != sizeof(msg)) {
-               connman_error("Broken time request for server %s", server);
+               connman_error("Broken time request for server %s",
+                       inet_ntop(server->sa_family, addr, ipaddrstring, sizeof(ipaddrstring)));
                return;
        }
-}
 
-static gboolean next_server(gpointer user_data)
-{
-       if (timeserver != NULL) {
-               g_free(timeserver);
-               timeserver = NULL;
-       }
-
-       __connman_timeserver_sync_next();
+       /*
+        * Add an exponential retry timeout to retry the existing
+        * request. After a set number of retries, we'll fallback to
+        * trying another server.
+        */
 
-       return FALSE;
+       timeout_id = g_timeout_add_seconds(timeout, send_timeout,
+                                       GUINT_TO_POINTER(timeout));
 }
 
 static gboolean next_poll(gpointer user_data)
 {
-       if (timeserver == NULL || transmit_fd == 0)
+       poll_id = 0;
+
+       if (!timeserver || transmit_fd == 0)
                return FALSE;
 
-       send_packet(transmit_fd, timeserver);
+       send_packet(transmit_fd, (struct sockaddr *)&timeserver_addr, NTP_SEND_TIMEOUT);
 
        return FALSE;
 }
 
-static void decode_msg(void *base, size_t len, struct timeval *tv)
+static void reset_timeout(void)
+{
+       if (timeout_id > 0) {
+               g_source_remove(timeout_id);
+               timeout_id = 0;
+       }
+
+       retries = 0;
+}
+
+static void decode_msg(void *base, size_t len, struct timeval *tv,
+               struct timespec *mrx_time)
 {
        struct ntp_msg *msg = base;
-       double org, rec, xmt, dst;
+       double m_delta, org, rec, xmt, dst;
        double delay, offset;
        static guint transmit_delay;
-
+#if !defined TIZEN_EXT
+       struct timex tmx = {};
+#endif
        if (len < sizeof(*msg)) {
                connman_error("Invalid response from time server");
                return;
        }
 
-       if (tv == NULL) {
+       if (!tv) {
                connman_error("Invalid packet timestamp from time server");
                return;
        }
@@ -197,13 +276,44 @@ static void decode_msg(void *base, size_t len, struct timeval *tv)
                        msg->rootdisp.seconds, msg->rootdisp.fraction);
        DBG("reference  : 0x%04x", msg->refid);
 
+       if (!msg->stratum) {
+               /* RFC 4330 ch 8 Kiss-of-Death packet */
+               uint32_t code = ntohl(msg->refid);
+
+               connman_info("Skipping server %s KoD code %c%c%c%c",
+                       timeserver, code >> 24, code >> 16 & 0xff,
+                       code >> 8 & 0xff, code & 0xff);
+               next_server();
+               return;
+       }
+
        transmit_delay = LOGTOD(msg->poll);
 
-       if (msg->flags != 0x24)
+       if (NTP_FLAGS_LI_DECODE(msg->flags) == NTP_FLAG_LI_NOTINSYNC) {
+               DBG("ignoring unsynchronized peer");
                return;
+       }
+
 
-       org = transmit_timeval.tv_sec +
-                       (1.0e-6 * transmit_timeval.tv_usec) + OFFSET_1900_1970;
+       if (NTP_FLAGS_VN_DECODE(msg->flags) != NTP_FLAG_VN_VER4) {
+               if (NTP_FLAGS_VN_DECODE(msg->flags) == NTP_FLAG_VN_VER3) {
+                       DBG("requested version %d, accepting version %d",
+                               NTP_FLAG_VN_VER4, NTP_FLAGS_VN_DECODE(msg->flags));
+               } else {
+                       DBG("unsupported version %d", NTP_FLAGS_VN_DECODE(msg->flags));
+                       return;
+               }
+       }
+
+       if (NTP_FLAGS_MD_DECODE(msg->flags) != NTP_FLAG_MD_SERVER) {
+               DBG("unsupported mode %d", NTP_FLAGS_MD_DECODE(msg->flags));
+               return;
+       }
+
+       m_delta = mrx_time->tv_sec - mtx_time.tv_sec +
+               1.0e-9 * (mrx_time->tv_nsec - mtx_time.tv_nsec);
+
+       org = tv->tv_sec + (1.0e-6 * tv->tv_usec) - m_delta + OFFSET_1900_1970;
        rec = ntohl(msg->rectime.seconds) +
                        ((double) ntohl(msg->rectime.fraction) / UINT_MAX);
        xmt = ntohl(msg->xmttime.seconds) +
@@ -218,8 +328,8 @@ static void decode_msg(void *base, size_t len, struct timeval *tv)
        DBG("offset=%f delay=%f", offset, delay);
 
        /* Remove the timeout, as timeserver has responded */
-       if (timeout_id > 0)
-               g_source_remove(timeout_id);
+
+       reset_timeout();
 
        /*
         * Now poll the server every transmit_delay seconds
@@ -232,53 +342,124 @@ static void decode_msg(void *base, size_t len, struct timeval *tv)
 
        poll_id = g_timeout_add_seconds(transmit_delay, next_poll, NULL);
 
-       connman_info("ntp: time slew %+.6f s", offset);
+#if defined TIZEN_EXT
+       //send the dbus message to alram-manager
+       {
+#define TIME_BUS_NAME "org.tizen.alarm.manager"
+#define TIME_INTERFACE "org.tizen.alarm.manager"
+#define TIME_PATH "/org/tizen/alarm/manager"
+#define TIME_METHOD "alarm_set_time_with_propagation_delay"
 
-       if (offset < STEPTIME_MIN_OFFSET && offset > -STEPTIME_MIN_OFFSET) {
-               struct timeval adj;
+               struct timespec cur = {0};
+               struct timespec req = {0};
+               double dtime;
 
-               adj.tv_sec = (long) offset;
-               adj.tv_usec = (offset - adj.tv_sec) * 1000000;
+               DBusConnection *connection = NULL;
+               DBusMessage *msg = NULL, *reply = NULL;
+               DBusError error;
 
-               DBG("adjusting time");
+               dbus_error_init(&error);
 
-               if (adjtime(&adj, &adj) < 0) {
-                       connman_error("Failed to adjust time");
+               connection = connman_dbus_get_connection();
+               if(!connection){
+                       DBG("dbus connection does not exist");
                        return;
                }
 
-               DBG("%lu seconds, %lu msecs", adj.tv_sec, adj.tv_usec);
-       } else {
-               struct timeval cur;
-               double dtime;
-
-               gettimeofday(&cur, NULL);
-               dtime = offset + cur.tv_sec + 1.0e-6 * cur.tv_usec;
+               clock_gettime(CLOCK_REALTIME, &cur);
+               dtime = offset + cur.tv_sec + 1.0e-9 * cur.tv_nsec;
                cur.tv_sec = (long) dtime;
-               cur.tv_usec = (dtime - cur.tv_sec) * 1000000;
+               cur.tv_nsec = (dtime - cur.tv_sec) * 1000000000;
+
+               clock_gettime(CLOCK_REALTIME, &req);
+               msg = dbus_message_new_method_call(TIME_BUS_NAME, TIME_PATH,
+                       TIME_INTERFACE, TIME_METHOD);
+               dbus_message_append_args(msg, DBUS_TYPE_UINT32, &(cur.tv_sec),
+                       DBUS_TYPE_UINT32, &(cur.tv_nsec),
+                       DBUS_TYPE_UINT32, &(req.tv_sec),
+                       DBUS_TYPE_UINT32, &(req.tv_nsec), DBUS_TYPE_INVALID);
+               reply = dbus_connection_send_with_reply_and_block(connection, msg,
+                               DBUS_TIMEOUT_USE_DEFAULT, &error);
+               if(reply == NULL){
+                       if(dbus_error_is_set(&error)){
+                               DBG("%s", error.message);
+                               dbus_error_free(&error);
+                       }
+                       else{
+                               DBG("Failed to request set time");
+                       }
+                       dbus_connection_unref(connection);
+                       dbus_message_unref(msg);
+                       return;
+               }
 
-               DBG("setting time");
+               dbus_message_unref(msg);
+               dbus_message_unref(reply);
+               dbus_connection_unref(connection);
 
-               if (settimeofday(&cur, NULL) < 0) {
-                       connman_error("Failed to set time");
-                       return;
+               DBG("%lu cur seconds, %lu cur nsecs, %lu req seconds, %lu req nsecs",
+                       cur.tv_sec, cur.tv_nsec, req.tv_sec, req.tv_nsec);
+               DBG("setting time");
+       }
+#else
+       if (offset < STEPTIME_MIN_OFFSET && offset > -STEPTIME_MIN_OFFSET) {
+               tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR | ADJ_ESTERROR;
+               tmx.status = STA_PLL;
+               tmx.offset = offset * NSEC_PER_SEC;
+               tmx.constant = msg->poll - 4;
+               tmx.maxerror = 0;
+               tmx.esterror = 0;
+
+               connman_info("ntp: adjust (slew): %+.6f sec", offset);
+       } else {
+               tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_SETOFFSET | ADJ_MAXERROR | ADJ_ESTERROR;
+
+               /* ADJ_NANO uses nanoseconds in the microseconds field */
+               tmx.time.tv_sec = (long)offset;
+               tmx.time.tv_usec = (offset - tmx.time.tv_sec) * NSEC_PER_SEC;
+               tmx.maxerror = 0;
+               tmx.esterror = 0;
+
+               /* the kernel expects -0.3s as {-1, 7000.000.000} */
+               if (tmx.time.tv_usec < 0) {
+                       tmx.time.tv_sec  -= 1;
+                       tmx.time.tv_usec += NSEC_PER_SEC;
                }
 
-               DBG("%lu seconds, %lu msecs", cur.tv_sec, cur.tv_usec);
+               connman_info("ntp: adjust (jump): %+.6f sec", offset);
        }
+
+       if (NTP_FLAGS_LI_DECODE(msg->flags) & NTP_FLAG_LI_ADDSECOND)
+               tmx.status |= STA_INS;
+       else if (NTP_FLAGS_LI_DECODE(msg->flags) & NTP_FLAG_LI_DELSECOND)
+               tmx.status |= STA_DEL;
+
+       if (adjtimex(&tmx) < 0) {
+               connman_error("Failed to adjust time");
+               return;
+       }
+
+       DBG("interval/delta/delay/drift %fs/%+.3fs/%.3fs/%+ldppm",
+                       LOGTOD(msg->poll), offset, delay, tmx.freq / 65536);
+#endif
 }
 
 static gboolean received_data(GIOChannel *channel, GIOCondition condition,
                                                        gpointer user_data)
 {
        unsigned char buf[128];
+       struct sockaddr_in6 sender_addr;
        struct msghdr msg;
        struct iovec iov;
        struct cmsghdr *cmsg;
        struct timeval *tv;
+       struct timespec mrx_time;
        char aux[128];
        ssize_t len;
        int fd;
+       int size;
+       void * addr_ptr;
+       void * src_ptr;
 
        if (condition & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
                connman_error("Problem with timer server channel");
@@ -296,12 +477,31 @@ static gboolean received_data(GIOChannel *channel, GIOCondition condition,
        msg.msg_iovlen = 1;
        msg.msg_control = aux;
        msg.msg_controllen = sizeof(aux);
+       msg.msg_name = &sender_addr;
+       msg.msg_namelen = sizeof(sender_addr);
 
        len = recvmsg(fd, &msg, MSG_DONTWAIT);
        if (len < 0)
                return TRUE;
 
+       if (sender_addr.sin6_family == AF_INET) {
+               size = 4;
+               addr_ptr = &((struct sockaddr_in *)&timeserver_addr)->sin_addr;
+               src_ptr = &((struct sockaddr_in *)&sender_addr)->sin_addr;
+       } else if (sender_addr.sin6_family == AF_INET6) {
+               size = 16;
+               addr_ptr = &((struct sockaddr_in6 *)&timeserver_addr)->sin6_addr;
+               src_ptr = &((struct sockaddr_in6 *)&sender_addr)->sin6_addr;
+       } else {
+               connman_error("Not a valid family type");
+               return TRUE;
+       }
+
+       if(memcmp(addr_ptr, src_ptr, size) != 0)
+               return TRUE;
+
        tv = NULL;
+       clock_gettime(CLOCK_MONOTONIC, &mrx_time);
 
        for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
                if (cmsg->cmsg_level != SOL_SOCKET)
@@ -314,7 +514,7 @@ static gboolean received_data(GIOChannel *channel, GIOCondition condition,
                }
        }
 
-       decode_msg(iov.iov_base, iov.iov_len, tv);
+       decode_msg(iov.iov_base, iov.iov_len, tv, &mrx_time);
 
        return TRUE;
 }
@@ -322,36 +522,76 @@ static gboolean received_data(GIOChannel *channel, GIOCondition condition,
 static void start_ntp(char *server)
 {
        GIOChannel *channel;
-       struct sockaddr_in addr;
+       struct addrinfo hint;
+       struct addrinfo *info;
+       struct sockaddr * addr;
+       struct sockaddr_in  * in4addr;
+       struct sockaddr_in6 in6addr;
+       int size;
+       int family;
        int tos = IPTOS_LOWDELAY, timestamp = 1;
+       int ret;
 
-       if (server == NULL)
+       if (!server)
                return;
 
-       DBG("server %s", server);
+       memset(&hint, 0, sizeof(hint));
+       hint.ai_family = AF_UNSPEC;
+       hint.ai_socktype = SOCK_DGRAM;
+       hint.ai_flags = AI_NUMERICHOST | AI_PASSIVE;
+       ret = getaddrinfo(server, NULL, &hint, &info);
 
-       if (channel_watch > 0)
-               goto send;
+       if (ret) {
+               connman_error("cannot get server info");
+               return;
+       }
 
-       transmit_fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
-       if (transmit_fd < 0) {
-               connman_error("Failed to open time server socket");
+       family = info->ai_family;
+
+       memcpy(&timeserver_addr, info->ai_addr, info->ai_addrlen);
+       freeaddrinfo(info);
+       memset(&in6addr, 0, sizeof(in6addr));
+
+       if (family == AF_INET) {
+               ((struct sockaddr_in *)&timeserver_addr)->sin_port = htons(123);
+               in4addr = (struct sockaddr_in *)&in6addr;
+               in4addr->sin_family = family;
+               addr = (struct sockaddr *)in4addr;
+               size = sizeof(struct sockaddr_in);
+       } else if (family == AF_INET6) {
+               timeserver_addr.sin6_port = htons(123);
+               in6addr.sin6_family = family;
+               addr = (struct sockaddr *)&in6addr;
+               size = sizeof(in6addr);
+       } else {
+               connman_error("Family is neither ipv4 nor ipv6");
                return;
        }
 
-       memset(&addr, 0, sizeof(addr));
-       addr.sin_family = AF_INET;
+       DBG("server %s family %d", server, family);
+
+       if (channel_watch > 0)
+               goto send;
+
+       transmit_fd = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
 
-       if (bind(transmit_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+       if (transmit_fd <= 0) {
+                connman_error("Failed to open time server socket");
+                return;
+       }
+
+       if (bind(transmit_fd, (struct sockaddr *) addr, size) < 0) {
                connman_error("Failed to bind time server socket");
                close(transmit_fd);
                return;
        }
 
-       if (setsockopt(transmit_fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) {
-               connman_error("Failed to set type of service option");
-               close(transmit_fd);
-               return;
+       if (family == AF_INET) {
+               if (setsockopt(transmit_fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) {
+                       connman_error("Failed to set type of service option");
+                       close(transmit_fd);
+                       return;
+               }
        }
 
        if (setsockopt(transmit_fd, SOL_SOCKET, SO_TIMESTAMP, &timestamp,
@@ -362,7 +602,7 @@ static void start_ntp(char *server)
        }
 
        channel = g_io_channel_unix_new(transmit_fd);
-       if (channel == NULL) {
+       if (!channel) {
                close(transmit_fd);
                return;
        }
@@ -379,30 +619,23 @@ static void start_ntp(char *server)
        g_io_channel_unref(channel);
 
 send:
-       send_packet(transmit_fd, server);
+       send_packet(transmit_fd, (struct sockaddr*)&timeserver_addr, NTP_SEND_TIMEOUT);
 }
 
 int __connman_ntp_start(char *server)
 {
        DBG("%s", server);
 
-       if (server == NULL)
+       if (!server)
                return -EINVAL;
 
-       if (timeserver != NULL)
+       if (timeserver)
                g_free(timeserver);
 
        timeserver = g_strdup(server);
 
        start_ntp(timeserver);
 
-       /*
-        * Add a fallback timeout , preferably short, 5 sec here,
-        * to fallback on the next server.
-        */
-
-       timeout_id = g_timeout_add_seconds(5, next_server, NULL);
-
        return 0;
 }
 
@@ -410,11 +643,12 @@ void __connman_ntp_stop()
 {
        DBG("");
 
-       if (poll_id > 0)
+       if (poll_id > 0) {
                g_source_remove(poll_id);
+               poll_id = 0;
+       }
 
-       if (timeout_id > 0)
-               g_source_remove(timeout_id);
+       reset_timeout();
 
        if (channel_watch > 0) {
                g_source_remove(channel_watch);
@@ -422,7 +656,7 @@ void __connman_ntp_stop()
                transmit_fd = 0;
        }
 
-       if (timeserver != NULL) {
+       if (timeserver) {
                g_free(timeserver);
                timeserver = NULL;
        }