Ok, this went overboard. I just wanted to clean up a bit more in check_tcp.c but noticed check_send_expect and CHECK_BINSEND_EXPECT.
This code is not very consitent in the differnt ways the strings are encoded. Especially check_send_expect() is a bit of a mess because of that. While there I noticed string2binary() and decided to write it in simpler way (copying code over from rpki-client). All in all I think this diff is improving the situation a little bit. -- :wq Claudio Index: check_tcp.c =================================================================== RCS file: /cvs/src/usr.sbin/relayd/check_tcp.c,v retrieving revision 1.59 diff -u -p -r1.59 check_tcp.c --- check_tcp.c 20 Jun 2023 09:54:57 -0000 1.59 +++ check_tcp.c 20 Jun 2023 10:55:12 -0000 @@ -183,10 +183,6 @@ tcp_host_up(struct ctl_tcp_event *cte) return; } - if (cte->table->sendbuf != NULL && cte->table->sendbinbuf == NULL) { - cte->req = cte->table->sendbuf; - } else if (cte->table->sendbinbuf != NULL) - cte->req = cte->table->sendbinbuf->buf; if (cte->table->sendbuf != NULL || cte->table->sendbinbuf != NULL) { event_again(&cte->ev, cte->s, EV_TIMEOUT|EV_WRITE, tcp_send_req, &cte->tv_start, &cte->table->conf.timeout, cte); @@ -203,6 +199,7 @@ void tcp_send_req(int s, short event, void *arg) { struct ctl_tcp_event *cte = arg; + char *req; int bs; int len; @@ -214,14 +211,17 @@ tcp_send_req(int s, short event, void *a if (cte->table->sendbinbuf != NULL) { len = ibuf_size(cte->table->sendbinbuf); + req = ibuf_data(cte->table->sendbinbuf); log_debug("%s: table %s sending binary", __func__, cte->table->conf.name); print_hex(cte->table->sendbinbuf->buf, 0, len); - } else - len = strlen(cte->req); + } else { + len = strlen(cte->table->sendbuf); + req = cte->table->sendbuf; + } do { - bs = write(s, cte->req, len); + bs = write(s, req, len); if (bs == -1) { if (errno == EAGAIN || errno == EINTR) goto retry; @@ -230,7 +230,7 @@ tcp_send_req(int s, short event, void *a hce_notify_done(cte->host, HCE_TCP_WRITE_FAIL); return; } - cte->req += bs; + req += bs; len -= bs; } while (len > 0); @@ -302,20 +302,22 @@ check_send_expect(struct ctl_tcp_event * u_char *b; if (cte->table->conf.check == CHECK_BINSEND_EXPECT) { + size_t exlen; + + exlen = strlen(cte->table->conf.exbuf) / 2; log_debug("%s: table %s expecting binary", __func__, cte->table->conf.name); - print_hex(cte->table->conf.exbinbuf, 0, - strlen(cte->table->conf.exbuf) / 2); + print_hex(cte->table->conf.exbinbuf, 0, exlen); - if (memcmp(cte->table->conf.exbinbuf, cte->buf->buf, - strlen(cte->table->conf.exbuf) / 2) == 0) { + if (ibuf_size(cte->buf) >= exlen && memcmp(ibuf_data(cte->buf), + cte->table->conf.exbinbuf, exlen) == 0) { cte->host->he = HCE_SEND_EXPECT_OK; cte->host->up = HOST_UP; return (0); - } else { + } else if (ibuf_size(cte->buf) >= exlen) { log_debug("%s: table %s received mismatching binary", __func__, cte->table->conf.name); - print_hex(cte->buf->buf, 0, ibuf_size(cte->buf)); + print_hex(ibuf_data(cte->buf), 0, ibuf_size(cte->buf)); } } else if (cte->table->conf.check == CHECK_SEND_EXPECT) { /* @@ -353,7 +355,7 @@ check_http_code(struct ctl_tcp_event *ct if (ibuf_add_zero(cte->buf, 1) == -1) fatal("out of memory"); - head = cte->buf->buf; + head = ibuf_data(cte->buf); host = cte->host; host->he = HCE_HTTP_CODE_ERROR; host->code = 0; @@ -404,7 +406,7 @@ check_http_digest(struct ctl_tcp_event * if (ibuf_add_zero(cte->buf, 1) == -1) fatal("out of memory"); - head = cte->buf->buf; + head = ibuf_data(cte->buf); host = cte->host; host->he = HCE_HTTP_DIGEST_ERROR; Index: relayd.h =================================================================== RCS file: /cvs/src/usr.sbin/relayd/relayd.h,v retrieving revision 1.269 diff -u -p -r1.269 relayd.h --- relayd.h 31 Aug 2022 16:17:18 -0000 1.269 +++ relayd.h 20 Jun 2023 10:47:36 -0000 @@ -176,7 +176,6 @@ struct ctl_icmp_event { struct ctl_tcp_event { int s; - char *req; struct ibuf *buf; struct host *host; struct table *table; Index: util.c =================================================================== RCS file: /cvs/src/usr.sbin/relayd/util.c,v retrieving revision 1.3 diff -u -p -r1.3 util.c --- util.c 15 Sep 2019 19:23:29 -0000 1.3 +++ util.c 20 Jun 2023 10:16:46 -0000 @@ -289,44 +289,42 @@ getmonotime(struct timeval *tv) struct ibuf * string2binary(const char *string) { - unsigned long i, j, x; - unsigned char *binary = NULL; struct ibuf *ibuf = NULL; - char hex[3]; - int len; + unsigned char ch, r; + size_t i, len; - if (strlen(string) % 2 != 0) { - return NULL; - } - - binary = calloc(strlen(string), sizeof(unsigned char)); - if (binary == NULL) { - return NULL; - } + len = strlen(string); + if (len % 2 != 0) + goto fail; + if ((ibuf = ibuf_open(len / 2)) == NULL) + goto fail; - hex[2] = '\0'; - j = 0; - for (i = 0; i < strlen(string); i++) { - if (isxdigit(string[i]) == 0 || isxdigit(string[i+1]) == 0) { - free(binary); - return NULL; - } else { - hex[0] = string[i]; - hex[1] = string[i+1]; - x = strtoul(hex, NULL, 16); - binary[j++] = (unsigned char)x; - i++; + while (*string) { + r = 0; + for (i = 0; i < 2; i++) { + ch = string[i]; + if (isdigit(ch)) + ch -= '0'; + else if (islower(ch)) + ch -= ('a' - 10); + else if (isupper(ch)) + ch -= ('A' - 10); + else + goto fail; + if (ch > 0xf) + goto fail; + r = r << 4 | ch; } + if (ibuf_add_n8(ibuf, r) == -1) + goto fail; + string += 2; } - len = strlen(string) / 2; - if ((ibuf = ibuf_open(len)) == NULL || - ibuf_add(ibuf, binary, len) == -1) { - ibuf_free(ibuf); - free(binary); - return NULL; - } - free(binary); + return ibuf; + +fail: + ibuf_free(ibuf); + return NULL; } void