Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support for system-assigned ports during test #346

Merged
merged 8 commits into from Aug 25, 2020
2 changes: 1 addition & 1 deletion ares__sortaddrinfo.c
Expand Up @@ -427,7 +427,7 @@ static int find_src_addr(ares_channel channel,
return 0;
}

if (getsockname(sock, src_addr, &len) == -1)
if (getsockname(sock, src_addr, &len) != 0)
{
ares__close_socket(channel, sock);
return -1;
Expand Down
44 changes: 38 additions & 6 deletions test/ares-test.cc
Expand Up @@ -30,7 +30,8 @@ namespace ares {
namespace test {

bool verbose = false;
int mock_port = 5300;
static constexpr int dynamic_port = 0;
int mock_port = dynamic_port;

const std::vector<int> both_families = {AF_INET, AF_INET6};
const std::vector<int> ipv4_family = {AF_INET};
Expand Down Expand Up @@ -169,8 +170,8 @@ void DefaultChannelModeTest::Process() {
ProcessWork(channel_, NoExtraFDs, nullptr);
}

MockServer::MockServer(int family, int port, int tcpport)
: udpport_(port), tcpport_(tcpport ? tcpport : udpport_), qid_(-1) {
apenn-msft marked this conversation as resolved.
Show resolved Hide resolved
MockServer::MockServer(int family, int port)
: udpport_(port), tcpport_(udpport_), qid_(-1) {
// Create a TCP socket to receive data on.
tcpfd_ = socket(family, SOCK_STREAM, 0);
EXPECT_NE(-1, tcpfd_);
Expand All @@ -197,6 +198,21 @@ MockServer::MockServer(int family, int port, int tcpport)
addr.sin_port = htons(udpport_);
int udprc = bind(udpfd_, (struct sockaddr*)&addr, sizeof(addr));
EXPECT_EQ(0, udprc) << "Failed to bind AF_INET to UDP port " << udpport_;
// retrieve system-assigned port
if (udpport_ == dynamic_port) {
ares_socklen_t len = sizeof(addr);
auto result = getsockname(udpfd_, (struct sockaddr*)&addr, &len);
EXPECT_EQ(0, result);
udpport_ = ntohs(addr.sin_port);
EXPECT_NE(dynamic_port, udpport_);
}
if (tcpport_ == dynamic_port) {
ares_socklen_t len = sizeof(addr);
auto result = getsockname(tcpfd_, (struct sockaddr*)&addr, &len);
EXPECT_EQ(0, result);
tcpport_ = ntohs(addr.sin_port);
EXPECT_NE(dynamic_port, tcpport_);
}
} else {
EXPECT_EQ(AF_INET6, family);
struct sockaddr_in6 addr;
Expand All @@ -209,6 +225,21 @@ MockServer::MockServer(int family, int port, int tcpport)
addr.sin6_port = htons(udpport_);
int udprc = bind(udpfd_, (struct sockaddr*)&addr, sizeof(addr));
EXPECT_EQ(0, udprc) << "Failed to bind AF_INET6 to UDP port " << udpport_;
// retrieve system-assigned port
if (udpport_ == dynamic_port) {
ares_socklen_t len = sizeof(addr);
auto result = getsockname(udpfd_, (struct sockaddr*)&addr, &len);
EXPECT_EQ(0, result);
udpport_ = ntohs(addr.sin6_port);
EXPECT_NE(dynamic_port, udpport_);
}
if (tcpport_ == dynamic_port) {
ares_socklen_t len = sizeof(addr);
auto result = getsockname(tcpfd_, (struct sockaddr*)&addr, &len);
EXPECT_EQ(0, result);
tcpport_ = ntohs(addr.sin6_port);
EXPECT_NE(dynamic_port, tcpport_);
}
}
if (verbose) std::cerr << "Configured "
<< (family == AF_INET ? "IPv4" : "IPv6")
Expand Down Expand Up @@ -381,7 +412,8 @@ MockChannelOptsTest::NiceMockServers MockChannelOptsTest::BuildServers(int count
NiceMockServers servers;
assert(count > 0);
for (int ii = 0; ii < count; ii++) {
std::unique_ptr<NiceMockServer> server(new NiceMockServer(family, base_port + ii));
int port = base_port == dynamic_port ? dynamic_port : base_port + ii;
std::unique_ptr<NiceMockServer> server(new NiceMockServer(family, port));
servers.push_back(std::move(server));
}
return servers;
Expand All @@ -403,9 +435,9 @@ MockChannelOptsTest::MockChannelOptsTest(int count,
}

// Point the library at the first mock server by default (overridden below).
opts.udp_port = mock_port;
opts.udp_port = server_.udpport();
optmask |= ARES_OPT_UDP_PORT;
opts.tcp_port = mock_port;
opts.tcp_port = server_.tcpport();
optmask |= ARES_OPT_TCP_PORT;

// If not already overridden, set short-ish timeouts.
Expand Down
2 changes: 1 addition & 1 deletion test/ares-test.h
Expand Up @@ -136,7 +136,7 @@ class DefaultChannelModeTest
// Mock DNS server to allow responses to be scripted by tests.
class MockServer {
public:
MockServer(int family, int port, int tcpport = 0);
MockServer(int family, int port);
~MockServer();

// Mock method indicating the processing of a particular <name, RRtype>
Expand Down