34 typedef std::unique_ptr<PacketFrom>
SPtr;
42 return tb->tun_builder_dco_available();
44 return GeNLImpl::available();
57 bool status = parse_number_validate<uint32_t>(
58 o->get(1, 16), 16, 0, OVPN_PEER_ID_UNDEF - 1, &peer_id);
60 OPENVPN_THROW(dcocli_error,
"Parse/range issue with pushed peer-id");
67 catch (
const std::exception &e)
69 OPENVPN_THROW(dcocli_error,
"Cannot extract peer-id: " << e.what());
77 dc_settings.factory(),
this,
config->transport.frame)));
84 tun_parent->tun_connected();
103 return transport->server_endpoint_port();
117 if (!
config->transport.protocol.is_tcp())
120 udpconf->remote_list =
config->transport.remote_list;
121 udpconf->frame =
config->transport.frame;
122 udpconf->stats =
config->transport.stats;
123 udpconf->socket_protect =
config->transport.socket_protect;
124 udpconf->server_addr_float =
config->transport.server_addr_float;
125 transport_factory = udpconf;
130 tcpconf->remote_list =
config->transport.remote_list;
131 tcpconf->frame =
config->transport.frame;
132 tcpconf->stats =
config->transport.stats;
133 tcpconf->socket_protect =
config->transport.socket_protect;
134 transport_factory = tcpconf;
137 config->transport.stats->dco_configure(
this);
139 transport = transport_factory->new_transport_client_obj(io_context,
this);
145 return transport->transport_send_const(buf);
151 "Non-const send expected for data channel only, but "
152 "ovpndcocli is not expected to handle data packets");
158 memset(&sa, 0,
sizeof(sa));
160 struct sockaddr_in *sa4 = (
struct sockaddr_in *)&sa;
161 struct sockaddr_in6 *sa6 = (
struct sockaddr_in6 *)&sa;
164 if (remote_addr.version() == IP::Addr::V4)
166 salen =
sizeof(*sa4);
171 salen =
sizeof(*sa6);
172 *sa6 = remote_addr.to_ipv6().to_sockaddr(
transport->server_endpoint_port());
183 tb->tun_builder_dco_del_peer(peer_id);
187 genl->del_peer(peer_id);
192 struct sockaddr_storage sa;
197 OPENVPN_LOG(
"Adding DCO peer " << peer_id <<
" remote "
198 <<
transport->server_endpoint_addr() <<
":"
204 tb->tun_builder_dco_new_peer(peer_id,
206 (
struct sockaddr *)&sa,
213 genl->new_peer(peer_id,
215 (
struct sockaddr *)&sa,
225 OPENVPN_LOG(
"Updating stats for DCO peer " << peer_id);
227 if (peer_id == OVPN_PEER_ID_UNDEF)
233 tb->tun_builder_dco_get_peer(peer_id, sync);
238 genl->get_peer(peer_id, sync);
245 results_type results)
override
260 config->builder->tun_builder_teardown(
true);
266 std::ostringstream
os;
270 int res = TunNetlink::iface_del(
os,
config->dev_name);
273 OPENVPN_LOG(
"ovpndcocli: error deleting iface ovpn:" <<
os.str());
285 tun_parent->tun_connected();
308 case CryptoDCInstance::ACTIVATE_PRIMARY:
309 OPENVPN_LOG(
"Installing PRIMARY key for peer " << peer_id);
315 case CryptoDCInstance::NEW_SECONDARY:
316 OPENVPN_LOG(
"Installing SECONDARY key for peer " << peer_id);
320 case CryptoDCInstance::PRIMARY_SECONDARY_SWAP:
322 genl->swap_keys(peer_id);
325 case CryptoDCInstance::DEACTIVATE_SECONDARY:
326 OPENVPN_LOG(
"Deleting SECONDARY key for peer " << peer_id);
330 case CryptoDCInstance::DEACTIVATE_ALL:
331 OPENVPN_LOG(
"Deleting all keys for peer " << peer_id);
337 OPENVPN_LOG(
"ovpndcocli: unknown rekey type: " << rktype);
352 case CryptoDCInstance::ACTIVATE_PRIMARY:
358 case CryptoDCInstance::NEW_SECONDARY:
362 case CryptoDCInstance::PRIMARY_SECONDARY_SWAP:
363 tb->tun_builder_dco_swap_keys(peer_id);
366 case CryptoDCInstance::DEACTIVATE_SECONDARY:
370 case CryptoDCInstance::DEACTIVATE_ALL:
376 OPENVPN_LOG(
"ovpndcocli: unknown rekey type: " << rktype);
383 transport_parent->transport_recv(buf);
392 buf.read(&cmd,
sizeof(cmd));
399 buf.read(&peer_id,
sizeof(peer_id));
401 buf.read(&reason,
sizeof(reason));
403 std::ostringstream
os;
409 err = Error::TRANSPORT_ERROR;
410 os <<
"keepalive timeout";
414 err = Error::TRANSPORT_ERROR;
415 os <<
"transport error";
419 err = Error::TRANSPORT_ERROR;
420 os <<
"peer deleted, id=" << peer_id <<
", teardown";
426 <<
", requested by userspace");
427 peer_id = OVPN_PEER_ID_UNDEF;
431 err = Error::TUN_HALT;
432 os <<
"peer deleted, id=" << peer_id <<
", reason=" << reason;
437 transport_parent->transport_error(err,
os.str());
444 buf.read(&peer,
sizeof(peer));
447 peer.transport.tx_bytes,
450 peer.transport.rx_pkts,
451 peer.transport.tx_pkts,
461 transport_parent->transport_error(Error::TUN_HALT, buf_to_string(buf));
475 transport_parent->transport_needs_send();
479 const std::string &err_text)
override
481 transport_parent->transport_error(fatal_err, err_text);
485 const std::string &err_text)
override
487 transport_parent->proxy_error(fatal_err, err_text);
492 return transport_parent->transport_is_openvpn_protocol();
497 transport_parent->transport_pre_resolve();
502 transport_parent->transport_wait_proxy();
507 transport_parent->transport_wait();
512 transport_parent->transport_connecting();
517 return transport_parent->is_keepalive_enabled();
521 unsigned int &keepalive_timeout)
override
523 transport_parent->disable_keepalive(keepalive_ping, keepalive_timeout);
530 :
Client(io_context_arg, config_arg, parent_arg)
537 int fd = tb->tun_builder_dco_enable(
config->dev_name);
541 transport_parent->transport_error(Error::TUN_IFACE_CREATE,
542 "error creating ovpn-dco device");
546 pipe.reset(
new openvpn_io::posix::stream_descriptor(io_context, fd));
550 std::ostringstream
os;
555 transport_parent->transport_error(Error::TUN_IFACE_CREATE,
os.str());
560 io_context_arg, if_nametoindex(config_arg->dev_name.c_str()),
this));
566 tun_parent->tun_pre_tun_config();
574 builder =
config->builder;
582 TunProp::configure_builder(builder,
597 config->builder->tun_builder_dco_establish();
602 remove_cmds->execute_log();
607 std::vector<IP::Route> rtvec;
609 TUN_LINUX::tun_config(
config->dev_name,
614 TunConfigFlags::ADD_BYPASS_ROUTES);
617 add_cmds->execute_log();
625 if (transport_parent->is_keepalive_enabled())
627 unsigned int keepalive_interval = 0;
628 unsigned int keepalive_timeout = 0;
634 transport_parent->disable_keepalive(keepalive_interval,
638 if (
config->ping_restart_override)
639 keepalive_timeout =
config->ping_restart_override;
643 config->builder->tun_builder_dco_set_peer(peer_id, keepalive_interval, keepalive_timeout);
647 OPENVPN_LOG(
"Setting DCO peer " << peer_id <<
" interval: " << keepalive_interval <<
" timeout: " << keepalive_timeout);
650 genl->set_peer(peer_id, keepalive_interval, keepalive_timeout);
664 BufAllocFlags::GROW | BufAllocFlags::CONSTRUCT_ZERO | BufAllocFlags::DESTRUCT_ZERO);
665 pipe->async_read_some(
666 pkt->
buf.mutable_buffer(),
669 const size_t bytes_recvd)
mutable
673 pkt->
buf.set_size(bytes_recvd);
674 if (self->tun_read_handler(pkt->
buf))
675 self->queue_read_pipe(pkt.release());
681 OPENVPN_LOG(
"ovpn-dco pipe read error: " << error.message());
683 self->transport_parent->transport_error(Error::TUN_HALT,
705 std::unique_ptr<openvpn_io::posix::stream_descriptor>
pipe;
std::string tun_name() const override
void del_peer(uint32_t peer_id)
bool transport_send(BufferAllocated &buf) override
void transport_recv(BufferAllocated &buf) override
void rekey_impl_tb(const CryptoDCInstance::RekeyType rktype, const KoRekey::Info &rkinfo)
void transport_pre_resolve() override
void disable_keepalive(unsigned int &keepalive_ping, unsigned int &keepalive_timeout) override
TransportClient::Ptr transport
IP::Addr server_endpoint_addr() const override
void get_remote_sockaddr(struct sockaddr_storage &sa, socklen_t &salen)
void proxy_error(const Error::Type fatal_err, const std::string &err_text) override
void transport_error(const Error::Type fatal_err, const std::string &err_text) override
static bool available(TunBuilderBase *tb)
bool transport_is_openvpn_protocol() override
void rekey(const CryptoDCInstance::RekeyType rktype, const KoRekey::Info &rkinfo) override
void update_peer_stats(uint32_t peer_id, bool sync)
void tun_setup(const OptionList &opt)
void apply_push_update(const OptionList &opt, TransportClient &) override
void transport_needs_send() override
void queue_read_pipe(PacketFrom *pkt)
void add_peer(uint32_t peer_id, IPv4::Addr ipv4, IPv6::Addr ipv6)
OvpnDcoClient(openvpn_io::io_context &io_context_arg, ClientConfig *config_arg, TransportClientParent *parent_arg)
void rekey_impl(const CryptoDCInstance::RekeyType rktype, const KoRekey::Info &rkinfo)
unsigned short server_endpoint_port() const override
std::unique_ptr< openvpn_io::posix::stream_descriptor > pipe
bool tun_read_handler(BufferAllocated &buf)
RCPtr< OvpnDcoClient > Ptr
void transport_connecting() override
SessionStats::DCOTransportSource::Data dco_transport_stats_delta() override
SessionStats::DCOTransportSource::Data last_delta
void resolve_callback(const openvpn_io::error_code &error, results_type results) override
void transport_wait_proxy() override
friend class ClientConfig
bool is_keepalive_enabled() const override
void transport_wait() override
GeNL< OvpnDcoClient * > GeNLImpl
void transport_start() override
Protocol transport_protocol() const override
SessionStats::DCOTransportSource::Data last_stats
void tun_start(const OptionList &opt, TransportClient &transcli, CryptoDCSettings &dc_settings) override
bool transport_send_const(const Buffer &buf) override
OPENVPN_EXCEPTION(dcocli_error)
Private::ClientState * state
MySessionStats::Ptr stats
const IPv4::Addr & to_ipv4() const
sockaddr_in to_sockaddr(const unsigned short port=0) const
Parses key information into format consumed by ovpn-dco.
const std::string * get_ptr(const size_t index, const size_t max_len) const
T * get() const noexcept
Returns the raw pointer to the object T, or nullptr.
TunBuilder methods, loosely based on the Android VpnService.Builder abstraction.
virtual bool tun_builder_new()
Callback to construct a new TunBuilder. This function should be called first.
#define OPENVPN_THROW(exc, stuff)
#define OPENVPN_LOG(args)
@ OVPN_KEY_SLOT_SECONDARY
@ OVPN_DEL_PEER_REASON_EXPIRED
@ OVPN_DEL_PEER_REASON_TRANSPORT_ERROR
@ OVPN_DEL_PEER_REASON_USERSPACE
@ OVPN_DEL_PEER_REASON_TEARDOWN
std::unique_ptr< PacketFrom > SPtr
static const char config[]