Forum Discussion

dragonflymr's avatar
dragonflymr
Icon for Cirrostratus rankCirrostratus
Dec 14, 2015

iRule - which option is better performance wise

Hi,

 

I need to reject request when given number of concurrent HTTP session is created (based on session cookie). So above limit I should not accept more requests.

 

I wonder which way will be less performance hungry. Here is my code:

 

when CLIENT_ACCEPTED {
    log local0. "-"
    TCP::collect

    set mc "my_cookie"
}

when CLIENT_DATA {
    log local0. "-"

    if { [set cv [findstr [TCP::payload] ${mc}= 0 " "]] ne "" } {

        set val [lindex [split $cv "="] 1]

        log local0. "Cookie \"$mc\" found \"$cv\". Value \"$val\""

        log local0. "TCP::payload -> [TCP::payload]"

        TCP::release


    } else {

        TCP::release
        reject
    }

}

I can check if cookie with given name exists in request via TCP::payload and then reject connection in CLIENT_ACCEPTED or I can check cookie existence in HTTP_REQUEST event.

 

Is TCP:collect/payload overhead justified by being able to reject after 3WHS and not waiting on L7 processing in iRule?

 

If so are there any issues with this iRule I should correct?

 

Piotr

 

9 Replies

  • Hi Piotr,

     

    According to this article, CLIENT_DATA occurs after HTTP_REQUEST.

     

    So checking HTTP variables may be better than searching in the entire TCP Payload.

     

  • Hmm,

    I am not so sure about CLIENT_DATA after HTTP_REQUEST - at least it's not explicitly stated like that in article. I think HTTP_REQUEST_DATA might occur after HTTP_REQUEST.

    I tried setting all three events and log execution. result is:

    Dec 14 14:45:30 bigip11 info tmm1[5640]: Rule /Common/http_payload_v2 : CLIENT_ACCEPTED
    Dec 14 14:45:30 bigip11 info tmm1[5640]: Rule /Common/http_payload_v2 : CLIENT_DATA
    Dec 14 14:45:30 bigip11 info tmm1[5640]: Rule /Common/http_payload_v2 : HTTP_REQUEST
    

    Not 100% sure if order of logging = order of execution but it sounds logical.

    Piotr

    • Kai_Wilke's avatar
      Kai_Wilke
      Icon for MVP rankMVP
      I don't think that CLIENT_DATA is triggered after HTTP_REQUEST, since CLIENT_DATA has been used in the past to parse SNI information during SSL-Handshakes (which obvouisly happens before any HTTP data is send). The lovely HTTP-Flow diagram does also states that CLIENT_DATA happend right before HTTP is getting parsed... https://devcentral.f5.com/s/feed/0D51T00006i7X94SAE
  • Hi Piotr,

     

    i dont think that using "TCP::collect" (without specifying a buffer size) would be a good idea. In this case CLIENT_DATA would be triggered on each received "IP-Datagram" and may or may not cover the entire HTTP-request.

     

    So you may get into trouble if someone is sending the HTTP request "CHAR" by "CHAR" and you may also become problems if the HTTP header is spanning multiple IP-Datagrams. To resolve those edge scenarios, you have to check on each received "IP-Datagram" if the entire HTTP-header (or at least the entire Cookie header value) is already received and if not wait for additional CLIENT_DATA.

     

    In the end I'm somewhat sure that it would be much much much faster to use the build in C++ HTTP parser and use the HTTP_REQUEST event for any HTTP related operation.

     

    P.s.: But indeed a very creative approach trying to optimize the Big-PIPE ;-)

     

    Cheers, Kai

     

  • Hi Kai,

     

    My filling was as well that performance wise it's better to use HTTP::cookie value $cookie ne "" in HTTP_REQUEST but you never know :-)

     

    Based on iRule performance stats it as well seems that working in L7 is less cycle hungry that in L4.

     

    Piotr

     

    P.S. Not my idea, just found some iRule posted on the forum and modified it as much I my skills allowed :-)

     

    • Kai_Wilke's avatar
      Kai_Wilke
      Icon for MVP rankMVP
      If you really want to get sure which method is faster, then you may set a timestamp (e.g. set start_time [clock clicks] during "CLIENT_ACCEPTED" and then recheck this timestamp (e.g. [expr { $stop_time - $start_time }] when you have proven the existence of the cookie using the one and the other mothod. But I strongly believe this would be just for coriousity... ;-)
    • dragonflymr's avatar
      dragonflymr
      Icon for Cirrostratus rankCirrostratus
      Curiosity is powerful motivation :-) so maybe I will but I think it's not worth effort in this case... Piotr
  • It's better to use integrated functions than trying to parse all tcp payload with script (irule) to find the cookie values.