github.com/status-im/status-go@v1.1.0/server/pairing/peers/udp_notifier.go (about) 1 package peers 2 3 import ( 4 "crypto/rand" 5 "fmt" 6 "time" 7 8 "github.com/golang/protobuf/proto" 9 udpp2p "github.com/schollz/peerdiscovery" 10 "go.uber.org/zap" 11 ) 12 13 const ( 14 pingInterval = 500 * time.Millisecond 15 searchLimit = 2 * time.Minute 16 ) 17 18 type NotifyHandler func(*LocalPairingPeerHello) 19 20 type UDPNotifier struct { 21 logger *zap.Logger 22 id []byte 23 notifyOutput NotifyHandler 24 } 25 26 func NewUDPNotifier(logger *zap.Logger, outputFunc NotifyHandler) (*UDPNotifier, error) { 27 randID := make([]byte, 32) 28 _, err := rand.Read(randID) 29 if err != nil { 30 return nil, err 31 } 32 33 n := new(UDPNotifier) 34 n.logger = logger 35 n.id = randID 36 n.notifyOutput = outputFunc 37 return n, nil 38 } 39 40 func (u *UDPNotifier) makePayload(deviceName, deviceType string) (*LocalPairingPeerHello, error) { 41 return NewLocalPairingPeerHello(u.id, deviceName, deviceType, k) 42 } 43 44 func (u *UDPNotifier) notify(d udpp2p.Discovered) { 45 h := new(LocalPairingPeerHello) 46 err := proto.Unmarshal(d.Payload, &h.LocalPairingPeerHello) 47 if err != nil { 48 u.logger.Error("notify unmarshalling of payload failed", zap.Error(err)) 49 return 50 } 51 52 ok := h.verify(&k.PublicKey) 53 if !ok { 54 u.logger.Error("verification of unmarshalled payload failed", zap.Any("LocalPairingPeerHello", h)) 55 return 56 } 57 58 h.Discovered = d 59 u.notifyOutput(h) 60 } 61 62 func (u *UDPNotifier) MakeUDPP2PSettings(deviceName, deviceType string) (*udpp2p.Settings, error) { 63 if u.notifyOutput == nil { 64 return nil, fmt.Errorf("UDPNotifier has no notiftOutput function defined") 65 } 66 67 h, err := u.makePayload(deviceName, deviceType) 68 if err != nil { 69 return nil, err 70 } 71 72 mh, err := proto.Marshal(&h.LocalPairingPeerHello) 73 if err != nil { 74 return nil, err 75 } 76 77 return &udpp2p.Settings{ 78 Notify: u.notify, 79 Payload: mh, 80 }, nil 81 } 82 83 func Search(deviceName, deviceType string, notify NotifyHandler, stop chan struct{}, logger *zap.Logger) error { 84 un, err := NewUDPNotifier(logger, notify) 85 if err != nil { 86 return err 87 } 88 89 settings, err := un.MakeUDPP2PSettings(deviceName, deviceType) 90 if err != nil { 91 return err 92 } 93 94 settings.Delay = pingInterval 95 settings.TimeLimit = searchLimit 96 settings.StopChan = stop 97 98 go func() { 99 _, err = udpp2p.Discover(*settings) 100 logger.Error("error while discovering udp peers", zap.Error(err)) 101 }() 102 return nil 103 }