Forum Discussion

transmission_co's avatar
transmission_co
Historic F5 Account
Jul 20, 2007

Help with IP::idle_timeout

If one would like to change the idle timeout for a given connection - say, after a database query that is known to take 20 minutes - can IP::idle_timeout accomplish this?

 

 

I have tried adapting the code in the example. My rule runs; however LTM still deletes the connection and emits resets after the idle timeout specified in the associated TCP profile.

 

 

Perhaps I misunderstand this description:

 

 


Description
Returns the idle timeout value, or specifies an idle timeout value as the criteria for selecting the pool to which you want the BIG-IP system to send traffic.

 

 

Intuitively I imagine this iRule command could change the idle timeout for the relevant connection; and the below example reads like it might have that effect. But the above description speaks of selecting a pool.

 

 

Thank you for help understanding IP::idle_timeout or any alternate idea.

 

 

----------

 

 

http://devcentral.f5.com/Wiki/default.aspx/iRules/IP__idle_timeout.html

 

when HTTP_REQUEST {
  if {[HTTP::uri] starts_with "portal" } {
    IP::idle_timeout 3600
  }
}

8 Replies

  • Hi,

     

    I'm having the same issue. How can I check to see which is getting modified? And if it is getting modified on the client side only, is it even possible to set it on the serverside for an HTTP_REQUEST event? The docs don't list it as a valid command.

     

     

    Thanks

     

    -Doug

     

  • Hi Doug,

    You'd want to update the client and serverside idle timeouts if you expect the server to take longer than the default idle timeout to respond. This should ensure that neither the client or server side connections are closed prematurely.

    Here is an example which shows how to do both:

    
    when HTTP_REQUEST {
       if {$some_condition == 1}{
          log local0. "original timeout: [IP::idle_timeout]"
       
          IP::idle_timeout 1801
          log local0. "updated timeout: [IP::idle_timeout]"
          set update_serverside_idle_timeout 1
       }
    }
    when SERVER_CONNECTED {
       log local0. "original timeout: [IP::idle_timeout]"
       if {$update_serverside_idle_timeout}{
          IP::idle_timeout 1802
          log local0. "updated timeout: [IP::idle_timeout]"
       }
    }

    You can check the ltm log for the log output to see that the rule triggered.

    idle_timeout_rule : original timeout: 300

    idle_timeout_rule : updated timeout: 1801

    idle_timeout_rule : original timeout: 300

    idle_timeout_rule : updated timeout: 1802

    And you can check the b conn output for your client IP to see the idle timeout.

    b conn client 10.0.0.10 show all

    VIRTUAL 2.2.2.2:http <-> NODE any6:any

    CLIENTSIDE 10.0.0.10:4161 <-> 2.2.2.2:http

    (pkts,bits) in = (2, 960), out = (1, 528)

    SERVERSIDE 2.2.2.3:4409 <-> 3.3.3.3:80

    (pkts,bits) in = (3, 4952), out = (4, 2440)

    PROTOCOL tcp UNIT 1 IDLE 58 (1802) LASTHOP 4093 00:00:00:e2:1a:2e

    As a test, I set the client and serverside timeouts to different values. When checking the timeout listed in the 'b conn' output it looks like the timeout (listed after the idle count in parens) is set to the timeout of the current connection context. ie, once a clientside connection is established, the timeout listed in the 'b conn' output is the client side timeout. Once the serverside connection is established, the timeout listed is the serverside timeout. I wasn't able to figure out how to list both the client and serverside timeouts. The b conn help output indicates you can use 'b conn client x idle timeout show', but this didn't return the idle timeouts on 9.2.4. I guess that the shorter of the two timeouts is the one that is used, as the second connections would probably be closed if the first is timed out.

    Aaron
  • Aaron,

     

    Thank you for the config; it clears up a lot. But, one piece of information was not supplied to you: the iRule is being hit many times per second with overlapping connections matching different conditions, most of which do not need the timeout updated.

     

     

    After implementing the above on my system I got an error "no such variable" in the when SERVER_CONNECTED tries to read the value. Figuring it was a scoping issue, I added "set update_serverside_idle_timeout 0" to the beginning of the "when HTTP_REQUEST" and the error went away.

     

     

    But, here's what happens:

     

    1. Initial request hits {$some_condition == 1} and the variable is set.

     

    2. A second request comes in (before the 1st request reaches the SERVER_CONNECTED event) and the variable is set back to 0. But since this request is triggering the same iRule but doesn't match the same condition the timeout is not updated.

     

    3. The SERVER_CONNECTED event is reached for the 1st request. Now that the variable was set back to 0 because of the 2nd request, the timeout is not updated.

     

     

    So, being new to iRules and TCL in general, can the variable be scoped so it's available to both events and be limited to an instantiation of an iRule?

     

     

    Thank you,

     

    Doug

     

  • Local variables are valid only for the TCP connection. They are persisted throughout the TCP connection, so that a variable set for one HTTP request will be available (and modifiable) in subsequent requests on the same TCP connection.

     

     

    Is this an accurate summary of the problem?

     

     

    I assume the first client request on the TCP connection is a POST request with a fair amount of data. The rule triggers when the HTTP headers for that request are parsed and the local (valid only for that TCP connection) variable is set to 1. Then, before the first request's data is processed and a server side connection is established (SERVER_CONNECTED), the client sends a second request over the same TCP connection. This request doesn't match the criteria for modifying the timeout, so the variable is set to 0. When the server side connection is established for the first HTTP request, the variable is set to 0, so the timeout isn't modified.

     

     

    This sounds like requests are being pipelined. Though in theory, POST requests shouldn't be pipelined.

     

     

    Is there a proxy server in front of the BIG-IP? Or does the client use pipelining? If you connect directly to the VIP (not through a proxy server) and disable pipelining on the client, does the problem go away? Do you have OneConnect enabled on the HTTP profile or the VIP?

     

     

    Aaron
  • Pipelining isn't what I'm seeing. Two separate people (let's call them Bob and Joe) are making the requests from two different sources at the same time and each match two different conditions in the iRule, only one of which needs the timeout changed. So, connection 2 is stomping on connection 1. The $update_serverside_idle_timeout variable is the "same" between the two. I'd expect there to be one $update_serverside_idle_timeout variable for Bob's session, and another $update_serverside_idle_timeout variable for Joe's session.

     

     

    No proxy server, OneConnect is not enabled on the VIP but OneConnect Transformations is enabled on the standard http profile.

     

     

    Thank you,

     

    Doug

     

  • Ah... that makes a bit more sense. If it's two separate TCP connections, then I assume the issue is that the idle timeout set by IP::idle_timeout isn't connection specific. Can anyone confirm/deny this?

     

     

    Aaron
  • Help...I'd like to know the answer to this too!! maybe it makes sense that it's not connection specific otherwise it would be TCP::idle_timeout? Anyway - would really like an informed response on the exact behaviour.
  • Hi Joanna,

     

     

    The IP::idle_timeout command is connection specific. I'm not sure why it's in the IP namespace though :). I think the issue Joe was seeing was due to OneConnect connection pooling.

     

     

    Aaron