Download raw body.
relayd: refactor config_getrelayfd
On Thu, 29 Oct 2026 08:58:26 +0100,
Rafael Sadowski <rafael@sizeofvoid.org> wrote:
>
> Based on tb@'s feedback below, you can find a suggestion for
> implementing this function properly with correct error handling.
>
> Unknown fd types and imsgs without an fd are now treated as errors
> instead of being silently ignored.
>
> As an improvement no orphan cert is created when the relay is unknown.
>
> BTW the old code loves to trust imsg_get_fd blindly.
>
> Feedback, OK?
>
It reads way better than current code, thanks.
OK kirill@
> >> config.c:1219:36: warning: 'cert' may be used uninitialized [-Wmaybe-uninitialized]
> >> 1219 | cert->cert_ocsp_fd = imsg_get_fd(imsg);
> >> | ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
> >> config.c:1186:34: note: 'cert' was declared here
> >> 1186 | struct relay_cert *cert;
> >> | ^~~~
> >
> >Maybe we should just ignore these warnings... Adding kludges to badly
> >written code to appease a dumb compiler isn't making the world better
> >place.
>
>
> diff --git a/config.c b/config.c
> index d1f8f8c..4690ae9 100644
> --- a/config.c
> +++ b/config.c
> @@ -31,6 +31,9 @@
> #include "relayd.h"
> #include "log.h"
>
> +static struct relay_cert *config_getcert(struct relayd *,
> + struct ctl_relayfd *);
> +
> int
> config_init(struct relayd *env)
> {
> @@ -1178,55 +1181,70 @@ config_getrelaytable(struct relayd *env, struct imsg *imsg)
> return (-1);
> }
>
> +static struct relay_cert *
> +config_getcert(struct relayd *env, struct ctl_relayfd *crfd)
> +{
> + struct relay_cert *cert;
> +
> + if ((cert = cert_find(env, crfd->id)) == NULL) {
> + if ((cert = cert_add(env, crfd->id)) == NULL)
> + return (NULL);
> + cert->cert_relayid = crfd->relayid;
> + }
> + return (cert);
> +}
> +
> int
> config_getrelayfd(struct relayd *env, struct imsg *imsg)
> {
> struct ctl_relayfd crfd;
> - struct relay *rlay = NULL;
> + struct relay *rlay;
> struct relay_cert *cert;
> + int fd;
>
> if (imsg_get_data(imsg, &crfd, sizeof(crfd)) == -1) {
> log_warn("%s: imsg_get_data", __func__);
> return (-1);
> }
>
> - switch (crfd.type) {
> - case RELAY_FD_CERT:
> - case RELAY_FD_KEY:
> - case RELAY_FD_OCSP:
> - if ((cert = cert_find(env, crfd.id)) == NULL) {
> - if ((cert = cert_add(env, crfd.id)) == NULL)
> - return (-1);
> - cert->cert_relayid = crfd.relayid;
> - }
> - /* FALLTHROUGH */
> - default:
> - if ((rlay = relay_find(env, crfd.relayid)) == NULL) {
> - log_debug("%s: unknown relay", __func__);
> - return (-1);
> - }
> - break;
> + if ((rlay = relay_find(env, crfd.relayid)) == NULL) {
> + log_debug("%s: unknown relay", __func__);
> + return (-1);
> + }
> +
> + if ((fd = imsg_get_fd(imsg)) == -1) {
> + log_warnx("%s: no fd for type %d", __func__, crfd.type);
> + return (-1);
> }
>
> switch (crfd.type) {
> case RELAY_FD_CERT:
> - cert->cert_fd = imsg_get_fd(imsg);
> + if ((cert = config_getcert(env, &crfd)) == NULL)
> + goto fail;
> + cert->cert_fd = fd;
> break;
> case RELAY_FD_KEY:
> - cert->cert_key_fd = imsg_get_fd(imsg);
> + if ((cert = config_getcert(env, &crfd)) == NULL)
> + goto fail;
> + cert->cert_key_fd = fd;
> break;
> case RELAY_FD_OCSP:
> - cert->cert_ocsp_fd = imsg_get_fd(imsg);
> + if ((cert = config_getcert(env, &crfd)) == NULL)
> + goto fail;
> + cert->cert_ocsp_fd = fd;
> break;
> case RELAY_FD_CACERT:
> - rlay->rl_tls_ca_fd = imsg_get_fd(imsg);
> + rlay->rl_tls_ca_fd = fd;
> break;
> case RELAY_FD_CAFILE:
> - rlay->rl_tls_cacert_fd = imsg_get_fd(imsg);
> + rlay->rl_tls_cacert_fd = fd;
> break;
> case RELAY_FD_CLIENTCACERT:
> - rlay->rl_tls_client_ca_fd = imsg_get_fd(imsg);
> + rlay->rl_tls_client_ca_fd = fd;
> break;
> + default:
> + log_warnx("%s: unknown type %d", __func__, crfd.type);
> + goto fail;
> }
>
> log_debug("%s: %s %d received relay type %d for relay %s", __func__,
> @@ -1234,4 +1252,8 @@ config_getrelayfd(struct relayd *env, struct imsg *imsg)
> crfd.type, rlay->rl_conf.name);
>
> return (0);
> +
> + fail:
> + close(fd);
> + return (-1);
> }
>
--
wbr, Kirill
relayd: refactor config_getrelayfd