Add state management of NetSessions's IP tunnel map.

Entries are checked for inactivity at an interval controlled by
"Tunnel::ip_tunnel_timeout" and discarded if needed.
This commit is contained in:
Jon Siwek 2012-06-18 15:44:34 -05:00
parent 2ba3f5420b
commit e04d629733
6 changed files with 50 additions and 4 deletions

View file

@ -2717,6 +2717,9 @@ export {
## reduce false positives of UDP traffic (e.g. DNS) that also happens ## reduce false positives of UDP traffic (e.g. DNS) that also happens
## to have a valid Teredo encapsulation. ## to have a valid Teredo encapsulation.
const yielding_teredo_decapsulation = T &redef; const yielding_teredo_decapsulation = T &redef;
## How often to cleanup internal state for inactive IP tunnels.
const ip_tunnel_timeout = 24hrs &redef;
} # end export } # end export
module GLOBAL; module GLOBAL;

View file

@ -68,6 +68,24 @@ void TimerMgrExpireTimer::Dispatch(double t, int is_expire)
} }
} }
void IPTunnelTimer::Dispatch(double t, int is_expire)
{
NetSessions::IPTunnelMap::const_iterator it =
sessions->ip_tunnels.find(tunnel_idx);
if ( it == sessions->ip_tunnels.end() ) return;
double last_active = it->second.second;
double inactive_time = t > last_active ? t - last_active : 0;
if ( inactive_time >= BifConst::Tunnel::ip_tunnel_timeout )
// tunnel activity timed out, delete it from map
sessions->ip_tunnels.erase(tunnel_idx);
else if ( ! is_expire )
// tunnel activity didn't timeout, schedule another timer
timer_mgr->Add(new IPTunnelTimer(t, tunnel_idx));
}
NetSessions::NetSessions() NetSessions::NetSessions()
{ {
TypeList* t = new TypeList(); TypeList* t = new TypeList();
@ -569,16 +587,20 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
else else
tunnel_idx = IPPair(ip_hdr->DstAddr(), ip_hdr->SrcAddr()); tunnel_idx = IPPair(ip_hdr->DstAddr(), ip_hdr->SrcAddr());
IPTunnelMap::const_iterator it = ip_tunnels.find(tunnel_idx); IPTunnelMap::iterator it = ip_tunnels.find(tunnel_idx);
if ( it == ip_tunnels.end() ) if ( it == ip_tunnels.end() )
{ {
EncapsulatingConn ec(ip_hdr->SrcAddr(), ip_hdr->DstAddr()); EncapsulatingConn ec(ip_hdr->SrcAddr(), ip_hdr->DstAddr());
ip_tunnels[tunnel_idx] = ec; ip_tunnels[tunnel_idx] = TunnelActivity(ec, network_time);
timer_mgr->Add(new IPTunnelTimer(network_time, tunnel_idx));
outer->Add(ec); outer->Add(ec);
} }
else else
outer->Add(it->second); {
it->second.second = network_time;
outer->Add(it->second.first);
}
DoNextInnerPacket(t, hdr, inner, outer); DoNextInnerPacket(t, hdr, inner, outer);

View file

@ -181,6 +181,7 @@ protected:
friend class RemoteSerializer; friend class RemoteSerializer;
friend class ConnCompressor; friend class ConnCompressor;
friend class TimerMgrExpireTimer; friend class TimerMgrExpireTimer;
friend class IPTunnelTimer;
Connection* NewConn(HashKey* k, double t, const ConnID* id, Connection* NewConn(HashKey* k, double t, const ConnID* id,
const u_char* data, int proto, uint32 flow_lable, const u_char* data, int proto, uint32 flow_lable,
@ -240,8 +241,10 @@ protected:
PDict(Connection) udp_conns; PDict(Connection) udp_conns;
PDict(Connection) icmp_conns; PDict(Connection) icmp_conns;
PDict(FragReassembler) fragments; PDict(FragReassembler) fragments;
typedef pair<IPAddr, IPAddr> IPPair; typedef pair<IPAddr, IPAddr> IPPair;
typedef std::map<IPPair, EncapsulatingConn> IPTunnelMap; typedef pair<EncapsulatingConn, double> TunnelActivity;
typedef std::map<IPPair, TunnelActivity> IPTunnelMap;
IPTunnelMap ip_tunnels; IPTunnelMap ip_tunnels;
ARP_Analyzer* arp_analyzer; ARP_Analyzer* arp_analyzer;
@ -261,6 +264,21 @@ protected:
TimerMgrMap timer_mgrs; TimerMgrMap timer_mgrs;
}; };
class IPTunnelTimer : public Timer {
public:
IPTunnelTimer(double t, NetSessions::IPPair p)
: Timer(t + BifConst::Tunnel::ip_tunnel_timeout,
TIMER_IP_TUNNEL_INACTIVITY), tunnel_idx(p) {}
~IPTunnelTimer() {}
void Dispatch(double t, int is_expire);
protected:
NetSessions::IPPair tunnel_idx;
};
// Manager for the currently active sessions. // Manager for the currently active sessions.
extern NetSessions* sessions; extern NetSessions* sessions;

View file

@ -20,6 +20,7 @@ const char* TimerNames[] = {
"IncrementalSendTimer", "IncrementalSendTimer",
"IncrementalWriteTimer", "IncrementalWriteTimer",
"InterconnTimer", "InterconnTimer",
"IPTunnelInactivityTimer",
"NetbiosExpireTimer", "NetbiosExpireTimer",
"NetworkTimer", "NetworkTimer",
"NTPExpireTimer", "NTPExpireTimer",

View file

@ -26,6 +26,7 @@ enum TimerType {
TIMER_INCREMENTAL_SEND, TIMER_INCREMENTAL_SEND,
TIMER_INCREMENTAL_WRITE, TIMER_INCREMENTAL_WRITE,
TIMER_INTERCONN, TIMER_INTERCONN,
TIMER_IP_TUNNEL_INACTIVITY,
TIMER_NB_EXPIRE, TIMER_NB_EXPIRE,
TIMER_NETWORK, TIMER_NETWORK,
TIMER_NTP_EXPIRE, TIMER_NTP_EXPIRE,

View file

@ -16,5 +16,6 @@ const Tunnel::enable_ip: bool;
const Tunnel::enable_ayiya: bool; const Tunnel::enable_ayiya: bool;
const Tunnel::enable_teredo: bool; const Tunnel::enable_teredo: bool;
const Tunnel::yielding_teredo_decapsulation: bool; const Tunnel::yielding_teredo_decapsulation: bool;
const Tunnel::ip_tunnel_timeout: interval;
const Threading::heartbeat_interval: interval; const Threading::heartbeat_interval: interval;