status-go/server/ips_test.go

272 lines
6.4 KiB
Go

package server
import (
"fmt"
"net"
"testing"
"github.com/stretchr/testify/suite"
"go.uber.org/zap"
"github.com/status-im/status-go/server/servertest"
)
func TestIPsTestingSuite(t *testing.T) {
suite.Run(t, new(IPsTestingSuite))
}
type IPsTestingSuite struct {
suite.Suite
servertest.TestLoggerComponents
}
func (s *IPsTestingSuite) SetupSuite() {
s.SetupLoggerComponents()
}
func (s *IPsTestingSuite) TestConnectionParams_GetLocalAddressesForPairingServer() {
allIps := [][]net.IP{
{
net.IPv4(127, 0, 0, 1),
net.IPv6loopback,
},
{
net.IPv4(192, 168, 1, 42),
net.IP{0xfc, 0x80, 0, 0, 0, 0, 0, 0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},
},
{
net.IPv4(11, 12, 13, 14),
},
{
net.IP{0xfc, 0x80, 0, 0, 0, 0, 0, 0, 0xff, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},
},
{
net.IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0xff, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},
},
}
// First NI is a loop-back
ni0 := allIps[0]
s.Require().NotNil(ni0[0].To4())
s.Require().True(ni0[0].IsLoopback())
s.Require().Len(ni0[1], net.IPv6len)
s.Require().True(ni0[1].IsLoopback())
// Second NI's both IP addresses fits the needs. IPv6 should be filtered out.
ni1 := allIps[1]
s.Require().NotNil(ni1[0].To4())
s.Require().True(ni1[0].IsGlobalUnicast())
s.Require().True(ni1[0].IsPrivate())
s.Require().Len(ni1[1], net.IPv6len)
s.Require().True(ni1[1].IsGlobalUnicast())
s.Require().True(ni1[1].IsPrivate())
// Next NI should be filtered out as non-private
ni2 := allIps[2]
s.Require().NotNil(ni2[0].To4())
s.Require().False(ni2[0].IsPrivate())
// Next NI fits the needs, should be taken,
// as no preferred IPv4 is available on this NI.
ni3 := allIps[3]
s.Require().Len(ni3[0], net.IPv6len)
s.Require().True(ni3[0].IsGlobalUnicast())
s.Require().True(ni3[0].IsPrivate())
// Last NI has a link-local unicast address,
// which should be filtered out as non-private.
ni4 := allIps[4]
s.Require().Len(ni4[0], net.IPv6len)
s.Require().True(ni4[0].IsLinkLocalUnicast())
s.Require().False(ni4[0].IsGlobalUnicast())
s.Require().False(ni4[0].IsPrivate())
ips := filterAddressesForPairingServer(allIps)
s.Require().Len(ips, 2)
s.Require().NotNil(ips[0].To4())
s.Require().NotNil(ni1[0].To4())
s.Require().Equal(ips[0].To4(), ni1[0].To4())
s.Require().Equal(ips[1], ni3[0])
}
func (s *IPsTestingSuite) TestConnectionParams_FindReachableAddresses() {
var remoteIps []net.IP
var localNets []net.IPNet
var ips []net.IP
// Test 1
remoteIps = []net.IP{
net.IPv4(10, 1, 2, 3),
net.IPv4(172, 16, 2, 42),
net.IPv4(192, 168, 1, 42),
}
localNets = []net.IPNet{
{IP: net.IPv4(192, 168, 1, 43), Mask: net.IPv4Mask(255, 255, 255, 0)},
}
ips = findReachableAddresses(remoteIps, localNets)
s.Require().Len(ips, 1)
s.Require().Equal(ips[0], remoteIps[2])
// Test 2
remoteIps = []net.IP{
net.IPv4(10, 1, 2, 3),
net.IPv4(172, 16, 2, 42),
net.IPv4(192, 168, 1, 42),
}
localNets = []net.IPNet{
{IP: net.IPv4(10, 1, 1, 1), Mask: net.IPv4Mask(255, 255, 0, 0)},
{IP: net.IPv4(172, 16, 2, 43), Mask: net.IPv4Mask(255, 255, 255, 0)},
{IP: net.IPv4(192, 168, 2, 43), Mask: net.IPv4Mask(255, 255, 255, 0)},
}
ips = findReachableAddresses(remoteIps, localNets)
s.Require().Len(ips, 2)
s.Require().Equal(ips[0], remoteIps[0])
s.Require().Equal(ips[1], remoteIps[1])
// Test 3
remoteIps = []net.IP{
net.IPv4(10, 1, 2, 3),
net.IPv4(172, 16, 2, 42),
net.IPv4(192, 168, 1, 42),
}
localNets = []net.IPNet{}
ips = findReachableAddresses(remoteIps, localNets)
s.Require().Len(ips, 0)
// Test 4
remoteIps = []net.IP{}
localNets = []net.IPNet{}
ips = findReachableAddresses(remoteIps, localNets)
s.Require().Len(ips, 0)
}
func (s *IPsTestingSuite) TestConnectionParams_RealNetworksTest() {
// This test is intended to be run manually.
// 1. set `printDetails` to true
// 2. run Part 1 on 2 devices
// 3. copy printed results to Part 2
// 4. update expected results in Part 3
// 5. run Part 3
// printing is disabled by default to avoid showing sensitive information
const printDetails = false
printLocalAddresses := func(in [][]net.IP) {
fmt.Println("{")
for _, a := range in {
fmt.Println(" {")
for _, v := range a {
fmt.Println(" net.ParseIP(\"", v.String(), "\"),")
}
fmt.Println(" },")
}
fmt.Println("}")
}
printNets := func(in []net.IPNet) {
fmt.Println("{")
for _, n := range in {
fmt.Println(" \"", n.String(), "\",")
}
fmt.Println("}")
}
parseNets := func(in []string) []net.IPNet {
var out []net.IPNet
for _, v := range in {
_, network, err := net.ParseCIDR(v)
s.Require().NoError(err)
out = append(out, *network)
}
return out
}
// Part 1:
// print needed stuff. Run on both machines.
addrs, err := getLocalAddresses()
s.Require().NoError(err)
s.Logger.Info("MacOS:", zap.Any("addrs", addrs))
if printDetails {
printLocalAddresses(addrs)
}
nets, err := getAllAvailableNetworks()
s.Require().NoError(err)
s.Logger.Info("MacOS:", zap.Any("nets", nets))
if printDetails {
printNets(nets)
}
// Part 2:
// Input all printed devices details below
macNIs := [][]net.IP{
{
net.ParseIP("127.0.0.1"),
net.ParseIP("::1"),
net.ParseIP("fe80::1"),
},
{
net.ParseIP("fe80::c1f:ee0d:1476:dd9a"),
net.ParseIP("192.168.1.36"),
},
{
net.ParseIP("172.16.9.1"),
},
}
macNets := parseNets([]string{
"127.0.0.1/8",
"::1/128",
"fe80::1/64",
"fe80::c1f:ee0d:1476:dd9a/64",
"192.168.1.36/24",
"172.16.9.1/24",
})
winNIs := [][]net.IP{
{
net.ParseIP("fe80::6fd7:5ce4:554f:165a"),
net.ParseIP("192.168.1.33"),
},
{
net.ParseIP("fe80::ffa5:98e1:285c:42eb"),
net.ParseIP("10.0.85.2"),
},
{
net.ParseIP("::1"),
net.ParseIP("127.0.0.1"),
},
}
winNets := parseNets([]string{
"fe80::6fd7:5ce4:554f:165a/64",
"192.168.1.33/24",
"fe80::ffa5:98e1:285c:42eb/64",
"10.0.85.2/32",
"::1/128",
"127.0.0.1/8",
})
// Part 3:
// The test itself
// Windows as server, Mac as client
winIPs := filterAddressesForPairingServer(winNIs)
winReachableIps := findReachableAddresses(winIPs, macNets)
s.Require().Len(winReachableIps, 1)
s.Require().Equal(winReachableIps[0].String(), "192.168.1.33")
// Windows as server, Mac as client
macIPs := filterAddressesForPairingServer(macNIs)
macReachableIps := findReachableAddresses(macIPs, winNets)
s.Require().Len(macReachableIps, 1)
s.Require().Equal(macReachableIps[0].String(), "192.168.1.36")
}