aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--buffer.c34
-rw-r--r--buffer.h2
-rw-r--r--error.c10
-rw-r--r--openvpn.85
-rw-r--r--options.c4
-rw-r--r--socket.c2
-rw-r--r--ssl.c22
-rw-r--r--ssl.h2
-rw-r--r--syshead.h4
-rw-r--r--tun.c20
-rw-r--r--version.m42
-rw-r--r--win32.h1
12 files changed, 88 insertions, 20 deletions
diff --git a/buffer.c b/buffer.c
index c7a42fb..5108429 100644
--- a/buffer.c
+++ b/buffer.c
@@ -896,8 +896,11 @@ buffer_list_new (const int max_size)
void
buffer_list_free (struct buffer_list *ol)
{
- buffer_list_reset (ol);
- free (ol);
+ if (ol)
+ {
+ buffer_list_reset (ol);
+ free (ol);
+ }
}
bool
@@ -924,9 +927,21 @@ buffer_list_reset (struct buffer_list *ol)
void
buffer_list_push (struct buffer_list *ol, const unsigned char *str)
{
- if (!ol->max_size || ol->size < ol->max_size)
+ if (str)
+ {
+ const size_t len = strlen ((const char *)str);
+ struct buffer_entry *e = buffer_list_push_data (ol, str, len+1);
+ if (e)
+ e->buf.len = len; /* Don't count trailing '\0' as part of length */
+ }
+}
+
+struct buffer_entry *
+buffer_list_push_data (struct buffer_list *ol, const uint8_t *data, size_t size)
+{
+ struct buffer_entry *e = NULL;
+ if (data && (!ol->max_size || ol->size < ol->max_size))
{
- struct buffer_entry *e;
ALLOC_OBJ_CLEAR (e, struct buffer_entry);
++ol->size;
@@ -940,15 +955,18 @@ buffer_list_push (struct buffer_list *ol, const unsigned char *str)
ASSERT (!ol->head);
ol->head = e;
}
- e->buf = string_alloc_buf ((const char *) str, NULL);
+ e->buf = alloc_buf (size);
+ memcpy (e->buf.data, data, size);
+ e->buf.len = (int)size;
ol->tail = e;
}
+ return e;
}
struct buffer *
buffer_list_peek (struct buffer_list *ol)
{
- if (ol->head)
+ if (ol && ol->head)
return &ol->head->buf;
else
return NULL;
@@ -993,10 +1011,10 @@ buffer_list_aggregate (struct buffer_list *bl, const size_t max)
}
}
-static void
+void
buffer_list_pop (struct buffer_list *ol)
{
- if (ol->head)
+ if (ol && ol->head)
{
struct buffer_entry *e = ol->head->next;
free_buf (&ol->head->buf);
diff --git a/buffer.h b/buffer.h
index 9351c4e..0f22cda 100644
--- a/buffer.h
+++ b/buffer.h
@@ -851,8 +851,10 @@ bool buffer_list_defined (const struct buffer_list *ol);
void buffer_list_reset (struct buffer_list *ol);
void buffer_list_push (struct buffer_list *ol, const unsigned char *str);
+struct buffer_entry *buffer_list_push_data (struct buffer_list *ol, const uint8_t *data, size_t size);
struct buffer *buffer_list_peek (struct buffer_list *ol);
void buffer_list_advance (struct buffer_list *ol, int n);
+void buffer_list_pop (struct buffer_list *ol);
void buffer_list_aggregate (struct buffer_list *bl, const size_t max);
diff --git a/error.c b/error.c
index ec8f9df..873718c 100644
--- a/error.c
+++ b/error.c
@@ -477,14 +477,16 @@ redirect_stdout_stderr (const char *file, bool append)
{
HANDLE log_handle;
int log_fd;
- struct security_attributes sa;
- init_security_attributes_allow_all (&sa);
+ SECURITY_ATTRIBUTES saAttr;
+ saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
+ saAttr.bInheritHandle = TRUE;
+ saAttr.lpSecurityDescriptor = NULL;
log_handle = CreateFile (file,
GENERIC_WRITE,
FILE_SHARE_READ,
- &sa.sa,
+ &saAttr,
append ? OPEN_ALWAYS : CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
@@ -505,10 +507,12 @@ redirect_stdout_stderr (const char *file, bool append)
/* save original stderr for password prompts */
orig_stderr = GetStdHandle (STD_ERROR_HANDLE);
+#if 0 /* seems not be necessary with stdout/stderr redirection below*/
/* set up for redirection */
if (!SetStdHandle (STD_OUTPUT_HANDLE, log_handle)
|| !SetStdHandle (STD_ERROR_HANDLE, log_handle))
msg (M_ERR, "Error: cannot redirect stdout/stderr to --log file: %s", file);
+#endif
/* direct stdout/stderr to point to log_handle */
log_fd = _open_osfhandle ((intptr_t)log_handle, _O_TEXT);
diff --git a/openvpn.8 b/openvpn.8
index 3ad232a..54fe720 100644
--- a/openvpn.8
+++ b/openvpn.8
@@ -4763,8 +4763,9 @@ above.
.\"*********************************************************
.TP
.B \-\-register-dns
-Run ipconfig /flushdns and ipconfig /registerdns on
-connection initiation. This is known to kick Windows into
+Run net stop dnscache, net start dnscache, ipconfig /flushdns
+and ipconfig /registerdns on connection initiation.
+This is known to kick Windows into
recognizing pushed DNS servers.
.\"*********************************************************
.TP
diff --git a/options.c b/options.c
index 6dd0b7d..2c2a782 100644
--- a/options.c
+++ b/options.c
@@ -628,8 +628,8 @@ static const char usage_message[] =
"--dhcp-pre-release : Ask Windows to release the previous TAP adapter lease on\n"
" startup.\n"
"--dhcp-release : Ask Windows to release the TAP adapter lease on shutdown.\n"
- "--register-dns : Run ipconfig /flushdns and ipconfig /registerdns on\n"
- " connection initiation.\n"
+ "--register-dns : Run net stop dnscache, net start dnscache, ipconfig /flushdns\n"
+ " and ipconfig /registerdns on connection initiation.\n"
"--tap-sleep n : Sleep for n seconds after TAP adapter open before\n"
" attempting to set adapter properties.\n"
"--pause-exit : When run from a console window, pause before exiting.\n"
diff --git a/socket.c b/socket.c
index 8f9d17d..b02d3da 100644
--- a/socket.c
+++ b/socket.c
@@ -231,7 +231,7 @@ getaddr_multi (unsigned int flags,
n);
/* choose address randomly, for basic load-balancing capability */
- /*ia.s_addr = *(in_addr_t *) (h->h_addr_list[get_random () % n]);*
+ /*ia.s_addr = *(in_addr_t *) (h->h_addr_list[get_random () % n]);*/
/* choose first address */
ia.s_addr = *(in_addr_t *) (h->h_addr_list[0]);
diff --git a/ssl.c b/ssl.c
index 8c7a5ee..0a84b0d 100644
--- a/ssl.c
+++ b/ssl.c
@@ -2366,6 +2366,7 @@ key_state_free (struct key_state *ks, bool clear)
free_buf (&ks->plaintext_read_buf);
free_buf (&ks->plaintext_write_buf);
free_buf (&ks->ack_write_buf);
+ buffer_list_free(ks->paybuf);
if (ks->send_reliable)
{
@@ -3164,6 +3165,17 @@ key_source2_read (struct key_source2 *k2,
return 1;
}
+static void
+flush_payload_buffer (struct tls_multi *multi, struct key_state *ks)
+{
+ struct buffer *b;
+ while ((b = buffer_list_peek (ks->paybuf)))
+ {
+ key_state_write_plaintext_const (multi, ks, b->data, b->len);
+ buffer_list_pop (ks->paybuf);
+ }
+}
+
/*
* Macros for key_state_soft_reset & tls_process
*/
@@ -4078,6 +4090,9 @@ tls_process (struct tls_multi *multi,
/* Set outgoing address for data channel packets */
link_socket_set_outgoing_addr (NULL, to_link_socket_info, &ks->remote_addr, session->common_name, session->opt->es);
+ /* Flush any payload packets that were buffered before our state transitioned to S_ACTIVE */
+ flush_payload_buffer (multi, ks);
+
#ifdef MEASURE_TLS_HANDSHAKE_STATS
show_tls_performance_stats();
#endif
@@ -5177,6 +5192,13 @@ tls_send_payload (struct tls_multi *multi,
if (key_state_write_plaintext_const (multi, ks, data, size) == 1)
ret = true;
}
+ else
+ {
+ if (!ks->paybuf)
+ ks->paybuf = buffer_list_new (0);
+ buffer_list_push_data (ks->paybuf, data, (size_t)size);
+ ret = true;
+ }
ERR_clear_error ();
diff --git a/ssl.h b/ssl.h
index 02234c3..8415d55 100644
--- a/ssl.h
+++ b/ssl.h
@@ -379,6 +379,8 @@ struct key_state
struct reliable *rec_reliable; /* order incoming ciphertext packets before we pass to TLS */
struct reliable_ack *rec_ack; /* buffers all packet IDs we want to ACK back to sender */
+ struct buffer_list *paybuf;
+
counter_type n_bytes; /* how many bytes sent/recvd since last key exchange */
counter_type n_packets; /* how many packets sent/recvd since last key exchange */
diff --git a/syshead.h b/syshead.h
index 7cc4dba..1b8bfad 100644
--- a/syshead.h
+++ b/syshead.h
@@ -535,11 +535,9 @@ socket_defined (const socket_descriptor_t sd)
#endif
/*
- * Don't compile the struct buffer_list code unless something needs it
+ * Compile the struct buffer_list code
*/
-#if defined(ENABLE_MANAGEMENT) || defined(ENABLE_PF)
#define ENABLE_BUFFER_LIST
-#endif
/*
* Do we have pthread capability?
diff --git a/tun.c b/tun.c
index 07e4c4e..91fff0b 100644
--- a/tun.c
+++ b/tun.c
@@ -3379,17 +3379,37 @@ ipconfig_register_dns (const struct env_set *es)
const char err[] = "ERROR: Windows ipconfig command failed";
netcmd_semaphore_lock ();
+
argv_init (&argv);
+
+ argv_printf (&argv, "%s%sc stop dnscache",
+ get_win_sys_path(),
+ WIN_NET_PATH_SUFFIX);
+ argv_msg (D_TUNTAP_INFO, &argv);
+ status = openvpn_execve_check (&argv, es, 0, err);
+ argv_reset(&argv);
+
+ argv_printf (&argv, "%s%sc start dnscache",
+ get_win_sys_path(),
+ WIN_NET_PATH_SUFFIX);
+ argv_msg (D_TUNTAP_INFO, &argv);
+ status = openvpn_execve_check (&argv, es, 0, err);
+ argv_reset(&argv);
+
argv_printf (&argv, "%s%sc /flushdns",
get_win_sys_path(),
WIN_IPCONFIG_PATH_SUFFIX);
+ argv_msg (D_TUNTAP_INFO, &argv);
status = openvpn_execve_check (&argv, es, 0, err);
argv_reset(&argv);
+
argv_printf (&argv, "%s%sc /registerdns",
get_win_sys_path(),
WIN_IPCONFIG_PATH_SUFFIX);
+ argv_msg (D_TUNTAP_INFO, &argv);
status = openvpn_execve_check (&argv, es, 0, err);
argv_reset(&argv);
+
netcmd_semaphore_release ();
}
diff --git a/version.m4 b/version.m4
index b6d1f61..4add313 100644
--- a/version.m4
+++ b/version.m4
@@ -1,5 +1,5 @@
dnl define the OpenVPN version
-define(PRODUCT_VERSION,[2.1.1m])
+define(PRODUCT_VERSION,[2.1.1o])
dnl define the TAP version
define(PRODUCT_TAP_ID,[tap0901])
define(PRODUCT_TAP_WIN32_MIN_MAJOR,[9])
diff --git a/win32.h b/win32.h
index f974b06..fcc3062 100644
--- a/win32.h
+++ b/win32.h
@@ -34,6 +34,7 @@
#define NETSH_PATH_SUFFIX "\\system32\\netsh.exe"
#define WIN_ROUTE_PATH_SUFFIX "\\system32\\route.exe"
#define WIN_IPCONFIG_PATH_SUFFIX "\\system32\\ipconfig.exe"
+#define WIN_NET_PATH_SUFFIX "\\system32\\net.exe"
/*
* Win32-specific OpenVPN code, targetted at the mingw