mirror of https://gerrit.osmocom.org/libosmocore
Update multiaddr helper
* use osmo_strbuf instead of plain buffer * properly handle OOM * fix missing trailing ')' Related: OS#5581 Change-Id: Icef53fe4b6e51563d97a1bc48001d67679b3b6e9
This commit is contained in:
parent
e816ac673a
commit
e2ac1a1b4c
65
src/socket.c
65
src/socket.c
|
@ -202,37 +202,57 @@ static int socket_helper_osa(const struct osmo_sockaddr *addr, uint16_t type, ui
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LIBSCTP
|
#ifdef HAVE_LIBSCTP
|
||||||
/* Fill buf with a string representation of the address set, in the form:
|
/* Fill osmo_strbuf with a string representation of the address set, in the form:
|
||||||
* buf_len == 0: "()"
|
* buf_len == 0: "()"
|
||||||
* buf_len == 1: "hostA"
|
* buf_len == 1: "hostA"
|
||||||
* buf_len >= 2: (hostA|hostB|...|...)
|
* buf_len >= 2: (hostA|hostB|...|...)
|
||||||
*/
|
*/
|
||||||
static int multiaddr_snprintf(char* buf, size_t buf_len, const char **hosts, size_t host_cnt)
|
static int multiaddr_strbuf(struct osmo_strbuf *sb,
|
||||||
|
const char **hosts, size_t host_count,
|
||||||
|
struct sockaddr **addrs, size_t addrs_count)
|
||||||
{
|
{
|
||||||
int len = 0, offset = 0, rem = buf_len;
|
bool use_hosts = hosts ? true : false;
|
||||||
size_t i;
|
size_t i, count = use_hosts ? host_count : addrs_count;
|
||||||
int ret;
|
struct osmo_sockaddr_str t;
|
||||||
|
struct osmo_sockaddr_str *oss = &t;
|
||||||
char *after;
|
char *after;
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (buf_len < 3)
|
if (sb->len < 3)
|
||||||
return -EINVAL;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (host_cnt != 1) {
|
if (count != 1)
|
||||||
ret = snprintf(buf, rem, "(");
|
OSMO_STRBUF_PRINTF(*sb, "(");
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
for (i = 0; i < count; i++) {
|
||||||
OSMO_SNPRINTF_RET(ret, rem, offset, len);
|
const struct sockaddr *addr = &(*addrs)[i];
|
||||||
}
|
|
||||||
for (i = 0; i < host_cnt; i++) {
|
if (count == 1)
|
||||||
if (host_cnt == 1)
|
|
||||||
after = "";
|
after = "";
|
||||||
else
|
else
|
||||||
after = (i == (host_cnt - 1)) ? ")" : "|";
|
after = (i == (count - 1)) ? ")" : "|";
|
||||||
ret = snprintf(buf + offset, rem, "%s%s", hosts[i] ? : "0.0.0.0", after);
|
|
||||||
OSMO_SNPRINTF_RET(ret, rem, offset, len);
|
if (use_hosts) {
|
||||||
|
if (hosts[i])
|
||||||
|
OSMO_STRBUF_PRINTF(*sb, "%s%s", hosts[i], after);
|
||||||
|
} else {
|
||||||
|
rc = osmo_sockaddr_str_from_sockaddr(oss, (const struct sockaddr_storage *)addr);
|
||||||
|
if (rc < 0) {
|
||||||
|
LOGP(DLGLOBAL, LOGL_DEBUG, "Conversion failure in multiaddr_strbuf(): %s\n", strerror(-rc));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
OSMO_STRBUF_PRINTF(*sb, OSMO_SOCKADDR_STR_NO_PORT_FMT "%s",
|
||||||
|
OSMO_SOCKADDR_STR_NO_PORT_FMT_ARGS(oss), after);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
if (count == 0)
|
||||||
|
OSMO_STRBUF_PRINTF(*sb, ")");
|
||||||
|
|
||||||
|
if (sb->chars_needed >= sb->len)
|
||||||
|
return -ENOSPC;
|
||||||
|
|
||||||
|
return sb->chars_needed;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_LIBSCTP */
|
#endif /* HAVE_LIBSCTP */
|
||||||
|
|
||||||
|
@ -726,6 +746,7 @@ int osmo_sock_init2_multiaddr(uint16_t family, uint16_t type, uint8_t proto,
|
||||||
bool loc_has_v6addr, rem_has_v6addr;
|
bool loc_has_v6addr, rem_has_v6addr;
|
||||||
struct sockaddr_in6 addrs_buf[OSMO_SOCK_MAX_ADDRS];
|
struct sockaddr_in6 addrs_buf[OSMO_SOCK_MAX_ADDRS];
|
||||||
char strbuf[512];
|
char strbuf[512];
|
||||||
|
struct osmo_strbuf sb = { .buf = strbuf, .len = 512 };
|
||||||
|
|
||||||
/* updated later in case of AF_UNSPEC */
|
/* updated later in case of AF_UNSPEC */
|
||||||
loc_has_v4addr = rem_has_v4addr = (family == AF_INET);
|
loc_has_v4addr = rem_has_v4addr = (family == AF_INET);
|
||||||
|
@ -794,7 +815,7 @@ int osmo_sock_init2_multiaddr(uint16_t family, uint16_t type, uint8_t proto,
|
||||||
rc = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR,
|
rc = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR,
|
||||||
&on, sizeof(on));
|
&on, sizeof(on));
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
multiaddr_snprintf(strbuf, sizeof(strbuf), local_hosts, local_hosts_cnt);
|
multiaddr_strbuf(&sb, local_hosts, local_hosts_cnt, NULL, 0);
|
||||||
LOGP(DLGLOBAL, LOGL_ERROR,
|
LOGP(DLGLOBAL, LOGL_ERROR,
|
||||||
"cannot setsockopt socket:"
|
"cannot setsockopt socket:"
|
||||||
" %s:%u: %s\n",
|
" %s:%u: %s\n",
|
||||||
|
@ -817,7 +838,7 @@ int osmo_sock_init2_multiaddr(uint16_t family, uint16_t type, uint8_t proto,
|
||||||
|
|
||||||
rc = sctp_bindx(sfd, (struct sockaddr *)addrs_buf, local_hosts_cnt, SCTP_BINDX_ADD_ADDR);
|
rc = sctp_bindx(sfd, (struct sockaddr *)addrs_buf, local_hosts_cnt, SCTP_BINDX_ADD_ADDR);
|
||||||
if (rc == -1) {
|
if (rc == -1) {
|
||||||
multiaddr_snprintf(strbuf, sizeof(strbuf), local_hosts, local_hosts_cnt);
|
multiaddr_strbuf(&sb, local_hosts, local_hosts_cnt, NULL, 0);
|
||||||
LOGP(DLGLOBAL, LOGL_NOTICE, "unable to bind socket: %s:%u: %s\n",
|
LOGP(DLGLOBAL, LOGL_NOTICE, "unable to bind socket: %s:%u: %s\n",
|
||||||
strbuf, local_port, strerror(errno));
|
strbuf, local_port, strerror(errno));
|
||||||
rc = -ENODEV;
|
rc = -ENODEV;
|
||||||
|
@ -839,7 +860,7 @@ int osmo_sock_init2_multiaddr(uint16_t family, uint16_t type, uint8_t proto,
|
||||||
|
|
||||||
rc = sctp_connectx(sfd, (struct sockaddr *)addrs_buf, remote_hosts_cnt, NULL);
|
rc = sctp_connectx(sfd, (struct sockaddr *)addrs_buf, remote_hosts_cnt, NULL);
|
||||||
if (rc != 0 && errno != EINPROGRESS) {
|
if (rc != 0 && errno != EINPROGRESS) {
|
||||||
multiaddr_snprintf(strbuf, sizeof(strbuf), remote_hosts, remote_hosts_cnt);
|
multiaddr_strbuf(&sb, remote_hosts, remote_hosts_cnt, NULL, 0);
|
||||||
LOGP(DLGLOBAL, LOGL_ERROR, "unable to connect socket: %s:%u: %s\n",
|
LOGP(DLGLOBAL, LOGL_ERROR, "unable to connect socket: %s:%u: %s\n",
|
||||||
strbuf, remote_port, strerror(errno));
|
strbuf, remote_port, strerror(errno));
|
||||||
rc = -ENODEV;
|
rc = -ENODEV;
|
||||||
|
|
Loading…
Reference in New Issue