hibernate.c
上传用户:awang829
上传日期:2019-07-14
资源大小:2356k
文件大小:30k
源码类别:

网络

开发平台:

Unix_Linux

  1. /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  2.  * Copyright (c) 2007-2009, The Tor Project, Inc. */
  3. /* See LICENSE for licensing information */
  4. /**
  5.  * file hibernate.c
  6.  * brief Functions to close listeners, stop allowing new circuits,
  7.  * etc in preparation for closing down or going dormant; and to track
  8.  * bandwidth and time intervals to know when to hibernate and when to
  9.  * stop hibernating.
  10.  **/
  11. /*
  12. hibernating, phase 1:
  13.   - send destroy in response to create cells
  14.   - send end (policy failed) in response to begin cells
  15.   - close an OR conn when it has no circuits
  16. hibernating, phase 2:
  17.   (entered when bandwidth hard limit reached)
  18.   - close all OR/AP/exit conns)
  19. */
  20. #include "or.h"
  21. /** Possible values of hibernate_state */
  22. typedef enum {
  23.   /** We are running normally. */
  24.   HIBERNATE_STATE_LIVE=1,
  25.   /** We're trying to shut down cleanly, and we'll kill all active connections
  26.    * at shutdown_time. */
  27.   HIBERNATE_STATE_EXITING=2,
  28.   /** We're running low on allocated bandwidth for this period, so we won't
  29.    * accept any new connections. */
  30.   HIBERNATE_STATE_LOWBANDWIDTH=3,
  31.   /** We are hibernating, and we won't wake up till there's more bandwidth to
  32.    * use. */
  33.   HIBERNATE_STATE_DORMANT=4
  34. } hibernate_state_t;
  35. extern long stats_n_seconds_working; /* published uptime */
  36. /** Are we currently awake, asleep, running out of bandwidth, or shutting
  37.  * down? */
  38. static hibernate_state_t hibernate_state = HIBERNATE_STATE_LIVE;
  39. /** If are hibernating, when do we plan to wake up? Set to 0 if we
  40.  * aren't hibernating. */
  41. static time_t hibernate_end_time = 0;
  42. /** If we are shutting down, when do we plan finally exit? Set to 0 if
  43.  * we aren't shutting down. */
  44. static time_t shutdown_time = 0;
  45. /** Possible accounting periods. */
  46. typedef enum {
  47.   UNIT_MONTH=1, UNIT_WEEK=2, UNIT_DAY=3,
  48. } time_unit_t;
  49. /* Fields for accounting logic.  Accounting overview:
  50.  *
  51.  * Accounting is designed to ensure that no more than N bytes are sent in
  52.  * either direction over a given interval (currently, one month, one week, or
  53.  * one day) We could
  54.  * try to do this by choking our bandwidth to a trickle, but that
  55.  * would make our streams useless.  Instead, we estimate what our
  56.  * bandwidth usage will be, and guess how long we'll be able to
  57.  * provide that much bandwidth before hitting our limit.  We then
  58.  * choose a random time within the accounting interval to come up (so
  59.  * that we don't get 50 Tors running on the 1st of the month and none
  60.  * on the 30th).
  61.  *
  62.  * Each interval runs as follows:
  63.  *
  64.  * 1. We guess our bandwidth usage, based on how much we used
  65.  *     last time.  We choose a "wakeup time" within the interval to come up.
  66.  * 2. Until the chosen wakeup time, we hibernate.
  67.  * 3. We come up at the wakeup time, and provide bandwidth until we are
  68.  *    "very close" to running out.
  69.  * 4. Then we go into low-bandwidth mode, and stop accepting new
  70.  *    connections, but provide bandwidth until we run out.
  71.  * 5. Then we hibernate until the end of the interval.
  72.  *
  73.  * If the interval ends before we run out of bandwidth, we go back to
  74.  * step one.
  75.  */
  76. /** How many bytes have we read in this accounting interval? */
  77. static uint64_t n_bytes_read_in_interval = 0;
  78. /** How many bytes have we written in this accounting interval? */
  79. static uint64_t n_bytes_written_in_interval = 0;
  80. /** How many seconds have we been running this interval? */
  81. static uint32_t n_seconds_active_in_interval = 0;
  82. /** When did this accounting interval start? */
  83. static time_t interval_start_time = 0;
  84. /** When will this accounting interval end? */
  85. static time_t interval_end_time = 0;
  86. /** How far into the accounting interval should we hibernate? */
  87. static time_t interval_wakeup_time = 0;
  88. /** How much bandwidth do we 'expect' to use per minute?  (0 if we have no
  89.  * info from the last period.) */
  90. static uint64_t expected_bandwidth_usage = 0;
  91. /** What unit are we using for our accounting? */
  92. static time_unit_t cfg_unit = UNIT_MONTH;
  93. /** How many days,hours,minutes into each unit does our accounting interval
  94.  * start? */
  95. static int cfg_start_day = 0,
  96.            cfg_start_hour = 0,
  97.            cfg_start_min = 0;
  98. static void reset_accounting(time_t now);
  99. static int read_bandwidth_usage(void);
  100. static time_t start_of_accounting_period_after(time_t now);
  101. static time_t start_of_accounting_period_containing(time_t now);
  102. static void accounting_set_wakeup_time(void);
  103. /* ************
  104.  * Functions for bandwidth accounting.
  105.  * ************/
  106. /** Configure accounting start/end time settings based on
  107.  * options->AccountingStart.  Return 0 on success, -1 on failure. If
  108.  * <b>validate_only</b> is true, do not change the current settings. */
  109. int
  110. accounting_parse_options(or_options_t *options, int validate_only)
  111. {
  112.   time_unit_t unit;
  113.   int ok, idx;
  114.   long d,h,m;
  115.   smartlist_t *items;
  116.   const char *v = options->AccountingStart;
  117.   const char *s;
  118.   char *cp;
  119.   if (!v) {
  120.     if (!validate_only) {
  121.       cfg_unit = UNIT_MONTH;
  122.       cfg_start_day = 1;
  123.       cfg_start_hour = 0;
  124.       cfg_start_min = 0;
  125.     }
  126.     return 0;
  127.   }
  128.   items = smartlist_create();
  129.   smartlist_split_string(items, v, NULL,
  130.                          SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK,0);
  131.   if (smartlist_len(items)<2) {
  132.     log_warn(LD_CONFIG, "Too few arguments to AccountingStart");
  133.     goto err;
  134.   }
  135.   s = smartlist_get(items,0);
  136.   if (0==strcasecmp(s, "month")) {
  137.     unit = UNIT_MONTH;
  138.   } else if (0==strcasecmp(s, "week")) {
  139.     unit = UNIT_WEEK;
  140.   } else if (0==strcasecmp(s, "day")) {
  141.     unit = UNIT_DAY;
  142.   } else {
  143.     log_warn(LD_CONFIG,
  144.              "Unrecognized accounting unit '%s': only 'month', 'week',"
  145.              " and 'day' are supported.", s);
  146.     goto err;
  147.   }
  148.   switch (unit) {
  149.   case UNIT_WEEK:
  150.     d = tor_parse_long(smartlist_get(items,1), 10, 1, 7, &ok, NULL);
  151.     if (!ok) {
  152.       log_warn(LD_CONFIG, "Weekly accounting must begin on a day between "
  153.                "1 (Monday) and 7 (Sunday)");
  154.       goto err;
  155.     }
  156.     break;
  157.   case UNIT_MONTH:
  158.     d = tor_parse_long(smartlist_get(items,1), 10, 1, 28, &ok, NULL);
  159.     if (!ok) {
  160.       log_warn(LD_CONFIG, "Monthly accounting must begin on a day between "
  161.                "1 and 28");
  162.       goto err;
  163.     }
  164.     break;
  165.   case UNIT_DAY:
  166.     d = 0;
  167.     break;
  168.   default:
  169.     tor_assert(0);
  170.   }
  171.   idx = unit==UNIT_DAY?1:2;
  172.   if (smartlist_len(items) != (idx+1)) {
  173.     log_warn(LD_CONFIG,"Accounting unit '%s' requires %d argument%s.",
  174.              s, idx, (idx>1)?"s":"");
  175.     goto err;
  176.   }
  177.   s = smartlist_get(items, idx);
  178.   h = tor_parse_long(s, 10, 0, 23, &ok, &cp);
  179.   if (!ok) {
  180.     log_warn(LD_CONFIG,"Accounting start time not parseable: bad hour.");
  181.     goto err;
  182.   }
  183.   if (!cp || *cp!=':') {
  184.     log_warn(LD_CONFIG,
  185.              "Accounting start time not parseable: not in HH:MM format");
  186.     goto err;
  187.   }
  188.   m = tor_parse_long(cp+1, 10, 0, 59, &ok, &cp);
  189.   if (!ok) {
  190.     log_warn(LD_CONFIG, "Accounting start time not parseable: bad minute");
  191.     goto err;
  192.   }
  193.   if (!cp || *cp!='') {
  194.     log_warn(LD_CONFIG,
  195.              "Accounting start time not parseable: not in HH:MM format");
  196.     goto err;
  197.   }
  198.   if (!validate_only) {
  199.     cfg_unit = unit;
  200.     cfg_start_day = (int)d;
  201.     cfg_start_hour = (int)h;
  202.     cfg_start_min = (int)m;
  203.   }
  204.   SMARTLIST_FOREACH(items, char *, item, tor_free(item));
  205.   smartlist_free(items);
  206.   return 0;
  207.  err:
  208.   SMARTLIST_FOREACH(items, char *, item, tor_free(item));
  209.   smartlist_free(items);
  210.   return -1;
  211. }
  212. /** If we want to manage the accounting system and potentially
  213.  * hibernate, return 1, else return 0.
  214.  */
  215. int
  216. accounting_is_enabled(or_options_t *options)
  217. {
  218.   if (options->AccountingMax)
  219.     return 1;
  220.   return 0;
  221. }
  222. /** Called from main.c to tell us that <b>seconds</b> seconds have
  223.  * passed, <b>n_read</b> bytes have been read, and <b>n_written</b>
  224.  * bytes have been written. */
  225. void
  226. accounting_add_bytes(size_t n_read, size_t n_written, int seconds)
  227. {
  228.   n_bytes_read_in_interval += n_read;
  229.   n_bytes_written_in_interval += n_written;
  230.   /* If we haven't been called in 10 seconds, we're probably jumping
  231.    * around in time. */
  232.   n_seconds_active_in_interval += (seconds < 10) ? seconds : 0;
  233. }
  234. /** If get_end, return the end of the accounting period that contains
  235.  * the time <b>now</b>.  Else, return the start of the accounting
  236.  * period that contains the time <b>now</b> */
  237. static time_t
  238. edge_of_accounting_period_containing(time_t now, int get_end)
  239. {
  240.   int before;
  241.   struct tm tm;
  242.   tor_localtime_r(&now, &tm);
  243.   /* Set 'before' to true iff the current time is before the hh:mm
  244.    * changeover time for today. */
  245.   before = tm.tm_hour < cfg_start_hour ||
  246.     (tm.tm_hour == cfg_start_hour && tm.tm_min < cfg_start_min);
  247.   /* Dispatch by unit.  First, find the start day of the given period;
  248.    * then, if get_end is true, increment to the end day. */
  249.   switch (cfg_unit)
  250.     {
  251.     case UNIT_MONTH: {
  252.       /* If this is before the Nth, we want the Nth of last month. */
  253.       if (tm.tm_mday < cfg_start_day ||
  254.           (tm.tm_mday < cfg_start_day && before)) {
  255.         --tm.tm_mon;
  256.       }
  257.       /* Otherwise, the month is correct. */
  258.       tm.tm_mday = cfg_start_day;
  259.       if (get_end)
  260.         ++tm.tm_mon;
  261.       break;
  262.     }
  263.     case UNIT_WEEK: {
  264.       /* What is the 'target' day of the week in struct tm format? (We
  265.          say Sunday==7; struct tm says Sunday==0.) */
  266.       int wday = cfg_start_day % 7;
  267.       /* How many days do we subtract from today to get to the right day? */
  268.       int delta = (7+tm.tm_wday-wday)%7;
  269.       /* If we are on the right day, but the changeover hasn't happened yet,
  270.        * then subtract a whole week. */
  271.       if (delta == 0 && before)
  272.         delta = 7;
  273.       tm.tm_mday -= delta;
  274.       if (get_end)
  275.         tm.tm_mday += 7;
  276.       break;
  277.     }
  278.     case UNIT_DAY:
  279.       if (before)
  280.         --tm.tm_mday;
  281.       if (get_end)
  282.         ++tm.tm_mday;
  283.       break;
  284.     default:
  285.       tor_assert(0);
  286.   }
  287.   tm.tm_hour = cfg_start_hour;
  288.   tm.tm_min = cfg_start_min;
  289.   tm.tm_sec = 0;
  290.   tm.tm_isdst = -1; /* Autodetect DST */
  291.   return mktime(&tm);
  292. }
  293. /** Return the start of the accounting period containing the time
  294.  * <b>now</b>. */
  295. static time_t
  296. start_of_accounting_period_containing(time_t now)
  297. {
  298.   return edge_of_accounting_period_containing(now, 0);
  299. }
  300. /** Return the start of the accounting period that comes after the one
  301.  * containing the time <b>now</b>. */
  302. static time_t
  303. start_of_accounting_period_after(time_t now)
  304. {
  305.   return edge_of_accounting_period_containing(now, 1);
  306. }
  307. /** Initialize the accounting subsystem. */
  308. void
  309. configure_accounting(time_t now)
  310. {
  311.   /* Try to remember our recorded usage. */
  312.   if (!interval_start_time)
  313.     read_bandwidth_usage(); /* If we fail, we'll leave values at zero, and
  314.                              * reset below.*/
  315.   if (!interval_start_time ||
  316.       start_of_accounting_period_after(interval_start_time) <= now) {
  317.     /* We didn't have recorded usage, or we don't have recorded usage
  318.      * for this interval. Start a new interval. */
  319.     log_info(LD_ACCT, "Starting new accounting interval.");
  320.     reset_accounting(now);
  321.   } else if (interval_start_time ==
  322.         start_of_accounting_period_containing(interval_start_time)) {
  323.     log_info(LD_ACCT, "Continuing accounting interval.");
  324.     /* We are in the interval we thought we were in. Do nothing.*/
  325.     interval_end_time = start_of_accounting_period_after(interval_start_time);
  326.   } else {
  327.     log_warn(LD_ACCT,
  328.              "Mismatched accounting interval; starting a fresh one.");
  329.     reset_accounting(now);
  330.   }
  331.   accounting_set_wakeup_time();
  332. }
  333. /** Set expected_bandwidth_usage based on how much we sent/received
  334.  * per minute last interval (if we were up for at least 30 minutes),
  335.  * or based on our declared bandwidth otherwise. */
  336. static void
  337. update_expected_bandwidth(void)
  338. {
  339.   uint64_t used, expected;
  340.   uint64_t max_configured = (get_options()->BandwidthRate * 60);
  341.   if (n_seconds_active_in_interval < 1800) {
  342.     /* If we haven't gotten enough data last interval, set 'expected'
  343.      * to 0.  This will set our wakeup to the start of the interval.
  344.      * Next interval, we'll choose our starting time based on how much
  345.      * we sent this interval.
  346.      */
  347.     expected = 0;
  348.   } else {
  349.     used = n_bytes_written_in_interval < n_bytes_read_in_interval ?
  350.       n_bytes_read_in_interval : n_bytes_written_in_interval;
  351.     expected = used / (n_seconds_active_in_interval / 60);
  352.     if (expected > max_configured)
  353.       expected = max_configured;
  354.   }
  355.   expected_bandwidth_usage = expected;
  356. }
  357. /** Called at the start of a new accounting interval: reset our
  358.  * expected bandwidth usage based on what happened last time, set up
  359.  * the start and end of the interval, and clear byte/time totals.
  360.  */
  361. static void
  362. reset_accounting(time_t now)
  363. {
  364.   log_info(LD_ACCT, "Starting new accounting interval.");
  365.   update_expected_bandwidth();
  366.   interval_start_time = start_of_accounting_period_containing(now);
  367.   interval_end_time = start_of_accounting_period_after(interval_start_time);
  368.   n_bytes_read_in_interval = 0;
  369.   n_bytes_written_in_interval = 0;
  370.   n_seconds_active_in_interval = 0;
  371. }
  372. /** Return true iff we should save our bandwidth usage to disk. */
  373. static INLINE int
  374. time_to_record_bandwidth_usage(time_t now)
  375. {
  376.   /* Note every 600 sec */
  377. #define NOTE_INTERVAL (600)
  378.   /* Or every 20 megabytes */
  379. #define NOTE_BYTES 20*(1024*1024)
  380.   static uint64_t last_read_bytes_noted = 0;
  381.   static uint64_t last_written_bytes_noted = 0;
  382.   static time_t last_time_noted = 0;
  383.   if (last_time_noted + NOTE_INTERVAL <= now ||
  384.       last_read_bytes_noted + NOTE_BYTES <= n_bytes_read_in_interval ||
  385.       last_written_bytes_noted + NOTE_BYTES <= n_bytes_written_in_interval ||
  386.       (interval_end_time && interval_end_time <= now)) {
  387.     last_time_noted = now;
  388.     last_read_bytes_noted = n_bytes_read_in_interval;
  389.     last_written_bytes_noted = n_bytes_written_in_interval;
  390.     return 1;
  391.   }
  392.   return 0;
  393. }
  394. /** Invoked once per second.  Checks whether it is time to hibernate,
  395.  * record bandwidth used, etc.  */
  396. void
  397. accounting_run_housekeeping(time_t now)
  398. {
  399.   if (now >= interval_end_time) {
  400.     configure_accounting(now);
  401.   }
  402.   if (time_to_record_bandwidth_usage(now)) {
  403.     if (accounting_record_bandwidth_usage(now, get_or_state())) {
  404.       log_warn(LD_FS, "Couldn't record bandwidth usage to disk.");
  405.     }
  406.   }
  407. }
  408. /** When we have no idea how fast we are, how long do we assume it will take
  409.  * us to exhaust our bandwidth? */
  410. #define GUESS_TIME_TO_USE_BANDWIDTH (24*60*60)
  411. /** Based on our interval and our estimated bandwidth, choose a
  412.  * deterministic (but random-ish) time to wake up. */
  413. static void
  414. accounting_set_wakeup_time(void)
  415. {
  416.   char buf[ISO_TIME_LEN+1];
  417.   char digest[DIGEST_LEN];
  418.   crypto_digest_env_t *d_env;
  419.   int time_in_interval;
  420.   uint64_t time_to_exhaust_bw;
  421.   int time_to_consider;
  422.   if (! identity_key_is_set()) {
  423.     if (init_keys() < 0) {
  424.       log_err(LD_BUG, "Error initializing keys");
  425.       tor_assert(0);
  426.     }
  427.   }
  428.   format_iso_time(buf, interval_start_time);
  429.   crypto_pk_get_digest(get_identity_key(), digest);
  430.   d_env = crypto_new_digest_env();
  431.   crypto_digest_add_bytes(d_env, buf, ISO_TIME_LEN);
  432.   crypto_digest_add_bytes(d_env, digest, DIGEST_LEN);
  433.   crypto_digest_get_digest(d_env, digest, DIGEST_LEN);
  434.   crypto_free_digest_env(d_env);
  435.   if (!expected_bandwidth_usage) {
  436.     char buf1[ISO_TIME_LEN+1];
  437.     char buf2[ISO_TIME_LEN+1];
  438.     format_local_iso_time(buf1, interval_start_time);
  439.     format_local_iso_time(buf2, interval_end_time);
  440.     time_to_exhaust_bw = GUESS_TIME_TO_USE_BANDWIDTH;
  441.     interval_wakeup_time = interval_start_time;
  442.     log_notice(LD_ACCT,
  443.            "Configured hibernation.  This interval begins at %s "
  444.            "and ends at %s.  We have no prior estimate for bandwidth, so "
  445.            "we will start out awake and hibernate when we exhaust our quota.",
  446.            buf1, buf2);
  447.     return;
  448.   }
  449.   time_in_interval = (int)(interval_end_time - interval_start_time);
  450.   time_to_exhaust_bw =
  451.     (get_options()->AccountingMax/expected_bandwidth_usage)*60;
  452.   if (time_to_exhaust_bw > TIME_MAX) {
  453.     time_to_exhaust_bw = TIME_MAX;
  454.     time_to_consider = 0;
  455.   } else {
  456.     time_to_consider = time_in_interval - (int)time_to_exhaust_bw;
  457.   }
  458.   if (time_to_consider<=0) {
  459.     interval_wakeup_time = interval_start_time;
  460.   } else {
  461.     /* XXX can we simplify this just by picking a random (non-deterministic)
  462.      * time to be up? If we go down and come up, then we pick a new one. Is
  463.      * that good enough? -RD */
  464.     /* This is not a perfectly unbiased conversion, but it is good enough:
  465.      * in the worst case, the first half of the day is 0.06 percent likelier
  466.      * to be chosen than the last half. */
  467.     interval_wakeup_time = interval_start_time +
  468.       (get_uint32(digest) % time_to_consider);
  469.     format_iso_time(buf, interval_wakeup_time);
  470.   }
  471.   {
  472.     char buf1[ISO_TIME_LEN+1];
  473.     char buf2[ISO_TIME_LEN+1];
  474.     char buf3[ISO_TIME_LEN+1];
  475.     char buf4[ISO_TIME_LEN+1];
  476.     time_t down_time;
  477.     if (interval_wakeup_time+time_to_exhaust_bw > TIME_MAX)
  478.       down_time = TIME_MAX;
  479.     else
  480.       down_time = (time_t)(interval_wakeup_time+time_to_exhaust_bw);
  481.     if (down_time>interval_end_time)
  482.       down_time = interval_end_time;
  483.     format_local_iso_time(buf1, interval_start_time);
  484.     format_local_iso_time(buf2, interval_wakeup_time);
  485.     format_local_iso_time(buf3, down_time);
  486.     format_local_iso_time(buf4, interval_end_time);
  487.     log_notice(LD_ACCT,
  488.            "Configured hibernation.  This interval began at %s; "
  489.            "the scheduled wake-up time %s %s; "
  490.            "we expect%s to exhaust our quota for this interval around %s; "
  491.            "the next interval begins at %s (all times local)",
  492.            buf1,
  493.            time(NULL)<interval_wakeup_time?"is":"was", buf2,
  494.            time(NULL)<down_time?"":"ed", buf3,
  495.            buf4);
  496.   }
  497. }
  498. /* This rounds 0 up to 1000, but that's actually a feature. */
  499. #define ROUND_UP(x) (((x) + 0x3ff) & ~0x3ff)
  500. /** Save all our bandwidth tracking information to disk. Return 0 on
  501.  * success, -1 on failure. */
  502. int
  503. accounting_record_bandwidth_usage(time_t now, or_state_t *state)
  504. {
  505.   /* Just update the state */
  506.   state->AccountingIntervalStart = interval_start_time;
  507.   state->AccountingBytesReadInInterval = ROUND_UP(n_bytes_read_in_interval);
  508.   state->AccountingBytesWrittenInInterval =
  509.     ROUND_UP(n_bytes_written_in_interval);
  510.   state->AccountingSecondsActive = n_seconds_active_in_interval;
  511.   state->AccountingExpectedUsage = expected_bandwidth_usage;
  512.   or_state_mark_dirty(state,
  513.                       now+(get_options()->AvoidDiskWrites ? 7200 : 60));
  514.   return 0;
  515. }
  516. #undef ROUND_UP
  517. /** Read stored accounting information from disk. Return 0 on success;
  518.  * return -1 and change nothing on failure. */
  519. static int
  520. read_bandwidth_usage(void)
  521. {
  522.   or_state_t *state = get_or_state();
  523.   {
  524.     char *fname = get_datadir_fname("bw_accounting");
  525.     unlink(fname);
  526.     tor_free(fname);
  527.   }
  528.   if (!state)
  529.     return -1;
  530.   /* Okay; it looks like the state file is more up-to-date than the
  531.    * bw_accounting file, or the bw_accounting file is nonexistent,
  532.    * or the bw_accounting file is corrupt.
  533.    */
  534.   log_info(LD_ACCT, "Reading bandwidth accounting data from state file");
  535.   n_bytes_read_in_interval = state->AccountingBytesReadInInterval;
  536.   n_bytes_written_in_interval = state->AccountingBytesWrittenInInterval;
  537.   n_seconds_active_in_interval = state->AccountingSecondsActive;
  538.   interval_start_time = state->AccountingIntervalStart;
  539.   expected_bandwidth_usage = state->AccountingExpectedUsage;
  540.   {
  541.     char tbuf1[ISO_TIME_LEN+1];
  542.     char tbuf2[ISO_TIME_LEN+1];
  543.     format_iso_time(tbuf1, state->LastWritten);
  544.     format_iso_time(tbuf2, state->AccountingIntervalStart);
  545.     log_info(LD_ACCT,
  546.        "Successfully read bandwidth accounting info from state written at %s "
  547.        "for interval starting at %s.  We have been active for %lu seconds in "
  548.        "this interval.  At the start of the interval, we expected to use "
  549.        "about %lu KB per second. ("U64_FORMAT" bytes read so far, "
  550.        U64_FORMAT" bytes written so far)",
  551.        tbuf1, tbuf2,
  552.        (unsigned long)n_seconds_active_in_interval,
  553.        (unsigned long)(expected_bandwidth_usage*1024/60),
  554.        U64_PRINTF_ARG(n_bytes_read_in_interval),
  555.        U64_PRINTF_ARG(n_bytes_written_in_interval));
  556.   }
  557.   return 0;
  558. }
  559. /** Return true iff we have sent/received all the bytes we are willing
  560.  * to send/receive this interval. */
  561. static int
  562. hibernate_hard_limit_reached(void)
  563. {
  564.   uint64_t hard_limit = get_options()->AccountingMax;
  565.   if (!hard_limit)
  566.     return 0;
  567.   return n_bytes_read_in_interval >= hard_limit
  568.     || n_bytes_written_in_interval >= hard_limit;
  569. }
  570. /** Return true iff we have sent/received almost all the bytes we are willing
  571.  * to send/receive this interval. */
  572. static int
  573. hibernate_soft_limit_reached(void)
  574. {
  575.   uint64_t soft_limit = DBL_TO_U64(U64_TO_DBL(get_options()->AccountingMax)
  576.                                    * .95);
  577.   if (!soft_limit)
  578.     return 0;
  579.   return n_bytes_read_in_interval >= soft_limit
  580.     || n_bytes_written_in_interval >= soft_limit;
  581. }
  582. /** Called when we get a SIGINT, or when bandwidth soft limit is
  583.  * reached. Puts us into "loose hibernation": we don't accept new
  584.  * connections, but we continue handling old ones. */
  585. static void
  586. hibernate_begin(hibernate_state_t new_state, time_t now)
  587. {
  588.   connection_t *conn;
  589.   or_options_t *options = get_options();
  590.   if (new_state == HIBERNATE_STATE_EXITING &&
  591.       hibernate_state != HIBERNATE_STATE_LIVE) {
  592.     log_notice(LD_GENERAL,"SIGINT received %s; exiting now.",
  593.                hibernate_state == HIBERNATE_STATE_EXITING ?
  594.                "a second time" : "while hibernating");
  595.     tor_cleanup();
  596.     exit(0);
  597.   }
  598.   /* close listeners. leave control listener(s). */
  599.   while ((conn = connection_get_by_type(CONN_TYPE_OR_LISTENER)) ||
  600.          (conn = connection_get_by_type(CONN_TYPE_AP_LISTENER)) ||
  601.          (conn = connection_get_by_type(CONN_TYPE_AP_TRANS_LISTENER)) ||
  602.          (conn = connection_get_by_type(CONN_TYPE_AP_DNS_LISTENER)) ||
  603.          (conn = connection_get_by_type(CONN_TYPE_AP_NATD_LISTENER)) ||
  604.          (conn = connection_get_by_type(CONN_TYPE_DIR_LISTENER))) {
  605.     log_info(LD_NET,"Closing listener type %d", conn->type);
  606.     connection_mark_for_close(conn);
  607.   }
  608.   /* XXX kill intro point circs */
  609.   /* XXX upload rendezvous service descriptors with no intro points */
  610.   if (new_state == HIBERNATE_STATE_EXITING) {
  611.     log_notice(LD_GENERAL,"Interrupt: will shut down in %d seconds. Interrupt "
  612.                "again to exit now.", options->ShutdownWaitLength);
  613.     shutdown_time = time(NULL) + options->ShutdownWaitLength;
  614.   } else { /* soft limit reached */
  615.     hibernate_end_time = interval_end_time;
  616.   }
  617.   hibernate_state = new_state;
  618.   accounting_record_bandwidth_usage(now, get_or_state());
  619.   or_state_mark_dirty(get_or_state(),
  620.                       get_options()->AvoidDiskWrites ? now+600 : 0);
  621. }
  622. /** Called when we've been hibernating and our timeout is reached. */
  623. static void
  624. hibernate_end(hibernate_state_t new_state)
  625. {
  626.   tor_assert(hibernate_state == HIBERNATE_STATE_LOWBANDWIDTH ||
  627.              hibernate_state == HIBERNATE_STATE_DORMANT);
  628.   /* listeners will be relaunched in run_scheduled_events() in main.c */
  629.   log_notice(LD_ACCT,"Hibernation period ended. Resuming normal activity.");
  630.   hibernate_state = new_state;
  631.   hibernate_end_time = 0; /* no longer hibernating */
  632.   stats_n_seconds_working = 0; /* reset published uptime */
  633. }
  634. /** A wrapper around hibernate_begin, for when we get SIGINT. */
  635. void
  636. hibernate_begin_shutdown(void)
  637. {
  638.   hibernate_begin(HIBERNATE_STATE_EXITING, time(NULL));
  639. }
  640. /** Return true iff we are currently hibernating. */
  641. int
  642. we_are_hibernating(void)
  643. {
  644.   return hibernate_state != HIBERNATE_STATE_LIVE;
  645. }
  646. /** If we aren't currently dormant, close all connections and become
  647.  * dormant. */
  648. static void
  649. hibernate_go_dormant(time_t now)
  650. {
  651.   connection_t *conn;
  652.   if (hibernate_state == HIBERNATE_STATE_DORMANT)
  653.     return;
  654.   else if (hibernate_state == HIBERNATE_STATE_LOWBANDWIDTH)
  655.     hibernate_state = HIBERNATE_STATE_DORMANT;
  656.   else
  657.     hibernate_begin(HIBERNATE_STATE_DORMANT, now);
  658.   log_notice(LD_ACCT,"Going dormant. Blowing away remaining connections.");
  659.   /* Close all OR/AP/exit conns. Leave dir conns because we still want
  660.    * to be able to upload server descriptors so people know we're still
  661.    * running, and download directories so we can detect if we're obsolete.
  662.    * Leave control conns because we still want to be controllable.
  663.    */
  664.   while ((conn = connection_get_by_type(CONN_TYPE_OR)) ||
  665.          (conn = connection_get_by_type(CONN_TYPE_AP)) ||
  666.          (conn = connection_get_by_type(CONN_TYPE_EXIT))) {
  667.     if (CONN_IS_EDGE(conn))
  668.       connection_edge_end(TO_EDGE_CONN(conn), END_STREAM_REASON_HIBERNATING);
  669.     log_info(LD_NET,"Closing conn type %d", conn->type);
  670.     if (conn->type == CONN_TYPE_AP) /* send socks failure if needed */
  671.       connection_mark_unattached_ap(TO_EDGE_CONN(conn),
  672.                                     END_STREAM_REASON_HIBERNATING);
  673.     else
  674.       connection_mark_for_close(conn);
  675.   }
  676.   if (now < interval_wakeup_time)
  677.     hibernate_end_time = interval_wakeup_time;
  678.   else
  679.     hibernate_end_time = interval_end_time;
  680.   accounting_record_bandwidth_usage(now, get_or_state());
  681.   or_state_mark_dirty(get_or_state(),
  682.                       get_options()->AvoidDiskWrites ? now+600 : 0);
  683. }
  684. /** Called when hibernate_end_time has arrived. */
  685. static void
  686. hibernate_end_time_elapsed(time_t now)
  687. {
  688.   char buf[ISO_TIME_LEN+1];
  689.   /* The interval has ended, or it is wakeup time.  Find out which. */
  690.   accounting_run_housekeeping(now);
  691.   if (interval_wakeup_time <= now) {
  692.     /* The interval hasn't changed, but interval_wakeup_time has passed.
  693.      * It's time to wake up and start being a server. */
  694.     hibernate_end(HIBERNATE_STATE_LIVE);
  695.     return;
  696.   } else {
  697.     /* The interval has changed, and it isn't time to wake up yet. */
  698.     hibernate_end_time = interval_wakeup_time;
  699.     format_iso_time(buf,interval_wakeup_time);
  700.     if (hibernate_state != HIBERNATE_STATE_DORMANT) {
  701.       /* We weren't sleeping before; we should sleep now. */
  702.       log_notice(LD_ACCT,
  703.                  "Accounting period ended. Commencing hibernation until "
  704.                  "%s GMT", buf);
  705.       hibernate_go_dormant(now);
  706.     } else {
  707.       log_notice(LD_ACCT,
  708.              "Accounting period ended. This period, we will hibernate"
  709.              " until %s GMT",buf);
  710.     }
  711.   }
  712. }
  713. /** Consider our environment and decide if it's time
  714.  * to start/stop hibernating.
  715.  */
  716. void
  717. consider_hibernation(time_t now)
  718. {
  719.   int accounting_enabled = get_options()->AccountingMax != 0;
  720.   char buf[ISO_TIME_LEN+1];
  721.   /* If we're in 'exiting' mode, then we just shut down after the interval
  722.    * elapses. */
  723.   if (hibernate_state == HIBERNATE_STATE_EXITING) {
  724.     tor_assert(shutdown_time);
  725.     if (shutdown_time <= now) {
  726.       log_notice(LD_GENERAL, "Clean shutdown finished. Exiting.");
  727.       tor_cleanup();
  728.       exit(0);
  729.     }
  730.     return; /* if exiting soon, don't worry about bandwidth limits */
  731.   }
  732.   if (hibernate_state == HIBERNATE_STATE_DORMANT) {
  733.     /* We've been hibernating because of bandwidth accounting. */
  734.     tor_assert(hibernate_end_time);
  735.     if (hibernate_end_time > now && accounting_enabled) {
  736.       /* If we're hibernating, don't wake up until it's time, regardless of
  737.        * whether we're in a new interval. */
  738.       return ;
  739.     } else {
  740.       hibernate_end_time_elapsed(now);
  741.     }
  742.   }
  743.   /* Else, we aren't hibernating. See if it's time to start hibernating, or to
  744.    * go dormant. */
  745.   if (hibernate_state == HIBERNATE_STATE_LIVE) {
  746.     if (hibernate_soft_limit_reached()) {
  747.       log_notice(LD_ACCT,
  748.                  "Bandwidth soft limit reached; commencing hibernation.");
  749.       hibernate_begin(HIBERNATE_STATE_LOWBANDWIDTH, now);
  750.     } else if (accounting_enabled && now < interval_wakeup_time) {
  751.       format_local_iso_time(buf,interval_wakeup_time);
  752.       log_notice(LD_ACCT,
  753.                  "Commencing hibernation. We will wake up at %s local time.",
  754.                  buf);
  755.       hibernate_go_dormant(now);
  756.     }
  757.   }
  758.   if (hibernate_state == HIBERNATE_STATE_LOWBANDWIDTH) {
  759.     if (!accounting_enabled) {
  760.       hibernate_end_time_elapsed(now);
  761.     } else if (hibernate_hard_limit_reached()) {
  762.       hibernate_go_dormant(now);
  763.     } else if (hibernate_end_time <= now) {
  764.       /* The hibernation period ended while we were still in lowbandwidth.*/
  765.       hibernate_end_time_elapsed(now);
  766.     }
  767.   }
  768. }
  769. /** Helper function: called when we get a GETINFO request for an
  770.  * accounting-related key on the control connection <b>conn</b>.  If we can
  771.  * answer the request for <b>question</b>, then set *<b>answer</b> to a newly
  772.  * allocated string holding the result.  Otherwise, set *<b>answer</b> to
  773.  * NULL. */
  774. int
  775. getinfo_helper_accounting(control_connection_t *conn,
  776.                           const char *question, char **answer)
  777. {
  778.   (void) conn;
  779.   if (!strcmp(question, "accounting/enabled")) {
  780.     *answer = tor_strdup(accounting_is_enabled(get_options()) ? "1" : "0");
  781.   } else if (!strcmp(question, "accounting/hibernating")) {
  782.     if (hibernate_state == HIBERNATE_STATE_DORMANT)
  783.       *answer = tor_strdup("hard");
  784.     else if (hibernate_state == HIBERNATE_STATE_LOWBANDWIDTH)
  785.       *answer = tor_strdup("soft");
  786.     else
  787.       *answer = tor_strdup("awake");
  788.   } else if (!strcmp(question, "accounting/bytes")) {
  789.     *answer = tor_malloc(32);
  790.     tor_snprintf(*answer, 32, U64_FORMAT" "U64_FORMAT,
  791.                  U64_PRINTF_ARG(n_bytes_read_in_interval),
  792.                  U64_PRINTF_ARG(n_bytes_written_in_interval));
  793.   } else if (!strcmp(question, "accounting/bytes-left")) {
  794.     uint64_t limit = get_options()->AccountingMax;
  795.     uint64_t read_left = 0, write_left = 0;
  796.     if (n_bytes_read_in_interval < limit)
  797.       read_left = limit - n_bytes_read_in_interval;
  798.     if (n_bytes_written_in_interval < limit)
  799.       write_left = limit - n_bytes_written_in_interval;
  800.     *answer = tor_malloc(64);
  801.     tor_snprintf(*answer, 64, U64_FORMAT" "U64_FORMAT,
  802.                  U64_PRINTF_ARG(read_left), U64_PRINTF_ARG(write_left));
  803.   } else if (!strcmp(question, "accounting/interval-start")) {
  804.     *answer = tor_malloc(ISO_TIME_LEN+1);
  805.     format_iso_time(*answer, interval_start_time);
  806.   } else if (!strcmp(question, "accounting/interval-wake")) {
  807.     *answer = tor_malloc(ISO_TIME_LEN+1);
  808.     format_iso_time(*answer, interval_wakeup_time);
  809.   } else if (!strcmp(question, "accounting/interval-end")) {
  810.     *answer = tor_malloc(ISO_TIME_LEN+1);
  811.     format_iso_time(*answer, interval_end_time);
  812.   } else {
  813.     *answer = NULL;
  814.   }
  815.   return 0;
  816. }