tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

dispatch_cfg.c (4087B)


      1 /* Copyright (c) 2001, Matej Pfajfar.
      2 * Copyright (c) 2001-2004, Roger Dingledine.
      3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
      4 * Copyright (c) 2007-2021, The Tor Project, Inc. */
      5 /* See LICENSE for licensing information */
      6 
      7 /**
      8 * \file dispatch_cfg.c
      9 * \brief Create and configure a dispatch_cfg_t.
     10 *
     11 * A dispatch_cfg_t object is used to configure a set of messages and
     12 * associated information before creating a dispatch_t.
     13 */
     14 
     15 #define DISPATCH_PRIVATE
     16 
     17 #include "orconfig.h"
     18 #include "lib/dispatch/dispatch_cfg.h"
     19 #include "lib/dispatch/dispatch_cfg_st.h"
     20 #include "lib/dispatch/dispatch.h"
     21 #include "lib/dispatch/dispatch_st.h"
     22 
     23 #include "lib/container/smartlist.h"
     24 #include "lib/malloc/malloc.h"
     25 
     26 /**
     27 * Create and return a new dispatch_cfg_t.
     28 **/
     29 dispatch_cfg_t *
     30 dcfg_new(void)
     31 {
     32  dispatch_cfg_t *cfg = tor_malloc(sizeof(dispatch_cfg_t));
     33  cfg->type_by_msg = smartlist_new();
     34  cfg->chan_by_msg = smartlist_new();
     35  cfg->fns_by_type = smartlist_new();
     36  cfg->recv_by_msg = smartlist_new();
     37  return cfg;
     38 }
     39 
     40 /**
     41 * Associate a message with a datatype.  Return 0 on success, -1 if a
     42 * different type was previously associated with the message ID.
     43 **/
     44 int
     45 dcfg_msg_set_type(dispatch_cfg_t *cfg, message_id_t msg,
     46                  msg_type_id_t type)
     47 {
     48  smartlist_grow(cfg->type_by_msg, msg+1);
     49  msg_type_id_t *oldval = smartlist_get(cfg->type_by_msg, msg);
     50  if (oldval != NULL && *oldval != type) {
     51    return -1;
     52  }
     53  if (!oldval)
     54    smartlist_set(cfg->type_by_msg, msg, tor_memdup(&type, sizeof(type)));
     55  return 0;
     56 }
     57 
     58 /**
     59 * Associate a message with a channel.  Return 0 on success, -1 if a
     60 * different channel was previously associated with the message ID.
     61 **/
     62 int
     63 dcfg_msg_set_chan(dispatch_cfg_t *cfg, message_id_t msg,
     64                  channel_id_t chan)
     65 {
     66  smartlist_grow(cfg->chan_by_msg, msg+1);
     67  channel_id_t *oldval = smartlist_get(cfg->chan_by_msg, msg);
     68  if (oldval != NULL && *oldval != chan) {
     69    return -1;
     70  }
     71  if (!oldval)
     72    smartlist_set(cfg->chan_by_msg, msg, tor_memdup(&chan, sizeof(chan)));
     73  return 0;
     74 }
     75 
     76 /**
     77 * Associate a set of functions with a datatype. Return 0 on success, -1 if
     78 * different functions were previously associated with the type.
     79 **/
     80 int
     81 dcfg_type_set_fns(dispatch_cfg_t *cfg, msg_type_id_t type,
     82                  const dispatch_typefns_t *fns)
     83 {
     84  smartlist_grow(cfg->fns_by_type, type+1);
     85  dispatch_typefns_t *oldfns = smartlist_get(cfg->fns_by_type, type);
     86  if (oldfns && (oldfns->free_fn != fns->free_fn ||
     87                 oldfns->fmt_fn != fns->fmt_fn))
     88    return -1;
     89  if (!oldfns)
     90    smartlist_set(cfg->fns_by_type, type, tor_memdup(fns, sizeof(*fns)));
     91  return 0;
     92 }
     93 
     94 /**
     95 * Associate a receiver with a message ID.  Multiple receivers may be
     96 * associated with a single message ID.
     97 *
     98 * Return 0 on success, on failure.
     99 **/
    100 int
    101 dcfg_add_recv(dispatch_cfg_t *cfg, message_id_t msg,
    102              subsys_id_t sys, recv_fn_t fn)
    103 {
    104  smartlist_grow(cfg->recv_by_msg, msg+1);
    105  smartlist_t *receivers = smartlist_get(cfg->recv_by_msg, msg);
    106  if (!receivers) {
    107    receivers = smartlist_new();
    108    smartlist_set(cfg->recv_by_msg, msg, receivers);
    109  }
    110 
    111  dispatch_rcv_t *rcv = tor_malloc(sizeof(dispatch_rcv_t));
    112  rcv->sys = sys;
    113  rcv->enabled = true;
    114  rcv->fn = fn;
    115  smartlist_add(receivers, (void*)rcv);
    116  return 0;
    117 }
    118 
    119 /** Helper: release all storage held by <b>cfg</b>. */
    120 void
    121 dcfg_free_(dispatch_cfg_t *cfg)
    122 {
    123  if (!cfg)
    124    return;
    125 
    126  SMARTLIST_FOREACH(cfg->type_by_msg, msg_type_id_t *, id, tor_free(id));
    127  SMARTLIST_FOREACH(cfg->chan_by_msg, channel_id_t *, id, tor_free(id));
    128  SMARTLIST_FOREACH(cfg->fns_by_type, dispatch_typefns_t *, f, tor_free(f));
    129  smartlist_free(cfg->type_by_msg);
    130  smartlist_free(cfg->chan_by_msg);
    131  smartlist_free(cfg->fns_by_type);
    132  SMARTLIST_FOREACH_BEGIN(cfg->recv_by_msg, smartlist_t *, receivers) {
    133    if (!receivers)
    134      continue;
    135    SMARTLIST_FOREACH(receivers, dispatch_rcv_t *, rcv, tor_free(rcv));
    136    smartlist_free(receivers);
    137  } SMARTLIST_FOREACH_END(receivers);
    138  smartlist_free(cfg->recv_by_msg);
    139 
    140  tor_free(cfg);
    141 }