+static int virtual_server_idx(const char *name)
+{
+ uint32_t hash;
+
+ if (!name) return 0;
+
+ hash = fr_hash_string(name);
+
+ return hash & (VIRTUAL_SERVER_HASH_SIZE - 1);
+}
+
+static void virtual_server_free(virtual_server_t *server)
+{
+ if (!server) return;
+
+ if (server->components) rbtree_free(server->components);
+ server->components = NULL;
+
+ free(server);
+}
+
+void virtual_servers_free(time_t when)
+{
+ int i;
+ virtual_server_t **last;
+
+ for (i = 0; i < VIRTUAL_SERVER_HASH_SIZE; i++) {
+ virtual_server_t *server, *next;
+
+ last = &virtual_servers[i];
+ for (server = virtual_servers[i];
+ server != NULL;
+ server = next) {
+ next = server->next;
+
+ /*
+ * If we delete it, fix the links so that
+ * we don't orphan anything. Also,
+ * delete it if it's old, AND a newer one
+ * was defined.
+ *
+ * Otherwise, the last pointer gets set to
+ * the one we didn't delete.
+ */
+ if ((when == 0) ||
+ ((server->created < when) && server->can_free)) {
+ *last = server->next;
+ virtual_server_free(server);
+ } else {
+ last = &(server->next);
+ }
+ }
+ }
+}