Tor  0.4.3.0-alpha-dev
statefile.c
Go to the documentation of this file.
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-2019, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
6 
7 /**
8  * \file statefile.c
9  *
10  * \brief Handles parsing and encoding the persistent 'state' file that carries
11  * miscellaneous persistent state between Tor invocations.
12  *
13  * This 'state' file is a typed key-value store that allows multiple
14  * entries for the same key. It follows the same metaformat as described
15  * in confmgt.c, and uses the same code to read and write itself.
16  *
17  * The state file is most suitable for small values that don't change too
18  * frequently. For values that become very large, we typically use a separate
19  * file -- for example, see how we handle microdescriptors, by storing them in
20  * a separate file with a journal.
21  *
22  * The current state is accessed via get_or_state(), which returns a singleton
23  * or_state_t object. Functions that change it should call
24  * or_state_mark_dirty() to ensure that it will get written to disk.
25  *
26  * The or_state_save() function additionally calls various functioens
27  * throughout Tor that might want to flush more state to the the disk,
28  * including some in rephist.c, entrynodes.c, circuitstats.c, hibernate.c.
29  */
30 
31 #define STATEFILE_PRIVATE
32 #include "core/or/or.h"
33 #include "core/or/circuitstats.h"
34 #include "app/config/config.h"
36 #include "lib/confmgt/confmgt.h"
37 #include "core/mainloop/mainloop.h"
43 #include "feature/stats/rephist.h"
44 #include "feature/relay/router.h"
46 #include "lib/sandbox/sandbox.h"
47 #include "app/config/statefile.h"
48 #include "app/main/subsysmgr.h"
49 #include "lib/encoding/confline.h"
50 #include "lib/net/resolve.h"
51 #include "lib/version/torversion.h"
52 
53 #include "app/config/or_state_st.h"
54 
55 #ifdef HAVE_UNISTD_H
56 #include <unistd.h>
57 #endif
58 
59 /** A list of state-file "abbreviations," for compatibility. */
61  { "AccountingBytesReadInterval", "AccountingBytesReadInInterval", 0, 0 },
62  { "HelperNode", "EntryGuard", 0, 0 },
63  { "HelperNodeDownSince", "EntryGuardDownSince", 0, 0 },
64  { "HelperNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
65  { "EntryNode", "EntryGuard", 0, 0 },
66  { "EntryNodeDownSince", "EntryGuardDownSince", 0, 0 },
67  { "EntryNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
68  { NULL, NULL, 0, 0},
69 };
70 
71 /** dummy instance of or_state_t, used for type-checking its
72  * members with CONF_CHECK_VAR_TYPE. */
74 
75 #define VAR(varname,conftype,member,initvalue) \
76  CONFIG_VAR_ETYPE(or_state_t, varname, conftype, member, 0, initvalue)
77 #define V(member,conftype,initvalue) \
78  VAR(#member, conftype, member, initvalue)
79 
80 /** Array of "state" variables saved to the ~/.tor/state file. */
81 static const config_var_t state_vars_[] = {
82  /* Remember to document these in state-contents.txt ! */
83 
84  V(AccountingBytesReadInInterval, MEMUNIT, NULL),
85  V(AccountingBytesWrittenInInterval, MEMUNIT, NULL),
86  V(AccountingExpectedUsage, MEMUNIT, NULL),
87  V(AccountingIntervalStart, ISOTIME, NULL),
88  V(AccountingSecondsActive, INTERVAL, NULL),
89  V(AccountingSecondsToReachSoftLimit,INTERVAL, NULL),
90  V(AccountingSoftLimitHitAt, ISOTIME, NULL),
91  V(AccountingBytesAtSoftLimit, MEMUNIT, NULL),
92 
93  VAR("EntryGuard", LINELIST_S, EntryGuards, NULL),
94  VAR("EntryGuardDownSince", LINELIST_S, EntryGuards, NULL),
95  VAR("EntryGuardUnlistedSince", LINELIST_S, EntryGuards, NULL),
96  VAR("EntryGuardAddedBy", LINELIST_S, EntryGuards, NULL),
97  VAR("EntryGuardPathBias", LINELIST_S, EntryGuards, NULL),
98  VAR("EntryGuardPathUseBias", LINELIST_S, EntryGuards, NULL),
99  V(EntryGuards, LINELIST_V, NULL),
100 
101  VAR("TransportProxy", LINELIST_S, TransportProxies, NULL),
102  V(TransportProxies, LINELIST_V, NULL),
103 
104  V(HidServRevCounter, LINELIST, NULL),
105 
106  V(BWHistoryReadEnds, ISOTIME, NULL),
107  V(BWHistoryReadInterval, POSINT, "900"),
108  V(BWHistoryReadValues, CSV, ""),
109  V(BWHistoryReadMaxima, CSV, ""),
110  V(BWHistoryWriteEnds, ISOTIME, NULL),
111  V(BWHistoryWriteInterval, POSINT, "900"),
112  V(BWHistoryWriteValues, CSV, ""),
113  V(BWHistoryWriteMaxima, CSV, ""),
114  V(BWHistoryDirReadEnds, ISOTIME, NULL),
115  V(BWHistoryDirReadInterval, POSINT, "900"),
116  V(BWHistoryDirReadValues, CSV, ""),
117  V(BWHistoryDirReadMaxima, CSV, ""),
118  V(BWHistoryDirWriteEnds, ISOTIME, NULL),
119  V(BWHistoryDirWriteInterval, POSINT, "900"),
120  V(BWHistoryDirWriteValues, CSV, ""),
121  V(BWHistoryDirWriteMaxima, CSV, ""),
122 
123  V(Guard, LINELIST, NULL),
124 
125  V(TorVersion, STRING, NULL),
126 
127  V(LastRotatedOnionKey, ISOTIME, NULL),
128  V(LastWritten, ISOTIME, NULL),
129 
130  V(TotalBuildTimes, POSINT, NULL),
131  V(CircuitBuildAbandonedCount, POSINT, "0"),
132  VAR("CircuitBuildTimeBin", LINELIST_S, BuildtimeHistogram, NULL),
133  VAR("BuildtimeHistogram", LINELIST_V, BuildtimeHistogram, NULL),
134 
136 };
137 
138 #undef VAR
139 #undef V
140 
141 static int or_state_validate(or_state_t *state, char **msg);
142 
143 static int or_state_validate_cb(const void *old_options,
144  void *options, char **msg);
145 
146 /** Magic value for or_state_t. */
147 #define OR_STATE_MAGIC 0x57A73f57
148 
149 /** "Extra" variable in the state that receives lines we can't parse. This
150  * lets us preserve options from versions of Tor newer than us. */
152  .name = "__extra",
153  .type = CONFIG_TYPE_LINELIST,
154  .offset = offsetof(or_state_t, ExtraLines),
155 };
156 
157 /** Configuration format for or_state_t. */
159  .size = sizeof(or_state_t),
160  .magic = {
161  "or_state_t",
163  offsetof(or_state_t, magic_),
164  },
165  .abbrevs = state_abbrevs_,
166  .vars = state_vars_,
167  .legacy_validate_fn = or_state_validate_cb,
168  .extra = &state_extra_var,
169  .has_config_suite = true,
170  .config_suite_offset = offsetof(or_state_t, substates_),
171 };
172 
173 /* A global configuration manager for state-file objects */
174 static config_mgr_t *state_mgr = NULL;
175 
176 /** Return the configuration manager for state-file objects. */
177 STATIC const config_mgr_t *
179 {
180  if (PREDICT_UNLIKELY(state_mgr == NULL)) {
181  state_mgr = config_mgr_new(&state_format);
182  int rv = subsystems_register_state_formats(state_mgr);
183  tor_assert(rv == 0);
184  config_mgr_freeze(state_mgr);
185  }
186  return state_mgr;
187 }
188 
189 #define CHECK_STATE_MAGIC(s) STMT_BEGIN \
190  config_check_toplevel_magic(get_state_mgr(), (s)); \
191  STMT_END
192 
193 /** Persistent serialized state. */
194 static or_state_t *global_state = NULL;
195 
196 /** Return the persistent state struct for this Tor. */
198 get_or_state, (void))
199 {
201  return global_state;
202 }
203 
204 /** Return true iff we have loaded the global state for this Tor */
205 int
207 {
208  return global_state != NULL;
209 }
210 
211 /** Return true if <b>line</b> is a valid state TransportProxy line.
212  * Return false otherwise. */
213 static int
215 {
216  smartlist_t *items = NULL;
217  char *addrport=NULL;
218  tor_addr_t addr;
219  uint16_t port = 0;
220  int r;
221 
222  items = smartlist_new();
223  smartlist_split_string(items, line, NULL,
224  SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
225 
226  if (smartlist_len(items) != 2) {
227  log_warn(LD_CONFIG, "state: Not enough arguments in TransportProxy line.");
228  goto err;
229  }
230 
231  addrport = smartlist_get(items, 1);
232  if (tor_addr_port_lookup(addrport, &addr, &port) < 0) {
233  log_warn(LD_CONFIG, "state: Could not parse addrport.");
234  goto err;
235  }
236 
237  if (!port) {
238  log_warn(LD_CONFIG, "state: Transport line did not contain port.");
239  goto err;
240  }
241 
242  r = 1;
243  goto done;
244 
245  err:
246  r = 0;
247 
248  done:
249  SMARTLIST_FOREACH(items, char*, s, tor_free(s));
250  smartlist_free(items);
251  return r;
252 }
253 
254 /** Return 0 if all TransportProxy lines in <b>state</b> are well
255  * formed. Otherwise, return -1. */
256 static int
258 {
259  int broken = 0;
260  config_line_t *line;
261 
262  for (line = state->TransportProxies ; line ; line = line->next) {
263  tor_assert(!strcmp(line->key, "TransportProxy"));
264  if (!state_transport_line_is_valid(line->value))
265  broken = 1;
266  }
267 
268  if (broken)
269  log_warn(LD_CONFIG, "state: State file seems to be broken.");
270 
271  return 0;
272 }
273 
274 /** Return 0 if every setting in <b>state</b> is reasonable, and a
275  * permissible transition from <b>old_state</b>. Else warn and return -1.
276  * Should have no side effects, except for normalizing the contents of
277  * <b>state</b>.
278  */
279 static int
280 or_state_validate(or_state_t *state, char **msg)
281 {
282  return config_validate(get_state_mgr(), NULL, state, msg);
283 }
284 
285 /**
286  * Legacy validation/normalization callback for or_state_t. See
287  * legacy_validate_fn_t for more information.
288  */
289 static int
290 or_state_validate_cb(const void *old_state, void *state_, char **msg)
291 {
292  /* There is not a meaningful concept of a state-to-state transition,
293  * since we do not reload the state after we start. */
294  (void) old_state;
295  CHECK_STATE_MAGIC(state_);
296 
297  or_state_t *state = state_;
298 
299  if (entry_guards_parse_state(state, 0, msg)<0)
300  return -1;
301 
302  if (validate_transports_in_state(state)<0)
303  return -1;
304 
305  return 0;
306 }
307 
308 /** Replace the current persistent state with <b>new_state</b> */
309 static int
311 {
312  char *err = NULL;
313  int ret = 0;
314  tor_assert(new_state);
315  config_free(get_state_mgr(), global_state);
316  global_state = new_state;
318  ret = -1;
319  }
320  if (entry_guards_parse_state(global_state, 1, &err)<0) {
321  log_warn(LD_GENERAL,"%s",err);
322  tor_free(err);
323  ret = -1;
324  }
325  if (rep_hist_load_state(global_state, &err)<0) {
326  log_warn(LD_GENERAL,"Unparseable bandwidth history state: %s",err);
327  tor_free(err);
328  ret = -1;
329  }
332  ret = -1;
333  }
334 
335  return ret;
336 }
337 
338 /**
339  * Save a broken state file to a backup location.
340  */
341 static void
343 {
344  int i, res;
345  file_status_t status;
346  char *fname2 = NULL;
347  for (i = 0; i < 100; ++i) {
348  tor_asprintf(&fname2, "%s.%d", fname, i);
349  status = file_status(fname2);
350  if (status == FN_NOENT)
351  break;
352  tor_free(fname2);
353  }
354  if (i == 100) {
355  log_warn(LD_BUG, "Unable to parse state in \"%s\"; too many saved bad "
356  "state files to move aside. Discarding the old state file.",
357  fname);
358  res = unlink(fname);
359  if (res != 0) {
360  log_warn(LD_FS,
361  "Also couldn't discard old state file \"%s\" because "
362  "unlink() failed: %s",
363  fname, strerror(errno));
364  }
365  } else {
366  log_warn(LD_BUG, "Unable to parse state in \"%s\". Moving it aside "
367  "to \"%s\". This could be a bug in Tor; please tell "
368  "the developers.", fname, fname2);
369  if (tor_rename(fname, fname2) < 0) {//XXXX sandbox prohibits
370  log_warn(LD_BUG, "Weirdly, I couldn't even move the state aside. The "
371  "OS gave an error of %s", strerror(errno));
372  }
373  }
374  tor_free(fname2);
375 }
376 
378 or_state_new(void)
379 {
380  or_state_t *new_state = config_new(get_state_mgr());
381  config_init(get_state_mgr(), new_state);
382 
383  return new_state;
384 }
385 
386 /** Reload the persistent state from disk, generating a new state as needed.
387  * Return 0 on success, less than 0 on failure.
388  */
389 int
391 {
392  or_state_t *new_state = NULL;
393  char *contents = NULL, *fname;
394  char *errmsg = NULL;
395  int r = -1, badstate = 0;
396 
397  fname = get_datadir_fname("state");
398  switch (file_status(fname)) {
399  case FN_FILE:
400  if (!(contents = read_file_to_str(fname, 0, NULL))) {
401  log_warn(LD_FS, "Unable to read state file \"%s\"", fname);
402  goto done;
403  }
404  break;
405  /* treat empty state files as if the file doesn't exist, and generate
406  * a new state file, overwriting the empty file in or_state_save() */
407  case FN_NOENT:
408  case FN_EMPTY:
409  break;
410  case FN_ERROR:
411  case FN_DIR:
412  default:
413  log_warn(LD_GENERAL,"State file \"%s\" is not a file? Failing.", fname);
414  goto done;
415  }
416  new_state = or_state_new();
417  if (contents) {
418  config_line_t *lines=NULL;
419  int assign_retval;
420  if (config_get_lines(contents, &lines, 0)<0)
421  goto done;
422  assign_retval = config_assign(get_state_mgr(), new_state,
423  lines, 0, &errmsg);
424  config_free_lines(lines);
425  if (assign_retval<0)
426  badstate = 1;
427  if (errmsg) {
428  log_warn(LD_GENERAL, "%s", errmsg);
429  tor_free(errmsg);
430  }
431  }
432 
433  if (!badstate && or_state_validate(new_state, &errmsg) < 0)
434  badstate = 1;
435 
436  if (errmsg) {
437  log_warn(LD_GENERAL, "%s", errmsg);
438  tor_free(errmsg);
439  }
440 
441  if (badstate && !contents) {
442  log_warn(LD_BUG, "Uh oh. We couldn't even validate our own default state."
443  " This is a bug in Tor.");
444  goto done;
445  } else if (badstate && contents) {
446  or_state_save_broken(fname);
447 
448  tor_free(contents);
449  config_free(get_state_mgr(), new_state);
450 
451  new_state = or_state_new();
452  } else if (contents) {
453  log_info(LD_GENERAL, "Loaded state from \"%s\"", fname);
454  /* Warn the user if their clock has been set backwards,
455  * they could be tricked into using old consensuses */
456  time_t apparent_skew = time(NULL) - new_state->LastWritten;
457  if (apparent_skew < 0) {
458  /* Initialize bootstrap event reporting because we might call
459  * clock_skew_warning() before the bootstrap state is
460  * initialized, causing an assertion failure. */
461  control_event_bootstrap(BOOTSTRAP_STATUS_STARTING, 0);
462  clock_skew_warning(NULL, (long)apparent_skew, 1, LD_GENERAL,
463  "local state file", fname);
464  }
465  } else {
466  log_info(LD_GENERAL, "Initialized state");
467  }
468  if (or_state_set(new_state) == -1) {
469  or_state_save_broken(fname);
470  }
471  new_state = NULL;
472  if (!contents) {
474  or_state_save(time(NULL));
475  }
476  r = 0;
477 
478  done:
479  tor_free(fname);
480  tor_free(contents);
481  if (new_state)
482  config_free(get_state_mgr(), new_state);
483 
484  return r;
485 }
486 
487 /** Did the last time we tried to write the state file fail? If so, we
488  * should consider disabling such features as preemptive circuit generation
489  * to compute circuit-build-time. */
491 
492 /** Return whether the state file failed to write last time we tried. */
493 int
495 {
497 }
498 
499 /** If writing the state to disk fails, try again after this many seconds. */
500 #define STATE_WRITE_RETRY_INTERVAL 3600
501 
502 /** If we're a relay, how often should we checkpoint our state file even
503  * if nothing else dirties it? This will checkpoint ongoing stats like
504  * bandwidth used, per-country user stats, etc. */
505 #define STATE_RELAY_CHECKPOINT_INTERVAL (12*60*60)
506 
507 /** Write the persistent state to disk. Return 0 for success, <0 on failure. */
508 int
509 or_state_save(time_t now)
510 {
511  char *state, *contents;
512  char tbuf[ISO_TIME_LEN+1];
513  char *fname;
514 
516 
517  if (global_state->next_write > now)
518  return 0;
519 
520  /* Call everything else that might dirty the state even more, in order
521  * to avoid redundant writes. */
526 
529 
530  global_state->LastWritten = now;
531 
534 
535  state = config_dump(get_state_mgr(), NULL, global_state, 1, 0);
536  format_local_iso_time(tbuf, now);
537  tor_asprintf(&contents,
538  "# Tor state file last generated on %s local time\n"
539  "# Other times below are in UTC\n"
540  "# You *do not* need to edit this file.\n\n%s",
541  tbuf, state);
542  tor_free(state);
543  fname = get_datadir_fname("state");
544  if (write_str_to_file(fname, contents, 0)<0) {
545  log_warn(LD_FS, "Unable to write state to file \"%s\"; "
546  "will try again later", fname);
548  tor_free(fname);
549  tor_free(contents);
550  /* Try again after STATE_WRITE_RETRY_INTERVAL (or sooner, if the state
551  * changes sooner). */
553  return -1;
554  }
555 
557  log_info(LD_GENERAL, "Saved state to \"%s\"", fname);
558  tor_free(fname);
559  tor_free(contents);
560 
561  if (server_mode(get_options()))
563  else
564  global_state->next_write = TIME_MAX;
565 
566  return 0;
567 }
568 
569 /** Return the config line for transport <b>transport</b> in the current state.
570  * Return NULL if there is no config line for <b>transport</b>. */
572 get_transport_in_state_by_name(const char *transport)
573 {
574  or_state_t *or_state = get_or_state();
575  config_line_t *line;
576  config_line_t *ret = NULL;
577  smartlist_t *items = NULL;
578 
579  for (line = or_state->TransportProxies ; line ; line = line->next) {
580  tor_assert(!strcmp(line->key, "TransportProxy"));
581 
582  items = smartlist_new();
583  smartlist_split_string(items, line->value, NULL,
584  SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
585  if (smartlist_len(items) != 2) /* broken state */
586  goto done;
587 
588  if (!strcmp(smartlist_get(items, 0), transport)) {
589  ret = line;
590  goto done;
591  }
592 
593  SMARTLIST_FOREACH(items, char*, s, tor_free(s));
594  smartlist_free(items);
595  items = NULL;
596  }
597 
598  done:
599  if (items) {
600  SMARTLIST_FOREACH(items, char*, s, tor_free(s));
601  smartlist_free(items);
602  }
603  return ret;
604 }
605 
606 /** Return string containing the address:port part of the
607  * TransportProxy <b>line</b> for transport <b>transport</b>.
608  * If the line is corrupted, return NULL. */
609 static const char *
610 get_transport_bindaddr(const char *line, const char *transport)
611 {
612  char *line_tmp = NULL;
613 
614  if (strlen(line) < strlen(transport) + 2) {
615  goto broken_state;
616  } else {
617  /* line should start with the name of the transport and a space.
618  (for example, "obfs2 127.0.0.1:47245") */
619  tor_asprintf(&line_tmp, "%s ", transport);
620  if (strcmpstart(line, line_tmp))
621  goto broken_state;
622 
623  tor_free(line_tmp);
624  return (line+strlen(transport)+1);
625  }
626 
627  broken_state:
628  tor_free(line_tmp);
629  return NULL;
630 }
631 
632 /** Return a string containing the address:port that a proxy transport
633  * should bind on. The string is stored on the heap and must be freed
634  * by the caller of this function. */
635 char *
637 {
638  char *default_addrport = NULL;
639  const char *stored_bindaddr = NULL;
640  config_line_t *line = NULL;
641 
642  {
643  /* See if the user explicitly asked for a specific listening
644  address for this transport. */
645  char *conf_bindaddr = pt_get_bindaddr_from_config(transport);
646  if (conf_bindaddr)
647  return conf_bindaddr;
648  }
649 
650  line = get_transport_in_state_by_name(transport);
651  if (!line) /* Found no references in state for this transport. */
652  goto no_bindaddr_found;
653 
654  stored_bindaddr = get_transport_bindaddr(line->value, transport);
655  if (stored_bindaddr) /* found stored bindaddr in state file. */
656  return tor_strdup(stored_bindaddr);
657 
658  no_bindaddr_found:
659  /** If we didn't find references for this pluggable transport in the
660  state file, we should instruct the pluggable transport proxy to
661  listen on INADDR_ANY on a random ephemeral port. */
662  tor_asprintf(&default_addrport, "%s:%s", fmt_addr32(INADDR_ANY), "0");
663  return default_addrport;
664 }
665 
666 /** Save <b>transport</b> listening on <b>addr</b>:<b>port</b> to
667  state */
668 void
669 save_transport_to_state(const char *transport,
670  const tor_addr_t *addr, uint16_t port)
671 {
672  or_state_t *state = get_or_state();
673 
674  char *transport_addrport=NULL;
675 
676  /** find where to write on the state */
677  config_line_t **next, *line;
678 
679  /* see if this transport is already stored in state */
680  config_line_t *transport_line =
682 
683  if (transport_line) { /* if transport already exists in state... */
684  const char *prev_bindaddr = /* get its addrport... */
685  get_transport_bindaddr(transport_line->value, transport);
686  transport_addrport = tor_strdup(fmt_addrport(addr, port));
687 
688  /* if transport in state has the same address as this one, life is good */
689  if (!strcmp(prev_bindaddr, transport_addrport)) {
690  log_info(LD_CONFIG, "Transport seems to have spawned on its usual "
691  "address:port.");
692  goto done;
693  } else { /* if addrport in state is different than the one we got */
694  log_info(LD_CONFIG, "Transport seems to have spawned on different "
695  "address:port. Let's update the state file with the new "
696  "address:port");
697  tor_free(transport_line->value); /* free the old line */
698  /* replace old addrport line with new line */
699  tor_asprintf(&transport_line->value, "%s %s", transport,
700  fmt_addrport(addr, port));
701  }
702  } else { /* never seen this one before; save it in state for next time */
703  log_info(LD_CONFIG, "It's the first time we see this transport. "
704  "Let's save its address:port");
705  next = &state->TransportProxies;
706  /* find the last TransportProxy line in the state and point 'next'
707  right after it */
708  line = state->TransportProxies;
709  while (line) {
710  next = &(line->next);
711  line = line->next;
712  }
713 
714  /* allocate space for the new line and fill it in */
715  *next = line = tor_malloc_zero(sizeof(config_line_t));
716  line->key = tor_strdup("TransportProxy");
717  tor_asprintf(&line->value, "%s %s", transport, fmt_addrport(addr, port));
718  }
719 
720  if (!get_options()->AvoidDiskWrites)
721  or_state_mark_dirty(state, 0);
722 
723  done:
724  tor_free(transport_addrport);
725 }
726 
727 /** Change the next_write time of <b>state</b> to <b>when</b>, unless the
728  * state is already scheduled to be written to disk earlier than <b>when</b>.
729  */
730 void
731 or_state_mark_dirty(or_state_t *state, time_t when)
732 {
733  if (state->next_write > when) {
734  state->next_write = when;
736  }
737 }
738 
739 STATIC void
740 or_state_free_(or_state_t *state)
741 {
742  if (!state)
743  return;
744 
745  config_free(get_state_mgr(), state);
746 }
747 
748 void
749 or_state_free_all(void)
750 {
751  or_state_free(global_state);
752  global_state = NULL;
753  config_mgr_free(state_mgr);
754 }
Header file for circuitstats.c.
Header for statefile.c.
void * config_new(const config_mgr_t *mgr)
Definition: confmgt.c:387
STATIC config_line_t * get_transport_in_state_by_name(const char *transport)
Definition: statefile.c:572
Header for confline.c.
int subsystems_flush_state(const config_mgr_t *mgr, struct or_state_t *state)
Definition: subsysmgr.c:447
Header file for circuitbuild.c.
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
STATIC const config_mgr_t * get_state_mgr(void)
Definition: statefile.c:178
void format_local_iso_time(char *buf, time_t t)
Definition: time_fmt.c:285
int or_state_loaded(void)
Definition: statefile.c:206
Header file for connection.c.
static config_abbrev_t state_abbrevs_[]
Definition: statefile.c:60
#define LD_GENERAL
Definition: log.h:62
Header for feature/relay/transport_config.c.
void reschedule_or_state_save(void)
Definition: mainloop.c:1908
int accounting_is_enabled(const or_options_t *options)
Definition: hibernate.c:305
Header file for config.c.
static const config_var_t state_vars_[]
Definition: statefile.c:81
time_t next_write
Definition: or_state_st.h:26
#define STATE_WRITE_RETRY_INTERVAL
Definition: statefile.c:500
const or_options_t * get_options(void)
Definition: config.c:941
#define tor_assert(expr)
Definition: util_bug.h:102
time_t LastWritten
Definition: or_state_st.h:29
static or_state_t * global_state
Definition: statefile.c:194
#define END_OF_CONFIG_VARS
Definition: confmacros.h:22
int strcmpstart(const char *s1, const char *s2)
Definition: util_string.c:206
#define tor_free(p)
Definition: malloc.h:52
Header file for mainloop.c.
void accounting_run_housekeeping(time_t now)
Definition: hibernate.c:585
smartlist_t * smartlist_new(void)
int entry_guards_parse_state(or_state_t *state, int set, char **msg)
Definition: entrynodes.c:3379
static const config_format_t state_format
Definition: statefile.c:158
int tor_addr_port_lookup(const char *s, tor_addr_t *addr_out, uint16_t *port_out)
Definition: resolve.c:252
int config_get_lines(const char *string, config_line_t **result, int extended)
Definition: confline.c:201
int or_state_load(void)
Definition: statefile.c:390
#define STATIC
Definition: testsupport.h:32
#define OR_STATE_MAGIC
Definition: statefile.c:147
int write_str_to_file(const char *fname, const char *str, int bin)
Definition: files.c:258
char * pt_get_bindaddr_from_config(const char *transport)
void save_transport_to_state(const char *transport, const tor_addr_t *addr, uint16_t port)
Definition: statefile.c:669
config_mgr_t * config_mgr_new(const config_format_t *toplevel_fmt)
Definition: confmgt.c:145
void control_event_bootstrap(bootstrap_status_t status, int progress)
Header file for hibernate.c.
static int or_state_validate(or_state_t *state, char **msg)
Definition: statefile.c:280
void rep_hist_update_state(or_state_t *state)
Definition: rephist.c:1398
int subsystems_register_state_formats(config_mgr_t *mgr)
Definition: subsysmgr.c:325
Header file for routermode.c.
int tor_asprintf(char **strp, const char *fmt,...)
Definition: printf.c:75
const char * fmt_addrport(const tor_addr_t *addr, uint16_t port)
Definition: address.c:1169
static int last_state_file_write_failed
Definition: statefile.c:490
Header for version.c.
Header file for sandbox.c.
char * config_dump(const config_mgr_t *mgr, const void *default_options, const void *options, int minimal, int comment_defaults)
Definition: confmgt.c:1311
const char * name
Definition: conftypes.h:98
Master header file for Tor-specific functionality.
static const char * get_transport_bindaddr(const char *line, const char *transport)
Definition: statefile.c:610
char * get_stored_bindaddr_for_server_transport(const char *transport)
Definition: statefile.c:636
DUMMY_TYPECHECK_INSTANCE(or_state_t)
Header file for rephist.c.
const char * fmt_addr32(uint32_t addr)
Definition: address.c:1181
Header for netstatus.c.
int config_assign(const config_mgr_t *mgr, void *options, config_line_t *list, unsigned config_assign_flags, char **msg)
Definition: confmgt.c:934
#define LD_FS
Definition: log.h:70
int rep_hist_load_state(or_state_t *state, char **err)
Definition: rephist.c:1498
char * TorVersion
Definition: or_state_st.h:83
static int or_state_set(or_state_t *new_state)
Definition: statefile.c:310
static int validate_transports_in_state(or_state_t *state)
Definition: statefile.c:257
int subsystems_set_state(const config_mgr_t *mgr, struct or_state_t *state)
Definition: subsysmgr.c:423
static int or_state_validate_cb(const void *old_options, void *options, char **msg)
Definition: statefile.c:290
void clock_skew_warning(const connection_t *conn, long apparent_skew, int trusted, log_domain_mask_t domain, const char *received, const char *source)
Definition: connection.c:5549
#define SMARTLIST_FOREACH(sl, type, var, cmd)
The or_state_t structure, which represents Tor's state file.
Header file for router.c.
#define STATE_RELAY_CHECKPOINT_INTERVAL
Definition: statefile.c:505
file_status_t
Definition: files.h:55
int did_last_state_file_write_fail(void)
Definition: statefile.c:494
circuit_build_times_t * get_circuit_build_times_mutable(void)
Definition: circuitstats.c:89
const circuit_build_times_t * get_circuit_build_times(void)
Definition: circuitstats.c:82
void entry_guards_update_state(or_state_t *state)
Definition: entrynodes.c:3441
Header for resolve.c.
static void or_state_save_broken(char *fname)
Definition: statefile.c:342
Header for confmgt.c.
static struct_member_t state_extra_var
Definition: statefile.c:151
void or_state_mark_dirty(or_state_t *state, time_t when)
Definition: statefile.c:731
int or_state_save(time_t now)
Definition: statefile.c:509
Header for subsysmgr.c.
void config_mgr_freeze(config_mgr_t *mgr)
Definition: confmgt.c:285
#define VAR(varname, conftype, member, initvalue)
Definition: config.c:259
int circuit_build_times_parse_state(circuit_build_times_t *cbt, or_state_t *state)
void circuit_build_times_update_state(const circuit_build_times_t *cbt, or_state_t *state)
Definition: circuitstats.c:932
or_state_t * get_or_state(void)
Definition: statefile.c:198
int tor_rename(const char *path_old, const char *path_new)
Definition: files.c:103
const char * get_version(void)
Definition: version.c:38
int server_mode(const or_options_t *options)
Definition: routermode.c:34
validation_status_t config_validate(const config_mgr_t *mgr, const void *old_options, void *options, char **msg_out)
Definition: confmgt.c:1269
Header file for control_events.c.
file_status_t file_status(const char *filename)
Definition: files.c:212
void config_init(const config_mgr_t *mgr, void *options)
Definition: confmgt.c:1155
#define LD_BUG
Definition: log.h:86
#define LD_CONFIG
Definition: log.h:68
static int state_transport_line_is_valid(const char *line)
Definition: statefile.c:214
int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep, int flags, int max)