@@ -80,11 +80,22 @@ struct hash_entry {
80
80
static_assert ((MIN_BUCKETS & (MIN_BUCKETS - 1 )) == 0 ,
81
81
"Bucket size is power of 2" );
82
82
83
+ #define DEFAULT_FNV1A_64_SEED 0xcbf29ce484222325ull
84
+ #define DEFAULT_FNV1A_32_SEED 0x811c9dc5u
85
+
86
+ uint64_t fnv1a_64_seed = DEFAULT_FNV1A_64_SEED ;
87
+ uint32_t fnv1a_32_seed = DEFAULT_FNV1A_32_SEED ;
88
+
89
+ #define ASSERT_SEED_INITIALIZED () \
90
+ do { \
91
+ assert(fnv1a_64_seed != DEFAULT_FNV1A_64_SEED); \
92
+ assert(fnv1a_32_seed != DEFAULT_FNV1A_32_SEED); \
93
+ } while (0)
94
+
83
95
static inline unsigned int hash_fnv1a_32 (const void * keyptr );
84
96
static inline unsigned int hash_int_32 (const void * keyptr );
85
97
static inline unsigned int hash_int_64 (const void * keyptr );
86
98
87
- static unsigned int odd_constant = DEFAULT_ODD_CONSTANT ;
88
99
static unsigned (* hash_str )(const void * key ) = hash_fnv1a_32 ;
89
100
static unsigned (* hash_int )(const void * key ) = hash_int_32 ;
90
101
static unsigned (* hash_int64 )(const void * key ) = hash_int_64 ;
@@ -135,10 +146,12 @@ static inline unsigned int hash_int_64(const void *keyptr)
135
146
#if defined(LWAN_HAVE_BUILTIN_CPU_INIT ) && defined(LWAN_HAVE_BUILTIN_IA32_CRC32 )
136
147
static inline unsigned int hash_str_crc32 (const void * keyptr )
137
148
{
138
- unsigned int hash = odd_constant ;
149
+ unsigned int hash = fnv1a_32_seed ;
139
150
const char * key = keyptr ;
140
151
size_t len = strlen (key );
141
152
153
+ ASSERT_SEED_INITIALIZED ();
154
+
142
155
#if __x86_64__
143
156
while (len >= sizeof (uint64_t )) {
144
157
uint64_t data ;
@@ -171,20 +184,24 @@ static inline unsigned int hash_str_crc32(const void *keyptr)
171
184
172
185
static inline unsigned int hash_int_crc32 (const void * keyptr )
173
186
{
174
- return __builtin_ia32_crc32si (odd_constant ,
187
+ ASSERT_SEED_INITIALIZED ();
188
+
189
+ return __builtin_ia32_crc32si (fnv1a_32_seed ,
175
190
(unsigned int )(uintptr_t )keyptr );
176
191
}
177
192
178
193
static inline unsigned int hash_int64_crc32 (const void * keyptr )
179
194
{
195
+ ASSERT_SEED_INITIALIZED ();
196
+
180
197
#ifdef __x86_64__
181
- return (unsigned int )__builtin_ia32_crc32di (odd_constant ,
198
+ return (unsigned int )__builtin_ia32_crc32di (fnv1a_32_seed ,
182
199
(uint64_t )(uintptr_t )keyptr );
183
200
#else
184
201
const uint64_t key = (uint64_t )(uintptr_t )keyptr ;
185
202
uint32_t crc ;
186
203
187
- crc = __builtin_ia32_crc32si (odd_constant , (uint32_t )(key & 0xffffffff ));
204
+ crc = __builtin_ia32_crc32si (fnv1a_32_seed , (uint32_t )(key & 0xffffffff ));
188
205
crc = __builtin_ia32_crc32si (crc , (uint32_t )(key >> 32 ));
189
206
190
207
return crc ;
@@ -193,19 +210,20 @@ static inline unsigned int hash_int64_crc32(const void *keyptr)
193
210
194
211
#endif
195
212
196
- uint64_t fnv1a_64_seed = 0xcbf29ce484222325ull ;
197
- uint32_t fnv1a_32_seed = 0x811c9dc5u ;
198
-
199
- __attribute__((constructor (65535 ))) static void initialize_odd_constant (void )
213
+ __attribute__((constructor (65535 ))) static void initialize_fnv1a_seed (void )
200
214
{
201
- /* This constant is randomized in order to mitigate the DDoS attack
215
+ uint8_t entropy [128 ];
216
+
217
+ /* The seeds are randomized in order to mitigate the DDoS attack
202
218
* described by Crosby and Wallach in UsenixSec2003. */
203
- if (lwan_getentropy (& odd_constant , sizeof (odd_constant ), 0 ) < 0 )
204
- odd_constant = DEFAULT_ODD_CONSTANT ;
205
- odd_constant |= 1 ;
219
+ if (UNLIKELY (lwan_getentropy (entropy , sizeof (entropy ), 0 ) < 0 )) {
220
+ lwan_status_perror ("Could not initialize FNV1a seed" );
221
+ __builtin_unreachable ();
222
+ }
206
223
207
- fnv1a_64_seed = fnv1a_64 (& odd_constant , sizeof (odd_constant ));
208
- fnv1a_32_seed = fnv1a_32 (& odd_constant , sizeof (odd_constant ));
224
+ fnv1a_64_seed = fnv1a_64 (entropy , sizeof (entropy ));
225
+ fnv1a_32_seed = fnv1a_32 (entropy , sizeof (entropy ));
226
+ lwan_always_bzero (entropy , sizeof (entropy ));
209
227
210
228
#if defined(LWAN_HAVE_BUILTIN_CPU_INIT ) && defined(LWAN_HAVE_BUILTIN_IA32_CRC32 )
211
229
__builtin_cpu_init ();
0 commit comments