*/
rlm_radius_udp_request_t *status_u; //!< For Status-Server checks.
rlm_radius_id_t *id; //!< RADIUS ID tracking structure.
+ bool status_check_blocked; //!< if we blocked writing status check packets
} rlm_radius_udp_connection_t;
* Re-initialize the timers.
*/
u->timer.count = 0;
+ c->status_check_blocked = false;
rcode = conn_write(c, u);
if (rcode < 0) {
/*
* If we wrote the packet to the connection, we're done.
*/
- if (rcode != 0) return;
+ if (rcode != 0) {
+ if (u == c->status_u) {
+ c->status_check_blocked = false;
+ }
+ return;
+ }
/*
* EWOULDBLOCK, move the connection to blocked/
conn_transition(c, CONN_BLOCKED);
/*
- * @todo - status packets should get written as soon as
- * the socket becomes writable.
+ * Remember to write status check packets as soon as the
+ * socket becomes writable.
*/
- if (u == c->status_u) return;
+ if (u == c->status_u) {
+ c->status_check_blocked = true;
+ return;
+ }
/*
* Move the packet back to the thread queue, and try to
bool pending = false;
rlm_radius_udp_connection_state_t prev_state = c->state;
rlm_radius_udp_connection_t *next;
+ int rcode;
DEBUG3("%s - Writing packets for connection %s", c->module_name, c->name);
/*
- * @todo - if we have a pending status check packet,
- * write that first.
+ * If we have a pending status check packet, write that
+ * first.
*/
+ if (c->status_check_blocked) {
+ c->status_check_blocked = false;
+ rcode = conn_write(c, c->status_u);
+
+ /*
+ * Error, close the connection.
+ */
+ if (rcode < 0) {
+ talloc_free(c);
+ return;
+ }
+
+ /*
+ * Blocked, don't write anything more to the
+ * connection.
+ */
+ if (rcode == 0) {
+ c->status_check_blocked = true;
+ conn_transition(c, CONN_BLOCKED);
+ return;
+ }
+
+ /*
+ * Written successfully, go write more packets.
+ */
+ }
/*
* Empty the global queue of packets to send.
*/
while ((u = fr_heap_peek(c->thread->queued)) != NULL) {
- int rcode;
-
rad_assert(u->state == PACKET_STATE_QUEUED);
/*