pespin has uploaded this change for review.

View Change

socket: Introduce API osmo_sock_multiaddr_get_name_buf()

Change-Id: I48950754ed6f61ee5ffa04a447fab8903f10acc0
---
M TODO-RELEASE
M include/osmocom/core/socket.h
M src/core/libosmocore.map
M src/core/socket.c
4 files changed, 107 insertions(+), 1 deletion(-)

git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/80/35180/1
diff --git a/TODO-RELEASE b/TODO-RELEASE
index e365746..9db6f16 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -8,7 +8,7 @@
# If any interfaces have been removed or changed since the last public release: c:r:0.
#library what description / commit summary line
core ADD osmo_sock_multiaddr_{add,del}_local_addr()
-core ADD osmo_sock_multiaddr_get_ip_and_port()
+core ADD osmo_sock_multiaddr_get_ip_and_port(), osmo_sock_multiaddr_get_name_buf()
core ADD gsmtap_inst_fd2() core, DEPRECATE gsmtap_inst_fd()
isdn ABI change add states and flags for external T200 handling
gsm ABI change add T200 timer states to lapdm_datalink
diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h
index 9397343..cae8b11 100644
--- a/include/osmocom/core/socket.h
+++ b/include/osmocom/core/socket.h
@@ -193,6 +193,7 @@

int osmo_sock_multiaddr_get_ip_and_port(int fd, int ip_proto, char *ip, size_t ip_len, size_t *ip_cnt,
char *port, size_t port_len, bool local);
+int osmo_sock_multiaddr_get_name_buf(char *str, size_t str_len, int fd, int sk_proto);
int osmo_sock_multiaddr_add_local_addr(int sfd, const char **addrs, size_t addrs_cnt);
int osmo_sock_multiaddr_del_local_addr(int sfd, const char **addrs, size_t addrs_cnt);

diff --git a/src/core/libosmocore.map b/src/core/libosmocore.map
index 1d00fe8..e67946b 100644
--- a/src/core/libosmocore.map
+++ b/src/core/libosmocore.map
@@ -437,6 +437,7 @@
osmo_sock_multiaddr_add_local_addr;
osmo_sock_multiaddr_del_local_addr;
osmo_sock_multiaddr_get_ip_and_port;
+osmo_sock_multiaddr_get_name_buf;
osmo_sock_set_dscp;
osmo_sock_set_priority;
osmo_sock_unix_init;
diff --git a/src/core/socket.c b/src/core/socket.c
index 1d97018..2f3a02b 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -1952,6 +1952,101 @@
* \param[out] str Destination string buffer.
* \param[in] str_len sizeof(str).
* \param[in] fd File descriptor of socket.
+ * \param[in] fd IPPROTO of the socket, eg: IPPROTO_SCTP.
+ * \return String length as returned by snprintf(), or negative on error.
+ */
+int osmo_sock_multiaddr_get_name_buf(char *str, size_t str_len, int fd, int sk_proto)
+{
+ char hostbuf[32][INET6_ADDRSTRLEN];
+ size_t num_hostbuf = ARRAY_SIZE(hostbuf);
+ char portbuf[6];
+ struct osmo_strbuf sb = { .buf = str, .len = str_len };
+ unsigned int i;
+
+ if (fd < 0) {
+ osmo_strlcpy(str, "<error-bad-fd>", str_len);
+ return -EBADF;
+ }
+
+ switch (sk_proto) {
+ case IPPROTO_SCTP:
+ break; /* continue below */
+ default:
+ return osmo_sock_get_name_buf(str, str_len, fd);
+ }
+
+ /* get remote */
+ OSMO_STRBUF_PRINTF(sb, "r=");
+ if (osmo_sock_multiaddr_get_ip_and_port(fd, sk_proto, &hostbuf[0][0], sizeof(hostbuf[0]),
+ &num_hostbuf, portbuf, sizeof(portbuf), false) != 0) {
+ OSMO_STRBUF_PRINTF(sb, "NULL");
+ } else if (num_hostbuf == 0) {
+ OSMO_STRBUF_PRINTF(sb, "NULL");
+ } else {
+ bool is_v6 = false;
+ bool need_more_bufs = num_hostbuf > ARRAY_SIZE(hostbuf);
+ if (need_more_bufs)
+ num_hostbuf = ARRAY_SIZE(hostbuf);
+
+ if (num_hostbuf > 1)
+ OSMO_STRBUF_PRINTF(sb, "(");
+ else if ((is_v6 = !!strchr(hostbuf[0], ':'))) /* IPv6, add [] to separate from port. */
+ OSMO_STRBUF_PRINTF(sb, "[");
+
+ for (i = 0; i < num_hostbuf - 1; i++)
+ OSMO_STRBUF_PRINTF(sb, "%s,", hostbuf[i]);
+ OSMO_STRBUF_PRINTF(sb, "%s", hostbuf[i]);
+
+ if (num_hostbuf > 1)
+ OSMO_STRBUF_PRINTF(sb, ")");
+ else if (is_v6)
+ OSMO_STRBUF_PRINTF(sb, "]");
+ if (need_more_bufs)
+ OSMO_STRBUF_PRINTF(sb, "<need-more-bufs!>");
+ OSMO_STRBUF_PRINTF(sb, ":%s", portbuf);
+ }
+
+ OSMO_STRBUF_PRINTF(sb, "<->l=");
+
+ /* get local */
+ num_hostbuf = ARRAY_SIZE(hostbuf);
+ if (osmo_sock_multiaddr_get_ip_and_port(fd, sk_proto, &hostbuf[0][0], sizeof(hostbuf[0]),
+ &num_hostbuf, portbuf, sizeof(portbuf), true) != 0) {
+ OSMO_STRBUF_PRINTF(sb, "NULL");
+ } else if (num_hostbuf == 0) {
+ OSMO_STRBUF_PRINTF(sb, "NULL");
+ } else {
+ bool is_v6 = false;
+ bool need_more_bufs = num_hostbuf > ARRAY_SIZE(hostbuf);
+ if (need_more_bufs)
+ num_hostbuf = ARRAY_SIZE(hostbuf);
+
+ if (num_hostbuf > 1)
+ OSMO_STRBUF_PRINTF(sb, "(");
+ else if ((is_v6 = !!strchr(hostbuf[0], ':'))) /* IPv6, add [] to separate from port. */
+ OSMO_STRBUF_PRINTF(sb, "[");
+
+ for (i = 0; i < num_hostbuf - 1; i++)
+ OSMO_STRBUF_PRINTF(sb, "%s,", hostbuf[i]);
+ OSMO_STRBUF_PRINTF(sb, "%s", hostbuf[i]);
+
+ if (num_hostbuf > 1)
+ OSMO_STRBUF_PRINTF(sb, ")");
+ else if (is_v6)
+ OSMO_STRBUF_PRINTF(sb, "]");
+ if (need_more_bufs)
+ OSMO_STRBUF_PRINTF(sb, "<need-more-bufs!>");
+ OSMO_STRBUF_PRINTF(sb, ":%s", portbuf);
+ }
+
+ return sb.chars_needed;
+}
+
+/*! Get address/port information on socket in provided string buffer, like "r=1.2.3.4:5<->l=6.7.8.9:10".
+ * This does not include braces like osmo_sock_get_name().
+ * \param[out] str Destination string buffer.
+ * \param[in] str_len sizeof(str).
+ * \param[in] fd File descriptor of socket.
* \return String length as returned by snprintf(), or negative on error.
*/
int osmo_sock_get_name_buf(char *str, size_t str_len, int fd)

To view, visit change 35180. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I48950754ed6f61ee5ffa04a447fab8903f10acc0
Gerrit-Change-Number: 35180
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin@sysmocom.de>
Gerrit-MessageType: newchange