Skip to content

Commit 9fd68d6

Browse files
committed
aplay/mixer: factor out sockaddr_compare
1 parent 273f6d3 commit 9fd68d6

File tree

3 files changed

+55
-34
lines changed

3 files changed

+55
-34
lines changed

src/audio/playback/mixer.cpp

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -89,40 +89,8 @@ using namespace std::chrono;
8989
class sockaddr_storage_less {
9090
public:
9191
bool operator() (const sockaddr_storage & x, const sockaddr_storage & y) const {
92-
if (x.ss_family != y.ss_family) {
93-
return x.ss_family < y.ss_family;
94-
}
95-
96-
if (x.ss_family == AF_INET) {
97-
const auto &sin_x =
98-
reinterpret_cast<const sockaddr_in &>(x);
99-
const auto &sin_y =
100-
reinterpret_cast<const sockaddr_in &>(y);
101-
102-
if (sin_x.sin_addr.s_addr != sin_y.sin_addr.s_addr) {
103-
return sin_x.sin_addr.s_addr < sin_y.sin_addr.s_addr;
104-
}
105-
return sin_x.sin_port < sin_y.sin_port;
106-
} else if (x.ss_family == AF_INET6) {
107-
const auto &sin_x =
108-
reinterpret_cast<const sockaddr_in6 &>(x);
109-
const auto &sin_y =
110-
reinterpret_cast<const sockaddr_in6 &>(y);
111-
112-
for (int i = 0; i < 16; ++i) {
113-
if (sin_x.sin6_addr.s6_addr[i] != sin_y.sin6_addr.s6_addr[i]) {
114-
return sin_x.sin6_addr.s6_addr[i] < sin_y.sin6_addr.s6_addr[i];
115-
}
116-
}
117-
118-
if (IN6_IS_ADDR_LINKLOCAL(&sin_x.sin6_addr) &&
119-
sin_x.sin6_scope_id != sin_y.sin6_scope_id) {
120-
return sin_x.sin6_scope_id < sin_y.sin6_scope_id;
121-
}
122-
123-
return sin_x.sin6_port < sin_y.sin6_port;
124-
}
125-
abort();
92+
return sockaddr_compare((const sockaddr *) &x,
93+
(const sockaddr *) &y) < 0;
12694
}
12795
};
12896

src/utils/net.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,58 @@ get_sockaddr(const char *hostport, int mode)
518518
return ret;
519519
}
520520

521+
/**
522+
* @retval <0 struct represents "smaller" address (port)
523+
* @retval 0 addresses equal
524+
* @retval >0 struct represents "bigger" address (port)
525+
* @note
526+
* v4-mapped ports are not handled
527+
*/
528+
int
529+
sockaddr_compare(const struct sockaddr *x, const struct sockaddr *y)
530+
{
531+
if (x->sa_family != y->sa_family) {
532+
return y->sa_family - x->sa_family;
533+
}
534+
535+
if (x->sa_family == AF_INET) {
536+
const struct sockaddr_in *sin_x = (const void *) x;
537+
const struct sockaddr_in *sin_y = (const void *) y;
538+
539+
if (sin_x->sin_addr.s_addr != sin_y->sin_addr.s_addr) {
540+
return ntohl(sin_x->sin_addr.s_addr) <
541+
ntohl(sin_y->sin_addr.s_addr)
542+
? -1
543+
: 1;
544+
}
545+
return ntohs(sin_y->sin_port) - ntohs(sin_x->sin_port);
546+
}
547+
if (x->sa_family == AF_INET6) {
548+
const struct sockaddr_in6 *sin_x = (const void *) x;
549+
const struct sockaddr_in6 *sin_y = (const void *) y;
550+
551+
for (int i = 0; i < 16; ++i) {
552+
if (sin_x->sin6_addr.s6_addr[i] !=
553+
sin_y->sin6_addr.s6_addr[i]) {
554+
return sin_y->sin6_addr.s6_addr[i] -
555+
sin_x->sin6_addr.s6_addr[i];
556+
}
557+
}
558+
559+
// sin6_scope_id is opaque so do not cope with endianity
560+
// (actually it is host order on both Linux and Windows)
561+
if (IN6_IS_ADDR_LINKLOCAL(&sin_x->sin6_addr) &&
562+
sin_x->sin6_scope_id != sin_y->sin6_scope_id) {
563+
return sin_x->sin6_scope_id < sin_y->sin6_scope_id ? -1
564+
: 1;
565+
}
566+
567+
return ntohs(sin_y->sin6_port) - sin_x->sin6_port;
568+
}
569+
MSG(ERROR, "Unsupported address class %d!", (int) x->sa_family);
570+
abort();
571+
}
572+
521573
const char *ug_gai_strerror(int errcode)
522574
{
523575
#ifdef _WIN32

src/utils/net.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ char *get_sockaddr_str(const struct sockaddr *sa, unsigned sa_len, char *buf,
9191
size_t n);
9292
struct sockaddr_storage get_sockaddr(const char *hostport, int mode);
9393
const char *ug_gai_strerror(int errcode);
94+
int sockaddr_compare(const struct sockaddr *x, const struct sockaddr *y);
9495

9596
#ifdef _WIN32
9697
#define CLOSESOCKET closesocket

0 commit comments

Comments
 (0)