diff --git a/udp/udp_rio_windows.go b/udp/udp_rio_windows.go index ee7e1e0..87cf655 100644 --- a/udp/udp_rio_windows.go +++ b/udp/udp_rio_windows.go @@ -14,6 +14,7 @@ import ( "sync" "sync/atomic" "syscall" + "time" "unsafe" "github.com/sirupsen/logrus" @@ -125,14 +126,28 @@ func (u *RIOConn) ListenOut(r EncReader, lhf LightHouseHandlerFunc, cache *firew fwPacket := &firewall.Packet{} nb := make([]byte, 12, 12) + consecutiveErrors := 0 for { // Just read one packet at a time n, rua, err := u.receive(buffer) if err != nil { - u.l.WithError(err).Debug("udp socket is closed, exiting read loop") - return + if errors.Is(err, net.ErrClosed) { + u.l.WithError(err).Debug("udp socket is closed, exiting read loop") + return + } + // Try to suss out whether this is a transient error or something more permanent + consecutiveErrors++ + u.l.WithError(err).WithField("consecutiveErrors", consecutiveErrors).Error("unexpected udp socket recieve error") + if consecutiveErrors > 15 { + panic("too many consecutive UDP receive errors") + } else if consecutiveErrors > 10 { + time.Sleep(100 * time.Millisecond) + } + continue } + consecutiveErrors = 0 + r( netip.AddrPortFrom(netip.AddrFrom16(rua.Addr).Unmap(), (rua.Port>>8)|((rua.Port&0xff)<<8)), plaintext[:0],