mirror of https://gerrit.osmocom.org/libosmocore
socket: Introduce API osmo_sock_sctp_get_peer_addr_info()
This is a convenience helper to reetrieve the whole set of remote addresses and call getsockopt() on them, making it easy for users to analyse the full set of remote addresses of a socket simply providing an fd. Related: SYS#6636 Change-Id: I3e1c84526b006baff435bbbca49dc6cf7d201cf5
This commit is contained in:
parent
9c603e64bf
commit
19f27bb551
|
@ -9,6 +9,7 @@
|
|||
#library what description / commit summary line
|
||||
core ADD osmo_sock_multiaddr_{add,del}_local_addr()
|
||||
core ADD osmo_sock_multiaddr_get_ip_and_port(), osmo_multiaddr_ip_and_port_snprintf(), osmo_sock_multiaddr_get_name_buf()
|
||||
core ADD osmo_sock_sctp_get_peer_addr_info()
|
||||
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
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
struct sockaddr_in;
|
||||
struct sockaddr;
|
||||
struct osmo_fd;
|
||||
struct sctp_paddrinfo;
|
||||
|
||||
struct osmo_sockaddr {
|
||||
union {
|
||||
|
@ -211,5 +212,7 @@ int osmo_sock_local_ip(char *local_ip, const char *remote_ip);
|
|||
int osmo_sock_set_dscp(int fd, uint8_t dscp);
|
||||
int osmo_sock_set_priority(int fd, int prio);
|
||||
|
||||
int osmo_sock_sctp_get_peer_addr_info(int fd, struct sctp_paddrinfo *pinfo, size_t *pinfo_cnt);
|
||||
|
||||
#endif /* (!EMBEDDED) */
|
||||
/*! @} */
|
||||
|
|
|
@ -439,6 +439,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_sctp_get_peer_addr_info;
|
||||
osmo_sock_set_dscp;
|
||||
osmo_sock_set_priority;
|
||||
osmo_sock_unix_init;
|
||||
|
|
|
@ -2653,6 +2653,83 @@ int osmo_sock_set_priority(int fd, int prio)
|
|||
return setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio));
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBSCTP
|
||||
/*! Fill in array of struct sctp_paddrinfo with each of the remote addresses of an SCTP socket
|
||||
* \param[in] fd file descriptor of SCTP socket
|
||||
* \param[out] pinfo Pointer to memory holding an array of struct sctp_paddrinfo (pinfo_cnt length).
|
||||
* \param[in,out] pinfo_cnt length of pinfo array (in elements). On return it contains the number of addresses found.
|
||||
* \returns 0 on success; negative otherwise
|
||||
*
|
||||
* Upon return, pinfo_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 pinfo_cnt addresses
|
||||
* are filled in, as per the value provided by the caller.
|
||||
*
|
||||
* Usage example retrieving struct sctp_paddrinfo for all (up to OSMO_SOCK_MAX_ADDRS, 32) remote IP addresses:
|
||||
* struct sctp_paddrinfo pinfo[OSMO_SOCK_MAX_ADDRS];
|
||||
* size_t pinfo_cnt = ARRAY_SIZE(pinfo);
|
||||
* rc = osmo_sock_sctp_get_peer_addr_info(fd, &pinfo[0], &num_hostbuf, pinfo_cnt);
|
||||
* if (rc < 0)
|
||||
* goto error;
|
||||
* if (pinfo_cnt > ARRAY_SIZE(hostbuf))
|
||||
* goto not_enough_buffers;
|
||||
*/
|
||||
int osmo_sock_sctp_get_peer_addr_info(int fd, struct sctp_paddrinfo *pinfo, size_t *pinfo_cnt)
|
||||
{
|
||||
struct sockaddr *addrs = NULL;
|
||||
unsigned int n_addrs, i;
|
||||
void *addr_buf;
|
||||
int rc;
|
||||
socklen_t optlen;
|
||||
|
||||
rc = 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;
|
||||
|
||||
switch (sa_addr->sa_family) {
|
||||
case AF_INET:
|
||||
addrlen = sizeof(struct sockaddr_in);
|
||||
break;
|
||||
case AF_INET6:
|
||||
addrlen = sizeof(struct sockaddr_in6);
|
||||
break;
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
goto free_addrs_ret;
|
||||
}
|
||||
|
||||
if (i >= *pinfo_cnt) {
|
||||
addr_buf += addrlen;
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(&pinfo[i], 0, sizeof(pinfo[0]));
|
||||
memcpy(&pinfo[i].spinfo_address, sa_addr, addrlen);
|
||||
optlen = sizeof(pinfo[0]);
|
||||
rc = getsockopt(fd, SOL_SCTP, SCTP_GET_PEER_ADDR_INFO, &pinfo[i], &optlen);
|
||||
if (rc < 0)
|
||||
goto free_addrs_ret;
|
||||
|
||||
addr_buf += addrlen;
|
||||
}
|
||||
|
||||
*pinfo_cnt = n_addrs;
|
||||
rc = 0;
|
||||
free_addrs_ret:
|
||||
sctp_freepaddrs(addrs);
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_SYS_SOCKET_H */
|
||||
|
||||
/*! @} */
|
||||
|
|
Loading…
Reference in New Issue