More FR_CONF_OFFSET fixups
[freeradius.git] / src / main / connection.c
1 /*
2  *   This program is free software; you can redistribute it and/or modify
3  *   it under the terms of the GNU General Public License as published by
4  *   the Free Software Foundation; either version 2 of the License, or
5  *   (at your option) any later version.
6  *
7  *   This program is distributed in the hope that it will be useful,
8  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *   GNU General Public License for more details.
11  *
12  *   You should have received a copy of the GNU General Public License
13  *   along with this program; if not, write to the Free Software
14  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16
17 /**
18  * @file connection.c
19  * @brief Handle pools of connections (threads, sockets, etc.)
20  * @note This API must be used by all modules in the public distribution that
21  * maintain pools of connections.
22  *
23  * @copyright 2012  The FreeRADIUS server project
24  * @copyright 2012  Alan DeKok <aland@deployingradius.com>
25  */
26 RCSID("$Id$")
27
28 #include <freeradius-devel/radiusd.h>
29 #include <freeradius-devel/rad_assert.h>
30
31 typedef struct fr_connection fr_connection_t;
32
33 static int fr_connection_pool_check(fr_connection_pool_t *pool);
34
35 extern bool check_config;
36
37 #ifndef NDEBUG
38 #ifdef HAVE_PTHREAD_H
39 /* #define PTHREAD_DEBUG (1) */
40 #endif
41 #endif
42
43 /** An individual connection within the connection pool
44  *
45  * Defines connection counters, timestamps, and holds a pointer to the
46  * connection handle itself.
47  *
48  * @see fr_connection_pool_t
49  */
50 struct fr_connection {
51         fr_connection_t *prev;          //!< Previous connection in list.
52         fr_connection_t *next;          //!< Next connection in list.
53
54         time_t          created;        //!< Time connection was created.
55         time_t          last_used;      //!< Last time the connection was
56                                         //!< reserved.
57
58         uint32_t        num_uses;       //!< Number of times the connection
59                                         //!< has been reserved.
60         uint64_t        number;         //!< Unique ID assigned when the
61                                         //!< connection is created, these will
62                                         //!< monotonically increase over the
63                                         //!< lifetime of the connection pool.
64         void            *connection;    //!< Pointer to whatever the module
65                                         //!< uses for a connection handle.
66         bool            in_use;         //!< Whether the connection is currently
67                                         //!< reserved.
68 #ifdef PTHREAD_DEBUG
69         pthread_t       pthread_id;     //!< When 'in_use == true'
70 #endif
71 };
72
73 /** A connection pool
74  *
75  * Defines the configuration of the connection pool, all the counters and
76  * timestamps related to the connection pool, the mutex that stops multiple
77  * threads leaving the pool in an inconsistent state, and the callbacks
78  * required to open, close and check the status of connections within the pool.
79  *
80  * @see fr_connection
81  */
82 struct fr_connection_pool_t {
83         uint32_t        start;          //!< Number of initial connections
84         uint32_t        min;            //!< Minimum number of concurrent
85                                         //!< connections to keep open.
86         uint32_t        max;            //!< Maximum number of concurrent
87                                         //!< connections to allow.
88         uint32_t        spare;          //!< Number of spare connections to try
89         uint32_t        retry_delay;    //!< seconds to delay re-open
90                                         //!< after a failed open.
91         uint32_t        cleanup_interval; //!< Initial timer for how
92                                           //!< often we sweep the pool
93                                           //!< for free connections.
94                                           //!< (0 is infinite).
95         int             delay_interval;  //!< When we next do a
96                                         //!< cleanup.  Initialized to
97                                         //!< cleanup_interval, and increase
98                                         //!< from there based on the delay.
99         int             next_delay;     //!< The next delay time.
100                                         //!< cleanup.  Initialized to
101                                         //!< cleanup_interval, and decays
102                                         //!< from there.
103         uint32_t        max_uses;       //!< Maximum number of times a
104                                         //!< connection can be used before being
105                                         //!< closed.
106         uint32_t        lifetime;       //!< How long a connection can be open
107                                         //!< before being closed (irrespective
108                                         //!< of whether it's idle or not).
109         uint32_t        idle_timeout;   //!< How long a connection can be idle
110                                         //!< before being closed.
111
112         bool            trigger;        //!< If true execute connection triggers
113                                         //!< associated with the connection
114                                         //!< pool.
115
116         bool            spread;         //!< If true requests will be spread
117                                         //!< across all connections, instead of
118                                         //!< re-using the most recently used
119                                         //!< connections first.
120
121         time_t          last_checked;   //!< Last time we pruned the connection
122                                         //!< pool.
123         time_t          last_spawned;   //!< Last time we spawned a connection.
124         time_t          last_failed;    //!< Last time we tried to spawn a
125                                         //!< a connection but failed.
126         time_t          last_throttled; //!< Last time we refused to spawn a
127                                         //!< connection because the last
128                                         //!< connection failed, or we were
129                                         //!< already spawning a connection.
130         time_t          last_at_max;    //!< Last time we hit the maximum number
131                                         //!< of allowed connections.
132
133         uint64_t        count;          //!< Number of connections spawned over
134                                         //!< the lifetime of the pool.
135         uint32_t        num;            //!< Number of connections in the pool.
136         int             active;         //!< Number of currently reserved
137                                         //!< connections.
138
139         fr_connection_t *head;          //!< Start of the connection list.
140         fr_connection_t *tail;          //!< End of the connection list.
141
142         bool            spawning;       //!< Whether we are currently attempting
143                                         //!< to spawn a new connection.
144
145 #ifdef HAVE_PTHREAD_H
146         pthread_mutex_t mutex;          //!< Mutex used to keep consistent state
147                                         //!< when making modifications in
148                                         //!< threaded mode.
149 #endif
150
151         CONF_SECTION    *cs;            //!< Configuration section holding
152                                         //!< the section of parsed config file
153                                         //!< that relates to this pool.
154         void            *ctx;           //!< Pointer to context data that will
155                                         //!< be passed to callbacks.
156
157         char            *log_prefix;    //!< Log prefix to prepend to all log
158                                         //!< messages created by the connection
159                                         //!< pool code.
160
161         fr_connection_create_t  create; //!< Function used to create new
162                                         //!< connections.
163         fr_connection_alive_t   alive;  //!< Function used to check status
164                                         //!< of connections.
165         fr_connection_delete_t  delete; //!< Function used to close existing
166                                         //!< connections.
167 };
168
169 #define LOG_PREFIX "rlm_%s (%s)"
170 #ifndef HAVE_PTHREAD_H
171 #define pthread_mutex_lock(_x)
172 #define pthread_mutex_unlock(_x)
173 #endif
174
175 static const CONF_PARSER connection_config[] = {
176         { "start",    FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_connection_pool_t, start), "5" },
177         { "min",      FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_connection_pool_t, min), "5" },
178         { "max",      FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_connection_pool_t, max), "10" },
179         { "spare",    FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_connection_pool_t, spare), "3" },
180         { "uses",     FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_connection_pool_t, max_uses), "0" },
181         { "lifetime", FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_connection_pool_t, lifetime), "0" },
182         { "cleanup_delay", FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_connection_pool_t, cleanup_interval), NULL},
183         { "cleanup_interval", FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_connection_pool_t, cleanup_interval), "30" },
184         { "idle_timeout",  FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_connection_pool_t, idle_timeout), "60" },
185         { "retry_delay",  FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_connection_pool_t, retry_delay), "1" },
186         { "spread", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, fr_connection_pool_t, spread), "no" },
187         { NULL, -1, 0, NULL, NULL }
188 };
189
190 /** Removes a connection from the connection list
191  *
192  * @note Must be called with the mutex held.
193  *
194  * @param[in,out] pool to modify.
195  * @param[in] this Connection to delete.
196  */
197 static void fr_connection_unlink(fr_connection_pool_t *pool,
198                                  fr_connection_t *this)
199 {
200         if (this->prev) {
201                 rad_assert(pool->head != this);
202                 this->prev->next = this->next;
203         } else {
204                 rad_assert(pool->head == this);
205                 pool->head = this->next;
206         }
207         if (this->next) {
208                 rad_assert(pool->tail != this);
209                 this->next->prev = this->prev;
210         } else {
211                 rad_assert(pool->tail == this);
212                 pool->tail = this->prev;
213         }
214
215         this->prev = this->next = NULL;
216 }
217
218 /** Adds a connection to the head of the connection list
219  *
220  * @note Must be called with the mutex held.
221  *
222  * @param[in,out] pool to modify.
223  * @param[in] this Connection to add.
224  */
225 static void fr_connection_link_head(fr_connection_pool_t *pool,
226                                     fr_connection_t *this)
227 {
228         rad_assert(pool != NULL);
229         rad_assert(this != NULL);
230         rad_assert(pool->head != this);
231         rad_assert(pool->tail != this);
232
233         if (pool->head) {
234                 pool->head->prev = this;
235         }
236
237         this->next = pool->head;
238         this->prev = NULL;
239         pool->head = this;
240         if (!pool->tail) {
241                 rad_assert(this->next == NULL);
242                 pool->tail = this;
243         } else {
244                 rad_assert(this->next != NULL);
245         }
246 }
247
248 /** Adds a connection to the tail of the connection list
249  *
250  * @note Must be called with the mutex held.
251  *
252  * @param[in,out] pool to modify.
253  * @param[in] this Connection to add.
254  */
255 static void fr_connection_link_tail(fr_connection_pool_t *pool,
256                                     fr_connection_t *this)
257 {
258         rad_assert(pool != NULL);
259         rad_assert(this != NULL);
260         rad_assert(pool->head != this);
261         rad_assert(pool->tail != this);
262
263         if (pool->tail) {
264                 pool->tail->next = this;
265         }
266         this->prev = pool->tail;
267         this->next = NULL;
268         pool->tail = this;
269         if (!pool->head) {
270                 rad_assert(this->prev == NULL);
271                 pool->head = this;
272         } else {
273                 rad_assert(this->prev != NULL);
274         }
275 }
276
277
278 /** Spawns a new connection
279  *
280  * Spawns a new connection using the create callback, and returns it for
281  * adding to the connection list.
282  *
283  * @note Will call the 'open' trigger.
284  * @note Must be called with the mutex free.
285  *
286  * @param[in] pool to modify.
287  * @param[in] now Current time.
288  * @param[in] in_use whether the new connection should be "in_use" or not
289  * @return the new connection struct or NULL on error.
290  */
291 static fr_connection_t *fr_connection_spawn(fr_connection_pool_t *pool,
292                                             time_t now, bool in_use)
293 {
294         fr_connection_t *this;
295         void *conn;
296
297         rad_assert(pool != NULL);
298
299         /*
300          *      Prevent all threads from blocking if the resource
301          *      were managing connections for appears to be unavailable.
302          */
303         if ((pool->num == 0) && pool->spawning) {
304                 return NULL;
305         }
306
307         pthread_mutex_lock(&pool->mutex);
308         rad_assert(pool->num <= pool->max);
309
310         /*
311          *      Don't spawn multiple connections at the same time.
312          */
313         if (pool->spawning) {
314                 pthread_mutex_unlock(&pool->mutex);
315
316                 ERROR("%s: Cannot open new connection, "
317                       "connection spawning already in "
318                       "progress", pool->log_prefix);
319                 return NULL;
320         }
321
322         /*
323          *      If the last attempt failed, wait a bit before
324          *      retrying.
325          */
326         if (pool->last_failed && ((pool->last_failed + pool->retry_delay) > now)) {
327                 bool complain = false;
328
329                 if (pool->last_throttled != now) {
330                         complain = true;
331
332                         pool->last_throttled = now;
333                 }
334
335                 pthread_mutex_unlock(&pool->mutex);
336
337                 if (!RATE_LIMIT_ENABLED || complain) {
338                         ERROR("%s: Last connection attempt failed, waiting %d seconds before retrying",
339                               pool->log_prefix, pool->retry_delay);
340                 }
341
342                 return NULL;
343         }
344
345         pool->spawning = true;
346
347         /*
348          *      Unlock the mutex while we try to open a new
349          *      connection.  If there are issues with the back-end,
350          *      opening a new connection may take a LONG time.  In
351          *      that case, we want the other connections to continue
352          *      to be used.
353          */
354         pthread_mutex_unlock(&pool->mutex);
355
356         INFO("%s: Opening additional connection (%" PRIu64 ")", pool->log_prefix, pool->count);
357
358         /*
359          *      This may take a long time, which prevents other
360          *      threads from releasing connections.  We don't care
361          *      about other threads opening new connections, as we
362          *      already have no free connections.
363          */
364         conn = pool->create(pool->ctx);
365         if (!conn) {
366                 ERROR("%s: Opening connection failed (%" PRIu64 ")", pool->log_prefix, pool->count);
367
368                 pool->last_failed = now;
369                 pool->spawning = false; /* atomic, so no lock is needed */
370                 return NULL;
371         }
372
373         /*
374          *      And lock the mutex again while we link the new
375          *      connection back into the pool.
376          */
377         pthread_mutex_lock(&pool->mutex);
378
379         this = talloc_zero(pool, fr_connection_t);
380         if (!this) {
381                 pthread_mutex_unlock(&pool->mutex);
382                 return NULL;
383         }
384
385         this->created = now;
386         this->connection = conn;
387         this->in_use = in_use;
388
389         this->number = pool->count++;
390         this->last_used = now;
391         fr_connection_link_head(pool, this);
392         pool->num++;
393         pool->spawning = false;
394         pool->last_spawned = time(NULL);
395         pool->delay_interval = pool->cleanup_interval;
396         pool->next_delay = pool->cleanup_interval;
397         pool->last_failed = 0;
398
399         pthread_mutex_unlock(&pool->mutex);
400
401         if (pool->trigger) exec_trigger(NULL, pool->cs, "open", true);
402
403         return this;
404 }
405
406 /** Close an existing connection.
407  *
408  * Removes the connection from the list, calls the delete callback to close
409  * the connection, then frees memory allocated to the connection.
410  *
411  * @note Will call the 'close' trigger.
412  * @note Must be called with the mutex held.
413  *
414  * @param[in,out] pool to modify.
415  * @param[in,out] this Connection to delete.
416
417  */
418 static void fr_connection_close(fr_connection_pool_t *pool,
419                                 fr_connection_t *this)
420 {
421         /*
422          *      If it's in use, release it.
423          */
424         if (this->in_use) {
425 #ifdef PTHREAD_DEBUG
426                 pthread_t pthread_id = pthread_self();
427                 rad_assert(pthread_equal(this->pthread_id, pthread_id) != 0);
428 #endif
429                 this->in_use = false;
430
431                 rad_assert(pool->active > 0);
432                 pool->active--;
433         }
434
435         if (pool->trigger) exec_trigger(NULL, pool->cs, "close", true);
436
437         fr_connection_unlink(pool, this);
438         pool->delete(pool->ctx, this->connection);
439         rad_assert(pool->num > 0);
440         pool->num--;
441         talloc_free(this);
442 }
443
444 /** Find a connection handle in the connection list
445  *
446  * Walks over the list of connections searching for a specified connection
447  * handle and returns the first connection that contains that pointer.
448  *
449  * @note Will lock mutex and only release mutex if connection handle
450  * is not found, so will usually return will mutex held.
451  * @note Must be called with the mutex free.
452  *
453  * @param[in] pool to search in.
454  * @param[in] conn handle to search for.
455  * @return the connection containing the specified handle, or NULL if non is
456  * found.
457  */
458 static fr_connection_t *fr_connection_find(fr_connection_pool_t *pool, void *conn)
459 {
460         fr_connection_t *this;
461
462         if (!pool || !conn) return NULL;
463
464         pthread_mutex_lock(&pool->mutex);
465
466         /*
467          *      FIXME: This loop could be avoided if we passed a 'void
468          *      **connection' instead.  We could use "offsetof" in
469          *      order to find top of the parent structure.
470          */
471         for (this = pool->head; this != NULL; this = this->next) {
472                 if (this->connection == conn) {
473 #ifdef PTHREAD_DEBUG
474                         pthread_t pthread_id;
475
476                         pthread_id = pthread_self();
477                         rad_assert(pthread_equal(this->pthread_id, pthread_id) != 0);
478 #endif
479
480                         rad_assert(this->in_use == true);
481                         return this;
482                 }
483         }
484
485         pthread_mutex_unlock(&pool->mutex);
486         return NULL;
487 }
488
489 /** Delete a connection from the connection pool.
490  *
491  * Resolves the connection handle to a connection, then (if found)
492  * closes, unlinks and frees that connection.
493  *
494  * @note Must be called with the mutex free.
495  *
496  * @param[in,out] pool Connection pool to modify.
497  * @param[in] conn to delete.
498  * @return 0 if the connection could not be found, else 1.
499  */
500 int fr_connection_del(fr_connection_pool_t *pool, void *conn)
501 {
502         fr_connection_t *this;
503
504         this = fr_connection_find(pool, conn);
505         if (!this) return 0;
506
507         INFO("%s: Deleting connection (%" PRIu64 ")", pool->log_prefix, this->number);
508
509         fr_connection_close(pool, this);
510         fr_connection_pool_check(pool);
511         return 1;
512 }
513
514 /** Delete a connection pool
515  *
516  * Closes, unlinks and frees all connections in the connection pool, then frees
517  * all memory used by the connection pool.
518  *
519  * @note Will call the 'stop' trigger.
520  * @note Must be called with the mutex free.
521  *
522  * @param[in,out] pool to delete.
523  */
524 void fr_connection_pool_delete(fr_connection_pool_t *pool)
525 {
526         fr_connection_t *this, *next;
527
528         if (!pool) return;
529
530         DEBUG("%s: Removing connection pool", pool->log_prefix);
531
532         pthread_mutex_lock(&pool->mutex);
533
534         for (this = pool->head; this != NULL; this = next) {
535                 next = this->next;
536
537                 INFO("%s: Closing connection (%" PRIu64 ")", pool->log_prefix, this->number);
538
539                 fr_connection_close(pool, this);
540         }
541
542         if (pool->trigger) exec_trigger(NULL, pool->cs, "stop", true);
543
544         rad_assert(pool->head == NULL);
545         rad_assert(pool->tail == NULL);
546         rad_assert(pool->num == 0);
547
548         talloc_free(pool);
549 }
550
551 /** Create a new connection pool
552  *
553  * Allocates structures used by the connection pool, initialises the various
554  * configuration options and counters, and sets the callback functions.
555  *
556  * Will also spawn the number of connections specified by the 'start'
557  * configuration options.
558  *
559  * @note Will call the 'start' trigger.
560  *
561  * @param[in] parent configuration section containing a 'pool' subsection.
562  * @param[in] ctx pointer to pass to callbacks.
563  * @param[in] c Callback to create new connections.
564  * @param[in] a Callback to check the status of connections.
565  * @param[in] d Callback to delete connections.
566  * @param[in] prefix to prepend to all log message, if NULL will create prefix
567  *      from parent conf section names.
568  * @return A new connection pool or NULL on error.
569  */
570 fr_connection_pool_t *fr_connection_pool_init(CONF_SECTION *parent,
571                                               void *ctx,
572                                               fr_connection_create_t c,
573                                               fr_connection_alive_t a,
574                                               fr_connection_delete_t d,
575                                               char const *prefix)
576 {
577         uint32_t i;
578         fr_connection_pool_t *pool;
579         fr_connection_t *this;
580         CONF_SECTION *modules;
581         CONF_SECTION *cs;
582         char const *cs_name1, *cs_name2;
583         time_t now = time(NULL);
584
585         if (!parent || !ctx || !c || !d) return NULL;
586
587         cs = cf_section_sub_find(parent, "pool");
588         if (!cs) cs = cf_section_sub_find(parent, "limit");
589
590         if (cs) {
591                 pool = talloc_zero(cs, fr_connection_pool_t);
592         } else {
593                 pool = talloc_zero(parent, fr_connection_pool_t);
594         }
595         if (!pool) return NULL;
596
597         pool->cs = cs;
598         pool->ctx = ctx;
599         pool->create = c;
600         pool->alive = a;
601         pool->delete = d;
602
603         pool->head = pool->tail = NULL;
604
605 #ifdef HAVE_PTHREAD_H
606         pthread_mutex_init(&pool->mutex, NULL);
607 #endif
608
609         if (!prefix) {
610                 modules = cf_item_parent(cf_sectiontoitem(parent));
611                 if (modules) {
612                         cs_name1 = cf_section_name1(modules);
613                         if (cs_name1 && (strcmp(cs_name1, "modules") == 0)) {
614                                 cs_name1 = cf_section_name1(parent);
615                                 cs_name2 = cf_section_name2(parent);
616                                 if (!cs_name2) {
617                                         cs_name2 = cs_name1;
618                                 }
619
620                                 pool->log_prefix = talloc_typed_asprintf(pool, LOG_PREFIX, cs_name1,
621                                                                    cs_name2);
622                         }
623                 } else {                /* not a module configuration */
624                         cs_name1 = cf_section_name1(parent);
625
626                         pool->log_prefix = talloc_typed_strdup(pool, cs_name1);
627                 }
628         } else {
629                 pool->log_prefix = talloc_typed_strdup(pool, prefix);
630         }
631
632         DEBUG("%s: Initialising connection pool", pool->log_prefix);
633
634         if (cs) {
635                 if (cf_section_parse(cs, pool, connection_config) < 0) {
636                         goto error;
637                 }
638
639                 if (cf_section_sub_find(cs, "trigger")) pool->trigger = true;
640         } else {
641                 pool->start = 5;
642                 pool->min = 5;
643                 pool->max = 10;
644                 pool->spare = 3;
645                 pool->cleanup_interval = 30;
646                 pool->idle_timeout = 60;
647         }
648
649         /*
650          *      Some simple limits
651          */
652         if (pool->max == 0) {
653                 cf_log_err_cs(cs, "Cannot set 'max' to zero");
654                 goto error;
655         }
656         if (pool->min > pool->max) {
657                 cf_log_err_cs(cs, "Cannot set 'min' to more than 'max'");
658                 goto error;
659         }
660
661         if (pool->max > 1024) pool->max = 1024;
662         if (pool->start > pool->max) pool->start = pool->max;
663         if (pool->spare > (pool->max - pool->min)) {
664                 pool->spare = pool->max - pool->min;
665         }
666         if ((pool->lifetime > 0) && (pool->idle_timeout > pool->lifetime)) {
667                 pool->idle_timeout = 0;
668         }
669
670         if ((pool->idle_timeout > 0) && (pool->cleanup_interval > pool->idle_timeout)) {
671                 pool->cleanup_interval = pool->idle_timeout;
672         }
673
674         /*
675          *      Don't open any connections.  Instead, force the limits
676          *      to only 1 connection.
677          *
678          */
679         if (check_config) {
680                 pool->start = pool->min = pool->max = 1;
681                 return pool;
682         }
683
684         /*
685          *      Create all of the connections, unless the admin says
686          *      not to.
687          */
688         for (i = 0; i < pool->start; i++) {
689                 this = fr_connection_spawn(pool, now, false);
690                 if (!this) {
691                 error:
692                         fr_connection_pool_delete(pool);
693                         return NULL;
694                 }
695         }
696
697         if (pool->trigger) exec_trigger(NULL, pool->cs, "start", true);
698
699         return pool;
700 }
701
702
703 /** Check whether a connection needs to be removed from the pool
704  *
705  * Will verify that the connection is within idle_timeout, max_uses, and
706  * lifetime values. If it is not, the connection will be closed.
707  *
708  * @note Will only close connections not in use.
709  * @note Must be called with the mutex held.
710  *
711  * @param[in,out] pool to modify.
712  * @param[in,out] this Connection to manage.
713  * @param[in] now Current time.
714  * @return 0 if the connection was closed, otherwise 1.
715  */
716 static int fr_connection_manage(fr_connection_pool_t *pool,
717                                 fr_connection_t *this,
718                                 time_t now)
719 {
720         rad_assert(pool != NULL);
721         rad_assert(this != NULL);
722
723         /*
724          *      Don't terminated in-use connections
725          */
726         if (this->in_use) return 1;
727
728         if ((pool->max_uses > 0) &&
729             (this->num_uses >= pool->max_uses)) {
730                 DEBUG("%s: Closing expired connection (%" PRIu64 "): Hit max_uses limit", pool->log_prefix,
731                       this->number);
732         do_delete:
733                 if (pool->num <= pool->min) {
734                         RATE_LIMIT(WARN("%s: You probably need to lower \"min\"", pool->log_prefix));
735                 }
736                 fr_connection_close(pool, this);
737                 return 0;
738         }
739
740         if ((pool->lifetime > 0) &&
741             ((this->created + pool->lifetime) < now)) {
742                 DEBUG("%s: Closing expired connection (%" PRIu64 ")", pool->log_prefix, this->number);
743                 goto do_delete;
744         }
745
746         if ((pool->idle_timeout > 0) &&
747             ((this->last_used + pool->idle_timeout) < now)) {
748                 INFO("%s: Closing connection (%" PRIu64 "): Hit idle_timeout, was idle for %u seconds",
749                      pool->log_prefix, this->number, (int) (now - this->last_used));
750                 goto do_delete;
751         }
752
753         return 1;
754 }
755
756
757 /** Check whether any connections needs to be removed from the pool
758  *
759  * Maintains the number of connections in the pool as per the configuration
760  * parameters for the connection pool.
761  *
762  * @note Will only run checks the first time it's called in a given second,
763  * to throttle connection spawning/closing.
764  * @note Will only close connections not in use.
765  * @note Must be called with the mutex held, will release mutex before
766  * returning.
767  *
768  * @param[in,out] pool to manage.
769  * @return 1
770  */
771 static int fr_connection_pool_check(fr_connection_pool_t *pool)
772 {
773         uint32_t spawn, idle, extra;
774         time_t now = time(NULL);
775         fr_connection_t *this, *next;
776
777         if (pool->last_checked == now) {
778                 pthread_mutex_unlock(&pool->mutex);
779                 return 1;
780         }
781
782         /*
783          *      Some idle connections are OK, if they're within the
784          *      configured "spare" range.  Any extra connections
785          *      outside of that range can be closed.
786          */
787         idle = pool->num - pool->active;
788         if (idle <= pool->spare) {
789                 extra = 0;
790         } else {
791                 extra = idle - pool->spare;
792         }
793
794         /*
795          *      The other end can close connections.  If so, we'll
796          *      have fewer than "min".  When that happens, open more
797          *      connections to enforce "min".
798          */
799         if (pool->num <= pool->min) {
800                 if (pool->spawning) {
801                         spawn = 0;
802                 } else {
803                         spawn = pool->min - pool->num;
804                 }
805                 extra = 0;
806
807         } else if (pool->num >= pool->max) {
808                 /*
809                  *      Ensure we don't spawn more connections.  If
810                  *      there are extra idle connections, we can
811                  *      delete all of them.
812                  */
813                 spawn = 0;
814                 /* leave extra alone from above */
815
816         } else if (idle <= pool->spare) {
817                 /*
818                  *      Not enough spare connections.  Spawn a few.
819                  *      But cap the pool size at "max"
820                  */
821                 spawn = pool->spare - idle;
822                 extra = 0;
823
824                 if ((pool->num + spawn) > pool->max) {
825                         spawn = pool->max - pool->num;
826                 }
827
828         } else if ((pool->min + extra) >= pool->num) {
829                 /*
830                  *      If closing the extra connections would take us
831                  *      below "min", then don't do that.  Cap the
832                  *      spare connections at the ones which will take
833                  *      us exactly to "min".
834                  */
835                 spawn = 0;
836                 extra = pool->num - pool->min;
837
838         } else {
839                 /*
840                  *      Closing the "extra" connections won't take us
841                  *      below "min".  It's therefore safe to close
842                  *      them all.
843                  */
844                 spawn = 0;
845                 /* leave extra alone from above */
846         }
847
848         if (spawn) {
849                 pthread_mutex_unlock(&pool->mutex);
850                 fr_connection_spawn(pool, now, false); /* ignore return code */
851                 pthread_mutex_lock(&pool->mutex);
852         }
853
854         /*
855          *      We haven't spawned connections in a while, and there
856          *      are too many spare ones.  Close the one which has been
857          *      unused for the longest.
858          */
859         if (extra && (now >= (pool->last_spawned + pool->delay_interval))) {
860                 fr_connection_t *found;
861
862                 found = NULL;
863                 for (this = pool->tail; this != NULL; this = this->prev) {
864                         if (this->in_use) continue;
865
866                         if (!found ||
867                            (this->last_used < found->last_used)) {
868                                 found = this;
869                         }
870                 }
871
872                 rad_assert(found != NULL);
873
874                 INFO("%s: Closing connection (%" PRIu64 "), from %d unused connections", pool->log_prefix,
875                      found->number, extra);
876                 fr_connection_close(pool, found);
877
878                 /*
879                  *      Decrease the delay for the next time we clean
880                  *      up.
881                  */
882                 pool->next_delay >>= 1;
883                 if (pool->next_delay == 0) pool->next_delay = 1;
884                 pool->delay_interval += pool->next_delay;
885         }
886
887         /*
888          *      Pass over all of the connections in the pool, limiting
889          *      lifetime, idle time, max requests, etc.
890          */
891         for (this = pool->head; this != NULL; this = next) {
892                 next = this->next;
893                 fr_connection_manage(pool, this, now);
894         }
895
896         pool->last_checked = now;
897         pthread_mutex_unlock(&pool->mutex);
898
899         return 1;
900 }
901
902 /** Get a connection from the connection pool
903  *
904  * @param[in,out] pool to reserve the connection from.
905  * @param[in] spawn whether to spawn a new connection
906  * @return a pointer to the connection handle, or NULL on error.
907  */
908 static void *fr_connection_get_internal(fr_connection_pool_t *pool, int spawn)
909 {
910         time_t now;
911         fr_connection_t *this, *next;
912
913         if (!pool) return NULL;
914
915         pthread_mutex_lock(&pool->mutex);
916
917         now = time(NULL);
918         for (this = pool->head; this != NULL; this = next) {
919                 next = this->next;
920
921                 if (!this->in_use) goto do_return;
922         }
923
924         if (pool->num == pool->max) {
925                 bool complain = false;
926
927                 /*
928                  *      Rate-limit complaints.
929                  */
930                 if (pool->last_at_max != now) {
931                         complain = true;
932                         pool->last_at_max = now;
933                 }
934
935                 pthread_mutex_unlock(&pool->mutex);
936
937                 if (!RATE_LIMIT_ENABLED || complain) {
938                         ERROR("%s: No connections available and at max connection limit", pool->log_prefix);
939                 }
940
941                 return NULL;
942         }
943
944         pthread_mutex_unlock(&pool->mutex);
945
946         if (!spawn) return NULL;
947
948         this = fr_connection_spawn(pool, now, true); /* MY connection! */
949         if (!this) return NULL;
950         pthread_mutex_lock(&pool->mutex);
951
952 do_return:
953         pool->active++;
954         this->num_uses++;
955         this->last_used = now;
956         this->in_use = true;
957
958 #ifdef PTHREAD_DEBUG
959         this->pthread_id = pthread_self();
960 #endif
961         pthread_mutex_unlock(&pool->mutex);
962
963         DEBUG("%s: Reserved connection (%" PRIu64 ")", pool->log_prefix, this->number);
964
965         return this->connection;
966 }
967
968
969 /** Reserve a connection in the connection pool
970  *
971  * Will attempt to find an unused connection in the connection pool, if one is
972  * found, will mark it as in in use increment the number of active connections
973  * and return the connection handle.
974  *
975  * If no free connections are found will attempt to spawn a new one, conditional
976  * on a connection spawning not already being in progress, and not being at the
977  * 'max' connection limit.
978  *
979  * @note fr_connection_release must be called once the caller has finished
980  * using the connection.
981  *
982  * @see fr_connection_release
983  * @param[in,out] pool to reserve the connection from.
984  * @return a pointer to the connection handle, or NULL on error.
985  */
986 void *fr_connection_get(fr_connection_pool_t *pool)
987 {
988         return fr_connection_get_internal(pool, true);
989 }
990
991 /** Get the number of connections currently in the pool
992  *
993  * @param pool to count connections for.
994  * @return the number of connections in the pool
995  */
996 int fr_connection_get_num(fr_connection_pool_t *pool)
997 {
998         return pool->num;
999 }
1000
1001 /** Release a connection
1002  *
1003  * Will mark a connection as unused and decrement the number of active
1004  * connections.
1005  *
1006  * @see fr_connection_get
1007  * @param[in,out] pool to release the connection in.
1008  * @param[in,out] conn to release.
1009  */
1010 void fr_connection_release(fr_connection_pool_t *pool, void *conn)
1011 {
1012         fr_connection_t *this;
1013
1014         this = fr_connection_find(pool, conn);
1015         if (!this) return;
1016
1017         this->in_use = false;
1018
1019         /*
1020          *      Determines whether the last used connection gets
1021          *      re-used first.
1022          */
1023         if (pool->spread) {
1024                 /*
1025                  *      Put it at the tail of the list, so
1026                  *      that it will get re-used last.
1027                  */
1028                 if (this != pool->tail) {
1029                         fr_connection_unlink(pool, this);
1030                         fr_connection_link_tail(pool, this);
1031                 }
1032         } else {
1033                 /*
1034                  *      Put it at the head of the list, so
1035                  *      that it will get re-used quickly.
1036                  */
1037                 if (this != pool->head) {
1038                         fr_connection_unlink(pool, this);
1039                         fr_connection_link_head(pool, this);
1040                 }
1041         }
1042
1043         rad_assert(pool->active > 0);
1044         pool->active--;
1045
1046         DEBUG("%s: Released connection (%" PRIu64 ")", pool->log_prefix, this->number);
1047
1048         /*
1049          *      We mirror the "spawn on get" functionality by having
1050          *      "delete on release".  If there are too many spare
1051          *      connections, go manage the pool && clean some up.
1052          */
1053         fr_connection_pool_check(pool);
1054 }
1055
1056 /** Reconnect a suspected inviable connection
1057  *
1058  * This should be called by the module if it suspects that a connection is
1059  * not viable (e.g. the server has closed it).
1060  *
1061  * Will attempt to create a new connection handle using the create callback,
1062  * and if this is successful the new handle will be assigned to the existing
1063  * pool connection.
1064  *
1065  * If this is not successful, the connection will be removed from the pool.
1066  *
1067  * When implementing a module that uses the connection pool API, it is advisable
1068  * to pass a pointer to the pointer to the handle (void **conn)
1069  * to all functions which may call reconnect. This is so that if a new handle
1070  * is created and returned, the handle pointer can be updated up the callstack,
1071  * and a function higher up the stack doesn't attempt to use a now invalid
1072  * connection handle.
1073  *
1074  * @warning After calling reconnect the caller *MUST NOT* attempt to use
1075  * the old handle in any other operations, as its memory will have been freed.
1076  *
1077  * @see fr_connection_get
1078  * @param[in,out] pool to reconnect the connection in.
1079  * @param[in,out] conn to reconnect.
1080  * @return new connection handle if successful else NULL.
1081  */
1082 void *fr_connection_reconnect(fr_connection_pool_t *pool, void *conn)
1083 {
1084         void *new_conn;
1085         fr_connection_t *this;
1086         uint64_t conn_number;
1087
1088         if (!pool || !conn) return NULL;
1089
1090         this = fr_connection_find(pool, conn);
1091         if (!this) return NULL;
1092
1093         /*
1094          *      The pool is now locked.
1095          */
1096         conn_number = this->number;
1097
1098         DEBUG("%s: Reconnecting (%" PRIu64 ")", pool->log_prefix, conn_number);
1099
1100         new_conn = pool->create(pool->ctx);
1101         if (!new_conn) {
1102                 /*
1103                  *      We can't create a new connection, so close
1104                  *      this one.
1105                  */
1106                 fr_connection_close(pool, this);
1107
1108                 /*
1109                  *      Maybe there's a connection which is unused and
1110                  *      available.  If so, return it.
1111                  */
1112                 pthread_mutex_unlock(&pool->mutex);
1113                 new_conn = fr_connection_get_internal(pool, false);
1114                 if (new_conn) return new_conn;
1115
1116                 RATE_LIMIT(ERROR("%s: Failed to reconnect (%" PRIu64 "), no free connections are available", pool->log_prefix,
1117                                  conn_number));
1118                 return NULL;
1119         }
1120
1121         if (pool->trigger) exec_trigger(NULL, pool->cs, "close", true);
1122         pool->delete(pool->ctx, conn);
1123         this->connection = new_conn;
1124         pthread_mutex_unlock(&pool->mutex);
1125         return new_conn;
1126 }