diff --git a/.gitignore b/.gitignore index 808d3ffb4..1d597f705 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,4 @@ Char /SkywireInstaller*.pkg *.dmg /scripts/mac_installer/icon.iconset/ +releaseChangelog.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 70d94ce02..28445d98c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - added `update` and `summary` as subcommand to `skywire-cli visor` - added multiple new flag to update configuration in `skywire-cli config update` - added shell autocompletion command to `skywire-cli` and `skywire-visor` +- added `dsmgHTTPStruct` in visorconfig pkg to usable other repos, such as `skybian` +- added `dmsghttp-config.json` which contains the `dmsg-urls` of services and info of `dmsg-servers` for both prod and test +- added `servers` filed to `dmsg` in config +- added `-d,--dmsghttp` flag to `skywire-cli config gen` +- added `dmsgdirect` client to connect to services over dmsg ## 0.5.0 ### Changed diff --git a/Makefile b/Makefile index bfbefde0f..8c73e42a8 100644 --- a/Makefile +++ b/Makefile @@ -149,7 +149,10 @@ build-deploy: ## Build for deployment Docker images ${OPTS} go build ${BUILD_OPTS_DEPLOY} -o /release/apps/skysocks-client ./cmd/apps/skysocks-client github-release: - goreleaser --rm-dist + $(eval GITHUB_TAG=$(shell git describe --abbrev=0 --tags | cut -c 2-)) + sed '/^## ${GITHUB_TAG}$$/,/^## .*/!d;//d;/^$$/d' ./CHANGELOG.md > releaseChangelog.md + goreleaser --rm-dist --release-notes releaseChangelog.md + build-docker: ## Build docker image ./ci_scripts/docker-push.sh -t ${BRANCH} -b diff --git a/cmd/skywire-cli/commands/config/gen.go b/cmd/skywire-cli/commands/config/gen.go index 12b9a2491..3df3c8686 100644 --- a/cmd/skywire-cli/commands/config/gen.go +++ b/cmd/skywire-cli/commands/config/gen.go @@ -104,10 +104,10 @@ var genConfigCmd = &cobra.Command{ logger.WithError(err).Fatal("Failed to create config.") } - // Use local servers + // Use dmsg urls for services and add dmsg-servers if dmsgHTTP { - var dmsgHTTPServersList dmsgHTTPServers - serversListJSON, err := ioutil.ReadFile("localServers.json") + var dmsgHTTPServersList visorconfig.DmsgHTTPServers + serversListJSON, err := ioutil.ReadFile("dmsghttp-config.json") if err != nil { logger.WithError(err).Fatal("Failed to read servers.json file.") } @@ -186,17 +186,3 @@ func readOldConfig(log *logging.MasterLogger, confPath string, replace bool) (*v return conf, true } - -type dmsgHTTPServers struct { - Test dmsgHTTPServersData `json:"test"` - Prod dmsgHTTPServersData `json:"prod"` -} -type dmsgHTTPServersData struct { - DMSGServers []string `json:"dmsg_servers"` - DMSGDiscovery string `json:"dmsg_discovery"` - TransportDiscovery string `json:"transport_discovery"` - AddressResolver string `json:"address_resolver"` - RouteFinder string `json:"route_finder"` - UptimeTracker string `json:"uptime_tracker"` - ServiceDiscovery string `json:"service_discovery"` -} diff --git a/cmd/skywire-cli/commands/mdisc/root.go b/cmd/skywire-cli/commands/mdisc/root.go index aff26c156..42c210cd2 100644 --- a/cmd/skywire-cli/commands/mdisc/root.go +++ b/cmd/skywire-cli/commands/mdisc/root.go @@ -3,6 +3,7 @@ package mdisc import ( "context" "fmt" + "net/http" "os" "text/tabwriter" "time" @@ -41,7 +42,7 @@ var entryCmd = &cobra.Command{ ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) defer cancel() pk := internal.ParsePK("visor-public-key", args[0]) - entry, err := disc.NewHTTP(mdAddr).Entry(ctx, pk) + entry, err := disc.NewHTTP(mdAddr, http.Client{}).Entry(ctx, pk) internal.Catch(err) fmt.Println(entry) }, @@ -53,7 +54,7 @@ var availableServersCmd = &cobra.Command{ Run: func(_ *cobra.Command, _ []string) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) defer cancel() - entries, err := disc.NewHTTP(mdAddr).AvailableServers(ctx) + entries, err := disc.NewHTTP(mdAddr, http.Client{}).AvailableServers(ctx) internal.Catch(err) printAvailableServers(entries) }, diff --git a/cmd/skywire-cli/commands/rtfind/root.go b/cmd/skywire-cli/commands/rtfind/root.go index 29e29d35d..a847dc1a8 100644 --- a/cmd/skywire-cli/commands/rtfind/root.go +++ b/cmd/skywire-cli/commands/rtfind/root.go @@ -2,6 +2,7 @@ package rtfind import ( "fmt" + "net/http" "time" "github.com/skycoin/dmsg/cipher" @@ -31,7 +32,7 @@ var RootCmd = &cobra.Command{ Short: "Queries the Route Finder for available routes between two visors", Args: cobra.MinimumNArgs(2), Run: func(_ *cobra.Command, args []string) { - rfc := rfclient.NewHTTP(frAddr, timeout) + rfc := rfclient.NewHTTP(frAddr, timeout, http.Client{}) var srcPK, dstPK cipher.PubKey internal.Catch(srcPK.Set(args[0])) diff --git a/go.mod b/go.mod index 4fc6ffbf4..ac38f4e26 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/schollz/progressbar/v2 v2.15.0 github.com/shirou/gopsutil/v3 v3.21.4 github.com/sirupsen/logrus v1.8.1 - github.com/skycoin/dmsg v0.0.0-20211007145032-962409e5845f + github.com/skycoin/dmsg v0.0.0-20211125122021-388f2fc645c9 github.com/skycoin/skycoin v0.27.1 github.com/skycoin/yamux v0.0.0-20200803175205-571ceb89da9f github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 diff --git a/go.sum b/go.sum index 19f69100c..87511c3de 100644 --- a/go.sum +++ b/go.sum @@ -306,8 +306,8 @@ github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5k github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/skycoin/dmsg v0.0.0-20211007145032-962409e5845f h1:0/PJaqsGvkfuf4I/Jg2ayQq0AJg5qhIhK4YzevX72Bg= -github.com/skycoin/dmsg v0.0.0-20211007145032-962409e5845f/go.mod h1:p9RQVoY18Rpi5mrbIfE55z7XcKTscIUiNh8nv1ou1/8= +github.com/skycoin/dmsg v0.0.0-20211125122021-388f2fc645c9 h1:Cy62MJBJkPWc/zoNBnwJC7+ak+Hj20TgwxOMKkhi8mI= +github.com/skycoin/dmsg v0.0.0-20211125122021-388f2fc645c9/go.mod h1:EgRg8fy5RjF67OJlh9w+vhq3+Phyn6AXKSedkzhf1ww= github.com/skycoin/noise v0.0.0-20180327030543-2492fe189ae6 h1:1Nc5EBY6pjfw1kwW0duwyG+7WliWz5u9kgk1h5MnLuA= github.com/skycoin/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:UXghlricA7J3aRD/k7p/zBObQfmBawwCxIVPVjz2Q3o= github.com/skycoin/skycoin v0.26.0/go.mod h1:78nHjQzd8KG0jJJVL/j0xMmrihXi70ti63fh8vXScJw= @@ -479,7 +479,6 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210503060354-a79de5458b56 h1:b8jxX3zqjpqb2LklXPzKSGJhzyxCOZSz8ncv8Nv+y7w= golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/internal/httpauth/client.go b/internal/httpauth/client.go index ce3280e99..ea4a82507 100644 --- a/internal/httpauth/client.go +++ b/internal/httpauth/client.go @@ -63,10 +63,10 @@ type Client struct { // * SW-Public: The specified public key // * SW-Nonce: The nonce for that public key // * SW-Sig: The signature of the payload + the nonce -func NewClient(ctx context.Context, addr string, key cipher.PubKey, sec cipher.SecKey) (*Client, error) { +func NewClient(ctx context.Context, addr string, key cipher.PubKey, sec cipher.SecKey, client *http.Client) (*Client, error) { c := &Client{ - client: &http.Client{}, - reuseClient: &http.Client{}, + client: client, + reuseClient: client, key: key, sec: sec, addr: sanitizedAddr(addr), diff --git a/internal/httpauth/client_test.go b/internal/httpauth/client_test.go index 33d4d6d42..2a08d8030 100644 --- a/internal/httpauth/client_test.go +++ b/internal/httpauth/client_test.go @@ -45,7 +45,7 @@ func TestClient(t *testing.T) { ts := newTestServer(t, pk, headerCh) defer ts.Close() - c, err := NewClient(context.TODO(), ts.URL, pk, sk) + c, err := NewClient(context.TODO(), ts.URL, pk, sk, &http.Client{}) require.NoError(t, err) req, err := http.NewRequest(http.MethodGet, ts.URL+"/foo", bytes.NewBufferString(payload)) @@ -71,7 +71,7 @@ func TestClient_BadNonce(t *testing.T) { ts := newTestServer(t, pk, headerCh) defer ts.Close() - c, err := NewClient(context.TODO(), ts.URL, pk, sk) + c, err := NewClient(context.TODO(), ts.URL, pk, sk, &http.Client{}) require.NoError(t, err) c.nonce = 999 diff --git a/internal/utclient/client.go b/internal/utclient/client.go index b187b3156..7457189b5 100644 --- a/internal/utclient/client.go +++ b/internal/utclient/client.go @@ -50,13 +50,13 @@ const ( // * SW-Public: The specified public key // * SW-Nonce: The nonce for that public key // * SW-Sig: The signature of the payload + the nonce -func NewHTTP(addr string, pk cipher.PubKey, sk cipher.SecKey) (APIClient, error) { +func NewHTTP(addr string, pk cipher.PubKey, sk cipher.SecKey, httpC http.Client) (APIClient, error) { var client *httpauth.Client var err error retrier := netutil.NewRetrier(createRetryDelay, 10, 2, log) retrierFunc := func() error { - client, err = httpauth.NewClient(context.Background(), addr, pk, sk) + client, err = httpauth.NewClient(context.Background(), addr, pk, sk, &httpC) if err != nil { return fmt.Errorf("uptime tracker httpauth: %w", err) } diff --git a/internal/utclient/client_test.go b/internal/utclient/client_test.go index d895133e8..15d8b7693 100644 --- a/internal/utclient/client_test.go +++ b/internal/utclient/client_test.go @@ -42,7 +42,7 @@ func TestClientAuth(t *testing.T) { )) defer srv.Close() - client, err := NewHTTP(srv.URL, testPubKey, testSecKey) + client, err := NewHTTP(srv.URL, testPubKey, testSecKey, http.Client{}) require.NoError(t, err) c := client.(*httpClient) @@ -67,7 +67,7 @@ func TestUpdateVisorUptime(t *testing.T) { defer srv.Close() - c, err := NewHTTP(srv.URL, testPubKey, testSecKey) + c, err := NewHTTP(srv.URL, testPubKey, testSecKey, http.Client{}) require.NoError(t, err) err = c.UpdateVisorUptime(context.TODO()) diff --git a/localServers.json b/localServers.json deleted file mode 100644 index cf197f987..000000000 --- a/localServers.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "test": { - "dmsg_servers": [ - "ip:port", - "ip:port", - "ip:port" - ], - "dmsg_discovery": "dmsg://pk:port", - "transport_discovery": "dmsg://pk:port", - "address_resolver": "dmsg://pk:port", - "route_finder": "dmsg://pk:port", - "uptime_tracker": "dmsg://pk:port", - "service_discovery": "dmsg://pk:port" - }, -"prod": { - "dmsg_servers": [ - "ip:port", - "ip:port", - "ip:port" - ], - "dmsg_discovery": "dmsg://pk:port", - "transport_discovery": "dmsg://pk:port", - "address_resolver": "dmsg://pk:port", - "route_finder": "dmsg://pk:port", - "uptime_tracker": "dmsg://pk:port", - "service_discovery": "dmsg://pk:port" -} -} diff --git a/pkg/app/appdisc/factory.go b/pkg/app/appdisc/factory.go index a1c35eb5a..f015615eb 100644 --- a/pkg/app/appdisc/factory.go +++ b/pkg/app/appdisc/factory.go @@ -1,6 +1,8 @@ package appdisc import ( + "net/http" + "github.com/sirupsen/logrus" "github.com/skycoin/dmsg/cipher" "github.com/skycoin/skycoin/src/util/logging" @@ -16,6 +18,7 @@ type Factory struct { PK cipher.PubKey SK cipher.SecKey ServiceDisc string // Address of service-discovery + Client http.Client } func (f *Factory) setDefaults() { @@ -43,7 +46,7 @@ func (f *Factory) VisorUpdater(port uint16) Updater { } return &serviceUpdater{ - client: servicedisc.NewClient(f.Log, conf), + client: servicedisc.NewClient(f.Log, conf, f.Client), } } @@ -74,11 +77,11 @@ func (f *Factory) AppUpdater(conf appcommon.ProcConfig) (Updater, bool) { switch conf.AppName { case skyenv.VPNServerName: return &serviceUpdater{ - client: servicedisc.NewClient(log, getServiceDiscConf(conf, servicedisc.ServiceTypeVPN)), + client: servicedisc.NewClient(log, getServiceDiscConf(conf, servicedisc.ServiceTypeVPN), f.Client), }, true case skyenv.SkysocksName: return &serviceUpdater{ - client: servicedisc.NewClient(log, getServiceDiscConf(conf, servicedisc.ServiceTypeSkysocks)), + client: servicedisc.NewClient(log, getServiceDiscConf(conf, servicedisc.ServiceTypeSkysocks), f.Client), }, true default: return &emptyUpdater{}, false diff --git a/pkg/dmsgc/dmsgc.go b/pkg/dmsgc/dmsgc.go index 085edab71..7eeb35dcd 100644 --- a/pkg/dmsgc/dmsgc.go +++ b/pkg/dmsgc/dmsgc.go @@ -2,6 +2,7 @@ package dmsgc import ( "context" + "net/http" "github.com/skycoin/dmsg" "github.com/skycoin/dmsg/cipher" @@ -13,13 +14,13 @@ import ( // DmsgConfig defines config for Dmsg network. type DmsgConfig struct { - Discovery string `json:"discovery"` - SessionsCount int `json:"sessions_count"` - Servers []string `json:"servers"` + Discovery string `json:"discovery"` + SessionsCount int `json:"sessions_count"` + Servers []*disc.Entry `json:"servers"` } // New makes new dmsg client from configuration -func New(pk cipher.PubKey, sk cipher.SecKey, eb *appevent.Broadcaster, conf *DmsgConfig) *dmsg.Client { +func New(pk cipher.PubKey, sk cipher.SecKey, eb *appevent.Broadcaster, conf *DmsgConfig, httpC http.Client) *dmsg.Client { dmsgConf := &dmsg.Config{ MinSessions: conf.SessionsCount, Callbacks: &dmsg.ClientCallbacks{ @@ -37,7 +38,8 @@ func New(pk cipher.PubKey, sk cipher.SecKey, eb *appevent.Broadcaster, conf *Dms }, }, } - dmsgC := dmsg.NewClient(pk, sk, disc.NewHTTP(conf.Discovery), dmsgConf) + + dmsgC := dmsg.NewClient(pk, sk, disc.NewHTTP(conf.Discovery, httpC), dmsgConf) dmsgC.SetLogger(logging.MustGetLogger("dmsgC")) return dmsgC } diff --git a/pkg/routefinder/rfclient/client.go b/pkg/routefinder/rfclient/client.go index 8fbeb0570..700c83e20 100644 --- a/pkg/routefinder/rfclient/client.go +++ b/pkg/routefinder/rfclient/client.go @@ -62,14 +62,14 @@ type apiClient struct { } // NewHTTP constructs new Client that communicates over http. -func NewHTTP(addr string, apiTimeout time.Duration) Client { +func NewHTTP(addr string, apiTimeout time.Duration, client http.Client) Client { if apiTimeout == 0 { apiTimeout = defaultContextTimeout } return &apiClient{ addr: sanitizedAddr(addr), - client: http.Client{}, + client: client, apiTimeout: apiTimeout, } } diff --git a/pkg/servicedisc/autoconnect.go b/pkg/servicedisc/autoconnect.go index 28c2657df..1195160f5 100644 --- a/pkg/servicedisc/autoconnect.go +++ b/pkg/servicedisc/autoconnect.go @@ -2,6 +2,7 @@ package servicedisc import ( "context" + "net/http" "time" "github.com/sirupsen/logrus" @@ -38,9 +39,9 @@ type autoconnector struct { // MakeConnector returns a new connector that will try to connect to at most maxConns // services -func MakeConnector(conf Config, maxConns int, tm *transport.Manager, log *logging.Logger) Autoconnector { +func MakeConnector(conf Config, maxConns int, tm *transport.Manager, httpC http.Client, log *logging.Logger) Autoconnector { connector := &autoconnector{} - connector.client = NewClient(log, conf) + connector.client = NewClient(log, conf, httpC) connector.maxConns = maxConns connector.log = log connector.tm = tm diff --git a/pkg/servicedisc/client.go b/pkg/servicedisc/client.go index 05b0af2bb..892c83fc8 100644 --- a/pkg/servicedisc/client.go +++ b/pkg/servicedisc/client.go @@ -50,7 +50,7 @@ type HTTPClient struct { } // NewClient creates a new HTTPClient. -func NewClient(log logrus.FieldLogger, conf Config) *HTTPClient { +func NewClient(log logrus.FieldLogger, conf Config, client http.Client) *HTTPClient { return &HTTPClient{ log: log, conf: conf, @@ -59,7 +59,7 @@ func NewClient(log logrus.FieldLogger, conf Config) *HTTPClient { Type: conf.Type, Version: buildinfo.Version(), }, - client: http.Client{}, + client: client, } } @@ -96,7 +96,7 @@ func (c *HTTPClient) Auth(ctx context.Context) (*httpauth.Client, error) { return auth, nil } - auth, err := httpauth.NewClient(ctx, c.conf.DiscAddr, c.conf.PK, c.conf.SK) + auth, err := httpauth.NewClient(ctx, c.conf.DiscAddr, c.conf.PK, c.conf.SK, &c.client) if err != nil { return nil, err } diff --git a/pkg/setup/node.go b/pkg/setup/node.go index 95fee8963..a684487a4 100644 --- a/pkg/setup/node.go +++ b/pkg/setup/node.go @@ -3,6 +3,7 @@ package setup import ( "context" "fmt" + "net/http" "net/rpc" "time" @@ -33,7 +34,7 @@ func NewNode(conf *Config) (*Node, error) { } // Connect to dmsg network. - dmsgDisc := disc.NewHTTP(conf.Dmsg.Discovery) + dmsgDisc := disc.NewHTTP(conf.Dmsg.Discovery, http.Client{}) dmsgConf := &dmsg.Config{MinSessions: conf.Dmsg.SessionsCount} dmsgC := dmsg.NewClient(conf.PK, conf.SK, dmsgDisc, dmsgConf) go dmsgC.Serve(context.Background()) diff --git a/pkg/transport/network/addrresolver/client.go b/pkg/transport/network/addrresolver/client.go index e914167be..856b60d18 100644 --- a/pkg/transport/network/addrresolver/client.go +++ b/pkg/transport/network/addrresolver/client.go @@ -90,7 +90,7 @@ type httpClient struct { // * SW-Public: The specified public key. // * SW-Nonce: The nonce for that public key. // * SW-Sig: The signature of the payload + the nonce. -func NewHTTP(remoteAddr string, pk cipher.PubKey, sk cipher.SecKey, log *logging.Logger) (APIClient, error) { +func NewHTTP(remoteAddr string, pk cipher.PubKey, sk cipher.SecKey, httpC http.Client, log *logging.Logger) (APIClient, error) { remoteURL, err := url.Parse(remoteAddr) if err != nil { return nil, fmt.Errorf("parse URL: %w", err) @@ -113,13 +113,13 @@ func NewHTTP(remoteAddr string, pk cipher.PubKey, sk cipher.SecKey, log *logging client.log.Infof("Remote UDP server: %q", remoteUDP) - go client.initHTTPClient() + go client.initHTTPClient(httpC) return client, nil } -func (c *httpClient) initHTTPClient() { - httpAuthClient, err := httpauth.NewClient(context.Background(), c.remoteHTTPAddr, c.pk, c.sk) +func (c *httpClient) initHTTPClient(httpC http.Client) { + httpAuthClient, err := httpauth.NewClient(context.Background(), c.remoteHTTPAddr, c.pk, c.sk, &httpC) if err != nil { c.log.WithError(err). Warnf("Failed to connect to address resolver. STCPR/SUDPH services are temporarily unavailable. Retrying...") @@ -128,7 +128,7 @@ func (c *httpClient) initHTTPClient() { retry := dmsgnetutil.NewRetrier(retryLog, 1*time.Second, 10*time.Second, 0, 1) err := retry.Do(context.Background(), func() error { - httpAuthClient, err = httpauth.NewClient(context.Background(), c.remoteHTTPAddr, c.pk, c.sk) + httpAuthClient, err = httpauth.NewClient(context.Background(), c.remoteHTTPAddr, c.pk, c.sk, &httpC) return err }) diff --git a/pkg/transport/network/addrresolver/client_test.go b/pkg/transport/network/addrresolver/client_test.go index 1746c0e7a..9978f6293 100644 --- a/pkg/transport/network/addrresolver/client_test.go +++ b/pkg/transport/network/addrresolver/client_test.go @@ -44,7 +44,7 @@ func TestClientAuth(t *testing.T) { defer srv.Close() log := logging.MustGetLogger("test_client_auth") - apiClient, err := NewHTTP(srv.URL, testPubKey, testSecKey, log) + apiClient, err := NewHTTP(srv.URL, testPubKey, testSecKey, http.Client{}, log) require.NoError(t, err) c := apiClient.(*httpClient) @@ -73,7 +73,7 @@ func TestBind(t *testing.T) { defer srv.Close() log := logging.MustGetLogger("test_bind") - c, err := NewHTTP(srv.URL, testPubKey, testSecKey, log) + c, err := NewHTTP(srv.URL, testPubKey, testSecKey, http.Client{}, log) require.NoError(t, err) err = c.BindSTCPR(context.TODO(), "1234") diff --git a/pkg/transport/tpdclient/client.go b/pkg/transport/tpdclient/client.go index cfc2e3efa..168cc8062 100644 --- a/pkg/transport/tpdclient/client.go +++ b/pkg/transport/tpdclient/client.go @@ -37,8 +37,8 @@ type apiClient struct { // * SW-Public: The specified public key // * SW-Nonce: The nonce for that public key // * SW-Sig: The signature of the payload + the nonce -func NewHTTP(addr string, key cipher.PubKey, sec cipher.SecKey) (transport.DiscoveryClient, error) { - client, err := httpauth.NewClient(context.Background(), addr, key, sec) +func NewHTTP(addr string, key cipher.PubKey, sec cipher.SecKey, httpC http.Client) (transport.DiscoveryClient, error) { + client, err := httpauth.NewClient(context.Background(), addr, key, sec, &httpC) if err != nil { return nil, fmt.Errorf("transport discovery httpauth: %w", err) } diff --git a/pkg/transport/tpdclient/client_test.go b/pkg/transport/tpdclient/client_test.go index 988915fed..a61b11de7 100644 --- a/pkg/transport/tpdclient/client_test.go +++ b/pkg/transport/tpdclient/client_test.go @@ -73,7 +73,7 @@ func TestClientAuth(t *testing.T) { )) defer srv.Close() - client, err := NewHTTP(srv.URL, testPubKey, testSecKey) + client, err := NewHTTP(srv.URL, testPubKey, testSecKey, http.Client{}) require.NoError(t, err) c := client.(*apiClient) @@ -154,7 +154,7 @@ func TestRegisterTransportResponses(t *testing.T) { }))) defer srv.Close() - c, err := NewHTTP(srv.URL, testPubKey, testSecKey) + c, err := NewHTTP(srv.URL, testPubKey, testSecKey, http.Client{}) require.NoError(t, err) err = c.RegisterTransports(context.Background(), &transport.SignedEntry{}) if tc.assert != nil { @@ -180,7 +180,7 @@ func TestRegisterTransports(t *testing.T) { }))) defer srv.Close() - c, err := NewHTTP(srv.URL, testPubKey, testSecKey) + c, err := NewHTTP(srv.URL, testPubKey, testSecKey, http.Client{}) require.NoError(t, err) require.NoError(t, c.RegisterTransports(context.Background(), sEntry)) } @@ -193,7 +193,7 @@ func TestGetTransportByID(t *testing.T) { }))) defer srv.Close() - c, err := NewHTTP(srv.URL, testPubKey, testSecKey) + c, err := NewHTTP(srv.URL, testPubKey, testSecKey, http.Client{}) require.NoError(t, err) resEntry, err := c.GetTransportByID(context.Background(), entry.ID) require.NoError(t, err) @@ -209,7 +209,7 @@ func TestGetTransportsByEdge(t *testing.T) { }))) defer srv.Close() - c, err := NewHTTP(srv.URL, testPubKey, testSecKey) + c, err := NewHTTP(srv.URL, testPubKey, testSecKey, http.Client{}) require.NoError(t, err) entries, err := c.GetTransportsByEdge(context.Background(), entry.Edges[0]) require.NoError(t, err) diff --git a/pkg/visor/init.go b/pkg/visor/init.go index 197ba8c48..34a9c71cd 100644 --- a/pkg/visor/init.go +++ b/pkg/visor/init.go @@ -13,7 +13,11 @@ import ( "github.com/sirupsen/logrus" "github.com/skycoin/dmsg" "github.com/skycoin/dmsg/cipher" + "github.com/skycoin/dmsg/direct" + dmsgdisc "github.com/skycoin/dmsg/disc" "github.com/skycoin/dmsg/dmsgctrl" + "github.com/skycoin/dmsg/dmsgget" + "github.com/skycoin/dmsg/dmsghttp" dmsgnetutil "github.com/skycoin/dmsg/netutil" "github.com/skycoin/skycoin/src/util/logging" @@ -97,8 +101,10 @@ var ( tm vinit.Module // hypervisor module hv vinit.Module - // dmsg ctrl + // Dmsg ctrl module dmsgCtrl vinit.Module + // Dmsg http module + dmsgHTTP vinit.Module // visor that groups all modules together vis vinit.Module ) @@ -112,25 +118,26 @@ func registerModules(logger *logging.MasterLogger) { return vinit.MakeModule(name, withInitCtx(f), logger, deps...) } up = maker("updater", initUpdater) + dmsgHTTP = maker("dmsg_http", initDmsgHTTP) ebc = maker("event_broadcaster", initEventBroadcaster) - ar = maker("address_resolver", initAddressResolver) - disc = maker("discovery", initDiscovery) - tr = maker("transport", initTransport, &ar, &ebc) + ar = maker("address_resolver", initAddressResolver, &dmsgHTTP) + disc = maker("discovery", initDiscovery, &dmsgHTTP) + tr = maker("transport", initTransport, &ar, &ebc, &dmsgHTTP) sc = maker("stun_client", initStunClient) sudphC = maker("sudph", initSudphClient, &sc, &tr) stcprC = maker("stcpr", initStcprClient, &tr) stcpC = maker("stcp", initStcpClient, &tr) - dmsgC = maker("dmsg", initDmsg, &ebc) + dmsgC = maker("dmsg", initDmsg, &ebc, &dmsgHTTP) dmsgCtrl = maker("dmsg_ctrl", initDmsgCtrl, &dmsgC, &tr) pty = maker("dmsg_pty", initDmsgpty, &dmsgC) - rt = maker("router", initRouter, &tr, &dmsgC) + rt = maker("router", initRouter, &tr, &dmsgC, &dmsgHTTP) launch = maker("launcher", initLauncher, &ebc, &disc, &dmsgC, &tr, &rt) cli = maker("cli", initCLI) hvs = maker("hypervisors", initHypervisors, &dmsgC) - ut = maker("uptime_tracker", initUptimeTracker) - pv = maker("public_autoconnect", initPublicAutoconnect, &tr) + ut = maker("uptime_tracker", initUptimeTracker, &dmsgHTTP) + pv = maker("public_autoconnect", initPublicAutoconnect, &tr, &disc) trs = maker("transport_setup", initTransportSetup, &dmsgC, &tr) tm = vinit.MakeModule("transports", vinit.DoNothing, logger, &sc, &sudphC, &dmsgCtrl) pvs = maker("public_visor", initPublicVisor, &tr, &ar, &disc, &stcprC) @@ -153,6 +160,31 @@ func initUpdater(ctx context.Context, v *Visor, log *logging.Logger) error { return nil } +func initDmsgHTTP(ctx context.Context, v *Visor, log *logging.Logger) error { + var keys cipher.PubKeys + servers := v.conf.Dmsg.Servers + + keys = append(keys, v.conf.PK) + dClient := direct.NewDirectClient(direct.GetAllEntries(keys, servers)) + + dmsgD, closeDmsgD, err := direct.StartDmsg(ctx, log, v.conf.PK, v.conf.SK, dClient, dmsg.DefaultConfig()) + if err != nil { + return fmt.Errorf("failed to start dmsg: %w", err) + } + dmsgHTTP := http.Client{Transport: dmsghttp.MakeHTTPTransport(dmsgD)} + + v.pushCloseStack("dmsg_http", func() error { + closeDmsgD() + return nil + }) + + v.initLock.Lock() + v.dClient = dClient + v.dmsgHTTP = &dmsgHTTP + v.initLock.Unlock() + return nil +} + func initEventBroadcaster(ctx context.Context, v *Visor, log *logging.Logger) error { const ebcTimeout = time.Second ebc := appevent.NewBroadcaster(log, ebcTimeout) @@ -167,7 +199,12 @@ func initEventBroadcaster(ctx context.Context, v *Visor, log *logging.Logger) er func initAddressResolver(ctx context.Context, v *Visor, log *logging.Logger) error { conf := v.conf.Transport - arClient, err := addrresolver.NewHTTP(conf.AddressResolver, v.conf.PK, v.conf.SK, log) + httpC, err := getHTTPClient(ctx, v, conf.AddressResolver) + if err != nil { + return err + } + + arClient, err := addrresolver.NewHTTP(conf.AddressResolver, v.conf.PK, v.conf.SK, httpC, log) if err != nil { err = fmt.Errorf("failed to create address resolver client: %w", err) return err @@ -223,11 +260,18 @@ func initDiscovery(ctx context.Context, v *Visor, log *logging.Logger) error { conf := v.conf.Launcher + httpC, err := getHTTPClient(ctx, v, conf.ServiceDisc) + if err != nil { + return err + } + if conf.ServiceDisc != "" { factory.PK = v.conf.PK factory.SK = v.conf.SK factory.ServiceDisc = conf.ServiceDisc + factory.Client = httpC } + v.initLock.Lock() v.serviceDisc = factory v.initLock.Unlock() @@ -242,11 +286,17 @@ func initStunClient(ctx context.Context, v *Visor, log *logging.Logger) error { return nil } -func initDmsg(ctx context.Context, v *Visor, log *logging.Logger) error { +func initDmsg(ctx context.Context, v *Visor, log *logging.Logger) (err error) { if v.conf.Dmsg == nil { return fmt.Errorf("cannot initialize dmsg: empty configuration") } - dmsgC := dmsgc.New(v.conf.PK, v.conf.SK, v.ebc, v.conf.Dmsg) + + httpC, err := getHTTPClient(ctx, v, v.conf.Dmsg.Discovery) + if err != nil { + return err + } + + dmsgC := dmsgc.New(v.conf.PK, v.conf.SK, v.ebc, v.conf.Dmsg, httpC) wg := new(sync.WaitGroup) wg.Add(1) @@ -325,7 +375,7 @@ func initStcpClient(ctx context.Context, v *Visor, log *logging.Logger) error { func initTransport(ctx context.Context, v *Visor, log *logging.Logger) error { - tpdC, err := connectToTpDisc(v) + tpdC, err := connectToTpDisc(ctx, v) if err != nil { err := fmt.Errorf("failed to create transport discovery client: %w", err) return err @@ -469,7 +519,13 @@ func getRouteSetupHooks(ctx context.Context, v *Visor, log *logging.Logger) []ro func initRouter(ctx context.Context, v *Visor, log *logging.Logger) error { conf := v.conf.Routing - rfClient := rfclient.NewHTTP(conf.RouteFinder, time.Duration(conf.RouteFinderTimeout)) + + httpC, err := getHTTPClient(ctx, v, conf.RouteFinder) + if err != nil { + return err + } + + rfClient := rfclient.NewHTTP(conf.RouteFinder, time.Duration(conf.RouteFinderTimeout), httpC) logger := v.MasterLogger().PackageLogger("router") rConf := router.Config{ Logger: logger, @@ -671,7 +727,7 @@ func initHypervisors(ctx context.Context, v *Visor, log *logging.Logger) error { return nil } -func initUptimeTracker(_ context.Context, v *Visor, log *logging.Logger) error { +func initUptimeTracker(ctx context.Context, v *Visor, log *logging.Logger) error { const tickDuration = 1 * time.Minute conf := v.conf.UptimeTracker @@ -681,7 +737,12 @@ func initUptimeTracker(_ context.Context, v *Visor, log *logging.Logger) error { return nil } - ut, err := utclient.NewHTTP(conf.Addr, v.conf.PK, v.conf.SK) + httpC, err := getHTTPClient(ctx, v, conf.Addr) + if err != nil { + return err + } + + ut, err := utclient.NewHTTP(conf.Addr, v.conf.PK, v.conf.SK, httpC) if err != nil { v.log.WithError(err).Warn("Failed to connect to uptime tracker.") return nil @@ -776,7 +837,7 @@ func initPublicAutoconnect(ctx context.Context, v *Visor, log *logging.Logger) e Port: uint16(0), DiscAddr: serviceDisc, } - connector := servicedisc.MakeConnector(conf, 3, v.tpM, log) + connector := servicedisc.MakeConnector(conf, 3, v.tpM, v.serviceDisc.Client, log) go connector.Run(ctx) //nolint:errcheck return nil @@ -824,7 +885,7 @@ func initHypervisor(_ context.Context, v *Visor, log *logging.Logger) error { return nil } -func connectToTpDisc(v *Visor) (transport.DiscoveryClient, error) { +func connectToTpDisc(ctx context.Context, v *Visor) (transport.DiscoveryClient, error) { const ( initBO = 1 * time.Second maxBO = 10 * time.Second @@ -835,6 +896,11 @@ func connectToTpDisc(v *Visor) (transport.DiscoveryClient, error) { conf := v.conf.Transport + httpC, err := getHTTPClient(ctx, v, conf.Discovery) + if err != nil { + return nil, err + } + log := v.MasterLogger().PackageLogger("tp_disc_retrier") tpdCRetrier := dmsgnetutil.NewRetrier(log, initBO, maxBO, tries, factor) @@ -842,7 +908,7 @@ func connectToTpDisc(v *Visor) (transport.DiscoveryClient, error) { var tpdC transport.DiscoveryClient retryFunc := func() error { var err error - tpdC, err = tpdclient.NewHTTP(conf.Discovery, v.conf.PK, v.conf.SK) + tpdC, err = tpdclient.NewHTTP(conf.Discovery, v.conf.PK, v.conf.SK, httpC) if err != nil { log.WithError(err).Error("Failed to connect to transport discovery, retrying...") return err @@ -896,3 +962,27 @@ func getErrors(ctx context.Context) chan error { } return errs } + +func getHTTPClient(ctx context.Context, v *Visor, service string) (httpC http.Client, err error) { + + var serviceURL dmsgget.URL + + err = serviceURL.Fill(service) + + if serviceURL.Scheme == "dmsg" { + if err != nil { + return http.Client{}, fmt.Errorf("provided URL is invalid: %w", err) + } + clientEntry := &dmsgdisc.Entry{ + Client: &dmsgdisc.Client{}, + Static: serviceURL.Addr.PK, + } + err = v.dClient.PostEntry(ctx, clientEntry) + if err != nil { + return http.Client{}, fmt.Errorf("Error saving clientEntry: %w", err) + } + httpC = *v.dmsgHTTP + return httpC, nil + } + return httpC, nil +} diff --git a/pkg/visor/visor.go b/pkg/visor/visor.go index ace98c654..c18c5799b 100644 --- a/pkg/visor/visor.go +++ b/pkg/visor/visor.go @@ -5,11 +5,13 @@ import ( "context" "errors" "fmt" + "net/http" "sync" "time" "github.com/skycoin/dmsg" "github.com/skycoin/dmsg/cipher" + "github.com/skycoin/dmsg/direct" "github.com/skycoin/skycoin/src/util/logging" "github.com/skycoin/skywire/internal/utclient" @@ -59,6 +61,8 @@ type Visor struct { ebc *appevent.Broadcaster // event broadcaster dmsgC *dmsg.Client + dClient direct.APIClient // dmsg direct client + dmsgHTTP *http.Client // dmsghttp client trackers *dmsgtracker.Manager stunClient *network.StunDetails @@ -122,7 +126,6 @@ func NewVisor(conf *visorconfig.V1, restartCtx *restart.Context) (*Visor, bool) v.log.WithError(err).Warn("Failed to read log level from config.") } else { v.conf.MasterLogger().SetLevel(logLvl) - logging.SetLevel(logLvl) } log := v.MasterLogger().PackageLogger("visor:startup") diff --git a/pkg/visor/visorconfig/config.go b/pkg/visor/visorconfig/config.go index 77ba8d5d7..0d4755f10 100644 --- a/pkg/visor/visorconfig/config.go +++ b/pkg/visor/visorconfig/config.go @@ -4,6 +4,7 @@ import ( "runtime" "github.com/skycoin/dmsg/cipher" + "github.com/skycoin/dmsg/disc" "github.com/skycoin/skycoin/src/util/logging" "github.com/skycoin/skywire/pkg/app/launcher" @@ -24,7 +25,7 @@ func MakeBaseConfig(common *Common) *V1 { conf.Dmsg = &dmsgc.DmsgConfig{ Discovery: skyenv.DefaultDmsgDiscAddr, SessionsCount: 1, - Servers: []string{}, + Servers: []*disc.Entry{}, } conf.Transport = &V1Transport{ Discovery: skyenv.DefaultTpDiscAddr, @@ -244,3 +245,20 @@ func launcherAddAllApps(launcherCfg []launcher.AppConfig) []launcher.AppConfig { }...) return launcherCfg } + +// DmsgHTTPServers struct use to unmarshal dmsghttp file +type DmsgHTTPServers struct { + Test DmsgHTTPServersData `json:"test"` + Prod DmsgHTTPServersData `json:"prod"` +} + +// DmsgHTTPServersData is a part of DmsgHTTPServers +type DmsgHTTPServersData struct { + DMSGServers []*disc.Entry `json:"dmsg_servers"` + DMSGDiscovery string `json:"dmsg_discovery"` + TransportDiscovery string `json:"transport_discovery"` + AddressResolver string `json:"address_resolver"` + RouteFinder string `json:"route_finder"` + UptimeTracker string `json:"uptime_tracker"` + ServiceDiscovery string `json:"service_discovery"` +} diff --git a/vendor/github.com/skycoin/dmsg/.appveyor.yml b/vendor/github.com/skycoin/dmsg/.appveyor.yml index fd5267bf0..6df37197a 100644 --- a/vendor/github.com/skycoin/dmsg/.appveyor.yml +++ b/vendor/github.com/skycoin/dmsg/.appveyor.yml @@ -25,6 +25,7 @@ for: - go mod vendor before_build: + - golangci-lint cache clean - make check - # Windows @@ -45,6 +46,7 @@ for: before_build: - set GO111MODULE=on + - golangci-lint cache clean - make check-windows build_script: diff --git a/vendor/github.com/skycoin/dmsg/client.go b/vendor/github.com/skycoin/dmsg/client.go index ddc7d770f..87cdc1639 100644 --- a/vendor/github.com/skycoin/dmsg/client.go +++ b/vendor/github.com/skycoin/dmsg/client.go @@ -49,12 +49,6 @@ type Config struct { // Ensure ensures all config values are set. func (c *Config) Ensure() { - if c.MinSessions == 0 { - c.MinSessions = DefaultMinSessions - } - if c.UpdateInterval == 0 { - c.UpdateInterval = DefaultUpdateInterval - } if c.Callbacks == nil { c.Callbacks = new(ClientCallbacks) } @@ -173,9 +167,9 @@ func (ce *Client) Serve(ctx context.Context) { if isClosed(ce.done) { return } - - // If we have enough sessions, we wait for error or done signal. - if ce.SessionCount() >= ce.conf.MinSessions { + // If MinSessions is set to 0 then we connect to all available servers. + // If MinSessions is not 0 AND we have enough sessions, we wait for error or done signal. + if ce.conf.MinSessions != 0 && ce.SessionCount() >= ce.conf.MinSessions { select { case <-ce.done: return @@ -195,6 +189,16 @@ func (ce *Client) Serve(ctx context.Context) { time.Sleep(serveWait) } } + // We dial all servers and wait for error or done signal. + select { + case <-ce.done: + return + case err := <-ce.errCh: + ce.log.WithError(err).Info("Session stopped.") + if isClosed(ce.done) { + return + } + } } } @@ -236,7 +240,7 @@ func (ce *Client) Close() error { ce.log.Info("All sessions closed.") ce.sessionsMx.Unlock() ce.porter.CloseAll(ce.log) - err = ce.EntityCommon.delClientEntry(context.Background()) + err = ce.EntityCommon.delEntry(context.Background()) }) return err } diff --git a/vendor/github.com/skycoin/dmsg/const.go b/vendor/github.com/skycoin/dmsg/const.go index 2a3edb9e6..d19568712 100644 --- a/vendor/github.com/skycoin/dmsg/const.go +++ b/vendor/github.com/skycoin/dmsg/const.go @@ -11,4 +11,6 @@ const ( DefaultUpdateInterval = time.Minute DefaultMaxSessions = 100 + + DefaultDmsgHTTPPort = uint16(80) ) diff --git a/vendor/github.com/skycoin/dmsg/direct/client.go b/vendor/github.com/skycoin/dmsg/direct/client.go new file mode 100644 index 000000000..9789d58ee --- /dev/null +++ b/vendor/github.com/skycoin/dmsg/direct/client.go @@ -0,0 +1,113 @@ +package direct + +import ( + "context" + "sync" + + "github.com/skycoin/skycoin/src/util/logging" + + "github.com/skycoin/dmsg/cipher" + "github.com/skycoin/dmsg/disc" +) + +var log = logging.MustGetLogger("direct") + +// APIClient implements dmsg discovery API client. +type APIClient interface { + Entry(context.Context, cipher.PubKey) (*disc.Entry, error) + PostEntry(context.Context, *disc.Entry) error + PutEntry(context.Context, cipher.SecKey, *disc.Entry) error + DelEntry(context.Context, *disc.Entry) error + AvailableServers(context.Context) ([]*disc.Entry, error) +} + +// directClient represents a client that doesnot communicates with a dmsg-discovery, instead directly gets the dmsg-server info via the user or is hardcoded, it +// implements APIClient +type directClient struct { + entries map[cipher.PubKey]*disc.Entry + mx sync.RWMutex +} + +// NewDirectClient constructs a new APIClient that communicates with discovery via http. +func NewDirectClient(entries []*disc.Entry) APIClient { + entriesMap := make(map[cipher.PubKey]*disc.Entry) + for _, entry := range entries { + entriesMap[entry.Static] = entry + } + log.WithField("func", "direct.NewClient"). + Debug("Created Direct client.") + return &directClient{ + entries: entriesMap, + } +} + +// Entry retrieves an entry associated with the given public key. +func (c *directClient) Entry(ctx context.Context, pubKey cipher.PubKey) (*disc.Entry, error) { + c.mx.RLock() + defer c.mx.RUnlock() + for _, entry := range c.entries { + if entry.Static == pubKey { + return entry, nil + } + } + return &disc.Entry{}, nil +} + +// PostEntry adds a new Entry. +func (c *directClient) PostEntry(ctx context.Context, e *disc.Entry) error { + c.mx.Lock() + defer c.mx.Unlock() + var servers cipher.PubKeys + + for _, entry := range c.entries { + if entry.Server != nil { + servers = append(servers, entry.Static) + } + } + + if e.Client != nil { + e.Client.DelegatedServers = servers + c.entries[e.Static] = e + } + + if e.Server != nil { + servers = append(servers, e.Static) + c.entries[e.Static] = e + } + + for _, entry := range c.entries { + if entry.Client != nil { + entry.Client.DelegatedServers = servers + } + } + + return nil +} + +// DelEntry deletes an Entry. +func (c *directClient) DelEntry(ctx context.Context, e *disc.Entry) error { + c.mx.Lock() + defer c.mx.Unlock() + delete(c.entries, e.Static) + return nil +} + +// PutEntry updates Entry. +func (c *directClient) PutEntry(ctx context.Context, _ cipher.SecKey, entry *disc.Entry) error { + c.mx.Lock() + defer c.mx.Unlock() + c.entries[entry.Static] = entry + return nil +} + +// AvailableServers returns list of available servers. +func (c *directClient) AvailableServers(ctx context.Context) (entries []*disc.Entry, err error) { + c.mx.RLock() + defer c.mx.RUnlock() + for _, entry := range c.entries { + if entry.Server != nil { + entries = append(entries, entry) + } + } + return entries, nil +} diff --git a/vendor/github.com/skycoin/dmsg/direct/direct.go b/vendor/github.com/skycoin/dmsg/direct/direct.go new file mode 100644 index 000000000..3b985d72d --- /dev/null +++ b/vendor/github.com/skycoin/dmsg/direct/direct.go @@ -0,0 +1,36 @@ +package direct + +import ( + "context" + + "github.com/sirupsen/logrus" + + "github.com/skycoin/dmsg" + "github.com/skycoin/dmsg/cipher" +) + +// StartDmsg starts dmsg directly without the discovery +func StartDmsg(ctx context.Context, log logrus.FieldLogger, pk cipher.PubKey, sk cipher.SecKey, + dClient APIClient, config *dmsg.Config) (dmsgC *dmsg.Client, stop func(), err error) { + + dmsgC = dmsg.NewClient(pk, sk, dClient, config) + go dmsgC.Serve(context.Background()) + + stop = func() { + err := dmsgC.Close() + log.WithError(err).Info("Disconnected from dmsg network.") + } + + log.WithField("public_key", pk.String()). + Info("Connecting to dmsg network...") + + select { + case <-ctx.Done(): + stop() + return nil, nil, ctx.Err() + + case <-dmsgC.Ready(): + log.Info("Dmsg network ready.") + return dmsgC, stop, nil + } +} diff --git a/vendor/github.com/skycoin/dmsg/direct/entries.go b/vendor/github.com/skycoin/dmsg/direct/entries.go new file mode 100644 index 000000000..4a093172f --- /dev/null +++ b/vendor/github.com/skycoin/dmsg/direct/entries.go @@ -0,0 +1,32 @@ +package direct + +import ( + "github.com/skycoin/dmsg/cipher" + "github.com/skycoin/dmsg/disc" +) + +// GetClientEntry gives all client entries +func GetClientEntry(pks cipher.PubKeys, servers []*disc.Entry) (clients []*disc.Entry) { + srvPKs := make([]cipher.PubKey, 0) + for _, entry := range servers { + srvPKs = append(srvPKs, entry.Static) + } + + for _, pk := range pks { + client := &disc.Entry{ + Static: pk, + Client: &disc.Client{ + DelegatedServers: srvPKs, + }, + } + clients = append(clients, client) + } + return clients +} + +// GetAllEntries gives all the entries +func GetAllEntries(pks cipher.PubKeys, servers []*disc.Entry) (entries []*disc.Entry) { + client := GetClientEntry(pks, servers) + entries = append(client, servers...) + return entries +} diff --git a/vendor/github.com/skycoin/dmsg/disc/client.go b/vendor/github.com/skycoin/dmsg/disc/client.go index d85dd1c1b..f1e8582d4 100644 --- a/vendor/github.com/skycoin/dmsg/disc/client.go +++ b/vendor/github.com/skycoin/dmsg/disc/client.go @@ -38,12 +38,12 @@ type httpClient struct { } // NewHTTP constructs a new APIClient that communicates with discovery via http. -func NewHTTP(address string) APIClient { +func NewHTTP(address string, client http.Client) APIClient { log.WithField("func", "disc.NewHTTP"). WithField("addr", address). Debug("Created HTTP client.") return &httpClient{ - client: http.Client{}, + client: client, address: address, } } @@ -240,7 +240,6 @@ func (c *httpClient) AvailableServers(ctx context.Context) ([]*Entry, error) { if err != nil { return nil, err } - req = req.WithContext(ctx) resp, err := c.client.Do(req) diff --git a/vendor/github.com/skycoin/dmsg/dmsgget/dmsgget.go b/vendor/github.com/skycoin/dmsg/dmsgget/dmsgget.go new file mode 100644 index 000000000..75bbcec1b --- /dev/null +++ b/vendor/github.com/skycoin/dmsg/dmsgget/dmsgget.go @@ -0,0 +1,264 @@ +package dmsgget + +import ( + "context" + "errors" + "flag" + "fmt" + "io" + "net/http" + "os" + "path/filepath" + "time" + + jsoniter "github.com/json-iterator/go" + "github.com/sirupsen/logrus" + "github.com/skycoin/skycoin/src/util/logging" + + "github.com/skycoin/dmsg" + "github.com/skycoin/dmsg/cipher" + "github.com/skycoin/dmsg/disc" + "github.com/skycoin/dmsg/dmsghttp" +) + +var json = jsoniter.ConfigFastest + +// DmsgGet contains the logic for dmsgget (wget over dmsg). +type DmsgGet struct { + startF startupFlags + dmsgF dmsgFlags + dlF downloadFlags + httpF httpFlags + fs *flag.FlagSet +} + +// New creates a new DmsgGet instance. +func New(fs *flag.FlagSet) *DmsgGet { + dg := &DmsgGet{fs: fs} + + for _, fg := range dg.flagGroups() { + fg.Init(fs) + } + + w := fs.Output() + flag.Usage = func() { + _, _ = fmt.Fprintf(w, "Skycoin %s %s, wget over dmsg.\n", ExecName, Version) + _, _ = fmt.Fprintf(w, "Usage: %s [OPTION]... [URL]\n\n", ExecName) + flag.PrintDefaults() + _, _ = fmt.Fprintln(w, "") + } + + return dg +} + +// String implements io.Stringer +func (dg *DmsgGet) String() string { + m := make(map[string]interface{}) + for _, fg := range dg.flagGroups() { + m[fg.Name()] = fg + } + j, err := json.Marshal(m) + if err != nil { + panic(err) + } + return string(j) +} + +func (dg *DmsgGet) flagGroups() []FlagGroup { + return []FlagGroup{&dg.startF, &dg.dmsgF, &dg.dlF, &dg.httpF} +} + +// Run runs the download logic. +func (dg *DmsgGet) Run(ctx context.Context, log logrus.FieldLogger, skStr string, args []string) (err error) { + if log == nil { + log = logging.MustGetLogger("dmsgget") + } + + if dg.startF.Help { + dg.fs.Usage() + return nil + } + + pk, sk, err := parseKeyPair(skStr) + if err != nil { + return fmt.Errorf("failed to parse provided key pair: %w", err) + } + + u, err := parseURL(args) + if err != nil { + return fmt.Errorf("failed to parse provided URL: %w", err) + } + + file, err := parseOutputFile(dg.dlF.Output, u.URL.Path) + if err != nil { + return fmt.Errorf("failed to prepare output file: %w", err) + } + defer func() { + if fErr := file.Close(); fErr != nil { + log.WithError(fErr).Warn("Failed to close output file.") + } + if err != nil { + if rErr := os.RemoveAll(file.Name()); rErr != nil { + log.WithError(rErr).Warn("Failed to remove output file.") + } + } + }() + + dmsgC, closeDmsg, err := dg.startDmsg(ctx, log, pk, sk) + if err != nil { + return fmt.Errorf("failed to start dmsg: %w", err) + } + defer closeDmsg() + + httpC := http.Client{Transport: dmsghttp.MakeHTTPTransport(dmsgC)} + + for i := 0; i < dg.dlF.Tries; i++ { + log.Infof("Download attempt %d/%d ...", i, dg.dlF.Tries) + + if _, err := file.Seek(0, 0); err != nil { + return fmt.Errorf("failed to reset file: %w", err) + } + + if err := Download(ctx, log, &httpC, file, u.URL.String()); err != nil { + log.WithError(err).Error() + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(time.Duration(dg.dlF.Wait) * time.Second): + continue + } + } + + // download successful. + return nil + } + + return errors.New("all download attempts failed") +} + +func parseKeyPair(skStr string) (pk cipher.PubKey, sk cipher.SecKey, err error) { + if skStr == "" { + pk, sk = cipher.GenerateKeyPair() + return + } + + if err = sk.Set(skStr); err != nil { + return + } + + pk, err = sk.PubKey() + return +} + +func parseURL(args []string) (*URL, error) { + if len(args) == 0 { + return nil, ErrNoURLs + } + + if len(args) > 1 { + return nil, ErrMultipleURLsNotSupported + } + + var out URL + if err := out.Fill(args[0]); err != nil { + return nil, fmt.Errorf("provided URL is invalid: %w", err) + } + + return &out, nil +} + +func parseOutputFile(name string, urlPath string) (*os.File, error) { + stat, statErr := os.Stat(name) + if statErr != nil { + if os.IsNotExist(statErr) { + f, err := os.Create(name) + if err != nil { + return nil, err + } + return f, nil + } + return nil, statErr + } + + if stat.IsDir() { + f, err := os.Create(filepath.Join(name, urlPath)) + if err != nil { + return nil, err + } + return f, nil + } + + return nil, os.ErrExist +} + +func (dg *DmsgGet) startDmsg(ctx context.Context, log logrus.FieldLogger, pk cipher.PubKey, sk cipher.SecKey) (dmsgC *dmsg.Client, stop func(), err error) { + dmsgC = dmsg.NewClient(pk, sk, disc.NewHTTP(dg.dmsgF.Disc, http.Client{}), &dmsg.Config{MinSessions: dg.dmsgF.Sessions}) + go dmsgC.Serve(context.Background()) + + stop = func() { + err := dmsgC.Close() + log.WithError(err).Info("Disconnected from dmsg network.") + } + + log.WithField("public_key", pk.String()).WithField("dmsg_disc", dg.dmsgF.Disc). + Info("Connecting to dmsg network...") + + select { + case <-ctx.Done(): + stop() + return nil, nil, ctx.Err() + + case <-dmsgC.Ready(): + log.Info("Dmsg network ready.") + return dmsgC, stop, nil + } +} + +// Download downloads a file from the given URL into 'w'. +func Download(ctx context.Context, log logrus.FieldLogger, httpC *http.Client, w io.Writer, urlStr string) error { + req, err := http.NewRequest(http.MethodGet, urlStr, nil) + if err != nil { + log.WithError(err).Fatal("Failed to formulate HTTP request.") + } + + resp, err := httpC.Do(req) + if err != nil { + return fmt.Errorf("failed to connect to HTTP server: %w", err) + } + n, err := CancellableCopy(ctx, w, resp.Body, resp.ContentLength) + if err != nil { + return fmt.Errorf("download failed at %d/%dB: %w", n, resp.ContentLength, err) + } + defer func() { + if err := resp.Body.Close(); err != nil { + log.WithError(err).Warn("HTTP Response body closed with non-nil error.") + } + }() + + return nil +} + +type readerFunc func(p []byte) (n int, err error) + +func (rf readerFunc) Read(p []byte) (n int, err error) { return rf(p) } + +// CancellableCopy will call the Reader and Writer interface multiple time, in order +// to copy by chunk (avoiding loading the whole file in memory). +func CancellableCopy(ctx context.Context, w io.Writer, body io.ReadCloser, length int64) (int64, error) { + + n, err := io.Copy(io.MultiWriter(w, &ProgressWriter{Total: length}), readerFunc(func(p []byte) (int, error) { + + // golang non-blocking channel: https://gobyexample.com/non-blocking-channel-operations + select { + + // if context has been canceled + case <-ctx.Done(): + // stop process and propagate "Download Canceled" error + return 0, errors.New("Download Canceled") + default: + // otherwise just run default io.Reader implementation + return body.Read(p) + } + })) + return n, err +} diff --git a/vendor/github.com/skycoin/dmsg/dmsgget/flags.go b/vendor/github.com/skycoin/dmsg/dmsgget/flags.go new file mode 100644 index 000000000..2c125c60e --- /dev/null +++ b/vendor/github.com/skycoin/dmsg/dmsgget/flags.go @@ -0,0 +1,66 @@ +package dmsgget + +import ( + "flag" + + "github.com/skycoin/dmsg/buildinfo" +) + +// ExecName contains the execution name. +const ExecName = "dmsgget" + +// Version contains the version string. +var Version = buildinfo.Version() + +// FlagGroup represents a group of flags. +type FlagGroup interface { + Name() string + Init(fs *flag.FlagSet) +} + +type startupFlags struct { + Help bool +} + +func (f *startupFlags) Name() string { return "Startup" } + +func (f *startupFlags) Init(fs *flag.FlagSet) { + fs.BoolVar(&f.Help, "help", false, "print this help") + fs.BoolVar(&f.Help, "h", false, "") +} + +type dmsgFlags struct { + Disc string + Sessions int +} + +func (f *dmsgFlags) Name() string { return "Dmsg" } + +func (f *dmsgFlags) Init(fs *flag.FlagSet) { + fs.StringVar(&f.Disc, "dmsg-disc", "http://dmsgd.skywire.skycoin.com", "dmsg discovery `URL`") + fs.IntVar(&f.Sessions, "dmsg-sessions", 1, "connect to `NUMBER` of dmsg servers") +} + +type downloadFlags struct { + Output string + Tries int + Wait int +} + +func (f *downloadFlags) Name() string { return "Download" } + +func (f *downloadFlags) Init(fs *flag.FlagSet) { + fs.StringVar(&f.Output, "O", ".", "write documents to `FILE`") + fs.IntVar(&f.Tries, "t", 1, "set number of retries to `NUMBER` (0 unlimits)") + fs.IntVar(&f.Wait, "w", 0, "wait `SECONDS` between retrievals") +} + +type httpFlags struct { + UserAgent string +} + +func (f *httpFlags) Name() string { return "HTTP" } + +func (f *httpFlags) Init(fs *flag.FlagSet) { + fs.StringVar(&f.UserAgent, "U", ExecName+"/"+Version, "identify as `AGENT`") +} diff --git a/vendor/github.com/skycoin/dmsg/dmsgget/progress_writer.go b/vendor/github.com/skycoin/dmsg/dmsgget/progress_writer.go new file mode 100644 index 000000000..1518d4963 --- /dev/null +++ b/vendor/github.com/skycoin/dmsg/dmsgget/progress_writer.go @@ -0,0 +1,31 @@ +package dmsgget + +import ( + "fmt" + "sync/atomic" +) + +// ProgressWriter prints the progress of a download to stdout. +type ProgressWriter struct { + // atomic requires 64-bit alignment for struct field access + Current int64 + Total int64 +} + +// Write implements io.Writer +func (pw *ProgressWriter) Write(p []byte) (int, error) { + n := len(p) + + current := atomic.AddInt64(&pw.Current, int64(n)) + total := atomic.LoadInt64(&pw.Total) + pc := fmt.Sprintf("%d%%", current*100/total) + + fmt.Printf("Downloading: %d/%dB (%s)", current, total, pc) + if current != total { + fmt.Print("\r") + } else { + fmt.Print("\n") + } + + return n, nil +} diff --git a/vendor/github.com/skycoin/dmsg/dmsgget/url.go b/vendor/github.com/skycoin/dmsg/dmsgget/url.go new file mode 100644 index 000000000..7a5821a7c --- /dev/null +++ b/vendor/github.com/skycoin/dmsg/dmsgget/url.go @@ -0,0 +1,39 @@ +package dmsgget + +import ( + "errors" + "net/url" + + "github.com/skycoin/dmsg" +) + +// Errors related to URLs. +var ( + ErrNoURLs = errors.New("no URLs provided") + ErrMultipleURLsNotSupported = errors.New("multiple URLs is not yet supported") +) + +// URL represents a dmsg http URL. +type URL struct { + dmsg.Addr + url.URL +} + +// Fill fills the internal fields from an URL string. +func (du *URL) Fill(str string) error { + u, err := url.Parse(str) + if err != nil { + return err + } + + if u.Scheme == "" { + return errors.New("URL is missing a scheme") + } + + if u.Host == "" { + return errors.New("URL is missing a host") + } + + du.URL = *u + return du.Addr.Set(u.Host) +} diff --git a/vendor/github.com/skycoin/dmsg/dmsghttp/http.go b/vendor/github.com/skycoin/dmsg/dmsghttp/http.go new file mode 100644 index 000000000..7bc99a462 --- /dev/null +++ b/vendor/github.com/skycoin/dmsg/dmsghttp/http.go @@ -0,0 +1,39 @@ +package dmsghttp + +import ( + "context" + "fmt" + "net/http" + + "github.com/skycoin/dmsg" + "github.com/skycoin/dmsg/cipher" + "github.com/skycoin/dmsg/direct" + + "github.com/skycoin/skycoin/src/util/logging" +) + +// ListenAndServe serves http over dmsg +func ListenAndServe(ctx context.Context, pk cipher.PubKey, sk cipher.SecKey, a http.Handler, dClient direct.APIClient, dmsgPort uint16, + config *dmsg.Config, log *logging.Logger) error { + dmsgC, closeDmsg, err := direct.StartDmsg(ctx, log, pk, sk, dClient, config) + if err != nil { + return fmt.Errorf("failed to start dmsg: %w", err) + } + defer closeDmsg() + + lis, err := dmsgC.Listen(dmsgPort) + if err != nil { + log.WithError(err).Fatal() + } + go func() { + <-ctx.Done() + if err := lis.Close(); err != nil { + log.WithError(err).Error() + } + }() + + log.WithField("dmsg_addr", fmt.Sprintf("dmsg://%v", lis.Addr().String())). + Info("Serving...") + + return http.Serve(lis, a) +} diff --git a/vendor/github.com/skycoin/dmsg/dmsghttp/http_transport.go b/vendor/github.com/skycoin/dmsg/dmsghttp/http_transport.go new file mode 100644 index 000000000..4ae90ac98 --- /dev/null +++ b/vendor/github.com/skycoin/dmsg/dmsghttp/http_transport.go @@ -0,0 +1,48 @@ +package dmsghttp + +import ( + "bufio" + "fmt" + "net/http" + + "github.com/skycoin/dmsg" +) + +const defaultHTTPPort = uint16(80) + +// HTTPTransport implements http.RoundTripper +// Do not confuse this with a Skywire Transport implementation. +type HTTPTransport struct { + dmsgC *dmsg.Client +} + +// MakeHTTPTransport makes an HTTPTransport. +func MakeHTTPTransport(dmsgC *dmsg.Client) HTTPTransport { + return HTTPTransport{dmsgC: dmsgC} +} + +// RoundTrip implements golang's http package support for alternative HTTP transport protocols. +// In this case dmsg is used instead of TCP to initiate the communication with the server. +func (t HTTPTransport) RoundTrip(req *http.Request) (*http.Response, error) { + var hostAddr dmsg.Addr + if err := hostAddr.Set(req.Host); err != nil { + return nil, fmt.Errorf("invalid host address: %w", err) + } + if hostAddr.Port == 0 { + hostAddr.Port = defaultHTTPPort + } + + // TODO(evanlinjin): In the future, we should implement stream reuse to save bandwidth. + // We do not close the stream here as it is the user's responsibility to close the stream after resp.Body is fully + // read. + stream, err := t.dmsgC.DialStream(req.Context(), hostAddr) + if err != nil { + return nil, err + } + + if err := req.Write(stream); err != nil { + return nil, err + } + bufR := bufio.NewReader(stream) + return http.ReadResponse(bufR, req) +} diff --git a/vendor/github.com/skycoin/dmsg/dmsghttp/util.go b/vendor/github.com/skycoin/dmsg/dmsghttp/util.go new file mode 100644 index 000000000..c5c3df0be --- /dev/null +++ b/vendor/github.com/skycoin/dmsg/dmsghttp/util.go @@ -0,0 +1,57 @@ +package dmsghttp + +import ( + "context" + "net/http" + "time" + + "github.com/skycoin/dmsg/direct" + "github.com/skycoin/dmsg/disc" + + "github.com/skycoin/skycoin/src/util/logging" +) + +// GetServers is used to get all the available servers from the dmsg-discovery. +func GetServers(ctx context.Context, dmsgDisc string, log *logging.Logger) (entries []*disc.Entry) { + dmsgclient := disc.NewHTTP(dmsgDisc, http.Client{}) + ticker := time.NewTicker(time.Second * 10) + defer ticker.Stop() + for { + servers, err := dmsgclient.AvailableServers(ctx) + if err != nil { + log.WithError(err).Fatal("Error getting dmsg-servers.") + } + if len(servers) > 0 { + return servers + } + log.Warn("No dmsg-servers found, trying again in 1 minute.") + select { + case <-ctx.Done(): + return []*disc.Entry{} + case <-ticker.C: + GetServers(ctx, dmsgDisc, log) + } + } +} + +// UpdateServers is used to update the servers in the direct client. +func UpdateServers(ctx context.Context, dClient direct.APIClient, dmsgDisc string, log *logging.Logger) (entries []*disc.Entry) { + dmsgclient := disc.NewHTTP(dmsgDisc, http.Client{}) + ticker := time.NewTicker(time.Second * 10) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + servers, err := dmsgclient.AvailableServers(ctx) + if err != nil { + log.WithError(err).Error("Error getting dmsg-servers.") + break + } + for _, server := range servers { + dClient.PostEntry(ctx, server) //nolint + } + } + } +} diff --git a/vendor/github.com/skycoin/dmsg/dmsgpty/cli.go b/vendor/github.com/skycoin/dmsg/dmsgpty/cli.go index ac71769a6..adcad5486 100644 --- a/vendor/github.com/skycoin/dmsg/dmsgpty/cli.go +++ b/vendor/github.com/skycoin/dmsg/dmsgpty/cli.go @@ -6,6 +6,9 @@ import ( "io" "net" "os" + "path/filepath" + "strings" + "syscall" "github.com/sirupsen/logrus" "github.com/skycoin/skycoin/src/util/logging" @@ -134,8 +137,14 @@ func (cli *CLI) servePty(ctx context.Context, ptyC *PtyClient, cmd string, args _, _ = io.Copy(ptyC, os.Stdin) //nolint:errcheck }() + EioPtyErr := os.PathError{ + Op: "read", + Path: filepath.FromSlash("/dev/ptmx"), + Err: syscall.Errno(0x5), + } + // Read loop. - if _, err := io.Copy(os.Stdout, ptyC); err != nil { + if _, err := io.Copy(os.Stdout, ptyC); err != nil && strings.Compare(err.Error(), EioPtyErr.Error()) != 0 { cli.Log. WithError(err). Error("Read loop closed with error.") diff --git a/vendor/github.com/skycoin/dmsg/entity_common.go b/vendor/github.com/skycoin/dmsg/entity_common.go index 779860160..ec5410f8b 100644 --- a/vendor/github.com/skycoin/dmsg/entity_common.go +++ b/vendor/github.com/skycoin/dmsg/entity_common.go @@ -242,7 +242,7 @@ func (c *EntityCommon) updateClientEntry(ctx context.Context, done chan struct{} return c.dc.PutEntry(ctx, c.sk, entry) } -func (c *EntityCommon) delClientEntry(ctx context.Context) (err error) { +func (c *EntityCommon) delEntry(ctx context.Context) (err error) { entry, err := c.dc.Entry(ctx, c.pk) if err != nil { diff --git a/vendor/github.com/skycoin/dmsg/go.mod b/vendor/github.com/skycoin/dmsg/go.mod index e40de35cf..5ce3c27c1 100644 --- a/vendor/github.com/skycoin/dmsg/go.mod +++ b/vendor/github.com/skycoin/dmsg/go.mod @@ -28,7 +28,6 @@ require ( golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c - golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect nhooyr.io/websocket v1.8.2 ) diff --git a/vendor/github.com/skycoin/dmsg/go.sum b/vendor/github.com/skycoin/dmsg/go.sum index 979c61321..cf64583d8 100644 --- a/vendor/github.com/skycoin/dmsg/go.sum +++ b/vendor/github.com/skycoin/dmsg/go.sum @@ -6,15 +6,11 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/VictoriaMetrics/metrics v1.12.3 h1:Fe6JHC6MSEKa+BtLhPN8WIvS+HKPzMc2evEpNeCGy7I= github.com/VictoriaMetrics/metrics v1.12.3/go.mod h1:Z1tSfPfngDn12bTfZSCqArT3OPY3u88J12hSoOhuiRE= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/containerd/console v1.0.2 h1:Pi6D+aZXM+oUw1czuKgH5IJ+y0jhYcwBJfx5/Ghn9dE= -github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.10 h1:Xv3/hZlzZeTSMk5upBEt3iFdxWaPS3xYIm+BBySIqlY= -github.com/creack/pty v1.1.10/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.15 h1:cKRCLMj3Ddm54bKSpemfQ8AtYFBhAI2MPmdys22fBdc= github.com/creack/pty v1.1.15/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -92,8 +88,6 @@ github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pires/go-proxyproto v0.3.3 h1:jOXGrsAfSQVFiD1hWg1aiHpLYsd6SJw/8cLN594sB7Q= github.com/pires/go-proxyproto v0.3.3/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -155,13 +149,9 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200428200454-593003d681fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091 h1:DMyOG0U+gKfu8JZzg2UQe9MeaC1X+xQWlAKcRnjxjCw= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72 h1:VqE9gduFZ4dbR7XoL77lHFp0/DyDUBKSXK7CMFkVcV0= -golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= diff --git a/vendor/github.com/skycoin/dmsg/server.go b/vendor/github.com/skycoin/dmsg/server.go index 638d9d118..795ec3b31 100644 --- a/vendor/github.com/skycoin/dmsg/server.go +++ b/vendor/github.com/skycoin/dmsg/server.go @@ -98,6 +98,10 @@ func (s *Server) Close() error { close(s.done) s.wg.Wait() }) + err := s.delEntry(context.Background()) + if err != nil { + s.log.Warn("Cannot delete entry from db.") + } return nil } diff --git a/vendor/modules.txt b/vendor/modules.txt index 1803b23c8..b1cbcc177 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -158,14 +158,17 @@ github.com/shirou/gopsutil/v3/process ## explicit github.com/sirupsen/logrus github.com/sirupsen/logrus/hooks/syslog -# github.com/skycoin/dmsg v0.0.0-20211007145032-962409e5845f +# github.com/skycoin/dmsg v0.0.0-20211125122021-388f2fc645c9 ## explicit github.com/skycoin/dmsg github.com/skycoin/dmsg/buildinfo github.com/skycoin/dmsg/cipher github.com/skycoin/dmsg/cmdutil +github.com/skycoin/dmsg/direct github.com/skycoin/dmsg/disc github.com/skycoin/dmsg/dmsgctrl +github.com/skycoin/dmsg/dmsgget +github.com/skycoin/dmsg/dmsghttp github.com/skycoin/dmsg/dmsgpty github.com/skycoin/dmsg/dmsgtest github.com/skycoin/dmsg/httputil