wgengine/magicsock: log when a ReceiveFunc fails

Updates #10976

Change-Id: I86d30151a25c7d42ed36e273fb207873f4acfdb4
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2024-08-14 10:28:39 -07:00 committed by Brad Fitzpatrick
parent 74b9fa1348
commit 2dd71e64ac
2 changed files with 26 additions and 4 deletions

View File

@ -65,6 +65,11 @@ type Tracker struct {
// magicsock receive functions: IPv4, IPv6, and DERP.
MagicSockReceiveFuncs [3]ReceiveFuncStats // indexed by ReceiveFunc values
// initOnce guards the initialization of the Tracker.
// Notably, it initializes the MagicSockReceiveFuncs names.
// mu should not be held during init.
initOnce sync.Once
// mu guards everything that follows.
mu sync.Mutex
@ -433,6 +438,7 @@ func (t *Tracker) RegisterWatcher(cb func(w *Warnable, r *UnhealthyState)) (unre
if t.nil() {
return func() {}
}
t.initOnce.Do(t.doOnceInit)
t.mu.Lock()
defer t.mu.Unlock()
if t.watchers == nil {
@ -859,6 +865,7 @@ func (t *Tracker) timerSelfCheck() {
if t.nil() {
return
}
t.initOnce.Do(t.doOnceInit)
t.mu.Lock()
defer t.mu.Unlock()
t.checkReceiveFuncsLocked()
@ -1168,6 +1175,11 @@ type ReceiveFuncStats struct {
missing bool
}
// Name returns the name of the receive func ("ReceiveIPv4", "ReceiveIPv6", etc).
func (s *ReceiveFuncStats) Name() string {
return s.name
}
func (s *ReceiveFuncStats) Enter() {
s.numCalls.Add(1)
s.inCall.Store(true)
@ -1185,15 +1197,20 @@ func (t *Tracker) ReceiveFuncStats(which ReceiveFunc) *ReceiveFuncStats {
if t == nil {
return nil
}
t.initOnce.Do(t.doOnceInit)
return &t.MagicSockReceiveFuncs[which]
}
func (t *Tracker) doOnceInit() {
for i := range t.MagicSockReceiveFuncs {
f := &t.MagicSockReceiveFuncs[i]
f.name = (ReceiveFunc(i)).String()
}
}
func (t *Tracker) checkReceiveFuncsLocked() {
for i := range t.MagicSockReceiveFuncs {
f := &t.MagicSockReceiveFuncs[i]
if f.name == "" {
f.name = (ReceiveFunc(i)).String()
}
if runtime.GOOS == "js" && i < 2 {
// Skip IPv4 and IPv6 on js.
continue

View File

@ -1274,10 +1274,15 @@ func (c *Conn) mkReceiveFunc(ruc *RebindingUDPConn, healthItem *health.ReceiveFu
// epCache caches an IPPort->endpoint for hot flows.
var epCache ippEndpointCache
return func(buffs [][]byte, sizes []int, eps []conn.Endpoint) (int, error) {
return func(buffs [][]byte, sizes []int, eps []conn.Endpoint) (_ int, retErr error) {
if healthItem != nil {
healthItem.Enter()
defer healthItem.Exit()
defer func() {
if retErr != nil {
c.logf("Receive func %s exiting with error: %T, %v", healthItem.Name(), retErr, retErr)
}
}()
}
if ruc == nil {
panic("nil RebindingUDPConn")