From bf9703cbfa434ee583ef168aeb3dcd9a5df0d5ed Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Sun, 23 Jun 2024 12:30:10 -0500 Subject: [PATCH 1/6] update system survey to include more of the deployment configuration --- cmd/skywire-cli/commands/survey/root.go | 98 +++++++++++++++++++------ pkg/visor/survey.go | 29 ++++---- 2 files changed, 90 insertions(+), 37 deletions(-) diff --git a/cmd/skywire-cli/commands/survey/root.go b/cmd/skywire-cli/commands/survey/root.go index c791ea2354..df283d6073 100644 --- a/cmd/skywire-cli/commands/survey/root.go +++ b/cmd/skywire-cli/commands/survey/root.go @@ -2,26 +2,52 @@ package clisurvey import ( - "crypto/sha256" "encoding/json" "fmt" "os" "github.com/spf13/cobra" + "github.com/skycoin/skywire-utilities/pkg/buildinfo" + "github.com/skycoin/skywire-utilities/pkg/logging" "github.com/skycoin/skywire/cmd/skywire-cli/internal" "github.com/skycoin/skywire/pkg/visor/visorconfig" ) var ( - // pk cipher.PubKey - // pkString string - isCksum bool + logger = logging.MustGetLogger("skywire-visor") //nolint:unused + isCksum bool + mLog = logging.NewMasterLogger() + log = mLog.PackageLogger("survey") + confPath string + // stdin bool + // confArg string + visorBuildInfo *buildinfo.Info + pkg bool + usr bool + pkgconfigexists bool + userconfigexists bool + conf *visorconfig.V1 + useConf bool ) func init() { surveyCmd.Flags().SortFlags = false - surveyCmd.Flags().BoolVarP(&isCksum, "sha", "s", false, "generate checksum of system survey") + surveyCmd.Flags().StringVarP(&confPath, "config", "c", "", "optionl config file to use (i.e.: "+visorconfig.ConfigName+")") + // surveyCmd.Flags().StringVarP(&confArg, "confarg", "C", "", "supply config as argument") + // surveyCmd.Flags().BoolVarP(&stdin, "stdin", "n", false, "read config from stdin") + if _, err := os.Stat(visorconfig.SkywirePath + "/" + visorconfig.ConfigJSON); err == nil { + pkgconfigexists = true + } + if _, err := os.Stat(visorconfig.HomePath() + "/" + visorconfig.ConfigName); err == nil { + userconfigexists = true + } + if pkgconfigexists { + surveyCmd.Flags().BoolVarP(&pkg, "pkg", "p", false, "use package config "+visorconfig.SkywirePath+"/"+visorconfig.ConfigJSON) + } + if userconfigexists { + surveyCmd.Flags().BoolVarP(&usr, "user", "u", false, "use config at: "+visorconfig.HomePath()+"/"+visorconfig.ConfigName) + } } // RootCmd is surveyCmd @@ -33,36 +59,60 @@ var surveyCmd = &cobra.Command{ Short: "system survey", Long: "print the system survey", Run: func(cmd *cobra.Command, args []string) { + if pkg { + confPath = visorconfig.SkywirePath + "/" + visorconfig.ConfigJSON + } + if usr { + confPath = visorconfig.HomePath() + "/" + visorconfig.ConfigName + } + // if confPath != "" && confArg != "" { + // log.Fatal("cannot specify both --config, -c and --confarg, -C") + // } + // if confPath != "" && stdin { + // log.Fatal("cannot specify both --config, -c and --stdin, -n") + // } + // if stdin && confArg != "" { + // log.Fatal("cannot specify both --confarg, -C and --stdin, -n") + // } + // if stdin || confArg != "" || confPath != "" { + + if confPath != "" { + // conf = initConfig() + confJSON, err := os.ReadFile(confPath) + if err != nil { + log.WithError(err).Fatal("Failed to read config file: %v", err) + } + err = json.Unmarshal(confJSON, &conf) + if err != nil { + log.WithError(err).Fatal("Failed to unmarshal old config json") + } + } survey, err := visorconfig.SystemSurvey() if err != nil { internal.Catch(cmd.Flags(), fmt.Errorf("Failed to generate system survey: %v", err)) } - // //non-critical logic implemented with bitfield/script - // pkString, err = script.Exec(`skywire-cli visor pk -p`).String() - // //fail silently or proceed on nil error - // if err != nil { - // internal.Catch(cmd.Flags(), fmt.Errorf("failed to fetch visor public key: %v", err)) - // } else { - // err = pk.Set(pkString) - // if err != nil { - // internal.Catch(cmd.Flags(), fmt.Errorf("failed to validate visor public key: %v", err)) - // } else { - // survey.PubKey = pk - // } - // } skyaddr, err := os.ReadFile(visorconfig.PackageConfig().LocalPath + "/" + visorconfig.RewardFile) //nolint if err == nil { survey.SkycoinAddress = string(skyaddr) } - + if conf != nil { + survey.PubKey = conf.PK + survey.ServicesURLs.DmsgDiscovery = conf.Dmsg.Discovery + survey.ServicesURLs.TransportDiscovery = conf.Transport.Discovery + survey.ServicesURLs.AddressResolver = conf.Transport.AddressResolver + survey.ServicesURLs.RouteFinder = conf.Routing.RouteFinder + survey.ServicesURLs.RouteSetupNodes = conf.Routing.RouteSetupNodes + survey.ServicesURLs.TransportSetupPKs = conf.Transport.TransportSetupPKs + survey.ServicesURLs.UptimeTracker = conf.UptimeTracker.Addr + survey.ServicesURLs.ServiceDiscovery = conf.Launcher.ServiceDisc + survey.ServicesURLs.SurveyWhitelist = conf.SurveyWhitelist + survey.ServicesURLs.StunServers = conf.StunServers + //survey.DmsgServers = v.dmsgC.ConnectedServersPK() + } s, err := json.MarshalIndent(survey, "", "\t") if err != nil { internal.PrintFatalError(cmd.Flags(), fmt.Errorf("Could not marshal json: %v", err)) } - if isCksum { - fmt.Printf("%x/n", sha256.Sum256([]byte(s))) - } else { - fmt.Printf("%s", s) - } + fmt.Printf("%s", s) }, } diff --git a/pkg/visor/survey.go b/pkg/visor/survey.go index f81ce918d5..24107be62c 100644 --- a/pkg/visor/survey.go +++ b/pkg/visor/survey.go @@ -32,29 +32,32 @@ func GenerateSurvey(v *Visor, log *logging.Logger, routine bool) { log.Info("Skycoin reward address: ", cAddr.String()) //generate the system survey pathutil.EnsureDir(v.conf.LocalPath) //nolint - generatedSurvey, err := visconf.SystemSurvey() + survey, err := visconf.SystemSurvey() if err != nil { log.WithError(err).Error("Could not read system info.") return } - generatedSurvey.PubKey = v.conf.PK - generatedSurvey.SkycoinAddress = cAddr.String() - - generatedSurvey.ServicesURLs.TransportDiscovery = v.conf.Transport.Discovery - generatedSurvey.ServicesURLs.AddressResolver = v.conf.Transport.AddressResolver - generatedSurvey.ServicesURLs.RouteFinder = v.conf.Routing.RouteFinder - generatedSurvey.ServicesURLs.RouteSetupNodes = v.conf.Routing.RouteSetupNodes - generatedSurvey.ServicesURLs.UptimeTracker = v.conf.UptimeTracker.Addr - generatedSurvey.ServicesURLs.ServiceDiscovery = v.conf.Launcher.ServiceDisc - generatedSurvey.DmsgServers = v.dmsgC.ConnectedServersPK() + survey.PubKey = v.conf.PK + survey.SkycoinAddress = cAddr.String() + survey.ServicesURLs.DmsgDiscovery = v.conf.Dmsg.Discovery + survey.ServicesURLs.TransportDiscovery = v.conf.Transport.Discovery + survey.ServicesURLs.AddressResolver = v.conf.Transport.AddressResolver + survey.ServicesURLs.RouteFinder = v.conf.Routing.RouteFinder + survey.ServicesURLs.RouteSetupNodes = v.conf.Routing.RouteSetupNodes + survey.ServicesURLs.TransportSetupPKs = v.conf.Transport.TransportSetupPKs + survey.ServicesURLs.UptimeTracker = v.conf.UptimeTracker.Addr + survey.ServicesURLs.ServiceDiscovery = v.conf.Launcher.ServiceDisc + survey.ServicesURLs.SurveyWhitelist = v.conf.SurveyWhitelist + survey.ServicesURLs.StunServers = v.conf.StunServers + survey.DmsgServers = v.dmsgC.ConnectedServersPK() log.Info("Generating system survey") v.surveyLock.Lock() - v.survey = generatedSurvey + v.survey = survey v.surveyLock.Unlock() // Save survey as file - s, err := json.MarshalIndent(generatedSurvey, "", "\t") + s, err := json.MarshalIndent(survey, "", "\t") if err != nil { log.WithError(err).Error("Could not marshal json.") return From 5ac5c962110e01913504e2d49071c9b340dceaf1 Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Sun, 23 Jun 2024 12:43:38 -0500 Subject: [PATCH 2/6] update dmsg dependency --- go.mod | 11 +- go.sum | 4 +- .../dmsg/cmd/dmsgweb/commands/dmsgweb.go | 695 +++++------------- .../dmsg/cmd/dmsgweb/commands/dmsgwebsrv.go | 281 +++++++ .../skycoin/dmsg/cmd/dmsgweb/commands/root.go | 400 ++++++++++ .../github.com/skycoin/dmsg/pkg/dmsg/const.go | 4 +- .../dmsg/pkg/dmsgctrl/serve_listener.go | 4 +- .../skycoin/dmsg/pkg/dmsgpty/ui_windows.go | 4 +- vendor/modules.txt | 2 +- 9 files changed, 867 insertions(+), 538 deletions(-) create mode 100644 vendor/github.com/skycoin/dmsg/cmd/dmsgweb/commands/dmsgwebsrv.go create mode 100644 vendor/github.com/skycoin/dmsg/cmd/dmsgweb/commands/root.go diff --git a/go.mod b/go.mod index d1d6902acf..687f944256 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/robert-nix/ansihtml v1.0.1 github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 github.com/sirupsen/logrus v1.9.3 - github.com/skycoin/dmsg v1.3.22-0.20240520184015-5d7616ee506a + github.com/skycoin/dmsg v1.3.22-0.20240622174622-39e439d5679d github.com/skycoin/skycoin v0.27.1 github.com/skycoin/skycoin-service-discovery v0.0.0-20240306165129-2af10aca698e github.com/skycoin/skywire-services v0.0.0-20240403004908-50ccbbf07004 @@ -191,3 +191,12 @@ replace github.com/xxxserxxx/gotop/v4 => github.com/ersonp/gotop/v4 v4.2.1 // replace github.com/skycoin/skywire-services => ../skywire-services // replace github.com/skycoin/skycoin-service-discovery => ../skycoin-service-discovery // replace github.com/skycoin/skywire-utilities => ../skywire-utilities + +// Uncomment to update other skywire deps to specific commit hash. +// run `go mod tidy ; go mod vendor` +// copy the changed line to the correct place in the above +// then, re-comment the line before saving. +// replace github.com/skycoin/dmsg => github.com/skycoin/dmsg +// replace github.com/skycoin/skywire-services => github.com/skycoin/skywire-services +// replace github.com/skycoin/skycoin-service-discovery => github.com/skycoin/skycoin-service-discovery +// replace github.com/skycoin/skywire-utilities => github.com/skycoin/skywire-utilities diff --git a/go.sum b/go.sum index f1eba23cce..ada2345d66 100644 --- a/go.sum +++ b/go.sum @@ -725,8 +725,8 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skycoin/dmsg v1.3.22-0.20240520184015-5d7616ee506a h1:GNEzS7oWScmzp4LBHTcSpRpo4ABbO6lblE4jnwlXgWw= -github.com/skycoin/dmsg v1.3.22-0.20240520184015-5d7616ee506a/go.mod h1:QMd7NXzarhpTJrdmJLCnqBqI0hMj0RIou9DI9s1e5mo= +github.com/skycoin/dmsg v1.3.22-0.20240622174622-39e439d5679d h1:nop/q3XL7GDMP9QpyuBV1fi5Y0rnI7iZeRdHtLfMNt4= +github.com/skycoin/dmsg v1.3.22-0.20240622174622-39e439d5679d/go.mod h1:QMd7NXzarhpTJrdmJLCnqBqI0hMj0RIou9DI9s1e5mo= 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.27.1 h1:HatxsRwVSPaV4qxH6290xPBmkH/HgiuAoY2qC+e8C9I= diff --git a/vendor/github.com/skycoin/dmsg/cmd/dmsgweb/commands/dmsgweb.go b/vendor/github.com/skycoin/dmsg/cmd/dmsgweb/commands/dmsgweb.go index fc79bb48fb..ca2ce14c91 100644 --- a/vendor/github.com/skycoin/dmsg/cmd/dmsgweb/commands/dmsgweb.go +++ b/vendor/github.com/skycoin/dmsg/cmd/dmsgweb/commands/dmsgweb.go @@ -8,8 +8,6 @@ import ( "log" "net" "net/http" - "net/http/httputil" - "net/url" "os" "os/signal" "path/filepath" @@ -17,9 +15,7 @@ import ( "runtime" "strconv" "strings" - "sync" "syscall" - "time" "github.com/bitfield/script" "github.com/confiant-inc/go-socks5" @@ -32,7 +28,6 @@ import ( "github.com/spf13/cobra" "golang.org/x/net/proxy" - "github.com/skycoin/dmsg/pkg/disc" dmsg "github.com/skycoin/dmsg/pkg/dmsg" "github.com/skycoin/dmsg/pkg/dmsghttp" ) @@ -56,23 +51,6 @@ func (r *customResolver) Resolve(ctx context.Context, name string) (context.Cont return ctx, nil, nil } -var ( - httpC http.Client - dmsgDisc string - dmsgSessions int - filterDomainSuffix string - sk cipher.SecKey - pk cipher.PubKey - dmsgWebLog *logging.Logger - logLvl string - webPort uint - proxyPort uint - addProxy string - resolveDmsgAddr string - wg sync.WaitGroup - isEnvs bool -) - const dmsgwebenvname = "DMSGWEB" var dmsgwebconffile = os.Getenv(dmsgwebenvname) @@ -82,16 +60,17 @@ func init() { RootCmd.Flags().StringVarP(&filterDomainSuffix, "filter", "f", ".dmsg", "domain suffix to filter") RootCmd.Flags().UintVarP(&proxyPort, "socks", "q", scriptExecUint("${PROXYPORT:-4445}", dmsgwebconffile), "port to serve the socks5 proxy") RootCmd.Flags().StringVarP(&addProxy, "proxy", "r", scriptExecString("${ADDPROXY}", dmsgwebconffile), "configure additional socks5 proxy for dmsgweb (i.e. 127.0.0.1:1080)") - RootCmd.Flags().UintVarP(&webPort, "port", "p", scriptExecUint("${WEBPORT:-8080}", dmsgwebconffile), "port to serve the web application") - RootCmd.Flags().StringVarP(&resolveDmsgAddr, "resolve", "t", scriptExecString("${RESOLVEPK}", dmsgwebconffile), "resolve the specified dmsg address:port on the local port & disable proxy") + 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", skyenv.DmsgDiscAddr, "dmsg discovery url") 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") - if os.Getenv("DMSGWEB_SK") != "" { - sk.Set(os.Getenv("DMSGWEB_SK")) //nolint + if os.Getenv("DMSGWEBSK") != "" { + sk.Set(os.Getenv("DMSGWEBSK")) //nolint } - if scriptExecString("${DMSGWEB_SK}", dmsgwebconffile) != "" { - sk.Set(scriptExecString("${DMSGWEB_SK}", dmsgwebconffile)) //nolint + if scriptExecString("${DMSGWEBSK}", dmsgwebconffile) != "" { + sk.Set(scriptExecString("${DMSGWEBSK}", dmsgwebconffile)) //nolint } RootCmd.Flags().VarP(&sk, "sk", "s", "a random key is generated if unspecified\n\r") RootCmd.Flags().BoolVarP(&isEnvs, "envs", "z", false, "show example .conf file") @@ -138,6 +117,7 @@ dmsgweb conf file detected: ` + dmsgwebconffile fmt.Println(envfile) os.Exit(0) } + c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, syscall.SIGTERM) //nolint go func() { @@ -153,6 +133,37 @@ dmsgweb conf file detected: ` + dmsgwebconffile } } + if len(resolveDmsgAddr) > 0 && len(webPort) != len(resolveDmsgAddr) { + dmsgWebLog.Fatal("-resolve --t flag cannot contain a different number of elements than -port -p flag") + } + if len(resolveDmsgAddr) == 0 && len(webPort) > 1 { + dmsgWebLog.Fatal("-port --p flag cannot specify multiple ports without specifying multiple dmsg address:port(s) to -resolve --t flag") + } + + seenResolveDmsgAddr := make(map[string]bool) + for _, item := range resolveDmsgAddr { + if seenResolveDmsgAddr[item] { + dmsgWebLog.Fatal("-resolve --t flag cannot contain duplicates") + } + seenResolveDmsgAddr[item] = true + } + + seenWebPort := make(map[uint]bool) + for _, item := range webPort { + if seenWebPort[item] { + dmsgWebLog.Fatal("-port --p flag cannot contain duplicates") + } + seenWebPort[item] = true + } + + if len(rawTCP) < len(resolveDmsgAddr) { + for len(rawTCP) < len(resolveDmsgAddr) { + rawTCP = append(rawTCP, false) + } + } else if len(rawTCP) > len(resolveDmsgAddr) { + rawTCP = rawTCP[:len(resolveDmsgAddr)] + } + if filterDomainSuffix == "" { dmsgWebLog.Fatal("domain suffix to filter cannot be an empty string") } @@ -166,7 +177,26 @@ dmsgweb conf file detected: ` + dmsgwebconffile if err != nil { pk, sk = cipher.GenerateKeyPair() } + dmsgWebLog.Info("dmsg client pk: %v", pk.String()) + if len(resolveDmsgAddr) > 0 { + for i, dmsgaddr := range resolveDmsgAddr { + dmsgAddr = strings.Split(dmsgaddr, ":") + err = dialPK[i].Set(dmsgAddr[0]) + if err != nil { + log.Fatalf("failed to parse dmsg
: : %v", err) + } + if len(dmsgAddr) > 1 { + dport, err := strconv.ParseUint(dmsgAddr[1], 10, 64) + if err != nil { + log.Fatalf("Failed to parse dmsg port: %v", err) + } + dmsgPorts[i] = uint(dport) + } else { + dmsgPorts[i] = uint(80) + } + } + } dmsgC, closeDmsg, err := startDmsg(ctx, pk, sk) if err != nil { dmsgWebLog.WithError(err).Fatal("failed to start dmsg") @@ -177,12 +207,12 @@ dmsgweb conf file detected: ` + dmsgwebconffile <-ctx.Done() cancel() closeDmsg() - os.Exit(0) //this should not be necessary + os.Exit(0) }() httpC = http.Client{Transport: dmsghttp.MakeHTTPTransport(ctx, dmsgC)} - if resolveDmsgAddr == "" { + if len(resolveDmsgAddr) == 0 { // Create a SOCKS5 server with custom name resolution conf := &socks5.Config{ Resolver: &customResolver{}, @@ -234,515 +264,139 @@ dmsgweb conf file detected: ` + dmsgwebconffile dmsgWebLog.Debug("Stopped serving SOCKS5 proxy on " + socksAddr) }() } - r := gin.New() - - r.Use(gin.Recovery()) - - r.Use(loggingMiddleware()) - r.Any("/*path", func(c *gin.Context) { - var urlStr string - if resolveDmsgAddr != "" { - urlStr = fmt.Sprintf("dmsg://%s%s", resolveDmsgAddr, c.Param("path")) - if c.Request.URL.RawQuery != "" { - urlStr = fmt.Sprintf("%s?%s", urlStr, c.Request.URL.RawQuery) - } + if len(resolveDmsgAddr) == 0 && len(webPort) == 1 { + if rawTCP[0] { + proxyTCPConn(-1) } else { - hostParts := strings.Split(c.Request.Host, ":") - var dmsgp string - if len(hostParts) > 1 { - dmsgp = hostParts[1] - } else { - dmsgp = "80" - } - urlStr = fmt.Sprintf("dmsg://%s:%s%s", strings.TrimRight(hostParts[0], filterDomainSuffix), dmsgp, c.Param("path")) - if c.Request.URL.RawQuery != "" { - urlStr = fmt.Sprintf("%s?%s", urlStr, c.Request.URL.RawQuery) - } + proxyHTTPConn(-1) } - - fmt.Printf("Proxying request: %s %s\n", c.Request.Method, urlStr) - req, err := http.NewRequest(c.Request.Method, urlStr, c.Request.Body) - if err != nil { - c.String(http.StatusInternalServerError, "Failed to create HTTP request") - return - } - - for header, values := range c.Request.Header { - for _, value := range values { - req.Header.Add(header, value) - } - } - - resp, err := httpC.Do(req) - if err != nil { - c.String(http.StatusInternalServerError, "Failed to connect to HTTP server") - fmt.Printf("Error: %v\n", err) - return - } - defer resp.Body.Close() //nolint - - for header, values := range resp.Header { - for _, value := range values { - c.Writer.Header().Add(header, value) + } else { + for i := range resolveDmsgAddr { + if rawTCP[i] { + proxyTCPConn(i) + } else { + proxyHTTPConn(i) } } - - c.Status(resp.StatusCode) - if _, err := io.Copy(c.Writer, resp.Body); err != nil { - c.String(http.StatusInternalServerError, "Failed to copy response body") - fmt.Printf("Error copying response body: %v\n", err) - } - }) - wg.Add(1) - go func() { - dmsgWebLog.Debug(fmt.Sprintf("Serving http on: http://127.0.0.1:%v", webPort)) - r.Run(":" + fmt.Sprintf("%v", webPort)) //nolint - dmsgWebLog.Debug(fmt.Sprintf("Stopped serving http on: http://127.0.0.1:%v", webPort)) - wg.Done() - }() + } wg.Wait() }, } -var ( - dmsgPort uint - dmsgSess int - wl string - wlkeys []cipher.PubKey - localPort uint - websrvPort uint - err error -) - -const dmsgwebsrvenvname = "DMSGWEBSRV" +func proxyHTTPConn(n int) { + r := gin.New() -var dmsgwebsrvconffile = os.Getenv(dmsgwebsrvenvname) + r.Use(gin.Recovery()) -func init() { - RootCmd.AddCommand(srvCmd) - srvCmd.Flags().UintVarP(&localPort, "lport", "l", scriptExecUint("${LOCALPORT:-8086}", dmsgwebsrvconffile), "local application http interface port") - srvCmd.Flags().UintVarP(&websrvPort, "port", "p", scriptExecUint("${WEBPORT:-8081}", dmsgwebsrvconffile), "port to serve") - srvCmd.Flags().UintVarP(&dmsgPort, "dport", "d", scriptExecUint("${DMSGPORT:-80}", dmsgwebsrvconffile), "dmsg port to serve") - srvCmd.Flags().StringVarP(&wl, "wl", "w", scriptExecArray("${WHITELISTPKS[@]}", dmsgwebsrvconffile), "whitelisted keys for dmsg authenticated routes\r") - srvCmd.Flags().StringVarP(&dmsgDisc, "dmsg-disc", "D", skyenv.DmsgDiscAddr, "dmsg discovery url") - srvCmd.Flags().IntVarP(&dmsgSess, "dsess", "e", scriptExecInt("${DMSGSESSIONS:-1}", dmsgwebsrvconffile), "dmsg sessions") - if os.Getenv("DMSGWEBSRV_SK") != "" { - sk.Set(os.Getenv("DMSGWEBSRV_SK")) //nolint - } - if scriptExecString("${DMSGWEBSRV_SK}", dmsgwebsrvconffile) != "" { - sk.Set(scriptExecString("${DMSGWEBSRV_SK}", dmsgwebsrvconffile)) //nolint - } - pk, _ = sk.PubKey() //nolint - srvCmd.Flags().VarP(&sk, "sk", "s", "a random key is generated if unspecified\n\r") - srvCmd.Flags().BoolVarP(&isEnvs, "envs", "z", false, "show example .conf file") + r.Use(loggingMiddleware()) - srvCmd.CompletionOptions.DisableDefaultCmd = true -} - -var srvCmd = &cobra.Command{ - Use: "srv", - Short: "serve http from local port over dmsg", - Long: `DMSG web server - serve http interface from local port over dmsg` + func() string { - if _, err := os.Stat(dmsgwebsrvconffile); err == nil { - return ` - dmsenv file detected: ` + dmsgwebsrvconffile - } - return ` - .conf file may also be specified with - ` + dmsgwebsrvenvname + `=/path/to/dmsgwebsrv.conf skywire dmsg web srv` - }(), - Run: func(_ *cobra.Command, _ []string) { - if isEnvs { - envfile := srvenvfileLinux - if runtime.GOOS == "windows" { - envfileslice, _ := script.Echo(envfile).Slice() //nolint - for i := range envfileslice { - efs, _ := script.Echo(envfileslice[i]).Reject("##").Reject("#-").Reject("# ").Replace("#", "#$").String() //nolint - if efs != "" && efs != "\n" { - envfileslice[i] = strings.ReplaceAll(efs, "\n", "") - } - } - envfile = strings.Join(envfileslice, "\n") + r.Any("/*path", func(c *gin.Context) { + var urlStr string + if n > -1 { + urlStr = fmt.Sprintf("dmsg://%s%s", resolveDmsgAddr[n], c.Param("path")) + if c.Request.URL.RawQuery != "" { + urlStr = fmt.Sprintf("%s?%s", urlStr, c.Request.URL.RawQuery) + } + } else { + hostParts := strings.Split(c.Request.Host, ":") + var dmsgp string + if len(hostParts) > 1 { + dmsgp = hostParts[1] + } else { + dmsgp = "80" + } + urlStr = fmt.Sprintf("dmsg://%s:%s%s", strings.TrimRight(hostParts[0], filterDomainSuffix), dmsgp, c.Param("path")) + if c.Request.URL.RawQuery != "" { + urlStr = fmt.Sprintf("%s?%s", urlStr, c.Request.URL.RawQuery) } - fmt.Println(envfile) - os.Exit(0) } - server() - }, -} -func server() { - log := logging.MustGetLogger("dmsgwebsrv") - - ctx, cancel := cmdutil.SignalContext(context.Background(), log) + fmt.Printf("Proxying request: %s %s\n", c.Request.Method, urlStr) + req, err := http.NewRequest(c.Request.Method, urlStr, c.Request.Body) + if err != nil { + c.String(http.StatusInternalServerError, "Failed to create HTTP request") + return + } - defer cancel() - pk, err = sk.PubKey() - if err != nil { - pk, sk = cipher.GenerateKeyPair() - } - if wl != "" { - wlk := strings.Split(wl, ",") - for _, key := range wlk { - var pk0 cipher.PubKey - err := pk0.Set(key) - if err == nil { - wlkeys = append(wlkeys, pk0) + for header, values := range c.Request.Header { + for _, value := range values { + req.Header.Add(header, value) } } - } - if len(wlkeys) > 0 { - if len(wlkeys) == 1 { - log.Info(fmt.Sprintf("%d key whitelisted", len(wlkeys))) - } else { - log.Info(fmt.Sprintf("%d keys whitelisted", len(wlkeys))) - } - } - dmsgC := dmsg.NewClient(pk, sk, disc.NewHTTP(dmsgDisc, &http.Client{}, log), dmsg.DefaultConfig()) - defer func() { - if err := dmsgC.Close(); err != nil { - log.WithError(err).Error() + resp, err := httpC.Do(req) + if err != nil { + c.String(http.StatusInternalServerError, "Failed to connect to HTTP server") + fmt.Printf("Error: %v\n", err) + return } - }() - - go dmsgC.Serve(context.Background()) - - select { - case <-ctx.Done(): - log.WithError(ctx.Err()).Warn() - return - - case <-dmsgC.Ready(): - } + defer resp.Body.Close() //nolint - lis, err := dmsgC.Listen(uint16(dmsgPort)) - if err != nil { - log.WithError(err).Fatal() - } - go func() { - <-ctx.Done() - if err := lis.Close(); err != nil { - log.WithError(err).Error() + for header, values := range resp.Header { + for _, value := range values { + c.Writer.Header().Add(header, value) + } } - }() - - r1 := gin.New() - r1.Use(gin.Recovery()) - r1.Use(loggingMiddleware()) - authRoute := r1.Group("/") - if len(wlkeys) > 0 { - authRoute.Use(whitelistAuth(wlkeys)) - } - authRoute.Any("/*path", func(c *gin.Context) { - targetURL, _ := url.Parse(fmt.Sprintf("http://127.0.0.1:%v%s?%s", localPort, c.Request.URL.Path, c.Request.URL.RawQuery)) //nolint - proxy := httputil.ReverseProxy{ - Director: func(req *http.Request) { - req.URL = targetURL - req.Host = targetURL.Host - req.Method = c.Request.Method - }, - Transport: &http.Transport{}, + c.Status(resp.StatusCode) + if _, err := io.Copy(c.Writer, resp.Body); err != nil { + c.String(http.StatusInternalServerError, "Failed to copy response body") + fmt.Printf("Error copying response body: %v\n", err) } - proxy.ServeHTTP(c.Writer, c.Request) }) - - serve := &http.Server{ - Handler: &ginHandler{Router: r1}, - ReadHeaderTimeout: 5 * time.Second, - ReadTimeout: 10 * time.Second, - WriteTimeout: 10 * time.Second, - } - - wg := new(sync.WaitGroup) wg.Add(1) go func() { - log.WithField("dmsg_addr", lis.Addr().String()).Info("Serving... ") - if err := serve.Serve(lis); err != nil && err != http.ErrServerClosed { - log.Fatalf("Serve1: %v", err) - } + dmsgWebLog.Debug(fmt.Sprintf("Serving http on: http://127.0.0.1:%v", webPort)) + r.Run(":" + fmt.Sprintf("%v", webPort)) //nolint + dmsgWebLog.Debug(fmt.Sprintf("Stopped serving http on: http://127.0.0.1:%v", webPort)) wg.Done() }() - - wg.Add(1) - go func() { - fmt.Printf("listening on http://127.0.0.1:%d using gin router\n", websrvPort) - r1.Run(fmt.Sprintf(":%d", websrvPort)) //nolint - wg.Done() - }() - - wg.Wait() -} - -func whitelistAuth(whitelistedPKs []cipher.PubKey) gin.HandlerFunc { - return func(c *gin.Context) { - remotePK, _, err := net.SplitHostPort(c.Request.RemoteAddr) - if err != nil { - c.Writer.WriteHeader(http.StatusInternalServerError) - c.Writer.Write([]byte("500 Internal Server Error")) //nolint - c.AbortWithStatus(http.StatusInternalServerError) - return - } - whitelisted := false - if len(whitelistedPKs) == 0 { - whitelisted = true - } else { - for _, whitelistedPK := range whitelistedPKs { - if remotePK == whitelistedPK.String() { - whitelisted = true - break - } - } - } - if whitelisted { - c.Next() - } else { - c.Writer.WriteHeader(http.StatusUnauthorized) - c.Writer.Write([]byte("401 Unauthorized")) //nolint - c.AbortWithStatus(http.StatusUnauthorized) - return - } - } -} - -type ginHandler struct { - Router *gin.Engine } - -func (h *ginHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - h.Router.ServeHTTP(w, r) -} - -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{}, dmsgWebLog), &dmsg.Config{MinSessions: dmsgSessions}) - go dmsgC.Serve(context.Background()) - - stop = func() { - err := dmsgC.Close() - dmsgWebLog.WithError(err).Debug("Disconnected from dmsg network.") - fmt.Printf("\n") - } - dmsgWebLog.WithField("public_key", pk.String()).WithField("dmsg_disc", dmsgDisc). - Debug("Connecting to dmsg network...") - - select { - case <-ctx.Done(): - stop() - os.Exit(0) - return nil, nil, ctx.Err() - - case <-dmsgC.Ready(): - dmsgWebLog.Debug("Dmsg network ready.") - return dmsgC, stop, nil +func proxyTCPConn(n int) { + listener, err := net.Listen("tcp", fmt.Sprintf(":%d", webPort[n])) + if err != nil { + log.Fatalf("Failed to start TCP listener on port %d: %v", webPort[n], err) } -} + defer listener.Close() //nolint + log.Printf("Serving TCP on 127.0.0.1:%d", webPort[n]) -func loggingMiddleware() gin.HandlerFunc { - return func(c *gin.Context) { - start := time.Now() - c.Next() - latency := time.Since(start) - if latency > time.Minute { - latency = latency.Truncate(time.Second) + for { + conn, err := listener.Accept() + if err != nil { + log.Printf("Failed to accept connection: %v", err) + continue } - statusCode := c.Writer.Status() - method := c.Request.Method - path := c.Request.URL.Path - // Get the background color based on the status code - statusCodeBackgroundColor := getBackgroundColor(statusCode) - // Get the method color - methodColor := getMethodColor(method) - // Print the logging in a custom format which includes the publickeyfrom c.Request.RemoteAddr ex.: - // [DMSGHTTP] 2023/05/18 - 19:43:15 | 200 | 10.80885ms | | 02b5ee5333aa6b7f5fc623b7d5f35f505cb7f974e98a70751cf41962f84c8c4637:49153 | GET /node-info.json - fmt.Printf("[DMSGWEB] %s |%s %3d %s| %13v | %15s | %72s |%s %-7s %s %s\n", - time.Now().Format("2006/01/02 - 15:04:05"), - statusCodeBackgroundColor, - statusCode, - resetColor(), - latency, - c.ClientIP(), - c.Request.RemoteAddr, - methodColor, - method, - resetColor(), - path, - ) - } -} -func getBackgroundColor(statusCode int) string { - switch { - case statusCode >= http.StatusOK && statusCode < http.StatusMultipleChoices: - return green - case statusCode >= http.StatusMultipleChoices && statusCode < http.StatusBadRequest: - return white - case statusCode >= http.StatusBadRequest && statusCode < http.StatusInternalServerError: - return yellow - default: - return red - } -} -func getMethodColor(method string) string { - switch method { - case http.MethodGet: - return blue - case http.MethodPost: - return cyan - case http.MethodPut: - return yellow - case http.MethodDelete: - return red - case http.MethodPatch: - return green - case http.MethodHead: - return magenta - case http.MethodOptions: - return white - default: - return reset - } -} - -func resetColor() string { - return reset -} - -const ( - green = "\033[97;42m" - white = "\033[90;47m" - yellow = "\033[90;43m" - red = "\033[97;41m" - blue = "\033[97;44m" - magenta = "\033[97;45m" - cyan = "\033[97;46m" - reset = "\033[0m" -) - -// Execute executes root CLI command. -func Execute() { - if err := RootCmd.Execute(); err != nil { - log.Fatal("Failed to execute command: ", err) - } -} + wg.Add(1) + go func(conn net.Conn, n int) { + defer wg.Done() + defer conn.Close() //nolint -func scriptExecString(s, envfile string) string { - if runtime.GOOS == "windows" { - var variable, defaultvalue string - if strings.Contains(s, ":-") { - parts := strings.SplitN(s, ":-", 2) - variable = parts[0] + "}" - defaultvalue = strings.TrimRight(parts[1], "}") - } else { - variable = s - defaultvalue = "" - } - out, err := script.Exec(fmt.Sprintf(`powershell -c '$SKYENV = "%s"; if ($SKYENV -ne "" -and (Test-Path $SKYENV)) { . $SKYENV }; echo %s"`, envfile, variable)).String() - if err == nil { - if (out == "") || (out == variable) { - return defaultvalue + dmsgConn, err := dmsgC.DialStream(context.Background(), dmsg.Addr{PK: dialPK[n], Port: uint16(dmsgPorts[n])}) + if err != nil { + log.Printf("Failed to dial dmsg address %v:%v %v", dialPK[n].String(), dmsgPorts[n], err) + return } - return strings.TrimRight(out, "\n") - } - return defaultvalue - } - z, err := script.Exec(fmt.Sprintf(`sh -c 'SKYENV=%s ; if [[ $SKYENV != "" ]] && [[ -f $SKYENV ]] ; then source $SKYENV ; fi ; printf "%s"'`, envfile, s)).String() - if err == nil { - return strings.TrimSpace(z) - } - return "" -} + defer dmsgConn.Close() //nolint -func scriptExecArray(s, envfile string) string { - if runtime.GOOS == "windows" { - variable := s - if strings.Contains(variable, "[@]}") { - variable = strings.TrimRight(variable, "[@]}") - variable = strings.TrimRight(variable, "{") - } - out, err := script.Exec(fmt.Sprintf(`powershell -c '$SKYENV = "%s"; if ($SKYENV -ne "" -and (Test-Path $SKYENV)) { . $SKYENV }; foreach ($item in %s) { Write-Host $item }'`, envfile, variable)).Slice() - if err == nil { - if len(out) != 0 { - return "" - } - return strings.Join(out, ",") - } - } - y, err := script.Exec(fmt.Sprintf(`bash -c 'SKYENV=%s ; if [[ $SKYENV != "" ]] && [[ -f $SKYENV ]] ; then source $SKYENV ; fi ; for _i in %s ; do echo "$_i" ; done'`, envfile, s)).Slice() - if err == nil { - return strings.Join(y, ",") - } - return "" -} + go func() { + _, err := io.Copy(dmsgConn, conn) + if err != nil { + log.Printf("Error copying data to dmsg server: %v", err) + } + dmsgConn.Close() //nolint + }() -func scriptExecInt(s, envfile string) int { - if runtime.GOOS == "windows" { - var variable string - if strings.Contains(s, ":-") { - parts := strings.SplitN(s, ":-", 2) - variable = parts[0] + "}" - } else { - variable = s - } - out, err := script.Exec(fmt.Sprintf(`powershell -c '$SKYENV = "%s"; if ($SKYENV -ne "" -and (Test-Path $SKYENV)) { . $SKYENV }; echo %s"`, envfile, variable)).String() - if err == nil { - if (out == "") || (out == variable) { - return 0 - } - i, err := strconv.Atoi(strings.TrimSpace(strings.TrimRight(out, "\n"))) - if err == nil { - return i - } - return 0 - } - return 0 - } - z, err := script.Exec(fmt.Sprintf(`sh -c 'SKYENV=%s ; if [[ $SKYENV != "" ]] && [[ -f $SKYENV ]] ; then source $SKYENV ; fi ; printf "%s"'`, envfile, s)).String() - if err == nil { - if z == "" { - return 0 - } - i, err := strconv.Atoi(z) - if err == nil { - return i - } - } - return 0 -} -func scriptExecUint(s, envfile string) uint { - if runtime.GOOS == "windows" { - var variable string - if strings.Contains(s, ":-") { - parts := strings.SplitN(s, ":-", 2) - variable = parts[0] + "}" - } else { - variable = s - } - out, err := script.Exec(fmt.Sprintf(`powershell -c '$SKYENV = "%s"; if ($SKYENV -ne "" -and (Test-Path $SKYENV)) { . $SKYENV }; echo %s"`, envfile, variable)).String() - if err == nil { - if (out == "") || (out == variable) { - return 0 - } - i, err := strconv.Atoi(strings.TrimSpace(strings.TrimRight(out, "\n"))) - if err == nil { - return uint(i) - } - return 0 - } - return 0 - } - z, err := script.Exec(fmt.Sprintf(`sh -c 'SKYENV=%s ; if [[ $SKYENV != "" ]] && [[ -f $SKYENV ]] ; then source $SKYENV ; fi ; printf "%s"'`, envfile, s)).String() - if err == nil { - if z == "" { - return 0 - } - i, err := strconv.Atoi(z) - if err == nil { - return uint(i) - } + go func() { + _, err := io.Copy(conn, dmsgConn) + if err != nil { + log.Printf("Error copying data from dmsg server: %v", err) + } + conn.Close() //nolint + }() + }(conn, n) } - return uint(0) } const envfileLinux = ` @@ -750,51 +404,30 @@ const envfileLinux = ` #-- DMSGWEB CONFIG TEMPLATE #-- Defaults shown #-- Uncomment to change default value +#-- WEBPORT and DMSGPORT must contain the same number of elements ######################################################################### #-- Set port for proxy interface #PROXYPORT=4445 -#-- Configure additional proxy for dmsgvlc to use +#-- Configure additional socks5 proxy for dmsgweb to use to connect to dmsg #ADDPROXY='127.0.0.1:1080' #-- Web Interface Port -#WEBPORT=8080 +#WEBPORT=('8080') #-- Resove a specific PK to the web port (also disables proxy) -#RESOLVEPK='' +#RESOLVEPK=('') + +#-- Use raw tcp mode instead of http (also disables proxy) +#RAWTCP=('false') #-- Number of dmsg servers to connect to (0 unlimits) -#DMSGSESSIONS=1 +#DMSGSESSIONS=2 #-- Dmsg port to use -#DMSGPORT=80 +#DMSGPORT=('80') #-- Set secret key -#DMSGWEB_SK='' -` -const srvenvfileLinux = ` -######################################################################### -#-- DMSGWEB SRV CONFIG TEMPLATE -#-- Defaults shown -#-- Uncomment to change default value -######################################################################### - -#-- DMSG port to serve -#DMSGPORT=80 - -#-- Port for this application to serve http -#WEBPORT=8081 - -#-- Local Port to serve over dmsg -LOCALPORT=8086 - -#-- Number of dmsg servers to connect to (0 unlimits) -#DMSGSESSIONS=1 - -#-- Set secret key -#DMSGWEBSRV_SK='' - -#-- Whitelisted keys to access the web interface -#WHITELISTPKS=('') +#DMSGWEBSK='' ` diff --git a/vendor/github.com/skycoin/dmsg/cmd/dmsgweb/commands/dmsgwebsrv.go b/vendor/github.com/skycoin/dmsg/cmd/dmsgweb/commands/dmsgwebsrv.go new file mode 100644 index 0000000000..547df6392b --- /dev/null +++ b/vendor/github.com/skycoin/dmsg/cmd/dmsgweb/commands/dmsgwebsrv.go @@ -0,0 +1,281 @@ +// Package commands cmd/dmsgweb/commands/dmsgwebsrv.go +package commands + +import ( + "context" + "fmt" + "io" + "net" + "net/http" + "net/http/httputil" + "net/url" + "os" + "runtime" + "strings" + "sync" + "time" + + "github.com/bitfield/script" + "github.com/gin-gonic/gin" + "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" + dmsg "github.com/skycoin/dmsg/pkg/dmsg" +) + +const dmsgwebsrvenvname = "DMSGWEBSRV" + +var dmsgwebsrvconffile = os.Getenv(dmsgwebsrvenvname) + +func init() { + RootCmd.AddCommand(srvCmd) + 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", skyenv.DmsgDiscAddr, "dmsg discovery url") + 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") != "" { + sk.Set(os.Getenv("DMSGWEBSRVSK")) //nolint + } + if scriptExecString("${DMSGWEBSRVSK}", dmsgwebsrvconffile) != "" { + sk.Set(scriptExecString("${DMSGWEBSRVSK}", dmsgwebsrvconffile)) //nolint + } + pk, _ = sk.PubKey() //nolint + srvCmd.Flags().VarP(&sk, "sk", "s", "a random key is generated if unspecified\n\r") + srvCmd.Flags().BoolVarP(&isEnvs, "envs", "z", false, "show example .conf file") + + srvCmd.CompletionOptions.DisableDefaultCmd = true +} + +var srvCmd = &cobra.Command{ + Use: "srv", + Short: "serve http or raw TCP from local port over dmsg", + Long: `DMSG web server - serve http or raw TCP interface from local port over dmsg` + func() string { + if _, err := os.Stat(dmsgwebsrvconffile); err == nil { + return ` + dmsenv file detected: ` + dmsgwebsrvconffile + } + return ` + .conf file may also be specified with + ` + dmsgwebsrvenvname + `=/path/to/dmsgwebsrv.conf skywire dmsg web srv` + }(), + Run: func(_ *cobra.Command, _ []string) { + if isEnvs { + envfile := srvenvfileLinux + if runtime.GOOS == "windows" { + envfileslice, _ := script.Echo(envfile).Slice() //nolint + for i := range envfileslice { + efs, _ := script.Echo(envfileslice[i]).Reject("##").Reject("#-").Reject("# ").Replace("#", "#$").String() //nolint + if efs != "" && efs != "\n" { + envfileslice[i] = strings.ReplaceAll(efs, "\n", "") + } + } + envfile = strings.Join(envfileslice, "\n") + } + fmt.Println(envfile) + os.Exit(0) + } + + server() + }, +} + +func server() { + log := logging.MustGetLogger("dmsgwebsrv") + if len(localPort) != len(dmsgPort) { + log.Fatal(fmt.Sprintf("the same number of local ports as dmsg ports must be specified ; local ports: %v ; dmsg ports: %v", len(localPort), len(dmsgPort))) + } + + seenLocalPort := make(map[uint]bool) + for _, item := range localPort { + if seenLocalPort[item] { + log.Fatal("-lport --l flag cannot contain duplicates") + } + seenLocalPort[item] = true + } + + seenDmsgPort := make(map[uint]bool) + for _, item := range dmsgPort { + if seenDmsgPort[item] { + log.Fatal("-dport --d flag cannot contain duplicates") + } + seenDmsgPort[item] = true + } + + ctx, cancel := cmdutil.SignalContext(context.Background(), log) + + defer cancel() + pk, err = sk.PubKey() + if err != nil { + pk, sk = cipher.GenerateKeyPair() + } + log.Infof("dmsg client pk: %v", pk.String()) + + if len(wl) > 0 { + for _, key := range wl { + var pk0 cipher.PubKey + err := pk0.Set(key) + if err == nil { + wlkeys = append(wlkeys, pk0) + } + } + } + if len(wlkeys) > 0 { + if len(wlkeys) == 1 { + log.Info(fmt.Sprintf("%d key whitelisted", len(wlkeys))) + } else { + log.Info(fmt.Sprintf("%d keys whitelisted", len(wlkeys))) + } + } + + dmsgC := dmsg.NewClient(pk, sk, disc.NewHTTP(dmsgDisc, &http.Client{}, log), dmsg.DefaultConfig()) + defer func() { + if err := dmsgC.Close(); err != nil { + log.WithError(err).Error() + } + }() + + go dmsgC.Serve(context.Background()) + + select { + case <-ctx.Done(): + log.WithError(ctx.Err()).Warn() + return + + case <-dmsgC.Ready(): + } + + var listN []net.Listener + + for _, dport := range dmsgPort { + lis, err := dmsgC.Listen(uint16(dport)) + if err != nil { + log.Fatalf("Error listening on port %d: %v", dport, err) + } + + listN = append(listN, lis) + + dport := dport + go func(l net.Listener, port uint) { + <-ctx.Done() + if err := l.Close(); err != nil { + log.Printf("Error closing listener on port %d: %v", port, err) + log.WithError(err).Error() + } + }(lis, dport) + } + + wg := new(sync.WaitGroup) + + for i, lpt := range localPort { + wg.Add(1) + go func(localPort uint, rtcp bool, lis net.Listener) { + defer wg.Done() + if rtcp { + proxyTCPConnections(localPort, lis, log) + } else { + proxyHTTPConnections(localPort, lis, log) + } + }(lpt, rawTCP[i], listN[i]) + } + + wg.Wait() +} + +func proxyHTTPConnections(localPort uint, lis net.Listener, log *logging.Logger) { + r1 := gin.New() + r1.Use(gin.Recovery()) + r1.Use(loggingMiddleware()) + + authRoute := r1.Group("/") + if len(wlkeys) > 0 { + authRoute.Use(whitelistAuth(wlkeys)) + } + authRoute.Any("/*path", func(c *gin.Context) { + targetURL, _ := url.Parse(fmt.Sprintf("http://127.0.0.1:%v%s?%s", localPort, c.Request.URL.Path, c.Request.URL.RawQuery)) //nolint + proxy := httputil.ReverseProxy{ + Director: func(req *http.Request) { + req.URL = targetURL + req.Host = targetURL.Host + req.Method = c.Request.Method + }, + Transport: &http.Transport{}, + } + proxy.ServeHTTP(c.Writer, c.Request) + }) + serve := &http.Server{ + Handler: &ginHandler{Router: r1}, + ReadHeaderTimeout: 5 * time.Second, + ReadTimeout: 10 * time.Second, + WriteTimeout: 10 * time.Second, + } + log.Printf("Serving HTTP on dmsg port %v with DMSG listener %s", localPort, lis.Addr().String()) + if err := serve.Serve(lis); err != nil && err != http.ErrServerClosed { + log.Fatalf("Serve: %v", err) + } +} + +func proxyTCPConnections(localPort uint, lis net.Listener, log *logging.Logger) { + for { + conn, err := lis.Accept() + if err != nil { + log.Printf("Error accepting connection: %v", err) + return + } + + go handleTCPConnection(conn, localPort, log) + } +} + +func handleTCPConnection(dmsgConn net.Conn, localPort uint, log *logging.Logger) { + defer dmsgConn.Close() //nolint + + localConn, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", localPort)) + if err != nil { + log.Printf("Error connecting to local port %d: %v", localPort, err) + return + } + defer localConn.Close() //nolint + + copyConn := func(dst net.Conn, src net.Conn) { + _, err := io.Copy(dst, src) + if err != nil { + log.Printf("Error during copy: %v", err) + } + } + + go copyConn(dmsgConn, localConn) + go copyConn(localConn, dmsgConn) +} + +const srvenvfileLinux = ` +######################################################################### +#-- DMSGWEB SRV CONFIG TEMPLATE +#-- Defaults shown +#-- Uncomment to change default value +#-- LOCALPORT and DMSGPORT must contain the same number of elements +######################################################################### + +#-- DMSG port to serve +#DMSGPORT=('80') + +#-- Local Port to serve over dmsg +#LOCALPORT=('8086') + +#-- Number of dmsg servers to connect to (0 unlimits) +#DMSGSESSIONS=1 + +#-- Set secret key +#DMSGWEBSRVSK='' + +#-- Whitelisted keys to access the web interface +#WHITELISTPKS=('') + +#-- Proxy as raw TCP +#RAWTCP=('false') +` diff --git a/vendor/github.com/skycoin/dmsg/cmd/dmsgweb/commands/root.go b/vendor/github.com/skycoin/dmsg/cmd/dmsgweb/commands/root.go new file mode 100644 index 0000000000..37643db7ec --- /dev/null +++ b/vendor/github.com/skycoin/dmsg/cmd/dmsgweb/commands/root.go @@ -0,0 +1,400 @@ +// Package commands cmd/dmsgweb/commands/root.go +package commands + +import ( + "context" + "fmt" + "log" + "net" + "net/http" + "os" + "runtime" + "strconv" + "strings" + "sync" + "time" + + "github.com/bitfield/script" + "github.com/gin-gonic/gin" + "github.com/skycoin/skywire-utilities/pkg/cipher" + "github.com/skycoin/skywire-utilities/pkg/logging" + + "github.com/skycoin/dmsg/pkg/disc" + dmsg "github.com/skycoin/dmsg/pkg/dmsg" +) + +var ( + httpC http.Client + dmsgC *dmsg.Client + dmsgDisc string + dmsgSessions int + dmsgAddr []string + dialPK []cipher.PubKey + filterDomainSuffix string + sk cipher.SecKey + pk cipher.PubKey + dmsgWebLog *logging.Logger + logLvl string + webPort []uint + proxyPort uint + addProxy string + resolveDmsgAddr []string + wg sync.WaitGroup + isEnvs bool + dmsgPort []uint + dmsgPorts []uint + dmsgSess int + wl []string + wlkeys []cipher.PubKey + localPort []uint + err error + rawTCP []bool +) + +// Execute executes root CLI command. +func Execute() { + if err := RootCmd.Execute(); err != nil { + log.Fatal("Failed to execute command: ", err) + } +} + +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{}, dmsgWebLog), &dmsg.Config{MinSessions: dmsgSessions}) + go dmsgC.Serve(context.Background()) + + stop = func() { + err := dmsgC.Close() + dmsgWebLog.WithError(err).Debug("Disconnected from dmsg network.") + fmt.Printf("\n") + } + dmsgWebLog.WithField("public_key", pk.String()).WithField("dmsg_disc", dmsgDisc). + Debug("Connecting to dmsg network...") + + select { + case <-ctx.Done(): + stop() + os.Exit(0) + return nil, nil, ctx.Err() + + case <-dmsgC.Ready(): + dmsgWebLog.Debug("Dmsg network ready.") + return dmsgC, stop, nil + } +} + +func scriptExecString(s, envfile string) string { + if runtime.GOOS == "windows" { + var variable, defaultvalue string + if strings.Contains(s, ":-") { + parts := strings.SplitN(s, ":-", 2) + variable = parts[0] + "}" + defaultvalue = strings.TrimRight(parts[1], "}") + } else { + variable = s + defaultvalue = "" + } + out, err := script.Exec(fmt.Sprintf(`powershell -c '$SKYENV = "%s"; if ($SKYENV -ne "" -and (Test-Path $SKYENV)) { . $SKYENV }; echo %s"`, envfile, variable)).String() + if err == nil { + if (out == "") || (out == variable) { + return defaultvalue + } + return strings.TrimRight(out, "\n") + } + return defaultvalue + } + z, err := script.Exec(fmt.Sprintf(`sh -c 'SKYENV=%s ; if [[ $SKYENV != "" ]] && [[ -f $SKYENV ]] ; then source $SKYENV ; fi ; printf "%s"'`, envfile, s)).String() + if err == nil { + return strings.TrimSpace(z) + } + return "" +} + +/* + func scriptExecArray(s, envfile string) string { + if runtime.GOOS == "windows" { + variable := s + if strings.Contains(variable, "[@]}") { + variable = strings.TrimRight(variable, "[@]}") + variable = strings.TrimRight(variable, "{") + } + out, err := script.Exec(fmt.Sprintf(`powershell -c '$SKYENV = "%s"; if ($SKYENV -ne "" -and (Test-Path $SKYENV)) { . $SKYENV }; foreach ($item in %s) { Write-Host $item }'`, envfile, variable)).Slice() + if err == nil { + if len(out) != 0 { + return "" + } + return strings.Join(out, ",") + } + } + y, err := script.Exec(fmt.Sprintf(`bash -c 'SKYENV=%s ; if [[ $SKYENV != "" ]] && [[ -f $SKYENV ]] ; then source $SKYENV ; fi ; for _i in %s ; do echo "$_i" ; done'`, envfile, s)).Slice() + if err == nil { + return strings.Join(y, ",") + } + return "" + } +*/ +func scriptExecStringSlice(s, envfile string) []string { + if runtime.GOOS == "windows" { + variable := s + if strings.Contains(variable, "[@]}") { + variable = strings.TrimRight(variable, "[@]}") + variable = strings.TrimRight(variable, "{") + } + out, err := script.Exec(fmt.Sprintf(`powershell -c '$SKYENV = "%s"; if ($SKYENV -ne "" -and (Test-Path $SKYENV)) { . $SKYENV }; foreach ($item in %s) { Write-Host $item }'`, envfile, variable)).Slice() + if err == nil { + return out + } + } + y, err := script.Exec(fmt.Sprintf(`bash -c 'SKYENV=%s ; if [[ $SKYENV != "" ]] && [[ -f $SKYENV ]] ; then source $SKYENV ; fi ; for _i in %s ; do echo "$_i" ; done'`, envfile, s)).Slice() + if err == nil { + return y + } + return []string{} +} + +func scriptExecBoolSlice(s, envfile string) []bool { + var result []bool + + if runtime.GOOS == "windows" { + variable := s + if strings.Contains(variable, "[@]}") { + variable = strings.TrimRight(variable, "[@]}") + variable = strings.TrimRight(variable, "{") + } + out, err := script.Exec(fmt.Sprintf(`powershell -c '$SKYENV = "%s"; if ($SKYENV -ne "" -and (Test-Path $SKYENV)) { . $SKYENV }; foreach ($item in %s) { Write-Host $item }'`, envfile, variable)).Slice() + if err == nil { + for _, item := range out { + result = append(result, item != "") + } + return result + } + } else { + y, err := script.Exec(fmt.Sprintf(`bash -c 'SKYENV=%s ; if [[ $SKYENV != "" ]] && [[ -f $SKYENV ]] ; then source $SKYENV ; fi ; for _i in %s ; do echo "$_i" ; done'`, envfile, s)).Slice() + if err == nil { + for _, item := range y { + result = append(result, item != "") + } + return result + } + } + + return result +} + +func scriptExecUintSlice(s, envfile string) []uint { + var out []string + var err error + + if runtime.GOOS == "windows" { + variable := s + if strings.Contains(variable, "[@]}") { + variable = strings.TrimRight(variable, "[@]}") + variable = strings.TrimRight(variable, "{") + } + out, err = script.Exec(fmt.Sprintf(`powershell -c '$SKYENV = "%s"; if ($SKYENV -ne "" -and (Test-Path $SKYENV)) { . $SKYENV }; foreach ($item in %s) { Write-Host $item }'`, envfile, variable)).Slice() + } else { + out, err = script.Exec(fmt.Sprintf(`bash -c 'SKYENV=%s ; if [[ $SKYENV != "" ]] && [[ -f $SKYENV ]] ; then source $SKYENV ; fi ; for _i in %s ; do echo "$_i" ; done'`, envfile, s)).Slice() + } + + if err != nil { + return []uint{} + } + + var res []uint + for _, item := range out { + num, err := strconv.ParseUint(item, 10, 64) + if err == nil { + res = append(res, uint(num)) + } + } + + return res +} + +func scriptExecInt(s, envfile string) int { + if runtime.GOOS == "windows" { + var variable string + if strings.Contains(s, ":-") { + parts := strings.SplitN(s, ":-", 2) + variable = parts[0] + "}" + } else { + variable = s + } + out, err := script.Exec(fmt.Sprintf(`powershell -c '$SKYENV = "%s"; if ($SKYENV -ne "" -and (Test-Path $SKYENV)) { . $SKYENV }; echo %s"`, envfile, variable)).String() + if err == nil { + if (out == "") || (out == variable) { + return 0 + } + i, err := strconv.Atoi(strings.TrimSpace(strings.TrimRight(out, "\n"))) + if err == nil { + return i + } + return 0 + } + return 0 + } + z, err := script.Exec(fmt.Sprintf(`sh -c 'SKYENV=%s ; if [[ $SKYENV != "" ]] && [[ -f $SKYENV ]] ; then source $SKYENV ; fi ; printf "%s"'`, envfile, s)).String() + if err == nil { + if z == "" { + return 0 + } + i, err := strconv.Atoi(z) + if err == nil { + return i + } + } + return 0 +} +func scriptExecUint(s, envfile string) uint { + if runtime.GOOS == "windows" { + var variable string + if strings.Contains(s, ":-") { + parts := strings.SplitN(s, ":-", 2) + variable = parts[0] + "}" + } else { + variable = s + } + out, err := script.Exec(fmt.Sprintf(`powershell -c '$SKYENV = "%s"; if ($SKYENV -ne "" -and (Test-Path $SKYENV)) { . $SKYENV }; echo %s"`, envfile, variable)).String() + if err == nil { + if (out == "") || (out == variable) { + return 0 + } + i, err := strconv.Atoi(strings.TrimSpace(strings.TrimRight(out, "\n"))) + if err == nil { + return uint(i) + } + return 0 + } + return 0 + } + z, err := script.Exec(fmt.Sprintf(`sh -c 'SKYENV=%s ; if [[ $SKYENV != "" ]] && [[ -f $SKYENV ]] ; then source $SKYENV ; fi ; printf "%s"'`, envfile, s)).String() + if err == nil { + if z == "" { + return 0 + } + i, err := strconv.Atoi(z) + if err == nil { + return uint(i) + } + } + return uint(0) +} + +func whitelistAuth(whitelistedPKs []cipher.PubKey) gin.HandlerFunc { + return func(c *gin.Context) { + remotePK, _, err := net.SplitHostPort(c.Request.RemoteAddr) + if err != nil { + c.Writer.WriteHeader(http.StatusInternalServerError) + c.Writer.Write([]byte("500 Internal Server Error")) //nolint + c.AbortWithStatus(http.StatusInternalServerError) + return + } + whitelisted := false + if len(whitelistedPKs) == 0 { + whitelisted = true + } else { + for _, whitelistedPK := range whitelistedPKs { + if remotePK == whitelistedPK.String() { + whitelisted = true + break + } + } + } + if whitelisted { + c.Next() + } else { + c.Writer.WriteHeader(http.StatusUnauthorized) + c.Writer.Write([]byte("401 Unauthorized")) //nolint + c.AbortWithStatus(http.StatusUnauthorized) + return + } + } +} + +type ginHandler struct { + Router *gin.Engine +} + +func (h *ginHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + h.Router.ServeHTTP(w, r) +} + +func loggingMiddleware() gin.HandlerFunc { + return func(c *gin.Context) { + start := time.Now() + c.Next() + latency := time.Since(start) + if latency > time.Minute { + latency = latency.Truncate(time.Second) + } + statusCode := c.Writer.Status() + method := c.Request.Method + path := c.Request.URL.Path + // Get the background color based on the status code + statusCodeBackgroundColor := getBackgroundColor(statusCode) + // Get the method color + methodColor := getMethodColor(method) + // Print the logging in a custom format which includes the publickeyfrom c.Request.RemoteAddr ex.: + // [DMSGHTTP] 2023/05/18 - 19:43:15 | 200 | 10.80885ms | | 02b5ee5333aa6b7f5fc623b7d5f35f505cb7f974e98a70751cf41962f84c8c4637:49153 | GET /node-info.json + fmt.Printf("[DMSGWEB] %s |%s %3d %s| %13v | %15s | %72s |%s %-7s %s %s\n", + time.Now().Format("2006/01/02 - 15:04:05"), + statusCodeBackgroundColor, + statusCode, + resetColor(), + latency, + c.ClientIP(), + c.Request.RemoteAddr, + methodColor, + method, + resetColor(), + path, + ) + } +} +func getBackgroundColor(statusCode int) string { + switch { + case statusCode >= http.StatusOK && statusCode < http.StatusMultipleChoices: + return green + case statusCode >= http.StatusMultipleChoices && statusCode < http.StatusBadRequest: + return white + case statusCode >= http.StatusBadRequest && statusCode < http.StatusInternalServerError: + return yellow + default: + return red + } +} + +func getMethodColor(method string) string { + switch method { + case http.MethodGet: + return blue + case http.MethodPost: + return cyan + case http.MethodPut: + return yellow + case http.MethodDelete: + return red + case http.MethodPatch: + return green + case http.MethodHead: + return magenta + case http.MethodOptions: + return white + default: + return reset + } +} + +func resetColor() string { + return reset +} + +const ( + green = "\033[97;42m" + white = "\033[90;47m" + yellow = "\033[90;43m" + red = "\033[97;41m" + blue = "\033[97;44m" + magenta = "\033[97;45m" + cyan = "\033[97;46m" + reset = "\033[0m" +) diff --git a/vendor/github.com/skycoin/dmsg/pkg/dmsg/const.go b/vendor/github.com/skycoin/dmsg/pkg/dmsg/const.go index cac2c8b820..731c2bc8d6 100644 --- a/vendor/github.com/skycoin/dmsg/pkg/dmsg/const.go +++ b/vendor/github.com/skycoin/dmsg/pkg/dmsg/const.go @@ -1,7 +1,9 @@ // Package dmsg pkg/dmsg/const.go package dmsg -import "time" +import ( + "time" +) // Constants. const ( diff --git a/vendor/github.com/skycoin/dmsg/pkg/dmsgctrl/serve_listener.go b/vendor/github.com/skycoin/dmsg/pkg/dmsgctrl/serve_listener.go index da1721811c..2fd9b92835 100644 --- a/vendor/github.com/skycoin/dmsg/pkg/dmsgctrl/serve_listener.go +++ b/vendor/github.com/skycoin/dmsg/pkg/dmsgctrl/serve_listener.go @@ -1,7 +1,9 @@ // Package dmsgctrl pkg/dmsgctrl/serve_listener.go package dmsgctrl -import "net" +import ( + "net" +) // ServeListener serves a listener with dmsgctrl.Control. // It returns a channel for incoming Controls. diff --git a/vendor/github.com/skycoin/dmsg/pkg/dmsgpty/ui_windows.go b/vendor/github.com/skycoin/dmsg/pkg/dmsgpty/ui_windows.go index 915f553e3b..2cb3d978fb 100644 --- a/vendor/github.com/skycoin/dmsg/pkg/dmsgpty/ui_windows.go +++ b/vendor/github.com/skycoin/dmsg/pkg/dmsgpty/ui_windows.go @@ -4,7 +4,9 @@ // Package dmsgpty pkg/dmsgpty/ui_windows.go package dmsgpty -import "golang.org/x/sys/windows" +import ( + "golang.org/x/sys/windows" +) func (ui *UI) uiStartSize(ptyC *PtyClient) error { ws, err := NewWinSize(&windows.Coord{ diff --git a/vendor/modules.txt b/vendor/modules.txt index 2fd32966fc..ed26867a4e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -536,7 +536,7 @@ github.com/shoenig/go-m1cpu ## explicit; go 1.13 github.com/sirupsen/logrus github.com/sirupsen/logrus/hooks/syslog -# github.com/skycoin/dmsg v1.3.22-0.20240520184015-5d7616ee506a +# github.com/skycoin/dmsg v1.3.22-0.20240622174622-39e439d5679d ## explicit; go 1.21 github.com/skycoin/dmsg/cmd/dmsg-discovery/commands github.com/skycoin/dmsg/cmd/dmsg-server/commands From 8bbd127d179a1db75e065adf2ad284ab2d39dba9 Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Sun, 23 Jun 2024 12:45:31 -0500 Subject: [PATCH 3/6] fix CI errors --- cmd/skywire-cli/commands/survey/root.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/cmd/skywire-cli/commands/survey/root.go b/cmd/skywire-cli/commands/survey/root.go index df283d6073..6c40d3109b 100644 --- a/cmd/skywire-cli/commands/survey/root.go +++ b/cmd/skywire-cli/commands/survey/root.go @@ -8,7 +8,6 @@ import ( "github.com/spf13/cobra" - "github.com/skycoin/skywire-utilities/pkg/buildinfo" "github.com/skycoin/skywire-utilities/pkg/logging" "github.com/skycoin/skywire/cmd/skywire-cli/internal" "github.com/skycoin/skywire/pkg/visor/visorconfig" @@ -16,19 +15,16 @@ import ( var ( logger = logging.MustGetLogger("skywire-visor") //nolint:unused - isCksum bool mLog = logging.NewMasterLogger() log = mLog.PackageLogger("survey") confPath string // stdin bool // confArg string - visorBuildInfo *buildinfo.Info pkg bool usr bool pkgconfigexists bool userconfigexists bool conf *visorconfig.V1 - useConf bool ) func init() { @@ -78,7 +74,7 @@ var surveyCmd = &cobra.Command{ if confPath != "" { // conf = initConfig() - confJSON, err := os.ReadFile(confPath) + confJSON, err := os.ReadFile(confPath) //nolint if err != nil { log.WithError(err).Fatal("Failed to read config file: %v", err) } From c4ee8b6ae3971d41e02f92628bd8d61d09cf012d Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Sun, 23 Jun 2024 12:56:24 -0500 Subject: [PATCH 4/6] fix logging --- cmd/skywire-cli/commands/survey/root.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/skywire-cli/commands/survey/root.go b/cmd/skywire-cli/commands/survey/root.go index 6c40d3109b..f40e32178a 100644 --- a/cmd/skywire-cli/commands/survey/root.go +++ b/cmd/skywire-cli/commands/survey/root.go @@ -76,7 +76,7 @@ var surveyCmd = &cobra.Command{ // conf = initConfig() confJSON, err := os.ReadFile(confPath) //nolint if err != nil { - log.WithError(err).Fatal("Failed to read config file: %v", err) + log.WithError(err).Fatal("Failed to read config file") } err = json.Unmarshal(confJSON, &conf) if err != nil { From 34e27e30f5ad7447f3ee33f9741616e01e27804c Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Sun, 23 Jun 2024 13:04:44 -0500 Subject: [PATCH 5/6] update skycoin-service-discovery dependency --- go.mod | 2 +- go.sum | 4 ++-- vendor/modules.txt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 687f944256..43a72c4f0f 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/skycoin/dmsg v1.3.22-0.20240622174622-39e439d5679d github.com/skycoin/skycoin v0.27.1 - github.com/skycoin/skycoin-service-discovery v0.0.0-20240306165129-2af10aca698e + github.com/skycoin/skycoin-service-discovery v0.0.0-20240623180153-a8ad1c33ec6b github.com/skycoin/skywire-services v0.0.0-20240403004908-50ccbbf07004 github.com/skycoin/skywire-utilities v1.3.18-0.20240208220612-9f31eda72f33 github.com/skycoin/systray v1.10.0 diff --git a/go.sum b/go.sum index ada2345d66..a07fe376ef 100644 --- a/go.sum +++ b/go.sum @@ -731,8 +731,8 @@ github.com/skycoin/noise v0.0.0-20180327030543-2492fe189ae6 h1:1Nc5EBY6pjfw1kwW0 github.com/skycoin/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:UXghlricA7J3aRD/k7p/zBObQfmBawwCxIVPVjz2Q3o= github.com/skycoin/skycoin v0.27.1 h1:HatxsRwVSPaV4qxH6290xPBmkH/HgiuAoY2qC+e8C9I= github.com/skycoin/skycoin v0.27.1/go.mod h1:78nHjQzd8KG0jJJVL/j0xMmrihXi70ti63fh8vXScJw= -github.com/skycoin/skycoin-service-discovery v0.0.0-20240306165129-2af10aca698e h1:y9C5pGHQp/iJFj0QJqr5SboE+Q2RmeYav/AncHOAmWg= -github.com/skycoin/skycoin-service-discovery v0.0.0-20240306165129-2af10aca698e/go.mod h1:h2Yq97wrppNdVgtAhEhY/9w568wS3T6CkK2pWhfUQm0= +github.com/skycoin/skycoin-service-discovery v0.0.0-20240623180153-a8ad1c33ec6b h1:5HUw+Uckv5mZORdcSC1TLmAu2ICRYjouoqATa8mTp74= +github.com/skycoin/skycoin-service-discovery v0.0.0-20240623180153-a8ad1c33ec6b/go.mod h1:FeOj6UmWl3fHf09yndIljAznZeAFiu95eUjNW/nIIHs= github.com/skycoin/skywire-services v0.0.0-20240403004908-50ccbbf07004 h1:VTcuwPkcRkPP4QojtKv4OvsNua30xuY5c/SdpefU+ys= github.com/skycoin/skywire-services v0.0.0-20240403004908-50ccbbf07004/go.mod h1:HGvza0o1t9KI/wGcklvoKIgfxfbI7M2PEtc+HsPz1nc= github.com/skycoin/skywire-utilities v1.3.18-0.20240208220612-9f31eda72f33 h1:BzhyKolEWT8cnXZJMxC0TYGCvu3wMYdI6NOpvToN+uQ= diff --git a/vendor/modules.txt b/vendor/modules.txt index ed26867a4e..6dd2e8ff61 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -577,7 +577,7 @@ github.com/skycoin/skycoin/src/cipher/ripemd160 github.com/skycoin/skycoin/src/cipher/secp256k1-go github.com/skycoin/skycoin/src/cipher/secp256k1-go/secp256k1-go2 github.com/skycoin/skycoin/src/util/logging -# github.com/skycoin/skycoin-service-discovery v0.0.0-20240306165129-2af10aca698e +# github.com/skycoin/skycoin-service-discovery v0.0.0-20240623180153-a8ad1c33ec6b ## explicit; go 1.21 github.com/skycoin/skycoin-service-discovery/cmd/service-discovery/commands github.com/skycoin/skycoin-service-discovery/internal/pg From e3d48bfe3bd74efb9c5cc76ec3fc3271e0c982dd Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Sun, 23 Jun 2024 13:10:22 -0500 Subject: [PATCH 6/6] update skywire-services dependency --- go.mod | 2 +- go.sum | 4 ++-- vendor/modules.txt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 43a72c4f0f..97d268fa57 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/skycoin/dmsg v1.3.22-0.20240622174622-39e439d5679d github.com/skycoin/skycoin v0.27.1 github.com/skycoin/skycoin-service-discovery v0.0.0-20240623180153-a8ad1c33ec6b - github.com/skycoin/skywire-services v0.0.0-20240403004908-50ccbbf07004 + github.com/skycoin/skywire-services v0.0.0-20240623180621-d0bc8fd4da3d github.com/skycoin/skywire-utilities v1.3.18-0.20240208220612-9f31eda72f33 github.com/skycoin/systray v1.10.0 github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 diff --git a/go.sum b/go.sum index a07fe376ef..bc7c015511 100644 --- a/go.sum +++ b/go.sum @@ -733,8 +733,8 @@ github.com/skycoin/skycoin v0.27.1 h1:HatxsRwVSPaV4qxH6290xPBmkH/HgiuAoY2qC+e8C9 github.com/skycoin/skycoin v0.27.1/go.mod h1:78nHjQzd8KG0jJJVL/j0xMmrihXi70ti63fh8vXScJw= github.com/skycoin/skycoin-service-discovery v0.0.0-20240623180153-a8ad1c33ec6b h1:5HUw+Uckv5mZORdcSC1TLmAu2ICRYjouoqATa8mTp74= github.com/skycoin/skycoin-service-discovery v0.0.0-20240623180153-a8ad1c33ec6b/go.mod h1:FeOj6UmWl3fHf09yndIljAznZeAFiu95eUjNW/nIIHs= -github.com/skycoin/skywire-services v0.0.0-20240403004908-50ccbbf07004 h1:VTcuwPkcRkPP4QojtKv4OvsNua30xuY5c/SdpefU+ys= -github.com/skycoin/skywire-services v0.0.0-20240403004908-50ccbbf07004/go.mod h1:HGvza0o1t9KI/wGcklvoKIgfxfbI7M2PEtc+HsPz1nc= +github.com/skycoin/skywire-services v0.0.0-20240623180621-d0bc8fd4da3d h1:KZT7CjyFy465RLjEZyPU0NzEa2pQY6wH38EOkWH7HL8= +github.com/skycoin/skywire-services v0.0.0-20240623180621-d0bc8fd4da3d/go.mod h1:61gfVmHyIAZexpeGKqaYrwelKW4VUIgjmtg5QpG2sf0= github.com/skycoin/skywire-utilities v1.3.18-0.20240208220612-9f31eda72f33 h1:BzhyKolEWT8cnXZJMxC0TYGCvu3wMYdI6NOpvToN+uQ= github.com/skycoin/skywire-utilities v1.3.18-0.20240208220612-9f31eda72f33/go.mod h1:yFKWpL1bDRPKU3uK+cTF4PnYUMe+eyIj5N2bk4sF5Cw= github.com/skycoin/systray v1.10.0 h1:fQZJHMylpVvfmOOTLvUssfyHVDoC8Idx6Ba2BlLEuGg= diff --git a/vendor/modules.txt b/vendor/modules.txt index 6dd2e8ff61..6d62f87362 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -584,7 +584,7 @@ github.com/skycoin/skycoin-service-discovery/internal/pg github.com/skycoin/skycoin-service-discovery/internal/sdmetrics github.com/skycoin/skycoin-service-discovery/pkg/service-discovery/api github.com/skycoin/skycoin-service-discovery/pkg/service-discovery/store -# github.com/skycoin/skywire-services v0.0.0-20240403004908-50ccbbf07004 +# github.com/skycoin/skywire-services v0.0.0-20240623180621-d0bc8fd4da3d ## explicit; go 1.21 github.com/skycoin/skywire-services/cmd/address-resolver/commands github.com/skycoin/skywire-services/cmd/config-bootstrapper/commands