Forum Discussion

Dmitry_Kuzura's avatar
Dmitry_Kuzura
Icon for Nimbostratus rankNimbostratus
Nov 17, 2008

need help with iRule that is using a piece of TCP payload for persistence

Guys,

 

need some help with the subject.

 

there is a communication going on between front-end and back-end servers.

 

communication consists of a number of separate TCP connections.

 

when initial connection goes from the front-end to the back-end server, the back-end servers gets picked up from the pool.

 

in reply the back-end server inserts its ID into a payload.

 

When fron-end servers initiates next TCP connection, it is inserting that ID into the payload. I'm using TCP::collect in order to catch that. and I'm able to see that ID. Means it is present and correct.

 

after i catch that ID i'm trying to send this connection to a specific back-end server..and i'm getting Tcl errors about address being in use.

 

tried using LB::detach before pool command - no luck.

 

any ideas?

 

 

when CLIENT_ACCEPTED {

 

TCP::collect 2 56

 

}

 

 

when CLIENT_DATA {

 

if {[TCP::payload 2] == "40" } {

 

pool member

 

log local0. "the ID value is [TCP::payload 2]

 

}

 

elseif {[TCP::payload 2] == "50" } {

 

pool member

 

log local0. "the ID value is [TCP::payload 2]

 

}

 

TCP::release

 

}

 

 

thx!

7 Replies

  • James_Quinby_46's avatar
    James_Quinby_46
    Historic F5 Account
    Are you trying to simply persist based on the payload value you're collecting, or are you trying to send everyone who has value X to one pool/member and everyone with value Y somewhere else?
  • Trying to persist based on the value from the payload.

     

    whoever has value X is going to server X

     

    whoever has value Y is going to server Y

     

    whoever has different value is going through load balancing (did not include that into iRule example)

     

     

    thx!
  • James_Quinby_46's avatar
    James_Quinby_46
    Historic F5 Account
    Could you post the exact rule you're using, and any errors that show up in /var/log/ltm?
  • when CLIENT_ACCEPTED {

     

    TCP::collect 2 56

     

    }

     

     

    when CLIENT_DATA {

     

    if {[TCP::payload 2] == "40" } {

     

    pool member

     

    log local0. "the ID value is [TCP::payload 2]

     

    }

     

    elseif {[TCP::payload 2] == "50" } {

     

    pool member

     

    log local0. "the ID value is [TCP::payload 2]

     

    }

     

    else {

     

    pool

     

    log local0. "initial load balancing"

     

    }

     

    TCP::release

     

    }

     

     

    do not have access to log right now.

     

    it looked like this:

     

     

    Nov 13 12:34:25 tmm tmm[]: 01220001:3: TCL error: Rule HASH-DATA-PERSIST - Address in use (line 7) invoked from within "pool pool member "
  • spark_86682's avatar
    spark_86682
    Historic F5 Account
    The problem is that since you are using the parameter to TCP::collect, the connection to the server is not being held up (see the TCP::collect wiki page for more on this). So by the time your pool commands are running, the server selection has already happened, and the connection to it has already been made. That's why you're getting the "address in use" error. Indeed, it's possible (though unlikely in practice) that some of those 56 bytes you're skipping have already been sent to it.

     

     

    What you should do is a regular "TCP::collect 58" and then in CLIENT_DATA just extract the two bytes you care about; that will hold up server selection and connection allowing you to choose a different server based on those bytes.
  • Spark, you are right about the connection not being held up.

     

    When i skipped first 56 bytes of TCP payload, they were sent to a back-end server as a separate packet.

     

    the rest of the data was sent in a separate packet after...

     

    this is not how back-end servers expect to receive this data. they are expecting all the data to be sent in one packet..

     

    now i'm thinking about catching all the tcp data.

     

    the question i have right now - how i extract the data from the exact location within TCP payload?

     

    i know that interesting data is located in bytes 57 and 58.

     

    How i configure the iRUle to extract that data??? thought the findstr would help me..but having hard time to use it.

     

     

    thanks!