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 "lib/confmgt/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 #define VAR(varname,conftype,member,initvalue) \
74  CONFIG_VAR_ETYPE(or_state_t, varname, conftype, member, 0, initvalue)
75 #define V(member,conftype,initvalue) \
76  VAR(#member, conftype, member, initvalue)
77 
79 static const config_var_t state_vars_[] = {
80  /* Remember to document these in state-contents.txt ! */
81 
82  V(AccountingBytesReadInInterval, MEMUNIT, NULL),
83  V(AccountingBytesWrittenInInterval, MEMUNIT, NULL),
84  V(AccountingExpectedUsage, MEMUNIT, NULL),
85  V(AccountingIntervalStart, ISOTIME, NULL),
86  V(AccountingSecondsActive, INTERVAL, NULL),
87  V(AccountingSecondsToReachSoftLimit,INTERVAL, NULL),
88  V(AccountingSoftLimitHitAt, ISOTIME, NULL),
89  V(AccountingBytesAtSoftLimit, MEMUNIT, NULL),
90 
91  VAR("EntryGuard", LINELIST_S, EntryGuards, NULL),
92  VAR("EntryGuardDownSince", LINELIST_S, EntryGuards, NULL),
93  VAR("EntryGuardUnlistedSince", LINELIST_S, EntryGuards, NULL),
94  VAR("EntryGuardAddedBy", LINELIST_S, EntryGuards, NULL),
95  VAR("EntryGuardPathBias", LINELIST_S, EntryGuards, NULL),
96  VAR("EntryGuardPathUseBias", LINELIST_S, EntryGuards, NULL),
97  V(EntryGuards, LINELIST_V, NULL),
98 
99  VAR("TransportProxy", LINELIST_S, TransportProxies, NULL),
100  V(TransportProxies, LINELIST_V, NULL),
101 
102  V(HidServRevCounter, LINELIST, NULL),
103 
104  V(BWHistoryReadEnds, ISOTIME, NULL),
105  V(BWHistoryReadInterval, POSINT, "900"),
106  V(BWHistoryReadValues, CSV, ""),
107  V(BWHistoryReadMaxima, CSV, ""),
108  V(BWHistoryWriteEnds, ISOTIME, NULL),
109  V(BWHistoryWriteInterval, POSINT, "900"),
110  V(BWHistoryWriteValues, CSV, ""),
111  V(BWHistoryWriteMaxima, CSV, ""),
112  V(BWHistoryDirReadEnds, ISOTIME, NULL),
113  V(BWHistoryDirReadInterval, POSINT, "900"),
114  V(BWHistoryDirReadValues, CSV, ""),
115  V(BWHistoryDirReadMaxima, CSV, ""),
116  V(BWHistoryDirWriteEnds, ISOTIME, NULL),
117  V(BWHistoryDirWriteInterval, POSINT, "900"),
118  V(BWHistoryDirWriteValues, CSV, ""),
119  V(BWHistoryDirWriteMaxima, CSV, ""),
120 
121  V(Guard, LINELIST, NULL),
122 
123  V(TorVersion, STRING, NULL),
124 
125  V(LastRotatedOnionKey, ISOTIME, NULL),
126  V(LastWritten, ISOTIME, NULL),
127 
128  V(TotalBuildTimes, POSINT, NULL),
129  V(CircuitBuildAbandonedCount, POSINT, "0"),
130  VAR("CircuitBuildTimeBin", LINELIST_S, BuildtimeHistogram, NULL),
131  VAR("BuildtimeHistogram", LINELIST_V, BuildtimeHistogram, NULL),
132 
133  V(MinutesSinceUserActivity, POSINT, NULL),
134  V(Dormant, AUTOBOOL, "auto"),
135 
137 };
138 
139 #undef VAR
140 #undef V
141 
142 static int or_state_validate(or_state_t *state, char **msg);
143 
144 static int or_state_validate_cb(void *old_options, void *options,
145  void *default_options,
146  int from_setconf, char **msg);
147 
149 #define OR_STATE_MAGIC 0x57A73f57
150 
154  .name = "__extra",
155  .type = CONFIG_TYPE_LINELIST,
156  .offset = offsetof(or_state_t, ExtraLines),
157 };
158 
161  sizeof(or_state_t),
162  {
163  "or_state_t",
165  offsetof(or_state_t, magic_),
166  },
168  NULL,
169  state_vars_,
170  or_state_validate_cb,
171  NULL,
173  offsetof(or_state_t, substates_),
174 };
175 
176 /* A global configuration manager for state-file objects */
177 static config_mgr_t *state_mgr = NULL;
178 
180 static const config_mgr_t *
182 {
183  if (PREDICT_UNLIKELY(state_mgr == NULL)) {
184  state_mgr = config_mgr_new(&state_format);
185  config_mgr_freeze(state_mgr);
186  }
187  return state_mgr;
188 }
189 
191 static or_state_t *global_state = NULL;
192 
195 get_or_state, (void))
196 {
198  return global_state;
199 }
200 
202 int
204 {
205  return global_state != NULL;
206 }
207 
210 static int
212 {
213  smartlist_t *items = NULL;
214  char *addrport=NULL;
215  tor_addr_t addr;
216  uint16_t port = 0;
217  int r;
218 
219  items = smartlist_new();
220  smartlist_split_string(items, line, NULL,
221  SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
222 
223  if (smartlist_len(items) != 2) {
224  log_warn(LD_CONFIG, "state: Not enough arguments in TransportProxy line.");
225  goto err;
226  }
227 
228  addrport = smartlist_get(items, 1);
229  if (tor_addr_port_lookup(addrport, &addr, &port) < 0) {
230  log_warn(LD_CONFIG, "state: Could not parse addrport.");
231  goto err;
232  }
233 
234  if (!port) {
235  log_warn(LD_CONFIG, "state: Transport line did not contain port.");
236  goto err;
237  }
238 
239  r = 1;
240  goto done;
241 
242  err:
243  r = 0;
244 
245  done:
246  SMARTLIST_FOREACH(items, char*, s, tor_free(s));
247  smartlist_free(items);
248  return r;
249 }
250 
253 static int
255 {
256  int broken = 0;
257  config_line_t *line;
258 
259  for (line = state->TransportProxies ; line ; line = line->next) {
260  tor_assert(!strcmp(line->key, "TransportProxy"));
261  if (!state_transport_line_is_valid(line->value))
262  broken = 1;
263  }
264 
265  if (broken)
266  log_warn(LD_CONFIG, "state: State file seems to be broken.");
267 
268  return 0;
269 }
270 
271 static int
272 or_state_validate_cb(void *old_state, void *state, void *default_state,
273  int from_setconf, char **msg)
274 {
275  /* We don't use these; only options do. Still, we need to match that
276  * signature. */
277  (void) from_setconf;
278  (void) default_state;
279  (void) old_state;
280 
281  return or_state_validate(state, msg);
282 }
283 
289 static int
290 or_state_validate(or_state_t *state, char **msg)
291 {
292  if (entry_guards_parse_state(state, 0, msg)<0)
293  return -1;
294 
295  if (validate_transports_in_state(state)<0)
296  return -1;
297 
298  return 0;
299 }
300 
302 static int
304 {
305  char *err = NULL;
306  int ret = 0;
307  tor_assert(new_state);
308  config_free(get_state_mgr(), global_state);
309  global_state = new_state;
310  if (entry_guards_parse_state(global_state, 1, &err)<0) {
311  log_warn(LD_GENERAL,"%s",err);
312  tor_free(err);
313  ret = -1;
314  }
315  if (rep_hist_load_state(global_state, &err)<0) {
316  log_warn(LD_GENERAL,"Unparseable bandwidth history state: %s",err);
317  tor_free(err);
318  ret = -1;
319  }
322  ret = -1;
323  }
324  netstatus_load_from_state(global_state, time(NULL));
325 
326  return ret;
327 }
328 
332 static void
334 {
335  int i, res;
336  file_status_t status;
337  char *fname2 = NULL;
338  for (i = 0; i < 100; ++i) {
339  tor_asprintf(&fname2, "%s.%d", fname, i);
340  status = file_status(fname2);
341  if (status == FN_NOENT)
342  break;
343  tor_free(fname2);
344  }
345  if (i == 100) {
346  log_warn(LD_BUG, "Unable to parse state in \"%s\"; too many saved bad "
347  "state files to move aside. Discarding the old state file.",
348  fname);
349  res = unlink(fname);
350  if (res != 0) {
351  log_warn(LD_FS,
352  "Also couldn't discard old state file \"%s\" because "
353  "unlink() failed: %s",
354  fname, strerror(errno));
355  }
356  } else {
357  log_warn(LD_BUG, "Unable to parse state in \"%s\". Moving it aside "
358  "to \"%s\". This could be a bug in Tor; please tell "
359  "the developers.", fname, fname2);
360  if (tor_rename(fname, fname2) < 0) {//XXXX sandbox prohibits
361  log_warn(LD_BUG, "Weirdly, I couldn't even move the state aside. The "
362  "OS gave an error of %s", strerror(errno));
363  }
364  }
365  tor_free(fname2);
366 }
367 
368 STATIC or_state_t *
369 or_state_new(void)
370 {
371  or_state_t *new_state = config_new(get_state_mgr());
372  config_init(get_state_mgr(), new_state);
373 
374  return new_state;
375 }
376 
380 int
382 {
383  or_state_t *new_state = NULL;
384  char *contents = NULL, *fname;
385  char *errmsg = NULL;
386  int r = -1, badstate = 0;
387 
388  fname = get_datadir_fname("state");
389  switch (file_status(fname)) {
390  case FN_FILE:
391  if (!(contents = read_file_to_str(fname, 0, NULL))) {
392  log_warn(LD_FS, "Unable to read state file \"%s\"", fname);
393  goto done;
394  }
395  break;
396  /* treat empty state files as if the file doesn't exist, and generate
397  * a new state file, overwriting the empty file in or_state_save() */
398  case FN_NOENT:
399  case FN_EMPTY:
400  break;
401  case FN_ERROR:
402  case FN_DIR:
403  default:
404  log_warn(LD_GENERAL,"State file \"%s\" is not a file? Failing.", fname);
405  goto done;
406  }
407  new_state = or_state_new();
408  if (contents) {
409  config_line_t *lines=NULL;
410  int assign_retval;
411  if (config_get_lines(contents, &lines, 0)<0)
412  goto done;
413  assign_retval = config_assign(get_state_mgr(), new_state,
414  lines, 0, &errmsg);
415  config_free_lines(lines);
416  if (assign_retval<0)
417  badstate = 1;
418  if (errmsg) {
419  log_warn(LD_GENERAL, "%s", errmsg);
420  tor_free(errmsg);
421  }
422  }
423 
424  if (!badstate && or_state_validate(new_state, &errmsg) < 0)
425  badstate = 1;
426 
427  if (errmsg) {
428  log_warn(LD_GENERAL, "%s", errmsg);
429  tor_free(errmsg);
430  }
431 
432  if (badstate && !contents) {
433  log_warn(LD_BUG, "Uh oh. We couldn't even validate our own default state."
434  " This is a bug in Tor.");
435  goto done;
436  } else if (badstate && contents) {
437  or_state_save_broken(fname);
438 
439  tor_free(contents);
440  config_free(get_state_mgr(), new_state);
441 
442  new_state = or_state_new();
443  } else if (contents) {
444  log_info(LD_GENERAL, "Loaded state from \"%s\"", fname);
445  /* Warn the user if their clock has been set backwards,
446  * they could be tricked into using old consensuses */
447  time_t apparent_skew = time(NULL) - new_state->LastWritten;
448  if (apparent_skew < 0) {
449  /* Initialize bootstrap event reporting because we might call
450  * clock_skew_warning() before the bootstrap state is
451  * initialized, causing an assertion failure. */
452  control_event_bootstrap(BOOTSTRAP_STATUS_STARTING, 0);
453  clock_skew_warning(NULL, (long)apparent_skew, 1, LD_GENERAL,
454  "local state file", fname);
455  }
456  } else {
457  log_info(LD_GENERAL, "Initialized state");
458  }
459  if (or_state_set(new_state) == -1) {
460  or_state_save_broken(fname);
461  }
462  new_state = NULL;
463  if (!contents) {
465  or_state_save(time(NULL));
466  }
467  r = 0;
468 
469  done:
470  tor_free(fname);
471  tor_free(contents);
472  if (new_state)
473  config_free(get_state_mgr(), new_state);
474 
475  return r;
476 }
477 
482 
484 int
486 {
488 }
489 
491 #define STATE_WRITE_RETRY_INTERVAL 3600
492 
496 #define STATE_RELAY_CHECKPOINT_INTERVAL (12*60*60)
497 
499 int
500 or_state_save(time_t now)
501 {
502  char *state, *contents;
503  char tbuf[ISO_TIME_LEN+1];
504  char *fname;
505 
507 
508  if (global_state->next_write > now)
509  return 0;
510 
511  /* Call everything else that might dirty the state even more, in order
512  * to avoid redundant writes. */
516  netstatus_flush_to_state(global_state, now);
517 
518  if (accounting_is_enabled(get_options()))
520 
521  global_state->LastWritten = now;
522 
524  tor_asprintf(&global_state->TorVersion, "Tor %s", get_version());
525 
526  state = config_dump(get_state_mgr(), NULL, global_state, 1, 0);
527  format_local_iso_time(tbuf, now);
528  tor_asprintf(&contents,
529  "# Tor state file last generated on %s local time\n"
530  "# Other times below are in UTC\n"
531  "# You *do not* need to edit this file.\n\n%s",
532  tbuf, state);
533  tor_free(state);
534  fname = get_datadir_fname("state");
535  if (write_str_to_file(fname, contents, 0)<0) {
536  log_warn(LD_FS, "Unable to write state to file \"%s\"; "
537  "will try again later", fname);
539  tor_free(fname);
540  tor_free(contents);
541  /* Try again after STATE_WRITE_RETRY_INTERVAL (or sooner, if the state
542  * changes sooner). */
544  return -1;
545  }
546 
548  log_info(LD_GENERAL, "Saved state to \"%s\"", fname);
549  tor_free(fname);
550  tor_free(contents);
551 
552  if (server_mode(get_options()))
554  else
555  global_state->next_write = TIME_MAX;
556 
557  return 0;
558 }
559 
562 STATIC config_line_t *
563 get_transport_in_state_by_name(const char *transport)
564 {
565  or_state_t *or_state = get_or_state();
566  config_line_t *line;
567  config_line_t *ret = NULL;
568  smartlist_t *items = NULL;
569 
570  for (line = or_state->TransportProxies ; line ; line = line->next) {
571  tor_assert(!strcmp(line->key, "TransportProxy"));
572 
573  items = smartlist_new();
574  smartlist_split_string(items, line->value, NULL,
575  SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
576  if (smartlist_len(items) != 2) /* broken state */
577  goto done;
578 
579  if (!strcmp(smartlist_get(items, 0), transport)) {
580  ret = line;
581  goto done;
582  }
583 
584  SMARTLIST_FOREACH(items, char*, s, tor_free(s));
585  smartlist_free(items);
586  items = NULL;
587  }
588 
589  done:
590  if (items) {
591  SMARTLIST_FOREACH(items, char*, s, tor_free(s));
592  smartlist_free(items);
593  }
594  return ret;
595 }
596 
600 static const char *
601 get_transport_bindaddr(const char *line, const char *transport)
602 {
603  char *line_tmp = NULL;
604 
605  if (strlen(line) < strlen(transport) + 2) {
606  goto broken_state;
607  } else {
608  /* line should start with the name of the transport and a space.
609  (for example, "obfs2 127.0.0.1:47245") */
610  tor_asprintf(&line_tmp, "%s ", transport);
611  if (strcmpstart(line, line_tmp))
612  goto broken_state;
613 
614  tor_free(line_tmp);
615  return (line+strlen(transport)+1);
616  }
617 
618  broken_state:
619  tor_free(line_tmp);
620  return NULL;
621 }
622 
626 char *
628 {
629  char *default_addrport = NULL;
630  const char *stored_bindaddr = NULL;
631  config_line_t *line = NULL;
632 
633  {
634  /* See if the user explicitly asked for a specific listening
635  address for this transport. */
636  char *conf_bindaddr = get_transport_bindaddr_from_config(transport);
637  if (conf_bindaddr)
638  return conf_bindaddr;
639  }
640 
641  line = get_transport_in_state_by_name(transport);
642  if (!line) /* Found no references in state for this transport. */
643  goto no_bindaddr_found;
644 
645  stored_bindaddr = get_transport_bindaddr(line->value, transport);
646  if (stored_bindaddr) /* found stored bindaddr in state file. */
647  return tor_strdup(stored_bindaddr);
648 
649  no_bindaddr_found:
653  tor_asprintf(&default_addrport, "%s:%s", fmt_addr32(INADDR_ANY), "0");
654  return default_addrport;
655 }
656 
659 void
660 save_transport_to_state(const char *transport,
661  const tor_addr_t *addr, uint16_t port)
662 {
663  or_state_t *state = get_or_state();
664 
665  char *transport_addrport=NULL;
666 
668  config_line_t **next, *line;
669 
670  /* see if this transport is already stored in state */
671  config_line_t *transport_line =
673 
674  if (transport_line) { /* if transport already exists in state... */
675  const char *prev_bindaddr = /* get its addrport... */
676  get_transport_bindaddr(transport_line->value, transport);
677  transport_addrport = tor_strdup(fmt_addrport(addr, port));
678 
679  /* if transport in state has the same address as this one, life is good */
680  if (!strcmp(prev_bindaddr, transport_addrport)) {
681  log_info(LD_CONFIG, "Transport seems to have spawned on its usual "
682  "address:port.");
683  goto done;
684  } else { /* if addrport in state is different than the one we got */
685  log_info(LD_CONFIG, "Transport seems to have spawned on different "
686  "address:port. Let's update the state file with the new "
687  "address:port");
688  tor_free(transport_line->value); /* free the old line */
689  /* replace old addrport line with new line */
690  tor_asprintf(&transport_line->value, "%s %s", transport,
691  fmt_addrport(addr, port));
692  }
693  } else { /* never seen this one before; save it in state for next time */
694  log_info(LD_CONFIG, "It's the first time we see this transport. "
695  "Let's save its address:port");
696  next = &state->TransportProxies;
697  /* find the last TransportProxy line in the state and point 'next'
698  right after it */
699  line = state->TransportProxies;
700  while (line) {
701  next = &(line->next);
702  line = line->next;
703  }
704 
705  /* allocate space for the new line and fill it in */
706  *next = line = tor_malloc_zero(sizeof(config_line_t));
707  line->key = tor_strdup("TransportProxy");
708  tor_asprintf(&line->value, "%s %s", transport, fmt_addrport(addr, port));
709  }
710 
711  if (!get_options()->AvoidDiskWrites)
712  or_state_mark_dirty(state, 0);
713 
714  done:
715  tor_free(transport_addrport);
716 }
717 
721 void
722 or_state_mark_dirty(or_state_t *state, time_t when)
723 {
724  if (state->next_write > when) {
725  state->next_write = when;
727  }
728 }
729 
730 STATIC void
731 or_state_free_(or_state_t *state)
732 {
733  if (!state)
734  return;
735 
736  config_free(get_state_mgr(), state);
737 }
738 
739 void
740 or_state_free_all(void)
741 {
742  or_state_free(global_state);
743  global_state = NULL;
744  config_mgr_free(state_mgr);
745 }
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:563
Header for confline.c.
Header file for circuitbuild.c.
void config_mgr_freeze(config_mgr_t *mgr)
Definition: confparse.c:280
void config_init(const config_mgr_t *mgr, void *options)
Definition: confparse.c:1134
void format_local_iso_time(char *buf, time_t t)
Definition: time_fmt.c:285
int or_state_loaded(void)
Definition: statefile.c:203
Header file for connection.c.
static config_abbrev_t state_abbrevs_[]
Definition: statefile.c:58
#define LD_GENERAL
Definition: log.h:60
void reschedule_or_state_save(void)
Definition: mainloop.c:1886
Header file for config.c.
config_mgr_t * config_mgr_new(const config_format_t *toplevel_fmt)
Definition: confparse.c:145
static const config_var_t state_vars_[]
Definition: statefile.c:79
#define STATE_WRITE_RETRY_INTERVAL
Definition: statefile.c:491
static or_state_t * global_state
Definition: statefile.c:191
#define END_OF_CONFIG_VARS
Definition: confmacros.h:21
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
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:160
int tor_addr_port_lookup(const char *s, tor_addr_t *addr_out, uint16_t *port_out)
Definition: resolve.c:255
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:381
#define OR_STATE_MAGIC
Definition: statefile.c:149
void save_transport_to_state(const char *transport, const tor_addr_t *addr, uint16_t port)
Definition: statefile.c:660
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:290
void rep_hist_update_state(or_state_t *state)
Definition: rephist.c:1398
time_t LastWritten
Definition: or_state_st.h:29
tor_assert(buffer)
char * get_transport_bindaddr_from_config(const char *transport)
Definition: config.c:6282
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:481
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:601
char * get_stored_bindaddr_for_server_transport(const char *transport)
Definition: statefile.c:627
DUMMY_TYPECHECK_INSTANCE(or_state_t)
Header file for rephist.c.
const char * fmt_addr32(uint32_t addr)
Definition: address.c:1181
static const config_mgr_t * get_state_mgr(void)
Definition: statefile.c:181
char * config_dump(const config_mgr_t *mgr, const void *default_options, const void *options, int minimal, int comment_defaults)
Definition: confparse.c:1150
const char * name
Definition: conftypes.h:87
void * config_new(const config_mgr_t *mgr)
Definition: confparse.c:371
#define LD_FS
Definition: log.h:68
int rep_hist_load_state(or_state_t *state, char **err)
Definition: rephist.c:1498
time_t next_write
Definition: or_state_st.h:26
static int or_state_set(or_state_t *new_state)
Definition: statefile.c:303
static int validate_transports_in_state(or_state_t *state)
Definition: statefile.c:254
#define SMARTLIST_FOREACH(sl, type, var, cmd)
int config_assign(const config_mgr_t *mgr, void *options, config_line_t *list, unsigned config_assign_flags, char **msg)
Definition: confparse.c:913
Header file for router.c.
#define STATE_RELAY_CHECKPOINT_INTERVAL
Definition: statefile.c:496
file_status_t
Definition: files.h:55
int did_last_state_file_write_fail(void)
Definition: statefile.c:485
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:333
static struct_member_t state_extra_var
Definition: statefile.c:153
void or_state_mark_dirty(or_state_t *state, time_t when)
Definition: statefile.c:722
int or_state_save(time_t now)
Definition: statefile.c:500
MOCK_IMPL(or_state_t *, get_or_state,(void))
Definition: statefile.c:194
#define VAR(varname, conftype, member, initvalue)
Definition: config.c:261
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:83
file_status_t file_status(const char *filename)
Definition: files.c:212
#define LD_BUG
Definition: log.h:84
#define LD_CONFIG
Definition: log.h:66
Header for confparse.c.
static int state_transport_line_is_valid(const char *line)
Definition: statefile.c:211
int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep, int flags, int max)