return NULL;
}
- if (dict->proto && dict->proto->init && (dict->proto->init() < 0)) return NULL;
+ /*
+ * If we call init(), make sure that we call free();
+ */
+ if (dict->proto && dict->proto->init) {
+ if (dict->proto->init() < 0) return NULL;
+
+ /*
+ * Mark the *referencing* dictionary as autofree.
+ *
+ * Changing this to dict->autofree=true will break things. :(
+ */
+ (*dict_def)->autofree = true;
+ }
/*
* The reference is to the root of the foreign protocol, we're done.
bool string_based; //!< TACACS, etc.
+ bool autofree; //!< from dict_fixup.
+
fr_hash_table_t *vendors_by_name; //!< Lookup vendor by name.
fr_hash_table_t *vendors_by_num; //!< Lookup vendor by PEN.
}
#endif
+ /*
+ * If we called init(), then call free()
+ */
+ if (dict->autofree) {
+ fr_assert(dict->proto);
+ fr_assert(dict->proto->free);
+ dict->proto->free();
+ }
+
if (!fr_cond_assert(!dict->in_protocol_by_name || fr_hash_table_delete(dict->gctx->protocol_by_name, dict))) {
fr_strerror_printf("Failed removing dictionary from protocol hash \"%s\"", dict->root->name);
return -1;