On the side of the road in northern Missouri just north of Mark Twain’s stomping grounds, there is a slice of hillside removed just to the side of the highway. In Arkansas, there’s a nondescript field tucked away in a state park. Short of word of mouth and this thing they call the internet, you wouldn’t be any the wiser that buried or surfaced in these two locations are an amazing variety of geodes and diamonds, respectively. In this article series I will explore recent and well-aged gems from the codeshare, highlighting inventive solutions contributed by you, the community. Please join me on this great adventure as we oscillate on the Mohs’ scale of codeshare geekery.

DNS Response Translation

This solution from MVP Hamish Marson utilizes the local traffic manager aspect of iRules to service the global traffic manager response data. In fact, the iRule doesn’t care about the request at all. It looks for two things, the answer to the request (one or more addresses) and the client IP making the request. There is a lot more included in the rule (variable setting, HSL logging, comments) but here's the meat of it:

when DNS_RESPONSE {
  set rrs [DNS::answer]
  foreach rr $rrs {
    if { [DNS::type $rr] == "A" } {
      set dstip [DNS::rdata $rr]
      set gteAddClass [class match -value [IP::client_addr] equals $LOCAL_CLASS_ADDRESS ]
      switch -exact $gteAddClass {
        internal { set transIP  [class match -value $dstip equals $GTE_CLASS_INTERNAL] }
        3dp      { set transIP  [class match -value $dstip equals $GTE_CLASS_3DP] }
        default  { set transIP  [class match -value $dstip equals $GTE_CLASS_INTERNET] }
      }
      if { $transIP ne "" } {
        DNS::rdata $rr $transIP
        return
      }
    }
  }
}

Thanks to the DNS services profile, you no longer need to roll your own decodes with binary scan, you can use the DNS:: namespace iRules commands. Because more than one answer could be returned, the foreach loop is utilized to iterate through the list. In the loop, a check for an A record is made, and then a couple variables are setup for the client IP and the GTM response address. Then, the switch sets the translations with data from the data groups (variables established in the full rule linked above) before the resource record data is updated by the DNS::rdata command.

Clever solution, Hamish! What other catch from the codeshare would you like to see highlighted? Post a comment below to let me know!