mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Some working code. Adds UID pools classified by string. Just compiles
and runs; need to go back through and make sure this code is actually doing what I want it to do. Note: Added new function unique_id_from(pool: string, prefix: string) that allows the user to explicitly specify a randomness pool to use when generating unique IDs.
This commit is contained in:
parent
f36310dc0e
commit
9322c063cc
10 changed files with 78 additions and 21 deletions
|
@ -3414,10 +3414,16 @@ function bro_has_ipv6%(%) : bool
|
|||
function unique_id%(prefix: string%) : string
|
||||
%{
|
||||
char tmp[20];
|
||||
uint64 uid = calculate_unique_id();
|
||||
uint64 uid = calculate_unique_id(BRO_SCRIPT_UID_POOL);
|
||||
return new StringVal(uitoa_n(uid, tmp, sizeof(tmp), 62, prefix->CheckString()));
|
||||
%}
|
||||
|
||||
function unique_id_from%(pool: string, prefix: string%) : string
|
||||
%{
|
||||
char tmp[20];
|
||||
uint64 uid = calculate_unique_id(string((const char *)pool->Bytes(), pool->Len()));
|
||||
return new StringVal(uitoa_n(uid, tmp, sizeof(tmp), 62, prefix->CheckString()));
|
||||
%}
|
||||
%%{
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/asn1.h>
|
||||
|
|
71
src/util.cc
71
src/util.cc
|
@ -1206,15 +1206,30 @@ int time_compare(struct timeval* tv_a, struct timeval* tv_b)
|
|||
return tv_a->tv_sec - tv_b->tv_sec;
|
||||
}
|
||||
|
||||
static uint64 uid_counter; // Counter for unique IDs.
|
||||
static uint64 uid_instance; // Instance ID, computed once.
|
||||
struct BroUidEntry
|
||||
{
|
||||
uint64 instance;
|
||||
uint64 counter;
|
||||
BroUidEntry(const uint64 i)
|
||||
: instance(i), counter(0) { }
|
||||
};
|
||||
|
||||
static std::map<string, BroUidEntry> uid_pool;
|
||||
static const std::string default_pool = string(BRO_DEFAULT_UID_POOL);
|
||||
|
||||
uint64 calculate_unique_id()
|
||||
{
|
||||
if ( uid_instance == 0 )
|
||||
{
|
||||
// This is the first time we need a UID.
|
||||
return calculate_unique_id(default_pool);
|
||||
}
|
||||
|
||||
uint64 calculate_unique_id(const std::string& pool)
|
||||
{
|
||||
uint64 uid_instance = 0;
|
||||
std::map<std::string, BroUidEntry>::iterator pool_iter = uid_pool.find(pool);
|
||||
if ( pool_iter == uid_pool.end() )
|
||||
{
|
||||
// This is the first time we need a UID for this pool.
|
||||
const size_t pool_sz = (pool.length() < 32) ? pool.length() : 32; //Only keep the first 32 characters of the pool name
|
||||
if ( ! have_random_seed() )
|
||||
{
|
||||
// If we don't need deterministic output (as
|
||||
|
@ -1222,14 +1237,16 @@ uint64 calculate_unique_id()
|
|||
// instance ID by hashing something likely to be
|
||||
// globally unique.
|
||||
struct {
|
||||
char hostname[128];
|
||||
char hostname[96];
|
||||
char pool[32];
|
||||
struct timeval time;
|
||||
pid_t pid;
|
||||
int rnd;
|
||||
} unique;
|
||||
|
||||
memset(&unique, 0, sizeof(unique)); // Make valgrind happy.
|
||||
gethostname(unique.hostname, 128);
|
||||
gethostname(unique.hostname, 96);
|
||||
memcpy(unique.pool, pool.c_str(), pool_sz);
|
||||
unique.hostname[sizeof(unique.hostname)-1] = '\0';
|
||||
gettimeofday(&unique.time, 0);
|
||||
unique.pid = getpid();
|
||||
|
@ -1238,22 +1255,38 @@ uint64 calculate_unique_id()
|
|||
uid_instance = HashKey::HashBytes(&unique, sizeof(unique));
|
||||
++uid_instance; // Now it's larger than zero.
|
||||
}
|
||||
|
||||
else
|
||||
// Generate determistic UIDs.
|
||||
uid_instance = 1;
|
||||
{
|
||||
// Generate determistic UIDs for each individual pool
|
||||
uid_instance = HashKey::HashBytes(pool.c_str(), strnlen(pool.c_str(), pool_sz));
|
||||
}
|
||||
// Guarantee no collisions (keep hashing until we get a unique instance)
|
||||
bool found_collision = true;
|
||||
while(found_collision)
|
||||
{
|
||||
found_collision = false;
|
||||
for(pool_iter = uid_pool.begin(); pool_iter != uid_pool.end(); ++pool_iter)
|
||||
{
|
||||
if(pool_iter->second.instance == uid_instance)
|
||||
{
|
||||
found_collision = true;
|
||||
uid_instance = HashKey::HashBytes(&uid_instance, sizeof(uid_instance));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Our instance is unique. Huzzah.
|
||||
uid_pool.insert(std::make_pair(pool, BroUidEntry(uid_instance)));
|
||||
pool_iter = uid_pool.end();
|
||||
}
|
||||
|
||||
// Now calculate the unique ID.
|
||||
struct {
|
||||
uint64 counter;
|
||||
hash_t instance;
|
||||
} key;
|
||||
if(pool_iter == uid_pool.end())
|
||||
{
|
||||
pool_iter = uid_pool.find(pool);
|
||||
}
|
||||
assert(pool_iter != uid_pool.end()); // After all that work, wouldn't it be a shame...?
|
||||
++(pool_iter->second.counter);
|
||||
|
||||
key.counter = ++uid_counter;
|
||||
key.instance = uid_instance;
|
||||
|
||||
uint64_t h = HashKey::HashBytes(&key, sizeof(key));
|
||||
uint64_t h = HashKey::HashBytes(&(pool_iter->second), sizeof(pool_iter->second));
|
||||
return h;
|
||||
}
|
||||
|
||||
|
|
|
@ -226,7 +226,10 @@ extern int time_compare(struct timeval* tv_a, struct timeval* tv_b);
|
|||
|
||||
// Returns an integer that's very likely to be unique, even across Bro
|
||||
// instances.
|
||||
#define BRO_DEFAULT_UID_POOL "bro"
|
||||
#define BRO_SCRIPT_UID_POOL "bro script"
|
||||
extern uint64 calculate_unique_id();
|
||||
extern uint64 calculate_unique_id(const std::string& pool);
|
||||
|
||||
// For now, don't use hash_maps - they're not fully portable.
|
||||
#if 0
|
||||
|
|
|
@ -7,3 +7,6 @@
|
|||
print unique_id("A-");
|
||||
print unique_id("B-");
|
||||
print unique_id("C-");
|
||||
print unique_id_from("alpha", "D-");
|
||||
print unique_id_from("beta", "E-");
|
||||
print unique_id_from("beta", "F-");
|
||||
|
|
|
@ -5,3 +5,6 @@
|
|||
print unique_id("A-");
|
||||
print unique_id("B-");
|
||||
print unique_id("C-");
|
||||
print unique_id_from("alpha", "D-");
|
||||
print unique_id_from("beta", "E-");
|
||||
print unique_id_from("beta", "F-");
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
[btest]
|
||||
ProfileDir = profiles
|
||||
TestDirs = doc bifs language core policy istate
|
||||
TmpDir = %(testbase)s/.tmp
|
||||
BaselineDir = %(testbase)s/Baseline
|
||||
|
|
2
testing/btest/profiles/default/finish
Executable file
2
testing/btest/profiles/default/finish
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/usr/bin/env bash
|
||||
|
2
testing/btest/profiles/default/setup
Executable file
2
testing/btest/profiles/default/setup
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/usr/bin/env bash
|
||||
|
2
testing/btest/profiles/default/supported
Executable file
2
testing/btest/profiles/default/supported
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/usr/bin/env bash
|
||||
|
2
testing/btest/profiles/default/transform
Executable file
2
testing/btest/profiles/default/transform
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/usr/bin/env bash
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue