BUG/MINOR: ssl: ckch_inst wrongly inserted in crtlist_entry
The instances were wrongly inserted in the crtlist entries, all
instances of a crt-list were inserted in the last crt-list entry.
Which was kind of handy to free all instances upon error.
Now that it's done correctly, the error path was changed, it must
iterate on the entries and find the ckch_insts which were generated for
this bind_conf. To avoid wasting time, it stops the iteration once it
found the first unsuccessful generation.
diff --git a/include/types/ssl_sock.h b/include/types/ssl_sock.h
index e5d676d..2f366fc 100644
--- a/include/types/ssl_sock.h
+++ b/include/types/ssl_sock.h
@@ -166,7 +166,7 @@
unsigned int linenum;
unsigned int fcount; /* filters count */
char **filters;
- struct list ckch_inst; /* list of instances of this entry */
+ struct list ckch_inst; /* list of instances of this entry, there is 1 ckch_inst per instance of the crt-list */
struct list by_crtlist; /* ordered entries */
struct ebpt_node node; /* key is a ptr to a ckch_store */
};
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index f21c4b9..e8d64c9 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -4896,13 +4896,10 @@
{
struct crtlist *crtlist = NULL;
struct ebmb_node *eb;
- struct crtlist_entry *entry;
- struct list instances; /* temporary list head */
+ struct crtlist_entry *entry = NULL;
struct bind_conf_list *bind_conf_node = NULL;
int cfgerr = 0;
- LIST_INIT(&instances);
-
bind_conf_node = malloc(sizeof(*bind_conf_node));
if (!bind_conf_node) {
memprintf(err, "%sCan't alloc memory!\n", err && *err ? *err : "");
@@ -4943,10 +4940,8 @@
memprintf(err, "error processing line %d in file '%s' : %s", entry->linenum, file, *err);
goto error;
}
- LIST_ADDQ(&instances, &ckch_inst->by_crtlist_entry);
+ LIST_ADDQ(&entry->ckch_inst, &ckch_inst->by_crtlist_entry);
}
- /* add the instances to the actual instance list in the crtlist_entry */
- LIST_SPLICE(&entry->ckch_inst, &instances);
/* add the bind_conf to the list */
bind_conf_node->next = crtlist->bind_conf;
@@ -4955,19 +4950,32 @@
return cfgerr;
error:
{
+ struct crtlist_entry *lastentry;
struct ckch_inst *inst, *s_inst;
+ lastentry = entry; /* which entry we tried to generate last */
+ if (lastentry) {
+ list_for_each_entry(entry, &crtlist->ord_entries, by_crtlist) {
+ if (entry == lastentry) /* last entry we tried to generate, no need to go further */
+ break;
+
- list_for_each_entry_safe(inst, s_inst, &instances, by_crtlist_entry) {
- struct sni_ctx *sni, *s_sni;
+ list_for_each_entry_safe(inst, s_inst, &entry->ckch_inst, by_crtlist_entry) {
+ struct sni_ctx *sni, *s_sni;
- /* free the sni_ctx */
- list_for_each_entry_safe(sni, s_sni, &inst->sni_ctx, by_ckch_inst) {
- ebmb_delete(&sni->name);
- LIST_DEL(&sni->by_ckch_inst);
- free(sni);
+ /* this was not generated for this bind_conf, skip */
+ if (inst->bind_conf != bind_conf)
+ continue;
+
+ /* free the sni_ctx */
+ list_for_each_entry_safe(sni, s_sni, &inst->sni_ctx, by_ckch_inst) {
+ ebmb_delete(&sni->name);
+ LIST_DEL(&sni->by_ckch_inst);
+ free(sni);
+ }
+ LIST_DEL(&inst->by_crtlist_entry);
+ free(inst);
+ }
}
- LIST_DEL(&inst->by_crtlist_entry);
- free(inst);
}
free(bind_conf_node);
}