Tor  0.4.4.0-alpha-dev
dispatch_cfg.c
Go to the documentation of this file.
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-2020, 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"
20 #include "lib/dispatch/dispatch.h"
22 
24 #include "lib/malloc/malloc.h"
25 
26 /**
27  * Create and return a new dispatch_cfg_t.
28  **/
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
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 messasge 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
122 {
123  if (!cfg)
124  return;
125 
127  SMARTLIST_FOREACH(cfg->chan_by_msg, channel_id_t *, id, tor_free(id));
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 }
void dcfg_free_(dispatch_cfg_t *cfg)
Definition: dispatch_cfg.c:121
void smartlist_grow(smartlist_t *sl, size_t new_size)
int dcfg_add_recv(dispatch_cfg_t *cfg, message_id_t msg, subsys_id_t sys, recv_fn_t fn)
Definition: dispatch_cfg.c:101
Header for smartlist.c.
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
int dcfg_msg_set_type(dispatch_cfg_t *cfg, message_id_t msg, msg_type_id_t type)
Definition: dispatch_cfg.c:45
Declarations for dispatch-configuration types.
void smartlist_add(smartlist_t *sl, void *element)
int dcfg_msg_set_chan(dispatch_cfg_t *cfg, message_id_t msg, channel_id_t chan)
Definition: dispatch_cfg.c:63
#define tor_free(p)
Definition: malloc.h:52
Headers for util_malloc.c.
smartlist_t * smartlist_new(void)
struct smartlist_t * type_by_msg
char *(* fmt_fn)(msg_aux_data_t)
Definition: msgtypes.h:77
struct smartlist_t * fns_by_type
Low-level APIs for message-passing system.
uint16_t msg_type_id_t
Definition: msgtypes.h:29
uint16_t subsys_id_t
Definition: msgtypes.h:22
void(* recv_fn_t)(const msg_t *m)
Definition: msgtypes.h:66
int dcfg_type_set_fns(dispatch_cfg_t *cfg, msg_type_id_t type, const dispatch_typefns_t *fns)
Definition: dispatch_cfg.c:81
#define SMARTLIST_FOREACH(sl, type, var, cmd)
private structures used for the dispatcher module
struct smartlist_t * recv_by_msg
void(* free_fn)(msg_aux_data_t)
Definition: msgtypes.h:74
Header for distpach_cfg.c.
struct smartlist_t * chan_by_msg
dispatch_cfg_t * dcfg_new(void)
Definition: dispatch_cfg.c:30