Skip to content

Commit

Permalink
set timer for free of dynamic clients
Browse files Browse the repository at this point in the history
instead of magic in client_free() where it's not really needed,
put the timer into listen.c.
  • Loading branch information
alandekok committed Dec 27, 2018
1 parent f44c5e4 commit 7026efa
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 40 deletions.
1 change: 1 addition & 0 deletions src/include/clients.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ typedef struct radclient {
//!< clients.

bool rate_limit; //!< Where addition of clients should be rate limited.
fr_event_t *ev; //!< for deleting dynamic clients
#endif

#ifdef WITH_COA
Expand Down
38 changes: 0 additions & 38 deletions src/main/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,49 +55,13 @@ static int tree_num_max = 0;
#endif
static RADCLIENT_LIST *root_clients = NULL;

#ifdef WITH_DYNAMIC_CLIENTS
static fr_fifo_t *deleted_clients = NULL;
#endif

/*
* Callback for freeing a client.
*/
void client_free(RADCLIENT *client)
{
if (!client) return;

#ifdef WITH_DYNAMIC_CLIENTS
if (client->dynamic == 2) {
time_t now;

if (!deleted_clients) {
deleted_clients = fr_fifo_create(NULL, 1024, (void (*)(void *))client_free);
if (!deleted_clients) return; /* MEMLEAK */
}

/*
* Mark it as in the fifo, and remember when we
* pushed it.
*/
client->dynamic = 3;
client->created = now = time(NULL); /* re-set it */
fr_fifo_push(deleted_clients, client);

/*
* Peek at the head of the fifo. If it might
* still be in use, return. Otherwise, pop it
* from the queue and delete it.
*/
client = fr_fifo_peek(deleted_clients);
rad_assert(client != NULL);

if ((client->created + 120) >= now) return;

client = fr_fifo_pop(deleted_clients);
rad_assert(client != NULL);
}
#endif

talloc_free(client);
}

Expand Down Expand Up @@ -386,8 +350,6 @@ void client_delete(RADCLIENT_LIST *clients, RADCLIENT *client)

rad_assert(client->ipaddr.prefix <= 128);

client->dynamic = 2; /* signal to client_free */

#ifdef WITH_STATS
rbtree_deletebydata(tree_num, client);
#endif
Expand Down
27 changes: 25 additions & 2 deletions src/main/listen.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ static int command_write_magic(int newfd, listen_socket_t *sock);

static fr_protocol_t master_listen[];

#ifdef WITH_DYNAMIC_CLIENTS
static void client_timer_free(void *ctx)
{
RADCLIENT *client = ctx;

client_free(client);
}
#endif

/*
* Find a per-socket client.
*/
Expand Down Expand Up @@ -161,6 +170,8 @@ RADCLIENT *client_listener_find(rad_listen_t *listener,
#ifdef HAVE_SYS_STAT_H
char const *filename;
#endif
fr_event_list_t *el;
struct timeval when;

/*
* Lives forever. Return it.
Expand Down Expand Up @@ -201,11 +212,23 @@ RADCLIENT *client_listener_find(rad_listen_t *listener,


/*
* This really puts them onto a queue for later
* deletion.
* Delete the client from the known list.
*/
client_delete(clients, client);

/*
* Add a timer to free the client in 120s
*/
el = radius_event_list_corral(EVENT_CORRAL_MAIN);

gettimeofday(&when, NULL);
when.tv_sec += 120;

/*
* If this fails, we leak memory. That's better than crashing...
*/
(void) fr_event_insert(el, client_timer_free, client, &when, &client->ev);

/*
* Go find the enclosing network again.
*/
Expand Down

0 comments on commit 7026efa

Please sign in to comment.