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 |