Attention is currently required from: plaisthos.
Hello plaisthos,
I'd like you to do a code review.
Please visit
http://gerrit.openvpn.net/c/openvpn/+/1769?usp=email
to review the following change.
Change subject: socket: adopt a pre-created UDP socket for a client connection
......................................................................
socket: adopt a pre-created UDP socket for a client connection
Add LS_MODE_UDP_ADOPT: a client link_socket can take ownership of an
already-bound UDP socket handed off via c2.oob_probe_adopt/oob_probe_sd
instead of creating its own, and pins c2.oob_probe_remote as the outgoing
address. This lets the OOB server-probe socket become the connection socket,
so the source IP+port and destination match what the server's handshake
cookie is bound to.
- link_socket_init_phase1: adopt the fd, inherit the address family, skip the
local bind, and pre-set lsa->actual (resolve_remote preserves an already-
defined actual)
- link_socket_init_phase2: skip create_socket() so the adopted fd is not
clobbered (overlapped-I/O init is fd-independent, so Windows is fine)
- do_init_socket_phase1: select the mode for the single client socket
Dormant until the client sets oob_probe_adopt (next commit).
Change-Id: Iec384ee6844ab278b280d6eafec8aaecf9dde755
Signed-off-by: Lev Stipakov <[email protected]>
---
M src/openvpn/init.c
M src/openvpn/openvpn.h
M src/openvpn/socket.c
M src/openvpn/socket.h
4 files changed, 65 insertions(+), 2 deletions(-)
git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/69/1769/1
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index e0d6a14..8eca6f7 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -3820,6 +3820,12 @@
mode = LS_MODE_TCP_ACCEPT_FROM;
}
}
+ /* adopt the OOB server-probe socket as this client's connection socket
+ * (handshake shortcut); only the single client socket is ever adopted
*/
+ else if (c->c2.oob_probe_adopt && i == 0)
+ {
+ mode = LS_MODE_UDP_ADOPT;
+ }
/* init each socket with its specific args */
link_socket_init_phase1(c, i, mode);
@@ -3985,6 +3991,16 @@
static void
do_close_link_socket(struct context *c)
{
+ /* An OOB probe socket handed off for the handshake shortcut is adopted by
the
+ * link socket in link_socket_init_phase1() (which clears oob_probe_sd).
If the
+ * connection attempt aborted before that, the fd is still owned here;
close it
+ * so it is not leaked when context_clear_2() zeroes c2. */
+ if (c->c2.oob_probe_sd != SOCKET_UNDEFINED)
+ {
+ openvpn_close_socket(c->c2.oob_probe_sd);
+ c->c2.oob_probe_sd = SOCKET_UNDEFINED;
+ }
+
if (c->c2.link_sockets && c->c2.link_socket_owned)
{
for (int i = 0; i < c->c1.link_sockets_num; i++)
diff --git a/src/openvpn/openvpn.h b/src/openvpn/openvpn.h
index fa00822..e5a1d76 100644
--- a/src/openvpn/openvpn.h
+++ b/src/openvpn/openvpn.h
@@ -239,7 +239,16 @@
bool link_socket_owned;
- const struct link_socket *accept_from; /* possibly do accept() on a
parent link_socket */
+ const struct link_socket *accept_from; /* possibly do accept() on a parent
link_socket */
+
+ /* OOB server-probe handshake shortcut: when oob_probe_adopt is true, the
+ * connection adopts oob_probe_sd (the winning remote's already-bound probe
+ * socket) instead of creating one, and pins oob_probe_remote (the exact
+ * address probed) as the outgoing address, so the source IP+port and the
+ * destination match what the server's handshake cookie is bound to. */
+ bool oob_probe_adopt;
+ socket_descriptor_t oob_probe_sd;
+ struct openvpn_sockaddr oob_probe_remote;
struct link_socket_actual *to_link_addr; /* IP address of remote */
struct link_socket_actual from; /* address of incoming datagram */
diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c
index df2cc9e..a9dca0a 100644
--- a/src/openvpn/socket.c
+++ b/src/openvpn/socket.c
@@ -1428,6 +1428,41 @@
/* inherit (possibly guessed) info AF from parent context */
sock->info.af = c->c2.accept_from->info.af;
}
+ else if (mode == LS_MODE_UDP_ADOPT)
+ {
+ /* Adopt the OOB probe socket: same source IP+port the server's cookie
is
+ * bound to. It is already bound, so do not bind again. */
+ ASSERT(c->c2.oob_probe_sd != SOCKET_UNDEFINED);
+ sock->sd = c->c2.oob_probe_sd;
+ c->c2.oob_probe_sd = SOCKET_UNDEFINED; /* ownership moves to the link
socket */
+ sock->info.af = c->c2.oob_probe_remote.addr.sa.sa_family;
+ sock->bind_local = false;
+
+ /* The probe socket was created plainly, so apply the same options
+ * create_socket() would (it is already bound, so no bind here).
+ * --multihome's IP_PKTINFO never applies to a probing client, so it is
+ * intentionally not set. */
+ sock->sockflags |= SF_GETADDRINFO_DGRAM;
+ socket_set_buffers(sock->sd, &sock->socket_buffer_sizes, true);
+ socket_set_mark(sock->sd, sock->mark);
+#if defined(TARGET_LINUX)
+ if (sock->bind_dev)
+ {
+ msg(M_INFO, "Using bind-dev %s", sock->bind_dev);
+ if (setsockopt(sock->sd, SOL_SOCKET, SO_BINDTODEVICE,
sock->bind_dev,
+ strlen(sock->bind_dev) + 1)
+ != 0)
+ {
+ msg(M_WARN | M_ERRNO, "WARN: setsockopt SO_BINDTODEVICE=%s
failed", sock->bind_dev);
+ }
+ }
+#endif
+
+ /* Pin the exact address we probed so the connection targets the
address
+ * the cookie was minted for; resolve_remote() preserves a defined
actual. */
+ CLEAR(sock->info.lsa->actual);
+ sock->info.lsa->actual.dest = c->c2.oob_probe_remote;
+ }
/* are we running in HTTP proxy mode? */
if (sock->http_proxy)
@@ -1720,7 +1755,7 @@
goto done;
}
#endif
- if (sock->info.lsa->current_remote)
+ if (sock->mode != LS_MODE_UDP_ADOPT && sock->info.lsa->current_remote)
{
create_socket(sock, sock->info.lsa->current_remote);
}
diff --git a/src/openvpn/socket.h b/src/openvpn/socket.h
index cd4e8ed..d807f36 100644
--- a/src/openvpn/socket.h
+++ b/src/openvpn/socket.h
@@ -197,6 +197,9 @@
#define LS_MODE_DEFAULT 0
#define LS_MODE_TCP_LISTEN 1
#define LS_MODE_TCP_ACCEPT_FROM 2
+/* Adopt a pre-created, already-bound UDP socket (from the OOB server probe) as
+ * the connection socket, instead of creating one. */
+#define LS_MODE_UDP_ADOPT 3
int mode;
int resolve_retry_seconds;
--
To view, visit http://gerrit.openvpn.net/c/openvpn/+/1769?usp=email
To unsubscribe, or for help writing mail filters, visit
http://gerrit.openvpn.net/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: Iec384ee6844ab278b280d6eafec8aaecf9dde755
Gerrit-Change-Number: 1769
Gerrit-PatchSet: 1
Gerrit-Owner: stipa <[email protected]>
Gerrit-Reviewer: plaisthos <[email protected]>
Gerrit-CC: openvpn-devel <[email protected]>
Gerrit-Attention: plaisthos <[email protected]>
_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel