From b070a1a984e55f30e56116d608f9baa97f14f84b Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Sat, 31 Aug 2024 11:04:28 -0500 Subject: [PATCH 1/3] dmsgcurl use multiple dmsg-discoveries in fallback configuration --- cmd/dmsgcurl/commands/dmsgcurl.go | 274 ++++++++++++------------------ 1 file changed, 113 insertions(+), 161 deletions(-) diff --git a/cmd/dmsgcurl/commands/dmsgcurl.go b/cmd/dmsgcurl/commands/dmsgcurl.go index 69b6a7c0..bf1f7638 100644 --- a/cmd/dmsgcurl/commands/dmsgcurl.go +++ b/cmd/dmsgcurl/commands/dmsgcurl.go @@ -1,4 +1,4 @@ -// Package commands cmd/dmsgcurl/commands/dmsgcurl.go +// Package commands cmd/dmsgcurl/commands package commands import ( @@ -30,10 +30,9 @@ import ( ) var ( - dmsgDisc string - dmsgSessions int - dmsgcurlData string - // dmsgcurlHeader string + dmsgDisc []string + dmsgSessions int + dmsgcurlData string sk cipher.SecKey dmsgcurlLog *logging.Logger dmsgcurlAgent string @@ -45,44 +44,37 @@ var ( ) func init() { - RootCmd.Flags().StringVarP(&dmsgDisc, "dmsg-disc", "c", "", "dmsg discovery url default:\n"+skyenv.DmsgDiscAddr) + RootCmd.Flags().StringSliceVarP(&dmsgDisc, "dmsg-disc", "c", []string{skyenv.DmsgDiscAddr}, "dmsg discovery url(s)") RootCmd.Flags().IntVarP(&dmsgSessions, "sess", "e", 1, "number of dmsg servers to connect to") - RootCmd.Flags().StringVarP(&logLvl, "loglvl", "l", "fatal", "[ debug | warn | error | fatal | panic | trace | info ]\033[0m") + RootCmd.Flags().StringVarP(&logLvl, "loglvl", "l", "fatal", "[ debug | warn | error | fatal | panic | trace | info ]") RootCmd.Flags().StringVarP(&dmsgcurlData, "data", "d", "", "dmsghttp POST data") - // RootCmd.Flags().StringVarP(&dmsgcurlHeader, "header", "H", "", "Pass custom header(s) to server") RootCmd.Flags().StringVarP(&dmsgcurlOutput, "out", "o", "", "output filepath") - RootCmd.Flags().BoolVarP(&replace, "replace", "r", false, "replace exist file with new downloaded") + RootCmd.Flags().BoolVarP(&replace, "replace", "r", false, "replace existing file with new downloaded") RootCmd.Flags().IntVarP(&dmsgcurlTries, "try", "t", 1, "download attempts (0 unlimits)") RootCmd.Flags().IntVarP(&dmsgcurlWait, "wait", "w", 0, "time to wait between fetches") RootCmd.Flags().StringVarP(&dmsgcurlAgent, "agent", "a", "dmsgcurl/"+buildinfo.Version(), "identify as `AGENT`") if os.Getenv("DMSGCURL_SK") != "" { sk.Set(os.Getenv("DMSGCURL_SK")) //nolint } - RootCmd.Flags().VarP(&sk, "sk", "s", "a random key is generated if unspecified\n\r") + RootCmd.Flags().VarP(&sk, "sk", "s", "a random key is generated if unspecified") } -// RootCmd containsa the root dmsgcurl command +// RootCmd contains the root cli command var RootCmd = &cobra.Command{ Use: func() string { return strings.Split(filepath.Base(strings.ReplaceAll(strings.ReplaceAll(fmt.Sprintf("%v", os.Args), "[", ""), "]", "")), " ")[0] }(), - Short: "DMSG curl utility", - Long: ` - ┌┬┐┌┬┐┌─┐┌─┐┌─┐┬ ┬┬─┐┬ - │││││└─┐│ ┬│ │ │├┬┘│ - ─┴┘┴ ┴└─┘└─┘└─┘└─┘┴└─┴─┘ -DMSG curl utility`, + Short: "DMSG curl utility", + Long: `DMSG curl utility`, SilenceErrors: true, SilenceUsage: true, DisableSuggestions: true, DisableFlagsInUseLine: true, Version: buildinfo.Version(), - PreRun: func(cmd *cobra.Command, args []string) { - if dmsgDisc == "" { - dmsgDisc = skyenv.DmsgDiscAddr + RunE: func(_ *cobra.Command, args []string) error { + if len(dmsgDisc) == 0 || dmsgDisc[0] == "" { + dmsgDisc = []string{skyenv.DmsgDiscAddr} } - }, - RunE: func(cmd *cobra.Command, args []string) error { if dmsgcurlLog == nil { dmsgcurlLog = logging.MustGetLogger("dmsgcurl") } @@ -91,144 +83,125 @@ DMSG curl utility`, logging.SetLevel(lvl) } } - ctx, cancel := cmdutil.SignalContext(context.Background(), dmsgcurlLog) defer cancel() - pk, err := sk.PubKey() if err != nil { pk, sk = cipher.GenerateKeyPair() } - - u, err := parseURL(args) + if len(args) == 0 { + return errors.New("no URL(s) provided") + } + if len(args) > 1 { + return errors.New("multiple URLs is not yet supported") + } + parsedURL, err := url.Parse(args[0]) if err != nil { dmsgcurlLog.WithError(err).Fatal("failed to parse provided URL") } if dmsgcurlData != "" { - dmsgC, closeDmsg, err := startDmsg(ctx, pk, sk) - if err != nil { - dmsgcurlLog.WithError(err).Fatal("failed to start dmsg") - } - defer closeDmsg() + return handlePostRequest(ctx, pk, parsedURL) + } + return handleDownload(ctx, pk, parsedURL) + }, +} - httpC := http.Client{Transport: dmsghttp.MakeHTTPTransport(ctx, dmsgC)} +func handlePostRequest(ctx context.Context, pk cipher.PubKey, parsedURL *url.URL) error { + for _, disco := range dmsgDisc { + dmsgC, closeDmsg, err := startDmsg(ctx, pk, sk, disco) + if err != nil { + dmsgcurlLog.WithError(err).Warnf("Failed to start dmsg with discovery %s", disco) + continue + } + defer closeDmsg() - req, err := http.NewRequest(http.MethodPost, u.URL.String(), strings.NewReader(dmsgcurlData)) - if err != nil { - dmsgcurlLog.WithError(err).Fatal("Failed to formulate HTTP request.") - } - req.Header.Set("Content-Type", "text/plain") + httpC := http.Client{Transport: dmsghttp.MakeHTTPTransport(ctx, dmsgC)} + req, err := http.NewRequest(http.MethodPost, parsedURL.String(), strings.NewReader(dmsgcurlData)) + if err != nil { + dmsgcurlLog.WithError(err).Fatal("Failed to formulate HTTP request.") + } + req.Header.Set("Content-Type", "text/plain") - resp, err := httpC.Do(req) - if err != nil { - dmsgcurlLog.WithError(err).Fatal("Failed to execute HTTP request.") - } + resp, err := httpC.Do(req) + if err != nil { + dmsgcurlLog.WithError(err).Warnf("Failed to execute HTTP request with discovery %s", disco) + continue + } + defer closeResponseBody(resp) - defer func() { - if err := resp.Body.Close(); err != nil { - dmsgcurlLog.WithError(err).Fatal("Failed to close response body") - } - }() - respBody, err := io.ReadAll(resp.Body) - if err != nil { - dmsgcurlLog.WithError(err).Fatal("Failed to read respose body.") - } - fmt.Println(string(respBody)) - } else { - file := os.Stdout - if dmsgcurlOutput != "" { - file, err = parseOutputFile(dmsgcurlOutput, replace) - } - if err != nil { - return fmt.Errorf("failed to prepare output file: %w", err) - } - defer func() { - if fErr := file.Close(); fErr != nil { - dmsgcurlLog.WithError(fErr).Warn("Failed to close output file.") - } - if err != nil { - if rErr := os.RemoveAll(file.Name()); rErr != nil { - dmsgcurlLog.WithError(rErr).Warn("Failed to remove output file.") - } - } - }() + respBody, err := io.ReadAll(resp.Body) + if err != nil { + dmsgcurlLog.WithError(err).Fatal("Failed to read response body.") + } + fmt.Println(string(respBody)) + return nil + } + return errors.New("all dmsg discovery addresses failed") +} - dmsgC, closeDmsg, err := startDmsg(ctx, pk, sk) - if err != nil { - return fmt.Errorf("failed to start dmsg: %w", err) - } - defer closeDmsg() +func handleDownload(ctx context.Context, pk cipher.PubKey, parsedURL *url.URL) error { + file, err := prepareOutputFile() + if err != nil { + return fmt.Errorf("failed to prepare output file: %w", err) + } + defer closeAndCleanFile(file, err) + + for _, disco := range dmsgDisc { + dmsgC, closeDmsg, err := startDmsg(ctx, pk, sk, disco) + if err != nil { + dmsgcurlLog.WithError(err).Warnf("Failed to start dmsg with discovery %s", disco) + continue + } + defer closeDmsg() - httpC := http.Client{Transport: dmsghttp.MakeHTTPTransport(ctx, dmsgC)} + httpC := http.Client{Transport: dmsghttp.MakeHTTPTransport(ctx, dmsgC)} - for i := 0; i < dmsgcurlTries; i++ { - if dmsgcurlOutput != "" { - dmsgcurlLog.Debugf("Download attempt %d/%d ...", i, dmsgcurlTries) - if _, err := file.Seek(0, 0); err != nil { - return fmt.Errorf("failed to reset file: %w", err) - } + for i := 0; i < dmsgcurlTries; i++ { + if dmsgcurlOutput != "" { + dmsgcurlLog.Debugf("Download attempt %d/%d ...", i, dmsgcurlTries) + if _, err := file.Seek(0, 0); err != nil { + return fmt.Errorf("failed to reset file: %w", err) } - if err := Download(ctx, dmsgcurlLog, &httpC, file, u.URL.String(), 0); err != nil { - dmsgcurlLog.WithError(err).Error() - select { - case <-ctx.Done(): - return ctx.Err() - case <-time.After(time.Duration(dmsgcurlWait) * time.Second): - continue - } + } + if err := download(ctx, dmsgcurlLog, &httpC, file, parsedURL.String(), 0); err != nil { + dmsgcurlLog.WithError(err).Error() + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(time.Duration(dmsgcurlWait) * time.Second): + continue } - - // download successful. - return nil } - return errors.New("all download attempts failed") - + return nil } - return nil - }, -} - -// 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") - } + return errors.New("all download attempts failed with all dmsg discovery addresses") +} - if u.Host == "" { - return errors.New("URL is missing a host") +func prepareOutputFile() (*os.File, error) { + if dmsgcurlOutput == "" { + return os.Stdout, nil } - - du.URL = *u - return du.Addr.Set(u.Host) + return parseOutputFile(dmsgcurlOutput, replace) } -func parseURL(args []string) (*URL, error) { - if len(args) == 0 { - return nil, errors.New("no URL(s) provided") +func closeAndCleanFile(file *os.File, err error) { + if fErr := file.Close(); fErr != nil { + dmsgcurlLog.WithError(fErr).Warn("Failed to close output file.") } - - if len(args) > 1 { - return nil, errors.New("multiple URLs is not yet supported") + if err != nil && file != os.Stdout { + if rErr := os.RemoveAll(file.Name()); rErr != nil { + dmsgcurlLog.WithError(rErr).Warn("Failed to remove output file.") + } } +} - var out URL - if err := out.fill(args[0]); err != nil { - return nil, fmt.Errorf("provided URL is invalid: %w", err) +func closeResponseBody(resp *http.Response) { + if err := resp.Body.Close(); err != nil { + dmsgcurlLog.WithError(err).Fatal("Failed to close response body") } - - return &out, nil } func parseOutputFile(output string, replace bool) (*os.File, error) { @@ -252,8 +225,8 @@ func parseOutputFile(output string, replace bool) (*os.File, error) { return nil, os.ErrExist } -func startDmsg(ctx context.Context, pk cipher.PubKey, sk cipher.SecKey) (dmsgC *dmsg.Client, stop func(), err error) { - dmsgC = dmsg.NewClient(pk, sk, disc.NewHTTP(dmsgDisc, &http.Client{}, dmsgcurlLog), &dmsg.Config{MinSessions: dmsgSessions}) +func startDmsg(ctx context.Context, pk cipher.PubKey, sk cipher.SecKey, disco string) (dmsgC *dmsg.Client, stop func(), err error) { + dmsgC = dmsg.NewClient(pk, sk, disc.NewHTTP(disco, &http.Client{}, dmsgcurlLog), &dmsg.Config{MinSessions: dmsgSessions}) go dmsgC.Serve(context.Background()) stop = func() { @@ -275,8 +248,7 @@ func startDmsg(ctx context.Context, pk cipher.PubKey, sk cipher.SecKey) (dmsgC * } } -// 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, maxSize int64) error { +func download(ctx context.Context, log logrus.FieldLogger, httpC *http.Client, w io.Writer, urlStr string, maxSize int64) error { req, err := http.NewRequest(http.MethodGet, urlStr, nil) if err != nil { log.WithError(err).Fatal("Failed to formulate HTTP request.") @@ -285,20 +257,14 @@ func Download(ctx context.Context, log logrus.FieldLogger, httpC *http.Client, w if err != nil { return fmt.Errorf("failed to connect to HTTP server: %w", err) } - if maxSize > 0 { - if resp.ContentLength > maxSize*1024 { - return fmt.Errorf("requested file size is more than allowed size: %d KB > %d KB", (resp.ContentLength / 1024), maxSize) - } + if maxSize > 0 && resp.ContentLength > maxSize*1024 { + return fmt.Errorf("requested file size is more than allowed size: %d KB > %d KB", (resp.ContentLength / 1024), maxSize) } - n, err := CancellableCopy(ctx, w, resp.Body, resp.ContentLength) + 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.") - } - }() + defer closeResponseBody(resp) return nil } @@ -307,38 +273,25 @@ 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 +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) { 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 } -// ProgressWriter prints the progress of a download to stdout. -type ProgressWriter struct { - // atomic requires 64-bit alignment for struct field access +type progressWriter struct { Current int64 Total int64 } -// Write implements io.Writer -func (pw *ProgressWriter) Write(p []byte) (int, error) { +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) @@ -350,11 +303,10 @@ func (pw *ProgressWriter) Write(p []byte) (int, error) { fmt.Print("\n") } } - return n, nil } -// Execute executes root CLI command. +// Execute executes the RootCmd func Execute() { if err := RootCmd.Execute(); err != nil { log.Fatal("Failed to execute command: ", err) From b43826a65fc69cb194821b0aecce3b65d5a41481 Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Thu, 26 Sep 2024 08:58:26 -0500 Subject: [PATCH 2/3] fix golangci-lint errors --- cmd/dmsg-server/commands/config/gen.go | 2 +- cmd/dmsg-server/commands/start/root.go | 4 ++-- cmd/dmsg-socks5/commands/dmsg-socks5.go | 4 ++-- cmd/dmsgcurl/commands/dmsgcurl.go | 5 ++--- cmd/dmsghttp/commands/dmsghttp.go | 2 +- cmd/dmsgip/commands/dmsgip.go | 8 +++----- cmd/dmsgpty-cli/commands/root.go | 2 +- cmd/dmsgpty-cli/commands/whitelist.go | 2 +- cmd/dmsgpty-host/commands/confgen.go | 7 +++---- cmd/dmsgpty-host/commands/root.go | 5 ++--- cmd/dmsgpty-ui/commands/dmsgpty-ui.go | 2 +- cmd/dmsgweb/commands/dmsgweb.go | 4 ++-- cmd/dmsgweb/commands/dmsgwebsrv.go | 2 +- internal/dmsg-discovery/api/entries_endpoint_test.go | 3 ++- pkg/disc/client_mock_test.go | 6 ++++-- pkg/dmsg/session_common.go | 2 +- pkg/dmsgcurl/dmsgcurl.go | 6 +++--- pkg/dmsghttp/examples_test.go | 3 ++- pkg/dmsghttp/http_test.go | 2 +- pkg/dmsghttp/util.go | 2 +- pkg/dmsgpty/cli_unix.go | 4 ++-- pkg/dmsgpty/host.go | 6 ++++-- pkg/noise/read_writer.go | 2 +- 23 files changed, 43 insertions(+), 42 deletions(-) diff --git a/cmd/dmsg-server/commands/config/gen.go b/cmd/dmsg-server/commands/config/gen.go index fac91bbf..22b278f1 100644 --- a/cmd/dmsg-server/commands/config/gen.go +++ b/cmd/dmsg-server/commands/config/gen.go @@ -26,7 +26,7 @@ func init() { var genConfigCmd = &cobra.Command{ Use: "gen", Short: "Generate a config file", - Run: func(cmd *cobra.Command, args []string) { + Run: func(_ *cobra.Command, _ []string) { mLog := logging.NewMasterLogger() mLog.SetLevel(logrus.InfoLevel) logger := mLog.PackageLogger("dmsg-server config generator") diff --git a/cmd/dmsg-server/commands/start/root.go b/cmd/dmsg-server/commands/start/root.go index d691d623..2c219dce 100644 --- a/cmd/dmsg-server/commands/start/root.go +++ b/cmd/dmsg-server/commands/start/root.go @@ -40,8 +40,8 @@ func init() { var RootCmd = &cobra.Command{ Use: "start", Short: "Start Dmsg Server", - PreRunE: func(cmd *cobra.Command, args []string) error { return sf.Check() }, - Run: func(_ *cobra.Command, args []string) { + PreRunE: func(_ *cobra.Command, _ []string) error { return sf.Check() }, + Run: func(_ *cobra.Command, _ []string) { if _, err := buildinfo.Get().WriteTo(os.Stdout); err != nil { log.Printf("Failed to output build info: %v", err) } diff --git a/cmd/dmsg-socks5/commands/dmsg-socks5.go b/cmd/dmsg-socks5/commands/dmsg-socks5.go index 5b084142..e7eac5c7 100644 --- a/cmd/dmsg-socks5/commands/dmsg-socks5.go +++ b/cmd/dmsg-socks5/commands/dmsg-socks5.go @@ -97,7 +97,7 @@ var serveCmd = &cobra.Command{ SilenceUsage: true, DisableSuggestions: true, DisableFlagsInUseLine: true, - Run: func(cmd *cobra.Command, args []string) { + Run: func(_ *cobra.Command, _ []string) { log := logging.MustGetLogger("ssh-proxy") interrupt := make(chan os.Signal, 1) signal.Notify(interrupt, os.Interrupt) @@ -178,7 +178,7 @@ var serveCmd = &cobra.Command{ var proxyCmd = &cobra.Command{ Use: "client", Short: "socks5 proxy client for dmsg socks5 proxy server", - Run: func(cmd *cobra.Command, args []string) { + Run: func(_ *cobra.Command, _ []string) { log := logging.MustGetLogger("ssh-proxy-client") var pubKey cipher.PubKey err := pubKey.Set(pubk) diff --git a/cmd/dmsgcurl/commands/dmsgcurl.go b/cmd/dmsgcurl/commands/dmsgcurl.go index 9baa8ef7..3d1e4798 100644 --- a/cmd/dmsgcurl/commands/dmsgcurl.go +++ b/cmd/dmsgcurl/commands/dmsgcurl.go @@ -3,7 +3,6 @@ package commands import ( "context" - "encoding/json" "errors" "fmt" "io" @@ -18,11 +17,11 @@ import ( "time" "github.com/sirupsen/logrus" - "github.com/skycoin/skywire" "github.com/skycoin/skywire-utilities/pkg/buildinfo" "github.com/skycoin/skywire-utilities/pkg/cipher" "github.com/skycoin/skywire-utilities/pkg/cmdutil" "github.com/skycoin/skywire-utilities/pkg/logging" + "github.com/skycoin/skywire-utilities/pkg/skyenv" "github.com/spf13/cobra" "github.com/skycoin/dmsg/pkg/disc" @@ -221,7 +220,7 @@ func parseOutputFile(output string, replace bool) (*os.File, error) { return nil, statErr } if replace { - return os.OpenFile(filepath.Clean(output), os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.ModePerm) + return os.OpenFile(filepath.Clean(output), os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.ModePerm) //nolint } return nil, os.ErrExist } diff --git a/cmd/dmsghttp/commands/dmsghttp.go b/cmd/dmsghttp/commands/dmsghttp.go index 647fa294..292957fc 100644 --- a/cmd/dmsghttp/commands/dmsghttp.go +++ b/cmd/dmsghttp/commands/dmsghttp.go @@ -62,7 +62,7 @@ DMSG http file server`, DisableFlagsInUseLine: true, Version: buildinfo.Version(), - Run: func(cmd *cobra.Command, args []string) { + Run: func(_ *cobra.Command, _ []string) { log := logging.MustGetLogger("dmsghttp") if dmsgDisc == "" { log.Fatal("Dmsg Discovery URL not specified") diff --git a/cmd/dmsgip/commands/dmsgip.go b/cmd/dmsgip/commands/dmsgip.go index 2b6a14ab..1626d5bf 100644 --- a/cmd/dmsgip/commands/dmsgip.go +++ b/cmd/dmsgip/commands/dmsgip.go @@ -54,14 +54,12 @@ DMSG ip utility`, DisableSuggestions: true, DisableFlagsInUseLine: true, Version: buildinfo.Version(), - PreRun: func(cmd *cobra.Command, args []string) { + RunE: func(_ *cobra.Command, _ []string) error { + log := logging.MustGetLogger("dmsgip") + if dmsgDisc == "" { dmsgDisc = skyenv.DmsgDiscAddr } - }, - RunE: func(cmd *cobra.Command, args []string) error { - log := logging.MustGetLogger("dmsgip") - if logLvl != "" { if lvl, err := logging.LevelFromString(logLvl); err == nil { logging.SetLevel(lvl) diff --git a/cmd/dmsgpty-cli/commands/root.go b/cmd/dmsgpty-cli/commands/root.go index ad57f386..811b7b23 100644 --- a/cmd/dmsgpty-cli/commands/root.go +++ b/cmd/dmsgpty-cli/commands/root.go @@ -104,7 +104,7 @@ DMSG pseudoterminal command line interface`, remoteAddr.Port = dmsgpty.DefaultPort } }, - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(_ *cobra.Command, _ []string) error { if _, err := buildinfo.Get().WriteTo(log.Writer()); err != nil { log.Printf("Failed to output build info: %v", err) } diff --git a/cmd/dmsgpty-cli/commands/whitelist.go b/cmd/dmsgpty-cli/commands/whitelist.go index 3f31bba1..4d0e7e96 100644 --- a/cmd/dmsgpty-cli/commands/whitelist.go +++ b/cmd/dmsgpty-cli/commands/whitelist.go @@ -19,7 +19,7 @@ func init() { var whitelistCmd = &cobra.Command{ Use: "whitelist", Short: "lists all whitelisted public keys", - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(_ *cobra.Command, _ []string) error { wlC, err := cli.WhitelistClient() if err != nil { return err diff --git a/cmd/dmsgpty-host/commands/confgen.go b/cmd/dmsgpty-host/commands/confgen.go index c097c6c7..ba0c1e7d 100644 --- a/cmd/dmsgpty-host/commands/confgen.go +++ b/cmd/dmsgpty-host/commands/confgen.go @@ -20,10 +20,9 @@ func init() { } var confgenCmd = &cobra.Command{ - Use: "confgen ", - Short: "generates config file", - Args: cobra.MaximumNArgs(1), - PreRun: func(cmd *cobra.Command, args []string) {}, + Use: "confgen ", + Short: "generates config file", + Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { diff --git a/cmd/dmsgpty-host/commands/root.go b/cmd/dmsgpty-host/commands/root.go index 44dc9043..4c0eb111 100644 --- a/cmd/dmsgpty-host/commands/root.go +++ b/cmd/dmsgpty-host/commands/root.go @@ -84,8 +84,7 @@ DMSG host for pseudoterminal command line interface`, SilenceUsage: true, DisableSuggestions: true, DisableFlagsInUseLine: true, - PreRun: func(cmd *cobra.Command, args []string) {}, - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(cmd *cobra.Command, _ []string) error { conf, err := getConfig(cmd, false) if err != nil { return fmt.Errorf("failed to get config: %w", err) @@ -260,7 +259,7 @@ func fillConfigFromENV(conf dmsgpty.Config) (dmsgpty.Config, error) { return conf, fmt.Errorf("failed to parse dmsg port: %w", err) } - conf.DmsgPort = uint16(dmsgPort) + conf.DmsgPort = uint16(dmsgPort) //nolint } if val, ok := os.LookupEnv(envPrefix + "_CLINET"); ok { diff --git a/cmd/dmsgpty-ui/commands/dmsgpty-ui.go b/cmd/dmsgpty-ui/commands/dmsgpty-ui.go index 69ddad92..140a2312 100644 --- a/cmd/dmsgpty-ui/commands/dmsgpty-ui.go +++ b/cmd/dmsgpty-ui/commands/dmsgpty-ui.go @@ -43,7 +43,7 @@ var RootCmd = &cobra.Command{ │││││└─┐│ ┬├─┘ │ └┬┘───│ ││ ─┴┘┴ ┴└─┘└─┘┴ ┴ ┴ └─┘┴ ` + "DMSG pseudoterminal GUI", - Run: func(cmd *cobra.Command, args []string) { + Run: func(_ *cobra.Command, _ []string) { if _, err := buildinfo.Get().WriteTo(log.Writer()); err != nil { log.Printf("Failed to output build info: %v", err) } diff --git a/cmd/dmsgweb/commands/dmsgweb.go b/cmd/dmsgweb/commands/dmsgweb.go index 9d9d8497..46d3a453 100644 --- a/cmd/dmsgweb/commands/dmsgweb.go +++ b/cmd/dmsgweb/commands/dmsgweb.go @@ -99,7 +99,7 @@ dmsgweb conf file detected: ` + dmsgwebconffile DisableSuggestions: true, DisableFlagsInUseLine: true, Version: buildinfo.Version(), - Run: func(cmd *cobra.Command, _ []string) { + Run: func(_ *cobra.Command, _ []string) { if isEnvs { envfile := envfileLinux if runtime.GOOS == "windows" { @@ -391,7 +391,7 @@ func proxyTCPConn(n int) { defer wg.Done() defer conn.Close() //nolint - dmsgConn, err := dmsgC.DialStream(context.Background(), dmsg.Addr{PK: dialPK[n], Port: uint16(dmsgPorts[n])}) + dmsgConn, err := dmsgC.DialStream(context.Background(), dmsg.Addr{PK: dialPK[n], Port: uint16(dmsgPorts[n])}) //nolint if err != nil { log.Printf("Failed to dial dmsg address %v:%v %v", dialPK[n].String(), dmsgPorts[n], err) return diff --git a/cmd/dmsgweb/commands/dmsgwebsrv.go b/cmd/dmsgweb/commands/dmsgwebsrv.go index 04e9ca49..c7734934 100644 --- a/cmd/dmsgweb/commands/dmsgwebsrv.go +++ b/cmd/dmsgweb/commands/dmsgwebsrv.go @@ -152,7 +152,7 @@ func server() { var listN []net.Listener for _, dport := range dmsgPort { - lis, err := dmsgC.Listen(uint16(dport)) + lis, err := dmsgC.Listen(uint16(dport)) //nolint if err != nil { log.Fatalf("Error listening on port %d: %v", dport, err) } diff --git a/internal/dmsg-discovery/api/entries_endpoint_test.go b/internal/dmsg-discovery/api/entries_endpoint_test.go index 75689528..20c21657 100644 --- a/internal/dmsg-discovery/api/entries_endpoint_test.go +++ b/internal/dmsg-discovery/api/entries_endpoint_test.go @@ -54,7 +54,8 @@ func TestEntriesEndpoint(t *testing.T) { contentType: "application/json", responseIsEntry: true, entry: baseEntry, - entryPreHook: func(t *testing.T, e *disc.Entry, body *string) { + // entryPreHook: func(t *testing.T, e *disc.Entry, body *string) { + entryPreHook: func(t *testing.T, e *disc.Entry, _ *string) { err := e.Sign(sk) require.NoError(t, err) }, diff --git a/pkg/disc/client_mock_test.go b/pkg/disc/client_mock_test.go index b8976f8d..cade59a9 100644 --- a/pkg/disc/client_mock_test.go +++ b/pkg/disc/client_mock_test.go @@ -293,7 +293,8 @@ func TestNewMockUpdateEntriesEndpoint(t *testing.T) { name: "update entry iteration", responseShouldError: false, secretKey: sk, - storerPreHook: func(apiClient disc.APIClient, e *disc.Entry) { + // storerPreHook: func(apiClient disc.APIClient, e *disc.Entry) { + storerPreHook: func(_ disc.APIClient, e *disc.Entry) { e.Server.Address = "different one" }, }, @@ -301,7 +302,8 @@ func TestNewMockUpdateEntriesEndpoint(t *testing.T) { name: "update entry unauthorized", responseShouldError: true, secretKey: ephemeralSk1, - storerPreHook: func(apiClient disc.APIClient, e *disc.Entry) { + // storerPreHook: func(apiClient disc.APIClient, e *disc.Entry) { + storerPreHook: func(_ disc.APIClient, e *disc.Entry) { e.Server.Address = "different one" }, }, diff --git a/pkg/dmsg/session_common.go b/pkg/dmsg/session_common.go index 12e9c818..38bbdd9e 100644 --- a/pkg/dmsg/session_common.go +++ b/pkg/dmsg/session_common.go @@ -123,7 +123,7 @@ func (sc *SessionCommon) writeObject(w io.Writer, obj SignedObject) error { p := sc.ns.EncryptUnsafe(obj) sc.wMx.Unlock() p = append(make([]byte, 2), p...) - binary.BigEndian.PutUint16(p, uint16(len(p)-2)) + binary.BigEndian.PutUint16(p, uint16(len(p)-2)) //nolint _, err := w.Write(p) return err } diff --git a/pkg/dmsgcurl/dmsgcurl.go b/pkg/dmsgcurl/dmsgcurl.go index d713115e..5a32d63f 100644 --- a/pkg/dmsgcurl/dmsgcurl.go +++ b/pkg/dmsgcurl/dmsgcurl.go @@ -43,10 +43,10 @@ func New(fs *flag.FlagSet) *DmsgCurl { 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) + _, _ = fmt.Fprintf(w, "Skycoin %s %s, wget over dmsg.\n", ExecName, Version) //nolint + _, _ = fmt.Fprintf(w, "Usage: %s [OPTION]... [URL]\n\n", ExecName) //nolint flag.PrintDefaults() - _, _ = fmt.Fprintln(w, "") + _, _ = fmt.Fprintln(w, "") //nolint } return dg diff --git a/pkg/dmsghttp/examples_test.go b/pkg/dmsghttp/examples_test.go index df949313..b3e01c15 100644 --- a/pkg/dmsghttp/examples_test.go +++ b/pkg/dmsghttp/examples_test.go @@ -74,7 +74,8 @@ func ExampleMakeHTTPTransport() { }() r := chi.NewRouter() - r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + // r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + r.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write([]byte("

Hello World!

")) //nolint:errcheck }) go func() { _ = http.Serve(lis, r) }() //nolint diff --git a/pkg/dmsghttp/http_test.go b/pkg/dmsghttp/http_test.go index d098c787..7f69876e 100644 --- a/pkg/dmsghttp/http_test.go +++ b/pkg/dmsghttp/http_test.go @@ -86,7 +86,7 @@ func (r httpClientResult) Assert(t *testing.T, i int) { func startHTTPServer(t *testing.T, results chan httpServerResult, lis net.Listener) { r := chi.NewRouter() - r.HandleFunc(endpointHTML, func(w http.ResponseWriter, r *http.Request) { + r.HandleFunc(endpointHTML, func(w http.ResponseWriter, _ *http.Request) { result := httpServerResult{Path: endpointHTML} n, err := w.Write(endpointHTMLData) diff --git a/pkg/dmsghttp/util.go b/pkg/dmsghttp/util.go index af97bc7b..dfe93cf1 100644 --- a/pkg/dmsghttp/util.go +++ b/pkg/dmsghttp/util.go @@ -52,7 +52,7 @@ func UpdateServers(ctx context.Context, dClient disc.APIClient, dmsgDisc string, for { select { case <-ctx.Done(): - return + return entries case <-ticker.C: servers, err := dmsgclient.AllServers(ctx) if err != nil { diff --git a/pkg/dmsgpty/cli_unix.go b/pkg/dmsgpty/cli_unix.go index d4b20157..bd80167a 100644 --- a/pkg/dmsgpty/cli_unix.go +++ b/pkg/dmsgpty/cli_unix.go @@ -47,7 +47,7 @@ func getPtySize(t *os.File) (*pty.Winsize, error) { // prepareStdin sets stdin to raw mode and provides a function to restore the original state. func (cli *CLI) prepareStdin() (restore func(), err error) { var oldState *term.State - if oldState, err = term.MakeRaw(int(os.Stdin.Fd())); err != nil { + if oldState, err = term.MakeRaw(int(os.Stdin.Fd())); err != nil { //nolint cli.Log. WithError(err). Warn("Failed to set stdin to raw mode.") @@ -55,7 +55,7 @@ func (cli *CLI) prepareStdin() (restore func(), err error) { } restore = func() { // Attempt to restore state. - if err = term.Restore(int(os.Stdin.Fd()), oldState); err != nil { + if err = term.Restore(int(os.Stdin.Fd()), oldState); err != nil { //nolint cli.Log. WithError(err). Error("Failed to restore original stdin state.") diff --git a/pkg/dmsgpty/host.go b/pkg/dmsgpty/host.go index 6784ae2f..7ebaa920 100644 --- a/pkg/dmsgpty/host.go +++ b/pkg/dmsgpty/host.go @@ -210,13 +210,15 @@ func dmsgEndpoints(h *Host) (mux hostMux) { } func handleWhitelist(h *Host) handleFunc { - return func(ctx context.Context, uri *url.URL, rpcS *rpc.Server) error { + // return func(ctx context.Context, uri *url.URL, rpcS *rpc.Server) error { + return func(_ context.Context, _ *url.URL, rpcS *rpc.Server) error { return rpcS.RegisterName(WhitelistRPCName, NewWhitelistGateway(h.wl)) } } func handlePty(h *Host) handleFunc { - return func(ctx context.Context, uri *url.URL, rpcS *rpc.Server) error { + // return func(ctx context.Context, uri *url.URL, rpcS *rpc.Server) error { + return func(ctx context.Context, _ *url.URL, rpcS *rpc.Server) error { pty := NewPty() go func() { <-ctx.Done() diff --git a/pkg/noise/read_writer.go b/pkg/noise/read_writer.go index 8315753f..17cf1806 100644 --- a/pkg/noise/read_writer.go +++ b/pkg/noise/read_writer.go @@ -263,7 +263,7 @@ func ResponderHandshake(ns *Noise, r *bufio.Reader, w io.Writer) error { // It returns the bytes written. func WriteRawFrame(w io.Writer, p []byte) ([]byte, error) { buf := make([]byte, prefixSize+len(p)) - binary.BigEndian.PutUint16(buf, uint16(len(p))) + binary.BigEndian.PutUint16(buf, uint16(len(p))) //nolint copy(buf[prefixSize:], p) n, err := w.Write(buf) From 8470f5b9882340421f987983b0cdaf244a72341b Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Fri, 4 Oct 2024 10:51:41 -0500 Subject: [PATCH 3/3] continue multi dmsg disc implementation --- cmd/dmsgcurl/commands/dmsgcurl.go | 5 ++--- cmd/dmsgweb/commands/dmsgweb.go | 7 ++----- cmd/dmsgweb/commands/dmsgwebsrv.go | 2 +- cmd/dmsgweb/commands/root.go | 2 +- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/cmd/dmsgcurl/commands/dmsgcurl.go b/cmd/dmsgcurl/commands/dmsgcurl.go index 3d1e4798..03d5c214 100644 --- a/cmd/dmsgcurl/commands/dmsgcurl.go +++ b/cmd/dmsgcurl/commands/dmsgcurl.go @@ -21,7 +21,6 @@ import ( "github.com/skycoin/skywire-utilities/pkg/cipher" "github.com/skycoin/skywire-utilities/pkg/cmdutil" "github.com/skycoin/skywire-utilities/pkg/logging" - "github.com/skycoin/skywire-utilities/pkg/skyenv" "github.com/spf13/cobra" "github.com/skycoin/dmsg/pkg/disc" @@ -44,7 +43,7 @@ var ( ) func init() { - RootCmd.Flags().StringSliceVarP(&dmsgDisc, "dmsg-disc", "c", []string{skyenv.DmsgDiscAddr}, "dmsg discovery url(s)") + RootCmd.Flags().StringSliceVarP(&dmsgDisc, "dmsg-disc", "c", []string{dmsg.DiscAddr(false)}, "dmsg discovery url(s)") RootCmd.Flags().IntVarP(&dmsgSessions, "sess", "e", 1, "number of dmsg servers to connect to") RootCmd.Flags().StringVarP(&logLvl, "loglvl", "l", "fatal", "[ debug | warn | error | fatal | panic | trace | info ]") RootCmd.Flags().StringVarP(&dmsgcurlData, "data", "d", "", "dmsghttp POST data") @@ -73,7 +72,7 @@ var RootCmd = &cobra.Command{ Version: buildinfo.Version(), RunE: func(_ *cobra.Command, args []string) error { if len(dmsgDisc) == 0 || dmsgDisc[0] == "" { - dmsgDisc = []string{skyenv.DmsgDiscAddr} + dmsgDisc = []string{dmsg.DiscAddr(false)} } if dmsgcurlLog == nil { dmsgcurlLog = logging.MustGetLogger("dmsgcurl") diff --git a/cmd/dmsgweb/commands/dmsgweb.go b/cmd/dmsgweb/commands/dmsgweb.go index 46d3a453..a1e1a639 100644 --- a/cmd/dmsgweb/commands/dmsgweb.go +++ b/cmd/dmsgweb/commands/dmsgweb.go @@ -60,7 +60,7 @@ func init() { RootCmd.Flags().StringVarP(&addProxy, "proxy", "r", scriptExecString("${ADDPROXY}", dmsgwebconffile), "configure additional socks5 proxy for dmsgweb (i.e. 127.0.0.1:1080)") RootCmd.Flags().UintSliceVarP(&webPort, "port", "p", scriptExecUintSlice("${WEBPORT[@]:-8080}", dmsgwebconffile), "port(s) to serve the web application") RootCmd.Flags().StringSliceVarP(&resolveDmsgAddr, "resolve", "t", scriptExecStringSlice("${RESOLVEPK[@]}", dmsgwebconffile), "resolve the specified dmsg address:port on the local port & disable proxy") - RootCmd.Flags().StringVarP(&dmsgDisc, "dmsg-disc", "d", dmsg.DiscAddr(false), "dmsg discovery url") + RootCmd.Flags().StringSliceVarP(&dmsgDisc, "dmsg-disc", "c", []string{dmsg.DiscAddr(false)}, "dmsg discovery url(s)") RootCmd.Flags().IntVarP(&dmsgSessions, "sess", "e", scriptExecInt("${DMSGSESSIONS:-1}", dmsgwebconffile), "number of dmsg servers to connect to") RootCmd.Flags().BoolSliceVarP(&rawTCP, "rt", "c", scriptExecBoolSlice("${RAWTCP[@]:-false}", dmsgwebconffile), "proxy local port as raw TCP") RootCmd.Flags().StringVarP(&logLvl, "loglvl", "l", "", "[ debug | warn | error | fatal | panic | trace | info ]\033[0m") @@ -130,7 +130,7 @@ dmsgweb conf file detected: ` + dmsgwebconffile logging.SetLevel(lvl) } } - if dmsgDisc == "" { + if len(dmsgDisc) == 0 || dmsgDisc[0] == "" { dmsgWebLog.Fatal("Dmsg Discovery URL not specified") } @@ -168,9 +168,6 @@ dmsgweb conf file detected: ` + dmsgwebconffile if filterDomainSuffix == "" { dmsgWebLog.Fatal("domain suffix to filter cannot be an empty string") } - if dmsgDisc == "" { - dmsgDisc = dmsg.DiscAddr(false) - } ctx, cancel := cmdutil.SignalContext(context.Background(), dmsgWebLog) defer cancel() diff --git a/cmd/dmsgweb/commands/dmsgwebsrv.go b/cmd/dmsgweb/commands/dmsgwebsrv.go index c7734934..065fba8e 100644 --- a/cmd/dmsgweb/commands/dmsgwebsrv.go +++ b/cmd/dmsgweb/commands/dmsgwebsrv.go @@ -35,7 +35,7 @@ func init() { srvCmd.Flags().UintSliceVarP(&localPort, "lport", "l", scriptExecUintSlice("${LOCALPORT[@]:-8086}", dmsgwebsrvconffile), "local application http interface port(s)") srvCmd.Flags().UintSliceVarP(&dmsgPort, "dport", "d", scriptExecUintSlice("${DMSGPORT[@]:-80}", dmsgwebsrvconffile), "dmsg port(s) to serve") srvCmd.Flags().StringSliceVarP(&wl, "wl", "w", scriptExecStringSlice("${WHITELISTPKS[@]}", dmsgwebsrvconffile), "whitelisted keys for dmsg authenticated routes\r") - srvCmd.Flags().StringVarP(&dmsgDisc, "dmsg-disc", "D", dmsg.DiscAddr(false), "dmsg discovery url") + srvCmd.Flags().StringSliceVarP(&dmsgDisc, "dmsg-disc", "c", []string{dmsg.DiscAddr(false)}, "dmsg discovery url(s)") srvCmd.Flags().IntVarP(&dmsgSess, "dsess", "e", scriptExecInt("${DMSGSESSIONS:-1}", dmsgwebsrvconffile), "dmsg sessions") srvCmd.Flags().BoolSliceVarP(&rawTCP, "rt", "c", scriptExecBoolSlice("${RAWTCP[@]:-false}", dmsgwebsrvconffile), "proxy local port as raw TCP") if os.Getenv("DMSGWEBSRVSK") != "" { diff --git a/cmd/dmsgweb/commands/root.go b/cmd/dmsgweb/commands/root.go index 091a3123..7e5adfc4 100644 --- a/cmd/dmsgweb/commands/root.go +++ b/cmd/dmsgweb/commands/root.go @@ -26,7 +26,7 @@ import ( var ( httpC http.Client dmsgC *dmsg.Client - dmsgDisc string + dmsgDisc []string dmsgSessions int dmsgAddr []string dialPK []cipher.PubKey