mirror of
https://github.com/zeek/zeek.git
synced 2025-10-09 18:18:19 +00:00
Merge remote-tracking branch 'origin/topic/jsiwek/v6-dns-name-lookup' into topic/robin/v6-addr-merge
* origin/topic/jsiwek/v6-dns-name-lookup: DNS name lookups performed by Bro now also query AAAA records. Conflicts: src/DNS_Mgr.cc
This commit is contained in:
commit
be3fb5fb81
2 changed files with 148 additions and 33 deletions
176
src/DNS_Mgr.cc
176
src/DNS_Mgr.cc
|
@ -46,8 +46,8 @@ 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) { host = copy_string(h); }
|
DNS_Mgr_Request(const char* h, int af) { host = copy_string(h); fam = af; }
|
||||||
DNS_Mgr_Request(const IPAddr& a) { addr = a; host = 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.
|
||||||
|
@ -61,8 +61,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
|
||||||
IPAddr addr;
|
IPAddr addr;
|
||||||
uint32 ttl;
|
|
||||||
int request_pending;
|
int request_pending;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -75,7 +75,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_request(nb_dns, host, (void*) this, err) >= 0;
|
return nb_dns_host_request2(nb_dns, host, fam, (void*) this, err) >= 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const uint32* bytes;
|
const uint32* bytes;
|
||||||
|
@ -116,7 +116,14 @@ public:
|
||||||
int Valid() const { return ! failed; }
|
int Valid() const { return ! failed; }
|
||||||
|
|
||||||
bool Expired() const
|
bool Expired() const
|
||||||
{ return current_time() > (creation_time + req_ttl); }
|
{
|
||||||
|
if ( req_host && num_addrs == 0)
|
||||||
|
return false; // nothing to expire
|
||||||
|
|
||||||
|
return current_time() > (creation_time + req_ttl);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Type() const { return map_type; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class DNS_Mgr;
|
friend class DNS_Mgr;
|
||||||
|
@ -141,6 +148,7 @@ protected:
|
||||||
|
|
||||||
int failed;
|
int failed;
|
||||||
double creation_time;
|
double creation_time;
|
||||||
|
int map_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
void DNS_Mgr_mapping_delete_func(void* v)
|
void DNS_Mgr_mapping_delete_func(void* v)
|
||||||
|
@ -193,8 +201,9 @@ DNS_Mapping::DNS_Mapping(FILE* f)
|
||||||
char req_buf[512+1], name_buf[512+1];
|
char req_buf[512+1], name_buf[512+1];
|
||||||
int is_req_host;
|
int is_req_host;
|
||||||
|
|
||||||
if ( sscanf(buf, "%lf %d %512s %d %512s %d", &creation_time, &is_req_host,
|
if ( sscanf(buf, "%lf %d %512s %d %512s %d %d %"PRIu32, &creation_time,
|
||||||
req_buf, &failed, name_buf, &num_addrs) != 6 )
|
&is_req_host, req_buf, &failed, name_buf, &map_type, &num_addrs,
|
||||||
|
&req_ttl) != 8 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( is_req_host )
|
if ( is_req_host )
|
||||||
|
@ -299,6 +308,7 @@ void DNS_Mapping::Init(struct hostent* h)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
map_type = h->h_addrtype;
|
||||||
num_names = 1; // for now, just use official name
|
num_names = 1; // for now, just use official name
|
||||||
names = new char*[num_names];
|
names = new char*[num_names];
|
||||||
names[0] = h->h_name ? copy_string(h->h_name) : 0;
|
names[0] = h->h_name ? copy_string(h->h_name) : 0;
|
||||||
|
@ -331,15 +341,16 @@ void DNS_Mapping::Clear()
|
||||||
host_val = 0;
|
host_val = 0;
|
||||||
addrs_val = 0;
|
addrs_val = 0;
|
||||||
no_mapping = 0;
|
no_mapping = 0;
|
||||||
|
map_type = 0;
|
||||||
failed = 1;
|
failed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DNS_Mapping::Save(FILE* f) const
|
void DNS_Mapping::Save(FILE* f) const
|
||||||
{
|
{
|
||||||
fprintf(f, "%.0f %d %s %d %s %d\n", creation_time, req_host != 0,
|
fprintf(f, "%.0f %d %s %d %s %d %d %"PRIu32"\n", creation_time, req_host != 0,
|
||||||
req_host ? req_host : req_addr.AsString().c_str(),
|
req_host ? req_host : req_addr.AsString().c_str(),
|
||||||
failed, (names && names[0]) ? names[0] : "*",
|
failed, (names && names[0]) ? names[0] : "*",
|
||||||
num_addrs);
|
map_type, num_addrs, req_ttl);
|
||||||
|
|
||||||
for ( int i = 0; i < num_addrs; ++i )
|
for ( int i = 0; i < num_addrs; ++i )
|
||||||
fprintf(f, "%s\n", addrs[i].AsString().c_str());
|
fprintf(f, "%s\n", addrs[i].AsString().c_str());
|
||||||
|
@ -352,7 +363,6 @@ DNS_Mgr::DNS_Mgr(DNS_MgrMode arg_mode)
|
||||||
|
|
||||||
mode = arg_mode;
|
mode = arg_mode;
|
||||||
|
|
||||||
host_mappings.SetDeleteFunc(DNS_Mgr_mapping_delete_func);
|
|
||||||
addr_mappings.SetDeleteFunc(DNS_Mgr_mapping_delete_func);
|
addr_mappings.SetDeleteFunc(DNS_Mgr_mapping_delete_func);
|
||||||
|
|
||||||
char err[NB_DNS_ERRSIZE];
|
char err[NB_DNS_ERRSIZE];
|
||||||
|
@ -441,24 +451,34 @@ TableVal* DNS_Mgr::LookupHost(const char* name)
|
||||||
|
|
||||||
if ( mode != DNS_PRIME )
|
if ( mode != DNS_PRIME )
|
||||||
{
|
{
|
||||||
DNS_Mapping* d = host_mappings.Lookup(name);
|
HostMap::iterator it = host_mappings.find(name);
|
||||||
|
|
||||||
if ( d )
|
if ( it != host_mappings.end() )
|
||||||
{
|
{
|
||||||
if ( d->Valid() )
|
DNS_Mapping* d4 = it->second.first;
|
||||||
return d->Addrs()->ConvertToSet();
|
DNS_Mapping* d6 = it->second.second;
|
||||||
else
|
|
||||||
|
if ( (d4 && d4->Failed()) || (d6 && d6->Failed()) )
|
||||||
{
|
{
|
||||||
reporter->Warning("no such host: %s", name);
|
reporter->Warning("no such host: %s", name);
|
||||||
return empty_addr_set();
|
return empty_addr_set();
|
||||||
}
|
}
|
||||||
|
else if ( d4 && d6 )
|
||||||
|
{
|
||||||
|
TableVal* tv4 = d4->AddrsSet();
|
||||||
|
TableVal* tv6 = d6->AddrsSet();
|
||||||
|
tv4->AddTo(tv6, false);
|
||||||
|
Unref(tv4);
|
||||||
|
return tv6;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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));
|
requests.append(new DNS_Mgr_Request(name, AF_INET));
|
||||||
|
requests.append(new DNS_Mgr_Request(name, AF_INET6));
|
||||||
return empty_addr_set();
|
return empty_addr_set();
|
||||||
|
|
||||||
case DNS_FORCE:
|
case DNS_FORCE:
|
||||||
|
@ -466,7 +486,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));
|
requests.append(new DNS_Mgr_Request(name, AF_INET));
|
||||||
|
requests.append(new DNS_Mgr_Request(name, AF_INET6));
|
||||||
Resolve();
|
Resolve();
|
||||||
return LookupHost(name);
|
return LookupHost(name);
|
||||||
|
|
||||||
|
@ -683,13 +704,43 @@ void DNS_Mgr::AddResult(DNS_Mgr_Request* dr, struct nb_dns_result* r)
|
||||||
if ( dr->ReqHost() )
|
if ( dr->ReqHost() )
|
||||||
{
|
{
|
||||||
new_dm = new DNS_Mapping(dr->ReqHost(), h, ttl);
|
new_dm = new DNS_Mapping(dr->ReqHost(), h, ttl);
|
||||||
prev_dm = host_mappings.Insert(dr->ReqHost(), new_dm);
|
|
||||||
|
HostMap::iterator it = host_mappings.find(dr->ReqHost());
|
||||||
|
if ( it == host_mappings.end() )
|
||||||
|
{
|
||||||
|
host_mappings[dr->ReqHost()].first =
|
||||||
|
new_dm->Type() == AF_INET ? new_dm : 0;
|
||||||
|
host_mappings[dr->ReqHost()].second =
|
||||||
|
new_dm->Type() == AF_INET6 ? new_dm : 0;
|
||||||
|
|
||||||
|
prev_dm = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prev_dm = 0;
|
||||||
|
|
||||||
|
if ( new_dm->Type() == AF_INET )
|
||||||
|
{
|
||||||
|
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.
|
||||||
(void) host_mappings.Insert(dr->ReqHost(), prev_dm);
|
if ( prev_dm->Type() == AF_INET )
|
||||||
|
host_mappings[dr->ReqHost()].first = prev_dm;
|
||||||
|
else
|
||||||
|
host_mappings[dr->ReqHost()].second = prev_dm;
|
||||||
|
|
||||||
++keep_prev;
|
++keep_prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -810,7 +861,17 @@ void DNS_Mgr::LoadCache(FILE* f)
|
||||||
for ( ; ! m->NoMapping() && ! m->InitFailed(); m = new DNS_Mapping(f) )
|
for ( ; ! m->NoMapping() && ! m->InitFailed(); m = new DNS_Mapping(f) )
|
||||||
{
|
{
|
||||||
if ( m->ReqHost() )
|
if ( m->ReqHost() )
|
||||||
host_mappings.Insert(m->ReqHost(), m);
|
{
|
||||||
|
if ( host_mappings.find(m->ReqHost()) == host_mappings.end() )
|
||||||
|
{
|
||||||
|
host_mappings[m->ReqHost()].first = 0;
|
||||||
|
host_mappings[m->ReqHost()].second = 0;
|
||||||
|
}
|
||||||
|
if ( m->Type() == AF_INET )
|
||||||
|
host_mappings[m->ReqHost()].first = m;
|
||||||
|
else
|
||||||
|
host_mappings[m->ReqHost()].second = m;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HashKey h(m->ReqAddr());
|
HashKey h(m->ReqAddr());
|
||||||
|
@ -834,6 +895,20 @@ void DNS_Mgr::Save(FILE* f, PDict(DNS_Mapping)& m)
|
||||||
dm->Save(f);
|
dm->Save(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DNS_Mgr::Save(FILE* f, const HostMap& m)
|
||||||
|
{
|
||||||
|
HostMap::const_iterator it;
|
||||||
|
|
||||||
|
for ( it = m.begin(); it != m.end(); ++it )
|
||||||
|
{
|
||||||
|
if ( it->second.first )
|
||||||
|
it->second.first->Save(f);
|
||||||
|
|
||||||
|
if ( it->second.second )
|
||||||
|
it->second.second->Save(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const char* DNS_Mgr::LookupAddrInCache(const IPAddr& addr)
|
const char* DNS_Mgr::LookupAddrInCache(const IPAddr& addr)
|
||||||
{
|
{
|
||||||
HashKey h(addr);
|
HashKey h(addr);
|
||||||
|
@ -856,20 +931,29 @@ const char* DNS_Mgr::LookupAddrInCache(const IPAddr& addr)
|
||||||
|
|
||||||
TableVal* DNS_Mgr::LookupNameInCache(string name)
|
TableVal* DNS_Mgr::LookupNameInCache(string name)
|
||||||
{
|
{
|
||||||
DNS_Mapping* d = dns_mgr->host_mappings.Lookup(name.c_str());
|
HostMap::iterator it = dns_mgr->host_mappings.find(name);
|
||||||
|
if ( it == dns_mgr->host_mappings.end() )
|
||||||
if ( ! d || ! d->names )
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ( d->Expired() )
|
DNS_Mapping* d4 = it->second.first;
|
||||||
|
DNS_Mapping* d6 = it->second.second;
|
||||||
|
|
||||||
|
if ( ! d4 || ! d4->names || ! d6 || ! d6->names )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ( d4->Expired() || d6->Expired() )
|
||||||
{
|
{
|
||||||
HashKey h(name.c_str());
|
dns_mgr->host_mappings.erase(it);
|
||||||
dns_mgr->host_mappings.Remove(&h);
|
delete d4;
|
||||||
delete d;
|
delete d6;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return d->AddrsSet();
|
TableVal* tv4 = d4->AddrsSet();
|
||||||
|
TableVal* tv6 = d6->AddrsSet();
|
||||||
|
tv4->AddTo(tv6, false);
|
||||||
|
Unref(tv4);
|
||||||
|
return tv6;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DNS_Mgr::AsyncLookupAddr(const IPAddr& host, LookupCallback* callback)
|
void DNS_Mgr::AsyncLookupAddr(const IPAddr& host, LookupCallback* callback)
|
||||||
|
@ -951,10 +1035,15 @@ void DNS_Mgr::IssueAsyncRequests()
|
||||||
++num_requests;
|
++num_requests;
|
||||||
|
|
||||||
DNS_Mgr_Request* dr;
|
DNS_Mgr_Request* dr;
|
||||||
|
DNS_Mgr_Request* dr6 = 0;
|
||||||
|
|
||||||
if ( req->IsAddrReq() )
|
if ( req->IsAddrReq() )
|
||||||
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());
|
{
|
||||||
|
dr = new DNS_Mgr_Request(req->name.c_str(), AF_INET);
|
||||||
|
dr6 = new DNS_Mgr_Request(req->name.c_str(), AF_INET6);
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! dr->MakeRequest(nb_dns) )
|
if ( ! dr->MakeRequest(nb_dns) )
|
||||||
{
|
{
|
||||||
|
@ -964,6 +1053,14 @@ void DNS_Mgr::IssueAsyncRequests()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( dr6 && ! dr6->MakeRequest(nb_dns) )
|
||||||
|
{
|
||||||
|
reporter->Warning("can't issue DNS request");
|
||||||
|
++failed;
|
||||||
|
req->Timeout();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
req->time = current_time();
|
req->time = current_time();
|
||||||
asyncs_timeouts.push(req);
|
asyncs_timeouts.push(req);
|
||||||
|
|
||||||
|
@ -1055,7 +1152,14 @@ void DNS_Mgr::Flush()
|
||||||
{
|
{
|
||||||
DoProcess(false);
|
DoProcess(false);
|
||||||
|
|
||||||
host_mappings.Clear();
|
HostMap::iterator it;
|
||||||
|
for ( it = host_mappings.begin(); it != host_mappings.end(); ++it )
|
||||||
|
{
|
||||||
|
delete it->second.first;
|
||||||
|
delete it->second.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
host_mappings.clear();
|
||||||
addr_mappings.Clear();
|
addr_mappings.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1099,6 +1203,14 @@ void DNS_Mgr::DoProcess(bool flush)
|
||||||
else if ( status > 0 )
|
else if ( status > 0 )
|
||||||
{
|
{
|
||||||
DNS_Mgr_Request* dr = (DNS_Mgr_Request*) r.cookie;
|
DNS_Mgr_Request* dr = (DNS_Mgr_Request*) r.cookie;
|
||||||
|
|
||||||
|
bool do_host_timeout = true;
|
||||||
|
if ( dr->ReqHost() &&
|
||||||
|
host_mappings.find(dr->ReqHost()) == host_mappings.end() )
|
||||||
|
// Don't timeout when this is the first result in an expected pair
|
||||||
|
// (one result each for A and AAAA queries).
|
||||||
|
do_host_timeout = false;
|
||||||
|
|
||||||
if ( dr->RequestPending() )
|
if ( dr->RequestPending() )
|
||||||
{
|
{
|
||||||
AddResult(dr, &r);
|
AddResult(dr, &r);
|
||||||
|
@ -1108,7 +1220,7 @@ void DNS_Mgr::DoProcess(bool flush)
|
||||||
if ( ! dr->ReqHost() )
|
if ( ! dr->ReqHost() )
|
||||||
CheckAsyncAddrRequest(dr->ReqAddr(), true);
|
CheckAsyncAddrRequest(dr->ReqAddr(), true);
|
||||||
else
|
else
|
||||||
CheckAsyncHostRequest(dr->ReqHost(), true);
|
CheckAsyncHostRequest(dr->ReqHost(), do_host_timeout);
|
||||||
|
|
||||||
IssueAsyncRequests();
|
IssueAsyncRequests();
|
||||||
|
|
||||||
|
@ -1159,7 +1271,7 @@ void DNS_Mgr::GetStats(Stats* stats)
|
||||||
stats->successful = successful;
|
stats->successful = successful;
|
||||||
stats->failed = failed;
|
stats->failed = failed;
|
||||||
stats->pending = asyncs_pending;
|
stats->pending = asyncs_pending;
|
||||||
stats->cached_hosts = host_mappings.Length();
|
stats->cached_hosts = host_mappings.size();
|
||||||
stats->cached_addresses = addr_mappings.Length();
|
stats->cached_addresses = addr_mappings.Length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "BroList.h"
|
#include "BroList.h"
|
||||||
|
@ -104,8 +105,10 @@ protected:
|
||||||
ListVal* AddrListDelta(ListVal* al1, ListVal* al2);
|
ListVal* AddrListDelta(ListVal* al1, ListVal* al2);
|
||||||
void DumpAddrList(FILE* f, ListVal* al);
|
void DumpAddrList(FILE* f, ListVal* al);
|
||||||
|
|
||||||
|
typedef map<string, pair<DNS_Mapping*, DNS_Mapping*> > HostMap;
|
||||||
void LoadCache(FILE* f);
|
void LoadCache(FILE* f);
|
||||||
void Save(FILE* f, PDict(DNS_Mapping)& m);
|
void Save(FILE* f, PDict(DNS_Mapping)& m);
|
||||||
|
void Save(FILE* f, const HostMap& m);
|
||||||
|
|
||||||
// Selects on the fd to see if there is an answer available (timeout
|
// Selects on the fd to see if there is an answer available (timeout
|
||||||
// is secs). Returns 0 on timeout, -1 on EINTR or other error, and 1
|
// is secs). Returns 0 on timeout, -1 on EINTR or other error, and 1
|
||||||
|
@ -133,7 +136,7 @@ protected:
|
||||||
|
|
||||||
PDict(ListVal) services;
|
PDict(ListVal) services;
|
||||||
|
|
||||||
PDict(DNS_Mapping) host_mappings;
|
HostMap host_mappings;
|
||||||
PDict(DNS_Mapping) addr_mappings;
|
PDict(DNS_Mapping) addr_mappings;
|
||||||
|
|
||||||
DNS_mgr_request_list requests;
|
DNS_mgr_request_list requests;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue