status-go/server/pairing/TODO.MD

4.4 KiB

Local Pairing To-dos

Network Address / Peer Discovery

Revamp the preferred network discovery process

Note this functionality is pre-secret share so doesn't ...

  • Pre-shared secret: scan the QR code first, containing the secret and then attempt to discover the other device(s)
    • ⚠️ Problem: Only works if UDP discovery works. See possible solution for UDP discovery failure mitigation
    • Start pairing server on relevant device, listen to 0.0.0.0.
      • get selected port number
      • get TLS pub key
      • get secret
    • Scan QR code which including:
      • selected port number
      • TLS pub key
      • secret
    • UDP discovery happens 🧙🪄
    • devices acquire ip addresses of peer(s), and themselves.
    • client device attempts connection as normal
  • Post-shared secret, which is confirmed later with the QR code
    • UDP discovery happens 🧙🪄
    • devices acquire ip addresses of peer(s), and themselves.
      • can also optionally give feedback to the user with the pairing options.
    • server device starts server listener, listen to known network ip address
      • get selected port number
      • get TLS pub key
      • get secret
    • Scan QR code which including:
      • selected port number
      • TLS pub key
      • secret
    • client device attempts connection as normal

Self IP address acquisition

  1. Ask network interface for its preferred outbound IP address
    • The process currently relied on
    • Add a required a self "confirmation" ping, to ensure the given address is network addressable.
    • On fail, fall through to stage 2
  2. device gets a list of its network addresses.
    • Use netIfaces, err := net.Interfaces() See snippet
    • run filter for only local private net addrs
    • open listener on 0.0.0.0
    • make an outbound network call to all ips
      • call should include the addressing ip so device knows which address is network addressable
    • record all ip addresses that are able to ping the listener.
      • hopefully the list will only ever contain 1 IP address
    • On fail, fall through to stage 3
  3. Attempt discovery via UDP multicast
    • Question : How do both devices know when to start UDP discovery?
      • Perhaps the QR code device can add details to the application
    • no guarantee that both devices get an IP address

Network Debug Diagnostics

We need to check a few things if a connection isn't working

  • What network ip address does the device think it has?
  • What is the port number the listener is listening on?
  • Can the device access its own network IP address?
  • Can a device find, and be found by, other devices?
    • attempt UDP discovery
  • What is the device's network connection(s) status?
    • ipconfig / ifconfig
  • Test each in series, all above functions
    • Capture everything, even errors
      • DO NOT early return errors, log the errors, proceed with the next function.
    • log all outputs to standard logger
    • log all outputs memory for export / return
    • When test suite is complete return log out put

Refs

UDP discovery failure mitigation
  • Both devices listen on a tcp port chosen by the network interface
  • Attempt UDP discovery
  • In the UDP packet include:
    • the device's listener port number
    • ensure the notifier's id is stored for later connections via tcp
  • When peer A discovers peer B, peer A pings peer B's "confirmation" listener with peer B's IP address and network info about peer A
  • peer B attempts an outbound TLS connection to its own "confirmation" server, with a random code, to confirm its own IP address.
Get all network addresses
package test

import (
   "fmt"
   "net"
)

func AllNetworkAddresses() error {
   netIfaces, err := net.Interfaces()
   if err != nil {
      return err
   }

   for _, i := range netIfaces {
      addrs, err := i.Addrs()
      if err != nil {
         return err
      }

      for _, addr := range addrs {
         var ip net.IP
         switch v := addr.(type) {
         case *net.IPNet:
            ip = v.IP
         case *net.IPAddr:
            ip = v.IP
         default:
			 return fmt.Errorf("unknown ip type %s", v)
         }
         fmt.Print(ip)
      }
   }
   return nil
}