Add new Tunnel::delay_teredo_confirmation option, default to true.

This option indicates that the Teredo analyzer should wait until
it sees both sides of a connection using a valid Teredo encapsulation
before issuing a protocol_confirmation.  Previous behavior confirmed
on the first instance of a valid encapsulation, which could result
in more false positives (and e.g. bogus entries in known-services.log).

Addresses #890.
This commit is contained in:
Jon Siwek 2012-10-02 15:13:38 -05:00
parent b4b7a384dc
commit 5f3af9e9eb
11 changed files with 87 additions and 30 deletions

View file

@ -138,6 +138,11 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
{
Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen);
if ( orig )
valid_orig = false;
else
valid_resp = false;
TeredoEncapsulation te(this);
if ( ! te.Parse(data, len) )
@ -150,7 +155,7 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
if ( e && e->Depth() >= BifConst::Tunnel::max_depth )
{
Weird("tunnel_depth");
Weird("tunnel_depth", true);
return;
}
@ -162,7 +167,7 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
if ( inner->NextProto() == IPPROTO_NONE && inner->PayloadLen() == 0 )
// Teredo bubbles having data after IPv6 header isn't strictly a
// violation, but a little weird.
Weird("Teredo_bubble_with_payload");
Weird("Teredo_bubble_with_payload", true);
else
{
delete inner;
@ -173,6 +178,11 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
if ( rslt == 0 || rslt > 0 )
{
if ( orig )
valid_orig = true;
else
valid_resp = true;
if ( BifConst::Tunnel::yielding_teredo_decapsulation &&
! ProtocolConfirmed() )
{
@ -193,7 +203,7 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
}
if ( ! sibling_has_confirmed )
ProtocolConfirmation();
Confirm();
else
{
delete inner;
@ -203,7 +213,7 @@ void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
else
{
// Aggressively decapsulate anything with valid Teredo encapsulation
ProtocolConfirmation();
Confirm();
}
}

View file

@ -6,7 +6,8 @@
class Teredo_Analyzer : public Analyzer {
public:
Teredo_Analyzer(Connection* conn) : Analyzer(AnalyzerTag::Teredo, conn)
Teredo_Analyzer(Connection* conn) : Analyzer(AnalyzerTag::Teredo, conn),
valid_orig(false), valid_resp(false)
{}
virtual ~Teredo_Analyzer()
@ -26,18 +27,34 @@ public:
/**
* Emits a weird only if the analyzer has previously been able to
* decapsulate a Teredo packet since otherwise the weirds could happen
* frequently enough to be less than helpful.
* decapsulate a Teredo packet in both directions or if *force* param is
* set, since otherwise the weirds could happen frequently enough to be less
* than helpful. The *force* param is meant for cases where just one side
* has a valid encapsulation and so the weird would be informative.
*/
void Weird(const char* name) const
void Weird(const char* name, bool force = false) const
{
if ( ProtocolConfirmed() )
if ( ProtocolConfirmed() || force )
reporter->Weird(Conn(), name);
}
/**
* If the delayed confirmation option is set, then a valid encapsulation
* seen from both end points is required before confirming
*/
void Confirm()
{
if ( ! BifConst::Tunnel::delay_teredo_confirmation ||
( valid_orig && valid_resp ) )
ProtocolConfirmation();
}
protected:
friend class AnalyzerTimer;
void ExpireTimer(double t);
bool valid_orig;
bool valid_resp;
};
class TeredoEncapsulation {

View file

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