Forum Discussion

Nikolay_Matveev's avatar
Nikolay_Matveev
Icon for Nimbostratus rankNimbostratus
Mar 20, 2015

Universal persistence based on UDP payload - what event to use?

Could some body help to shed some light on the below, please?

I have an application that sends loads of short UDP messages which I need to load balance across two servers. Sometimes the messages are big and the senders chunk them (as per the spec here) and in this case all messages from the same sequence must be sent to the same server.

This seemed to be a relatively straightforward scenario for a custom Universal persistence so I created a rule as follows:

when CLIENT_ACCEPTED {
 if {[UDP::payload length] >= 12 } {

    binary scan [UDP::payload 12] H* chunkedheader
    binary scan [UDP::payload 12] H4H16c1c1 magicbytes messageid seqno seqcount
    incr seqno

    if { $magicbytes equals "1e0f"} {
      log local0. "GrayLog chunked message received. Header: $chunkedheader; ID: $messageid (msg $seqno of $seqcount)"
      persist uie $messageid

    }
 }
}

and it seemed to be working fine:

but I do not understand why 🙂

The thing is that the application sends all datagrams from different source ports. Even the datagrams which are part of the same big chunked message are sent from different source ports. As I understand from BigIP perspective this means that every such datagram is a different UDP session in essense. Is this correct? Then logically, as per the UDP event model described here, I should be using CLIENT_DATA event so that the iRule was triggered on every single datagram received from senders. To my surprise, when I do so the persistence table remains empty! How can this be explained? The result must be the same as with CLIENT_ACCEPTED. And, actually, the latter should not work in unlikely cases when subsequent parts of a chunked application message come from the same port number and thus remaining a part of the same session. I have not observed this (same port numbers) in the samples of traffic which I have captured but as I do not know exact specification and logic of the application I am trying to cover all possible scenarios by using CLIENT_DATA. This does not work which confuses me a lot 😞

5 Replies

  • giltjr's avatar
    giltjr
    Icon for Nimbostratus rankNimbostratus

    UDP is connectionless and there for it has no sessions from a network protocol point of view.

     

    It sounds like the application may have a "session", if so, then there is something that MUST be included in each message that identifies which "session" that message is part of. So as long as your iRule is looking that the correct part of the message, it should work. The only think you might need to look at is how long you keep the persist record around. By default it is 3 minutes after the last reference. So without any time value on your persist command, 3 minutes after the last reference. How long are the "sessions" supposed to last?

     

  • There is no session as such on the application side. The only timeout their protocol specifies relates to a timeslot which all parts of a chunked message should arrive within - and it's 5 seconds. Unfortunately this is not exactly what time-out for an entry in persistence table means.

     

    Though I'm not really concerned about the timeout here. What confuses me is why I am seeing no entries in the persistence table when I am changing iRule event from CLIENT_ACCEPTED to CLIENT_DATA.

     

     

    As per the screenshot above CLIENT_ACCEPTED events are supposed to be a subset of all CLIENT_DATA event in the context of UDP virtual servers but this does not seem to be the case in my scenario.

     

  • giltjr's avatar
    giltjr
    Icon for Nimbostratus rankNimbostratus

    You may want to check the last part of:

     

    https://devcentral.f5.com/wiki/iRules.EventsForUDPVirtualServers.ashx

     

    I think the last part may explain what you are seeing dealing with version specific behavior. It says that starting with 9.4.0 only CLIENT_ACCEPTED is triggered before LB_SELECTED, meaning CLIENT_DATA now is triggered after the LB decision has been made and so it is too late to add a persistence entry and CLIENT_ACCEPTED should be used.