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);
const char * fmt_addrport(const tor_addr_t *addr, uint16_t port)
const char * fmt_addr32(uint32_t addr)
void bwhist_update_state(or_state_t *state)
int bwhist_load_state(or_state_t *state, char **err)
Header for feature/stats/bwhist.c.
int circuit_build_times_parse_state(circuit_build_times_t *cbt, or_state_t *state)
const circuit_build_times_t * get_circuit_build_times(void)
void circuit_build_times_update_state(const circuit_build_times_t *cbt, or_state_t *state)
circuit_build_times_t * get_circuit_build_times_mutable(void)
Header file for circuitstats.c.
const or_options_t * get_options(void)
#define VAR(varname, conftype, member, initvalue)
Header file for config.c.
int config_get_lines(const char *string, config_line_t **result, int extended)
#define END_OF_CONFIG_VARS
void config_init(const config_mgr_t *mgr, void *options)
void config_mgr_freeze(config_mgr_t *mgr)
char * config_dump(const config_mgr_t *mgr, const void *default_options, const void *options, int minimal, int comment_defaults)
void * config_new(const config_mgr_t *mgr)
config_mgr_t * config_mgr_new(const config_format_t *toplevel_fmt)
validation_status_t config_validate(const config_mgr_t *mgr, const void *old_options, void *options, char **msg_out)
int config_assign(const config_mgr_t *mgr, void *options, config_line_t *list, unsigned config_assign_flags, char **msg)
void clock_skew_warning(const connection_t *conn, long apparent_skew, int trusted, log_domain_mask_t domain, const char *received, const char *source)
Header file for connection.c.
void control_event_bootstrap(bootstrap_status_t status, int progress)
Header file for control_events.c.
void entry_guards_update_state(or_state_t *state)
int entry_guards_parse_state(or_state_t *state, int set, char **msg)
Header file for circuitbuild.c.
int write_str_to_file(const char *fname, const char *str, int bin)
file_status_t file_status(const char *filename)
int tor_rename(const char *path_old, const char *path_new)
int accounting_is_enabled(const or_options_t *options)
void accounting_run_housekeeping(time_t now)
Header file for hibernate.c.
void reschedule_or_state_save(void)
Header file for mainloop.c.
void * strmap_get_lc(const strmap_t *map, const char *key)
void * strmap_set_lc(strmap_t *map, const char *key, void *val)
Master header file for Tor-specific functionality.
The or_state_t structure, which represents Tor's state file.
int tor_asprintf(char **strp, const char *fmt,...)
int tor_addr_port_lookup(const char *s, tor_addr_t *addr_out, uint16_t *port_out)
Header file for router.c.
int server_mode(const or_options_t *options)
Header file for routermode.c.
Header file for sandbox.c.
smartlist_t * smartlist_new(void)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep, int flags, int max)
#define STATE_WRITE_RETRY_INTERVAL
int or_state_loaded(void)
STATIC const config_mgr_t * get_state_mgr(void)
static const config_format_t state_format
void save_transport_to_state(const char *transport, const tor_addr_t *addr, uint16_t port)
or_state_t * get_or_state(void)
void or_state_mark_dirty(or_state_t *state, time_t when)
STATIC void or_state_remove_obsolete_lines(config_line_t **extra_lines)
static const char * obsolete_state_keys[]
STATIC config_line_t * get_transport_in_state_by_name(const char *transport)
static int last_state_file_write_failed
static const config_var_t state_vars_[]
char * get_stored_bindaddr_for_server_transport(const char *transport)
static const char * get_transport_bindaddr(const char *line, const char *transport)
int did_last_state_file_write_fail(void)
static struct_member_t state_extra_var
static config_abbrev_t state_abbrevs_[]
static void or_state_save_broken(char *fname)
#define STATE_RELAY_CHECKPOINT_INTERVAL
static int validate_transports_in_state(or_state_t *state)
int or_state_save(time_t now)
static int state_transport_line_is_valid(const char *line)
static int or_state_set(or_state_t *new_state)
DUMMY_TYPECHECK_INSTANCE(or_state_t)
static int or_state_validate_cb(const void *old_options, void *options, char **msg)
static or_state_t * global_state
static int or_state_validate(or_state_t *state, char **msg)
struct config_line_t * ExtraLines
int subsystems_register_state_formats(config_mgr_t *mgr)
int subsystems_set_state(const config_mgr_t *mgr, struct or_state_t *state)
int subsystems_flush_state(const config_mgr_t *mgr, struct or_state_t *state)
#define MOCK_IMPL(rv, funcname, arglist)
void format_local_iso_time(char *buf, time_t t)
const char * get_version(void)
char * pt_get_bindaddr_from_config(const char *transport)
Header for feature/relay/transport_config.c.
int strcmpstart(const char *s1, const char *s2)