diff --git a/src/socket.c b/src/socket.c index 4605db4c0..34a163e2d 100644 --- a/src/socket.c +++ b/src/socket.c @@ -202,38 +202,65 @@ static int socket_helper_osa(const struct osmo_sockaddr *addr, uint16_t type, ui } #ifdef HAVE_LIBSCTP -/* Fill buf with a string representation of the address set, in the form: - * buf_len == 0: "()" - * buf_len == 1: "hostA" - * buf_len >= 2: (hostA|hostB|...|...) +/* Fill osmo_strbuf with a string representation of the address set, in the form: + * count == 0: "()" + * count == 1: "hostA" + * count >= 2: (hostA|hostB|...|...) + * where count is either host_count or addrs_count */ -static int multiaddr_snprintf(char* buf, size_t buf_len, const char **hosts, size_t host_cnt) +static int multiaddr_strbuf(struct osmo_strbuf *sb, + const char **hosts, size_t host_count, + struct sockaddr **addrs, size_t addrs_count) { - int len = 0, offset = 0, rem = buf_len; - size_t i; - int ret; + bool use_hosts = hosts ? true : false; + size_t count = use_hosts ? host_count : addrs_count; + struct osmo_sockaddr_str t; + struct osmo_sockaddr_str *oss = &t; char *after; + int rc; - if (buf_len < 3) - return -EINVAL; + if (sb->len < 3) + return -ENOMEM; - if (host_cnt != 1) { - ret = snprintf(buf, rem, "("); - if (ret < 0) - return ret; - OSMO_SNPRINTF_RET(ret, rem, offset, len); - } - for (i = 0; i < host_cnt; i++) { - if (host_cnt == 1) + if (count != 1) + OSMO_STRBUF_PRINTF(*sb, "("); + + for (size_t i = 0; i < count; i++) { + const struct sockaddr *addr = &(*addrs)[i]; + + if (count == 1) after = ""; else - after = (i == (host_cnt - 1)) ? ")" : "|"; - ret = snprintf(buf + offset, rem, "%s%s", hosts[i] ? : "0.0.0.0", after); - OSMO_SNPRINTF_RET(ret, rem, offset, len); + after = (i == (count - 1)) ? ")" : "|"; + + if (use_hosts) { + if (hosts[i]) + OSMO_STRBUF_PRINTF(*sb, "%s%s", hosts[i], after); + } else { + rc = osmo_sockaddr_str_from_sockaddr(oss, (const struct sockaddr_storage *)addr); + if (rc < 0) + return rc; + + OSMO_STRBUF_PRINTF(*sb, "%s%s", oss->ip, after); + } } - return len; + if (count == 0) + OSMO_STRBUF_PRINTF(*sb, ")"); + + if (sb->chars_needed >= sb->len) + return -ENOSPC; + + return sb->chars_needed; } + +static int multiaddr_snprintf(char *buf, size_t buf_len, const char **hosts, size_t host_cnt) +{ + struct osmo_strbuf sb = { .buf = buf, .len = buf_len }; + + return multiaddr_strbuf(&sb, hosts, host_cnt, NULL, 0); +} + #endif /* HAVE_LIBSCTP */ static int osmo_sock_init_tail(int fd, uint16_t type, unsigned int flags)