Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This patch is trying to provide asynchronous authentification and accounting support for freeRADIUS client library. Since RADIUS is sometimes used in conjonction with tools that
process thousands of packets per second (like SIP proxies for example), asynchronous operations are needed to get rid, as much as possible, from any wait situation which can be fatal at such packets per second rates. Since RADIUS client does not provide such capabilities, we decided that the effort we could have put in developing these features would be far outweighed by the improvements that they could bring to us.
Our application provides a reactor which receives open file descriptors and resume functions, and calls the resume function when the socket is readable. So what we need from RADIUS library was to provide the socket just after the send operation and a resume function to be called when data can be received.
We split rc_aaa function in two rc_aaa_async and rc_aaa_receive so that we can put a reactor in the middle. In order to keep all the parameters we defined a struct called SEND_CONTEXT which contains everything needed for the resume function. Also the socket file descriptor ( sockfd ) is being held inside this structure. Blocking send and receive has been completely removed from the library. If one sends a packet to a server and it does not respond, it is the job of the upper layer application to do this, in order to avoid blocking the process from inside the library. If, by any reason, the server does not respond, the upper layer application can detect this and call the library function again with the SEND_CONTEXT structure that has been returned by the first call. Since we split the rc_aaa function we also needed to split rc_sendserver function. Also, all the parameters used by rc_send_server are being held in SEND_CONTEXT structure.
If rc_aaa_async function was successful, OK_RC and NOT NULL SEND_CONTEXT is returned to the user, else ERROR_RC is returned and NULL SEND_CONTEXT, since no destination responded to our send tries.
rc_aaa_async can also be called with a NOT NULL SEND_CONTEXT meaning that you want to try another destination, since the current one did not respond. The behaviour will be as above, but this time not all destinations shall be tried, only the ones after the current one.
In order to implement asynchronous receive, we needed to define a new return code to signal EWOULDBLOCK/EAGAIN errno’s. We called this return code READBLOCK_RC and it has the identification integer number 3. Else, if receive was successful, OK_RC and NULL SEND_CONTEXT is returned from the library.
From outside the library, rc_acct_async and rc_auth_async functions can be used to try send the message and rc_acct_resume and rc_auth_resume to resume receiving the server response RADIUS message.