mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 15:48:19 +00:00
Merge remote-tracking branch 'vlad/topic/vladg/dns_txt_queries'
* vlad/topic/vladg/dns_txt_queries: DNS TXT support I've tweaked it a little bit, still seems to work ... I'd like to add a test for this but I'n not quite sure how to do that. We'd have to hardcode a destination server that then'd be contacted each time the test-suite runs.
This commit is contained in:
commit
dfebb82238
7 changed files with 216 additions and 56 deletions
5
CHANGES
5
CHANGES
|
@ -1,4 +1,9 @@
|
||||||
|
|
||||||
|
2.1-104 | 2012-11-01 10:37:50 -0700
|
||||||
|
|
||||||
|
* A new built-in function lookup_hostname_txt() provides support for
|
||||||
|
DNS TXT queries. (Vlad Grigorescu)
|
||||||
|
|
||||||
2.1-101 | 2012-10-31 14:30:26 -0700
|
2.1-101 | 2012-10-31 14:30:26 -0700
|
||||||
|
|
||||||
* Documentation reorg: The install info has been consolidated into a
|
* Documentation reorg: The install info has been consolidated into a
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
2.1-101
|
2.1-104
|
||||||
|
|
176
src/DNS_Mgr.cc
176
src/DNS_Mgr.cc
|
@ -46,13 +46,15 @@ extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
|
||||||
|
|
||||||
class DNS_Mgr_Request {
|
class DNS_Mgr_Request {
|
||||||
public:
|
public:
|
||||||
DNS_Mgr_Request(const char* h, int af) { host = copy_string(h); fam = af; }
|
DNS_Mgr_Request(const char* h, int af, bool is_txt)
|
||||||
|
{ host = copy_string(h); fam = af; qtype = is_txt ? 16 : 0; }
|
||||||
DNS_Mgr_Request(const IPAddr& a) { addr = a; host = 0; fam = 0; }
|
DNS_Mgr_Request(const IPAddr& a) { addr = a; host = 0; fam = 0; }
|
||||||
~DNS_Mgr_Request() { delete [] host; }
|
~DNS_Mgr_Request() { delete [] host; }
|
||||||
|
|
||||||
// Returns nil if this was an address request.
|
// Returns nil if this was an address request.
|
||||||
const char* ReqHost() const { return host; }
|
const char* ReqHost() const { return host; }
|
||||||
const IPAddr& ReqAddr() const { return addr; }
|
const IPAddr& ReqAddr() const { return addr; }
|
||||||
|
const bool ReqIsTxt() const { return qtype == 16; }
|
||||||
|
|
||||||
int MakeRequest(nb_dns_info* nb_dns);
|
int MakeRequest(nb_dns_info* nb_dns);
|
||||||
int RequestPending() const { return request_pending; }
|
int RequestPending() const { return request_pending; }
|
||||||
|
@ -61,7 +63,8 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
char* host; // if non-nil, this is a host request
|
char* host; // if non-nil, this is a host request
|
||||||
int fam; // address family query type for host requests
|
int fam; // address family query type for host requests
|
||||||
|
int qtype; // Query type
|
||||||
IPAddr addr;
|
IPAddr addr;
|
||||||
int request_pending;
|
int request_pending;
|
||||||
};
|
};
|
||||||
|
@ -75,7 +78,7 @@ int DNS_Mgr_Request::MakeRequest(nb_dns_info* nb_dns)
|
||||||
|
|
||||||
char err[NB_DNS_ERRSIZE];
|
char err[NB_DNS_ERRSIZE];
|
||||||
if ( host )
|
if ( host )
|
||||||
return nb_dns_host_request2(nb_dns, host, fam, (void*) this, err) >= 0;
|
return nb_dns_host_request2(nb_dns, host, fam, qtype, (void*) this, err) >= 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const uint32* bytes;
|
const uint32* bytes;
|
||||||
|
@ -475,8 +478,8 @@ TableVal* DNS_Mgr::LookupHost(const char* name)
|
||||||
// Not found, or priming.
|
// Not found, or priming.
|
||||||
switch ( mode ) {
|
switch ( mode ) {
|
||||||
case DNS_PRIME:
|
case DNS_PRIME:
|
||||||
requests.append(new DNS_Mgr_Request(name, AF_INET));
|
requests.append(new DNS_Mgr_Request(name, AF_INET, false));
|
||||||
requests.append(new DNS_Mgr_Request(name, AF_INET6));
|
requests.append(new DNS_Mgr_Request(name, AF_INET6, false));
|
||||||
return empty_addr_set();
|
return empty_addr_set();
|
||||||
|
|
||||||
case DNS_FORCE:
|
case DNS_FORCE:
|
||||||
|
@ -484,8 +487,8 @@ TableVal* DNS_Mgr::LookupHost(const char* name)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case DNS_DEFAULT:
|
case DNS_DEFAULT:
|
||||||
requests.append(new DNS_Mgr_Request(name, AF_INET));
|
requests.append(new DNS_Mgr_Request(name, AF_INET, false));
|
||||||
requests.append(new DNS_Mgr_Request(name, AF_INET6));
|
requests.append(new DNS_Mgr_Request(name, AF_INET6, false));
|
||||||
Resolve();
|
Resolve();
|
||||||
return LookupHost(name);
|
return LookupHost(name);
|
||||||
|
|
||||||
|
@ -636,6 +639,7 @@ int DNS_Mgr::Save()
|
||||||
|
|
||||||
Save(f, host_mappings);
|
Save(f, host_mappings);
|
||||||
Save(f, addr_mappings);
|
Save(f, addr_mappings);
|
||||||
|
// Save(f, text_mappings); // We don't save the TXT mappings (yet?).
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
|
@ -704,39 +708,48 @@ void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r)
|
||||||
new_dm = new DNS_Mapping(dr->ReqHost(), h, ttl);
|
new_dm = new DNS_Mapping(dr->ReqHost(), h, ttl);
|
||||||
prev_dm = 0;
|
prev_dm = 0;
|
||||||
|
|
||||||
HostMap::iterator it = host_mappings.find(dr->ReqHost());
|
if ( dr->ReqIsTxt() )
|
||||||
if ( it == host_mappings.end() )
|
|
||||||
{
|
{
|
||||||
host_mappings[dr->ReqHost()].first =
|
TextMap::iterator it = text_mappings.find(dr->ReqHost());
|
||||||
new_dm->Type() == AF_INET ? new_dm : 0;
|
if ( it == text_mappings.end() )
|
||||||
host_mappings[dr->ReqHost()].second =
|
text_mappings[dr->ReqHost()] = new_dm;
|
||||||
new_dm->Type() == AF_INET ? 0 : new_dm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( new_dm->Type() == AF_INET )
|
HostMap::iterator it = host_mappings.find(dr->ReqHost());
|
||||||
|
if ( it == host_mappings.end() )
|
||||||
{
|
{
|
||||||
prev_dm = it->second.first;
|
host_mappings[dr->ReqHost()].first =
|
||||||
it->second.first = new_dm;
|
new_dm->Type() == AF_INET ? new_dm : 0;
|
||||||
|
|
||||||
|
host_mappings[dr->ReqHost()].second =
|
||||||
|
new_dm->Type() == AF_INET ? 0 : new_dm;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prev_dm = it->second.second;
|
if ( new_dm->Type() == AF_INET )
|
||||||
it->second.second = new_dm;
|
{
|
||||||
|
prev_dm = it->second.first;
|
||||||
|
it->second.first = new_dm;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prev_dm = it->second.second;
|
||||||
|
it->second.second = new_dm;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ( new_dm->Failed() && prev_dm && prev_dm->Valid() )
|
if ( new_dm->Failed() && prev_dm && prev_dm->Valid() )
|
||||||
{
|
{
|
||||||
// Put previous, valid entry back - CompareMappings
|
// Put previous, valid entry back - CompareMappings
|
||||||
// will generate a corresponding warning.
|
// will generate a corresponding warning.
|
||||||
if ( prev_dm->Type() == AF_INET )
|
if ( prev_dm->Type() == AF_INET )
|
||||||
host_mappings[dr->ReqHost()].first = prev_dm;
|
host_mappings[dr->ReqHost()].first = prev_dm;
|
||||||
else
|
else
|
||||||
host_mappings[dr->ReqHost()].second = prev_dm;
|
host_mappings[dr->ReqHost()].second = prev_dm;
|
||||||
|
|
||||||
++keep_prev;
|
++keep_prev;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -928,7 +941,10 @@ TableVal* DNS_Mgr::LookupNameInCache(string name)
|
||||||
{
|
{
|
||||||
HostMap::iterator it = dns_mgr->host_mappings.find(name);
|
HostMap::iterator it = dns_mgr->host_mappings.find(name);
|
||||||
if ( it == dns_mgr->host_mappings.end() )
|
if ( it == dns_mgr->host_mappings.end() )
|
||||||
|
{
|
||||||
|
it = dns_mgr->host_mappings.begin();
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
DNS_Mapping* d4 = it->second.first;
|
DNS_Mapping* d4 = it->second.first;
|
||||||
DNS_Mapping* d6 = it->second.second;
|
DNS_Mapping* d6 = it->second.second;
|
||||||
|
@ -951,6 +967,26 @@ TableVal* DNS_Mgr::LookupNameInCache(string name)
|
||||||
return tv6;
|
return tv6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* DNS_Mgr::LookupTextInCache(string name)
|
||||||
|
{
|
||||||
|
TextMap::iterator it = dns_mgr->text_mappings.find(name);
|
||||||
|
if ( it == dns_mgr->text_mappings.end() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
DNS_Mapping* d = it->second;
|
||||||
|
|
||||||
|
if ( d->Expired() )
|
||||||
|
{
|
||||||
|
dns_mgr->text_mappings.erase(it);
|
||||||
|
delete d;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The escapes in the following strings are to avoid having it
|
||||||
|
// interpreted as a trigraph sequence.
|
||||||
|
return d->names ? d->names[0] : "<\?\?\?>";
|
||||||
|
}
|
||||||
|
|
||||||
void DNS_Mgr::AsyncLookupAddr(const IPAddr& host, LookupCallback* callback)
|
void DNS_Mgr::AsyncLookupAddr(const IPAddr& host, LookupCallback* callback)
|
||||||
{
|
{
|
||||||
if ( ! did_init )
|
if ( ! did_init )
|
||||||
|
@ -976,6 +1012,7 @@ void DNS_Mgr::AsyncLookupAddr(const IPAddr& host, LookupCallback* callback)
|
||||||
// A new one.
|
// A new one.
|
||||||
req = new AsyncRequest;
|
req = new AsyncRequest;
|
||||||
req->host = host;
|
req->host = host;
|
||||||
|
req->is_txt = false;
|
||||||
asyncs_queued.push_back(req);
|
asyncs_queued.push_back(req);
|
||||||
asyncs_addrs.insert(AsyncRequestAddrMap::value_type(host, req));
|
asyncs_addrs.insert(AsyncRequestAddrMap::value_type(host, req));
|
||||||
}
|
}
|
||||||
|
@ -985,19 +1022,36 @@ void DNS_Mgr::AsyncLookupAddr(const IPAddr& host, LookupCallback* callback)
|
||||||
IssueAsyncRequests();
|
IssueAsyncRequests();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DNS_Mgr::AsyncLookupName(string name, LookupCallback* callback)
|
void DNS_Mgr::AsyncLookupName(string name, LookupCallback* callback, bool is_txt)
|
||||||
{
|
{
|
||||||
if ( ! did_init )
|
if ( ! did_init )
|
||||||
Init();
|
Init();
|
||||||
|
|
||||||
// Do we already know the answer?
|
// Do we already know the answer?
|
||||||
TableVal* addrs = LookupNameInCache(name);
|
|
||||||
if ( addrs )
|
if ( is_txt )
|
||||||
{
|
{
|
||||||
callback->Resolved(addrs);
|
const char* text = LookupTextInCache(name);
|
||||||
Unref(addrs);
|
|
||||||
delete callback;
|
if ( text )
|
||||||
return;
|
{
|
||||||
|
callback->Resolved(text);
|
||||||
|
delete callback;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TableVal* addrs = LookupNameInCache(name);
|
||||||
|
|
||||||
|
if ( addrs )
|
||||||
|
{
|
||||||
|
callback->Resolved(addrs);
|
||||||
|
Unref(addrs);
|
||||||
|
delete callback;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncRequest* req = 0;
|
AsyncRequest* req = 0;
|
||||||
|
@ -1011,6 +1065,7 @@ void DNS_Mgr::AsyncLookupName(string name, LookupCallback* callback)
|
||||||
// A new one.
|
// A new one.
|
||||||
req = new AsyncRequest;
|
req = new AsyncRequest;
|
||||||
req->name = name;
|
req->name = name;
|
||||||
|
req->is_txt = is_txt;
|
||||||
asyncs_queued.push_back(req);
|
asyncs_queued.push_back(req);
|
||||||
asyncs_names.insert(AsyncRequestNameMap::value_type(name, req));
|
asyncs_names.insert(AsyncRequestNameMap::value_type(name, req));
|
||||||
}
|
}
|
||||||
|
@ -1036,8 +1091,9 @@ void DNS_Mgr::IssueAsyncRequests()
|
||||||
dr = new DNS_Mgr_Request(req->host);
|
dr = new DNS_Mgr_Request(req->host);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dr = new DNS_Mgr_Request(req->name.c_str(), AF_INET);
|
dr = new DNS_Mgr_Request(req->name.c_str(), AF_INET, req->is_txt);
|
||||||
dr6 = new DNS_Mgr_Request(req->name.c_str(), AF_INET6);
|
if ( ! req->is_txt )
|
||||||
|
dr6 = new DNS_Mgr_Request(req->name.c_str(), AF_INET6, req->is_txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! dr->MakeRequest(nb_dns) )
|
if ( ! dr->MakeRequest(nb_dns) )
|
||||||
|
@ -1109,6 +1165,39 @@ void DNS_Mgr::CheckAsyncAddrRequest(const IPAddr& addr, bool timeout)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DNS_Mgr::CheckAsyncTextRequest(const char* host, bool timeout)
|
||||||
|
{
|
||||||
|
// Note that this code is a mirror of that for CheckAsyncAddrRequest.
|
||||||
|
|
||||||
|
AsyncRequestTextMap::iterator i = asyncs_texts.find(host);
|
||||||
|
|
||||||
|
if ( i != asyncs_texts.end() )
|
||||||
|
{
|
||||||
|
const char* name = LookupTextInCache(host);
|
||||||
|
if ( name )
|
||||||
|
{
|
||||||
|
++successful;
|
||||||
|
i->second->Resolved(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ( timeout )
|
||||||
|
{
|
||||||
|
AsyncRequestTextMap::iterator it = asyncs_texts.begin();
|
||||||
|
++failed;
|
||||||
|
i->second->Timeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
asyncs_texts.erase(i);
|
||||||
|
--asyncs_pending;
|
||||||
|
|
||||||
|
// Don't delete the request. That will be done once it
|
||||||
|
// eventually times out.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DNS_Mgr::CheckAsyncHostRequest(const char* host, bool timeout)
|
void DNS_Mgr::CheckAsyncHostRequest(const char* host, bool timeout)
|
||||||
{
|
{
|
||||||
// Note that this code is a mirror of that for CheckAsyncAddrRequest.
|
// Note that this code is a mirror of that for CheckAsyncAddrRequest.
|
||||||
|
@ -1157,8 +1246,12 @@ void DNS_Mgr::Flush()
|
||||||
for ( AddrMap::iterator it2 = addr_mappings.begin(); it2 != addr_mappings.end(); ++it2 )
|
for ( AddrMap::iterator it2 = addr_mappings.begin(); it2 != addr_mappings.end(); ++it2 )
|
||||||
delete it2->second;
|
delete it2->second;
|
||||||
|
|
||||||
|
for ( TextMap::iterator it3 = text_mappings.begin(); it3 != text_mappings.end(); ++it3 )
|
||||||
|
delete it3->second;
|
||||||
|
|
||||||
host_mappings.clear();
|
host_mappings.clear();
|
||||||
addr_mappings.clear();
|
addr_mappings.clear();
|
||||||
|
text_mappings.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DNS_Mgr::Process()
|
void DNS_Mgr::Process()
|
||||||
|
@ -1177,6 +1270,8 @@ void DNS_Mgr::DoProcess(bool flush)
|
||||||
|
|
||||||
if ( req->IsAddrReq() )
|
if ( req->IsAddrReq() )
|
||||||
CheckAsyncAddrRequest(req->host, true);
|
CheckAsyncAddrRequest(req->host, true);
|
||||||
|
else if ( req->is_txt )
|
||||||
|
CheckAsyncTextRequest(req->name.c_str(), true);
|
||||||
else
|
else
|
||||||
CheckAsyncHostRequest(req->name.c_str(), true);
|
CheckAsyncHostRequest(req->name.c_str(), true);
|
||||||
|
|
||||||
|
@ -1184,7 +1279,7 @@ void DNS_Mgr::DoProcess(bool flush)
|
||||||
delete req;
|
delete req;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( asyncs_addrs.size() == 0 && asyncs_names.size() == 0 )
|
if ( asyncs_addrs.size() == 0 && asyncs_names.size() == 0 && asyncs_texts.size() == 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( AnswerAvailable(0) <= 0 )
|
if ( AnswerAvailable(0) <= 0 )
|
||||||
|
@ -1217,6 +1312,8 @@ void DNS_Mgr::DoProcess(bool flush)
|
||||||
|
|
||||||
if ( ! dr->ReqHost() )
|
if ( ! dr->ReqHost() )
|
||||||
CheckAsyncAddrRequest(dr->ReqAddr(), true);
|
CheckAsyncAddrRequest(dr->ReqAddr(), true);
|
||||||
|
else if ( dr->ReqIsTxt() )
|
||||||
|
CheckAsyncTextRequest(dr->ReqHost(), do_host_timeout);
|
||||||
else
|
else
|
||||||
CheckAsyncHostRequest(dr->ReqHost(), do_host_timeout);
|
CheckAsyncHostRequest(dr->ReqHost(), do_host_timeout);
|
||||||
|
|
||||||
|
@ -1271,5 +1368,6 @@ void DNS_Mgr::GetStats(Stats* stats)
|
||||||
stats->pending = asyncs_pending;
|
stats->pending = asyncs_pending;
|
||||||
stats->cached_hosts = host_mappings.size();
|
stats->cached_hosts = host_mappings.size();
|
||||||
stats->cached_addresses = addr_mappings.size();
|
stats->cached_addresses = addr_mappings.size();
|
||||||
|
stats->cached_texts = text_mappings.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,7 @@ public:
|
||||||
|
|
||||||
const char* LookupAddrInCache(const IPAddr& addr);
|
const char* LookupAddrInCache(const IPAddr& addr);
|
||||||
TableVal* LookupNameInCache(string name);
|
TableVal* LookupNameInCache(string name);
|
||||||
|
const char* LookupTextInCache(string name);
|
||||||
|
|
||||||
// Support for async lookups.
|
// Support for async lookups.
|
||||||
class LookupCallback {
|
class LookupCallback {
|
||||||
|
@ -76,7 +77,9 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
void AsyncLookupAddr(const IPAddr& host, LookupCallback* callback);
|
void AsyncLookupAddr(const IPAddr& host, LookupCallback* callback);
|
||||||
void AsyncLookupName(string name, LookupCallback* callback);
|
|
||||||
|
// If is_txt is true, perform a TXT lookup.
|
||||||
|
void AsyncLookupName(string name, LookupCallback* callback, bool is_txt = false);
|
||||||
|
|
||||||
struct Stats {
|
struct Stats {
|
||||||
unsigned long requests; // These count only async requests.
|
unsigned long requests; // These count only async requests.
|
||||||
|
@ -85,6 +88,7 @@ public:
|
||||||
unsigned long pending;
|
unsigned long pending;
|
||||||
unsigned long cached_hosts;
|
unsigned long cached_hosts;
|
||||||
unsigned long cached_addresses;
|
unsigned long cached_addresses;
|
||||||
|
unsigned long cached_texts;
|
||||||
};
|
};
|
||||||
|
|
||||||
void GetStats(Stats* stats);
|
void GetStats(Stats* stats);
|
||||||
|
@ -106,6 +110,7 @@ protected:
|
||||||
|
|
||||||
typedef map<string, pair<DNS_Mapping*, DNS_Mapping*> > HostMap;
|
typedef map<string, pair<DNS_Mapping*, DNS_Mapping*> > HostMap;
|
||||||
typedef map<IPAddr, DNS_Mapping*> AddrMap;
|
typedef map<IPAddr, DNS_Mapping*> AddrMap;
|
||||||
|
typedef map<string, DNS_Mapping*> TextMap;
|
||||||
void LoadCache(FILE* f);
|
void LoadCache(FILE* f);
|
||||||
void Save(FILE* f, const AddrMap& m);
|
void Save(FILE* f, const AddrMap& m);
|
||||||
void Save(FILE* f, const HostMap& m);
|
void Save(FILE* f, const HostMap& m);
|
||||||
|
@ -122,6 +127,7 @@ protected:
|
||||||
// requested.
|
// requested.
|
||||||
void CheckAsyncAddrRequest(const IPAddr& addr, bool timeout);
|
void CheckAsyncAddrRequest(const IPAddr& addr, bool timeout);
|
||||||
void CheckAsyncHostRequest(const char* host, bool timeout);
|
void CheckAsyncHostRequest(const char* host, bool timeout);
|
||||||
|
void CheckAsyncTextRequest(const char* host, bool timeout);
|
||||||
|
|
||||||
// Process outstanding requests.
|
// Process outstanding requests.
|
||||||
void DoProcess(bool flush);
|
void DoProcess(bool flush);
|
||||||
|
@ -138,6 +144,7 @@ protected:
|
||||||
|
|
||||||
HostMap host_mappings;
|
HostMap host_mappings;
|
||||||
AddrMap addr_mappings;
|
AddrMap addr_mappings;
|
||||||
|
TextMap text_mappings;
|
||||||
|
|
||||||
DNS_mgr_request_list requests;
|
DNS_mgr_request_list requests;
|
||||||
|
|
||||||
|
@ -165,6 +172,7 @@ protected:
|
||||||
double time;
|
double time;
|
||||||
IPAddr host;
|
IPAddr host;
|
||||||
string name;
|
string name;
|
||||||
|
bool is_txt;
|
||||||
CallbackList callbacks;
|
CallbackList callbacks;
|
||||||
|
|
||||||
bool IsAddrReq() const { return name.length() == 0; }
|
bool IsAddrReq() const { return name.length() == 0; }
|
||||||
|
@ -210,6 +218,9 @@ protected:
|
||||||
typedef map<string, AsyncRequest*> AsyncRequestNameMap;
|
typedef map<string, AsyncRequest*> AsyncRequestNameMap;
|
||||||
AsyncRequestNameMap asyncs_names;
|
AsyncRequestNameMap asyncs_names;
|
||||||
|
|
||||||
|
typedef map<string, AsyncRequest*> AsyncRequestTextMap;
|
||||||
|
AsyncRequestTextMap asyncs_texts;
|
||||||
|
|
||||||
typedef list<AsyncRequest*> QueuedList;
|
typedef list<AsyncRequest*> QueuedList;
|
||||||
QueuedList asyncs_queued;
|
QueuedList asyncs_queued;
|
||||||
|
|
||||||
|
|
30
src/bro.bif
30
src/bro.bif
|
@ -3770,6 +3770,36 @@ function lookup_addr%(host: addr%) : string
|
||||||
return 0;
|
return 0;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
## Issues an asynchronous TEXT DNS lookup and delays the function result.
|
||||||
|
## This function can therefore only be called inside a ``when`` condition,
|
||||||
|
## e.g., ``when ( local h = lookup_hostname_txt("www.bro-ids.org") ) { f(h); }``.
|
||||||
|
##
|
||||||
|
## host: The hostname to lookup.
|
||||||
|
##
|
||||||
|
## Returns: A set of DNS A and AAAA records associated with *host*.
|
||||||
|
##
|
||||||
|
## .. bro:see:: lookup_hostname
|
||||||
|
function lookup_hostname_txt%(host: string%) : addr_set
|
||||||
|
%{
|
||||||
|
// FIXME: Is should be easy to adapt the function to synchronous
|
||||||
|
// lookups if we're reading a trace.
|
||||||
|
Trigger* trigger = frame->GetTrigger();
|
||||||
|
|
||||||
|
if ( ! trigger)
|
||||||
|
{
|
||||||
|
builtin_error("lookup_hostname_txt() can only be called inside a when-condition");
|
||||||
|
return new StringVal("<error>");
|
||||||
|
}
|
||||||
|
|
||||||
|
frame->SetDelayed();
|
||||||
|
trigger->Hold();
|
||||||
|
|
||||||
|
dns_mgr->AsyncLookupName(host->CheckString(),
|
||||||
|
new LookupHostCallback(trigger, frame->GetCall(), false),
|
||||||
|
true);
|
||||||
|
return 0;
|
||||||
|
%}
|
||||||
|
|
||||||
## Issues an asynchronous DNS lookup and delays the function result.
|
## Issues an asynchronous DNS lookup and delays the function result.
|
||||||
## This function can therefore only be called inside a ``when`` condition,
|
## This function can therefore only be called inside a ``when`` condition,
|
||||||
## e.g., ``when ( local h = lookup_hostname("www.bro-ids.org") ) { f(h); }``.
|
## e.g., ``when ( local h = lookup_hostname("www.bro-ids.org") ) { f(h); }``.
|
||||||
|
|
44
src/nb_dns.c
44
src/nb_dns.c
|
@ -307,31 +307,32 @@ nb_dns_host_request(register struct nb_dns_info *nd, register const char *name,
|
||||||
register void *cookie, register char *errstr)
|
register void *cookie, register char *errstr)
|
||||||
{
|
{
|
||||||
|
|
||||||
return (nb_dns_host_request2(nd, name, AF_INET, cookie, errstr));
|
return (nb_dns_host_request2(nd, name, AF_INET, 0, cookie, errstr));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
nb_dns_host_request2(register struct nb_dns_info *nd, register const char *name,
|
nb_dns_host_request2(register struct nb_dns_info *nd, register const char *name,
|
||||||
register int af, register void *cookie, register char *errstr)
|
register int af, register int qtype, register void *cookie, register char *errstr)
|
||||||
{
|
{
|
||||||
register int qtype;
|
if (qtype != 16) {
|
||||||
|
|
||||||
switch (af) {
|
switch (af) {
|
||||||
|
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
qtype = T_A;
|
qtype = T_A;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef AF_INET6
|
#ifdef AF_INET6
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
qtype = T_AAAA;
|
qtype = T_AAAA;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
snprintf(errstr, NB_DNS_ERRSIZE,
|
snprintf(errstr, NB_DNS_ERRSIZE,
|
||||||
"nb_dns_host_request2(): uknown address family %d", af);
|
"nb_dns_host_request2(): unknown address family %d", af);
|
||||||
return (-1);
|
return (-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (_nb_dns_mkquery(nd, name, af, qtype, cookie, errstr));
|
return (_nb_dns_mkquery(nd, name, af, qtype, cookie, errstr));
|
||||||
}
|
}
|
||||||
|
@ -579,6 +580,7 @@ nb_dns_activity(struct nb_dns_info *nd, struct nb_dns_result *nr, char *errstr)
|
||||||
nr->host_errno = NO_RECOVERY;
|
nr->host_errno = NO_RECOVERY;
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(bp, rdata, rdlen);
|
memcpy(bp, rdata, rdlen);
|
||||||
*hap++ = bp;
|
*hap++ = bp;
|
||||||
bp += rdlen;
|
bp += rdlen;
|
||||||
|
@ -587,6 +589,20 @@ nb_dns_activity(struct nb_dns_info *nd, struct nb_dns_result *nr, char *errstr)
|
||||||
/* Keep looking for more A records */
|
/* Keep looking for more A records */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_TXT:
|
||||||
|
if (bp + rdlen >= ep) {
|
||||||
|
snprintf(errstr, NB_DNS_ERRSIZE,
|
||||||
|
"nb_dns_activity(): overflow 1 for txt");
|
||||||
|
nr->host_errno = NO_RECOVERY;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(bp, rdata, rdlen);
|
||||||
|
he->h_name = bp+1; /* First char is a control character. */
|
||||||
|
nr->hostent = he;
|
||||||
|
nr->ttl = rttl;
|
||||||
|
return (1);
|
||||||
|
|
||||||
case T_PTR:
|
case T_PTR:
|
||||||
n = dn_expand((const u_char *)msg,
|
n = dn_expand((const u_char *)msg,
|
||||||
(const u_char *)msg + msglen, rdata, bp, ep - bp);
|
(const u_char *)msg + msglen, rdata, bp, ep - bp);
|
||||||
|
|
|
@ -22,7 +22,7 @@ void nb_dns_finish(struct nb_dns_info *);
|
||||||
int nb_dns_fd(struct nb_dns_info *);
|
int nb_dns_fd(struct nb_dns_info *);
|
||||||
|
|
||||||
int nb_dns_host_request(struct nb_dns_info *, const char *, void *, char *);
|
int nb_dns_host_request(struct nb_dns_info *, const char *, void *, char *);
|
||||||
int nb_dns_host_request2(struct nb_dns_info *, const char *, int,
|
int nb_dns_host_request2(struct nb_dns_info *, const char *, int, int,
|
||||||
void *, char *);
|
void *, char *);
|
||||||
|
|
||||||
int nb_dns_addr_request(struct nb_dns_info *, nb_uint32_t, void *, char *);
|
int nb_dns_addr_request(struct nb_dns_info *, nb_uint32_t, void *, char *);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue