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
|
||||
/* 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 == 1: "hostA"
|
||||
* 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;
|
||||
size_t i;
|
||||
int ret;
|
||||
bool use_hosts = hosts ? true : false;
|
||||
size_t i, count = use_hosts ? host_count : addrs_count;
|
||||
struct osmo_sockaddr_str t;
|
||||
struct osmo_sockaddr_str *oss = &t;
|
||||
char *after;
|
||||
int rc;
|
||||
|
||||
if (buf_len < 3)
|
||||
return -EINVAL;
|
||||
if (sb->len < 3)
|
||||
return -ENOMEM;
|
||||
|
||||
if (host_cnt != 1) {
|
||||
ret = snprintf(buf, rem, "(");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
OSMO_SNPRINTF_RET(ret, rem, offset, len);
|
||||
}
|
||||
for (i = 0; i < host_cnt; i++) {
|
||||
if (host_cnt == 1)
|
||||
if (count != 1)
|
||||
OSMO_STRBUF_PRINTF(*sb, "(");
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
const struct sockaddr *addr = &(*addrs)[i];
|
||||
|
||||
if (count == 1)
|
||||
after = "";
|
||||
else
|
||||
after = (i == (host_cnt - 1)) ? ")" : "|";
|
||||
ret = snprintf(buf + offset, rem, "%s%s", hosts[i] ? : "0.0.0.0", after);
|
||||
OSMO_SNPRINTF_RET(ret, rem, offset, len);
|
||||
after = (i == (count - 1)) ? ")" : "|";
|
||||
|
||||
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 */
|
||||
|
||||
|
@ -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;
|
||||
struct sockaddr_in6 addrs_buf[OSMO_SOCK_MAX_ADDRS];
|
||||
char strbuf[512];
|
||||
struct osmo_strbuf sb = { .buf = strbuf, .len = 512 };
|
||||
|
||||
/* updated later in case of AF_UNSPEC */
|
||||
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,
|
||||
&on, sizeof(on));
|
||||
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,
|
||||
"cannot setsockopt socket:"
|
||||
" %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);
|
||||
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",
|
||||
strbuf, local_port, strerror(errno));
|
||||
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);
|
||||
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",
|
||||
strbuf, remote_port, strerror(errno));
|
||||
rc = -ENODEV;
|
||||
|
|
Loading…
Reference in New Issue