tor  0.4.2.1-alpha-dev
btrack_orconn_maps.c
Go to the documentation of this file.
1 /* Copyright (c) 2007-2019, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
3 
12 #include <stdbool.h>
13 
14 #include "core/or/or.h"
15 
16 #include "ht.h"
17 #include "siphash.h"
18 
19 #define BTRACK_ORCONN_PRIVATE
20 
23 #include "lib/log/log.h"
24 
25 static inline unsigned int
26 bto_gid_hash_(bt_orconn_t *elm)
27 {
28  return (unsigned)siphash24g(&elm->gid, sizeof(elm->gid));
29 }
30 
31 static inline int
32 bto_gid_eq_(bt_orconn_t *a, bt_orconn_t *b)
33 {
34  return a->gid == b->gid;
35 }
36 
37 static inline unsigned int
38 bto_chan_hash_(bt_orconn_t *elm)
39 {
40  return (unsigned)siphash24g(&elm->chan, sizeof(elm->chan));
41 }
42 
43 static inline int
44 bto_chan_eq_(bt_orconn_t *a, bt_orconn_t *b)
45 {
46  return a->chan == b->chan;
47 }
48 
49 HT_HEAD(bto_gid_ht, bt_orconn_t);
50 HT_PROTOTYPE(bto_gid_ht, bt_orconn_t, node, bto_gid_hash_, bto_gid_eq_)
51 HT_GENERATE2(bto_gid_ht, bt_orconn_t, node,
52  bto_gid_hash_, bto_gid_eq_, 0.6,
54 static struct bto_gid_ht *bto_gid_map;
55 
56 HT_HEAD(bto_chan_ht, bt_orconn_t);
57 HT_PROTOTYPE(bto_chan_ht, bt_orconn_t, chan_node, bto_chan_hash_, bto_chan_eq_)
58 HT_GENERATE2(bto_chan_ht, bt_orconn_t, chan_node,
59  bto_chan_hash_, bto_chan_eq_, 0.6,
61 static struct bto_chan_ht *bto_chan_map;
62 
65 static void
67 {
68  bt_orconn_t **elt, **next, *c;
69 
70  for (elt = HT_START(bto_gid_ht, bto_gid_map);
71  elt;
72  elt = next) {
73  c = *elt;
74  next = HT_NEXT_RMV(bto_gid_ht, bto_gid_map, elt);
75 
76  c->gid = 0;
77  /* Don't delete if chan ID isn't zero: it's still in the chan hash map */
78  if (!c->chan)
79  tor_free(c);
80  }
81  HT_CLEAR(bto_gid_ht, bto_gid_map);
82  tor_free(bto_gid_map);
83 }
84 
87 static void
89 {
90  bt_orconn_t **elt, **next, *c;
91 
92  for (elt = HT_START(bto_chan_ht, bto_chan_map);
93  elt;
94  elt = next) {
95  c = *elt;
96  next = HT_NEXT_RMV(bto_chan_ht, bto_chan_map, elt);
97 
98  c->chan = 0;
99  /* Don't delete if GID isn't zero, it's still in the GID hash map */
100  if (!c->gid)
101  tor_free(c);
102  }
103  HT_CLEAR(bto_chan_ht, bto_chan_map);
104  tor_free(bto_chan_map);
105 }
106 
108 void
109 bto_delete(uint64_t gid)
110 {
111  bt_orconn_t key, *bto;
112 
113  key.gid = gid;
114  key.chan = 0;
115  bto = HT_FIND(bto_gid_ht, bto_gid_map, &key);
116  if (!bto) {
117  /* The orconn might be unregistered because it's an EXT_OR_CONN? */
118  log_debug(LD_BTRACK, "tried to delete unregistered ORCONN gid=%"PRIu64,
119  gid);
120  return;
121  }
122  HT_REMOVE(bto_gid_ht, bto_gid_map, &key);
123  if (bto->chan) {
124  key.chan = bto->chan;
125  HT_REMOVE(bto_chan_ht, bto_chan_map, &key);
126  }
127  tor_free(bto);
128 }
129 
136 static bt_orconn_t *
137 bto_update(bt_orconn_t *bto, const bt_orconn_t *key)
138 {
139  /* ORCONN GIDs shouldn't change once assigned */
140  tor_assert(!bto->gid || !key->gid || bto->gid == key->gid);
141  if (!bto->gid && key->gid) {
142  /* Got a gid when we didn't already have one; insert into gid map */
143  log_debug(LD_BTRACK, "ORCONN chan=%"PRIu64" newgid=%"PRIu64, key->chan,
144  key->gid);
145  bto->gid = key->gid;
146  HT_INSERT(bto_gid_ht, bto_gid_map, bto);
147  }
148  /* association of ORCONN with channel shouldn't change */
149  tor_assert(!bto->chan || !key->chan || bto->chan == key->chan);
150  if (!bto->chan && key->chan) {
151  /* Got a chan when we didn't already have one; insert into chan map */
152  log_debug(LD_BTRACK, "ORCONN gid=%"PRIu64" newchan=%"PRIu64,
153  bto->gid, key->chan);
154  bto->chan = key->chan;
155  HT_INSERT(bto_chan_ht, bto_chan_map, bto);
156  }
157  return bto;
158 }
159 
161 static bt_orconn_t *
162 bto_new(const bt_orconn_t *key)
163 {
164  struct bt_orconn_t *bto = tor_malloc(sizeof(*bto));
165 
166  bto->gid = key->gid;
167  bto->chan = key->chan;
168  bto->state = 0;
169  bto->proxy_type = 0;
170  bto->is_orig = false;
171  bto->is_onehop = true;
172 
173  if (bto->gid)
174  HT_INSERT(bto_gid_ht, bto_gid_map, bto);
175  if (bto->chan)
176  HT_INSERT(bto_chan_ht, bto_chan_map, bto);
177 
178  return bto;
179 }
180 
187 bt_orconn_t *
188 bto_find_or_new(uint64_t gid, uint64_t chan)
189 {
190  bt_orconn_t key, *bto = NULL;
191 
192  tor_assert(gid || chan);
193  key.gid = gid;
194  key.chan = chan;
195  if (key.gid)
196  bto = HT_FIND(bto_gid_ht, bto_gid_map, &key);
197  if (!bto && key.chan) {
198  /* Not found by GID; look up by chan ID */
199  bto = HT_FIND(bto_chan_ht, bto_chan_map, &key);
200  }
201  if (bto)
202  return bto_update(bto, &key);
203  else
204  return bto_new(&key);
205 }
206 
208 void
210 {
211  bto_gid_map = tor_malloc(sizeof(*bto_gid_map));
212  HT_INIT(bto_gid_ht, bto_gid_map);
213  bto_chan_map = tor_malloc(sizeof(*bto_chan_map));
214  HT_INIT(bto_chan_ht, bto_chan_map);
215 }
216 
218 void
220 {
223 }
HT_PROTOTYPE(HT_GENERATE2(strmap_impl, HT_GENERATE2(strmap_entry_t, HT_GENERATE2(node, HT_GENERATE2(strmap_entry_hash, HT_GENERATE2(strmap_entries_eq)
Definition: map.c:87
void bto_init_maps(void)
#define tor_free(p)
Definition: malloc.h:52
void * tor_reallocarray_(void *ptr, size_t sz1, size_t sz2)
Definition: malloc.c:146
static bt_orconn_t * bto_update(bt_orconn_t *bto, const bt_orconn_t *key)
tor_assert(buffer)
Master header file for Tor-specific functionality.
Header file for btrack_orconn.c.
void tor_free_(void *mem)
Definition: malloc.c:227
Header file for btrack_orconn_maps.c.
#define LD_BTRACK
Definition: log.h:117
void bto_clear_maps(void)
static void bto_gid_clear_map(void)
static void bto_chan_clear_map(void)
Headers for log.c.
void bto_delete(uint64_t gid)
bt_orconn_t * bto_find_or_new(uint64_t gid, uint64_t chan)
static bt_orconn_t * bto_new(const bt_orconn_t *key)