Forum Discussion

David_22984's avatar
David_22984
Icon for Nimbostratus rankNimbostratus
Oct 26, 2010

DNS notify loadbalancing

 

I'm trying to handle the case of a loadbalanced authoritative DNS server pool. This pool has two members, however DNS notifies need to go to only one of them (the one with the master SQL database).

 

 

I've put together an iRule for the UDP notify request and it seems to be working, however I'm not having any luck creating a TCP version of it.

 

 

UDP iRule for DNS notify

 

when CLIENT_ACCEPTED {

 

binary scan [UDP::payload] SS id flags

 

set opcode [expr ($flags >> 11) & 0xf]

 

Send NOTIFYs (opcode 4) to the master SQL database node.

 

if { $opcode == 4 } {

 

log local0. "DEBUG: NOTIFY, sending to MASTER"

 

node MASTER_SERVER_IP 53

 

}

 

else {

 

log local0. "DEBUG: NOT A NOTIFY"

 

}

 

}

 

This test irule works OK for UDP, however not being an irule expert my naive attempt to convert that to a TCP irule doesn't appear to work.

 

 

when CLIENT_ACCEPTED {

 

binary scan [TCP::payload] SS id flags

 

set opcode [expr ($flags >> 11) & 0xf]

 

Send NOTIFYs (opcode 4) to the master SQL database node.

 

if { $opcode == 4 } {

 

log local0. "DEBUG: NOTIFY TCP, sending to MASTER"

 

node MASTER_SERVER_IP 53

 

}

 

else {

 

log local0. "DEBUG TCP: NOT A NOTIFY"

 

}

 

}

 

 

Any suggestions? According to the RFC's a DNS notify can come over TCP or UDP (UDP is tried first, but it falls back to TCP in the case of a large packet and or firewall blocking).

 

 

Thx

 

-- david

 

1 Reply

  • 2 things

    1) when dealing with TCP, in client_accepted, you may collect data first...do what you need in client_data, then release the data...

    your irule may look like this...

    when CLIENT_ACCEPTED {

    TCP::collect

    }

    when CLIENT_DATA {

    do what you what here...

    TCP::release

    }

    2)

    according to rfc 1035

    4.2.2. TCP usage

    Messages sent over TCP connections use server port 53 (decimal). The

    message is prefixed with a two byte length field which gives the message

    length, excluding the two byte length field. This length field allows

    the low-level processing to assemble a complete message before beginning

    to parse it.

    so your binary scan command has to change to

    binary scan [TCP::payload] SSS length id flags

    combine both together it probably look like this... (not test)

    
    when CLIENT_ACCEPTED {
            TCP::collect
    }
    when CLIENT_DATA {
            binary scan [TCP::payload] SSS length id flags   
            set opcode [expr ($flags >> 11) & 0xf]
             Send NOTIFYs (opcode 4) to the master SQL database node.
            if { $opcode == 4 } {
                    log local0. "DEBUG: NOTIFY TCP, sending to MASTER"
                    node  MASTER_SERVER_IP 53
            }
            else {
                    log local0. "DEBUG TCP: NOT A NOTIFY"
            }
            TCP::release
    }
    

    Nat