hibernate.c (44066B)
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 /* 20 hibernating, 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 25 hibernating, 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" 35 #include "core/mainloop/connection.h" 36 #include "core/or/connection_edge.h" 37 #include "core/or/connection_or.h" 38 #include "feature/control/control_events.h" 39 #include "lib/crypt_ops/crypto_rand.h" 40 #include "lib/defs/time.h" 41 #include "feature/hibernate/hibernate.h" 42 #include "core/mainloop/mainloop.h" 43 #include "feature/relay/router.h" 44 #include "app/config/statefile.h" 45 #include "lib/evloop/compat_libevent.h" 46 47 #include "core/or/or_connection_st.h" 48 #include "app/config/or_state_st.h" 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? */ 66 static 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. */ 69 static 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.) */ 73 static time_t shutdown_time = 0; 74 75 /** A timed event that we'll use when it's time to wake up from 76 * hibernation. */ 77 static mainloop_event_t *wakeup_event = NULL; 78 79 /** Possible accounting periods. */ 80 typedef enum { 81 UNIT_MONTH=1, UNIT_WEEK=2, UNIT_DAY=3, 82 } time_unit_t; 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? */ 119 static uint64_t n_bytes_read_in_interval = 0; 120 /** How many bytes have we written in this accounting interval? */ 121 static uint64_t n_bytes_written_in_interval = 0; 122 /** How many seconds have we been running this interval? */ 123 static uint32_t n_seconds_active_in_interval = 0; 124 /** How many seconds were we active in this interval before we hit our soft 125 * limit? */ 126 static int n_seconds_to_hit_soft_limit = 0; 127 /** When in this interval was the soft limit hit. */ 128 static time_t soft_limit_hit_at = 0; 129 /** How many bytes had we read/written when we hit the soft limit? */ 130 static uint64_t n_bytes_at_soft_limit = 0; 131 /** When did this accounting interval start? */ 132 static time_t interval_start_time = 0; 133 /** When will this accounting interval end? */ 134 static time_t interval_end_time = 0; 135 /** How far into the accounting interval should we hibernate? */ 136 static 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.) */ 139 static uint64_t expected_bandwidth_usage = 0; 140 /** What unit are we using for our accounting? */ 141 static time_unit_t cfg_unit = UNIT_MONTH; 142 143 /** How many days,hours,minutes into each unit does our accounting interval 144 * start? */ 145 /** @{ */ 146 static int cfg_start_day = 0, 147 cfg_start_hour = 0, 148 cfg_start_min = 0; 149 /** @} */ 150 151 static const char *hibernate_state_to_string(hibernate_state_t state); 152 static void reset_accounting(time_t now); 153 static int read_bandwidth_usage(void); 154 static time_t start_of_accounting_period_after(time_t now); 155 static time_t start_of_accounting_period_containing(time_t now); 156 static void accounting_set_wakeup_time(void); 157 static void on_hibernate_state_change(hibernate_state_t prev_state); 158 static void hibernate_schedule_wakeup_event(time_t now, time_t end_time); 159 static 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 */ 164 static const char * 165 hibernate_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. */ 189 int 190 accounting_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 */ 304 MOCK_IMPL(int, 305 accounting_is_enabled,(const or_options_t *options)) 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. */ 314 int 315 accounting_get_interval_length(void) 316 { 317 return (int)(interval_end_time - interval_start_time); 318 } 319 320 /** Return the time at which the current accounting interval will end. */ 321 MOCK_IMPL(time_t, 322 accounting_get_end_time,(void)) 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. */ 330 void 331 accounting_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> */ 343 static time_t 344 edge_of_accounting_period_containing(time_t now, int get_end) 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>. */ 405 static time_t 406 start_of_accounting_period_containing(time_t now) 407 { 408 return edge_of_accounting_period_containing(now, 0); 409 } 410 411 /** Return the start of the accounting period that comes after the one 412 * containing the time <b>now</b>. */ 413 static time_t 414 start_of_accounting_period_after(time_t now) 415 { 416 return edge_of_accounting_period_containing(now, 1); 417 } 418 419 /** Return the length of the accounting period containing the time 420 * <b>now</b>. */ 421 static long 422 length_of_accounting_period_containing(time_t now) 423 { 424 return edge_of_accounting_period_containing(now, 1) - 425 edge_of_accounting_period_containing(now, 0); 426 } 427 428 /** Initialize the accounting subsystem. */ 429 void 430 configure_accounting(time_t now) 431 { 432 time_t s_now; 433 /* Try to remember our recorded usage. */ 434 if (!interval_start_time) 435 read_bandwidth_usage(); /* If we fail, we'll leave values at zero, and 436 * reset below.*/ 437 438 s_now = start_of_accounting_period_containing(now); 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.*/ 447 interval_end_time = start_of_accounting_period_after(interval_start_time); 448 } else { 449 long duration = 450 length_of_accounting_period_containing(interval_start_time); 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); 459 interval_end_time = start_of_accounting_period_after(now); 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 } 472 accounting_set_wakeup_time(); 473 } 474 475 /** Return the relevant number of bytes sent/received this interval 476 * based on the set AccountingRule */ 477 uint64_t 478 get_accounting_bytes(void) 479 { 480 if (get_options()->AccountingRule == ACCT_SUM) 481 return n_bytes_read_in_interval+n_bytes_written_in_interval; 482 else if (get_options()->AccountingRule == ACCT_IN) 483 return n_bytes_read_in_interval; 484 else if (get_options()->AccountingRule == ACCT_OUT) 485 return n_bytes_written_in_interval; 486 else 487 return MAX(n_bytes_read_in_interval, n_bytes_written_in_interval); 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. */ 493 static void 494 update_expected_bandwidth(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 509 if (soft_limit_hit_at > interval_start_time && n_bytes_at_soft_limit && 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 / 516 (soft_limit_hit_at - interval_start_time); 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 */ 543 static void 544 reset_accounting(time_t now) 545 { 546 log_info(LD_ACCT, "Starting new accounting interval."); 547 update_expected_bandwidth(); 548 interval_start_time = start_of_accounting_period_containing(now); 549 interval_end_time = start_of_accounting_period_after(interval_start_time); 550 n_bytes_read_in_interval = 0; 551 n_bytes_written_in_interval = 0; 552 n_seconds_active_in_interval = 0; 553 n_bytes_at_soft_limit = 0; 554 soft_limit_hit_at = 0; 555 n_seconds_to_hit_soft_limit = 0; 556 } 557 558 /** Return true iff we should save our bandwidth usage to disk. */ 559 static inline int 560 time_to_record_bandwidth_usage(time_t now) 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 || 573 (interval_end_time && interval_end_time <= now)) { 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. */ 584 void 585 accounting_run_housekeeping(time_t now) 586 { 587 if (now >= interval_end_time) { 588 configure_accounting(now); 589 } 590 if (time_to_record_bandwidth_usage(now)) { 591 if (accounting_record_bandwidth_usage(now, get_or_state())) { 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. */ 599 static void 600 accounting_set_wakeup_time(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 607 if (! server_identity_key_is_set()) { 608 if (init_keys() < 0) { 609 log_err(LD_BUG, "Error initializing keys"); 610 tor_assert(0); 611 } 612 } 613 614 if (server_identity_key_is_set()) { 615 char buf[ISO_TIME_LEN+1]; 616 format_iso_time(buf, interval_start_time); 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 632 if (!expected_bandwidth_usage) { 633 char buf1[ISO_TIME_LEN+1]; 634 char buf2[ISO_TIME_LEN+1]; 635 format_local_iso_time(buf1, interval_start_time); 636 format_local_iso_time(buf2, interval_end_time); 637 interval_wakeup_time = interval_start_time; 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 = 648 (get_options()->AccountingMax/expected_bandwidth_usage)*60; 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) { 658 interval_wakeup_time = interval_start_time; 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. */ 667 interval_wakeup_time = interval_start_time + 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; 683 format_local_iso_time(buf1, interval_start_time); 684 format_local_iso_time(buf2, interval_wakeup_time); 685 format_local_iso_time(buf3, down_time); 686 format_local_iso_time(buf4, interval_end_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. */ 704 int 705 accounting_record_bandwidth_usage(time_t now, or_state_t *state) 706 { 707 /* Just update the state */ 708 state->AccountingIntervalStart = interval_start_time; 709 state->AccountingBytesReadInInterval = ROUND_UP(n_bytes_read_in_interval); 710 state->AccountingBytesWrittenInInterval = 711 ROUND_UP(n_bytes_written_in_interval); 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 719 or_state_mark_dirty(state, 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. */ 728 static int 729 read_bandwidth_usage(void) 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; 754 interval_start_time = state->AccountingIntervalStart; 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 { 767 soft_limit_hit_at = 0; 768 n_bytes_at_soft_limit = 0; 769 n_seconds_to_hit_soft_limit = 0; 770 } 771 772 { 773 char tbuf1[ISO_TIME_LEN+1]; 774 char tbuf2[ISO_TIME_LEN+1]; 775 format_iso_time(tbuf1, state->LastWritten); 776 format_iso_time(tbuf2, state->AccountingIntervalStart); 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), 787 (n_bytes_read_in_interval), 788 (n_bytes_written_in_interval)); 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. */ 796 static int 797 hibernate_hard_limit_reached(void) 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. */ 807 static int 808 hibernate_soft_limit_reached(void) 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 } 824 if (expected_bandwidth_usage) { 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. */ 839 static void 840 hibernate_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"); 849 tor_shutdown_event_loop_and_exit(0); 850 return; 851 } 852 853 if (new_state == HIBERNATE_STATE_LOWBANDWIDTH && 854 hibernate_state == HIBERNATE_STATE_LIVE) { 855 soft_limit_hit_at = now; 856 n_seconds_to_hit_soft_limit = n_seconds_active_in_interval; 857 n_bytes_at_soft_limit = get_accounting_bytes(); 858 } 859 860 /* close listeners. leave control listener(s). */ 861 connection_mark_all_noncontrol_listeners(); 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; 876 mainloop_schedule_shutdown(options->ShutdownWaitLength); 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 */ 898 hibernate_end_time = interval_end_time; 899 } 900 901 hibernate_state = new_state; 902 accounting_record_bandwidth_usage(now, get_or_state()); 903 904 or_state_mark_dirty(get_or_state(), 905 get_options()->AvoidDiskWrites ? now+600 : 0); 906 } 907 908 /** Called when we've been hibernating and our timeout is reached. */ 909 static void 910 hibernate_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. */ 926 void 927 hibernate_begin_shutdown(void) 928 { 929 hibernate_begin(HIBERNATE_STATE_EXITING, time(NULL)); 930 } 931 932 /** 933 * Return true iff we are currently shutting down. 934 */ 935 MOCK_IMPL(int, 936 we_are_shutting_down,(void)) 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 */ 945 MOCK_IMPL(int, 946 we_are_hibernating,(void)) 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 */ 955 MOCK_IMPL(int, 956 we_are_fully_hibernating,(void)) 957 { 958 return hibernate_state == HIBERNATE_STATE_DORMANT; 959 } 960 961 /** If we aren't currently dormant, close all connections and become 962 * dormant. */ 963 static void 964 hibernate_go_dormant(time_t now) 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)) || 983 (conn = connection_get_by_type(CONN_TYPE_AP)) || 984 (conn = connection_get_by_type(CONN_TYPE_EXIT))) { 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) { 995 connection_or_close_normally(TO_OR_CONN(conn), 0); 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) 1005 hibernate_end_time = interval_wakeup_time; 1006 else 1007 hibernate_end_time = interval_end_time; 1008 1009 accounting_record_bandwidth_usage(now, get_or_state()); 1010 1011 or_state_mark_dirty(get_or_state(), 1012 get_options()->AvoidDiskWrites ? now+600 : 0); 1013 1014 hibernate_schedule_wakeup_event(now, hibernate_end_time); 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 */ 1025 static void 1026 hibernate_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) { 1039 wakeup_event = mainloop_event_postloop_new(wakeup_event_callback, NULL); 1040 } 1041 1042 mainloop_event_schedule(wakeup_event, &delay); 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 **/ 1049 static void 1050 wakeup_event_callback(mainloop_event_t *ev, void *data) 1051 { 1052 (void) ev; 1053 (void) data; 1054 1055 const time_t now = time(NULL); 1056 accounting_run_housekeeping(now); 1057 consider_hibernation(now); 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) 1065 hibernate_end_time = interval_wakeup_time; 1066 else 1067 hibernate_end_time = interval_end_time; 1068 1069 hibernate_schedule_wakeup_event(now, hibernate_end_time); 1070 } 1071 1072 /** Called when hibernate_end_time has arrived. */ 1073 static void 1074 hibernate_end_time_elapsed(time_t now) 1075 { 1076 char buf[ISO_TIME_LEN+1]; 1077 1078 /* The interval has ended, or it is wakeup time. Find out which. */ 1079 accounting_run_housekeeping(now); 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. */ 1087 hibernate_end_time = interval_wakeup_time; 1088 format_iso_time(buf,interval_wakeup_time); 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); 1094 hibernate_go_dormant(now); 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 */ 1106 void 1107 consider_hibernation(time_t now) 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) { 1117 tor_assert(shutdown_time); 1118 if (shutdown_time <= now) { 1119 log_notice(LD_BUG, "Mainloop did not catch shutdown event; exiting."); 1120 tor_shutdown_event_loop_and_exit(0); 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. */ 1127 tor_assert(hibernate_end_time); 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 { 1133 hibernate_end_time_elapsed(now); 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) { 1141 if (hibernate_soft_limit_reached()) { 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) { 1147 format_local_iso_time(buf,interval_wakeup_time); 1148 log_notice(LD_ACCT, 1149 "Commencing hibernation. We will wake up at %s local time.", 1150 buf); 1151 hibernate_go_dormant(now); 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) { 1159 hibernate_end_time_elapsed(now); 1160 } else if (hibernate_hard_limit_reached()) { 1161 hibernate_go_dormant(now); 1162 } else if (hibernate_end_time <= now) { 1163 /* The hibernation period ended while we were still in lowbandwidth.*/ 1164 hibernate_end_time_elapsed(now); 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. */ 1178 int 1179 getinfo_helper_accounting(control_connection_t *conn, 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, 1192 (n_bytes_read_in_interval), 1193 (n_bytes_written_in_interval)); 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); 1226 format_iso_time(*answer, interval_start_time); 1227 } else if (!strcmp(question, "accounting/interval-wake")) { 1228 *answer = tor_malloc(ISO_TIME_LEN+1); 1229 format_iso_time(*answer, interval_wakeup_time); 1230 } else if (!strcmp(question, "accounting/interval-end")) { 1231 *answer = tor_malloc(ISO_TIME_LEN+1); 1232 format_iso_time(*answer, interval_end_time); 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 */ 1244 static void 1245 on_hibernate_state_change(hibernate_state_t prev_state) 1246 { 1247 control_event_server_status(LOG_NOTICE, 1248 "HIBERNATION_STATUS STATUS=%s", 1249 hibernate_state_to_string(hibernate_state)); 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) { 1257 rescan_periodic_events(get_options()); 1258 } 1259 } 1260 1261 /** Free all resources held by the accounting module */ 1262 void 1263 accounting_free_all(void) 1264 { 1265 mainloop_event_free(wakeup_event); 1266 hibernate_state = HIBERNATE_STATE_INITIAL; 1267 hibernate_end_time = 0; 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 */ 1276 void 1277 hibernate_set_state_for_testing_(hibernate_state_t newstate) 1278 { 1279 hibernate_state = newstate; 1280 } 1281 #endif /* defined(TOR_UNIT_TESTS) */