From: Alan T. DeKok Date: Wed, 16 Aug 2017 07:28:13 +0000 (+0200) Subject: move packets to queue on conn_error() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5ea8a729a082233fe0b1ef575bd547ace32c1949;p=thirdparty%2Ffreeradius-server.git move packets to queue on conn_error() so we can retransmit them --- diff --git a/src/modules/rlm_radius/rlm_radius_udp.c b/src/modules/rlm_radius/rlm_radius_udp.c index 8b93e466827..faaeb324fbd 100644 --- a/src/modules/rlm_radius/rlm_radius_udp.c +++ b/src/modules/rlm_radius/rlm_radius_udp.c @@ -123,8 +123,6 @@ typedef struct rlm_radius_udp_connection_t { fr_ipaddr_t src_ipaddr; //!< my source IP uint16_t src_port; //!< my source port - // @todo - track status-server, open, signaling, etc. - uint8_t *buffer; //!< receive buffer size_t buflen; //!< receive buffer length @@ -394,6 +392,7 @@ static void conn_zombie(rlm_radius_udp_connection_t *c) */ static void conn_error(fr_event_list_t *el, UNUSED int fd, UNUSED int flags, int fd_errno, void *uctx) { + fr_dlist_t *entry; rlm_radius_udp_connection_t *c = talloc_get_type_abort(uctx, rlm_radius_udp_connection_t); ERROR("%s Failed new connection %s: %s", @@ -411,10 +410,30 @@ static void conn_error(fr_event_list_t *el, UNUSED int fd, UNUSED int flags, int (void) fr_event_timer_delete(el, &c->zombie_ev); /* - * @todo - remove timers from sent packets? - * i.e. retransmits when the socket isn't open is - * probably a bad idea... + * Move "sent" packets back to the connection queue, and + * remove their retransmission timers. + * + * @todo - ensure that the retransmission is independent + * of which connection the packet is sent on. This means + * keeping the various timers in 'u' instead of in 'rr'. */ + while ((entry = FR_DLIST_FIRST(c->sent)) != NULL) { + rlm_radius_udp_request_t *u; + + u = fr_ptr_to_type(rlm_radius_udp_request_t, entry, entry); + + (void) rr_track_delete(c->id, u->rr); + u->rr = NULL; + u->c = NULL; + fr_dlist_remove(&u->entry); + + /* + * @todo - when c->queued is a heap, this will + * fix ordering issues. + */ + fr_dlist_insert_tail(&c->queued, &u->entry); + c->pending = true; + } /* * Something bad happened... Fix it... @@ -1449,10 +1468,14 @@ static int conn_free(rlm_radius_udp_connection_t *c) u = fr_ptr_to_type(rlm_radius_udp_request_t, entry, entry); + /* + * Don't bother freeing individual entries. They + * will get deleted when c->id is free'd. + */ u->rr = NULL; u->c = NULL; (void) fr_event_timer_delete(c->thread->el, &u->rr->ev); - fr_dlist_remove(&c->entry); + fr_dlist_remove(&u->entry); fr_dlist_insert_tail(&t->queued, &u->entry); t->pending = true; } @@ -1467,7 +1490,7 @@ static int conn_free(rlm_radius_udp_connection_t *c) u->rr = NULL; u->c = NULL; - fr_dlist_remove(&c->entry); + fr_dlist_remove(&u->entry); fr_dlist_insert_tail(&t->queued, &u->entry); t->pending = true; }