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