Sam Hartman <[log in to unmask]> wrote
Wed, 02 Mar 2011 12:56:20 -0500:
| I'll admit I'm not understanding the value of a blocking server,
| particularly given that you can receive from only one connection at a
| time.
True. In the TCP/TLS case at least. Probably most valuable as a test
server.
Hmm. Maybe "blocking" is a bad word for describing what I'm thinking.
The difference between blocking and non-blocking mode is that in
blocking mode, the application doesn't register any callbacks while in
non-blocking it does.
For a comparison, this is what a blocking client (not using the request
object) might look like:
--8<---------------cut here---------------start------------->8---
struct rs_context *ctx;
struct rs_connection *conn;
struct rs_packet *req, *resp;
rs_context_create (&ctx, FREERADIUS_DICTIONARY);
rs_context_read_config (ctx, CONFIG_FILE);
rs_conn_create (ctx, &conn, CONFIG_ENTRY);
rs_packet_create_authn_request (conn, &req, USER_NAME, USER_PW);
err = rs_packet_send (req, NULL);
if (err == RSE_TIMEOUT_CONN)
; /* connection timeout */
if (err == RSE_TIMEOUT_IO)
; /* send timeout */
err = rs_conn_receive_packet (conn, req, &resp);
if (err == RSE_TIMEOUT_IO)
; /* receive timeout */
rs_packet_destroy (req);
/* do something with received packet */
rs_packet_destroy (resp);
--8<---------------cut here---------------end--------------->8---
Compare with the corresponding non-blocking client:
--8<---------------cut here---------------start------------->8---
void on_connected (struct rs_connection *conn, void *d)
{
rs_packet_send ((struct rs_packet *) d, NULL);
}
void on_packet_sent (struct rs_packet *packet, void *d)
{
/* optionally register a timeout event */
}
void on_packet_received (struct rs_packet *packet, void *d)
{
rs_packet_destroy ((struct rs_packet *) d); /* req */
/* do something with received packet */
}
struct rs_context *ctx;
struct rs_connection *conn;
struct rs_packet *req, *resp;
rs_context_create (&ctx, FREERADIUS_DICTIONARY);
rs_context_read_config (ctx, CONFIG_FILE);
rs_conn_create (ctx, &conn, CONFIG_ENTRY);
rs_packet_create_authn_request (conn, &req, USER_NAME, USER_PW);
rs_conn_set_connected_callback (conn, on_connected, req);
rs_conn_set_packet_received_callback (conn, on_packet_received, req);
event_base_dispatch (rs_conn_get_evb (conn));
rs_conn_destroy (conn);
rs_context_destroy (ctx);
--8<---------------cut here---------------end--------------->8---
And yes, rs_packet_send() will have to do retransmission in the UDP/DTLS
case (possibly to another server) and server failover in the TCP/TLS
case.
| However, even if I had a blocking server, why would I want
| read/write/connect timeouts?
| Why wouldn't the single inactivity timer I proposed be sufficient?
A connect timeout is obviously not interesting for a server, agreed.
A read timeout is probably not very interesting for a real RADIUS
server, agreed. A server for testing RADIUS clients might want it
though.
A write timeout could be useful for determining that the client or the
network is not doing what it should. Hmm, is this true? And if it is,
is it interesting? I really don't know.
But the inactivity timeout would be a good thing too!
|