mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
A new bif unique_id(prefix) that returns a string that's unique across
Bro instaces with high probablity. "prefix" is a string that will be prepended to the returned ID.
This commit is contained in:
parent
4bdb94955d
commit
8266709e20
10 changed files with 96 additions and 59 deletions
52
src/Conn.cc
52
src/Conn.cc
|
@ -216,56 +216,6 @@ Connection::~Connection()
|
||||||
--external_connections;
|
--external_connections;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 Connection::uid_counter = 0;
|
|
||||||
uint64 Connection::uid_instance = 0;
|
|
||||||
|
|
||||||
uint64 Connection::CalculateNextUID()
|
|
||||||
{
|
|
||||||
if ( uid_instance == 0 )
|
|
||||||
{
|
|
||||||
// This is the first time we need a UID.
|
|
||||||
|
|
||||||
if ( ! have_random_seed() )
|
|
||||||
{
|
|
||||||
// If we don't need deterministic output (as
|
|
||||||
// indicated by a set seed), we calculate the
|
|
||||||
// instance ID by hashing something likely to be
|
|
||||||
// globally unique.
|
|
||||||
struct {
|
|
||||||
char hostname[128];
|
|
||||||
struct timeval time;
|
|
||||||
pid_t pid;
|
|
||||||
int rnd;
|
|
||||||
} unique;
|
|
||||||
|
|
||||||
gethostname(unique.hostname, 128);
|
|
||||||
unique.hostname[sizeof(unique.hostname)-1] = '\0';
|
|
||||||
gettimeofday(&unique.time, 0);
|
|
||||||
unique.pid = getpid();
|
|
||||||
unique.rnd = bro_random();
|
|
||||||
|
|
||||||
uid_instance = HashKey::HashBytes(&unique, sizeof(unique));
|
|
||||||
++uid_instance; // Now it's larger than zero.
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
// Generate determistic UIDs.
|
|
||||||
uid_instance = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now calculate the unique ID for this connection.
|
|
||||||
struct {
|
|
||||||
uint64 counter;
|
|
||||||
hash_t instance;
|
|
||||||
} key;
|
|
||||||
|
|
||||||
key.counter = ++uid_counter;
|
|
||||||
key.instance = uid_instance;
|
|
||||||
|
|
||||||
uint64_t h = HashKey::HashBytes(&key, sizeof(key));
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Connection::Done()
|
void Connection::Done()
|
||||||
{
|
{
|
||||||
finished = 1;
|
finished = 1;
|
||||||
|
@ -417,7 +367,7 @@ RecordVal* Connection::BuildConnVal()
|
||||||
conn_val->Assign(8, new StringVal("")); // history
|
conn_val->Assign(8, new StringVal("")); // history
|
||||||
|
|
||||||
if ( ! uid )
|
if ( ! uid )
|
||||||
uid = CalculateNextUID();
|
uid = calculate_unique_id();
|
||||||
|
|
||||||
char tmp[20];
|
char tmp[20];
|
||||||
conn_val->Assign(9, new StringVal(uitoa_n(uid, tmp, sizeof(tmp), 62)));
|
conn_val->Assign(9, new StringVal(uitoa_n(uid, tmp, sizeof(tmp), 62)));
|
||||||
|
|
|
@ -303,8 +303,6 @@ public:
|
||||||
|
|
||||||
void SetUID(uint64 arg_uid) { uid = arg_uid; }
|
void SetUID(uint64 arg_uid) { uid = arg_uid; }
|
||||||
|
|
||||||
static uint64 CalculateNextUID();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Connection() { persistent = 0; }
|
Connection() { persistent = 0; }
|
||||||
|
@ -363,9 +361,6 @@ protected:
|
||||||
PIA* primary_PIA;
|
PIA* primary_PIA;
|
||||||
|
|
||||||
uint64 uid; // Globally unique connection ID.
|
uint64 uid; // Globally unique connection ID.
|
||||||
|
|
||||||
static uint64 uid_counter; // Counter for uids.
|
|
||||||
static uint64 uid_instance; // Instance ID, computed once.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConnectionTimer : public Timer {
|
class ConnectionTimer : public Timer {
|
||||||
|
|
|
@ -620,7 +620,7 @@ void ConnCompressor::PktHdrToPendingConn(double time, const HashKey* key,
|
||||||
c->FIN = (tp->th_flags & TH_FIN) != 0;
|
c->FIN = (tp->th_flags & TH_FIN) != 0;
|
||||||
c->RST = (tp->th_flags & TH_RST) != 0;
|
c->RST = (tp->th_flags & TH_RST) != 0;
|
||||||
c->ACK = (tp->th_flags & TH_ACK) != 0;
|
c->ACK = (tp->th_flags & TH_ACK) != 0;
|
||||||
c->uid = Connection::CalculateNextUID();
|
c->uid = calculate_unique_id();
|
||||||
c->num_bytes_ip = ip->TotalLen();
|
c->num_bytes_ip = ip->TotalLen();
|
||||||
c->num_pkts = 1;
|
c->num_pkts = 1;
|
||||||
c->invalid = 0;
|
c->invalid = 0;
|
||||||
|
|
|
@ -3349,6 +3349,12 @@ function bro_has_ipv6%(%) : bool
|
||||||
#endif
|
#endif
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
function unique_id%(prefix: string%) : bool
|
||||||
|
%{
|
||||||
|
char tmp[20];
|
||||||
|
uint64 uid = calculate_unique_id();
|
||||||
|
return new StringVal(uitoa_n(uid, tmp, sizeof(tmp), 62, prefix->CheckString()));
|
||||||
|
%}
|
||||||
|
|
||||||
%%{
|
%%{
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
|
|
64
src/util.cc
64
src/util.cc
|
@ -344,15 +344,27 @@ template<class T> int atoi_n(int len, const char* s, const char** end, int base,
|
||||||
template int atoi_n<int>(int len, const char* s, const char** end, int base, int& result);
|
template int atoi_n<int>(int len, const char* s, const char** end, int base, int& result);
|
||||||
template int atoi_n<int64_t>(int len, const char* s, const char** end, int base, int64_t& result);
|
template int atoi_n<int64_t>(int len, const char* s, const char** end, int base, int64_t& result);
|
||||||
|
|
||||||
char* uitoa_n(uint64 value, char* str, int n, int base)
|
char* uitoa_n(uint64 value, char* str, int n, int base, const char* prefix)
|
||||||
{
|
{
|
||||||
static char dig[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
static char dig[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
|
||||||
|
assert(n);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
uint64 v;
|
uint64 v;
|
||||||
char* p, *q;
|
char* p, *q;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
|
if ( prefix )
|
||||||
|
{
|
||||||
|
strncpy(str, prefix, n);
|
||||||
|
str[n-1] = '\0';
|
||||||
|
i += strlen(prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( i >= n )
|
||||||
|
return str;
|
||||||
|
|
||||||
v = value;
|
v = value;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -1122,6 +1134,56 @@ int time_compare(struct timeval* tv_a, struct timeval* tv_b)
|
||||||
return tv_a->tv_sec - tv_b->tv_sec;
|
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.
|
||||||
|
|
||||||
|
uint64 calculate_unique_id()
|
||||||
|
{
|
||||||
|
if ( uid_instance == 0 )
|
||||||
|
{
|
||||||
|
// This is the first time we need a UID.
|
||||||
|
|
||||||
|
if ( ! have_random_seed() )
|
||||||
|
{
|
||||||
|
// If we don't need deterministic output (as
|
||||||
|
// indicated by a set seed), we calculate the
|
||||||
|
// instance ID by hashing something likely to be
|
||||||
|
// globally unique.
|
||||||
|
struct {
|
||||||
|
char hostname[128];
|
||||||
|
struct timeval time;
|
||||||
|
pid_t pid;
|
||||||
|
int rnd;
|
||||||
|
} unique;
|
||||||
|
|
||||||
|
gethostname(unique.hostname, 128);
|
||||||
|
unique.hostname[sizeof(unique.hostname)-1] = '\0';
|
||||||
|
gettimeofday(&unique.time, 0);
|
||||||
|
unique.pid = getpid();
|
||||||
|
unique.rnd = bro_random();
|
||||||
|
|
||||||
|
uid_instance = HashKey::HashBytes(&unique, sizeof(unique));
|
||||||
|
++uid_instance; // Now it's larger than zero.
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
// Generate determistic UIDs.
|
||||||
|
uid_instance = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now calculate the unique ID.
|
||||||
|
struct {
|
||||||
|
uint64 counter;
|
||||||
|
hash_t instance;
|
||||||
|
} key;
|
||||||
|
|
||||||
|
key.counter = ++uid_counter;
|
||||||
|
key.instance = uid_instance;
|
||||||
|
|
||||||
|
uint64_t h = HashKey::HashBytes(&key, sizeof(key));
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
void out_of_memory(const char* where)
|
void out_of_memory(const char* where)
|
||||||
{
|
{
|
||||||
fprintf( stderr, "bro: out of memory in %s.\n", where );
|
fprintf( stderr, "bro: out of memory in %s.\n", where );
|
||||||
|
|
|
@ -111,7 +111,7 @@ extern char* strcasestr(const char* s, const char* find);
|
||||||
#endif
|
#endif
|
||||||
extern const char* strpbrk_n(size_t len, const char* s, const char* charset);
|
extern const char* strpbrk_n(size_t len, const char* s, const char* charset);
|
||||||
template<class T> int atoi_n(int len, const char* s, const char** end, int base, T& result);
|
template<class T> int atoi_n(int len, const char* s, const char** end, int base, T& result);
|
||||||
extern char* uitoa_n(uint64 value, char* str, int n, int base);
|
extern char* uitoa_n(uint64 value, char* str, int n, int base, const char* prefix=0);
|
||||||
int strstr_n(const int big_len, const unsigned char* big,
|
int strstr_n(const int big_len, const unsigned char* big,
|
||||||
const int little_len, const unsigned char* little);
|
const int little_len, const unsigned char* little);
|
||||||
extern int fputs(int len, const char* s, FILE* fp);
|
extern int fputs(int len, const char* s, FILE* fp);
|
||||||
|
@ -233,6 +233,10 @@ extern struct timeval double_to_timeval(double t);
|
||||||
// Return > 0 if tv_a > tv_b, 0 if equal, < 0 if tv_a < tv_b.
|
// Return > 0 if tv_a > tv_b, 0 if equal, < 0 if tv_a < tv_b.
|
||||||
extern int time_compare(struct timeval* tv_a, struct timeval* tv_b);
|
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.
|
||||||
|
extern uint64 calculate_unique_id();
|
||||||
|
|
||||||
// For now, don't use hash_maps - they're not fully portable.
|
// For now, don't use hash_maps - they're not fully portable.
|
||||||
#if 0
|
#if 0
|
||||||
// Use for hash_map's string keys.
|
// Use for hash_map's string keys.
|
||||||
|
|
1
testing/btest/Baseline/bifs.unique_id-rnd/count
Normal file
1
testing/btest/Baseline/bifs.unique_id-rnd/count
Normal file
|
@ -0,0 +1 @@
|
||||||
|
6
|
3
testing/btest/Baseline/bifs.unique_id/out
Normal file
3
testing/btest/Baseline/bifs.unique_id/out
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
A-UWkUyAuUGXf
|
||||||
|
B-56gKBmhBBB6
|
||||||
|
C-50da4BEzauh
|
9
testing/btest/bifs/unique_id-rnd.bro
Normal file
9
testing/btest/bifs/unique_id-rnd.bro
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: BRO_SEED_FILE= bro %INPUT 2>/dev/null >out
|
||||||
|
# @TEST-EXEC: BRO_SEED_FILE= bro %INPUT 2>/dev/null >>out
|
||||||
|
# @TEST-EXEC: cat out | sort | uniq | wc -l >count
|
||||||
|
# @TEST-EXEC: btest-diff count
|
||||||
|
|
||||||
|
print unique_id("A-");
|
||||||
|
print unique_id("B-");
|
||||||
|
print unique_id("C-");
|
7
testing/btest/bifs/unique_id.bro
Normal file
7
testing/btest/bifs/unique_id.bro
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: bro %INPUT >out
|
||||||
|
# @TEST-EXEC: btest-diff out
|
||||||
|
|
||||||
|
print unique_id("A-");
|
||||||
|
print unique_id("B-");
|
||||||
|
print unique_id("C-");
|
Loading…
Add table
Add a link
Reference in a new issue