tor  0.4.2.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 
31 #define STATEFILE_PRIVATE
32 #include "core/or/or.h"
33 #include "core/or/circuitstats.h"
34 #include "app/config/config.h"
35 #include "app/config/confparse.h"
36 #include "core/mainloop/mainloop.h"
37 #include "core/mainloop/netstatus.h"
42 #include "feature/stats/rephist.h"
43 #include "feature/relay/router.h"
45 #include "lib/sandbox/sandbox.h"
46 #include "app/config/statefile.h"
47 #include "lib/encoding/confline.h"
48 #include "lib/net/resolve.h"
49 #include "lib/version/torversion.h"
50 
51 #include "app/config/or_state_st.h"
52 
53 #ifdef HAVE_UNISTD_H
54 #include <unistd.h>
55 #endif
56 
59  { "AccountingBytesReadInterval", "AccountingBytesReadInInterval", 0, 0 },
60  { "HelperNode", "EntryGuard", 0, 0 },
61  { "HelperNodeDownSince", "EntryGuardDownSince", 0, 0 },
62  { "HelperNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
63  { "EntryNode", "EntryGuard", 0, 0 },
64  { "EntryNodeDownSince", "EntryGuardDownSince", 0, 0 },
65  { "EntryNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
66  { NULL, NULL, 0, 0},
67 };
68 
72 
73 /*XXXX these next two are duplicates or near-duplicates from config.c */
74 #define VAR(name,conftype,member,initvalue) \
75  { name, CONFIG_TYPE_ ## conftype, offsetof(or_state_t, member), \
76  initvalue CONF_TEST_MEMBERS(or_state_t, conftype, member) }
77 
78 #define V(member,conftype,initvalue) \
79  VAR(#member, conftype, member, initvalue)
80 
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, UINT, "900"),
109  V(BWHistoryReadValues, CSV, ""),
110  V(BWHistoryReadMaxima, CSV, ""),
111  V(BWHistoryWriteEnds, ISOTIME, NULL),
112  V(BWHistoryWriteInterval, UINT, "900"),
113  V(BWHistoryWriteValues, CSV, ""),
114  V(BWHistoryWriteMaxima, CSV, ""),
115  V(BWHistoryDirReadEnds, ISOTIME, NULL),
116  V(BWHistoryDirReadInterval, UINT, "900"),
117  V(BWHistoryDirReadValues, CSV, ""),
118  V(BWHistoryDirReadMaxima, CSV, ""),
119  V(BWHistoryDirWriteEnds, ISOTIME, NULL),
120  V(BWHistoryDirWriteInterval, UINT, "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, UINT, NULL),
132  V(CircuitBuildAbandonedCount, UINT, "0"),
133  VAR("CircuitBuildTimeBin", LINELIST_S, BuildtimeHistogram, NULL),
134  VAR("BuildtimeHistogram", LINELIST_V, BuildtimeHistogram, NULL),
135 
136  V(MinutesSinceUserActivity, UINT, NULL),
137  V(Dormant, AUTOBOOL, "auto"),
138 
139  END_OF_CONFIG_VARS
140 };
141 
142 #undef VAR
143 #undef V
144 
145 static int or_state_validate(or_state_t *state, char **msg);
146 
147 static int or_state_validate_cb(void *old_options, void *options,
148  void *default_options,
149  int from_setconf, char **msg);
150 
151 static void or_state_free_cb(void *state);
152 
154 #define OR_STATE_MAGIC 0x57A73f57
155 
159  "__extra", CONFIG_TYPE_LINELIST, offsetof(or_state_t, ExtraLines), NULL
160  CONF_TEST_MEMBERS(or_state_t, LINELIST, ExtraLines)
161 };
162 
165  sizeof(or_state_t),
167  offsetof(or_state_t, magic_),
169  NULL,
170  state_vars_,
171  or_state_validate_cb,
172  or_state_free_cb,
174 };
175 
177 static or_state_t *global_state = NULL;
178 
181 get_or_state, (void))
182 {
184  return global_state;
185 }
186 
188 int
190 {
191  return global_state != NULL;
192 }
193 
196 static int
198 {
199  smartlist_t *items = NULL;
200  char *addrport=NULL;
201  tor_addr_t addr;
202  uint16_t port = 0;
203  int r;
204 
205  items = smartlist_new();
206  smartlist_split_string(items, line, NULL,
207  SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
208 
209  if (smartlist_len(items) != 2) {
210  log_warn(LD_CONFIG, "state: Not enough arguments in TransportProxy line.");
211  goto err;
212  }
213 
214  addrport = smartlist_get(items, 1);
215  if (tor_addr_port_lookup(addrport, &addr, &port) < 0) {
216  log_warn(LD_CONFIG, "state: Could not parse addrport.");
217  goto err;
218  }
219 
220  if (!port) {
221  log_warn(LD_CONFIG, "state: Transport line did not contain port.");
222  goto err;
223  }
224 
225  r = 1;
226  goto done;
227 
228  err:
229  r = 0;
230 
231  done:
232  SMARTLIST_FOREACH(items, char*, s, tor_free(s));
233  smartlist_free(items);
234  return r;
235 }
236 
239 static int
241 {
242  int broken = 0;
243  config_line_t *line;
244 
245  for (line = state->TransportProxies ; line ; line = line->next) {
246  tor_assert(!strcmp(line->key, "TransportProxy"));
247  if (!state_transport_line_is_valid(line->value))
248  broken = 1;
249  }
250 
251  if (broken)
252  log_warn(LD_CONFIG, "state: State file seems to be broken.");
253 
254  return 0;
255 }
256 
257 static int
258 or_state_validate_cb(void *old_state, void *state, void *default_state,
259  int from_setconf, char **msg)
260 {
261  /* We don't use these; only options do. Still, we need to match that
262  * signature. */
263  (void) from_setconf;
264  (void) default_state;
265  (void) old_state;
266 
267  return or_state_validate(state, msg);
268 }
269 
270 static void
271 or_state_free_cb(void *state)
272 {
273  or_state_free_(state);
274 }
275 
281 static int
282 or_state_validate(or_state_t *state, char **msg)
283 {
284  if (entry_guards_parse_state(state, 0, msg)<0)
285  return -1;
286 
287  if (validate_transports_in_state(state)<0)
288  return -1;
289 
290  return 0;
291 }
292 
294 static int
296 {
297  char *err = NULL;
298  int ret = 0;
299  tor_assert(new_state);
300  config_free(&state_format, global_state);
301  global_state = new_state;
302  if (entry_guards_parse_state(global_state, 1, &err)<0) {
303  log_warn(LD_GENERAL,"%s",err);
304  tor_free(err);
305  ret = -1;
306  }
307  if (rep_hist_load_state(global_state, &err)<0) {
308  log_warn(LD_GENERAL,"Unparseable bandwidth history state: %s",err);
309  tor_free(err);
310  ret = -1;
311  }
314  ret = -1;
315  }
316  netstatus_load_from_state(global_state, time(NULL));
317 
318  return ret;
319 }
320 
324 static void
326 {
327  int i, res;
328  file_status_t status;
329  char *fname2 = NULL;
330  for (i = 0; i < 100; ++i) {
331  tor_asprintf(&fname2, "%s.%d", fname, i);
332  status = file_status(fname2);
333  if (status == FN_NOENT)
334  break;
335  tor_free(fname2);
336  }
337  if (i == 100) {
338  log_warn(LD_BUG, "Unable to parse state in \"%s\"; too many saved bad "
339  "state files to move aside. Discarding the old state file.",
340  fname);
341  res = unlink(fname);
342  if (res != 0) {
343  log_warn(LD_FS,
344  "Also couldn't discard old state file \"%s\" because "
345  "unlink() failed: %s",
346  fname, strerror(errno));
347  }
348  } else {
349  log_warn(LD_BUG, "Unable to parse state in \"%s\". Moving it aside "
350  "to \"%s\". This could be a bug in Tor; please tell "
351  "the developers.", fname, fname2);
352  if (tor_rename(fname, fname2) < 0) {//XXXX sandbox prohibits
353  log_warn(LD_BUG, "Weirdly, I couldn't even move the state aside. The "
354  "OS gave an error of %s", strerror(errno));
355  }
356  }
357  tor_free(fname2);
358 }
359 
360 STATIC or_state_t *
361 or_state_new(void)
362 {
363  or_state_t *new_state = tor_malloc_zero(sizeof(or_state_t));
364  new_state->magic_ = OR_STATE_MAGIC;
365  config_init(&state_format, new_state);
366 
367  return new_state;
368 }
369 
373 int
375 {
376  or_state_t *new_state = NULL;
377  char *contents = NULL, *fname;
378  char *errmsg = NULL;
379  int r = -1, badstate = 0;
380 
381  fname = get_datadir_fname("state");
382  switch (file_status(fname)) {
383  case FN_FILE:
384  if (!(contents = read_file_to_str(fname, 0, NULL))) {
385  log_warn(LD_FS, "Unable to read state file \"%s\"", fname);
386  goto done;
387  }
388  break;
389  /* treat empty state files as if the file doesn't exist, and generate
390  * a new state file, overwriting the empty file in or_state_save() */
391  case FN_NOENT:
392  case FN_EMPTY:
393  break;
394  case FN_ERROR:
395  case FN_DIR:
396  default:
397  log_warn(LD_GENERAL,"State file \"%s\" is not a file? Failing.", fname);
398  goto done;
399  }
400  new_state = or_state_new();
401  if (contents) {
402  config_line_t *lines=NULL;
403  int assign_retval;
404  if (config_get_lines(contents, &lines, 0)<0)
405  goto done;
406  assign_retval = config_assign(&state_format, new_state,
407  lines, 0, &errmsg);
408  config_free_lines(lines);
409  if (assign_retval<0)
410  badstate = 1;
411  if (errmsg) {
412  log_warn(LD_GENERAL, "%s", errmsg);
413  tor_free(errmsg);
414  }
415  }
416 
417  if (!badstate && or_state_validate(new_state, &errmsg) < 0)
418  badstate = 1;
419 
420  if (errmsg) {
421  log_warn(LD_GENERAL, "%s", errmsg);
422  tor_free(errmsg);
423  }
424 
425  if (badstate && !contents) {
426  log_warn(LD_BUG, "Uh oh. We couldn't even validate our own default state."
427  " This is a bug in Tor.");
428  goto done;
429  } else if (badstate && contents) {
430  or_state_save_broken(fname);
431 
432  tor_free(contents);
433  config_free(&state_format, new_state);
434 
435  new_state = or_state_new();
436  } else if (contents) {
437  log_info(LD_GENERAL, "Loaded state from \"%s\"", fname);
438  /* Warn the user if their clock has been set backwards,
439  * they could be tricked into using old consensuses */
440  time_t apparent_skew = time(NULL) - new_state->LastWritten;
441  if (apparent_skew < 0) {
442  /* Initialize bootstrap event reporting because we might call
443  * clock_skew_warning() before the bootstrap state is
444  * initialized, causing an assertion failure. */
445  control_event_bootstrap(BOOTSTRAP_STATUS_STARTING, 0);
446  clock_skew_warning(NULL, (long)apparent_skew, 1, LD_GENERAL,
447  "local state file", fname);
448  }
449  } else {
450  log_info(LD_GENERAL, "Initialized state");
451  }
452  if (or_state_set(new_state) == -1) {
453  or_state_save_broken(fname);
454  }
455  new_state = NULL;
456  if (!contents) {
458  or_state_save(time(NULL));
459  }
460  r = 0;
461 
462  done:
463  tor_free(fname);
464  tor_free(contents);
465  if (new_state)
466  config_free(&state_format, new_state);
467 
468  return r;
469 }
470 
475 
477 int
479 {
481 }
482 
484 #define STATE_WRITE_RETRY_INTERVAL 3600
485 
489 #define STATE_RELAY_CHECKPOINT_INTERVAL (12*60*60)
490 
492 int
493 or_state_save(time_t now)
494 {
495  char *state, *contents;
496  char tbuf[ISO_TIME_LEN+1];
497  char *fname;
498 
500 
501  if (global_state->next_write > now)
502  return 0;
503 
504  /* Call everything else that might dirty the state even more, in order
505  * to avoid redundant writes. */
509  netstatus_flush_to_state(global_state, now);
510 
511  if (accounting_is_enabled(get_options()))
513 
514  global_state->LastWritten = now;
515 
517  tor_asprintf(&global_state->TorVersion, "Tor %s", get_version());
518 
519  state = config_dump(&state_format, NULL, global_state, 1, 0);
520  format_local_iso_time(tbuf, now);
521  tor_asprintf(&contents,
522  "# Tor state file last generated on %s local time\n"
523  "# Other times below are in UTC\n"
524  "# You *do not* need to edit this file.\n\n%s",
525  tbuf, state);
526  tor_free(state);
527  fname = get_datadir_fname("state");
528  if (write_str_to_file(fname, contents, 0)<0) {
529  log_warn(LD_FS, "Unable to write state to file \"%s\"; "
530  "will try again later", fname);
532  tor_free(fname);
533  tor_free(contents);
534  /* Try again after STATE_WRITE_RETRY_INTERVAL (or sooner, if the state
535  * changes sooner). */
537  return -1;
538  }
539 
541  log_info(LD_GENERAL, "Saved state to \"%s\"", fname);
542  tor_free(fname);
543  tor_free(contents);
544 
545  if (server_mode(get_options()))
547  else
548  global_state->next_write = TIME_MAX;
549 
550  return 0;
551 }
552 
555 STATIC config_line_t *
556 get_transport_in_state_by_name(const char *transport)
557 {
558  or_state_t *or_state = get_or_state();
559  config_line_t *line;
560  config_line_t *ret = NULL;
561  smartlist_t *items = NULL;
562 
563  for (line = or_state->TransportProxies ; line ; line = line->next) {
564  tor_assert(!strcmp(line->key, "TransportProxy"));
565 
566  items = smartlist_new();
567  smartlist_split_string(items, line->value, NULL,
568  SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
569  if (smartlist_len(items) != 2) /* broken state */
570  goto done;
571 
572  if (!strcmp(smartlist_get(items, 0), transport)) {
573  ret = line;
574  goto done;
575  }
576 
577  SMARTLIST_FOREACH(items, char*, s, tor_free(s));
578  smartlist_free(items);
579  items = NULL;
580  }
581 
582  done:
583  if (items) {
584  SMARTLIST_FOREACH(items, char*, s, tor_free(s));
585  smartlist_free(items);
586  }
587  return ret;
588 }
589 
593 static const char *
594 get_transport_bindaddr(const char *line, const char *transport)
595 {
596  char *line_tmp = NULL;
597 
598  if (strlen(line) < strlen(transport) + 2) {
599  goto broken_state;
600  } else {
601  /* line should start with the name of the transport and a space.
602  (for example, "obfs2 127.0.0.1:47245") */
603  tor_asprintf(&line_tmp, "%s ", transport);
604  if (strcmpstart(line, line_tmp))
605  goto broken_state;
606 
607  tor_free(line_tmp);
608  return (line+strlen(transport)+1);
609  }
610 
611  broken_state:
612  tor_free(line_tmp);
613  return NULL;
614 }
615 
619 char *
621 {
622  char *default_addrport = NULL;
623  const char *stored_bindaddr = NULL;
624  config_line_t *line = NULL;
625 
626  {
627  /* See if the user explicitly asked for a specific listening
628  address for this transport. */
629  char *conf_bindaddr = get_transport_bindaddr_from_config(transport);
630  if (conf_bindaddr)
631  return conf_bindaddr;
632  }
633 
634  line = get_transport_in_state_by_name(transport);
635  if (!line) /* Found no references in state for this transport. */
636  goto no_bindaddr_found;
637 
638  stored_bindaddr = get_transport_bindaddr(line->value, transport);
639  if (stored_bindaddr) /* found stored bindaddr in state file. */
640  return tor_strdup(stored_bindaddr);
641 
642  no_bindaddr_found:
646  tor_asprintf(&default_addrport, "%s:%s", fmt_addr32(INADDR_ANY), "0");
647  return default_addrport;
648 }
649 
652 void
653 save_transport_to_state(const char *transport,
654  const tor_addr_t *addr, uint16_t port)
655 {
656  or_state_t *state = get_or_state();
657 
658  char *transport_addrport=NULL;
659 
661  config_line_t **next, *line;
662 
663  /* see if this transport is already stored in state */
664  config_line_t *transport_line =
666 
667  if (transport_line) { /* if transport already exists in state... */
668  const char *prev_bindaddr = /* get its addrport... */
669  get_transport_bindaddr(transport_line->value, transport);
670  transport_addrport = tor_strdup(fmt_addrport(addr, port));
671 
672  /* if transport in state has the same address as this one, life is good */
673  if (!strcmp(prev_bindaddr, transport_addrport)) {
674  log_info(LD_CONFIG, "Transport seems to have spawned on its usual "
675  "address:port.");
676  goto done;
677  } else { /* if addrport in state is different than the one we got */
678  log_info(LD_CONFIG, "Transport seems to have spawned on different "
679  "address:port. Let's update the state file with the new "
680  "address:port");
681  tor_free(transport_line->value); /* free the old line */
682  /* replace old addrport line with new line */
683  tor_asprintf(&transport_line->value, "%s %s", transport,
684  fmt_addrport(addr, port));
685  }
686  } else { /* never seen this one before; save it in state for next time */
687  log_info(LD_CONFIG, "It's the first time we see this transport. "
688  "Let's save its address:port");
689  next = &state->TransportProxies;
690  /* find the last TransportProxy line in the state and point 'next'
691  right after it */
692  line = state->TransportProxies;
693  while (line) {
694  next = &(line->next);
695  line = line->next;
696  }
697 
698  /* allocate space for the new line and fill it in */
699  *next = line = tor_malloc_zero(sizeof(config_line_t));
700  line->key = tor_strdup("TransportProxy");
701  tor_asprintf(&line->value, "%s %s", transport, fmt_addrport(addr, port));
702  }
703 
704  if (!get_options()->AvoidDiskWrites)
705  or_state_mark_dirty(state, 0);
706 
707  done:
708  tor_free(transport_addrport);
709 }
710 
714 void
715 or_state_mark_dirty(or_state_t *state, time_t when)
716 {
717  if (state->next_write > when) {
718  state->next_write = when;
720  }
721 }
722 
723 STATIC void
724 or_state_free_(or_state_t *state)
725 {
726  if (!state)
727  return;
728 
729  config_free(&state_format, state);
730 }
731 
732 void
733 or_state_free_all(void)
734 {
735  or_state_free(global_state);
736  global_state = NULL;
737 }
static config_var_t state_extra_var
Definition: statefile.c:158
void config_init(const config_format_t *fmt, void *options)
Definition: confparse.c:926
Header file for circuitstats.c.
Header for statefile.c.
STATIC config_line_t * get_transport_in_state_by_name(const char *transport)
Definition: statefile.c:556
Header for confline.c.
Header file for circuitbuild.c.
#define V(member, conftype, initvalue)
Definition: statefile.c:78
void format_local_iso_time(char *buf, time_t t)
Definition: time_fmt.c:285
int or_state_loaded(void)
Definition: statefile.c:189
Header file for connection.c.
static config_abbrev_t state_abbrevs_[]
Definition: statefile.c:58
#define LD_GENERAL
Definition: log.h:59
void reschedule_or_state_save(void)
Definition: mainloop.c:1886
Header file for config.c.
#define STATE_WRITE_RETRY_INTERVAL
Definition: statefile.c:484
static or_state_t * global_state
Definition: statefile.c:177
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
char * config_dump(const config_format_t *fmt, const void *default_options, const void *options, int minimal, int comment_defaults)
Definition: confparse.c:945
int entry_guards_parse_state(or_state_t *state, int set, char **msg)
Definition: entrynodes.c:3375
static const config_format_t state_format
Definition: statefile.c:164
int tor_addr_port_lookup(const char *s, tor_addr_t *addr_out, uint16_t *port_out)
Definition: resolve.c:184
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:374
#define OR_STATE_MAGIC
Definition: statefile.c:154
void save_transport_to_state(const char *transport, const tor_addr_t *addr, uint16_t port)
Definition: statefile.c:653
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:282
void rep_hist_update_state(or_state_t *state)
Definition: rephist.c:1398
time_t LastWritten
Definition: or_state_st.h:28
tor_assert(buffer)
char * get_transport_bindaddr_from_config(const char *transport)
Definition: config.c:6314
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:1168
static int last_state_file_write_failed
Definition: statefile.c:474
Header file for sandbox.c.
Master header file for Tor-specific functionality.
static const char * get_transport_bindaddr(const char *line, const char *transport)
Definition: statefile.c:594
char * get_stored_bindaddr_for_server_transport(const char *transport)
Definition: statefile.c:620
DUMMY_TYPECHECK_INSTANCE(or_state_t)
Header file for rephist.c.
const char * fmt_addr32(uint32_t addr)
Definition: address.c:1180
static config_var_t state_vars_[]
Definition: statefile.c:82
#define LD_FS
Definition: log.h:67
int rep_hist_load_state(or_state_t *state, char **err)
Definition: rephist.c:1498
time_t next_write
Definition: or_state_st.h:25
static int or_state_set(or_state_t *new_state)
Definition: statefile.c:295
static int validate_transports_in_state(or_state_t *state)
Definition: statefile.c:240
#define SMARTLIST_FOREACH(sl, type, var, cmd)
Header file for router.c.
#define STATE_RELAY_CHECKPOINT_INTERVAL
Definition: statefile.c:489
file_status_t
Definition: files.h:55
int did_last_state_file_write_fail(void)
Definition: statefile.c:478
circuit_build_times_t * get_circuit_build_times_mutable(void)
Definition: circuitstats.c:89
int config_assign(const config_format_t *fmt, void *options, config_line_t *list, unsigned config_assign_flags, char **msg)
Definition: confparse.c:719
#define VAR(name, conftype, member, initvalue)
Definition: config.c:260
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:3437
Header for resolve.c.
static void or_state_save_broken(char *fname)
Definition: statefile.c:325
void or_state_mark_dirty(or_state_t *state, time_t when)
Definition: statefile.c:715
int or_state_save(time_t now)
Definition: statefile.c:493
MOCK_IMPL(or_state_t *, get_or_state,(void))
Definition: statefile.c:180
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
int tor_rename(const char *path_old, const char *path_new)
Definition: files.c:103
Header file for control_events.c.
char * TorVersion
Definition: or_state_st.h:82
file_status_t file_status(const char *filename)
Definition: files.c:212
#define LD_BUG
Definition: log.h:83
#define LD_CONFIG
Definition: log.h:65
Header for confparse.c.
static int state_transport_line_is_valid(const char *line)
Definition: statefile.c:197
int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep, int flags, int max)