Handle ICMP not permitted errors
This commit is contained in:
@@ -5,10 +5,12 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
ErrICMPNotPermitted = errors.New("ICMP not permitted")
|
||||||
ErrICMPDestinationUnreachable = errors.New("ICMP destination unreachable")
|
ErrICMPDestinationUnreachable = errors.New("ICMP destination unreachable")
|
||||||
ErrICMPCommunicationAdministrativelyProhibited = errors.New("communication administratively prohibited")
|
ErrICMPCommunicationAdministrativelyProhibited = errors.New("communication administratively prohibited")
|
||||||
ErrICMPBodyUnsupported = errors.New("ICMP body type is not supported")
|
ErrICMPBodyUnsupported = errors.New("ICMP body type is not supported")
|
||||||
@@ -16,6 +18,8 @@ var (
|
|||||||
|
|
||||||
func wrapConnErr(err error, timedCtx context.Context, pingTimeout time.Duration) error { //nolint:revive
|
func wrapConnErr(err error, timedCtx context.Context, pingTimeout time.Duration) error { //nolint:revive
|
||||||
switch {
|
switch {
|
||||||
|
case strings.HasSuffix(err.Error(), "sendto: operation not permitted"):
|
||||||
|
err = fmt.Errorf("%w", ErrICMPNotPermitted)
|
||||||
case errors.Is(timedCtx.Err(), context.DeadlineExceeded):
|
case errors.Is(timedCtx.Err(), context.DeadlineExceeded):
|
||||||
err = fmt.Errorf("%w (timed out after %s)", net.ErrClosed, pingTimeout)
|
err = fmt.Errorf("%w (timed out after %s)", net.ErrClosed, pingTimeout)
|
||||||
case timedCtx.Err() != nil:
|
case timedCtx.Err() != nil:
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -36,6 +37,9 @@ func listenICMPv4(ctx context.Context) (conn net.PacketConn, err error) {
|
|||||||
const listenAddress = ""
|
const listenAddress = ""
|
||||||
packetConn, err := listenConfig.ListenPacket(ctx, "ip4:icmp", listenAddress)
|
packetConn, err := listenConfig.ListenPacket(ctx, "ip4:icmp", listenAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if strings.HasSuffix(err.Error(), "socket: operation not permitted") {
|
||||||
|
err = fmt.Errorf("%w: you can try adding NET_RAW capability to resolve this", ErrICMPNotPermitted)
|
||||||
|
}
|
||||||
return nil, fmt.Errorf("listening for ICMP packets: %w", err)
|
return nil, fmt.Errorf("listening for ICMP packets: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/net/icmp"
|
"golang.org/x/net/icmp"
|
||||||
@@ -21,6 +22,9 @@ func listenICMPv6(ctx context.Context) (conn net.PacketConn, err error) {
|
|||||||
const listenAddress = ""
|
const listenAddress = ""
|
||||||
packetConn, err := listenConfig.ListenPacket(ctx, "ip6:ipv6-icmp", listenAddress)
|
packetConn, err := listenConfig.ListenPacket(ctx, "ip6:ipv6-icmp", listenAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if strings.HasSuffix(err.Error(), "socket: operation not permitted") {
|
||||||
|
err = fmt.Errorf("%w: you can try adding NET_RAW capability to resolve this", ErrICMPNotPermitted)
|
||||||
|
}
|
||||||
return nil, fmt.Errorf("listening for ICMPv6 packets: %w", err)
|
return nil, fmt.Errorf("listening for ICMPv6 packets: %w", err)
|
||||||
}
|
}
|
||||||
return packetConn, nil
|
return packetConn, nil
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/net/icmp"
|
"golang.org/x/net/icmp"
|
||||||
@@ -87,6 +88,9 @@ func pmtudMultiSizes(ctx context.Context, ip netip.Addr,
|
|||||||
conn, err = listenICMPv6(ctx)
|
conn, err = listenICMPv6(ctx)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if strings.HasSuffix(err.Error(), "socket: operation not permitted") {
|
||||||
|
err = fmt.Errorf("%w: you can try adding NET_RAW capability to resolve this", ErrICMPNotPermitted)
|
||||||
|
}
|
||||||
return 0, fmt.Errorf("listening for ICMP packets: %w", err)
|
return 0, fmt.Errorf("listening for ICMP packets: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,6 +124,9 @@ func pmtudMultiSizes(ctx context.Context, ip netip.Addr,
|
|||||||
|
|
||||||
_, err = conn.WriteTo(encodedMessage, &net.IPAddr{IP: ip.AsSlice()})
|
_, err = conn.WriteTo(encodedMessage, &net.IPAddr{IP: ip.AsSlice()})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if strings.HasSuffix(err.Error(), "sendto: operation not permitted") {
|
||||||
|
err = fmt.Errorf("%w", ErrICMPNotPermitted)
|
||||||
|
}
|
||||||
return 0, fmt.Errorf("writing ICMP message: %w", err)
|
return 0, fmt.Errorf("writing ICMP message: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,10 +120,10 @@ func updateToMaxMTU(ctx context.Context, vpnInterface string,
|
|||||||
vpnLinkMTU, err = pmtud.PathMTUDiscover(ctx, vpnGatewayIP, vpnLinkMTU, pingTimeout, logger)
|
vpnLinkMTU, err = pmtud.PathMTUDiscover(ctx, vpnGatewayIP, vpnLinkMTU, pingTimeout, logger)
|
||||||
switch {
|
switch {
|
||||||
case err == nil:
|
case err == nil:
|
||||||
logger.Infof("Setting VPN interface %s MTU to maximum valid MTU %d", vpnInterface, vpnLinkMTU)
|
logger.Infof("setting VPN interface %s MTU to maximum valid MTU %d", vpnInterface, vpnLinkMTU)
|
||||||
case errors.Is(err, pmtud.ErrMTUNotFound):
|
case errors.Is(err, pmtud.ErrMTUNotFound) || errors.Is(err, pmtud.ErrICMPNotPermitted):
|
||||||
vpnLinkMTU = int(originalMTU)
|
vpnLinkMTU = int(originalMTU)
|
||||||
logger.Infof("Reverting VPN interface %s MTU to %d (due to: %s)",
|
logger.Infof("reverting VPN interface %s MTU to %d (due to: %s)",
|
||||||
vpnInterface, originalMTU, err)
|
vpnInterface, originalMTU, err)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("path MTU discovering: %w", err)
|
return fmt.Errorf("path MTU discovering: %w", err)
|
||||||
|
|||||||
Reference in New Issue
Block a user