Tor 0.4.9.0-alpha-dev
hibernate.c
Go to the documentation of this file.
1/* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
2 * Copyright (c) 2007-2021, The Tor Project, Inc. */
3/* See LICENSE for licensing information */
4
5/**
6 * \file hibernate.c
7 * \brief Functions to close listeners, stop allowing new circuits,
8 * etc in preparation for closing down or going dormant; and to track
9 * bandwidth and time intervals to know when to hibernate and when to
10 * stop hibernating.
11 *
12 * Ordinarily a Tor relay is "Live".
13 *
14 * A live relay can stop accepting connections for one of two reasons: either
15 * it is trying to conserve bandwidth because of bandwidth accounting rules
16 * ("soft hibernation"), or it is about to shut down ("exiting").
17 **/
18
19/*
20hibernating, phase 1:
21 - send destroy in response to create cells
22 - send end (policy failed) in response to begin cells
23 - close an OR conn when it has no circuits
24
25hibernating, phase 2:
26 (entered when bandwidth hard limit reached)
27 - close all OR/AP/exit conns)
28*/
29
30#define HIBERNATE_PRIVATE
31#include "core/or/or.h"
32#include "core/or/channel.h"
33#include "core/or/channeltls.h"
34#include "app/config/config.h"
40#include "lib/defs/time.h"
46
49
50#ifdef HAVE_UNISTD_H
51#include <unistd.h>
52#endif
53
54#ifdef HAVE_SYSTEMD
55# if defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__)
56/* Systemd's use of gcc's __INCLUDE_LEVEL__ extension macro appears to confuse
57 * Coverity. Here's a kludge to unconfuse it.
58 */
59# define __INCLUDE_LEVEL__ 2
60#endif /* defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__) */
61#include <systemd/sd-daemon.h>
62#endif /* defined(HAVE_SYSTEMD) */
63
64/** Are we currently awake, asleep, running out of bandwidth, or shutting
65 * down? */
66static hibernate_state_t hibernate_state = HIBERNATE_STATE_INITIAL;
67/** If are hibernating, when do we plan to wake up? Set to 0 if we
68 * aren't hibernating. */
69static time_t hibernate_end_time = 0;
70/** If we are shutting down, when do we plan to finally exit? Set to 0 if we
71 * aren't shutting down. (This is obsolete; scheduled shutdowns are supposed
72 * to happen from mainloop_schedule_shutdown() now.) */
73static time_t shutdown_time = 0;
74
75/** A timed event that we'll use when it's time to wake up from
76 * hibernation. */
78
79/** Possible accounting periods. */
80typedef enum {
81 UNIT_MONTH=1, UNIT_WEEK=2, UNIT_DAY=3,
83
84/*
85 * @file hibernate.c
86 *
87 * <h4>Accounting</h4>
88 * Accounting is designed to ensure that no more than N bytes are sent in
89 * either direction over a given interval (currently, one month, one week, or
90 * one day) We could
91 * try to do this by choking our bandwidth to a trickle, but that
92 * would make our streams useless. Instead, we estimate what our
93 * bandwidth usage will be, and guess how long we'll be able to
94 * provide that much bandwidth before hitting our limit. We then
95 * choose a random time within the accounting interval to come up (so
96 * that we don't get 50 Tors running on the 1st of the month and none
97 * on the 30th).
98 *
99 * Each interval runs as follows:
100 *
101 * <ol>
102 * <li>We guess our bandwidth usage, based on how much we used
103 * last time. We choose a "wakeup time" within the interval to come up.
104 * <li>Until the chosen wakeup time, we hibernate.
105 * <li> We come up at the wakeup time, and provide bandwidth until we are
106 * "very close" to running out.
107 * <li> Then we go into low-bandwidth mode, and stop accepting new
108 * connections, but provide bandwidth until we run out.
109 * <li> Then we hibernate until the end of the interval.
110 *
111 * If the interval ends before we run out of bandwidth, we go back to
112 * step one.
113 *
114 * Accounting is controlled by the AccountingMax, AccountingRule, and
115 * AccountingStart options.
116 */
117
118/** How many bytes have we read in this accounting interval? */
119static uint64_t n_bytes_read_in_interval = 0;
120/** How many bytes have we written in this accounting interval? */
121static uint64_t n_bytes_written_in_interval = 0;
122/** How many seconds have we been running this interval? */
124/** How many seconds were we active in this interval before we hit our soft
125 * limit? */
127/** When in this interval was the soft limit hit. */
128static time_t soft_limit_hit_at = 0;
129/** How many bytes had we read/written when we hit the soft limit? */
130static uint64_t n_bytes_at_soft_limit = 0;
131/** When did this accounting interval start? */
132static time_t interval_start_time = 0;
133/** When will this accounting interval end? */
134static time_t interval_end_time = 0;
135/** How far into the accounting interval should we hibernate? */
136static time_t interval_wakeup_time = 0;
137/** How much bandwidth do we 'expect' to use per minute? (0 if we have no
138 * info from the last period.) */
139static uint64_t expected_bandwidth_usage = 0;
140/** What unit are we using for our accounting? */
141static time_unit_t cfg_unit = UNIT_MONTH;
142
143/** How many days,hours,minutes into each unit does our accounting interval
144 * start? */
145/** @{ */
146static int cfg_start_day = 0,
147 cfg_start_hour = 0,
148 cfg_start_min = 0;
149/** @} */
150
151static const char *hibernate_state_to_string(hibernate_state_t state);
152static void reset_accounting(time_t now);
153static int read_bandwidth_usage(void);
154static time_t start_of_accounting_period_after(time_t now);
155static time_t start_of_accounting_period_containing(time_t now);
156static void accounting_set_wakeup_time(void);
157static void on_hibernate_state_change(hibernate_state_t prev_state);
158static void hibernate_schedule_wakeup_event(time_t now, time_t end_time);
159static void wakeup_event_callback(mainloop_event_t *ev, void *data);
160
161/**
162 * Return the human-readable name for the hibernation state <b>state</b>
163 */
164static const char *
165hibernate_state_to_string(hibernate_state_t state)
166{
167 static char buf[64];
168 switch (state) {
169 case HIBERNATE_STATE_EXITING: return "EXITING";
170 case HIBERNATE_STATE_LOWBANDWIDTH: return "SOFT";
171 case HIBERNATE_STATE_DORMANT: return "HARD";
172 case HIBERNATE_STATE_INITIAL:
173 case HIBERNATE_STATE_LIVE:
174 return "AWAKE";
175 default:
176 log_warn(LD_BUG, "unknown hibernate state %d", state);
177 tor_snprintf(buf, sizeof(buf), "unknown [%d]", state);
178 return buf;
179 }
180}
181
182/* ************
183 * Functions for bandwidth accounting.
184 * ************/
185
186/** Configure accounting start/end time settings based on
187 * options->AccountingStart. Return 0 on success, -1 on failure. If
188 * <b>validate_only</b> is true, do not change the current settings. */
189int
190accounting_parse_options(const or_options_t *options, int validate_only)
191{
192 time_unit_t unit;
193 int ok, idx;
194 long d,h,m;
195 smartlist_t *items;
196 const char *v = options->AccountingStart;
197 const char *s;
198 char *cp;
199
200 if (!v) {
201 if (!validate_only) {
202 cfg_unit = UNIT_MONTH;
203 cfg_start_day = 1;
204 cfg_start_hour = 0;
205 cfg_start_min = 0;
206 }
207 return 0;
208 }
209
210 items = smartlist_new();
211 smartlist_split_string(items, v, NULL,
212 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK,0);
213 if (smartlist_len(items)<2) {
214 log_warn(LD_CONFIG, "Too few arguments to AccountingStart");
215 goto err;
216 }
217 s = smartlist_get(items,0);
218 if (0==strcasecmp(s, "month")) {
219 unit = UNIT_MONTH;
220 } else if (0==strcasecmp(s, "week")) {
221 unit = UNIT_WEEK;
222 } else if (0==strcasecmp(s, "day")) {
223 unit = UNIT_DAY;
224 } else {
225 log_warn(LD_CONFIG,
226 "Unrecognized accounting unit '%s': only 'month', 'week',"
227 " and 'day' are supported.", s);
228 goto err;
229 }
230
231 switch (unit) {
232 case UNIT_WEEK:
233 d = tor_parse_long(smartlist_get(items,1), 10, 1, 7, &ok, NULL);
234 if (!ok) {
235 log_warn(LD_CONFIG, "Weekly accounting must begin on a day between "
236 "1 (Monday) and 7 (Sunday)");
237 goto err;
238 }
239 break;
240 case UNIT_MONTH:
241 d = tor_parse_long(smartlist_get(items,1), 10, 1, 28, &ok, NULL);
242 if (!ok) {
243 log_warn(LD_CONFIG, "Monthly accounting must begin on a day between "
244 "1 and 28");
245 goto err;
246 }
247 break;
248 case UNIT_DAY:
249 d = 0;
250 break;
251 /* Coverity dislikes unreachable default cases; some compilers warn on
252 * switch statements missing a case. Tell Coverity not to worry. */
253 /* coverity[dead_error_begin] */
254 default:
255 tor_assert(0);
256 }
257
258 idx = unit==UNIT_DAY?1:2;
259 if (smartlist_len(items) != (idx+1)) {
260 log_warn(LD_CONFIG,"Accounting unit '%s' requires %d argument%s.",
261 s, idx, (idx>1)?"s":"");
262 goto err;
263 }
264 s = smartlist_get(items, idx);
265 h = tor_parse_long(s, 10, 0, 23, &ok, &cp);
266 if (!ok) {
267 log_warn(LD_CONFIG,"Accounting start time not parseable: bad hour.");
268 goto err;
269 }
270 if (!cp || *cp!=':') {
271 log_warn(LD_CONFIG,
272 "Accounting start time not parseable: not in HH:MM format");
273 goto err;
274 }
275 m = tor_parse_long(cp+1, 10, 0, 59, &ok, &cp);
276 if (!ok) {
277 log_warn(LD_CONFIG, "Accounting start time not parseable: bad minute");
278 goto err;
279 }
280 if (!cp || *cp!='\0') {
281 log_warn(LD_CONFIG,
282 "Accounting start time not parseable: not in HH:MM format");
283 goto err;
284 }
285
286 if (!validate_only) {
287 cfg_unit = unit;
288 cfg_start_day = (int)d;
289 cfg_start_hour = (int)h;
290 cfg_start_min = (int)m;
291 }
292 SMARTLIST_FOREACH(items, char *, item, tor_free(item));
293 smartlist_free(items);
294 return 0;
295 err:
296 SMARTLIST_FOREACH(items, char *, item, tor_free(item));
297 smartlist_free(items);
298 return -1;
299}
300
301/** If we want to manage the accounting system and potentially
302 * hibernate, return 1, else return 0.
303 */
304MOCK_IMPL(int,
306{
307 if (options->AccountingMax)
308 return 1;
309 return 0;
310}
311
312/** If accounting is enabled, return how long (in seconds) this
313 * interval lasts. */
314int
316{
318}
319
320/** Return the time at which the current accounting interval will end. */
321MOCK_IMPL(time_t,
323{
324 return interval_end_time;
325}
326
327/** Called from connection.c to tell us that <b>seconds</b> seconds have
328 * passed, <b>n_read</b> bytes have been read, and <b>n_written</b>
329 * bytes have been written. */
330void
331accounting_add_bytes(size_t n_read, size_t n_written, int seconds)
332{
333 n_bytes_read_in_interval += n_read;
334 n_bytes_written_in_interval += n_written;
335 /* If we haven't been called in 10 seconds, we're probably jumping
336 * around in time. */
337 n_seconds_active_in_interval += (seconds < 10) ? seconds : 0;
338}
339
340/** If get_end, return the end of the accounting period that contains
341 * the time <b>now</b>. Else, return the start of the accounting
342 * period that contains the time <b>now</b> */
343static time_t
345{
346 int before;
347 struct tm tm;
348 tor_localtime_r(&now, &tm);
349
350 /* Set 'before' to true iff the current time is before the hh:mm
351 * changeover time for today. */
352 before = tm.tm_hour < cfg_start_hour ||
353 (tm.tm_hour == cfg_start_hour && tm.tm_min < cfg_start_min);
354
355 /* Dispatch by unit. First, find the start day of the given period;
356 * then, if get_end is true, increment to the end day. */
357 switch (cfg_unit)
358 {
359 case UNIT_MONTH: {
360 /* If this is before the Nth, we want the Nth of last month. */
361 if (tm.tm_mday < cfg_start_day ||
362 (tm.tm_mday == cfg_start_day && before)) {
363 --tm.tm_mon;
364 }
365 /* Otherwise, the month is correct. */
366 tm.tm_mday = cfg_start_day;
367 if (get_end)
368 ++tm.tm_mon;
369 break;
370 }
371 case UNIT_WEEK: {
372 /* What is the 'target' day of the week in struct tm format? (We
373 say Sunday==7; struct tm says Sunday==0.) */
374 int wday = cfg_start_day % 7;
375 /* How many days do we subtract from today to get to the right day? */
376 int delta = (7+tm.tm_wday-wday)%7;
377 /* If we are on the right day, but the changeover hasn't happened yet,
378 * then subtract a whole week. */
379 if (delta == 0 && before)
380 delta = 7;
381 tm.tm_mday -= delta;
382 if (get_end)
383 tm.tm_mday += 7;
384 break;
385 }
386 case UNIT_DAY:
387 if (before)
388 --tm.tm_mday;
389 if (get_end)
390 ++tm.tm_mday;
391 break;
392 default:
393 tor_assert(0);
394 }
395
396 tm.tm_hour = cfg_start_hour;
397 tm.tm_min = cfg_start_min;
398 tm.tm_sec = 0;
399 tm.tm_isdst = -1; /* Autodetect DST */
400 return mktime(&tm);
401}
402
403/** Return the start of the accounting period containing the time
404 * <b>now</b>. */
405static time_t
407{
409}
410
411/** Return the start of the accounting period that comes after the one
412 * containing the time <b>now</b>. */
413static time_t
415{
417}
418
419/** Return the length of the accounting period containing the time
420 * <b>now</b>. */
421static long
423{
426}
427
428/** Initialize the accounting subsystem. */
429void
431{
432 time_t s_now;
433 /* Try to remember our recorded usage. */
435 read_bandwidth_usage(); /* If we fail, we'll leave values at zero, and
436 * reset below.*/
437
439
440 if (!interval_start_time) {
441 /* We didn't have recorded usage; Start a new interval. */
442 log_info(LD_ACCT, "Starting new accounting interval.");
443 reset_accounting(now);
444 } else if (s_now == interval_start_time) {
445 log_info(LD_ACCT, "Continuing accounting interval.");
446 /* We are in the interval we thought we were in. Do nothing.*/
448 } else {
449 long duration =
451 double delta = ((double)(s_now - interval_start_time)) / duration;
452 if (-0.50 <= delta && delta <= 0.50) {
453 /* The start of the period is now a little later or earlier than we
454 * remembered. That's fine; we might lose some bytes we could otherwise
455 * have written, but better to err on the side of obeying accounting
456 * settings. */
457 log_info(LD_ACCT, "Accounting interval moved by %.02f%%; "
458 "that's fine.", delta*100);
460 } else if (delta >= 0.99) {
461 /* This is the regular time-moved-forward case; don't be too noisy
462 * about it or people will complain */
463 log_info(LD_ACCT, "Accounting interval elapsed; starting a new one");
464 reset_accounting(now);
465 } else {
466 log_warn(LD_ACCT,
467 "Mismatched accounting interval: moved by %.02f%%. "
468 "Starting a fresh one.", delta*100);
469 reset_accounting(now);
470 }
471 }
473}
474
475/** Return the relevant number of bytes sent/received this interval
476 * based on the set AccountingRule */
477uint64_t
479{
480 if (get_options()->AccountingRule == ACCT_SUM)
482 else if (get_options()->AccountingRule == ACCT_IN)
484 else if (get_options()->AccountingRule == ACCT_OUT)
486 else
488}
489
490/** Set expected_bandwidth_usage based on how much we sent/received
491 * per minute last interval (if we were up for at least 30 minutes),
492 * or based on our declared bandwidth otherwise. */
493static void
495{
496 uint64_t expected;
497 const or_options_t *options= get_options();
498 uint64_t max_configured = (options->RelayBandwidthRate > 0 ?
499 options->RelayBandwidthRate :
500 options->BandwidthRate) * 60;
501 /* max_configured is the larger of bytes read and bytes written
502 * If we are accounting based on sum, worst case is both are
503 * at max, doubling the expected sum of bandwidth */
504 if (get_options()->AccountingRule == ACCT_SUM)
505 max_configured *= 2;
506
507#define MIN_TIME_FOR_MEASUREMENT (1800)
508
510 (soft_limit_hit_at - interval_start_time) > MIN_TIME_FOR_MEASUREMENT) {
511 /* If we hit our soft limit last time, only count the bytes up to that
512 * time. This is a better predictor of our actual bandwidth than
513 * considering the entirety of the last interval, since we likely started
514 * using bytes very slowly once we hit our soft limit. */
515 expected = n_bytes_at_soft_limit /
517 expected /= 60;
518 } else if (n_seconds_active_in_interval >= MIN_TIME_FOR_MEASUREMENT) {
519 /* Otherwise, we either measured enough time in the last interval but
520 * never hit our soft limit, or we're using a state file from a Tor that
521 * doesn't know to store soft-limit info. Just take rate at which
522 * we were reading/writing in the last interval as our expected rate.
523 */
524 uint64_t used = get_accounting_bytes();
525 expected = used / (n_seconds_active_in_interval / 60);
526 } else {
527 /* If we haven't gotten enough data last interval, set 'expected'
528 * to 0. This will set our wakeup to the start of the interval.
529 * Next interval, we'll choose our starting time based on how much
530 * we sent this interval.
531 */
532 expected = 0;
533 }
534 if (expected > max_configured)
535 expected = max_configured;
536 expected_bandwidth_usage = expected;
537}
538
539/** Called at the start of a new accounting interval: reset our
540 * expected bandwidth usage based on what happened last time, set up
541 * the start and end of the interval, and clear byte/time totals.
542 */
543static void
545{
546 log_info(LD_ACCT, "Starting new accounting interval.");
556}
557
558/** Return true iff we should save our bandwidth usage to disk. */
559static inline int
561{
562 /* Note every 600 sec */
563#define NOTE_INTERVAL (600)
564 /* Or every 20 megabytes */
565#define NOTE_BYTES (20*1024*1024)
566 static uint64_t last_read_bytes_noted = 0;
567 static uint64_t last_written_bytes_noted = 0;
568 static time_t last_time_noted = 0;
569
570 if (last_time_noted + NOTE_INTERVAL <= now ||
571 last_read_bytes_noted + NOTE_BYTES <= n_bytes_read_in_interval ||
572 last_written_bytes_noted + NOTE_BYTES <= n_bytes_written_in_interval ||
574 last_time_noted = now;
575 last_read_bytes_noted = n_bytes_read_in_interval;
576 last_written_bytes_noted = n_bytes_written_in_interval;
577 return 1;
578 }
579 return 0;
580}
581
582/** Invoked once per second. Checks whether it is time to hibernate,
583 * record bandwidth used, etc. */
584void
586{
587 if (now >= interval_end_time) {
589 }
592 log_warn(LD_FS, "Couldn't record bandwidth usage to disk.");
593 }
594 }
595}
596
597/** Based on our interval and our estimated bandwidth, choose a
598 * deterministic (but random-ish) time to wake up. */
599static void
601{
602 char digest[DIGEST_LEN];
603 crypto_digest_t *d_env;
604 uint64_t time_to_exhaust_bw;
605 int time_to_consider;
606
608 if (init_keys() < 0) {
609 log_err(LD_BUG, "Error initializing keys");
610 tor_assert(0);
611 }
612 }
613
615 char buf[ISO_TIME_LEN+1];
617
618 if (crypto_pk_get_digest(get_server_identity_key(), digest) < 0) {
619 log_err(LD_BUG, "Error getting our key's digest.");
620 tor_assert(0);
621 }
622
623 d_env = crypto_digest_new();
624 crypto_digest_add_bytes(d_env, buf, ISO_TIME_LEN);
625 crypto_digest_add_bytes(d_env, digest, DIGEST_LEN);
626 crypto_digest_get_digest(d_env, digest, DIGEST_LEN);
627 crypto_digest_free(d_env);
628 } else {
629 crypto_rand(digest, DIGEST_LEN);
630 }
631
633 char buf1[ISO_TIME_LEN+1];
634 char buf2[ISO_TIME_LEN+1];
638
639 log_notice(LD_ACCT,
640 "Configured hibernation. This interval begins at %s "
641 "and ends at %s. We have no prior estimate for bandwidth, so "
642 "we will start out awake and hibernate when we exhaust our quota.",
643 buf1, buf2);
644 return;
645 }
646
647 time_to_exhaust_bw =
649 if (time_to_exhaust_bw > INT_MAX) {
650 time_to_exhaust_bw = INT_MAX;
651 time_to_consider = 0;
652 } else {
653 time_to_consider = accounting_get_interval_length() -
654 (int)time_to_exhaust_bw;
655 }
656
657 if (time_to_consider<=0) {
659 } else {
660 /* XXX can we simplify this just by picking a random (non-deterministic)
661 * time to be up? If we go down and come up, then we pick a new one. Is
662 * that good enough? -RD */
663
664 /* This is not a perfectly unbiased conversion, but it is good enough:
665 * in the worst case, the first half of the day is 0.06 percent likelier
666 * to be chosen than the last half. */
668 (get_uint32(digest) % time_to_consider);
669 }
670
671 {
672 char buf1[ISO_TIME_LEN+1];
673 char buf2[ISO_TIME_LEN+1];
674 char buf3[ISO_TIME_LEN+1];
675 char buf4[ISO_TIME_LEN+1];
676 time_t down_time;
677 if (interval_wakeup_time+time_to_exhaust_bw > TIME_MAX)
678 down_time = TIME_MAX;
679 else
680 down_time = (time_t)(interval_wakeup_time+time_to_exhaust_bw);
681 if (down_time>interval_end_time)
682 down_time = interval_end_time;
685 format_local_iso_time(buf3, down_time);
687
688 log_notice(LD_ACCT,
689 "Configured hibernation. This interval began at %s; "
690 "the scheduled wake-up time %s %s; "
691 "we expect%s to exhaust our quota for this interval around %s; "
692 "the next interval begins at %s (all times local)",
693 buf1,
694 time(NULL)<interval_wakeup_time?"is":"was", buf2,
695 time(NULL)<down_time?"":"ed", buf3,
696 buf4);
697 }
698}
699
700/* This rounds 0 up to 1000, but that's actually a feature. */
701#define ROUND_UP(x) (((x) + 0x3ff) & ~0x3ff)
702/** Save all our bandwidth tracking information to disk. Return 0 on
703 * success, -1 on failure. */
704int
706{
707 /* Just update the state */
709 state->AccountingBytesReadInInterval = ROUND_UP(n_bytes_read_in_interval);
710 state->AccountingBytesWrittenInInterval =
712 state->AccountingSecondsActive = n_seconds_active_in_interval;
713 state->AccountingExpectedUsage = expected_bandwidth_usage;
714
715 state->AccountingSecondsToReachSoftLimit = n_seconds_to_hit_soft_limit;
716 state->AccountingSoftLimitHitAt = soft_limit_hit_at;
717 state->AccountingBytesAtSoftLimit = n_bytes_at_soft_limit;
718
720 now+(get_options()->AvoidDiskWrites ? 7200 : 60));
721
722 return 0;
723}
724#undef ROUND_UP
725
726/** Read stored accounting information from disk. Return 0 on success;
727 * return -1 and change nothing on failure. */
728static int
730{
731 or_state_t *state = get_or_state();
732
733 {
734 char *fname = get_datadir_fname("bw_accounting");
735 int res;
736
737 res = unlink(fname);
738 if (res != 0 && errno != ENOENT) {
739 log_warn(LD_FS,
740 "Failed to unlink %s: %s",
741 fname, strerror(errno));
742 }
743
744 tor_free(fname);
745 }
746
747 if (!state)
748 return -1;
749
750 log_info(LD_ACCT, "Reading bandwidth accounting data from state file");
751 n_bytes_read_in_interval = state->AccountingBytesReadInInterval;
752 n_bytes_written_in_interval = state->AccountingBytesWrittenInInterval;
753 n_seconds_active_in_interval = state->AccountingSecondsActive;
755 expected_bandwidth_usage = state->AccountingExpectedUsage;
756
757 /* Older versions of Tor (before 0.2.2.17-alpha or so) didn't generate these
758 * fields. If you switch back and forth, you might get an
759 * AccountingSoftLimitHitAt value from long before the most recent
760 * interval_start_time. If that's so, then ignore the softlimit-related
761 * values. */
762 if (state->AccountingSoftLimitHitAt > interval_start_time) {
763 soft_limit_hit_at = state->AccountingSoftLimitHitAt;
764 n_bytes_at_soft_limit = state->AccountingBytesAtSoftLimit;
765 n_seconds_to_hit_soft_limit = state->AccountingSecondsToReachSoftLimit;
766 } else {
770 }
771
772 {
773 char tbuf1[ISO_TIME_LEN+1];
774 char tbuf2[ISO_TIME_LEN+1];
775 format_iso_time(tbuf1, state->LastWritten);
777
778 log_info(LD_ACCT,
779 "Successfully read bandwidth accounting info from state written at %s "
780 "for interval starting at %s. We have been active for %lu seconds in "
781 "this interval. At the start of the interval, we expected to use "
782 "about %lu KB per second. (%"PRIu64" bytes read so far, "
783 "%"PRIu64" bytes written so far)",
784 tbuf1, tbuf2,
785 (unsigned long)n_seconds_active_in_interval,
786 (unsigned long)(expected_bandwidth_usage*1024/60),
789 }
790
791 return 0;
792}
793
794/** Return true iff we have sent/received all the bytes we are willing
795 * to send/receive this interval. */
796static int
798{
799 uint64_t hard_limit = get_options()->AccountingMax;
800 if (!hard_limit)
801 return 0;
802 return get_accounting_bytes() >= hard_limit;
803}
804
805/** Return true iff we have sent/received almost all the bytes we are willing
806 * to send/receive this interval. */
807static int
809{
810 const uint64_t acct_max = get_options()->AccountingMax;
811#define SOFT_LIM_PCT (.95)
812#define SOFT_LIM_BYTES (500*1024*1024)
813#define SOFT_LIM_MINUTES (3*60)
814 /* The 'soft limit' is a fair bit more complicated now than once it was.
815 * We want to stop accepting connections when ALL of the following are true:
816 * - We expect to use up the remaining bytes in under 3 hours
817 * - We have used up 95% of our bytes.
818 * - We have less than 500MBytes left.
819 */
820 uint64_t soft_limit = (uint64_t) (acct_max * SOFT_LIM_PCT);
821 if (acct_max > SOFT_LIM_BYTES && acct_max - SOFT_LIM_BYTES > soft_limit) {
822 soft_limit = acct_max - SOFT_LIM_BYTES;
823 }
825 const uint64_t expected_usage =
826 expected_bandwidth_usage * SOFT_LIM_MINUTES;
827 if (acct_max > expected_usage && acct_max - expected_usage > soft_limit)
828 soft_limit = acct_max - expected_usage;
829 }
830
831 if (!soft_limit)
832 return 0;
833 return get_accounting_bytes() >= soft_limit;
834}
835
836/** Called when we get a SIGINT, or when bandwidth soft limit is
837 * reached. Puts us into "loose hibernation": we don't accept new
838 * connections, but we continue handling old ones. */
839static void
840hibernate_begin(hibernate_state_t new_state, time_t now)
841{
842 const or_options_t *options = get_options();
843
844 if (new_state == HIBERNATE_STATE_EXITING &&
845 hibernate_state != HIBERNATE_STATE_LIVE) {
846 log_notice(LD_GENERAL,"SIGINT received %s; exiting now.",
847 hibernate_state == HIBERNATE_STATE_EXITING ?
848 "a second time" : "while hibernating");
850 return;
851 }
852
853 if (new_state == HIBERNATE_STATE_LOWBANDWIDTH &&
854 hibernate_state == HIBERNATE_STATE_LIVE) {
855 soft_limit_hit_at = now;
858 }
859
860 /* close listeners. leave control listener(s). */
862
863 /* XXX kill intro point circs */
864 /* XXX upload rendezvous service descriptors with no intro points */
865
866 if (new_state == HIBERNATE_STATE_EXITING) {
867 log_notice(LD_GENERAL,"Interrupt: we have stopped accepting new "
868 "connections, and will shut down in %d seconds. Interrupt "
869 "again to exit now.", options->ShutdownWaitLength);
870 /* We add an arbitrary delay here so that even if something goes wrong
871 * with the mainloop shutdown code, we can still shutdown from
872 * consider_hibernation() if we call it... but so that the
873 * mainloop_schedule_shutdown() mechanism will be the first one called.
874 */
875 shutdown_time = time(NULL) + options->ShutdownWaitLength + 5;
877#ifdef HAVE_SYSTEMD
878 /* tell systemd that we may need more than the default 90 seconds to shut
879 * down so they don't kill us. add some extra time to actually finish
880 * shutting down, otherwise systemd will kill us immediately after the
881 * EXTEND_TIMEOUT_USEC expires. this is an *upper* limit; tor will probably
882 * only take one or two more seconds, but assume that maybe we got swapped
883 * out and it takes a little while longer.
884 *
885 * as of writing, this is a no-op with all-defaults: ShutdownWaitLength is
886 * 30 seconds, so this will extend the timeout to 60 seconds.
887 * default systemd DefaultTimeoutStopSec is 90 seconds, so systemd will
888 * wait (up to) 90 seconds anyways.
889 *
890 * 2^31 usec = ~2147 sec = ~35 min. probably nobody will actually set
891 * ShutdownWaitLength to more than that, but use a longer type so we don't
892 * need to think about UB on overflow
893 */
894 sd_notifyf(0, "EXTEND_TIMEOUT_USEC=%" PRIu64,
895 ((uint64_t)(options->ShutdownWaitLength) + 30) * TOR_USEC_PER_SEC);
896#endif /* defined(HAVE_SYSTEMD) */
897 } else { /* soft limit reached */
899 }
900
901 hibernate_state = new_state;
903
905 get_options()->AvoidDiskWrites ? now+600 : 0);
906}
907
908/** Called when we've been hibernating and our timeout is reached. */
909static void
910hibernate_end(hibernate_state_t new_state)
911{
912 tor_assert(hibernate_state == HIBERNATE_STATE_LOWBANDWIDTH ||
913 hibernate_state == HIBERNATE_STATE_DORMANT ||
914 hibernate_state == HIBERNATE_STATE_INITIAL);
915
916 /* listeners will be relaunched in run_scheduled_events() in main.c */
917 if (hibernate_state != HIBERNATE_STATE_INITIAL)
918 log_notice(LD_ACCT,"Hibernation period ended. Resuming normal activity.");
919
920 hibernate_state = new_state;
921 hibernate_end_time = 0; /* no longer hibernating */
922 reset_uptime(); /* reset published uptime */
923}
924
925/** A wrapper around hibernate_begin, for when we get SIGINT. */
926void
928{
929 hibernate_begin(HIBERNATE_STATE_EXITING, time(NULL));
930}
931
932/**
933 * Return true iff we are currently hibernating -- that is, if we are in
934 * any non-live state.
935 */
936MOCK_IMPL(int,
938{
939 return hibernate_state != HIBERNATE_STATE_LIVE;
940}
941
942/**
943 * Return true iff we are currently _fully_ hibernating -- that is, if we are
944 * in a state where we expect to handle no network activity at all.
945 */
946MOCK_IMPL(int,
948{
949 return hibernate_state == HIBERNATE_STATE_DORMANT;
950}
951
952/** If we aren't currently dormant, close all connections and become
953 * dormant. */
954static void
956{
957 connection_t *conn;
958
959 if (hibernate_state == HIBERNATE_STATE_DORMANT)
960 return;
961 else if (hibernate_state == HIBERNATE_STATE_LOWBANDWIDTH)
962 hibernate_state = HIBERNATE_STATE_DORMANT;
963 else
964 hibernate_begin(HIBERNATE_STATE_DORMANT, now);
965
966 log_notice(LD_ACCT,"Going dormant. Blowing away remaining connections.");
967
968 /* Close all OR/AP/exit conns. Leave dir conns because we still want
969 * to be able to upload server descriptors so clients know we're still
970 * running, and download directories so we can detect if we're obsolete.
971 * Leave control conns because we still want to be controllable.
972 */
973 while ((conn = connection_get_by_type(CONN_TYPE_OR)) ||
976 if (CONN_IS_EDGE(conn)) {
977 connection_edge_end(TO_EDGE_CONN(conn), END_STREAM_REASON_HIBERNATING);
978 }
979 log_info(LD_NET,"Closing conn type %d", conn->type);
980 if (conn->type == CONN_TYPE_AP) {
981 /* send socks failure if needed */
982 connection_mark_unattached_ap(TO_ENTRY_CONN(conn),
983 END_STREAM_REASON_HIBERNATING);
984 } else if (conn->type == CONN_TYPE_OR) {
985 if (TO_OR_CONN(conn)->chan) {
987 } else {
988 connection_mark_for_close(conn);
989 }
990 } else {
991 connection_mark_for_close(conn);
992 }
993 }
994
995 if (now < interval_wakeup_time)
997 else
999
1001
1003 get_options()->AvoidDiskWrites ? now+600 : 0);
1004
1006}
1007
1008/**
1009 * Schedule a mainloop event at <b>end_time</b> to wake up from a dormant
1010 * state. We can't rely on this happening from second_elapsed_callback,
1011 * since second_elapsed_callback will be shut down when we're dormant.
1012 *
1013 * (Note that We might immediately go back to sleep after we set the next
1014 * wakeup time.)
1015 */
1016static void
1017hibernate_schedule_wakeup_event(time_t now, time_t end_time)
1018{
1019 struct timeval delay = { 0, 0 };
1020
1021 if (now >= end_time) {
1022 // In these cases we always wait at least a second, to avoid running
1023 // the callback in a tight loop.
1024 delay.tv_sec = 1;
1025 } else {
1026 delay.tv_sec = (end_time - now);
1027 }
1028
1029 if (!wakeup_event) {
1031 }
1032
1034}
1035
1036/**
1037 * Called at the end of the interval, or at the wakeup time of the current
1038 * interval, to exit the dormant state.
1039 **/
1040static void
1042{
1043 (void) ev;
1044 (void) data;
1045
1046 const time_t now = time(NULL);
1049 if (hibernate_state != HIBERNATE_STATE_DORMANT) {
1050 /* We woke up, so everything's great here */
1051 return;
1052 }
1053
1054 /* We're still dormant. */
1055 if (now < interval_wakeup_time)
1057 else
1059
1061}
1062
1063/** Called when hibernate_end_time has arrived. */
1064static void
1066{
1067 char buf[ISO_TIME_LEN+1];
1068
1069 /* The interval has ended, or it is wakeup time. Find out which. */
1071 if (interval_wakeup_time <= now) {
1072 /* The interval hasn't changed, but interval_wakeup_time has passed.
1073 * It's time to wake up and start being a server. */
1074 hibernate_end(HIBERNATE_STATE_LIVE);
1075 return;
1076 } else {
1077 /* The interval has changed, and it isn't time to wake up yet. */
1080 if (hibernate_state != HIBERNATE_STATE_DORMANT) {
1081 /* We weren't sleeping before; we should sleep now. */
1082 log_notice(LD_ACCT,
1083 "Accounting period ended. Commencing hibernation until "
1084 "%s UTC", buf);
1086 } else {
1087 log_notice(LD_ACCT,
1088 "Accounting period ended. This period, we will hibernate"
1089 " until %s UTC",buf);
1090 }
1091 }
1092}
1093
1094/** Consider our environment and decide if it's time
1095 * to start/stop hibernating.
1096 */
1097void
1099{
1100 int accounting_enabled = get_options()->AccountingMax != 0;
1101 char buf[ISO_TIME_LEN+1];
1102 hibernate_state_t prev_state = hibernate_state;
1103
1104 /* If we're in 'exiting' mode, then we just shut down after the interval
1105 * elapses. The mainloop was supposed to catch this via
1106 * mainloop_schedule_shutdown(), but apparently it didn't. */
1107 if (hibernate_state == HIBERNATE_STATE_EXITING) {
1109 if (shutdown_time <= now) {
1110 log_notice(LD_BUG, "Mainloop did not catch shutdown event; exiting.");
1112 }
1113 return; /* if exiting soon, don't worry about bandwidth limits */
1114 }
1115
1116 if (hibernate_state == HIBERNATE_STATE_DORMANT) {
1117 /* We've been hibernating because of bandwidth accounting. */
1119 if (hibernate_end_time > now && accounting_enabled) {
1120 /* If we're hibernating, don't wake up until it's time, regardless of
1121 * whether we're in a new interval. */
1122 return;
1123 } else {
1125 }
1126 }
1127
1128 /* Else, we aren't hibernating. See if it's time to start hibernating, or to
1129 * go dormant. */
1130 if (hibernate_state == HIBERNATE_STATE_LIVE ||
1131 hibernate_state == HIBERNATE_STATE_INITIAL) {
1133 log_notice(LD_ACCT,
1134 "Bandwidth soft limit reached; commencing hibernation. "
1135 "No new connections will be accepted");
1136 hibernate_begin(HIBERNATE_STATE_LOWBANDWIDTH, now);
1137 } else if (accounting_enabled && now < interval_wakeup_time) {
1139 log_notice(LD_ACCT,
1140 "Commencing hibernation. We will wake up at %s local time.",
1141 buf);
1143 } else if (hibernate_state == HIBERNATE_STATE_INITIAL) {
1144 hibernate_end(HIBERNATE_STATE_LIVE);
1145 }
1146 }
1147
1148 if (hibernate_state == HIBERNATE_STATE_LOWBANDWIDTH) {
1149 if (!accounting_enabled) {
1151 } else if (hibernate_hard_limit_reached()) {
1153 } else if (hibernate_end_time <= now) {
1154 /* The hibernation period ended while we were still in lowbandwidth.*/
1156 }
1157 }
1158
1159 /* Dispatch a controller event if the hibernation state changed. */
1160 if (hibernate_state != prev_state)
1161 on_hibernate_state_change(prev_state);
1162}
1163
1164/** Helper function: called when we get a GETINFO request for an
1165 * accounting-related key on the control connection <b>conn</b>. If we can
1166 * answer the request for <b>question</b>, then set *<b>answer</b> to a newly
1167 * allocated string holding the result. Otherwise, set *<b>answer</b> to
1168 * NULL. */
1169int
1171 const char *question, char **answer,
1172 const char **errmsg)
1173{
1174 (void) conn;
1175 (void) errmsg;
1176 if (!strcmp(question, "accounting/enabled")) {
1177 *answer = tor_strdup(accounting_is_enabled(get_options()) ? "1" : "0");
1178 } else if (!strcmp(question, "accounting/hibernating")) {
1179 *answer = tor_strdup(hibernate_state_to_string(hibernate_state));
1180 tor_strlower(*answer);
1181 } else if (!strcmp(question, "accounting/bytes")) {
1182 tor_asprintf(answer, "%"PRIu64" %"PRIu64,
1185 } else if (!strcmp(question, "accounting/bytes-left")) {
1186 uint64_t limit = get_options()->AccountingMax;
1187 if (get_options()->AccountingRule == ACCT_SUM) {
1188 uint64_t total_left = 0;
1189 uint64_t total_bytes = get_accounting_bytes();
1190 if (total_bytes < limit)
1191 total_left = limit - total_bytes;
1192 tor_asprintf(answer, "%"PRIu64" %"PRIu64,
1193 (total_left), (total_left));
1194 } else if (get_options()->AccountingRule == ACCT_IN) {
1195 uint64_t read_left = 0;
1196 if (n_bytes_read_in_interval < limit)
1197 read_left = limit - n_bytes_read_in_interval;
1198 tor_asprintf(answer, "%"PRIu64" %"PRIu64,
1199 (read_left), (limit));
1200 } else if (get_options()->AccountingRule == ACCT_OUT) {
1201 uint64_t write_left = 0;
1202 if (n_bytes_written_in_interval < limit)
1203 write_left = limit - n_bytes_written_in_interval;
1204 tor_asprintf(answer, "%"PRIu64" %"PRIu64,
1205 (limit), (write_left));
1206 } else {
1207 uint64_t read_left = 0, write_left = 0;
1208 if (n_bytes_read_in_interval < limit)
1209 read_left = limit - n_bytes_read_in_interval;
1210 if (n_bytes_written_in_interval < limit)
1211 write_left = limit - n_bytes_written_in_interval;
1212 tor_asprintf(answer, "%"PRIu64" %"PRIu64,
1213 (read_left), (write_left));
1214 }
1215 } else if (!strcmp(question, "accounting/interval-start")) {
1216 *answer = tor_malloc(ISO_TIME_LEN+1);
1218 } else if (!strcmp(question, "accounting/interval-wake")) {
1219 *answer = tor_malloc(ISO_TIME_LEN+1);
1221 } else if (!strcmp(question, "accounting/interval-end")) {
1222 *answer = tor_malloc(ISO_TIME_LEN+1);
1224 } else {
1225 *answer = NULL;
1226 }
1227 return 0;
1228}
1229
1230/**
1231 * Helper function: called when the hibernation state changes, and sends a
1232 * SERVER_STATUS event to notify interested controllers of the accounting
1233 * state change.
1234 */
1235static void
1236on_hibernate_state_change(hibernate_state_t prev_state)
1237{
1239 "HIBERNATION_STATUS STATUS=%s",
1241
1242 /* We are changing hibernation state, this can affect the main loop event
1243 * list. Rescan it to update the events state. We do this whatever the new
1244 * hibernation state because they can each possibly affect an event. The
1245 * initial state means we are booting up so we shouldn't scan here because
1246 * at this point the events in the list haven't been initialized. */
1247 if (prev_state != HIBERNATE_STATE_INITIAL) {
1249 }
1250}
1251
1252/** Free all resources held by the accounting module */
1253void
1255{
1256 mainloop_event_free(wakeup_event);
1257 hibernate_state = HIBERNATE_STATE_INITIAL;
1259 shutdown_time = 0;
1260}
1261
1262#ifdef TOR_UNIT_TESTS
1263/**
1264 * Manually change the hibernation state. Private; used only by the unit
1265 * tests.
1266 */
1267void
1268hibernate_set_state_for_testing_(hibernate_state_t newstate)
1269{
1270 hibernate_state = newstate;
1271}
1272#endif /* defined(TOR_UNIT_TESTS) */
static uint32_t get_uint32(const void *cp)
Definition: bytes.h:54
Header file for channel.c.
Header file for channeltls.c.
#define MAX(a, b)
Definition: cmp.h:22
mainloop_event_t * mainloop_event_postloop_new(void(*cb)(mainloop_event_t *, void *), void *userdata)
int mainloop_event_schedule(mainloop_event_t *event, const struct timeval *tv)
Header for compat_libevent.c.
const or_options_t * get_options(void)
Definition: config.c:944
Header file for config.c.
void connection_mark_all_noncontrol_listeners(void)
Definition: connection.c:3355
connection_t * connection_get_by_type(int type)
Definition: connection.c:4920
Header file for connection.c.
#define CONN_TYPE_OR
Definition: connection.h:44
#define CONN_TYPE_AP
Definition: connection.h:51
#define CONN_TYPE_EXIT
Definition: connection.h:46
int connection_edge_end(edge_connection_t *conn, uint8_t reason)
entry_connection_t * TO_ENTRY_CONN(connection_t *c)
edge_connection_t * TO_EDGE_CONN(connection_t *c)
Header file for connection_edge.c.
or_connection_t * TO_OR_CONN(connection_t *c)
void connection_or_close_normally(or_connection_t *orconn, int flush)
Header file for connection_or.c.
#define CONN_IS_EDGE(x)
int control_event_server_status(int severity, const char *format,...)
Header file for control_events.c.
void crypto_digest_get_digest(crypto_digest_t *digest, char *out, size_t out_len)
#define crypto_digest_free(d)
void crypto_digest_add_bytes(crypto_digest_t *digest, const char *data, size_t len)
crypto_digest_t * crypto_digest_new(void)
void crypto_rand(char *to, size_t n)
Definition: crypto_rand.c:479
Common functions for using (pseudo-)random number generators.
int crypto_pk_get_digest(const crypto_pk_t *pk, char *digest_out)
Definition: crypto_rsa.c:356
#define DIGEST_LEN
Definition: digest_sizes.h:20
time_t accounting_get_end_time(void)
Definition: hibernate.c:322
static time_t start_of_accounting_period_containing(time_t now)
Definition: hibernate.c:406
int accounting_parse_options(const or_options_t *options, int validate_only)
Definition: hibernate.c:190
static void wakeup_event_callback(mainloop_event_t *ev, void *data)
Definition: hibernate.c:1041
static void on_hibernate_state_change(hibernate_state_t prev_state)
Definition: hibernate.c:1236
int getinfo_helper_accounting(control_connection_t *conn, const char *question, char **answer, const char **errmsg)
Definition: hibernate.c:1170
int accounting_record_bandwidth_usage(time_t now, or_state_t *state)
Definition: hibernate.c:705
static time_t interval_end_time
Definition: hibernate.c:134
static void accounting_set_wakeup_time(void)
Definition: hibernate.c:600
time_unit_t
Definition: hibernate.c:80
static uint32_t n_seconds_active_in_interval
Definition: hibernate.c:123
static uint64_t expected_bandwidth_usage
Definition: hibernate.c:139
static time_t shutdown_time
Definition: hibernate.c:73
static time_t interval_start_time
Definition: hibernate.c:132
static void hibernate_begin(hibernate_state_t new_state, time_t now)
Definition: hibernate.c:840
void accounting_add_bytes(size_t n_read, size_t n_written, int seconds)
Definition: hibernate.c:331
void consider_hibernation(time_t now)
Definition: hibernate.c:1098
int we_are_fully_hibernating(void)
Definition: hibernate.c:947
void configure_accounting(time_t now)
Definition: hibernate.c:430
static long length_of_accounting_period_containing(time_t now)
Definition: hibernate.c:422
static mainloop_event_t * wakeup_event
Definition: hibernate.c:77
static uint64_t n_bytes_at_soft_limit
Definition: hibernate.c:130
int accounting_is_enabled(const or_options_t *options)
Definition: hibernate.c:305
static hibernate_state_t hibernate_state
Definition: hibernate.c:66
static int read_bandwidth_usage(void)
Definition: hibernate.c:729
static void hibernate_end(hibernate_state_t new_state)
Definition: hibernate.c:910
static void hibernate_schedule_wakeup_event(time_t now, time_t end_time)
Definition: hibernate.c:1017
static time_t start_of_accounting_period_after(time_t now)
Definition: hibernate.c:414
static int hibernate_soft_limit_reached(void)
Definition: hibernate.c:808
void accounting_free_all(void)
Definition: hibernate.c:1254
void accounting_run_housekeeping(time_t now)
Definition: hibernate.c:585
int we_are_hibernating(void)
Definition: hibernate.c:937
static time_t hibernate_end_time
Definition: hibernate.c:69
static time_t edge_of_accounting_period_containing(time_t now, int get_end)
Definition: hibernate.c:344
static const char * hibernate_state_to_string(hibernate_state_t state)
Definition: hibernate.c:165
static void hibernate_end_time_elapsed(time_t now)
Definition: hibernate.c:1065
static time_t interval_wakeup_time
Definition: hibernate.c:136
static int cfg_start_day
Definition: hibernate.c:146
static int time_to_record_bandwidth_usage(time_t now)
Definition: hibernate.c:560
static void reset_accounting(time_t now)
Definition: hibernate.c:544
static int n_seconds_to_hit_soft_limit
Definition: hibernate.c:126
static uint64_t n_bytes_written_in_interval
Definition: hibernate.c:121
static int hibernate_hard_limit_reached(void)
Definition: hibernate.c:797
void hibernate_begin_shutdown(void)
Definition: hibernate.c:927
uint64_t get_accounting_bytes(void)
Definition: hibernate.c:478
static void hibernate_go_dormant(time_t now)
Definition: hibernate.c:955
static time_unit_t cfg_unit
Definition: hibernate.c:141
static void update_expected_bandwidth(void)
Definition: hibernate.c:494
static time_t soft_limit_hit_at
Definition: hibernate.c:128
static uint64_t n_bytes_read_in_interval
Definition: hibernate.c:119
int accounting_get_interval_length(void)
Definition: hibernate.c:315
Header file for hibernate.c.
#define LD_ACCT
Definition: log.h:97
#define LD_FS
Definition: log.h:70
#define LD_BUG
Definition: log.h:86
#define LD_NET
Definition: log.h:66
#define LD_GENERAL
Definition: log.h:62
#define LOG_NOTICE
Definition: log.h:50
#define LD_CONFIG
Definition: log.h:68
void reset_uptime(void)
Definition: mainloop.c:2564
void mainloop_schedule_shutdown(int delay_sec)
Definition: mainloop.c:1670
void tor_shutdown_event_loop_and_exit(int exitcode)
Definition: mainloop.c:773
void rescan_periodic_events(const or_options_t *options)
Definition: mainloop.c:1597
Header file for mainloop.c.
#define tor_free(p)
Definition: malloc.h:56
Master header file for Tor-specific functionality.
OR connection structure.
The or_state_t structure, which represents Tor's state file.
long tor_parse_long(const char *s, int base, long min, long max, int *ok, char **next)
Definition: parse_int.c:59
int tor_asprintf(char **strp, const char *fmt,...)
Definition: printf.c:75
int tor_snprintf(char *str, size_t size, const char *format,...)
Definition: printf.c:27
int init_keys(void)
Definition: router.c:967
int server_identity_key_is_set(void)
Definition: router.c:412
Header file for router.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)
void or_state_mark_dirty(or_state_t *state, time_t when)
Definition: statefile.c:784
or_state_t * get_or_state(void)
Definition: statefile.c:220
Header for statefile.c.
unsigned int type
Definition: connection_st.h:50
int ShutdownWaitLength
uint64_t BandwidthRate
uint64_t AccountingMax
uint64_t RelayBandwidthRate
char * AccountingStart
time_t AccountingIntervalStart
Definition: or_state_st.h:32
time_t LastWritten
Definition: or_state_st.h:29
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
Definitions for timing-related constants.
#define TOR_USEC_PER_SEC
Definition: time.h:17
void format_iso_time(char *buf, time_t t)
Definition: time_fmt.c:326
void format_local_iso_time(char *buf, time_t t)
Definition: time_fmt.c:316
struct tm * tor_localtime_r(const time_t *timep, struct tm *result)
Definition: time_fmt.c:48
#define tor_assert(expr)
Definition: util_bug.h:103
void tor_strlower(char *s)
Definition: util_string.c:129