Intergrated with external API endpoint
This commit is contained in:
parent
419700f2c3
commit
552c58bb9c
|
@ -1023,6 +1023,21 @@ func GenerateImages(filepath string, aX, aY, bX, bY int) string {
|
|||
return string(data)
|
||||
}
|
||||
|
||||
// StartSearchForLocalPairingPeers starts a UDP multicast beacon that both listens for and broadcasts to LAN peers
|
||||
// on discovery the beacon will emit a signal with the details of the discovered peer.
|
||||
//
|
||||
// Currently, beacons are configured to search for 2 minutes pinging the network every 500 ms;
|
||||
// - If no peer discovery is made before this time elapses the operation will terminate.
|
||||
// - If a peer is discovered the pairing.PeerNotifier will terminate operation after 5 seconds, giving the peer
|
||||
// reasonable time to discover this device.
|
||||
//
|
||||
// Peer details are represented by a json.Marshal peers.LocalPairingPeerHello
|
||||
func StartSearchForLocalPairingPeers() string {
|
||||
pn := pairing.NewPeerNotifier()
|
||||
err := pn.Search()
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
// GetConnectionStringForBeingBootstrapped starts a pairing.ReceiverServer
|
||||
// then generates a pairing.ConnectionParams. Used when the device is Logged out or has no Account keys
|
||||
// and the device has no camera to read a QR code with
|
||||
|
|
|
@ -6,6 +6,7 @@ type EventType string
|
|||
const (
|
||||
// Both Sender and Receiver
|
||||
|
||||
EventPeerDiscovered EventType = "peer-discovered"
|
||||
EventConnectionError EventType = "connection-error"
|
||||
EventConnectionSuccess EventType = "connection-success"
|
||||
EventTransferError EventType = "transfer-error"
|
||||
|
@ -33,4 +34,5 @@ const (
|
|||
ActionPairingAccount
|
||||
ActionSyncDevice
|
||||
ActionPairingInstallation
|
||||
ActionPeerDiscovery
|
||||
)
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
package pairing
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/status-im/status-go/logutils"
|
||||
"github.com/status-im/status-go/server"
|
||||
"github.com/status-im/status-go/server/pairing/peers"
|
||||
"github.com/status-im/status-go/signal"
|
||||
)
|
||||
|
||||
type PeerNotifier struct {
|
||||
logger *zap.Logger
|
||||
stop chan struct{}
|
||||
}
|
||||
|
||||
func NewPeerNotifier() *PeerNotifier {
|
||||
logger := logutils.ZapLogger().Named("PeerNotifier")
|
||||
stop := make(chan struct{})
|
||||
|
||||
return &PeerNotifier{
|
||||
logger: logger,
|
||||
stop: stop,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PeerNotifier) handler(hello *peers.LocalPairingPeerHello) {
|
||||
signal.SendLocalPairingEvent(Event{Type: EventPeerDiscovered, Action: ActionPeerDiscovery, Data: hello})
|
||||
p.logger.Debug("received peers.LocalPairingPeerHello message", zap.Any("hello message", hello))
|
||||
// TODO p.stop <- struct{}{} Don't do this immediately start a countdown to kill after 5 seconds to allow the
|
||||
// peer to discover us.
|
||||
}
|
||||
|
||||
func (p *PeerNotifier) Search() error {
|
||||
dn, err := server.GetDeviceName()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return peers.Search(dn, runtime.GOOS, p.handler, p.stop, p.logger)
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
package peers
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
udpp2p "github.com/schollz/peerdiscovery"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/status-im/status-go/server"
|
||||
)
|
||||
|
||||
var (
|
||||
// pk Yes this is an actual ECDSA **private** key committed to a public repository visible to anyone.
|
||||
// DO NOT use this key for anything other than signing udp "hellos". The key's value is in giving other Status
|
||||
// installations CONFIDENCE, NOT proof, that the sender of the UDP pings is another Status device.
|
||||
// We do not rely on UDP message information to orchestrate connections or swap secrets. The use case is purely
|
||||
// to make preflight checks which ADVISE the application and the user.
|
||||
//
|
||||
// A signature is more robust and flexible than an application identifier, and serves the same role as an ID, while
|
||||
// securing the payload against tampering.
|
||||
pk = []byte{0xbf, 0x3b, 0x37, 0x04, 0x30, 0x04, 0x32, 0x15, 0x72, 0xb0, 0x7f, 0x56, 0x72, 0x30, 0xae, 0x5b, 0x41, 0xf4, 0x4b, 0x42, 0x4a, 0xa2, 0x33, 0x53, 0x76, 0xed, 0x7a, 0xb9, 0x2d, 0x40, 0x37, 0x73}
|
||||
k = &ecdsa.PrivateKey{}
|
||||
)
|
||||
|
||||
func init() {
|
||||
k = server.ToECDSA(pk)
|
||||
}
|
||||
|
||||
type UDPNotifier struct {
|
||||
logger *zap.Logger
|
||||
id []byte
|
||||
notifyOutput func(*LocalPairingPeerHello)
|
||||
}
|
||||
|
||||
func NewUDPNotifier(logger *zap.Logger, outputFunc func(*LocalPairingPeerHello)) (*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 string) (*LocalPairingPeerHello, error) {
|
||||
return NewLocalPairingPeerHello(u.id, deviceName, runtime.GOOS, 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 string) (*udpp2p.Settings, error) {
|
||||
if u.notifyOutput == nil {
|
||||
return nil, fmt.Errorf("UDPNotifier has no notiftOutput function defined")
|
||||
}
|
||||
|
||||
h, err := u.MakePayload(deviceName)
|
||||
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() {
|
||||
discoveries, _ := udpp2p.Discover(udpp2p.Settings{Limit: 1, AllowSelf: true})
|
||||
for _, d := range discoveries {
|
||||
fmt.Printf("discovered '%s'\n", d.Address)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package peers
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
|
||||
"github.com/status-im/status-go/server"
|
||||
)
|
||||
|
||||
var (
|
||||
// pk Yes this is an actual ECDSA **private** key committed to a public repository visible to anyone.
|
||||
// DO NOT use this key for anything other than signing udp "hellos". The key's value is in giving other Status
|
||||
// installations CONFIDENCE, NOT proof, that the sender of the UDP pings is another Status device.
|
||||
// We do not rely on UDP message information to orchestrate connections or swap secrets. The use case is purely
|
||||
// to make preflight checks which ADVISE the application and the user.
|
||||
//
|
||||
// A signature is more robust and flexible than an application identifier, and serves the same role as an ID, while
|
||||
// securing the payload against tampering.
|
||||
pk = []byte{0xbf, 0x3b, 0x37, 0x04, 0x30, 0x04, 0x32, 0x15, 0x72, 0xb0, 0x7f, 0x56, 0x72, 0x30, 0xae, 0x5b, 0x41, 0xf4, 0x4b, 0x42, 0x4a, 0xa2, 0x33, 0x53, 0x76, 0xed, 0x7a, 0xb9, 0x2d, 0x40, 0x37, 0x73}
|
||||
k = &ecdsa.PrivateKey{}
|
||||
)
|
||||
|
||||
func init() {
|
||||
k = server.ToECDSA(pk)
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
package peers
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
udpp2p "github.com/schollz/peerdiscovery"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
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 = 500 * time.Millisecond
|
||||
settings.TimeLimit = 2 * time.Minute
|
||||
settings.StopChan = stop
|
||||
|
||||
go func() {
|
||||
_, err = udpp2p.Discover(*settings)
|
||||
logger.Error("error while discovering udp peers", zap.Error(err))
|
||||
}()
|
||||
return nil
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package peers
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -8,7 +9,6 @@ import (
|
|||
udpp2p "github.com/schollz/peerdiscovery"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/status-im/status-go/server"
|
||||
"github.com/status-im/status-go/server/servertest"
|
||||
)
|
||||
|
||||
|
@ -30,7 +30,7 @@ type testSignalLogger struct {
|
|||
lock sync.Mutex
|
||||
}
|
||||
|
||||
func NewTestSignalLogger() *testSignalLogger {
|
||||
func newTestSignalLogger() *testSignalLogger {
|
||||
tsl := new(testSignalLogger)
|
||||
tsl.log = make(map[string]map[string]bool)
|
||||
return tsl
|
||||
|
@ -39,17 +39,15 @@ func NewTestSignalLogger() *testSignalLogger {
|
|||
func (t *testSignalLogger) testSignal(h *LocalPairingPeerHello) {
|
||||
t.lock.Lock()
|
||||
defer t.lock.Unlock()
|
||||
|
||||
if _, ok := t.log[h.Discovered.Address]; !ok {
|
||||
t.log[h.Discovered.Address] = make(map[string]bool)
|
||||
}
|
||||
t.log[h.Discovered.Address][h.DeviceName] = true
|
||||
}
|
||||
|
||||
func (s *UDPPeerDiscoverySuite) Test() {
|
||||
n, err := server.GetDeviceName()
|
||||
s.Require().NoError(err)
|
||||
|
||||
tsl := NewTestSignalLogger()
|
||||
func (s *UDPPeerDiscoverySuite) TestUDPNotifier() {
|
||||
tsl := newTestSignalLogger()
|
||||
|
||||
u1, err := NewUDPNotifier(s.Logger, tsl.testSignal)
|
||||
s.Require().NoError(err)
|
||||
|
@ -57,13 +55,13 @@ func (s *UDPPeerDiscoverySuite) Test() {
|
|||
u2, err := NewUDPNotifier(s.Logger, tsl.testSignal)
|
||||
s.Require().NoError(err)
|
||||
|
||||
n1 := n + " - device 1"
|
||||
n2 := n + " - device 2"
|
||||
n1 := "device 1"
|
||||
n2 := "device 2"
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
settings, err := u1.MakeUDPP2PSettings(n1)
|
||||
settings, err := u1.MakeUDPP2PSettings(n1, runtime.GOOS)
|
||||
s.Require().NoError(err)
|
||||
|
||||
settings.TimeLimit = 2 * time.Second
|
||||
|
@ -77,7 +75,7 @@ func (s *UDPPeerDiscoverySuite) Test() {
|
|||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
settings, err := u2.MakeUDPP2PSettings(n2)
|
||||
settings, err := u2.MakeUDPP2PSettings(n2, runtime.GOOS)
|
||||
s.Require().NoError(err)
|
||||
|
||||
settings.TimeLimit = 2 * time.Second
|
Loading…
Reference in New Issue