Forum Discussion

Tomasz_Radzisze's avatar
Tomasz_Radzisze
Icon for Nimbostratus rankNimbostratus
Aug 14, 2007

Variable set in SERVER_CONNECTED is unknown in SERVER_DATA

I have a problem with a variable in an iRule. I set a variable "inBody" in the SERVER_CONNECTED event, in which I also call TCP::collect. Then, when TCP data arrives and the SERVER_DATA event is triggered, I got error saying that the variable is not set:

 

Aug 14 10:39:27 tmm tmm[22032]: 01220001:3: TCL error: Rule test - can't read "inBody": no such variable while executing "if { $inBody == 0 } {...

 

The begining of the iRule is as shown below.

 


when SERVER_CONNECTED {
log local0.debug "Connected to HTTP server"
set inBody 0
TCP::collect
}
when SERVER_DATA {
for {set iter 0} {$iter < $maxiter} {incr iter} {
if { $inBody == 0 } {
log local0.debug "Main loop: not in body"
...

 

The error sometimes happens and some times doesn't. I think that a variable set in SERVER_CONNECTED or SERVER_DATA should be local to specific TCP connection. Am I right?

 

I can't make this variable global, because it can have different values in different connections and this is as it should be.

 

Another question: is it guarranteed that SERVER_CONNECTED is triggered before SERVER_DATA for specific connection? From the logs it seems that it is so, but I'm not sure that logs from SERVER_DATA refer to the same connection as the ones from SERVER_CONNECTED

 

 

--edit--

 

I added more logs and changed the code a bit and it seems that sometimes SERVER_DATA is triggered before SERVER_CONNECTED. I solved the problem by checking if the variables are set in server data and setting them if not.
  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    Sounds like your workaround is finding that inBody doesn't exist before you enter the loop, even though the variable is initialized unconditionally?

     

     

    That is not expected behaviour, & I'd suggest opening a Support case referencing this post.

     

     

    I just was talking with one of our iRules developers who indicated that there should always be a CONNECTED event before the DATA event for any connection, and it sounds like you may have encountered a product defect.

     

     

    An alternative workaround would be to store the value in the session table in the CONNECTED event, then retrieving it in the DATA event. (Same workaround we use to save variables from the SSL handshake events for use in HTTP_REQUEST.)

     

     

    HTH

     

    /deb

     

     

    I didn't notice a value being set for your loop control var $maxiter, though.
  • Regarding $maxiter, I cut out part of I rule to simplify it and I cut out too much as you noticed. The variable is set. Regarding my problem, I am now checking if the variable is set at the beginning of both SERVER_CONNECTED and SERVER_DATA events. In both cases, I set it if it isn't set, but I print logs when the behaviour is not as expected, i.e.

     

    - when I find the variable already set in SERVER_CONNECTED,

     

    - when I find the variable unset in SERVER_DATA.

     

     

    I observe both logs from time to time. However, the situation is more complicated, because there is also an iRule for clientside events, which uses LB::detach and node to change associated server during connection. It seems that wrong order of SERVER_CONNECTED and SERVER_DATA occurs just after reselecting server with LB::detach + node. I didn't debug it thoroughly. I'll probably leave it with checking the variables and setting them conditionally, because this solution has proven to work well even in high load tests, when there are several connections active at the same time.
  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    OK, thanks for posting back.

     

     

    I'll try to replicate (and possibly explain) your experience.

     

     

    /deb