mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Refactor DNS script's state management to improve performance.
The amount of timers involved in DNS::PendingMessage tables' expiration attributes have a significant performance hit. Instead the script now relies solely on maximum thresholds for pending message quantities to limit amount of accumulated state. There's a new option, "DNS::max_pending_query_ids", to limit the number outstanding messages across all DNS query IDs ("DNS::max_pending_msgs" still limits number of outstanding messages for a *given* query ID).
This commit is contained in:
parent
f45bd84f4c
commit
3c95d1d695
2 changed files with 33 additions and 36 deletions
|
@ -109,16 +109,6 @@ export {
|
||||||
## DNS message query/transaction ID.
|
## DNS message query/transaction ID.
|
||||||
type PendingMessages: table[count] of Queue::Queue;
|
type PendingMessages: table[count] of Queue::Queue;
|
||||||
|
|
||||||
## Called when a pending DNS query has not been matched with a reply (or
|
|
||||||
## vice versa) in a sufficent amount of time.
|
|
||||||
##
|
|
||||||
## pending: table of pending messages, indexed by transaction ID.
|
|
||||||
##
|
|
||||||
## id: the index of he element being expired.
|
|
||||||
##
|
|
||||||
## Returns: amount of time to delay expiration of the element.
|
|
||||||
global expire_pending_msg: function(pending: PendingMessages, id: count): interval;
|
|
||||||
|
|
||||||
## The amount of time that DNS queries or replies for a given
|
## The amount of time that DNS queries or replies for a given
|
||||||
## query/transaction ID are allowed to be queued while waiting for
|
## query/transaction ID are allowed to be queued while waiting for
|
||||||
## a matching reply or query.
|
## a matching reply or query.
|
||||||
|
@ -131,16 +121,21 @@ export {
|
||||||
## response is ongoing).
|
## response is ongoing).
|
||||||
const max_pending_msgs = 50 &redef;
|
const max_pending_msgs = 50 &redef;
|
||||||
|
|
||||||
|
## Give up trying to match pending DNS queries or replies across all
|
||||||
|
## query/transaction IDs once there is at least one unmatched query or
|
||||||
|
## reply across this number of different query IDs.
|
||||||
|
const max_pending_query_ids = 50 &redef;
|
||||||
|
|
||||||
## A record type which tracks the status of DNS queries for a given
|
## A record type which tracks the status of DNS queries for a given
|
||||||
## :bro:type:`connection`.
|
## :bro:type:`connection`.
|
||||||
type State: record {
|
type State: record {
|
||||||
## Indexed by query id, returns Info record corresponding to
|
## Indexed by query id, returns Info record corresponding to
|
||||||
## queries that haven't been matched with a response yet.
|
## queries that haven't been matched with a response yet.
|
||||||
pending_queries: PendingMessages &read_expire=pending_msg_expiry_interval &expire_func=expire_pending_msg;
|
pending_queries: PendingMessages;
|
||||||
|
|
||||||
## Indexed by query id, returns Info record corresponding to
|
## Indexed by query id, returns Info record corresponding to
|
||||||
## replies that haven't been matched with a query yet.
|
## replies that haven't been matched with a query yet.
|
||||||
pending_replies: PendingMessages &read_expire=pending_msg_expiry_interval &expire_func=expire_pending_msg;
|
pending_replies: PendingMessages;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +171,11 @@ function log_unmatched_msgs_queue(q: Queue::Queue)
|
||||||
Queue::get_vector(q, infos);
|
Queue::get_vector(q, infos);
|
||||||
|
|
||||||
for ( i in infos )
|
for ( i in infos )
|
||||||
|
{
|
||||||
|
event flow_weird("dns_unmatched_msg",
|
||||||
|
infos[i]$id$orig_h, infos[i]$id$resp_h);
|
||||||
Log::write(DNS::LOG, infos[i]);
|
Log::write(DNS::LOG, infos[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function log_unmatched_msgs(msgs: PendingMessages)
|
function log_unmatched_msgs(msgs: PendingMessages)
|
||||||
|
@ -191,16 +190,28 @@ function log_unmatched_msgs(msgs: PendingMessages)
|
||||||
function enqueue_new_msg(msgs: PendingMessages, id: count, msg: Info)
|
function enqueue_new_msg(msgs: PendingMessages, id: count, msg: Info)
|
||||||
{
|
{
|
||||||
if ( id !in msgs )
|
if ( id !in msgs )
|
||||||
msgs[id] = Queue::init();
|
|
||||||
else if ( Queue::len(msgs[id]) > max_pending_msgs )
|
|
||||||
{
|
{
|
||||||
local info: Info = Queue::peek(msgs[id]);
|
if ( |msgs| > max_pending_query_ids )
|
||||||
event flow_weird("dns_unmatched_msg_quantity", info$id$orig_h,
|
{
|
||||||
info$id$resp_h);
|
event flow_weird("dns_unmatched_query_id_quantity",
|
||||||
log_unmatched_msgs_queue(msgs[id]);
|
msg$id$orig_h, msg$id$resp_h);
|
||||||
# Throw away all unmatched on assumption they'll never be matched.
|
# Throw away all unmatched on assumption they'll never be matched.
|
||||||
|
log_unmatched_msgs(msgs);
|
||||||
|
}
|
||||||
|
|
||||||
msgs[id] = Queue::init();
|
msgs[id] = Queue::init();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( Queue::len(msgs[id]) > max_pending_msgs )
|
||||||
|
{
|
||||||
|
event flow_weird("dns_unmatched_msg_quantity",
|
||||||
|
msg$id$orig_h, msg$id$resp_h);
|
||||||
|
log_unmatched_msgs_queue(msgs[id]);
|
||||||
|
# Throw away all unmatched on assumption they'll never be matched.
|
||||||
|
msgs[id] = Queue::init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Queue::put(msgs[id], msg);
|
Queue::put(msgs[id], msg);
|
||||||
}
|
}
|
||||||
|
@ -447,18 +458,3 @@ event connection_state_remove(c: connection) &priority=-5
|
||||||
log_unmatched_msgs(c$dns_state$pending_queries);
|
log_unmatched_msgs(c$dns_state$pending_queries);
|
||||||
log_unmatched_msgs(c$dns_state$pending_replies);
|
log_unmatched_msgs(c$dns_state$pending_replies);
|
||||||
}
|
}
|
||||||
|
|
||||||
function expire_pending_msg(pending: PendingMessages, id: count): interval
|
|
||||||
{
|
|
||||||
local infos: vector of Info;
|
|
||||||
Queue::get_vector(pending[id], infos);
|
|
||||||
|
|
||||||
for ( i in infos )
|
|
||||||
{
|
|
||||||
Log::write(DNS::LOG, infos[i]);
|
|
||||||
event flow_weird("dns_unmatched_msg", infos[i]$id$orig_h,
|
|
||||||
infos[i]$id$resp_h);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0sec;
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
#empty_field (empty)
|
#empty_field (empty)
|
||||||
#unset_field -
|
#unset_field -
|
||||||
#path weird
|
#path weird
|
||||||
#open 2013-08-26-19-36-33
|
#open 2014-02-13-20-36-35
|
||||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
|
||||||
#types time string addr port addr port string string bool string
|
#types time string addr port addr port string string bool string
|
||||||
1363716396.798286 CXWv6p3arKYeMETxOg 55.247.223.174 27285 222.195.43.124 53 DNS_RR_unknown_type - F bro
|
1363716396.798286 CXWv6p3arKYeMETxOg 55.247.223.174 27285 222.195.43.124 53 DNS_RR_unknown_type - F bro
|
||||||
1363716396.798374 CXWv6p3arKYeMETxOg 55.247.223.174 27285 222.195.43.124 53 dns_unmatched_reply - F bro
|
1363716396.798374 CXWv6p3arKYeMETxOg 55.247.223.174 27285 222.195.43.124 53 dns_unmatched_reply - F bro
|
||||||
#close 2013-08-26-19-36-33
|
1363716396.798374 - - - - - dns_unmatched_msg - F bro
|
||||||
|
#close 2014-02-13-20-36-35
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue