From 68b8f12b25746f0dcc1a261e6d8a11c476bdb0ac Mon Sep 17 00:00:00 2001 From: James Yonan Date: Sun, 17 May 2015 01:41:16 -0600 Subject: [PATCH] Refactored ScopedPtr usage to std::unique_ptr. Removed ScopedPtr. --- client/ovpncli.cpp | 1 - openvpn/client/cliconnect.hpp | 5 +- openvpn/common/enumdir.hpp | 19 +-- openvpn/common/scoped_ptr.hpp | 149 ------------------ openvpn/common/unicode.hpp | 4 +- .../util/free.hpp => common/uniqueptr.hpp} | 21 +-- openvpn/netconf/enumiface.hpp | 27 ++-- openvpn/openssl/ssl/sslctx.hpp | 8 +- openvpn/polarssl/ssl/sslctx.hpp | 8 +- openvpn/ssl/proto.hpp | 10 +- openvpn/transport/tcplink.hpp | 4 +- openvpn/transport/udplink.hpp | 5 +- openvpn/tun/builder/client.hpp | 4 +- openvpn/tun/linux/tun.hpp | 3 +- openvpn/tun/mac/client/tuncli.hpp | 3 +- openvpn/tun/mac/gwv4.hpp | 4 +- openvpn/tun/mac/macdns.hpp | 12 +- openvpn/tun/win/client/tuncli.hpp | 3 +- openvpn/tun/win/tunutil.hpp | 25 +-- openvpn/win/call.hpp | 23 +-- openvpn/win/unicode.hpp | 10 +- 21 files changed, 86 insertions(+), 262 deletions(-) delete mode 100644 openvpn/common/scoped_ptr.hpp rename openvpn/{openssl/util/free.hpp => common/uniqueptr.hpp} (78%) diff --git a/client/ovpncli.cpp b/client/ovpncli.cpp index 2be29d9df..54cf3abfe 100644 --- a/client/ovpncli.cpp +++ b/client/ovpncli.cpp @@ -96,7 +96,6 @@ #include #include -#include #include #include #include diff --git a/openvpn/client/cliconnect.hpp b/openvpn/client/cliconnect.hpp index f4ad478d4..b1a2d342c 100644 --- a/openvpn/client/cliconnect.hpp +++ b/openvpn/client/cliconnect.hpp @@ -49,8 +49,9 @@ #ifndef OPENVPN_CLIENT_CLICONNECT_H #define OPENVPN_CLIENT_CLICONNECT_H +#include + #include -#include #include #include #include @@ -551,7 +552,7 @@ namespace openvpn { AsioTimer restart_wait_timer; AsioTimer conn_timer; bool conn_timer_pending; - ScopedPtr asio_work; + std::unique_ptr asio_work; RemoteList::PreResolve::Ptr pre_resolve; }; diff --git a/openvpn/common/enumdir.hpp b/openvpn/common/enumdir.hpp index 52364fb4f..447de85c8 100644 --- a/openvpn/common/enumdir.hpp +++ b/openvpn/common/enumdir.hpp @@ -28,36 +28,27 @@ #include #include #include +#include #include #include -#include +#include namespace openvpn { OPENVPN_EXCEPTION(enum_dir_error); - template - class FreeDIR { - public: - static void del(T* p) - { - // delete method for pointer returned by opendir - closedir(p); - } - }; - std::vector enum_dir(const std::string& dirname, const size_t size_hint=0) { std::vector ret; if (size_hint) ret.reserve(size_hint); - ScopedPtr dir(opendir(dirname.c_str())); - if (!dir.defined()) + unique_ptr_del dir(opendir(dirname.c_str()), [](DIR* d) { closedir(d); }); + if (!dir) throw enum_dir_error(dirname + ": cannot open directory"); struct dirent *e; - while ((e = readdir(dir())) != NULL) + while ((e = readdir(dir.get())) != NULL) { std::string fn(e->d_name); if (fn != "." && fn != "..") diff --git a/openvpn/common/scoped_ptr.hpp b/openvpn/common/scoped_ptr.hpp deleted file mode 100644 index 86d923194..000000000 --- a/openvpn/common/scoped_ptr.hpp +++ /dev/null @@ -1,149 +0,0 @@ -// OpenVPN -- An application to securely tunnel IP networks -// over a single port, with support for SSL/TLS-based -// session authentication and key exchange, -// packet encryption, packet authentication, and -// packet compression. -// -// Copyright (C) 2012-2015 OpenVPN Technologies, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License Version 3 -// as published by the Free Software Foundation. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program in the COPYING file. -// If not, see . - -// A scoped pointer class similar to boost::scoped_ptr. - -#ifndef OPENVPN_COMMON_SCOPED_PTR_H -#define OPENVPN_COMMON_SCOPED_PTR_H - -#include - -#include - -namespace openvpn { - - // default delete method for ScopedPtr - template - class PtrFree { - public: - static void del(T* p) - { - delete p; - } - }; - - // array delete method for ScopedPtr - template - class PtrArrayFree { - public: - static void del(T* p) - { - delete [] p; - } - }; - - // Similar to boost::scoped_ptr but has release, reset methods, - // and default constructor usage. Also allows definition of - // alternative delete methods via second argument. - template class F = PtrFree> - class ScopedPtr - { - ScopedPtr(const ScopedPtr&) = delete; - ScopedPtr& operator=(const ScopedPtr&) = delete; - - public: - explicit ScopedPtr(T* p = 0) - : px(p) {} - - bool defined() const { return px != 0; } - - void reset(T* p = 0) - { - if (px) - del(px); - px = p; - } - - T* release() - { - T* ret = px; - px = NULL; - return ret; - } - - void swap(ScopedPtr& other) - { - std::swap(px, other.px); - } - - T& operator*() const - { - return *px; - } - - T* operator->() const - { - return px; - } - - T* get() const - { - return px; - } - - T* operator()() const - { - return px; - } - - T* operator[](const size_t index) - { - return &px[index]; - } - - T** ref() - { - return &px; - } - - ~ScopedPtr() - { - if (px) - del(px); - } - - ScopedPtr(ScopedPtr&& other) noexcept - { - px = other.px; - other.px = NULL; - } - - ScopedPtr& operator=(ScopedPtr&& other) noexcept - { - if (px) - del(px); - px = other.px; - other.px = NULL; - return *this; - } - - private: - static void del(T* p) - { - F::del(p); - } - - T* px; - }; - -} // namespace openvpn - -#endif // OPENVPN_COMMON_SCOPED_PTR_H diff --git a/openvpn/common/unicode.hpp b/openvpn/common/unicode.hpp index d66b3f019..082b34431 100644 --- a/openvpn/common/unicode.hpp +++ b/openvpn/common/unicode.hpp @@ -26,10 +26,10 @@ #include #include // for std::min +#include #include #include -#include #include #include @@ -197,7 +197,7 @@ namespace openvpn { template inline BufferPtr string_to_utf16(const STRING& str) { - ScopedPtr utf16_dest(new UTF16[str.length()]); + std::unique_ptr utf16_dest(new UTF16[str.length()]); const UTF8 *src = (UTF8 *)str.c_str(); UTF16 *dest = utf16_dest.get(); const ConversionResult res = ConvertUTF8toUTF16(&src, src + str.length(), diff --git a/openvpn/openssl/util/free.hpp b/openvpn/common/uniqueptr.hpp similarity index 78% rename from openvpn/openssl/util/free.hpp rename to openvpn/common/uniqueptr.hpp index f430dc87b..c75256fe9 100644 --- a/openvpn/openssl/util/free.hpp +++ b/openvpn/common/uniqueptr.hpp @@ -19,24 +19,15 @@ // along with this program in the COPYING file. // If not, see . -// deallocator for objects that were allocated by OpenSSL +#ifndef OPENVPN_COMMON_UNIQUEPTR_H +#define OPENVPN_COMMON_UNIQUEPTR_H -#ifndef OPENVPN_OPENSSL_UTIL_FREE_H -#define OPENVPN_OPENSSL_UTIL_FREE_H - -#include +#include +#include namespace openvpn { - - template - class OpenSSLFree { - public: - static void del(T* p) - { - OPENSSL_free (p); - } - }; - + template + using unique_ptr_del = std::unique_ptr>; } #endif diff --git a/openvpn/netconf/enumiface.hpp b/openvpn/netconf/enumiface.hpp index e1b298517..cb78d6a7a 100644 --- a/openvpn/netconf/enumiface.hpp +++ b/openvpn/netconf/enumiface.hpp @@ -37,10 +37,10 @@ #include #include #include +#include #include #include -#include #include namespace openvpn { @@ -50,8 +50,8 @@ namespace openvpn { OPENVPN_EXCEPTION(enum_iface_error); EnumIface() + : ifinfo(alloc_if_addrs(), free_if_addrs) { - getifaddrs(ifinfo.ref()); } std::string to_string() const @@ -198,17 +198,20 @@ namespace openvpn { return ret; } - template - class FreeIFAddrs { - public: - static void del(T* p) - { - // delete method for pointer returned by getifaddrs - freeifaddrs(p); - } - }; + static ifaddrs* alloc_if_addrs() + { + ifaddrs* ifa = nullptr; + ::getifaddrs(&ifa); + return ifa; + } + + static void free_if_addrs(ifaddrs* p) + { + // delete method for pointer returned by getifaddrs + freeifaddrs(p); + } - ScopedPtr ifinfo; + std::unique_ptr ifinfo; }; } diff --git a/openvpn/openssl/ssl/sslctx.hpp b/openvpn/openssl/ssl/sslctx.hpp index 8d2ad2b0e..eb9d7b312 100644 --- a/openvpn/openssl/ssl/sslctx.hpp +++ b/openvpn/openssl/ssl/sslctx.hpp @@ -36,9 +36,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -56,7 +56,6 @@ #include #include #include -#include // An SSL Context is essentially a configuration that can be used // to generate an arbitrary number of actual SSL connections objects. @@ -991,8 +990,9 @@ namespace openvpn { static std::string x509_get_subject(::X509 *cert) { - ScopedPtr subject(X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0)); - if (subject.defined()) + unique_ptr_del subject(X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0), + [](char* p) { OPENSSL_free(p); }); + if (subject) return std::string(subject.get()); else return std::string(""); diff --git a/openvpn/polarssl/ssl/sslctx.hpp b/openvpn/polarssl/ssl/sslctx.hpp index b943cb2c3..e5bf54129 100644 --- a/openvpn/polarssl/ssl/sslctx.hpp +++ b/openvpn/polarssl/ssl/sslctx.hpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -36,7 +37,6 @@ #include #include -#include #include #include #include @@ -1002,10 +1002,10 @@ namespace openvpn { static std::string cert_info(const x509_crt *cert, const char *prefix = NULL) { const size_t buf_size = 4096; - ScopedPtr buf(new char[buf_size]); - const int size = x509_crt_info(buf(), buf_size, prefix ? prefix : "", cert); + std::unique_ptr buf(new char[buf_size]); + const int size = x509_crt_info(buf.get(), buf_size, prefix ? prefix : "", cert); if (size >= 0) - return std::string(buf()); + return std::string(buf.get()); else return "error rendering cert"; } diff --git a/openvpn/ssl/proto.hpp b/openvpn/ssl/proto.hpp index 2b6583a40..4895c5624 100644 --- a/openvpn/ssl/proto.hpp +++ b/openvpn/ssl/proto.hpp @@ -30,6 +30,7 @@ #include #include // for std::min #include // for std::uint32_t, etc. +#include #include // for boost::algorithm::starts_with @@ -43,7 +44,6 @@ #include #include #include -#include #include #include #include @@ -1307,7 +1307,7 @@ namespace openvpn { { if (crypto) crypto->rekey(type); - else if (data_channel_key.defined()) + else if (data_channel_key) { // save for deferred processing data_channel_key->rekey_type = type; @@ -1435,7 +1435,7 @@ namespace openvpn { void init_data_channel() { // set up crypto for data channel - if (data_channel_key.defined()) + if (data_channel_key) { bool enable_compress = true; Config& c = *proto.config; @@ -1757,7 +1757,7 @@ namespace openvpn { // the data channel crypto context void generate_session_keys() { - ScopedPtr dck(new DataChannelKey()); + std::unique_ptr dck(new DataChannelKey()); tlsprf->generate_key_expansion(dck->key, proto.psid_self, proto.psid_peer); OPENVPN_LOG_PROTO_VERBOSE("KEY " << proto.mode().str() << ' ' << dck->key.render()); tlsprf->erase(); @@ -2102,7 +2102,7 @@ namespace openvpn { EventType current_event; EventType next_event; std::deque app_pre_write_queue; - ScopedPtr data_channel_key; + std::unique_ptr data_channel_key; }; public: diff --git a/openvpn/transport/tcplink.hpp b/openvpn/transport/tcplink.hpp index 7a79d3a5d..fa7446b6c 100644 --- a/openvpn/transport/tcplink.hpp +++ b/openvpn/transport/tcplink.hpp @@ -26,11 +26,11 @@ #include #include // for std::move +#include #include #include -#include #include #include #include @@ -58,7 +58,7 @@ namespace openvpn { struct PacketFrom { - typedef ScopedPtr SPtr; + typedef std::unique_ptr SPtr; BufferAllocated buf; }; diff --git a/openvpn/transport/udplink.hpp b/openvpn/transport/udplink.hpp index f491ddbcc..e7921f16e 100644 --- a/openvpn/transport/udplink.hpp +++ b/openvpn/transport/udplink.hpp @@ -24,10 +24,11 @@ #ifndef OPENVPN_TRANSPORT_UDPLINK_H #define OPENVPN_TRANSPORT_UDPLINK_H +#include + #include #include -#include #include #include #include @@ -57,7 +58,7 @@ namespace openvpn { struct PacketFrom { - typedef ScopedPtr SPtr; + typedef std::unique_ptr SPtr; BufferAllocated buf; AsioEndpoint sender_endpoint; }; diff --git a/openvpn/tun/builder/client.hpp b/openvpn/tun/builder/client.hpp index 0fb6b7840..f50ed23f1 100644 --- a/openvpn/tun/builder/client.hpp +++ b/openvpn/tun/builder/client.hpp @@ -26,6 +26,8 @@ #ifndef OPENVPN_TUN_BUILDER_CLIENT_H #define OPENVPN_TUN_BUILDER_CLIENT_H +#include + #include #include #include @@ -39,7 +41,7 @@ namespace openvpn { // struct used to pass received tun packets struct PacketFrom { - typedef ScopedPtr SPtr; + typedef std::unique_ptr SPtr; BufferAllocated buf; }; diff --git a/openvpn/tun/linux/tun.hpp b/openvpn/tun/linux/tun.hpp index 08f7435b5..e62c99b49 100644 --- a/openvpn/tun/linux/tun.hpp +++ b/openvpn/tun/linux/tun.hpp @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -43,7 +44,7 @@ namespace openvpn { struct PacketFrom { - typedef ScopedPtr SPtr; + typedef std::unique_ptr SPtr; BufferAllocated buf; }; diff --git a/openvpn/tun/mac/client/tuncli.hpp b/openvpn/tun/mac/client/tuncli.hpp index 3b745df0b..098cc12fa 100644 --- a/openvpn/tun/mac/client/tuncli.hpp +++ b/openvpn/tun/mac/client/tuncli.hpp @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -174,7 +175,7 @@ namespace openvpn { // struct used to pass received tun packets struct PacketFrom { - typedef ScopedPtr SPtr; + typedef std::unique_ptr SPtr; BufferAllocated buf; }; diff --git a/openvpn/tun/mac/gwv4.hpp b/openvpn/tun/mac/gwv4.hpp index c7257dbda..50cea4249 100644 --- a/openvpn/tun/mac/gwv4.hpp +++ b/openvpn/tun/mac/gwv4.hpp @@ -35,11 +35,11 @@ #include #include // for std::max #include // for std::uint32_t +#include #include #include #include -#include #include #include #include @@ -195,7 +195,7 @@ namespace openvpn { struct ifreq *ifr; const int bufsize = 4096; - ScopedPtr buffer(new char[bufsize]); + std::unique_ptr buffer(new char[bufsize]); std::memset(buffer.get(), 0, bufsize); sockfd.reset(socket(AF_INET, SOCK_DGRAM, 0)); if (!sockfd.defined()) diff --git a/openvpn/tun/mac/macdns.hpp b/openvpn/tun/mac/macdns.hpp index 6547575a8..6c880dbd0 100644 --- a/openvpn/tun/mac/macdns.hpp +++ b/openvpn/tun/mac/macdns.hpp @@ -26,13 +26,13 @@ #include #include +#include #include // for boost::algorithm::starts_with #include #include #include -#include #include #include #include @@ -430,15 +430,15 @@ namespace openvpn { void restore_orig() { const CFIndex size = CFDictionaryGetCount(dict()); - ScopedPtr keys(new const void *[size]); - ScopedPtr values(new const void *[size]); - CFDictionaryGetKeysAndValues(dict(), keys(), values()); + std::unique_ptr keys(new const void *[size]); + std::unique_ptr values(new const void *[size]); + CFDictionaryGetKeysAndValues(dict(), keys.get(), values.get()); const CF::String orig_prefix = orig_key(""); const CFIndex orig_prefix_len = CFStringGetLength(orig_prefix()); const CF::String delval = delete_value(); for (CFIndex i = 0; i < size; ++i) { - const CF::String key = CF::string_cast(keys()[i]); + const CF::String key = CF::string_cast(keys[i]); if (CFStringHasPrefix(key(), orig_prefix())) { const CFIndex key_len = CFStringGetLength(key()); @@ -446,7 +446,7 @@ namespace openvpn { { const CFRange r = CFRangeMake(orig_prefix_len, key_len - orig_prefix_len); const CF::String k(CFStringCreateWithSubstring(kCFAllocatorDefault, key(), r)); - const CFTypeRef v = values()[i]; + const CFTypeRef v = values[i]; const CF::String vstr = CF::string_cast(v); will_modify(); if (vstr.defined() && CFStringCompare(vstr(), delval(), 0) == kCFCompareEqualTo) diff --git a/openvpn/tun/win/client/tuncli.hpp b/openvpn/tun/win/client/tuncli.hpp index 9289de5c1..c4aff5cb8 100644 --- a/openvpn/tun/win/client/tuncli.hpp +++ b/openvpn/tun/win/client/tuncli.hpp @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -46,7 +47,7 @@ namespace openvpn { // struct used to pass received tun packets struct PacketFrom { - typedef ScopedPtr SPtr; + typedef std::unique_ptr SPtr; BufferAllocated buf; }; diff --git a/openvpn/tun/win/tunutil.hpp b/openvpn/tun/win/tunutil.hpp index b67d67b84..620213308 100644 --- a/openvpn/tun/win/tunutil.hpp +++ b/openvpn/tun/win/tunutil.hpp @@ -35,8 +35,8 @@ #include #include #include - #include // for std::uint32_t +#include #include @@ -46,8 +46,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -393,7 +393,7 @@ namespace openvpn { inline void tap_process_logging(HANDLE th) { const size_t size = 1024; - ScopedPtr line(new char[size]); + std::unique_ptr line(new char[size]); DWORD len; while (DeviceIoControl (th, TAP_WIN_IOCTL_GET_LOG_LINE, @@ -492,7 +492,7 @@ namespace openvpn { { ULONG size = 0; DWORD status; - ScopedPtr rt; + std::unique_ptr rt; status = GetIpForwardTable (NULL, &size, TRUE); if (status == ERROR_INSUFFICIENT_BUFFER) @@ -508,16 +508,6 @@ namespace openvpn { return rt.release(); } - // delete method for PMIB_IPFORWARD_TABLE2 - template - class FreeFwdTable2 { - public: - static void del(T* p) - { - FreeMibTable((PVOID)p); - } - }; - // Get the Windows IPv4/IPv6 routing table. // Note that returned pointer must be freed with FreeMibTable. inline const MIB_IPFORWARD_TABLE2* windows_routing_table2(ADDRESS_FAMILY af) @@ -537,7 +527,7 @@ namespace openvpn { DefaultGateway() : index(DWORD(-1)) { - ScopedPtr rt(windows_routing_table()); + std::unique_ptr rt(windows_routing_table()); if (rt.defined()) { const MIB_IPFORWARDROW* gw = NULL; @@ -601,7 +591,7 @@ namespace openvpn { private: static void remove_all_ipv4_routes_on_iface(DWORD index, ActionList& actions) { - ScopedPtr rt(windows_routing_table()); + std::unique_ptr rt(windows_routing_table()); if (rt.defined()) { for (size_t i = 0; i < rt()->dwNumEntries; ++i) @@ -628,7 +618,8 @@ namespace openvpn { static void remove_all_ipv6_routes_on_iface(DWORD index, ActionList& actions) { - ScopedPtr rt2(windows_routing_table2(AF_INET6)); + unique_ptr_del rt2(windows_routing_table2(AF_INET6), + [](const MIB_IPFORWARD_TABLE2* p) { FreeMibTable((PVOID)p); }); if (rt2.defined()) { const IPv6::Addr ll_net = IPv6::Addr::from_string("fe80::"); diff --git a/openvpn/win/call.hpp b/openvpn/win/call.hpp index 042c5d7bd..65557d1c1 100644 --- a/openvpn/win/call.hpp +++ b/openvpn/win/call.hpp @@ -27,7 +27,7 @@ #include #include -#include +#include #include namespace openvpn { @@ -35,16 +35,6 @@ namespace openvpn { OPENVPN_EXCEPTION(win_call); - // delete method for CoTask - template - class FreeCoTask { - public: - static void del(T* p) - { - CoTaskMemFree(p); - } - }; - inline std::string call(const std::string& cmd) { // split command name from args @@ -62,14 +52,15 @@ namespace openvpn { #if _WIN32_WINNT >= 0x0600 // get system path (Vista and higher) - ScopedPtr syspath; - if (SHGetKnownFolderPath(FOLDERID_System, 0, NULL, syspath.ref()) != S_OK) + wchar_t *syspath_ptr = nullptr; + if (SHGetKnownFolderPath(FOLDERID_System, 0, NULL, &syspath_ptr) != S_OK) throw win_call("cannot get system path using SHGetKnownFolderPath"); + unique_ptr_del syspath(syspath_ptr, [](wchar_t* p) { CoTaskMemFree(p); }); # define SYSPATH_FMT_CHAR L"s" # define SYSPATH_LEN_METH(x) wcslen(x) #else // get system path (XP and higher) - ScopedPtr syspath(new char[MAX_PATH]); + std::unique_ptr syspath(new char[MAX_PATH]); if (SHGetFolderPath(NULL, CSIDL_SYSTEM, NULL, 0, syspath()) != S_OK) throw win_call("cannot get system path using SHGetFolderPath"); # define SYSPATH_FMT_CHAR L"S" @@ -78,7 +69,7 @@ namespace openvpn { // build command line const size_t wcmdlen = SYSPATH_LEN_METH(syspath()) + name.length() + args.length() + 64; - ScopedPtr wcmd(new wchar_t[wcmdlen]); + std::unique_ptr wcmd(new wchar_t[wcmdlen]); const char *spc = ""; if (!args.empty()) spc = " "; @@ -140,7 +131,7 @@ namespace openvpn { // read child's stdout const size_t outbuf_size = 512; - ScopedPtr outbuf(new char[outbuf_size]); + std::unique_ptr outbuf(new char[outbuf_size]); std::string out; while (true) { diff --git a/openvpn/win/unicode.hpp b/openvpn/win/unicode.hpp index 8643ffb48..f807aa2b9 100644 --- a/openvpn/win/unicode.hpp +++ b/openvpn/win/unicode.hpp @@ -22,17 +22,17 @@ #ifndef OPENVPN_WIN_UNICODE_H #define OPENVPN_WIN_UNICODE_H -#include - #include +#include +#include + #include #include -#include namespace openvpn { namespace Win { - typedef ScopedPtr UTF16; + typedef std::unique_ptr UTF16; OPENVPN_SIMPLE_EXCEPTION(win_utf16); @@ -52,7 +52,7 @@ namespace openvpn { 0, str.c_str(), -1, - ret(), + ret.get(), len); if (len != len2) throw win_utf16();