Forum Discussion
hooleylist
Sep 30, 2008Cirrostratus
Here is an updated (but untested) version which checks the connection limit in CLIENT_ACCEPTED and redirects clients who don't already have an existing connection open to a busy page in HTTP_REQUEST. It might be more graceful to allow clients who have established a previous TCP connection to continue opening new TCP connections. This could be done using the session table.
Name : connection limit with HTTP redirect rule
v1.1 - Aaron Hooley, 30 Sept 2008
Purpose:
Limit the number of TCP connections from clients to the virtual server. When the connection limit is reached,
only allow clients who already have an active connection open to the VIP to establish new TCP connections.
Clients who establish a new TCP connection after the limit is reached are sent an HTTP redirect to a busy page.
when RULE_INIT {
Set the maximum number of TCP connections
set ::max_active_IPs 20
Clear the array if it exists
if {[array exists ::active_IPs]}{
array unset ::active_IPs
}
}
when CLIENT_ACCEPTED {
Track whether we'll redirect the client in HTTP_REQUEST
set redirect 0
Check if the current client IP already exists in our array of active client IPs
if { [info exists ::active_IPs([IP::client_addr])] } {
Client exists in the current connection array, so don't redirect them
set redirect 0
} else {
Client didn't have an existing active TCP connection, so check if there are available connection slots
if { [array size ::active_IPs] >= $::max_active_IPs } {
We're over the connection limit, so redirect the client
set redirect 1
} else {
We're allowing the client, so add it to the array
set ::active_IPs([IP::client_addr]) 1
Don't redirect the client
set redirect 0
}
}
}
when HTTP_REQUEST {
If the client connection wasn't allowed in CLIENT_ACCEPTED, redirect them here.
Tell the client to close the TCP connection with Conenction: Close header in response
if {$redirect}{
HTTP::respond 302 "http://busy.example.com" \
"Connection" "Close" \
"Cache-Control" "no-cache" \
"Pragma" "no-cache"
}
}
when CLIENT_CLOSED {
Client connection was closed, so remove the IP address from the array
if { [info exists ::active_IPs([IP::client_addr])] } {
unset ::active_IPs([IP::client_addr])
}
}
Aaron