aboutsummaryrefslogtreecommitdiffstats
path: root/src/socket.c
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2021-12-01 10:25:02 +0100
committerneels <nhofmeyr@sysmocom.de>2022-01-31 15:03:53 +0000
commit09d6574a457d3f06a372990b83311bbd4b98757c (patch)
tree06c379f68d470995f66220aa9ec8a1083dd2aa36 /src/socket.c
parente56f1b67f4330978c152a0b9cbfb4e37b974bb67 (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.c72
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;
}