Hi,
Sorry for the long delay in getting back to this..
On Tue, Feb 22, 2022 at 9:13 AM Lev Stipakov <lstipakov@gmail.com> wrote:
> From: Lev Stipakov <lev@openvpn.net>
>
> We use M_ERRNO flag in logging to display error code
> and error message. This has been broken on Windows,
> where we use error code from GetLastError() and
> error description from strerror(). strerror() expects
> C runtime error code, which is quite different from
> last error code from WinAPI call. As a result, we got
> incorrect error description.
>
> The ultimate fix would be introducing another flag
> for WinAPI errors, like M_WINERR and use either that or
> M_ERRNO depends on context. However, the change would be
> quite intrusive and in some cases it is hard to say which
> one to use without looking into internals.
>
> Instead we stick to M_ERRNO and in Windows case we
> first try to obtain error code from GetLastError() and
> if it returns ERROR_SUCCESS (which is 0), we assume that
> we have C runtime error and use errno. To get error
> description we use strerror_win32() with GetLastError()
> and strerror() with errno.
>
> strerror_win32() uses FormatMessage() internally, which
> is the right way to get WinAPI error description.
>
> While on it, add a new flag M_SKERR to display socket
> error. On Linux it is resolved into M_ERRNO and on Windows
> to an conjunction of another new flag M_WSAERR and M_ERRNO.
> With M_WSAERR we use WSAGetLastError() to get error code
> and strerror_win32() to get error description.
> WSAGetLastError() is a correct way to get WinSock error code,
> according to documentation.
>
> Signed-off-by: Lev Stipakov <lev@openvpn.net>
> ---
> src/openvpn/error.c | 26 ++++++++++++++++++++++----
> src/openvpn/error.h | 11 ++++++++++-
> src/openvpn/manage.c | 4 ++--
> src/openvpn/mtu.c | 2 +-
> src/openvpn/platform.c | 2 +-
> src/openvpn/proxy.c | 8 ++++----
> src/openvpn/ps.c | 2 +-
> src/openvpn/socket.c | 20 ++++++++++----------
> src/openvpn/socket.h | 6 ++++++
> src/openvpn/socks.c | 26 +++++++++++++-------------
> 10 files changed, 70 insertions(+), 37 deletions(-)
>
> diff --git a/src/openvpn/error.c b/src/openvpn/error.c
> index b0e9a48c..5da588d9 100644
> --- a/src/openvpn/error.c
> +++ b/src/openvpn/error.c
> @@ -242,7 +242,25 @@ x_msg_va(const unsigned int flags, const char
> *format, va_list arglist)
> return;
> }
>
> - e = openvpn_errno();
> + bool use_strerr = false;
> +#ifdef _WIN32
> + if (flags & M_WSAERR)
> + {
> + e = WSAGetLastError();
> + }
> + else
> + {
> + e = GetLastError();
> + if (e == ERROR_SUCCESS)
> + {
> + /* error is likely C runtime, fallback to errno/strerr */
> + use_strerr = true;
> + e = errno;
> + }
> + }
> +#else
> + e = errno;
> +#endif
>
>
Ideally I would have liked to modify openvpn_errno() and
openvpn_strerror() to do the right thing instead of adding this logic here
and below. I have not worked out what exactly that would entail -- most
likely those two functions would require an extra argument to keep track of
the kind of error.
Also there are some places openvpn_errno() is used and the result checked
against POSIX error codes:
in forward.c around line 2102:
if (.... && ENETUNREACH == error_code && ...)
where error_code = openvpn_errno() which may return WSAENETUNREACH on
Windows not ENETUNREACH-- even that depends on GetLastError() and
WSAGetLastError() to behave identically.
Also does code like the below in socket.c do the right thing?
(around line 1451 in socket.c)
status = openvpn_errno();
if (status == WSAEWOULDBLOCK) ....
but openvpn_errono() doesn't look for WSA errors (though it probably still
works?).
/*
> * Apply muting filter.
> @@ -264,7 +282,7 @@ x_msg_va(const unsigned int flags, const char *format,
> va_list arglist)
> if ((flags & M_ERRNO) && e)
> {
> openvpn_snprintf(m2, ERR_BUF_SIZE, "%s: %s (errno=%d)",
> - m1, strerror(e), e);
> + m1, use_strerr ? strerror(e) :
> openvpn_strerror(e, &gc), e);
> SWAP;
> }
>
> @@ -678,13 +696,13 @@ x_check_status(int status,
> {
> msg(x_cs_info_level, "%s %s [%s]: %s (fd=%d,code=%d)",
> description,
> sock ? proto2ascii(sock->info.proto, sock->info.af,
> true) : "",
> - extended_msg, strerror(my_errno), sock ? sock->sd :
> -1, my_errno);
> + extended_msg, openvpn_strerror(my_errno, &gc), sock ?
> sock->sd : -1, my_errno);
>
Here my_errno = openvpn_errno() -- don't we need the fallback to POSIX
errno in this case? Could this also get called when a socket error is
expected?
> }
> else
> {
> msg(x_cs_info_level, "%s %s: %s (fd=%d,code=%d)",
> description,
> sock ? proto2ascii(sock->info.proto, sock->info.af,
> true) : "",
> - strerror(my_errno), sock ? sock->sd : -1, my_errno);
> + openvpn_strerror(my_errno, &gc), sock ? sock->sd :
> -1, my_errno);
> }
>
> if (x_cs_err_delay_ms)
> diff --git a/src/openvpn/error.h b/src/openvpn/error.h
> index ad7defe8..9c3f4dfb 100644
> --- a/src/openvpn/error.h
> +++ b/src/openvpn/error.h
> @@ -99,9 +99,18 @@ extern int x_msg_line_num;
> #define M_NONFATAL (1<<5) /* non-fatal error */
> #define M_WARN (1<<6) /* call syslog with LOG_WARNING
> */
> #define M_DEBUG (1<<7)
> -
> #define M_ERRNO (1<<8) /* show errno description */
>
> +#ifdef _WIN32
> +#define M_WSAERR (1<<9) /* WinSock errors */
> +#endif
> +
> +#ifdef _WIN32
> +#define M_SKERR (M_ERRNO | M_WSAERR) /* socket errors */
> +#else
> +#define M_SKERR M_ERRNO
> +#endif
>
The two ifdefs could be combined into one.
The rest looks good to me.
> +
> #define M_NOMUTE (1<<11) /* don't do mute processing */
> #define M_NOPREFIX (1<<12) /* don't show date/time prefix */
> #define M_USAGE_SMALL (1<<13) /* fatal options error, call
> usage_small */
> diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c
> index 496042a6..2fa508ef 100644
> --- a/src/openvpn/manage.c
> +++ b/src/openvpn/manage.c
> @@ -1890,13 +1890,13 @@ man_connect(struct management *man)
> #if UNIX_SOCK_SUPPORT
> if (man->settings.flags & MF_UNIX_SOCK)
> {
> - msg(D_LINK_ERRORS | M_ERRNO,
> + msg(D_LINK_ERRORS | M_SKERR,
> "MANAGEMENT: connect to unix socket %s failed",
> sockaddr_unix_name(&man->settings.local_unix, "NULL"));
> }
> else
> #endif
> - msg(D_LINK_ERRORS | M_ERRNO,
> + msg(D_LINK_ERRORS | M_SKERR,
> "MANAGEMENT: connect to %s failed",
> print_sockaddr(man->settings.local->ai_addr, &gc));
> throw_signal_soft(SIGTERM, "management-connect-failed");
> diff --git a/src/openvpn/mtu.c b/src/openvpn/mtu.c
> index aa810f1c..45398953 100644
> --- a/src/openvpn/mtu.c
> +++ b/src/openvpn/mtu.c
> @@ -407,7 +407,7 @@ set_sock_extended_error_passing(int sd)
> int on = 1;
> if (setsockopt(sd, SOL_IP, IP_RECVERR, (void *) &on, sizeof(on)))
> {
> - msg(M_WARN | M_ERRNO,
> + msg(M_WARN | M_SKERR,
> "Note: enable extended error passing on TCP/UDP socket failed
> (IP_RECVERR)");
> }
> }
> diff --git a/src/openvpn/platform.c b/src/openvpn/platform.c
> index 450f28ba..1aafd604 100644
> --- a/src/openvpn/platform.c
> +++ b/src/openvpn/platform.c
> @@ -532,7 +532,7 @@ platform_test_file(const char *filename)
> }
> else
> {
> - if (openvpn_errno() == EACCES)
> + if (errno == EACCES)
> {
> msg( M_WARN | M_ERRNO, "Could not access file '%s'",
> filename);
> }
> diff --git a/src/openvpn/proxy.c b/src/openvpn/proxy.c
> index ed720161..409bc4af 100644
> --- a/src/openvpn/proxy.c
> +++ b/src/openvpn/proxy.c
> @@ -110,7 +110,7 @@ recv_line(socket_descriptor_t sd,
> {
> if (verbose)
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "recv_line: TCP port read
> timeout expired");
> + msg(D_LINK_ERRORS | M_SKERR, "recv_line: TCP port read
> timeout expired");
> }
> goto error;
> }
> @@ -120,7 +120,7 @@ recv_line(socket_descriptor_t sd,
> {
> if (verbose)
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "recv_line: TCP port read
> failed on select()");
> + msg(D_LINK_ERRORS | M_SKERR, "recv_line: TCP port read
> failed on select()");
> }
> goto error;
> }
> @@ -133,7 +133,7 @@ recv_line(socket_descriptor_t sd,
> {
> if (verbose)
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "recv_line: TCP port read
> failed on recv()");
> + msg(D_LINK_ERRORS | M_SKERR, "recv_line: TCP port read
> failed on recv()");
> }
> goto error;
> }
> @@ -199,7 +199,7 @@ send_line(socket_descriptor_t sd,
> const ssize_t size = send(sd, buf, strlen(buf), MSG_NOSIGNAL);
> if (size != (ssize_t) strlen(buf))
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "send_line: TCP port write failed on
> send()");
> + msg(D_LINK_ERRORS | M_SKERR, "send_line: TCP port write failed on
> send()");
> return false;
> }
> return true;
> diff --git a/src/openvpn/ps.c b/src/openvpn/ps.c
> index 9dca53c8..64cc1ed3 100644
> --- a/src/openvpn/ps.c
> +++ b/src/openvpn/ps.c
> @@ -429,7 +429,7 @@ proxy_entry_new(struct proxy_connection **list,
> /* connect to port share server */
> if ((sd_server = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
> {
> - msg(M_WARN|M_ERRNO, "PORT SHARE PROXY: cannot create socket");
> + msg(M_WARN|M_SKERR, "PORT SHARE PROXY: cannot create socket");
> return false;
> }
> status = openvpn_connect(sd_server,(const struct sockaddr *)
> &server_addr, 5, NULL);
> diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c
> index 0f34a5de..acfcfd65 100644
> --- a/src/openvpn/socket.c
> +++ b/src/openvpn/socket.c
> @@ -1143,7 +1143,7 @@ create_socket(struct link_socket *sock, struct
> addrinfo *addr)
> msg(M_INFO, "Using bind-dev %s", sock->bind_dev);
> if (setsockopt(sock->sd, SOL_SOCKET, SO_BINDTODEVICE,
> sock->bind_dev, strlen(sock->bind_dev) + 1) != 0)
> {
> - msg(M_WARN|M_ERRNO, "WARN: setsockopt SO_BINDTODEVICE=%s
> failed", sock->bind_dev);
> + msg(M_WARN|M_SKERR, "WARN: setsockopt SO_BINDTODEVICE=%s
> failed", sock->bind_dev);
> }
>
> }
> @@ -1222,7 +1222,7 @@ socket_do_accept(socket_descriptor_t sd,
>
> if (!socket_defined(new_sd))
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "TCP: getpeername() failed");
> + msg(D_LINK_ERRORS | M_SKERR, "TCP: getpeername() failed");
> }
> else
> {
> @@ -1247,7 +1247,7 @@ socket_do_accept(socket_descriptor_t sd,
>
> if (!socket_defined(new_sd))
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "TCP: accept(%d) failed", (int)sd);
> + msg(D_LINK_ERRORS | M_SKERR, "TCP: accept(%d) failed", (int)sd);
> }
> /* only valid if we have remote_len_af!=0 */
> else if (remote_len_af && remote_len != remote_len_af)
> @@ -1313,7 +1313,7 @@ socket_listen_accept(socket_descriptor_t sd,
>
> if (status < 0)
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "TCP: select() failed");
> + msg(D_LINK_ERRORS | M_SKERR, "TCP: select() failed");
> }
>
> if (status <= 0)
> @@ -1409,12 +1409,12 @@ socket_bind(socket_descriptor_t sd,
> msg(M_INFO, "setsockopt(IPV6_V6ONLY=%d)", v6only);
> if (setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, (void *) &v6only,
> sizeof(v6only)))
> {
> - msg(M_NONFATAL|M_ERRNO, "Setting IPV6_V6ONLY=%d failed",
> v6only);
> + msg(M_NONFATAL | M_SKERR, "Setting IPV6_V6ONLY=%d failed",
> v6only);
> }
> }
> if (bind(sd, cur->ai_addr, cur->ai_addrlen))
> {
> - msg(M_FATAL | M_ERRNO, "%s: Socket bind failed on local address
> %s",
> + msg(M_FATAL | M_SKERR, "%s: Socket bind failed on local address
> %s",
> prefix,
> print_sockaddr_ex(local->ai_addr, ":", PS_SHOW_PORT, &gc));
> }
> @@ -2254,7 +2254,7 @@ link_socket_close(struct link_socket *sock)
> msg(D_LOW, "TCP/UDP: Closing socket");
> if (openvpn_close_socket(sock->sd))
> {
> - msg(M_WARN | M_ERRNO, "TCP/UDP: Close Socket failed");
> + msg(M_WARN | M_SKERR, "TCP/UDP: Close Socket failed");
> }
> }
> sock->sd = SOCKET_UNDEFINED;
> @@ -2271,7 +2271,7 @@ link_socket_close(struct link_socket *sock)
> {
> if (openvpn_close_socket(sock->ctrl_sd))
> {
> - msg(M_WARN | M_ERRNO, "TCP/UDP: Close Socket (ctrl_sd)
> failed");
> + msg(M_WARN | M_SKERR, "TCP/UDP: Close Socket (ctrl_sd)
> failed");
> }
> sock->ctrl_sd = SOCKET_UNDEFINED;
> }
> @@ -3668,7 +3668,7 @@ sockethandle_finalize(sockethandle_t sh,
> /* if no error (i.e. just not finished yet), then
> DON'T execute this code */
> io->iostate = IOSTATE_INITIAL;
> ASSERT(ResetEvent(io->overlapped.hEvent));
> - msg(D_WIN32_IO | M_ERRNO, "WIN32 I/O: Completion
> error");
> + msg(D_WIN32_IO | SocketHandleErrorFlag(sh), "WIN32
> I/O: Completion error");
> }
> }
> break;
> @@ -3681,7 +3681,7 @@ sockethandle_finalize(sockethandle_t sh,
> /* error return for a non-queued operation */
> SocketHandleSetLastError(sh, io->status);
> ret = -1;
> - msg(D_WIN32_IO | M_ERRNO, "WIN32 I/O: Completion
> non-queued error");
> + msg(D_WIN32_IO | SocketHandleErrorFlag(sh), "WIN32 I/O:
> Completion non-queued error");
> }
> else
> {
> diff --git a/src/openvpn/socket.h b/src/openvpn/socket.h
> index e9f1524d..a7ec827a 100644
> --- a/src/openvpn/socket.h
> +++ b/src/openvpn/socket.h
> @@ -301,6 +301,12 @@ SocketHandleSetInvalError(sockethandle_t sh)
> sh.is_handle ? SetLastError(ERROR_INVALID_FUNCTION) :
> WSASetLastError(WSAEINVAL);
> }
>
> +static inline int
> +SocketHandleErrorFlag(sockethandle_t sh)
> +{
> + return sh.is_handle ? M_ERRNO : M_SKERR;
> +}
> +
> #else /* ifdef _WIN32 */
>
> #define openvpn_close_socket(s) close(s)
> diff --git a/src/openvpn/socks.c b/src/openvpn/socks.c
> index 768bb613..10107c18 100644
> --- a/src/openvpn/socks.c
> +++ b/src/openvpn/socks.c
> @@ -117,7 +117,7 @@ socks_username_password_auth(struct socks_proxy_info
> *p,
>
> if (size != strlen(to_send))
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP
> port write failed on send()");
> + msg(D_LINK_ERRORS | M_SKERR, "socks_username_password_auth: TCP
> port write failed on send()");
> goto cleanup;
> }
>
> @@ -145,14 +145,14 @@ socks_username_password_auth(struct socks_proxy_info
> *p,
> /* timeout? */
> if (status == 0)
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth:
> TCP port read timeout expired");
> + msg(D_LINK_ERRORS | M_SKERR, "socks_username_password_auth:
> TCP port read timeout expired");
> goto cleanup;
> }
>
> /* error */
> if (status < 0)
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth:
> TCP port read failed on select()");
> + msg(D_LINK_ERRORS | M_SKERR, "socks_username_password_auth:
> TCP port read failed on select()");
> goto cleanup;
> }
>
> @@ -162,7 +162,7 @@ socks_username_password_auth(struct socks_proxy_info
> *p,
> /* error? */
> if (size != 1)
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth:
> TCP port read failed on recv()");
> + msg(D_LINK_ERRORS | M_SKERR, "socks_username_password_auth:
> TCP port read failed on recv()");
> goto cleanup;
> }
>
> @@ -204,7 +204,7 @@ socks_handshake(struct socks_proxy_info *p,
> size = send(sd, method_sel, sizeof(method_sel), MSG_NOSIGNAL);
> if (size != sizeof(method_sel))
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port write
> failed on send()");
> + msg(D_LINK_ERRORS | M_SKERR, "socks_handshake: TCP port write
> failed on send()");
> return false;
> }
>
> @@ -232,14 +232,14 @@ socks_handshake(struct socks_proxy_info *p,
> /* timeout? */
> if (status == 0)
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read
> timeout expired");
> + msg(D_LINK_ERRORS | M_SKERR, "socks_handshake: TCP port read
> timeout expired");
> return false;
> }
>
> /* error */
> if (status < 0)
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read
> failed on select()");
> + msg(D_LINK_ERRORS | M_SKERR, "socks_handshake: TCP port read
> failed on select()");
> return false;
> }
>
> @@ -249,7 +249,7 @@ socks_handshake(struct socks_proxy_info *p,
> /* error? */
> if (size != 1)
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read
> failed on recv()");
> + msg(D_LINK_ERRORS | M_SKERR, "socks_handshake: TCP port read
> failed on recv()");
> return false;
> }
>
> @@ -342,14 +342,14 @@ recv_socks_reply(socket_descriptor_t sd,
> /* timeout? */
> if (status == 0)
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read
> timeout expired");
> + msg(D_LINK_ERRORS | M_SKERR, "recv_socks_reply: TCP port read
> timeout expired");
> return false;
> }
>
> /* error */
> if (status < 0)
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read
> failed on select()");
> + msg(D_LINK_ERRORS | M_SKERR, "recv_socks_reply: TCP port read
> failed on select()");
> return false;
> }
>
> @@ -359,7 +359,7 @@ recv_socks_reply(socket_descriptor_t sd,
> /* error? */
> if (size != 1)
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read
> failed on recv()");
> + msg(D_LINK_ERRORS | M_SKERR, "recv_socks_reply: TCP port read
> failed on recv()");
> return false;
> }
>
> @@ -484,7 +484,7 @@ establish_socks_proxy_passthru(struct socks_proxy_info
> *p,
> const ssize_t size = send(sd, buf, 5 + len + 2, MSG_NOSIGNAL);
> if ((int)size != 5 + (int)len + 2)
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "establish_socks_proxy_passthru:
> TCP port write failed on send()");
> + msg(D_LINK_ERRORS | M_SKERR, "establish_socks_proxy_passthru:
> TCP port write failed on send()");
> goto error;
> }
> }
> @@ -527,7 +527,7 @@ establish_socks_proxy_udpassoc(struct socks_proxy_info
> *p,
> 10, MSG_NOSIGNAL);
> if (size != 10)
> {
> - msg(D_LINK_ERRORS | M_ERRNO, "establish_socks_proxy_passthru:
> TCP port write failed on send()");
> + msg(D_LINK_ERRORS | M_SKERR, "establish_socks_proxy_passthru:
> TCP port write failed on send()");
> goto error;
> }
> }
> --
>
All that said, it may be hard to get all error reporting fixed in one
patch, so we could proceed in steps. First make openvpn_errno() and
openvpn_strerror() do the right thing with GetLastError() vs errno, then
fix WSA error printing, then the rest if any. Just a thought.
Selva
<div dir="ltr"><div>Hi,</div><div><br></div><div>Sorry for the long delay in getting back to this.. </div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Feb 22, 2022 at 9:13 AM Lev Stipakov <<a href="mailto:lstipakov@gmail.com" target="_blank">lstipakov@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">From: Lev Stipakov <<a href="mailto:lev@openvpn.net" target="_blank">lev@openvpn.net</a>><br>
<br>
We use M_ERRNO flag in logging to display error code<br>
and error message. This has been broken on Windows,<br>
where we use error code from GetLastError() and<br>
error description from strerror(). strerror() expects<br>
C runtime error code, which is quite different from<br>
last error code from WinAPI call. As a result, we got<br>
incorrect error description.<br>
<br>
The ultimate fix would be introducing another flag<br>
for WinAPI errors, like M_WINERR and use either that or<br>
M_ERRNO depends on context. However, the change would be<br>
quite intrusive and in some cases it is hard to say which<br>
one to use without looking into internals.<br>
<br>
Instead we stick to M_ERRNO and in Windows case we<br>
first try to obtain error code from GetLastError() and<br>
if it returns ERROR_SUCCESS (which is 0), we assume that<br>
we have C runtime error and use errno. To get error<br>
description we use strerror_win32() with GetLastError()<br>
and strerror() with errno.<br>
<br>
strerror_win32() uses FormatMessage() internally, which<br>
is the right way to get WinAPI error description.<br>
<br>
While on it, add a new flag M_SKERR to display socket<br>
error. On Linux it is resolved into M_ERRNO and on Windows<br>
to an conjunction of another new flag M_WSAERR and M_ERRNO.<br>
With M_WSAERR we use WSAGetLastError() to get error code<br>
and strerror_win32() to get error description.<br>
WSAGetLastError() is a correct way to get WinSock error code,<br>
according to documentation.<br>
<br>
Signed-off-by: Lev Stipakov <<a href="mailto:lev@openvpn.net" target="_blank">lev@openvpn.net</a>><br>
---<br>
src/openvpn/error.c | 26 ++++++++++++++++++++++----<br>
src/openvpn/error.h | 11 ++++++++++-<br>
src/openvpn/manage.c | 4 ++--<br>
src/openvpn/mtu.c | 2 +-<br>
src/openvpn/platform.c | 2 +-<br>
src/openvpn/proxy.c | 8 ++++----<br>
src/openvpn/ps.c | 2 +-<br>
src/openvpn/socket.c | 20 ++++++++++----------<br>
src/openvpn/socket.h | 6 ++++++<br>
src/openvpn/socks.c | 26 +++++++++++++-------------<br>
10 files changed, 70 insertions(+), 37 deletions(-)<br>
<br>
diff --git a/src/openvpn/error.c b/src/openvpn/error.c<br>
index b0e9a48c..5da588d9 100644<br>
--- a/src/openvpn/error.c<br>
+++ b/src/openvpn/error.c<br>
@@ -242,7 +242,25 @@ x_msg_va(const unsigned int flags, const char *format, va_list arglist)<br>
return;<br>
}<br>
<br>
- e = openvpn_errno();<br>
+ bool use_strerr = false;<br>
+#ifdef _WIN32<br>
+ if (flags & M_WSAERR)<br>
+ {<br>
+ e = WSAGetLastError();<br>
+ }<br>
+ else<br>
+ {<br>
+ e = GetLastError();<br>
+ if (e == ERROR_SUCCESS)<br>
+ {<br>
+ /* error is likely C runtime, fallback to errno/strerr */<br>
+ use_strerr = true;<br>
+ e = errno;<br>
+ }<br>
+ }<br>
+#else<br>
+ e = errno;<br>
+#endif<br>
<br></blockquote><div><br></div><div>Ideally I would have liked to modify openvpn_errno() and openvpn_strerror() to do the right thing instead of adding this logic here and below. I have not worked out what exactly that would entail -- most likely those two functions would require an extra argument to keep track of the kind of error.</div><div><br></div><div>Also there are some places openvpn_errno() is used and the result checked against POSIX error codes:</div><div><div>in forward.c around line 2102:</div><div><br></div><div>if (.... && ENETUNREACH == error_code && ...)</div><div><br></div><div>where error_code = openvpn_errno() which may return WSAENETUNREACH on Windows not ENETUNREACH-- even that depends on GetLastError() and WSAGetLastError() to behave identically.</div></div><div><br></div><div>Also does code like the below in socket.c do the right thing?</div><div>(around line 1451 in socket.c)</div><div>status = openvpn_errno(); </div><div>if (status == WSAEWOULDBLOCK) ....</div><div>but openvpn_errono() doesn't look for WSA errors (though it probably still works?).</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
/*<br>
* Apply muting filter.<br>
@@ -264,7 +282,7 @@ x_msg_va(const unsigned int flags, const char *format, va_list arglist)<br>
if ((flags & M_ERRNO) && e)<br>
{<br>
openvpn_snprintf(m2, ERR_BUF_SIZE, "%s: %s (errno=%d)",<br>
- m1, strerror(e), e);<br>
+ m1, use_strerr ? strerror(e) : openvpn_strerror(e, &gc), e);<br>
SWAP;<br>
}<br>
<br>
@@ -678,13 +696,13 @@ x_check_status(int status,<br>
{<br>
msg(x_cs_info_level, "%s %s [%s]: %s (fd=%d,code=%d)", description,<br>
sock ? proto2ascii(sock->info.proto, sock-><a href="http://info.af" rel="noreferrer" target="_blank">info.af</a>, true) : "",<br>
- extended_msg, strerror(my_errno), sock ? sock->sd : -1, my_errno);<br>
+ extended_msg, openvpn_strerror(my_errno, &gc), sock ? sock->sd : -1, my_errno);<br></blockquote><div><br></div><div>Here my_errno = openvpn_errno() -- don't we need the fallback to POSIX errno in this case? Could this also get called when a socket error is expected?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
}<br>
else<br>
{<br>
msg(x_cs_info_level, "%s %s: %s (fd=%d,code=%d)", description,<br>
sock ? proto2ascii(sock->info.proto, sock-><a href="http://info.af" rel="noreferrer" target="_blank">info.af</a>, true) : "",<br>
- strerror(my_errno), sock ? sock->sd : -1, my_errno);<br>
+ openvpn_strerror(my_errno, &gc), sock ? sock->sd : -1, my_errno);<br>
}<br>
<br>
if (x_cs_err_delay_ms)<br>
diff --git a/src/openvpn/error.h b/src/openvpn/error.h<br>
index ad7defe8..9c3f4dfb 100644<br>
--- a/src/openvpn/error.h<br>
+++ b/src/openvpn/error.h<br>
@@ -99,9 +99,18 @@ extern int x_msg_line_num;<br>
#define M_NONFATAL (1<<5) /* non-fatal error */<br>
#define M_WARN (1<<6) /* call syslog with LOG_WARNING */<br>
#define M_DEBUG (1<<7)<br>
-<br>
#define M_ERRNO (1<<8) /* show errno description */<br>
<br>
+#ifdef _WIN32<br>
+#define M_WSAERR (1<<9) /* WinSock errors */<br>
+#endif<br>
+<br>
+#ifdef _WIN32<br>
+#define M_SKERR (M_ERRNO | M_WSAERR) /* socket errors */<br>
+#else<br>
+#define M_SKERR M_ERRNO<br>
+#endif<br></blockquote><div><br></div><div>The two ifdefs could be combined into one.</div><div><br></div><div>The rest looks good to me.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
#define M_NOMUTE (1<<11) /* don't do mute processing */<br>
#define M_NOPREFIX (1<<12) /* don't show date/time prefix */<br>
#define M_USAGE_SMALL (1<<13) /* fatal options error, call usage_small */<br>
diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c<br>
index 496042a6..2fa508ef 100644<br>
--- a/src/openvpn/manage.c<br>
+++ b/src/openvpn/manage.c<br>
@@ -1890,13 +1890,13 @@ man_connect(struct management *man)<br>
#if UNIX_SOCK_SUPPORT<br>
if (man->settings.flags & MF_UNIX_SOCK)<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO,<br>
+ msg(D_LINK_ERRORS | M_SKERR,<br>
"MANAGEMENT: connect to unix socket %s failed",<br>
sockaddr_unix_name(&man->settings.local_unix, "NULL"));<br>
}<br>
else<br>
#endif<br>
- msg(D_LINK_ERRORS | M_ERRNO,<br>
+ msg(D_LINK_ERRORS | M_SKERR,<br>
"MANAGEMENT: connect to %s failed",<br>
print_sockaddr(man->settings.local->ai_addr, &gc));<br>
throw_signal_soft(SIGTERM, "management-connect-failed");<br>
diff --git a/src/openvpn/mtu.c b/src/openvpn/mtu.c<br>
index aa810f1c..45398953 100644<br>
--- a/src/openvpn/mtu.c<br>
+++ b/src/openvpn/mtu.c<br>
@@ -407,7 +407,7 @@ set_sock_extended_error_passing(int sd)<br>
int on = 1;<br>
if (setsockopt(sd, SOL_IP, IP_RECVERR, (void *) &on, sizeof(on)))<br>
{<br>
- msg(M_WARN | M_ERRNO,<br>
+ msg(M_WARN | M_SKERR,<br>
"Note: enable extended error passing on TCP/UDP socket failed (IP_RECVERR)");<br>
}<br>
}<br>
diff --git a/src/openvpn/platform.c b/src/openvpn/platform.c<br>
index 450f28ba..1aafd604 100644<br>
--- a/src/openvpn/platform.c<br>
+++ b/src/openvpn/platform.c<br>
@@ -532,7 +532,7 @@ platform_test_file(const char *filename)<br>
}<br>
else<br>
{<br>
- if (openvpn_errno() == EACCES)<br>
+ if (errno == EACCES)<br>
{<br>
msg( M_WARN | M_ERRNO, "Could not access file '%s'", filename);<br>
}<br>
diff --git a/src/openvpn/proxy.c b/src/openvpn/proxy.c<br>
index ed720161..409bc4af 100644<br>
--- a/src/openvpn/proxy.c<br>
+++ b/src/openvpn/proxy.c<br>
@@ -110,7 +110,7 @@ recv_line(socket_descriptor_t sd,<br>
{<br>
if (verbose)<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "recv_line: TCP port read timeout expired");<br>
+ msg(D_LINK_ERRORS | M_SKERR, "recv_line: TCP port read timeout expired");<br>
}<br>
goto error;<br>
}<br>
@@ -120,7 +120,7 @@ recv_line(socket_descriptor_t sd,<br>
{<br>
if (verbose)<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "recv_line: TCP port read failed on select()");<br>
+ msg(D_LINK_ERRORS | M_SKERR, "recv_line: TCP port read failed on select()");<br>
}<br>
goto error;<br>
}<br>
@@ -133,7 +133,7 @@ recv_line(socket_descriptor_t sd,<br>
{<br>
if (verbose)<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "recv_line: TCP port read failed on recv()");<br>
+ msg(D_LINK_ERRORS | M_SKERR, "recv_line: TCP port read failed on recv()");<br>
}<br>
goto error;<br>
}<br>
@@ -199,7 +199,7 @@ send_line(socket_descriptor_t sd,<br>
const ssize_t size = send(sd, buf, strlen(buf), MSG_NOSIGNAL);<br>
if (size != (ssize_t) strlen(buf))<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "send_line: TCP port write failed on send()");<br>
+ msg(D_LINK_ERRORS | M_SKERR, "send_line: TCP port write failed on send()");<br>
return false;<br>
}<br>
return true;<br>
diff --git a/src/openvpn/ps.c b/src/openvpn/ps.c<br>
index 9dca53c8..64cc1ed3 100644<br>
--- a/src/openvpn/ps.c<br>
+++ b/src/openvpn/ps.c<br>
@@ -429,7 +429,7 @@ proxy_entry_new(struct proxy_connection **list,<br>
/* connect to port share server */<br>
if ((sd_server = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)<br>
{<br>
- msg(M_WARN|M_ERRNO, "PORT SHARE PROXY: cannot create socket");<br>
+ msg(M_WARN|M_SKERR, "PORT SHARE PROXY: cannot create socket");<br>
return false;<br>
}<br>
status = openvpn_connect(sd_server,(const struct sockaddr *) &server_addr, 5, NULL);<br>
diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c<br>
index 0f34a5de..acfcfd65 100644<br>
--- a/src/openvpn/socket.c<br>
+++ b/src/openvpn/socket.c<br>
@@ -1143,7 +1143,7 @@ create_socket(struct link_socket *sock, struct addrinfo *addr)<br>
msg(M_INFO, "Using bind-dev %s", sock->bind_dev);<br>
if (setsockopt(sock->sd, SOL_SOCKET, SO_BINDTODEVICE, sock->bind_dev, strlen(sock->bind_dev) + 1) != 0)<br>
{<br>
- msg(M_WARN|M_ERRNO, "WARN: setsockopt SO_BINDTODEVICE=%s failed", sock->bind_dev);<br>
+ msg(M_WARN|M_SKERR, "WARN: setsockopt SO_BINDTODEVICE=%s failed", sock->bind_dev);<br>
}<br>
<br>
}<br>
@@ -1222,7 +1222,7 @@ socket_do_accept(socket_descriptor_t sd,<br>
<br>
if (!socket_defined(new_sd))<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "TCP: getpeername() failed");<br>
+ msg(D_LINK_ERRORS | M_SKERR, "TCP: getpeername() failed");<br>
}<br>
else<br>
{<br>
@@ -1247,7 +1247,7 @@ socket_do_accept(socket_descriptor_t sd,<br>
<br>
if (!socket_defined(new_sd))<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "TCP: accept(%d) failed", (int)sd);<br>
+ msg(D_LINK_ERRORS | M_SKERR, "TCP: accept(%d) failed", (int)sd);<br>
}<br>
/* only valid if we have remote_len_af!=0 */<br>
else if (remote_len_af && remote_len != remote_len_af)<br>
@@ -1313,7 +1313,7 @@ socket_listen_accept(socket_descriptor_t sd,<br>
<br>
if (status < 0)<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "TCP: select() failed");<br>
+ msg(D_LINK_ERRORS | M_SKERR, "TCP: select() failed");<br>
}<br>
<br>
if (status <= 0)<br>
@@ -1409,12 +1409,12 @@ socket_bind(socket_descriptor_t sd,<br>
msg(M_INFO, "setsockopt(IPV6_V6ONLY=%d)", v6only);<br>
if (setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, (void *) &v6only, sizeof(v6only)))<br>
{<br>
- msg(M_NONFATAL|M_ERRNO, "Setting IPV6_V6ONLY=%d failed", v6only);<br>
+ msg(M_NONFATAL | M_SKERR, "Setting IPV6_V6ONLY=%d failed", v6only);<br>
}<br>
}<br>
if (bind(sd, cur->ai_addr, cur->ai_addrlen))<br>
{<br>
- msg(M_FATAL | M_ERRNO, "%s: Socket bind failed on local address %s",<br>
+ msg(M_FATAL | M_SKERR, "%s: Socket bind failed on local address %s",<br>
prefix,<br>
print_sockaddr_ex(local->ai_addr, ":", PS_SHOW_PORT, &gc));<br>
}<br>
@@ -2254,7 +2254,7 @@ link_socket_close(struct link_socket *sock)<br>
msg(D_LOW, "TCP/UDP: Closing socket");<br>
if (openvpn_close_socket(sock->sd))<br>
{<br>
- msg(M_WARN | M_ERRNO, "TCP/UDP: Close Socket failed");<br>
+ msg(M_WARN | M_SKERR, "TCP/UDP: Close Socket failed");<br>
}<br>
}<br>
sock->sd = SOCKET_UNDEFINED;<br>
@@ -2271,7 +2271,7 @@ link_socket_close(struct link_socket *sock)<br>
{<br>
if (openvpn_close_socket(sock->ctrl_sd))<br>
{<br>
- msg(M_WARN | M_ERRNO, "TCP/UDP: Close Socket (ctrl_sd) failed");<br>
+ msg(M_WARN | M_SKERR, "TCP/UDP: Close Socket (ctrl_sd) failed");<br>
}<br>
sock->ctrl_sd = SOCKET_UNDEFINED;<br>
}<br>
@@ -3668,7 +3668,7 @@ sockethandle_finalize(sockethandle_t sh,<br>
/* if no error (i.e. just not finished yet), then DON'T execute this code */<br>
io->iostate = IOSTATE_INITIAL;<br>
ASSERT(ResetEvent(io->overlapped.hEvent));<br>
- msg(D_WIN32_IO | M_ERRNO, "WIN32 I/O: Completion error");<br>
+ msg(D_WIN32_IO | SocketHandleErrorFlag(sh), "WIN32 I/O: Completion error");<br>
}<br>
}<br>
break;<br>
@@ -3681,7 +3681,7 @@ sockethandle_finalize(sockethandle_t sh,<br>
/* error return for a non-queued operation */<br>
SocketHandleSetLastError(sh, io->status);<br>
ret = -1;<br>
- msg(D_WIN32_IO | M_ERRNO, "WIN32 I/O: Completion non-queued error");<br>
+ msg(D_WIN32_IO | SocketHandleErrorFlag(sh), "WIN32 I/O: Completion non-queued error");<br>
}<br>
else<br>
{<br>
diff --git a/src/openvpn/socket.h b/src/openvpn/socket.h<br>
index e9f1524d..a7ec827a 100644<br>
--- a/src/openvpn/socket.h<br>
+++ b/src/openvpn/socket.h<br>
@@ -301,6 +301,12 @@ SocketHandleSetInvalError(sockethandle_t sh)<br>
sh.is_handle ? SetLastError(ERROR_INVALID_FUNCTION) : WSASetLastError(WSAEINVAL);<br>
}<br>
<br>
+static inline int<br>
+SocketHandleErrorFlag(sockethandle_t sh)<br>
+{<br>
+ return sh.is_handle ? M_ERRNO : M_SKERR;<br>
+}<br>
+<br>
#else /* ifdef _WIN32 */<br>
<br>
#define openvpn_close_socket(s) close(s)<br>
diff --git a/src/openvpn/socks.c b/src/openvpn/socks.c<br>
index 768bb613..10107c18 100644<br>
--- a/src/openvpn/socks.c<br>
+++ b/src/openvpn/socks.c<br>
@@ -117,7 +117,7 @@ socks_username_password_auth(struct socks_proxy_info *p,<br>
<br>
if (size != strlen(to_send))<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port write failed on send()");<br>
+ msg(D_LINK_ERRORS | M_SKERR, "socks_username_password_auth: TCP port write failed on send()");<br>
goto cleanup;<br>
}<br>
<br>
@@ -145,14 +145,14 @@ socks_username_password_auth(struct socks_proxy_info *p,<br>
/* timeout? */<br>
if (status == 0)<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read timeout expired");<br>
+ msg(D_LINK_ERRORS | M_SKERR, "socks_username_password_auth: TCP port read timeout expired");<br>
goto cleanup;<br>
}<br>
<br>
/* error */<br>
if (status < 0)<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read failed on select()");<br>
+ msg(D_LINK_ERRORS | M_SKERR, "socks_username_password_auth: TCP port read failed on select()");<br>
goto cleanup;<br>
}<br>
<br>
@@ -162,7 +162,7 @@ socks_username_password_auth(struct socks_proxy_info *p,<br>
/* error? */<br>
if (size != 1)<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read failed on recv()");<br>
+ msg(D_LINK_ERRORS | M_SKERR, "socks_username_password_auth: TCP port read failed on recv()");<br>
goto cleanup;<br>
}<br>
<br>
@@ -204,7 +204,7 @@ socks_handshake(struct socks_proxy_info *p,<br>
size = send(sd, method_sel, sizeof(method_sel), MSG_NOSIGNAL);<br>
if (size != sizeof(method_sel))<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port write failed on send()");<br>
+ msg(D_LINK_ERRORS | M_SKERR, "socks_handshake: TCP port write failed on send()");<br>
return false;<br>
}<br>
<br>
@@ -232,14 +232,14 @@ socks_handshake(struct socks_proxy_info *p,<br>
/* timeout? */<br>
if (status == 0)<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read timeout expired");<br>
+ msg(D_LINK_ERRORS | M_SKERR, "socks_handshake: TCP port read timeout expired");<br>
return false;<br>
}<br>
<br>
/* error */<br>
if (status < 0)<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read failed on select()");<br>
+ msg(D_LINK_ERRORS | M_SKERR, "socks_handshake: TCP port read failed on select()");<br>
return false;<br>
}<br>
<br>
@@ -249,7 +249,7 @@ socks_handshake(struct socks_proxy_info *p,<br>
/* error? */<br>
if (size != 1)<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read failed on recv()");<br>
+ msg(D_LINK_ERRORS | M_SKERR, "socks_handshake: TCP port read failed on recv()");<br>
return false;<br>
}<br>
<br>
@@ -342,14 +342,14 @@ recv_socks_reply(socket_descriptor_t sd,<br>
/* timeout? */<br>
if (status == 0)<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read timeout expired");<br>
+ msg(D_LINK_ERRORS | M_SKERR, "recv_socks_reply: TCP port read timeout expired");<br>
return false;<br>
}<br>
<br>
/* error */<br>
if (status < 0)<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read failed on select()");<br>
+ msg(D_LINK_ERRORS | M_SKERR, "recv_socks_reply: TCP port read failed on select()");<br>
return false;<br>
}<br>
<br>
@@ -359,7 +359,7 @@ recv_socks_reply(socket_descriptor_t sd,<br>
/* error? */<br>
if (size != 1)<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read failed on recv()");<br>
+ msg(D_LINK_ERRORS | M_SKERR, "recv_socks_reply: TCP port read failed on recv()");<br>
return false;<br>
}<br>
<br>
@@ -484,7 +484,7 @@ establish_socks_proxy_passthru(struct socks_proxy_info *p,<br>
const ssize_t size = send(sd, buf, 5 + len + 2, MSG_NOSIGNAL);<br>
if ((int)size != 5 + (int)len + 2)<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "establish_socks_proxy_passthru: TCP port write failed on send()");<br>
+ msg(D_LINK_ERRORS | M_SKERR, "establish_socks_proxy_passthru: TCP port write failed on send()");<br>
goto error;<br>
}<br>
}<br>
@@ -527,7 +527,7 @@ establish_socks_proxy_udpassoc(struct socks_proxy_info *p,<br>
10, MSG_NOSIGNAL);<br>
if (size != 10)<br>
{<br>
- msg(D_LINK_ERRORS | M_ERRNO, "establish_socks_proxy_passthru: TCP port write failed on send()");<br>
+ msg(D_LINK_ERRORS | M_SKERR, "establish_socks_proxy_passthru: TCP port write failed on send()");<br>
goto error;<br>
}<br>
}<br>
-- <br>
</blockquote><div><br></div><div>All that said, it may be hard to get all error reporting fixed in one patch, so we could proceed in steps. First make openvpn_errno() and openvpn_strerror() do the right thing with GetLastError() vs errno, then fix WSA error printing, then the rest if any. Just a thought.</div><div><br></div><div>Selva</div></div></div>
@@ -242,7 +242,25 @@ x_msg_va(const unsigned int flags, const char *format, va_list arglist)
return;
}
- e = openvpn_errno();
+ bool use_strerr = false;
+#ifdef _WIN32
+ if (flags & M_WSAERR)
+ {
+ e = WSAGetLastError();
+ }
+ else
+ {
+ e = GetLastError();
+ if (e == ERROR_SUCCESS)
+ {
+ /* error is likely C runtime, fallback to errno/strerr */
+ use_strerr = true;
+ e = errno;
+ }
+ }
+#else
+ e = errno;
+#endif
/*
* Apply muting filter.
@@ -264,7 +282,7 @@ x_msg_va(const unsigned int flags, const char *format, va_list arglist)
if ((flags & M_ERRNO) && e)
{
openvpn_snprintf(m2, ERR_BUF_SIZE, "%s: %s (errno=%d)",
- m1, strerror(e), e);
+ m1, use_strerr ? strerror(e) : openvpn_strerror(e, &gc), e);
SWAP;
}
@@ -678,13 +696,13 @@ x_check_status(int status,
{
msg(x_cs_info_level, "%s %s [%s]: %s (fd=%d,code=%d)", description,
sock ? proto2ascii(sock->info.proto, sock->info.af, true) : "",
- extended_msg, strerror(my_errno), sock ? sock->sd : -1, my_errno);
+ extended_msg, openvpn_strerror(my_errno, &gc), sock ? sock->sd : -1, my_errno);
}
else
{
msg(x_cs_info_level, "%s %s: %s (fd=%d,code=%d)", description,
sock ? proto2ascii(sock->info.proto, sock->info.af, true) : "",
- strerror(my_errno), sock ? sock->sd : -1, my_errno);
+ openvpn_strerror(my_errno, &gc), sock ? sock->sd : -1, my_errno);
}
if (x_cs_err_delay_ms)
@@ -99,9 +99,18 @@ extern int x_msg_line_num;
#define M_NONFATAL (1<<5) /* non-fatal error */
#define M_WARN (1<<6) /* call syslog with LOG_WARNING */
#define M_DEBUG (1<<7)
-
#define M_ERRNO (1<<8) /* show errno description */
+#ifdef _WIN32
+#define M_WSAERR (1<<9) /* WinSock errors */
+#endif
+
+#ifdef _WIN32
+#define M_SKERR (M_ERRNO | M_WSAERR) /* socket errors */
+#else
+#define M_SKERR M_ERRNO
+#endif
+
#define M_NOMUTE (1<<11) /* don't do mute processing */
#define M_NOPREFIX (1<<12) /* don't show date/time prefix */
#define M_USAGE_SMALL (1<<13) /* fatal options error, call usage_small */
@@ -1890,13 +1890,13 @@ man_connect(struct management *man)
#if UNIX_SOCK_SUPPORT
if (man->settings.flags & MF_UNIX_SOCK)
{
- msg(D_LINK_ERRORS | M_ERRNO,
+ msg(D_LINK_ERRORS | M_SKERR,
"MANAGEMENT: connect to unix socket %s failed",
sockaddr_unix_name(&man->settings.local_unix, "NULL"));
}
else
#endif
- msg(D_LINK_ERRORS | M_ERRNO,
+ msg(D_LINK_ERRORS | M_SKERR,
"MANAGEMENT: connect to %s failed",
print_sockaddr(man->settings.local->ai_addr, &gc));
throw_signal_soft(SIGTERM, "management-connect-failed");
@@ -407,7 +407,7 @@ set_sock_extended_error_passing(int sd)
int on = 1;
if (setsockopt(sd, SOL_IP, IP_RECVERR, (void *) &on, sizeof(on)))
{
- msg(M_WARN | M_ERRNO,
+ msg(M_WARN | M_SKERR,
"Note: enable extended error passing on TCP/UDP socket failed (IP_RECVERR)");
}
}
@@ -532,7 +532,7 @@ platform_test_file(const char *filename)
}
else
{
- if (openvpn_errno() == EACCES)
+ if (errno == EACCES)
{
msg( M_WARN | M_ERRNO, "Could not access file '%s'", filename);
}
@@ -110,7 +110,7 @@ recv_line(socket_descriptor_t sd,
{
if (verbose)
{
- msg(D_LINK_ERRORS | M_ERRNO, "recv_line: TCP port read timeout expired");
+ msg(D_LINK_ERRORS | M_SKERR, "recv_line: TCP port read timeout expired");
}
goto error;
}
@@ -120,7 +120,7 @@ recv_line(socket_descriptor_t sd,
{
if (verbose)
{
- msg(D_LINK_ERRORS | M_ERRNO, "recv_line: TCP port read failed on select()");
+ msg(D_LINK_ERRORS | M_SKERR, "recv_line: TCP port read failed on select()");
}
goto error;
}
@@ -133,7 +133,7 @@ recv_line(socket_descriptor_t sd,
{
if (verbose)
{
- msg(D_LINK_ERRORS | M_ERRNO, "recv_line: TCP port read failed on recv()");
+ msg(D_LINK_ERRORS | M_SKERR, "recv_line: TCP port read failed on recv()");
}
goto error;
}
@@ -199,7 +199,7 @@ send_line(socket_descriptor_t sd,
const ssize_t size = send(sd, buf, strlen(buf), MSG_NOSIGNAL);
if (size != (ssize_t) strlen(buf))
{
- msg(D_LINK_ERRORS | M_ERRNO, "send_line: TCP port write failed on send()");
+ msg(D_LINK_ERRORS | M_SKERR, "send_line: TCP port write failed on send()");
return false;
}
return true;
@@ -429,7 +429,7 @@ proxy_entry_new(struct proxy_connection **list,
/* connect to port share server */
if ((sd_server = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
- msg(M_WARN|M_ERRNO, "PORT SHARE PROXY: cannot create socket");
+ msg(M_WARN|M_SKERR, "PORT SHARE PROXY: cannot create socket");
return false;
}
status = openvpn_connect(sd_server,(const struct sockaddr *) &server_addr, 5, NULL);
@@ -1143,7 +1143,7 @@ create_socket(struct link_socket *sock, struct addrinfo *addr)
msg(M_INFO, "Using bind-dev %s", sock->bind_dev);
if (setsockopt(sock->sd, SOL_SOCKET, SO_BINDTODEVICE, sock->bind_dev, strlen(sock->bind_dev) + 1) != 0)
{
- msg(M_WARN|M_ERRNO, "WARN: setsockopt SO_BINDTODEVICE=%s failed", sock->bind_dev);
+ msg(M_WARN|M_SKERR, "WARN: setsockopt SO_BINDTODEVICE=%s failed", sock->bind_dev);
}
}
@@ -1222,7 +1222,7 @@ socket_do_accept(socket_descriptor_t sd,
if (!socket_defined(new_sd))
{
- msg(D_LINK_ERRORS | M_ERRNO, "TCP: getpeername() failed");
+ msg(D_LINK_ERRORS | M_SKERR, "TCP: getpeername() failed");
}
else
{
@@ -1247,7 +1247,7 @@ socket_do_accept(socket_descriptor_t sd,
if (!socket_defined(new_sd))
{
- msg(D_LINK_ERRORS | M_ERRNO, "TCP: accept(%d) failed", (int)sd);
+ msg(D_LINK_ERRORS | M_SKERR, "TCP: accept(%d) failed", (int)sd);
}
/* only valid if we have remote_len_af!=0 */
else if (remote_len_af && remote_len != remote_len_af)
@@ -1313,7 +1313,7 @@ socket_listen_accept(socket_descriptor_t sd,
if (status < 0)
{
- msg(D_LINK_ERRORS | M_ERRNO, "TCP: select() failed");
+ msg(D_LINK_ERRORS | M_SKERR, "TCP: select() failed");
}
if (status <= 0)
@@ -1409,12 +1409,12 @@ socket_bind(socket_descriptor_t sd,
msg(M_INFO, "setsockopt(IPV6_V6ONLY=%d)", v6only);
if (setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, (void *) &v6only, sizeof(v6only)))
{
- msg(M_NONFATAL|M_ERRNO, "Setting IPV6_V6ONLY=%d failed", v6only);
+ msg(M_NONFATAL | M_SKERR, "Setting IPV6_V6ONLY=%d failed", v6only);
}
}
if (bind(sd, cur->ai_addr, cur->ai_addrlen))
{
- msg(M_FATAL | M_ERRNO, "%s: Socket bind failed on local address %s",
+ msg(M_FATAL | M_SKERR, "%s: Socket bind failed on local address %s",
prefix,
print_sockaddr_ex(local->ai_addr, ":", PS_SHOW_PORT, &gc));
}
@@ -2254,7 +2254,7 @@ link_socket_close(struct link_socket *sock)
msg(D_LOW, "TCP/UDP: Closing socket");
if (openvpn_close_socket(sock->sd))
{
- msg(M_WARN | M_ERRNO, "TCP/UDP: Close Socket failed");
+ msg(M_WARN | M_SKERR, "TCP/UDP: Close Socket failed");
}
}
sock->sd = SOCKET_UNDEFINED;
@@ -2271,7 +2271,7 @@ link_socket_close(struct link_socket *sock)
{
if (openvpn_close_socket(sock->ctrl_sd))
{
- msg(M_WARN | M_ERRNO, "TCP/UDP: Close Socket (ctrl_sd) failed");
+ msg(M_WARN | M_SKERR, "TCP/UDP: Close Socket (ctrl_sd) failed");
}
sock->ctrl_sd = SOCKET_UNDEFINED;
}
@@ -3668,7 +3668,7 @@ sockethandle_finalize(sockethandle_t sh,
/* if no error (i.e. just not finished yet), then DON'T execute this code */
io->iostate = IOSTATE_INITIAL;
ASSERT(ResetEvent(io->overlapped.hEvent));
- msg(D_WIN32_IO | M_ERRNO, "WIN32 I/O: Completion error");
+ msg(D_WIN32_IO | SocketHandleErrorFlag(sh), "WIN32 I/O: Completion error");
}
}
break;
@@ -3681,7 +3681,7 @@ sockethandle_finalize(sockethandle_t sh,
/* error return for a non-queued operation */
SocketHandleSetLastError(sh, io->status);
ret = -1;
- msg(D_WIN32_IO | M_ERRNO, "WIN32 I/O: Completion non-queued error");
+ msg(D_WIN32_IO | SocketHandleErrorFlag(sh), "WIN32 I/O: Completion non-queued error");
}
else
{
@@ -301,6 +301,12 @@ SocketHandleSetInvalError(sockethandle_t sh)
sh.is_handle ? SetLastError(ERROR_INVALID_FUNCTION) : WSASetLastError(WSAEINVAL);
}
+static inline int
+SocketHandleErrorFlag(sockethandle_t sh)
+{
+ return sh.is_handle ? M_ERRNO : M_SKERR;
+}
+
#else /* ifdef _WIN32 */
#define openvpn_close_socket(s) close(s)
@@ -117,7 +117,7 @@ socks_username_password_auth(struct socks_proxy_info *p,
if (size != strlen(to_send))
{
- msg(D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port write failed on send()");
+ msg(D_LINK_ERRORS | M_SKERR, "socks_username_password_auth: TCP port write failed on send()");
goto cleanup;
}
@@ -145,14 +145,14 @@ socks_username_password_auth(struct socks_proxy_info *p,
/* timeout? */
if (status == 0)
{
- msg(D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read timeout expired");
+ msg(D_LINK_ERRORS | M_SKERR, "socks_username_password_auth: TCP port read timeout expired");
goto cleanup;
}
/* error */
if (status < 0)
{
- msg(D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read failed on select()");
+ msg(D_LINK_ERRORS | M_SKERR, "socks_username_password_auth: TCP port read failed on select()");
goto cleanup;
}
@@ -162,7 +162,7 @@ socks_username_password_auth(struct socks_proxy_info *p,
/* error? */
if (size != 1)
{
- msg(D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read failed on recv()");
+ msg(D_LINK_ERRORS | M_SKERR, "socks_username_password_auth: TCP port read failed on recv()");
goto cleanup;
}
@@ -204,7 +204,7 @@ socks_handshake(struct socks_proxy_info *p,
size = send(sd, method_sel, sizeof(method_sel), MSG_NOSIGNAL);
if (size != sizeof(method_sel))
{
- msg(D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port write failed on send()");
+ msg(D_LINK_ERRORS | M_SKERR, "socks_handshake: TCP port write failed on send()");
return false;
}
@@ -232,14 +232,14 @@ socks_handshake(struct socks_proxy_info *p,
/* timeout? */
if (status == 0)
{
- msg(D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read timeout expired");
+ msg(D_LINK_ERRORS | M_SKERR, "socks_handshake: TCP port read timeout expired");
return false;
}
/* error */
if (status < 0)
{
- msg(D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read failed on select()");
+ msg(D_LINK_ERRORS | M_SKERR, "socks_handshake: TCP port read failed on select()");
return false;
}
@@ -249,7 +249,7 @@ socks_handshake(struct socks_proxy_info *p,
/* error? */
if (size != 1)
{
- msg(D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read failed on recv()");
+ msg(D_LINK_ERRORS | M_SKERR, "socks_handshake: TCP port read failed on recv()");
return false;
}
@@ -342,14 +342,14 @@ recv_socks_reply(socket_descriptor_t sd,
/* timeout? */
if (status == 0)
{
- msg(D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read timeout expired");
+ msg(D_LINK_ERRORS | M_SKERR, "recv_socks_reply: TCP port read timeout expired");
return false;
}
/* error */
if (status < 0)
{
- msg(D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read failed on select()");
+ msg(D_LINK_ERRORS | M_SKERR, "recv_socks_reply: TCP port read failed on select()");
return false;
}
@@ -359,7 +359,7 @@ recv_socks_reply(socket_descriptor_t sd,
/* error? */
if (size != 1)
{
- msg(D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read failed on recv()");
+ msg(D_LINK_ERRORS | M_SKERR, "recv_socks_reply: TCP port read failed on recv()");
return false;
}
@@ -484,7 +484,7 @@ establish_socks_proxy_passthru(struct socks_proxy_info *p,
const ssize_t size = send(sd, buf, 5 + len + 2, MSG_NOSIGNAL);
if ((int)size != 5 + (int)len + 2)
{
- msg(D_LINK_ERRORS | M_ERRNO, "establish_socks_proxy_passthru: TCP port write failed on send()");
+ msg(D_LINK_ERRORS | M_SKERR, "establish_socks_proxy_passthru: TCP port write failed on send()");
goto error;
}
}
@@ -527,7 +527,7 @@ establish_socks_proxy_udpassoc(struct socks_proxy_info *p,
10, MSG_NOSIGNAL);
if (size != 10)
{
- msg(D_LINK_ERRORS | M_ERRNO, "establish_socks_proxy_passthru: TCP port write failed on send()");
+ msg(D_LINK_ERRORS | M_SKERR, "establish_socks_proxy_passthru: TCP port write failed on send()");
goto error;
}
}