Making exchange of addresses between threads thread-safe.

As we can't use the IPAddr class (because it's not thread-safe), this
involved a bit manual address manipulation and also shuffling some
things around a bit.

Not fully working yet, the tests for remote logging still fail.
This commit is contained in:
Robin Sommer 2012-02-28 15:12:35 -08:00
parent 14916b43f6
commit edc9bb14af
24 changed files with 325 additions and 84 deletions

View file

@ -30,12 +30,6 @@ Value::~Value()
&& present )
delete val.string_val;
if ( type == TYPE_ADDR && present )
delete val.addr_val;
if ( type == TYPE_SUBNET && present )
delete val.subnet_val;
if ( type == TYPE_TABLE && present )
{
for ( int i = 0; i < val.set_val.size; i++ )
@ -130,8 +124,8 @@ bool Value::Read(SerializationFormat* fmt)
if ( ! (fmt->Read(&val.port_val.port, "port") && fmt->Read(&proto, "proto") ) ) {
return false;
}
switch (proto) {
switch ( proto ) {
case 0:
val.port_val.proto = TRANSPORT_UNKNOWN;
break;
@ -147,20 +141,35 @@ bool Value::Read(SerializationFormat* fmt)
default:
return false;
}
return true;
}
case TYPE_SUBNET:
{
val.subnet_val = new IPPrefix;
return fmt->Read(val.subnet_val, "subnet");
}
case TYPE_ADDR:
{
val.addr_val = new IPAddr;
return fmt->Read(val.addr_val, "addr");
int family;
if ( ! fmt->Read(&family, "addr-family") )
return false;
switch ( family ) {
case 4:
val.addr_val.family = IPv4;
return fmt->Read(&val.addr_val.in.in4, "addr-in4");
case 6:
val.addr_val.family = IPv6;
return fmt->Read(&val.addr_val.in.in6, "addr-in6");
}
// Can't be reached.
abort();
}
case TYPE_SUBNET:
{
// FIXME.
}
case TYPE_DOUBLE:
@ -239,13 +248,27 @@ bool Value::Write(SerializationFormat* fmt) const
return fmt->Write(val.uint_val, "uint");
case TYPE_PORT:
return fmt->Write(val.port_val.port, "port") && fmt->Write(val.port_val.proto, "proto");
return fmt->Write(val.port_val.port, "port") && fmt->Write(val.port_val.proto, "proto");
case TYPE_SUBNET:
return fmt->Write(*val.subnet_val, "subnet");
return false; // FIXME.
case TYPE_ADDR:
return fmt->Write(*val.addr_val, "addr");
{
switch ( val.addr_val.family ) {
case IPv4:
return fmt->Write((int)4, "addr-family")
&& fmt->Write(val.addr_val.in.in4, "addr-in4");
case IPv6:
return fmt->Write((int)6, "addr-family")
&& fmt->Write(val.addr_val.in.in6, "addr-in6");
break;
}
// Can't be reached.
abort();
}
case TYPE_DOUBLE:
case TYPE_TIME:

View file

@ -2,10 +2,13 @@
#ifndef THREADING_SERIALIZATIONTYPES_H
#define THREADING_SERIALIZATIONTYPES_H
#include "../RemoteSerializer.h"
using namespace std;
#include "Type.h"
#include "net_util.h"
class SerializationFormat;
namespace threading {
/**
@ -62,6 +65,16 @@ struct Value {
typedef set_t vec_t;
struct port_t { bro_uint_t port; TransportProto proto; };
struct addr_t {
IPFamily family;
union {
struct in_addr in4;
struct in6_addr in6;
} in;
};
struct subnet_t { addr_t prefix; uint8_t length; };
/**
* This union is a subset of BroValUnion, including only the types we
* can log directly. See IsCompatibleType().
@ -73,8 +86,8 @@ struct Value {
double double_val;
set_t set_val;
vec_t vector_val;
IPAddr* addr_val;
IPPrefix* subnet_val;
addr_t addr_val;
subnet_t subnet_val;
string* string_val;
} val;
@ -120,6 +133,7 @@ struct Value {
static bool IsCompatibleType(BroType* t, bool atomic_only=false);
private:
friend class ::IPAddr;
Value(const Value& other) { } // Disabled.
};