tor  0.4.2.0-alpha-dev
namemap.c
1 /* Copyright (c) 2003-2004, Roger Dingledine
2  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3  * Copyright (c) 2007-2018, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
6 #include "orconfig.h"
9 #include "lib/container/namemap_st.h"
10 #include "lib/log/util_bug.h"
11 #include "lib/malloc/malloc.h"
12 #include "lib/string/printf.h"
13 
14 #include "ext/siphash.h"
15 
16 #include <string.h>
17 
19 static inline int
20 mapped_name_eq(const mapped_name_t *a, const mapped_name_t *b)
21 {
22  return !strcmp(a->name, b->name);
23 }
24 
26 static inline unsigned
27 mapped_name_hash(const mapped_name_t *a)
28 {
29  return (unsigned) siphash24g(a->name, strlen(a->name));
30 }
31 
32 HT_PROTOTYPE(namemap_ht, mapped_name_t, node, mapped_name_hash,
33  mapped_name_eq)
34 HT_GENERATE2(namemap_ht, mapped_name_t, node, mapped_name_hash,
35  mapped_name_eq, 0.6, tor_reallocarray_, tor_free_)
36 
37 
38 void
39 namemap_init(namemap_t *map)
40 {
41  memset(map, 0, sizeof(*map));
42  HT_INIT(namemap_ht, &map->ht);
43  map->names = smartlist_new();
44 }
45 
48 const char *
49 namemap_get_name(const namemap_t *map, unsigned id)
50 {
51  if (map->names && id < (unsigned)smartlist_len(map->names)) {
52  mapped_name_t *name = smartlist_get(map->names, (int)id);
53  return name->name;
54  } else {
55  return NULL;
56  }
57 }
58 
64 const char *
65 namemap_fmt_name(const namemap_t *map, unsigned id)
66 {
67  static char buf[32];
68 
69  const char *name = namemap_get_name(map, id);
70  if (name)
71  return name;
72 
73  tor_snprintf(buf, sizeof(buf), "{%u}", id);
74 
75  return buf;
76 }
77 
83 static unsigned
84 namemap_get_id_unchecked(const namemap_t *map,
85  const char *name,
86  size_t namelen)
87 {
88  union {
89  mapped_name_t n;
90  char storage[MAX_NAMEMAP_NAME_LEN + sizeof(mapped_name_t) + 1];
91  } u;
92  memcpy(u.n.name, name, namelen);
93  u.n.name[namelen] = 0;
94  const mapped_name_t *found = HT_FIND(namemap_ht, &map->ht, &u.n);
95  if (found) {
96  tor_assert(map->names);
97  tor_assert(smartlist_get(map->names, found->intval) == found);
98  return found->intval;
99  }
100 
101  return NAMEMAP_ERR;
102 }
103 
108 unsigned
110  const char *name)
111 {
112  size_t namelen = strlen(name);
113  if (namelen > MAX_NAMEMAP_NAME_LEN) {
114  return NAMEMAP_ERR;
115  }
116 
117  return namemap_get_id_unchecked(map, name, namelen);
118 }
119 
127 unsigned
129  const char *name)
130 {
131  size_t namelen = strlen(name);
132  if (namelen > MAX_NAMEMAP_NAME_LEN) {
133  return NAMEMAP_ERR;
134  }
135 
136  if (PREDICT_UNLIKELY(map->names == NULL))
137  map->names = smartlist_new();
138 
139  unsigned found = namemap_get_id_unchecked(map, name, namelen);
140  if (found != NAMEMAP_ERR)
141  return found;
142 
143  unsigned new_id = (unsigned)smartlist_len(map->names);
144  if (new_id == NAMEMAP_ERR)
145  return NAMEMAP_ERR; /* Can't allocate any more. */
146 
147  mapped_name_t *insert = tor_malloc_zero(
148  offsetof(mapped_name_t, name) + namelen + 1);
149  memcpy(insert->name, name, namelen+1);
150  insert->intval = new_id;
151 
152  HT_INSERT(namemap_ht, &map->ht, insert);
153  smartlist_add(map->names, insert);
154 
155  return new_id;
156 }
157 
159 size_t
161 {
162  if (PREDICT_UNLIKELY(map->names == NULL))
163  return 0;
164 
165  return smartlist_len(map->names);
166 }
167 
171 void
173 {
174  if (!map)
175  return;
176 
177  HT_CLEAR(namemap_ht, &map->ht);
178  if (map->names) {
179  SMARTLIST_FOREACH(map->names, mapped_name_t *, n,
180  tor_free(n));
181  smartlist_free(map->names);
182  }
183  memset(map, 0, sizeof(*map));
184 }
Header for printf.c.
unsigned namemap_get_or_create_id(namemap_t *map, const char *name)
Definition: namemap.c:128
Header for smartlist.c.
size_t namemap_get_size(const namemap_t *map)
Definition: namemap.c:160
void namemap_clear(namemap_t *map)
Definition: namemap.c:172
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 smartlist_add(smartlist_t *sl, void *element)
const char * namemap_get_name(const namemap_t *map, unsigned id)
Definition: namemap.c:49
Header for namemap.c.
#define tor_free(p)
Definition: malloc.h:52
Headers for util_malloc.c.
void * tor_reallocarray_(void *ptr, size_t sz1, size_t sz2)
Definition: malloc.c:146
tor_assert(buffer)
const char * namemap_fmt_name(const namemap_t *map, unsigned id)
Definition: namemap.c:65
void tor_free_(void *mem)
Definition: malloc.c:227
int tor_snprintf(char *str, size_t size, const char *format,...)
Definition: printf.c:27
#define SMARTLIST_FOREACH(sl, type, var, cmd)
#define NAMEMAP_ERR
Definition: namemap.h:23
Macros to manage assertions, fatal and non-fatal.
unsigned namemap_get_id(const namemap_t *map, const char *name)
Definition: namemap.c:109