use time_monotonic() instead of time() for statistics and time difference calculations
authorMartin Willi <martin@strongswan.org>
Mon, 31 Aug 2009 15:59:00 +0000 (17:59 +0200)
committerMartin Willi <martin@strongswan.org>
Mon, 31 Aug 2009 16:00:28 +0000 (18:00 +0200)
13 files changed:
src/charon/kernel/kernel_ipsec.h
src/charon/network/receiver.c
src/charon/plugins/kernel_klips/kernel_klips_ipsec.c
src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c
src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
src/charon/plugins/load_tester/load_tester_ipsec.c
src/charon/plugins/stroke/stroke_list.c
src/charon/sa/child_sa.c
src/charon/sa/ike_sa.c
src/charon/sa/tasks/ike_auth_lifetime.c
src/libfast/dispatcher.c
src/scepclient/scepclient.c
src/starter/starter.c

index d6438c1..4abe3bf 100644 (file)
@@ -228,13 +228,14 @@ struct kernel_ipsec_t {
        /**
         * Query the use time of a policy.
         *
-        * The use time of a policy is the time the policy was used
-        * for the last time.
+        * The use time of a policy is the time the policy was used for the last
+        * time. It is not the system time, but a monotonic timestamp as returned
+        * by time_monotonic.
         * 
         * @param src_ts                traffic selector to match traffic source
         * @param dst_ts                traffic selector to match traffic dest
         * @param direction             direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD
-        * @param[out] use_time the time of this SA's last use
+        * @param[out] use_time the monotonic timestamp of this SA's last use
         * @return                              SUCCESS if operation completed
         */
        status_t (*query_policy) (kernel_ipsec_t *this,
index ab4d6d5..5c24a62 100644 (file)
@@ -168,7 +168,7 @@ static bool cookie_verify(private_receiver_t *this, message_t *message,
        chunk_t reference;
        chunk_t secret;
        
-       now = time(NULL);
+       now = time_monotonic(NULL);
        t = *(u_int32_t*)cookie.ptr;
        
        if (cookie.len != sizeof(u_int32_t) +
@@ -296,9 +296,9 @@ static job_requeue_t receive_packets(private_receiver_t *this)
                /* check for cookies */
                if (this->cookie_threshold && cookie_required(this, message))
                {
-                       u_int32_t now = time(NULL);
+                       u_int32_t now = time_monotonic(NULL);
                        chunk_t cookie = cookie_build(this, message, now - this->secret_offset,
-                                                                                 chunk_from_thing(this->secret));      
+                                                                                 chunk_from_thing(this->secret));
                        
                        DBG2(DBG_NET, "received packet from: %#H to %#H",
                                 message->get_source(message),
@@ -352,7 +352,7 @@ static void destroy(private_receiver_t *this)
 receiver_t *receiver_create()
 {
        private_receiver_t *this = malloc_thing(private_receiver_t);
-       u_int32_t now = time(NULL);
+       u_int32_t now = time_monotonic(NULL);
        
        this->public.destroy = (void(*)(receiver_t*)) destroy;
        
index 9a903d0..0a35546 100644 (file)
@@ -2382,7 +2382,7 @@ static status_t query_policy(private_kernel_klips_ipsec_t *this,
                                break;
                        }
                        
-                       *use_time = time(NULL) - idle_time;
+                       *use_time = time_monotonic(NULL) - idle_time;
                        status = SUCCESS;
                        break;
                }
index 63a9683..edad7f7 100644 (file)
@@ -1774,7 +1774,16 @@ static status_t query_policy(private_kernel_netlink_ipsec_t *this,
                free(out);
                return FAILED;
        }
-       *use_time = (time_t)policy->curlft.use_time;
+       
+       if (policy->curlft.use_time)
+       {
+               /* we need the monotonic time, but the kernel returns system time. */
+               *use_time = time_monotonic(NULL) - (time(NULL) - policy->curlft.use_time);
+       }
+       else
+       {
+               *use_time = 0;
+       }
        
        free(out);
        return SUCCESS;
index 1f83e8f..7674654 100644 (file)
@@ -1911,9 +1911,16 @@ static status_t query_policy(private_kernel_pfkey_ipsec_t *this,
                free(out);
                return FAILED;
        }
-       
-       *use_time = response.lft_current->sadb_lifetime_usetime;
-       
+       /* we need the monotonic time, but the kernel returns system time. */
+       if (response.lft_current->sadb_lifetime_usetime)
+       {
+               *use_time = time_monotonic(NULL) -
+                                       (time(NULL) - response.lft_current->sadb_lifetime_usetime);
+       }
+       else
+       {
+               *use_time = 0;
+       }
        free(out);
        
        return SUCCESS;
index e463d2a..76652d3 100644 (file)
@@ -126,7 +126,7 @@ static status_t query_policy(private_load_tester_ipsec_t *this,
                                                         traffic_selector_t *dst_ts,
                                                         policy_dir_t direction, u_int32_t *use_time)
 {
-       *use_time = time(NULL);
+       *use_time = time_monotonic(NULL);
        return SUCCESS;
 }
 
index 0011657..d675448 100644 (file)
@@ -58,7 +58,7 @@ struct private_stroke_list_t {
 static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
 {
        ike_sa_id_t *id = ike_sa->get_id(ike_sa);
-       time_t now = time(NULL);
+       time_t now = time_monotonic(NULL);
        
        fprintf(out, "%12s[%d]: %N",
                        ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
@@ -146,11 +146,12 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
  */
 static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
 {
-       time_t use_in, use_out, rekey, now = time(NULL);
+       time_t use_in, use_out, rekey, now;
        u_int64_t bytes_in, bytes_out;
        proposal_t *proposal;
        child_cfg_t *config = child_sa->get_config(child_sa);
        
+       
        fprintf(out, "%12s{%d}:  %N, %N%s", 
                        child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
                        child_sa_state_names, child_sa->get_state(child_sa),
@@ -205,7 +206,8 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
                                        }
                                }
                        }
-
+                       
+                       now = time_monotonic(NULL);
                        child_sa->get_usestats(child_sa, TRUE, &use_in, &bytes_in);
                        fprintf(out, ", %llu bytes_i", bytes_in);
                        if (use_in)
@@ -367,11 +369,14 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
                char *plugin, *pool;
                host_t *host;
                u_int32_t dpd;
-               time_t now = time(NULL);
+               time_t since, now;
                u_int size, online, offline;
                
+               now = time_monotonic(NULL);
+               since = time(NULL) - (now - this->uptime);
+               
                fprintf(out, "Status of IKEv2 charon daemon (strongSwan "VERSION"):\n");
-               fprintf(out, "  uptime: %V, since %T\n", &now, &this->uptime, &this->uptime, FALSE);
+               fprintf(out, "  uptime: %V, since %T\n", &now, &this->uptime, &since, FALSE);
                fprintf(out, "  worker threads: %d idle of %d,",
                                charon->processor->get_idle_threads(charon->processor),
                                charon->processor->get_total_threads(charon->processor));
@@ -1113,7 +1118,7 @@ stroke_list_t *stroke_list_create(stroke_attribute_t *attribute)
        this->public.leases = (void(*)(stroke_list_t*, stroke_msg_t *msg, FILE *out))leases;
        this->public.destroy = (void(*)(stroke_list_t*))destroy;
        
-       this->uptime = time(NULL);
+       this->uptime = time_monotonic(NULL);
        this->attribute = attribute;
        
        return &this->public;
index 28c5136..ed7df65 100644 (file)
@@ -593,7 +593,7 @@ static status_t install(private_child_sa_t *this, chunk_t encr, chunk_t integ,
                                inbound ? soft : 0, hard, enc_alg, encr, int_alg, integ,
                                this->mode, this->ipcomp, cpi, this->encap, update);
        
-       now = time(NULL);
+       now = time_monotonic(NULL);
        if (soft)
        {
                this->rekey_time = now + soft;
index d2ab41e..712c022 100644 (file)
@@ -428,7 +428,7 @@ static void send_keepalive(private_ike_sa_t *this)
        }
        
        last_out = get_use_time(this, FALSE);
-       now = time(NULL);
+       now = time_monotonic(NULL);
        
        diff = now - last_out;
        
@@ -570,7 +570,7 @@ static status_t send_dpd(private_ike_sa_t *this)
                /* check if there was any inbound traffic */
                time_t last_in, now;
                last_in = get_use_time(this, TRUE);
-               now = time(NULL);
+               now = time_monotonic(NULL);
                diff = now - last_in;
                if (diff >= delay)
                {
@@ -632,7 +632,7 @@ static void set_state(private_ike_sa_t *this, ike_sa_state_t state)
                                u_int32_t t;
                        
                                /* calculate rekey, reauth and lifetime */
-                               this->stats[STAT_ESTABLISHED] = time(NULL);
+                               this->stats[STAT_ESTABLISHED] = time_monotonic(NULL);
                                
                                /* schedule rekeying if we have a time which is smaller than
                                 * an already scheduled rekeying */
@@ -895,7 +895,7 @@ static void update_hosts(private_ike_sa_t *this, host_t *me, host_t *other)
 static status_t generate_message(private_ike_sa_t *this, message_t *message,
                                                                 packet_t **packet)
 {
-       this->stats[STAT_OUTBOUND] = time(NULL);
+       this->stats[STAT_OUTBOUND] = time_monotonic(NULL);
        message->set_ike_sa_id(message, this->ike_sa_id);
        return message->generate(message,
                                this->keymat->get_crypter(this->keymat, FALSE),
@@ -1290,7 +1290,7 @@ static status_t process_message(private_ike_sa_t *this, message_t *message)
                        charon->scheduler->schedule_job(charon->scheduler, job,
                                                                                        HALF_OPEN_IKE_SA_TIMEOUT);
                }
-               this->stats[STAT_INBOUND] = time(NULL);
+               this->stats[STAT_INBOUND] = time_monotonic(NULL);
                /* check if message is trustworthy, and update host information */
                if (this->state == IKE_CREATED || this->state == IKE_CONNECTING ||
                        message->get_exchange_type(message) != IKE_SA_INIT)
@@ -1514,7 +1514,7 @@ static status_t reauth(private_ike_sa_t *this)
 #endif /* ME */
                        )
                {
-                       time_t now = time(NULL);
+                       time_t now = time_monotonic(NULL);
                        
                        DBG1(DBG_IKE, "IKE_SA will timeout in %V",
                                 &now, &this->stats[STAT_DELETE]);
@@ -1668,7 +1668,7 @@ static status_t reestablish(private_ike_sa_t *this)
  */
 static status_t retransmit(private_ike_sa_t *this, u_int32_t message_id)
 {
-       this->stats[STAT_OUTBOUND] = time(NULL);
+       this->stats[STAT_OUTBOUND] = time_monotonic(NULL);
        if (this->task_manager->retransmit(this->task_manager, message_id) != SUCCESS)
        {
                /* send a proper signal to brief interested bus listeners */
@@ -1710,7 +1710,7 @@ static status_t retransmit(private_ike_sa_t *this, u_int32_t message_id)
 static void set_auth_lifetime(private_ike_sa_t *this, u_int32_t lifetime)
 {
        u_int32_t reduction = this->peer_cfg->get_over_time(this->peer_cfg);
-       u_int32_t reauth_time = time(NULL) + lifetime - reduction;
+       u_int32_t reauth_time = time_monotonic(NULL) + lifetime - reduction;
 
        if (lifetime < reduction)
        {
@@ -1731,8 +1731,9 @@ static void set_auth_lifetime(private_ike_sa_t *this, u_int32_t lifetime)
        }
        else
        {
-               DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, reauthentication already "
-                        "scheduled in %ds", lifetime, this->stats[STAT_REAUTH] - time(NULL));
+               DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, "
+                        "reauthentication already scheduled in %ds", lifetime,
+                        this->stats[STAT_REAUTH] - time_monotonic(NULL));
        }
 }
 
@@ -1923,7 +1924,7 @@ static status_t inherit(private_ike_sa_t *this, private_ike_sa_t *other)
        /* reauthentication timeout survives a rekeying */
        if (other->stats[STAT_REAUTH])
        {
-               time_t reauth, delete, now = time(NULL);
+               time_t reauth, delete, now = time_monotonic(NULL);
        
                this->stats[STAT_REAUTH] = other->stats[STAT_REAUTH];
                reauth = this->stats[STAT_REAUTH] - now;
@@ -2113,7 +2114,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
        this->keepalive_interval = lib->settings->get_time(lib->settings,
                                                                        "charon.keep_alive", KEEPALIVE_INTERVAL);
        memset(this->stats, 0, sizeof(this->stats));
-       this->stats[STAT_INBOUND] = this->stats[STAT_OUTBOUND] = time(NULL);
+       this->stats[STAT_INBOUND] = this->stats[STAT_OUTBOUND] = time_monotonic(NULL);
        this->ike_cfg = NULL;
        this->peer_cfg = NULL;
        this->my_auth = auth_cfg_create();
index a047e6b..4b926a9 100644 (file)
@@ -50,7 +50,7 @@ static void add_auth_lifetime(private_ike_auth_lifetime_t *this, message_t *mess
        lifetime = this->ike_sa->get_statistic(this->ike_sa, STAT_REAUTH);
        if (lifetime)
        {
-               lifetime -= time(NULL);
+               lifetime -= time_monotonic(NULL);
                chunk = chunk_from_thing(lifetime);
                *(u_int32_t*)chunk.ptr = htonl(lifetime);
                message->add_notify(message, FALSE, AUTH_LIFETIME, chunk);
index 35ae558..9f4cc01 100644 (file)
@@ -174,7 +174,7 @@ static session_entry_t *session_entry_create(private_dispatcher_t *this,
        entry->closed = FALSE;
        pthread_cond_init(&entry->cond, NULL);
        entry->session = load_session(this);
-       entry->used = time(NULL);
+       entry->used = time_monotonic(NULL);
        entry->host = strdup(host);
        
        return entry;
@@ -237,7 +237,7 @@ static void dispatch(private_dispatcher_t *this)
                        continue;
                }
                sid = request->get_cookie(request, "SID");
-               now = time(NULL);
+               now = time_monotonic(NULL);
                
                /* find session */
                pthread_mutex_lock(&this->mutex);
@@ -281,7 +281,7 @@ static void dispatch(private_dispatcher_t *this)
        
                /* start processing */
                found->session->process(found->session, request);
-               found->used = time(NULL);
+               found->used = time_monotonic(NULL);
                
                /* release session */
                pthread_mutex_lock(&this->mutex);
index ca6b070..e01997c 100644 (file)
@@ -1006,7 +1006,7 @@ int main(int argc, char **argv)
        {
                char *path = concatenate_paths(CA_CERT_PATH, file_in_cacert_sig);
                cert_t cert;
-               time_t poll_start;
+               time_t poll_start = 0;
 
                x509cert_t       *certs         = NULL;
                chunk_t           envelopedData = chunk_empty;
@@ -1035,7 +1035,7 @@ int main(int argc, char **argv)
                {
                        plog("  scep request pending, polling every %d seconds"
                                , poll_interval);
-                       time(&poll_start);
+                       poll_start = time_monotonic(NULL);
                        issuerAndSubject = asn1_wrap(ASN1_SEQUENCE, "cc"
                                                                   , x509_ca_sig->subject
                                                                   , subject);
@@ -1043,7 +1043,7 @@ int main(int argc, char **argv)
                while (attrs.pkiStatus == SCEP_PENDING)
                {
                        if (max_poll_time > 0
-                       && (time(NULL) - poll_start >= max_poll_time))
+                       && (time_monotonic(NULL) - poll_start >= max_poll_time))
                        {
                                exit_scepclient("maximum poll time reached: %d seconds"
                                                           , max_poll_time);
index b675ccf..ff5ab9d 100644 (file)
@@ -353,7 +353,7 @@ int main (int argc, char **argv)
                }
        }
 
-       last_reload = time(NULL);
+       last_reload = time_monotonic(NULL);
 
        if (stat(STARTER_PID_FILE, &stb) == 0)
        {
@@ -582,7 +582,7 @@ int main (int argc, char **argv)
                                }
                        }
                        _action_ &= ~FLAG_ACTION_UPDATE;
-                       last_reload = time(NULL);
+                       last_reload = time_monotonic(NULL);
                }
 
                /*
@@ -736,7 +736,7 @@ int main (int argc, char **argv)
                 */
                if (auto_update)
                {
-                       time_t now = time(NULL);
+                       time_t now = time_monotonic(NULL);
 
                        tv.tv_sec = (now < last_reload + auto_update)
                                        ? (last_reload + auto_update-now) : 0;