|
reSIProcate
SIP stack, Dialog Usage Manager and related libraries
|
Hasher for hash containers keyed by data received from the network, e.g. More...
#include <Data.hxx>
Public Member Functions | |
| size_t | operator() (const Data &data) const |
Hasher for hash containers keyed by data received from the network, e.g.
HashMap<Data, Data, KeyedDataHash>.
Why not a plain HashMap<Data, ...>: the default std::hash<Data> is Data::hash(), a fixed Pearson hash with no secret. Anyone can compute it offline and generate as many distinct keys with the same hash as they like (a few seconds of work gives thousands). All such keys land in one bucket, so each insert compares against every key already there and filling the map becomes quadratic. This is hash flooding: in testing, 65536 colliding SDP attribute names - about 8 MB, one SIP message over TCP - took 30 s of CPU to insert, against 0.06 s for random names. Whichever thread does the parsing (the stack or DUM thread) stalls for that long.
KeyedDataHash uses Data::keyedHash(), which mixes in a random key chosen once per process. Without the key nobody can predict which inputs collide, so insertion stays linear whatever the input.
Use it (or Data::keyedCaseInsensitiveHash() / hashCombine() for case-insensitive or composite keys) whenever a remote party chooses the keys: header and parameter values, tags, Call-IDs, branches, body contents. The fixed hash is fine for keys the application chooses itself.
|
inline |