mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Fix flaky RawPingAndSockets (and MultipleSocketsRecieve just in case).
PiperOrigin-RevId: 238474202 Change-Id: Ib8c431e973e8cf1e1c8ee2f8c1978ddb8e88b0b8
This commit is contained in:
committed by
Shentubot
parent
5496be7c5d
commit
6ee3d6614b
@@ -164,23 +164,45 @@ TEST_F(RawSocketTest, MultipleSocketReceive) {
|
||||
icmp.un.echo.id = 2018;
|
||||
ASSERT_NO_FATAL_FAILURE(SendEmptyICMP(&icmp));
|
||||
|
||||
// Receive it on socket 1.
|
||||
char recv_buf1[512];
|
||||
// Both sockets will receive the echo request and reply in indeterminate
|
||||
// order, so we'll need to read 2 packets from each.
|
||||
|
||||
// Receive on socket 1.
|
||||
constexpr int kBufSize = 256;
|
||||
std::vector<char[kBufSize]> recv_buf1(2);
|
||||
struct sockaddr_in src;
|
||||
ASSERT_NO_FATAL_FAILURE(ReceiveICMP(recv_buf1, ABSL_ARRAYSIZE(recv_buf1),
|
||||
sizeof(struct icmphdr), &src));
|
||||
EXPECT_EQ(memcmp(&src, &addr_, sizeof(sockaddr_in)), 0);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ASSERT_NO_FATAL_FAILURE(ReceiveICMP(recv_buf1[i],
|
||||
ABSL_ARRAYSIZE(recv_buf1[i]),
|
||||
sizeof(struct icmphdr), &src));
|
||||
EXPECT_EQ(memcmp(&src, &addr_, sizeof(sockaddr_in)), 0);
|
||||
}
|
||||
|
||||
// Receive it on socket 2.
|
||||
char recv_buf2[512];
|
||||
ASSERT_NO_FATAL_FAILURE(ReceiveICMPFrom(recv_buf2, ABSL_ARRAYSIZE(recv_buf2),
|
||||
sizeof(struct icmphdr), &src,
|
||||
s2.get()));
|
||||
EXPECT_EQ(memcmp(&src, &addr_, sizeof(sockaddr_in)), 0);
|
||||
// Receive on socket 2.
|
||||
std::vector<char[kBufSize]> recv_buf2(2);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
ReceiveICMPFrom(recv_buf2[i], ABSL_ARRAYSIZE(recv_buf2[i]),
|
||||
sizeof(struct icmphdr), &src, s2.get()));
|
||||
EXPECT_EQ(memcmp(&src, &addr_, sizeof(sockaddr_in)), 0);
|
||||
}
|
||||
|
||||
EXPECT_EQ(memcmp(recv_buf1 + sizeof(struct iphdr),
|
||||
recv_buf2 + sizeof(struct iphdr), sizeof(icmp)),
|
||||
0);
|
||||
// Ensure both sockets receive identical packets.
|
||||
int types[] = {ICMP_ECHO, ICMP_ECHOREPLY};
|
||||
for (int type : types) {
|
||||
auto match_type = [=](char buf[kBufSize]) {
|
||||
struct icmphdr *icmp =
|
||||
reinterpret_cast<struct icmphdr *>(buf + sizeof(struct iphdr));
|
||||
return icmp->type == type;
|
||||
};
|
||||
char *icmp1 = *std::find_if(recv_buf1.begin(), recv_buf1.end(), match_type);
|
||||
char *icmp2 = *std::find_if(recv_buf2.begin(), recv_buf2.end(), match_type);
|
||||
ASSERT_NE(icmp1, *recv_buf1.end());
|
||||
ASSERT_NE(icmp2, *recv_buf2.end());
|
||||
EXPECT_EQ(memcmp(icmp1 + sizeof(struct iphdr), icmp2 + sizeof(struct iphdr),
|
||||
sizeof(icmp)),
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
// A raw ICMP socket and ping socket should both receive the ICMP packets
|
||||
@@ -201,23 +223,47 @@ TEST_F(RawSocketTest, RawAndPingSockets) {
|
||||
(struct sockaddr *)&addr_, sizeof(addr_)),
|
||||
SyscallSucceedsWithValue(sizeof(icmp)));
|
||||
|
||||
// Receive the packet via raw socket.
|
||||
char recv_buf[512];
|
||||
// Both sockets will receive the echo request and reply in indeterminate
|
||||
// order, so we'll need to read 2 packets from each.
|
||||
|
||||
// Receive on socket 1.
|
||||
constexpr int kBufSize = 256;
|
||||
std::vector<char[kBufSize]> recv_buf1(2);
|
||||
struct sockaddr_in src;
|
||||
ASSERT_NO_FATAL_FAILURE(ReceiveICMP(recv_buf, ABSL_ARRAYSIZE(recv_buf),
|
||||
sizeof(struct icmphdr), &src));
|
||||
EXPECT_EQ(memcmp(&src, &addr_, sizeof(sockaddr_in)), 0);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
ReceiveICMP(recv_buf1[i], kBufSize, sizeof(struct icmphdr), &src));
|
||||
EXPECT_EQ(memcmp(&src, &addr_, sizeof(sockaddr_in)), 0);
|
||||
}
|
||||
|
||||
// Receive the packet via ping socket.
|
||||
struct icmphdr ping_header;
|
||||
ASSERT_THAT(
|
||||
RetryEINTR(recv)(ping_sock.get(), &ping_header, sizeof(ping_header), 0),
|
||||
SyscallSucceedsWithValue(sizeof(ping_header)));
|
||||
// Receive on socket 2.
|
||||
std::vector<char[kBufSize]> recv_buf2(2);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ASSERT_THAT(RetryEINTR(recv)(ping_sock.get(), recv_buf2[i], kBufSize, 0),
|
||||
SyscallSucceedsWithValue(sizeof(struct icmphdr)));
|
||||
}
|
||||
|
||||
// Packets should be the same.
|
||||
EXPECT_EQ(memcmp(recv_buf + sizeof(struct iphdr), &ping_header,
|
||||
sizeof(struct icmphdr)),
|
||||
0);
|
||||
// Ensure both sockets receive identical packets.
|
||||
int types[] = {ICMP_ECHO, ICMP_ECHOREPLY};
|
||||
for (int type : types) {
|
||||
auto match_type_ping = [=](char buf[kBufSize]) {
|
||||
struct icmphdr *icmp = reinterpret_cast<struct icmphdr *>(buf);
|
||||
return icmp->type == type;
|
||||
};
|
||||
auto match_type_raw = [=](char buf[kBufSize]) {
|
||||
struct icmphdr *icmp =
|
||||
reinterpret_cast<struct icmphdr *>(buf + sizeof(struct iphdr));
|
||||
return icmp->type == type;
|
||||
};
|
||||
|
||||
char *icmp1 =
|
||||
*std::find_if(recv_buf1.begin(), recv_buf1.end(), match_type_raw);
|
||||
char *icmp2 =
|
||||
*std::find_if(recv_buf2.begin(), recv_buf2.end(), match_type_ping);
|
||||
ASSERT_NE(icmp1, *recv_buf1.end());
|
||||
ASSERT_NE(icmp2, *recv_buf2.end());
|
||||
EXPECT_EQ(memcmp(icmp1 + sizeof(struct iphdr), icmp2, sizeof(icmp)), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void RawSocketTest::SendEmptyICMP(struct icmphdr *icmp) {
|
||||
|
||||
Reference in New Issue
Block a user