@@ -460,7 +460,7 @@
return 0;
}
- struct link_socket *ls = c->c2.link_socket;
+ struct link_socket *ls = c->c2.link_sockets[0];
ASSERT(ls->info.connection_established);
@@ -476,7 +476,7 @@
}
#endif
int ret = dco_new_peer(&c->c1.tuntap->dco, multi->peer_id,
- c->c2.link_socket->sd, NULL, remoteaddr, NULL, NULL);
+ c->c2.link_sockets[0]->sd, NULL, remoteaddr, NULL, NULL);
if (ret < 0)
{
return ret;
@@ -509,12 +509,12 @@
#if ENABLE_IP_PKTINFO
struct context *c = &mi->context;
- if (!proto_is_udp(c->c2.link_socket->info.proto) || !(c->options.sockflags & SF_USE_IP_PKTINFO))
+ if (!proto_is_udp(c->c2.link_sockets[0]->info.proto) || !(c->options.sockflags & SF_USE_IP_PKTINFO))
{
return false;
}
- struct link_socket_actual *actual = &c->c2.link_socket_info->lsa->actual;
+ struct link_socket_actual *actual = &c->c2.link_socket_infos[0]->lsa->actual;
switch (actual->dest.addr.sa.sa_family)
{
@@ -559,7 +559,7 @@
int peer_id = c->c2.tls_multi->peer_id;
struct sockaddr *remoteaddr, *localaddr = NULL;
struct sockaddr_storage local = { 0 };
- int sd = c->c2.link_socket->sd;
+ int sd = c->c2.link_sockets[0]->sd;
if (c->mode == CM_CHILD_TCP)
@@ -569,8 +569,8 @@
}
else
{
- ASSERT(c->c2.link_socket_info->connection_established);
- remoteaddr = &c->c2.link_socket_info->lsa->actual.dest.addr.sa;
+ ASSERT(c->c2.link_socket_infos[0]->connection_established);
+ remoteaddr = &c->c2.link_socket_infos[0]->lsa->actual.dest.addr.sa;
}
/* In server mode we need to fetch the remote addresses from the push config */
@@ -141,6 +141,7 @@
struct event_arg
{
event_arg_t type;
+ bool pending; /* in UDP/P2P mode marks sockets waiting for processing */
union {
struct multi_instance *mi; /* if type = EVENT_ARG_MULTI_INSTANCE */
struct link_socket *ls; /* if type = EVENT_ARG_LINK_SOCKET */
@@ -57,12 +57,18 @@
wait_status_string(struct context *c, struct gc_arena *gc)
{
struct buffer out = alloc_buf_gc(64, gc);
- buf_printf(&out, "I/O WAIT %s|%s|%s|%s %s",
+ int i;
+
+ buf_printf(&out, "I/O WAIT %s|%s| %s",
tun_stat(c->c1.tuntap, EVENT_READ, gc),
tun_stat(c->c1.tuntap, EVENT_WRITE, gc),
- socket_stat(c->c2.link_socket, EVENT_READ, gc),
- socket_stat(c->c2.link_socket, EVENT_WRITE, gc),
tv_string(&c->c2.timeval, gc));
+ for (i = 0; i < c->c1.link_sockets_num; i++)
+ {
+ buf_printf(&out, "\n %s|%s",
+ socket_stat(c->c2.link_sockets[i], EVENT_READ, gc),
+ socket_stat(c->c2.link_sockets[i], EVENT_WRITE, gc));
+ }
return BSTR(&out);
}
@@ -98,7 +104,7 @@
{
if (c->c2.tls_multi && c->c2.tls_exit_signal)
{
- if (link_socket_connection_oriented(c->c2.link_socket))
+ if (link_socket_connection_oriented(c->c2.link_sockets[0]))
{
if (c->c2.tls_multi->n_soft_errors)
{
@@ -551,6 +557,7 @@
#ifdef ENABLE_FRAGMENT
/*
* Should we deliver a datagram fragment to remote?
+ * c is expected to be a single-link context (p2p or child)
*/
static void
check_fragment(struct context *c)
@@ -1107,7 +1114,9 @@
decrypt_status = openvpn_decrypt(&c->c2.buf, c->c2.buffers->decrypt_buf,
co, &c->c2.frame, ad_start);
- if (!decrypt_status && link_socket_connection_oriented(c->c2.link_socket))
+ if (!decrypt_status
+ /* all sockets are of the same type, so just check the first one */
+ && link_socket_connection_oriented(c->c2.link_sockets[0]))
{
/* decryption errors are fatal in TCP mode */
register_signal(c->sig, SIGUSR1, "decryption-error"); /* SOFT-SIGUSR1 -- decryption error in TCP mode */
@@ -1429,7 +1438,7 @@
*/
void
-process_incoming_tun(struct context *c)
+process_incoming_tun(struct context *c, struct link_socket *out_ls)
{
struct gc_arena gc = gc_new();
@@ -1462,7 +1471,8 @@
*/
unsigned int flags = PIPV4_PASSTOS | PIP_MSSFIX | PIPV4_CLIENT_NAT
| PIPV6_IMCP_NOHOST_CLIENT;
- process_ip_header(c, flags, &c->c2.buf);
+ process_ip_header(c, flags, &c->c2.buf,
+ out_ls);
#ifdef PACKET_TRUNCATION_CHECK
/* if (c->c2.buf.len > 1) --c->c2.buf.len; */
@@ -1623,7 +1633,8 @@
}
void
-process_ip_header(struct context *c, unsigned int flags, struct buffer *buf)
+process_ip_header(struct context *c, unsigned int flags, struct buffer *buf,
+ struct link_socket *ls)
{
if (!c->options.ce.mssfix)
{
@@ -1669,7 +1680,7 @@
/* extract TOS from IP header */
if (flags & PIPV4_PASSTOS)
{
- link_socket_extract_tos(c->c2.link_socket, &ipbuf);
+ link_socket_extract_tos(ls, &ipbuf);
}
#endif
@@ -1878,7 +1889,7 @@
*/
void
-process_outgoing_tun(struct context *c)
+process_outgoing_tun(struct context *c, struct link_socket *in_ls)
{
/*
* Set up for write() call to TUN/TAP
@@ -1895,9 +1906,8 @@
* The --mssfix option requires
* us to examine the IP header (IPv4 or IPv6).
*/
- process_ip_header(c,
- PIP_MSSFIX | PIPV4_EXTRACT_DHCP_ROUTER | PIPV4_CLIENT_NAT | PIP_OUTGOING,
- &c->c2.to_tun);
+ process_ip_header(c, PIP_MSSFIX|PIPV4_EXTRACT_DHCP_ROUTER|PIPV4_CLIENT_NAT|PIP_OUTGOING, &c->c2.to_tun,
+ in_ls);
if (c->c2.to_tun.len <= c->c2.frame.buf.payload_size)
{
@@ -2059,6 +2069,7 @@
#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
static int dco_shift = DCO_SHIFT; /* Event from DCO linux kernel module */
#endif
+ int i;
/*
* Decide what kind of events we want to wait for.
@@ -2164,8 +2175,11 @@
/*
* Configure event wait based on socket, tuntap flags.
*/
- socket_set(c->c2.link_socket, c->c2.event_set, socket,
- &c->c2.link_socket->ev_arg, NULL);
+ for (i = 0; i < c->c1.link_sockets_num; i++)
+ {
+ socket_set(c->c2.link_sockets[i], c->c2.event_set, socket,
+ &c->c2.link_sockets[i]->ev_arg, NULL);
+ }
tun_set(c->c1.tuntap, c->c2.event_set, tuntap, (void *)tun_shift, NULL);
#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
if (socket & EVENT_READ && c->c2.did_open_tun)
@@ -2203,7 +2217,7 @@
if (!c->sig->signal_received)
{
- if (!(flags & IOW_CHECK_RESIDUAL) || !socket_read_residual(c->c2.link_socket))
+ if (!(flags & IOW_CHECK_RESIDUAL) || !sockets_read_residual(c))
{
int status;
@@ -2242,6 +2256,9 @@
}
shift = socket_shift;
+ /* mark socket so that the multi code knows where we
+ * have pending i/o */
+ ev_arg->pending = true;
}
else
{
@@ -2295,7 +2312,7 @@
/* TUN device ready to accept write */
else if (status & TUN_WRITE)
{
- process_outgoing_tun(c);
+ process_outgoing_tun(c, ls);
}
/* Incoming data on TCP/UDP port */
else if (status & SOCKET_READ)
@@ -2312,7 +2329,7 @@
read_incoming_tun(c);
if (!IS_SIG(c))
{
- process_incoming_tun(c);
+ process_incoming_tun(c, ls);
}
}
else if (status & DCO_READ)
@@ -231,10 +231,12 @@
*
* If an error occurs, it is logged and the packet is dropped.
*
- * @param c - The context structure of the VPN tunnel associated with the
- * packet.
+ * @param c The context structure of the VPN tunnel associated with
+ * the packet.
+ * @param out_ls Socket that will be used to send out the packet.
+ *
*/
-void process_incoming_tun(struct context *c);
+void process_incoming_tun(struct context *c, struct link_socket *out_ls);
/**
@@ -246,10 +248,11 @@
*
* If an error occurs, it is logged and the packet is dropped.
*
- * @param c - The context structure of the VPN tunnel associated with
- * the packet.
+ * @param c The context structure of the VPN tunnel associated
+ * with the packet.
+ * @param in_ls Socket where the packet was received.
*/
-void process_outgoing_tun(struct context *c);
+void process_outgoing_tun(struct context *c, struct link_socket *in_ls);
/**************************************************************************/
@@ -303,20 +306,21 @@
#define PIPV6_IMCP_NOHOST_CLIENT (1<<5)
#define PIPV6_IMCP_NOHOST_SERVER (1<<6)
-void process_ip_header(struct context *c, unsigned int flags, struct buffer *buf);
+void process_ip_header(struct context *c, unsigned int flags, struct buffer *buf,
+ struct link_socket *ls);
void schedule_exit(struct context *c, const int n_seconds, const int signal);
static inline struct link_socket_info *
get_link_socket_info(struct context *c)
{
- if (c->c2.link_socket_info)
+ if (c->c2.link_socket_infos)
{
- return c->c2.link_socket_info;
+ return c->c2.link_socket_infos[0];
}
else
{
- return &c->c2.link_socket->info;
+ return &c->c2.link_sockets[0]->info;
}
}
@@ -533,12 +533,11 @@
{
/* Check if there is another resolved address to try for
* the current connection */
- if (c->c1.link_socket_addr.current_remote
- && c->c1.link_socket_addr.current_remote->ai_next
- && !c->options.advance_next_remote)
+ if (c->c1.link_socket_addrs[0].current_remote
+ && c->c1.link_socket_addrs[0].current_remote->ai_next)
{
- c->c1.link_socket_addr.current_remote =
- c->c1.link_socket_addr.current_remote->ai_next;
+ c->c1.link_socket_addrs[0].current_remote =
+ c->c1.link_socket_addrs[0].current_remote->ai_next;
}
else
{
@@ -554,20 +553,20 @@
* skipped by management on the previous loop.
* If so, clear the addrinfo objects as close_instance does
*/
- if (c->c1.link_socket_addr.remote_list)
+ if (c->c1.link_socket_addrs[0].remote_list)
{
- clear_remote_addrlist(&c->c1.link_socket_addr,
+ clear_remote_addrlist(&c->c1.link_socket_addrs[0],
!c->options.resolve_in_advance);
}
/* close_instance should have cleared the addrinfo objects */
- ASSERT(c->c1.link_socket_addr.current_remote == NULL);
- ASSERT(c->c1.link_socket_addr.remote_list == NULL);
+ ASSERT(c->c1.link_socket_addrs[0].current_remote == NULL);
+ ASSERT(c->c1.link_socket_addrs[0].remote_list == NULL);
}
else
{
- c->c1.link_socket_addr.current_remote =
- c->c1.link_socket_addr.remote_list;
+ c->c1.link_socket_addrs[0].current_remote =
+ c->c1.link_socket_addrs[0].remote_list;
}
int advance_count = 1;
@@ -730,6 +729,13 @@
uninit_proxy_dowork(c);
}
+static void
+do_link_socket_addr_new(struct context *c)
+{
+ ALLOC_ARRAY_CLEAR_GC(c->c1.link_socket_addrs, struct link_socket_addr,
+ c->c1.link_sockets_num, &c->gc);
+}
+
void
context_init_1(struct context *c)
{
@@ -739,6 +745,10 @@
init_connection_list(c);
+ c->c1.link_sockets_num = 1;
+
+ do_link_socket_addr_new(c);
+
#if defined(ENABLE_PKCS11)
if (c->first_time)
{
@@ -1667,7 +1677,7 @@
CLEAR(local);
actual = &get_link_socket_info(c)->lsa->actual;
remote = actual->dest;
- getsockname(c->c2.link_socket->sd, &local.addr.sa, &sa_len);
+ getsockname(c->c2.link_sockets[0]->sd, &local.addr.sa, &sa_len);
#if ENABLE_IP_PKTINFO
if (!addr_defined(&local))
{
@@ -1781,8 +1791,8 @@
c->options.ifconfig_ipv6_local,
c->options.ifconfig_ipv6_netbits,
c->options.ifconfig_ipv6_remote,
- c->c1.link_socket_addr.bind_local,
- c->c1.link_socket_addr.remote_list,
+ c->c1.link_socket_addrs[0].bind_local,
+ c->c1.link_socket_addrs[0].remote_list,
!c->options.ifconfig_nowarn,
c->c2.es,
&c->net_ctx,
@@ -1856,17 +1866,16 @@
do_alloc_route_list(c);
/* parse and resolve the route option list */
- ASSERT(c->c2.link_socket);
+ ASSERT(c->c2.link_sockets);
if (c->options.routes && c->c1.route_list)
{
do_init_route_list(&c->options, c->c1.route_list,
- &c->c2.link_socket->info, c->c2.es, &c->net_ctx);
+ &c->c2.link_sockets[0]->info, c->c2.es, &c->net_ctx);
}
if (c->options.routes_ipv6 && c->c1.route_ipv6_list)
{
do_init_route_ipv6_list(&c->options, c->c1.route_ipv6_list,
- &c->c2.link_socket->info, c->c2.es,
- &c->net_ctx);
+ &c->c2.link_sockets[0]->info, c->c2.es, &c->net_ctx);
}
/* do ifconfig */
@@ -1879,8 +1888,7 @@
c->options.dev_type,
c->options.dev_node,
&gc);
- do_ifconfig(c->c1.tuntap, guess, c->c2.frame.tun_mtu, c->c2.es,
- &c->net_ctx);
+ do_ifconfig(c->c1.tuntap, guess, c->c2.frame.tun_mtu, c->c2.es, &c->net_ctx);
}
/* possibly add routes */
@@ -1895,6 +1903,7 @@
/* Store the old fd inside the fd so open_tun can use it */
c->c1.tuntap->fd = oldtunfd;
#endif
+
if (dco_enabled(&c->options))
{
ovpn_dco_init(c->mode, &c->c1.tuntap->dco);
@@ -1907,16 +1916,14 @@
/* set the hardware address */
if (c->options.lladdr)
{
- set_lladdr(&c->net_ctx, c->c1.tuntap->actual_name, c->options.lladdr,
- c->c2.es);
+ set_lladdr(&c->net_ctx, c->c1.tuntap->actual_name, c->options.lladdr, c->c2.es);
}
/* do ifconfig */
if (!c->options.ifconfig_noexec
&& ifconfig_order() == IFCONFIG_AFTER_TUN_OPEN)
{
- do_ifconfig(c->c1.tuntap, c->c1.tuntap->actual_name,
- c->c2.frame.tun_mtu, c->c2.es, &c->net_ctx);
+ do_ifconfig(c->c1.tuntap, c->c1.tuntap->actual_name, c->c2.frame.tun_mtu, c->c2.es, &c->net_ctx);
}
/* run the up script */
@@ -2427,7 +2434,7 @@
{
msg(M_NONFATAL, "dco-win doesn't yet support reopening TUN device");
/* prevent link_socket_close() from closing handle with WinSock API */
- c->c2.link_socket->sd = SOCKET_UNDEFINED;
+ c->c2.link_sockets[0]->sd = SOCKET_UNDEFINED;
return false;
}
else
@@ -2657,14 +2664,28 @@
if (found & OPT_P_SOCKBUF)
{
+ int i;
+
msg(D_PUSH, "OPTIONS IMPORT: --sndbuf/--rcvbuf options modified");
- link_socket_update_buffer_sizes(c->c2.link_socket, c->options.rcvbuf, c->options.sndbuf);
+
+ for (i = 0; i < c->c1.link_sockets_num; i++)
+ {
+ link_socket_update_buffer_sizes(c->c2.link_sockets[i],
+ c->options.rcvbuf,
+ c->options.sndbuf);
+ }
}
if (found & OPT_P_SOCKFLAGS)
{
+ int i;
+
msg(D_PUSH, "OPTIONS IMPORT: --socket-flags option modified");
- link_socket_update_flags(c->c2.link_socket, c->options.sockflags);
+ for (i = 0; i < c->c1.link_sockets_num; i++)
+ {
+ link_socket_update_flags(c->c2.link_sockets[i],
+ c->options.sockflags);
+ }
}
if (found & OPT_P_PERSIST)
@@ -3747,12 +3768,103 @@
static void
do_link_socket_new(struct context *c)
{
- ASSERT(!c->c2.link_socket);
- c->c2.link_socket = link_socket_new();
+ int i;
+
+ ASSERT(!c->c2.link_sockets);
+
+ ALLOC_ARRAY_GC(c->c2.link_sockets, struct link_socket *,
+ c->c1.link_sockets_num, &c->c2.gc);
+
+ for (i = 0; i < c->c1.link_sockets_num; i++)
+ {
+ c->c2.link_sockets[i] = link_socket_new();
+ }
c->c2.link_socket_owned = true;
}
/*
+ * bind TCP/UDP sockets
+ */
+static void
+do_init_socket_1(struct context *c)
+{
+ unsigned int sockflags = c->options.sockflags;
+ int i;
+
+#if PORT_SHARE
+ if (c->options.port_share_host && c->options.port_share_port)
+ {
+ sockflags |= SF_PORT_SHARE;
+ }
+#endif
+
+ for (i = 0; i < c->c1.link_sockets_num; i++)
+ {
+ int mode = LS_MODE_DEFAULT;
+
+ /* mode allows CM_CHILD_TCP
+ * instances to inherit acceptable fds
+ * from a top-level parent */
+ if (c->options.mode == MODE_SERVER)
+ {
+ /* initializing listening socket */
+ if (c->mode == CM_TOP)
+ {
+ mode = LS_MODE_TCP_LISTEN;
+ }
+ /* initializing socket to client */
+ else if (c->mode == CM_CHILD_TCP)
+ {
+ mode = LS_MODE_TCP_ACCEPT_FROM;
+ }
+ }
+
+ /* init each socket with its specific port */
+ link_socket_init_phase1(c->c2.link_sockets[i],
+ c->options.ce.local,
+ c->options.ce.local_port,
+ c->options.ce.remote,
+ c->options.ce.remote_port,
+ c->c1.dns_cache,
+ c->options.ce.proto,
+ c->options.ce.af,
+ c->options.ce.bind_ipv6_only,
+ mode,
+ c->c2.accept_from,
+ c->c1.http_proxy,
+ c->c1.socks_proxy,
+#ifdef ENABLE_DEBUG
+ c->options.gremlin,
+#endif
+ c->options.ce.bind_local,
+ c->options.ce.remote_float,
+ &c->c1.link_socket_addrs[i],
+ c->options.ipchange,
+ c->plugins,
+ c->options.resolve_retry_seconds,
+ c->options.ce.mtu_discover_type,
+ c->options.rcvbuf,
+ c->options.sndbuf,
+ c->options.mark,
+ &c->c2.server_poll_interval,
+ sockflags);
+ }
+}
+
+/*
+ * finalize TCP/UDP sockets
+ */
+static void
+do_init_socket_2(struct context *c)
+{
+ int i;
+ for (i = 0; i < c->c1.link_sockets_num; i++)
+ {
+ link_socket_init_phase2(c, c->c2.link_sockets[i]);
+ }
+}
+
+/*
* Print MTU INFO
*/
static void
@@ -3907,15 +4019,20 @@
/* in dco-win case, link socket is a tun handle which is
* 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)
+ if (tuntap_is_dco_win(c->c1.tuntap) && c->c2.link_sockets && c->c2.link_sockets[0])
{
- c->c2.link_socket->sd = SOCKET_UNDEFINED;
+ c->c2.link_sockets[0]->sd = SOCKET_UNDEFINED;
}
- if (c->c2.link_socket && c->c2.link_socket_owned)
+ if (c->c2.link_sockets && c->c2.link_socket_owned)
{
- link_socket_close(c->c2.link_socket);
- c->c2.link_socket = NULL;
+ int i;
+
+ for (i = 0; i < c->c1.link_sockets_num; i++)
+ {
+ link_socket_close(c->c2.link_sockets[i]);
+ }
+ c->c2.link_sockets = NULL;
}
@@ -3926,28 +4043,33 @@
&& ( (c->options.persist_remote_ip)
||
( c->sig->source != SIG_SOURCE_HARD
- && ((c->c1.link_socket_addr.current_remote
- && c->c1.link_socket_addr.current_remote->ai_next)
+ && ((c->c1.link_socket_addrs[0].current_remote
+ && c->c1.link_socket_addrs[0].current_remote->ai_next)
|| c->options.no_advance))
)))
{
- clear_remote_addrlist(&c->c1.link_socket_addr, !c->options.resolve_in_advance);
+ clear_remote_addrlist(&c->c1.link_socket_addrs[0],
+ !c->options.resolve_in_advance);
}
/* Clear the remote actual address when persist_remote_ip is not in use */
if (!(c->sig->signal_received == SIGUSR1 && c->options.persist_remote_ip))
{
- CLEAR(c->c1.link_socket_addr.actual);
+ CLEAR(c->c1.link_socket_addrs[0].actual);
}
- if (!(c->sig->signal_received == SIGUSR1 && c->options.persist_local_ip))
+ for (int i = 0; i < c->c1.link_sockets_num; i++)
{
- if (c->c1.link_socket_addr.bind_local && !c->options.resolve_in_advance)
+ if (!(c->sig->signal_received == SIGUSR1 && c->options.persist_local_ip))
{
- freeaddrinfo(c->c1.link_socket_addr.bind_local);
- }
+ if (c->c1.link_socket_addrs[i].bind_local
+ && !c->options.resolve_in_advance)
+ {
+ freeaddrinfo(c->c1.link_socket_addrs[i].bind_local);
+ }
- c->c1.link_socket_addr.bind_local = NULL;
+ c->c1.link_socket_addrs[i].bind_local = NULL;
+ }
}
}
@@ -4430,7 +4552,6 @@
{
const struct options *options = &c->options;
const bool child = (c->mode == CM_CHILD_TCP || c->mode == CM_CHILD_UDP);
- int link_socket_mode = LS_MODE_DEFAULT;
/* init garbage collection level */
gc_init(&c->c2.gc);
@@ -4471,21 +4592,6 @@
/* map in current connection entry */
next_connection_entry(c);
- /* link_socket_mode allows CM_CHILD_TCP
- * instances to inherit acceptable fds
- * from a top-level parent */
- if (c->options.ce.proto == PROTO_TCP_SERVER)
- {
- if (c->mode == CM_TOP)
- {
- link_socket_mode = LS_MODE_TCP_LISTEN;
- }
- else if (c->mode == CM_CHILD_TCP)
- {
- link_socket_mode = LS_MODE_TCP_ACCEPT_FROM;
- }
- }
-
/* should we disable paging? */
if (c->first_time && options->mlock)
{
@@ -4628,7 +4734,7 @@
/* bind the TCP/UDP socket */
if (c->mode == CM_P2P || c->mode == CM_TOP || c->mode == CM_CHILD_TCP)
{
- link_socket_init_phase1(c, link_socket_mode);
+ do_init_socket_1(c);
}
/* initialize tun/tap device object,
@@ -4671,7 +4777,7 @@
/* finalize the TCP/UDP socket */
if (c->mode == CM_P2P || c->mode == CM_TOP || c->mode == CM_CHILD_TCP)
{
- link_socket_init_phase2(c);
+ do_init_socket_2(c);
/* Update dynamic frame calculation as exact transport socket information
@@ -4807,7 +4913,8 @@
void
inherit_context_child(struct context *dest,
- const struct context *src)
+ const struct context *src,
+ struct link_socket *ls)
{
CLEAR(*dest);
@@ -4820,6 +4927,8 @@
/* c1 init */
packet_id_persist_init(&dest->c1.pid_persist);
+ dest->c1.link_sockets_num = 1;
+ do_link_socket_addr_new(dest);
dest->c1.ks.key_type = src->c1.ks.key_type;
/* inherit SSL context */
@@ -4844,7 +4953,7 @@
* The CM_TOP context does the socket listen(),
* and the CM_CHILD_TCP context does the accept().
*/
- dest->c2.accept_from = src->c2.link_socket;
+ dest->c2.accept_from = ls;
}
#ifdef ENABLE_PLUGIN
@@ -4868,18 +4977,26 @@
/* UDP inherits some extra things which TCP does not */
if (dest->mode == CM_CHILD_UDP)
{
+ ASSERT(!dest->c2.link_sockets);
+
/* inherit buffers */
dest->c2.buffers = src->c2.buffers;
- /* inherit parent link_socket and tuntap */
- dest->c2.link_socket = src->c2.link_socket;
+ ALLOC_ARRAY_GC(dest->c2.link_sockets, struct link_socket *, 1,
+ &dest->gc);
- ALLOC_OBJ_GC(dest->c2.link_socket_info, struct link_socket_info, &dest->gc);
- *dest->c2.link_socket_info = src->c2.link_socket->info;
+ /* inherit parent link_socket and tuntap */
+ dest->c2.link_sockets[0] = ls;
+
+ ALLOC_ARRAY_GC(dest->c2.link_socket_infos, struct link_socket_info *, 1,
+ &dest->gc);
+ ALLOC_OBJ_GC(dest->c2.link_socket_infos[0], struct link_socket_info,
+ &dest->gc);
+ *dest->c2.link_socket_infos[0] = ls->info;
/* locally override some link_socket_info fields */
- dest->c2.link_socket_info->lsa = &dest->c1.link_socket_addr;
- dest->c2.link_socket_info->connection_established = false;
+ dest->c2.link_socket_infos[0]->lsa = &dest->c1.link_socket_addrs[0];
+ dest->c2.link_socket_infos[0]->connection_established = false;
}
}
@@ -95,7 +95,8 @@
bool do_deferred_options(struct context *c, const unsigned int found);
void inherit_context_child(struct context *dest,
- const struct context *src);
+ const struct context *src,
+ struct link_socket *ls);
void inherit_context_top(struct context *dest,
const struct context *src);
@@ -357,7 +357,7 @@
struct link_socket_info *lsi = get_link_socket_info(c);
struct options *o = &c->options;
- int pmtu = c->c2.link_socket->mtu;
+ int pmtu = c->c2.link_sockets[0]->mtu;
sa_family_t af = lsi->lsa->actual.dest.addr.sa.sa_family;
int proto = lsi->proto;
@@ -115,13 +115,13 @@
#endif /* ENABLE_DEBUG */
static struct multi_instance *
-multi_create_instance_tcp(struct multi_context *m)
+multi_create_instance_tcp(struct multi_context *m, struct link_socket *ls)
{
struct gc_arena gc = gc_new();
struct multi_instance *mi = NULL;
struct hash *hash = m->hash;
- mi = multi_create_instance(m, NULL);
+ mi = multi_create_instance(m, NULL, ls);
if (mi)
{
struct hash_element *he;
@@ -171,13 +171,16 @@
/* buffer for queued TCP socket output packets */
mi->tcp_link_out_deferred = mbuf_init(m->top.options.n_bcast_buf);
- ASSERT(mi->context.c2.link_socket);
- ASSERT(mi->context.c2.link_socket->info.lsa);
- ASSERT(mi->context.c2.link_socket->mode == LS_MODE_TCP_ACCEPT_FROM);
- ASSERT(mi->context.c2.link_socket->info.lsa->actual.dest.addr.sa.sa_family == AF_INET
- || mi->context.c2.link_socket->info.lsa->actual.dest.addr.sa.sa_family == AF_INET6
+ ASSERT(mi->context.c2.link_sockets);
+ ASSERT(mi->context.c2.link_sockets[0]);
+ ASSERT(mi->context.c2.link_sockets[0]->info.lsa);
+ ASSERT(mi->context.c2.link_sockets[0]->mode == LS_MODE_TCP_ACCEPT_FROM);
+ ASSERT(mi->context.c2.link_sockets[0]->info.lsa->actual.dest.addr.sa.sa_family == AF_INET
+ || mi->context.c2.link_sockets[0]->info.lsa->actual.dest.addr.sa.sa_family == AF_INET6
);
- if (!mroute_extract_openvpn_sockaddr(&mi->real, &mi->context.c2.link_socket->info.lsa->actual.dest, true))
+ if (!mroute_extract_openvpn_sockaddr(&mi->real,
+ &mi->context.c2.link_sockets[0]->info.lsa->actual.dest,
+ true))
{
msg(D_MULTI_ERRORS, "MULTI TCP: TCP client address is undefined");
return false;
@@ -233,7 +236,7 @@
void
multi_tcp_dereference_instance(struct multi_tcp *mtcp, struct multi_instance *mi)
{
- struct link_socket *ls = mi->context.c2.link_socket;
+ struct link_socket *ls = mi->context.c2.link_sockets[0];
if (ls && mi->socket_set_called)
{
event_del(mtcp->es, socket_event_handle(ls));
@@ -248,7 +251,7 @@
if (mi)
{
mi->socket_set_called = true;
- socket_set(mi->context.c2.link_socket,
+ socket_set(mi->context.c2.link_sockets[0],
m->mtcp->es,
mbuf_defined(mi->tcp_link_out_deferred) ? EVENT_WRITE : EVENT_READ,
&mi->ev_arg,
@@ -260,10 +263,14 @@
multi_tcp_wait(const struct context *c,
struct multi_tcp *mtcp)
{
- int status;
+ int i, status;
unsigned int *persistent = &mtcp->tun_rwflags;
- socket_set_listen_persistent(c->c2.link_socket, mtcp->es,
- &c->c2.link_socket->ev_arg);
+
+ for (i = 0; i < c->c1.link_sockets_num; i++)
+ {
+ socket_set_listen_persistent(c->c2.link_sockets[i], mtcp->es,
+ &c->c2.link_sockets[i]->ev_arg);
+ }
#ifdef _WIN32
if (tuntap_is_wintun(c->c1.tuntap))
@@ -481,16 +488,18 @@
case TA_SOCKET_READ:
case TA_SOCKET_READ_RESIDUAL:
ASSERT(mi);
- ASSERT(mi->context.c2.link_socket);
+ ASSERT(mi->context.c2.link_sockets);
+ ASSERT(mi->context.c2.link_sockets[0]);
set_prefix(mi);
- read_incoming_link(&mi->context, mi->context.c2.link_socket);
+ read_incoming_link(&mi->context, mi->context.c2.link_sockets[0]);
clear_prefix();
if (!IS_SIG(&mi->context))
{
- multi_process_incoming_link(m, mi, mpp_flags);
+ multi_process_incoming_link(m, mi, mpp_flags,
+ mi->context.c2.link_sockets[0]);
if (!IS_SIG(&mi->context))
{
- stream_buf_read_setup(mi->context.c2.link_socket);
+ stream_buf_read_setup(mi->context.c2.link_sockets[0]);
}
}
break;
@@ -566,7 +575,7 @@
break;
case MTP_NONE:
- if (mi && socket_read_residual(c->c2.link_socket))
+ if (mi && sockets_read_residual(c))
{
newaction = TA_SOCKET_READ_RESIDUAL;
}
@@ -721,9 +730,14 @@
/* new incoming TCP client attempting to connect? */
case EVENT_ARG_LINK_SOCKET:
- ASSERT(m->top.c2.link_socket);
- socket_reset_listen_persistent(m->top.c2.link_socket);
- mi = multi_create_instance_tcp(m);
+ if (!ev_arg->u.ls)
+ {
+ msg(D_MULTI_ERRORS, "MULTI: mtcp_proc_io: null socket");
+ break;
+ }
+
+ socket_reset_listen_persistent(ev_arg->u.ls);
+ mi = multi_create_instance_tcp(m, ev_arg->u.ls);
if (mi)
{
multi_tcp_action(m, mi, TA_INITIAL, false);
@@ -757,9 +771,9 @@
else if (e->arg == MTCP_SOCKET)
{
struct multi_instance *mi;
- ASSERT(m->top.c2.link_socket);
- socket_reset_listen_persistent(m->top.c2.link_socket);
- mi = multi_create_instance_tcp(m);
+ ASSERT(m->top.c2.link_sockets[0]);
+ socket_reset_listen_persistent(m->top.c2.link_sockets[0]);
+ mi = multi_create_instance_tcp(m, m->top.c2.link_sockets[0]);
if (mi)
{
multi_tcp_action(m, mi, TA_INITIAL, false);
@@ -185,7 +185,8 @@
*/
struct multi_instance *
-multi_get_create_instance_udp(struct multi_context *m, bool *floated)
+multi_get_create_instance_udp(struct multi_context *m, bool *floated,
+ struct link_socket *ls)
{
struct gc_arena gc = gc_new();
struct mroute_addr real;
@@ -256,7 +257,7 @@
* connect-freq but not against connect-freq-initial */
reflect_filter_rate_limit_decrease(m->initial_rate_limiter);
- mi = multi_create_instance(m, &real);
+ mi = multi_create_instance(m, &real, ls);
if (mi)
{
hash_add_fast(hash, bucket, &mi->real, hv, mi);
@@ -317,7 +318,7 @@
msg_set_prefix("Connection Attempt");
m->top.c2.to_link = m->hmac_reply;
m->top.c2.to_link_addr = m->hmac_reply_dest;
- process_outgoing_link(&m->top, &m->top.c2.link_socket[0]);
+ process_outgoing_link(&m->top, m->top.c2.link_sockets[0]);
m->hmac_reply_dest = NULL;
}
}
@@ -380,10 +381,20 @@
/* Incoming data on UDP port */
else if (status & SOCKET_READ)
{
- read_incoming_link(&m->top, m->top.c2.link_socket);
- if (!IS_SIG(&m->top))
+ int i;
+ for (i = 0; i < m->top.c1.link_sockets_num; i++)
{
- multi_process_incoming_link(m, NULL, mpp_flags);
+ if (!m->top.c2.link_sockets[i]->ev_arg.pending)
+ {
+ continue;
+ }
+
+ read_incoming_link(&m->top, m->top.c2.link_sockets[i]);
+ if (!IS_SIG(&m->top))
+ {
+ multi_process_incoming_link(m, NULL, mpp_flags,
+ m->top.c2.link_sockets[i]);
+ }
}
}
/* Incoming data on TUN device */
@@ -55,12 +55,14 @@
* it. If no entry exists, this function handles its creation, and if
* successful, returns the newly created instance.
*
- * @param m - The single multi_context structure.
+ * @param m - The single multi_context structure.
+ * @param ls - Listening socket where this instance is connecting to
*
* @return A pointer to a multi_instance if one already existed for the
* packet's source address or if one was a newly created successfully.
* NULL if one did not yet exist and a new one was not created.
*/
-struct multi_instance *multi_get_create_instance_udp(struct multi_context *m, bool *floated);
+struct multi_instance *multi_get_create_instance_udp(struct multi_context *m, bool *floated,
+ struct link_socket *ls);
#endif /* ifndef MUDP_H */
@@ -682,7 +682,10 @@
multi_client_disconnect_script(m, mi);
}
- close_context(&mi->context, SIGTERM, CC_GC_FREE);
+ if (mi->did_open_context)
+ {
+ close_context(&mi->context, SIGTERM, CC_GC_FREE);
+ }
multi_tcp_instance_specific_free(mi);
@@ -750,7 +753,8 @@
* Create a client instance object for a newly connected client.
*/
struct multi_instance *
-multi_create_instance(struct multi_context *m, const struct mroute_addr *real)
+multi_create_instance(struct multi_context *m, const struct mroute_addr *real,
+ struct link_socket *ls)
{
struct gc_arena gc = gc_new();
struct multi_instance *mi;
@@ -773,7 +777,8 @@
generate_prefix(mi);
}
- inherit_context_child(&mi->context, &m->top);
+ mi->did_open_context = true;
+ inherit_context_child(&mi->context, &m->top, ls);
if (IS_SIG(&mi->context))
{
goto err;
@@ -3128,7 +3133,8 @@
}
void
-multi_process_float(struct multi_context *m, struct multi_instance *mi)
+multi_process_float(struct multi_context *m, struct multi_instance *mi,
+ struct link_socket *ls)
{
struct mroute_addr real;
struct hash *hash = m->hash;
@@ -3184,8 +3190,8 @@
mi->context.c2.to_link_addr = &mi->context.c2.from;
/* inherit parent link_socket and link_socket_info */
- mi->context.c2.link_socket = m->top.c2.link_socket;
- mi->context.c2.link_socket_info->lsa->actual = m->top.c2.from;
+ mi->context.c2.link_sockets[0] = ls;
+ mi->context.c2.link_socket_infos[0]->lsa->actual = m->top.c2.from;
tls_update_remote_addr(mi->context.c2.tls_multi, &mi->context.c2.from);
@@ -3333,7 +3339,8 @@
* i.e. client -> server direction.
*/
bool
-multi_process_incoming_link(struct multi_context *m, struct multi_instance *instance, const unsigned int mpp_flags)
+multi_process_incoming_link(struct multi_context *m, struct multi_instance *instance, const unsigned int mpp_flags,
+ struct link_socket *ls)
{
struct gc_arena gc = gc_new();
@@ -3354,7 +3361,7 @@
#ifdef MULTI_DEBUG_EVENT_LOOP
printf("TCP/UDP -> TUN [%d]\n", BLEN(&m->top.c2.buf));
#endif
- multi_set_pending(m, multi_get_create_instance_udp(m, &floated));
+ multi_set_pending(m, multi_get_create_instance_udp(m, &floated, ls));
}
else
{
@@ -3395,7 +3402,7 @@
/* nonzero length means that we have a valid, decrypted packed */
if (floated && c->c2.buf.len > 0)
{
- multi_process_float(m, m->pending);
+ multi_process_float(m, m->pending, ls);
}
process_incoming_link_part2(c, lsi, orig_buf);
@@ -3614,7 +3621,7 @@
}
/* encrypt in instance context */
- process_incoming_tun(c);
+ process_incoming_tun(c, c->c2.link_sockets[0]);
/* postprocess and set wakeup */
ret = multi_process_post(m, m->pending, mpp_flags);
@@ -3646,7 +3653,8 @@
{
pip_flags |= PIP_MSSFIX;
}
- process_ip_header(&item.instance->context, pip_flags, &item.instance->context.c2.buf);
+ process_ip_header(&item.instance->context, pip_flags, &item.instance->context.c2.buf,
+ item.instance->context.c2.link_sockets[0]);
encrypt_sign(&item.instance->context, true);
mbuf_free_buf(item.buffer);
@@ -125,6 +125,7 @@
in_addr_t reporting_addr; /* IP address shown in status listing */
struct in6_addr reporting_addr_ipv6; /* IPv6 address in status listing */
+ bool did_open_context;
bool did_real_hash;
bool did_iter;
#ifdef ENABLE_MANAGEMENT
@@ -269,7 +270,8 @@
void multi_top_free(struct multi_context *m);
-struct multi_instance *multi_create_instance(struct multi_context *m, const struct mroute_addr *real);
+struct multi_instance *multi_create_instance(struct multi_context *m, const struct mroute_addr *real,
+ struct link_socket *ls);
void multi_close_instance(struct multi_context *m, struct multi_instance *mi, bool shutdown);
@@ -283,7 +285,8 @@
* existing peer. Updates multi_instance with new address,
* updates hashtables in multi_context.
*/
-void multi_process_float(struct multi_context *m, struct multi_instance *mi);
+void multi_process_float(struct multi_context *m, struct multi_instance *mi,
+ struct link_socket *ls);
#define MPP_PRE_SELECT (1<<0)
#define MPP_CONDITIONAL_PRE_SELECT (1<<1)
@@ -348,8 +351,10 @@
* when using TCP transport. Otherwise NULL, as is
* the case when using UDP transport.
* @param mpp_flags - Fast I/O optimization flags.
+ * @param ls - Socket where the packet was received.
*/
-bool multi_process_incoming_link(struct multi_context *m, struct multi_instance *instance, const unsigned int mpp_flags);
+bool multi_process_incoming_link(struct multi_context *m, struct multi_instance *instance, const unsigned int mpp_flags,
+ struct link_socket *ls);
/**
@@ -663,7 +668,7 @@
#endif
set_prefix(mi);
vlan_process_outgoing_tun(m, mi);
- process_outgoing_tun(&mi->context);
+ process_outgoing_tun(&mi->context, mi->context.c2.link_sockets[0]);
ret = multi_process_post(m, mi, mpp_flags);
clear_prefix();
return ret;
@@ -678,7 +683,7 @@
{
bool ret = true;
set_prefix(mi);
- process_outgoing_link(&mi->context, mi->context.c2.link_socket);
+ process_outgoing_link(&mi->context, mi->context.c2.link_sockets[0]);
ret = multi_process_post(m, mi, mpp_flags);
clear_prefix();
return ret;
@@ -89,7 +89,7 @@
}
/* process the I/O which triggered select */
- process_io(c, c->c2.link_socket);
+ process_io(c, c->c2.link_sockets[0]);
P2P_CHECK_SIG();
perf_pop();
@@ -154,7 +154,8 @@
*/
struct context_1
{
- struct link_socket_addr link_socket_addr;
+ int link_sockets_num;
+ struct link_socket_addr *link_socket_addrs;
/**< Local and remote addresses on the
* external network. */
@@ -237,11 +238,11 @@
/* bitmask for event status. Check event.h for possible values */
unsigned int event_set_status;
- struct link_socket *link_socket; /* socket used for TCP/UDP connection to remote */
+ struct link_socket **link_sockets;
+ struct link_socket_info **link_socket_infos;
+
bool link_socket_owned;
- /** This variable is used instead link_socket->info for P2MP UDP childs */
- struct link_socket_info *link_socket_info;
const struct link_socket *accept_from; /* possibly do accept() on a parent link_socket */
struct link_socket_actual *to_link_addr; /* IP address of remote */
@@ -104,7 +104,7 @@
LONG Major;
LONG Minor;
LONG Patch;
-} OVPN_VERSION, * POVPN_VERSION;
+} OVPN_VERSION, *POVPN_VERSION;
#define OVPN_IOCTL_NEW_PEER CTL_CODE(FILE_DEVICE_UNKNOWN, 1, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define OVPN_IOCTL_GET_STATS CTL_CODE(FILE_DEVICE_UNKNOWN, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)
@@ -63,7 +63,7 @@
&& event_timeout_trigger(&c->c2.ping_rec_interval,
&c->c2.timeval,
(!c->options.ping_timer_remote
- || link_socket_actual_defined(&c->c1.link_socket_addr.actual))
+ || link_socket_actual_defined(&c->c1.link_socket_addrs[0].actual))
? ETT_DEFAULT : 15))
{
trigger_ping_timeout_signal(c);
@@ -42,6 +42,21 @@
#include "memdbg.h"
+bool
+sockets_read_residual(const struct context *c)
+{
+ int i;
+
+ for (i = 0; i < c->c1.link_sockets_num; i++)
+ {
+ if (c->c2.link_sockets[i]->stream_buf.residual_fully_formed)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
/*
* Convert sockflags/getaddr_flags into getaddr_flags
*/
@@ -999,7 +1014,6 @@
create_socket_tcp(struct addrinfo *addrinfo)
{
socket_descriptor_t sd;
-
ASSERT(addrinfo);
ASSERT(addrinfo->ai_socktype == SOCK_STREAM);
@@ -1031,7 +1045,6 @@
create_socket_udp(struct addrinfo *addrinfo, const unsigned int flags)
{
socket_descriptor_t sd;
-
ASSERT(addrinfo);
ASSERT(addrinfo->ai_socktype == SOCK_DGRAM);
@@ -1441,7 +1454,6 @@
#ifdef TARGET_ANDROID
protect_fd_nonlocal(sd, remote);
#endif
-
set_nonblock(sd);
status = connect(sd, remote, af_addr_size(remote->sa_family));
if (status)
@@ -1834,60 +1846,75 @@
}
void
-link_socket_init_phase1(struct context *c, int mode)
+link_socket_init_phase1(struct link_socket *sock,
+ const char *local_host,
+ const char *local_port,
+ const char *remote_host,
+ const char *remote_port,
+ struct cached_dns_entry *dns_cache,
+ int proto,
+ sa_family_t af,
+ bool bind_ipv6_only,
+ int mode,
+ const struct link_socket *accept_from,
+ struct http_proxy_info *http_proxy,
+ struct socks_proxy_info *socks_proxy,
+#ifdef ENABLE_DEBUG
+ int gremlin,
+#endif
+ bool bind_local,
+ bool remote_float,
+ struct link_socket_addr *lsa,
+ const char *ipchange_command,
+ const struct plugin_list *plugins,
+ int resolve_retry_seconds,
+ int mtu_discover_type,
+ int rcvbuf,
+ int sndbuf,
+ int mark,
+ struct event_timeout *server_poll_timeout,
+ unsigned int sockflags)
{
- struct link_socket *sock = c->c2.link_socket;
- struct options *o = &c->options;
ASSERT(sock);
- const char *remote_host = o->ce.remote;
- const char *remote_port = o->ce.remote_port;
-
- sock->local_host = o->ce.local;
- sock->local_port = o->ce.local_port;
+ sock->local_host = local_host;
+ sock->local_port = local_port;
sock->remote_host = remote_host;
sock->remote_port = remote_port;
- sock->dns_cache = c->c1.dns_cache;
- sock->http_proxy = c->c1.http_proxy;
- sock->socks_proxy = c->c1.socks_proxy;
- sock->bind_local = o->ce.bind_local;
- sock->resolve_retry_seconds = o->resolve_retry_seconds;
- sock->mtu_discover_type = o->ce.mtu_discover_type;
+ sock->dns_cache = dns_cache;
+ sock->http_proxy = http_proxy;
+ sock->socks_proxy = socks_proxy;
+ sock->bind_local = bind_local;
+ sock->resolve_retry_seconds = resolve_retry_seconds;
+ sock->mtu_discover_type = mtu_discover_type;
#ifdef ENABLE_DEBUG
- sock->gremlin = o->gremlin;
+ sock->gremlin = gremlin;
#endif
- sock->socket_buffer_sizes.rcvbuf = o->rcvbuf;
- sock->socket_buffer_sizes.sndbuf = o->sndbuf;
+ sock->socket_buffer_sizes.rcvbuf = rcvbuf;
+ sock->socket_buffer_sizes.sndbuf = sndbuf;
- sock->sockflags = o->sockflags;
-#if PORT_SHARE
- if (o->port_share_host && o->port_share_port)
- {
- sock->sockflags |= SF_PORT_SHARE;
- }
-#endif
- sock->mark = o->mark;
- sock->bind_dev = o->bind_dev;
+ sock->sockflags = sockflags;
+ sock->mark = mark;
- sock->info.proto = o->ce.proto;
- sock->info.af = o->ce.af;
- sock->info.remote_float = o->ce.remote_float;
- sock->info.lsa = &c->c1.link_socket_addr;
- sock->info.bind_ipv6_only = o->ce.bind_ipv6_only;
- sock->info.ipchange_command = o->ipchange;
- sock->info.plugins = c->plugins;
- sock->server_poll_timeout = &c->c2.server_poll_interval;
+ sock->info.proto = proto;
+ sock->info.af = af;
+ sock->info.remote_float = remote_float;
+ sock->info.lsa = lsa;
+ sock->info.bind_ipv6_only = bind_ipv6_only;
+ sock->info.ipchange_command = ipchange_command;
+ sock->info.plugins = plugins;
+ sock->server_poll_timeout = server_poll_timeout;
sock->mode = mode;
if (mode == LS_MODE_TCP_ACCEPT_FROM)
{
- ASSERT(c->c2.accept_from);
+ ASSERT(accept_from);
ASSERT(sock->info.proto == PROTO_TCP_SERVER);
- sock->sd = c->c2.accept_from->sd;
+ sock->sd = accept_from->sd;
/* inherit (possibly guessed) info AF from parent context */
- sock->info.af = c->c2.accept_from->info.af;
+ sock->info.af = accept_from->info.af;
}
/* are we running in HTTP proxy mode? */
@@ -1896,8 +1923,8 @@
ASSERT(sock->info.proto == PROTO_TCP_CLIENT);
/* the proxy server */
- sock->remote_host = c->c1.http_proxy->options.server;
- sock->remote_port = c->c1.http_proxy->options.port;
+ sock->remote_host = http_proxy->options.server;
+ sock->remote_port = http_proxy->options.port;
/* the OpenVPN server we will use the proxy to connect to */
sock->proxy_dest_host = remote_host;
@@ -1906,9 +1933,10 @@
/* or in Socks proxy mode? */
else if (sock->socks_proxy)
{
+
/* the proxy server */
- sock->remote_host = c->c1.socks_proxy->server;
- sock->remote_port = c->c1.socks_proxy->port;
+ sock->remote_host = socks_proxy->server;
+ sock->remote_port = socks_proxy->port;
/* the OpenVPN server we will use the proxy to connect to */
sock->proxy_dest_host = remote_host;
@@ -2166,22 +2194,21 @@
/* finalize socket initialization */
void
-link_socket_init_phase2(struct context *c)
+link_socket_init_phase2(struct context *c,
+ struct link_socket *sock)
{
- struct link_socket *sock = c->c2.link_socket;
const struct frame *frame = &c->c2.frame;
struct signal_info *sig_info = c->sig;
-
const char *remote_dynamic = NULL;
- struct signal_info sig_save = {0};
+ int sig_save = 0;
ASSERT(sock);
ASSERT(sig_info);
if (sig_info->signal_received)
{
- sig_save = *sig_info;
- sig_save.signal_received = signal_reset(sig_info, 0);
+ sig_save = sig_info->signal_received;
+ sig_info->signal_received = 0;
}
/* initialize buffers */
@@ -2203,7 +2230,7 @@
/* If a valid remote has been found, create the socket with its addrinfo */
if (sock->info.lsa->current_remote)
{
-#if defined(_WIN32)
+#if defined (_WIN32)
if (dco_enabled(&c->options))
{
create_socket_dco_win(c, sock, sig_info);
@@ -2214,7 +2241,6 @@
{
create_socket(sock, sock->info.lsa->current_remote);
}
-
}
/* If socket has not already been created create it now */
@@ -2233,7 +2259,6 @@
addr_family_name(sock->info.lsa->bind_local->ai_family));
sock->info.af = sock->info.lsa->bind_local->ai_family;
}
-
create_socket(sock, sock->info.lsa->bind_local);
}
}
@@ -2242,7 +2267,7 @@
if (sock->sd == SOCKET_UNDEFINED)
{
msg(M_WARN, "Could not determine IPv4/IPv6 protocol");
- register_signal(sig_info, SIGUSR1, "Could not determine IPv4/IPv6 protocol");
+ sig_info->signal_received = SIGUSR1;
goto done;
}
@@ -2253,7 +2278,8 @@
if (sock->info.proto == PROTO_TCP_SERVER)
{
- phase2_tcp_server(sock, remote_dynamic, sig_info);
+ phase2_tcp_server(sock, remote_dynamic,
+ sig_info);
}
else if (sock->info.proto == PROTO_TCP_CLIENT)
{
@@ -2279,16 +2305,11 @@
linksock_print_addr(sock);
done:
- if (sig_save.signal_received)
+ if (sig_save)
{
- /* Always restore the saved signal -- register/throw_signal will handle priority */
- if (sig_save.source == SIG_SOURCE_HARD && sig_info == &siginfo_static)
+ if (!sig_info->signal_received)
{
- throw_signal(sig_save.signal_received);
- }
- else
- {
- register_signal(sig_info, sig_save.signal_received, sig_save.signal_text);
+ sig_info->signal_received = sig_save;
}
}
}
@@ -329,9 +329,38 @@
/*
* Initialize link_socket object.
*/
-void link_socket_init_phase1(struct context *c, int mode);
+void
+link_socket_init_phase1(struct link_socket *sock,
+ const char *local_host,
+ const char *local_port,
+ const char *remote_host,
+ const char *remote_port,
+ struct cached_dns_entry *dns_cache,
+ int proto,
+ sa_family_t af,
+ bool bind_ipv6_only,
+ int mode,
+ const struct link_socket *accept_from,
+ struct http_proxy_info *http_proxy,
+ struct socks_proxy_info *socks_proxy,
+#ifdef ENABLE_DEBUG
+ int gremlin,
+#endif
+ bool bind_local,
+ bool remote_float,
+ struct link_socket_addr *lsa,
+ const char *ipchange_command,
+ const struct plugin_list *plugins,
+ int resolve_retry_seconds,
+ int mtu_discover_type,
+ int rcvbuf,
+ int sndbuf,
+ int mark,
+ struct event_timeout *server_poll_timeout,
+ unsigned int sockflags);
-void link_socket_init_phase2(struct context *c);
+void link_socket_init_phase2(struct context *c,
+ struct link_socket *sock);
void do_preresolve(struct context *c);
@@ -1239,11 +1268,7 @@
* Socket I/O wait functions
*/
-static inline bool
-socket_read_residual(const struct link_socket *s)
-{
- return s && s->stream_buf.residual_fully_formed;
-}
+bool sockets_read_residual(const struct context *c);
static inline event_t
socket_event_handle(const struct link_socket *s)
Attention is currently required from: flichtenheld, plaisthos. Hello plaisthos, flichtenheld, I'd like you to do a code review. Please visit http://gerrit.openvpn.net/c/openvpn/+/434?usp=email to review the following change. Change subject: allow tcp/udp server to listen on multiple ports at the same time ...................................................................... allow tcp/udp server to listen on multiple ports at the same time Change-Id: Ia0a889e800f0b36aed770ee36e31afeec5df6084 Signed-off-by: Antonio Quartulli <a@unstable.cc> --- M src/openvpn/dco.c M src/openvpn/event.h M src/openvpn/forward.c M src/openvpn/forward.h M src/openvpn/init.c M src/openvpn/init.h M src/openvpn/mss.c M src/openvpn/mtcp.c M src/openvpn/mudp.c M src/openvpn/mudp.h M src/openvpn/multi.c M src/openvpn/multi.h M src/openvpn/openvpn.c M src/openvpn/openvpn.h M src/openvpn/ovpn_dco_win.h M src/openvpn/ping.h M src/openvpn/socket.c M src/openvpn/socket.h 18 files changed, 458 insertions(+), 231 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/34/434/1