]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
use failed callback
authorAlan T. DeKok <aland@freeradius.org>
Fri, 7 Jul 2017 18:36:45 +0000 (14:36 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 7 Jul 2017 18:43:54 +0000 (14:43 -0400)
src/modules/rlm_radius/rlm_radius.c
src/modules/rlm_radius/rlm_radius.h

index c3d132fa44c5893e158f701b786eb8b81dfd9f5b..c165e5b94c0b96a37f4ede8223e2b8e9146f4eff 100644 (file)
@@ -250,28 +250,23 @@ static void mod_radius_conn_error(UNUSED fr_event_list_t *el, int sock, UNUSED i
        fr_connection_reconnect(c->conn);
 }
 
-/** Shutdown/close a file descriptor
+/** Deal with a failure case.
  *
  */
-static void mod_radius_conn_close(int fd, void *uctx)
+static fr_connection_state_t mod_radius_conn_failed(UNUSED int fd, fr_connection_state_t prev, void *uctx)
 {
        rlm_radius_connection_t *c = talloc_get_type_abort(uctx, rlm_radius_connection_t);
        rlm_radius_thread_t     *t = c->thread;
-       rlm_radius_t const      *inst = talloc_get_type_abort(t->inst, rlm_radius_t);
        fr_dlist_t              *entry, *next;
 
        /*
-        *      Tell the IO handler that the socket is closed.  This
-        *      handler should just nuke any data structures it has to
-        *      manage multiple requests (e.g. rbtrees, per-request
-        *      timers), and assume that we will take care of managing
-        *      the REQUESTs
+        *      If it's not trying to reconnect, trash the entire
+        *      connection.
         */
-       inst->client_io->close(c->client_io_ctx);
-
-       DEBUG3("Closing socket (%i)", fd);
-       if (shutdown(fd, SHUT_RDWR) < 0) DEBUG3("Shutdown on socket (%i) failed: %s", fd, fr_syserror(errno));
-       if (close(fd) < 0) DEBUG3("Closing socket (%i) failed: %s", fd, fr_syserror(errno));
+       if (prev != FR_CONNECTION_STATE_CONNECTED) {
+               talloc_free(c);
+               return FR_CONNECTION_STATE_HALTED;
+       }
 
        /*
         *      Remove the connection from whatever list it's in, and
@@ -280,10 +275,10 @@ static void mod_radius_conn_close(int fd, void *uctx)
        fr_dlist_remove(&c->entry);
        fr_dlist_insert_tail(&t->closed, &c->entry);
 
-        /*
-         *     Move any requests from the "sent" back to the
-         *     "queued" list.
-         */
+       /*
+             Move any requests from the "sent" back to the
+             "queued" list.
+        */
        for (entry = FR_DLIST_FIRST(c->sent);
             entry != NULL;
             entry = next) {
@@ -309,14 +304,10 @@ static void mod_radius_conn_close(int fd, void *uctx)
 
        /*
         *      Once the connection is open again, the pending queue
-        *      will be automatically cleared.
-        *
-        *      If the connection DOESN'T open within
-        *      connection_timeout, it will automatically be free'd.
-        *
-        *      If the connection is free'd, the queued packets will
-        *      be moved back to t->queued.
+        *      will be automatically cleared by the "open" callback.
         */
+
+       return FR_CONNECTION_STATE_INIT;
 }
 
 /** Process notification that fd is open
@@ -332,6 +323,13 @@ static fr_connection_state_t mod_radius_conn_open(UNUSED int fd, UNUSED fr_event
 
        DEBUG2("Connected - %s", c->name);
 
+       /*
+        *      Remove the connection from the "frozen" list, and add
+        *      it to the "active" list.
+        */
+       fr_dlist_remove(&c->entry);
+       fr_dlist_insert_tail(&t->active, &c->entry);
+
        /*
         *      If we have data pending, add the writable event immediately
         */
@@ -341,13 +339,6 @@ static fr_connection_state_t mod_radius_conn_open(UNUSED int fd, UNUSED fr_event
                mod_radius_fd_idle(c);
        }
 
-       /*
-        *      Remove the connection from the "frozen" list, and add
-        *      it to the "connected" list.
-        */
-       fr_dlist_remove(&c->entry);
-       fr_dlist_insert_tail(&t->active, &c->entry);
-
        return FR_CONNECTION_STATE_CONNECTED;
 }
 
@@ -368,9 +359,7 @@ static fr_connection_state_t mod_radius_conn_init(int *fd_out, void *uctx)
 }
 
 
-/** Unlink the connection from the thread list.
- *
- *  The connection API will take care of calling our 'close' routine.
+/** The connection is beign free'd
  */
 static int mod_radius_conn_free(rlm_radius_connection_t *c)
 {
@@ -383,7 +372,7 @@ static int mod_radius_conn_free(rlm_radius_connection_t *c)
        fr_dlist_remove(&c->entry);
 
         /*
-         *     Move any requests from the connection "waiting" back to the
+         *     Move any requests from the connection "sent" back to the
          *     thread "queued" list.
          */
        for (entry = FR_DLIST_FIRST(c->sent);
@@ -729,11 +718,20 @@ static int mod_thread_instantiate(CONF_SECTION const *cs, void *instance, fr_eve
         *      This opens the outbound connection
         */
        c->conn = fr_connection_alloc(c, el, &inst->connection_timeout, &inst->reconnection_delay,
-                                     mod_radius_conn_init, mod_radius_conn_open, mod_radius_conn_close,
+                                     mod_radius_conn_init, mod_radius_conn_open, inst->client_io->close,
                                      inst->name, c);
        if (c->conn == NULL) return -1;
 
-       fr_dlist_insert_tail(&t->frozen, &c->entry);
+       /*
+        *      We have to catch errors on failed.
+        */
+       fr_connection_failed_func(c->conn, mod_radius_conn_failed);
+
+       /*
+        *      Add the connection to the "closed" list, because it's
+        *      not open, and there are no requests outstanding on it.
+        */
+       fr_dlist_insert_tail(&t->closed, &c->entry);
 
        fr_connection_start(c->conn);
 
index 3d42db99ed455f36f73e9f98be33761252491aef..28c9ac5b4b6638708952ed92839bd1f3dea054c0 100644 (file)
  */
 typedef int (*fr_radius_client_process_t)(void *thread, REQUEST *request);
 
-/** Close a client IO socket
- *
- */
-typedef int (*fr_radius_client_close_t)(void *uctx);
-
 /** Get a printable name for a socket.
  *
  */
@@ -57,7 +52,7 @@ typedef struct fr_radius_client_io_t {
 
        fr_connection_init_t            init;                   //!< initialize a socket using thread instance data
        fr_connection_open_t            open;                   //!< open a socket using thread instance data
-       fr_radius_client_close_t        close;                  //!< close a socket using thread instance data
+       fr_connection_close_t           close;                  //!< close a socket using thread instance data
        fr_radius_client_name_t         get_name;                       //!< get the name of this socket.
        // get name
        // write