From: Alan T. DeKok Date: Mon, 10 Jul 2017 18:30:07 +0000 (-0400) Subject: make write() work X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ae5f08031656d17de7a769a7aade426e3d4f3783;p=thirdparty%2Ffreeradius-server.git make write() work and add flush, for cases like TLS, where there's data to be written to the socket even when there's no REQUEST --- diff --git a/src/modules/rlm_radius/rlm_radius.c b/src/modules/rlm_radius/rlm_radius.c index 64b386eaa41..86740e7a37b 100644 --- a/src/modules/rlm_radius/rlm_radius.c +++ b/src/modules/rlm_radius/rlm_radius.c @@ -228,12 +228,39 @@ static void mod_radius_conn_read(fr_event_list_t *el, int sock, UNUSED int flags static void mod_radius_conn_writable(UNUSED fr_event_list_t *el, UNUSED int sock, UNUSED int flags, void *uctx) { rlm_radius_connection_t *c = talloc_get_type_abort(uctx, rlm_radius_connection_t); + fr_dlist_t *entry, *next; + bool sent; + + /* + * Send all of the requests to the transport. + */ + for (entry = FR_DLIST_FIRST(c->queued); + entry != NULL; + entry = next) { + rlm_radius_link_t *link; + + link = fr_ptr_to_type(rlm_radius_link_t, entry, entry); - // if no requests, still call client_io->service, as it may have signaling data to write + next = FR_DLIST_NEXT(c->queued, entry); + + rad_assert(link->waiting = false); + + fr_dlist_remove(&link->entry); + fr_dlist_insert_head(&c->sent, &link->entry); + link->waiting = true; + sent = true; - // dequeue a REQUEST - // add it to the socket - // if EWOULDBLOCK, return. + // @todo - if this returns EWOULDBLOCK, stop + // @todo - if this returns "too many requests", stop. But the caller should have checked... + (void) c->inst->client_io->write(link->request, link->request_io_ctx, c->client_io_ctx); + } + + // @todo - maybe grab more packets from t->queued? + + /* + * We didn't send anything, go flush the socket. + */ + if (!sent) (void) c->inst->client_io->flush(c->client_io_ctx); mod_radius_fd_idle(c); } diff --git a/src/modules/rlm_radius/rlm_radius.h b/src/modules/rlm_radius/rlm_radius.h index b012ad15e96..61651745896 100644 --- a/src/modules/rlm_radius/rlm_radius.h +++ b/src/modules/rlm_radius/rlm_radius.h @@ -51,6 +51,10 @@ typedef int (*fr_radius_client_read_t)(REQUEST **p_request, rlm_rcode_t *p_rcode */ typedef int (*fr_radius_client_write_t)(REQUEST *request, void *request_ctx, void *uctx); +/** Flush a socket for writing + * + */ +typedef int (*fr_radius_client_flush_t)(void *uctx); /** Public structure describing an I/O path for an outgoing socket. @@ -77,6 +81,7 @@ typedef struct fr_radius_client_io_t { fr_radius_client_write_t write; //!< write a REQUEST to a socket fr_radius_client_write_t remove; //!< remove a written request from a socket fr_radius_client_read_t read; //!< read a REQUEST from a socket. + fr_radius_client_flush_t flush; //!< flush data for an outgoing socket } fr_radius_client_io_t; #endif /* _RLM_RADIUS_H */