LCOV - code coverage report
Current view: top level - feature/control - control_events.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 362 906 40.0 %
Date: 2021-11-24 03:28:48 Functions: 51 79 64.6 %

          Line data    Source code
       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 control_events.c
       7             :  * \brief Implement the event-reporting part of the controller API.
       8             :  **/
       9             : 
      10             : #define CONTROL_MODULE_PRIVATE
      11             : #define CONTROL_EVENTS_PRIVATE
      12             : #define OCIRC_EVENT_PRIVATE
      13             : 
      14             : #include "core/or/or.h"
      15             : #include "app/config/config.h"
      16             : #include "core/mainloop/connection.h"
      17             : #include "core/mainloop/mainloop.h"
      18             : #include "core/or/channeltls.h"
      19             : #include "core/or/circuitlist.h"
      20             : #include "core/or/circuitstats.h"
      21             : #include "core/or/command.h"
      22             : #include "core/or/connection_edge.h"
      23             : #include "core/or/connection_or.h"
      24             : #include "core/or/reasons.h"
      25             : #include "feature/control/control.h"
      26             : #include "feature/control/control_events.h"
      27             : #include "feature/control/control_fmt.h"
      28             : #include "feature/control/control_proto.h"
      29             : #include "feature/dircommon/directory.h"
      30             : #include "feature/nodelist/describe.h"
      31             : #include "feature/nodelist/networkstatus.h"
      32             : #include "feature/nodelist/nodelist.h"
      33             : 
      34             : #include "feature/control/control_connection_st.h"
      35             : #include "core/or/entry_connection_st.h"
      36             : #include "feature/nodelist/networkstatus_st.h"
      37             : #include "core/or/or_connection_st.h"
      38             : #include "core/or/or_circuit_st.h"
      39             : #include "core/or/origin_circuit_st.h"
      40             : 
      41             : #include "lib/evloop/compat_libevent.h"
      42             : #include "lib/encoding/confline.h"
      43             : 
      44             : static void flush_queued_events_cb(mainloop_event_t *event, void *arg);
      45             : static void control_get_bytes_rw_last_sec(uint64_t *r, uint64_t *w);
      46             : 
      47             : /** Yield true iff <b>s</b> is the state of a control_connection_t that has
      48             :  * finished authentication and is accepting commands. */
      49             : #define STATE_IS_OPEN(s) ((s) == CONTROL_CONN_STATE_OPEN)
      50             : 
      51             : /** An event mask of all the events that any controller is interested in
      52             :  * receiving. */
      53             : static event_mask_t global_event_mask = 0;
      54             : 
      55             : /** True iff we have disabled log messages from being sent to the controller */
      56             : static int disable_log_messages = 0;
      57             : 
      58             : /** Macro: true if any control connection is interested in events of type
      59             :  * <b>e</b>. */
      60             : #define EVENT_IS_INTERESTING(e) \
      61             :   (!! (global_event_mask & EVENT_MASK_(e)))
      62             : 
      63             : /** Macro: true if any event from the bitfield 'e' is interesting. */
      64             : #define ANY_EVENT_IS_INTERESTING(e) \
      65             :   (!! (global_event_mask & (e)))
      66             : 
      67             : static void send_control_event_impl(uint16_t event,
      68             :                                     const char *format, va_list ap)
      69             :   CHECK_PRINTF(2,0);
      70             : static int control_event_status(int type, int severity, const char *format,
      71             :                                 va_list args)
      72             :   CHECK_PRINTF(3,0);
      73             : 
      74             : static void send_control_event(uint16_t event,
      75             :                                const char *format, ...)
      76             :   CHECK_PRINTF(2,3);
      77             : 
      78             : /** Table mapping event values to their names.  Used to implement SETEVENTS
      79             :  * and GETINFO events/names, and to keep they in sync. */
      80             : const struct control_event_t control_event_table[] = {
      81             :   { EVENT_CIRCUIT_STATUS, "CIRC" },
      82             :   { EVENT_CIRCUIT_STATUS_MINOR, "CIRC_MINOR" },
      83             :   { EVENT_STREAM_STATUS, "STREAM" },
      84             :   { EVENT_OR_CONN_STATUS, "ORCONN" },
      85             :   { EVENT_BANDWIDTH_USED, "BW" },
      86             :   { EVENT_DEBUG_MSG, "DEBUG" },
      87             :   { EVENT_INFO_MSG, "INFO" },
      88             :   { EVENT_NOTICE_MSG, "NOTICE" },
      89             :   { EVENT_WARN_MSG, "WARN" },
      90             :   { EVENT_ERR_MSG, "ERR" },
      91             :   { EVENT_NEW_DESC, "NEWDESC" },
      92             :   { EVENT_ADDRMAP, "ADDRMAP" },
      93             :   { EVENT_DESCCHANGED, "DESCCHANGED" },
      94             :   { EVENT_NS, "NS" },
      95             :   { EVENT_STATUS_GENERAL, "STATUS_GENERAL" },
      96             :   { EVENT_STATUS_CLIENT, "STATUS_CLIENT" },
      97             :   { EVENT_STATUS_SERVER, "STATUS_SERVER" },
      98             :   { EVENT_GUARD, "GUARD" },
      99             :   { EVENT_STREAM_BANDWIDTH_USED, "STREAM_BW" },
     100             :   { EVENT_CLIENTS_SEEN, "CLIENTS_SEEN" },
     101             :   { EVENT_NEWCONSENSUS, "NEWCONSENSUS" },
     102             :   { EVENT_BUILDTIMEOUT_SET, "BUILDTIMEOUT_SET" },
     103             :   { EVENT_GOT_SIGNAL, "SIGNAL" },
     104             :   { EVENT_CONF_CHANGED, "CONF_CHANGED"},
     105             :   { EVENT_CONN_BW, "CONN_BW" },
     106             :   { EVENT_CELL_STATS, "CELL_STATS" },
     107             :   { EVENT_CIRC_BANDWIDTH_USED, "CIRC_BW" },
     108             :   { EVENT_TRANSPORT_LAUNCHED, "TRANSPORT_LAUNCHED" },
     109             :   { EVENT_HS_DESC, "HS_DESC" },
     110             :   { EVENT_HS_DESC_CONTENT, "HS_DESC_CONTENT" },
     111             :   { EVENT_NETWORK_LIVENESS, "NETWORK_LIVENESS" },
     112             :   { 0, NULL },
     113             : };
     114             : 
     115             : /** Given a log severity, return the corresponding control event code. */
     116             : static inline int
     117           8 : log_severity_to_event(int severity)
     118             : {
     119           8 :   switch (severity) {
     120             :     case LOG_DEBUG: return EVENT_DEBUG_MSG;
     121             :     case LOG_INFO: return EVENT_INFO_MSG;
     122             :     case LOG_NOTICE: return EVENT_NOTICE_MSG;
     123             :     case LOG_WARN: return EVENT_WARN_MSG;
     124             :     case LOG_ERR: return EVENT_ERR_MSG;
     125             :     default: return -1;
     126             :   }
     127             : }
     128             : 
     129             : /** Helper: clear bandwidth counters of all origin circuits. */
     130             : static void
     131           0 : clear_circ_bw_fields(void)
     132             : {
     133           0 :   origin_circuit_t *ocirc;
     134           0 :   SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
     135           0 :     if (!CIRCUIT_IS_ORIGIN(circ))
     136           0 :       continue;
     137           0 :     ocirc = TO_ORIGIN_CIRCUIT(circ);
     138           0 :     ocirc->n_written_circ_bw = ocirc->n_read_circ_bw = 0;
     139           0 :     ocirc->n_overhead_written_circ_bw = ocirc->n_overhead_read_circ_bw = 0;
     140           0 :     ocirc->n_delivered_written_circ_bw = ocirc->n_delivered_read_circ_bw = 0;
     141             :   }
     142           0 :   SMARTLIST_FOREACH_END(circ);
     143           0 : }
     144             : 
     145             : /* Helper to emit the BUILDTIMEOUT_SET circuit build time event */
     146             : void
     147         113 : cbt_control_event_buildtimeout_set(const circuit_build_times_t *cbt,
     148             :                                    buildtimeout_set_event_t type)
     149             : {
     150         113 :   char *args = NULL;
     151         113 :   double qnt;
     152         113 :   double timeout_rate = 0.0;
     153         113 :   double close_rate = 0.0;
     154             : 
     155         113 :   switch (type) {
     156             :     case BUILDTIMEOUT_SET_EVENT_RESET:
     157             :     case BUILDTIMEOUT_SET_EVENT_SUSPENDED:
     158             :     case BUILDTIMEOUT_SET_EVENT_DISCARD:
     159             :       qnt = 1.0;
     160             :       break;
     161           3 :     case BUILDTIMEOUT_SET_EVENT_COMPUTED:
     162             :     case BUILDTIMEOUT_SET_EVENT_RESUME:
     163             :     default:
     164           3 :       qnt = circuit_build_times_quantile_cutoff();
     165           3 :       break;
     166             :   }
     167             : 
     168             :   /* The timeout rate is the ratio of the timeout count over
     169             :    * the total number of circuits attempted. The total number of
     170             :    * circuits is (timeouts+succeeded), since every circuit
     171             :    * either succeeds, or times out. "Closed" circuits are
     172             :    * MEASURE_TIMEOUT circuits whose measurement period expired.
     173             :    * All MEASURE_TIMEOUT circuits are counted in the timeouts stat
     174             :    * before transitioning to MEASURE_TIMEOUT (in
     175             :    * circuit_build_times_mark_circ_as_measurement_only()).
     176             :    * MEASURE_TIMEOUT circuits that succeed are *not* counted as
     177             :    * "succeeded". See circuit_build_times_handle_completed_hop().
     178             :    *
     179             :    * We cast the denominator
     180             :    * to promote it to double before the addition, to avoid int32
     181             :    * overflow. */
     182         113 :   const double total_circuits =
     183         113 :     ((double)cbt->num_circ_timeouts) + cbt->num_circ_succeeded;
     184         113 :   if (total_circuits >= 1.0) {
     185           0 :     timeout_rate = cbt->num_circ_timeouts / total_circuits;
     186           0 :     close_rate = cbt->num_circ_closed / total_circuits;
     187             :   }
     188             : 
     189         113 :   tor_asprintf(&args, "TOTAL_TIMES=%lu "
     190             :                "TIMEOUT_MS=%lu XM=%lu ALPHA=%f CUTOFF_QUANTILE=%f "
     191             :                "TIMEOUT_RATE=%f CLOSE_MS=%lu CLOSE_RATE=%f",
     192         113 :                (unsigned long)cbt->total_build_times,
     193         113 :                (unsigned long)cbt->timeout_ms,
     194         113 :                (unsigned long)cbt->Xm, cbt->alpha, qnt,
     195             :                timeout_rate,
     196         113 :                (unsigned long)cbt->close_ms,
     197             :                close_rate);
     198             : 
     199         113 :   control_event_buildtimeout_set(type, args);
     200             : 
     201         113 :   tor_free(args);
     202         113 : }
     203             : /** Set <b>global_event_mask*</b> to the bitwise OR of each live control
     204             :  * connection's event_mask field. */
     205             : void
     206         235 : control_update_global_event_mask(void)
     207             : {
     208         235 :   smartlist_t *conns = get_connection_array();
     209         235 :   event_mask_t old_mask, new_mask;
     210         235 :   old_mask = global_event_mask;
     211         235 :   int any_old_per_sec_events = control_any_per_second_event_enabled();
     212             : 
     213         235 :   global_event_mask = 0;
     214         235 :   SMARTLIST_FOREACH(conns, connection_t *, _conn,
     215             :   {
     216             :     if (_conn->type == CONN_TYPE_CONTROL &&
     217             :         STATE_IS_OPEN(_conn->state)) {
     218             :       control_connection_t *conn = TO_CONTROL_CONN(_conn);
     219             :       global_event_mask |= conn->event_mask;
     220             :     }
     221             :   });
     222             : 
     223         235 :   new_mask = global_event_mask;
     224             : 
     225             :   /* Handle the aftermath.  Set up the log callback to tell us only what
     226             :    * we want to hear...*/
     227         235 :   control_adjust_event_log_severity();
     228             : 
     229             :   /* Macro: true if ev was false before and is true now. */
     230             : #define NEWLY_ENABLED(ev) \
     231             :   (! (old_mask & (ev)) && (new_mask & (ev)))
     232             : 
     233             :   /* ...then, if we've started logging stream or circ bw, clear the
     234             :    * appropriate fields. */
     235         235 :   if (NEWLY_ENABLED(EVENT_STREAM_BANDWIDTH_USED)) {
     236           0 :     SMARTLIST_FOREACH(conns, connection_t *, conn,
     237             :     {
     238             :       if (conn->type == CONN_TYPE_AP) {
     239             :         edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
     240             :         edge_conn->n_written = edge_conn->n_read = 0;
     241             :       }
     242             :     });
     243             :   }
     244         235 :   if (NEWLY_ENABLED(EVENT_CIRC_BANDWIDTH_USED)) {
     245           0 :     clear_circ_bw_fields();
     246             :   }
     247         235 :   if (NEWLY_ENABLED(EVENT_BANDWIDTH_USED)) {
     248           0 :     uint64_t r, w;
     249           0 :     control_get_bytes_rw_last_sec(&r, &w);
     250             :   }
     251         235 :   if (any_old_per_sec_events != control_any_per_second_event_enabled()) {
     252           0 :     rescan_periodic_events(get_options());
     253             :   }
     254             : 
     255             : #undef NEWLY_ENABLED
     256         235 : }
     257             : 
     258             : /** Given a control event code for a message event, return the corresponding
     259             :  * log severity. */
     260             : static inline int
     261           0 : event_to_log_severity(int event)
     262             : {
     263           0 :   switch (event) {
     264             :     case EVENT_DEBUG_MSG: return LOG_DEBUG;
     265             :     case EVENT_INFO_MSG: return LOG_INFO;
     266             :     case EVENT_NOTICE_MSG: return LOG_NOTICE;
     267             :     case EVENT_WARN_MSG: return LOG_WARN;
     268             :     case EVENT_ERR_MSG: return LOG_ERR;
     269             :     default: return -1;
     270             :   }
     271             : }
     272             : 
     273             : /** Adjust the log severities that result in control_event_logmsg being called
     274             :  * to match the severity of log messages that any controllers are interested
     275             :  * in. */
     276             : void
     277         244 : control_adjust_event_log_severity(void)
     278             : {
     279         244 :   int i;
     280         244 :   int min_log_event=EVENT_ERR_MSG, max_log_event=EVENT_DEBUG_MSG;
     281             : 
     282        1464 :   for (i = EVENT_DEBUG_MSG; i <= EVENT_ERR_MSG; ++i) {
     283        1220 :     if (EVENT_IS_INTERESTING(i)) {
     284             :       min_log_event = i;
     285             :       break;
     286             :     }
     287             :   }
     288        1464 :   for (i = EVENT_ERR_MSG; i >= EVENT_DEBUG_MSG; --i) {
     289        1220 :     if (EVENT_IS_INTERESTING(i)) {
     290             :       max_log_event = i;
     291             :       break;
     292             :     }
     293             :   }
     294         244 :   if (EVENT_IS_INTERESTING(EVENT_STATUS_GENERAL)) {
     295           0 :     if (min_log_event > EVENT_NOTICE_MSG)
     296             :       min_log_event = EVENT_NOTICE_MSG;
     297             :     if (max_log_event < EVENT_ERR_MSG)
     298             :       max_log_event = EVENT_ERR_MSG;
     299             :   }
     300         244 :   if (min_log_event <= max_log_event)
     301           0 :     change_callback_log_severity(event_to_log_severity(min_log_event),
     302             :                                  event_to_log_severity(max_log_event),
     303             :                                  control_event_logmsg);
     304             :   else
     305         244 :     change_callback_log_severity(LOG_ERR, LOG_ERR,
     306             :                                  control_event_logmsg);
     307         244 : }
     308             : 
     309             : /** Return true iff the event with code <b>c</b> is being sent to any current
     310             :  * control connection.  This is useful if the amount of work needed to prepare
     311             :  * to call the appropriate control_event_...() function is high.
     312             :  */
     313             : int
     314        4991 : control_event_is_interesting(int event)
     315             : {
     316        4991 :   return EVENT_IS_INTERESTING(event);
     317             : }
     318             : 
     319             : /** Return true if any event that needs to fire once a second is enabled. */
     320             : int
     321         778 : control_any_per_second_event_enabled(void)
     322             : {
     323         778 :   return ANY_EVENT_IS_INTERESTING(
     324             :       EVENT_MASK_(EVENT_BANDWIDTH_USED) |
     325             :       EVENT_MASK_(EVENT_CELL_STATS) |
     326             :       EVENT_MASK_(EVENT_CIRC_BANDWIDTH_USED) |
     327             :       EVENT_MASK_(EVENT_CONN_BW) |
     328             :       EVENT_MASK_(EVENT_STREAM_BANDWIDTH_USED)
     329             :   );
     330             : }
     331             : 
     332             : /* The value of 'get_bytes_read()' the previous time that
     333             :  * control_get_bytes_rw_last_sec() as called. */
     334             : static uint64_t stats_prev_n_read = 0;
     335             : /* The value of 'get_bytes_written()' the previous time that
     336             :  * control_get_bytes_rw_last_sec() as called. */
     337             : static uint64_t stats_prev_n_written = 0;
     338             : 
     339             : /**
     340             :  * Set <b>n_read</b> and <b>n_written</b> to the total number of bytes read
     341             :  * and written by Tor since the last call to this function.
     342             :  *
     343             :  * Call this only from the main thread.
     344             :  */
     345             : static void
     346           0 : control_get_bytes_rw_last_sec(uint64_t *n_read,
     347             :                               uint64_t *n_written)
     348             : {
     349           0 :   const uint64_t stats_n_bytes_read = get_bytes_read();
     350           0 :   const uint64_t stats_n_bytes_written = get_bytes_written();
     351             : 
     352           0 :   *n_read = stats_n_bytes_read - stats_prev_n_read;
     353           0 :   *n_written = stats_n_bytes_written - stats_prev_n_written;
     354           0 :   stats_prev_n_read = stats_n_bytes_read;
     355           0 :   stats_prev_n_written = stats_n_bytes_written;
     356           0 : }
     357             : 
     358             : /**
     359             :  * Run all the controller events (if any) that are scheduled to trigger once
     360             :  * per second.
     361             :  */
     362             : void
     363           0 : control_per_second_events(void)
     364             : {
     365           0 :   if (!control_any_per_second_event_enabled())
     366           0 :     return;
     367             : 
     368           0 :   uint64_t bytes_read, bytes_written;
     369           0 :   control_get_bytes_rw_last_sec(&bytes_read, &bytes_written);
     370           0 :   control_event_bandwidth_used((uint32_t)bytes_read,(uint32_t)bytes_written);
     371             : 
     372           0 :   control_event_stream_bandwidth_used();
     373           0 :   control_event_conn_bandwidth_used();
     374           0 :   control_event_circ_bandwidth_used();
     375           0 :   control_event_circuit_cell_stats();
     376             : }
     377             : 
     378             : /** Represents an event that's queued to be sent to one or more
     379             :  * controllers. */
     380             : typedef struct queued_event_t {
     381             :   uint16_t event;
     382             :   char *msg;
     383             : } queued_event_t;
     384             : 
     385             : /** Pointer to int. If this is greater than 0, we don't allow new events to be
     386             :  * queued. */
     387             : static tor_threadlocal_t block_event_queue_flag;
     388             : 
     389             : /** Holds a smartlist of queued_event_t objects that may need to be sent
     390             :  * to one or more controllers */
     391             : static smartlist_t *queued_control_events = NULL;
     392             : 
     393             : /** True if the flush_queued_events_event is pending. */
     394             : static int flush_queued_event_pending = 0;
     395             : 
     396             : /** Lock to protect the above fields. */
     397             : static tor_mutex_t *queued_control_events_lock = NULL;
     398             : 
     399             : /** An event that should fire in order to flush the contents of
     400             :  * queued_control_events. */
     401             : static mainloop_event_t *flush_queued_events_event = NULL;
     402             : 
     403             : void
     404          13 : control_initialize_event_queue(void)
     405             : {
     406          13 :   if (queued_control_events == NULL) {
     407          13 :     queued_control_events = smartlist_new();
     408             :   }
     409             : 
     410          13 :   if (flush_queued_events_event == NULL) {
     411          13 :     struct event_base *b = tor_libevent_get_base();
     412          13 :     if (b) {
     413          26 :       flush_queued_events_event =
     414          13 :         mainloop_event_new(flush_queued_events_cb, NULL);
     415          13 :       tor_assert(flush_queued_events_event);
     416             :     }
     417             :   }
     418             : 
     419          13 :   if (queued_control_events_lock == NULL) {
     420          13 :     queued_control_events_lock = tor_mutex_new();
     421          13 :     tor_threadlocal_init(&block_event_queue_flag);
     422             :   }
     423          13 : }
     424             : 
     425             : static int *
     426           0 : get_block_event_queue(void)
     427             : {
     428           0 :   int *val = tor_threadlocal_get(&block_event_queue_flag);
     429           0 :   if (PREDICT_UNLIKELY(val == NULL)) {
     430           0 :     val = tor_malloc_zero(sizeof(int));
     431           0 :     tor_threadlocal_set(&block_event_queue_flag, val);
     432             :   }
     433           0 :   return val;
     434             : }
     435             : 
     436             : /** Helper: inserts an event on the list of events queued to be sent to
     437             :  * one or more controllers, and schedules the events to be flushed if needed.
     438             :  *
     439             :  * This function takes ownership of <b>msg</b>, and may free it.
     440             :  *
     441             :  * We queue these events rather than send them immediately in order to break
     442             :  * the dependency in our callgraph from code that generates events for the
     443             :  * controller, and the network layer at large.  Otherwise, nearly every
     444             :  * interesting part of Tor would potentially call every other interesting part
     445             :  * of Tor.
     446             :  */
     447         229 : MOCK_IMPL(STATIC void,
     448             : queue_control_event_string,(uint16_t event, char *msg))
     449             : {
     450             :   /* This is redundant with checks done elsewhere, but it's a last-ditch
     451             :    * attempt to avoid queueing something we shouldn't have to queue. */
     452         229 :   if (PREDICT_UNLIKELY( ! EVENT_IS_INTERESTING(event) )) {
     453         229 :     tor_free(msg);
     454         229 :     return;
     455             :   }
     456             : 
     457           0 :   int *block_event_queue = get_block_event_queue();
     458           0 :   if (*block_event_queue) {
     459           0 :     tor_free(msg);
     460           0 :     return;
     461             :   }
     462             : 
     463           0 :   queued_event_t *ev = tor_malloc(sizeof(*ev));
     464           0 :   ev->event = event;
     465           0 :   ev->msg = msg;
     466             : 
     467             :   /* No queueing an event while queueing an event */
     468           0 :   ++*block_event_queue;
     469             : 
     470           0 :   tor_mutex_acquire(queued_control_events_lock);
     471           0 :   tor_assert(queued_control_events);
     472           0 :   smartlist_add(queued_control_events, ev);
     473             : 
     474           0 :   int activate_event = 0;
     475           0 :   if (! flush_queued_event_pending && in_main_thread()) {
     476           0 :     activate_event = 1;
     477           0 :     flush_queued_event_pending = 1;
     478             :   }
     479             : 
     480           0 :   tor_mutex_release(queued_control_events_lock);
     481             : 
     482           0 :   --*block_event_queue;
     483             : 
     484             :   /* We just put an event on the queue; mark the queue to be
     485             :    * flushed.  We only do this from the main thread for now; otherwise,
     486             :    * we'd need to incur locking overhead in Libevent or use a socket.
     487             :    */
     488           0 :   if (activate_event) {
     489           0 :     tor_assert(flush_queued_events_event);
     490           0 :     mainloop_event_activate(flush_queued_events_event);
     491             :   }
     492             : }
     493             : 
     494             : #define queued_event_free(ev) \
     495             :   FREE_AND_NULL(queued_event_t, queued_event_free_, (ev))
     496             : 
     497             : /** Release all storage held by <b>ev</b>. */
     498             : static void
     499           0 : queued_event_free_(queued_event_t *ev)
     500             : {
     501           0 :   if (ev == NULL)
     502             :     return;
     503             : 
     504           0 :   tor_free(ev->msg);
     505           0 :   tor_free(ev);
     506             : }
     507             : 
     508             : /** Send every queued event to every controller that's interested in it,
     509             :  * and remove the events from the queue.  If <b>force</b> is true,
     510             :  * then make all controllers send their data out immediately, since we
     511             :  * may be about to shut down. */
     512             : static void
     513           0 : queued_events_flush_all(int force)
     514             : {
     515             :   /* Make sure that we get all the pending log events, if there are any. */
     516           0 :   flush_pending_log_callbacks();
     517             : 
     518           0 :   if (PREDICT_UNLIKELY(queued_control_events == NULL)) {
     519           0 :     return;
     520             :   }
     521           0 :   smartlist_t *all_conns = get_connection_array();
     522           0 :   smartlist_t *controllers = smartlist_new();
     523           0 :   smartlist_t *queued_events;
     524             : 
     525           0 :   int *block_event_queue = get_block_event_queue();
     526           0 :   ++*block_event_queue;
     527             : 
     528           0 :   tor_mutex_acquire(queued_control_events_lock);
     529             :   /* No queueing an event while flushing events. */
     530           0 :   flush_queued_event_pending = 0;
     531           0 :   queued_events = queued_control_events;
     532           0 :   queued_control_events = smartlist_new();
     533           0 :   tor_mutex_release(queued_control_events_lock);
     534             : 
     535             :   /* Gather all the controllers that will care... */
     536           0 :   SMARTLIST_FOREACH_BEGIN(all_conns, connection_t *, conn) {
     537           0 :     if (conn->type == CONN_TYPE_CONTROL &&
     538           0 :         !conn->marked_for_close &&
     539           0 :         conn->state == CONTROL_CONN_STATE_OPEN) {
     540           0 :       control_connection_t *control_conn = TO_CONTROL_CONN(conn);
     541             : 
     542           0 :       smartlist_add(controllers, control_conn);
     543             :     }
     544           0 :   } SMARTLIST_FOREACH_END(conn);
     545             : 
     546           0 :   SMARTLIST_FOREACH_BEGIN(queued_events, queued_event_t *, ev) {
     547           0 :     const event_mask_t bit = ((event_mask_t)1) << ev->event;
     548           0 :     const size_t msg_len = strlen(ev->msg);
     549           0 :     SMARTLIST_FOREACH_BEGIN(controllers, control_connection_t *,
     550             :                             control_conn) {
     551           0 :       if (control_conn->event_mask & bit) {
     552           0 :         connection_buf_add(ev->msg, msg_len, TO_CONN(control_conn));
     553             :       }
     554           0 :     } SMARTLIST_FOREACH_END(control_conn);
     555             : 
     556           0 :     queued_event_free(ev);
     557           0 :   } SMARTLIST_FOREACH_END(ev);
     558             : 
     559           0 :   if (force) {
     560           0 :     SMARTLIST_FOREACH_BEGIN(controllers, control_connection_t *,
     561             :                             control_conn) {
     562           0 :       connection_flush(TO_CONN(control_conn));
     563           0 :     } SMARTLIST_FOREACH_END(control_conn);
     564             :   }
     565             : 
     566           0 :   smartlist_free(queued_events);
     567           0 :   smartlist_free(controllers);
     568             : 
     569           0 :   --*block_event_queue;
     570             : }
     571             : 
     572             : /** Libevent callback: Flushes pending events to controllers that are
     573             :  * interested in them. */
     574             : static void
     575           0 : flush_queued_events_cb(mainloop_event_t *event, void *arg)
     576             : {
     577           0 :   (void) event;
     578           0 :   (void) arg;
     579           0 :   queued_events_flush_all(0);
     580           0 : }
     581             : 
     582             : /** Send an event to all v1 controllers that are listening for code
     583             :  * <b>event</b>.  The event's body is given by <b>msg</b>.
     584             :  *
     585             :  * The EXTENDED_FORMAT and NONEXTENDED_FORMAT flags behave similarly with
     586             :  * respect to the EXTENDED_EVENTS feature. */
     587         107 : MOCK_IMPL(STATIC void,
     588             : send_control_event_string,(uint16_t event,
     589             :                            const char *msg))
     590             : {
     591         107 :   tor_assert(event >= EVENT_MIN_ && event <= EVENT_MAX_);
     592         107 :   queue_control_event_string(event, tor_strdup(msg));
     593         107 : }
     594             : 
     595             : /** Helper for send_control_event and control_event_status:
     596             :  * Send an event to all v1 controllers that are listening for code
     597             :  * <b>event</b>.  The event's body is created by the printf-style format in
     598             :  * <b>format</b>, and other arguments as provided. */
     599             : static void
     600         173 : send_control_event_impl(uint16_t event,
     601             :                         const char *format, va_list ap)
     602             : {
     603         173 :   char *buf = NULL;
     604         173 :   int len;
     605             : 
     606         173 :   len = tor_vasprintf(&buf, format, ap);
     607         173 :   if (len < 0) {
     608           0 :     log_warn(LD_BUG, "Unable to format event for controller.");
     609           0 :     return;
     610             :   }
     611             : 
     612         173 :   queue_control_event_string(event, buf);
     613             : }
     614             : 
     615             : /** Send an event to all v1 controllers that are listening for code
     616             :  * <b>event</b>.  The event's body is created by the printf-style format in
     617             :  * <b>format</b>, and other arguments as provided. */
     618             : static void
     619         173 : send_control_event(uint16_t event,
     620             :                    const char *format, ...)
     621             : {
     622         173 :   va_list ap;
     623         173 :   va_start(ap, format);
     624         173 :   send_control_event_impl(event, format, ap);
     625         173 :   va_end(ap);
     626         173 : }
     627             : 
     628             : /** Something major has happened to circuit <b>circ</b>: tell any
     629             :  * interested control connections. */
     630             : int
     631           1 : control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp,
     632             :                              int reason_code)
     633             : {
     634           1 :   const char *status;
     635           1 :   char reasons[64] = "";
     636             : 
     637           1 :   if (!EVENT_IS_INTERESTING(EVENT_CIRCUIT_STATUS))
     638             :     return 0;
     639           0 :   tor_assert(circ);
     640             : 
     641           0 :   switch (tp)
     642             :     {
     643             :     case CIRC_EVENT_LAUNCHED: status = "LAUNCHED"; break;
     644           0 :     case CIRC_EVENT_BUILT: status = "BUILT"; break;
     645           0 :     case CIRC_EVENT_EXTENDED: status = "EXTENDED"; break;
     646           0 :     case CIRC_EVENT_FAILED: status = "FAILED"; break;
     647           0 :     case CIRC_EVENT_CLOSED: status = "CLOSED"; break;
     648           0 :     default:
     649           0 :       log_warn(LD_BUG, "Unrecognized status code %d", (int)tp);
     650           0 :       tor_fragile_assert();
     651             :       return 0;
     652             :     }
     653             : 
     654           0 :   if (tp == CIRC_EVENT_FAILED || tp == CIRC_EVENT_CLOSED) {
     655           0 :     const char *reason_str = circuit_end_reason_to_control_string(reason_code);
     656           0 :     char unk_reason_buf[16];
     657           0 :     if (!reason_str) {
     658           0 :       tor_snprintf(unk_reason_buf, 16, "UNKNOWN_%d", reason_code);
     659           0 :       reason_str = unk_reason_buf;
     660             :     }
     661           0 :     if (reason_code > 0 && reason_code & END_CIRC_REASON_FLAG_REMOTE) {
     662           0 :       tor_snprintf(reasons, sizeof(reasons),
     663             :                    " REASON=DESTROYED REMOTE_REASON=%s", reason_str);
     664             :     } else {
     665           0 :       tor_snprintf(reasons, sizeof(reasons),
     666             :                    " REASON=%s", reason_str);
     667             :     }
     668             :   }
     669             : 
     670             :   {
     671           0 :     char *circdesc = circuit_describe_status_for_controller(circ);
     672           0 :     const char *sp = strlen(circdesc) ? " " : "";
     673           0 :     send_control_event(EVENT_CIRCUIT_STATUS,
     674             :                                 "650 CIRC %lu %s%s%s%s\r\n",
     675           0 :                                 (unsigned long)circ->global_identifier,
     676             :                                 status, sp,
     677             :                                 circdesc,
     678             :                                 reasons);
     679           0 :     tor_free(circdesc);
     680             :   }
     681             : 
     682           0 :   return 0;
     683             : }
     684             : 
     685             : /** Something minor has happened to circuit <b>circ</b>: tell any
     686             :  * interested control connections. */
     687             : static int
     688          10 : control_event_circuit_status_minor(origin_circuit_t *circ,
     689             :                                    circuit_status_minor_event_t e,
     690             :                                    int purpose, const struct timeval *tv)
     691             : {
     692          10 :   const char *event_desc;
     693          10 :   char event_tail[160] = "";
     694          10 :   if (!EVENT_IS_INTERESTING(EVENT_CIRCUIT_STATUS_MINOR))
     695             :     return 0;
     696           0 :   tor_assert(circ);
     697             : 
     698           0 :   switch (e)
     699             :     {
     700           0 :     case CIRC_MINOR_EVENT_PURPOSE_CHANGED:
     701           0 :       event_desc = "PURPOSE_CHANGED";
     702             : 
     703             :       {
     704             :         /* event_tail can currently be up to 68 chars long */
     705           0 :         const char *hs_state_str =
     706           0 :           circuit_purpose_to_controller_hs_state_string(purpose);
     707           0 :         tor_snprintf(event_tail, sizeof(event_tail),
     708             :                      " OLD_PURPOSE=%s%s%s",
     709             :                      circuit_purpose_to_controller_string(purpose),
     710             :                      (hs_state_str != NULL) ? " OLD_HS_STATE=" : "",
     711             :                      (hs_state_str != NULL) ? hs_state_str : "");
     712             :       }
     713             : 
     714           0 :       break;
     715           0 :     case CIRC_MINOR_EVENT_CANNIBALIZED:
     716           0 :       event_desc = "CANNIBALIZED";
     717             : 
     718             :       {
     719             :         /* event_tail can currently be up to 130 chars long */
     720           0 :         const char *hs_state_str =
     721           0 :           circuit_purpose_to_controller_hs_state_string(purpose);
     722           0 :         const struct timeval *old_timestamp_began = tv;
     723           0 :         char tbuf[ISO_TIME_USEC_LEN+1];
     724           0 :         format_iso_time_nospace_usec(tbuf, old_timestamp_began);
     725             : 
     726           0 :         tor_snprintf(event_tail, sizeof(event_tail),
     727             :                      " OLD_PURPOSE=%s%s%s OLD_TIME_CREATED=%s",
     728             :                      circuit_purpose_to_controller_string(purpose),
     729             :                      (hs_state_str != NULL) ? " OLD_HS_STATE=" : "",
     730             :                      (hs_state_str != NULL) ? hs_state_str : "",
     731             :                      tbuf);
     732             :       }
     733             : 
     734           0 :       break;
     735           0 :     default:
     736           0 :       log_warn(LD_BUG, "Unrecognized status code %d", (int)e);
     737           0 :       tor_fragile_assert();
     738             :       return 0;
     739             :     }
     740             : 
     741             :   {
     742           0 :     char *circdesc = circuit_describe_status_for_controller(circ);
     743           0 :     const char *sp = strlen(circdesc) ? " " : "";
     744           0 :     send_control_event(EVENT_CIRCUIT_STATUS_MINOR,
     745             :                        "650 CIRC_MINOR %lu %s%s%s%s\r\n",
     746           0 :                        (unsigned long)circ->global_identifier,
     747             :                        event_desc, sp,
     748             :                        circdesc,
     749             :                        event_tail);
     750           0 :     tor_free(circdesc);
     751             :   }
     752             : 
     753           0 :   return 0;
     754             : }
     755             : 
     756             : /**
     757             :  * <b>circ</b> has changed its purpose from <b>old_purpose</b>: tell any
     758             :  * interested controllers.
     759             :  */
     760             : int
     761          10 : control_event_circuit_purpose_changed(origin_circuit_t *circ,
     762             :                                       int old_purpose)
     763             : {
     764          10 :   return control_event_circuit_status_minor(circ,
     765             :                                             CIRC_MINOR_EVENT_PURPOSE_CHANGED,
     766             :                                             old_purpose,
     767             :                                             NULL);
     768             : }
     769             : 
     770             : /**
     771             :  * <b>circ</b> has changed its purpose from <b>old_purpose</b>, and its
     772             :  * created-time from <b>old_tv_created</b>: tell any interested controllers.
     773             :  */
     774             : int
     775           0 : control_event_circuit_cannibalized(origin_circuit_t *circ,
     776             :                                    int old_purpose,
     777             :                                    const struct timeval *old_tv_created)
     778             : {
     779           0 :   return control_event_circuit_status_minor(circ,
     780             :                                             CIRC_MINOR_EVENT_CANNIBALIZED,
     781             :                                             old_purpose,
     782             :                                             old_tv_created);
     783             : }
     784             : 
     785             : /** Something has happened to the stream associated with AP connection
     786             :  * <b>conn</b>: tell any interested control connections. */
     787             : int
     788          27 : control_event_stream_status(entry_connection_t *conn, stream_status_event_t tp,
     789             :                             int reason_code)
     790             : {
     791          27 :   char reason_buf[64];
     792          27 :   char addrport_buf[64];
     793          27 :   const char *status;
     794          27 :   circuit_t *circ;
     795          27 :   origin_circuit_t *origin_circ = NULL;
     796          27 :   char buf[256];
     797          27 :   const char *purpose = "";
     798          27 :   tor_assert(conn->socks_request);
     799             : 
     800          27 :   if (!EVENT_IS_INTERESTING(EVENT_STREAM_STATUS))
     801             :     return 0;
     802             : 
     803           0 :   if (tp == STREAM_EVENT_CLOSED &&
     804           0 :       (reason_code & END_STREAM_REASON_FLAG_ALREADY_SENT_CLOSED))
     805             :     return 0;
     806             : 
     807           0 :   write_stream_target_to_buf(conn, buf, sizeof(buf));
     808             : 
     809           0 :   reason_buf[0] = '\0';
     810           0 :   switch (tp)
     811             :     {
     812             :     case STREAM_EVENT_SENT_CONNECT: status = "SENTCONNECT"; break;
     813           0 :     case STREAM_EVENT_SENT_RESOLVE: status = "SENTRESOLVE"; break;
     814           0 :     case STREAM_EVENT_SUCCEEDED: status = "SUCCEEDED"; break;
     815           0 :     case STREAM_EVENT_FAILED: status = "FAILED"; break;
     816           0 :     case STREAM_EVENT_CLOSED: status = "CLOSED"; break;
     817           0 :     case STREAM_EVENT_NEW: status = "NEW"; break;
     818           0 :     case STREAM_EVENT_NEW_RESOLVE: status = "NEWRESOLVE"; break;
     819           0 :     case STREAM_EVENT_FAILED_RETRIABLE: status = "DETACHED"; break;
     820           0 :     case STREAM_EVENT_REMAP: status = "REMAP"; break;
     821           0 :     case STREAM_EVENT_CONTROLLER_WAIT: status = "CONTROLLER_WAIT"; break;
     822           0 :     default:
     823           0 :       log_warn(LD_BUG, "Unrecognized status code %d", (int)tp);
     824           0 :       return 0;
     825             :     }
     826           0 :   if (reason_code && (tp == STREAM_EVENT_FAILED ||
     827           0 :                       tp == STREAM_EVENT_CLOSED ||
     828           0 :                       tp == STREAM_EVENT_FAILED_RETRIABLE)) {
     829           0 :     const char *reason_str = stream_end_reason_to_control_string(reason_code);
     830           0 :     char *r = NULL;
     831           0 :     if (!reason_str) {
     832           0 :       tor_asprintf(&r, " UNKNOWN_%d", reason_code);
     833           0 :       reason_str = r;
     834             :     }
     835           0 :     if (reason_code & END_STREAM_REASON_FLAG_REMOTE)
     836           0 :       tor_snprintf(reason_buf, sizeof(reason_buf),
     837             :                    " REASON=END REMOTE_REASON=%s", reason_str);
     838             :     else
     839           0 :       tor_snprintf(reason_buf, sizeof(reason_buf),
     840             :                    " REASON=%s", reason_str);
     841           0 :     tor_free(r);
     842           0 :   } else if (reason_code && tp == STREAM_EVENT_REMAP) {
     843           0 :     switch (reason_code) {
     844           0 :     case REMAP_STREAM_SOURCE_CACHE:
     845           0 :       strlcpy(reason_buf, " SOURCE=CACHE", sizeof(reason_buf));
     846           0 :       break;
     847           0 :     case REMAP_STREAM_SOURCE_EXIT:
     848           0 :       strlcpy(reason_buf, " SOURCE=EXIT", sizeof(reason_buf));
     849           0 :       break;
     850           0 :     default:
     851           0 :       tor_snprintf(reason_buf, sizeof(reason_buf), " REASON=UNKNOWN_%d",
     852             :                    reason_code);
     853             :       /* XXX do we want SOURCE=UNKNOWN_%d above instead? -RD */
     854           0 :       break;
     855             :     }
     856             :   }
     857             : 
     858           0 :   if (tp == STREAM_EVENT_NEW || tp == STREAM_EVENT_NEW_RESOLVE) {
     859             :     /*
     860             :      * When the control conn is an AF_UNIX socket and we have no address,
     861             :      * it gets set to "(Tor_internal)"; see dnsserv_launch_request() in
     862             :      * dnsserv.c.
     863             :      */
     864           0 :     if (strcmp(ENTRY_TO_CONN(conn)->address, "(Tor_internal)") != 0) {
     865           0 :       tor_snprintf(addrport_buf,sizeof(addrport_buf), " SOURCE_ADDR=%s:%d",
     866           0 :                    ENTRY_TO_CONN(conn)->address, ENTRY_TO_CONN(conn)->port);
     867             :     } else {
     868             :       /*
     869             :        * else leave it blank so control on AF_UNIX doesn't need to make
     870             :        * something up.
     871             :        */
     872           0 :       addrport_buf[0] = '\0';
     873             :     }
     874             :   } else {
     875           0 :     addrport_buf[0] = '\0';
     876             :   }
     877             : 
     878           0 :   if (tp == STREAM_EVENT_NEW_RESOLVE) {
     879             :     purpose = " PURPOSE=DNS_REQUEST";
     880           0 :   } else if (tp == STREAM_EVENT_NEW) {
     881           0 :     if (conn->use_begindir) {
     882           0 :       connection_t *linked = ENTRY_TO_CONN(conn)->linked_conn;
     883           0 :       int linked_dir_purpose = -1;
     884           0 :       if (linked && linked->type == CONN_TYPE_DIR)
     885           0 :         linked_dir_purpose = linked->purpose;
     886           0 :       if (DIR_PURPOSE_IS_UPLOAD(linked_dir_purpose))
     887             :         purpose = " PURPOSE=DIR_UPLOAD";
     888             :       else
     889           0 :         purpose = " PURPOSE=DIR_FETCH";
     890             :     } else
     891             :       purpose = " PURPOSE=USER";
     892             :   }
     893             : 
     894           0 :   circ = circuit_get_by_edge_conn(ENTRY_TO_EDGE_CONN(conn));
     895           0 :   if (circ && CIRCUIT_IS_ORIGIN(circ))
     896           0 :     origin_circ = TO_ORIGIN_CIRCUIT(circ);
     897             : 
     898             :   {
     899           0 :     char *conndesc = entry_connection_describe_status_for_controller(conn);
     900           0 :     const char *sp = strlen(conndesc) ? " " : "";
     901           0 :     send_control_event(EVENT_STREAM_STATUS,
     902             :                         "650 STREAM %"PRIu64" %s %lu %s%s%s%s%s%s\r\n",
     903             :                      (ENTRY_TO_CONN(conn)->global_identifier),
     904             :                      status,
     905             :                         origin_circ?
     906           0 :                            (unsigned long)origin_circ->global_identifier : 0ul,
     907             :                         buf, reason_buf, addrport_buf, purpose, sp, conndesc);
     908           0 :     tor_free(conndesc);
     909             :   }
     910             : 
     911             :   /* XXX need to specify its intended exit, etc? */
     912             : 
     913           0 :   return 0;
     914             : }
     915             : 
     916             : /** Called when the status of an OR connection <b>conn</b> changes: tell any
     917             :  * interested control connections. <b>tp</b> is the new status for the
     918             :  * connection.  If <b>conn</b> has just closed or failed, then <b>reason</b>
     919             :  * may be the reason why.
     920             :  */
     921             : int
     922           5 : control_event_or_conn_status(or_connection_t *conn, or_conn_status_event_t tp,
     923             :                              int reason)
     924             : {
     925           5 :   int ncircs = 0;
     926           5 :   const char *status;
     927           5 :   char name[128];
     928           5 :   char ncircs_buf[32] = {0}; /* > 8 + log10(2^32)=10 + 2 */
     929             : 
     930           5 :   if (!EVENT_IS_INTERESTING(EVENT_OR_CONN_STATUS))
     931             :     return 0;
     932             : 
     933           0 :   switch (tp)
     934             :     {
     935             :     case OR_CONN_EVENT_LAUNCHED: status = "LAUNCHED"; break;
     936           0 :     case OR_CONN_EVENT_CONNECTED: status = "CONNECTED"; break;
     937           0 :     case OR_CONN_EVENT_FAILED: status = "FAILED"; break;
     938           0 :     case OR_CONN_EVENT_CLOSED: status = "CLOSED"; break;
     939           0 :     case OR_CONN_EVENT_NEW: status = "NEW"; break;
     940           0 :     default:
     941           0 :       log_warn(LD_BUG, "Unrecognized status code %d", (int)tp);
     942           0 :       return 0;
     943             :     }
     944           0 :   if (conn->chan) {
     945           0 :     ncircs = circuit_count_pending_on_channel(TLS_CHAN_TO_BASE(conn->chan));
     946             :   } else {
     947             :     ncircs = 0;
     948             :   }
     949           0 :   ncircs += connection_or_get_num_circuits(conn);
     950           0 :   if (ncircs && (tp == OR_CONN_EVENT_FAILED || tp == OR_CONN_EVENT_CLOSED)) {
     951           0 :     tor_snprintf(ncircs_buf, sizeof(ncircs_buf), " NCIRCS=%d", ncircs);
     952             :   }
     953             : 
     954           0 :   orconn_target_get_name(name, sizeof(name), conn);
     955           0 :   send_control_event(EVENT_OR_CONN_STATUS,
     956             :                               "650 ORCONN %s %s%s%s%s ID=%"PRIu64"\r\n",
     957             :                               name, status,
     958             :                               reason ? " REASON=" : "",
     959             :                               orconn_end_reason_to_control_string(reason),
     960             :                               ncircs_buf,
     961             :                               (conn->base_.global_identifier));
     962             : 
     963           0 :   return 0;
     964             : }
     965             : 
     966             : /**
     967             :  * Print out STREAM_BW event for a single conn
     968             :  */
     969             : int
     970           6 : control_event_stream_bandwidth(edge_connection_t *edge_conn)
     971             : {
     972           6 :   struct timeval now;
     973           6 :   char tbuf[ISO_TIME_USEC_LEN+1];
     974           6 :   if (EVENT_IS_INTERESTING(EVENT_STREAM_BANDWIDTH_USED)) {
     975           0 :     if (!edge_conn->n_read && !edge_conn->n_written)
     976             :       return 0;
     977             : 
     978           0 :     tor_gettimeofday(&now);
     979           0 :     format_iso_time_nospace_usec(tbuf, &now);
     980           0 :     send_control_event(EVENT_STREAM_BANDWIDTH_USED,
     981             :                        "650 STREAM_BW %"PRIu64" %lu %lu %s\r\n",
     982             :                        (edge_conn->base_.global_identifier),
     983           0 :                        (unsigned long)edge_conn->n_read,
     984           0 :                        (unsigned long)edge_conn->n_written,
     985             :                        tbuf);
     986             : 
     987           0 :     edge_conn->n_written = edge_conn->n_read = 0;
     988             :   }
     989             : 
     990             :   return 0;
     991             : }
     992             : 
     993             : /** A second or more has elapsed: tell any interested control
     994             :  * connections how much bandwidth streams have used. */
     995             : int
     996           0 : control_event_stream_bandwidth_used(void)
     997             : {
     998           0 :   if (EVENT_IS_INTERESTING(EVENT_STREAM_BANDWIDTH_USED)) {
     999           0 :     smartlist_t *conns = get_connection_array();
    1000           0 :     edge_connection_t *edge_conn;
    1001           0 :     struct timeval now;
    1002           0 :     char tbuf[ISO_TIME_USEC_LEN+1];
    1003             : 
    1004           0 :     SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn)
    1005             :     {
    1006           0 :         if (conn->type != CONN_TYPE_AP)
    1007           0 :           continue;
    1008           0 :         edge_conn = TO_EDGE_CONN(conn);
    1009           0 :         if (!edge_conn->n_read && !edge_conn->n_written)
    1010           0 :           continue;
    1011             : 
    1012           0 :         tor_gettimeofday(&now);
    1013           0 :         format_iso_time_nospace_usec(tbuf, &now);
    1014           0 :         send_control_event(EVENT_STREAM_BANDWIDTH_USED,
    1015             :                            "650 STREAM_BW %"PRIu64" %lu %lu %s\r\n",
    1016             :                            (edge_conn->base_.global_identifier),
    1017           0 :                            (unsigned long)edge_conn->n_read,
    1018           0 :                            (unsigned long)edge_conn->n_written,
    1019             :                            tbuf);
    1020             : 
    1021           0 :         edge_conn->n_written = edge_conn->n_read = 0;
    1022             :     }
    1023           0 :     SMARTLIST_FOREACH_END(conn);
    1024             :   }
    1025             : 
    1026           0 :   return 0;
    1027             : }
    1028             : 
    1029             : /** A second or more has elapsed: tell any interested control connections
    1030             :  * how much bandwidth origin circuits have used. */
    1031             : int
    1032           0 : control_event_circ_bandwidth_used(void)
    1033             : {
    1034           0 :   if (!EVENT_IS_INTERESTING(EVENT_CIRC_BANDWIDTH_USED))
    1035             :     return 0;
    1036             : 
    1037           0 :   SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
    1038           0 :     if (!CIRCUIT_IS_ORIGIN(circ))
    1039           0 :       continue;
    1040             : 
    1041           0 :     control_event_circ_bandwidth_used_for_circ(TO_ORIGIN_CIRCUIT(circ));
    1042             :   }
    1043           0 :   SMARTLIST_FOREACH_END(circ);
    1044             : 
    1045             :   return 0;
    1046             : }
    1047             : 
    1048             : /**
    1049             :  * Emit a CIRC_BW event line for a specific circuit.
    1050             :  *
    1051             :  * This function sets the values it emits to 0, and does not emit
    1052             :  * an event if there is no new data to report since the last call.
    1053             :  *
    1054             :  * Therefore, it may be called at any frequency.
    1055             :  */
    1056             : int
    1057           0 : control_event_circ_bandwidth_used_for_circ(origin_circuit_t *ocirc)
    1058             : {
    1059           0 :   struct timeval now;
    1060           0 :   char tbuf[ISO_TIME_USEC_LEN+1];
    1061             : 
    1062           0 :   tor_assert(ocirc);
    1063             : 
    1064           0 :   if (!EVENT_IS_INTERESTING(EVENT_CIRC_BANDWIDTH_USED))
    1065             :     return 0;
    1066             : 
    1067             :   /* n_read_circ_bw and n_written_circ_bw are always updated
    1068             :    * when there is any new cell on a circuit, and set to 0 after
    1069             :    * the event, below.
    1070             :    *
    1071             :    * Therefore, checking them is sufficient to determine if there
    1072             :    * is new data to report. */
    1073           0 :   if (!ocirc->n_read_circ_bw && !ocirc->n_written_circ_bw)
    1074             :     return 0;
    1075             : 
    1076           0 :   tor_gettimeofday(&now);
    1077           0 :   format_iso_time_nospace_usec(tbuf, &now);
    1078           0 :   send_control_event(EVENT_CIRC_BANDWIDTH_USED,
    1079             :                      "650 CIRC_BW ID=%d READ=%lu WRITTEN=%lu TIME=%s "
    1080             :                      "DELIVERED_READ=%lu OVERHEAD_READ=%lu "
    1081             :                      "DELIVERED_WRITTEN=%lu OVERHEAD_WRITTEN=%lu\r\n",
    1082             :                      ocirc->global_identifier,
    1083           0 :                      (unsigned long)ocirc->n_read_circ_bw,
    1084           0 :                      (unsigned long)ocirc->n_written_circ_bw,
    1085             :                      tbuf,
    1086           0 :                      (unsigned long)ocirc->n_delivered_read_circ_bw,
    1087           0 :                      (unsigned long)ocirc->n_overhead_read_circ_bw,
    1088           0 :                      (unsigned long)ocirc->n_delivered_written_circ_bw,
    1089           0 :                      (unsigned long)ocirc->n_overhead_written_circ_bw);
    1090           0 :   ocirc->n_written_circ_bw = ocirc->n_read_circ_bw = 0;
    1091           0 :   ocirc->n_overhead_written_circ_bw = ocirc->n_overhead_read_circ_bw = 0;
    1092           0 :   ocirc->n_delivered_written_circ_bw = ocirc->n_delivered_read_circ_bw = 0;
    1093             : 
    1094           0 :   return 0;
    1095             : }
    1096             : 
    1097             : /** Print out CONN_BW event for a single OR/DIR/EXIT <b>conn</b> and reset
    1098             :   * bandwidth counters. */
    1099             : int
    1100          14 : control_event_conn_bandwidth(connection_t *conn)
    1101             : {
    1102          14 :   const char *conn_type_str;
    1103          14 :   if (!get_options()->TestingEnableConnBwEvent ||
    1104           0 :       !EVENT_IS_INTERESTING(EVENT_CONN_BW))
    1105             :     return 0;
    1106           0 :   if (!conn->n_read_conn_bw && !conn->n_written_conn_bw)
    1107             :     return 0;
    1108           0 :   switch (conn->type) {
    1109             :     case CONN_TYPE_OR:
    1110             :       conn_type_str = "OR";
    1111             :       break;
    1112           0 :     case CONN_TYPE_DIR:
    1113           0 :       conn_type_str = "DIR";
    1114           0 :       break;
    1115           0 :     case CONN_TYPE_EXIT:
    1116           0 :       conn_type_str = "EXIT";
    1117           0 :       break;
    1118             :     default:
    1119             :       return 0;
    1120             :   }
    1121           0 :   send_control_event(EVENT_CONN_BW,
    1122             :                      "650 CONN_BW ID=%"PRIu64" TYPE=%s "
    1123             :                      "READ=%lu WRITTEN=%lu\r\n",
    1124             :                      (conn->global_identifier),
    1125             :                      conn_type_str,
    1126           0 :                      (unsigned long)conn->n_read_conn_bw,
    1127           0 :                      (unsigned long)conn->n_written_conn_bw);
    1128           0 :   conn->n_written_conn_bw = conn->n_read_conn_bw = 0;
    1129           0 :   return 0;
    1130             : }
    1131             : 
    1132             : /** A second or more has elapsed: tell any interested control
    1133             :  * connections how much bandwidth connections have used. */
    1134             : int
    1135           0 : control_event_conn_bandwidth_used(void)
    1136             : {
    1137           0 :   if (get_options()->TestingEnableConnBwEvent &&
    1138           0 :       EVENT_IS_INTERESTING(EVENT_CONN_BW)) {
    1139           0 :     SMARTLIST_FOREACH(get_connection_array(), connection_t *, conn,
    1140             :                       control_event_conn_bandwidth(conn));
    1141             :   }
    1142           0 :   return 0;
    1143             : }
    1144             : 
    1145             : /** Helper: iterate over cell statistics of <b>circ</b> and sum up added
    1146             :  * cells, removed cells, and waiting times by cell command and direction.
    1147             :  * Store results in <b>cell_stats</b>.  Free cell statistics of the
    1148             :  * circuit afterwards. */
    1149             : void
    1150           4 : sum_up_cell_stats_by_command(circuit_t *circ, cell_stats_t *cell_stats)
    1151             : {
    1152           4 :   memset(cell_stats, 0, sizeof(cell_stats_t));
    1153           8 :   SMARTLIST_FOREACH_BEGIN(circ->testing_cell_stats,
    1154             :                           const testing_cell_stats_entry_t *, ent) {
    1155           4 :     tor_assert(ent->command <= CELL_COMMAND_MAX_);
    1156           4 :     if (!ent->removed && !ent->exitward) {
    1157           1 :       cell_stats->added_cells_appward[ent->command] += 1;
    1158           3 :     } else if (!ent->removed && ent->exitward) {
    1159           1 :       cell_stats->added_cells_exitward[ent->command] += 1;
    1160           2 :     } else if (!ent->exitward) {
    1161           1 :       cell_stats->removed_cells_appward[ent->command] += 1;
    1162           1 :       cell_stats->total_time_appward[ent->command] += ent->waiting_time * 10;
    1163             :     } else {
    1164           1 :       cell_stats->removed_cells_exitward[ent->command] += 1;
    1165           1 :       cell_stats->total_time_exitward[ent->command] += ent->waiting_time * 10;
    1166             :     }
    1167           4 :   } SMARTLIST_FOREACH_END(ent);
    1168           4 :   circuit_clear_testing_cell_stats(circ);
    1169           4 : }
    1170             : 
    1171             : /** Helper: append a cell statistics string to <code>event_parts</code>,
    1172             :  * prefixed with <code>key</code>=.  Statistics consist of comma-separated
    1173             :  * key:value pairs with lower-case command strings as keys and cell
    1174             :  * numbers or total waiting times as values.  A key:value pair is included
    1175             :  * if the entry in <code>include_if_non_zero</code> is not zero, but with
    1176             :  * the (possibly zero) entry from <code>number_to_include</code>.  Both
    1177             :  * arrays are expected to have a length of CELL_COMMAND_MAX_ + 1.  If no
    1178             :  * entry in <code>include_if_non_zero</code> is positive, no string will
    1179             :  * be added to <code>event_parts</code>. */
    1180             : void
    1181          34 : append_cell_stats_by_command(smartlist_t *event_parts, const char *key,
    1182             :                              const uint64_t *include_if_non_zero,
    1183             :                              const uint64_t *number_to_include)
    1184             : {
    1185          34 :   smartlist_t *key_value_strings = smartlist_new();
    1186          34 :   int i;
    1187        4590 :   for (i = 0; i <= CELL_COMMAND_MAX_; i++) {
    1188        4522 :     if (include_if_non_zero[i] > 0) {
    1189          14 :       smartlist_add_asprintf(key_value_strings, "%s:%"PRIu64,
    1190             :                              cell_command_to_string(i),
    1191          14 :                              (number_to_include[i]));
    1192             :     }
    1193             :   }
    1194          34 :   if (smartlist_len(key_value_strings) > 0) {
    1195          11 :     char *joined = smartlist_join_strings(key_value_strings, ",", 0, NULL);
    1196          11 :     smartlist_add_asprintf(event_parts, "%s=%s", key, joined);
    1197          25 :     SMARTLIST_FOREACH(key_value_strings, char *, cp, tor_free(cp));
    1198          11 :     tor_free(joined);
    1199             :   }
    1200          34 :   smartlist_free(key_value_strings);
    1201          34 : }
    1202             : 
    1203             : /** Helper: format <b>cell_stats</b> for <b>circ</b> for inclusion in a
    1204             :  * CELL_STATS event and write result string to <b>event_string</b>. */
    1205             : void
    1206           7 : format_cell_stats(char **event_string, circuit_t *circ,
    1207             :                   cell_stats_t *cell_stats)
    1208             : {
    1209           7 :   smartlist_t *event_parts = smartlist_new();
    1210           7 :   if (CIRCUIT_IS_ORIGIN(circ)) {
    1211           4 :     origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
    1212           4 :     smartlist_add_asprintf(event_parts, "ID=%lu",
    1213           4 :                  (unsigned long)ocirc->global_identifier);
    1214           3 :   } else if (TO_OR_CIRCUIT(circ)->p_chan) {
    1215           3 :     or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
    1216           3 :     smartlist_add_asprintf(event_parts, "InboundQueue=%lu",
    1217           3 :                  (unsigned long)or_circ->p_circ_id);
    1218           3 :     smartlist_add_asprintf(event_parts, "InboundConn=%"PRIu64,
    1219           3 :                  (or_circ->p_chan->global_identifier));
    1220           3 :     append_cell_stats_by_command(event_parts, "InboundAdded",
    1221             :                                  cell_stats->added_cells_appward,
    1222           3 :                                  cell_stats->added_cells_appward);
    1223           3 :     append_cell_stats_by_command(event_parts, "InboundRemoved",
    1224             :                                  cell_stats->removed_cells_appward,
    1225           3 :                                  cell_stats->removed_cells_appward);
    1226           3 :     append_cell_stats_by_command(event_parts, "InboundTime",
    1227             :                                  cell_stats->removed_cells_appward,
    1228           3 :                                  cell_stats->total_time_appward);
    1229             :   }
    1230           7 :   if (circ->n_chan) {
    1231           7 :     smartlist_add_asprintf(event_parts, "OutboundQueue=%lu",
    1232           7 :                      (unsigned long)circ->n_circ_id);
    1233           7 :     smartlist_add_asprintf(event_parts, "OutboundConn=%"PRIu64,
    1234           7 :                  (circ->n_chan->global_identifier));
    1235           7 :     append_cell_stats_by_command(event_parts, "OutboundAdded",
    1236             :                                  cell_stats->added_cells_exitward,
    1237           7 :                                  cell_stats->added_cells_exitward);
    1238           7 :     append_cell_stats_by_command(event_parts, "OutboundRemoved",
    1239             :                                  cell_stats->removed_cells_exitward,
    1240           7 :                                  cell_stats->removed_cells_exitward);
    1241           7 :     append_cell_stats_by_command(event_parts, "OutboundTime",
    1242             :                                  cell_stats->removed_cells_exitward,
    1243           7 :                                  cell_stats->total_time_exitward);
    1244             :   }
    1245           7 :   *event_string = smartlist_join_strings(event_parts, " ", 0, NULL);
    1246          40 :   SMARTLIST_FOREACH(event_parts, char *, cp, tor_free(cp));
    1247           7 :   smartlist_free(event_parts);
    1248           7 : }
    1249             : 
    1250             : /** A second or more has elapsed: tell any interested control connection
    1251             :  * how many cells have been processed for a given circuit. */
    1252             : int
    1253           0 : control_event_circuit_cell_stats(void)
    1254             : {
    1255           0 :   cell_stats_t *cell_stats;
    1256           0 :   char *event_string;
    1257           0 :   if (!get_options()->TestingEnableCellStatsEvent ||
    1258           0 :       !EVENT_IS_INTERESTING(EVENT_CELL_STATS))
    1259             :     return 0;
    1260           0 :   cell_stats = tor_malloc(sizeof(cell_stats_t));
    1261           0 :   SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
    1262           0 :     if (!circ->testing_cell_stats)
    1263           0 :       continue;
    1264           0 :     sum_up_cell_stats_by_command(circ, cell_stats);
    1265           0 :     format_cell_stats(&event_string, circ, cell_stats);
    1266           0 :     send_control_event(EVENT_CELL_STATS,
    1267             :                        "650 CELL_STATS %s\r\n", event_string);
    1268           0 :     tor_free(event_string);
    1269             :   }
    1270           0 :   SMARTLIST_FOREACH_END(circ);
    1271           0 :   tor_free(cell_stats);
    1272           0 :   return 0;
    1273             : }
    1274             : 
    1275             : /* about 5 minutes worth. */
    1276             : #define N_BW_EVENTS_TO_CACHE 300
    1277             : /* Index into cached_bw_events to next write. */
    1278             : static int next_measurement_idx = 0;
    1279             : /* number of entries set in n_measurements */
    1280             : static int n_measurements = 0;
    1281             : static struct cached_bw_event_t {
    1282             :   uint32_t n_read;
    1283             :   uint32_t n_written;
    1284             : } cached_bw_events[N_BW_EVENTS_TO_CACHE];
    1285             : 
    1286             : /** A second or more has elapsed: tell any interested control
    1287             :  * connections how much bandwidth we used. */
    1288             : int
    1289           0 : control_event_bandwidth_used(uint32_t n_read, uint32_t n_written)
    1290             : {
    1291           0 :   cached_bw_events[next_measurement_idx].n_read = n_read;
    1292           0 :   cached_bw_events[next_measurement_idx].n_written = n_written;
    1293           0 :   if (++next_measurement_idx == N_BW_EVENTS_TO_CACHE)
    1294           0 :     next_measurement_idx = 0;
    1295           0 :   if (n_measurements < N_BW_EVENTS_TO_CACHE)
    1296           0 :     ++n_measurements;
    1297             : 
    1298           0 :   if (EVENT_IS_INTERESTING(EVENT_BANDWIDTH_USED)) {
    1299           0 :     send_control_event(EVENT_BANDWIDTH_USED,
    1300             :                        "650 BW %lu %lu\r\n",
    1301             :                        (unsigned long)n_read,
    1302             :                        (unsigned long)n_written);
    1303             :   }
    1304             : 
    1305           0 :   return 0;
    1306             : }
    1307             : 
    1308             : char *
    1309           0 : get_bw_samples(void)
    1310             : {
    1311           0 :   int i;
    1312           0 :   int idx = (next_measurement_idx + N_BW_EVENTS_TO_CACHE - n_measurements)
    1313             :     % N_BW_EVENTS_TO_CACHE;
    1314           0 :   tor_assert(0 <= idx && idx < N_BW_EVENTS_TO_CACHE);
    1315             : 
    1316           0 :   smartlist_t *elements = smartlist_new();
    1317             : 
    1318           0 :   for (i = 0; i < n_measurements; ++i) {
    1319           0 :     tor_assert(0 <= idx && idx < N_BW_EVENTS_TO_CACHE);
    1320           0 :     const struct cached_bw_event_t *bwe = &cached_bw_events[idx];
    1321             : 
    1322           0 :     smartlist_add_asprintf(elements, "%u,%u",
    1323           0 :                            (unsigned)bwe->n_read,
    1324           0 :                            (unsigned)bwe->n_written);
    1325             : 
    1326           0 :     idx = (idx + 1) % N_BW_EVENTS_TO_CACHE;
    1327             :   }
    1328             : 
    1329           0 :   char *result = smartlist_join_strings(elements, " ", 0, NULL);
    1330             : 
    1331           0 :   SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
    1332           0 :   smartlist_free(elements);
    1333             : 
    1334           0 :   return result;
    1335             : }
    1336             : 
    1337             : /** Called when we are sending a log message to the controllers: suspend
    1338             :  * sending further log messages to the controllers until we're done.  Used by
    1339             :  * CONN_LOG_PROTECT. */
    1340             : void
    1341           0 : disable_control_logging(void)
    1342             : {
    1343           0 :   ++disable_log_messages;
    1344           0 : }
    1345             : 
    1346             : /** We're done sending a log message to the controllers: re-enable controller
    1347             :  * logging.  Used by CONN_LOG_PROTECT. */
    1348             : void
    1349           0 : enable_control_logging(void)
    1350             : {
    1351           0 :   if (--disable_log_messages < 0)
    1352           0 :     tor_assert(0);
    1353           0 : }
    1354             : 
    1355             : /** Remove newline and carriage-return characters from @a msg, replacing them
    1356             :  * with spaces, and discarding any that appear at the end of the message */
    1357             : void
    1358           8 : control_logmsg_strip_newlines(char *msg)
    1359             : {
    1360           8 :   char *cp;
    1361          86 :   for (cp = msg; *cp; ++cp) {
    1362          78 :     if (*cp == '\r' || *cp == '\n') {
    1363           7 :       *cp = ' ';
    1364             :     }
    1365             :   }
    1366           8 :   if (cp == msg)
    1367             :     return;
    1368             :   /* Remove trailing spaces */
    1369          24 :   for (--cp; *cp == ' '; --cp) {
    1370          19 :     *cp = '\0';
    1371          19 :     if (cp == msg)
    1372             :       break;
    1373             :   }
    1374             : }
    1375             : 
    1376             : /** We got a log message: tell any interested control connections. */
    1377             : void
    1378           8 : control_event_logmsg(int severity, log_domain_mask_t domain, const char *msg)
    1379             : {
    1380           8 :   int event;
    1381             : 
    1382             :   /* Don't even think of trying to add stuff to a buffer from a cpuworker
    1383             :    * thread. (See #25987 for plan to fix.) */
    1384           8 :   if (! in_main_thread())
    1385             :     return;
    1386             : 
    1387           8 :   if (disable_log_messages)
    1388             :     return;
    1389             : 
    1390           8 :   if (domain == LD_BUG && EVENT_IS_INTERESTING(EVENT_STATUS_GENERAL) &&
    1391             :       severity <= LOG_NOTICE) {
    1392           0 :     char *esc = esc_for_log(msg);
    1393           0 :     ++disable_log_messages;
    1394           0 :     control_event_general_status(severity, "BUG REASON=%s", esc);
    1395           0 :     --disable_log_messages;
    1396           0 :     tor_free(esc);
    1397             :   }
    1398             : 
    1399           8 :   event = log_severity_to_event(severity);
    1400           8 :   if (event >= 0 && EVENT_IS_INTERESTING(event)) {
    1401           0 :     char *b = NULL;
    1402           0 :     const char *s;
    1403           0 :     if (strchr(msg, '\n')) {
    1404           0 :       b = tor_strdup(msg);
    1405           0 :       control_logmsg_strip_newlines(b);
    1406             :     }
    1407           0 :     switch (severity) {
    1408             :       case LOG_DEBUG: s = "DEBUG"; break;
    1409           0 :       case LOG_INFO: s = "INFO"; break;
    1410           0 :       case LOG_NOTICE: s = "NOTICE"; break;
    1411           0 :       case LOG_WARN: s = "WARN"; break;
    1412           0 :       case LOG_ERR: s = "ERR"; break;
    1413           0 :       default: s = "UnknownLogSeverity"; break;
    1414             :     }
    1415           0 :     ++disable_log_messages;
    1416           0 :     send_control_event(event,  "650 %s %s\r\n", s, b?b:msg);
    1417           0 :     if (severity == LOG_ERR) {
    1418             :       /* Force a flush, since we may be about to die horribly */
    1419           0 :       queued_events_flush_all(1);
    1420             :     }
    1421           0 :     --disable_log_messages;
    1422           0 :     tor_free(b);
    1423             :   }
    1424             : }
    1425             : 
    1426             : /**
    1427             :  * Logging callback: called when there is a queued pending log callback.
    1428             :  */
    1429             : void
    1430           0 : control_event_logmsg_pending(void)
    1431             : {
    1432           0 :   if (! in_main_thread()) {
    1433             :     /* We can't handle this case yet, since we're using a
    1434             :      * mainloop_event_t to invoke queued_events_flush_all.  We ought to
    1435             :      * use a different mechanism instead: see #25987.
    1436             :      **/
    1437             :     return;
    1438             :   }
    1439           0 :   tor_assert(flush_queued_events_event);
    1440           0 :   mainloop_event_activate(flush_queued_events_event);
    1441             : }
    1442             : 
    1443             : /** Called whenever we receive new router descriptors: tell any
    1444             :  * interested control connections.  <b>routers</b> is a list of
    1445             :  * routerinfo_t's.
    1446             :  */
    1447             : int
    1448          25 : control_event_descriptors_changed(smartlist_t *routers)
    1449             : {
    1450          25 :   char *msg;
    1451             : 
    1452          25 :   if (!EVENT_IS_INTERESTING(EVENT_NEW_DESC))
    1453             :     return 0;
    1454             : 
    1455             :   {
    1456           0 :     smartlist_t *names = smartlist_new();
    1457           0 :     char *ids;
    1458           0 :     SMARTLIST_FOREACH(routers, routerinfo_t *, ri, {
    1459             :         char *b = tor_malloc(MAX_VERBOSE_NICKNAME_LEN+1);
    1460             :         router_get_verbose_nickname(b, ri);
    1461             :         smartlist_add(names, b);
    1462             :       });
    1463           0 :     ids = smartlist_join_strings(names, " ", 0, NULL);
    1464           0 :     tor_asprintf(&msg, "650 NEWDESC %s\r\n", ids);
    1465           0 :     send_control_event_string(EVENT_NEW_DESC,  msg);
    1466           0 :     tor_free(ids);
    1467           0 :     tor_free(msg);
    1468           0 :     SMARTLIST_FOREACH(names, char *, cp, tor_free(cp));
    1469           0 :     smartlist_free(names);
    1470             :   }
    1471           0 :   return 0;
    1472             : }
    1473             : 
    1474             : /** Called when an address mapping on <b>from</b> from changes to <b>to</b>.
    1475             :  * <b>expires</b> values less than 3 are special; see connection_edge.c.  If
    1476             :  * <b>error</b> is non-NULL, it is an error code describing the failure
    1477             :  * mode of the mapping.
    1478             :  */
    1479             : int
    1480          41 : control_event_address_mapped(const char *from, const char *to,
    1481             :                              time_t expires, const char *error,
    1482             :                              const int cached, uint64_t stream_id)
    1483             : {
    1484          41 :   char *stream_id_str = NULL;
    1485          41 :   if (!EVENT_IS_INTERESTING(EVENT_ADDRMAP))
    1486             :     return 0;
    1487             : 
    1488           0 :   if (stream_id) {
    1489           0 :     tor_asprintf(&stream_id_str, " STREAMID=%"PRIu64"", stream_id);
    1490             :   }
    1491             : 
    1492           0 :   if (expires < 3 || expires == TIME_MAX)
    1493           0 :     send_control_event(EVENT_ADDRMAP,
    1494             :                                 "650 ADDRMAP %s %s NEVER %s%s"
    1495             :                                 "CACHED=\"%s\"%s\r\n",
    1496             :                                 from, to, error ? error : "", error ? " " : "",
    1497             :                                 cached ? "YES" : "NO",
    1498             :                                 stream_id ? stream_id_str : "");
    1499             :   else {
    1500           0 :     char buf[ISO_TIME_LEN+1];
    1501           0 :     char buf2[ISO_TIME_LEN+1];
    1502           0 :     format_local_iso_time(buf,expires);
    1503           0 :     format_iso_time(buf2,expires);
    1504           0 :     send_control_event(EVENT_ADDRMAP,
    1505             :                                 "650 ADDRMAP %s %s \"%s\" %s%sEXPIRES=\"%s\" "
    1506             :                                 "CACHED=\"%s\"%s\r\n",
    1507             :                                 from, to, buf, error ? error : "",
    1508             :                                 error ? " " : "", buf2, cached ? "YES" : "NO",
    1509             :                                 stream_id ? stream_id_str: "");
    1510             :   }
    1511             : 
    1512           0 :   tor_free(stream_id_str);
    1513             : 
    1514           0 :   return 0;
    1515             : }
    1516             : /** The network liveness has changed; this is called from circuitstats.c
    1517             :  * whenever we receive a cell, or when timeout expires and we assume the
    1518             :  * network is down. */
    1519             : int
    1520         221 : control_event_network_liveness_update(int liveness)
    1521             : {
    1522         221 :   if (liveness > 0) {
    1523         121 :     if (get_cached_network_liveness() <= 0) {
    1524             :       /* Update cached liveness */
    1525          58 :       set_cached_network_liveness(1);
    1526          58 :       log_debug(LD_CONTROL, "Sending NETWORK_LIVENESS UP");
    1527          58 :       send_control_event_string(EVENT_NETWORK_LIVENESS,
    1528             :                                 "650 NETWORK_LIVENESS UP\r\n");
    1529             :     }
    1530             :     /* else was already live, no-op */
    1531             :   } else {
    1532         100 :     if (get_cached_network_liveness() > 0) {
    1533             :       /* Update cached liveness */
    1534          49 :       set_cached_network_liveness(0);
    1535          49 :       log_debug(LD_CONTROL, "Sending NETWORK_LIVENESS DOWN");
    1536          49 :       send_control_event_string(EVENT_NETWORK_LIVENESS,
    1537             :                                 "650 NETWORK_LIVENESS DOWN\r\n");
    1538             :     }
    1539             :     /* else was already dead, no-op */
    1540             :   }
    1541             : 
    1542         221 :   return 0;
    1543             : }
    1544             : 
    1545             : /** Helper function for NS-style events. Constructs and sends an event
    1546             :  * of type <b>event</b> with string <b>event_string</b> out of the set of
    1547             :  * networkstatuses <b>statuses</b>. Currently it is used for NS events
    1548             :  * and NEWCONSENSUS events. */
    1549             : static int
    1550           0 : control_event_networkstatus_changed_helper(smartlist_t *statuses,
    1551             :                                            uint16_t event,
    1552             :                                            const char *event_string)
    1553             : {
    1554           0 :   smartlist_t *strs;
    1555           0 :   char *s, *esc = NULL;
    1556           0 :   if (!EVENT_IS_INTERESTING(event) || !smartlist_len(statuses))
    1557             :     return 0;
    1558             : 
    1559           0 :   strs = smartlist_new();
    1560           0 :   smartlist_add_strdup(strs, "650+");
    1561           0 :   smartlist_add_strdup(strs, event_string);
    1562           0 :   smartlist_add_strdup(strs, "\r\n");
    1563           0 :   SMARTLIST_FOREACH(statuses, const routerstatus_t *, rs,
    1564             :     {
    1565             :       s = networkstatus_getinfo_helper_single(rs);
    1566             :       if (!s) continue;
    1567             :       smartlist_add(strs, s);
    1568             :     });
    1569             : 
    1570           0 :   s = smartlist_join_strings(strs, "", 0, NULL);
    1571           0 :   write_escaped_data(s, strlen(s), &esc);
    1572           0 :   SMARTLIST_FOREACH(strs, char *, cp, tor_free(cp));
    1573           0 :   smartlist_free(strs);
    1574           0 :   tor_free(s);
    1575           0 :   send_control_event_string(event,  esc);
    1576           0 :   send_control_event_string(event,
    1577             :                             "650 OK\r\n");
    1578             : 
    1579           0 :   tor_free(esc);
    1580           0 :   return 0;
    1581             : }
    1582             : 
    1583             : /** Called when the routerstatus_ts <b>statuses</b> have changed: sends
    1584             :  * an NS event to any controller that cares. */
    1585             : int
    1586           0 : control_event_networkstatus_changed(smartlist_t *statuses)
    1587             : {
    1588           0 :   return control_event_networkstatus_changed_helper(statuses, EVENT_NS, "NS");
    1589             : }
    1590             : 
    1591             : /** Called when we get a new consensus networkstatus. Sends a NEWCONSENSUS
    1592             :  * event consisting of an NS-style line for each relay in the consensus. */
    1593             : int
    1594           5 : control_event_newconsensus(const networkstatus_t *consensus)
    1595             : {
    1596           5 :   if (!control_event_is_interesting(EVENT_NEWCONSENSUS))
    1597             :     return 0;
    1598           0 :   return control_event_networkstatus_changed_helper(
    1599           0 :            consensus->routerstatus_list, EVENT_NEWCONSENSUS, "NEWCONSENSUS");
    1600             : }
    1601             : 
    1602             : /** Called when we compute a new circuitbuildtimeout */
    1603             : int
    1604         113 : control_event_buildtimeout_set(buildtimeout_set_event_t type,
    1605             :                                const char *args)
    1606             : {
    1607         113 :   const char *type_string = NULL;
    1608             : 
    1609         113 :   if (!control_event_is_interesting(EVENT_BUILDTIMEOUT_SET))
    1610             :     return 0;
    1611             : 
    1612           0 :   switch (type) {
    1613             :     case BUILDTIMEOUT_SET_EVENT_COMPUTED:
    1614             :       type_string = "COMPUTED";
    1615             :       break;
    1616           0 :     case BUILDTIMEOUT_SET_EVENT_RESET:
    1617           0 :       type_string = "RESET";
    1618           0 :       break;
    1619           0 :     case BUILDTIMEOUT_SET_EVENT_SUSPENDED:
    1620           0 :       type_string = "SUSPENDED";
    1621           0 :       break;
    1622           0 :     case BUILDTIMEOUT_SET_EVENT_DISCARD:
    1623           0 :       type_string = "DISCARD";
    1624           0 :       break;
    1625           0 :     case BUILDTIMEOUT_SET_EVENT_RESUME:
    1626           0 :       type_string = "RESUME";
    1627           0 :       break;
    1628           0 :     default:
    1629           0 :       type_string = "UNKNOWN";
    1630           0 :       break;
    1631             :   }
    1632             : 
    1633           0 :   send_control_event(EVENT_BUILDTIMEOUT_SET,
    1634             :                      "650 BUILDTIMEOUT_SET %s %s\r\n",
    1635             :                      type_string, args);
    1636             : 
    1637           0 :   return 0;
    1638             : }
    1639             : 
    1640             : /** Called when a signal has been processed from signal_callback */
    1641             : int
    1642           4 : control_event_signal(uintptr_t signal_num)
    1643             : {
    1644           4 :   const char *signal_string = NULL;
    1645             : 
    1646           4 :   if (!control_event_is_interesting(EVENT_GOT_SIGNAL))
    1647             :     return 0;
    1648             : 
    1649          31 :   for (unsigned i = 0; signal_table[i].signal_name != NULL; ++i) {
    1650          30 :     if ((int)signal_num == signal_table[i].sig) {
    1651             :       signal_string = signal_table[i].signal_name;
    1652             :       break;
    1653             :     }
    1654             :   }
    1655             : 
    1656           3 :   if (signal_string == NULL) {
    1657           1 :     log_warn(LD_BUG, "Unrecognized signal %lu in control_event_signal",
    1658             :              (unsigned long)signal_num);
    1659           1 :     return -1;
    1660             :   }
    1661             : 
    1662           2 :   send_control_event(EVENT_GOT_SIGNAL,  "650 SIGNAL %s\r\n",
    1663             :                      signal_string);
    1664           2 :   return 0;
    1665             : }
    1666             : 
    1667             : /** Called when a single local_routerstatus_t has changed: Sends an NS event
    1668             :  * to any controller that cares. */
    1669             : int
    1670           0 : control_event_networkstatus_changed_single(const routerstatus_t *rs)
    1671             : {
    1672           0 :   smartlist_t *statuses;
    1673           0 :   int r;
    1674             : 
    1675           0 :   if (!EVENT_IS_INTERESTING(EVENT_NS))
    1676             :     return 0;
    1677             : 
    1678           0 :   statuses = smartlist_new();
    1679           0 :   smartlist_add(statuses, (void*)rs);
    1680           0 :   r = control_event_networkstatus_changed(statuses);
    1681           0 :   smartlist_free(statuses);
    1682           0 :   return r;
    1683             : }
    1684             : 
    1685             : /** Our own router descriptor has changed; tell any controllers that care.
    1686             :  */
    1687             : int
    1688           0 : control_event_my_descriptor_changed(void)
    1689             : {
    1690           0 :   send_control_event(EVENT_DESCCHANGED,  "650 DESCCHANGED\r\n");
    1691           0 :   return 0;
    1692             : }
    1693             : 
    1694             : /** Helper: sends a status event where <b>type</b> is one of
    1695             :  * EVENT_STATUS_{GENERAL,CLIENT,SERVER}, where <b>severity</b> is one of
    1696             :  * LOG_{NOTICE,WARN,ERR}, and where <b>format</b> is a printf-style format
    1697             :  * string corresponding to <b>args</b>. */
    1698             : static int
    1699          30 : control_event_status(int type, int severity, const char *format, va_list args)
    1700             : {
    1701          30 :   char *user_buf = NULL;
    1702          30 :   char format_buf[160];
    1703          30 :   const char *status, *sev;
    1704             : 
    1705          30 :   switch (type) {
    1706             :     case EVENT_STATUS_GENERAL:
    1707             :       status = "STATUS_GENERAL";
    1708             :       break;
    1709          30 :     case EVENT_STATUS_CLIENT:
    1710          30 :       status = "STATUS_CLIENT";
    1711          30 :       break;
    1712           0 :     case EVENT_STATUS_SERVER:
    1713           0 :       status = "STATUS_SERVER";
    1714           0 :       break;
    1715           0 :     default:
    1716           0 :       log_warn(LD_BUG, "Unrecognized status type %d", type);
    1717           0 :       return -1;
    1718             :   }
    1719          30 :   switch (severity) {
    1720             :     case LOG_NOTICE:
    1721             :       sev = "NOTICE";
    1722             :       break;
    1723           0 :     case LOG_WARN:
    1724           0 :       sev = "WARN";
    1725           0 :       break;
    1726           0 :     case LOG_ERR:
    1727           0 :       sev = "ERR";
    1728           0 :       break;
    1729           0 :     default:
    1730           0 :       log_warn(LD_BUG, "Unrecognized status severity %d", severity);
    1731           0 :       return -1;
    1732             :   }
    1733          30 :   if (tor_snprintf(format_buf, sizeof(format_buf), "650 %s %s",
    1734             :                    status, sev)<0) {
    1735           0 :     log_warn(LD_BUG, "Format string too long.");
    1736           0 :     return -1;
    1737             :   }
    1738          30 :   if (tor_vasprintf(&user_buf, format, args)<0) {
    1739           0 :     log_warn(LD_BUG, "Failed to create user buffer.");
    1740           0 :     return -1;
    1741             :   }
    1742             : 
    1743          30 :   send_control_event(type,  "%s %s\r\n", format_buf, user_buf);
    1744          30 :   tor_free(user_buf);
    1745          30 :   return 0;
    1746             : }
    1747             : 
    1748             : #ifndef COCCI
    1749             : #define CONTROL_EVENT_STATUS_BODY(event, sev)                   \
    1750             :   int r;                                                        \
    1751             :   do {                                                          \
    1752             :     va_list ap;                                                 \
    1753             :     if (!EVENT_IS_INTERESTING(event))                           \
    1754             :       return 0;                                                 \
    1755             :                                                                 \
    1756             :     va_start(ap, format);                                       \
    1757             :     r = control_event_status((event), (sev), format, ap);       \
    1758             :     va_end(ap);                                                 \
    1759             :   } while (0)
    1760             : #endif /* !defined(COCCI) */
    1761             : 
    1762             : /** Format and send an EVENT_STATUS_GENERAL event whose main text is obtained
    1763             :  * by formatting the arguments using the printf-style <b>format</b>. */
    1764             : int
    1765           3 : control_event_general_status(int severity, const char *format, ...)
    1766             : {
    1767           3 :   CONTROL_EVENT_STATUS_BODY(EVENT_STATUS_GENERAL, severity);
    1768           0 :   return r;
    1769             : }
    1770             : 
    1771             : /** Format and send an EVENT_STATUS_GENERAL LOG_ERR event, and flush it to the
    1772             :  * controller(s) immediately. */
    1773             : int
    1774           0 : control_event_general_error(const char *format, ...)
    1775             : {
    1776           0 :   CONTROL_EVENT_STATUS_BODY(EVENT_STATUS_GENERAL, LOG_ERR);
    1777             :   /* Force a flush, since we may be about to die horribly */
    1778           0 :   queued_events_flush_all(1);
    1779           0 :   return r;
    1780             : }
    1781             : 
    1782             : /** Format and send an EVENT_STATUS_CLIENT event whose main text is obtained
    1783             :  * by formatting the arguments using the printf-style <b>format</b>. */
    1784             : int
    1785          50 : control_event_client_status(int severity, const char *format, ...)
    1786             : {
    1787          50 :   CONTROL_EVENT_STATUS_BODY(EVENT_STATUS_CLIENT, severity);
    1788          30 :   return r;
    1789             : }
    1790             : 
    1791             : /** Format and send an EVENT_STATUS_CLIENT LOG_ERR event, and flush it to the
    1792             :  * controller(s) immediately. */
    1793             : int
    1794           0 : control_event_client_error(const char *format, ...)
    1795             : {
    1796           0 :   CONTROL_EVENT_STATUS_BODY(EVENT_STATUS_CLIENT, LOG_ERR);
    1797             :   /* Force a flush, since we may be about to die horribly */
    1798           0 :   queued_events_flush_all(1);
    1799           0 :   return r;
    1800             : }
    1801             : 
    1802             : /** Format and send an EVENT_STATUS_SERVER event whose main text is obtained
    1803             :  * by formatting the arguments using the printf-style <b>format</b>. */
    1804             : int
    1805          51 : control_event_server_status(int severity, const char *format, ...)
    1806             : {
    1807          51 :   CONTROL_EVENT_STATUS_BODY(EVENT_STATUS_SERVER, severity);
    1808           0 :   return r;
    1809             : }
    1810             : 
    1811             : /** Format and send an EVENT_STATUS_SERVER LOG_ERR event, and flush it to the
    1812             :  * controller(s) immediately. */
    1813             : int
    1814           0 : control_event_server_error(const char *format, ...)
    1815             : {
    1816           0 :   CONTROL_EVENT_STATUS_BODY(EVENT_STATUS_SERVER, LOG_ERR);
    1817             :   /* Force a flush, since we may be about to die horribly */
    1818           0 :   queued_events_flush_all(1);
    1819           0 :   return r;
    1820             : }
    1821             : 
    1822             : /** Called when the status of an entry guard with the given <b>nickname</b>
    1823             :  * and identity <b>digest</b> has changed to <b>status</b>: tells any
    1824             :  * controllers that care. */
    1825             : int
    1826        2105 : control_event_guard(const char *nickname, const char *digest,
    1827             :                     const char *status)
    1828             : {
    1829        2105 :   char hbuf[HEX_DIGEST_LEN+1];
    1830        2105 :   base16_encode(hbuf, sizeof(hbuf), digest, DIGEST_LEN);
    1831        2105 :   if (!EVENT_IS_INTERESTING(EVENT_GUARD))
    1832             :     return 0;
    1833             : 
    1834             :   {
    1835           0 :     char buf[MAX_VERBOSE_NICKNAME_LEN+1];
    1836           0 :     const node_t *node = node_get_by_id(digest);
    1837           0 :     if (node) {
    1838           0 :       node_get_verbose_nickname(node, buf);
    1839             :     } else {
    1840           0 :       tor_snprintf(buf, sizeof(buf), "$%s~%s", hbuf, nickname);
    1841             :     }
    1842           0 :     send_control_event(EVENT_GUARD,
    1843             :                        "650 GUARD ENTRY %s %s\r\n", buf, status);
    1844             :   }
    1845           0 :   return 0;
    1846             : }
    1847             : 
    1848             : /** Called when a configuration option changes. This is generally triggered
    1849             :  * by SETCONF requests and RELOAD/SIGHUP signals. The <b>changes</b> are
    1850             :  * a linked list of configuration key-values.
    1851             :  * <b>changes</b> can be NULL, meaning "no changes".
    1852             :  */
    1853             : void
    1854           5 : control_event_conf_changed(const config_line_t *changes)
    1855             : {
    1856           5 :   char *result;
    1857           5 :   smartlist_t *lines;
    1858           5 :   if (!EVENT_IS_INTERESTING(EVENT_CONF_CHANGED) || !changes) {
    1859           5 :     return;
    1860             :   }
    1861           0 :   lines = smartlist_new();
    1862           0 :   for (const config_line_t *line = changes; line; line = line->next) {
    1863           0 :     if (line->value == NULL) {
    1864           0 :       smartlist_add_asprintf(lines, "650-%s", line->key);
    1865             :     } else {
    1866           0 :       smartlist_add_asprintf(lines, "650-%s=%s", line->key, line->value);
    1867             :     }
    1868             :   }
    1869           0 :   result = smartlist_join_strings(lines, "\r\n", 0, NULL);
    1870           0 :   send_control_event(EVENT_CONF_CHANGED,
    1871             :     "650-CONF_CHANGED\r\n%s\r\n650 OK\r\n", result);
    1872           0 :   tor_free(result);
    1873           0 :   SMARTLIST_FOREACH(lines, char *, cp, tor_free(cp));
    1874           0 :   smartlist_free(lines);
    1875             : }
    1876             : 
    1877             : /** We just generated a new summary of which countries we've seen clients
    1878             :  * from recently. Send a copy to the controller in case it wants to
    1879             :  * display it for the user. */
    1880             : void
    1881           0 : control_event_clients_seen(const char *controller_str)
    1882             : {
    1883           0 :   send_control_event(EVENT_CLIENTS_SEEN,
    1884             :     "650 CLIENTS_SEEN %s\r\n", controller_str);
    1885           0 : }
    1886             : 
    1887             : /** A new pluggable transport called <b>transport_name</b> was
    1888             :  *  launched on <b>addr</b>:<b>port</b>. <b>mode</b> is either
    1889             :  *  "server" or "client" depending on the mode of the pluggable
    1890             :  *  transport.
    1891             :  *  "650" SP "TRANSPORT_LAUNCHED" SP Mode SP Name SP Address SP Port
    1892             :  */
    1893             : void
    1894           5 : control_event_transport_launched(const char *mode, const char *transport_name,
    1895             :                                  tor_addr_t *addr, uint16_t port)
    1896             : {
    1897           5 :   send_control_event(EVENT_TRANSPORT_LAUNCHED,
    1898             :                      "650 TRANSPORT_LAUNCHED %s %s %s %u\r\n",
    1899             :                      mode, transport_name, fmt_addr(addr), port);
    1900           5 : }
    1901             : 
    1902             : /** A pluggable transport called <b>pt_name</b> has emitted a log message
    1903             :  * found in <b>message</b> at <b>severity</b> log level. */
    1904             : void
    1905           5 : control_event_pt_log(const char *log)
    1906             : {
    1907           5 :   send_control_event(EVENT_PT_LOG,
    1908             :                      "650 PT_LOG %s\r\n",
    1909             :                      log);
    1910           5 : }
    1911             : 
    1912             : /** A pluggable transport has emitted a STATUS message found in
    1913             :  * <b>status</b>. */
    1914             : void
    1915           3 : control_event_pt_status(const char *status)
    1916             : {
    1917           3 :   send_control_event(EVENT_PT_STATUS,
    1918             :                      "650 PT_STATUS %s\r\n",
    1919             :                      status);
    1920           3 : }
    1921             : 
    1922             : /** Convert rendezvous auth type to string for HS_DESC control events
    1923             :  */
    1924             : const char *
    1925           9 : rend_auth_type_to_string(rend_auth_type_t auth_type)
    1926             : {
    1927           9 :   const char *str;
    1928             : 
    1929           9 :   switch (auth_type) {
    1930             :     case REND_NO_AUTH:
    1931             :       str = "NO_AUTH";
    1932             :       break;
    1933           0 :     case REND_V3_AUTH:
    1934           0 :       str = "REND_V3_AUTH";
    1935           0 :       break;
    1936           0 :     default:
    1937           0 :       str = "UNKNOWN";
    1938             :   }
    1939             : 
    1940           9 :   return str;
    1941             : }
    1942             : 
    1943             : /** Return either the onion address if the given pointer is a non empty
    1944             :  * string else the unknown string. */
    1945             : static const char *
    1946          16 : rend_hsaddress_str_or_unknown(const char *onion_address)
    1947             : {
    1948          16 :   static const char *str_unknown = "UNKNOWN";
    1949          16 :   const char *str_ret = str_unknown;
    1950             : 
    1951             :   /* No valid pointer, unknown it is. */
    1952          16 :   if (!onion_address) {
    1953           0 :     goto end;
    1954             :   }
    1955             :   /* Empty onion address thus we don't know, unknown it is. */
    1956          16 :   if (onion_address[0] == '\0') {
    1957           0 :     goto end;
    1958             :   }
    1959             :   /* All checks are good so return the given onion address. */
    1960             :   str_ret = onion_address;
    1961             : 
    1962          16 :  end:
    1963          16 :   return str_ret;
    1964             : }
    1965             : 
    1966             : /** send HS_DESC requested event.
    1967             :  *
    1968             :  * <b>rend_query</b> is used to fetch requested onion address and auth type.
    1969             :  * <b>hs_dir</b> is the description of contacting hs directory.
    1970             :  * <b>desc_id_base32</b> is the ID of requested hs descriptor.
    1971             :  * <b>hsdir_index</b> is the HSDir fetch index value for v3, an hex string.
    1972             :  */
    1973             : void
    1974           1 : control_event_hs_descriptor_requested(const char *onion_address,
    1975             :                                       rend_auth_type_t auth_type,
    1976             :                                       const char *id_digest,
    1977             :                                       const char *desc_id,
    1978             :                                       const char *hsdir_index)
    1979             : {
    1980           1 :   char *hsdir_index_field = NULL;
    1981             : 
    1982           1 :   if (BUG(!id_digest || !desc_id)) {
    1983           0 :     return;
    1984             :   }
    1985             : 
    1986           1 :   if (hsdir_index) {
    1987           1 :     tor_asprintf(&hsdir_index_field, " HSDIR_INDEX=%s", hsdir_index);
    1988             :   }
    1989             : 
    1990           1 :   send_control_event(EVENT_HS_DESC,
    1991             :                      "650 HS_DESC REQUESTED %s %s %s %s%s\r\n",
    1992             :                      rend_hsaddress_str_or_unknown(onion_address),
    1993             :                      rend_auth_type_to_string(auth_type),
    1994             :                      node_describe_longname_by_id(id_digest),
    1995             :                      desc_id,
    1996           1 :                      hsdir_index_field ? hsdir_index_field : "");
    1997           1 :   tor_free(hsdir_index_field);
    1998             : }
    1999             : 
    2000             : /** send HS_DESC CREATED event when a local service generates a descriptor.
    2001             :  *
    2002             :  * <b>onion_address</b> is service address.
    2003             :  * <b>desc_id</b> is the descriptor ID.
    2004             :  * <b>replica</b> is the the descriptor replica number. If it is negative, it
    2005             :  * is ignored.
    2006             :  */
    2007             : void
    2008          45 : control_event_hs_descriptor_created(const char *onion_address,
    2009             :                                     const char *desc_id,
    2010             :                                     int replica)
    2011             : {
    2012          45 :   char *replica_field = NULL;
    2013             : 
    2014          45 :   if (BUG(!onion_address || !desc_id)) {
    2015           0 :     return;
    2016             :   }
    2017             : 
    2018          45 :   if (replica >= 0) {
    2019           0 :     tor_asprintf(&replica_field, " REPLICA=%d", replica);
    2020             :   }
    2021             : 
    2022          45 :   send_control_event(EVENT_HS_DESC,
    2023             :                      "650 HS_DESC CREATED %s UNKNOWN UNKNOWN %s%s\r\n",
    2024             :                      onion_address, desc_id,
    2025          45 :                      replica_field ? replica_field : "");
    2026          45 :   tor_free(replica_field);
    2027             : }
    2028             : 
    2029             : /** send HS_DESC upload event.
    2030             :  *
    2031             :  * <b>onion_address</b> is service address.
    2032             :  * <b>hs_dir</b> is the description of contacting hs directory.
    2033             :  * <b>desc_id</b> is the ID of requested hs descriptor.
    2034             :  */
    2035             : void
    2036          67 : control_event_hs_descriptor_upload(const char *onion_address,
    2037             :                                    const char *id_digest,
    2038             :                                    const char *desc_id,
    2039             :                                    const char *hsdir_index)
    2040             : {
    2041          67 :   char *hsdir_index_field = NULL;
    2042             : 
    2043          67 :   if (BUG(!onion_address || !id_digest || !desc_id)) {
    2044           0 :     return;
    2045             :   }
    2046             : 
    2047          67 :   if (hsdir_index) {
    2048          67 :     tor_asprintf(&hsdir_index_field, " HSDIR_INDEX=%s", hsdir_index);
    2049             :   }
    2050             : 
    2051          67 :   send_control_event(EVENT_HS_DESC,
    2052             :                      "650 HS_DESC UPLOAD %s UNKNOWN %s %s%s\r\n",
    2053             :                      onion_address,
    2054             :                      node_describe_longname_by_id(id_digest),
    2055             :                      desc_id,
    2056          67 :                      hsdir_index_field ? hsdir_index_field : "");
    2057          67 :   tor_free(hsdir_index_field);
    2058             : }
    2059             : 
    2060             : /** send HS_DESC event after got response from hs directory.
    2061             :  *
    2062             :  * NOTE: this is an internal function used by following functions:
    2063             :  * control_event_hsv3_descriptor_failed
    2064             :  *
    2065             :  * So do not call this function directly.
    2066             :  */
    2067             : static void
    2068           8 : event_hs_descriptor_receive_end(const char *action,
    2069             :                                 const char *onion_address,
    2070             :                                 const char *desc_id,
    2071             :                                 rend_auth_type_t auth_type,
    2072             :                                 const char *hsdir_id_digest,
    2073             :                                 const char *reason)
    2074             : {
    2075           8 :   char *reason_field = NULL;
    2076             : 
    2077           8 :   if (BUG(!action || !onion_address)) {
    2078           0 :     return;
    2079             :   }
    2080             : 
    2081           8 :   if (reason) {
    2082           1 :     tor_asprintf(&reason_field, " REASON=%s", reason);
    2083             :   }
    2084             : 
    2085          16 :   send_control_event(EVENT_HS_DESC,
    2086             :                      "650 HS_DESC %s %s %s %s%s%s\r\n",
    2087             :                      action,
    2088             :                      rend_hsaddress_str_or_unknown(onion_address),
    2089             :                      rend_auth_type_to_string(auth_type),
    2090             :                      hsdir_id_digest ?
    2091           8 :                         node_describe_longname_by_id(hsdir_id_digest) :
    2092             :                         "UNKNOWN",
    2093             :                      desc_id ? desc_id : "",
    2094           8 :                      reason_field ? reason_field : "");
    2095             : 
    2096           8 :   tor_free(reason_field);
    2097             : }
    2098             : 
    2099             : /** send HS_DESC event after got response from hs directory.
    2100             :  *
    2101             :  * NOTE: this is an internal function used by following functions:
    2102             :  * control_event_hs_descriptor_uploaded
    2103             :  * control_event_hs_descriptor_upload_failed
    2104             :  *
    2105             :  * So do not call this function directly.
    2106             :  */
    2107             : void
    2108           1 : control_event_hs_descriptor_upload_end(const char *action,
    2109             :                                        const char *onion_address,
    2110             :                                        const char *id_digest,
    2111             :                                        const char *reason)
    2112             : {
    2113           1 :   char *reason_field = NULL;
    2114             : 
    2115           1 :   if (BUG(!action || !id_digest)) {
    2116           0 :     return;
    2117             :   }
    2118             : 
    2119           1 :   if (reason) {
    2120           0 :     tor_asprintf(&reason_field, " REASON=%s", reason);
    2121             :   }
    2122             : 
    2123           1 :   send_control_event(EVENT_HS_DESC,
    2124             :                      "650 HS_DESC %s %s UNKNOWN %s%s\r\n",
    2125             :                      action,
    2126             :                      rend_hsaddress_str_or_unknown(onion_address),
    2127             :                      node_describe_longname_by_id(id_digest),
    2128           1 :                      reason_field ? reason_field : "");
    2129             : 
    2130           1 :   tor_free(reason_field);
    2131             : }
    2132             : 
    2133             : /* Send HS_DESC RECEIVED event
    2134             :  *
    2135             :  * Called when we successfully received a hidden service descriptor. */
    2136             : void
    2137           7 : control_event_hsv3_descriptor_received(const char *onion_address,
    2138             :                                        const char *desc_id,
    2139             :                                        const char *hsdir_id_digest)
    2140             : {
    2141           7 :   char *desc_id_field = NULL;
    2142             : 
    2143           7 :   if (BUG(!onion_address || !desc_id || !hsdir_id_digest)) {
    2144           0 :     return;
    2145             :   }
    2146             : 
    2147             :   /* Because DescriptorID is an optional positional value, we need to add a
    2148             :    * whitespace before in order to not be next to the HsDir value. */
    2149           7 :   tor_asprintf(&desc_id_field, " %s", desc_id);
    2150             : 
    2151           7 :   event_hs_descriptor_receive_end("RECEIVED", onion_address, desc_id_field,
    2152             :                                   REND_NO_AUTH, hsdir_id_digest, NULL);
    2153           7 :   tor_free(desc_id_field);
    2154             : }
    2155             : 
    2156             : /** send HS_DESC UPLOADED event
    2157             :  *
    2158             :  * called when we successfully uploaded a hidden service descriptor.
    2159             :  */
    2160             : void
    2161           1 : control_event_hs_descriptor_uploaded(const char *id_digest,
    2162             :                                      const char *onion_address)
    2163             : {
    2164           1 :   if (BUG(!id_digest)) {
    2165           0 :     return;
    2166             :   }
    2167             : 
    2168           1 :   control_event_hs_descriptor_upload_end("UPLOADED", onion_address,
    2169             :                                          id_digest, NULL);
    2170             : }
    2171             : 
    2172             : /** Send HS_DESC event to inform controller that the query to
    2173             :  * <b>onion_address</b> failed to retrieve hidden service descriptor
    2174             :  * <b>desc_id</b> from directory identified by <b>hsdir_id_digest</b>. If
    2175             :  * NULL, "UNKNOWN" is used.  If <b>reason</b> is not NULL, add it to REASON=
    2176             :  * field. */
    2177             : void
    2178           1 : control_event_hsv3_descriptor_failed(const char *onion_address,
    2179             :                                      const char *desc_id,
    2180             :                                      const char *hsdir_id_digest,
    2181             :                                      const char *reason)
    2182             : {
    2183           1 :   char *desc_id_field = NULL;
    2184             : 
    2185           1 :   if (BUG(!onion_address || !desc_id || !reason)) {
    2186           0 :     return;
    2187             :   }
    2188             : 
    2189             :   /* Because DescriptorID is an optional positional value, we need to add a
    2190             :    * whitespace before in order to not be next to the HsDir value. */
    2191           1 :   tor_asprintf(&desc_id_field, " %s", desc_id);
    2192             : 
    2193           1 :   event_hs_descriptor_receive_end("FAILED", onion_address, desc_id_field,
    2194             :                                   REND_NO_AUTH, hsdir_id_digest, reason);
    2195           1 :   tor_free(desc_id_field);
    2196             : }
    2197             : 
    2198             : /** Send HS_DESC_CONTENT event after completion of a successful fetch
    2199             :  * from hs directory. If <b>hsdir_id_digest</b> is NULL, it is replaced
    2200             :  * by "UNKNOWN". If <b>content</b> is NULL, it is replaced by an empty
    2201             :  * string. The  <b>onion_address</b> or <b>desc_id</b> set to NULL will
    2202             :  * not trigger the control event. */
    2203             : void
    2204           6 : control_event_hs_descriptor_content(const char *onion_address,
    2205             :                                     const char *desc_id,
    2206             :                                     const char *hsdir_id_digest,
    2207             :                                     const char *content)
    2208             : {
    2209           6 :   static const char *event_name = "HS_DESC_CONTENT";
    2210           6 :   char *esc_content = NULL;
    2211             : 
    2212           6 :   if (!onion_address || !desc_id) {
    2213           0 :     log_warn(LD_BUG, "Called with onion_address==%p, desc_id==%p, ",
    2214             :              onion_address, desc_id);
    2215           0 :     return;
    2216             :   }
    2217             : 
    2218           6 :   if (content == NULL) {
    2219             :     /* Point it to empty content so it can still be escaped. */
    2220           0 :     content = "";
    2221             :   }
    2222           6 :   write_escaped_data(content, strlen(content), &esc_content);
    2223             : 
    2224          12 :   send_control_event(EVENT_HS_DESC_CONTENT,
    2225             :                      "650+%s %s %s %s\r\n%s650 OK\r\n",
    2226             :                      event_name,
    2227             :                      rend_hsaddress_str_or_unknown(onion_address),
    2228             :                      desc_id,
    2229             :                      hsdir_id_digest ?
    2230           6 :                         node_describe_longname_by_id(hsdir_id_digest) :
    2231             :                         "UNKNOWN",
    2232             :                      esc_content);
    2233           6 :   tor_free(esc_content);
    2234             : }
    2235             : 
    2236             : /** Send HS_DESC event to inform controller upload of hidden service
    2237             :  * descriptor identified by <b>id_digest</b> failed. If <b>reason</b>
    2238             :  * is not NULL, add it to REASON= field.
    2239             :  */
    2240             : void
    2241           0 : control_event_hs_descriptor_upload_failed(const char *id_digest,
    2242             :                                           const char *onion_address,
    2243             :                                           const char *reason)
    2244             : {
    2245           0 :   if (BUG(!id_digest)) {
    2246           0 :     return;
    2247             :   }
    2248           0 :   control_event_hs_descriptor_upload_end("FAILED", onion_address,
    2249             :                                          id_digest, reason);
    2250             : }
    2251             : 
    2252             : void
    2253         235 : control_events_free_all(void)
    2254             : {
    2255         235 :   smartlist_t *queued_events = NULL;
    2256             : 
    2257         235 :   stats_prev_n_read = stats_prev_n_written = 0;
    2258             : 
    2259         235 :   if (queued_control_events_lock) {
    2260           4 :     tor_mutex_acquire(queued_control_events_lock);
    2261           4 :     flush_queued_event_pending = 0;
    2262           4 :     queued_events = queued_control_events;
    2263           4 :     queued_control_events = NULL;
    2264           4 :     tor_mutex_release(queued_control_events_lock);
    2265             :   }
    2266           4 :   if (queued_events) {
    2267           4 :     SMARTLIST_FOREACH(queued_events, queued_event_t *, ev,
    2268             :                       queued_event_free(ev));
    2269           4 :     smartlist_free(queued_events);
    2270             :   }
    2271         235 :   if (flush_queued_events_event) {
    2272           4 :     mainloop_event_free(flush_queued_events_event);
    2273           4 :     flush_queued_events_event = NULL;
    2274             :   }
    2275         235 :   global_event_mask = 0;
    2276         235 :   disable_log_messages = 0;
    2277         235 : }
    2278             : 
    2279             : #ifdef TOR_UNIT_TESTS
    2280             : /* For testing: change the value of global_event_mask */
    2281             : void
    2282          83 : control_testing_set_global_event_mask(uint64_t mask)
    2283             : {
    2284          83 :   global_event_mask = mask;
    2285          83 : }
    2286             : #endif /* defined(TOR_UNIT_TESTS) */

Generated by: LCOV version 1.14