Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/dmsghttp/commands/dmsghttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func server() {
httpClient = &http.Client{
Transport: transport,
}
ctx = context.WithValue(context.Background(), "socks5_proxy", proxyAddr) //nolint
ctx = context.WithValue(ctx, "socks5_proxy", proxyAddr) //nolint
}

var dmsgC *dmsg.Client
Expand Down
2 changes: 0 additions & 2 deletions cmd/dmsgpty-cli/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ var RootCmd = &cobra.Command{
// case 2 : config file is old (already contains "wl" key)
// - load config file into memory to manipulate whitelists
// - writes changes back to config file
println(confPath)

if _, err := os.Stat(confPath); err != nil {
cli.Log.Fatalf("Config file %s not found.", confPath)
}
Expand Down
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ require (
github.com/pires/go-proxyproto v0.11.0
github.com/sirupsen/logrus v1.9.4
github.com/skycoin/noise v0.0.0-20180327030543-2492fe189ae6
github.com/skycoin/skycoin v0.28.6-0.20260325014814-f48988877c68
github.com/skycoin/skywire v1.3.37
github.com/skycoin/skycoin v0.28.6-0.20260328152706-a360adb0a4d3
github.com/skycoin/skywire v1.3.40-0.20260328171146-a5facdc74e72
github.com/spf13/cobra v1.10.2
github.com/stretchr/testify v1.11.1
golang.org/x/net v0.52.0
Expand Down Expand Up @@ -99,6 +99,7 @@ require (
golang.org/x/arch v0.25.0 // indirect
golang.org/x/crypto v0.49.0 // indirect
golang.org/x/text v0.35.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 // indirect
google.golang.org/protobuf v1.36.11 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools/v3 v3.5.2 // indirect
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,10 @@ github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w
github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
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.28.6-0.20260325014814-f48988877c68 h1:M+VmlCByq6jRbxio6GOn4h+5jP+nmumiu1xMZZg3MZI=
github.com/skycoin/skycoin v0.28.6-0.20260325014814-f48988877c68/go.mod h1:tgVxjBBV4/OxVBDrcpsVK0q/awGxqBjwTUPDBMh9ZcA=
github.com/skycoin/skywire v1.3.37 h1:LIgOrj6PqdH6RAOWsD8TSI/vTyp7kUYE2Ale6pkvjJw=
github.com/skycoin/skywire v1.3.37/go.mod h1:k3TA1edIXR96Jtec5XYVy7EGHQlZL524pCPYRTzBBok=
github.com/skycoin/skycoin v0.28.6-0.20260328152706-a360adb0a4d3 h1:yDTe5ISvCGJ/wsbaXcXKO/MgyB8/pam3GHsvwbVlPk8=
github.com/skycoin/skycoin v0.28.6-0.20260328152706-a360adb0a4d3/go.mod h1:tgVxjBBV4/OxVBDrcpsVK0q/awGxqBjwTUPDBMh9ZcA=
github.com/skycoin/skywire v1.3.40-0.20260328171146-a5facdc74e72 h1:KXG0RGXVDh2KNn35kGC5+mWXU6hlYYjowU9TXiGSwMU=
github.com/skycoin/skywire v1.3.40-0.20260328171146-a5facdc74e72/go.mod h1:GmBT7f+kIxR2ym3iBbtBNE75/W8XfG4JbkJODzD2azA=
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
Expand Down Expand Up @@ -251,8 +251,8 @@ golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=
golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=
google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d h1:EocjzKLywydp5uZ5tJ79iP6Q0UjDnyiHkGRWxuPBP8s=
google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:48U2I+QQUYhsFrg2SY6r+nJzeOtjey7j//WBESw+qyQ=
google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 h1:41r6JMbpzBMen0R/4TZeeAmGXSJC7DftGINUodzTkPI=
google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:EIQZ5bFCfRQDV4MhRle7+OgjNtZ6P1PiZBgAKuxXu/Y=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 h1:ndE4FoJqsIceKP2oYSnUZqhTdYufCYYkqwtFzfrhI7w=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
Expand Down
17 changes: 11 additions & 6 deletions pkg/dmsg/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,10 @@ func NewClient(pk cipher.PubKey, sk cipher.SecKey, dc disc.APIClient, conf *Conf

// Init callback: on set session.
c.EntityCommon.setSessionCallback = func(ctx context.Context) error {
if err := c.EntityCommon.updateClientEntry(ctx, c.done, c.conf.ClientType); err != nil {
c.sessionsMx.Lock()
err := c.EntityCommon.updateClientEntry(ctx, c.done, c.conf.ClientType)
c.sessionsMx.Unlock()
if err != nil {
return err
}
// Client is 'ready' once we have successfully updated the discovery entry
Expand All @@ -123,7 +126,9 @@ func NewClient(pk cipher.PubKey, sk cipher.SecKey, dc disc.APIClient, conf *Conf

// Init callback: on delete session.
c.EntityCommon.delSessionCallback = func(ctx context.Context) error {
c.sessionsMx.Lock()
err := c.EntityCommon.updateClientEntry(ctx, c.done, c.conf.ClientType)
c.sessionsMx.Unlock()
return err
}

Expand Down Expand Up @@ -275,6 +280,7 @@ func (ce *Client) Serve(ctx context.Context) {
select {
case ce.errCh <- err:
default:
ce.log.WithError(err).Warn("Error channel full, dropping error.")
}
ce.sesMx.Unlock()
}
Expand Down Expand Up @@ -376,12 +382,11 @@ func (ce *Client) serveWait() {
t := time.NewTimer(bo)
defer t.Stop()

if newBO := time.Duration(float64(bo) * ce.factor); ce.maxBO == 0 || newBO <= ce.maxBO {
ce.bo = newBO
if newBO > ce.maxBO {
ce.bo = ce.maxBO
}
newBO := time.Duration(float64(bo) * ce.factor)
if ce.maxBO > 0 && newBO > ce.maxBO {
newBO = ce.maxBO
}
ce.bo = newBO
<-t.C
}

Expand Down
22 changes: 14 additions & 8 deletions pkg/dmsg/entity_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,16 @@ func (c *EntityCommon) SessionCount() int {

func (c *EntityCommon) setSession(ctx context.Context, dSes *SessionCommon) bool {
c.sessionsMx.Lock()
defer c.sessionsMx.Unlock()

if _, ok := c.sessions[dSes.RemotePK()]; ok {
c.sessionsMx.Unlock()
return false
}
c.sessions[dSes.RemotePK()] = dSes
cb := c.setSessionCallback
c.sessionsMx.Unlock()

if c.setSessionCallback != nil {
if err := c.setSessionCallback(ctx); err != nil {
if cb != nil {
if err := cb(ctx); err != nil {
c.log.
WithField("func", "EntityCommon.setSession").
WithError(err).
Expand All @@ -131,23 +132,25 @@ func (c *EntityCommon) setSession(ctx context.Context, dSes *SessionCommon) bool
func (c *EntityCommon) delSession(ctx context.Context, pk cipher.PubKey) {
c.sessionsMx.Lock()
delete(c.sessions, pk)
if c.delSessionCallback != nil {
if err := c.delSessionCallback(ctx); err != nil {
cb := c.delSessionCallback
c.sessionsMx.Unlock()

if cb != nil {
if err := cb(ctx); err != nil {
c.log.
WithField("func", "EntityCommon.delSession").
WithError(err).
Warn("Callback returned non-nil error.\n")
}
}
c.sessionsMx.Unlock()
}

// updateServerEntry updates the dmsg server's entry within dmsg discovery.
// If 'addr' is an empty string, the Entry.addr field will not be updated in discovery.
// Caller must hold c.sessionsMx.
func (c *EntityCommon) updateServerEntry(ctx context.Context, addr string, maxSessions int, authPassphrase string) (err error) {
if addr == "" {
panic("updateServerEntry cannot accept empty 'addr' input") // this should never happen
return errors.New("updateServerEntry cannot accept empty 'addr' input")
}

// Record last update on success.
Expand All @@ -158,6 +161,9 @@ func (c *EntityCommon) updateServerEntry(ctx context.Context, addr string, maxSe
}()

availableSessions := maxSessions - len(c.sessions)
if availableSessions < 0 {
availableSessions = 0
}

entry, err := c.dc.Entry(ctx, c.pk)
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions pkg/dmsg/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ import (
"sync"
"sync/atomic"

"github.com/skycoin/skywire/pkg/skywire-utilities/pkg/logging"
"github.com/skycoin/skywire/pkg/skywire-utilities/pkg/netutil"
)

var listenerLog = logging.MustGetLogger("dmsg_listener")

// Listener listens for remote-initiated streams.
type Listener struct {
porter *netutil.Porter
Expand Down Expand Up @@ -59,6 +62,7 @@ func (l *Listener) introduceStream(tp *Stream) error {
return ErrEntityClosed

default:
listenerLog.WithField("addr", l.addr).Warn("Accept buffer full, dropping stream.")
_ = tp.Close() //nolint:errcheck
return ErrAcceptChanMaxed
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/dmsg/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,13 @@ func NewServer(pk cipher.PubKey, sk cipher.SecKey, dc disc.APIClient, conf *Serv
s.addrDone = make(chan struct{})
s.maxSessions = conf.MaxSessions
s.setSessionCallback = func(ctx context.Context) error {
s.sessionsMx.Lock()
defer s.sessionsMx.Unlock()
return s.updateServerEntry(ctx, s.AdvertisedAddr(), s.maxSessions, conf.AuthPassphrase)
}
s.delSessionCallback = func(ctx context.Context) error {
s.sessionsMx.Lock()
defer s.sessionsMx.Unlock()
return s.updateServerEntry(ctx, s.AdvertisedAddr(), s.maxSessions, conf.AuthPassphrase)
}
s.authPassphrase = conf.AuthPassphrase
Expand Down
3 changes: 1 addition & 2 deletions pkg/dmsg/session_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,7 @@ func (sc *SessionCommon) Close() error {
sc.sm.mutx.Lock()
if sc.sm.smux != nil {
err = sc.sm.smux.Close()
}
if sc.sm.yamux != nil {
} else if sc.sm.yamux != nil {
err = sc.sm.yamux.Close()
}
sc.sm.mutx.Unlock()
Expand Down
7 changes: 6 additions & 1 deletion pkg/dmsgcurl/dmsgcurl.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,12 @@ func parseOutputFile(name string, urlPath string) (*os.File, error) {
}

if stat.IsDir() {
f, err := os.Create(filepath.Join(name, urlPath)) //nolint
// Sanitize the URL path to prevent directory traversal.
cleanPath := filepath.Base(urlPath)
if cleanPath == "." || cleanPath == "/" || cleanPath == "" {
cleanPath = "index.html"
}
f, err := os.Create(filepath.Join(name, cleanPath)) //nolint
if err != nil {
return nil, err
}
Expand Down
1 change: 1 addition & 0 deletions pkg/dmsghttp/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func ListenAndServe(ctx context.Context, _ cipher.SecKey, a http.Handler, _ disc
WriteTimeout: 3 * time.Second,
IdleTimeout: 30 * time.Second,
ReadHeaderTimeout: 3 * time.Second,
MaxHeaderBytes: 1 << 14, // 16KB
Handler: a,
}

Expand Down
11 changes: 7 additions & 4 deletions pkg/dmsgpty/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net/url"
"strings"
"sync/atomic"
"time"

"github.com/sirupsen/logrus"
"github.com/skycoin/skywire/pkg/skywire-utilities/pkg/cipher"
Expand Down Expand Up @@ -64,6 +65,7 @@ func (h *Host) ServeCLI(ctx context.Context, lis net.Listener) error {
// This is the main comment for reference https://github.com/golang/go/issues/45729#issuecomment-1104607098
if err, ok := err.(net.Error); ok && err.Temporary() { //nolint
log.Warn("Failed to accept CLI connection with temporary error, continuing...")
time.Sleep(50 * time.Millisecond)
continue
}
if err == io.ErrClosedPipe || strings.Contains(err.Error(), "use of closed network connection") {
Expand Down Expand Up @@ -118,6 +120,7 @@ func (h *Host) ListenAndServe(ctx context.Context, port uint16) error {
// This is the main comment for reference https://github.com/golang/go/issues/45729#issuecomment-1104607098
if err, ok := err.(net.Error); ok && err.Temporary() { //nolint
log.Warn("Failed to accept dmsg.Stream with temporary error, continuing...")
time.Sleep(50 * time.Millisecond)
continue
}
if err == io.ErrClosedPipe || err == dmsg.ErrEntityClosed ||
Expand Down Expand Up @@ -197,15 +200,15 @@ func (h *Host) log() logrus.FieldLogger {

// cliEndpoints returns the endpoints served for CLI connections.
func cliEndpoints(h *Host) (mux hostMux) {
mux.Handle(WhitelistURI, handleWhitelist(h))
mux.Handle(PtyURI, handlePty(h))
mux.Handle(PtyProxyURI, handleProxy(h))
mux.Handle(WhitelistURI, handleWhitelist(h)) //nolint:errcheck,gosec
mux.Handle(PtyURI, handlePty(h)) //nolint:errcheck,gosec
mux.Handle(PtyProxyURI, handleProxy(h)) //nolint:errcheck,gosec
return mux
}

// dmsgEndpoints returns the endpoints served for remote dmsg connections.
func dmsgEndpoints(h *Host) (mux hostMux) {
mux.Handle(PtyURI, handlePty(h))
mux.Handle(PtyURI, handlePty(h)) //nolint:errcheck,gosec
return mux
}

Expand Down
8 changes: 5 additions & 3 deletions pkg/dmsgpty/host_mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package dmsgpty
import (
"context"
"errors"
"fmt"
"net"
"net/rpc"
"net/url"
Expand All @@ -22,15 +23,16 @@ type hostMux struct {

type handleFunc func(ctx context.Context, uri *url.URL, rpcS *rpc.Server) error

func (h *hostMux) Handle(pattern string, fn handleFunc) {
func (h *hostMux) Handle(pattern string, fn handleFunc) error {
pattern = strings.TrimPrefix(pattern, "/")
if _, err := path.Match(pattern, ""); err != nil {
panic(err)
return fmt.Errorf("invalid mux pattern %q: %w", pattern, err)
}
h.entries = append(h.entries, muxEntry{
pat: pattern,
fn: fn,
})
return nil
}

func (h *hostMux) ServeConn(ctx context.Context, conn net.Conn) error {
Expand All @@ -49,7 +51,7 @@ func (h *hostMux) ServeConn(ctx context.Context, conn net.Conn) error {
for _, entry := range h.entries {
ok, err := path.Match(entry.pat, uri.EscapedPath())
if err != nil {
panic(err)
return fmt.Errorf("path match error for pattern %q: %w", entry.pat, err)
}
if !ok {
continue
Expand Down
31 changes: 25 additions & 6 deletions pkg/dmsgpty/pty_gateway.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Package dmsgpty pkg/dmsgpty/pty_gateway.go
package dmsgpty

import "fmt"

// WinSize wraps around pty.Winsize and *windows.Coord
type WinSize struct {
X uint16
Expand Down Expand Up @@ -41,11 +43,21 @@ func (g *LocalPtyGateway) Stop(_, _ *struct{}) error {
return g.ses.Stop()
}

// maxPtyReadSize is the maximum bytes that can be requested in a single PTY read.
const maxPtyReadSize = 64 * 1024 // 64KB

// Read reads from the local pty.
func (g *LocalPtyGateway) Read(reqN *int, respB *[]byte) error {
b := make([]byte, *reqN)
n, err := g.ses.Read(b)
*respB = b[:n]
n := *reqN
if n <= 0 {
return fmt.Errorf("invalid read size: %d", n)
}
if n > maxPtyReadSize {
n = maxPtyReadSize
}
b := make([]byte, n)
nr, err := g.ses.Read(b)
*respB = b[:nr]
return err
}

Expand Down Expand Up @@ -93,9 +105,16 @@ func (g *ProxiedPtyGateway) Stop(_, _ *struct{}) error {

// Read reads from the remote pty.
func (g *ProxiedPtyGateway) Read(reqN *int, respB *[]byte) error {
b := make([]byte, *reqN)
n, err := g.ptyC.Read(b)
*respB = b[:n]
n := *reqN
if n <= 0 {
return fmt.Errorf("invalid read size: %d", n)
}
if n > maxPtyReadSize {
n = maxPtyReadSize
}
b := make([]byte, n)
nr, err := g.ptyC.Read(b)
*respB = b[:nr]
return err
}

Expand Down
Loading
Loading