Merge branch 'topic/bernhard/log-threads' into topic/bernhard/input-threads

Seems to work -- all test pass.
But there are thread-safety issues at the moment, because the constructors of IPAddr and IPPrefix are not thread-safe, but needed by workers.

Conflicts:
	src/logging/Manager.cc
This commit is contained in:
Bernhard Amann 2012-02-27 22:59:08 -08:00
commit 417542f283
148 changed files with 2635 additions and 2186 deletions

View file

@ -25,7 +25,7 @@
#include "PrefixTable.h"
#include "Conn.h"
#include "Reporter.h"
#include "IPAddr.h"
Val::Val(Func* f)
{
@ -205,29 +205,10 @@ bool Val::DoSerialize(SerialInfo* info) const
val.string_val->Len());
case TYPE_INTERNAL_ADDR:
return SERIALIZE(NUM_ADDR_WORDS)
#ifdef BROv6
&& SERIALIZE(uint32(ntohl(val.addr_val[0])))
&& SERIALIZE(uint32(ntohl(val.addr_val[1])))
&& SERIALIZE(uint32(ntohl(val.addr_val[2])))
&& SERIALIZE(uint32(ntohl(val.addr_val[3])));
#else
&& SERIALIZE(uint32(ntohl(val.addr_val)));
#endif
return SERIALIZE(*val.addr_val);
case TYPE_INTERNAL_SUBNET:
return info->s->WriteOpenTag("subnet")
&& SERIALIZE(NUM_ADDR_WORDS)
#ifdef BROv6
&& SERIALIZE(uint32(ntohl(val.subnet_val.net[0])))
&& SERIALIZE(uint32(ntohl(val.subnet_val.net[1])))
&& SERIALIZE(uint32(ntohl(val.subnet_val.net[2])))
&& SERIALIZE(uint32(ntohl(val.subnet_val.net[3])))
#else
&& SERIALIZE(uint32(ntohl(val.subnet_val.net)))
#endif
&& SERIALIZE(val.subnet_val.width)
&& info->s->WriteCloseTag("subnet");
return SERIALIZE(*val.subnet_val);
case TYPE_INTERNAL_OTHER:
// Derived classes are responsible for this.
@ -294,94 +275,15 @@ bool Val::DoUnserialize(UnserialInfo* info)
case TYPE_INTERNAL_ADDR:
{
int num_words;
if ( ! UNSERIALIZE(&num_words) )
return false;
if ( num_words != 1 && num_words != 4 )
{
info->s->Error("bad address type");
return false;
}
uint32 a[4]; // big enough to hold either
for ( int i = 0; i < num_words; ++i )
{
if ( ! UNSERIALIZE(&a[i]) )
return false;
a[i] = htonl(a[i]);
}
#ifndef BROv6
if ( num_words == 4 )
{
if ( a[0] || a[1] || a[2] )
info->s->Warning("received IPv6 address, ignoring");
((AddrVal*) this)->Init(a[3]);
}
else
((AddrVal*) this)->Init(a[0]);
#else
if ( num_words == 1 )
((AddrVal*) this)->Init(a[0]);
else
((AddrVal*) this)->Init(a);
#endif
val.addr_val = new IPAddr();
return UNSERIALIZE(val.addr_val);
}
return true;
case TYPE_INTERNAL_SUBNET:
{
int num_words;
if ( ! UNSERIALIZE(&num_words) )
return false;
if ( num_words != 1 && num_words != 4 )
{
info->s->Error("bad subnet type");
return false;
}
uint32 a[4]; // big enough to hold either
for ( int i = 0; i < num_words; ++i )
{
if ( ! UNSERIALIZE(&a[i]) )
return false;
a[i] = htonl(a[i]);
}
int width;
if ( ! UNSERIALIZE(&width) )
return false;
#ifdef BROv6
if ( num_words == 1 )
{
a[3] = a[0];
a[0] = a[1] = a[2] = 0;
}
((SubNetVal*) this)->Init(a, width);
#else
if ( num_words == 4 )
{
if ( a[0] || a[1] || a[2] )
info->s->Warning("received IPv6 subnet, ignoring");
a[0] = a[3];
if ( width > 32 )
width -= 96;
}
((SubNetVal*) this)->Init(a[0], width);
#endif
val.subnet_val = new IPPrefix();
return UNSERIALIZE(val.subnet_val);
}
return true;
case TYPE_INTERNAL_OTHER:
// Derived classes are responsible for this.
@ -590,12 +492,10 @@ void Val::ValDescribe(ODesc* d) const
case TYPE_INTERNAL_UNSIGNED: d->Add(val.uint_val); break;
case TYPE_INTERNAL_DOUBLE: d->Add(val.double_val); break;
case TYPE_INTERNAL_STRING: d->AddBytes(val.string_val); break;
case TYPE_INTERNAL_ADDR: d->Add(dotted_addr(val.addr_val)); break;
case TYPE_INTERNAL_ADDR: d->Add(val.addr_val->AsString().c_str()); break;
case TYPE_INTERNAL_SUBNET:
d->Add(dotted_addr(val.subnet_val.net));
d->Add("/");
d->Add(val.subnet_val.width);
d->Add(val.subnet_val->AsString().c_str());
break;
case TYPE_INTERNAL_ERROR: d->AddCS("error"); break;
@ -706,7 +606,8 @@ ID* MutableVal::Bind() const
ip = htonl(0x7f000001); // 127.0.0.1
safe_snprintf(name, MAX_NAME_SIZE, "#%s#%d#",
dotted_addr(ip), getpid());
IPAddr(IPAddr::IPv4, &ip, IPAddr::Network)->AsString().c_str(),
getpid());
#else
safe_snprintf(name, MAX_NAME_SIZE, "#%s#%d#", host, getpid());
#endif
@ -957,92 +858,41 @@ bool PortVal::DoUnserialize(UnserialInfo* info)
AddrVal::AddrVal(const char* text) : Val(TYPE_ADDR)
{
const char* colon = strchr(text, ':');
if ( colon )
{
#ifdef BROv6
Init(dotted_to_addr6(text));
#else
reporter->Error("bro wasn't compiled with IPv6 support");
Init(uint32(0));
#endif
}
else
Init(dotted_to_addr(text));
val.addr_val = new IPAddr(text);
}
AddrVal::AddrVal(uint32 addr) : Val(TYPE_ADDR)
{
// ### perhaps do gethostbyaddr here?
Init(addr);
val.addr_val = new IPAddr(IPAddr::IPv4, &addr, IPAddr::Network);
}
AddrVal::AddrVal(const uint32* addr) : Val(TYPE_ADDR)
AddrVal::AddrVal(const uint32 addr[4]) : Val(TYPE_ADDR)
{
Init(addr);
val.addr_val = new IPAddr(IPAddr::IPv6, addr, IPAddr::Network);
}
AddrVal::AddrVal(const IPAddr& addr) : Val(TYPE_ADDR)
{
val.addr_val = new IPAddr(addr);
}
AddrVal::~AddrVal()
{
#ifdef BROv6
delete [] val.addr_val;
#endif
}
Val* AddrVal::SizeVal() const
{
uint32 addr;
#ifdef BROv6
if ( ! is_v4_addr(val.addr_val) )
{
Error("|addr| for IPv6 addresses not supported");
return new Val(0, TYPE_COUNT);
}
addr = to_v4_addr(val.addr_val);
#else
addr = val.addr_val;
#endif
addr = ntohl(addr);
return new Val(addr, TYPE_COUNT);
}
void AddrVal::Init(uint32 addr)
{
#ifdef BROv6
val.addr_val = new uint32[4];
val.addr_val[0] = val.addr_val[1] = val.addr_val[2] = 0;
val.addr_val[3] = addr;
#else
val.addr_val = addr;
#endif
}
void AddrVal::Init(const uint32* addr)
{
#ifdef BROv6
val.addr_val = new uint32[4];
val.addr_val[0] = addr[0];
val.addr_val[1] = addr[1];
val.addr_val[2] = addr[2];
val.addr_val[3] = addr[3];
#else
val.addr_val = addr[0];
#endif
delete val.addr_val;
}
unsigned int AddrVal::MemoryAllocation() const
{
#ifdef BROv6
return padded_sizeof(*this) + pad_size(4 * sizeof(uint32));
#else
return padded_sizeof(*this);
#endif
return padded_sizeof(*this) + val.addr_val->MemoryAllocation();
}
Val* AddrVal::SizeVal() const
{
if ( val.addr_val->GetFamily() == IPAddr::IPv4 )
return new Val(32, TYPE_COUNT);
else
return new Val(128, TYPE_COUNT);
}
IMPLEMENT_SERIAL(AddrVal, SER_ADDR_VAL);
@ -1059,209 +909,104 @@ bool AddrVal::DoUnserialize(UnserialInfo* info)
return true;
}
static uint32 parse_dotted(const char* text, int& dots)
{
int addr[4];
uint32 a = 0;
dots = 0;
if ( sscanf(text, "%d.%d.%d.%d", addr+0, addr+1, addr+2, addr+3) == 4 )
{
a = (addr[0] << 24) | (addr[1] << 16) |
(addr[2] << 8) | addr[3];
dots = 3;
}
else if ( sscanf(text, "%d.%d.%d", addr+0, addr+1, addr+2) == 3 )
{
a = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8);
dots = 2;
}
else if ( sscanf(text, "%d.%d", addr+0, addr+1) == 2 )
{
a = (addr[0] << 24) | (addr[1] << 16);
dots = 1;
}
else
reporter->InternalError("scanf failed in parse_dotted()");
for ( int i = 0; i <= dots; ++i )
{
if ( addr[i] < 0 || addr[i] > 255 )
{
reporter->Error("bad dotted address %s", text);
break;
}
}
return a;
}
SubNetVal::SubNetVal(const char* text) : Val(TYPE_SUBNET)
{
const char* sep = strchr(text, '/');
if ( ! sep )
Internal("separator missing in SubNetVal::SubNetVal");
string s(text);
size_t slash_loc = s.find('/');
Init(text, atoi(sep+1));
if ( slash_loc == string::npos )
{
reporter->Error("Bad string in SubNetVal ctor: %s", text);
val.subnet_val = new IPPrefix();
}
else
{
val.subnet_val = new IPPrefix(s.substr(0, slash_loc),
atoi(s.substr(slash_loc + 1).c_str()));
}
}
SubNetVal::SubNetVal(const char* text, int width) : Val(TYPE_SUBNET)
{
Init(text, width);
val.subnet_val = new IPPrefix(text, width);
}
SubNetVal::SubNetVal(uint32 addr, int width) : Val(TYPE_SUBNET)
{
Init(addr, width);
IPAddr a(IPAddr::IPv4, &addr, IPAddr::Network);
val.subnet_val = new IPPrefix(a, width);
}
#ifdef BROv6
SubNetVal::SubNetVal(const uint32* addr, int width) : Val(TYPE_SUBNET)
{
Init(addr, width);
}
#endif
void SubNetVal::Init(const char* text, int width)
{
#ifdef BROv6
if ( width <= 0 || width > 128 )
#else
if ( width <= 0 || width > 32 )
#endif
Error("bad subnet width");
int dots;
uint32 a = parse_dotted(text, dots);
Init(uint32(htonl(a)), width);
IPAddr a(IPAddr::IPv6, addr, IPAddr::Network);
val.subnet_val = new IPPrefix(a, width);
}
void SubNetVal::Init(uint32 addr, int width)
SubNetVal::SubNetVal(const IPAddr& addr, int width) : Val(TYPE_SUBNET)
{
#ifdef BROv6
Internal("SubNetVal::Init called on 4-byte address w/ BROv6");
#else
val.subnet_val.net = mask_addr(addr, uint32(width));
val.subnet_val.width = width;
#endif
val.subnet_val = new IPPrefix(addr, width);
}
void SubNetVal::Init(const uint32* addr, int width)
SubNetVal::SubNetVal(const IPPrefix& prefix) : Val(TYPE_SUBNET)
{
#ifdef BROv6
const uint32* a = mask_addr(addr, uint32(width));
val.subnet_val = new IPPrefix(prefix);
}
val.subnet_val.net[0] = a[0];
val.subnet_val.net[1] = a[1];
val.subnet_val.net[2] = a[2];
val.subnet_val.net[3] = a[3];
SubNetVal::~SubNetVal()
{
delete val.subnet_val;
}
if ( is_v4_addr(addr) && width <= 32 )
val.subnet_val.width = width + 96;
else
val.subnet_val.width = width;
#else
Internal("SubNetVal::Init called on 16-byte address w/o BROv6");
#endif
unsigned int SubNetVal::MemoryAllocation() const
{
return padded_sizeof(*this) + val.subnet_val->MemoryAllocation();
}
Val* SubNetVal::SizeVal() const
{
int retained;
#ifdef BROv6
retained = 128 - Width();
#else
retained = 32 - Width();
#endif
int retained = 128 - val.subnet_val->LengthIPv6();
return new Val(pow(2.0, double(retained)), TYPE_DOUBLE);
}
void SubNetVal::ValDescribe(ODesc* d) const
{
d->Add(dotted_addr(val.subnet_val.net, d->Style() == ALTERNATIVE_STYLE));
d->Add("/");
#ifdef BROv6
if ( is_v4_addr(val.subnet_val.net) )
d->Add(val.subnet_val.width - 96);
else
#endif
d->Add(val.subnet_val.width);
d->Add(string(*val.subnet_val).c_str());
}
addr_type SubNetVal::Mask() const
IPAddr SubNetVal::Mask() const
{
if ( val.subnet_val.width == 0 )
if ( val.subnet_val->Length() == 0 )
{
// We need to special-case a mask width of zero, since
// the compiler doesn't guarantee that 1 << 32 yields 0.
#ifdef BROv6
uint32* m = new uint32[4];
for ( int i = 0; i < 4; ++i )
uint32 m[4];
for ( unsigned int i = 0; i < 4; ++i )
m[i] = 0;
return m;
#else
return 0;
#endif
IPAddr rval(IPAddr::IPv6, m, IPAddr::Host);
return rval;
}
#ifdef BROv6
uint32* m = new uint32[4];
uint32 m[4];
uint32* mp = m;
uint32 w;
for ( w = val.subnet_val.width; w >= 32; w -= 32 )
*(mp++) = 0xffffffff;
for ( w = val.subnet_val->Length(); w >= 32; w -= 32 )
*(mp++) = 0xffffffff;
*mp = ~((1 << (32 - w)) - 1);
while ( ++mp < m + 4 )
*mp = 0;
*mp = 0;
return m;
#else
return ~((1 << (32 - val.subnet_val.width)) - 1);
#endif
IPAddr rval(IPAddr::IPv6, m, IPAddr::Host);
return rval;
}
bool SubNetVal::Contains(const uint32 addr) const
bool SubNetVal::Contains(const IPAddr& addr) const
{
#ifdef BROv6
Internal("SubNetVal::Contains called on 4-byte address w/ BROv6");
return false;
#else
return ntohl(val.subnet_val.net) == (ntohl(addr) & Mask());
#endif
}
bool SubNetVal::Contains(const uint32* addr) const
{
#ifdef BROv6
const uint32* net = val.subnet_val.net;
const uint32* a = addr;
uint32 m;
for ( m = val.subnet_val.width; m > 32; m -= 32 )
{
if ( *net != *a )
return false;
++net;
++a;
}
uint32 mask = ~((1 << (32 - m)) - 1);
return ntohl(*net) == (ntohl(*a) & mask);
#else
return Contains(addr[3]);
#endif
IPAddr a(addr);
return val.subnet_val->Contains(a);
}
IMPLEMENT_SERIAL(SubNetVal, SER_SUBNET_VAL);
@ -3476,20 +3221,10 @@ int same_atomic_val(const Val* v1, const Val* v2)
return v1->InternalDouble() == v2->InternalDouble();
case TYPE_INTERNAL_STRING:
return Bstr_eq(v1->AsString(), v2->AsString());
case TYPE_INTERNAL_ADDR:
{
const addr_type& a1 = v1->AsAddr();
const addr_type& a2 = v2->AsAddr();
#ifdef BROv6
return addr_eq(a1, a2);
#else
return addr_eq(&a1, &a2);
#endif
}
return v1->AsAddr() == v2->AsAddr();
case TYPE_INTERNAL_SUBNET:
return subnet_eq(v1->AsSubNet(), v2->AsSubNet());
return v1->AsSubNet() == v2->AsSubNet();
default:
reporter->InternalError("same_atomic_val called for non-atomic value");