2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
8 * Copyright (C) 2002-2009 OpenVPN Technologies, Inc. <sales@openvpn.net>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 * This code is a fairly straightforward hash
30 * table implementation using Bob Jenkins'
33 * Hash tables are used in OpenVPN to keep track of
34 * client instances over various key spaces.
39 /* define this to enable special list test mode */
46 #define hashsize(n) ((uint32_t)1<<(n))
47 #define hashmask(n) (hashsize(n)-1)
53 unsigned int hash_value
;
54 struct hash_element
*next
;
60 struct hash_element
*list
;
69 uint32_t (*hash_function
)(const void *key
, uint32_t iv
);
70 bool (*compare_function
)(const void *key1
, const void *key2
); /* return true if equal */
71 struct hash_bucket
*buckets
;
74 struct hash
*hash_init (const int n_buckets
,
76 uint32_t (*hash_function
)(const void *key
, uint32_t iv
),
77 bool (*compare_function
)(const void *key1
, const void *key2
));
79 void hash_free (struct hash
*hash
);
81 bool hash_add (struct hash
*hash
, const void *key
, void *value
, bool replace
);
83 struct hash_element
*hash_lookup_fast (struct hash
*hash
,
84 struct hash_bucket
*bucket
,
88 bool hash_remove_fast (struct hash
*hash
,
89 struct hash_bucket
*bucket
,
93 void hash_remove_by_value (struct hash
*hash
, void *value
, bool autolock
);
99 struct hash_bucket
*bucket
;
100 struct hash_element
*elem
;
101 struct hash_element
*last
;
104 int bucket_index_start
;
105 int bucket_index_end
;
108 void hash_iterator_init_range (struct hash
*hash
,
109 struct hash_iterator
*hi
,
114 void hash_iterator_init (struct hash
*hash
, struct hash_iterator
*iter
, bool autolock
);
115 struct hash_element
*hash_iterator_next (struct hash_iterator
*hi
);
116 void hash_iterator_delete_element (struct hash_iterator
*hi
);
117 void hash_iterator_free (struct hash_iterator
*hi
);
119 uint32_t hash_func (const uint8_t *k
, uint32_t length
, uint32_t initval
);
121 uint32_t void_ptr_hash_function (const void *key
, uint32_t iv
);
122 bool void_ptr_compare_function (const void *key1
, const void *key2
);
125 void list_test (void);
128 static inline uint32_t
129 hash_value (const struct hash
*hash
, const void *key
)
131 return (*hash
->hash_function
)(key
, hash
->iv
);
135 hash_n_elements (const struct hash
*hash
)
137 return hash
->n_elements
;
141 hash_n_buckets (const struct hash
*hash
)
143 return hash
->n_buckets
;
146 static inline struct hash_bucket
*
147 hash_bucket (struct hash
*hash
, uint32_t hv
)
149 return &hash
->buckets
[hv
& hash
->mask
];
153 hash_bucket_lock (struct hash_bucket
*bucket
)
155 mutex_lock (&bucket
->mutex
);
159 hash_bucket_unlock (struct hash_bucket
*bucket
)
161 mutex_unlock (&bucket
->mutex
);
165 hash_lookup_lock (struct hash
*hash
, const void *key
, uint32_t hv
)
168 struct hash_element
*he
;
169 struct hash_bucket
*bucket
= &hash
->buckets
[hv
& hash
->mask
];
171 mutex_lock (&bucket
->mutex
);
172 he
= hash_lookup_fast (hash
, bucket
, key
, hv
);
175 mutex_unlock (&bucket
->mutex
);
181 hash_lookup (struct hash
*hash
, const void *key
)
183 return hash_lookup_lock (hash
, key
, hash_value (hash
, key
));
186 /* NOTE: assumes that key is not a duplicate */
188 hash_add_fast (struct hash
*hash
,
189 struct hash_bucket
*bucket
,
194 struct hash_element
*he
;
196 ALLOC_OBJ (he
, struct hash_element
);
200 he
->next
= bucket
->list
;
206 hash_remove (struct hash
*hash
, const void *key
)
209 struct hash_bucket
*bucket
;
212 hv
= hash_value (hash
, key
);
213 bucket
= &hash
->buckets
[hv
& hash
->mask
];
214 mutex_lock (&bucket
->mutex
);
215 ret
= hash_remove_fast (hash
, bucket
, key
, hv
);
216 mutex_unlock (&bucket
->mutex
);
220 #endif /* P2MP_SERVER */