Do not replace a HS descriptor with a different replica of itself
[tor.git] / src / or / statefile.c
blob7b9998fc1a24532a2b6efbd1013a341a51026efa
1 /* Copyright (c) 2001 Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 * Copyright (c) 2007-2013, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
7 #define STATEFILE_PRIVATE
8 #include "or.h"
9 #include "circuitstats.h"
10 #include "config.h"
11 #include "confparse.h"
12 #include "entrynodes.h"
13 #include "hibernate.h"
14 #include "rephist.h"
15 #include "router.h"
16 #include "sandbox.h"
17 #include "statefile.h"
19 /** A list of state-file "abbreviations," for compatibility. */
20 static config_abbrev_t state_abbrevs_[] = {
21 { "AccountingBytesReadInterval", "AccountingBytesReadInInterval", 0, 0 },
22 { "HelperNode", "EntryGuard", 0, 0 },
23 { "HelperNodeDownSince", "EntryGuardDownSince", 0, 0 },
24 { "HelperNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
25 { "EntryNode", "EntryGuard", 0, 0 },
26 { "EntryNodeDownSince", "EntryGuardDownSince", 0, 0 },
27 { "EntryNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
28 { NULL, NULL, 0, 0},
31 /*XXXX these next two are duplicates or near-duplicates from config.c */
32 #define VAR(name,conftype,member,initvalue) \
33 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_state_t, member), \
34 initvalue }
35 /** As VAR, but the option name and member name are the same. */
36 #define V(member,conftype,initvalue) \
37 VAR(#member, conftype, member, initvalue)
39 /** Array of "state" variables saved to the ~/.tor/state file. */
40 static config_var_t state_vars_[] = {
41 /* Remember to document these in state-contents.txt ! */
43 V(AccountingBytesReadInInterval, MEMUNIT, NULL),
44 V(AccountingBytesWrittenInInterval, MEMUNIT, NULL),
45 V(AccountingExpectedUsage, MEMUNIT, NULL),
46 V(AccountingIntervalStart, ISOTIME, NULL),
47 V(AccountingSecondsActive, INTERVAL, NULL),
48 V(AccountingSecondsToReachSoftLimit,INTERVAL, NULL),
49 V(AccountingSoftLimitHitAt, ISOTIME, NULL),
50 V(AccountingBytesAtSoftLimit, MEMUNIT, NULL),
52 VAR("EntryGuard", LINELIST_S, EntryGuards, NULL),
53 VAR("EntryGuardDownSince", LINELIST_S, EntryGuards, NULL),
54 VAR("EntryGuardUnlistedSince", LINELIST_S, EntryGuards, NULL),
55 VAR("EntryGuardAddedBy", LINELIST_S, EntryGuards, NULL),
56 VAR("EntryGuardPathBias", LINELIST_S, EntryGuards, NULL),
57 VAR("EntryGuardPathUseBias", LINELIST_S, EntryGuards, NULL),
58 V(EntryGuards, LINELIST_V, NULL),
60 VAR("TransportProxy", LINELIST_S, TransportProxies, NULL),
61 V(TransportProxies, LINELIST_V, NULL),
63 V(BWHistoryReadEnds, ISOTIME, NULL),
64 V(BWHistoryReadInterval, UINT, "900"),
65 V(BWHistoryReadValues, CSV, ""),
66 V(BWHistoryReadMaxima, CSV, ""),
67 V(BWHistoryWriteEnds, ISOTIME, NULL),
68 V(BWHistoryWriteInterval, UINT, "900"),
69 V(BWHistoryWriteValues, CSV, ""),
70 V(BWHistoryWriteMaxima, CSV, ""),
71 V(BWHistoryDirReadEnds, ISOTIME, NULL),
72 V(BWHistoryDirReadInterval, UINT, "900"),
73 V(BWHistoryDirReadValues, CSV, ""),
74 V(BWHistoryDirReadMaxima, CSV, ""),
75 V(BWHistoryDirWriteEnds, ISOTIME, NULL),
76 V(BWHistoryDirWriteInterval, UINT, "900"),
77 V(BWHistoryDirWriteValues, CSV, ""),
78 V(BWHistoryDirWriteMaxima, CSV, ""),
80 V(TorVersion, STRING, NULL),
82 V(LastRotatedOnionKey, ISOTIME, NULL),
83 V(LastWritten, ISOTIME, NULL),
85 V(TotalBuildTimes, UINT, NULL),
86 V(CircuitBuildAbandonedCount, UINT, "0"),
87 VAR("CircuitBuildTimeBin", LINELIST_S, BuildtimeHistogram, NULL),
88 VAR("BuildtimeHistogram", LINELIST_V, BuildtimeHistogram, NULL),
89 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
92 #undef VAR
93 #undef V
95 static int or_state_validate(or_state_t *state, char **msg);
97 static int or_state_validate_cb(void *old_options, void *options,
98 void *default_options,
99 int from_setconf, char **msg);
101 /** Magic value for or_state_t. */
102 #define OR_STATE_MAGIC 0x57A73f57
104 /** "Extra" variable in the state that receives lines we can't parse. This
105 * lets us preserve options from versions of Tor newer than us. */
106 static config_var_t state_extra_var = {
107 "__extra", CONFIG_TYPE_LINELIST, STRUCT_OFFSET(or_state_t, ExtraLines), NULL
110 /** Configuration format for or_state_t. */
111 static const config_format_t state_format = {
112 sizeof(or_state_t),
113 OR_STATE_MAGIC,
114 STRUCT_OFFSET(or_state_t, magic_),
115 state_abbrevs_,
116 state_vars_,
117 or_state_validate_cb,
118 &state_extra_var,
121 /** Persistent serialized state. */
122 static or_state_t *global_state = NULL;
124 /** Return the persistent state struct for this Tor. */
125 MOCK_IMPL(or_state_t *,
126 get_or_state, (void))
128 tor_assert(global_state);
129 return global_state;
132 /** Return true iff we have loaded the global state for this Tor */
134 or_state_loaded(void)
136 return global_state != NULL;
139 /** Return true if <b>line</b> is a valid state TransportProxy line.
140 * Return false otherwise. */
141 static int
142 state_transport_line_is_valid(const char *line)
144 smartlist_t *items = NULL;
145 char *addrport=NULL;
146 tor_addr_t addr;
147 uint16_t port = 0;
148 int r;
150 items = smartlist_new();
151 smartlist_split_string(items, line, NULL,
152 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
154 if (smartlist_len(items) != 2) {
155 log_warn(LD_CONFIG, "state: Not enough arguments in TransportProxy line.");
156 goto err;
159 addrport = smartlist_get(items, 1);
160 if (tor_addr_port_lookup(addrport, &addr, &port) < 0) {
161 log_warn(LD_CONFIG, "state: Could not parse addrport.");
162 goto err;
165 if (!port) {
166 log_warn(LD_CONFIG, "state: Transport line did not contain port.");
167 goto err;
170 r = 1;
171 goto done;
173 err:
174 r = 0;
176 done:
177 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
178 smartlist_free(items);
179 return r;
182 /** Return 0 if all TransportProxy lines in <b>state</b> are well
183 * formed. Otherwise, return -1. */
184 static int
185 validate_transports_in_state(or_state_t *state)
187 int broken = 0;
188 config_line_t *line;
190 for (line = state->TransportProxies ; line ; line = line->next) {
191 tor_assert(!strcmp(line->key, "TransportProxy"));
192 if (!state_transport_line_is_valid(line->value))
193 broken = 1;
196 if (broken)
197 log_warn(LD_CONFIG, "state: State file seems to be broken.");
199 return 0;
202 static int
203 or_state_validate_cb(void *old_state, void *state, void *default_state,
204 int from_setconf, char **msg)
206 /* We don't use these; only options do. Still, we need to match that
207 * signature. */
208 (void) from_setconf;
209 (void) default_state;
210 (void) old_state;
212 return or_state_validate(state, msg);
215 /** Return 0 if every setting in <b>state</b> is reasonable, and a
216 * permissible transition from <b>old_state</b>. Else warn and return -1.
217 * Should have no side effects, except for normalizing the contents of
218 * <b>state</b>.
220 static int
221 or_state_validate(or_state_t *state, char **msg)
223 if (entry_guards_parse_state(state, 0, msg)<0)
224 return -1;
226 if (validate_transports_in_state(state)<0)
227 return -1;
229 return 0;
232 /** Replace the current persistent state with <b>new_state</b> */
233 static int
234 or_state_set(or_state_t *new_state)
236 char *err = NULL;
237 int ret = 0;
238 tor_assert(new_state);
239 config_free(&state_format, global_state);
240 global_state = new_state;
241 if (entry_guards_parse_state(global_state, 1, &err)<0) {
242 log_warn(LD_GENERAL,"%s",err);
243 tor_free(err);
244 ret = -1;
246 if (rep_hist_load_state(global_state, &err)<0) {
247 log_warn(LD_GENERAL,"Unparseable bandwidth history state: %s",err);
248 tor_free(err);
249 ret = -1;
251 if (circuit_build_times_parse_state(
252 get_circuit_build_times_mutable(),global_state) < 0) {
253 ret = -1;
255 return ret;
259 * Save a broken state file to a backup location.
261 static void
262 or_state_save_broken(char *fname)
264 int i, res;
265 file_status_t status;
266 char *fname2 = NULL;
267 for (i = 0; i < 100; ++i) {
268 tor_asprintf(&fname2, "%s.%d", fname, i);
269 status = file_status(fname2);
270 if (status == FN_NOENT)
271 break;
272 tor_free(fname2);
274 if (i == 100) {
275 log_warn(LD_BUG, "Unable to parse state in \"%s\"; too many saved bad "
276 "state files to move aside. Discarding the old state file.",
277 fname);
278 res = unlink(fname);
279 if (res != 0) {
280 log_warn(LD_FS,
281 "Also couldn't discard old state file \"%s\" because "
282 "unlink() failed: %s",
283 fname, strerror(errno));
285 } else {
286 log_warn(LD_BUG, "Unable to parse state in \"%s\". Moving it aside "
287 "to \"%s\". This could be a bug in Tor; please tell "
288 "the developers.", fname, fname2);
289 if (tor_rename(fname, fname2) < 0) {//XXXX sandbox prohibits
290 log_warn(LD_BUG, "Weirdly, I couldn't even move the state aside. The "
291 "OS gave an error of %s", strerror(errno));
294 tor_free(fname2);
297 STATIC or_state_t *
298 or_state_new(void)
300 or_state_t *new_state = tor_malloc_zero(sizeof(or_state_t));
301 new_state->magic_ = OR_STATE_MAGIC;
302 config_init(&state_format, new_state);
304 return new_state;
307 /** Reload the persistent state from disk, generating a new state as needed.
308 * Return 0 on success, less than 0 on failure.
311 or_state_load(void)
313 or_state_t *new_state = NULL;
314 char *contents = NULL, *fname;
315 char *errmsg = NULL;
316 int r = -1, badstate = 0;
318 fname = get_datadir_fname("state");
319 switch (file_status(fname)) {
320 case FN_FILE:
321 if (!(contents = read_file_to_str(fname, 0, NULL))) {
322 log_warn(LD_FS, "Unable to read state file \"%s\"", fname);
323 goto done;
325 break;
326 case FN_NOENT:
327 break;
328 case FN_ERROR:
329 case FN_DIR:
330 default:
331 log_warn(LD_GENERAL,"State file \"%s\" is not a file? Failing.", fname);
332 goto done;
334 new_state = or_state_new();
335 if (contents) {
336 config_line_t *lines=NULL;
337 int assign_retval;
338 if (config_get_lines(contents, &lines, 0)<0)
339 goto done;
340 assign_retval = config_assign(&state_format, new_state,
341 lines, 0, 0, &errmsg);
342 config_free_lines(lines);
343 if (assign_retval<0)
344 badstate = 1;
345 if (errmsg) {
346 log_warn(LD_GENERAL, "%s", errmsg);
347 tor_free(errmsg);
351 if (!badstate && or_state_validate(new_state, &errmsg) < 0)
352 badstate = 1;
354 if (errmsg) {
355 log_warn(LD_GENERAL, "%s", errmsg);
356 tor_free(errmsg);
359 if (badstate && !contents) {
360 log_warn(LD_BUG, "Uh oh. We couldn't even validate our own default state."
361 " This is a bug in Tor.");
362 goto done;
363 } else if (badstate && contents) {
364 or_state_save_broken(fname);
366 tor_free(contents);
367 config_free(&state_format, new_state);
369 new_state = or_state_new();
370 } else if (contents) {
371 log_info(LD_GENERAL, "Loaded state from \"%s\"", fname);
372 } else {
373 log_info(LD_GENERAL, "Initialized state");
375 if (or_state_set(new_state) == -1) {
376 or_state_save_broken(fname);
378 new_state = NULL;
379 if (!contents) {
380 global_state->next_write = 0;
381 or_state_save(time(NULL));
383 r = 0;
385 done:
386 tor_free(fname);
387 tor_free(contents);
388 if (new_state)
389 config_free(&state_format, new_state);
391 return r;
394 /** Did the last time we tried to write the state file fail? If so, we
395 * should consider disabling such features as preemptive circuit generation
396 * to compute circuit-build-time. */
397 static int last_state_file_write_failed = 0;
399 /** Return whether the state file failed to write last time we tried. */
401 did_last_state_file_write_fail(void)
403 return last_state_file_write_failed;
406 /** If writing the state to disk fails, try again after this many seconds. */
407 #define STATE_WRITE_RETRY_INTERVAL 3600
409 /** If we're a relay, how often should we checkpoint our state file even
410 * if nothing else dirties it? This will checkpoint ongoing stats like
411 * bandwidth used, per-country user stats, etc. */
412 #define STATE_RELAY_CHECKPOINT_INTERVAL (12*60*60)
414 /** Write the persistent state to disk. Return 0 for success, <0 on failure. */
416 or_state_save(time_t now)
418 char *state, *contents;
419 char tbuf[ISO_TIME_LEN+1];
420 char *fname;
422 tor_assert(global_state);
424 if (global_state->next_write > now)
425 return 0;
427 /* Call everything else that might dirty the state even more, in order
428 * to avoid redundant writes. */
429 entry_guards_update_state(global_state);
430 rep_hist_update_state(global_state);
431 circuit_build_times_update_state(get_circuit_build_times(), global_state);
432 if (accounting_is_enabled(get_options()))
433 accounting_run_housekeeping(now);
435 global_state->LastWritten = now;
437 tor_free(global_state->TorVersion);
438 tor_asprintf(&global_state->TorVersion, "Tor %s", get_version());
440 state = config_dump(&state_format, NULL, global_state, 1, 0);
441 format_local_iso_time(tbuf, now);
442 tor_asprintf(&contents,
443 "# Tor state file last generated on %s local time\n"
444 "# Other times below are in UTC\n"
445 "# You *do not* need to edit this file.\n\n%s",
446 tbuf, state);
447 tor_free(state);
448 fname = get_datadir_fname("state");
449 if (write_str_to_file(fname, contents, 0)<0) {
450 log_warn(LD_FS, "Unable to write state to file \"%s\"; "
451 "will try again later", fname);
452 last_state_file_write_failed = 1;
453 tor_free(fname);
454 tor_free(contents);
455 /* Try again after STATE_WRITE_RETRY_INTERVAL (or sooner, if the state
456 * changes sooner). */
457 global_state->next_write = now + STATE_WRITE_RETRY_INTERVAL;
458 return -1;
461 last_state_file_write_failed = 0;
462 log_info(LD_GENERAL, "Saved state to \"%s\"", fname);
463 tor_free(fname);
464 tor_free(contents);
466 if (server_mode(get_options()))
467 global_state->next_write = now + STATE_RELAY_CHECKPOINT_INTERVAL;
468 else
469 global_state->next_write = TIME_MAX;
471 return 0;
474 /** Return the config line for transport <b>transport</b> in the current state.
475 * Return NULL if there is no config line for <b>transport</b>. */
476 STATIC config_line_t *
477 get_transport_in_state_by_name(const char *transport)
479 or_state_t *or_state = get_or_state();
480 config_line_t *line;
481 config_line_t *ret = NULL;
482 smartlist_t *items = NULL;
484 for (line = or_state->TransportProxies ; line ; line = line->next) {
485 tor_assert(!strcmp(line->key, "TransportProxy"));
487 items = smartlist_new();
488 smartlist_split_string(items, line->value, NULL,
489 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
490 if (smartlist_len(items) != 2) /* broken state */
491 goto done;
493 if (!strcmp(smartlist_get(items, 0), transport)) {
494 ret = line;
495 goto done;
498 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
499 smartlist_free(items);
500 items = NULL;
503 done:
504 if (items) {
505 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
506 smartlist_free(items);
508 return ret;
511 /** Return string containing the address:port part of the
512 * TransportProxy <b>line</b> for transport <b>transport</b>.
513 * If the line is corrupted, return NULL. */
514 static const char *
515 get_transport_bindaddr(const char *line, const char *transport)
517 char *line_tmp = NULL;
519 if (strlen(line) < strlen(transport) + 2) {
520 goto broken_state;
521 } else {
522 /* line should start with the name of the transport and a space.
523 (for example, "obfs2 127.0.0.1:47245") */
524 tor_asprintf(&line_tmp, "%s ", transport);
525 if (strcmpstart(line, line_tmp))
526 goto broken_state;
528 tor_free(line_tmp);
529 return (line+strlen(transport)+1);
532 broken_state:
533 tor_free(line_tmp);
534 return NULL;
537 /** Return a string containing the address:port that a proxy transport
538 * should bind on. The string is stored on the heap and must be freed
539 * by the caller of this function. */
540 char *
541 get_stored_bindaddr_for_server_transport(const char *transport)
543 char *default_addrport = NULL;
544 const char *stored_bindaddr = NULL;
545 config_line_t *line = NULL;
548 /* See if the user explicitly asked for a specific listening
549 address for this transport. */
550 char *conf_bindaddr = get_transport_bindaddr_from_config(transport);
551 if (conf_bindaddr)
552 return conf_bindaddr;
555 line = get_transport_in_state_by_name(transport);
556 if (!line) /* Found no references in state for this transport. */
557 goto no_bindaddr_found;
559 stored_bindaddr = get_transport_bindaddr(line->value, transport);
560 if (stored_bindaddr) /* found stored bindaddr in state file. */
561 return tor_strdup(stored_bindaddr);
563 no_bindaddr_found:
564 /** If we didn't find references for this pluggable transport in the
565 state file, we should instruct the pluggable transport proxy to
566 listen on INADDR_ANY on a random ephemeral port. */
567 tor_asprintf(&default_addrport, "%s:%s", fmt_addr32(INADDR_ANY), "0");
568 return default_addrport;
571 /** Save <b>transport</b> listening on <b>addr</b>:<b>port</b> to
572 state */
573 void
574 save_transport_to_state(const char *transport,
575 const tor_addr_t *addr, uint16_t port)
577 or_state_t *state = get_or_state();
579 char *transport_addrport=NULL;
581 /** find where to write on the state */
582 config_line_t **next, *line;
584 /* see if this transport is already stored in state */
585 config_line_t *transport_line =
586 get_transport_in_state_by_name(transport);
588 if (transport_line) { /* if transport already exists in state... */
589 const char *prev_bindaddr = /* get its addrport... */
590 get_transport_bindaddr(transport_line->value, transport);
591 transport_addrport = tor_strdup(fmt_addrport(addr, port));
593 /* if transport in state has the same address as this one, life is good */
594 if (!strcmp(prev_bindaddr, transport_addrport)) {
595 log_info(LD_CONFIG, "Transport seems to have spawned on its usual "
596 "address:port.");
597 goto done;
598 } else { /* if addrport in state is different than the one we got */
599 log_info(LD_CONFIG, "Transport seems to have spawned on different "
600 "address:port. Let's update the state file with the new "
601 "address:port");
602 tor_free(transport_line->value); /* free the old line */
603 /* replace old addrport line with new line */
604 tor_asprintf(&transport_line->value, "%s %s", transport,
605 fmt_addrport(addr, port));
607 } else { /* never seen this one before; save it in state for next time */
608 log_info(LD_CONFIG, "It's the first time we see this transport. "
609 "Let's save its address:port");
610 next = &state->TransportProxies;
611 /* find the last TransportProxy line in the state and point 'next'
612 right after it */
613 line = state->TransportProxies;
614 while (line) {
615 next = &(line->next);
616 line = line->next;
619 /* allocate space for the new line and fill it in */
620 *next = line = tor_malloc_zero(sizeof(config_line_t));
621 line->key = tor_strdup("TransportProxy");
622 tor_asprintf(&line->value, "%s %s", transport, fmt_addrport(addr, port));
624 next = &(line->next);
627 if (!get_options()->AvoidDiskWrites)
628 or_state_mark_dirty(state, 0);
630 done:
631 tor_free(transport_addrport);
634 STATIC void
635 or_state_free(or_state_t *state)
637 if (!state)
638 return;
640 config_free(&state_format, state);
643 void
644 or_state_free_all(void)
646 or_state_free(global_state);
647 global_state = NULL;