Skip to content

Instantly share code, notes, and snippets.

@tamird
Last active March 4, 2022 16:44
Show Gist options
  • Save tamird/5bd644f058b27c4e75af0ea48087b0da to your computer and use it in GitHub Desktop.
Save tamird/5bd644f058b27c4e75af0ea48087b0da to your computer and use it in GitHub Desktop.
TEST(LocalhostTest, IpAddMembershipAny) {
fbl::unique_fd s;
ASSERT_TRUE(s = fbl::unique_fd(socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))) << strerror(errno);
ip_mreqn param = {
.imr_address =
{
.s_addr = htonl(INADDR_ANY),
},
.imr_ifindex = 1,
};
int n = inet_pton(AF_INET, "224.0.2.1", &param.imr_multiaddr.s_addr);
ASSERT_GE(n, 0) << strerror(errno);
ASSERT_EQ(n, 1);
ASSERT_EQ(setsockopt(s.get(), SOL_IP, IP_ADD_MEMBERSHIP, &param, sizeof(param)), 0)
<< strerror(errno);
fbl::unique_fd client, server;
ASSERT_TRUE(client = fbl::unique_fd(socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))) << strerror(errno);
ASSERT_TRUE(server = fbl::unique_fd(socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))) << strerror(errno);
{
in_addr loopback = {
.s_addr = htonl(INADDR_LOOPBACK),
};
ASSERT_EQ(setsockopt(server.get(), SOL_IP, IP_MULTICAST_IF, &loopback, sizeof(loopback)), 0)
<< strerror(errno);
}
sockaddr_in addr = {
.sin_family = AF_INET,
.sin_addr =
{
.s_addr = htonl(INADDR_ANY),
},
};
ASSERT_EQ(bind(client.get(), reinterpret_cast<const sockaddr*>(&addr), sizeof(addr)), 0)
<< strerror(errno);
socklen_t addrlen = sizeof(addr);
ASSERT_EQ(getsockname(client.get(), reinterpret_cast<sockaddr*>(&addr), &addrlen), 0)
<< strerror(errno);
ASSERT_EQ(addrlen, sizeof(addr));
char addr_buf[INET_ADDRSTRLEN];
std::cout << "bound to " << inet_ntop(addr.sin_family, &addr.sin_addr, addr_buf, sizeof(addr_buf))
<< ':' << addr.sin_port << std::endl;
addr.sin_addr = param.imr_multiaddr;
std::cout << "sending to "
<< inet_ntop(addr.sin_family, &addr.sin_addr, addr_buf, sizeof(addr_buf)) << ':'
<< addr.sin_port << std::endl;
char buf[1];
ASSERT_EQ(sendto(server.get(), buf, sizeof(buf), 0, reinterpret_cast<sockaddr*>(&addr), addrlen),
ssize_t(sizeof(buf)))
<< strerror(errno);
ASSERT_EQ(
recvfrom(client.get(), buf, sizeof(buf), 0, reinterpret_cast<sockaddr*>(&addr), &addrlen),
ssize_t(sizeof(buf)))
<< strerror(errno);
ASSERT_EQ(addrlen, sizeof(addr));
std::cout << "received from "
<< inet_ntop(addr.sin_family, &addr.sin_addr, addr_buf, sizeof(addr_buf)) << ':'
<< addr.sin_port << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment