Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

skysocksc command #1455

Merged
merged 6 commits into from
Jan 25, 2023
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
3 changes: 2 additions & 1 deletion cmd/apps/skysocks-client/skysocks-client.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const (
var r = netutil.NewRetrier(nil, time.Second, netutil.DefaultMaxBackoff, 0, 1)

func dialServer(ctx context.Context, appCl *app.Client, pk cipher.PubKey) (net.Conn, error) {
appCl.SetDetailedStatus(appserver.AppDetailedStatusStarting) //nolint
var conn net.Conn
err := r.Do(ctx, func() error {
var err error
Expand Down Expand Up @@ -89,7 +90,6 @@ func main() {
}

fmt.Printf("Connected to %v\n", pk)

client, err := skysocks.NewClient(conn, appCl)
if err != nil {
print(fmt.Sprintf("Failed to create a new client: %v\n", err))
Expand All @@ -98,6 +98,7 @@ func main() {
}

fmt.Printf("Serving proxy client %v\n", *addr)
setAppStatus(appCl, appserver.AppDetailedStatusRunning)

if err := client.ListenAndServe(*addr); err != nil {
print(fmt.Sprintf("Error serving proxy client: %v\n", err))
Expand Down
2 changes: 2 additions & 0 deletions cmd/skywire-cli/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
clirtfind "github.com/skycoin/skywire/cmd/skywire-cli/commands/rtfind"
cliskyfwd "github.com/skycoin/skywire/cmd/skywire-cli/commands/skyfwd"
cliskyrev "github.com/skycoin/skywire/cmd/skywire-cli/commands/skyrev"
cliskysocksc "github.com/skycoin/skywire/cmd/skywire-cli/commands/skysocksc"
clisurvey "github.com/skycoin/skywire/cmd/skywire-cli/commands/survey"
clivisor "github.com/skycoin/skywire/cmd/skywire-cli/commands/visor"
clivpn "github.com/skycoin/skywire/cmd/skywire-cli/commands/vpn"
Expand Down Expand Up @@ -188,6 +189,7 @@ func init() {
climdisc.RootCmd,
clicompletion.RootCmd,
clilog.RootCmd,
cliskysocksc.RootCmd,
treeCmd,
docCmd,
)
Expand Down
12 changes: 12 additions & 0 deletions cmd/skywire-cli/commands/skysocksc/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Package skysocksc root.go
package skysocksc

import (
"github.com/spf13/cobra"
)

// RootCmd contains commands that interact with the skywire-visor
var RootCmd = &cobra.Command{
Use: "skysocksc",
Short: "controls for Skysocks client",
}
122 changes: 122 additions & 0 deletions cmd/skywire-cli/commands/skysocksc/skysocksc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// Package skysocksc cmd/skywire-cli/commands/skysocksc/skysocks.go
package skysocksc

import (
"bytes"
"fmt"
"os"
"text/tabwriter"
"time"

"github.com/spf13/cobra"

clirpc "github.com/skycoin/skywire/cmd/skywire-cli/commands/rpc"
"github.com/skycoin/skywire/cmd/skywire-cli/internal"
"github.com/skycoin/skywire/pkg/app/appserver"
)

var pk string

func init() {
RootCmd.PersistentFlags().StringVar(&clirpc.Addr, "rpc", "localhost:3435", "RPC server address")
RootCmd.AddCommand(
skysockscStartCmd,
skysockscStopCmd,
skysockscStatusCmd,
)
skysockscStartCmd.Flags().StringVar(&pk, "pk", "", "skysocks server public key")
}

var skysockscStartCmd = &cobra.Command{
Use: "start",
Short: "start the skysocks-client",
Args: cobra.MinimumNArgs(0),
Run: func(cmd *cobra.Command, args []string) {
rpcClient, err := clirpc.Client(cmd.Flags())
if err != nil {
os.Exit(1)
}
internal.Catch(cmd.Flags(), rpcClient.StartSkysocksClient(pk))
internal.PrintOutput(cmd.Flags(), nil, "Starting.")
startProcess := true
for startProcess {
time.Sleep(time.Second * 1)
internal.PrintOutput(cmd.Flags(), nil, ".")
states, err := rpcClient.Apps()
internal.Catch(cmd.Flags(), err)

type output struct {
AppError string `json:"app_error,omitempty"`
}

for _, state := range states {
if state.Name == "skysocks-client" {
if state.Status == appserver.AppStatusRunning {
startProcess = false
internal.PrintOutput(cmd.Flags(), nil, fmt.Sprintln("\nRunning!"))
}
if state.Status == appserver.AppStatusErrored {
startProcess = false
out := output{
AppError: state.DetailedStatus,
}
internal.PrintOutput(cmd.Flags(), out, fmt.Sprintln("\nError! > "+state.DetailedStatus))
}
}
}
}
},
}

var skysockscStopCmd = &cobra.Command{
Use: "stop",
Short: "stop the skysocks-client",
Run: func(cmd *cobra.Command, _ []string) {
rpcClient, err := clirpc.Client(cmd.Flags())
if err != nil {
os.Exit(1)
}
internal.Catch(cmd.Flags(), rpcClient.StopSkysocksClient())
internal.PrintOutput(cmd.Flags(), "OK", fmt.Sprintln("OK"))
},
}

var skysockscStatusCmd = &cobra.Command{
Use: "status",
Short: "skysocks-client status",
Run: func(cmd *cobra.Command, _ []string) {
rpcClient, err := clirpc.Client(cmd.Flags())
if err != nil {
os.Exit(1)
}
states, err := rpcClient.Apps()
internal.Catch(cmd.Flags(), err)

var b bytes.Buffer
w := tabwriter.NewWriter(&b, 0, 0, 5, ' ', tabwriter.TabIndent)
internal.Catch(cmd.Flags(), err)
type appState struct {
Status string `json:"status"`
}
var jsonAppStatus appState
for _, state := range states {
if state.Name == "skysocks-client" {

status := "stopped"
if state.Status == appserver.AppStatusRunning {
status = "running"
}
if state.Status == appserver.AppStatusErrored {
status = "errored"
}
jsonAppStatus = appState{
Status: status,
}
_, err = fmt.Fprintf(w, "%s\n", status)
internal.Catch(cmd.Flags(), err)
}
}
internal.Catch(cmd.Flags(), w.Flush())
internal.PrintOutput(cmd.Flags(), jsonAppStatus, b.String())
},
}
10 changes: 0 additions & 10 deletions internal/skysocks/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/skycoin/yamux"

"github.com/skycoin/skywire/pkg/app"
"github.com/skycoin/skywire/pkg/app/appserver"
"github.com/skycoin/skywire/pkg/router"
"github.com/skycoin/skywire/pkg/skyenv"
)
Expand Down Expand Up @@ -61,9 +60,6 @@ func (c *Client) ListenAndServe(addr string) error {
fmt.Printf("Listening skysocks client on %s", addr)

c.listener = l
if c.appCl != nil {
c.setAppStatus(appserver.AppDetailedStatusRunning)
}

for {
select {
Expand Down Expand Up @@ -174,12 +170,6 @@ func (c *Client) ListenIPC(client *ipc.Client) {
})
}

func (c *Client) setAppStatus(status appserver.AppDetailedStatus) {
if err := c.appCl.SetDetailedStatus(string(status)); err != nil {
print(fmt.Sprintf("Failed to set status %v: %v\n", status, err))
}
}

func (c *Client) setAppError(appErr error) {
if err := c.appCl.SetError(appErr.Error()); err != nil {
print(fmt.Sprintf("Failed to set error %v: %v\n", appErr, err))
Expand Down
3 changes: 1 addition & 2 deletions pkg/servicedisc/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ import (
const (
// ServiceTypeSkysocks stands for the skysocks discovery.
ServiceTypeSkysocks = "skysocks"
// ServiceTypeProxy stands for the proxy discovery.
// proxy and skysock are same
// ServiceTypeProxy stands for the proxy discovery. Proxy and Skysocks are same
ServiceTypeProxy = "proxy"
// ServiceTypeVPN stands for the VPN discovery.
ServiceTypeVPN = "vpn"
Expand Down
87 changes: 80 additions & 7 deletions pkg/visor/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ type API interface {
StopVPNClient(appName string) error
VPNServers(version, country string) ([]servicedisc.Service, error)

//skysocks-client controls
StartSkysocksClient(pk string) error
StopSkysocksClient() error

//transports
TransportTypes() ([]string, error)
Transports(types []string, pks []cipher.PubKey, logs bool) ([]*TransportSummary, error)
Expand Down Expand Up @@ -511,6 +515,61 @@ func (v *Visor) StopVPNClient(appName string) error {
return ErrProcNotAvailable
}

// StartSkysocksClient implements API.
func (v *Visor) StartSkysocksClient(serverKey string) error {
var envs []string
if v.tpM == nil {
return ErrTrpMangerNotAvailable
}

if len(v.conf.Launcher.Apps) == 0 {
return errors.New("no skysocks-client app configuration found")
}

for index, app := range v.conf.Launcher.Apps {
if app.Name == visorconfig.SkysocksClientName {
if v.GetSkysocksClientAddress() == "" && serverKey == "" {
return errors.New("Skysocks server pub key is missing")
}

if serverKey != "" {
var pk cipher.PubKey
if err := pk.Set(serverKey); err != nil {
return err
}
v.SetAppPK(visorconfig.SkysocksClientName, pk) //nolint
// we set the args in memory and pass it in `v.appL.StartApp`
// unlike the api method `StartApp` where `nil` is passed in `v.appL.StartApp` as args
// but the args are set in the config
v.conf.Launcher.Apps[index].Args = []string{"-srv", pk.Hex()}
} else {
var pk cipher.PubKey
if err := pk.Set(v.GetSkysocksClientAddress()); err != nil {
return err
}
v.conf.Launcher.Apps[index].Args = []string{"-srv", pk.Hex()}
}

// check process manager availability
if v.procM != nil {
return v.appL.StartApp(visorconfig.SkysocksClientName, v.conf.Launcher.Apps[index].Args, envs)
}
return ErrProcNotAvailable
}
}
return errors.New("no skysocks-client app configuration found")
}

// StopSkysocksClient implements API.
func (v *Visor) StopSkysocksClient() error {
// check process manager availability
if v.procM != nil {
_, err := v.appL.StopApp(visorconfig.SkysocksClientName) //nolint:errcheck
return err
}
return ErrProcNotAvailable
}

// SetAppDetailedStatus implements API.
func (v *Visor) SetAppDetailedStatus(appName, status string) error {
proc, ok := v.procM.ProcByName(appName)
Expand Down Expand Up @@ -553,7 +612,7 @@ func (v *Visor) SetAutoStart(appName string, autoStart bool) error {
}

v.log.Infof("Saving auto start = %v for app %v to config", autoStart, appName)
return v.conf.UpdateAppAutostart(appName, autoStart)
return v.conf.UpdateAppAutostart(v.appL, appName, autoStart)
}

// SetAppPassword implements API.
Expand All @@ -578,7 +637,7 @@ func (v *Visor) SetAppPassword(appName, password string) error {
const (
passcodeArgName = "-passcode"
)
if err := v.conf.UpdateAppArg(appName, passcodeArgName, password); err != nil {
if err := v.conf.UpdateAppArg(v.appL, appName, passcodeArgName, password); err != nil {
return err
}

Expand All @@ -598,7 +657,7 @@ func (v *Visor) SetAppNetworkInterface(appName, netifc string) error {
const (
netifcArgName = "--netifc"
)
if err := v.conf.UpdateAppArg(appName, netifcArgName, netifc); err != nil {
if err := v.conf.UpdateAppArg(v.appL, appName, netifcArgName, netifc); err != nil {
return err
}

Expand All @@ -618,7 +677,7 @@ func (v *Visor) SetAppKillswitch(appName string, killswitch bool) error {
const (
killSwitchArg = "--killswitch"
)
if err := v.conf.UpdateAppArg(appName, killSwitchArg, killswitch); err != nil {
if err := v.conf.UpdateAppArg(v.appL, appName, killSwitchArg, killswitch); err != nil {
return err
}

Expand All @@ -638,7 +697,7 @@ func (v *Visor) SetAppSecure(appName string, isSecure bool) error {
const (
secureArgName = "--secure"
)
if err := v.conf.UpdateAppArg(appName, secureArgName, isSecure); err != nil {
if err := v.conf.UpdateAppArg(v.appL, appName, secureArgName, isSecure); err != nil {
return err
}
v.log.Infof("Updated %v secure state", appName)
Expand Down Expand Up @@ -667,7 +726,7 @@ func (v *Visor) SetAppPK(appName string, pk cipher.PubKey) error {
const (
pkArgName = "-srv"
)
if err := v.conf.UpdateAppArg(appName, pkArgName, pk.String()); err != nil {
if err := v.conf.UpdateAppArg(v.appL, appName, pkArgName, pk.String()); err != nil {
return err
}

Expand Down Expand Up @@ -697,7 +756,7 @@ func (v *Visor) SetAppDNS(appName string, dnsAddr string) error {
pkArgName = "-dns"
)

if err := v.conf.UpdateAppArg(appName, pkArgName, dnsAddr); err != nil {
if err := v.conf.UpdateAppArg(v.appL, appName, pkArgName, dnsAddr); err != nil {
return err
}

Expand Down Expand Up @@ -1274,6 +1333,20 @@ func (v *Visor) GetVPNClientAddress() string {
return ""
}

// GetSkysocksClientAddress get PK address of server set on skysocks-client
func (v *Visor) GetSkysocksClientAddress() string {
for _, v := range v.conf.Launcher.Apps {
if v.Name == visorconfig.SkysocksClientAddr {
for index := range v.Args {
if v.Args[index] == "-srv" {
return v.Args[index+1]
}
}
}
}
return ""
}

// IsDMSGClientReady return availability of dsmg client
func (v *Visor) IsDMSGClientReady() (bool, error) {
if v.isDTMReady() {
Expand Down
14 changes: 14 additions & 0 deletions pkg/visor/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,20 @@ func (r *RPC) StopVPNClient(name *string, _ *struct{}) (err error) {
return r.visor.StopVPNClient(*name)
}

// StartSkysocksClient starts SkysocksClient App
func (r *RPC) StartSkysocksClient(pk string, _ *struct{}) (err error) {
defer rpcutil.LogCall(r.log, "StartSkysocksClient", pk)(nil, &err)

return r.visor.StartSkysocksClient(pk)
}

// StopSkysocksClient stops SkysocksClient App
func (r *RPC) StopSkysocksClient(_ *struct{}, _ *struct{}) (err error) {
defer rpcutil.LogCall(r.log, "StopSkysocksClient", nil)(nil, &err)

return r.visor.StopSkysocksClient()
}

// RestartApp restarts App with provided name.
func (r *RPC) RestartApp(name *string, _ *struct{}) (err error) {
defer rpcutil.LogCall(r.log, "RestartApp", name)(nil, &err)
Expand Down
Loading