20 Lines or Less #32 – Sip, Counters & Classes
What could you do with your code in 20 Lines or Less? That's the question I ask (almost) every week for the devcentral community, and every week I go looking to find cool new examples that show just how flexible and powerful iRules can be without getting in over your head.
SIP topology hiding forward proxy
http://devcentral.f5.com/s/wiki/default.aspx/iRules/SIP_topology_hiding_and_forward_proxy.html
If you’re passing SIP traffic and want a way to mask the via & or from headers when passing traffic to the outside world, this might be just the rule you’ve been waiting for. It’s a cool look at using iRules for an off the wall issue with a non-HTTP protocol. This is a simplified version of the original iRule to cram it down to less than 21 lines, but the functionality is identical. Just a lot less comments and a few less variables being set. Good stuff.
when SIP_REQUEST {
set originator_ip [IP::remote_addr]
node [IP::local_addr]:[TCP::local_port]
}
when SIP_REQUEST_SEND {
set snat_ip [serverside {IP::local_addr}]
set ip_map [list [findstr [SIP::header From] "@" 1 ">"] $snat_ip]
SIP::header remove from
SIP::header insert from "[string map $ip_map [SIP::header "From"]]"
SIP::header remove via
SIP::header insert via [string map $ip_map [SIP::header "Via"]]
}
when SIP_RESPONSE {
set ip_map [list $snat_ip $originator_ip]
SIP::header remove from
SIP::header insert from "[string map $ip_map [SIP::header "From"]]"
SIP::header remove via
SIP::header insert via [string map $ip_map [SIP::header "Via"]]
}
CMP v10 Compatible counters using the session table
In this codeshare entry hoolio outlines two different ways to set up counters using the session table in v10. The benefit to this is that it’s fully CMP compliant which in certain systems will up performance considerably. It’s also much cooler because the second of the two examples packed into a single iRule shows how to make virtual specific variables for your counters, which is a trick I like a lot. I’m just highlighting the virtual specific version though Aaron showed you how to do both a virtual specific version and a global version in the original post, linked above.
when HTTP_REQUEST {
set vip [virtual name]
set value [session lookup uie "${vip}_my_counter"]
if {$value eq ""}{
session add uie "${vip}_my_counter" 0
} else {
session add uie "${vip}_my_counter" [expr {$value + 1}]
}
}
v10 Class matching
http://devcentral.f5.com/s/Default.aspx?tabid=53&forumid=5&postid=86237&view=topic
In version 10 iRules were given a whole new way to access data groups: the class command. The class command offers a host of new and powerful abilities and Aaron’s making use of one of them in this example. I want to dig into this more and see what other options there might be to achieve what he’s gunning for, but this one isn’t a bad one at all, so I thought I’d highlight it.
# Loop through each class line
for {set i 0} {$i < [class size my_dgl]} {incr i} {
# Use scan to parse the two fields from the class
scan [class element -name $i my_dgl] {%[^ ]%s} my_pattern my_value
# Use string match to evaluate the pattern against the string
if {[string match -nocase $my_pattern [HTTP::uri]]}{
# Found a match
log local0. "Matched $my_pattern, using $my_value"
break
}
}
That’s it for this week. I’ll be out next week for vacation/holiday so check back the week after for more condensed iRule goodness!
#Colin