mirror of
https://github.com/OpenVPN/openvpn3.git
synced 2024-09-20 12:12:15 +02:00
add unit tests for class RemoteList
Signed-off-by: Heiko Hund <heiko@openvpn.net>
This commit is contained in:
parent
d83da4b53b
commit
bdc135c0d6
@ -104,6 +104,8 @@ namespace openvpn {
|
||||
typename ResolveThread::Ptr resolve_thread;
|
||||
|
||||
public:
|
||||
using resolver_type = RESOLVER_TYPE;
|
||||
|
||||
AsyncResolvable(openvpn_io::io_context& io_context_arg)
|
||||
: io_context(io_context_arg)
|
||||
{
|
||||
@ -130,7 +132,7 @@ namespace openvpn {
|
||||
// that here we have control over the resolving thread and we
|
||||
// can easily detach it. Deatching the internal thread created
|
||||
// by ASIO would not be feasible as it is not exposed.
|
||||
void async_resolve_name(const std::string& host, const std::string& port)
|
||||
virtual void async_resolve_name(const std::string& host, const std::string& port)
|
||||
{
|
||||
resolve_thread.reset(new ResolveThread(io_context, this, host, port));
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ namespace openvpn {
|
||||
RESOLVER_TYPE resolver;
|
||||
|
||||
public:
|
||||
using resolver_type = RESOLVER_TYPE;
|
||||
|
||||
AsyncResolvable(openvpn_io::io_context& io_context_arg)
|
||||
: io_context(io_context_arg),
|
||||
resolver(io_context_arg)
|
||||
@ -54,7 +56,7 @@ namespace openvpn {
|
||||
//
|
||||
// For example, iOS implements aync_resolve using GCD and CFHost. This
|
||||
// implementation satisfies the constraints mentioned above
|
||||
void async_resolve_name(const std::string& host, const std::string& port)
|
||||
virtual void async_resolve_name(const std::string& host, const std::string& port)
|
||||
{
|
||||
resolver.async_resolve(host, port, [self=Ptr(this)](const openvpn_io::error_code& error,
|
||||
typename RESOLVER_TYPE::results_type results)
|
||||
|
@ -251,7 +251,7 @@ namespace openvpn {
|
||||
// This is useful in tun_persist mode, where it may be necessary
|
||||
// to pre-resolve all potential remote server items prior
|
||||
// to initial tunnel establishment.
|
||||
class PreResolve : public virtual RC<thread_unsafe_refcount>, AsyncResolvableTCP
|
||||
class PreResolve : public virtual RC<thread_unsafe_refcount>, protected AsyncResolvableTCP
|
||||
{
|
||||
public:
|
||||
typedef RCPtr<PreResolve> Ptr;
|
||||
@ -305,7 +305,7 @@ namespace openvpn {
|
||||
async_resolve_cancel();
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
void next()
|
||||
{
|
||||
while (index < remote_list->list.size())
|
||||
|
@ -21,6 +21,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <openvpn/log/logbase.hpp>
|
||||
#include <openvpn/io/io.hpp>
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/hexstr.hpp>
|
||||
#include <openvpn/random/mtrandapi.hpp>
|
||||
@ -232,9 +233,69 @@ inline std::string getSortedString(const std::string& output)
|
||||
return s.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fake DNS resolver.
|
||||
* Inherits from tested class and overrides async_resolve_name().
|
||||
* Returns error if host/service pair has not been added with set_results() before.
|
||||
*/
|
||||
template<typename RESOLVABLE, typename... CTOR_ARGS>
|
||||
class FakeAsyncResolvable : public RESOLVABLE
|
||||
{
|
||||
public:
|
||||
using Result = std::pair<const std::string, const unsigned short>;
|
||||
using ResultList = std::vector<Result>;
|
||||
|
||||
using ResultsType = typename RESOLVABLE::resolver_type::results_type;
|
||||
using EndpointType = typename RESOLVABLE::resolver_type::endpoint_type;
|
||||
using EndpointList = std::vector<EndpointType>;
|
||||
|
||||
std::map<const std::string, EndpointList> results_;
|
||||
|
||||
EndpointType init_endpoint() const
|
||||
{
|
||||
return EndpointType();
|
||||
}
|
||||
|
||||
void set_results(const std::string& host, const std::string& service, const ResultList&& results)
|
||||
{
|
||||
EndpointList endpoints;
|
||||
for (const auto& result : results)
|
||||
{
|
||||
EndpointType ep(openvpn_io::ip::make_address(result.first), result.second);
|
||||
endpoints.push_back(ep);
|
||||
}
|
||||
results_[host +":"+ service] = endpoints;
|
||||
}
|
||||
|
||||
FakeAsyncResolvable(CTOR_ARGS... args) : RESOLVABLE(args...) {}
|
||||
|
||||
void async_resolve_name(const std::string& host, const std::string& service) override
|
||||
{
|
||||
const std::string key(host +":"+ service);
|
||||
openvpn_io::error_code error = openvpn_io::error::host_not_found;
|
||||
ResultsType results;
|
||||
|
||||
if (results_.count(key))
|
||||
{
|
||||
const EndpointList& ep = results_[key];
|
||||
if (ep.size())
|
||||
{
|
||||
error = openvpn_io::error_code();
|
||||
results = ResultsType::create(ep.cbegin(), ep.cend(), host, service);
|
||||
}
|
||||
}
|
||||
|
||||
this->resolve_callback(error, results);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Predictable RNG that claims to be secure to be used in reproducable unit
|
||||
* tests
|
||||
*
|
||||
* Note: this is not fit to be used as UniformRandomBitGenerator since
|
||||
* its maximum range is [0x03020100, 0xfffefdfc]. Especially the lower
|
||||
* bound makes the std::shuffle implementation in libc++ loop endlessly.
|
||||
*/
|
||||
class FakeSecureRand : public openvpn::RandomAPI
|
||||
{
|
||||
|
@ -24,6 +24,329 @@
|
||||
|
||||
using namespace openvpn;
|
||||
|
||||
struct PreResolveNotifyIgn : RemoteList::PreResolve::NotifyCallback {
|
||||
void pre_resolve_done() override {}
|
||||
};
|
||||
struct PreResolveNotifyLog : RemoteList::PreResolve::NotifyCallback {
|
||||
explicit PreResolveNotifyLog(const std::string& msg = "")
|
||||
: msg_(msg) {}
|
||||
void pre_resolve_done() override {
|
||||
OPENVPN_LOG(msg_);
|
||||
}
|
||||
const std::string msg_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
TEST(RemoteList, CtorRemoteOverride)
|
||||
{
|
||||
struct TestOverride : public RemoteList::RemoteOverride {
|
||||
TestOverride(const std::string& server_host,
|
||||
const std::string& server_port,
|
||||
const Protocol& transport_protocol)
|
||||
{
|
||||
item_.reset(new RemoteList::Item);
|
||||
item_->server_host = server_host;
|
||||
item_->server_port = server_port;
|
||||
item_->transport_protocol = transport_protocol;
|
||||
}
|
||||
RemoteList::Item::Ptr get() override {
|
||||
return item_;
|
||||
}
|
||||
RemoteList::Item::Ptr item_;
|
||||
};
|
||||
|
||||
TestOverride test_ovr("1.1.1.1", "1111", Protocol(Protocol::UDPv4));
|
||||
RemoteList rl(&test_ovr);
|
||||
|
||||
ASSERT_EQ(rl.defined(), true);
|
||||
ASSERT_EQ(rl.size(), 1);
|
||||
ASSERT_EQ(rl.get_item(0).server_host, "1.1.1.1");
|
||||
ASSERT_EQ(rl.get_item(0).server_port, "1111");
|
||||
ASSERT_EQ(rl.get_item(0).transport_protocol, Protocol(Protocol::UDPv4));
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST(RemoteList, CtorSingleHost)
|
||||
{
|
||||
RemoteList rl("1.1.1.1", "1111", Protocol(Protocol::TCPv6), "");
|
||||
ASSERT_EQ(rl.defined(), true);
|
||||
ASSERT_EQ(rl.size(), 1);
|
||||
ASSERT_EQ(rl.get_item(0).server_host, "1.1.1.1");
|
||||
ASSERT_EQ(rl.get_item(0).server_port, "1111");
|
||||
ASSERT_EQ(rl.get_item(0).transport_protocol, Protocol(Protocol::TCPv6));
|
||||
}
|
||||
TEST(RemoteList, CtorSingleHostBadPort)
|
||||
{
|
||||
JY_EXPECT_THROW(
|
||||
RemoteList("1.1.1.1", "99999", Protocol(Protocol::TCPv6), "CtorSingleHostBadPort"),
|
||||
HostPort::host_port_error, "CtorSingleHostBadPort"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
TEST(RemoteList, CtorRemoteList)
|
||||
{
|
||||
OptionList cfg;
|
||||
cfg.parse_from_config(
|
||||
"proto tcp6\n"
|
||||
"remote 0.default.invalid\n"
|
||||
"port 9999\n"
|
||||
"remote 1.domain.invalid 1111 udp\n"
|
||||
"<connection>\n"
|
||||
" remote 2.domain.invalid\n"
|
||||
" port 8888\n"
|
||||
"</connection>\n"
|
||||
"<connection>\n"
|
||||
" proto udp6\n"
|
||||
" remote 3:f00d:4::1\n"
|
||||
"</connection>\n"
|
||||
, nullptr);
|
||||
cfg.update_map();
|
||||
|
||||
RemoteList rl(cfg, "", 0, nullptr);
|
||||
ASSERT_EQ(rl.defined(), true);
|
||||
ASSERT_EQ(rl.size(), 4);
|
||||
ASSERT_EQ(rl.get_item(0).server_host, "0.default.invalid");
|
||||
ASSERT_EQ(rl.get_item(0).server_port, "9999");
|
||||
ASSERT_EQ(rl.get_item(0).transport_protocol, Protocol(Protocol::TCPv6));
|
||||
ASSERT_EQ(rl.get_item(1).server_host, "1.domain.invalid");
|
||||
ASSERT_EQ(rl.get_item(1).server_port, "1111");
|
||||
ASSERT_EQ(rl.get_item(1).transport_protocol, Protocol(Protocol::UDPv4));
|
||||
ASSERT_EQ(rl.get_item(2).server_host, "2.domain.invalid");
|
||||
ASSERT_EQ(rl.get_item(2).server_port, "8888");
|
||||
ASSERT_EQ(rl.get_item(2).transport_protocol, Protocol(Protocol::TCPv6));
|
||||
ASSERT_EQ(rl.get_item(3).server_host, "3:f00d:4::1");
|
||||
ASSERT_EQ(rl.get_item(3).server_port, "9999");
|
||||
ASSERT_EQ(rl.get_item(3).transport_protocol, Protocol(Protocol::UDPv6));
|
||||
}
|
||||
TEST(RemoteList, CtorRemoteListConnBlockOnly)
|
||||
{
|
||||
OptionList cfg;
|
||||
cfg.parse_from_config(
|
||||
"remote 1.noblock.invalid 1111 udp\n"
|
||||
"<connection>\n"
|
||||
" remote 2.block.invalid\n"
|
||||
"</connection>\n"
|
||||
, nullptr);
|
||||
cfg.update_map();
|
||||
|
||||
RemoteList rl(cfg, "", RemoteList::CONN_BLOCK_ONLY, nullptr);
|
||||
ASSERT_EQ(rl.defined(), true);
|
||||
ASSERT_EQ(rl.size(), 1);
|
||||
ASSERT_EQ(rl.get_item(0).server_host, "2.block.invalid");
|
||||
}
|
||||
TEST(RemoteList, CtorRemoteListEmpty)
|
||||
{
|
||||
OptionList cfg;
|
||||
cfg.parse_from_config("", nullptr);
|
||||
cfg.update_map();
|
||||
|
||||
ASSERT_THROW(RemoteList(cfg, "", 0, nullptr), option_error);
|
||||
RemoteList rl(cfg, "", RemoteList::ALLOW_EMPTY, nullptr);
|
||||
}
|
||||
TEST(RemoteList, CtorRemoteListConnBlockFactory)
|
||||
{
|
||||
struct TestConnBlock : public RemoteList::ConnBlock
|
||||
{
|
||||
void new_item(const RemoteList::Item& item) override
|
||||
{
|
||||
OPENVPN_LOG("TestConnBlock: " << item.to_string());
|
||||
}
|
||||
};
|
||||
struct TestConnBlockFactory : public RemoteList::ConnBlockFactory
|
||||
{
|
||||
RemoteList::ConnBlock::Ptr new_conn_block(const OptionList::Ptr& opt) override
|
||||
{
|
||||
if (opt->exists("block-option"))
|
||||
return RemoteList::ConnBlock::Ptr(new TestConnBlock());
|
||||
return RemoteList::ConnBlock::Ptr();
|
||||
}
|
||||
};
|
||||
|
||||
OptionList cfg;
|
||||
cfg.parse_from_config(
|
||||
"<block>\n"
|
||||
" remote block.invalid\n"
|
||||
" block-option\n"
|
||||
"</block>\n"
|
||||
"<block>\n"
|
||||
" remote block.invalid\n"
|
||||
" unknown-block-option\n"
|
||||
"</block>\n"
|
||||
, nullptr);
|
||||
cfg.update_map();
|
||||
TestConnBlockFactory tcbf;
|
||||
|
||||
testLog->startCollecting();
|
||||
RemoteList rl1(cfg, "block", 0, &tcbf);
|
||||
std::string output1(testLog->stopCollecting());
|
||||
ASSERT_NE(output1.find("TestConnBlock"), std::string::npos);
|
||||
ASSERT_EQ(rl1.size(), 2);
|
||||
|
||||
testLog->startCollecting();
|
||||
RemoteList rl2(cfg, "block", RemoteList::CONN_BLOCK_OMIT_UNDEF, &tcbf);
|
||||
std::string output2(testLog->stopCollecting());
|
||||
ASSERT_NE(output2.find("TestConnBlock"), std::string::npos);
|
||||
ASSERT_EQ(rl2.size(), 1);
|
||||
}
|
||||
TEST(RemoteList, CtorRemoteListWarnUnsupported)
|
||||
{
|
||||
OptionList cfg;
|
||||
cfg.parse_from_config(
|
||||
"<connection>\n"
|
||||
" remote block.invalid\n"
|
||||
" http-proxy\n"
|
||||
" http-proxy-option\n"
|
||||
" http-proxy-user-pass\n"
|
||||
"</connection>\n"
|
||||
, nullptr);
|
||||
cfg.update_map();
|
||||
|
||||
testLog->startCollecting();
|
||||
RemoteList rl(cfg, "", RemoteList::WARN_UNSUPPORTED, nullptr);
|
||||
std::string output(testLog->stopCollecting());
|
||||
|
||||
ASSERT_NE(output.find(" http-proxy "), std::string::npos);
|
||||
ASSERT_NE(output.find(" http-proxy-option "), std::string::npos);
|
||||
ASSERT_NE(output.find(" http-proxy-user-pass "), std::string::npos);
|
||||
}
|
||||
TEST(RemoteList, CtorRemoteListBlockLimit)
|
||||
{
|
||||
OptionList cfg;
|
||||
cfg.parse_from_config(
|
||||
"<connection>\n"
|
||||
" remote block.invalid\n"
|
||||
" directive-with-a-way-too-long-name-to-be-accepted-by-the-block-parser\n"
|
||||
"</connection>\n"
|
||||
, nullptr);
|
||||
cfg.update_map();
|
||||
|
||||
JY_EXPECT_THROW(RemoteList(cfg, "", 0, nullptr), option_error, "connection_block");
|
||||
}
|
||||
|
||||
|
||||
TEST(RemoteList, RemoteListPreResolve)
|
||||
{
|
||||
OptionList cfg;
|
||||
cfg.parse_from_config(
|
||||
"remote 1.1.1.1 1111 udp\n"
|
||||
"remote 2:cafe::1 2222 tcp\n"
|
||||
"remote 3.domain.tld 3333 udp4\n"
|
||||
"remote 3.domain.tld 33333 udp6\n"
|
||||
"remote 4.domain.tld 4444 udp4\n"
|
||||
"remote 5.noresolve.tld 5555 udp4\n"
|
||||
, nullptr);
|
||||
cfg.update_map();
|
||||
|
||||
RemoteList::Ptr rl(new RemoteList(cfg, "", 0, nullptr));
|
||||
rl->set_enable_cache(true);
|
||||
|
||||
RandomAPI::Ptr rng(new MTRand(3735928559));
|
||||
rl->set_random(rng);
|
||||
|
||||
openvpn_io::io_context ioctx;
|
||||
SessionStats::Ptr stats(new SessionStats());
|
||||
FakeAsyncResolvable<
|
||||
RemoteList::PreResolve,
|
||||
openvpn_io::io_context&,
|
||||
const RemoteList::Ptr&,
|
||||
const SessionStats::Ptr&>
|
||||
fake_preres(ioctx, rl, stats);
|
||||
|
||||
fake_preres.set_results("1.1.1.1", "1111", { {"1.1.1.1", 1111} });
|
||||
fake_preres.set_results("2:cafe::1", "2222", { {"2:cafe::1", 2222} });
|
||||
fake_preres.set_results("3.domain.tld", "3333", { {"3.3.3.3", 3333}, {"3::3", 3333} });
|
||||
fake_preres.set_results("4.domain.tld", "4444", { {"4.4.4.4", 4444}, {"4::4", 4444} });
|
||||
|
||||
PreResolveNotifyLog logmsg("<<<RemoteListPreResolve>>>");
|
||||
testLog->startCollecting();
|
||||
fake_preres.start(&logmsg);
|
||||
std::string output(testLog->stopCollecting());
|
||||
ASSERT_NE(output.find("<<<RemoteListPreResolve>>>"), std::string::npos);
|
||||
|
||||
ASSERT_EQ(5, rl->size())
|
||||
<< "Unexpected remote list item count" << std::endl
|
||||
<< output;
|
||||
|
||||
ASSERT_EQ(rl->get_item(0).res_addr_list_defined(), true);
|
||||
ASSERT_EQ(rl->get_item(0).res_addr_list->size(), 1);
|
||||
ASSERT_EQ(rl->get_item(0).res_addr_list->at(0)->to_string(), "1.1.1.1");
|
||||
ASSERT_EQ(rl->get_item(1).res_addr_list_defined(), true);
|
||||
ASSERT_EQ(rl->get_item(1).res_addr_list->size(), 1);
|
||||
ASSERT_EQ(rl->get_item(1).res_addr_list->at(0)->to_string(), "2:cafe::1");
|
||||
ASSERT_EQ(rl->get_item(2).res_addr_list_defined(), true);
|
||||
ASSERT_EQ(rl->get_item(2).res_addr_list->size(), 2);
|
||||
ASSERT_EQ(rl->get_item(2).res_addr_list->at(0)->to_string(), "3.3.3.3");
|
||||
ASSERT_EQ(rl->get_item(2).res_addr_list->at(1)->to_string(), "3::3");
|
||||
ASSERT_EQ(rl->get_item(3).res_addr_list_defined(), true);
|
||||
ASSERT_EQ(rl->get_item(3).res_addr_list->size(), 2);
|
||||
ASSERT_EQ(rl->get_item(3).res_addr_list->at(0)->to_string(), "3.3.3.3");
|
||||
ASSERT_EQ(rl->get_item(3).res_addr_list->at(1)->to_string(), "3::3");
|
||||
ASSERT_EQ(rl->get_item(3).actual_host(), rl->get_item(2).actual_host());
|
||||
ASSERT_EQ(rl->get_item(4).res_addr_list_defined(), true);
|
||||
ASSERT_EQ(rl->get_item(4).res_addr_list->size(), 2);
|
||||
ASSERT_EQ(rl->get_item(4).res_addr_list->at(0)->to_string(), "4.4.4.4");
|
||||
ASSERT_EQ(rl->get_item(4).res_addr_list->at(1)->to_string(), "4::4");
|
||||
|
||||
// in case it gets randomized before the other 3.domain.tld
|
||||
fake_preres.set_results("3.domain.tld", "33333", { {"3.3.3.3", 33333}, {"3::3", 33333} });
|
||||
rl->reset_cache();
|
||||
rl->randomize();
|
||||
|
||||
PreResolveNotifyIgn ignore;
|
||||
testLog->startCollecting();
|
||||
fake_preres.start(&ignore);
|
||||
output = testLog->stopCollecting();
|
||||
|
||||
ASSERT_EQ(5, rl->size())
|
||||
<< "Unexpected remote list item count" << std::endl
|
||||
<< output;
|
||||
|
||||
for (size_t i=0; i < rl->size(); ++i)
|
||||
{
|
||||
ASSERT_EQ(rl->get_item(i).res_addr_list_defined(), true);
|
||||
if (rl->get_item(i).server_host[0] == '1')
|
||||
{
|
||||
ASSERT_EQ(rl->get_item(i).res_addr_list->size(), 1);
|
||||
ASSERT_EQ(rl->get_item(i).res_addr_list->at(0)->to_string(), "1.1.1.1");
|
||||
}
|
||||
else if (rl->get_item(i).server_host[0] == '2')
|
||||
{
|
||||
ASSERT_EQ(rl->get_item(i).res_addr_list->size(), 1);
|
||||
ASSERT_EQ(rl->get_item(i).res_addr_list->at(0)->to_string(), "2:cafe::1");
|
||||
}
|
||||
else
|
||||
ASSERT_EQ(rl->get_item(i).res_addr_list->size(), 2);
|
||||
}
|
||||
|
||||
for (size_t i=0; i < rl->size(); ++i)
|
||||
{
|
||||
for (size_t j=0; j < rl->get_item(i).res_addr_list->size(); ++j)
|
||||
{
|
||||
std::string host;
|
||||
std::string port;
|
||||
Protocol proto;
|
||||
ASSERT_EQ(rl->endpoint_available(&host, &port, &proto), true);
|
||||
ASSERT_EQ(rl->get_item(i).actual_host(), host);
|
||||
ASSERT_EQ(rl->get_item(i).server_port, port);
|
||||
// proto is not yet honored by Item when adding resolver results
|
||||
//ASSERT_EQ(rl->current_transport_protocol(), proto);
|
||||
|
||||
auto ep1 = fake_preres.init_endpoint();
|
||||
auto ep2 = fake_preres.init_endpoint();
|
||||
rl->get_endpoint(ep1);
|
||||
rl->get_item(i).get_endpoint(ep2, j);
|
||||
ASSERT_EQ(ep1, ep2);
|
||||
|
||||
rl->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST(RemoteList, RemoteRandomHostname)
|
||||
{
|
||||
OptionList cfg;
|
||||
@ -48,8 +371,22 @@ TEST(RemoteList, RemoteRandomHostname)
|
||||
ASSERT_EQ(rl.get_item(1).actual_host(), "f7f8f9fafbfc.2.domain.invalid");
|
||||
ASSERT_EQ(rl.get_item(2).actual_host(), "fdfeff000102.3.domain.invalid");
|
||||
ASSERT_EQ(rl.get_item(3).actual_host(), "4:cafe::1");
|
||||
}
|
||||
rl.next();
|
||||
ASSERT_EQ(rl.current_server_host(), "030405060708.2.domain.invalid");
|
||||
rl.next();
|
||||
ASSERT_EQ(rl.current_server_host(), "090a0b0c0d0e.3.domain.invalid");
|
||||
|
||||
ASSERT_EQ(rl.get_enable_cache(), false);
|
||||
rl.set_enable_cache(true);
|
||||
ASSERT_EQ(rl.get_enable_cache(), true);
|
||||
rl.next();
|
||||
rl.next();
|
||||
|
||||
rl.next();
|
||||
ASSERT_EQ(rl.current_server_host(), "030405060708.2.domain.invalid");
|
||||
rl.next();
|
||||
ASSERT_EQ(rl.current_server_host(), "090a0b0c0d0e.3.domain.invalid");
|
||||
}
|
||||
TEST(RemoteList, RemoteRandomHostnameNoPRNG)
|
||||
{
|
||||
OptionList cfg;
|
||||
@ -61,3 +398,33 @@ TEST(RemoteList, RemoteRandomHostnameNoPRNG)
|
||||
|
||||
ASSERT_THROW(RemoteList(cfg, "", 0, nullptr), RemoteList::remote_list_error);
|
||||
}
|
||||
|
||||
|
||||
TEST(RemoteList, OverrideFunctions)
|
||||
{
|
||||
OptionList cfg;
|
||||
cfg.parse_from_config(
|
||||
"remote-random-hostname\n"
|
||||
"remote config.host.invalid 1111 udp6\n"
|
||||
"remote config.host.invalid 1111 tcp\n"
|
||||
, nullptr);
|
||||
cfg.update_map();
|
||||
|
||||
RandomAPI::Ptr rng(new FakeSecureRand(0xf7));
|
||||
RemoteList rl(cfg, "", 0, nullptr, rng);
|
||||
ASSERT_EQ(rl.size(), 2);
|
||||
|
||||
rl.handle_proto_override(Protocol(Protocol::UDPv4), true);
|
||||
ASSERT_EQ(rl.size(), 1);
|
||||
ASSERT_EQ(rl.current_transport_protocol(), Protocol(Protocol::TCP));
|
||||
|
||||
rl.set_port_override("4711");
|
||||
ASSERT_EQ(rl.size(), 1);
|
||||
ASSERT_EQ(rl.get_item(0).server_port, "4711");
|
||||
|
||||
rl.set_server_override("override.host.invalid");
|
||||
ASSERT_EQ(rl.size(), 1);
|
||||
ASSERT_EQ(rl.current_server_host(), "override.host.invalid");
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user