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