[Openvpn-devel,v2] Fix error message about extended errors for IPv4-only sockets.
Commit Message
The new code to enable IPv6 extended error reporting will cause
an error ("Protocol not available (errno=92)") if trying to enable
that setsockopt() option on an IPv4-only socket.
Fix: pass sock->info.af to set_sock_extended_error_passing(), only
apply to AF_INET6 sockets.
To make that work, ensure that sock->info.af is set to not only
the value coming from config (which might be AF_UNSPEC) but to the
actual value used in socket creation (credits: Arne Schwabe).
Add comments to make explicit that the asymmetry here (IPv4 extended
socket error reporting is enabled on all sockets) is intentional.
Signed-off-by: Gert Doering <gert@greenie.muc.de>
--
v2: set sock->info.af in create_socket() (Arne Schwabe)
---
src/openvpn/mtu.c | 13 +++++++++----
src/openvpn/mtu.h | 2 +-
src/openvpn/socket.c | 6 +++++-
3 files changed, 15 insertions(+), 6 deletions(-)
Comments
On Sat, Jul 23, 2022 at 02:19:09PM +0200, Gert Doering wrote:
> The new code to enable IPv6 extended error reporting will cause
> an error ("Protocol not available (errno=92)") if trying to enable
> that setsockopt() option on an IPv4-only socket.
>
> Fix: pass sock->info.af to set_sock_extended_error_passing(), only
> apply to AF_INET6 sockets.
>
> To make that work, ensure that sock->info.af is set to not only
> the value coming from config (which might be AF_UNSPEC) but to the
> actual value used in socket creation (credits: Arne Schwabe).
>
> Add comments to make explicit that the asymmetry here (IPv4 extended
> socket error reporting is enabled on all sockets) is intentional.
>
> Signed-off-by: Gert Doering <gert@greenie.muc.de>
Acked-By: Frank Lichtenheld <frank@lichtenheld.com>
Tested that it indeed removes the spurious error.
Code changes look good to me.
Regards,
Patch has been applied to the master branch.
For good measure, passed "make check" on FreeBSD and Linux.
commit a2e63fb978b7497ebc7e8ec56504fd2300f97621
Author: Gert Doering
Date: Sat Jul 23 14:19:09 2022 +0200
Fix error message about extended errors for IPv4-only sockets.
Signed-off-by: Gert Doering <gert@greenie.muc.de>
Acked-by: Frank Lichtenheld <frank@lichtenheld.com>
Message-Id: <20220723121909.21943-1-gert@greenie.muc.de>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg24731.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
--
kind regards,
Gert Doering
@@ -413,17 +413,22 @@ exit:
}
void
-set_sock_extended_error_passing(int sd)
+set_sock_extended_error_passing(int sd, sa_family_t proto_af)
{
int on = 1;
- /* see "man 7 ip" (on Linux) */
+ /* see "man 7 ip" (on Linux)
+ * this works on IPv4 and IPv6(-dual-stack) sockets (v4-mapped)
+ */
if (setsockopt(sd, SOL_IP, IP_RECVERR, (void *) &on, sizeof(on)) != 0)
{
msg(M_WARN | M_ERRNO,
"Note: enable extended error passing on TCP/UDP socket failed (IP_RECVERR)");
}
- /* see "man 7 ipv6" (on Linux) */
- if (setsockopt(sd, IPPROTO_IPV6, IPV6_RECVERR, (void *) &on, sizeof(on)) != 0)
+ /* see "man 7 ipv6" (on Linux)
+ * this only works on IPv6 sockets
+ */
+ if (proto_af == AF_INET6
+ && setsockopt(sd, IPPROTO_IPV6, IPV6_RECVERR, (void *) &on, sizeof(on)) != 0)
{
msg(M_WARN | M_ERRNO,
"Note: enable extended error passing on TCP/UDP socket failed (IPV6_RECVERR)");
@@ -268,7 +268,7 @@ void alloc_buf_sock_tun(struct buffer *buf,
#if EXTENDED_SOCKET_ERROR_CAPABILITY
-void set_sock_extended_error_passing(int sd);
+void set_sock_extended_error_passing(int sd, sa_family_t proto_af);
const char *format_extended_socket_error(int fd, int *mtu, struct gc_arena *gc);
@@ -1131,6 +1131,10 @@ create_socket(struct link_socket *sock, struct addrinfo *addr)
{
ASSERT(0);
}
+ /* Set af field of sock->info, so it always reflects the address family
+ * of the created socket */
+ sock->info.af = addr->ai_family;
+
/* set socket buffers based on --sndbuf and --rcvbuf options */
socket_set_buffers(sock->sd, &sock->socket_buffer_sizes);
@@ -1949,7 +1953,7 @@ phase2_set_socket_flags(struct link_socket *sock)
#if EXTENDED_SOCKET_ERROR_CAPABILITY
/* if the OS supports it, enable extended error passing on the socket */
- set_sock_extended_error_passing(sock->sd);
+ set_sock_extended_error_passing(sock->sd, sock->info.af);
#endif
}