Conflicts:
openvpn.8
- Enhancements to the --register-dns description
ssl.h
- Community changed n_packets and n_bytes to use
counter_type instead of int to avoid integer overflows
(commit 6484c6299cf298107316e6497)
Signed-off-by: David Sommerseth <dazo@users.sourceforge.net>
... | ... |
@@ -896,8 +896,11 @@ buffer_list_new (const int max_size) |
896 | 896 |
void |
897 | 897 |
buffer_list_free (struct buffer_list *ol) |
898 | 898 |
{ |
899 |
- buffer_list_reset (ol); |
|
900 |
- free (ol); |
|
899 |
+ if (ol) |
|
900 |
+ { |
|
901 |
+ buffer_list_reset (ol); |
|
902 |
+ free (ol); |
|
903 |
+ } |
|
901 | 904 |
} |
902 | 905 |
|
903 | 906 |
bool |
... | ... |
@@ -924,9 +927,21 @@ buffer_list_reset (struct buffer_list *ol) |
924 | 924 |
void |
925 | 925 |
buffer_list_push (struct buffer_list *ol, const unsigned char *str) |
926 | 926 |
{ |
927 |
- if (!ol->max_size || ol->size < ol->max_size) |
|
927 |
+ if (str) |
|
928 |
+ { |
|
929 |
+ const size_t len = strlen ((const char *)str); |
|
930 |
+ struct buffer_entry *e = buffer_list_push_data (ol, str, len+1); |
|
931 |
+ if (e) |
|
932 |
+ e->buf.len = len; /* Don't count trailing '\0' as part of length */ |
|
933 |
+ } |
|
934 |
+} |
|
935 |
+ |
|
936 |
+struct buffer_entry * |
|
937 |
+buffer_list_push_data (struct buffer_list *ol, const uint8_t *data, size_t size) |
|
938 |
+{ |
|
939 |
+ struct buffer_entry *e = NULL; |
|
940 |
+ if (data && (!ol->max_size || ol->size < ol->max_size)) |
|
928 | 941 |
{ |
929 |
- struct buffer_entry *e; |
|
930 | 942 |
ALLOC_OBJ_CLEAR (e, struct buffer_entry); |
931 | 943 |
|
932 | 944 |
++ol->size; |
... | ... |
@@ -940,15 +955,18 @@ buffer_list_push (struct buffer_list *ol, const unsigned char *str) |
940 | 940 |
ASSERT (!ol->head); |
941 | 941 |
ol->head = e; |
942 | 942 |
} |
943 |
- e->buf = string_alloc_buf ((const char *) str, NULL); |
|
943 |
+ e->buf = alloc_buf (size); |
|
944 |
+ memcpy (e->buf.data, data, size); |
|
945 |
+ e->buf.len = (int)size; |
|
944 | 946 |
ol->tail = e; |
945 | 947 |
} |
948 |
+ return e; |
|
946 | 949 |
} |
947 | 950 |
|
948 | 951 |
struct buffer * |
949 | 952 |
buffer_list_peek (struct buffer_list *ol) |
950 | 953 |
{ |
951 |
- if (ol->head) |
|
954 |
+ if (ol && ol->head) |
|
952 | 955 |
return &ol->head->buf; |
953 | 956 |
else |
954 | 957 |
return NULL; |
... | ... |
@@ -993,10 +1011,10 @@ buffer_list_aggregate (struct buffer_list *bl, const size_t max) |
993 | 993 |
} |
994 | 994 |
} |
995 | 995 |
|
996 |
-static void |
|
996 |
+void |
|
997 | 997 |
buffer_list_pop (struct buffer_list *ol) |
998 | 998 |
{ |
999 |
- if (ol->head) |
|
999 |
+ if (ol && ol->head) |
|
1000 | 1000 |
{ |
1001 | 1001 |
struct buffer_entry *e = ol->head->next; |
1002 | 1002 |
free_buf (&ol->head->buf); |
... | ... |
@@ -851,8 +851,10 @@ bool buffer_list_defined (const struct buffer_list *ol); |
851 | 851 |
void buffer_list_reset (struct buffer_list *ol); |
852 | 852 |
|
853 | 853 |
void buffer_list_push (struct buffer_list *ol, const unsigned char *str); |
854 |
+struct buffer_entry *buffer_list_push_data (struct buffer_list *ol, const uint8_t *data, size_t size); |
|
854 | 855 |
struct buffer *buffer_list_peek (struct buffer_list *ol); |
855 | 856 |
void buffer_list_advance (struct buffer_list *ol, int n); |
857 |
+void buffer_list_pop (struct buffer_list *ol); |
|
856 | 858 |
|
857 | 859 |
void buffer_list_aggregate (struct buffer_list *bl, const size_t max); |
858 | 860 |
|
... | ... |
@@ -477,14 +477,16 @@ redirect_stdout_stderr (const char *file, bool append) |
477 | 477 |
{ |
478 | 478 |
HANDLE log_handle; |
479 | 479 |
int log_fd; |
480 |
- struct security_attributes sa; |
|
481 | 480 |
|
482 |
- init_security_attributes_allow_all (&sa); |
|
481 |
+ SECURITY_ATTRIBUTES saAttr; |
|
482 |
+ saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); |
|
483 |
+ saAttr.bInheritHandle = TRUE; |
|
484 |
+ saAttr.lpSecurityDescriptor = NULL; |
|
483 | 485 |
|
484 | 486 |
log_handle = CreateFile (file, |
485 | 487 |
GENERIC_WRITE, |
486 | 488 |
FILE_SHARE_READ, |
487 |
- &sa.sa, |
|
489 |
+ &saAttr, |
|
488 | 490 |
append ? OPEN_ALWAYS : CREATE_ALWAYS, |
489 | 491 |
FILE_ATTRIBUTE_NORMAL, |
490 | 492 |
NULL); |
... | ... |
@@ -505,10 +507,12 @@ redirect_stdout_stderr (const char *file, bool append) |
505 | 505 |
/* save original stderr for password prompts */ |
506 | 506 |
orig_stderr = GetStdHandle (STD_ERROR_HANDLE); |
507 | 507 |
|
508 |
+#if 0 /* seems not be necessary with stdout/stderr redirection below*/ |
|
508 | 509 |
/* set up for redirection */ |
509 | 510 |
if (!SetStdHandle (STD_OUTPUT_HANDLE, log_handle) |
510 | 511 |
|| !SetStdHandle (STD_ERROR_HANDLE, log_handle)) |
511 | 512 |
msg (M_ERR, "Error: cannot redirect stdout/stderr to --log file: %s", file); |
513 |
+#endif |
|
512 | 514 |
|
513 | 515 |
/* direct stdout/stderr to point to log_handle */ |
514 | 516 |
log_fd = _open_osfhandle ((intptr_t)log_handle, _O_TEXT); |
... | ... |
@@ -4763,8 +4763,9 @@ above. |
4763 | 4763 |
.\"********************************************************* |
4764 | 4764 |
.TP |
4765 | 4765 |
.B \-\-register-dns |
4766 |
-Run ipconfig /flushdns and ipconfig /registerdns on |
|
4767 |
-connection initiation. This is known to kick Windows into |
|
4766 |
+Run net stop dnscache, net start dnscache, ipconfig /flushdns |
|
4767 |
+and ipconfig /registerdns on connection initiation. |
|
4768 |
+This is known to kick Windows into |
|
4768 | 4769 |
recognizing pushed DNS servers. |
4769 | 4770 |
.\"********************************************************* |
4770 | 4771 |
.TP |
... | ... |
@@ -628,8 +628,8 @@ static const char usage_message[] = |
628 | 628 |
"--dhcp-pre-release : Ask Windows to release the previous TAP adapter lease on\n" |
629 | 629 |
" startup.\n" |
630 | 630 |
"--dhcp-release : Ask Windows to release the TAP adapter lease on shutdown.\n" |
631 |
- "--register-dns : Run ipconfig /flushdns and ipconfig /registerdns on\n" |
|
632 |
- " connection initiation.\n" |
|
631 |
+ "--register-dns : Run net stop dnscache, net start dnscache, ipconfig /flushdns\n" |
|
632 |
+ " and ipconfig /registerdns on connection initiation.\n" |
|
633 | 633 |
"--tap-sleep n : Sleep for n seconds after TAP adapter open before\n" |
634 | 634 |
" attempting to set adapter properties.\n" |
635 | 635 |
"--pause-exit : When run from a console window, pause before exiting.\n" |
... | ... |
@@ -231,7 +231,7 @@ getaddr_multi (unsigned int flags, |
231 | 231 |
n); |
232 | 232 |
|
233 | 233 |
/* choose address randomly, for basic load-balancing capability */ |
234 |
- /*ia.s_addr = *(in_addr_t *) (h->h_addr_list[get_random () % n]);* |
|
234 |
+ /*ia.s_addr = *(in_addr_t *) (h->h_addr_list[get_random () % n]);*/ |
|
235 | 235 |
|
236 | 236 |
/* choose first address */ |
237 | 237 |
ia.s_addr = *(in_addr_t *) (h->h_addr_list[0]); |
... | ... |
@@ -2366,6 +2366,7 @@ key_state_free (struct key_state *ks, bool clear) |
2366 | 2366 |
free_buf (&ks->plaintext_read_buf); |
2367 | 2367 |
free_buf (&ks->plaintext_write_buf); |
2368 | 2368 |
free_buf (&ks->ack_write_buf); |
2369 |
+ buffer_list_free(ks->paybuf); |
|
2369 | 2370 |
|
2370 | 2371 |
if (ks->send_reliable) |
2371 | 2372 |
{ |
... | ... |
@@ -3164,6 +3165,17 @@ key_source2_read (struct key_source2 *k2, |
3164 | 3164 |
return 1; |
3165 | 3165 |
} |
3166 | 3166 |
|
3167 |
+static void |
|
3168 |
+flush_payload_buffer (struct tls_multi *multi, struct key_state *ks) |
|
3169 |
+{ |
|
3170 |
+ struct buffer *b; |
|
3171 |
+ while ((b = buffer_list_peek (ks->paybuf))) |
|
3172 |
+ { |
|
3173 |
+ key_state_write_plaintext_const (multi, ks, b->data, b->len); |
|
3174 |
+ buffer_list_pop (ks->paybuf); |
|
3175 |
+ } |
|
3176 |
+} |
|
3177 |
+ |
|
3167 | 3178 |
/* |
3168 | 3179 |
* Macros for key_state_soft_reset & tls_process |
3169 | 3180 |
*/ |
... | ... |
@@ -4078,6 +4090,9 @@ tls_process (struct tls_multi *multi, |
4078 | 4078 |
/* Set outgoing address for data channel packets */ |
4079 | 4079 |
link_socket_set_outgoing_addr (NULL, to_link_socket_info, &ks->remote_addr, session->common_name, session->opt->es); |
4080 | 4080 |
|
4081 |
+ /* Flush any payload packets that were buffered before our state transitioned to S_ACTIVE */ |
|
4082 |
+ flush_payload_buffer (multi, ks); |
|
4083 |
+ |
|
4081 | 4084 |
#ifdef MEASURE_TLS_HANDSHAKE_STATS |
4082 | 4085 |
show_tls_performance_stats(); |
4083 | 4086 |
#endif |
... | ... |
@@ -5177,6 +5192,13 @@ tls_send_payload (struct tls_multi *multi, |
5177 | 5177 |
if (key_state_write_plaintext_const (multi, ks, data, size) == 1) |
5178 | 5178 |
ret = true; |
5179 | 5179 |
} |
5180 |
+ else |
|
5181 |
+ { |
|
5182 |
+ if (!ks->paybuf) |
|
5183 |
+ ks->paybuf = buffer_list_new (0); |
|
5184 |
+ buffer_list_push_data (ks->paybuf, data, (size_t)size); |
|
5185 |
+ ret = true; |
|
5186 |
+ } |
|
5180 | 5187 |
|
5181 | 5188 |
ERR_clear_error (); |
5182 | 5189 |
|
... | ... |
@@ -379,6 +379,8 @@ struct key_state |
379 | 379 |
struct reliable *rec_reliable; /* order incoming ciphertext packets before we pass to TLS */ |
380 | 380 |
struct reliable_ack *rec_ack; /* buffers all packet IDs we want to ACK back to sender */ |
381 | 381 |
|
382 |
+ struct buffer_list *paybuf; |
|
383 |
+ |
|
382 | 384 |
counter_type n_bytes; /* how many bytes sent/recvd since last key exchange */ |
383 | 385 |
counter_type n_packets; /* how many packets sent/recvd since last key exchange */ |
384 | 386 |
|
... | ... |
@@ -535,11 +535,9 @@ socket_defined (const socket_descriptor_t sd) |
535 | 535 |
#endif |
536 | 536 |
|
537 | 537 |
/* |
538 |
- * Don't compile the struct buffer_list code unless something needs it |
|
538 |
+ * Compile the struct buffer_list code |
|
539 | 539 |
*/ |
540 |
-#if defined(ENABLE_MANAGEMENT) || defined(ENABLE_PF) |
|
541 | 540 |
#define ENABLE_BUFFER_LIST |
542 |
-#endif |
|
543 | 541 |
|
544 | 542 |
/* |
545 | 543 |
* Do we have pthread capability? |
... | ... |
@@ -3379,17 +3379,37 @@ ipconfig_register_dns (const struct env_set *es) |
3379 | 3379 |
const char err[] = "ERROR: Windows ipconfig command failed"; |
3380 | 3380 |
|
3381 | 3381 |
netcmd_semaphore_lock (); |
3382 |
+ |
|
3382 | 3383 |
argv_init (&argv); |
3384 |
+ |
|
3385 |
+ argv_printf (&argv, "%s%sc stop dnscache", |
|
3386 |
+ get_win_sys_path(), |
|
3387 |
+ WIN_NET_PATH_SUFFIX); |
|
3388 |
+ argv_msg (D_TUNTAP_INFO, &argv); |
|
3389 |
+ status = openvpn_execve_check (&argv, es, 0, err); |
|
3390 |
+ argv_reset(&argv); |
|
3391 |
+ |
|
3392 |
+ argv_printf (&argv, "%s%sc start dnscache", |
|
3393 |
+ get_win_sys_path(), |
|
3394 |
+ WIN_NET_PATH_SUFFIX); |
|
3395 |
+ argv_msg (D_TUNTAP_INFO, &argv); |
|
3396 |
+ status = openvpn_execve_check (&argv, es, 0, err); |
|
3397 |
+ argv_reset(&argv); |
|
3398 |
+ |
|
3383 | 3399 |
argv_printf (&argv, "%s%sc /flushdns", |
3384 | 3400 |
get_win_sys_path(), |
3385 | 3401 |
WIN_IPCONFIG_PATH_SUFFIX); |
3402 |
+ argv_msg (D_TUNTAP_INFO, &argv); |
|
3386 | 3403 |
status = openvpn_execve_check (&argv, es, 0, err); |
3387 | 3404 |
argv_reset(&argv); |
3405 |
+ |
|
3388 | 3406 |
argv_printf (&argv, "%s%sc /registerdns", |
3389 | 3407 |
get_win_sys_path(), |
3390 | 3408 |
WIN_IPCONFIG_PATH_SUFFIX); |
3409 |
+ argv_msg (D_TUNTAP_INFO, &argv); |
|
3391 | 3410 |
status = openvpn_execve_check (&argv, es, 0, err); |
3392 | 3411 |
argv_reset(&argv); |
3412 |
+ |
|
3393 | 3413 |
netcmd_semaphore_release (); |
3394 | 3414 |
} |
3395 | 3415 |
|
... | ... |
@@ -34,6 +34,7 @@ |
34 | 34 |
#define NETSH_PATH_SUFFIX "\\system32\\netsh.exe" |
35 | 35 |
#define WIN_ROUTE_PATH_SUFFIX "\\system32\\route.exe" |
36 | 36 |
#define WIN_IPCONFIG_PATH_SUFFIX "\\system32\\ipconfig.exe" |
37 |
+#define WIN_NET_PATH_SUFFIX "\\system32\\net.exe" |
|
37 | 38 |
|
38 | 39 |
/* |
39 | 40 |
* Win32-specific OpenVPN code, targetted at the mingw |