Outlook Anywhere Persistence with Cookie Backup
Problem this snippet solves:
The deployment guide for Microsoft Exchange Server 2007 (http://www.f5.com/pdf/deployment-guides/f5-exchange07-dg.pdf)) specifies that Universal persistence is required for the proper functioning of Outlook Anywhere, and it provides a iRule for this purpose. If the same virtual server is being used for Outlook Web Access, however, you cannot apply a standard cookie persistence profile at the same time.
Therefore, the following iRule expands upon the iRule provided in the deployment guide to reproduce basic cookie persistence behavior. This cookie persistence is not as complete as the built-in cookie persistence feature, but it is functional when load balancing to the default pool.
Code :
when RULE_INIT { # see SOL6917 for cookie encoding details: https://tech.f5.com/home/solutions/sol6917.html set ::debug 0 } when HTTP_REQUEST { set reselect_retries 0 set persistCookieNeeded 0 if { [HTTP::header exists "Authorization"] } { # If we detect this header, do Universal persistence as specified in the deployment document persist uie [HTTP::header "Authorization"] if {$::debug != 0}{log local0. "Outlook client detected at [IP::client_addr]:[TCP::client_port]"} } else { # Implement cookie persistence manually. Will only work with the default pool. if { [HTTP::cookie exists "BIGipServer[LB::server pool]"] } { if { [catch { scan [HTTP::cookie "BIGipServer[LB::server pool]"] "%d.%d.%d" myIpE myPortE unused if {$::debug != 0}{log local0. "myIpD=$myIpE myPortE=$myPortE unused=$unused"} # calculate IP set myIpH [format %08x $myIpE] if {$::debug != 0}{log local0. "myIpH=$myIpH"} set myIpD "[expr 0x[substr $myIpH 6 2]].[expr 0x[substr $myIpH 4 2]].[expr 0x[substr $myIpH 2 2]].[expr 0x[substr $myIpH 0 2]]" if {$::debug != 0}{log local0. "myIpD=$myIpD"} # calculate port set myPortH [format %x $myPortE] if {$::debug != 0}{log local0. "myPortH=$myPortH"} set myPortD [string trimleft [expr 0x[substr $myPortH 2 2]][expr 0x[substr $myPortH 0 2]] 0] if {$::debug != 0}{log local0. "myPortD=$myPortD"} # Send the request to the indicated pool member, cheating to use only port 80 pool [LB::server pool] member $myIpD $myPortD } ] } { set persistCookieNeeded 1 if {$::debug != 0}{log local0. "We could not decipher a cookie with name BIGipServer[LB::server pool]"} } } else { set persistCookieNeeded 1 if {$::debug != 0}{log local0. "We do not detect a cookie with name BIGipServer[LB::server pool]"} } } } when LB_FAILED { if { ( $reselect_retries == 0 ) and ( [active_members [LB::server pool]] > 0 ) } { LB::detach LB::reselect [LB::server pool] set reselect_retries 1 if { not ( [HTTP::header exists "Authorization"] ) } {set persistCookieNeeded 1} if {$::debug != 0}{log local0. "[LB::server pool]/[LB::server addr]:[LB::server port] down, reselecting"} } } when HTTP_RESPONSE { if { $persistCookieNeeded } { # calculate IP section scan [LB::server addr] "%d.%d.%d.%d" poolIP1 poolIP2 poolIP3 poolIP4 set poolIPE [expr $poolIP4 * 16777216 + $poolIP3 * 65536 + $poolIP2 * 256 + $poolIP1 ] if {$::debug != 0}{log local0. "poolIPE=$poolIPE"} # calculate port section set poolPortE [expr 0x[substr [format %04x [LB::server port]] 2 2][substr [format %04x [LB::server port]] 0 2]] if {$::debug != 0}{log local0. "poolPortE=$poolPortE"} # Insert cookie HTTP::cookie insert name "BIGipServer[LB::server pool]" value "$poolIPE.$poolPortE.0000" if {$::debug != 0}{log local0. "BIGipServer[LB::server pool] value is $poolIPE.$poolPortE.0000"} } }
Published Mar 18, 2015
Version 1.0craff_17758
Historic F5 Account
Joined April 24, 2007
craff_17758
Historic F5 Account
Joined April 24, 2007
No CommentsBe the first to comment