Forum Discussion

Wade_Miller_113's avatar
Wade_Miller_113
Icon for Nimbostratus rankNimbostratus
Nov 12, 2007

Help with a difficult irule.

 

This is not http, but rather a proprietary protocol. Here is the scenario.

 

 

The first packet of the request comes in with a string identifying the desired slot.

 

 

On connect, check a table (probably data group) and if the string is not matched, select arbitrary pool member and persist.

 

 

If the string is matched, select specific pool member and persist.

 

 

 

That is easy enough, but they want more.

 

 

If the string is unmatched, it must write to the lookup table with the string AND the pool member selected.

 

 

 

 

The table would need to be flushed every day when the servers are bounced by cron.

 

 

6 Replies

  • I assume the protocol runs over TCP? You can do most of that with iRule functionaliy:

     

     

    1. Collect the TCP data in the request, using TCP::collect (Click here).

     

     

    2. Parse the data using TCP::payload (Click here).

     

     

    3. Check the session table for an existing entry, and send the request to that node. If there isn't an entry, add one (Click here). The session table entry would include the string, pool member and a timeout.

     

     

    The last requirement to flush the table every 24 hours would probably need to be done using an iControl app (Click here). I don't know of a way to get the current time with the TCL commands enabled in iRules.

     

     

    Aaron
  • You could set the expiration time on your session entry by calculating the time remaining from current time to the cron cycle time using the clock commands.
  • Yes, it is tcp.

     

     

    Wow, I think this will work. Thanks for the pointers. I'm going to code it out and give it a try.

     

     

    I think I may be able to delete the session table entries daily with an icontrol script as mentioned.
  • For the daily session flush, is I stop the servers for say 5 minutes before restarting them would the sessions all terminate or do I need to clean out the sessions manually?
  • It depends on the version. My understanding is that an outage on a server is supposed to trigger the bigip to perform cleanup on the session (and persistence) table for that server, but I have seen that NOT to be the case on a few 9.1.x & 9.2.x versions. I would definitely test this if you are going to rely on that behavior.
  • So far it is working quite well. I need to add handling for error conditions and other refinements. I learned a lot about i-rules with this one.

     

     

    when CLIENT_ACCEPTED {

     

    TCP::collect 44

     

    }

     

    when CLIENT_DATA {

     

    set ConStr [TCP::payload 44]

     

    set SessionID [substr [getfield $ConStr "@" 2] 0 " " ]

     

    log local0.info $SessionID

     

    set PersistTo [session lookup uie $SessionID]

     

    log local0.info $PersistTo

     

    if { $PersistTo equals "" } {

     

    pool [LB::server pool]

     

    log local0.info "No session ID, load balancing the connection."

     

    } else {

     

    pool [LB::server pool] member $PersistTo

     

    log local0.info "$SessionID sent to $PersistTo"

     

    }

     

    }

     

    when SERVER_CONNECTED {

     

    if { $PersistTo equals "" } {

     

    session add uie $SessionID [IP::server_addr]:[serverside {TCP::remote_port}]

     

    log local0.info "Added $SessionID to [IP::server_addr]:[serverside {TCP::remote_port}]"

     

    } else {

     

    log local0.info "$SessionID already exists to $PersistTo"

     

    }

     

    }