aboutsummaryrefslogtreecommitdiff
path: root/src/openvpn/dco.c
diff options
context:
space:
mode:
authorAntonio Quartulli2022-08-04 09:14:01 +0200
committerGert Doering2022-08-04 15:28:57 +0200
commitb6f7b285767e66f5cbd3854cf0ff918e87b31202 (patch)
tree27f2caa59c511b79a384d05477b3951e4dd531c0 /src/openvpn/dco.c
parent46f6a7e8b6daf02bebe4a46498665274f1673ac0 (diff)
downloadopenvpn-b6f7b285767e66f5cbd3854cf0ff918e87b31202.zip
openvpn-b6f7b285767e66f5cbd3854cf0ff918e87b31202.tar.gz
dco: implement dco support for p2p/client code path
With this change we introduce ovpn-dco support only along the p2p/client code path. Server codebase is still unchanged. Signed-off-by: Antonio Quartulli <a@unstable.cc> Acked-by: Gert Doering <gert@greenie.muc.de> Message-Id: <20220804071401.12410-1-a@unstable.cc> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg24798.html Signed-off-by: Gert Doering <gert@greenie.muc.de>
Diffstat (limited to 'src/openvpn/dco.c')
-rw-r--r--src/openvpn/dco.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/openvpn/dco.c b/src/openvpn/dco.c
index 8c22b7e..a8735e8 100644
--- a/src/openvpn/dco.c
+++ b/src/openvpn/dco.c
@@ -36,6 +36,7 @@
#include "crypto.h"
#include "dco.h"
#include "errlevel.h"
+#include "multi.h"
#include "networking.h"
#include "openvpn.h"
#include "options.h"
@@ -382,4 +383,93 @@ dco_check_pull_options(int msglevel, const struct options *o)
return true;
}
+int
+dco_p2p_add_new_peer(struct context *c)
+{
+ if (!dco_enabled(&c->options))
+ {
+ return 0;
+ }
+
+ struct tls_multi *multi = c->c2.tls_multi;
+ struct link_socket *ls = c->c2.link_socket;
+
+ struct in6_addr remote_ip6 = { 0 };
+ struct in_addr remote_ip4 = { 0 };
+
+ struct in6_addr *remote_addr6 = NULL;
+ struct in_addr *remote_addr4 = NULL;
+
+ const char *gw = NULL;
+
+ ASSERT(ls->info.connection_established);
+
+ /* In client mode if a P2P style topology is used we assume the
+ * remote-gateway is the IP of the peer */
+ if (c->options.topology == TOP_NET30 || c->options.topology == TOP_P2P)
+ {
+ gw = c->options.ifconfig_remote_netmask;
+ }
+ if (c->options.route_default_gateway)
+ {
+ gw = c->options.route_default_gateway;
+ }
+
+ /* These inet_pton conversion are fatal since options.c already implements
+ * checks to have only valid addresses when setting the options */
+ if (c->options.ifconfig_ipv6_remote)
+ {
+ if (inet_pton(AF_INET6, c->options.ifconfig_ipv6_remote, &remote_ip6) != 1)
+ {
+ msg(M_FATAL,
+ "DCO peer init: problem converting IPv6 ifconfig remote address %s to binary",
+ c->options.ifconfig_ipv6_remote);
+ }
+ remote_addr6 = &remote_ip6;
+ }
+
+ if (gw)
+ {
+ if (inet_pton(AF_INET, gw, &remote_ip4) != 1)
+ {
+ msg(M_FATAL, "DCO peer init: problem converting IPv4 ifconfig gateway address %s to binary", gw);
+ }
+ remote_addr4 = &remote_ip4;
+ }
+ else if (c->options.ifconfig_local)
+ {
+ msg(M_INFO, "DCO peer init: Need a peer VPN addresss to setup IPv4 (set --route-gateway)");
+ }
+
+ struct sockaddr *remoteaddr = &ls->info.lsa->actual.dest.addr.sa;
+
+ int ret = dco_new_peer(&c->c1.tuntap->dco, multi->peer_id,
+ c->c2.link_socket->sd, NULL, remoteaddr,
+ remote_addr4, remote_addr6);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ c->c2.tls_multi->dco_peer_added = true;
+ c->c2.link_socket->info.dco_installed = true;
+
+ return 0;
+}
+
+void
+dco_remove_peer(struct context *c)
+{
+ if (!dco_enabled(&c->options))
+ {
+ return;
+ }
+
+ if (c->c1.tuntap && c->c2.tls_multi && c->c2.tls_multi->dco_peer_added)
+ {
+ dco_del_peer(&c->c1.tuntap->dco, c->c2.tls_multi->peer_id);
+ c->c2.tls_multi->dco_peer_added = false;
+ }
+}
+
#endif /* defined(ENABLE_DCO) */