status-go/server/pairing/peers/udp_notifier.go
frank 38308d48f2
feat_: log on panic (#5849)
* feat_: log error and stacktrace when panic in goroutine

* test_: add test TestSafeGo

* chore_: rename logAndCall to call

* chore_: rename SafeGo to Go

* chore_: make lint-fix

* chore_: use t.Cleanup

* chore_: Revert "chore_: use t.Cleanup"

This reverts commit 4eb420d179cc0e208e84c13cb941e6b3d1ed9819.

* chore_: Revert "chore_: make lint-fix"

This reverts commit fcc995f157e671a4229b47419c3a0e4004b5fdab.

* chore_: Revert "chore_: rename SafeGo to Go"

This reverts commit a6d73d6df583f313032d79aac62f66328039cb55.

* chore_: Revert "chore_: rename logAndCall to call"

This reverts commit 8fbe993bedb9fbba67349a44f151e2dd5e3bc4cc.

* chore_: Revert "test_: add test TestSafeGo"

This reverts commit a1fa91839f3960398980c6bf456e6462ec944819.

* chore_: Revert "feat_: log error and stacktrace when panic in goroutine"

This reverts commit f612dd828fa2ce410d0e806fe773ecbe3e86a68a.

* feat_: log error and stacktrace when panic in goroutine

* chore_: make lint-fix

* chore_: rename logAndCall to call

* chore_: renaming LogOnPanic

* chore_: update rest goroutine function calls

* chore_: make lint-fix
2024-09-27 06:37:32 +08:00

107 lines
2.3 KiB
Go

package peers
import (
"crypto/rand"
"fmt"
"time"
"github.com/golang/protobuf/proto"
udpp2p "github.com/schollz/peerdiscovery"
"go.uber.org/zap"
"github.com/status-im/status-go/common"
)
const (
pingInterval = 500 * time.Millisecond
searchLimit = 2 * time.Minute
)
type NotifyHandler func(*LocalPairingPeerHello)
type UDPNotifier struct {
logger *zap.Logger
id []byte
notifyOutput NotifyHandler
}
func NewUDPNotifier(logger *zap.Logger, outputFunc NotifyHandler) (*UDPNotifier, error) {
randID := make([]byte, 32)
_, err := rand.Read(randID)
if err != nil {
return nil, err
}
n := new(UDPNotifier)
n.logger = logger
n.id = randID
n.notifyOutput = outputFunc
return n, nil
}
func (u *UDPNotifier) makePayload(deviceName, deviceType string) (*LocalPairingPeerHello, error) {
return NewLocalPairingPeerHello(u.id, deviceName, deviceType, k)
}
func (u *UDPNotifier) notify(d udpp2p.Discovered) {
h := new(LocalPairingPeerHello)
err := proto.Unmarshal(d.Payload, &h.LocalPairingPeerHello)
if err != nil {
u.logger.Error("notify unmarshalling of payload failed", zap.Error(err))
return
}
ok := h.verify(&k.PublicKey)
if !ok {
u.logger.Error("verification of unmarshalled payload failed", zap.Any("LocalPairingPeerHello", h))
return
}
h.Discovered = d
u.notifyOutput(h)
}
func (u *UDPNotifier) MakeUDPP2PSettings(deviceName, deviceType string) (*udpp2p.Settings, error) {
if u.notifyOutput == nil {
return nil, fmt.Errorf("UDPNotifier has no notiftOutput function defined")
}
h, err := u.makePayload(deviceName, deviceType)
if err != nil {
return nil, err
}
mh, err := proto.Marshal(&h.LocalPairingPeerHello)
if err != nil {
return nil, err
}
return &udpp2p.Settings{
Notify: u.notify,
Payload: mh,
}, nil
}
func Search(deviceName, deviceType string, notify NotifyHandler, stop chan struct{}, logger *zap.Logger) error {
un, err := NewUDPNotifier(logger, notify)
if err != nil {
return err
}
settings, err := un.MakeUDPP2PSettings(deviceName, deviceType)
if err != nil {
return err
}
settings.Delay = pingInterval
settings.TimeLimit = searchLimit
settings.StopChan = stop
go func() {
defer common.LogOnPanic()
_, err = udpp2p.Discover(*settings)
logger.Error("error while discovering udp peers", zap.Error(err))
}()
return nil
}