Skip to content

Commit d90d283

Browse files
committed
sockaddr_compare: handle v4-mapped sockaddr_in6
Current implementation of resolve_addrinfo defaults to v4-mapped ipv6 addresses even for dotted decimal.
1 parent 9fd68d6 commit d90d283

File tree

3 files changed

+47
-3
lines changed

3 files changed

+47
-3
lines changed

src/utils/net.c

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

521+
/**
522+
* If addr6 is not a v4-mapped address, return it.
523+
* Otherwise convert to sockaddr_in AF_INET address.
524+
*/
525+
static const struct sockaddr *
526+
v4_unmap(const struct sockaddr_in6 *addr6, struct sockaddr_in *buf4)
527+
{
528+
if (!IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
529+
return (const struct sockaddr *) addr6;
530+
}
531+
buf4->sin_family = AF_INET;
532+
buf4->sin_port = addr6->sin6_port;
533+
union {
534+
uint8_t bytes[4];
535+
uint32_t word;
536+
} u;
537+
for (int i = 0; i < 4; ++i) {
538+
u.bytes[i] = addr6->sin6_addr.s6_addr[12 + i];
539+
}
540+
buf4->sin_addr.s_addr = u.word;
541+
return (struct sockaddr *) buf4;
542+
}
543+
521544
/**
522545
* @retval <0 struct represents "smaller" address (port)
523546
* @retval 0 addresses equal
524547
* @retval >0 struct represents "bigger" address (port)
525548
* @note
526-
* v4-mapped ports are not handled
549+
* v4-mapped ipv6 address is considered eqaul to corresponding AF_INET addr
527550
*/
528551
int
529552
sockaddr_compare(const struct sockaddr *x, const struct sockaddr *y)
530553
{
554+
struct sockaddr_in tmp1;
555+
if (x->sa_family == AF_INET6) {
556+
x = v4_unmap((const struct sockaddr_in6 *) x, &tmp1);
557+
}
558+
struct sockaddr_in tmp2;
559+
if (y->sa_family == AF_INET6) {
560+
y = v4_unmap((const struct sockaddr_in6 *) y, &tmp2);
561+
}
562+
531563
if (x->sa_family != y->sa_family) {
532564
return y->sa_family - x->sa_family;
533565
}
@@ -564,7 +596,7 @@ sockaddr_compare(const struct sockaddr *x, const struct sockaddr *y)
564596
: 1;
565597
}
566598

567-
return ntohs(sin_y->sin6_port) - sin_x->sin6_port;
599+
return ntohs(sin_y->sin6_port) - ntohs(sin_x->sin6_port);
568600
}
569601
MSG(ERROR, "Unsupported address class %d!", (int) x->sa_family);
570602
abort();

test/misc_test.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414

1515
extern "C" {
1616
int misc_test_color_coeff_range();
17+
int misc_test_net_getsockaddr();
18+
int misc_test_net_sockaddr_compare_v4_mapped();
1719
int misc_test_replace_all();
1820
int misc_test_video_desc_io_op_symmetry();
19-
int misc_test_net_getsockaddr();
2021
}
2122

2223
using namespace std;
@@ -108,6 +109,15 @@ misc_test_net_getsockaddr()
108109
return 0;
109110
}
110111

112+
int misc_test_net_sockaddr_compare_v4_mapped() {
113+
struct sockaddr_storage v4 = get_sockaddr("10.0.0.1:10", 4);
114+
struct sockaddr_storage v4mapped = get_sockaddr("10.0.0.1:10", 0);
115+
ASSERT_MESSAGE("V4 mapped address doesn't equal plain V4",
116+
sockaddr_compare((struct sockaddr *) &v4,
117+
(struct sockaddr *) &v4mapped) == 0);
118+
return 0;
119+
}
120+
111121
#ifdef __clang__
112122
#pragma clang diagnostic ignored "-Wstring-concatenation"
113123
#endif

test/run_tests.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ DECLARE_TEST(gpujpeg_test_simple);
8888
DECLARE_TEST(libavcodec_test_get_decoder_from_uv_to_uv);
8989
DECLARE_TEST(misc_test_color_coeff_range);
9090
DECLARE_TEST(misc_test_net_getsockaddr);
91+
DECLARE_TEST(misc_test_net_sockaddr_compare_v4_mapped);
9192
DECLARE_TEST(misc_test_replace_all);
9293
DECLARE_TEST(misc_test_video_desc_io_op_symmetry);
9394

@@ -123,6 +124,7 @@ struct {
123124
DEFINE_TEST(libavcodec_test_get_decoder_from_uv_to_uv),
124125
DEFINE_TEST(misc_test_color_coeff_range),
125126
DEFINE_TEST(misc_test_net_getsockaddr),
127+
DEFINE_TEST(misc_test_net_sockaddr_compare_v4_mapped),
126128
DEFINE_TEST(misc_test_replace_all),
127129
DEFINE_TEST(misc_test_video_desc_io_op_symmetry),
128130
};

0 commit comments

Comments
 (0)