From d6f9fa913273889ea151c8267d4978fda71c8bec Mon Sep 17 00:00:00 2001 From: Taras Nepyipyvo Date: Wed, 18 Nov 2020 15:42:51 +0200 Subject: [PATCH 01/41] Advertise public visors. --- pkg/app/appdisc/factory.go | 24 ++++++++++++++++++ pkg/servicedisc/client.go | 25 +++++++++++-------- pkg/servicedisc/types.go | 11 ++++++--- pkg/snet/network.go | 47 +++++++++++++++++++++++++++++------ pkg/visor/init.go | 49 +++++++++++++++++++++++++++++++++++++ pkg/visor/visorconfig/v1.go | 5 ++-- 6 files changed, 138 insertions(+), 23 deletions(-) diff --git a/pkg/app/appdisc/factory.go b/pkg/app/appdisc/factory.go index bdcc145810..a7a33e88c1 100644 --- a/pkg/app/appdisc/factory.go +++ b/pkg/app/appdisc/factory.go @@ -55,6 +55,30 @@ func (f *Factory) VisorUpdater(port uint16) Updater { } } +// PublicVisorUpdater obtains a visor updater. +func (f *Factory) PublicVisorUpdater(port uint16, publicAddr string) Updater { + // Always return empty updater if keys are not set. + if f.setDefaults(); f.PK.Null() || f.SK.Null() { + return &emptyUpdater{} + } + + conf := servicedisc.Config{ + Type: servicedisc.ServiceTypePublicVisor, + PK: f.PK, + SK: f.SK, + Port: port, + DiscAddr: f.ProxyDisc, + } + + client := servicedisc.NewClient(f.Log, conf) + client.Entry.PublicAddress = publicAddr + + return &serviceUpdater{ + client: client, + interval: f.UpdateInterval, + } +} + // AppUpdater obtains an app updater based on the app name and configuration. func (f *Factory) AppUpdater(conf appcommon.ProcConfig) (Updater, bool) { // Always return empty updater if keys are not set. diff --git a/pkg/servicedisc/client.go b/pkg/servicedisc/client.go index d2cc51c79a..3abdf4cca4 100644 --- a/pkg/servicedisc/client.go +++ b/pkg/servicedisc/client.go @@ -8,6 +8,7 @@ import ( "fmt" "io/ioutil" "net/http" + "strconv" "strings" "sync" "time" @@ -36,7 +37,7 @@ type Config struct { type HTTPClient struct { log logrus.FieldLogger conf Config - entry Service + Entry Service entryMx sync.Mutex // only used if UpdateLoop && UpdateStats functions are used. client http.Client } @@ -51,7 +52,7 @@ func NewClient(log logrus.FieldLogger, conf Config) *HTTPClient { return &HTTPClient{ log: log, conf: conf, - entry: Service{ + Entry: Service{ Addr: NewSWAddr(conf.PK, conf.Port), Stats: stats, Type: conf.Type, @@ -96,8 +97,12 @@ func (c *HTTPClient) Auth(ctx context.Context) (*httpauth.Client, error) { } // Services calls 'GET /api/services'. -func (c *HTTPClient) Services(ctx context.Context) (out []Service, err error) { - req, err := http.NewRequestWithContext(ctx, http.MethodGet, c.addr("/api/services", c.entry.Type), nil) +func (c *HTTPClient) Services(ctx context.Context, quantity int) (out []Service, err error) { + addr := c.addr("/api/services", c.Entry.Type) + if quantity != 0 { + addr += "&quantity=" + strconv.Itoa(quantity) + } + req, err := http.NewRequestWithContext(ctx, http.MethodGet, addr, nil) if err != nil { return nil, err } @@ -133,9 +138,9 @@ func (c *HTTPClient) UpdateEntry(ctx context.Context) (*Service, error) { return nil, err } - c.entry.Addr = NewSWAddr(c.conf.PK, c.conf.Port) // Just in case. + c.Entry.Addr = NewSWAddr(c.conf.PK, c.conf.Port) // Just in case. - raw, err := json.Marshal(&c.entry) + raw, err := json.Marshal(&c.Entry) if err != nil { return nil, err } @@ -170,8 +175,8 @@ func (c *HTTPClient) UpdateEntry(ctx context.Context) (*Service, error) { return nil, hErr.Error } - err = json.NewDecoder(resp.Body).Decode(&c.entry) - return &c.entry, err + err = json.NewDecoder(resp.Body).Decode(&c.Entry) + return &c.Entry, err } // DeleteEntry calls 'DELETE /api/services/{entry_addr}'. @@ -181,7 +186,7 @@ func (c *HTTPClient) DeleteEntry(ctx context.Context) (err error) { return err } - req, err := http.NewRequestWithContext(ctx, http.MethodDelete, c.addr("/api/services/"+c.entry.Addr.String(), c.entry.Type), nil) + req, err := http.NewRequestWithContext(ctx, http.MethodDelete, c.addr("/api/services/"+c.Entry.Addr.String(), c.Entry.Type), nil) if err != nil { return err } @@ -260,6 +265,6 @@ func (c *HTTPClient) UpdateLoop(ctx context.Context, updateInterval time.Duratio // UpdateStats updates the stats field of the internal service entry state. func (c *HTTPClient) UpdateStats(stats Stats) { c.entryMx.Lock() - c.entry.Stats = &stats + c.Entry.Stats = &stats c.entryMx.Unlock() } diff --git a/pkg/servicedisc/types.go b/pkg/servicedisc/types.go index 9e7e06e988..ce5f38f5e5 100644 --- a/pkg/servicedisc/types.go +++ b/pkg/servicedisc/types.go @@ -17,6 +17,8 @@ const ( ServiceTypeVPN = "vpn" // ServiceTypeVisor stands for visor. ServiceTypeVisor = "visor" + // ServiceTypeVisor stands for type of visors that accessible on pulic address. + ServiceTypePublicVisor = "public_visor" ) // Errors associated with service discovery types. @@ -104,10 +106,11 @@ type Stats struct { // Service represents a service entry in service-discovery. type Service struct { - Addr SWAddr `json:"address"` - Type string `json:"type"` - Stats *Stats `json:"stats,omitempty"` // TODO: Have this implemented. - Geo *GeoLocation `json:"geo,omitempty"` + Addr SWAddr `json:"address"` + Type string `json:"type"` + PublicAddress string `json:"public_address,omitempty"` + Stats *Stats `json:"stats,omitempty"` // TODO: Have this implemented. + Geo *GeoLocation `json:"geo,omitempty"` } // MarshalBinary implements encoding.BinaryMarshaller diff --git a/pkg/snet/network.go b/pkg/snet/network.go index 094bc5aa52..8835ac0667 100644 --- a/pkg/snet/network.go +++ b/pkg/snet/network.go @@ -60,8 +60,9 @@ func (c *DmsgConfig) Type() string { // STCPConfig defines config for STCP network. type STCPConfig struct { - PKTable map[cipher.PubKey]string `json:"pk_table"` - LocalAddr string `json:"local_address"` + PKTable map[cipher.PubKey]string `json:"pk_table"` + LocalAddr string `json:"local_address"` + PublicAddress string `json:"public_address"` } // Type returns STCP type. @@ -77,6 +78,7 @@ type Config struct { NetworkConfigs NetworkConfigs ServiceDisc appdisc.Factory PublicTrusted bool + PublicAddress string } // NetworkConfigs represents all network configs. @@ -93,11 +95,12 @@ type NetworkClients struct { // Network represents a network between nodes in Skywire. type Network struct { - conf Config - netsMu sync.RWMutex - nets map[string]struct{} // networks to be used with transports - clients NetworkClients - visorUpdater appdisc.Updater + conf Config + netsMu sync.RWMutex + nets map[string]struct{} // networks to be used with transports + clients NetworkClients + visorUpdater appdisc.Updater + publicVisorUpdater appdisc.Updater onNewNetworkTypeMu sync.Mutex onNewNetworkType func(netType string) @@ -230,6 +233,9 @@ func (n *Network) Init() error { if n.conf.PublicTrusted { go n.registerPublicTrusted(client) } + if n.conf.PublicAddress != "" { + go n.registerAsPublicVisor(client) + } } else { log.Infof("No config found for stcpr") } @@ -272,6 +278,33 @@ func (n *Network) registerPublicTrusted(client directtp.Client) { log.Infof("Sent request to register visor as public trusted") } +func (n *Network) registerAsPublicVisor(client directtp.Client) { + log.Infof("Trying to register visor as public visor") + + la, err := client.LocalAddr() + if err != nil { + log.WithError(err).Errorf("Failed to get STCPR local addr") + return + } + + _, portStr, err := net.SplitHostPort(la.String()) + if err != nil { + log.WithError(err).Errorf("Failed to extract port from addr %v", la.String()) + return + } + + port, err := strconv.Atoi(portStr) + if err != nil { + log.WithError(err).Errorf("Failed to convert port to int") + return + } + + n.publicVisorUpdater = n.conf.ServiceDisc.PublicVisorUpdater(uint16(port), n.conf.PublicAddress) + + n.publicVisorUpdater.Start() + + log.Infof("Sent request to register visor as public") +} // OnNewNetworkType sets callback to be called when new network type is ready. func (n *Network) OnNewNetworkType(callback func(netType string)) { diff --git a/pkg/visor/init.go b/pkg/visor/init.go index 36527faae3..0f94633da5 100644 --- a/pkg/visor/init.go +++ b/pkg/visor/init.go @@ -26,6 +26,7 @@ import ( "github.com/skycoin/skywire/pkg/app/launcher" "github.com/skycoin/skywire/pkg/routefinder/rfclient" "github.com/skycoin/skywire/pkg/router" + "github.com/skycoin/skywire/pkg/servicedisc" "github.com/skycoin/skywire/pkg/setup/setupclient" "github.com/skycoin/skywire/pkg/skyenv" "github.com/skycoin/skywire/pkg/snet" @@ -56,6 +57,7 @@ func initStack() []initFunc { initUptimeTracker, initTrustedVisors, initHypervisor, + initPublicVisors, } } @@ -103,6 +105,7 @@ func initSNet(v *Visor) bool { NetworkConfigs: nc, ServiceDisc: v.serviceDisc, PublicTrusted: v.conf.PublicTrustedVisor, + PublicAddress: v.conf.STCP.PublicAddress, } n, err := snet.New(conf, v.ebc) @@ -519,6 +522,52 @@ func initTrustedVisors(v *Visor) bool { return true } +func initPublicVisors(v *Visor) bool { + const trustedVisorsTransportType = tptypes.STCPR + if v.conf.Launcher.Discovery.PublicVisorsEnabled { + proxyDisc := v.conf.Launcher.Discovery.ServiceDisc + if proxyDisc == "" { + proxyDisc = skyenv.DefaultServiceDiscAddr + } + log = logging.MustGetLogger("appdisc") + + conf := servicedisc.Config{ + Type: servicedisc.ServiceTypePublicVisor, + PK: v.conf.PK, + SK: v.conf.SK, + DiscAddr: proxyDisc, + } + + client := servicedisc.NewClient(log, conf) + client.Entry.PublicAddress = v.conf.STCP.PublicAddress + + go func() { + time.Sleep(transport.TrustedVisorsDelay * 2) + services, err := client.Services(context.Background(), 5) + if err != nil { + log.WithError(err).Error("Can't fetch public visors") + } + for _, service := range services { + pk := service.Addr.PubKey() + v.log.WithField("pk", pk).Infof("Adding public visor") + if _, err := v.tpM.SaveTransport(context.Background(), pk, trustedVisorsTransportType); err != nil { + v.log. + WithError(err). + WithField("pk", pk). + WithField("type", trustedVisorsTransportType). + Warnf("Failed to add transport to public visor via") + } else { + v.log. + WithField("pk", pk). + WithField("type", trustedVisorsTransportType). + Infof("Added transport to public visor") + } + } + }() + } + return true +} + func initHypervisor(v *Visor) bool { if v.conf.Hypervisor == nil { return true diff --git a/pkg/visor/visorconfig/v1.go b/pkg/visor/visorconfig/v1.go index a9b31f0739..83e049a5ae 100644 --- a/pkg/visor/visorconfig/v1.go +++ b/pkg/visor/visorconfig/v1.go @@ -77,8 +77,9 @@ type V1UptimeTracker struct { // V1AppDisc configures Skywire App Discovery Clients. type V1AppDisc struct { - UpdateInterval Duration `json:"update_interval,omitempty"` - ServiceDisc string `json:"proxy_discovery_addr"` // TODO: change JSON name + UpdateInterval Duration `json:"update_interval,omitempty"` + ServiceDisc string `json:"proxy_discovery_addr"` // TODO: change JSON name + PublicVisorsEnabled bool `json:"connect_to_public_visors"` // TODO: change JSON name } // V1Launcher configures the app launcher. From 0f2dfe8f7a379b80b3e1fb7c1cb912cee39abab6 Mon Sep 17 00:00:00 2001 From: Taras Nepyipyvo Date: Wed, 18 Nov 2020 15:52:56 +0200 Subject: [PATCH 02/41] Fix linter --- pkg/servicedisc/types.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/servicedisc/types.go b/pkg/servicedisc/types.go index ce5f38f5e5..a8d3d8b4cf 100644 --- a/pkg/servicedisc/types.go +++ b/pkg/servicedisc/types.go @@ -17,7 +17,7 @@ const ( ServiceTypeVPN = "vpn" // ServiceTypeVisor stands for visor. ServiceTypeVisor = "visor" - // ServiceTypeVisor stands for type of visors that accessible on pulic address. + // ServiceTypePublicVisor stands for type of visors that accessible on pulic address. ServiceTypePublicVisor = "public_visor" ) From c1f2a7374b69e1eb7018eb7b2f57eb9c9126dcbb Mon Sep 17 00:00:00 2001 From: Taras Nepyipyvo Date: Wed, 18 Nov 2020 17:05:02 +0200 Subject: [PATCH 03/41] Add explicit return. --- pkg/servicedisc/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/servicedisc/client.go b/pkg/servicedisc/client.go index 3abdf4cca4..bd7f1fe325 100644 --- a/pkg/servicedisc/client.go +++ b/pkg/servicedisc/client.go @@ -128,7 +128,7 @@ func (c *HTTPClient) Services(ctx context.Context, quantity int) (out []Service, return nil, &hErr } err = json.NewDecoder(resp.Body).Decode(&out) - return + return out, err } // UpdateEntry calls 'POST /api/services'. From c3ecaf24e26322fa9da8292418c3f6845622a39d Mon Sep 17 00:00:00 2001 From: Taras Nepyipyvo Date: Thu, 19 Nov 2020 14:23:19 +0200 Subject: [PATCH 04/41] Remove public_address field;Fix linter. --- internal/utclient/mock_api_client.go | 7 ++- internal/vpn/os_client_linux.go | 9 ++-- pkg/app/appdisc/factory.go | 24 ---------- pkg/app/appevent/mock_rpc_client.go | 10 ++-- pkg/app/appnet/mock_networker.go | 9 ++-- pkg/app/appserver/mock_proc_manager.go | 10 ++-- pkg/app/appserver/mock_rpc_ingress_client.go | 13 +++-- pkg/routefinder/rfclient/mock_client.go | 10 ++-- pkg/router/mock_router.go | 16 +++++-- pkg/servicedisc/client.go | 18 +++---- pkg/servicedisc/types.go | 9 ++-- pkg/setup/mock_id_reserver.go | 16 +++++-- .../setupclient/mock_route_group_dialer.go | 19 +++++--- pkg/snet/arclient/mock_api_client.go | 13 +++-- pkg/snet/mock_dialer.go | 13 +++-- pkg/snet/network.go | 47 +++---------------- pkg/visor/init.go | 9 ++-- 17 files changed, 126 insertions(+), 126 deletions(-) diff --git a/internal/utclient/mock_api_client.go b/internal/utclient/mock_api_client.go index 8252bd4924..42f06f07b2 100644 --- a/internal/utclient/mock_api_client.go +++ b/internal/utclient/mock_api_client.go @@ -2,8 +2,11 @@ package utclient -import context "context" -import mock "github.com/stretchr/testify/mock" +import ( + context "context" + + mock "github.com/stretchr/testify/mock" +) // MockAPIClient is an autogenerated mock type for the APIClient type type MockAPIClient struct { diff --git a/internal/vpn/os_client_linux.go b/internal/vpn/os_client_linux.go index 531ce56d8e..a2da0e844d 100644 --- a/internal/vpn/os_client_linux.go +++ b/internal/vpn/os_client_linux.go @@ -45,7 +45,8 @@ func DefaultNetworkGateway() (net.IP, error) { var setupClientOnce sync.Once -func setupClientSysPrivileges() (suid int, err error) { +func setupClientSysPrivileges() (int, error) { + var err error setupClientOnce.Do(func() { var caps capability.Capabilities @@ -63,14 +64,16 @@ func setupClientSysPrivileges() (suid int, err error) { // set `CAP_NET_ADMIN` capability to needed caps sets. caps.Set(capability.CAPS|capability.BOUNDS|capability.AMBIENT, capability.CAP_NET_ADMIN) - if err := caps.Apply(capability.CAPS | capability.BOUNDS | capability.AMBIENT); err != nil { + err = caps.Apply(capability.CAPS | capability.BOUNDS | capability.AMBIENT) + if err != nil { err = fmt.Errorf("failed to apply capabilties: %w", err) return } // let child process keep caps sets from the parent, so we may do calls to // system utilities with these caps. - if err := unix.Prctl(unix.PR_SET_KEEPCAPS, 1, 0, 0, 0); err != nil { + err = unix.Prctl(unix.PR_SET_KEEPCAPS, 1, 0, 0, 0) + if err != nil { err = fmt.Errorf("failed to set PR_SET_KEEPCAPS: %w", err) return } diff --git a/pkg/app/appdisc/factory.go b/pkg/app/appdisc/factory.go index a7a33e88c1..bdcc145810 100644 --- a/pkg/app/appdisc/factory.go +++ b/pkg/app/appdisc/factory.go @@ -55,30 +55,6 @@ func (f *Factory) VisorUpdater(port uint16) Updater { } } -// PublicVisorUpdater obtains a visor updater. -func (f *Factory) PublicVisorUpdater(port uint16, publicAddr string) Updater { - // Always return empty updater if keys are not set. - if f.setDefaults(); f.PK.Null() || f.SK.Null() { - return &emptyUpdater{} - } - - conf := servicedisc.Config{ - Type: servicedisc.ServiceTypePublicVisor, - PK: f.PK, - SK: f.SK, - Port: port, - DiscAddr: f.ProxyDisc, - } - - client := servicedisc.NewClient(f.Log, conf) - client.Entry.PublicAddress = publicAddr - - return &serviceUpdater{ - client: client, - interval: f.UpdateInterval, - } -} - // AppUpdater obtains an app updater based on the app name and configuration. func (f *Factory) AppUpdater(conf appcommon.ProcConfig) (Updater, bool) { // Always return empty updater if keys are not set. diff --git a/pkg/app/appevent/mock_rpc_client.go b/pkg/app/appevent/mock_rpc_client.go index e14f85b6a2..393e3af472 100644 --- a/pkg/app/appevent/mock_rpc_client.go +++ b/pkg/app/appevent/mock_rpc_client.go @@ -2,9 +2,13 @@ package appevent -import appcommon "github.com/skycoin/skywire/pkg/app/appcommon" -import context "context" -import mock "github.com/stretchr/testify/mock" +import ( + context "context" + + appcommon "github.com/skycoin/skywire/pkg/app/appcommon" + + mock "github.com/stretchr/testify/mock" +) // MockRPCClient is an autogenerated mock type for the RPCClient type type MockRPCClient struct { diff --git a/pkg/app/appnet/mock_networker.go b/pkg/app/appnet/mock_networker.go index 39178d034c..2258fc8552 100644 --- a/pkg/app/appnet/mock_networker.go +++ b/pkg/app/appnet/mock_networker.go @@ -2,9 +2,12 @@ package appnet -import context "context" -import mock "github.com/stretchr/testify/mock" -import net "net" +import ( + context "context" + net "net" + + mock "github.com/stretchr/testify/mock" +) // MockNetworker is an autogenerated mock type for the Networker type type MockNetworker struct { diff --git a/pkg/app/appserver/mock_proc_manager.go b/pkg/app/appserver/mock_proc_manager.go index 63b9935468..af4566b8a2 100644 --- a/pkg/app/appserver/mock_proc_manager.go +++ b/pkg/app/appserver/mock_proc_manager.go @@ -2,9 +2,13 @@ package appserver -import appcommon "github.com/skycoin/skywire/pkg/app/appcommon" -import mock "github.com/stretchr/testify/mock" -import net "net" +import ( + mock "github.com/stretchr/testify/mock" + + appcommon "github.com/skycoin/skywire/pkg/app/appcommon" + + net "net" +) // MockProcManager is an autogenerated mock type for the ProcManager type type MockProcManager struct { diff --git a/pkg/app/appserver/mock_rpc_ingress_client.go b/pkg/app/appserver/mock_rpc_ingress_client.go index c3e3494fd1..2df6e79b9c 100644 --- a/pkg/app/appserver/mock_rpc_ingress_client.go +++ b/pkg/app/appserver/mock_rpc_ingress_client.go @@ -2,10 +2,15 @@ package appserver -import appnet "github.com/skycoin/skywire/pkg/app/appnet" -import mock "github.com/stretchr/testify/mock" -import routing "github.com/skycoin/skywire/pkg/routing" -import time "time" +import ( + mock "github.com/stretchr/testify/mock" + + appnet "github.com/skycoin/skywire/pkg/app/appnet" + + routing "github.com/skycoin/skywire/pkg/routing" + + time "time" +) // MockRPCIngressClient is an autogenerated mock type for the RPCIngressClient type type MockRPCIngressClient struct { diff --git a/pkg/routefinder/rfclient/mock_client.go b/pkg/routefinder/rfclient/mock_client.go index 5291ea6ba3..b0b6242019 100644 --- a/pkg/routefinder/rfclient/mock_client.go +++ b/pkg/routefinder/rfclient/mock_client.go @@ -2,9 +2,13 @@ package rfclient -import context "context" -import mock "github.com/stretchr/testify/mock" -import routing "github.com/skycoin/skywire/pkg/routing" +import ( + context "context" + + mock "github.com/stretchr/testify/mock" + + routing "github.com/skycoin/skywire/pkg/routing" +) // MockClient is an autogenerated mock type for the Client type type MockClient struct { diff --git a/pkg/router/mock_router.go b/pkg/router/mock_router.go index aeb1d9666c..6b1865b74f 100644 --- a/pkg/router/mock_router.go +++ b/pkg/router/mock_router.go @@ -2,11 +2,17 @@ package router -import cipher "github.com/skycoin/dmsg/cipher" -import context "context" -import mock "github.com/stretchr/testify/mock" -import net "net" -import routing "github.com/skycoin/skywire/pkg/routing" +import ( + context "context" + + cipher "github.com/skycoin/dmsg/cipher" + + mock "github.com/stretchr/testify/mock" + + net "net" + + routing "github.com/skycoin/skywire/pkg/routing" +) // MockRouter is an autogenerated mock type for the Router type type MockRouter struct { diff --git a/pkg/servicedisc/client.go b/pkg/servicedisc/client.go index bd7f1fe325..26b4cb7fdc 100644 --- a/pkg/servicedisc/client.go +++ b/pkg/servicedisc/client.go @@ -37,7 +37,7 @@ type Config struct { type HTTPClient struct { log logrus.FieldLogger conf Config - Entry Service + entry Service entryMx sync.Mutex // only used if UpdateLoop && UpdateStats functions are used. client http.Client } @@ -52,7 +52,7 @@ func NewClient(log logrus.FieldLogger, conf Config) *HTTPClient { return &HTTPClient{ log: log, conf: conf, - Entry: Service{ + entry: Service{ Addr: NewSWAddr(conf.PK, conf.Port), Stats: stats, Type: conf.Type, @@ -98,7 +98,7 @@ func (c *HTTPClient) Auth(ctx context.Context) (*httpauth.Client, error) { // Services calls 'GET /api/services'. func (c *HTTPClient) Services(ctx context.Context, quantity int) (out []Service, err error) { - addr := c.addr("/api/services", c.Entry.Type) + addr := c.addr("/api/services", c.entry.Type) if quantity != 0 { addr += "&quantity=" + strconv.Itoa(quantity) } @@ -138,9 +138,9 @@ func (c *HTTPClient) UpdateEntry(ctx context.Context) (*Service, error) { return nil, err } - c.Entry.Addr = NewSWAddr(c.conf.PK, c.conf.Port) // Just in case. + c.entry.Addr = NewSWAddr(c.conf.PK, c.conf.Port) // Just in case. - raw, err := json.Marshal(&c.Entry) + raw, err := json.Marshal(&c.entry) if err != nil { return nil, err } @@ -175,8 +175,8 @@ func (c *HTTPClient) UpdateEntry(ctx context.Context) (*Service, error) { return nil, hErr.Error } - err = json.NewDecoder(resp.Body).Decode(&c.Entry) - return &c.Entry, err + err = json.NewDecoder(resp.Body).Decode(&c.entry) + return &c.entry, err } // DeleteEntry calls 'DELETE /api/services/{entry_addr}'. @@ -186,7 +186,7 @@ func (c *HTTPClient) DeleteEntry(ctx context.Context) (err error) { return err } - req, err := http.NewRequestWithContext(ctx, http.MethodDelete, c.addr("/api/services/"+c.Entry.Addr.String(), c.Entry.Type), nil) + req, err := http.NewRequestWithContext(ctx, http.MethodDelete, c.addr("/api/services/"+c.entry.Addr.String(), c.entry.Type), nil) if err != nil { return err } @@ -265,6 +265,6 @@ func (c *HTTPClient) UpdateLoop(ctx context.Context, updateInterval time.Duratio // UpdateStats updates the stats field of the internal service entry state. func (c *HTTPClient) UpdateStats(stats Stats) { c.entryMx.Lock() - c.Entry.Stats = &stats + c.entry.Stats = &stats c.entryMx.Unlock() } diff --git a/pkg/servicedisc/types.go b/pkg/servicedisc/types.go index a8d3d8b4cf..5078ae719f 100644 --- a/pkg/servicedisc/types.go +++ b/pkg/servicedisc/types.go @@ -106,11 +106,10 @@ type Stats struct { // Service represents a service entry in service-discovery. type Service struct { - Addr SWAddr `json:"address"` - Type string `json:"type"` - PublicAddress string `json:"public_address,omitempty"` - Stats *Stats `json:"stats,omitempty"` // TODO: Have this implemented. - Geo *GeoLocation `json:"geo,omitempty"` + Addr SWAddr `json:"address"` + Type string `json:"type"` + Stats *Stats `json:"stats,omitempty"` // TODO: Have this implemented. + Geo *GeoLocation `json:"geo,omitempty"` } // MarshalBinary implements encoding.BinaryMarshaller diff --git a/pkg/setup/mock_id_reserver.go b/pkg/setup/mock_id_reserver.go index 7be28aed22..8e8eace704 100644 --- a/pkg/setup/mock_id_reserver.go +++ b/pkg/setup/mock_id_reserver.go @@ -2,11 +2,17 @@ package setup -import cipher "github.com/skycoin/dmsg/cipher" -import context "context" -import mock "github.com/stretchr/testify/mock" -import routerclient "github.com/skycoin/skywire/pkg/router/routerclient" -import routing "github.com/skycoin/skywire/pkg/routing" +import ( + context "context" + + cipher "github.com/skycoin/dmsg/cipher" + + mock "github.com/stretchr/testify/mock" + + routerclient "github.com/skycoin/skywire/pkg/router/routerclient" + + routing "github.com/skycoin/skywire/pkg/routing" +) // MockIDReserver is an autogenerated mock type for the IDReserver type type MockIDReserver struct { diff --git a/pkg/setup/setupclient/mock_route_group_dialer.go b/pkg/setup/setupclient/mock_route_group_dialer.go index 4d40501d90..bd1d127d06 100644 --- a/pkg/setup/setupclient/mock_route_group_dialer.go +++ b/pkg/setup/setupclient/mock_route_group_dialer.go @@ -2,12 +2,19 @@ package setupclient -import cipher "github.com/skycoin/dmsg/cipher" -import context "context" -import logging "github.com/skycoin/skycoin/src/util/logging" -import mock "github.com/stretchr/testify/mock" -import routing "github.com/skycoin/skywire/pkg/routing" -import snet "github.com/skycoin/skywire/pkg/snet" +import ( + context "context" + + cipher "github.com/skycoin/dmsg/cipher" + + logging "github.com/skycoin/skycoin/src/util/logging" + + mock "github.com/stretchr/testify/mock" + + routing "github.com/skycoin/skywire/pkg/routing" + + snet "github.com/skycoin/skywire/pkg/snet" +) // MockRouteGroupDialer is an autogenerated mock type for the RouteGroupDialer type type MockRouteGroupDialer struct { diff --git a/pkg/snet/arclient/mock_api_client.go b/pkg/snet/arclient/mock_api_client.go index eb1dea0841..955bcb6d03 100644 --- a/pkg/snet/arclient/mock_api_client.go +++ b/pkg/snet/arclient/mock_api_client.go @@ -2,10 +2,15 @@ package arclient -import cipher "github.com/skycoin/dmsg/cipher" -import context "context" -import mock "github.com/stretchr/testify/mock" -import pfilter "github.com/AudriusButkevicius/pfilter" +import ( + context "context" + + cipher "github.com/skycoin/dmsg/cipher" + + mock "github.com/stretchr/testify/mock" + + pfilter "github.com/AudriusButkevicius/pfilter" +) // MockAPIClient is an autogenerated mock type for the APIClient type type MockAPIClient struct { diff --git a/pkg/snet/mock_dialer.go b/pkg/snet/mock_dialer.go index d5355cfca4..cf359fd18f 100644 --- a/pkg/snet/mock_dialer.go +++ b/pkg/snet/mock_dialer.go @@ -2,10 +2,15 @@ package snet -import cipher "github.com/skycoin/dmsg/cipher" -import context "context" -import mock "github.com/stretchr/testify/mock" -import net "net" +import ( + context "context" + + cipher "github.com/skycoin/dmsg/cipher" + + mock "github.com/stretchr/testify/mock" + + net "net" +) // MockDialer is an autogenerated mock type for the Dialer type type MockDialer struct { diff --git a/pkg/snet/network.go b/pkg/snet/network.go index 8835ac0667..094bc5aa52 100644 --- a/pkg/snet/network.go +++ b/pkg/snet/network.go @@ -60,9 +60,8 @@ func (c *DmsgConfig) Type() string { // STCPConfig defines config for STCP network. type STCPConfig struct { - PKTable map[cipher.PubKey]string `json:"pk_table"` - LocalAddr string `json:"local_address"` - PublicAddress string `json:"public_address"` + PKTable map[cipher.PubKey]string `json:"pk_table"` + LocalAddr string `json:"local_address"` } // Type returns STCP type. @@ -78,7 +77,6 @@ type Config struct { NetworkConfigs NetworkConfigs ServiceDisc appdisc.Factory PublicTrusted bool - PublicAddress string } // NetworkConfigs represents all network configs. @@ -95,12 +93,11 @@ type NetworkClients struct { // Network represents a network between nodes in Skywire. type Network struct { - conf Config - netsMu sync.RWMutex - nets map[string]struct{} // networks to be used with transports - clients NetworkClients - visorUpdater appdisc.Updater - publicVisorUpdater appdisc.Updater + conf Config + netsMu sync.RWMutex + nets map[string]struct{} // networks to be used with transports + clients NetworkClients + visorUpdater appdisc.Updater onNewNetworkTypeMu sync.Mutex onNewNetworkType func(netType string) @@ -233,9 +230,6 @@ func (n *Network) Init() error { if n.conf.PublicTrusted { go n.registerPublicTrusted(client) } - if n.conf.PublicAddress != "" { - go n.registerAsPublicVisor(client) - } } else { log.Infof("No config found for stcpr") } @@ -278,33 +272,6 @@ func (n *Network) registerPublicTrusted(client directtp.Client) { log.Infof("Sent request to register visor as public trusted") } -func (n *Network) registerAsPublicVisor(client directtp.Client) { - log.Infof("Trying to register visor as public visor") - - la, err := client.LocalAddr() - if err != nil { - log.WithError(err).Errorf("Failed to get STCPR local addr") - return - } - - _, portStr, err := net.SplitHostPort(la.String()) - if err != nil { - log.WithError(err).Errorf("Failed to extract port from addr %v", la.String()) - return - } - - port, err := strconv.Atoi(portStr) - if err != nil { - log.WithError(err).Errorf("Failed to convert port to int") - return - } - - n.publicVisorUpdater = n.conf.ServiceDisc.PublicVisorUpdater(uint16(port), n.conf.PublicAddress) - - n.publicVisorUpdater.Start() - - log.Infof("Sent request to register visor as public") -} // OnNewNetworkType sets callback to be called when new network type is ready. func (n *Network) OnNewNetworkType(callback func(netType string)) { diff --git a/pkg/visor/init.go b/pkg/visor/init.go index 0f94633da5..48fc71e1ad 100644 --- a/pkg/visor/init.go +++ b/pkg/visor/init.go @@ -105,7 +105,6 @@ func initSNet(v *Visor) bool { NetworkConfigs: nc, ServiceDisc: v.serviceDisc, PublicTrusted: v.conf.PublicTrustedVisor, - PublicAddress: v.conf.STCP.PublicAddress, } n, err := snet.New(conf, v.ebc) @@ -539,10 +538,14 @@ func initPublicVisors(v *Visor) bool { } client := servicedisc.NewClient(log, conf) - client.Entry.PublicAddress = v.conf.STCP.PublicAddress - go func() { time.Sleep(transport.TrustedVisorsDelay * 2) + go func() { + _, err := client.UpdateEntry(context.Background()) // try to register as public visor + if err != nil { + log.WithError(err).Warn("can't register as public visor") + } + }() services, err := client.Services(context.Background(), 5) if err != nil { log.WithError(err).Error("Can't fetch public visors") From 9b5cb14f75eb8e0658c0a6b1d6f04f8bc20085da Mon Sep 17 00:00:00 2001 From: Taras Nepyipyvo Date: Thu, 19 Nov 2020 14:58:26 +0200 Subject: [PATCH 05/41] Add ReadOnly address resolver client. --- pkg/snet/arclient/client.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/pkg/snet/arclient/client.go b/pkg/snet/arclient/client.go index 0f98e07903..272e0a37b0 100644 --- a/pkg/snet/arclient/client.go +++ b/pkg/snet/arclient/client.go @@ -115,6 +115,30 @@ func NewHTTP(remoteAddr string, pk cipher.PubKey, sk cipher.SecKey) (APIClient, return client, nil } +func NewReadOnlyHTTP(remoteAddr string) (APIClient, error) { + remoteURL, err := url.Parse(remoteAddr) + if err != nil { + return nil, fmt.Errorf("parse URL: %w", err) + } + + remoteUDP := remoteURL.Host + if _, _, err := net.SplitHostPort(remoteUDP); err != nil { + remoteUDP = net.JoinHostPort(remoteUDP, defaultUDPPort) + } + + client := &httpClient{ + log: logging.MustGetLogger("address-resolver"), + remoteHTTPAddr: remoteAddr, + remoteUDPAddr: remoteUDP, + ready: make(chan struct{}), + closed: make(chan struct{}), + } + + client.log.Infof("Remote UDP server: %q", remoteUDP) + + return client, nil +} + func (c *httpClient) initHTTPClient() { httpAuthClient, err := httpauth.NewClient(context.Background(), c.remoteHTTPAddr, c.pk, c.sk) if err != nil { From 1ca9025ab64e9deed2eac57d88c661612fc9faf4 Mon Sep 17 00:00:00 2001 From: Taras Nepyipyvo Date: Thu, 19 Nov 2020 19:48:49 +0200 Subject: [PATCH 06/41] Add boolean field wich indicates if visor is on public address. --- pkg/servicedisc/client.go | 2 +- pkg/snet/arclient/client.go | 24 ---------------------- pkg/snet/network.go | 5 +++-- pkg/visor/init.go | 41 +++++++++++++++++++------------------ 4 files changed, 25 insertions(+), 47 deletions(-) diff --git a/pkg/servicedisc/client.go b/pkg/servicedisc/client.go index 26b4cb7fdc..c8a1b585fe 100644 --- a/pkg/servicedisc/client.go +++ b/pkg/servicedisc/client.go @@ -45,7 +45,7 @@ type HTTPClient struct { // NewClient creates a new HTTPClient. func NewClient(log logrus.FieldLogger, conf Config) *HTTPClient { var stats *Stats - if conf.Type != ServiceTypeVisor { + if conf.Type != ServiceTypeVisor && conf.Type != ServiceTypePublicVisor { stats = &Stats{ConnectedClients: 0} } diff --git a/pkg/snet/arclient/client.go b/pkg/snet/arclient/client.go index 272e0a37b0..0f98e07903 100644 --- a/pkg/snet/arclient/client.go +++ b/pkg/snet/arclient/client.go @@ -115,30 +115,6 @@ func NewHTTP(remoteAddr string, pk cipher.PubKey, sk cipher.SecKey) (APIClient, return client, nil } -func NewReadOnlyHTTP(remoteAddr string) (APIClient, error) { - remoteURL, err := url.Parse(remoteAddr) - if err != nil { - return nil, fmt.Errorf("parse URL: %w", err) - } - - remoteUDP := remoteURL.Host - if _, _, err := net.SplitHostPort(remoteUDP); err != nil { - remoteUDP = net.JoinHostPort(remoteUDP, defaultUDPPort) - } - - client := &httpClient{ - log: logging.MustGetLogger("address-resolver"), - remoteHTTPAddr: remoteAddr, - remoteUDPAddr: remoteUDP, - ready: make(chan struct{}), - closed: make(chan struct{}), - } - - client.log.Infof("Remote UDP server: %q", remoteUDP) - - return client, nil -} - func (c *httpClient) initHTTPClient() { httpAuthClient, err := httpauth.NewClient(context.Background(), c.remoteHTTPAddr, c.pk, c.sk) if err != nil { diff --git a/pkg/snet/network.go b/pkg/snet/network.go index 094bc5aa52..ffd4d62828 100644 --- a/pkg/snet/network.go +++ b/pkg/snet/network.go @@ -60,8 +60,9 @@ func (c *DmsgConfig) Type() string { // STCPConfig defines config for STCP network. type STCPConfig struct { - PKTable map[cipher.PubKey]string `json:"pk_table"` - LocalAddr string `json:"local_address"` + PKTable map[cipher.PubKey]string `json:"pk_table"` + LocalAddr string `json:"local_address"` + AddrIsPublic bool `json:"addres_is_public"` } // Type returns STCP type. diff --git a/pkg/visor/init.go b/pkg/visor/init.go index 48fc71e1ad..9c3a4735c0 100644 --- a/pkg/visor/init.go +++ b/pkg/visor/init.go @@ -523,29 +523,30 @@ func initTrustedVisors(v *Visor) bool { func initPublicVisors(v *Visor) bool { const trustedVisorsTransportType = tptypes.STCPR - if v.conf.Launcher.Discovery.PublicVisorsEnabled { - proxyDisc := v.conf.Launcher.Discovery.ServiceDisc - if proxyDisc == "" { - proxyDisc = skyenv.DefaultServiceDiscAddr - } - log = logging.MustGetLogger("appdisc") - - conf := servicedisc.Config{ - Type: servicedisc.ServiceTypePublicVisor, - PK: v.conf.PK, - SK: v.conf.SK, - DiscAddr: proxyDisc, - } + proxyDisc := v.conf.Launcher.Discovery.ServiceDisc + if proxyDisc == "" { + proxyDisc = skyenv.DefaultServiceDiscAddr + } + log = logging.MustGetLogger("appdisc") - client := servicedisc.NewClient(log, conf) + conf := servicedisc.Config{ + Type: servicedisc.ServiceTypePublicVisor, + PK: v.conf.PK, + SK: v.conf.SK, + DiscAddr: proxyDisc, + } + client := servicedisc.NewClient(log, conf) + if v.conf.STCP.AddrIsPublic { go func() { time.Sleep(transport.TrustedVisorsDelay * 2) - go func() { - _, err := client.UpdateEntry(context.Background()) // try to register as public visor - if err != nil { - log.WithError(err).Warn("can't register as public visor") - } - }() + _, err := client.UpdateEntry(context.Background()) // try to register as public visor + if err != nil { + log.WithError(err).Warn("can't register as public visor") + } + }() + } + if v.conf.Launcher.Discovery.PublicVisorsEnabled { + go func() { services, err := client.Services(context.Background(), 5) if err != nil { log.WithError(err).Error("Can't fetch public visors") From 741a4b4d91b9e5c403bd6419e500bf22bbd497da Mon Sep 17 00:00:00 2001 From: Taras Nepyipyvo Date: Thu, 19 Nov 2020 20:28:42 +0200 Subject: [PATCH 07/41] Pass STCPR port to service-discover port. --- pkg/visor/init.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/pkg/visor/init.go b/pkg/visor/init.go index 9c3a4735c0..d39c0963b9 100644 --- a/pkg/visor/init.go +++ b/pkg/visor/init.go @@ -6,6 +6,7 @@ import ( "fmt" "net" "net/http" + "strconv" "sync" "time" @@ -528,11 +529,21 @@ func initPublicVisors(v *Visor) bool { proxyDisc = skyenv.DefaultServiceDiscAddr } log = logging.MustGetLogger("appdisc") - + _, portStr, err := net.SplitHostPort(v.conf.STCP.LocalAddr) + if err != nil { + log.WithError(err).Warn("can't parse address string") + return false + } + port, err := strconv.Atoi(portStr) + if err != nil { + log.WithError(err).Warn("can't convert port to integer") + return false + } conf := servicedisc.Config{ Type: servicedisc.ServiceTypePublicVisor, PK: v.conf.PK, SK: v.conf.SK, + Port: uint16(port), DiscAddr: proxyDisc, } client := servicedisc.NewClient(log, conf) From 17d85964f90683f038db50e956763e750d9ebf6a Mon Sep 17 00:00:00 2001 From: Taras Nepyipyvo Date: Thu, 19 Nov 2020 21:04:31 +0200 Subject: [PATCH 08/41] Fix sleep delays. --- pkg/visor/init.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/visor/init.go b/pkg/visor/init.go index 5b6a4e5508..808827f4dd 100644 --- a/pkg/visor/init.go +++ b/pkg/visor/init.go @@ -549,7 +549,7 @@ func initPublicVisors(v *Visor) bool { client := servicedisc.NewClient(log, conf) if v.conf.STCP.AddrIsPublic { go func() { - time.Sleep(transport.TrustedVisorsDelay * 2) + time.Sleep(transport.TrustedVisorsDelay) _, err := client.UpdateEntry(context.Background()) // try to register as public visor if err != nil { log.WithError(err).Warn("can't register as public visor") @@ -558,6 +558,7 @@ func initPublicVisors(v *Visor) bool { } if v.conf.Launcher.Discovery.PublicVisorsEnabled { go func() { + time.Sleep(transport.TrustedVisorsDelay * 2) services, err := client.Services(context.Background(), 5) if err != nil { log.WithError(err).Error("Can't fetch public visors") From 442625997bfd4f6effdd6ecf4de8a59f110ae552 Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Tue, 2 Feb 2021 23:15:52 +0300 Subject: [PATCH 09/41] Start merging old trusted visors with the new public visor concept --- pkg/transport/manager.go | 5 ++- pkg/visor/init.go | 57 ++++++++++++++++++++-------------- pkg/visor/visor_test.go | 1 - pkg/visor/visorconfig/parse.go | 1 - pkg/visor/visorconfig/v1.go | 7 ++--- 5 files changed, 38 insertions(+), 33 deletions(-) diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index e0e3a39a79..89f3140225 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -22,8 +22,8 @@ import ( ) const ( - // TrustedVisorsDelay defines a delay before adding transports to trusted visors. - TrustedVisorsDelay = 5 * time.Second + // PublicVisorsDelay defines a delay before adding transports to public visors. + PublicVisorsDelay = 5 * time.Second ) // TPCloseCallback triggers after a session is closed. @@ -33,7 +33,6 @@ type TPCloseCallback func(network, addr string) type ManagerConfig struct { PubKey cipher.PubKey SecKey cipher.SecKey - DefaultVisors []cipher.PubKey // Visors to automatically connect to DiscoveryClient DiscoveryClient LogStore LogStore } diff --git a/pkg/visor/init.go b/pkg/visor/init.go index 3a14414a6b..9a84ece7a8 100644 --- a/pkg/visor/init.go +++ b/pkg/visor/init.go @@ -56,9 +56,8 @@ func initStack() []initFunc { initCLI, initHypervisors, initUptimeTracker, - initTrustedVisors, - initHypervisor, initPublicVisors, + initHypervisor, } } @@ -182,7 +181,6 @@ func initTransport(v *Visor) bool { tpMConf := transport.ManagerConfig{ PubKey: v.conf.PK, SecKey: v.conf.SK, - DefaultVisors: conf.TrustedVisors, DiscoveryClient: tpdC, LogStore: logS, } @@ -491,7 +489,7 @@ func initUptimeTracker(v *Visor) bool { return true } -func initTrustedVisors(v *Visor) bool { +/*func initTrustedVisors(v *Visor) bool { const trustedVisorsTransportType = tptypes.STCPR go func() { @@ -515,34 +513,40 @@ func initTrustedVisors(v *Visor) bool { }() return true -} +}*/ +// TODO (darkrengarius): adv REMOVE func initPublicVisors(v *Visor) bool { - const trustedVisorsTransportType = tptypes.STCPR + const tpType = tptypes.STCPR + proxyDisc := v.conf.Launcher.Discovery.ServiceDisc if proxyDisc == "" { proxyDisc = skyenv.DefaultServiceDiscAddr } - log = logging.MustGetLogger("appdisc") + _, portStr, err := net.SplitHostPort(v.conf.STCP.LocalAddr) if err != nil { - log.WithError(err).Warn("can't parse address string") + v.log.WithError(err).Errorln("Failed to parse address string") return false } + port, err := strconv.Atoi(portStr) if err != nil { - log.WithError(err).Warn("can't convert port to integer") + v.log.WithError(err).Errorln("Failed to parse port") return false } + conf := servicedisc.Config{ - Type: servicedisc.ServiceTypePublicVisor, + Type: servicedisc.ServiceTypeVisor, PK: v.conf.PK, SK: v.conf.SK, Port: uint16(port), DiscAddr: proxyDisc, } - client := servicedisc.NewClient(log, conf) - if v.conf.STCP.AddrIsPublic { + discCl := servicedisc.NewClient(log, conf) + + // TODO (darkrengarius): adv this one should be done in the updater manner, like it's already done for trusted visors + /*if v.conf.STCP.AddrIsPublic { go func() { time.Sleep(transport.TrustedVisorsDelay) _, err := client.UpdateEntry(context.Background()) // try to register as public visor @@ -550,32 +554,37 @@ func initPublicVisors(v *Visor) bool { log.WithError(err).Warn("can't register as public visor") } }() - } + }*/ + if v.conf.Launcher.Discovery.PublicVisorsEnabled { go func() { - time.Sleep(transport.TrustedVisorsDelay * 2) - services, err := client.Services(context.Background(), 5) + time.Sleep(transport.PublicVisorsDelay * 2) + + visors, err := discCl.Services(context.Background(), 5) if err != nil { - log.WithError(err).Error("Can't fetch public visors") + log.WithError(err).Errorln("Failed to fetch public visors") + return } - for _, service := range services { - pk := service.Addr.PubKey() - v.log.WithField("pk", pk).Infof("Adding public visor") - if _, err := v.tpM.SaveTransport(context.Background(), pk, trustedVisorsTransportType); err != nil { + + for _, visor := range visors { + pk := visor.Addr.PubKey() + v.log.WithField("pk", pk).Infoln("Adding transport to public visor") + if _, err := v.tpM.SaveTransport(context.Background(), pk, tpType); err != nil { v.log. WithError(err). WithField("pk", pk). - WithField("type", trustedVisorsTransportType). - Warnf("Failed to add transport to public visor via") + WithField("type", tpType). + Warnln("Failed to add transport to public visor via") } else { v.log. WithField("pk", pk). - WithField("type", trustedVisorsTransportType). - Infof("Added transport to public visor") + WithField("type", tpType). + Infoln("Added transport to public visor") } } }() } + return true } diff --git a/pkg/visor/visor_test.go b/pkg/visor/visor_test.go index 7182f3b74f..4d2737fa72 100644 --- a/pkg/visor/visor_test.go +++ b/pkg/visor/visor_test.go @@ -61,7 +61,6 @@ func TestNewVisor(t *testing.T) { LogStore: &visorconfig.V1LogStore{ Type: visorconfig.MemoryLogStore, }, - TrustedVisors: nil, }, Routing: &visorconfig.V1Routing{ SetupNodes: nil, diff --git a/pkg/visor/visorconfig/parse.go b/pkg/visor/visorconfig/parse.go index 1cfbd026db..55d4e75705 100644 --- a/pkg/visor/visorconfig/parse.go +++ b/pkg/visor/visorconfig/parse.go @@ -103,7 +103,6 @@ func parseV0(cc *Common, raw []byte) (*V1, error) { conf.Transport.LogStore = old.Transport.LogStore } - conf.Transport.TrustedVisors = old.TrustedVisors if old.Routing != nil { conf.Routing = old.Routing } diff --git a/pkg/visor/visorconfig/v1.go b/pkg/visor/visorconfig/v1.go index 0e5f9fd8a9..9ca3b3f204 100644 --- a/pkg/visor/visorconfig/v1.go +++ b/pkg/visor/visorconfig/v1.go @@ -50,10 +50,9 @@ type V1Dmsgpty struct { // V1Transport defines a transport config. type V1Transport struct { - Discovery string `json:"discovery"` - AddressResolver string `json:"address_resolver"` - LogStore *V1LogStore `json:"log_store"` - TrustedVisors []cipher.PubKey `json:"trusted_visors"` + Discovery string `json:"discovery"` + AddressResolver string `json:"address_resolver"` + LogStore *V1LogStore `json:"log_store"` } // V1LogStore configures a LogStore. From 9eba53896260f59717aab89de35e280c6a113457 Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Tue, 2 Feb 2021 23:19:54 +0300 Subject: [PATCH 10/41] Add func to fetch default network interface name for OSX --- internal/vpn/os_darwin.go | 19 +++++++++++++++++++ internal/vpn/os_server.go | 5 ----- internal/vpn/os_windows.go | 5 +++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/internal/vpn/os_darwin.go b/internal/vpn/os_darwin.go index 0b32442f72..2eb77165ac 100644 --- a/internal/vpn/os_darwin.go +++ b/internal/vpn/os_darwin.go @@ -3,12 +3,31 @@ package vpn import ( + "bytes" "errors" "fmt" + "os/exec" "strconv" "strings" ) +const ( + defaultNetworkInterfaceCMD = "netstat -rn | sed -n '/Internet/,/Internet6/p' | grep default | awk '{print $4}'" +) + +// DefaultNetworkInterface fetches default network interface name. +func DefaultNetworkInterface() (string, error) { + outputBytes, err := exec.Command("sh", "-c", defaultNetworkInterfaceCMD).Output() + if err != nil { + return "", fmt.Errorf("error running command %s: %w", defaultNetworkInterfaceCMD, err) + } + + // just in case + outputBytes = bytes.TrimRight(outputBytes, "\n") + + return string(outputBytes), nil +} + // SetupTUN sets the allocated TUN interface up, setting its IP, gateway, netmask and MTU. func SetupTUN(ifcName, ipCIDR, gateway string, mtu int) error { ip, netmask, err := parseCIDR(ipCIDR) diff --git a/internal/vpn/os_server.go b/internal/vpn/os_server.go index aba342ea7d..db01dbdf98 100644 --- a/internal/vpn/os_server.go +++ b/internal/vpn/os_server.go @@ -38,11 +38,6 @@ func BlockIPToLocalNetwork(_, _ net.IP) error { return errServerMethodsNotSupported } -// DefaultNetworkInterface fetches default network interface name. -func DefaultNetworkInterface() (string, error) { - return "", errServerMethodsNotSupported -} - // GetIPv4ForwardingValue gets current value of IPv4 forwarding. func GetIPv4ForwardingValue() (string, error) { return "", errServerMethodsNotSupported diff --git a/internal/vpn/os_windows.go b/internal/vpn/os_windows.go index 05e3af888a..531f717020 100644 --- a/internal/vpn/os_windows.go +++ b/internal/vpn/os_windows.go @@ -12,6 +12,11 @@ const ( modifyRouteCMDFmt = "route %s %s mask %s %s" ) +// DefaultNetworkInterface fetches default network interface name. +func DefaultNetworkInterface() (string, error) { + return "", errServerMethodsNotSupported +} + // SetupTUN sets the allocated TUN interface up, setting its IP, gateway, netmask and MTU. func SetupTUN(ifcName, ipCIDR, gateway string, mtu int) error { ip, netmask, err := parseCIDR(ipCIDR) From ce12e5b3f22145134c497f67823cfc4c0c5a8694 Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Tue, 2 Feb 2021 23:35:50 +0300 Subject: [PATCH 11/41] Include local visor IPs in the update request for visor service --- pkg/servicedisc/client.go | 21 +++++++++++++++++++++ pkg/servicedisc/types.go | 11 ++++++----- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/pkg/servicedisc/client.go b/pkg/servicedisc/client.go index 5c535932c6..777b9ee171 100644 --- a/pkg/servicedisc/client.go +++ b/pkg/servicedisc/client.go @@ -13,6 +13,8 @@ import ( "sync" "time" + "github.com/skycoin/skywire/internal/vpn" + "github.com/sirupsen/logrus" "github.com/skycoin/dmsg/cipher" @@ -135,6 +137,25 @@ func (c *HTTPClient) Services(ctx context.Context, quantity int) (out []Service, // UpdateEntry calls 'POST /api/services'. func (c *HTTPClient) UpdateEntry(ctx context.Context) (*Service, error) { + if c.conf.Type == ServiceTypeVisor { + if len(c.entry.LocalIPs) == 0 { + networkIfc, err := vpn.DefaultNetworkInterface() + if err != nil { + return nil, fmt.Errorf("failed to get default network interface: %w", err) + } + + localIPs, err := vpn.NetworkInterfaceIPs(networkIfc) + if err != nil { + return nil, fmt.Errorf("failed to get IPs of %s: %w", networkIfc, err) + } + + c.entry.LocalIPs = make([]string, 0, len(localIPs)) + for _, ip := range localIPs { + c.entry.LocalIPs = append(c.entry.LocalIPs, ip.String()) + } + } + } + auth, err := c.Auth(ctx) if err != nil { return nil, err diff --git a/pkg/servicedisc/types.go b/pkg/servicedisc/types.go index 61d26975fd..1bdea249c7 100644 --- a/pkg/servicedisc/types.go +++ b/pkg/servicedisc/types.go @@ -106,11 +106,12 @@ type Stats struct { // Service represents a service entry in service-discovery. type Service struct { - Addr SWAddr `json:"address"` - Type string `json:"type"` - Stats *Stats `json:"stats,omitempty"` // TODO: Have this implemented. - Geo *GeoLocation `json:"geo,omitempty"` - Version string `json:"version,omitempty"` + Addr SWAddr `json:"address"` + Type string `json:"type"` + Stats *Stats `json:"stats,omitempty"` // TODO: Have this implemented. + Geo *GeoLocation `json:"geo,omitempty"` + Version string `json:"version,omitempty"` + LocalIPs []string `json:"local_ips,omitempty"` } // MarshalBinary implements encoding.BinaryMarshaller From 00fc277f21f6bf786255869315aca609d49ef6ab Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Tue, 2 Feb 2021 23:49:51 +0300 Subject: [PATCH 12/41] Clean up the code --- pkg/servicedisc/client.go | 2 +- pkg/servicedisc/types.go | 2 -- pkg/snet/network.go | 10 +++------- pkg/visor/init.go | 39 ------------------------------------- pkg/visor/visorconfig/v1.go | 2 -- 5 files changed, 4 insertions(+), 51 deletions(-) diff --git a/pkg/servicedisc/client.go b/pkg/servicedisc/client.go index 777b9ee171..8d7e91b917 100644 --- a/pkg/servicedisc/client.go +++ b/pkg/servicedisc/client.go @@ -48,7 +48,7 @@ type HTTPClient struct { // NewClient creates a new HTTPClient. func NewClient(log logrus.FieldLogger, conf Config) *HTTPClient { var stats *Stats - if conf.Type != ServiceTypeVisor && conf.Type != ServiceTypePublicVisor { + if conf.Type != ServiceTypeVisor { stats = &Stats{ConnectedClients: 0} } diff --git a/pkg/servicedisc/types.go b/pkg/servicedisc/types.go index 1bdea249c7..00dd8b055b 100644 --- a/pkg/servicedisc/types.go +++ b/pkg/servicedisc/types.go @@ -17,8 +17,6 @@ const ( ServiceTypeVPN = "vpn" // ServiceTypeVisor stands for visor. ServiceTypeVisor = "visor" - // ServiceTypePublicVisor stands for type of visors that accessible on pulic address. - ServiceTypePublicVisor = "public_visor" ) // Errors associated with service discovery types. diff --git a/pkg/snet/network.go b/pkg/snet/network.go index 095ccb3858..6e3f474cdc 100644 --- a/pkg/snet/network.go +++ b/pkg/snet/network.go @@ -60,9 +60,8 @@ func (c *DmsgConfig) Type() string { // STCPConfig defines config for STCP network. type STCPConfig struct { - PKTable map[cipher.PubKey]string `json:"pk_table"` - LocalAddr string `json:"local_address"` - AddrIsPublic bool `json:"address_is_public"` + PKTable map[cipher.PubKey]string `json:"pk_table"` + LocalAddr string `json:"local_address"` } // Type returns STCP type. @@ -77,7 +76,6 @@ type Config struct { ARClient arclient.APIClient NetworkConfigs NetworkConfigs ServiceDisc appdisc.Factory - PublicTrusted bool } // NetworkConfigs represents all network configs. @@ -228,9 +226,7 @@ func (n *Network) Init() error { return fmt.Errorf("failed to initiate 'stcpr': %w", err) } - if n.conf.PublicTrusted { - go n.registerPublicTrusted(client) - } + go n.registerPublicTrusted(client) } else { log.Infof("No config found for stcpr") } diff --git a/pkg/visor/init.go b/pkg/visor/init.go index 9a84ece7a8..78d296248b 100644 --- a/pkg/visor/init.go +++ b/pkg/visor/init.go @@ -99,7 +99,6 @@ func initSNet(v *Visor) bool { ARClient: v.arClient, NetworkConfigs: nc, ServiceDisc: v.serviceDisc, - PublicTrusted: v.conf.PublicTrustedVisor, } n, err := snet.New(conf, v.ebc) @@ -489,33 +488,6 @@ func initUptimeTracker(v *Visor) bool { return true } -/*func initTrustedVisors(v *Visor) bool { - const trustedVisorsTransportType = tptypes.STCPR - - go func() { - time.Sleep(transport.TrustedVisorsDelay) - for _, pk := range v.tpM.Conf.DefaultVisors { - v.log.WithField("pk", pk).Infof("Adding trusted visor") - - if _, err := v.tpM.SaveTransport(context.Background(), pk, trustedVisorsTransportType); err != nil { - v.log. - WithError(err). - WithField("pk", pk). - WithField("type", trustedVisorsTransportType). - Warnf("Failed to add transport to trusted visor via") - } else { - v.log. - WithField("pk", pk). - WithField("type", trustedVisorsTransportType). - Infof("Added transport to trusted visor") - } - } - }() - - return true -}*/ -// TODO (darkrengarius): adv REMOVE - func initPublicVisors(v *Visor) bool { const tpType = tptypes.STCPR @@ -545,17 +517,6 @@ func initPublicVisors(v *Visor) bool { } discCl := servicedisc.NewClient(log, conf) - // TODO (darkrengarius): adv this one should be done in the updater manner, like it's already done for trusted visors - /*if v.conf.STCP.AddrIsPublic { - go func() { - time.Sleep(transport.TrustedVisorsDelay) - _, err := client.UpdateEntry(context.Background()) // try to register as public visor - if err != nil { - log.WithError(err).Warn("can't register as public visor") - } - }() - }*/ - if v.conf.Launcher.Discovery.PublicVisorsEnabled { go func() { time.Sleep(transport.PublicVisorsDelay * 2) diff --git a/pkg/visor/visorconfig/v1.go b/pkg/visor/visorconfig/v1.go index 9ca3b3f204..63b9a8d07d 100644 --- a/pkg/visor/visorconfig/v1.go +++ b/pkg/visor/visorconfig/v1.go @@ -35,8 +35,6 @@ type V1 struct { ShutdownTimeout Duration `json:"shutdown_timeout,omitempty"` // time value, examples: 10s, 1m, etc RestartCheckDelay Duration `json:"restart_check_delay,omitempty"` // time value, examples: 10s, 1m, etc - PublicTrustedVisor bool `json:"public_trusted_visor,omitempty"` - Hypervisor *hypervisorconfig.Config `json:"hypervisor,omitempty"` } From 6568a2474d8ebb28da5a3598312a37d2d628faf1 Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Wed, 3 Feb 2021 00:24:30 +0300 Subject: [PATCH 13/41] Fix import cycle, fix visor test --- internal/vpn/client.go | 3 +- internal/vpn/os.go | 65 ------------------------------ internal/vpn/os_darwin.go | 19 --------- internal/vpn/os_server_linux.go | 14 ------- internal/vpn/os_windows.go | 5 --- internal/vpn/server.go | 6 ++- pkg/servicedisc/client.go | 6 +-- pkg/util/netutil/net.go | 71 +++++++++++++++++++++++++++++++++ pkg/util/netutil/net_darwin.go | 26 ++++++++++++ pkg/util/netutil/net_linux.go | 26 ++++++++++++ pkg/util/netutil/net_windows.go | 8 ++++ pkg/util/osutil/errors.go | 22 ++++++++++ pkg/util/osutil/run.go | 41 +++++++++++++++++++ pkg/visor/visor_test.go | 9 +++++ 14 files changed, 212 insertions(+), 109 deletions(-) create mode 100644 pkg/util/netutil/net.go create mode 100644 pkg/util/netutil/net_darwin.go create mode 100644 pkg/util/netutil/net_linux.go create mode 100644 pkg/util/netutil/net_windows.go create mode 100644 pkg/util/osutil/errors.go create mode 100644 pkg/util/osutil/run.go diff --git a/internal/vpn/client.go b/internal/vpn/client.go index b3327068bf..e33dc85f14 100644 --- a/internal/vpn/client.go +++ b/internal/vpn/client.go @@ -20,6 +20,7 @@ import ( "github.com/skycoin/skywire/pkg/app/appnet" "github.com/skycoin/skywire/pkg/routing" "github.com/skycoin/skywire/pkg/skyenv" + nutil "github.com/skycoin/skywire/pkg/util/netutil" ) const ( @@ -613,7 +614,7 @@ func stcpEntitiesFromEnv() ([]net.IP, error) { } func (c *Client) shakeHands(conn net.Conn) (TUNIP, TUNGateway net.IP, err error) { - unavailableIPs, err := LocalNetworkInterfaceIPs() + unavailableIPs, err := nutil.LocalNetworkInterfaceIPs() if err != nil { return nil, nil, fmt.Errorf("error getting unavailable private IPs: %w", err) } diff --git a/internal/vpn/os.go b/internal/vpn/os.go index 916fd8ffc0..e4cbe0cb20 100644 --- a/internal/vpn/os.go +++ b/internal/vpn/os.go @@ -10,71 +10,6 @@ import ( "strings" ) -// LocalNetworkInterfaceIPs gets IPs of all local interfaces. -func LocalNetworkInterfaceIPs() ([]net.IP, error) { - ips, _, err := localNetworkInterfaceIPs("") - return ips, err -} - -// NetworkInterfaceIPs gets IPs of network interface with name `name`. -func NetworkInterfaceIPs(name string) ([]net.IP, error) { - _, ifcIPs, err := localNetworkInterfaceIPs(name) - return ifcIPs, err -} - -// localNetworkInterfaceIPs gets IPs of all local interfaces. Separately returns list of IPs -// of interface `ifcName`. -func localNetworkInterfaceIPs(ifcName string) ([]net.IP, []net.IP, error) { - var ifcIPs []net.IP - - ifaces, err := net.Interfaces() - if err != nil { - return nil, nil, fmt.Errorf("error getting network interfaces: %w", err) - } - - var ips []net.IP - for _, iface := range ifaces { - if iface.Flags&net.FlagUp == 0 { - continue // interface down - } - if iface.Flags&net.FlagLoopback != 0 { - continue // loopback interface - } - - addrs, err := iface.Addrs() - if err != nil { - return nil, nil, fmt.Errorf("error getting addresses for interface %s: %w", iface.Name, 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 - } - - if ip == nil || ip.IsLoopback() { - continue - } - - ip = ip.To4() - if ip == nil { - continue // not an ipv4 address - } - - ips = append(ips, ip) - - if ifcName != "" && iface.Name == ifcName { - ifcIPs = append(ifcIPs, ip) - } - } - } - - return ips, ifcIPs, nil -} - func parseCIDR(ipCIDR string) (ipStr, netmask string, err error) { ip, net, err := net.ParseCIDR(ipCIDR) if err != nil { diff --git a/internal/vpn/os_darwin.go b/internal/vpn/os_darwin.go index 2eb77165ac..0b32442f72 100644 --- a/internal/vpn/os_darwin.go +++ b/internal/vpn/os_darwin.go @@ -3,31 +3,12 @@ package vpn import ( - "bytes" "errors" "fmt" - "os/exec" "strconv" "strings" ) -const ( - defaultNetworkInterfaceCMD = "netstat -rn | sed -n '/Internet/,/Internet6/p' | grep default | awk '{print $4}'" -) - -// DefaultNetworkInterface fetches default network interface name. -func DefaultNetworkInterface() (string, error) { - outputBytes, err := exec.Command("sh", "-c", defaultNetworkInterfaceCMD).Output() - if err != nil { - return "", fmt.Errorf("error running command %s: %w", defaultNetworkInterfaceCMD, err) - } - - // just in case - outputBytes = bytes.TrimRight(outputBytes, "\n") - - return string(outputBytes), nil -} - // SetupTUN sets the allocated TUN interface up, setting its IP, gateway, netmask and MTU. func SetupTUN(ifcName, ipCIDR, gateway string, mtu int) error { ip, netmask, err := parseCIDR(ipCIDR) diff --git a/internal/vpn/os_server_linux.go b/internal/vpn/os_server_linux.go index 17d00e6797..2a8ae0711d 100644 --- a/internal/vpn/os_server_linux.go +++ b/internal/vpn/os_server_linux.go @@ -11,7 +11,6 @@ import ( ) const ( - defaultNetworkInterfaceCMD = "ip r | awk '$1 == \"default\" {print $5}'" getIPv4ForwardingCMD = "sysctl net.ipv4.ip_forward" getIPv6ForwardingCMD = "sysctl net.ipv6.conf.all.forwarding" setIPv4ForwardingCMDFmt = "sysctl -w net.ipv4.ip_forward=%s" @@ -72,19 +71,6 @@ func BlockIPToLocalNetwork(src, dst net.IP) error { return nil } -// DefaultNetworkInterface fetches default network interface name. -func DefaultNetworkInterface() (string, error) { - outputBytes, err := exec.Command("sh", "-c", defaultNetworkInterfaceCMD).Output() - if err != nil { - return "", fmt.Errorf("error running command %s: %w", defaultNetworkInterfaceCMD, err) - } - - // just in case - outputBytes = bytes.TrimRight(outputBytes, "\n") - - return string(outputBytes), nil -} - // GetIPv4ForwardingValue gets current value of IPv4 forwarding. func GetIPv4ForwardingValue() (string, error) { return getIPForwardingValue(getIPv4ForwardingCMD) diff --git a/internal/vpn/os_windows.go b/internal/vpn/os_windows.go index 531f717020..05e3af888a 100644 --- a/internal/vpn/os_windows.go +++ b/internal/vpn/os_windows.go @@ -12,11 +12,6 @@ const ( modifyRouteCMDFmt = "route %s %s mask %s %s" ) -// DefaultNetworkInterface fetches default network interface name. -func DefaultNetworkInterface() (string, error) { - return "", errServerMethodsNotSupported -} - // SetupTUN sets the allocated TUN interface up, setting its IP, gateway, netmask and MTU. func SetupTUN(ifcName, ipCIDR, gateway string, mtu int) error { ip, netmask, err := parseCIDR(ipCIDR) diff --git a/internal/vpn/server.go b/internal/vpn/server.go index 34c7fb6669..11f356826e 100644 --- a/internal/vpn/server.go +++ b/internal/vpn/server.go @@ -7,6 +7,8 @@ import ( "net" "sync" + "github.com/skycoin/skywire/pkg/util/netutil" + "github.com/sirupsen/logrus" ) @@ -33,14 +35,14 @@ func NewServer(cfg ServerConfig, l logrus.FieldLogger) (*Server, error) { ipGen: NewIPGenerator(), } - defaultNetworkIfc, err := DefaultNetworkInterface() + defaultNetworkIfc, err := netutil.DefaultNetworkInterface() if err != nil { return nil, fmt.Errorf("error getting default network interface: %w", err) } l.Infof("Got default network interface: %s", defaultNetworkIfc) - defaultNetworkIfcIPs, err := NetworkInterfaceIPs(defaultNetworkIfc) + defaultNetworkIfcIPs, err := netutil.NetworkInterfaceIPs(defaultNetworkIfc) if err != nil { return nil, fmt.Errorf("error getting IPs of interface %s: %w", defaultNetworkIfc, err) } diff --git a/pkg/servicedisc/client.go b/pkg/servicedisc/client.go index 8d7e91b917..5901267285 100644 --- a/pkg/servicedisc/client.go +++ b/pkg/servicedisc/client.go @@ -13,7 +13,7 @@ import ( "sync" "time" - "github.com/skycoin/skywire/internal/vpn" + "github.com/skycoin/skywire/pkg/util/netutil" "github.com/sirupsen/logrus" "github.com/skycoin/dmsg/cipher" @@ -139,12 +139,12 @@ func (c *HTTPClient) Services(ctx context.Context, quantity int) (out []Service, func (c *HTTPClient) UpdateEntry(ctx context.Context) (*Service, error) { if c.conf.Type == ServiceTypeVisor { if len(c.entry.LocalIPs) == 0 { - networkIfc, err := vpn.DefaultNetworkInterface() + networkIfc, err := netutil.DefaultNetworkInterface() if err != nil { return nil, fmt.Errorf("failed to get default network interface: %w", err) } - localIPs, err := vpn.NetworkInterfaceIPs(networkIfc) + localIPs, err := netutil.NetworkInterfaceIPs(networkIfc) if err != nil { return nil, fmt.Errorf("failed to get IPs of %s: %w", networkIfc, err) } diff --git a/pkg/util/netutil/net.go b/pkg/util/netutil/net.go new file mode 100644 index 0000000000..18f5cd4d61 --- /dev/null +++ b/pkg/util/netutil/net.go @@ -0,0 +1,71 @@ +package netutil + +import ( + "fmt" + "net" +) + +// LocalNetworkInterfaceIPs gets IPs of all local interfaces. +func LocalNetworkInterfaceIPs() ([]net.IP, error) { + ips, _, err := localNetworkInterfaceIPs("") + return ips, err +} + +// NetworkInterfaceIPs gets IPs of network interface with name `name`. +func NetworkInterfaceIPs(name string) ([]net.IP, error) { + _, ifcIPs, err := localNetworkInterfaceIPs(name) + return ifcIPs, err +} + +// localNetworkInterfaceIPs gets IPs of all local interfaces. Separately returns list of IPs +// of interface `ifcName`. +func localNetworkInterfaceIPs(ifcName string) ([]net.IP, []net.IP, error) { + var ifcIPs []net.IP + + ifaces, err := net.Interfaces() + if err != nil { + return nil, nil, fmt.Errorf("error getting network interfaces: %w", err) + } + + var ips []net.IP + for _, iface := range ifaces { + if iface.Flags&net.FlagUp == 0 { + continue // interface down + } + if iface.Flags&net.FlagLoopback != 0 { + continue // loopback interface + } + + addrs, err := iface.Addrs() + if err != nil { + return nil, nil, fmt.Errorf("error getting addresses for interface %s: %w", iface.Name, 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 + } + + if ip == nil || ip.IsLoopback() { + continue + } + + ip = ip.To4() + if ip == nil { + continue // not an ipv4 address + } + + ips = append(ips, ip) + + if ifcName != "" && iface.Name == ifcName { + ifcIPs = append(ifcIPs, ip) + } + } + } + + return ips, ifcIPs, nil +} diff --git a/pkg/util/netutil/net_darwin.go b/pkg/util/netutil/net_darwin.go new file mode 100644 index 0000000000..4c5a0349fa --- /dev/null +++ b/pkg/util/netutil/net_darwin.go @@ -0,0 +1,26 @@ +//+build darwin + +package netutil + +import ( + "bytes" + "fmt" + "os/exec" +) + +const ( + defaultNetworkInterfaceCMD = "netstat -rn | sed -n '/Internet/,/Internet6/p' | grep default | awk '{print $4}'" +) + +// DefaultNetworkInterface fetches default network interface name. +func DefaultNetworkInterface() (string, error) { + outputBytes, err := exec.Command("sh", "-c", defaultNetworkInterfaceCMD).Output() + if err != nil { + return "", fmt.Errorf("error running command %s: %w", defaultNetworkInterfaceCMD, err) + } + + // just in case + outputBytes = bytes.TrimRight(outputBytes, "\n") + + return string(outputBytes), nil +} diff --git a/pkg/util/netutil/net_linux.go b/pkg/util/netutil/net_linux.go new file mode 100644 index 0000000000..55324a711b --- /dev/null +++ b/pkg/util/netutil/net_linux.go @@ -0,0 +1,26 @@ +//+build linux + +package netutil + +import ( + "bytes" + "fmt" + "os/exec" +) + +const ( + defaultNetworkInterfaceCMD = "ip r | awk '$1 == \"default\" {print $5}'" +) + +// DefaultNetworkInterface fetches default network interface name. +func DefaultNetworkInterface() (string, error) { + outputBytes, err := exec.Command("sh", "-c", defaultNetworkInterfaceCMD).Output() + if err != nil { + return "", fmt.Errorf("error running command %s: %w", defaultNetworkInterfaceCMD, err) + } + + // just in case + outputBytes = bytes.TrimRight(outputBytes, "\n") + + return string(outputBytes), nil +} diff --git a/pkg/util/netutil/net_windows.go b/pkg/util/netutil/net_windows.go new file mode 100644 index 0000000000..c5f6e9410a --- /dev/null +++ b/pkg/util/netutil/net_windows.go @@ -0,0 +1,8 @@ +//+build windows + +package netutil + +// DefaultNetworkInterface fetches default network interface name. +func DefaultNetworkInterface() (string, error) { + return "", errServerMethodsNotSupported +} diff --git a/pkg/util/osutil/errors.go b/pkg/util/osutil/errors.go new file mode 100644 index 0000000000..a95cea6f89 --- /dev/null +++ b/pkg/util/osutil/errors.go @@ -0,0 +1,22 @@ +package osutil + +// ErrorWithStderr is an error raised by the external process. +// `Err` is an actual error coming from `exec`, while `Stderr` contains +// stderr output of the process. +type ErrorWithStderr struct { + Err error + Stderr []byte +} + +// NewErrorWithStderr constructs new `ErrorWithStderr`. +func NewErrorWithStderr(err error, stderr []byte) *ErrorWithStderr { + return &ErrorWithStderr{ + Err: err, + Stderr: stderr, + } +} + +// Error implements `error`. +func (e *ErrorWithStderr) Error() string { + return e.Err.Error() + ": " + string(e.Stderr) +} diff --git a/pkg/util/osutil/run.go b/pkg/util/osutil/run.go new file mode 100644 index 0000000000..3e3198191b --- /dev/null +++ b/pkg/util/osutil/run.go @@ -0,0 +1,41 @@ +package osutil + +import ( + "bytes" + "fmt" + "io" + "os" + "os/exec" + "strings" +) + +// Run runs binary `bin` with `args`. +func Run(bin string, args ...string) error { + return run(bin, os.Stdout, args...) +} + +// RunWithResult runs binary `bin` with `args` returning stdout contents. +func RunWithResult(bin string, args ...string) (io.Reader, error) { + stdout := bytes.NewBuffer(nil) + + return stdout, run(bin, stdout, args...) +} + +func run(bin string, stdout io.Writer, args ...string) error { + fullCmd := bin + " " + strings.Join(args, " ") + + cmd := exec.Command(bin, args...) //nolint:gosec + + stderrBuf := bytes.NewBuffer(nil) + + cmd.Stderr = io.MultiWriter(os.Stderr, stderrBuf) + cmd.Stdout = stdout + cmd.Stdin = os.Stdin + + if err := cmd.Run(); err != nil { + return NewErrorWithStderr(fmt.Errorf("error running command \"%s\": %w", fullCmd, err), + stderrBuf.Bytes()) + } + + return nil +} diff --git a/pkg/visor/visor_test.go b/pkg/visor/visor_test.go index 4d2737fa72..bd6e0027f7 100644 --- a/pkg/visor/visor_test.go +++ b/pkg/visor/visor_test.go @@ -55,6 +55,10 @@ func TestNewVisor(t *testing.T) { Discovery: skyenv.DefaultDmsgDiscAddr, SessionsCount: 10, }, + STCP: &snet.STCPConfig{ + PKTable: nil, + LocalAddr: "localhost:7777", + }, Transport: &visorconfig.V1Transport{ Discovery: srv.URL, AddressResolver: skyenv.DefaultAddressResolverAddr, @@ -74,6 +78,11 @@ func TestNewVisor(t *testing.T) { {Name: "foo", Port: 1}, {Name: "bar", AutoStart: true, Port: 2}, }, + Discovery: &visorconfig.V1AppDisc{ + UpdateInterval: 0, + ServiceDisc: "", + PublicVisorsEnabled: false, + }, }, } From 9d74cd9b6b1db1015b9360e235612966a7ec6fbe Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Mon, 29 Mar 2021 01:46:31 +0300 Subject: [PATCH 14/41] Add debug logs --- pkg/snet/network.go | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/pkg/snet/network.go b/pkg/snet/network.go index 6e3f474cdc..8c64844b44 100644 --- a/pkg/snet/network.go +++ b/pkg/snet/network.go @@ -221,12 +221,15 @@ func (n *Network) Init() error { } if n.conf.ARClient != nil { + log.Infoln("AR CLIENT IS NOT NIL") if client, ok := n.clients.Direct[tptypes.STCPR]; ok && client != nil { + log.Infoln("GOT SCTCPR CLIENT") if err := client.Serve(); err != nil { + log.Infof("FAILED TO SERVE STCPR CLIENT: %v", err) return fmt.Errorf("failed to initiate 'stcpr': %w", err) } - go n.registerPublicTrusted(client) + go n.registerAsPublic(client) } else { log.Infof("No config found for stcpr") } @@ -238,25 +241,29 @@ func (n *Network) Init() error { } else { log.Infof("No config found for sudph") } + } else { + log.Infoln("ARCLIENT IS NIL") } return nil } -func (n *Network) registerPublicTrusted(client directtp.Client) { - log.Infof("Trying to register visor as public trusted") +func (n *Network) registerAsPublic(client directtp.Client) { + log.Infoln("Trying to register visor as public") la, err := client.LocalAddr() if err != nil { - log.WithError(err).Errorf("Failed to get STCPR local addr") + log.WithError(err).Errorln("Failed to get STCPR local addr") return } + log.Infof("LOCAL ADDR: %s", la.String()) _, portStr, err := net.SplitHostPort(la.String()) if err != nil { log.WithError(err).Errorf("Failed to extract port from addr %v", la.String()) return } + log.Infof("LOCAL PORT STR: %v", portStr) port, err := strconv.Atoi(portStr) if err != nil { @@ -264,10 +271,12 @@ func (n *Network) registerPublicTrusted(client directtp.Client) { return } + log.Infof("LOCAL PORT: %v", port) + n.visorUpdater = n.conf.ServiceDisc.VisorUpdater(uint16(port)) n.visorUpdater.Start() - log.Infof("Sent request to register visor as public trusted") + log.Infof("Sent request to register visor as public") } // OnNewNetworkType sets callback to be called when new network type is ready. From 6ffe9d39a914b704b9ebcc1388bdbdeed48604ac Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Mon, 29 Mar 2021 02:10:39 +0300 Subject: [PATCH 15/41] Update deps --- go.mod | 1 - go.sum | 31 +++++++++++++------------------ vendor/modules.txt | 2 -- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index c129fc3c53..c5957aca74 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,6 @@ require ( github.com/mmcloughlin/avo v0.0.0-20200523190732-4439b6b2c061 // indirect github.com/pkg/errors v0.8.1 // indirect github.com/pkg/profile v1.5.0 - github.com/prometheus/client_golang v1.7.1 // indirect github.com/schollz/progressbar/v2 v2.15.0 github.com/shirou/gopsutil v2.20.5+incompatible github.com/sirupsen/logrus v1.7.0 diff --git a/go.sum b/go.sum index f025f1c1b4..59905b3036 100644 --- a/go.sum +++ b/go.sum @@ -8,9 +8,7 @@ github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrU github.com/VictoriaMetrics/metrics v1.12.3 h1:Fe6JHC6MSEKa+BtLhPN8WIvS+HKPzMc2evEpNeCGy7I= github.com/VictoriaMetrics/metrics v1.12.3/go.mod h1:Z1tSfPfngDn12bTfZSCqArT3OPY3u88J12hSoOhuiRE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andybalholm/brotli v0.0.0-20190621154722-5f990b63d2d6 h1:bZ28Hqta7TFAK3Q08CMvv8y3/8ATaEqv2nGoc6yff6c= github.com/andybalholm/brotli v0.0.0-20190621154722-5f990b63d2d6/go.mod h1:+lx6/Aqd1kLJ1GQfkvOnaZ1WGmLpMpbprPuIOOZX30U= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= @@ -18,9 +16,7 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -46,15 +42,17 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec= github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= github.com/go-redis/redis v6.15.6+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= @@ -65,13 +63,13 @@ github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4er github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -79,6 +77,7 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= @@ -91,6 +90,7 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= @@ -100,7 +100,6 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= @@ -122,8 +121,10 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kz/discordrus v1.2.0 h1:r5uplKozPR+TIJ1NUZT758Lv7eukf8+fp3L4uRj+6xs= github.com/kz/discordrus v1.2.0/go.mod h1:cJ3TiJUUuY5Gm3DNYHnnaUa3iol8VBRPzztAeZm7exc= @@ -172,19 +173,12 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -258,6 +252,7 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xtaci/kcp-go v5.4.20+incompatible h1:TN1uey3Raw0sTz0Fg8GkfM0uH3YwzhnZWQ1bABv5xAg= github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE= +github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lLQwDsRyZfmkPeRbdgPtW609es+/9E= github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2CyokmAh4lp0EQnnWhmycP/TvwBGzvuie+H0= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -279,6 +274,7 @@ golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9 h1:sYNJzB4J8toYPQTM6pAkcm golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -287,7 +283,6 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191204025024-5ee1b9f4859a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -311,13 +306,11 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e h1:AyodaIpKjppX+cBfTASF2E1US3H2JFBj920Ot3rtDjs= golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -328,6 +321,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -352,10 +346,12 @@ google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= @@ -365,7 +361,6 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/vendor/modules.txt b/vendor/modules.txt index 3ad6975d6c..d957b71f04 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -116,8 +116,6 @@ github.com/pkg/errors github.com/pkg/profile # github.com/pmezard/go-difflib v1.0.0 github.com/pmezard/go-difflib/difflib -# github.com/prometheus/client_golang v1.7.1 -## explicit # github.com/schollz/progressbar/v2 v2.15.0 ## explicit github.com/schollz/progressbar/v2 From fb05117f570c4b8bdead1c642726e96a0e8de73d Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Mon, 29 Mar 2021 02:20:30 +0300 Subject: [PATCH 16/41] Add debug logs --- pkg/servicedisc/client.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pkg/servicedisc/client.go b/pkg/servicedisc/client.go index 5901267285..56fbd0f6a7 100644 --- a/pkg/servicedisc/client.go +++ b/pkg/servicedisc/client.go @@ -189,6 +189,7 @@ func (c *HTTPClient) UpdateEntry(ctx context.Context) (*Service, error) { if err != nil { return nil, fmt.Errorf("read response body: %w", err) } + c.log.Infof("GOT RESP ERR BODY: %v", string(respBody)) var hErr HTTPResponse if err = json.Unmarshal(respBody, &hErr); err != nil { @@ -198,6 +199,15 @@ func (c *HTTPClient) UpdateEntry(ctx context.Context) (*Service, error) { return nil, hErr.Error } + respBody, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + c.log.Infof("GOT OK RESP BODY: %v", string(respBody)) + if err := json.Unmarshal(respBody, &c.entry); err != nil { + return nil, err + } + return &c.entry, nil err = json.NewDecoder(resp.Body).Decode(&c.entry) return &c.entry, err } From a90a855217e3930d5457005b8c61631cb8b17549 Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Wed, 31 Mar 2021 01:19:09 +0300 Subject: [PATCH 17/41] Make service updater stop retrying if visor is unreachable --- pkg/servicedisc/client.go | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/pkg/servicedisc/client.go b/pkg/servicedisc/client.go index 56fbd0f6a7..d08a43a723 100644 --- a/pkg/servicedisc/client.go +++ b/pkg/servicedisc/client.go @@ -250,16 +250,17 @@ func (c *HTTPClient) DeleteEntry(ctx context.Context) (err error) { func (c *HTTPClient) UpdateLoop(ctx context.Context, updateInterval time.Duration) { defer func() { _ = c.DeleteEntry(context.Background()) }() //nolint:errcheck - update := func() { + update := func() error { for { c.entryMx.Lock() entry, err := c.UpdateEntry(ctx) c.entryMx.Unlock() if err != nil { + c.log.Infof("ERROR FROM SERVICE DISC REGISTER: %v", err) if strings.Contains(err.Error(), ErrVisorUnreachable.Error()) { c.log.Errorf("Unable to register visor as public trusted as it's unreachable from WAN") - return + return err } c.log.WithError(err).Warn("Failed to update service entry in discovery. Retrying...") @@ -276,21 +277,23 @@ func (c *HTTPClient) UpdateLoop(ctx context.Context, updateInterval time.Duratio } c.log.WithField("entry", string(j)).Debug("Entry updated.") - return + return nil } } - // Run initial update. - update() - ticker := time.NewTicker(updateInterval) for { + if err := update(); err != nil { + if strings.Contains(err.Error(), ErrVisorUnreachable.Error()) { + return + } + } + select { case <-ctx.Done(): ticker.Stop() return case <-ticker.C: - update() } } } From 4cc790f16a8a98191440c76b5413881ecfe739a4 Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Wed, 31 Mar 2021 01:20:49 +0300 Subject: [PATCH 18/41] Properly stop ticker on updater exit --- pkg/servicedisc/client.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/servicedisc/client.go b/pkg/servicedisc/client.go index d08a43a723..81ec828f08 100644 --- a/pkg/servicedisc/client.go +++ b/pkg/servicedisc/client.go @@ -282,6 +282,8 @@ func (c *HTTPClient) UpdateLoop(ctx context.Context, updateInterval time.Duratio } ticker := time.NewTicker(updateInterval) + defer ticker.Stop() + for { if err := update(); err != nil { if strings.Contains(err.Error(), ErrVisorUnreachable.Error()) { @@ -291,7 +293,6 @@ func (c *HTTPClient) UpdateLoop(ctx context.Context, updateInterval time.Duratio select { case <-ctx.Done(): - ticker.Stop() return case <-ticker.C: } From 083cf998cfa1ad5e129135a573e96ba2d56462bf Mon Sep 17 00:00:00 2001 From: Sir Darkrengarius Date: Wed, 31 Mar 2021 02:55:42 +0300 Subject: [PATCH 19/41] Remove debug logs --- pkg/servicedisc/client.go | 14 +------------- pkg/snet/network.go | 9 --------- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/pkg/servicedisc/client.go b/pkg/servicedisc/client.go index 81ec828f08..5d4cd81864 100644 --- a/pkg/servicedisc/client.go +++ b/pkg/servicedisc/client.go @@ -13,13 +13,12 @@ import ( "sync" "time" - "github.com/skycoin/skywire/pkg/util/netutil" - "github.com/sirupsen/logrus" "github.com/skycoin/dmsg/cipher" "github.com/skycoin/skywire/internal/httpauth" "github.com/skycoin/skywire/pkg/util/buildinfo" + "github.com/skycoin/skywire/pkg/util/netutil" ) var ( @@ -189,7 +188,6 @@ func (c *HTTPClient) UpdateEntry(ctx context.Context) (*Service, error) { if err != nil { return nil, fmt.Errorf("read response body: %w", err) } - c.log.Infof("GOT RESP ERR BODY: %v", string(respBody)) var hErr HTTPResponse if err = json.Unmarshal(respBody, &hErr); err != nil { @@ -199,15 +197,6 @@ func (c *HTTPClient) UpdateEntry(ctx context.Context) (*Service, error) { return nil, hErr.Error } - respBody, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - c.log.Infof("GOT OK RESP BODY: %v", string(respBody)) - if err := json.Unmarshal(respBody, &c.entry); err != nil { - return nil, err - } - return &c.entry, nil err = json.NewDecoder(resp.Body).Decode(&c.entry) return &c.entry, err } @@ -257,7 +246,6 @@ func (c *HTTPClient) UpdateLoop(ctx context.Context, updateInterval time.Duratio c.entryMx.Unlock() if err != nil { - c.log.Infof("ERROR FROM SERVICE DISC REGISTER: %v", err) if strings.Contains(err.Error(), ErrVisorUnreachable.Error()) { c.log.Errorf("Unable to register visor as public trusted as it's unreachable from WAN") return err diff --git a/pkg/snet/network.go b/pkg/snet/network.go index 8c64844b44..887ae8e39e 100644 --- a/pkg/snet/network.go +++ b/pkg/snet/network.go @@ -221,11 +221,8 @@ func (n *Network) Init() error { } if n.conf.ARClient != nil { - log.Infoln("AR CLIENT IS NOT NIL") if client, ok := n.clients.Direct[tptypes.STCPR]; ok && client != nil { - log.Infoln("GOT SCTCPR CLIENT") if err := client.Serve(); err != nil { - log.Infof("FAILED TO SERVE STCPR CLIENT: %v", err) return fmt.Errorf("failed to initiate 'stcpr': %w", err) } @@ -241,8 +238,6 @@ func (n *Network) Init() error { } else { log.Infof("No config found for sudph") } - } else { - log.Infoln("ARCLIENT IS NIL") } return nil @@ -256,14 +251,12 @@ func (n *Network) registerAsPublic(client directtp.Client) { log.WithError(err).Errorln("Failed to get STCPR local addr") return } - log.Infof("LOCAL ADDR: %s", la.String()) _, portStr, err := net.SplitHostPort(la.String()) if err != nil { log.WithError(err).Errorf("Failed to extract port from addr %v", la.String()) return } - log.Infof("LOCAL PORT STR: %v", portStr) port, err := strconv.Atoi(portStr) if err != nil { @@ -271,8 +264,6 @@ func (n *Network) registerAsPublic(client directtp.Client) { return } - log.Infof("LOCAL PORT: %v", port) - n.visorUpdater = n.conf.ServiceDisc.VisorUpdater(uint16(port)) n.visorUpdater.Start() From 0f249ce2d1e228c499666afaa0b41bbd5701a3d2 Mon Sep 17 00:00:00 2001 From: Never M Date: Tue, 27 Apr 2021 11:46:45 +0300 Subject: [PATCH 20/41] Run make format --- pkg/app/appevent/mock_rpc_client.go | 4 ++-- pkg/router/mock_router.go | 4 +--- pkg/setup/mock_id_reserver.go | 2 -- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/pkg/app/appevent/mock_rpc_client.go b/pkg/app/appevent/mock_rpc_client.go index 393e3af472..cb04624faf 100644 --- a/pkg/app/appevent/mock_rpc_client.go +++ b/pkg/app/appevent/mock_rpc_client.go @@ -5,9 +5,9 @@ package appevent import ( context "context" - appcommon "github.com/skycoin/skywire/pkg/app/appcommon" - mock "github.com/stretchr/testify/mock" + + appcommon "github.com/skycoin/skywire/pkg/app/appcommon" ) // MockRPCClient is an autogenerated mock type for the RPCClient type diff --git a/pkg/router/mock_router.go b/pkg/router/mock_router.go index 6b1865b74f..ff271b86ce 100644 --- a/pkg/router/mock_router.go +++ b/pkg/router/mock_router.go @@ -4,13 +4,11 @@ package router import ( context "context" + net "net" cipher "github.com/skycoin/dmsg/cipher" - mock "github.com/stretchr/testify/mock" - net "net" - routing "github.com/skycoin/skywire/pkg/routing" ) diff --git a/pkg/setup/mock_id_reserver.go b/pkg/setup/mock_id_reserver.go index 8e8eace704..351a2d0fc5 100644 --- a/pkg/setup/mock_id_reserver.go +++ b/pkg/setup/mock_id_reserver.go @@ -6,11 +6,9 @@ import ( context "context" cipher "github.com/skycoin/dmsg/cipher" - mock "github.com/stretchr/testify/mock" routerclient "github.com/skycoin/skywire/pkg/router/routerclient" - routing "github.com/skycoin/skywire/pkg/routing" ) From dbc25f647f382ebd88f46dabb0d687073f267c96 Mon Sep 17 00:00:00 2001 From: Never M Date: Tue, 27 Apr 2021 17:13:22 +0300 Subject: [PATCH 21/41] Use errors.Is instead of string matching --- pkg/servicedisc/client.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/pkg/servicedisc/client.go b/pkg/servicedisc/client.go index 5d4cd81864..116aab783a 100644 --- a/pkg/servicedisc/client.go +++ b/pkg/servicedisc/client.go @@ -9,7 +9,6 @@ import ( "io/ioutil" "net/http" "strconv" - "strings" "sync" "time" @@ -246,7 +245,7 @@ func (c *HTTPClient) UpdateLoop(ctx context.Context, updateInterval time.Duratio c.entryMx.Unlock() if err != nil { - if strings.Contains(err.Error(), ErrVisorUnreachable.Error()) { + if errors.Is(err, ErrVisorUnreachable) { c.log.Errorf("Unable to register visor as public trusted as it's unreachable from WAN") return err } @@ -273,10 +272,8 @@ func (c *HTTPClient) UpdateLoop(ctx context.Context, updateInterval time.Duratio defer ticker.Stop() for { - if err := update(); err != nil { - if strings.Contains(err.Error(), ErrVisorUnreachable.Error()) { - return - } + if err := update(); errors.Is(err, ErrVisorUnreachable) { + return } select { From 6af273c3aa6e4ec3cb4890ee7d36fba145578b50 Mon Sep 17 00:00:00 2001 From: Never M Date: Tue, 27 Apr 2021 17:47:44 +0300 Subject: [PATCH 22/41] Add exponential backoff to service update entry --- pkg/servicedisc/client.go | 64 ++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/pkg/servicedisc/client.go b/pkg/servicedisc/client.go index 116aab783a..7d02bba409 100644 --- a/pkg/servicedisc/client.go +++ b/pkg/servicedisc/client.go @@ -16,6 +16,7 @@ import ( "github.com/skycoin/dmsg/cipher" "github.com/skycoin/skywire/internal/httpauth" + nu "github.com/skycoin/skywire/internal/netutil" "github.com/skycoin/skywire/pkg/util/buildinfo" "github.com/skycoin/skywire/pkg/util/netutil" ) @@ -23,6 +24,7 @@ import ( var ( // ErrVisorUnreachable is returned when visor is unreachable. ErrVisorUnreachable = errors.New("visor is unreachable") + updateRetryDelay = 5 * time.Second ) // Config configures the HTTPClient. @@ -238,41 +240,11 @@ func (c *HTTPClient) DeleteEntry(ctx context.Context) (err error) { func (c *HTTPClient) UpdateLoop(ctx context.Context, updateInterval time.Duration) { defer func() { _ = c.DeleteEntry(context.Background()) }() //nolint:errcheck - update := func() error { - for { - c.entryMx.Lock() - entry, err := c.UpdateEntry(ctx) - c.entryMx.Unlock() - - if err != nil { - if errors.Is(err, ErrVisorUnreachable) { - c.log.Errorf("Unable to register visor as public trusted as it's unreachable from WAN") - return err - } - - c.log.WithError(err).Warn("Failed to update service entry in discovery. Retrying...") - time.Sleep(time.Second * 10) // TODO(evanlinjin): Exponential backoff. - continue - } - - c.entryMx.Lock() - j, err := json.Marshal(entry) - c.entryMx.Unlock() - - if err != nil { - panic(err) - } - - c.log.WithField("entry", string(j)).Debug("Entry updated.") - return nil - } - } - ticker := time.NewTicker(updateInterval) defer ticker.Stop() for { - if err := update(); errors.Is(err, ErrVisorUnreachable) { + if err := c.Update(ctx); errors.Is(err, ErrVisorUnreachable) { return } @@ -284,6 +256,36 @@ func (c *HTTPClient) UpdateLoop(ctx context.Context, updateInterval time.Duratio } } +// Update calls 'POST /api/services' to update service discovery entry +// it performs exponential backoff in case of errors during update, unless +// the error is unrecoverable from +func (c *HTTPClient) Update(ctx context.Context) error { + retrier := nu.NewRetrier(updateRetryDelay, 0, 2).WithErrWhitelist(ErrVisorUnreachable) + run := func() error { + c.entryMx.Lock() + entry, err := c.UpdateEntry(ctx) + c.entryMx.Unlock() + + if errors.Is(err, ErrVisorUnreachable) { + c.log.Errorf("Unable to register visor as public trusted as it's unreachable from WAN") + return err + } + + if err != nil { + c.log.WithError(err).Warn("Failed to update service entry in discovery. Retrying...") + return err + } + + c.entryMx.Lock() + j, err := json.Marshal(entry) + c.entryMx.Unlock() + + c.log.WithField("entry", string(j)).Debug("Entry updated.") + return nil + } + return retrier.Do(run) +} + // UpdateStats updates the stats field of the internal service entry state. func (c *HTTPClient) UpdateStats(stats Stats) { c.entryMx.Lock() From d7b23ae52a75d8828cbaf0f4c5f2b00ddc4a98eb Mon Sep 17 00:00:00 2001 From: Never M Date: Tue, 27 Apr 2021 17:57:03 +0300 Subject: [PATCH 23/41] Refactor entry update loop --- pkg/servicedisc/client.go | 51 +++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/pkg/servicedisc/client.go b/pkg/servicedisc/client.go index 7d02bba409..bad53b2a18 100644 --- a/pkg/servicedisc/client.go +++ b/pkg/servicedisc/client.go @@ -136,17 +136,17 @@ func (c *HTTPClient) Services(ctx context.Context, quantity int) (out []Service, } // UpdateEntry calls 'POST /api/services'. -func (c *HTTPClient) UpdateEntry(ctx context.Context) (*Service, error) { +func (c *HTTPClient) UpdateEntry(ctx context.Context) error { if c.conf.Type == ServiceTypeVisor { if len(c.entry.LocalIPs) == 0 { networkIfc, err := netutil.DefaultNetworkInterface() if err != nil { - return nil, fmt.Errorf("failed to get default network interface: %w", err) + return fmt.Errorf("failed to get default network interface: %w", err) } localIPs, err := netutil.NetworkInterfaceIPs(networkIfc) if err != nil { - return nil, fmt.Errorf("failed to get IPs of %s: %w", networkIfc, err) + return fmt.Errorf("failed to get IPs of %s: %w", networkIfc, err) } c.entry.LocalIPs = make([]string, 0, len(localIPs)) @@ -158,23 +158,23 @@ func (c *HTTPClient) UpdateEntry(ctx context.Context) (*Service, error) { auth, err := c.Auth(ctx) if err != nil { - return nil, err + return err } c.entry.Addr = NewSWAddr(c.conf.PK, c.conf.Port) // Just in case. raw, err := json.Marshal(&c.entry) if err != nil { - return nil, err + return err } req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.addr("/api/services", ""), bytes.NewReader(raw)) if err != nil { - return nil, err + return err } resp, err := auth.Do(req) if err != nil { - return nil, err + return err } if resp != nil { defer func() { @@ -187,19 +187,26 @@ func (c *HTTPClient) UpdateEntry(ctx context.Context) (*Service, error) { if resp.StatusCode != http.StatusOK { respBody, err := ioutil.ReadAll(resp.Body) if err != nil { - return nil, fmt.Errorf("read response body: %w", err) + return fmt.Errorf("read response body: %w", err) } var hErr HTTPResponse if err = json.Unmarshal(respBody, &hErr); err != nil { - return nil, err + return err } - return nil, hErr.Error + return hErr.Error } - err = json.NewDecoder(resp.Body).Decode(&c.entry) - return &c.entry, err + var entry Service + err = json.NewDecoder(resp.Body).Decode(&entry) + if err != nil { + return err + } + c.entryMx.Lock() + c.entry = entry + c.entryMx.Unlock() + return err } // DeleteEntry calls 'DELETE /api/services/{entry_addr}'. @@ -247,6 +254,16 @@ func (c *HTTPClient) UpdateLoop(ctx context.Context, updateInterval time.Duratio if err := c.Update(ctx); errors.Is(err, ErrVisorUnreachable) { return } + c.entryMx.Lock() + j, err := json.Marshal(c.entry) + c.entryMx.Unlock() + logger := c.log.WithField("entry", string(j)) + if err == nil { + logger.Debug("Entry updated.") + } else { + logger.Errorf("Service returned malformed entry, error: %s", err) + return + } select { case <-ctx.Done(): @@ -262,9 +279,7 @@ func (c *HTTPClient) UpdateLoop(ctx context.Context, updateInterval time.Duratio func (c *HTTPClient) Update(ctx context.Context) error { retrier := nu.NewRetrier(updateRetryDelay, 0, 2).WithErrWhitelist(ErrVisorUnreachable) run := func() error { - c.entryMx.Lock() - entry, err := c.UpdateEntry(ctx) - c.entryMx.Unlock() + err := c.UpdateEntry(ctx) if errors.Is(err, ErrVisorUnreachable) { c.log.Errorf("Unable to register visor as public trusted as it's unreachable from WAN") @@ -275,12 +290,6 @@ func (c *HTTPClient) Update(ctx context.Context) error { c.log.WithError(err).Warn("Failed to update service entry in discovery. Retrying...") return err } - - c.entryMx.Lock() - j, err := json.Marshal(entry) - c.entryMx.Unlock() - - c.log.WithField("entry", string(j)).Debug("Entry updated.") return nil } return retrier.Do(run) From 0ebc644464422c45bee1461e874d316e415c0b83 Mon Sep 17 00:00:00 2001 From: Never M Date: Tue, 27 Apr 2021 18:09:45 +0300 Subject: [PATCH 24/41] Move POST service discovery to a separate func --- pkg/servicedisc/client.go | 67 +++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/pkg/servicedisc/client.go b/pkg/servicedisc/client.go index bad53b2a18..f48ed7caf7 100644 --- a/pkg/servicedisc/client.go +++ b/pkg/servicedisc/client.go @@ -135,46 +135,59 @@ func (c *HTTPClient) Services(ctx context.Context, quantity int) (out []Service, return out, err } -// UpdateEntry calls 'POST /api/services'. +// UpdateEntry calls 'POST /api/services', retrieves the entry +// and updates local field with the result +// if there are no ip addresses in the entry it also tries to fetch those +// from local config func (c *HTTPClient) UpdateEntry(ctx context.Context) error { - if c.conf.Type == ServiceTypeVisor { - if len(c.entry.LocalIPs) == 0 { - networkIfc, err := netutil.DefaultNetworkInterface() - if err != nil { - return fmt.Errorf("failed to get default network interface: %w", err) - } + c.entryMx.Lock() + defer c.entryMx.Unlock() + if c.conf.Type == ServiceTypeVisor && len(c.entry.LocalIPs) == 0 { + networkIfc, err := netutil.DefaultNetworkInterface() + if err != nil { + return fmt.Errorf("failed to get default network interface: %w", err) + } - localIPs, err := netutil.NetworkInterfaceIPs(networkIfc) - if err != nil { - return fmt.Errorf("failed to get IPs of %s: %w", networkIfc, err) - } + localIPs, err := netutil.NetworkInterfaceIPs(networkIfc) + if err != nil { + return fmt.Errorf("failed to get IPs of %s: %w", networkIfc, err) + } - c.entry.LocalIPs = make([]string, 0, len(localIPs)) - for _, ip := range localIPs { - c.entry.LocalIPs = append(c.entry.LocalIPs, ip.String()) - } + c.entry.LocalIPs = make([]string, 0, len(localIPs)) + for _, ip := range localIPs { + c.entry.LocalIPs = append(c.entry.LocalIPs, ip.String()) } } + c.entry.Addr = NewSWAddr(c.conf.PK, c.conf.Port) // Just in case. - auth, err := c.Auth(ctx) + entry, err := c.postEntry(ctx) if err != nil { return err } + c.entry = entry + return nil +} - c.entry.Addr = NewSWAddr(c.conf.PK, c.conf.Port) // Just in case. +// postEntry calls 'POST /api/services' and sends current service entry +// as the payload +func (c *HTTPClient) postEntry(ctx context.Context) (Service, error) { + auth, err := c.Auth(ctx) + if err != nil { + return Service{}, err + } raw, err := json.Marshal(&c.entry) if err != nil { - return err + return Service{}, err } req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.addr("/api/services", ""), bytes.NewReader(raw)) if err != nil { - return err + return Service{}, err } resp, err := auth.Do(req) if err != nil { - return err + return Service{}, err } if resp != nil { defer func() { @@ -187,26 +200,20 @@ func (c *HTTPClient) UpdateEntry(ctx context.Context) error { if resp.StatusCode != http.StatusOK { respBody, err := ioutil.ReadAll(resp.Body) if err != nil { - return fmt.Errorf("read response body: %w", err) + return Service{}, fmt.Errorf("read response body: %w", err) } var hErr HTTPResponse if err = json.Unmarshal(respBody, &hErr); err != nil { - return err + return Service{}, err } - return hErr.Error + return Service{}, hErr.Error } var entry Service err = json.NewDecoder(resp.Body).Decode(&entry) - if err != nil { - return err - } - c.entryMx.Lock() - c.entry = entry - c.entryMx.Unlock() - return err + return entry, err } // DeleteEntry calls 'DELETE /api/services/{entry_addr}'. From 10b8760fb711062164f75d3a7c24a70bd6a701c2 Mon Sep 17 00:00:00 2001 From: Never M Date: Tue, 27 Apr 2021 18:17:00 +0300 Subject: [PATCH 25/41] Add DefaultNetworkInterfaceIPs netutil function --- pkg/servicedisc/client.go | 14 ++++---------- pkg/util/netutil/net_linux.go | 14 ++++++++++++++ pkg/visor/api.go | 15 +++++---------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/pkg/servicedisc/client.go b/pkg/servicedisc/client.go index f48ed7caf7..d0c0524bf9 100644 --- a/pkg/servicedisc/client.go +++ b/pkg/servicedisc/client.go @@ -143,18 +143,12 @@ func (c *HTTPClient) UpdateEntry(ctx context.Context) error { c.entryMx.Lock() defer c.entryMx.Unlock() if c.conf.Type == ServiceTypeVisor && len(c.entry.LocalIPs) == 0 { - networkIfc, err := netutil.DefaultNetworkInterface() + ips, err := netutil.DefaultNetworkInterfaceIPs() if err != nil { - return fmt.Errorf("failed to get default network interface: %w", err) - } - - localIPs, err := netutil.NetworkInterfaceIPs(networkIfc) - if err != nil { - return fmt.Errorf("failed to get IPs of %s: %w", networkIfc, err) + return err } - - c.entry.LocalIPs = make([]string, 0, len(localIPs)) - for _, ip := range localIPs { + c.entry.LocalIPs = make([]string, 0, len(ips)) + for _, ip := range ips { c.entry.LocalIPs = append(c.entry.LocalIPs, ip.String()) } } diff --git a/pkg/util/netutil/net_linux.go b/pkg/util/netutil/net_linux.go index 55324a711b..5b770abdf1 100644 --- a/pkg/util/netutil/net_linux.go +++ b/pkg/util/netutil/net_linux.go @@ -5,6 +5,7 @@ package netutil import ( "bytes" "fmt" + "net" "os/exec" ) @@ -24,3 +25,16 @@ func DefaultNetworkInterface() (string, error) { return string(outputBytes), nil } + +// DefaultNetworkInterfaceIPs returns IP addresses for the default network interface +func DefaultNetworkInterfaceIPs() ([]net.IP, error) { + networkIfc, err := DefaultNetworkInterface() + if err != nil { + return nil, fmt.Errorf("failed to get default network interface: %w", err) + } + localIPs, err := NetworkInterfaceIPs(networkIfc) + if err != nil { + return nil, fmt.Errorf("failed to get IPs of %s: %w", networkIfc, err) + } + return localIPs, nil +} diff --git a/pkg/visor/api.go b/pkg/visor/api.go index cbe28e8cf2..4e01a73214 100644 --- a/pkg/visor/api.go +++ b/pkg/visor/api.go @@ -104,16 +104,6 @@ func (v *Visor) Summary() (*Summary, error) { return true }) - defaultNetworkIfc, err := netutil.DefaultNetworkInterface() - if err != nil { - return nil, fmt.Errorf("failed to get default network interface: %w", err) - } - - localIPs, err := netutil.NetworkInterfaceIPs(defaultNetworkIfc) - if err != nil { - return nil, fmt.Errorf("failed to get IPs of interface %s: %w", defaultNetworkIfc, err) - } - summary := &Summary{ PubKey: v.conf.PK, BuildInfo: buildinfo.Get(), @@ -123,6 +113,11 @@ func (v *Visor) Summary() (*Summary, error) { RoutesCount: v.router.RoutesCount(), } + localIPs, err := netutil.DefaultNetworkInterfaceIPs() + if err != nil { + return nil, err + } + if len(localIPs) > 0 { // should be okay to have the first one, in the case of // active network interface, there's usually just a single IP From a78aea406e0ba92185215fa51f6f205e49dd96b5 Mon Sep 17 00:00:00 2001 From: Never M Date: Wed, 28 Apr 2021 12:38:19 +0300 Subject: [PATCH 26/41] Update config for pulic visors --- pkg/visor/init.go | 2 +- pkg/visor/visor_test.go | 6 +++--- pkg/visor/visorconfig/parse.go | 2 ++ pkg/visor/visorconfig/v1.go | 22 +++++++++++++++------- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/pkg/visor/init.go b/pkg/visor/init.go index a0273fc6e7..43f48a1b9a 100644 --- a/pkg/visor/init.go +++ b/pkg/visor/init.go @@ -516,7 +516,7 @@ func initPublicVisors(v *Visor) bool { } discCl := servicedisc.NewClient(log, conf) - if v.conf.Launcher.Discovery.PublicVisorsEnabled { + if v.conf.Transport.AutoconnectPublic { go func() { time.Sleep(transport.PublicVisorsDelay * 2) diff --git a/pkg/visor/visor_test.go b/pkg/visor/visor_test.go index bd6e0027f7..72efe21101 100644 --- a/pkg/visor/visor_test.go +++ b/pkg/visor/visor_test.go @@ -65,6 +65,7 @@ func TestNewVisor(t *testing.T) { LogStore: &visorconfig.V1LogStore{ Type: visorconfig.MemoryLogStore, }, + AutoconnectPublic: false, }, Routing: &visorconfig.V1Routing{ SetupNodes: nil, @@ -79,9 +80,8 @@ func TestNewVisor(t *testing.T) { {Name: "bar", AutoStart: true, Port: 2}, }, Discovery: &visorconfig.V1AppDisc{ - UpdateInterval: 0, - ServiceDisc: "", - PublicVisorsEnabled: false, + UpdateInterval: 0, + ServiceDisc: "", }, }, } diff --git a/pkg/visor/visorconfig/parse.go b/pkg/visor/visorconfig/parse.go index d12350de32..1c915da06a 100644 --- a/pkg/visor/visorconfig/parse.go +++ b/pkg/visor/visorconfig/parse.go @@ -35,6 +35,8 @@ func Parse(log *logging.MasterLogger, path string, raw []byte) (*V1, error) { switch cc.Version { // parse any v1-compatible version with v1 parse procedure + case V111Name: + fallthrough case V110Name: fallthrough case V100Name: diff --git a/pkg/visor/visorconfig/v1.go b/pkg/visor/visorconfig/v1.go index 447867dc90..59ec1fdd9e 100644 --- a/pkg/visor/visorconfig/v1.go +++ b/pkg/visor/visorconfig/v1.go @@ -21,8 +21,15 @@ const V100Name = "v1.0.0" // Added MinHops field to V1Routing section of config const V110Name = "v1.1.0" +// V111Name is the semantic version string for v1.1.1. +// Removed public_trusted_visor field from root section +// Removed trusted_visors field from transport section +// Added is_public field to root section +// Added public_autoconnect field to transport section +const V111Name = "v1.1.1" + // V1Name is the semantic version string for the most recent version of V1. -const V1Name = V110Name +const V1Name = V111Name // V1 is visor config v1.0.0 type V1 struct { @@ -43,6 +50,7 @@ type V1 struct { LogLevel string `json:"log_level"` ShutdownTimeout Duration `json:"shutdown_timeout,omitempty"` // time value, examples: 10s, 1m, etc RestartCheckDelay Duration `json:"restart_check_delay,omitempty"` // time value, examples: 10s, 1m, etc + IsPublic bool `json:"is_public"` Hypervisor *hypervisorconfig.Config `json:"hypervisor,omitempty"` } @@ -57,9 +65,10 @@ type V1Dmsgpty struct { // V1Transport defines a transport config. type V1Transport struct { - Discovery string `json:"discovery"` - AddressResolver string `json:"address_resolver"` - LogStore *V1LogStore `json:"log_store"` + Discovery string `json:"discovery"` + AddressResolver string `json:"address_resolver"` + LogStore *V1LogStore `json:"log_store"` + AutoconnectPublic bool `json:"public_autoconnect"` } // V1LogStore configures a LogStore. @@ -84,9 +93,8 @@ type V1UptimeTracker struct { // V1AppDisc configures Skywire App Discovery Clients. type V1AppDisc struct { - UpdateInterval Duration `json:"update_interval,omitempty"` - ServiceDisc string `json:"proxy_discovery_addr"` // TODO: change JSON name - PublicVisorsEnabled bool `json:"connect_to_public_visors"` // TODO: change JSON name + UpdateInterval Duration `json:"update_interval,omitempty"` + ServiceDisc string `json:"proxy_discovery_addr"` // TODO: change JSON name } // V1Launcher configures the app launcher. From 0055a0c2b03641bb7ff74fba206589b540e10578 Mon Sep 17 00:00:00 2001 From: Never M Date: Wed, 28 Apr 2021 13:04:15 +0300 Subject: [PATCH 27/41] Add IsPublicIp function to netutil --- pkg/util/netutil/net.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/pkg/util/netutil/net.go b/pkg/util/netutil/net.go index 18f5cd4d61..5d046f5d94 100644 --- a/pkg/util/netutil/net.go +++ b/pkg/util/netutil/net.go @@ -69,3 +69,24 @@ func localNetworkInterfaceIPs(ifcName string) ([]net.IP, []net.IP, error) { return ips, ifcIPs, nil } + +// IsPublicIP returns true if the provided IP is public. +// Obtained from: https://stackoverflow.com/questions/41670155/get-public-ip-in-golang +func IsPublicIP(IP net.IP) bool { + if IP.IsLoopback() || IP.IsLinkLocalMulticast() || IP.IsLinkLocalUnicast() { + return false + } + if ip4 := IP.To4(); ip4 != nil { + switch { + case ip4[0] == 10: + return false + case ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31: + return false + case ip4[0] == 192 && ip4[1] == 168: + return false + default: + return true + } + } + return false +} From 25b7ca00917daf19e71a78348c73350bf3828591 Mon Sep 17 00:00:00 2001 From: Never M Date: Wed, 28 Apr 2021 13:33:42 +0300 Subject: [PATCH 28/41] Check is_public field for self advertising --- pkg/snet/network.go | 24 +++++++++++++++++++++++- pkg/visor/init.go | 1 + 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/pkg/snet/network.go b/pkg/snet/network.go index 887ae8e39e..0af9044acb 100644 --- a/pkg/snet/network.go +++ b/pkg/snet/network.go @@ -21,6 +21,7 @@ import ( "github.com/skycoin/skywire/pkg/snet/directtp" "github.com/skycoin/skywire/pkg/snet/directtp/pktable" "github.com/skycoin/skywire/pkg/snet/directtp/tptypes" + "github.com/skycoin/skywire/pkg/util/netutil" ) var log = logging.MustGetLogger("snet") @@ -76,6 +77,7 @@ type Config struct { ARClient arclient.APIClient NetworkConfigs NetworkConfigs ServiceDisc appdisc.Factory + IsPublic bool } // NetworkConfigs represents all network configs. @@ -225,7 +227,6 @@ func (n *Network) Init() error { if err := client.Serve(); err != nil { return fmt.Errorf("failed to initiate 'stcpr': %w", err) } - go n.registerAsPublic(client) } else { log.Infof("No config found for stcpr") @@ -243,7 +244,28 @@ func (n *Network) Init() error { return nil } +func (n *Network) shouldRegisterAsPublic() bool { + if !n.conf.IsPublic { + return false + } + defaultIPs, err := netutil.DefaultNetworkInterfaceIPs() + if err != nil { + return false + } + for _, IP := range defaultIPs { + if netutil.IsPublicIP(IP) { + return true + } + } + return false +} + func (n *Network) registerAsPublic(client directtp.Client) { + // check involves getting some OS information which migh take non-zero time, + // so moved in this function that runs in its own goroutine + if !n.shouldRegisterAsPublic() { + return + } log.Infoln("Trying to register visor as public") la, err := client.LocalAddr() diff --git a/pkg/visor/init.go b/pkg/visor/init.go index 43f48a1b9a..686349552f 100644 --- a/pkg/visor/init.go +++ b/pkg/visor/init.go @@ -97,6 +97,7 @@ func initSNet(v *Visor) bool { ARClient: v.arClient, NetworkConfigs: nc, ServiceDisc: v.serviceDisc, + IsPublic: v.conf.IsPublic, } n, err := snet.New(conf, v.ebc) From 380ad3908235f984413780b3e5b23bd6ccc7a756 Mon Sep 17 00:00:00 2001 From: Never M Date: Wed, 28 Apr 2021 16:33:53 +0300 Subject: [PATCH 29/41] Move public visor connection to autoconnector --- pkg/servicedisc/autoconnect.go | 64 ++++++++++++++++++++++++++++++++++ pkg/transport/manager.go | 5 --- pkg/visor/init.go | 58 +++++++++++++----------------- 3 files changed, 88 insertions(+), 39 deletions(-) create mode 100644 pkg/servicedisc/autoconnect.go diff --git a/pkg/servicedisc/autoconnect.go b/pkg/servicedisc/autoconnect.go new file mode 100644 index 0000000000..6144c84651 --- /dev/null +++ b/pkg/servicedisc/autoconnect.go @@ -0,0 +1,64 @@ +package servicedisc + +import ( + "context" + "time" + + "github.com/skycoin/dmsg/cipher" + "github.com/skycoin/skycoin/src/util/logging" +) + +const ( + // PublicServiceDelay defines a delay before adding transports to public services. + PublicServiceDelay = 5 * time.Second +) + +// ConnectFn provides a way to connect to remote service +type ConnectFn func(context.Context, cipher.PubKey) error + +// Autoconnector continuously tries to connect to services +type Autoconnector interface { + Run(context.Context, ConnectFn) error +} + +type autoconnector struct { + client *HTTPClient + maxConns int + log *logging.Logger +} + +// MakeConnector returns a new connector that will try to connect to at most maxConns +// services +func MakeConnector(conf Config, maxConns int, log *logging.Logger) Autoconnector { + connector := &autoconnector{} + connector.client = NewClient(log, conf) + connector.maxConns = maxConns + connector.log = log + return connector +} + +// Run implements Autoconnector interface +func (a *autoconnector) Run(ctx context.Context, connector ConnectFn) error { + for { + time.Sleep(PublicServiceDelay * 2) + + services, err := a.client.Services(ctx, a.maxConns) + if err != nil { + a.log.WithError(err).Errorln("Failed to fetch services") + return err + } + + for _, service := range services { + pk := service.Addr.PubKey() + err := connector(ctx, pk) + if err != nil { + // ignore for now? + } + } + + if len(services) == 0 { + a.log.Println("no public services found") + } + } + +} diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index 89f3140225..074d32ea80 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -21,11 +21,6 @@ import ( "github.com/skycoin/skywire/pkg/snet/snettest" ) -const ( - // PublicVisorsDelay defines a delay before adding transports to public visors. - PublicVisorsDelay = 5 * time.Second -) - // TPCloseCallback triggers after a session is closed. type TPCloseCallback func(network, addr string) diff --git a/pkg/visor/init.go b/pkg/visor/init.go index 686349552f..79a5c86018 100644 --- a/pkg/visor/init.go +++ b/pkg/visor/init.go @@ -489,8 +489,10 @@ func initUptimeTracker(v *Visor) bool { } func initPublicVisors(v *Visor) bool { - const tpType = tptypes.STCPR - + if !v.conf.Transport.AutoconnectPublic { + return true + } + log := v.MasterLogger().PackageLogger("public_visors") proxyDisc := v.conf.Launcher.Discovery.ServiceDisc if proxyDisc == "" { proxyDisc = skyenv.DefaultServiceDiscAddr @@ -498,13 +500,13 @@ func initPublicVisors(v *Visor) bool { _, portStr, err := net.SplitHostPort(v.conf.STCP.LocalAddr) if err != nil { - v.log.WithError(err).Errorln("Failed to parse address string") + log.WithError(err).Errorln("Failed to parse address string") return false } port, err := strconv.Atoi(portStr) if err != nil { - v.log.WithError(err).Errorln("Failed to parse port") + log.WithError(err).Errorln("Failed to parse port") return false } @@ -515,36 +517,24 @@ func initPublicVisors(v *Visor) bool { Port: uint16(port), DiscAddr: proxyDisc, } - discCl := servicedisc.NewClient(log, conf) - - if v.conf.Transport.AutoconnectPublic { - go func() { - time.Sleep(transport.PublicVisorsDelay * 2) - - visors, err := discCl.Services(context.Background(), 5) - if err != nil { - log.WithError(err).Errorln("Failed to fetch public visors") - return - } - - for _, visor := range visors { - pk := visor.Addr.PubKey() - v.log.WithField("pk", pk).Infoln("Adding transport to public visor") - if _, err := v.tpM.SaveTransport(context.Background(), pk, tpType); err != nil { - v.log. - WithError(err). - WithField("pk", pk). - WithField("type", tpType). - Warnln("Failed to add transport to public visor via") - } else { - v.log. - WithField("pk", pk). - WithField("type", tpType). - Infoln("Added transport to public visor") - } - } - }() - } + connectFn := servicedisc.ConnectFn(func(ctx context.Context, pk cipher.PubKey) error { + log.WithField("pk", pk).Infoln("Adding transport to public visor") + if _, err := v.tpM.SaveTransport(ctx, pk, tptypes.STCPR); err != nil { + log. + WithError(err). + WithField("pk", pk). + WithField("type", tptypes.STCPR). + Warnln("Failed to add transport to public visor via") + return err + } + log. + WithField("pk", pk). + WithField("type", tptypes.STCPR). + Infoln("Added transport to public visor") + return nil + }) + connector := servicedisc.MakeConnector(conf, 5, log) + go connector.Run(context.Background(), connectFn) return true } From cc98efa3f6dc97c5f58591f61cfd998d8d5de5ed Mon Sep 17 00:00:00 2001 From: Never M Date: Wed, 28 Apr 2021 16:59:07 +0300 Subject: [PATCH 30/41] Keep track of the connected services --- pkg/servicedisc/autoconnect.go | 37 +++++++++++++++++++++++++++------- pkg/transport/manager.go | 13 ++++++++++++ pkg/visor/init.go | 8 +++++++- 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/pkg/servicedisc/autoconnect.go b/pkg/servicedisc/autoconnect.go index 6144c84651..d0628dabae 100644 --- a/pkg/servicedisc/autoconnect.go +++ b/pkg/servicedisc/autoconnect.go @@ -16,15 +16,19 @@ const ( // ConnectFn provides a way to connect to remote service type ConnectFn func(context.Context, cipher.PubKey) error +// CheckConnFN checks that connection is alive +type CheckConnFN func(cipher.PubKey) bool + // Autoconnector continuously tries to connect to services type Autoconnector interface { - Run(context.Context, ConnectFn) error + Run(context.Context, ConnectFn, CheckConnFN) error } type autoconnector struct { client *HTTPClient maxConns int log *logging.Logger + conns map[cipher.PubKey]struct{} } // MakeConnector returns a new connector that will try to connect to at most maxConns @@ -34,31 +38,50 @@ func MakeConnector(conf Config, maxConns int, log *logging.Logger) Autoconnector connector.client = NewClient(log, conf) connector.maxConns = maxConns connector.log = log + connector.conns = make(map[cipher.PubKey]struct{}) return connector } // Run implements Autoconnector interface -func (a *autoconnector) Run(ctx context.Context, connector ConnectFn) error { +func (a *autoconnector) Run(ctx context.Context, connector ConnectFn, checker CheckConnFN) error { for { time.Sleep(PublicServiceDelay * 2) - + a.checkConns(checker) + if len(a.conns) == a.maxConns { + continue + } services, err := a.client.Services(ctx, a.maxConns) if err != nil { + // todo: exponential backoff a.log.WithError(err).Errorln("Failed to fetch services") - return err + continue } for _, service := range services { pk := service.Addr.PubKey() + if _, ok := a.conns[pk]; ok { + continue + } err := connector(ctx, pk) if err != nil { // ignore for now? + } else { + a.conns[pk] = struct{}{} } } + } +} - if len(services) == 0 { - a.log.Println("no public services found") +// check if existing connections are still active using checker +// and delete those that are not +func (a *autoconnector) checkConns(checker CheckConnFN) { + toDelete := make([]cipher.PubKey, 0) + for pk := range a.conns { + if !checker(pk) { + toDelete = append(toDelete, pk) } } - + for _, pk := range toDelete { + delete(a.conns, pk) + } } diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index 074d32ea80..92ab0c9e60 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -253,6 +253,19 @@ func (tm *Manager) acceptTransport(ctx context.Context, lis *snet.Listener) erro return nil } +// HasTransport checks if given transport is present in the manager +func (tm *Manager) HasTransport(remote cipher.PubKey, tpType string) (bool, error) { + tm.mx.RLock() + defer tm.mx.RUnlock() + if !snet.IsKnownNetwork(tpType) { + return false, snet.ErrUnknownNetwork + } + + tpID := tm.tpIDFromPK(remote, tpType) + _, ok := tm.tps[tpID] + return ok, nil +} + // SaveTransport begins to attempt to establish data transports to the given 'remote' visor. func (tm *Manager) SaveTransport(ctx context.Context, remote cipher.PubKey, tpType string) (*ManagedTransport, error) { diff --git a/pkg/visor/init.go b/pkg/visor/init.go index 79a5c86018..45aced0602 100644 --- a/pkg/visor/init.go +++ b/pkg/visor/init.go @@ -533,8 +533,14 @@ func initPublicVisors(v *Visor) bool { Infoln("Added transport to public visor") return nil }) + // check will use transport manager to check if transport exists + // todo: check if it's possible for a transport to exist but be broken + checkFN := servicedisc.CheckConnFN(func(pk cipher.PubKey) bool { + ok, _ := v.tpM.HasTransport(pk, tptypes.STCPR) //nolint:errcheck + return ok + }) connector := servicedisc.MakeConnector(conf, 5, log) - go connector.Run(context.Background(), connectFn) + go connector.Run(context.Background(), connectFn, checkFN) return true } From a24fd9c94eb9b6a7a2d8e48b3f86d9050588dd72 Mon Sep 17 00:00:00 2001 From: Never M Date: Wed, 28 Apr 2021 17:08:32 +0300 Subject: [PATCH 31/41] Add exponential backoff for fetching services --- pkg/servicedisc/autoconnect.go | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/pkg/servicedisc/autoconnect.go b/pkg/servicedisc/autoconnect.go index d0628dabae..f5ced3e6bf 100644 --- a/pkg/servicedisc/autoconnect.go +++ b/pkg/servicedisc/autoconnect.go @@ -6,11 +6,14 @@ import ( "github.com/skycoin/dmsg/cipher" "github.com/skycoin/skycoin/src/util/logging" + "github.com/skycoin/skywire/internal/netutil" ) const ( // PublicServiceDelay defines a delay before adding transports to public services. PublicServiceDelay = 5 * time.Second + + fetchServicesDelay = 2 * time.Second ) // ConnectFn provides a way to connect to remote service @@ -44,18 +47,23 @@ func MakeConnector(conf Config, maxConns int, log *logging.Logger) Autoconnector // Run implements Autoconnector interface func (a *autoconnector) Run(ctx context.Context, connector ConnectFn, checker CheckConnFN) error { + retrier := netutil.NewRetrier(fetchServicesDelay, 0, 2) for { time.Sleep(PublicServiceDelay * 2) a.checkConns(checker) if len(a.conns) == a.maxConns { continue } - services, err := a.client.Services(ctx, a.maxConns) - if err != nil { - // todo: exponential backoff - a.log.WithError(err).Errorln("Failed to fetch services") - continue + var services []Service + fetch := func() (err error) { + // "return" services up from the closure + services, err = a.client.Services(ctx, a.maxConns) + if err != nil { + return err + } + return nil } + retrier.Do(fetch) for _, service := range services { pk := service.Addr.PubKey() From 31498e0bb54938e30532ba098586a8d723c82163 Mon Sep 17 00:00:00 2001 From: Never M Date: Thu, 29 Apr 2021 12:36:07 +0300 Subject: [PATCH 32/41] Fix lint errors --- pkg/servicedisc/autoconnect.go | 6 +++++- pkg/visor/init.go | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkg/servicedisc/autoconnect.go b/pkg/servicedisc/autoconnect.go index f5ced3e6bf..5df20b737e 100644 --- a/pkg/servicedisc/autoconnect.go +++ b/pkg/servicedisc/autoconnect.go @@ -6,6 +6,7 @@ import ( "github.com/skycoin/dmsg/cipher" "github.com/skycoin/skycoin/src/util/logging" + "github.com/skycoin/skywire/internal/netutil" ) @@ -63,7 +64,10 @@ func (a *autoconnector) Run(ctx context.Context, connector ConnectFn, checker Ch } return nil } - retrier.Do(fetch) + if err := retrier.Do(fetch); err != nil { + a.log.Errorf("Cannot fetch services: %s", err) + return err + } for _, service := range services { pk := service.Addr.PubKey() diff --git a/pkg/visor/init.go b/pkg/visor/init.go index 45aced0602..a10a73158d 100644 --- a/pkg/visor/init.go +++ b/pkg/visor/init.go @@ -540,7 +540,7 @@ func initPublicVisors(v *Visor) bool { return ok }) connector := servicedisc.MakeConnector(conf, 5, log) - go connector.Run(context.Background(), connectFn, checkFN) + go connector.Run(context.Background(), connectFn, checkFN) //nolint:errcheck return true } From 443e8f53ed6723bc05bf645fb514605bec7dddd0 Mon Sep 17 00:00:00 2001 From: Never M Date: Wed, 5 May 2021 17:15:12 +0300 Subject: [PATCH 33/41] Check if transport is up --- Char | 0 pkg/transport/manager.go | 13 ++++++++----- pkg/visor/init.go | 11 +++++++++-- 3 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 Char diff --git a/Char b/Char new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index 92ab0c9e60..07466b7b7a 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -253,17 +253,20 @@ func (tm *Manager) acceptTransport(ctx context.Context, lis *snet.Listener) erro return nil } -// HasTransport checks if given transport is present in the manager -func (tm *Manager) HasTransport(remote cipher.PubKey, tpType string) (bool, error) { +// GetTransport gets transport entity to the given remote +func (tm *Manager) GetTransport(remote cipher.PubKey, tpType string) (*ManagedTransport, error) { tm.mx.RLock() defer tm.mx.RUnlock() if !snet.IsKnownNetwork(tpType) { - return false, snet.ErrUnknownNetwork + return nil, snet.ErrUnknownNetwork } tpID := tm.tpIDFromPK(remote, tpType) - _, ok := tm.tps[tpID] - return ok, nil + t, ok := tm.tps[tpID] + if !ok { + return nil, fmt.Errorf("transport to %s of type %s not found", remote, tpType) + } + return t, nil } // SaveTransport begins to attempt to establish data transports to the given 'remote' visor. diff --git a/pkg/visor/init.go b/pkg/visor/init.go index a10a73158d..be89ac42e5 100644 --- a/pkg/visor/init.go +++ b/pkg/visor/init.go @@ -536,8 +536,15 @@ func initPublicVisors(v *Visor) bool { // check will use transport manager to check if transport exists // todo: check if it's possible for a transport to exist but be broken checkFN := servicedisc.CheckConnFN(func(pk cipher.PubKey) bool { - ok, _ := v.tpM.HasTransport(pk, tptypes.STCPR) //nolint:errcheck - return ok + t, err := v.tpM.GetTransport(pk, tptypes.STCPR) + if err != nil { + return false + } + up := t.IsUp() + if !up { + v.tpM.DeleteTransport(t.Entry.ID) + } + return up }) connector := servicedisc.MakeConnector(conf, 5, log) go connector.Run(context.Background(), connectFn, checkFN) //nolint:errcheck From 263a27a750670e9fabd228127b841ac6487cad88 Mon Sep 17 00:00:00 2001 From: Never M Date: Fri, 7 May 2021 16:52:28 +0300 Subject: [PATCH 34/41] Add codereview fixes: todos, error handling --- pkg/servicedisc/autoconnect.go | 6 +++--- pkg/servicedisc/types.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/servicedisc/autoconnect.go b/pkg/servicedisc/autoconnect.go index 5df20b737e..6500a14fd8 100644 --- a/pkg/servicedisc/autoconnect.go +++ b/pkg/servicedisc/autoconnect.go @@ -12,7 +12,7 @@ import ( const ( // PublicServiceDelay defines a delay before adding transports to public services. - PublicServiceDelay = 5 * time.Second + PublicServiceDelay = 10 * time.Second fetchServicesDelay = 2 * time.Second ) @@ -50,7 +50,7 @@ func MakeConnector(conf Config, maxConns int, log *logging.Logger) Autoconnector func (a *autoconnector) Run(ctx context.Context, connector ConnectFn, checker CheckConnFN) error { retrier := netutil.NewRetrier(fetchServicesDelay, 0, 2) for { - time.Sleep(PublicServiceDelay * 2) + time.Sleep(PublicServiceDelay) a.checkConns(checker) if len(a.conns) == a.maxConns { continue @@ -76,7 +76,7 @@ func (a *autoconnector) Run(ctx context.Context, connector ConnectFn, checker Ch } err := connector(ctx, pk) if err != nil { - // ignore for now? + a.log.WithField("remote_pk", pk).Warnf("Cannot connect to a service") } else { a.conns[pk] = struct{}{} } diff --git a/pkg/servicedisc/types.go b/pkg/servicedisc/types.go index 00dd8b055b..ab838d4c93 100644 --- a/pkg/servicedisc/types.go +++ b/pkg/servicedisc/types.go @@ -106,7 +106,7 @@ type Stats struct { type Service struct { Addr SWAddr `json:"address"` Type string `json:"type"` - Stats *Stats `json:"stats,omitempty"` // TODO: Have this implemented. + Stats *Stats `json:"stats,omitempty"` Geo *GeoLocation `json:"geo,omitempty"` Version string `json:"version,omitempty"` LocalIPs []string `json:"local_ips,omitempty"` From a90627e893c230d35134f540156d07027379a66d Mon Sep 17 00:00:00 2001 From: Never M Date: Tue, 11 May 2021 14:36:41 +0300 Subject: [PATCH 35/41] Refactor URL construction --- pkg/servicedisc/client.go | 56 +++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/pkg/servicedisc/client.go b/pkg/servicedisc/client.go index d0c0524bf9..553bc7a622 100644 --- a/pkg/servicedisc/client.go +++ b/pkg/servicedisc/client.go @@ -8,6 +8,7 @@ import ( "fmt" "io/ioutil" "net/http" + "net/url" "strconv" "sync" "time" @@ -21,10 +22,13 @@ import ( "github.com/skycoin/skywire/pkg/util/netutil" ) -var ( - // ErrVisorUnreachable is returned when visor is unreachable. - ErrVisorUnreachable = errors.New("visor is unreachable") - updateRetryDelay = 5 * time.Second +// ErrVisorUnreachable is returned when visor is not reachable +var ErrVisorUnreachable = errors.New("visor is unreachable") + +const ( + updateRetryDelay = 5 * time.Second + discServiceTypeParam = "type" + discServiceQtyParam = "quantity" ) // Config configures the HTTPClient. @@ -65,14 +69,22 @@ func NewClient(log logrus.FieldLogger, conf Config) *HTTPClient { } } -func (c *HTTPClient) addr(path string, sType string) string { - addr := c.conf.DiscAddr + path - - if sType != "" { - addr += "?type=" + sType +func (c *HTTPClient) addr(path, serviceType string, quantity int) (string, error) { + addr := c.conf.DiscAddr + url, err := url.Parse(addr) + if err != nil { + return "", errors.New("invalid service discovery address in config: " + addr) } - - return addr + url.Path = path + q := url.Query() + if serviceType != "" { + q.Set(discServiceTypeParam, serviceType) + } + if quantity > 1 { + q.Set(discServiceQtyParam, strconv.Itoa(quantity)) + } + url.RawQuery = q.Encode() + return url.String(), nil } var ( @@ -102,11 +114,11 @@ func (c *HTTPClient) Auth(ctx context.Context) (*httpauth.Client, error) { // Services calls 'GET /api/services'. func (c *HTTPClient) Services(ctx context.Context, quantity int) (out []Service, err error) { - addr := c.addr("/api/services", c.entry.Type) - if quantity != 0 { - addr += "&quantity=" + strconv.Itoa(quantity) + url, err := c.addr("/api/services", c.entry.Type, quantity) + if err != nil { + return nil, err } - req, err := http.NewRequestWithContext(ctx, http.MethodGet, addr, nil) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { return nil, err } @@ -170,11 +182,16 @@ func (c *HTTPClient) postEntry(ctx context.Context) (Service, error) { return Service{}, err } + url, err := c.addr("/api/services", "", 1) + if err != nil { + return Service{}, nil + } + raw, err := json.Marshal(&c.entry) if err != nil { return Service{}, err } - req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.addr("/api/services", ""), bytes.NewReader(raw)) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(raw)) if err != nil { return Service{}, err } @@ -217,7 +234,12 @@ func (c *HTTPClient) DeleteEntry(ctx context.Context) (err error) { return err } - req, err := http.NewRequestWithContext(ctx, http.MethodDelete, c.addr("/api/services/"+c.entry.Addr.String(), c.entry.Type), nil) + url, err := c.addr("/api/services/"+c.entry.Addr.String(), c.entry.Type, 1) + if err != nil { + return err + } + + req, err := http.NewRequestWithContext(ctx, http.MethodDelete, url, nil) if err != nil { return err } From 397448943aab13916719e04ad51c043ecdc7baca Mon Sep 17 00:00:00 2001 From: Never M Date: Tue, 11 May 2021 17:11:55 +0300 Subject: [PATCH 36/41] Add app disc refactoring todo --- pkg/visor/init.go | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/pkg/visor/init.go b/pkg/visor/init.go index be89ac42e5..5f5a225d1d 100644 --- a/pkg/visor/init.go +++ b/pkg/visor/init.go @@ -6,7 +6,6 @@ import ( "fmt" "net" "net/http" - "strconv" "sync" "time" @@ -498,25 +497,19 @@ func initPublicVisors(v *Visor) bool { proxyDisc = skyenv.DefaultServiceDiscAddr } - _, portStr, err := net.SplitHostPort(v.conf.STCP.LocalAddr) - if err != nil { - log.WithError(err).Errorln("Failed to parse address string") - return false - } - - port, err := strconv.Atoi(portStr) - if err != nil { - log.WithError(err).Errorln("Failed to parse port") - return false - } - + // todo: refactor appdisc: split connecting to services in appdisc and + // advertising oneself as a service. Currently, config is tailored to + // advertising oneself and requires things like port that are not used + // in connecting to services conf := servicedisc.Config{ Type: servicedisc.ServiceTypeVisor, PK: v.conf.PK, SK: v.conf.SK, - Port: uint16(port), + Port: uint16(0), DiscAddr: proxyDisc, } + // todo: refactor snet and app discovery in such a way that app discovery can make use of + // of transport directly, and avoid using callbacks connectFn := servicedisc.ConnectFn(func(ctx context.Context, pk cipher.PubKey) error { log.WithField("pk", pk).Infoln("Adding transport to public visor") if _, err := v.tpM.SaveTransport(ctx, pk, tptypes.STCPR); err != nil { @@ -533,8 +526,6 @@ func initPublicVisors(v *Visor) bool { Infoln("Added transport to public visor") return nil }) - // check will use transport manager to check if transport exists - // todo: check if it's possible for a transport to exist but be broken checkFN := servicedisc.CheckConnFN(func(pk cipher.PubKey) bool { t, err := v.tpM.GetTransport(pk, tptypes.STCPR) if err != nil { From b29358806fa888642873208093f9a708386c2c97 Mon Sep 17 00:00:00 2001 From: Never M Date: Tue, 11 May 2021 17:50:47 +0300 Subject: [PATCH 37/41] Take visor self-advertising out of snet package --- pkg/servicedisc/autoconnect.go | 5 +- pkg/snet/network.go | 84 ++++++---------------------------- pkg/visor/init.go | 60 ++++++++++++++++++++++-- 3 files changed, 76 insertions(+), 73 deletions(-) diff --git a/pkg/servicedisc/autoconnect.go b/pkg/servicedisc/autoconnect.go index 6500a14fd8..4f751d1137 100644 --- a/pkg/servicedisc/autoconnect.go +++ b/pkg/servicedisc/autoconnect.go @@ -8,6 +8,7 @@ import ( "github.com/skycoin/skycoin/src/util/logging" "github.com/skycoin/skywire/internal/netutil" + "github.com/skycoin/skywire/pkg/transport" ) const ( @@ -33,16 +34,18 @@ type autoconnector struct { maxConns int log *logging.Logger conns map[cipher.PubKey]struct{} + tm *transport.Manager } // MakeConnector returns a new connector that will try to connect to at most maxConns // services -func MakeConnector(conf Config, maxConns int, log *logging.Logger) Autoconnector { +func MakeConnector(conf Config, maxConns int, tm *transport.Manager, log *logging.Logger) Autoconnector { connector := &autoconnector{} connector.client = NewClient(log, conf) connector.maxConns = maxConns connector.log = log connector.conns = make(map[cipher.PubKey]struct{}) + connector.tm = tm return connector } diff --git a/pkg/snet/network.go b/pkg/snet/network.go index 0af9044acb..33d5dd07b4 100644 --- a/pkg/snet/network.go +++ b/pkg/snet/network.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "net" - "strconv" "strings" "sync" "time" @@ -15,13 +14,11 @@ import ( "github.com/skycoin/dmsg/disc" "github.com/skycoin/skycoin/src/util/logging" - "github.com/skycoin/skywire/pkg/app/appdisc" "github.com/skycoin/skywire/pkg/app/appevent" "github.com/skycoin/skywire/pkg/snet/arclient" "github.com/skycoin/skywire/pkg/snet/directtp" "github.com/skycoin/skywire/pkg/snet/directtp/pktable" "github.com/skycoin/skywire/pkg/snet/directtp/tptypes" - "github.com/skycoin/skywire/pkg/util/netutil" ) var log = logging.MustGetLogger("snet") @@ -76,8 +73,6 @@ type Config struct { SecKey cipher.SecKey ARClient arclient.APIClient NetworkConfigs NetworkConfigs - ServiceDisc appdisc.Factory - IsPublic bool } // NetworkConfigs represents all network configs. @@ -94,11 +89,10 @@ type NetworkClients struct { // Network represents a network between nodes in Skywire. type Network struct { - conf Config - netsMu sync.RWMutex - nets map[string]struct{} // networks to be used with transports - clients NetworkClients - visorUpdater appdisc.Updater + conf Config + netsMu sync.RWMutex + nets map[string]struct{} // networks to be used with transports + clients NetworkClients onNewNetworkTypeMu sync.Mutex onNewNetworkType func(netType string) @@ -227,7 +221,6 @@ func (n *Network) Init() error { if err := client.Serve(); err != nil { return fmt.Errorf("failed to initiate 'stcpr': %w", err) } - go n.registerAsPublic(client) } else { log.Infof("No config found for stcpr") } @@ -244,54 +237,6 @@ func (n *Network) Init() error { return nil } -func (n *Network) shouldRegisterAsPublic() bool { - if !n.conf.IsPublic { - return false - } - defaultIPs, err := netutil.DefaultNetworkInterfaceIPs() - if err != nil { - return false - } - for _, IP := range defaultIPs { - if netutil.IsPublicIP(IP) { - return true - } - } - return false -} - -func (n *Network) registerAsPublic(client directtp.Client) { - // check involves getting some OS information which migh take non-zero time, - // so moved in this function that runs in its own goroutine - if !n.shouldRegisterAsPublic() { - return - } - log.Infoln("Trying to register visor as public") - - la, err := client.LocalAddr() - if err != nil { - log.WithError(err).Errorln("Failed to get STCPR local addr") - return - } - - _, portStr, err := net.SplitHostPort(la.String()) - if err != nil { - log.WithError(err).Errorf("Failed to extract port from addr %v", la.String()) - return - } - - port, err := strconv.Atoi(portStr) - if err != nil { - log.WithError(err).Errorf("Failed to convert port to int") - return - } - - n.visorUpdater = n.conf.ServiceDisc.VisorUpdater(uint16(port)) - n.visorUpdater.Start() - - log.Infof("Sent request to register visor as public") -} - // OnNewNetworkType sets callback to be called when new network type is ready. func (n *Network) OnNewNetworkType(callback func(netType string)) { n.onNewNetworkTypeMu.Lock() @@ -312,10 +257,6 @@ func (n *Network) Close() error { n.netsMu.Lock() defer n.netsMu.Unlock() - if n.visorUpdater != nil { - n.visorUpdater.Stop() - } - wg := new(sync.WaitGroup) var dmsgErr error @@ -382,18 +323,23 @@ func (n *Network) TransportNetworks() []string { func (n *Network) Dmsg() *dmsg.Client { return n.clients.DmsgC } // STcp returns the underlying stcp.Client. -func (n *Network) STcp() directtp.Client { - return n.clients.Direct[tptypes.STCP] +func (n *Network) STcp() (directtp.Client, bool) { + return n.getClient(tptypes.STCP) } // STcpr returns the underlying stcpr.Client. -func (n *Network) STcpr() directtp.Client { - return n.clients.Direct[tptypes.STCPR] +func (n *Network) STcpr() (directtp.Client, bool) { + return n.getClient(tptypes.STCPR) } // SUdpH returns the underlying sudph.Client. -func (n *Network) SUdpH() directtp.Client { - return n.clients.Direct[tptypes.SUDPH] +func (n *Network) SUdpH() (directtp.Client, bool) { + return n.getClient(tptypes.SUDPH) +} + +func (n *Network) getClient(tpType string) (directtp.Client, bool) { + c, ok := n.clients.Direct[tpType] + return c, ok } // Dial dials a visor by its public key and returns a connection. diff --git a/pkg/visor/init.go b/pkg/visor/init.go index 5f5a225d1d..43403410f4 100644 --- a/pkg/visor/init.go +++ b/pkg/visor/init.go @@ -6,6 +6,7 @@ import ( "fmt" "net" "net/http" + "strconv" "sync" "time" @@ -32,6 +33,7 @@ import ( "github.com/skycoin/skywire/pkg/snet/directtp/tptypes" "github.com/skycoin/skywire/pkg/transport" "github.com/skycoin/skywire/pkg/transport/tpdclient" + "github.com/skycoin/skywire/pkg/util/netutil" "github.com/skycoin/skywire/pkg/util/updater" "github.com/skycoin/skywire/pkg/visor/hypervisorconfig" "github.com/skycoin/skywire/pkg/visor/visorconfig" @@ -46,6 +48,7 @@ func initStack() []initFunc { initAddressResolver, initDiscovery, initSNet, + initPublicVisor, initDmsgpty, initTransport, initRouter, @@ -95,8 +98,6 @@ func initSNet(v *Visor) bool { SecKey: v.conf.SK, ARClient: v.arClient, NetworkConfigs: nc, - ServiceDisc: v.serviceDisc, - IsPublic: v.conf.IsPublic, } n, err := snet.New(conf, v.ebc) @@ -139,6 +140,59 @@ func initSNet(v *Visor) bool { return report(nil) } +// this service is not considered critical and always returns true +// advertise this visor as public in service discovery +func initPublicVisor(v *Visor) bool { + if !v.conf.IsPublic { + return true + } + if v.arClient == nil { + return true + } + defaultIPs, err := netutil.DefaultNetworkInterfaceIPs() + if err != nil { + return true + } + for _, IP := range defaultIPs { + if netutil.IsPublicIP(IP) { + return true + } + } + + stcpr, ok := v.net.STcpr() + if !ok { + return true + } + + la, err := stcpr.LocalAddr() + if err != nil { + log.WithError(err).Errorln("Failed to get STCPR local addr") + return true + } + + _, portStr, err := net.SplitHostPort(la.String()) + if err != nil { + log.WithError(err).Errorf("Failed to extract port from addr %v", la.String()) + return true + } + + port, err := strconv.Atoi(portStr) + if err != nil { + log.WithError(err).Errorf("Failed to convert port to int") + return true + } + + visorUpdater := v.serviceDisc.VisorUpdater(uint16(port)) + visorUpdater.Start() + + v.log.Infof("Sent request to register visor as public") + v.pushCloseStack("visor updater", func() bool { + visorUpdater.Stop() + return true + }) + return true +} + func initAddressResolver(v *Visor) bool { report := v.makeReporter("address-resolver") conf := v.conf.Transport @@ -537,7 +591,7 @@ func initPublicVisors(v *Visor) bool { } return up }) - connector := servicedisc.MakeConnector(conf, 5, log) + connector := servicedisc.MakeConnector(conf, 5, v.tpM, log) go connector.Run(context.Background(), connectFn, checkFN) //nolint:errcheck return true From 5616644049745f2c93b0588cae5602b294b8ec6c Mon Sep 17 00:00:00 2001 From: Never M Date: Tue, 11 May 2021 17:58:20 +0300 Subject: [PATCH 38/41] Use transport manager in autoconnector --- pkg/servicedisc/autoconnect.go | 50 ++++++++++++++++++++++++---------- pkg/visor/init.go | 31 +-------------------- 2 files changed, 37 insertions(+), 44 deletions(-) diff --git a/pkg/servicedisc/autoconnect.go b/pkg/servicedisc/autoconnect.go index 4f751d1137..3f0d389f16 100644 --- a/pkg/servicedisc/autoconnect.go +++ b/pkg/servicedisc/autoconnect.go @@ -8,6 +8,7 @@ import ( "github.com/skycoin/skycoin/src/util/logging" "github.com/skycoin/skywire/internal/netutil" + "github.com/skycoin/skywire/pkg/snet/directtp/tptypes" "github.com/skycoin/skywire/pkg/transport" ) @@ -21,12 +22,9 @@ const ( // ConnectFn provides a way to connect to remote service type ConnectFn func(context.Context, cipher.PubKey) error -// CheckConnFN checks that connection is alive -type CheckConnFN func(cipher.PubKey) bool - // Autoconnector continuously tries to connect to services type Autoconnector interface { - Run(context.Context, ConnectFn, CheckConnFN) error + Run(context.Context) error } type autoconnector struct { @@ -50,11 +48,11 @@ func MakeConnector(conf Config, maxConns int, tm *transport.Manager, log *loggin } // Run implements Autoconnector interface -func (a *autoconnector) Run(ctx context.Context, connector ConnectFn, checker CheckConnFN) error { +func (a *autoconnector) Run(ctx context.Context) error { retrier := netutil.NewRetrier(fetchServicesDelay, 0, 2) for { time.Sleep(PublicServiceDelay) - a.checkConns(checker) + a.checkConns() if len(a.conns) == a.maxConns { continue } @@ -77,22 +75,17 @@ func (a *autoconnector) Run(ctx context.Context, connector ConnectFn, checker Ch if _, ok := a.conns[pk]; ok { continue } - err := connector(ctx, pk) - if err != nil { - a.log.WithField("remote_pk", pk).Warnf("Cannot connect to a service") - } else { - a.conns[pk] = struct{}{} - } + a.connect(ctx, pk) } } } // check if existing connections are still active using checker // and delete those that are not -func (a *autoconnector) checkConns(checker CheckConnFN) { +func (a *autoconnector) checkConns() { toDelete := make([]cipher.PubKey, 0) for pk := range a.conns { - if !checker(pk) { + if !a.checkConn(pk) { toDelete = append(toDelete, pk) } } @@ -100,3 +93,32 @@ func (a *autoconnector) checkConns(checker CheckConnFN) { delete(a.conns, pk) } } + +func (a *autoconnector) checkConn(pk cipher.PubKey) bool { + t, err := a.tm.GetTransport(pk, tptypes.STCPR) + if err != nil { + return false + } + up := t.IsUp() + if !up { + a.tm.DeleteTransport(t.Entry.ID) + } + return up +} + +func (a *autoconnector) connect(ctx context.Context, pk cipher.PubKey) { + a.log.WithField("pk", pk).Infoln("Adding transport to public visor") + if _, err := a.tm.SaveTransport(ctx, pk, tptypes.STCPR); err != nil { + a.log. + WithError(err). + WithField("pk", pk). + WithField("type", tptypes.STCPR). + Warnln("Failed to add transport to public visor") + return + } + a.log. + WithField("pk", pk). + WithField("type", tptypes.STCPR). + Infoln("Added transport to public visor") + a.conns[pk] = struct{}{} +} diff --git a/pkg/visor/init.go b/pkg/visor/init.go index 43403410f4..967c745903 100644 --- a/pkg/visor/init.go +++ b/pkg/visor/init.go @@ -562,37 +562,8 @@ func initPublicVisors(v *Visor) bool { Port: uint16(0), DiscAddr: proxyDisc, } - // todo: refactor snet and app discovery in such a way that app discovery can make use of - // of transport directly, and avoid using callbacks - connectFn := servicedisc.ConnectFn(func(ctx context.Context, pk cipher.PubKey) error { - log.WithField("pk", pk).Infoln("Adding transport to public visor") - if _, err := v.tpM.SaveTransport(ctx, pk, tptypes.STCPR); err != nil { - log. - WithError(err). - WithField("pk", pk). - WithField("type", tptypes.STCPR). - Warnln("Failed to add transport to public visor via") - return err - } - log. - WithField("pk", pk). - WithField("type", tptypes.STCPR). - Infoln("Added transport to public visor") - return nil - }) - checkFN := servicedisc.CheckConnFN(func(pk cipher.PubKey) bool { - t, err := v.tpM.GetTransport(pk, tptypes.STCPR) - if err != nil { - return false - } - up := t.IsUp() - if !up { - v.tpM.DeleteTransport(t.Entry.ID) - } - return up - }) connector := servicedisc.MakeConnector(conf, 5, v.tpM, log) - go connector.Run(context.Background(), connectFn, checkFN) //nolint:errcheck + go connector.Run(context.Background()) //nolint:errcheck return true } From f86bfb0b232a3211d4bc13170743a0fc9ea1158d Mon Sep 17 00:00:00 2001 From: Never M Date: Wed, 12 May 2021 18:12:39 +0300 Subject: [PATCH 39/41] Add public visor advertisement as init module --- pkg/visor/init.go | 73 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 66 insertions(+), 7 deletions(-) diff --git a/pkg/visor/init.go b/pkg/visor/init.go index f8ec65f386..e1e325c5e7 100644 --- a/pkg/visor/init.go +++ b/pkg/visor/init.go @@ -6,6 +6,7 @@ import ( "fmt" "net" "net/http" + "strconv" "sync" "time" @@ -33,6 +34,7 @@ import ( "github.com/skycoin/skywire/pkg/snet/directtp/tptypes" "github.com/skycoin/skywire/pkg/transport" "github.com/skycoin/skywire/pkg/transport/tpdclient" + "github.com/skycoin/skywire/pkg/util/netutil" "github.com/skycoin/skywire/pkg/util/updater" "github.com/skycoin/skywire/pkg/visor/visorconfig" vinit "github.com/skycoin/skywire/pkg/visor/visorinit" @@ -76,8 +78,10 @@ var ( hvs vinit.Module // Uptime tracker ut vinit.Module - // Trusted visors - trv vinit.Module + // Public visors: automatically establish connections to public visors + pvs vinit.Module + // Public visor: advertise current visor as public + pv vinit.Module // hypervisor module hv vinit.Module // dmsg ctrl @@ -107,10 +111,10 @@ func registerModules(logger *logging.MasterLogger) { cli = maker("cli", initCLI) hvs = maker("hypervisors", initHypervisors, &sn) ut = maker("uptime_tracker", initUptimeTracker) - trv = maker("trusted_visors", initPublicVisors, &tr) - + pv = maker("public_visors", initPublicVisors, &tr) + pvs = maker("public_visor", initPublicVisor, &sn, &ar, &disc) vis = vinit.MakeModule("visor", vinit.DoNothing, logger, &up, &ebc, &ar, &disc, &sn, &pty, - &tr, &rt, &launch, &cli, &hvs, &ut, &trv, &dmsgCtrl) + &tr, &rt, &launch, &cli, &hvs, &ut, &pv, &pvs, &dmsgCtrl) hv = maker("hypervisor", initHypervisor, &vis) } @@ -563,7 +567,62 @@ func initUptimeTracker(ctx context.Context, v *Visor, log *logging.Logger) error return nil } -func initPublicVisors(_ context.Context, v *Visor, log *logging.Logger) error { +// this service is not considered critical and always returns true +// advertise this visor as public in service discovery +func initPublicVisor(_ context.Context, v *Visor, log *logging.Logger) error { + if !v.conf.IsPublic { + return nil + } + + // retrieve interface IPs and check if at least one is public + defaultIPs, err := netutil.DefaultNetworkInterfaceIPs() + if err != nil { + return nil + } + var found bool + for _, IP := range defaultIPs { + if netutil.IsPublicIP(IP) { + found = true + break + } + } + if !found { + return nil + } + + // todo: consider moving this to transport into some helper function + stcpr, ok := v.net.STcpr() + if !ok { + return nil + } + la, err := stcpr.LocalAddr() + if err != nil { + log.WithError(err).Errorln("Failed to get STCPR local addr") + return nil + } + _, portStr, err := net.SplitHostPort(la.String()) + if err != nil { + log.WithError(err).Errorf("Failed to extract port from addr %v", la.String()) + return nil + } + port, err := strconv.Atoi(portStr) + if err != nil { + log.WithError(err).Errorf("Failed to convert port to int") + return nil + } + + visorUpdater := v.serviceDisc.VisorUpdater(uint16(port)) + visorUpdater.Start() + + v.log.Infof("Sent request to register visor as public") + v.pushCloseStack("visor updater", func() error { + visorUpdater.Stop() + return nil + }) + return nil +} + +func initPublicVisors(ctx context.Context, v *Visor, log *logging.Logger) error { if !v.conf.Transport.AutoconnectPublic { return nil } @@ -584,7 +643,7 @@ func initPublicVisors(_ context.Context, v *Visor, log *logging.Logger) error { DiscAddr: proxyDisc, } connector := servicedisc.MakeConnector(conf, 5, v.tpM, log) - go connector.Run(context.Background()) //nolint:errcheck + go connector.Run(ctx) //nolint:errcheck return nil } From 0a545768dc5c01bda0909d6daf11129e88ee4caa Mon Sep 17 00:00:00 2001 From: Never M Date: Thu, 13 May 2021 13:44:32 +0300 Subject: [PATCH 40/41] Use transport labels in connecting to public visors --- pkg/servicedisc/autoconnect.go | 109 ++++++++++++++++----------------- pkg/transport/manager.go | 13 ++++ 2 files changed, 67 insertions(+), 55 deletions(-) diff --git a/pkg/servicedisc/autoconnect.go b/pkg/servicedisc/autoconnect.go index 9910918e6c..3be39c3b95 100644 --- a/pkg/servicedisc/autoconnect.go +++ b/pkg/servicedisc/autoconnect.go @@ -31,7 +31,6 @@ type autoconnector struct { client *HTTPClient maxConns int log *logging.Logger - conns map[cipher.PubKey]struct{} tm *transport.Manager } @@ -42,83 +41,83 @@ func MakeConnector(conf Config, maxConns int, tm *transport.Manager, log *loggin connector.client = NewClient(log, conf) connector.maxConns = maxConns connector.log = log - connector.conns = make(map[cipher.PubKey]struct{}) connector.tm = tm return connector } // Run implements Autoconnector interface func (a *autoconnector) Run(ctx context.Context) error { - retrier := netutil.NewRetrier(fetchServicesDelay, 0, 2) for { time.Sleep(PublicServiceDelay) - a.checkConns() - if len(a.conns) == a.maxConns { - continue - } - var services []Service - fetch := func() (err error) { - // "return" services up from the closure - services, err = a.client.Services(ctx, a.maxConns) - if err != nil { - return err - } - return nil - } - if err := retrier.Do(fetch); err != nil { - a.log.Errorf("Cannot fetch services: %s", err) - return err + a.log.Infof("Fetching public visors") + addresses, err := a.fetchPubAddresses(ctx) + if err != nil { + a.log.Errorf("Cannot fetch public services: %s", err) } - for _, service := range services { - pk := service.Addr.PubKey() - if _, ok := a.conns[pk]; ok { + trs := a.updateTransports() + absent := a.calculateAbsent(addresses, trs) + for _, pk := range absent { + a.log.WithField("pk", pk).Infoln("Adding transport to public visor") + logger := a.log.WithField("pk", pk).WithField("type", tptypes.STCPR) + if _, err := a.tm.SaveTransport(ctx, pk, tptypes.STCPR, transport.LabelAutomatic); err != nil { + logger.WithError(err).Warnln("Failed to add transport to public visor") continue } - a.connect(ctx, pk) + logger.Infoln("Added transport to public visor") } } } -// check if existing connections are still active using checker -// and delete those that are not -func (a *autoconnector) checkConns() { - toDelete := make([]cipher.PubKey, 0) - for pk := range a.conns { - if !a.checkConn(pk) { - toDelete = append(toDelete, pk) +// Remove all inactive automatic transports and return all active +// automatic transports +func (a *autoconnector) updateTransports() []*transport.ManagedTransport { + trs := a.tm.GetTransportsByLabel(transport.LabelAutomatic) + var trsActive []*transport.ManagedTransport + for _, tr := range trs { + if !tr.IsUp() { + a.tm.DeleteTransport(tr.Entry.ID) + } else { + trsActive = append(trsActive, tr) } } - for _, pk := range toDelete { - delete(a.conns, pk) - } + return trsActive } -func (a *autoconnector) checkConn(pk cipher.PubKey) bool { - t, err := a.tm.GetTransport(pk, tptypes.STCPR) - if err != nil { - return false +func (a *autoconnector) fetchPubAddresses(ctx context.Context) ([]cipher.PubKey, error) { + retrier := netutil.NewRetrier(fetchServicesDelay, 0, 2) + var services []Service + fetch := func() (err error) { + // "return" services up from the closure + services, err = a.client.Services(ctx, a.maxConns) + if err != nil { + return err + } + return nil + } + if err := retrier.Do(fetch); err != nil { + return nil, err } - up := t.IsUp() - if !up { - a.tm.DeleteTransport(t.Entry.ID) + var pkeys []cipher.PubKey + for _, service := range services { + pkeys = append(pkeys, service.Addr.PubKey()) } - return up + return pkeys, nil } -func (a *autoconnector) connect(ctx context.Context, pk cipher.PubKey) { - a.log.WithField("pk", pk).Infoln("Adding transport to public visor") - if _, err := a.tm.SaveTransport(ctx, pk, tptypes.STCPR, transport.LabelAutomatic); err != nil { - a.log. - WithError(err). - WithField("pk", pk). - WithField("type", tptypes.STCPR). - Warnln("Failed to add transport to public visor") - return +func (a *autoconnector) calculateAbsent(pkeys []cipher.PubKey, trs []*transport.ManagedTransport) []cipher.PubKey { + var absent []cipher.PubKey + for _, pk := range pkeys { + found := false + for _, tr := range trs { + if tr.Entry.HasEdge(pk) { + found = true + break + } + } + if !found { + absent = append(absent, pk) + } } - a.log. - WithField("pk", pk). - WithField("type", tptypes.STCPR). - Infoln("Added transport to public visor") - a.conns[pk] = struct{}{} + return absent } diff --git a/pkg/transport/manager.go b/pkg/transport/manager.go index 0fc7801a90..d664848ae5 100644 --- a/pkg/transport/manager.go +++ b/pkg/transport/manager.go @@ -270,6 +270,19 @@ func (tm *Manager) GetTransport(remote cipher.PubKey, tpType string) (*ManagedTr return t, nil } +// GetTransportsByLabel returns all transports that have given label +func (tm *Manager) GetTransportsByLabel(label Label) []*ManagedTransport { + tm.mx.RLock() + defer tm.mx.RUnlock() + var trs []*ManagedTransport + for _, tr := range tm.tps { + if tr.Entry.Label == label { + trs = append(trs, tr) + } + } + return trs +} + // SaveTransport begins to attempt to establish data transports to the given 'remote' visor. func (tm *Manager) SaveTransport(ctx context.Context, remote cipher.PubKey, tpType string, label Label) (*ManagedTransport, error) { From c1017cc4ea09ac6ad982f7182e9018695d870e7f Mon Sep 17 00:00:00 2001 From: Never M Date: Mon, 17 May 2021 13:18:14 +0300 Subject: [PATCH 41/41] Use canonical names for variables --- pkg/servicedisc/autoconnect.go | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/pkg/servicedisc/autoconnect.go b/pkg/servicedisc/autoconnect.go index 3be39c3b95..0012d9fc7e 100644 --- a/pkg/servicedisc/autoconnect.go +++ b/pkg/servicedisc/autoconnect.go @@ -55,8 +55,8 @@ func (a *autoconnector) Run(ctx context.Context) error { a.log.Errorf("Cannot fetch public services: %s", err) } - trs := a.updateTransports() - absent := a.calculateAbsent(addresses, trs) + tps := a.updateTransports() + absent := a.filterDuplicates(addresses, tps) for _, pk := range absent { a.log.WithField("pk", pk).Infoln("Adding transport to public visor") logger := a.log.WithField("pk", pk).WithField("type", tptypes.STCPR) @@ -72,16 +72,16 @@ func (a *autoconnector) Run(ctx context.Context) error { // Remove all inactive automatic transports and return all active // automatic transports func (a *autoconnector) updateTransports() []*transport.ManagedTransport { - trs := a.tm.GetTransportsByLabel(transport.LabelAutomatic) - var trsActive []*transport.ManagedTransport - for _, tr := range trs { + tps := a.tm.GetTransportsByLabel(transport.LabelAutomatic) + var tpsActive []*transport.ManagedTransport + for _, tr := range tps { if !tr.IsUp() { a.tm.DeleteTransport(tr.Entry.ID) } else { - trsActive = append(trsActive, tr) + tpsActive = append(tpsActive, tr) } } - return trsActive + return tpsActive } func (a *autoconnector) fetchPubAddresses(ctx context.Context) ([]cipher.PubKey, error) { @@ -98,16 +98,17 @@ func (a *autoconnector) fetchPubAddresses(ctx context.Context) ([]cipher.PubKey, if err := retrier.Do(fetch); err != nil { return nil, err } - var pkeys []cipher.PubKey + var pks []cipher.PubKey for _, service := range services { - pkeys = append(pkeys, service.Addr.PubKey()) + pks = append(pks, service.Addr.PubKey()) } - return pkeys, nil + return pks, nil } -func (a *autoconnector) calculateAbsent(pkeys []cipher.PubKey, trs []*transport.ManagedTransport) []cipher.PubKey { +// return public keys from pks that are absent in given list of transports +func (a *autoconnector) filterDuplicates(pks []cipher.PubKey, trs []*transport.ManagedTransport) []cipher.PubKey { var absent []cipher.PubKey - for _, pk := range pkeys { + for _, pk := range pks { found := false for _, tr := range trs { if tr.Entry.HasEdge(pk) {