0
0
mirror of https://github.com/OpenVPN/openvpn3.git synced 2024-09-20 20:13:05 +02:00
openvpn3/openvpn/options/remotelist.hpp
James Yonan abbe662dcb Android 4 client changes:
* Allow protocol to be specified by "proto" directive instead
  of requiring it to be present in "remote" directive.

* Throw error if tls-remote is specified in client config file.

Updated Android client.txt notes.
2012-04-18 12:13:29 +00:00

116 lines
2.8 KiB
C++

#ifndef OPENVPN_OPTIONS_REMOTELIST_H
#define OPENVPN_OPTIONS_REMOTELIST_H
#include <string>
#include <sstream>
#include <vector>
#include <openvpn/common/exception.hpp>
#include <openvpn/common/options.hpp>
#include <openvpn/common/rc.hpp>
#include <openvpn/transport/protocol.hpp>
namespace openvpn {
class RemoteList : public RC<thread_unsafe_refcount>
{
public:
typedef boost::intrusive_ptr<RemoteList> Ptr;
struct Item
{
std::string server_host;
std::string server_port;
Protocol transport_protocol;
std::string render() const
{
std::ostringstream out;
out << "host=" << server_host
<< " port=" << server_port
<< " proto=" << transport_protocol.str();
return out.str();
}
};
RemoteList() {}
RemoteList(const OptionList& opt)
{
Protocol default_proto(Protocol::UDPv4);
// parse "proto" option if present
{
const Option* o = opt.get_ptr("proto");
if (o)
default_proto = Protocol::parse(o->get(1));
}
// cycle through remote entries
{
const OptionList::IndexList& rem = opt.get_index("remote");
for (OptionList::IndexList::const_iterator i = rem.begin(); i != rem.end(); i++)
{
Item e;
const Option& o = opt[*i];
e.server_host = o.get(1);
e.server_port = o.get(2);
if (o.size() >= 4)
e.transport_protocol = Protocol::parse(o.get(3));
else
e.transport_protocol = default_proto;
list.push_back(e);
}
}
}
// used to cycle through Item list
Item get(unsigned int& index, const std::string& server_override, const Protocol& proto_override) const
{
const unsigned int size = list.size();
index = find_with_proto_match(proto_override, index);
Item item = list[index % size];
if (!server_override.empty())
item.server_host = server_override;
// OPENVPN_LOG("****** GET REMOTE index=" << index << " so=" << server_override << " po=" << proto_override.str() << " item=" << item.render());
return item;
}
size_t size() const { return list.size(); }
const Item& operator[](const size_t i) const { return list[i]; }
std::string render() const
{
std::ostringstream out;
for (size_t i = 0; i < list.size(); ++i)
{
const Item& e = list[i];
out << '[' << i << "] " << e.render() << std::endl;
}
return out.str();
}
private:
unsigned int find_with_proto_match(const Protocol& proto, const unsigned int index) const
{
if (proto.defined())
{
const unsigned int size = list.size();
const unsigned int limit = index + size;
for (unsigned int i = index; i < limit; ++i)
{
const Item& item = list[i % size];
if (proto == item.transport_protocol)
return i;
}
}
return index;
}
std::vector<Item> list;
};
}
#endif