iRules Concepts: Considering Context part 2

In part 1 of this brief series we talked about what context means while coding, how it affects our perception of things and the different contexts within iRules that are inherent and would be covered in this 2 part-er. As a refresher, those contexts are:

  • Clientside
  • Serverside
  • Modifiers & Special Cases
  • Request based
  • Connection based

We've covered the first three, so that leaves us ready to discuss "Request based" & "Connection based" context.

Unlike Clientside vs. Serverside context Request Based context doesn't have anything to do with which side of the proxy the actions are happening on. Likewise it doesn't have to do much with what pieces of information are available when. What we're most concerned about when discussing Request vs. Connection based context is the frequency with which the data being retrieved is updated. Perhaps an odd concept at first, but an important one.

Just like certain data requires an HTTP profile to be retrieved, or can only be accessed in a clientside event, it holds true that some data is retrieved once per connection (Per session) while other data is retrieved for every new request passing through the already established connection. This becomes important for two reasons: Performance, and Accuracy. It is important for performance because less operations means better efficiency, which means higher performance on any given platform. By identifying which pieces of your code may be executed once per connection and removing them from a "per request" event, you'll be able to lower the overall resources required to run your iRule. As far as accuracy is concerned, it's conversely important to ensure that you are checking more often than once per connection for data that may in fact change on a per request basis, especially if that information is being used to make any sort of decision in your deployment. On to the examples.


Request Based

Request based events are by far the majority of events within iRules. Generally speaking, anything having to do with a specific profile is, as a rule of thumb, a request based event. For example:


Note that many of the request based events will have "REQUEST" or "RESPONSE" right in them, making them easy to identify, others take a little more inspection. It's important to understand though that any code placed within any of these events is going to fire any time a pertinent request passes through the BIG-IP. This means that if you set a variable in HTTP_REQUEST, that variable will be set and re-set by every single HTTP request sent through the VIP with the iRule applied. If that variable is updating on particular requests, great, but if not there's likely a better place to put it to save cycles. A common mistake made within HTTP dump nearly all of your code into the HTTP_REQUEST event without thinking about where it may make more sense to house it. By moving some of that code out to other events you may be able to quickly pick up some efficiency.

Connection Based

As you might imagine, Connection based events are the opposite of Request based events. That is, any code executed within a connection based event only occurs once for that connection. There are different Connection based events that happen at different times in the connection, but none of them will repeat themselves within the connection. This means your code will only execute once when put into one of these events:


Yep, that's it, it's a short list when talking about connection based events. There are plenty of other events like DNS_REQUEST or CLIENTSSL_DATA that will almost always only fire once during a connection, but under certain tricky circumstances you can get those to fire multiple times. By my own definition above, that means they're not technically Connection based, as you can't be positive the code you execute within them will only execute once. Even given that, though, DNS_REQUEST is likely to fire less often than HTTP_REQUEST in a normal HTTP connection, so take this short list with a grain of salt. For the sake of accuracy though, I'm leaving it at the two events that definitely only happen once per connection. This means that CLIENT_ACCEPTED is really the magic event here. It happens once per connection, at the very start of the connection, and works with any protocol.

As I said with Request based events, shifting some commands and code into a Connection based event, such as CLIENT_ACCEPTED, can save you cycles. It's important though to be sure you're moving the right code to the right place. Using the example from part1, take a look at what was placed in CLIENT_ACCEPTED.

   1: when CLIENT_ACCEPTED {
   2:   if { ([IP::addr [IP::client_addr] equals]) || ([class match [RESOLV::lookup -ptr [IP::client_addr]] eq authed_hosts]) } {
   3:     set secure 1
   4:   }
   5: }
   7: when HTTP_REQUEST_SEND {
   8:   if {!($secure)} {
   9:     if { ([class match [IP::server_addr] eq secure_servers]) && ([class match [clientside {[HTTP::uri]}] eq uris]) } {
  10:       drop
  11:       log "Bad request from [IP::client_addr] to [IP::server_addr] requesting [clientside {[HTTP::uri]}]"
  12:     }
  13:   }
  14: }

Things like IP based information are a perfect choice for a connection based event, since that information isn't going to change no matter how many requests are sent through a given session, and that information is available within the CLIENT_ACCEPTED event, since it doesn't need any profiles to be accessed. In the above example my first instinct was to put all of the processing code in HTTP_REQUEST_SEND. I realized however that I could save a decent amount of resources by moving the IP and host inspection up to the CLIENT_ACCEPTED event and only doing it once per connection. This is a prime example of Connection vs. Request based events at work and the benefits from understanding the difference when writing an iRule.

Hopefully this conversation about context has been beneficial and can help steer you in the right direction when planning your future iRules.

Published Jul 06, 2011
Version 1.0

Was this article helpful?

No CommentsBe the first to comment