tor  0.4.0.0-alpha-dev
status.c
Go to the documentation of this file.
1 /* Copyright (c) 2010-2018, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
3 
15 #define STATUS_PRIVATE
16 
17 #include "core/or/or.h"
18 #include "core/or/circuituse.h"
19 #include "app/config/config.h"
20 #include "core/or/status.h"
22 #include "core/or/relay.h"
23 #include "feature/relay/router.h"
25 #include "core/or/circuitlist.h"
26 #include "core/mainloop/mainloop.h"
27 #include "feature/stats/rephist.h"
29 #include "app/config/statefile.h"
30 #include "feature/hs/hs_stats.h"
31 #include "feature/hs/hs_service.h"
32 #include "core/or/dos.h"
34 
35 #include "app/config/or_state_st.h"
36 #include "feature/nodelist/routerinfo_st.h"
37 #include "lib/tls/tortls.h"
38 
39 static void log_accounting(const time_t now, const or_options_t *options);
40 
42 STATIC int
44 {
45  return smartlist_len(circuit_get_global_list());
46 }
47 
50 STATIC char *
51 secs_to_uptime(long secs)
52 {
53  long int days = secs / 86400;
54  int hours = (int)((secs - (days * 86400)) / 3600);
55  int minutes = (int)((secs - (days * 86400) - (hours * 3600)) / 60);
56  char *uptime_string = NULL;
57 
58  switch (days) {
59  case 0:
60  tor_asprintf(&uptime_string, "%d:%02d hours", hours, minutes);
61  break;
62  case 1:
63  tor_asprintf(&uptime_string, "%ld day %d:%02d hours",
64  days, hours, minutes);
65  break;
66  default:
67  tor_asprintf(&uptime_string, "%ld days %d:%02d hours",
68  days, hours, minutes);
69  break;
70  }
71 
72  return uptime_string;
73 }
74 
77 STATIC char *
78 bytes_to_usage(uint64_t bytes)
79 {
80  char *bw_string = NULL;
81 
82  if (bytes < (1<<20)) { /* Less than a megabyte. */
83  tor_asprintf(&bw_string, "%"PRIu64" kB", (bytes>>10));
84  } else if (bytes < (1<<30)) { /* Megabytes. Let's add some precision. */
85  double bw = ((double)bytes);
86  tor_asprintf(&bw_string, "%.2f MB", bw/(1<<20));
87  } else { /* Gigabytes. */
88  double bw = ((double)bytes);
89  tor_asprintf(&bw_string, "%.2f GB", bw/(1<<30));
90  }
91 
92  return bw_string;
93 }
94 
96 static void
98 {
99  unsigned int num_services = hs_service_get_num_services();
100 
101  /* If there are no active onion services, no need to print logs */
102  if (num_services == 0) {
103  return;
104  }
105 
106  log_notice(LD_HEARTBEAT,
107  "Our onion service%s received %u v2 and %u v3 INTRODUCE2 cells "
108  "and attempted to launch %d rendezvous circuits.",
109  num_services == 1 ? "" : "s",
113 }
114 
118 int
119 log_heartbeat(time_t now)
120 {
121  char *bw_sent = NULL;
122  char *bw_rcvd = NULL;
123  char *uptime = NULL;
124  const routerinfo_t *me;
125  double r = tls_get_write_overhead_ratio();
126  const int hibernating = we_are_hibernating();
127 
128  const or_options_t *options = get_options();
129 
130  if (public_server_mode(options) && !hibernating) {
131  /* Let's check if we are in the current cached consensus. */
132  if (!(me = router_get_my_routerinfo()))
133  return -1; /* Something stinks, we won't even attempt this. */
134  else
135  if (!node_get_by_id(me->cache_info.identity_digest))
136  log_fn(LOG_NOTICE, LD_HEARTBEAT, "Heartbeat: It seems like we are not "
137  "in the cached consensus.");
138  }
139 
140  uptime = secs_to_uptime(get_uptime());
141  bw_rcvd = bytes_to_usage(get_bytes_read());
142  bw_sent = bytes_to_usage(get_bytes_written());
143 
144  log_fn(LOG_NOTICE, LD_HEARTBEAT, "Heartbeat: Tor's uptime is %s, with %d "
145  "circuits open. I've sent %s and received %s.%s",
146  uptime, count_circuits(), bw_sent, bw_rcvd,
147  hibernating?" We are currently hibernating.":"");
148 
149  if (server_mode(options) && accounting_is_enabled(options) && !hibernating) {
150  log_accounting(now, options);
151  }
152 
153  double fullness_pct = 100;
154  if (stats_n_data_cells_packaged && !hibernating) {
155  fullness_pct =
156  100*(((double)stats_n_data_bytes_packaged) /
158  }
159  const double overhead_pct = ( r - 1.0 ) * 100.0;
160 
161 #define FULLNESS_PCT_THRESHOLD 80
162 #define TLS_OVERHEAD_THRESHOLD 15
163 
164  const int severity = (fullness_pct < FULLNESS_PCT_THRESHOLD ||
165  overhead_pct > TLS_OVERHEAD_THRESHOLD)
166  ? LOG_NOTICE : LOG_INFO;
167 
168  log_fn(severity, LD_HEARTBEAT,
169  "Average packaged cell fullness: %2.3f%%. "
170  "TLS write overhead: %.f%%", fullness_pct, overhead_pct);
171 
172  if (public_server_mode(options)) {
175  dos_log_heartbeat();
176  }
177 
179 
180  if (options->BridgeRelay) {
181  char *msg = NULL;
183  if (msg)
184  log_notice(LD_HEARTBEAT, "%s", msg);
185  tor_free(msg);
186  }
187 
188  if (options->MainloopStats) {
189  const uint64_t main_loop_success_count = get_main_loop_success_count();
190  const uint64_t main_loop_error_count = get_main_loop_error_count();
191  const uint64_t main_loop_idle_count = get_main_loop_idle_count();
192 
193  log_fn(LOG_NOTICE, LD_HEARTBEAT, "Main event loop statistics: "
194  "%"PRIu64 " successful returns, "
195  "%"PRIu64 " erroneous returns, and "
196  "%"PRIu64 " idle returns.",
197  (main_loop_success_count),
198  (main_loop_error_count),
199  (main_loop_idle_count));
200  }
201 
204 
205  tor_free(uptime);
206  tor_free(bw_sent);
207  tor_free(bw_rcvd);
208 
209  return 0;
210 }
211 
212 static void
213 log_accounting(const time_t now, const or_options_t *options)
214 {
215  or_state_t *state = get_or_state();
216  char *acc_rcvd = bytes_to_usage(state->AccountingBytesReadInInterval);
217  char *acc_sent = bytes_to_usage(state->AccountingBytesWrittenInInterval);
218  char *acc_used = bytes_to_usage(get_accounting_bytes());
219  uint64_t acc_bytes = options->AccountingMax;
220  char *acc_max;
221  time_t interval_end = accounting_get_end_time();
222  char end_buf[ISO_TIME_LEN + 1];
223  char *remaining = NULL;
224  acc_max = bytes_to_usage(acc_bytes);
225  format_local_iso_time(end_buf, interval_end);
226  remaining = secs_to_uptime(interval_end - now);
227 
228  const char *acc_rule;
229  switch (options->AccountingRule) {
230  case ACCT_MAX: acc_rule = "max";
231  break;
232  case ACCT_SUM: acc_rule = "sum";
233  break;
234  case ACCT_OUT: acc_rule = "out";
235  break;
236  case ACCT_IN: acc_rule = "in";
237  break;
238  default: acc_rule = "max";
239  break;
240  }
241 
242  log_notice(LD_HEARTBEAT, "Heartbeat: Accounting enabled. "
243  "Sent: %s, Received: %s, Used: %s / %s, Rule: %s. The "
244  "current accounting interval ends on %s, in %s.",
245  acc_sent, acc_rcvd, acc_used, acc_max, acc_rule, end_buf, remaining);
246 
247  tor_free(acc_rcvd);
248  tor_free(acc_sent);
249  tor_free(acc_used);
250  tor_free(acc_max);
251  tor_free(remaining);
252 }
#define RELAY_PAYLOAD_SIZE
Definition: or.h:605
Header for statefile.c.
uint64_t AccountingMax
uint64_t get_main_loop_error_count(void)
Definition: mainloop.c:551
uint32_t hs_stats_get_n_rendezvous_launches(void)
Definition: hs_stats.c:54
Header file containing service data for the HS subsytem.
uint64_t get_main_loop_idle_count(void)
Definition: mainloop.c:565
Header file for geoip_stats.c.
void format_local_iso_time(char *buf, time_t t)
Definition: time_fmt.c:281
uint64_t get_accounting_bytes(void)
Definition: hibernate.c:478
#define LOG_INFO
Definition: log.h:41
Header file for nodelist.c.
static void log_onion_service_stats(void)
Definition: status.c:97
Header file for config.c.
void rep_hist_log_link_protocol_counts(void)
Definition: rephist.c:2875
#define tor_free(p)
Definition: malloc.h:52
uint32_t hs_stats_get_n_introduce2_v2_cells(void)
Definition: hs_stats.c:40
#define LOG_NOTICE
Definition: log.h:46
Header file for mainloop.c.
Header file for hs_stats.c.
uint64_t get_main_loop_success_count(void)
Definition: mainloop.c:537
Header file for hibernate.c.
Header file for routermode.c.
int tor_asprintf(char **strp, const char *fmt,...)
Definition: printf.c:75
uint64_t stats_n_data_bytes_packaged
Definition: relay.c:1974
uint32_t hs_stats_get_n_introduce2_v3_cells(void)
Definition: hs_stats.c:33
int log_heartbeat(time_t now)
Definition: status.c:119
Master header file for Tor-specific functionality.
Header file for rephist.c.
Header file for circuituse.c.
Header file for circuitlist.c.
void circuit_log_ancient_one_hop_circuits(int age)
Definition: circuituse.c:873
uint64_t stats_n_data_cells_packaged
Definition: relay.c:1970
char identity_digest[DIGEST_LEN]
Header file for relay.c.
Header file for router.c.
#define log_fn(severity, domain, args,...)
Definition: log.h:255
Headers for tortls.c.
STATIC int count_circuits(void)
Definition: status.c:43
STATIC char * bytes_to_usage(uint64_t bytes)
Definition: status.c:78
char * format_client_stats_heartbeat(time_t now)
Definition: geoip_stats.c:1205
STATIC char * secs_to_uptime(long secs)
Definition: status.c:51
void rep_hist_log_circuit_handshake_stats(time_t now)
Definition: rephist.c:2460
#define LD_HEARTBEAT
Definition: log.h:99