Forum Discussion
Perry_71428
Nimbostratus
Mar 12, 2009Global variables question
Hi
In the following rule from the CodeBase, is there a way that ::max_active_clients can be changed without the RULE_INIT being fired? When RULE_INIT gets fired the ::total_active_clients will get reset to 0 which is not what I want to happen.
What I want to do is to have a similar rate limiting rule, but be able to manually tweak the ::max_active_clients clients value as the rule is running.
Can a global variable be set in one irule, and then used in another irule?
Also, as I am new to this, do global vaiables have a scope across the whole F5 (all virtual servers / pools) or just the virtual server where they were initialised?
I basically want to have a rule with different values of ::max_active_clients per virtual server - so do I need to use a different global variable name per rule for each virtual server?
Thanks for any help you can give.
rule HTTP_session_limit {
when RULE_INIT {
set ::total_active_clients 0
set ::max_active_clients 100
log local0. "rule session_limit initialized: total/max: $::total_active_clients/$::max_active_clients"
}
when HTTP_REQUEST {
; test cookie presence
if {[HTTP::cookie exists "ClientID"]} {
set need_cookie 0
set client_id [HTTP::cookie "ClientID"]
; if cookie not present & connection limit not reached, set up client_id
} else {
if {$::total_active_clients < $::max_active_clients} {
set need_cookie 1
set client_id [format "%08d" [expr { int(100000000 * rand()) }]]
incr ::total_active_clients
; otherwise redirect
} else {
HTTP::redirect "http://sorry.domain.com/"
return
}
}
}
when HTTP_RESPONSE {
; insert cookie if needed
if {$need_cookie == 1} {
HTTP::cookie insert name "ClientID" value $client_id path "/"
}
}
when CLIENT_CLOSED {
; decrement current connection counter for this client_id
if {$::total_active_clients > 0} {
incr ::total_active_clients -1
}
}
}
6 Replies
- hoolio
Cirrostratus
A global variable is accessible from any iRule on any connection. You can create a separate iRule with a RULE_INIT event and reset the value of the global variable:when RULE_INIT { Update the ::max_active_clients value without affecting the other iRule set ::max_active_clients 2000 }
There is an issue with that Codeshare example though:
In the current iteration of the rule, a new session is created and the total session count incremented on each HTTP request which doesn't already have a session cookie. The only time the total count is decremented is when the TCP connection is closed. So if there are multiple clients connecting over the same TCP connection (ie, coming in via a proxy), "session leakage" would occur. For proxied users, multiple sessions would be created, but only one session removed when the TCP connection is closed. To account for this, you'd have to count the number of new sessions created per TCP connection and then decrement the session count by this count in CLIENT_CLOSED.
Aaron - Perry_71428
Nimbostratus
Thanks
Yes I did see the rule caveat, so no worries there.
So in the scenario that I have two virtual servers VS1 and VS2 and I wax max connections for VS1 to be 100 and for VS2 to be two hundred if could do something like this....
SET_MAX_LIMITS Irulewhen RULE_INIT { Set Global variables value without affecting the other iRule set ::max_active_clients_vs1 100 set ::max_active_clients_vs2 200 }
I would then have 2 copies of the main irule (one assigned to VS1 and one assigned to VS2) that would have RULE_INIT sections like this...when RULE_INIT { Set Global variables value without affecting the other iRule set ::total_active_clients_vs1 0 } remainder of vs1 irule checking against ::max_active_clients_vs1when RULE_INIT { Set Global variables value without affecting the other iRule set ::total_active_clients_vs2 0 } remainder of vs2 irule checking against ::max_active_clients_vs2
When I want to adjust the ::max_active_clients_xxx I just amend the initial irule through the F5 control centre.
The only question I have is do I need to associate the "SET_MAX_LIMITS" irule to VS1 and/or VS2 or can it just sit standalone?
Thanks again. - hoolio
Cirrostratus
It looks like a good understanding of how to handle global variables in multiple iRules. You need to name them uniquely in all iRules to prevent trampling. If you've intentionally named them the same so you can configure one iRule from another, you only need to set the global variable in one iRule. As the global variable can be referenced from any iRule on any virtual server, the rule doesn't need to be added to any specific virtual server. Though, to make it simpler for someone else reading your iRule it might be clearer to explicitly set it in the request limiting iRule on each virtual server, as well as the "configuration" iRule:
vs1_limit_rulewhen RULE_INIT { This max is set here and in the set_max_limits_rule iRule set ::vs1_max 1000 } when HTTP_REQUEST { Rest of iRule code... }
vs2_limit_rulewhen RULE_INIT { This max is set here and in the set_maxes_rule iRule set ::vs2_max 2000 } when HTTP_REQUEST { Rest of iRule code... }
set_max_limits_rulewhen RULE_INIT { This max is set here and in the set_maxes_rule iRule set ::vs1_max 1000 set ::vs2_max 2000 }
Aaron - Perry_71428
Nimbostratus
Thanks Aaron
I have a test only virtual server set up so I'll try this out over the next day or so. Just got to work out the fix for the CLIENT_CLOSED that you mentioned. - Perry_71428
Nimbostratus
Just a thought....
Can you access IRULE global variables through iControl? If so I could create a management panel that would show me current values, alert me when say connections are > 90% of max allowed, and reset them as needed.
Thanks - hoolio
Cirrostratus
I don't think you can access a global variable from the iControl API. But you should be able to access/modify a datagroup or stats profile from iControl. You can poll a stats profile via SNMP as well.
Aaron
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)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
