diff options
author | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2021-12-01 10:25:02 +0100 |
---|---|---|
committer | neels <nhofmeyr@sysmocom.de> | 2022-01-31 15:03:53 +0000 |
commit | 09d6574a457d3f06a372990b83311bbd4b98757c (patch) | |
tree | 06c379f68d470995f66220aa9ec8a1083dd2aa36 /src/socket.c | |
parent | e56f1b67f4330978c152a0b9cbfb4e37b974bb67 (diff) |
add osmo_sockaddr_to_str_c(), osmo_sockaddr_to_str_buf2()
To easily log and print a sockaddr using OTC_SELECT, add
osmo_sockaddr_to_str_c().
Implement osmo_sockaddr_to_str_buf2() using osmo_strbuf, so that we can
return the chars_needed which osmo_sockaddr_to_str_c() uses.
From previous osmo_sockaddr_to_str_buf(), call
osmo_sockaddr_to_str_buf2() and return NULL if the buf_len was
insufficient, to mimick previous behavior. This makes it more
consistently returning NULL for insufficient buf_len, as shown in the
tweak that is needed in socket_test.c. Before osmo_sockaddr_to_str_buf()
would return a truncated port number, now it's all or NULL.
I will use osmo_sockaddr_to_str_c() in the new osmo-upf implementation.
Related: SYS#5599
Change-Id: I12771bf8a021e6785217b1faad03c09ec1cfef0e
Diffstat (limited to 'src/socket.c')
-rw-r--r-- | src/socket.c | 72 |
1 files changed, 44 insertions, 28 deletions
diff --git a/src/socket.c b/src/socket.c index 449c8258..0ffa11d4 100644 --- a/src/socket.c +++ b/src/socket.c @@ -1776,52 +1776,68 @@ const char *osmo_sockaddr_to_str(const struct osmo_sockaddr *sockaddr) return osmo_sockaddr_to_str_buf(buf, sizeof(buf), sockaddr); } -/*! string-format a given osmo_sockaddr address into a user-supplied buffer +/*! string-format a given osmo_sockaddr address into a user-supplied buffer. + * Same as osmo_sockaddr_to_str_buf() but returns a would-be length in snprintf() style. * \param[in] buf user-supplied output buffer * \param[in] buf_len size of the user-supplied output buffer in bytes * \param[in] sockaddr the osmo_sockaddr to print - * \return pointer to the string on success; NULL on error + * \return number of characters that would be written if the buffer is large enough, like snprintf(). */ -char *osmo_sockaddr_to_str_buf(char *buf, size_t buf_len, - const struct osmo_sockaddr *sockaddr) +int osmo_sockaddr_to_str_buf2(char *buf, size_t buf_len, const struct osmo_sockaddr *sockaddr) { + struct osmo_strbuf sb = { .buf = buf, .len = buf_len }; uint16_t port = 0; - size_t written; - if (buf_len < 5) - return NULL; - if (!sockaddr) - return NULL; + if (!sockaddr) { + OSMO_STRBUF_PRINTF(sb, "NULL"); + return sb.chars_needed; + } switch (sockaddr->u.sa.sa_family) { case AF_INET: - written = osmo_sockaddr_to_str_and_uint(buf, buf_len, &port, &sockaddr->u.sa); - if (written + 1 >= buf_len && port) - return NULL; + OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_and_uint, &port, &sockaddr->u.sa); if (port) - snprintf(buf + written, buf_len - written, ":%u", port); + OSMO_STRBUF_PRINTF(sb, ":%u", port); break; case AF_INET6: - buf[0] = '['; - written = osmo_sockaddr_to_str_and_uint(buf + 1, buf_len - 1, &port, &sockaddr->u.sa); - if (written + 2 >= buf_len) - return NULL; - - if (written + 3 >= buf_len && port) - return NULL; - + OSMO_STRBUF_PRINTF(sb, "["); + OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_and_uint, &port, &sockaddr->u.sa); + OSMO_STRBUF_PRINTF(sb, "]"); if (port) - snprintf(buf + 1 + written, buf_len - written - 1, "]:%u", port); - else { - buf[written + 1] = ']'; - buf[written + 2] = 0; - } + OSMO_STRBUF_PRINTF(sb, ":%u", port); break; default: - snprintf(buf, buf_len, "unsupported family %d", sockaddr->u.sa.sa_family); - return buf; + OSMO_STRBUF_PRINTF(sb, "unsupported family %d", sockaddr->u.sa.sa_family); + break; } + return sb.chars_needed; +} + +/*! string-format a given osmo_sockaddr address into a talloc allocated buffer. + * Like osmo_sockaddr_to_str_buf2() but returns a talloc allocated string. + * \param[in] ctx talloc context to allocate from, e.g. OTC_SELECT. + * \param[in] sockaddr the osmo_sockaddr to print. + * \return human readable string. + */ +char *osmo_sockaddr_to_str_c(void *ctx, const struct osmo_sockaddr *sockaddr) +{ + OSMO_NAME_C_IMPL(ctx, 64, "ERROR", osmo_sockaddr_to_str_buf2, sockaddr) +} + +/*! string-format a given osmo_sockaddr address into a user-supplied buffer. + * Like osmo_sockaddr_to_str_buf2() but returns buf, or NULL if too short. + * \param[in] buf user-supplied output buffer + * \param[in] buf_len size of the user-supplied output buffer in bytes + * \param[in] sockaddr the osmo_sockaddr to print + * \return pointer to the string on success; NULL on error + */ +char *osmo_sockaddr_to_str_buf(char *buf, size_t buf_len, + const struct osmo_sockaddr *sockaddr) +{ + int chars_needed = osmo_sockaddr_to_str_buf2(buf, buf_len, sockaddr); + if (chars_needed >= buf_len) + return NULL; return buf; } |