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
add_jitter(int base,int jitter)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
invalidate_time(struct state * state)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
action_invalidate_time(evutil_socket_t fd,short what,void * arg)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
setup_event_timer_sync(struct state * state)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 */
action_kickoff_time_sync(evutil_socket_t fd,short what,void * arg)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