diff options
-rw-r--r-- | buffer.c | 34 | ||||
-rw-r--r-- | buffer.h | 2 | ||||
-rw-r--r-- | error.c | 10 | ||||
-rw-r--r-- | openvpn.8 | 5 | ||||
-rw-r--r-- | options.c | 4 | ||||
-rw-r--r-- | socket.c | 2 | ||||
-rw-r--r-- | ssl.c | 22 | ||||
-rw-r--r-- | ssl.h | 2 | ||||
-rw-r--r-- | syshead.h | 4 | ||||
-rw-r--r-- | tun.c | 20 | ||||
-rw-r--r-- | version.m4 | 2 | ||||
-rw-r--r-- | win32.h | 1 |
12 files changed, 88 insertions, 20 deletions
@@ -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); @@ -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); @@ -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); @@ -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 @@ -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" @@ -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]); @@ -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 (); @@ -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 */ @@ -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? @@ -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 (); } @@ -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]) @@ -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 |