16#ifndef OPENVPN_CLIENT_REMOTELIST_H
17#define OPENVPN_CLIENT_REMOTELIST_H
44#if OPENVPN_DEBUG_REMOTELIST >= 1
45#define OPENVPN_LOG_REMOTELIST(x) OPENVPN_LOG(x)
47#define OPENVPN_LOG_REMOTELIST(x)
67 struct ResolvedAddrList :
public std::vector<ResolvedAddr::Ptr>,
public RC<thread_unsafe_refcount>
74 for (std::vector<ResolvedAddr::Ptr>::const_iterator i = begin(); i != end(); ++i)
78 ret += (*i)->to_string();
111 struct Item :
public RC<thread_unsafe_refcount>
130 std::time_t
decay_time = std::numeric_limits<std::time_t>::max();
149 decay_time = std::numeric_limits<std::time_t>::max();
154 template <
class EPRANGE>
158 if (endpoint_range.size())
161 for (
const auto &i : endpoint_range)
163 std::string ep_af =
"(unspec)";
164 if (i.endpoint().address().is_v6())
166 else if (i.endpoint().address().is_v4())
197 endpoint.port(parse_number_throw<unsigned short>(
server_port,
"remote_port"));
212 std::ostringstream
out;
234 :
connection(conn_tag.length() ? conn_tag :
"connection")
241 const std::string
port =
"port";
275 if (++
item_ >= item_len)
333 if (notify_callback_arg)
360 while (index < remote_list->
list.size())
364 if (item->need_resolve())
403 if (!item->need_resolve()
404 || item->server_host != resolve_item->server_host)
408 if (item == item_in_use)
412 item->random_host = resolve_item->random_host;
418 OPENVPN_LOG(
"DNS bulk-resolve error on " << resolve_item->actual_host()
419 <<
": " << error.message());
442 const std::string &server_port,
444 const std::string &title)
449 item->server_host = server_host;
450 item->server_port = server_port;
451 item->transport_protocol = transport_protocol;
452 list.push_back(item);
466 const std::string &connection_tag,
467 const unsigned int flags,
477 const std::string default_port =
get_port(opt,
"1194");
485 const size_t max_conn_block_size = 4096;
489 for (OptionList::IndexList::const_iterator i = conn->begin(); i != conn->end(); ++i)
493 const Option &o = opt[*i];
504 const std::string block_port =
get_port(*conn_block, default_port);
517 if (conn_block_factory)
520 add(*conn_block, block_proto, block_port, cb);
534 throw option_error(ERR_INVALID_CONFIG,
"remote option not specified");
556 if (server_override.empty())
558 for (
auto &item :
list)
560 item->server_host = server_override;
561 item->random_host.clear();
562 item->res_addr_list.reset();
571 if (port_override.empty())
573 for (
auto &item :
list)
575 item->server_port = port_override;
576 item->res_addr_list.reset();
586 for (
auto item :
list)
587 item->transport_protocol.mod_addr_version(v);
612 if (tcp_proxy_enabled)
618 throw option_error(ERR_INVALID_CONFIG,
"cannot connect via TCP-based proxy because no TCP server entries exist in profile");
634 list.push_back(std::move(item));
658 if (transport_protocol)
666 template <
class EPRANGE>
682 throw remote_list_error(
"current remote server endpoint is undefined");
688 return list.size() > 0;
716 template <
typename T>
725 std::ostringstream
out;
726 for (
size_t i = 0; i <
list.size(); ++i)
737 for (std::vector<Item::Ptr>::const_iterator i =
list.begin(); i !=
list.end(); ++i)
739 const Item &item = **i;
743 for (ResolvedAddrList::const_iterator j = ral.begin(); j != ral.end(); ++j)
757 e->res_addr_list.reset(
nullptr);
774 if (!opt.
exists(
"remote-cache-lifetime"))
783 for (
auto &item :
list)
785 if (item->res_addr_list_defined())
795 list[i]->res_addr_list.reset(
nullptr);
796 list[i]->decay_time = std::numeric_limits<std::time_t>::max();
806 if (pri <
list.size())
809 throw remote_list_error(
"current remote server item is undefined");
827 for (std::vector<Item::Ptr>::const_iterator i =
list.begin(); i !=
list.end(); ++i)
841 for (
size_t si = 0; si <
list.size(); ++si)
851 if (di !=
list.size())
860 for (std::vector<Item::Ptr>::const_iterator i =
list.begin(); i !=
list.end(); ++i)
862 const Item &item = **i;
874 for (
size_t si = 0; si <
list.size(); ++si)
888 if (di !=
list.size())
899 std::string
port = o->
get(1, 16);
911 return default_proto;
921 for (
const auto &i : *rem)
926 e->server_host = o.
get(1, 256);
930 e->server_port = o.
get(2, 16);
940 e->server_port = default_port;
941 if (o.
size() >= (
size_t)(4 + adj))
944 e->transport_protocol = default_proto;
945 e->conn_block = conn_block;
955 if (options.
exists(option))
956 OPENVPN_LOG(
"NOTE: " << option <<
" directive is not currently supported in <connection> blocks");
969 catch (
const IP::ip_exception &)
972 unsigned char prefix[6];
976 std::ostringstream random_host;
977 random_host << std::hex;
978 for (std::size_t i = 0; i <
sizeof(prefix); ++i)
980 random_host << std::setw(2) << std::setfill(
'0')
981 <<
static_cast<unsigned>(prefix[i]);
void async_resolve_cancel()
void async_resolve_lock()
typename RESOLVER_TYPE::results_type results_type
virtual void async_resolve_name(const std::string &host, const std::string &port)
void remove_label(const std::string &label)
void add_label(const std::string &label)
void add(const IP::Addr &a)
static Addr from_asio(const openvpn_io::ip::address &addr)
std::string to_string() const
const IndexList * get_index_ptr(const std::string &name) const
static OptionList::Ptr parse_from_config_static_ptr(const std::string &str, Limits *lim)
const Option & get(const std::string &name) const
const Option * get_ptr(const std::string &name) const
std::vector< unsigned int > IndexList
bool exists(const std::string &name) const
void touch(bool lightly=false) const
const std::string & get(const size_t index, const size_t max_len) const
T get_num(const size_t idx) const
const char * protocol_to_string() const
static bool is_local_type(const std::string &str)
static Protocol parse(const std::string &str, const AllowSuffix allow_suffix, const char *title=nullptr)
bool transport_match(const Protocol &other) const
void reset() noexcept
Points this RCPtr<T> to nullptr safely.
T * get() const noexcept
Returns the raw pointer to the object T, or nullptr.
Reference count base class for objects tracked by RCPtr. Disallows copying and assignment.
Abstract base class for random number generators.
virtual void rand_bytes(unsigned char *buf, size_t size)=0
Fill a buffer with random bytes.
RemoteList::Ptr remote_list
void resolve_callback(const openvpn_io::error_code &error, results_type results) override
void start(NotifyCallback *notify_callback_arg)
NotifyCallback * notify_callback
BulkResolve(openvpn_io::io_context &io_context_arg, const RemoteList::Ptr &remote_list_arg, const SessionStats::Ptr &stats_arg)
bool work_available() const
void set_endpoint_range(EPRANGE &endpoint_range)
std::size_t cache_lifetime
bool endpoint_available(std::string *server_host, std::string *server_port, Protocol *transport_protocol) const
void get_endpoint(EP &endpoint) const
RemoteOverride * remote_override
void add(const OptionList &opt, const Protocol &default_proto, const std::string &default_port, ConnBlock::Ptr conn_block)
RemoteList(const OptionList &opt, const std::string &connection_tag, const unsigned int flags, ConnBlockFactory *conn_block_factory, RandomAPI::Ptr rng_arg)
void unsupported_in_connection_block(const OptionList &options, const std::string &option)
void randomize_host(Item &item)
void set_server_override(const std::string &server_override)
void next(Advance type=Advance::Addr)
size_t item_addr_length(const size_t i) const
void cached_ip_address_list(IP::AddrList &addrlist) const
void handle_proto_override(const Protocol &proto_override, const bool tcp_proxy_enabled)
bool get_enable_cache() const
void set_proto_override(const Protocol &proto_override)
T * current_conn_block_rawptr() const
RemoteList(const std::string &server_host, const std::string &server_port, const Protocol &transport_protocol, const std::string &title)
std::string to_string() const
size_t item_index() const
std::vector< Item::Ptr > list
void set_enable_cache(const bool enable_cache_arg)
RemoteList(RemoteOverride *remote_override_arg)
void set_random(const RandomAPI::Ptr &rng_arg)
void reset_item(const size_t i)
void set_proto_version_override(const IP::Addr::Version v)
Item::Ptr get_item(const size_t index) const
void set_port_override(const std::string &port_override)
bool contains_protocol(const Protocol &proto)
std::string get_port(const OptionList &opt, const std::string &default_port)
const Protocol & current_transport_protocol() const
OPENVPN_EXCEPTION(remote_list_error)
void process_push(const OptionList &opt)
bool cached_item_exists() const
std::string current_server_host() const
Protocol get_proto(const OptionList &opt, const Protocol &default_proto)
void process_cache_lifetime(const OptionList &opt)
virtual void error(const size_t type, const std::string *text=nullptr)
#define OPENVPN_LOG(args)
void validate_port(const std::string &port, const std::string &title, unsigned int *value=nullptr)
Implementation of the base classes for random number generators.
#define OPENVPN_LOG_REMOTELIST(x)
virtual void bulk_resolve_done()=0
virtual ~NotifyCallback()=default
virtual ConnBlock::Ptr new_conn_block(const OptionList::Ptr &opt)=0
virtual ~ConnBlockFactory()=default
RCPtr< ConnBlockFactory > Ptr
virtual void new_item(const Item &item)=0
const std::string connection
Directives(const std::string &conn_tag="")
bool increment(const Advance type, const size_t item_len, const size_t addr_len)
void set_item(const size_t i)
bool get_endpoint(EP &endpoint, const size_t index) const
ResolvedAddrList::Ptr res_addr_list
Protocol transport_protocol
ConnBlock::Ptr conn_block
std::string actual_host() const
std::string to_string() const
void set_endpoint_range(const EPRANGE &endpoint_range, RandomAPI *rng, std::size_t addr_lifetime)
bool res_addr_list_defined() const
void set_ip_addr(const IP::Addr &addr)
virtual Item::Ptr get()=0
virtual ~RemoteOverride()=default
RCPtr< ResolvedAddrList > Ptr
std::string to_string() const
RCPtr< ResolvedAddr > Ptr
std::string to_string() const
static std::stringstream out