return true;
}
-static void
-addr_set_dco_installed(struct context *c)
-{
- /* We ensure that all addresses we currently hold have the dco_installed
- * bit set */
- for (int i = 0; i < KEY_SCAN_SIZE; ++i)
- {
- struct key_state *ks = get_key_scan(c->c2.tls_multi, i);
- if (ks)
- {
- ks->remote_addr.dco_installed = true;
- }
- }
- get_link_socket_info(c)->lsa->actual.dco_installed = true;
-}
-
int
dco_p2p_add_new_peer(struct context *c)
{
ASSERT(ls->info.connection_established);
- addr_set_dco_installed(c);
-
struct sockaddr *remoteaddr = &ls->info.lsa->actual.dest.addr.sa;
struct tls_multi *multi = c->c2.tls_multi;
#ifdef TARGET_FREEBSD
}
c->c2.tls_multi->dco_peer_id = multi->peer_id;
- c->c2.link_socket->info.lsa->actual.dco_installed = true;
+ c->c2.link_socket->dco_installed = true;
return 0;
}
ASSERT(c->c2.link_socket_info->connection_established);
remoteaddr = &c->c2.link_socket_info->lsa->actual.dest.addr.sa;
}
- addr_set_dco_installed(c);
/* In server mode we need to fetch the remote addresses from the push config */
struct in_addr vpn_ip4 = { 0 };
{
msg(D_DCO|M_ERRNO, "error closing TCP socket after DCO handover");
}
- c->c2.link_socket->info.lsa->actual.dco_installed = true;
+ c->c2.link_socket->dco_installed = true;
c->c2.link_socket->sd = SOCKET_UNDEFINED;
}
}
}
-/* Linux DCO implementations pass the socket to the kernel and
- * disallow usage of it from userland, so (control) packets sent and
- * received by OpenVPN need to go through the DCO interface.
+/*
+ * Linux DCO implementations pass the socket to the kernel and
+ * disallow usage of it from userland for TCP, so (control) packets
+ * sent and received by OpenVPN need to go through the DCO interface.
*
* Windows DCO needs control packets to be sent via the normal
* standard Overlapped I/O.
* in the future...) in a small inline function.
*/
static inline bool
-should_use_dco_socket(struct link_socket_actual *actual)
+should_use_dco_socket(struct link_socket *ls)
{
#if defined(TARGET_LINUX)
- return actual->dco_installed;
+ return ls->dco_installed && proto_is_tcp(ls->info.proto);
#else
return false;
#endif
socks_preprocess_outgoing_link(c, &to_addr, &size_delta);
/* Send packet */
- if (should_use_dco_socket(c->c2.to_link_addr))
+ if (should_use_dco_socket(c->c2.link_socket))
{
size = dco_do_write(&c->c1.tuntap->dco,
c->c2.tls_multi->dco_peer_id,
* closed in do_close_tun(). Set it to UNDEFINED so
* we won't use WinSock API to close it. */
if (tuntap_is_dco_win(c->c1.tuntap) && c->c2.link_socket
- && c->c2.link_socket->info.lsa->actual.dco_installed)
+ && c->c2.link_socket->dco_installed)
{
c->c2.link_socket->sd = SOCKET_UNDEFINED;
}
tv_clear(&c->c2.timeval); /* ZERO-TIMEOUT */
- if (mi && mi->context.c2.link_socket->info.lsa->actual.dco_installed)
+ if (mi && mi->context.c2.link_socket->dco_installed)
{
/* If we got a socket that has been handed over to the kernel
* we must not call the normal socket function to figure out
case TA_INITIAL:
ASSERT(mi);
- if (!mi->context.c2.link_socket->info.lsa->actual.dco_installed)
+ if (!mi->context.c2.link_socket->dco_installed)
{
multi_tcp_set_global_rw_flags(m, mi);
}
}
else
{
- if (!c->c2.link_socket->info.lsa->actual.dco_installed)
+ if (!c->c2.link_socket->dco_installed)
{
multi_tcp_set_global_rw_flags(m, mi);
}
get_server_poll_remaining_time(sock->server_poll_timeout),
signal_received);
- sock->info.lsa->actual.dco_installed = true;
+ sock->dco_installed = true;
if (*signal_received)
{
static int
socket_get_last_error(const struct link_socket *sock)
{
- if (sock->info.lsa->actual.dco_installed)
+ if (sock->dco_installed)
{
return GetLastError();
}
ASSERT(ResetEvent(sock->reads.overlapped.hEvent));
sock->reads.flags = 0;
- if (sock->info.lsa->actual.dco_installed)
+ if (sock->dco_installed)
{
status = ReadFile((HANDLE)sock->sd, wsabuf[0].buf, wsabuf[0].len,
&sock->reads.size, &sock->reads.overlapped);
ASSERT(ResetEvent(sock->writes.overlapped.hEvent));
sock->writes.flags = 0;
- if (sock->info.lsa->actual.dco_installed)
+ if (sock->dco_installed)
{
status = WriteFile((HANDLE)sock->sd, wsabuf[0].buf, wsabuf[0].len,
&sock->writes.size, &sock->writes.overlapped);
/*int dummy;*/ /* add offset to force a bug if dest not explicitly dereferenced */
struct openvpn_sockaddr dest;
- bool dco_installed;
#if ENABLE_IP_PKTINFO
union {
#if defined(HAVE_IN_PKTINFO) && defined(HAVE_IPI_SPEC_DST)
socket_descriptor_t sd;
socket_descriptor_t ctrl_sd; /* only used for UDP over Socks */
+ bool dco_installed;
#ifdef _WIN32
struct overlapped_io reads;
struct link_socket_actual *from)
{
sockethandle_t sh = { .s = sock->sd };
- if (sock->info.lsa->actual.dco_installed)
+ if (sock->dco_installed)
{
*from = sock->info.lsa->actual;
sh.is_handle = true;
struct buffer *buf,
struct link_socket_actual *from)
{
- if (proto_is_udp(sock->info.proto)
- || sock->info.lsa->actual.dco_installed)
+ if (proto_is_udp(sock->info.proto) || sock->dco_installed)
/* unified UDPv4 and UDPv6, for DCO the kernel
* will strip the length header */
{
{
int err = 0;
int status = 0;
- sockethandle_t sh = { .s = sock->sd, .is_handle = sock->info.lsa->actual.dco_installed };
+ sockethandle_t sh = { .s = sock->sd, .is_handle = sock->dco_installed };
if (overlapped_io_active(&sock->writes))
{
status = sockethandle_finalize(sh, &sock->writes, NULL, NULL);
struct buffer *buf,
struct link_socket_actual *to)
{
- if (proto_is_udp(sock->info.proto) || to->dco_installed)
+ if (proto_is_udp(sock->info.proto) || sock->dco_installed)
{
/* unified UDPv4 and UDPv6 and DCO (kernel adds size header) */
return link_socket_write_udp(sock, buf, to);