pespin has uploaded this change for review.

View Change

socket: Introduce API osmo_sock_multiaddr_get_ip_and_port()

Related: SYS#6636
Related: OS#5581
Change-Id: I19d560ab4aadec18a4c0f94115675ec1d7ab14d7
---
M TODO-RELEASE
M include/osmocom/core/socket.h
M src/core/libosmocore.map
M src/core/socket.c
4 files changed, 94 insertions(+), 0 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/79/35179/1
diff --git a/TODO-RELEASE b/TODO-RELEASE
index fa7bc57..e365746 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -8,6 +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 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 03f1d39..9397343 100644
--- a/include/osmocom/core/socket.h
+++ b/include/osmocom/core/socket.h
@@ -191,6 +191,8 @@
int osmo_sock_get_remote_ip(int fd, char *host, size_t len);
int osmo_sock_get_remote_ip_port(int fd, char *port, size_t len);

+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_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 3d6aa42..1d00fe8 100644
--- a/src/core/libosmocore.map
+++ b/src/core/libosmocore.map
@@ -436,6 +436,7 @@
osmo_sock_mcast_ttl_set;
osmo_sock_multiaddr_add_local_addr;
osmo_sock_multiaddr_del_local_addr;
+osmo_sock_multiaddr_get_ip_and_port;
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 1dc8e46..1d97018 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -1807,6 +1807,85 @@
return 0;
}

+/*! Get the IP and/or port number on socket in separate string buffers.
+ * \param[in] fd file descriptor of socket
+* \param[out] ip_proto IPPROTO of the socket, eg: IPPROTO_SCTP.
+ * \param[out] ip Pointer to memory holding consecutive buffers of size ip_len
+ * \param[in] ip_len length of each of the string buffer in the the ip array
+ * \param[in] ip_cnt length ip array pointer. on return it contains the number of addresses found.
+ * \param[out] port number (will be filled in when not NULL)
+ * \param[in] port_len length of the port buffer
+ * \param[in] local (true) or remote (false) name will get looked at
+ * \returns 0 on success; negative otherwise
+ *
+ * Upon return, ip_cnt can be set to a higher value than the one set by the
+ * caller. This can be used by the caller to find out the required array length
+ * and then obtaining by calling the function twice. Only up to ip_cnt addresses
+ * are filed in, as per the value provided by the caller.
+ */
+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)
+{
+ struct sockaddr *addrs = NULL;
+ unsigned int n_addrs, i;
+ void *addr_buf;
+ int rc;
+
+ switch (ip_proto) {
+ case IPPROTO_SCTP:
+ break; /* continue below */
+ default:
+ if (*ip_cnt == 0) {
+ *ip_cnt = 1;
+ return 0;
+ }
+ *ip_cnt = 1;
+ rc = osmo_sock_get_ip_and_port(fd, ip, ip_len, port, port_len, local);
+ return rc;
+ }
+
+ rc = local ? sctp_getladdrs(fd, 0, &addrs) : sctp_getpaddrs(fd, 0, &addrs);
+ if (rc < 0)
+ return rc;
+ if (rc == 0)
+ return -ENOTCONN;
+
+ n_addrs = rc;
+ addr_buf = (void *)addrs;
+ for (i = 0; i < n_addrs; i++) {
+ struct sockaddr *sa_addr = (struct sockaddr *)addr_buf;
+ size_t addrlen;
+
+ if (i >= *ip_cnt)
+ break;
+
+ switch (sa_addr->sa_family) {
+ case AF_INET:
+ addrlen = sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6:
+ addrlen = sizeof(struct sockaddr_in6);
+ break;
+ default:
+ local ? sctp_freeladdrs(addrs) : sctp_freepaddrs(addrs);
+ return -EINVAL;
+ }
+
+ rc = getnameinfo(sa_addr, addrlen, &ip[i*ip_len], ip_len,
+ port, port_len,
+ NI_NUMERICHOST | NI_NUMERICSERV);
+ if (rc < 0) {
+ local ? sctp_freeladdrs(addrs) : sctp_freepaddrs(addrs);
+ return rc;
+ }
+ addr_buf += addrlen;
+ }
+
+ *ip_cnt = n_addrs;
+ local ? sctp_freeladdrs(addrs) : sctp_freepaddrs(addrs);
+ return 0;
+}
+
/*! Get local IP address on socket
* \param[in] fd file descriptor of socket
* \param[out] ip IP address (will be filled in)

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

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