Tor 0.4.9.8
Loading...
Searching...
No Matches
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
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
410
411/** Return the start of the accounting period that comes after the one
412 * containing the time <b>now</b>. */
413static time_t
418
419/** Return the length of the accounting period containing the time
420 * <b>now</b>. */
421static long
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
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 shutting down.
934 */
935MOCK_IMPL(int,
937{
938 return hibernate_state == HIBERNATE_STATE_EXITING;
939}
940
941/**
942 * Return true iff we are currently hibernating -- that is, if we are in
943 * any non-live state.
944 */
945MOCK_IMPL(int,
947{
948 return hibernate_state != HIBERNATE_STATE_LIVE;
949}
950
951/**
952 * Return true iff we are currently _fully_ hibernating -- that is, if we are
953 * in a state where we expect to handle no network activity at all.
954 */
955MOCK_IMPL(int,
957{
958 return hibernate_state == HIBERNATE_STATE_DORMANT;
959}
960
961/** If we aren't currently dormant, close all connections and become
962 * dormant. */
963static void
965{
966 connection_t *conn;
967
968 if (hibernate_state == HIBERNATE_STATE_DORMANT)
969 return;
970 else if (hibernate_state == HIBERNATE_STATE_LOWBANDWIDTH)
971 hibernate_state = HIBERNATE_STATE_DORMANT;
972 else
973 hibernate_begin(HIBERNATE_STATE_DORMANT, now);
974
975 log_notice(LD_ACCT,"Going dormant. Blowing away remaining connections.");
976
977 /* Close all OR/AP/exit conns. Leave dir conns because we still want
978 * to be able to upload server descriptors so clients know we're still
979 * running, and download directories so we can detect if we're obsolete.
980 * Leave control conns because we still want to be controllable.
981 */
982 while ((conn = connection_get_by_type(CONN_TYPE_OR)) ||
985 if (CONN_IS_EDGE(conn)) {
986 connection_edge_end(TO_EDGE_CONN(conn), END_STREAM_REASON_HIBERNATING);
987 }
988 log_info(LD_NET,"Closing conn type %d", conn->type);
989 if (conn->type == CONN_TYPE_AP) {
990 /* send socks failure if needed */
991 connection_mark_unattached_ap(TO_ENTRY_CONN(conn),
992 END_STREAM_REASON_HIBERNATING);
993 } else if (conn->type == CONN_TYPE_OR) {
994 if (TO_OR_CONN(conn)->chan) {
996 } else {
997 connection_mark_for_close(conn);
998 }
999 } else {
1000 connection_mark_for_close(conn);
1001 }
1002 }
1003
1004 if (now < interval_wakeup_time)
1006 else
1008
1010
1012 get_options()->AvoidDiskWrites ? now+600 : 0);
1013
1015}
1016
1017/**
1018 * Schedule a mainloop event at <b>end_time</b> to wake up from a dormant
1019 * state. We can't rely on this happening from second_elapsed_callback,
1020 * since second_elapsed_callback will be shut down when we're dormant.
1021 *
1022 * (Note that We might immediately go back to sleep after we set the next
1023 * wakeup time.)
1024 */
1025static void
1026hibernate_schedule_wakeup_event(time_t now, time_t end_time)
1027{
1028 struct timeval delay = { 0, 0 };
1029
1030 if (now >= end_time) {
1031 // In these cases we always wait at least a second, to avoid running
1032 // the callback in a tight loop.
1033 delay.tv_sec = 1;
1034 } else {
1035 delay.tv_sec = (end_time - now);
1036 }
1037
1038 if (!wakeup_event) {
1040 }
1041
1043}
1044
1045/**
1046 * Called at the end of the interval, or at the wakeup time of the current
1047 * interval, to exit the dormant state.
1048 **/
1049static void
1051{
1052 (void) ev;
1053 (void) data;
1054
1055 const time_t now = time(NULL);
1058 if (hibernate_state != HIBERNATE_STATE_DORMANT) {
1059 /* We woke up, so everything's great here */
1060 return;
1061 }
1062
1063 /* We're still dormant. */
1064 if (now < interval_wakeup_time)
1066 else
1068
1070}
1071
1072/** Called when hibernate_end_time has arrived. */
1073static void
1075{
1076 char buf[ISO_TIME_LEN+1];
1077
1078 /* The interval has ended, or it is wakeup time. Find out which. */
1080 if (interval_wakeup_time <= now) {
1081 /* The interval hasn't changed, but interval_wakeup_time has passed.
1082 * It's time to wake up and start being a server. */
1083 hibernate_end(HIBERNATE_STATE_LIVE);
1084 return;
1085 } else {
1086 /* The interval has changed, and it isn't time to wake up yet. */
1089 if (hibernate_state != HIBERNATE_STATE_DORMANT) {
1090 /* We weren't sleeping before; we should sleep now. */
1091 log_notice(LD_ACCT,
1092 "Accounting period ended. Commencing hibernation until "
1093 "%s UTC", buf);
1095 } else {
1096 log_notice(LD_ACCT,
1097 "Accounting period ended. This period, we will hibernate"
1098 " until %s UTC",buf);
1099 }
1100 }
1101}
1102
1103/** Consider our environment and decide if it's time
1104 * to start/stop hibernating.
1105 */
1106void
1108{
1109 int accounting_enabled = get_options()->AccountingMax != 0;
1110 char buf[ISO_TIME_LEN+1];
1111 hibernate_state_t prev_state = hibernate_state;
1112
1113 /* If we're in 'exiting' mode, then we just shut down after the interval
1114 * elapses. The mainloop was supposed to catch this via
1115 * mainloop_schedule_shutdown(), but apparently it didn't. */
1116 if (hibernate_state == HIBERNATE_STATE_EXITING) {
1118 if (shutdown_time <= now) {
1119 log_notice(LD_BUG, "Mainloop did not catch shutdown event; exiting.");
1121 }
1122 return; /* if exiting soon, don't worry about bandwidth limits */
1123 }
1124
1125 if (hibernate_state == HIBERNATE_STATE_DORMANT) {
1126 /* We've been hibernating because of bandwidth accounting. */
1128 if (hibernate_end_time > now && accounting_enabled) {
1129 /* If we're hibernating, don't wake up until it's time, regardless of
1130 * whether we're in a new interval. */
1131 return;
1132 } else {
1134 }
1135 }
1136
1137 /* Else, we aren't hibernating. See if it's time to start hibernating, or to
1138 * go dormant. */
1139 if (hibernate_state == HIBERNATE_STATE_LIVE ||
1140 hibernate_state == HIBERNATE_STATE_INITIAL) {
1142 log_notice(LD_ACCT,
1143 "Bandwidth soft limit reached; commencing hibernation. "
1144 "No new connections will be accepted");
1145 hibernate_begin(HIBERNATE_STATE_LOWBANDWIDTH, now);
1146 } else if (accounting_enabled && now < interval_wakeup_time) {
1148 log_notice(LD_ACCT,
1149 "Commencing hibernation. We will wake up at %s local time.",
1150 buf);
1152 } else if (hibernate_state == HIBERNATE_STATE_INITIAL) {
1153 hibernate_end(HIBERNATE_STATE_LIVE);
1154 }
1155 }
1156
1157 if (hibernate_state == HIBERNATE_STATE_LOWBANDWIDTH) {
1158 if (!accounting_enabled) {
1160 } else if (hibernate_hard_limit_reached()) {
1162 } else if (hibernate_end_time <= now) {
1163 /* The hibernation period ended while we were still in lowbandwidth.*/
1165 }
1166 }
1167
1168 /* Dispatch a controller event if the hibernation state changed. */
1169 if (hibernate_state != prev_state)
1170 on_hibernate_state_change(prev_state);
1171}
1172
1173/** Helper function: called when we get a GETINFO request for an
1174 * accounting-related key on the control connection <b>conn</b>. If we can
1175 * answer the request for <b>question</b>, then set *<b>answer</b> to a newly
1176 * allocated string holding the result. Otherwise, set *<b>answer</b> to
1177 * NULL. */
1178int
1180 const char *question, char **answer,
1181 const char **errmsg)
1182{
1183 (void) conn;
1184 (void) errmsg;
1185 if (!strcmp(question, "accounting/enabled")) {
1186 *answer = tor_strdup(accounting_is_enabled(get_options()) ? "1" : "0");
1187 } else if (!strcmp(question, "accounting/hibernating")) {
1188 *answer = tor_strdup(hibernate_state_to_string(hibernate_state));
1189 tor_strlower(*answer);
1190 } else if (!strcmp(question, "accounting/bytes")) {
1191 tor_asprintf(answer, "%"PRIu64" %"PRIu64,
1194 } else if (!strcmp(question, "accounting/bytes-left")) {
1195 uint64_t limit = get_options()->AccountingMax;
1196 if (get_options()->AccountingRule == ACCT_SUM) {
1197 uint64_t total_left = 0;
1198 uint64_t total_bytes = get_accounting_bytes();
1199 if (total_bytes < limit)
1200 total_left = limit - total_bytes;
1201 tor_asprintf(answer, "%"PRIu64" %"PRIu64,
1202 (total_left), (total_left));
1203 } else if (get_options()->AccountingRule == ACCT_IN) {
1204 uint64_t read_left = 0;
1205 if (n_bytes_read_in_interval < limit)
1206 read_left = limit - n_bytes_read_in_interval;
1207 tor_asprintf(answer, "%"PRIu64" %"PRIu64,
1208 (read_left), (limit));
1209 } else if (get_options()->AccountingRule == ACCT_OUT) {
1210 uint64_t write_left = 0;
1211 if (n_bytes_written_in_interval < limit)
1212 write_left = limit - n_bytes_written_in_interval;
1213 tor_asprintf(answer, "%"PRIu64" %"PRIu64,
1214 (limit), (write_left));
1215 } else {
1216 uint64_t read_left = 0, write_left = 0;
1217 if (n_bytes_read_in_interval < limit)
1218 read_left = limit - n_bytes_read_in_interval;
1219 if (n_bytes_written_in_interval < limit)
1220 write_left = limit - n_bytes_written_in_interval;
1221 tor_asprintf(answer, "%"PRIu64" %"PRIu64,
1222 (read_left), (write_left));
1223 }
1224 } else if (!strcmp(question, "accounting/interval-start")) {
1225 *answer = tor_malloc(ISO_TIME_LEN+1);
1227 } else if (!strcmp(question, "accounting/interval-wake")) {
1228 *answer = tor_malloc(ISO_TIME_LEN+1);
1230 } else if (!strcmp(question, "accounting/interval-end")) {
1231 *answer = tor_malloc(ISO_TIME_LEN+1);
1233 } else {
1234 *answer = NULL;
1235 }
1236 return 0;
1237}
1238
1239/**
1240 * Helper function: called when the hibernation state changes, and sends a
1241 * SERVER_STATUS event to notify interested controllers of the accounting
1242 * state change.
1243 */
1244static void
1245on_hibernate_state_change(hibernate_state_t prev_state)
1246{
1248 "HIBERNATION_STATUS STATUS=%s",
1250
1251 /* We are changing hibernation state, this can affect the main loop event
1252 * list. Rescan it to update the events state. We do this whatever the new
1253 * hibernation state because they can each possibly affect an event. The
1254 * initial state means we are booting up so we shouldn't scan here because
1255 * at this point the events in the list haven't been initialized. */
1256 if (prev_state != HIBERNATE_STATE_INITIAL) {
1258 }
1259}
1260
1261/** Free all resources held by the accounting module */
1262void
1264{
1265 mainloop_event_free(wakeup_event);
1266 hibernate_state = HIBERNATE_STATE_INITIAL;
1268 shutdown_time = 0;
1269}
1270
1271#ifdef TOR_UNIT_TESTS
1272/**
1273 * Manually change the hibernation state. Private; used only by the unit
1274 * tests.
1275 */
1276void
1277hibernate_set_state_for_testing_(hibernate_state_t newstate)
1278{
1279 hibernate_state = newstate;
1280}
1281#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.
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:948
Header file for config.c.
void connection_mark_all_noncontrol_listeners(void)
connection_t * connection_get_by_type(int type)
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)
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
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:1050
static void on_hibernate_state_change(hibernate_state_t prev_state)
Definition hibernate.c:1245
int getinfo_helper_accounting(control_connection_t *conn, const char *question, char **answer, const char **errmsg)
Definition hibernate.c:1179
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:1107
int we_are_fully_hibernating(void)
Definition hibernate.c:956
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
int we_are_shutting_down(void)
Definition hibernate.c:936
static void hibernate_schedule_wakeup_event(time_t now, time_t end_time)
Definition hibernate.c:1026
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:1263
void accounting_run_housekeeping(time_t now)
Definition hibernate.c:585
int we_are_hibernating(void)
Definition hibernate.c:946
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:1074
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:964
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:2565
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:994
int server_identity_key_is_set(void)
Definition router.c:437
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
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)
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)