From: William Lallemand Date: Tue, 29 Mar 2022 12:29:31 +0000 (+0200) Subject: MINOR: ssl: split the cert commit io handler X-Git-Tag: v2.6-dev5~98 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3b5a3a6c03da67a86a508f8a7866b64851ccec9b;p=thirdparty%2Fhaproxy.git MINOR: ssl: split the cert commit io handler Extract the code that replace the ckch_store and its dependencies into the ckch_store_replace() function. This function must be used under the global ckch lock. It frees everything related to the old ckch_store. --- diff --git a/include/haproxy/ssl_ckch.h b/include/haproxy/ssl_ckch.h index 8ee3b74ea4..2eea80750b 100644 --- a/include/haproxy/ssl_ckch.h +++ b/include/haproxy/ssl_ckch.h @@ -42,7 +42,7 @@ struct ckch_store *ckchs_lookup(char *path); struct ckch_store *ckchs_dup(const struct ckch_store *src); struct ckch_store *ckch_store_new(const char *filename); void ckch_store_free(struct ckch_store *store); - +void ckch_store_replace(struct ckch_store *old_ckchs, struct ckch_store *new_ckchs); /* ckch_inst functions */ void ckch_inst_free(struct ckch_inst *inst); diff --git a/src/ssl_ckch.c b/src/ssl_ckch.c index 08472c68f1..d5444dfc66 100644 --- a/src/ssl_ckch.c +++ b/src/ssl_ckch.c @@ -1831,6 +1831,51 @@ static void __ckch_inst_free_locked(struct ckch_inst *ckchi) } } +/* Replace a ckch_store in the ckch tree and insert the whole dependencies, +* then free the previous dependencies and store. +* Used in the case of a certificate update. +* +* Every dependencies must allocated before using this function. +* +* This function can't fail as it only update pointers, and does not alloc anything. +* +* /!\ This function must be used under the ckch lock. /!\ +* +* - Insert every dependencies (SNI, crtlist_entry, ckch_inst, etc) +* - Delete the old ckch_store from the tree +* - Insert the new ckch_store +* - Free the old dependencies and the old ckch_store +*/ +void ckch_store_replace(struct ckch_store *old_ckchs, struct ckch_store *new_ckchs) +{ + struct crtlist_entry *entry; + struct ckch_inst *ckchi, *ckchis; + + LIST_SPLICE(&new_ckchs->crtlist_entry, &old_ckchs->crtlist_entry); + list_for_each_entry(entry, &new_ckchs->crtlist_entry, by_ckch_store) { + ebpt_delete(&entry->node); + /* change the ptr and reinsert the node */ + entry->node.key = new_ckchs; + ebpt_insert(&entry->crtlist->entries, &entry->node); + } + /* insert the new ckch_insts in the crtlist_entry */ + list_for_each_entry(ckchi, &new_ckchs->ckch_inst, by_ckchs) { + if (ckchi->crtlist_entry) + LIST_INSERT(&ckchi->crtlist_entry->ckch_inst, &ckchi->by_crtlist_entry); + } + /* First, we insert every new SNIs in the trees, also replace the default_ctx */ + list_for_each_entry_safe(ckchi, ckchis, &new_ckchs->ckch_inst, by_ckchs) { + __ssl_sock_load_new_ckch_instance(ckchi); + } + /* delete the old sni_ctx, the old ckch_insts and the ckch_store */ + list_for_each_entry_safe(ckchi, ckchis, &old_ckchs->ckch_inst, by_ckchs) { + __ckch_inst_free_locked(ckchi); + } + + ckch_store_free(old_ckchs); + ebst_insert(&ckchs_tree, &new_ckchs->node); +} + /* * This function tries to create the new ckch_inst and their SNIs @@ -1841,9 +1886,8 @@ static int cli_io_handler_commit_cert(struct appctx *appctx) int y = 0; char *err = NULL; struct ckch_store *old_ckchs, *new_ckchs = NULL; - struct ckch_inst *ckchi, *ckchis; + struct ckch_inst *ckchi; struct buffer *trash = alloc_trash_chunk(); - struct crtlist_entry *entry; if (trash == NULL) goto error; @@ -1914,34 +1958,9 @@ static int cli_io_handler_commit_cert(struct appctx *appctx) if (!new_ckchs) continue; - /* get the list of crtlist_entry in the old store, and update the pointers to the store */ - LIST_SPLICE(&new_ckchs->crtlist_entry, &old_ckchs->crtlist_entry); - list_for_each_entry(entry, &new_ckchs->crtlist_entry, by_ckch_store) { - ebpt_delete(&entry->node); - /* change the ptr and reinsert the node */ - entry->node.key = new_ckchs; - ebpt_insert(&entry->crtlist->entries, &entry->node); - } - - /* insert the new ckch_insts in the crtlist_entry */ - list_for_each_entry(ckchi, &new_ckchs->ckch_inst, by_ckchs) { - if (ckchi->crtlist_entry) - LIST_INSERT(&ckchi->crtlist_entry->ckch_inst, &ckchi->by_crtlist_entry); - } - - /* First, we insert every new SNIs in the trees, also replace the default_ctx */ - list_for_each_entry_safe(ckchi, ckchis, &new_ckchs->ckch_inst, by_ckchs) { - __ssl_sock_load_new_ckch_instance(ckchi); - } - - /* delete the old sni_ctx, the old ckch_insts and the ckch_store */ - list_for_each_entry_safe(ckchi, ckchis, &old_ckchs->ckch_inst, by_ckchs) { - __ckch_inst_free_locked(ckchi); - } + /* insert everything and remove the previous objects */ + ckch_store_replace(old_ckchs, new_ckchs); - /* Replace the old ckchs by the new one */ - ckch_store_free(old_ckchs); - ebst_insert(&ckchs_tree, &new_ckchs->node); appctx->st2 = SETCERT_ST_FIN; /* fallthrough */ case SETCERT_ST_FIN: