Forum Discussion

Denis's avatar
Denis
Icon for Nimbostratus rankNimbostratus
Jul 21, 2015

Asynchronous multiplexing client requests in oneconnect session

We are in a process of the virtual server configuration that is able to multiplex many client TCP sessions into one server side session. The TCP payload is simple, non-HTTP and session is single request/response oriented. So far we were successful in configuring TCP client session multiplexing using oneconnect profile and customized pool (request queuing) and member (connection limit) options. The communication between clients and server is synchronized, the first client is served first, the second is next and so on. All client's requests beside serviced client are being held in pool queue until serviced client releases the server side of connection.

 

The next task is to achieve asynchronous communication meaning that each client can send its request through oneconnect session toward the server without waiting for previous request to complete.

 

We were successful in sending asynchronously client requests using iRule and LB:detach in CLIENT_DATA event (see bellow). The problem is to reattach server and client side session when server response arrives. When response arrives LTM has no client side connection to send data to.

 

We are thinking to use iRule that keeps global session table with unique id field (taken from client request and which can be found in server response) and any client session identification (that F5 keeps in its connection table), if possible.

 

There are numerous iRule functions that lack any kind of description or example code. Some of them are LB::connect, LB::context_id, LB::src_tag and LB::dst_tag that can be found useful. Is it possible while hitting server side event in iRule to "see" all client side sessions and to reconnect with the specific one?

 

The other approach I have not tested yet is to use UIE persistence with unique data from the request to pair server and client side.

 

Is there a way to reattach client and server side connection using iRule? Or any other mechanism known to you?

 

Thanks for any help.

 

iRule that enables asynchronous requests in one oneconnect session.

 

when CLIENT_ACCEPTED {  
    TCP::collect
}
when CLIENT_DATA {
    TCP::release
    TCP::collect    
    TCP::notify request
}
when USER_REQUEST {
    LB::detach
}
when LB_FAILED {
    log local0. "LB_FAILED"
}
  • Normally, as you observe, oneconnect uses a "serializing" model for message delivery. That is, it delivers a message from client to server, waits for the response, then sends the next request, and so forth. What you want is "pipelining", where client-side messages are delivered as they arrive without regard for responses. The challenge, however, is how to map the response segments back to the proper client. When the message requests are serialized, this is trivial to deduce because only one client-side segment is "inflight" at a time. When the messages are pipelined, however, unless all TCP segments are from the same client, there must be some keying information in the response that can be used to map the response segment to the originating client.

    The LB::src_tag and LB::dst_tag are part of a system called TCP Message-Based Load-Balancing (mblb). If each TCP segment sent contains some key that can be used to match it back to the original client, and the response also contains either a.) the same key; or b.) a key that can be reverse mapped to the original source key, then that is a sensible way handle the condition you describe. This post:

    provides a sample. Basically, the code would extract whatever the identifying message key is from the client-side segment, and invoke LB::src_tag, passing it that key. This associates the client-side connection to that key. Then, when the server responds, you pass the same key to LB::dst_tag and the response will be routed to the original client-side connection. In order to use these, you must add the mblb profile to the Virtual Server. This can only be done with tmsh (that is, it cannot be done using the WebUI).

    It sounds, from your post, that a key of this type is in fact available.

    I believe that when mblb is used with the oneconnect profile, you will get the desired pipelining behavior; namely, BIG-IP will send multiple messages down the server-side connection without waiting for a response (by default, oneconnect will open new server-side connections if multiple client messages need simultaneous delivery), but I haven't tested recently to verify that my memory in this is correct.

    Since TCP mblb is not well-documented, you might consider engaging F5 Professional Services to assist with this endeavor.