magicsock: receive ICMP errors

Updates #311
This commit is contained in:
Claire Wang 2024-01-16 20:17:50 -05:00
parent ae5ba8467e
commit 50dbdfd02d
4 changed files with 39 additions and 7 deletions

View File

@ -1176,7 +1176,9 @@ func (c *Conn) mkReceiveFunc(ruc *RebindingUDPConn, healthItem *health.ReceiveFu
if neterror.PacketWasTruncated(err) {
continue
}
//_, err := ruc.ReadBatch(batch.msgs[:len(buffs)], MSG_ERRQUE) rcv message ip recv here
if c.peerMTUEnabled.Load() {
ruc.ReadICMPErrors(batch.msgs[:len(buffs)], c.logf)
}
return 0, err
}

View File

@ -104,6 +104,15 @@ func (c *Conn) UpdatePMTUD() {
_ = c.setDontFragment("udp6", false)
newStatus = false
}
err4 = c.setReceiveICMPErrors("udp4", enable)
err6 = c.setReceiveICMPErrors("udp6", enable)
if err4 != nil || err6 != nil {
c.logf("[unexpected] magicsock: peermtu: enabling receive ICMP errors to %v failed (v4: %v, v6: %v), disabling", enable, err4, err6)
_ = c.setReceiveICMPErrors("udp4", false)
_ = c.setReceiveICMPErrors("udp6", false)
}
if debugPMTUD() {
c.logf("magicsock: peermtu: peer MTU probes are %v", tstun.WireMTUsToProbe)
}

View File

@ -49,3 +49,7 @@ func (c *Conn) getDontFragment(network string) (bool, error) {
}
return false, err
}
func (c *Conn) setReceiveICMPErrors(network string, enable bool) error {
return nil
}

View File

@ -10,9 +10,12 @@ import (
"sync"
"sync/atomic"
"syscall"
"unsafe"
"golang.org/x/net/ipv6"
"golang.org/x/sys/unix"
"tailscale.com/net/netaddr"
"tailscale.com/types/logger"
"tailscale.com/types/nettype"
)
@ -178,11 +181,25 @@ func (c *RebindingUDPConn) SyscallConn() (syscall.RawConn, error) {
return sc.SyscallConn()
}
/*func (c *RebindingUDPConn) ReadICMPErrors(msgs []ipv6.Message) (int, error) {
func (c *RebindingUDPConn) ReadICMPErrors(msgs []ipv6.Message, logf logger.Logf) (int, error) {
for {
sc, ok := c.pconn.(syscall.Conn)
a, err := sc.SyscallConn()
err := syscall.SetsockoptInt(sc.SyscallConn(), syscall.SOL_IP, syscall.IP_RECVERR, 1)
return n, err
rc, err := c.SyscallConn()
if err == nil {
rc.Control(func(fd uintptr) {
err = syscall.SetsockoptInt(int(fd), syscall.SOL_IP, syscall.IP_RECVERR, 1)
var p = make([]byte, 1500)
var oob = make([]byte, 1500)
_, oobn, _, _, err := syscall.Recvmsg(int(fd), p, oob, syscall.MSG_ERRQUEUE)
if err != nil {
logf("magicsock: failed to receive ICMP message %v", err)
} else if oobn <= 0 {
logf("magicsock: failed to receive ICMP message oobn")
}
se := (*unix.SockExtendedErr)(unsafe.Pointer(&oob[syscall.SizeofCmsghdr]))
if se.Origin == 2 {
logf("magicsock: received ICMP error type %v info %v", se.Type, se.Info)
}
})
}
}
}*/
}