Forum Discussion
Mike_Lowell_456
Nov 29, 2005Historic F5 Account
DNS responder in an iRule, UDP::respond not terminating
I've written a rule which simply takes a UDP DNS packet, figures out if it's a AAAA request, and if so it replies to the request without any answer sections (i.e. simulating that no records were found).
The parsing and logic works fine, but I've found that even though I'm using UDP::respond in the CLIENT_ACCEPTED event, the client packet is still sent through to the server, and the response is also sent back to the client. The net effect is that the client receives TWO responses (one is mine, one is the servers).
I inserted a "drop" statement just after the UDP::respond statement, and this seems to work. Is this the right way to do this or should UDP::respond automatically stop the request from being sent to the server?
Also, any other thoughts on the rule (such as how to make it more efficient)?
Thanks!
when RULE_INIT {
set ::too_many_dns_parts 10
}
when CLIENT_ACCEPTED {
extract QNAME from QUESTION header
skip the DNS header, jump to the QNAME part of first QUESTION
set lastpart [string range [UDP::payload] 12 [UDP::payload length]]
byte contains the first part length
set byte [string range $lastpart 0 1]
make the byte an integer
binary scan $byte c foo
make the byte an unsigned integer
set byte [expr $foo & 0xff]
initialize our posisition in the QNAME parsing and the text QNAME
set offset 0
set name ""
$i is a sanity check so this logic won't spin on invalid QNAMEs
set i 0
while {$byte > 0 && $i < $::too_many_dns_parts } {
grab a part and put it in our text QNAME section
append name [string range $lastpart $offset [expr $offset + $byte]]
put a dot between parts like a normal DNS name
append name "."
increment the offset to the length byte of the next part
set offset [expr [expr $offset + $byte] + 1]
grab the length of the next part, and make it an unsigned integer
set byte [string range $lastpart $offset [expr $offset + 1]]
binary scan $byte c foo
set byte [expr $foo & 0xff]
incr i
}
increment offset past the final part so it points at the QTYPE field
set offset [expr $offset + 1]
/extract QNAME from QUESTION header
extract QTYPE from QUESTION header
grab the next 2 bytes that represent the QTYPE
set foo [string range $lastpart $offset [expr $offset + 2]]
binary scan $foo S byte
see if the QTYPE is 0x001c (TYPE_AAAA)
if {$byte == 0x001C} {
if so, log the event
log local0.notice "NAME: $name, TYPE_AAAA"
then take the existing request
binary scan [UDP::payload] Sca* id flags other
set the QR bit (query response)
set flags [expr $flags | 128]
and send the packet (just change that one bit and send)
set new_packet [binary format Sca* $id $flags $other]
UDP::respond $new_packet
drop
}
/extract QTYPE from QUESTION header
No RepliesBe the first to reply
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects