Skip to content

Commit 950f3dc

Browse files
committed
get_sockaddr_str: obtain IPv6 scope ID
write the IPv6 link-local address with scope ID This is achieved by using getnameinfo instead of inet_ntop. Also rewritten in respect to the above change - simplified, no need to get the port number separately (getnameinfo does that as well).
1 parent 16e647c commit 950f3dc

File tree

5 files changed

+55
-57
lines changed

5 files changed

+55
-57
lines changed

src/audio/playback/mixer.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,8 @@ void state_audio_mixer::worker()
339339
MSG(NOTICE, "removed participant: %s\n",
340340
get_sockaddr_str(
341341
(const struct sockaddr *) &it->first,
342-
buf, sizeof buf));
342+
sizeof it->first, buf, sizeof buf));
343+
343344
it = participants.erase(it);
344345
} else {
345346
++it;
@@ -453,9 +454,9 @@ static void audio_play_mixer_put_frame(void *state, const struct audio_frame *fr
453454
if (s->participants.find(ss) == s->participants.end()) {
454455
char buf[ADDR_STR_BUF_LEN];
455456
MSG(NOTICE, "added participant: %s\n",
456-
get_sockaddr_str(
457-
(struct sockaddr *) &ss, buf,
458-
sizeof buf));
457+
get_sockaddr_str((struct sockaddr *) &ss,
458+
sizeof(struct sockaddr_storage), buf,
459+
sizeof buf));
459460
s->participants.emplace(ss, am_participant{s->recv_socket, &ss, s->audio_codec});
460461
}
461462

src/hd-rum-translator/hd-rum-translator.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,7 @@ class Participant_manager{
889889
std::string msg = "delete-port ";
890890
auto addr = reinterpret_cast<struct sockaddr *>(&it->addr);
891891
char replica_name[ADDR_STR_BUF_LEN];
892-
msg += get_sockaddr_str(addr, replica_name,
892+
msg += get_sockaddr_str(addr, sizeof sin, replica_name,
893893
sizeof replica_name);
894894

895895
std::swap(*it, participants.back());
@@ -919,7 +919,7 @@ class Participant_manager{
919919
char buf[ADDR_STR_BUF_LEN];
920920
msg +=
921921
get_sockaddr_str(reinterpret_cast<sockaddr *>(&sin),
922-
buf, sizeof buf);
922+
addrlen, buf, sizeof buf);
923923
if(!compression.empty()){
924924
msg += " ";
925925
msg += compression;

src/rtp/rtp.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1574,7 +1574,8 @@ static void rtp_process_data(struct rtp *session, uint32_t curr_rtp_ts,
15741574
session->opt->send_back = FALSE; // avoid multiple checks if already sending
15751575
struct sockaddr *sa = (struct sockaddr *)(void *)((char *) packet + RTP_MAX_PACKET_LEN);
15761576
MSG(NOTICE, "Redirecting stream to a client %s.\n",
1577-
get_sockaddr_str(sa, (char[ADDR_STR_BUF_LEN]){ 0 },
1577+
get_sockaddr_str(sa, sizeof(struct sockaddr_storage),
1578+
(char[ADDR_STR_BUF_LEN]){ 0 },
15781579
ADDR_STR_BUF_LEN));
15791580
udp_set_receiver(session->rtp_socket, sa, sa->sa_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6));
15801581
}

src/utils/net.c

Lines changed: 25 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -411,64 +411,42 @@ bool is_ipv6_supported(void)
411411
return true;
412412
}
413413

414-
static unsigned
415-
get_sockaddr_addr_port(const struct sockaddr *sa)
414+
/**
415+
* @brief writes string "host:port" for given sockaddr
416+
*
417+
* IPv6 addresses will be enclosed in brackets [], scope ID is output as well if
418+
* defined.
419+
*
420+
* @param n size of buf; must be at least @ref ADDR_STR_BUF_LEN
421+
* @returns the input buffer (buf) pointer with result
422+
*/
423+
char *
424+
get_sockaddr_str(const struct sockaddr *sa, unsigned sa_len, char *buf,
425+
size_t n)
416426
{
417-
unsigned port = 0;
418-
if (sa->sa_family == AF_INET6) {
419-
port = ntohs(((const struct sockaddr_in6 *) (const void *) sa)
420-
->sin6_port);
421-
} else if (sa->sa_family == AF_INET) {
422-
port = ntohs(
423-
((const struct sockaddr_in *) (const void *) sa)->sin_port);
424-
} else {
425-
return UINT_MAX;
426-
}
427+
assert(n >= ADDR_STR_BUF_LEN);
427428

428-
return port;
429-
}
429+
char *buf_ptr = buf; // ptr to be appended to
430+
const char *buf_end = buf + n; // endptr to check
430431

431-
static char *
432-
get_sockaddr_addr_str(const struct sockaddr *sa, char *buf, size_t n)
433-
{
434-
const void *src = NULL;
435432
if (sa->sa_family == AF_INET6) {
436-
snprintf(buf, n, "[");
437-
src = &((const struct sockaddr_in6 *) (const void *) sa)
438-
->sin6_addr;
439-
} else if (sa->sa_family == AF_INET) {
440-
src =
441-
&((const struct sockaddr_in *) (const void *) sa)->sin_addr;
442-
} else {
443-
snprintf(buf, n, "(unknown)");
444-
return buf;
433+
buf_ptr += snprintf(buf_ptr, buf_end - buf_ptr, "[");
445434
}
446-
if (inet_ntop(sa->sa_family, src, buf + strlen(buf), n - strlen(buf)) == NULL) {
447-
perror("get_sockaddr_str");
435+
char port[IN_PORT_STR_LEN + 1];
436+
const int rc =
437+
getnameinfo(sa, sa_len, buf_ptr, buf_end - buf_ptr, port,
438+
sizeof port, NI_NUMERICHOST | NI_NUMERICSERV);
439+
if (rc != 0) {
440+
MSG(ERROR, "%s getnameinfo: %s\n", __func__, gai_strerror(rc));
448441
snprintf(buf, n, "(error)");
449442
return buf;
450443
}
444+
buf_ptr += strlen(buf_ptr);
451445

452446
if (sa->sa_family == AF_INET6) {
453-
snprintf(buf + strlen(buf), n - strlen(buf), "]");
447+
buf_ptr += snprintf(buf_ptr, buf_end - buf_ptr, "]");
454448
}
455-
return buf;
456-
}
457-
458-
/**
459-
* @param n size of buf; must be at least ADDR_STR_BUF_LEN
460-
* @returns the input buffer (buf)
461-
*/
462-
char *
463-
get_sockaddr_str(const struct sockaddr *sa, char *buf, size_t n)
464-
{
465-
assert(n >= ADDR_STR_BUF_LEN);
466-
get_sockaddr_addr_str(sa, buf, n);
467-
468-
unsigned port = get_sockaddr_addr_port(sa);
469-
if(port == UINT_MAX)
470-
return buf;
471-
snprintf(buf + strlen(buf), n - strlen(buf), ":%u", port);
449+
buf_ptr += snprintf(buf_ptr, buf_end - buf_ptr, ":%s", port);
472450

473451
return buf;
474452
}

src/utils/net.h

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,27 @@
4747
#include <stdint.h>
4848
#endif // __cplusplus
4949

50+
#ifdef _WIN32
51+
#include <winsock2.h> // dep for netioapi.h, ntddnidis.h
52+
#include <ntddndis.h> // dep for IF_NAMESIZE
53+
#include <iphlpapi.h> // for IF_NAMESIZE
54+
#else
55+
#include <net/if.h> // for IF_NAMESIZE
56+
#endif
57+
5058
enum {
51-
IN6_MAX_ASCII_LEN = 39, // 32 nibbles + 7 colons
59+
/// maximal length of textual representation of IPv6 address including
60+
/// eventual scope ID but without terminating NUL byte
61+
IN6_MAX_ASCII_LEN = 40 /* 32 nibbles + 7 colons + "%" */ + IF_NAMESIZE,
62+
/// not including terminating NUL
63+
IN_PORT_STR_LEN = 5,
64+
/**
65+
* buffer for host:port represenation. If IPv6 address is presented,
66+
* enclosed in []. Including terminating NUL byte.
67+
* @sa get_sockaddr_str
68+
*/
5269
ADDR_STR_BUF_LEN =
53-
IN6_MAX_ASCII_LEN + 3 /* []: */ + 5 /* port */ + 1 /* \0 */,
70+
IN6_MAX_ASCII_LEN + 3 /* []: */ + IN_PORT_STR_LEN + 1 /* \0 */,
5471
};
5572
// RFC 6666 prefix 100::/64, suffix 'UltrGrS'
5673
#define IN6_BLACKHOLE_SERVER_MODE_STR "100::556C:7472:4772:6453"
@@ -70,7 +87,8 @@ bool is_host_private(const char *hostname);
7087
uint16_t socket_get_recv_port(int fd);
7188
bool get_local_addresses(struct sockaddr_storage *addrs, size_t *len, int ip_version);
7289
bool is_ipv6_supported(void);
73-
char *get_sockaddr_str(const struct sockaddr *sa, char *buf, size_t n);
90+
char *get_sockaddr_str(const struct sockaddr *sa, unsigned sa_len, char *buf,
91+
size_t n);
7492
const char *ug_gai_strerror(int errcode);
7593

7694
#ifdef _WIN32

0 commit comments

Comments
 (0)