From da338c8ffebf154cc57885d57039ced2f683defd Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 10 Mar 2014 16:51:04 -0500 Subject: [PATCH] Teach async DNS lookup builtin-functions about BRO_DNS_FAKE. And enable fake DNS mode for test suites. Addresses BIT-1134. --- src/DNS_Mgr.cc | 76 +++++++++++++++++++----- src/DNS_Mgr.h | 13 ++-- testing/btest/Baseline/core.fake_dns/out | 10 ++++ testing/btest/btest.cfg | 1 + testing/btest/core/fake_dns.bro | 41 +++++++++++++ testing/btest/language/timeout.bro | 2 +- testing/external/subdir-btest.cfg | 1 + 7 files changed, 123 insertions(+), 21 deletions(-) create mode 100644 testing/btest/Baseline/core.fake_dns/out create mode 100644 testing/btest/core/fake_dns.bro diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index 17409a930b..636a03e5a0 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -443,6 +443,20 @@ bool DNS_Mgr::Init() return true; } +TableVal* DNS_Mgr::BuildFakeAddrResult() + { + ListVal* hv = new ListVal(TYPE_ADDR); + hv->Append(new AddrVal(++dns_fake_count)); + return hv->ConvertToSet(); + } + +const char* DNS_Mgr::BuildFakeNameResult() + { + static char tmp[32]; + snprintf(tmp, sizeof(tmp), "fake_result_%"PRIu32, ++dns_fake_count); + return tmp; + } + TableVal* DNS_Mgr::LookupHost(const char* name) { if ( ! nb_dns ) @@ -452,11 +466,7 @@ TableVal* DNS_Mgr::LookupHost(const char* name) Init(); if ( mode == DNS_FAKE ) - { - ListVal* hv = new ListVal(TYPE_ADDR); - hv->Append(new AddrVal(uint32(++dns_fake_count))); - return hv->ConvertToSet(); - } + return BuildFakeAddrResult(); if ( mode != DNS_PRIME ) { @@ -960,7 +970,7 @@ const char* DNS_Mgr::LookupAddrInCache(const IPAddr& addr) return d->names ? d->names[0] : "<\?\?\?>"; } -TableVal* DNS_Mgr::LookupNameInCache(string name) +TableVal* DNS_Mgr::LookupNameInCache(const string& name) { HostMap::iterator it = host_mappings.find(name); if ( it == host_mappings.end() ) @@ -990,7 +1000,7 @@ TableVal* DNS_Mgr::LookupNameInCache(string name) return tv6; } -const char* DNS_Mgr::LookupTextInCache(string name) +const char* DNS_Mgr::LookupTextInCache(const string& name) { TextMap::iterator it = text_mappings.find(name); if ( it == text_mappings.end() ) @@ -1010,17 +1020,37 @@ const char* DNS_Mgr::LookupTextInCache(string name) return d->names ? d->names[0] : "<\?\?\?>"; } +static void resolve_lookup_cb(DNS_Mgr::LookupCallback* callback, + TableVal* result) + { + callback->Resolved(result); + Unref(result); + delete callback; + } + +static void resolve_lookup_cb(DNS_Mgr::LookupCallback* callback, + const char* result) + { + callback->Resolved(result); + delete callback; + } + void DNS_Mgr::AsyncLookupAddr(const IPAddr& host, LookupCallback* callback) { if ( ! did_init ) Init(); + if ( mode == DNS_FAKE ) + { + resolve_lookup_cb(callback, BuildFakeNameResult()); + return; + } + // Do we already know the answer? const char* name = LookupAddrInCache(host); if ( name ) { - callback->Resolved(name); - delete callback; + resolve_lookup_cb(callback, name); return; } @@ -1044,18 +1074,22 @@ void DNS_Mgr::AsyncLookupAddr(const IPAddr& host, LookupCallback* callback) IssueAsyncRequests(); } -void DNS_Mgr::AsyncLookupName(string name, LookupCallback* callback) +void DNS_Mgr::AsyncLookupName(const string& name, LookupCallback* callback) { if ( ! did_init ) Init(); + if ( mode == DNS_FAKE ) + { + resolve_lookup_cb(callback, BuildFakeAddrResult()); + return; + } + // Do we already know the answer? TableVal* addrs = LookupNameInCache(name); if ( addrs ) { - callback->Resolved(addrs); - Unref(addrs); - delete callback; + resolve_lookup_cb(callback, addrs); return; } @@ -1079,13 +1113,25 @@ void DNS_Mgr::AsyncLookupName(string name, LookupCallback* callback) IssueAsyncRequests(); } -void DNS_Mgr::AsyncLookupNameText(string name, LookupCallback* callback) +void DNS_Mgr::AsyncLookupNameText(const string& name, LookupCallback* callback) { if ( ! did_init ) Init(); + if ( mode == DNS_FAKE ) + { + resolve_lookup_cb(callback, BuildFakeNameResult()); + return; + } + // Do we already know the answer? - TableVal* addrs; + const char* txt = LookupTextInCache(name); + + if ( txt ) + { + resolve_lookup_cb(callback, txt); + return; + } AsyncRequest* req = 0; diff --git a/src/DNS_Mgr.h b/src/DNS_Mgr.h index bfcc70a5c2..ccace3303e 100644 --- a/src/DNS_Mgr.h +++ b/src/DNS_Mgr.h @@ -62,8 +62,8 @@ public: int Save(); const char* LookupAddrInCache(const IPAddr& addr); - TableVal* LookupNameInCache(string name); - const char* LookupTextInCache(string name); + TableVal* LookupNameInCache(const string& name); + const char* LookupTextInCache(const string& name); // Support for async lookups. class LookupCallback { @@ -77,8 +77,8 @@ public: }; void AsyncLookupAddr(const IPAddr& host, LookupCallback* callback); - void AsyncLookupName(string name, LookupCallback* callback); - void AsyncLookupNameText(string name, LookupCallback* callback); + void AsyncLookupName(const string& name, LookupCallback* callback); + void AsyncLookupNameText(const string& name, LookupCallback* callback); struct Stats { unsigned long requests; // These count only async requests. @@ -102,6 +102,9 @@ protected: Val* BuildMappingVal(DNS_Mapping* dm); + TableVal* BuildFakeAddrResult(); + const char* BuildFakeNameResult(); + void AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r); void CompareMappings(DNS_Mapping* prev_dm, DNS_Mapping* new_dm); ListVal* AddrListDelta(ListVal* al1, ListVal* al2); @@ -163,7 +166,7 @@ protected: RecordType* dm_rec; - int dns_fake_count; // used to generate unique fake replies + uint32 dns_fake_count; // used to generate unique fake replies typedef list CallbackList; diff --git a/testing/btest/Baseline/core.fake_dns/out b/testing/btest/Baseline/core.fake_dns/out new file mode 100644 index 0000000000..5e1e72301d --- /dev/null +++ b/testing/btest/Baseline/core.fake_dns/out @@ -0,0 +1,10 @@ +{ +3.0.0.0, +2.0.0.0, +1.0.0.0 +} +lookup_hostname_txt, fake_result_4 +lookup_hostname, { +5.0.0.0 +} +lookup_addr, fake_result_6 diff --git a/testing/btest/btest.cfg b/testing/btest/btest.cfg index 39b64f7c09..0130cb6e1d 100644 --- a/testing/btest/btest.cfg +++ b/testing/btest/btest.cfg @@ -24,3 +24,4 @@ TEST_DIFF_CANONIFIER=%(testbase)s/../scripts/diff-canonifier TMPDIR=%(testbase)s/.tmp BRO_PROFILER_FILE=%(testbase)s/.tmp/script-coverage.XXXXXX BTEST_RST_FILTER=$SCRIPTS/rst-filter +BRO_DNS_FAKE=1 diff --git a/testing/btest/core/fake_dns.bro b/testing/btest/core/fake_dns.bro new file mode 100644 index 0000000000..f4d8c46777 --- /dev/null +++ b/testing/btest/core/fake_dns.bro @@ -0,0 +1,41 @@ +# @TEST-EXEC: BRO_DNS_FAKE=1 bro -b %INPUT >out +# @TEST-EXEC: btest-diff out + +redef exit_only_after_terminate = T; + +global addrs: set[addr] = { + google.com, + bing.com, + yahoo.com +}; + +global c: count = 0; + +function check_terminate() + { + ++c; + + if ( c > 2 ) + terminate(); + } + +event bro_init() + { + print addrs; + + when ( local result = lookup_hostname_txt("bro.wp.dg.cx") ) + { + print "lookup_hostname_txt", result; + check_terminate(); + } + when ( local result2 = lookup_hostname("example.com") ) + { + print "lookup_hostname", result2; + check_terminate(); + } + when ( local result3 = lookup_addr(1.2.3.4) ) + { + print "lookup_addr", result3; + check_terminate(); + } + } diff --git a/testing/btest/language/timeout.bro b/testing/btest/language/timeout.bro index b16ddd6e7c..632ab18b5f 100644 --- a/testing/btest/language/timeout.bro +++ b/testing/btest/language/timeout.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro -b %INPUT >out +# @TEST-EXEC: unset BRO_DNS_FAKE && bro -b %INPUT >out # @TEST-EXEC: btest-diff out diff --git a/testing/external/subdir-btest.cfg b/testing/external/subdir-btest.cfg index fb5873418a..f68849314e 100644 --- a/testing/external/subdir-btest.cfg +++ b/testing/external/subdir-btest.cfg @@ -19,3 +19,4 @@ SCRIPTS=%(testbase)s/../scripts DIST=%(testbase)s/../../.. BUILD=%(testbase)s/../../../build BRO_PROFILER_FILE=%(testbase)s/.tmp/script-coverage.XXXXXX +BRO_DNS_FAKE=1