1 /* 2 * kickoff_time_sync.c - network time synchronization 3 * Copyright (c) 2013 The Chromium Authors. All rights reserved. 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "config.h" 9 10 #ifdef USE_POLARSSL 11 #include <polarssl/entropy.h> 12 #include <polarssl/ctr_drbg.h> 13 #else 14 #include <openssl/rand.h> 15 #endif 16 #include <stdlib.h> 17 #include <time.h> 18 #include <unistd.h> 19 #include <event2/event.h> 20 21 #include "src/conf.h" 22 #include "src/util.h" 23 #include "src/tlsdate.h" 24 25 #ifdef USE_POLARSSL 26 static int random_init = 0; 27 static entropy_context entropy; 28 static ctr_drbg_context ctr_drbg; 29 static char *pers = "tlsdated"; 30 #endif 31 32 int 33 add_jitter (int base, int jitter) 34 { 35 int n = 0; 36 if (!jitter) 37 return base; 38 #ifdef USE_POLARSSL 39 if (0 == random_init) 40 { 41 entropy_init(&entropy); 42 if (0 > ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, 43 (unsigned char *) pers, strlen(pers))) 44 { 45 pfatal ("Failed to initialize random source"); 46 } 47 random_init = 1; 48 } 49 if (0 != ctr_drbg_random(&ctr_drbg, (unsigned char *)&n, sizeof(n))) 50 fatal ("ctr_drbg_random() failed"); 51 #else 52 if (RAND_bytes ( (unsigned char *) &n, sizeof (n)) != 1) 53 fatal ("RAND_bytes() failed"); 54 #endif 55 return base + (abs (n) % (2 * jitter)) - jitter; 56 } 57 58 void 59 invalidate_time (struct state *state) 60 { 61 state->last_sync_type = SYNC_TYPE_RTC; 62 state->last_time = time (NULL); 63 /* Note(!) this does not invalidate the clock_delta implicitly. 64 * This allows forced invalidation to not lose synchronization 65 * data. 66 */ 67 } 68 69 void 70 action_invalidate_time (evutil_socket_t fd, short what, void *arg) 71 { 72 struct state *state = arg; 73 verb_debug ("[event:%s] fired", __func__); 74 /* If time is already invalid and being acquired, do nothing. */ 75 if (state->last_sync_type == SYNC_TYPE_RTC && 76 event_pending (state->events[E_TLSDATE], EV_TIMEOUT, NULL)) 77 return; 78 /* Time out our trust in network synchronization but don't persist 79 * the change to disk or notify the system. Let a network sync 80 * failure or success do that. 81 */ 82 invalidate_time (state); 83 /* Then trigger a network sync if possible. */ 84 action_kickoff_time_sync (-1, EV_TIMEOUT, arg); 85 } 86 87 int 88 setup_event_timer_sync (struct state *state) 89 { 90 int wait_time = add_jitter (state->opts.steady_state_interval, 91 state->opts.jitter); 92 struct timeval interval = { wait_time, 0 }; 93 state->events[E_STEADYSTATE] = event_new (state->base, -1, 94 EV_TIMEOUT|EV_PERSIST, 95 action_invalidate_time, state); 96 if (!state->events[E_STEADYSTATE]) 97 { 98 error ("Failed to create interval event"); 99 return 1; 100 } 101 event_priority_set (state->events[E_STEADYSTATE], PRI_ANY); 102 return event_add (state->events[E_STEADYSTATE], &interval); 103 } 104 105 /* Begins a network synchronization attempt. If the local clocks 106 * are synchronized, then make sure that the _current_ synchronization 107 * source is set to the real-time clock and note that the clock_delta 108 * is unreliable. If the clock was in sync and the last synchronization 109 * source was the network, then this action does nothing. 110 * 111 * In the case of desynchronization, the clock_delta value is used as a 112 * guard to indicate that even if the synchronization source isn't the 113 * network, the source is still tracking the clock delta that was 114 * established from a network source. 115 * TODO(wad) Change the name of clock_delta to indicate that it is the local 116 * clock delta after the last network sync. 117 */ 118 void action_kickoff_time_sync (evutil_socket_t fd, short what, void *arg) 119 { 120 struct state *state = arg; 121 verb_debug ("[event:%s] fired", __func__); 122 time_t delta = state->clock_delta; 123 int jitter = 0; 124 if (check_continuity (&delta) > 0) 125 { 126 info ("[event:%s] clock delta desync detected (%d != %d)", __func__, 127 state->clock_delta, delta); 128 /* Add jitter iff we had network synchronization once before. */ 129 if (state->clock_delta) 130 jitter = add_jitter (30, 30); /* TODO(wad) make configurable */ 131 /* Forget the old delta until we have time again. */ 132 state->clock_delta = 0; 133 invalidate_time (state); 134 } 135 if (state->last_sync_type == SYNC_TYPE_NET) 136 { 137 verb_debug ("[event:%s] time in sync. skipping", __func__); 138 return; 139 } 140 /* Keep parity with run_tlsdate: for every wake, allow it to retry again. */ 141 if (state->tries > 0) 142 { 143 state->tries -= 1; 144 /* Don't bother re-triggering tlsdate */ 145 verb_debug ("[event:%s] called while tries are in progress", __func__); 146 return; 147 } 148 /* Don't over-schedule if the first attempt hasn't fired. If a wake event 149 * impacts the result of a proxy resolution, then the updated value can be 150 * acquired on the next run. If the wake comes in after E_TLSDATE is 151 * serviced, then the tries count will be decremented. 152 */ 153 if (event_pending (state->events[E_TLSDATE], EV_TIMEOUT, NULL)) 154 { 155 verb_debug ("[event:%s] called while tlsdate is pending", __func__); 156 return; 157 } 158 if (!state->events[E_RESOLVER]) 159 { 160 trigger_event (state, E_TLSDATE, jitter); 161 return; 162 } 163 /* If the resolver relies on an external response, then make sure that a 164 * tlsdate event is waiting in the wings if the resolver is too slow. Even 165 * if this fires, it won't stop eventual handling of the resolver since it 166 * doesn't event_del() E_RESOLVER. 167 */ 168 trigger_event (state, E_TLSDATE, jitter + RESOLVER_TIMEOUT); 169 trigger_event (state, E_RESOLVER, jitter); 170 } 171