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());
73 tun_parent->tun_pre_tun_config();
89 TunProp::configure_builder(builder,
104 config->builder->tun_builder_dco_establish();
111 std::vector<IP::Route> rtvec;
113 TUN_LINUX::tun_config(
config->dev_name,
118 TunConfigFlags::ADD_BYPASS_ROUTES);
121 add_cmds->execute_log();
127 dc_settings.factory(),
this,
config->transport.frame)));
131 state->vpn_ip4_gw.to_ipv4_zero(),
132 state->vpn_ip6_gw.to_ipv6_zero());
134 tun_parent->tun_connected();
145 return transport->server_endpoint_addr();
153 return transport->server_endpoint_port();
167 if (!
config->transport.protocol.is_tcp())
170 udpconf->remote_list =
config->transport.remote_list;
171 udpconf->frame =
config->transport.frame;
172 udpconf->stats =
config->transport.stats;
173 udpconf->socket_protect =
config->transport.socket_protect;
174 udpconf->server_addr_float =
config->transport.server_addr_float;
175 transport_factory = udpconf;
180 tcpconf->remote_list =
config->transport.remote_list;
181 tcpconf->frame =
config->transport.frame;
182 tcpconf->stats =
config->transport.stats;
183 tcpconf->socket_protect =
config->transport.socket_protect;
184 transport_factory = tcpconf;
187 config->transport.stats->dco_configure(
this);
189 transport = transport_factory->new_transport_client_obj(io_context,
this);
195 return transport->transport_send_const(buf);
201 "Non-const send expected for data channel only, but "
202 "ovpndcocli is not expected to handle data packets");
207 memset(&sa, 0,
sizeof(sa));
209 struct sockaddr_in *sa4 = (
struct sockaddr_in *)&sa;
210 struct sockaddr_in6 *sa6 = (
struct sockaddr_in6 *)&sa;
213 if (remote_addr.version() == IP::Addr::V4)
215 salen =
sizeof(*sa4);
220 salen =
sizeof(*sa6);
221 *sa6 = remote_addr.to_ipv6().to_sockaddr(
transport->server_endpoint_port());
230 tb->tun_builder_dco_del_peer(peer_id);
234 genl->del_peer(peer_id);
239 struct sockaddr_storage sa;
247 tb->tun_builder_dco_new_peer(peer_id,
249 (
struct sockaddr *)&sa,
256 genl->new_peer(peer_id,
258 (
struct sockaddr *)&sa,
268 if (peer_id == OVPN_PEER_ID_UNDEF)
274 tb->tun_builder_dco_get_peer(peer_id, sync);
279 genl->get_peer(peer_id, sync);
286 results_type results)
override
301 config->builder->tun_builder_teardown(
true);
307 std::ostringstream
os;
311 int res = TunNetlink::iface_del(
os,
config->dev_name);
314 OPENVPN_LOG(
"ovpndcocli: error deleting iface ovpn:" <<
os.str());
343 case CryptoDCInstance::ACTIVATE_PRIMARY:
349 case CryptoDCInstance::NEW_SECONDARY:
354 case CryptoDCInstance::PRIMARY_SECONDARY_SWAP:
356 genl->swap_keys(peer_id);
359 case CryptoDCInstance::DEACTIVATE_SECONDARY:
364 case CryptoDCInstance::DEACTIVATE_ALL:
370 OPENVPN_LOG(
"ovpndcocli: unknown rekey type: " << rktype);
385 case CryptoDCInstance::ACTIVATE_PRIMARY:
391 case CryptoDCInstance::NEW_SECONDARY:
395 case CryptoDCInstance::PRIMARY_SECONDARY_SWAP:
396 tb->tun_builder_dco_swap_keys(peer_id);
399 case CryptoDCInstance::DEACTIVATE_SECONDARY:
403 case CryptoDCInstance::DEACTIVATE_ALL:
409 OPENVPN_LOG(
"ovpndcocli: unknown rekey type: " << rktype);
416 transport_parent->transport_recv(buf);
425 buf.read(&cmd,
sizeof(cmd));
429 case OVPN_CMD_DEL_PEER:
432 buf.read(&peer_id,
sizeof(peer_id));
434 buf.read(&reason,
sizeof(reason));
436 std::ostringstream
os;
441 case OVPN_DEL_PEER_REASON_EXPIRED:
442 err = Error::TRANSPORT_ERROR;
443 os <<
"keepalive timeout";
446 case OVPN_DEL_PEER_REASON_TRANSPORT_ERROR:
447 err = Error::TRANSPORT_ERROR;
448 os <<
"transport error";
451 case OVPN_DEL_PEER_REASON_TEARDOWN:
452 err = Error::TRANSPORT_ERROR;
453 os <<
"peer deleted, id=" << peer_id <<
", teardown";
456 case OVPN_DEL_PEER_REASON_USERSPACE:
459 <<
", requested by userspace");
460 peer_id = OVPN_PEER_ID_UNDEF;
464 err = Error::TUN_HALT;
465 os <<
"peer deleted, id=" << peer_id <<
", reason=" << reason;
470 transport_parent->transport_error(err,
os.str());
474 case OVPN_CMD_GET_PEER:
477 buf.read(&peer,
sizeof(peer));
480 peer.transport.tx_bytes,
483 peer.transport.rx_pkts,
484 peer.transport.tx_pkts,
494 transport_parent->transport_error(Error::TUN_HALT, buf_to_string(buf));
508 transport_parent->transport_needs_send();
512 const std::string &err_text)
override
514 transport_parent->transport_error(fatal_err, err_text);
518 const std::string &err_text)
override
520 transport_parent->proxy_error(fatal_err, err_text);
525 return transport_parent->transport_is_openvpn_protocol();
530 transport_parent->transport_pre_resolve();
535 transport_parent->transport_wait_proxy();
540 transport_parent->transport_wait();
545 transport_parent->transport_connecting();
550 return transport_parent->is_keepalive_enabled();
554 unsigned int &keepalive_timeout)
override
556 transport_parent->disable_keepalive(keepalive_ping, keepalive_timeout);
563 :
Client(io_context_arg, config_arg, parent_arg)
570 int fd = tb->tun_builder_dco_enable(
config->dev_name);
574 transport_parent->transport_error(Error::TUN_IFACE_CREATE,
575 "error creating ovpn-dco device");
579 pipe.reset(
new openvpn_io::posix::stream_descriptor(io_context, fd));
583 std::ostringstream
os;
584 int res = TunNetlink::iface_new(
os,
config->dev_name,
"ovpn-dco");
588 transport_parent->transport_error(Error::TUN_IFACE_CREATE,
os.str());
593 io_context_arg, if_nametoindex(config_arg->dev_name.c_str()),
this));
600 if (transport_parent->is_keepalive_enabled())
602 unsigned int keepalive_interval = 0;
603 unsigned int keepalive_timeout = 0;
609 transport_parent->disable_keepalive(keepalive_interval,
613 if (
config->ping_restart_override)
614 keepalive_timeout =
config->ping_restart_override;
618 config->builder->tun_builder_dco_set_peer(peer_id, keepalive_interval, keepalive_timeout);
623 genl->set_peer(peer_id, keepalive_interval, keepalive_timeout);
637 BufAllocFlags::GROW | BufAllocFlags::CONSTRUCT_ZERO | BufAllocFlags::DESTRUCT_ZERO);
638 pipe->async_read_some(
639 pkt->
buf.mutable_buffer(),
642 const size_t bytes_recvd)
mutable
646 pkt->
buf.set_size(bytes_recvd);
647 if (self->tun_read_handler(pkt->
buf))
648 self->queue_read_pipe(pkt.release());
654 OPENVPN_LOG(
"ovpn-dco pipe read error: " << error.message());
656 self->transport_parent->transport_error(Error::TUN_HALT,
678 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 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
std::unique_ptr< PacketFrom > SPtr
static const char config[]