31 #define STATEFILE_PRIVATE
72 "AccountingBytesReadInterval",
74 "HelperNodeDownSince",
75 "HelperNodeUnlistedSince",
77 "HelperNodeDownSince",
78 "EntryNodeUnlistedSince",
81 "EntryGuardDownSince",
82 "EntryGuardUnlistedSince",
85 "EntryGuardPathUseBias",
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)
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),
116 VAR(
"TransportProxy", LINELIST_S, TransportProxies, NULL),
117 V(TransportProxies, LINELIST_V, NULL),
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,
""),
144 V(Guard, LINELIST, NULL),
146 V(TorVersion, STRING, NULL),
148 V(LastRotatedOnionKey, ISOTIME, NULL),
149 V(LastWritten, ISOTIME, NULL),
151 V(TotalBuildTimes, POSINT, NULL),
152 V(CircuitBuildAbandonedCount, POSINT,
"0"),
153 VAR(
"CircuitBuildTimeBin", LINELIST_S, BuildtimeHistogram, NULL),
154 VAR(
"BuildtimeHistogram", LINELIST_V, BuildtimeHistogram, NULL),
166 void *options,
char **msg);
169 #define OR_STATE_MAGIC 0x57A73f57
191 .has_config_suite =
true,
192 .config_suite_offset = offsetof(
or_state_t, substates_),
202 if (PREDICT_UNLIKELY(state_mgr == NULL)) {
211 #define CHECK_STATE_MAGIC(s) STMT_BEGIN \
212 config_check_toplevel_magic(get_state_mgr(), (s)); \
246 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
248 if (smartlist_len(items) != 2) {
249 log_warn(
LD_CONFIG,
"state: Not enough arguments in TransportProxy line.");
253 addrport = smartlist_get(items, 1);
255 log_warn(
LD_CONFIG,
"state: Could not parse addrport.");
260 log_warn(
LD_CONFIG,
"state: Transport line did not contain port.");
272 smartlist_free(items);
284 for (line = state->TransportProxies ; line ; line = line->next) {
285 tor_assert(!strcmp(line->key,
"TransportProxy"));
291 log_warn(
LD_CONFIG,
"state: State file seems to be broken.");
317 CHECK_STATE_MAGIC(state_);
348 log_warn(
LD_GENERAL,
"Unparseable bandwidth history state: %s",err);
369 for (i = 0; i < 100; ++i) {
372 if (status == FN_NOENT)
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.",
383 "Also couldn't discard old state file \"%s\" because "
384 "unlink() failed: %s",
385 fname, strerror(errno));
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);
392 log_warn(
LD_BUG,
"Weirdly, I couldn't even move the state aside. The "
393 "OS gave an error of %s", strerror(errno));
415 char *contents = NULL, *fname;
417 int r = -1, badstate = 0;
419 fname = get_datadir_fname(
"state");
422 if (!(contents = read_file_to_str(fname, 0, NULL))) {
423 log_warn(
LD_FS,
"Unable to read state file \"%s\"", fname);
435 log_warn(
LD_GENERAL,
"State file \"%s\" is not a file? Failing.", fname);
438 new_state = or_state_new();
446 config_free_lines(lines);
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.");
467 }
else if (badstate && contents) {
473 new_state = or_state_new();
474 }
else if (contents) {
475 log_info(
LD_GENERAL,
"Loaded state from \"%s\"", fname);
478 time_t apparent_skew = time(NULL) - new_state->
LastWritten;
479 if (apparent_skew < 0) {
485 "local state file", fname);
517 strmap_t *bad_keys = strmap_new();
527 *line = (*line)->next;
530 config_free_lines(victim);
533 line = &(*line)->next;
537 strmap_free(bad_keys, NULL);
553 #define STATE_WRITE_RETRY_INTERVAL 3600
558 #define STATE_RELAY_CHECKPOINT_INTERVAL (12*60*60)
564 char *state, *contents;
565 char tbuf[ISO_TIME_LEN+1];
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",
596 fname = get_datadir_fname(
"state");
598 log_warn(
LD_FS,
"Unable to write state to file \"%s\"; "
599 "will try again later", fname);
610 log_info(
LD_GENERAL,
"Saved state to \"%s\"", fname);
632 for (line = or_state->TransportProxies ; line ; line = line->next) {
633 tor_assert(!strcmp(line->key,
"TransportProxy"));
637 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
638 if (smartlist_len(items) != 2)
641 if (!strcmp(smartlist_get(items, 0), transport)) {
647 smartlist_free(items);
654 smartlist_free(items);
665 char *line_tmp = NULL;
667 if (strlen(line) < strlen(transport) + 2) {
677 return (line+strlen(transport)+1);
691 char *default_addrport = NULL;
692 const char *stored_bindaddr = NULL;
700 return conf_bindaddr;
705 goto no_bindaddr_found;
709 return tor_strdup(stored_bindaddr);
716 return default_addrport;
727 char *transport_addrport=NULL;
736 if (transport_line) {
737 const char *prev_bindaddr =
739 transport_addrport = tor_strdup(
fmt_addrport(addr, port));
742 if (!strcmp(prev_bindaddr, transport_addrport)) {
743 log_info(
LD_CONFIG,
"Transport seems to have spawned on its usual "
747 log_info(
LD_CONFIG,
"Transport seems to have spawned on different "
748 "address:port. Let's update the state file with the new "
752 tor_asprintf(&transport_line->value,
"%s %s", transport,
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;
761 line = state->TransportProxies;
763 next = &(line->next);
769 line->key = tor_strdup(
"TransportProxy");
802 or_state_free_all(
void)
806 config_mgr_free(state_mgr);