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