diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 503bf2547c..3a57a65b20 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -2717,6 +2717,9 @@ export { ## reduce false positives of UDP traffic (e.g. DNS) that also happens ## to have a valid Teredo encapsulation. const yielding_teredo_decapsulation = T &redef; + + ## How often to cleanup internal state for inactive IP tunnels. + const ip_tunnel_timeout = 24hrs &redef; } # end export module GLOBAL; diff --git a/src/Sessions.cc b/src/Sessions.cc index b5d82f147f..84c881b0ef 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -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() { TypeList* t = new TypeList(); @@ -569,16 +587,20 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr, else 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() ) { 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); } else - outer->Add(it->second); + { + it->second.second = network_time; + outer->Add(it->second.first); + } DoNextInnerPacket(t, hdr, inner, outer); diff --git a/src/Sessions.h b/src/Sessions.h index ed7f56c878..548c0903be 100644 --- a/src/Sessions.h +++ b/src/Sessions.h @@ -181,6 +181,7 @@ protected: friend class RemoteSerializer; friend class ConnCompressor; friend class TimerMgrExpireTimer; + friend class IPTunnelTimer; Connection* NewConn(HashKey* k, double t, const ConnID* id, const u_char* data, int proto, uint32 flow_lable, @@ -240,8 +241,10 @@ protected: PDict(Connection) udp_conns; PDict(Connection) icmp_conns; PDict(FragReassembler) fragments; + typedef pair IPPair; - typedef std::map IPTunnelMap; + typedef pair TunnelActivity; + typedef std::map IPTunnelMap; IPTunnelMap ip_tunnels; ARP_Analyzer* arp_analyzer; @@ -261,6 +264,21 @@ protected: 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. extern NetSessions* sessions; diff --git a/src/Timer.cc b/src/Timer.cc index 2e2fb09c6b..c2a8bb3421 100644 --- a/src/Timer.cc +++ b/src/Timer.cc @@ -20,6 +20,7 @@ const char* TimerNames[] = { "IncrementalSendTimer", "IncrementalWriteTimer", "InterconnTimer", + "IPTunnelInactivityTimer", "NetbiosExpireTimer", "NetworkTimer", "NTPExpireTimer", diff --git a/src/Timer.h b/src/Timer.h index bb6b8d56ae..310e72bdc9 100644 --- a/src/Timer.h +++ b/src/Timer.h @@ -26,6 +26,7 @@ enum TimerType { TIMER_INCREMENTAL_SEND, TIMER_INCREMENTAL_WRITE, TIMER_INTERCONN, + TIMER_IP_TUNNEL_INACTIVITY, TIMER_NB_EXPIRE, TIMER_NETWORK, TIMER_NTP_EXPIRE, diff --git a/src/const.bif b/src/const.bif index 368ee34396..499dc63314 100644 --- a/src/const.bif +++ b/src/const.bif @@ -16,5 +16,6 @@ const Tunnel::enable_ip: bool; const Tunnel::enable_ayiya: bool; const Tunnel::enable_teredo: bool; const Tunnel::yielding_teredo_decapsulation: bool; +const Tunnel::ip_tunnel_timeout: interval; const Threading::heartbeat_interval: interval;