Instead of building an API for ibufs to handle dynamic strings use open_memstream(3) which does the same via stdio.
Now open_memstream() requires a bit more plumbing (one needs to close the FILE stream and free the buffer) but on the plus side you can use all stdio functions like fprintf() to fill this string. While doing this also add error handling and check if the generated string was created successfully before calling log_info(). -- :wq Claudio Index: iked.h =================================================================== RCS file: /cvs/src/sbin/iked/iked.h,v retrieving revision 1.214 diff -u -p -r1.214 iked.h --- iked.h 30 May 2023 08:41:15 -0000 1.214 +++ iked.h 8 Jun 2023 19:19:41 -0000 @@ -1270,8 +1270,7 @@ struct ibuf * int ibuf_cat(struct ibuf *, struct ibuf *); size_t ibuf_length(struct ibuf *); int ibuf_setsize(struct ibuf *, size_t); -uint8_t * - ibuf_data(struct ibuf *); +void *ibuf_data(struct ibuf *); void *ibuf_getdata(struct ibuf *, size_t); struct ibuf * ibuf_get(struct ibuf *, size_t); @@ -1279,8 +1278,6 @@ struct ibuf * ibuf_dup(struct ibuf *); struct ibuf * ibuf_random(size_t); -int ibuf_strcat(struct ibuf **, const char *); -int ibuf_strlen(struct ibuf *); /* log.c */ void log_init(int, int); Index: ikev2.c =================================================================== RCS file: /cvs/src/sbin/iked/ikev2.c,v retrieving revision 1.367 diff -u -p -r1.367 ikev2.c --- ikev2.c 23 May 2023 13:57:14 -0000 1.367 +++ ikev2.c 8 Jun 2023 19:19:41 -0000 @@ -3019,18 +3019,24 @@ ikev2_handle_delete(struct iked *env, st struct iked_childsa **peersas = NULL; struct iked_sa *sa = msg->msg_sa; struct ikev2_delete *localdel; - struct ibuf *spibuf = NULL; + FILE *spif; + char *spibuf = NULL; uint64_t *localspi = NULL; uint64_t spi64, spi = 0; uint32_t spi32; uint8_t *buf; size_t found = 0; int ret = -1; - size_t i, sz, cnt, len; + size_t i, sz, cnt, len, dummy; if (!msg->msg_del_protoid) return (0); + if ((spif = open_memstream(&spibuf, &dummy)) == NULL) { + log_warn("%s", __func__); + return (0); + } + sz = msg->msg_del_spisize; switch (sz) { @@ -3093,11 +3099,10 @@ ikev2_handle_delete(struct iked *env, st if (ikev2_childsa_delete(env, sa, msg->msg_del_protoid, spi, &localspi[i], 0) != -1) { found++; - /* append SPI to log buffer */ - if (ibuf_strlen(spibuf)) - ibuf_strcat(&spibuf, ", "); - ibuf_strcat(&spibuf, print_spi(spi, sz)); + if (ftello(spif) > 0) + fputs(", ", spif); + fputs(print_spi(spi, sz), spif); } /* @@ -3143,11 +3148,12 @@ ikev2_handle_delete(struct iked *env, st break; } } - log_info("%sdeleted %zu SPI%s: %.*s", - SPI_SA(sa, NULL), found, - found == 1 ? "" : "s", - spibuf ? ibuf_strlen(spibuf) : 0, - spibuf ? (char *)ibuf_data(spibuf) : ""); + if (!ferror(spif)) { + fflush(spif); + log_info("%sdeleted %zu SPI%s: %s", + SPI_SA(sa, NULL), found, found == 1 ? "" : "s", + spibuf); + } } else { /* XXX should we send an INVALID_SPI notification? */ ret = 0; @@ -3156,7 +3162,8 @@ ikev2_handle_delete(struct iked *env, st done: free(localspi); free(peersas); - ibuf_free(spibuf); + fclose(spif); + free(spibuf); return (ret); } @@ -6414,15 +6421,21 @@ ikev2_childsa_enable(struct iked *env, s struct iked_childsa *csa, *ocsa, *ipcomp; struct iked_flow *flow, *oflow; int peer_changed, reload; - struct ibuf *spibuf = NULL; - struct ibuf *flowbuf = NULL; - char *buf; + FILE *spif, *flowf; + char *spibuf = NULL, *flowbuf = NULL; char prenat_mask[10]; uint16_t encrid = 0, integrid = 0, groupid = 0; - size_t encrlen = 0, integrlen = 0; + size_t encrlen = 0, integrlen = 0, spisz, flowsz; int esn = 0; int ret = -1; + spif = open_memstream(&spibuf, &spisz); + flowf = open_memstream(&flowbuf, &flowsz); + if (spif == NULL || flowf == NULL) { + log_warn("%s", __func__); + return (ret); + } + TAILQ_FOREACH(csa, &sa->sa_childsas, csa_entry) { if (csa->csa_rekey || csa->csa_loaded) continue; @@ -6466,16 +6479,12 @@ ikev2_childsa_enable(struct iked *env, s print_spi(csa->csa_spi.spi, csa->csa_spi.spi_size)); /* append SPI to log buffer */ - if (ibuf_strlen(spibuf)) - ibuf_strcat(&spibuf, ", "); - ibuf_strcat(&spibuf, print_spi(csa->csa_spi.spi, - csa->csa_spi.spi_size)); - if (ipcomp) { - ibuf_strcat(&spibuf, "("); - ibuf_strcat(&spibuf, print_spi(ipcomp->csa_spi.spi, + if (ftello(spif) > 0) + fputs(", ", spif); + fputs(print_spi(csa->csa_spi.spi, csa->csa_spi.spi_size), spif); + if (ipcomp) + fprintf(spif, "(%s)", print_spi(ipcomp->csa_spi.spi, ipcomp->csa_spi.spi_size)); - ibuf_strcat(&spibuf, ")"); - } if (!encrid) { encrid = csa->csa_encrid; encrlen = ibuf_length(csa->csa_encrkey); @@ -6538,25 +6547,26 @@ ikev2_childsa_enable(struct iked *env, s flow->flow_prenat.addr_mask); else prenat_mask[0] = '\0'; - if (flow->flow_dir == IPSP_DIRECTION_OUT && - asprintf(&buf, "%s-%s/%d%s%s%s%s%s=%s/%d(%u)%s", - print_map(flow->flow_saproto, ikev2_saproto_map), - print_host((struct sockaddr *)&flow->flow_src.addr, NULL, 0), - flow->flow_src.addr_mask, - flow->flow_prenat.addr_af != 0 ? "[": "", - flow->flow_prenat.addr_af != 0 ? print_host((struct sockaddr *) - &flow->flow_prenat.addr, NULL, 0) : "", - flow->flow_prenat.addr_af != 0 ? "/" : "", - flow->flow_prenat.addr_af != 0 ? prenat_mask : "", - flow->flow_prenat.addr_af != 0 ? "]": "", - print_host((struct sockaddr *)&flow->flow_dst.addr, NULL, 0), - flow->flow_dst.addr_mask, - flow->flow_ipproto, - reload ? "-R" : "") != -1) { - if (ibuf_strlen(flowbuf)) - ibuf_strcat(&flowbuf, ", "); - ibuf_strcat(&flowbuf, buf); - free(buf); + if (flow->flow_dir == IPSP_DIRECTION_OUT) { + if (ftello(flowf) > 0) + fputs(", ", flowf); + fprintf(flowf, "%s-%s/%d%s%s%s%s%s=%s/%d(%u)%s", + print_map(flow->flow_saproto, ikev2_saproto_map), + print_host((struct sockaddr *)&flow->flow_src.addr, + NULL, 0), + flow->flow_src.addr_mask, + flow->flow_prenat.addr_af != 0 ? "[": "", + flow->flow_prenat.addr_af != 0 ? + print_host((struct sockaddr *) + &flow->flow_prenat.addr, NULL, 0) : "", + flow->flow_prenat.addr_af != 0 ? "/" : "", + flow->flow_prenat.addr_af != 0 ? prenat_mask : "", + flow->flow_prenat.addr_af != 0 ? "]": "", + print_host((struct sockaddr *)&flow->flow_dst.addr, + NULL, 0), + flow->flow_dst.addr_mask, + flow->flow_ipproto, + reload ? "-R" : ""); } } @@ -6569,10 +6579,10 @@ ikev2_childsa_enable(struct iked *env, s NULL, 0)); } - if (ibuf_strlen(spibuf)) { - log_info("%s: loaded SPIs: %.*s (enc %s%s%s%s%s%s)", - SPI_SA(sa, __func__), - ibuf_strlen(spibuf), ibuf_data(spibuf), + if (ftello(spif) > 0 && !ferror(spif)) { + fflush(spif); + log_info("%s: loaded SPIs: %s (enc %s%s%s%s%s%s)", + SPI_SA(sa, __func__), spibuf, print_xf(encrid, encrlen, ipsecencxfs), integrid ? " auth " : "", integrid ? print_xf(integrid, integrlen, authxfs) : "", @@ -6580,14 +6590,17 @@ ikev2_childsa_enable(struct iked *env, s groupid ? print_xf(groupid, 0, groupxfs) : "", esn ? " esn" : ""); } - if (ibuf_strlen(flowbuf)) - log_info("%s: loaded flows: %.*s", SPI_SA(sa, __func__), - ibuf_strlen(flowbuf), ibuf_data(flowbuf)); + if (ftello(flowf) > 0 && !ferror(flowf)) { + fflush(flowf); + log_info("%s: loaded flows: %s", SPI_SA(sa, __func__), flowbuf); + } ret = 0; done: - ibuf_free(spibuf); - ibuf_free(flowbuf); + fclose(spif); + fclose(flowf); + free(spibuf); + free(flowbuf); return (ret); } Index: imsg_util.c =================================================================== RCS file: /cvs/src/sbin/iked/imsg_util.c,v retrieving revision 1.17 diff -u -p -r1.17 imsg_util.c --- imsg_util.c 30 May 2023 08:41:15 -0000 1.17 +++ imsg_util.c 8 Jun 2023 19:19:41 -0000 @@ -83,7 +83,7 @@ ibuf_length(struct ibuf *buf) return (ibuf_size(buf)); } -uint8_t * +void * ibuf_data(struct ibuf *buf) { return (ibuf_seek(buf, 0, 0)); @@ -143,28 +143,4 @@ ibuf_setsize(struct ibuf *buf, size_t le return (-1); buf->wpos = len; return (0); -} - -int -ibuf_strcat(struct ibuf **buf, const char *s) -{ - size_t slen; - - if (buf == NULL) - return (-1); - slen = strlen(s); - if (*buf == NULL) { - if ((*buf = ibuf_new(s, slen)) == NULL) - return (-1); - return (0); - } - return (ibuf_add(*buf, s, slen)); -} - -int -ibuf_strlen(struct ibuf *buf) -{ - if (ibuf_length(buf) > INT_MAX) - return (INT_MAX); - return ((int)ibuf_length(buf)); }