Skip to content

Commit 97557b4

Browse files
author
Jon Chiappetta
committed
dual mode
1 parent 00670e5 commit 97557b4

File tree

17 files changed

+596
-215
lines changed

17 files changed

+596
-215
lines changed

src/openvpn/forward.c

Lines changed: 73 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -376,14 +376,13 @@ check_connection_established(struct context *c)
376376
#endif
377377

378378
bool
379-
send_control_channel_string_dowork(struct tls_session *session, const char *str,
379+
send_control_channel_string_dowork(struct tls_session *session, struct key_state *ks, const char *str,
380380
msglvl_t msglevel)
381381
{
382382
struct gc_arena gc = gc_new();
383383
bool stat;
384384

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

388387
/* buffered cleartext write onto TLS control channel */
389388
stat = tls_send_payload(ks, (uint8_t *)str, strlen(str) + 1);
@@ -409,7 +408,18 @@ send_control_channel_string(struct context *c, const char *str, msglvl_t msgleve
409408
if (c->c2.tls_multi)
410409
{
411410
struct tls_session *session = &c->c2.tls_multi->session[TM_ACTIVE];
412-
bool ret = send_control_channel_string_dowork(session, str, msglevel);
411+
struct key_state *ks = &session->key[KS_PRIMARY];
412+
bool ret = send_control_channel_string_dowork(session, ks, str, msglevel);
413+
reschedule_multi_process(c);
414+
415+
session = &c->c2.tls_multi->session[TM_THREADED];
416+
ks = &session->key[KS_PRIMARY];
417+
send_control_channel_string_dowork(session, ks, str, msglevel);
418+
reschedule_multi_process(c);
419+
420+
session = &c->c2.tls_multi->session[TM_REKEYS];
421+
ks = &session->key[KS_PRIMARY];
422+
ret = send_control_channel_string_dowork(session, ks, str, msglevel);
413423
reschedule_multi_process(c);
414424

415425
return ret;
@@ -2358,11 +2368,13 @@ get_io_flags_udp(struct context *c, struct multi_io *multi_io, const unsigned in
23582368
}
23592369

23602370
void
2361-
io_wait_dowork(struct context *c, const unsigned int flags)
2371+
io_wait_dowork(struct context *c, const unsigned int flags, int z)
23622372
{
23632373
unsigned int out_socket;
23642374
unsigned int out_tuntap;
23652375
struct event_set_return esr[4];
2376+
struct event_set *event_set = ((z & THREAD_RTWL) != 0) ? c->c2.event_set : c->c2.event_set2;
2377+
unsigned int *event_set_status = ((z & THREAD_RTWL) != 0) ? &(c->c2.event_set_status) : &(c->c2.event_set_status2);
23662378

23672379
/* These shifts all depend on EVENT_READ and EVENT_WRITE */
23682380
static uintptr_t socket_shift = SOCKET_SHIFT; /* depends on SOCKET_READ and SOCKET_WRITE */
@@ -2380,29 +2392,29 @@ io_wait_dowork(struct context *c, const unsigned int flags)
23802392
/*
23812393
* Decide what kind of events we want to wait for.
23822394
*/
2383-
event_reset(c->c2.event_set);
2395+
event_reset(event_set);
23842396

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

23872399
#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
23882400
if (out_socket & EVENT_READ && c->c2.did_open_tun)
23892401
{
2390-
dco_event_set(&c->c1.tuntap->dco, c->c2.event_set, (void *)dco_shift);
2402+
dco_event_set(&c->c1.tuntap->dco, event_set, (void *)dco_shift);
23912403
}
23922404
#endif
23932405

23942406
#ifdef ENABLE_MANAGEMENT
23952407
if (management)
23962408
{
2397-
management_socket_set(management, c->c2.event_set, (void *)management_shift, NULL);
2409+
management_socket_set(management, event_set, (void *)management_shift, NULL);
23982410
}
23992411
#endif
24002412

24012413
#ifdef ENABLE_ASYNC_PUSH
24022414
/* arm inotify watcher */
24032415
if (c->options.mode == MODE_SERVER)
24042416
{
2405-
event_ctl(c->c2.event_set, c->c2.inotify_fd, EVENT_READ, (void *)file_shift);
2417+
event_ctl(event_set, c->c2.inotify_fd, EVENT_READ, (void *)file_shift);
24062418
}
24072419
#endif
24082420

@@ -2416,7 +2428,7 @@ io_wait_dowork(struct context *c, const unsigned int flags)
24162428
* (6) timeout (tv) expired
24172429
*/
24182430

2419-
c->c2.event_set_status = ES_ERROR;
2431+
*event_set_status = ES_ERROR;
24202432

24212433
if (!c->sig->signal_received)
24222434
{
@@ -2434,14 +2446,14 @@ io_wait_dowork(struct context *c, const unsigned int flags)
24342446
/*
24352447
* Wait for something to happen.
24362448
*/
2437-
status = event_wait(c->c2.event_set, &c->c2.timeval, esr, SIZE(esr));
2449+
status = event_wait(event_set, &c->c2.timeval, esr, SIZE(esr));
24382450

24392451
check_status(status, "event_wait", NULL, NULL);
24402452

24412453
if (status > 0)
24422454
{
24432455
int i;
2444-
c->c2.event_set_status = 0;
2456+
*event_set_status = 0;
24452457
for (i = 0; i < status; ++i)
24462458
{
24472459
const struct event_set_return *e = &esr[i];
@@ -2452,7 +2464,7 @@ io_wait_dowork(struct context *c, const unsigned int flags)
24522464
struct event_arg *ev_arg = (struct event_arg *)e->arg;
24532465
if (ev_arg->type != EVENT_ARG_LINK_SOCKET)
24542466
{
2455-
c->c2.event_set_status = ES_ERROR;
2467+
*event_set_status = ES_ERROR;
24562468
msg(D_LINK_ERRORS, "io_work: non socket event delivered");
24572469
return;
24582470
}
@@ -2464,30 +2476,30 @@ io_wait_dowork(struct context *c, const unsigned int flags)
24642476
shift = (uintptr_t)e->arg;
24652477
}
24662478

2467-
c->c2.event_set_status |= ((e->rwflags & 3) << shift);
2479+
*event_set_status |= ((e->rwflags & 3) << shift);
24682480
}
24692481
}
24702482
else if (status == 0)
24712483
{
2472-
c->c2.event_set_status = ES_TIMEOUT;
2484+
*event_set_status = ES_TIMEOUT;
24732485
}
24742486
}
24752487
else
24762488
{
2477-
c->c2.event_set_status = SOCKET_READ;
2489+
*event_set_status = SOCKET_READ;
24782490
}
24792491
}
24802492

24812493
/* 'now' should always be a reasonably up-to-date timestamp */
24822494
update_time();
24832495

24842496
/* set signal_received if a signal was received */
2485-
if (c->c2.event_set_status & ES_ERROR)
2497+
if (*event_set_status & ES_ERROR)
24862498
{
24872499
get_signal(&c->sig->signal_received);
24882500
}
24892501

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

24932505
void threaded_fwd_inp_intf(struct context *c, struct link_socket *sock, struct thread_pointer *b)
@@ -2507,7 +2519,7 @@ void threaded_fwd_inp_intf(struct context *c, struct link_socket *sock, struct t
25072519
}
25082520

25092521
void
2510-
process_io(struct context *c, struct link_socket *sock, struct thread_pointer *b)
2522+
process_io(struct context *c, struct link_socket *sock, struct thread_pointer *b, int z)
25112523
{
25122524
const unsigned int status = c->c2.event_set_status;
25132525

@@ -2520,17 +2532,17 @@ process_io(struct context *c, struct link_socket *sock, struct thread_pointer *b
25202532
#endif
25212533

25222534
/* TCP/UDP port ready to accept write */
2523-
if (status & SOCKET_WRITE)
2535+
if ((status & SOCKET_WRITE) && ((z & THREAD_RTWL) != 0))
25242536
{
25252537
process_outgoing_link(c, sock);
25262538
}
25272539
/* TUN device ready to accept write */
2528-
else if (status & TUN_WRITE)
2540+
else if ((status & TUN_WRITE) && ((z & THREAD_RLWT) != 0))
25292541
{
25302542
process_outgoing_tun(c, sock);
25312543
}
25322544
/* Incoming data on TCP/UDP port */
2533-
else if (status & SOCKET_READ)
2545+
else if ((status & SOCKET_READ) && ((z & THREAD_RLWT) != 0))
25342546
{
25352547
read_incoming_link(c, sock);
25362548
if (!IS_SIG(c))
@@ -2539,15 +2551,52 @@ process_io(struct context *c, struct link_socket *sock, struct thread_pointer *b
25392551
}
25402552
}
25412553
/* Incoming data on TUN device */
2542-
else if (status & TUN_READ)
2554+
else if ((status & TUN_READ) && ((z & THREAD_RTWL) != 0))
25432555
{
25442556
threaded_fwd_inp_intf(c, sock, b);
25452557
}
2546-
else if (status & DCO_READ)
2558+
else if ((status & DCO_READ) && ((z & THREAD_RTWL) != 0))
25472559
{
25482560
if (!IS_SIG(c))
25492561
{
25502562
process_incoming_dco(c);
25512563
}
25522564
}
25532565
}
2566+
2567+
void threaded_dual_init(struct dual_args *d)
2568+
{
2569+
if ((d->a == 0) && (d->c->c2.buffers))
2570+
{
2571+
if ((d->z & THREAD_RLWT) != 0)
2572+
{
2573+
d->c->c2.buffers->read_link_buf.len = 0;
2574+
d->c->c2.buf2 = d->c->c2.buffers->read_link_buf;
2575+
d->a = 1;
2576+
}
2577+
if ((d->z & THREAD_RTWL) != 0)
2578+
{
2579+
d->c->c2.buffers->read_tun_buf.len = 0;
2580+
d->c->c2.buf = d->c->c2.buffers->read_tun_buf;
2581+
d->a = 1;
2582+
}
2583+
}
2584+
}
2585+
2586+
void *threaded_process_io(void *a)
2587+
{
2588+
struct dual_args *d = (struct dual_args *)a;
2589+
while (true)
2590+
{
2591+
if (d->b->p->z != 1) { break; }
2592+
pthread_mutex_lock(&(d->i));
2593+
if (d->b->p->z != 1) { break; }
2594+
threaded_dual_init(d);
2595+
if (d->a == 1)
2596+
{
2597+
process_io(d->c, d->c->c2.link_sockets[0], d->b, d->z);
2598+
}
2599+
pthread_mutex_unlock(&(d->o));
2600+
}
2601+
return NULL;
2602+
}

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)