statefile.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  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-2015, The Tor Project, Inc. */
  5. /* See LICENSE for licensing information */
  6. /**
  7. * \file statefile.c
  8. *
  9. * \brief Handles parsing and encoding the persistent 'state' file that carries
  10. * miscellaneous persistent state between Tor invocations.
  11. */
  12. #define STATEFILE_PRIVATE
  13. #include "or.h"
  14. #include "circuitstats.h"
  15. #include "config.h"
  16. #include "confparse.h"
  17. #include "connection.h"
  18. #include "entrynodes.h"
  19. #include "hibernate.h"
  20. #include "rephist.h"
  21. #include "router.h"
  22. #include "sandbox.h"
  23. #include "statefile.h"
  24. /** A list of state-file "abbreviations," for compatibility. */
  25. static config_abbrev_t state_abbrevs_[] = {
  26. { "AccountingBytesReadInterval", "AccountingBytesReadInInterval", 0, 0 },
  27. { "HelperNode", "EntryGuard", 0, 0 },
  28. { "HelperNodeDownSince", "EntryGuardDownSince", 0, 0 },
  29. { "HelperNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
  30. { "EntryNode", "EntryGuard", 0, 0 },
  31. { "EntryNodeDownSince", "EntryGuardDownSince", 0, 0 },
  32. { "EntryNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
  33. { NULL, NULL, 0, 0},
  34. };
  35. /*XXXX these next two are duplicates or near-duplicates from config.c */
  36. #define VAR(name,conftype,member,initvalue) \
  37. { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_state_t, member), \
  38. initvalue }
  39. /** As VAR, but the option name and member name are the same. */
  40. #define V(member,conftype,initvalue) \
  41. VAR(#member, conftype, member, initvalue)
  42. /** Array of "state" variables saved to the ~/.tor/state file. */
  43. static config_var_t state_vars_[] = {
  44. /* Remember to document these in state-contents.txt ! */
  45. V(AccountingBytesReadInInterval, MEMUNIT, NULL),
  46. V(AccountingBytesWrittenInInterval, MEMUNIT, NULL),
  47. V(AccountingExpectedUsage, MEMUNIT, NULL),
  48. V(AccountingIntervalStart, ISOTIME, NULL),
  49. V(AccountingSecondsActive, INTERVAL, NULL),
  50. V(AccountingSecondsToReachSoftLimit,INTERVAL, NULL),
  51. V(AccountingSoftLimitHitAt, ISOTIME, NULL),
  52. V(AccountingBytesAtSoftLimit, MEMUNIT, NULL),
  53. VAR("EntryGuard", LINELIST_S, EntryGuards, NULL),
  54. VAR("EntryGuardDownSince", LINELIST_S, EntryGuards, NULL),
  55. VAR("EntryGuardUnlistedSince", LINELIST_S, EntryGuards, NULL),
  56. VAR("EntryGuardAddedBy", LINELIST_S, EntryGuards, NULL),
  57. VAR("EntryGuardPathBias", LINELIST_S, EntryGuards, NULL),
  58. VAR("EntryGuardPathUseBias", LINELIST_S, EntryGuards, NULL),
  59. V(EntryGuards, LINELIST_V, NULL),
  60. VAR("TransportProxy", LINELIST_S, TransportProxies, NULL),
  61. V(TransportProxies, LINELIST_V, NULL),
  62. V(BWHistoryReadEnds, ISOTIME, NULL),
  63. V(BWHistoryReadInterval, UINT, "900"),
  64. V(BWHistoryReadValues, CSV, ""),
  65. V(BWHistoryReadMaxima, CSV, ""),
  66. V(BWHistoryWriteEnds, ISOTIME, NULL),
  67. V(BWHistoryWriteInterval, UINT, "900"),
  68. V(BWHistoryWriteValues, CSV, ""),
  69. V(BWHistoryWriteMaxima, CSV, ""),
  70. V(BWHistoryDirReadEnds, ISOTIME, NULL),
  71. V(BWHistoryDirReadInterval, UINT, "900"),
  72. V(BWHistoryDirReadValues, CSV, ""),
  73. V(BWHistoryDirReadMaxima, CSV, ""),
  74. V(BWHistoryDirWriteEnds, ISOTIME, NULL),
  75. V(BWHistoryDirWriteInterval, UINT, "900"),
  76. V(BWHistoryDirWriteValues, CSV, ""),
  77. V(BWHistoryDirWriteMaxima, CSV, ""),
  78. V(TorVersion, STRING, NULL),
  79. V(LastRotatedOnionKey, ISOTIME, NULL),
  80. V(LastWritten, ISOTIME, NULL),
  81. V(TotalBuildTimes, UINT, NULL),
  82. V(CircuitBuildAbandonedCount, UINT, "0"),
  83. VAR("CircuitBuildTimeBin", LINELIST_S, BuildtimeHistogram, NULL),
  84. VAR("BuildtimeHistogram", LINELIST_V, BuildtimeHistogram, NULL),
  85. { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
  86. };
  87. #undef VAR
  88. #undef V
  89. static int or_state_validate(or_state_t *state, char **msg);
  90. static int or_state_validate_cb(void *old_options, void *options,
  91. void *default_options,
  92. int from_setconf, char **msg);
  93. /** Magic value for or_state_t. */
  94. #define OR_STATE_MAGIC 0x57A73f57
  95. /** "Extra" variable in the state that receives lines we can't parse. This
  96. * lets us preserve options from versions of Tor newer than us. */
  97. static config_var_t state_extra_var = {
  98. "__extra", CONFIG_TYPE_LINELIST, STRUCT_OFFSET(or_state_t, ExtraLines), NULL
  99. };
  100. /** Configuration format for or_state_t. */
  101. static const config_format_t state_format = {
  102. sizeof(or_state_t),
  103. OR_STATE_MAGIC,
  104. STRUCT_OFFSET(or_state_t, magic_),
  105. state_abbrevs_,
  106. state_vars_,
  107. or_state_validate_cb,
  108. &state_extra_var,
  109. };
  110. /** Persistent serialized state. */
  111. static or_state_t *global_state = NULL;
  112. /** Return the persistent state struct for this Tor. */
  113. MOCK_IMPL(or_state_t *,
  114. get_or_state, (void))
  115. {
  116. tor_assert(global_state);
  117. return global_state;
  118. }
  119. /** Return true iff we have loaded the global state for this Tor */
  120. int
  121. or_state_loaded(void)
  122. {
  123. return global_state != NULL;
  124. }
  125. /** Return true if <b>line</b> is a valid state TransportProxy line.
  126. * Return false otherwise. */
  127. static int
  128. state_transport_line_is_valid(const char *line)
  129. {
  130. smartlist_t *items = NULL;
  131. char *addrport=NULL;
  132. tor_addr_t addr;
  133. uint16_t port = 0;
  134. int r;
  135. items = smartlist_new();
  136. smartlist_split_string(items, line, NULL,
  137. SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
  138. if (smartlist_len(items) != 2) {
  139. log_warn(LD_CONFIG, "state: Not enough arguments in TransportProxy line.");
  140. goto err;
  141. }
  142. addrport = smartlist_get(items, 1);
  143. if (tor_addr_port_lookup(addrport, &addr, &port) < 0) {
  144. log_warn(LD_CONFIG, "state: Could not parse addrport.");
  145. goto err;
  146. }
  147. if (!port) {
  148. log_warn(LD_CONFIG, "state: Transport line did not contain port.");
  149. goto err;
  150. }
  151. r = 1;
  152. goto done;
  153. err:
  154. r = 0;
  155. done:
  156. SMARTLIST_FOREACH(items, char*, s, tor_free(s));
  157. smartlist_free(items);
  158. return r;
  159. }
  160. /** Return 0 if all TransportProxy lines in <b>state</b> are well
  161. * formed. Otherwise, return -1. */
  162. static int
  163. validate_transports_in_state(or_state_t *state)
  164. {
  165. int broken = 0;
  166. config_line_t *line;
  167. for (line = state->TransportProxies ; line ; line = line->next) {
  168. tor_assert(!strcmp(line->key, "TransportProxy"));
  169. if (!state_transport_line_is_valid(line->value))
  170. broken = 1;
  171. }
  172. if (broken)
  173. log_warn(LD_CONFIG, "state: State file seems to be broken.");
  174. return 0;
  175. }
  176. static int
  177. or_state_validate_cb(void *old_state, void *state, void *default_state,
  178. int from_setconf, char **msg)
  179. {
  180. /* We don't use these; only options do. Still, we need to match that
  181. * signature. */
  182. (void) from_setconf;
  183. (void) default_state;
  184. (void) old_state;
  185. return or_state_validate(state, msg);
  186. }
  187. /** Return 0 if every setting in <b>state</b> is reasonable, and a
  188. * permissible transition from <b>old_state</b>. Else warn and return -1.
  189. * Should have no side effects, except for normalizing the contents of
  190. * <b>state</b>.
  191. */
  192. static int
  193. or_state_validate(or_state_t *state, char **msg)
  194. {
  195. if (entry_guards_parse_state(state, 0, msg)<0)
  196. return -1;
  197. if (validate_transports_in_state(state)<0)
  198. return -1;
  199. return 0;
  200. }
  201. /** Replace the current persistent state with <b>new_state</b> */
  202. static int
  203. or_state_set(or_state_t *new_state)
  204. {
  205. char *err = NULL;
  206. int ret = 0;
  207. tor_assert(new_state);
  208. config_free(&state_format, global_state);
  209. global_state = new_state;
  210. if (entry_guards_parse_state(global_state, 1, &err)<0) {
  211. log_warn(LD_GENERAL,"%s",err);
  212. tor_free(err);
  213. ret = -1;
  214. }
  215. if (rep_hist_load_state(global_state, &err)<0) {
  216. log_warn(LD_GENERAL,"Unparseable bandwidth history state: %s",err);
  217. tor_free(err);
  218. ret = -1;
  219. }
  220. if (circuit_build_times_parse_state(
  221. get_circuit_build_times_mutable(),global_state) < 0) {
  222. ret = -1;
  223. }
  224. return ret;
  225. }
  226. /**
  227. * Save a broken state file to a backup location.
  228. */
  229. static void
  230. or_state_save_broken(char *fname)
  231. {
  232. int i, res;
  233. file_status_t status;
  234. char *fname2 = NULL;
  235. for (i = 0; i < 100; ++i) {
  236. tor_asprintf(&fname2, "%s.%d", fname, i);
  237. status = file_status(fname2);
  238. if (status == FN_NOENT)
  239. break;
  240. tor_free(fname2);
  241. }
  242. if (i == 100) {
  243. log_warn(LD_BUG, "Unable to parse state in \"%s\"; too many saved bad "
  244. "state files to move aside. Discarding the old state file.",
  245. fname);
  246. res = unlink(fname);
  247. if (res != 0) {
  248. log_warn(LD_FS,
  249. "Also couldn't discard old state file \"%s\" because "
  250. "unlink() failed: %s",
  251. fname, strerror(errno));
  252. }
  253. } else {
  254. log_warn(LD_BUG, "Unable to parse state in \"%s\". Moving it aside "
  255. "to \"%s\". This could be a bug in Tor; please tell "
  256. "the developers.", fname, fname2);
  257. if (tor_rename(fname, fname2) < 0) {//XXXX sandbox prohibits
  258. log_warn(LD_BUG, "Weirdly, I couldn't even move the state aside. The "
  259. "OS gave an error of %s", strerror(errno));
  260. }
  261. }
  262. tor_free(fname2);
  263. }
  264. STATIC or_state_t *
  265. or_state_new(void)
  266. {
  267. or_state_t *new_state = tor_malloc_zero(sizeof(or_state_t));
  268. new_state->magic_ = OR_STATE_MAGIC;
  269. config_init(&state_format, new_state);
  270. return new_state;
  271. }
  272. /** Reload the persistent state from disk, generating a new state as needed.
  273. * Return 0 on success, less than 0 on failure.
  274. */
  275. int
  276. or_state_load(void)
  277. {
  278. or_state_t *new_state = NULL;
  279. char *contents = NULL, *fname;
  280. char *errmsg = NULL;
  281. int r = -1, badstate = 0;
  282. fname = get_datadir_fname("state");
  283. switch (file_status(fname)) {
  284. case FN_FILE:
  285. if (!(contents = read_file_to_str(fname, 0, NULL))) {
  286. log_warn(LD_FS, "Unable to read state file \"%s\"", fname);
  287. goto done;
  288. }
  289. break;
  290. /* treat empty state files as if the file doesn't exist, and generate
  291. * a new state file, overwriting the empty file in or_state_save() */
  292. case FN_NOENT:
  293. case FN_EMPTY:
  294. break;
  295. case FN_ERROR:
  296. case FN_DIR:
  297. default:
  298. log_warn(LD_GENERAL,"State file \"%s\" is not a file? Failing.", fname);
  299. goto done;
  300. }
  301. new_state = or_state_new();
  302. if (contents) {
  303. config_line_t *lines=NULL;
  304. int assign_retval;
  305. if (config_get_lines(contents, &lines, 0)<0)
  306. goto done;
  307. assign_retval = config_assign(&state_format, new_state,
  308. lines, 0, 0, &errmsg);
  309. config_free_lines(lines);
  310. if (assign_retval<0)
  311. badstate = 1;
  312. if (errmsg) {
  313. log_warn(LD_GENERAL, "%s", errmsg);
  314. tor_free(errmsg);
  315. }
  316. }
  317. if (!badstate && or_state_validate(new_state, &errmsg) < 0)
  318. badstate = 1;
  319. if (errmsg) {
  320. log_warn(LD_GENERAL, "%s", errmsg);
  321. tor_free(errmsg);
  322. }
  323. if (badstate && !contents) {
  324. log_warn(LD_BUG, "Uh oh. We couldn't even validate our own default state."
  325. " This is a bug in Tor.");
  326. goto done;
  327. } else if (badstate && contents) {
  328. or_state_save_broken(fname);
  329. tor_free(contents);
  330. config_free(&state_format, new_state);
  331. new_state = or_state_new();
  332. } else if (contents) {
  333. log_info(LD_GENERAL, "Loaded state from \"%s\"", fname);
  334. /* Warn the user if their clock has been set backwards,
  335. * they could be tricked into using old consensuses */
  336. time_t apparent_skew = new_state->LastWritten - time(NULL);
  337. if (apparent_skew > 0)
  338. clock_skew_warning(NULL, (long)apparent_skew, 1, LD_GENERAL,
  339. "local state file", fname);
  340. } else {
  341. log_info(LD_GENERAL, "Initialized state");
  342. }
  343. if (or_state_set(new_state) == -1) {
  344. or_state_save_broken(fname);
  345. }
  346. new_state = NULL;
  347. if (!contents) {
  348. global_state->next_write = 0;
  349. or_state_save(time(NULL));
  350. }
  351. r = 0;
  352. done:
  353. tor_free(fname);
  354. tor_free(contents);
  355. if (new_state)
  356. config_free(&state_format, new_state);
  357. return r;
  358. }
  359. /** Did the last time we tried to write the state file fail? If so, we
  360. * should consider disabling such features as preemptive circuit generation
  361. * to compute circuit-build-time. */
  362. static int last_state_file_write_failed = 0;
  363. /** Return whether the state file failed to write last time we tried. */
  364. int
  365. did_last_state_file_write_fail(void)
  366. {
  367. return last_state_file_write_failed;
  368. }
  369. /** If writing the state to disk fails, try again after this many seconds. */
  370. #define STATE_WRITE_RETRY_INTERVAL 3600
  371. /** If we're a relay, how often should we checkpoint our state file even
  372. * if nothing else dirties it? This will checkpoint ongoing stats like
  373. * bandwidth used, per-country user stats, etc. */
  374. #define STATE_RELAY_CHECKPOINT_INTERVAL (12*60*60)
  375. /** Write the persistent state to disk. Return 0 for success, <0 on failure. */
  376. int
  377. or_state_save(time_t now)
  378. {
  379. char *state, *contents;
  380. char tbuf[ISO_TIME_LEN+1];
  381. char *fname;
  382. tor_assert(global_state);
  383. if (global_state->next_write > now)
  384. return 0;
  385. /* Call everything else that might dirty the state even more, in order
  386. * to avoid redundant writes. */
  387. entry_guards_update_state(global_state);
  388. rep_hist_update_state(global_state);
  389. circuit_build_times_update_state(get_circuit_build_times(), global_state);
  390. if (accounting_is_enabled(get_options()))
  391. accounting_run_housekeeping(now);
  392. global_state->LastWritten = now;
  393. tor_free(global_state->TorVersion);
  394. tor_asprintf(&global_state->TorVersion, "Tor %s", get_version());
  395. state = config_dump(&state_format, NULL, global_state, 1, 0);
  396. format_local_iso_time(tbuf, now);
  397. tor_asprintf(&contents,
  398. "# Tor state file last generated on %s local time\n"
  399. "# Other times below are in UTC\n"
  400. "# You *do not* need to edit this file.\n\n%s",
  401. tbuf, state);
  402. tor_free(state);
  403. fname = get_datadir_fname("state");
  404. if (write_str_to_file(fname, contents, 0)<0) {
  405. log_warn(LD_FS, "Unable to write state to file \"%s\"; "
  406. "will try again later", fname);
  407. last_state_file_write_failed = 1;
  408. tor_free(fname);
  409. tor_free(contents);
  410. /* Try again after STATE_WRITE_RETRY_INTERVAL (or sooner, if the state
  411. * changes sooner). */
  412. global_state->next_write = now + STATE_WRITE_RETRY_INTERVAL;
  413. return -1;
  414. }
  415. last_state_file_write_failed = 0;
  416. log_info(LD_GENERAL, "Saved state to \"%s\"", fname);
  417. tor_free(fname);
  418. tor_free(contents);
  419. if (server_mode(get_options()))
  420. global_state->next_write = now + STATE_RELAY_CHECKPOINT_INTERVAL;
  421. else
  422. global_state->next_write = TIME_MAX;
  423. return 0;
  424. }
  425. /** Return the config line for transport <b>transport</b> in the current state.
  426. * Return NULL if there is no config line for <b>transport</b>. */
  427. STATIC config_line_t *
  428. get_transport_in_state_by_name(const char *transport)
  429. {
  430. or_state_t *or_state = get_or_state();
  431. config_line_t *line;
  432. config_line_t *ret = NULL;
  433. smartlist_t *items = NULL;
  434. for (line = or_state->TransportProxies ; line ; line = line->next) {
  435. tor_assert(!strcmp(line->key, "TransportProxy"));
  436. items = smartlist_new();
  437. smartlist_split_string(items, line->value, NULL,
  438. SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
  439. if (smartlist_len(items) != 2) /* broken state */
  440. goto done;
  441. if (!strcmp(smartlist_get(items, 0), transport)) {
  442. ret = line;
  443. goto done;
  444. }
  445. SMARTLIST_FOREACH(items, char*, s, tor_free(s));
  446. smartlist_free(items);
  447. items = NULL;
  448. }
  449. done:
  450. if (items) {
  451. SMARTLIST_FOREACH(items, char*, s, tor_free(s));
  452. smartlist_free(items);
  453. }
  454. return ret;
  455. }
  456. /** Return string containing the address:port part of the
  457. * TransportProxy <b>line</b> for transport <b>transport</b>.
  458. * If the line is corrupted, return NULL. */
  459. static const char *
  460. get_transport_bindaddr(const char *line, const char *transport)
  461. {
  462. char *line_tmp = NULL;
  463. if (strlen(line) < strlen(transport) + 2) {
  464. goto broken_state;
  465. } else {
  466. /* line should start with the name of the transport and a space.
  467. (for example, "obfs2 127.0.0.1:47245") */
  468. tor_asprintf(&line_tmp, "%s ", transport);
  469. if (strcmpstart(line, line_tmp))
  470. goto broken_state;
  471. tor_free(line_tmp);
  472. return (line+strlen(transport)+1);
  473. }
  474. broken_state:
  475. tor_free(line_tmp);
  476. return NULL;
  477. }
  478. /** Return a string containing the address:port that a proxy transport
  479. * should bind on. The string is stored on the heap and must be freed
  480. * by the caller of this function. */
  481. char *
  482. get_stored_bindaddr_for_server_transport(const char *transport)
  483. {
  484. char *default_addrport = NULL;
  485. const char *stored_bindaddr = NULL;
  486. config_line_t *line = NULL;
  487. {
  488. /* See if the user explicitly asked for a specific listening
  489. address for this transport. */
  490. char *conf_bindaddr = get_transport_bindaddr_from_config(transport);
  491. if (conf_bindaddr)
  492. return conf_bindaddr;
  493. }
  494. line = get_transport_in_state_by_name(transport);
  495. if (!line) /* Found no references in state for this transport. */
  496. goto no_bindaddr_found;
  497. stored_bindaddr = get_transport_bindaddr(line->value, transport);
  498. if (stored_bindaddr) /* found stored bindaddr in state file. */
  499. return tor_strdup(stored_bindaddr);
  500. no_bindaddr_found:
  501. /** If we didn't find references for this pluggable transport in the
  502. state file, we should instruct the pluggable transport proxy to
  503. listen on INADDR_ANY on a random ephemeral port. */
  504. tor_asprintf(&default_addrport, "%s:%s", fmt_addr32(INADDR_ANY), "0");
  505. return default_addrport;
  506. }
  507. /** Save <b>transport</b> listening on <b>addr</b>:<b>port</b> to
  508. state */
  509. void
  510. save_transport_to_state(const char *transport,
  511. const tor_addr_t *addr, uint16_t port)
  512. {
  513. or_state_t *state = get_or_state();
  514. char *transport_addrport=NULL;
  515. /** find where to write on the state */
  516. config_line_t **next, *line;
  517. /* see if this transport is already stored in state */
  518. config_line_t *transport_line =
  519. get_transport_in_state_by_name(transport);
  520. if (transport_line) { /* if transport already exists in state... */
  521. const char *prev_bindaddr = /* get its addrport... */
  522. get_transport_bindaddr(transport_line->value, transport);
  523. transport_addrport = tor_strdup(fmt_addrport(addr, port));
  524. /* if transport in state has the same address as this one, life is good */
  525. if (!strcmp(prev_bindaddr, transport_addrport)) {
  526. log_info(LD_CONFIG, "Transport seems to have spawned on its usual "
  527. "address:port.");
  528. goto done;
  529. } else { /* if addrport in state is different than the one we got */
  530. log_info(LD_CONFIG, "Transport seems to have spawned on different "
  531. "address:port. Let's update the state file with the new "
  532. "address:port");
  533. tor_free(transport_line->value); /* free the old line */
  534. /* replace old addrport line with new line */
  535. tor_asprintf(&transport_line->value, "%s %s", transport,
  536. fmt_addrport(addr, port));
  537. }
  538. } else { /* never seen this one before; save it in state for next time */
  539. log_info(LD_CONFIG, "It's the first time we see this transport. "
  540. "Let's save its address:port");
  541. next = &state->TransportProxies;
  542. /* find the last TransportProxy line in the state and point 'next'
  543. right after it */
  544. line = state->TransportProxies;
  545. while (line) {
  546. next = &(line->next);
  547. line = line->next;
  548. }
  549. /* allocate space for the new line and fill it in */
  550. *next = line = tor_malloc_zero(sizeof(config_line_t));
  551. line->key = tor_strdup("TransportProxy");
  552. tor_asprintf(&line->value, "%s %s", transport, fmt_addrport(addr, port));
  553. next = &(line->next);
  554. }
  555. if (!get_options()->AvoidDiskWrites)
  556. or_state_mark_dirty(state, 0);
  557. done:
  558. tor_free(transport_addrport);
  559. }
  560. STATIC void
  561. or_state_free(or_state_t *state)
  562. {
  563. if (!state)
  564. return;
  565. config_free(&state_format, state);
  566. }
  567. void
  568. or_state_free_all(void)
  569. {
  570. or_state_free(global_state);
  571. global_state = NULL;
  572. }