Forum Discussion
Alan_Sha
Nimbostratus
Sep 02, 2005How can I trigger a CLIENT_DATA event manually?
I have an iRule that breaks out the client transactions coming from TCP socket and forwards them to different servers based on the content of each request.
The TCP client is working in an asynchronous mode (i.e. the client has two threads, one for sending request, another one for receiving response from the same socket where the request is sent. Therefore, the client can send a whole bunch of requests at the same time without waiting on the response. ). Because it is impossible for iRule to open multiple server connections at the same time, I have to withhold the subsequent requests at the BIG IP while I am sending one request to the destination and waiting on the response. Once I get the response, a LB::detach is issued to release the server connection so that the next request can be re-load balanced.
The problem I am having right now is that because the requests are withheld at the BIG IP buffer, the CLIENT_DATA event (where the request is being analyzed and determined where to go.) will not be triggered immediately after the response is received and the server connection is detached.
For example, the TCP client sends two requests to BIG IP at the same time, BIG IP forwards one to the destination while keeping the other one in the buffer. When I receive the response and detach the server, the CLIENT_DATA event will not be triggered until almost 20 seconds later, which means the second request is waiting on the BIG IP for 20+ seconds later before it is being processed.
My question is: is there a way I can trigger a CLIENT_DATA event right away once the first request is completed? If no, what other ways I can use to delay the requests at the BIG IP?
Thanks
- bl0ndie_127134Historic F5 AccountCurrently the only way to raise events from rule is to use TCP::notify. This rule is 'undocumented' and some what cumbersome to use. Check out this posting for an example of this rule in action.
- Alan_Sha
Nimbostratus
Thanks! I have read that posting before and written similar codes in SERVER_DATA and USER_RESPONSE event. Below is what I am using: - bl0ndie_127134Historic F5 AccountThe purpose of 'TCP::notify response' is to raise the USER_RESPONSE on the client side so that you can detach the serverside connection after all the data has been delivered to the client. You only need to call it once when you have received all the response data.
when SERVER_DATA { log local0.debug "Received SERVER response ... [TCP::payload]" if { [TCP::payload] ends_with $EOT } { TCP::notify response } TCP::release TCP::collect } when USER_RESPONSE { LB::detach log local0.debug "Detaches server connection ... " if {[TCP::payload length] > 0} { %TODO% Process additional client requests here ... } }
- Alan_Sha
Nimbostratus
No. The response is not length delimited. Since only one response is returned at a time and the end of response is always marked with EOT, even the response is segmented into several packets, the last one should always end with EOT, unless something happens and part of the response gets lost (rare case, right?) - Alan_Sha
Nimbostratus
Yes, when the terminator size is more than 1 byte, it is not guaranteed that the terminator will always come in one packet. - drteeth_127330Historic F5 AccountI don't think you need an explicit buffer. The data is implicitly buffered by BIG-IP and is accessible with TCP::payload. If the terminator is split across two or more TCP segments, then you simply need to scan TCP::payload for the complete terminator on each CLIENT_DATA event. Your iRule is operating on the TCP payload. There's not much need to be concerned about packets and segmentation.
- Alan_Sha
Nimbostratus
That's true. But, in my case, the response is quite large. And, it appears that Big IP does not wait until it receives the entire response before it raises the SERVER_DATA event. Therefore, the Big IP could raise the SERVER_DATA event several times for a single response. For each time that the SERVER_DATA event is raised, I simply release the TCP payload so that it can be forwarded back to the client right away. Once the TCP payload is released, the buffered data is gone. When the SERVER_DATA event is raised again, the TCP payload will only contain the latest response data received.
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects