Tunnel decapsulation bugfix when FlipRoles is called.

If FlipRoles() is called the conn_val in Conn.cc gets Unref'ed and thus
my tunnel_partent RecordVal was lost. Fixing this.
This commit is contained in:
Gregor Maier 2011-08-16 20:41:36 -07:00
parent ae1eb5379b
commit 08dc84a250
5 changed files with 64 additions and 37 deletions

View file

@ -15,6 +15,7 @@
#include "Timer.h"
#include "PIA.h"
#include "binpac.h"
#include "TunnelHandler.h"
HashKey* ConnID::BuildConnKey() const
{
@ -139,7 +140,7 @@ unsigned int Connection::external_connections = 0;
IMPLEMENT_SERIAL(Connection, SER_CONNECTION);
Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, RecordVal *arg_tunnel_parent)
Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, TunnelParent* arg_tunnel_parent)
{
sessions = s;
key = k;
@ -209,6 +210,9 @@ Connection::~Connection()
Unref(conn_val);
}
if ( tunnel_parent )
delete tunnel_parent;
delete key;
delete root_analyzer;
delete conn_timer_mgr;
@ -372,7 +376,8 @@ RecordVal* Connection::BuildConnVal()
char tmp[20];
conn_val->Assign(9, new StringVal(uitoa_n(uid, tmp, sizeof(tmp), 62)));
conn_val->Assign(10, tunnel_parent);
if ( tunnel_parent )
conn_val->Assign(10, tunnel_parent->GetRecordVal());
}
if ( root_analyzer )

View file

@ -23,6 +23,7 @@ class RuleHdrTest;
class Specific_RE_Matcher;
class TransportLayerAnalyzer;
class RuleEndpointState;
class TunnelParent;
typedef enum {
NUL_IN_LINE,
@ -86,7 +87,7 @@ class Analyzer;
class Connection : public BroObj {
public:
Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, RecordVal *arg_tunnel_parent);
Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, TunnelParent *arg_tunnel_parent);
virtual ~Connection();
// Invoked when connection is about to be removed. Use Ref(this)
@ -335,7 +336,7 @@ protected:
double inactivity_timeout;
RecordVal* conn_val;
LoginConn* login_conn; // either nil, or this
RecordVal* tunnel_parent; // nil if not tunneled
TunnelParent* tunnel_parent; // nil if not tunneled
int suppress_event; // suppress certain events to once per conn.
unsigned int installed_status_timer:1;

View file

@ -1018,10 +1018,7 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
int src_h = ntohs(id->src_port);
int dst_h = ntohs(id->dst_port);
int flags = 0;
RecordVal *tunnel_parent = 0;
if ( tunnel_info )
tunnel_parent = tunnel_info->GetRecordVal();
TunnelParent *tunnel_parent = 0;
// Hmm... This is not great.
TransportProto tproto;
@ -1068,6 +1065,9 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
id = &flip_id;
}
if ( tunnel_info )
tunnel_parent = new TunnelParent(&(tunnel_info->parent));
Connection* conn = new Connection(this, k, t, id, tunnel_parent);
conn->SetTransport(tproto);
dpm->BuildInitialAnalyzerTree(tproto, conn, data);

View file

@ -54,7 +54,7 @@ TunnelInfo* TunnelHandler::DecapsulateTunnel(const IP_Hdr *ip_hdr, int len, int
// TODO: check if IP6 header makes sense
tunnel_info = new TunnelInfo();
tunnel_info->child = new IP_Hdr((const struct ip6_hdr*)ip_hdr->Payload());
tunnel_info->tunneltype = BifEnum::Tunnel::IP6_IN_IP;
tunnel_info->parent.tunneltype = BifEnum::Tunnel::IP6_IN_IP;
tunnel_info->hdr_len = tunnel_info->child->HdrLen();
tunnel_info->SetParentIPs(ip_hdr);
return tunnel_info;
@ -137,7 +137,7 @@ TunnelInfo* TunnelHandler::HandleUDP(const IP_Hdr *ip_hdr, int len, int caplen)
{
TunnelInfo *tunnel_info = new TunnelInfo();
tunnel_info->child = cand_ip_hdr;
tunnel_info->tunneltype = tunneltype;
tunnel_info->parent.tunneltype = tunneltype;
tunnel_info->SetParentIPs(ip_hdr);
tunnel_info->SetParentPorts(uh);
tunnel_info->hdr_len = hdr_len + cand_ip_hdr->HdrLen();

View file

@ -4,37 +4,29 @@
#define tunnelhandler_h
#include <netinet/udp.h>
#include "net_util.h"
#include "IP.h"
#include "Conn.h"
#include "Sessions.h"
#include "Val.h"
class TunnelInfo {
class TunnelParent {
public:
TunnelInfo()
TunnelParent()
{
child = 0;
tunneltype = BifEnum::Tunnel::NONE;
hdr_len = 0;
parent.src_addr = parent.dst_addr = 0;
parent.src_port = parent.dst_port = 0;
parent.is_one_way = 0;
}
~TunnelInfo()
{
if (child) delete child;
src_port = dst_port = 0;
for (int i=0; i<NUM_ADDR_WORDS; i++)
src_addr[i] = dst_addr[i] = 0;
}
void SetParentIPs(const IP_Hdr *ip_hdr)
TunnelParent (TunnelParent *other)
{
parent.src_addr = ip_hdr->SrcAddr();
parent.dst_addr = ip_hdr->DstAddr();
}
void SetParentPorts(const struct udphdr *uh)
{
parent.src_port = uh->uh_sport;
parent.dst_port = uh->uh_dport;
tunneltype = other->tunneltype;
copy_addr(other->src_addr, src_addr);
copy_addr(other->dst_addr, dst_addr);
src_port = other->src_port;
dst_port = other->dst_port;
}
RecordVal* GetRecordVal() const
@ -51,21 +43,50 @@ public:
} // end switch
RecordVal* id_val = new RecordVal(conn_id);
id_val->Assign(0, new AddrVal(parent.src_addr));
id_val->Assign(1, new PortVal(ntohs(parent.src_port), tproto));
id_val->Assign(2, new AddrVal(parent.dst_addr));
id_val->Assign(3, new PortVal(ntohs(parent.dst_port), tproto));
id_val->Assign(0, new AddrVal(src_addr));
id_val->Assign(1, new PortVal(ntohs(src_port), tproto));
id_val->Assign(2, new AddrVal(dst_addr));
id_val->Assign(3, new PortVal(ntohs(dst_port), tproto));
rv->Assign(0, id_val);
rv->Assign(1, new EnumVal(tunneltype, BifType::Enum::Tunnel::Tunneltype));
return rv;
}
IP_Hdr *child;
ConnID parent;
int hdr_len;
uint32 src_addr[NUM_ADDR_WORDS];
uint32 dst_addr[NUM_ADDR_WORDS];
uint16 src_port;
uint16 dst_port;
BifEnum::Tunnel::Tunneltype tunneltype;
};
class TunnelInfo {
public:
TunnelInfo()
{
child = 0;
hdr_len = 0;
}
~TunnelInfo()
{
if (child) delete child;
}
void SetParentIPs(const IP_Hdr *ip_hdr)
{
copy_addr(ip_hdr->SrcAddr(), parent.src_addr);
copy_addr(ip_hdr->DstAddr(), parent.dst_addr);
}
void SetParentPorts(const struct udphdr *uh)
{
parent.src_port = uh->uh_sport;
parent.dst_port = uh->uh_dport;
}
IP_Hdr *child;
TunnelParent parent;
int hdr_len;
};
class TunnelHandler {
public:
TunnelHandler(NetSessions *arg_s);