[Openvpn-devel,v2] Fix error message about extended errors for IPv4-only sockets.

Message ID 20220723121909.21943-1-gert@greenie.muc.de
State Accepted
Headers show
Series [Openvpn-devel,v2] Fix error message about extended errors for IPv4-only sockets. | expand

Commit Message

Gert Doering July 23, 2022, 2:19 a.m. UTC
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

Frank Lichtenheld July 25, 2022, 2:02 a.m. UTC | #1
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,
Gert Doering July 25, 2022, 5:33 a.m. UTC | #2
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

Patch

diff --git a/src/openvpn/mtu.c b/src/openvpn/mtu.c
index 59b91798..f60f4853 100644
--- a/src/openvpn/mtu.c
+++ b/src/openvpn/mtu.c
@@ -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)");
diff --git a/src/openvpn/mtu.h b/src/openvpn/mtu.h
index 9db6cf26..d4856f16 100644
--- a/src/openvpn/mtu.h
+++ b/src/openvpn/mtu.h
@@ -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);
 
diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c
index 4e4a3a2f..b4c20f69 100644
--- a/src/openvpn/socket.c
+++ b/src/openvpn/socket.c
@@ -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
 }