struct fr_connection_s {
struct fr_connection_pub_s pub; //!< Public fields
- fr_connection_state_t state; //!< Current connection state.
-
void *uctx; //!< User data.
void *in_handler; //!< Connection is currently in a callback.
#define STATE_TRANSITION(_new) \
do { \
DEBUG2("Connection changed state %s -> %s", \
- fr_table_str_by_value(fr_connection_states, conn->state, "<INVALID>"), \
+ fr_table_str_by_value(fr_connection_states, conn->pub.state, "<INVALID>"), \
fr_table_str_by_value(fr_connection_states, _new, "<INVALID>")); \
- conn->state = _new; \
+ conn->pub.state = _new; \
} while (0)
#define BAD_STATE_TRANSITION(_new) \
do { \
if (!fr_cond_assert_msg(0, "Connection %" PRIu64 " invalid transition %s -> %s", \
conn->pub.id, \
- fr_table_str_by_value(fr_connection_states, conn->state, "<INVALID>"), \
+ fr_table_str_by_value(fr_connection_states, conn->pub.state, "<INVALID>"), \
fr_table_str_by_value(fr_connection_states, _new, "<INVALID>"))) return; \
} while (0)
entry->oneshot ? "oneshot " : "",
entry->func,
conn,
- fr_table_str_by_value(fr_connection_states, conn->state, "<INVALID>"),
+ fr_table_str_by_value(fr_connection_states, conn->pub.state, "<INVALID>"),
entry->uctx);
*/
- entry->func(conn, conn->state, entry->uctx);
+ entry->func(conn, conn->pub.state, entry->uctx);
if (oneshot) talloc_free(entry);
}
*/
#define WATCH_PRE(_conn) \
do { \
- if (fr_dlist_empty(&(_conn)->watch_pre[(_conn)->state])) break; \
- HANDLER_BEGIN(conn, &(_conn)->watch_pre[(_conn)->state]); \
- connection_watch_call((_conn), &(_conn)->watch_pre[(_conn)->state]); \
+ if (fr_dlist_empty(&(_conn)->watch_pre[(_conn)->pub.state])) break; \
+ HANDLER_BEGIN(conn, &(_conn)->watch_pre[(_conn)->pub.state]); \
+ connection_watch_call((_conn), &(_conn)->watch_pre[(_conn)->pub.state]); \
HANDLER_END(conn); \
} while(0)
*/
#define WATCH_POST(_conn) \
do { \
- if (fr_dlist_empty(&(_conn)->watch_post[(_conn)->state])) break; \
- HANDLER_BEGIN(conn, &(_conn)->watch_post[(_conn)->state]); \
- connection_watch_call((_conn), &(_conn)->watch_post[(_conn)->state]); \
+ if (fr_dlist_empty(&(_conn)->watch_post[(_conn)->pub.state])) break; \
+ HANDLER_BEGIN(conn, &(_conn)->watch_post[(_conn)->pub.state]); \
+ connection_watch_call((_conn), &(_conn)->watch_post[(_conn)->pub.state]); \
HANDLER_END(conn); \
} while(0)
{
fr_connection_t *conn = talloc_get_type_abort(uctx, fr_connection_t);
- switch (conn->state) {
+ switch (conn->pub.state) {
case FR_CONNECTION_STATE_FAILED:
case FR_CONNECTION_STATE_CLOSED:
connection_state_init_enter(conn);
*/
static void connection_state_closed_enter(fr_connection_t *conn)
{
- switch (conn->state) {
+ switch (conn->pub.state) {
case FR_CONNECTION_STATE_CONNECTING:
case FR_CONNECTION_STATE_CONNECTED:
case FR_CONNECTION_STATE_FAILED:
{
fr_connection_state_t ret;
- switch (conn->state) {
+ switch (conn->pub.state) {
case FR_CONNECTION_STATE_CONNECTED:
break;
fr_connection_state_t prev;
fr_connection_state_t ret = FR_CONNECTION_STATE_INIT;
- rad_assert(conn->state != FR_CONNECTION_STATE_FAILED);
+ rad_assert(conn->pub.state != FR_CONNECTION_STATE_FAILED);
/*
* Explicit error occurred, delete the connection timer
* Record what state the connection is currently in
* so we can figure out what to do next.
*/
- prev = conn->state;
+ prev = conn->pub.state;
/*
* Now transition to failed
*/
static void connection_state_timeout_enter(fr_connection_t *conn)
{
- switch (conn->state) {
+ switch (conn->pub.state) {
case FR_CONNECTION_STATE_CONNECTING:
case FR_CONNECTION_STATE_SHUTDOWN:
break;
{
int ret;
- rad_assert(conn->state == FR_CONNECTION_STATE_CONNECTING);
+ rad_assert(conn->pub.state == FR_CONNECTION_STATE_CONNECTING);
STATE_TRANSITION(FR_CONNECTION_STATE_CONNECTED);
*/
static void connection_state_connecting_enter(fr_connection_t *conn)
{
- switch (conn->state) {
+ switch (conn->pub.state) {
case FR_CONNECTION_STATE_INIT:
case FR_CONNECTION_STATE_CLOSED:
case FR_CONNECTION_STATE_FAILED:
{
fr_connection_state_t ret;
- switch (conn->state) {
+ switch (conn->pub.state) {
case FR_CONNECTION_STATE_HALTED:
case FR_CONNECTION_STATE_CLOSED:
case FR_CONNECTION_STATE_FAILED:
void fr_connection_signal_init(fr_connection_t *conn)
{
DEBUG2("Signalled to start from %s state",
- fr_table_str_by_value(fr_connection_states, conn->state, "<INVALID>"));
+ fr_table_str_by_value(fr_connection_states, conn->pub.state, "<INVALID>"));
if (conn->in_handler) {
connection_deferred_signal_add(conn, CONNECTION_DSIGNAL_INIT);
return;
}
- switch (conn->state) {
+ switch (conn->pub.state) {
case FR_CONNECTION_STATE_HALTED:
connection_state_init_enter(conn);
break;
rad_assert(!conn->open); /* Use one or the other not both! */
DEBUG2("Signalled connected from %s state",
- fr_table_str_by_value(fr_connection_states, conn->state, "<INVALID>"));
+ fr_table_str_by_value(fr_connection_states, conn->pub.state, "<INVALID>"));
if (conn->in_handler) {
connection_deferred_signal_add(conn, CONNECTION_DSIGNAL_CONNECTED);
return;
}
- switch (conn->state) {
+ switch (conn->pub.state) {
case FR_CONNECTION_STATE_CONNECTING:
connection_state_connected_enter(conn);
break;
void fr_connection_signal_reconnect(fr_connection_t *conn, fr_connection_reason_t reason)
{
DEBUG2("Signalled to reconnect from %s state",
- fr_table_str_by_value(fr_connection_states, conn->state, "<INVALID>"));
+ fr_table_str_by_value(fr_connection_states, conn->pub.state, "<INVALID>"));
if (conn->in_handler) {
if ((reason == FR_CONNECTION_EXPIRED) && conn->shutdown) {
return;
}
- switch (conn->state) {
+ switch (conn->pub.state) {
case FR_CONNECTION_STATE_FAILED: /* Don't circumvent reconnection_delay */
case FR_CONNECTION_STATE_CLOSED: /* Don't circumvent reconnection_delay */
case FR_CONNECTION_STATE_INIT: /* Already initialising */
void fr_connection_signal_shutdown(fr_connection_t *conn)
{
DEBUG2("Signalled to shutdown from %s state",
- fr_table_str_by_value(fr_connection_states, conn->state, "<INVALID>"));
+ fr_table_str_by_value(fr_connection_states, conn->pub.state, "<INVALID>"));
if (conn->in_handler) {
connection_deferred_signal_add(conn, CONNECTION_DSIGNAL_SHUTDOWN);
return;
}
- switch (conn->state) {
+ switch (conn->pub.state) {
case FR_CONNECTION_STATE_HALTED:
case FR_CONNECTION_STATE_SHUTDOWN:
break;
connection_state_shutdown_enter(conn);
break;
}
+ connection_state_closed_enter(conn);
/* FALL-THROUGH */
case FR_CONNECTION_STATE_FAILED:
- connection_state_closed_enter(conn);
+ rad_assert(conn->is_closed);
connection_state_halted_enter(conn);
break;
void fr_connection_signal_halt(fr_connection_t *conn)
{
DEBUG2("Signalled to halt from %s state",
- fr_table_str_by_value(fr_connection_states, conn->state, "<INVALID>"));
+ fr_table_str_by_value(fr_connection_states, conn->pub.state, "<INVALID>"));
if (conn->in_handler) {
connection_deferred_signal_add(conn, CONNECTION_DSIGNAL_HALT);
return;
}
- switch (conn->state) {
+ switch (conn->pub.state) {
case FR_CONNECTION_STATE_HALTED:
break;
case FR_CONNECTION_STATE_CONNECTED:
case FR_CONNECTION_STATE_CONNECTING:
+ connection_state_closed_enter(conn);
/*
* Failed connections need closing too
* else we assert on conn->is_closed
*/
case FR_CONNECTION_STATE_FAILED:
- connection_state_closed_enter(conn);
connection_state_halted_enter(conn);
break;
return -1;
}
- switch (conn->state) {
+ switch (conn->pub.state) {
case FR_CONNECTION_STATE_HALTED:
break;
talloc_set_destructor(conn, _connection_free);
conn->pub.id = atomic_fetch_add_explicit(&connection_counter, 1, memory_order_relaxed);
- conn->state = FR_CONNECTION_STATE_HALTED;
+ conn->pub.state = FR_CONNECTION_STATE_HALTED;
conn->pub.el = el;
conn->pub.h = NULL;
conn->reconnection_delay = conf->reconnection_delay;
# define _CONST
#endif
-/** Public fields for the connection
- *
- * This saves the overhead of using accessors for commonly used fields in
- * connections.
- *
- * Though these fields are public, they should _NOT_ be modified by clients of
- * the connection API.
- */
-struct fr_connection_pub_s {
- uint64_t _CONST id; //!< Unique identifier for the connection.
- void * _CONST h; //!< Connection handle
- fr_event_list_t * _CONST el; //!< Event list for timers and I/O events.
- char const * _CONST log_prefix; //!< Prefix to add to log messages.
-
- uint64_t _CONST reconnected; //!< How many times we've attempted to establish or
- ///< re-establish this connection.
- uint64_t _CONST timed_out; //!< How many times has this connection timed out when
- ///< connecting.
-};
-
typedef enum {
FR_CONNECTION_STATE_HALTED = 0, //!< The connection is in a halted stat. It does not have
///< a valid file descriptor, and it will not try and
FR_CONNECTION_STATE_TIMEOUT, //!< Timeout during #FR_CONNECTION_STATE_CONNECTING.
FR_CONNECTION_STATE_CONNECTED, //!< File descriptor is open (ready for writing).
FR_CONNECTION_STATE_SHUTDOWN, //!< Connection is shutting down.
+ FR_CONNECTION_STATE_FAILED, //!< Connection has failed.
FR_CONNECTION_STATE_CLOSED, //!< Connection has been closed.
- FR_CONNECTION_STATE_FAILED, //!< Connection failed and is waiting to reconnect.
FR_CONNECTION_STATE_MAX
} fr_connection_state_t;
+/** Public fields for the connection
+ *
+ * This saves the overhead of using accessors for commonly used fields in
+ * connections.
+ *
+ * Though these fields are public, they should _NOT_ be modified by clients of
+ * the connection API.
+ */
+struct fr_connection_pub_s {
+ fr_connection_state_t _CONST state; //!< Current connection state.
+ uint64_t _CONST id; //!< Unique identifier for the connection.
+ void * _CONST h; //!< Connection handle
+ fr_event_list_t * _CONST el; //!< Event list for timers and I/O events.
+ char const * _CONST log_prefix; //!< Prefix to add to log messages.
+
+ uint64_t _CONST reconnected; //!< How many times we've attempted to establish or
+ ///< re-establish this connection.
+ uint64_t _CONST timed_out; //!< How many times has this connection timed out when
+ ///< connecting.
+};
+
typedef enum {
FR_CONNECTION_FAILED = 0, //!< Connection is being reconnected because it failed.
FR_CONNECTION_EXPIRED //!< Connection is being reconnected because it's at