Skip to content

Commit 7ad457c

Browse files
author
Jon Chiappetta
committed
dual mode
1 parent 00670e5 commit 7ad457c

24 files changed

+740
-309
lines changed

src/openvpn/forward.c

Lines changed: 64 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ check_incoming_control_channel(struct context *c)
292292

293293
struct gc_arena gc = gc_new();
294294
struct buffer buf = alloc_buf_gc(len, &gc);
295-
if (tls_rec_payload(c->c2.tls_multi, &buf))
295+
while (tls_rec_payload(c->c2.tls_multi, &buf))
296296
{
297297
while (BLEN(&buf) > 1)
298298
{
@@ -304,10 +304,6 @@ check_incoming_control_channel(struct context *c)
304304
}
305305
}
306306
}
307-
else
308-
{
309-
msg(D_PUSH_ERRORS, "WARNING: Receive control message failed");
310-
}
311307

312308
gc_free(&gc);
313309
}
@@ -376,14 +372,13 @@ check_connection_established(struct context *c)
376372
#endif
377373

378374
bool
379-
send_control_channel_string_dowork(struct tls_session *session, const char *str,
375+
send_control_channel_string_dowork(struct tls_session *session, struct key_state *ks, const char *str,
380376
msglvl_t msglevel)
381377
{
382378
struct gc_arena gc = gc_new();
383379
bool stat;
384380

385381
ASSERT(session);
386-
struct key_state *ks = &session->key[KS_PRIMARY];
387382

388383
/* buffered cleartext write onto TLS control channel */
389384
stat = tls_send_payload(ks, (uint8_t *)str, strlen(str) + 1);
@@ -409,9 +404,9 @@ send_control_channel_string(struct context *c, const char *str, msglvl_t msgleve
409404
if (c->c2.tls_multi)
410405
{
411406
struct tls_session *session = &c->c2.tls_multi->session[TM_ACTIVE];
412-
bool ret = send_control_channel_string_dowork(session, str, msglevel);
407+
struct key_state *ks = &session->key[KS_PRIMARY];
408+
bool ret = send_control_channel_string_dowork(session, ks, str, msglevel);
413409
reschedule_multi_process(c);
414-
415410
return ret;
416411
}
417412
return true;
@@ -2358,11 +2353,13 @@ get_io_flags_udp(struct context *c, struct multi_io *multi_io, const unsigned in
23582353
}
23592354

23602355
void
2361-
io_wait_dowork(struct context *c, const unsigned int flags)
2356+
io_wait_dowork(struct context *c, const unsigned int flags, int z)
23622357
{
23632358
unsigned int out_socket;
23642359
unsigned int out_tuntap;
23652360
struct event_set_return esr[4];
2361+
struct event_set *event_set = ((z & THREAD_RTWL) != 0) ? c->c2.event_set : c->c2.event_set2;
2362+
unsigned int *event_set_status = ((z & THREAD_RTWL) != 0) ? &(c->c2.event_set_status) : &(c->c2.event_set_status2);
23662363

23672364
/* These shifts all depend on EVENT_READ and EVENT_WRITE */
23682365
static uintptr_t socket_shift = SOCKET_SHIFT; /* depends on SOCKET_READ and SOCKET_WRITE */
@@ -2380,29 +2377,29 @@ io_wait_dowork(struct context *c, const unsigned int flags)
23802377
/*
23812378
* Decide what kind of events we want to wait for.
23822379
*/
2383-
event_reset(c->c2.event_set);
2380+
event_reset(event_set);
23842381

2385-
multi_io_process_flags(c, c->c2.event_set, flags, &out_socket, &out_tuntap);
2382+
multi_io_process_flags(c, event_set, flags, &out_socket, &out_tuntap);
23862383

23872384
#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
23882385
if (out_socket & EVENT_READ && c->c2.did_open_tun)
23892386
{
2390-
dco_event_set(&c->c1.tuntap->dco, c->c2.event_set, (void *)dco_shift);
2387+
dco_event_set(&c->c1.tuntap->dco, event_set, (void *)dco_shift);
23912388
}
23922389
#endif
23932390

23942391
#ifdef ENABLE_MANAGEMENT
23952392
if (management)
23962393
{
2397-
management_socket_set(management, c->c2.event_set, (void *)management_shift, NULL);
2394+
management_socket_set(management, event_set, (void *)management_shift, NULL);
23982395
}
23992396
#endif
24002397

24012398
#ifdef ENABLE_ASYNC_PUSH
24022399
/* arm inotify watcher */
24032400
if (c->options.mode == MODE_SERVER)
24042401
{
2405-
event_ctl(c->c2.event_set, c->c2.inotify_fd, EVENT_READ, (void *)file_shift);
2402+
event_ctl(event_set, c->c2.inotify_fd, EVENT_READ, (void *)file_shift);
24062403
}
24072404
#endif
24082405

@@ -2416,7 +2413,7 @@ io_wait_dowork(struct context *c, const unsigned int flags)
24162413
* (6) timeout (tv) expired
24172414
*/
24182415

2419-
c->c2.event_set_status = ES_ERROR;
2416+
*event_set_status = ES_ERROR;
24202417

24212418
if (!c->sig->signal_received)
24222419
{
@@ -2434,14 +2431,14 @@ io_wait_dowork(struct context *c, const unsigned int flags)
24342431
/*
24352432
* Wait for something to happen.
24362433
*/
2437-
status = event_wait(c->c2.event_set, &c->c2.timeval, esr, SIZE(esr));
2434+
status = event_wait(event_set, &c->c2.timeval, esr, SIZE(esr));
24382435

24392436
check_status(status, "event_wait", NULL, NULL);
24402437

24412438
if (status > 0)
24422439
{
24432440
int i;
2444-
c->c2.event_set_status = 0;
2441+
*event_set_status = 0;
24452442
for (i = 0; i < status; ++i)
24462443
{
24472444
const struct event_set_return *e = &esr[i];
@@ -2452,7 +2449,7 @@ io_wait_dowork(struct context *c, const unsigned int flags)
24522449
struct event_arg *ev_arg = (struct event_arg *)e->arg;
24532450
if (ev_arg->type != EVENT_ARG_LINK_SOCKET)
24542451
{
2455-
c->c2.event_set_status = ES_ERROR;
2452+
*event_set_status = ES_ERROR;
24562453
msg(D_LINK_ERRORS, "io_work: non socket event delivered");
24572454
return;
24582455
}
@@ -2464,30 +2461,30 @@ io_wait_dowork(struct context *c, const unsigned int flags)
24642461
shift = (uintptr_t)e->arg;
24652462
}
24662463

2467-
c->c2.event_set_status |= ((e->rwflags & 3) << shift);
2464+
*event_set_status |= ((e->rwflags & 3) << shift);
24682465
}
24692466
}
24702467
else if (status == 0)
24712468
{
2472-
c->c2.event_set_status = ES_TIMEOUT;
2469+
*event_set_status = ES_TIMEOUT;
24732470
}
24742471
}
24752472
else
24762473
{
2477-
c->c2.event_set_status = SOCKET_READ;
2474+
*event_set_status = SOCKET_READ;
24782475
}
24792476
}
24802477

24812478
/* 'now' should always be a reasonably up-to-date timestamp */
24822479
update_time();
24832480

24842481
/* set signal_received if a signal was received */
2485-
if (c->c2.event_set_status & ES_ERROR)
2482+
if (*event_set_status & ES_ERROR)
24862483
{
24872484
get_signal(&c->sig->signal_received);
24882485
}
24892486

2490-
dmsg(D_EVENT_WAIT, "I/O WAIT status=0x%04x", c->c2.event_set_status);
2487+
dmsg(D_EVENT_WAIT, "I/O WAIT status=0x%04x", *event_set_status);
24912488
}
24922489

24932490
void threaded_fwd_inp_intf(struct context *c, struct link_socket *sock, struct thread_pointer *b)
@@ -2507,7 +2504,7 @@ void threaded_fwd_inp_intf(struct context *c, struct link_socket *sock, struct t
25072504
}
25082505

25092506
void
2510-
process_io(struct context *c, struct link_socket *sock, struct thread_pointer *b)
2507+
process_io(struct context *c, struct link_socket *sock, struct thread_pointer *b, int z)
25112508
{
25122509
const unsigned int status = c->c2.event_set_status;
25132510

@@ -2520,17 +2517,17 @@ process_io(struct context *c, struct link_socket *sock, struct thread_pointer *b
25202517
#endif
25212518

25222519
/* TCP/UDP port ready to accept write */
2523-
if (status & SOCKET_WRITE)
2520+
if ((status & SOCKET_WRITE) && ((z & THREAD_RTWL) != 0))
25242521
{
25252522
process_outgoing_link(c, sock);
25262523
}
25272524
/* TUN device ready to accept write */
2528-
else if (status & TUN_WRITE)
2525+
else if ((status & TUN_WRITE) && ((z & THREAD_RLWT) != 0))
25292526
{
25302527
process_outgoing_tun(c, sock);
25312528
}
25322529
/* Incoming data on TCP/UDP port */
2533-
else if (status & SOCKET_READ)
2530+
else if ((status & SOCKET_READ) && ((z & THREAD_RLWT) != 0))
25342531
{
25352532
read_incoming_link(c, sock);
25362533
if (!IS_SIG(c))
@@ -2539,15 +2536,52 @@ process_io(struct context *c, struct link_socket *sock, struct thread_pointer *b
25392536
}
25402537
}
25412538
/* Incoming data on TUN device */
2542-
else if (status & TUN_READ)
2539+
else if ((status & TUN_READ) && ((z & THREAD_RTWL) != 0))
25432540
{
25442541
threaded_fwd_inp_intf(c, sock, b);
25452542
}
2546-
else if (status & DCO_READ)
2543+
else if ((status & DCO_READ) && ((z & THREAD_RTWL) != 0))
25472544
{
25482545
if (!IS_SIG(c))
25492546
{
25502547
process_incoming_dco(c);
25512548
}
25522549
}
25532550
}
2551+
2552+
void threaded_dual_init(struct dual_args *d)
2553+
{
2554+
if ((d->a == 0) && (d->c->c2.buffers))
2555+
{
2556+
if ((d->z & THREAD_RLWT) != 0)
2557+
{
2558+
d->c->c2.buffers->read_link_buf.len = 0;
2559+
d->c->c2.buf2 = d->c->c2.buffers->read_link_buf;
2560+
d->a = 1;
2561+
}
2562+
if ((d->z & THREAD_RTWL) != 0)
2563+
{
2564+
d->c->c2.buffers->read_tun_buf.len = 0;
2565+
d->c->c2.buf = d->c->c2.buffers->read_tun_buf;
2566+
d->a = 1;
2567+
}
2568+
}
2569+
}
2570+
2571+
void *threaded_process_io(void *a)
2572+
{
2573+
struct dual_args *d = (struct dual_args *)a;
2574+
while (true)
2575+
{
2576+
if (d->b->p->z != 1) { break; }
2577+
pthread_mutex_lock(&(d->i));
2578+
if (d->b->p->z != 1) { break; }
2579+
threaded_dual_init(d);
2580+
if (d->a == 1)
2581+
{
2582+
process_io(d->c, d->c->c2.link_sockets[0], d->b, d->z);
2583+
}
2584+
pthread_mutex_unlock(&(d->o));
2585+
}
2586+
return NULL;
2587+
}

src/openvpn/forward.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,15 @@ void get_io_flags_dowork_udp(struct context *c, struct multi_io *multi_io,
7777

7878
void get_io_flags_udp(struct context *c, struct multi_io *multi_io, const unsigned int flags);
7979

80-
void io_wait_dowork(struct context *c, const unsigned int flags);
80+
void io_wait_dowork(struct context *c, const unsigned int flags, int z);
8181

8282
void pre_select(struct context *c);
8383

84-
void process_io(struct context *c, struct link_socket *sock, struct thread_pointer *b);
84+
void process_io(struct context *c, struct link_socket *sock, struct thread_pointer *b, int z);
85+
86+
void *threaded_process_io(void *a);
87+
88+
void threaded_dual_init(struct dual_args *d);
8589

8690

8791
/**********************************************************************/
@@ -309,7 +313,7 @@ bool send_control_channel_string(struct context *c, const char *str, msglvl_t ms
309313
* @param msglevel - Message level to use for logging
310314
*/
311315

312-
bool send_control_channel_string_dowork(struct tls_session *session, const char *str,
316+
bool send_control_channel_string_dowork(struct tls_session *session, struct key_state *ks, const char *str,
313317
msglvl_t msglevel);
314318

315319

@@ -386,7 +390,7 @@ p2p_iow_flags(const struct context *c)
386390
* for the top-level server sockets.
387391
*/
388392
static inline void
389-
io_wait(struct context *c, const unsigned int flags)
393+
io_wait(struct context *c, const unsigned int flags, int z)
390394
{
391395
if (proto_is_dgram(c->c2.link_sockets[0]->info.proto) && c->c2.fast_io
392396
&& (flags & (IOW_TO_TUN | IOW_TO_LINK | IOW_MBUF)))
@@ -406,7 +410,7 @@ io_wait(struct context *c, const unsigned int flags)
406410
else
407411
{
408412
/* slow path */
409-
io_wait_dowork(c, flags);
413+
io_wait_dowork(c, flags, z);
410414
}
411415
}
412416

src/openvpn/init.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2322,14 +2322,23 @@ do_deferred_options_part2(struct context *c)
23222322
#endif
23232323

23242324
struct tls_session *session = &c->c2.tls_multi->session[TM_ACTIVE];
2325-
if (!tls_session_update_crypto_params(c->c2.tls_multi, session, &c->options, &c->c2.frame,
2325+
struct key_state *ks = &session->key[KS_PRIMARY];
2326+
if (!tls_session_update_crypto_params(c->c2.tls_multi, session, ks, &c->options, &c->c2.frame,
23262327
frame_fragment, get_link_socket_info(c),
23272328
&c->c1.tuntap->dco))
23282329
{
23292330
msg(D_TLS_ERRORS, "OPTIONS ERROR: failed to import crypto options");
23302331
return false;
23312332
}
23322333

2334+
session = &c->c2.tls_multi->session[TM_THREADED];
2335+
ks = &session->key[KS_PRIMARY];
2336+
tls_session_update_crypto_params(c->c2.tls_multi, session, ks, &c->options, &c->c2.frame, frame_fragment, get_link_socket_info(c), &c->c1.tuntap->dco);
2337+
2338+
session = &c->c2.tls_multi->session[TM_REKEYS];
2339+
ks = &session->key[KS_PRIMARY];
2340+
tls_session_update_crypto_params(c->c2.tls_multi, session, ks, &c->options, &c->c2.frame, frame_fragment, get_link_socket_info(c), &c->c1.tuntap->dco);
2341+
23332342
return true;
23342343
}
23352344

@@ -2548,6 +2557,7 @@ do_deferred_p2p_ncp(struct context *c)
25482557
c->options.use_peer_id = c->c2.tls_multi->use_peer_id;
25492558

25502559
struct tls_session *session = &c->c2.tls_multi->session[TM_ACTIVE];
2560+
struct key_state *ks = &session->key[KS_PRIMARY];
25512561

25522562
const char *ncp_cipher =
25532563
get_p2p_ncp_cipher(session, c->c2.tls_multi->peer_info, &c->options.gc);
@@ -2572,13 +2582,22 @@ do_deferred_p2p_ncp(struct context *c)
25722582
}
25732583
#endif
25742584

2575-
if (!tls_session_update_crypto_params(c->c2.tls_multi, session, &c->options, &c->c2.frame,
2585+
if (!tls_session_update_crypto_params(c->c2.tls_multi, session, ks, &c->options, &c->c2.frame,
25762586
frame_fragment, get_link_socket_info(c),
25772587
&c->c1.tuntap->dco))
25782588
{
25792589
msg(D_TLS_ERRORS, "ERROR: failed to set crypto cipher");
25802590
return false;
25812591
}
2592+
2593+
session = &c->c2.tls_multi->session[TM_THREADED];
2594+
ks = &session->key[KS_PRIMARY];
2595+
tls_session_update_crypto_params(c->c2.tls_multi, session, ks, &c->options, &c->c2.frame, frame_fragment, get_link_socket_info(c), &c->c1.tuntap->dco);
2596+
2597+
session = &c->c2.tls_multi->session[TM_REKEYS];
2598+
ks = &session->key[KS_PRIMARY];
2599+
tls_session_update_crypto_params(c->c2.tls_multi, session, ks, &c->options, &c->c2.frame, frame_fragment, get_link_socket_info(c), &c->c1.tuntap->dco);
2600+
25822601
return true;
25832602
}
25842603

@@ -3438,6 +3457,8 @@ do_init_crypto_tls(struct context *c, const unsigned int flags)
34383457
/* let the TLS engine know if keys have to be installed in DCO or not */
34393458
to.dco_enabled = dco_enabled(options);
34403459

3460+
to.dual_mode = c->options.ce.dual_mode;
3461+
34413462
/*
34423463
* Initialize OpenVPN's master TLS-mode object.
34433464
*/
@@ -4111,6 +4132,7 @@ do_event_set_init(struct context *c, bool need_us_timeout)
41114132
}
41124133

41134134
c->c2.event_set = event_set_init(&c->c2.event_set_max, flags);
4135+
c->c2.event_set2 = event_set_init(&c->c2.event_set_max, flags);
41144136
c->c2.event_set_owned = true;
41154137
}
41164138

@@ -4120,7 +4142,9 @@ do_close_event_set(struct context *c)
41204142
if (c->c2.event_set && c->c2.event_set_owned)
41214143
{
41224144
event_free(c->c2.event_set);
4145+
event_free(c->c2.event_set2);
41234146
c->c2.event_set = NULL;
4147+
c->c2.event_set2 = NULL;
41244148
c->c2.event_set_owned = false;
41254149
}
41264150
}
@@ -4925,6 +4949,7 @@ inherit_context_child(struct context *dest, const struct context *src, struct li
49254949
options_detach(&dest->options);
49264950

49274951
dest->c2.event_set = src->c2.event_set;
4952+
dest->c2.event_set2 = src->c2.event_set2;
49284953

49294954
if (dest->mode == CM_CHILD_TCP)
49304955
{
@@ -5016,6 +5041,7 @@ inherit_context_top(struct context *dest, const struct context *src)
50165041
dest->c2.es_owned = false;
50175042

50185043
dest->c2.event_set = NULL;
5044+
dest->c2.event_set2 = NULL;
50195045
do_event_set_init(dest, false);
50205046

50215047
#ifdef USE_COMP

0 commit comments

Comments
 (0)