Skip to content

Commit 75d0277

Browse files
authored
Merge pull request #19 from threefoldtech/multile_remote_connection
allow client to connet to multiple router
2 parents c8b441f + 3e39eb3 commit 75d0277

File tree

5 files changed

+176
-89
lines changed

5 files changed

+176
-89
lines changed

client.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ package tcprouter
22

33
import (
44
"fmt"
5-
"github.com/rs/zerolog/log"
65
"io"
76
"net"
7+
8+
"github.com/rs/zerolog/log"
89
)
910

10-
type client struct {
11+
type Client struct {
1112
// connection to the tcp router server
1213
RemoteConn net.Conn
1314
// connection to the local application
@@ -18,13 +19,13 @@ type client struct {
1819
}
1920

2021
// NewClient creates a new TCP router client
21-
func NewClient(secret string) *client {
22-
return &client{
22+
func NewClient(secret string) *Client {
23+
return &Client{
2324
secret: []byte(secret),
2425
}
2526
}
2627

27-
func (c *client) ConnectRemote(addr string) error {
28+
func (c *Client) ConnectRemote(addr string) error {
2829
if len(c.secret) == 0 {
2930
return fmt.Errorf("no secret configured")
3031
}
@@ -39,7 +40,7 @@ func (c *client) ConnectRemote(addr string) error {
3940
return nil
4041
}
4142

42-
func (c *client) ConnectLocal(addr string) error {
43+
func (c *Client) ConnectLocal(addr string) error {
4344
conn, err := net.Dial("tcp", addr)
4445
if err != nil {
4546
return err
@@ -50,7 +51,7 @@ func (c *client) ConnectLocal(addr string) error {
5051
return nil
5152
}
5253

53-
func (c *client) Handshake() error {
54+
func (c *Client) Handshake() error {
5455
if c.RemoteConn == nil {
5556
return fmt.Errorf("not connected")
5657
}
@@ -64,7 +65,7 @@ func (c *client) Handshake() error {
6465
return h.Write(c.RemoteConn)
6566
}
6667

67-
func (c *client) Forward() {
68+
func (c *Client) Forward() {
6869

6970
cErr := make(chan error)
7071
defer func() {

cmds/client/main.go

Lines changed: 96 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,123 @@
11
package main
22

33
import (
4-
"flag"
4+
"context"
55
"fmt"
66
"os"
7+
"os/signal"
78
"time"
89

910
"github.com/cenkalti/backoff/v3"
1011
"github.com/rs/zerolog"
1112
"github.com/rs/zerolog/log"
12-
"github.com/xmonader/tcprouter"
13-
)
14-
15-
var (
16-
secret string
17-
remoteAddr string
18-
localAddr string
19-
boDuration int
13+
"github.com/threefoldtech/tcprouter"
14+
"github.com/urfave/cli/v2"
2015
)
2116

2217
func main() {
18+
app := cli.NewApp()
19+
app.Version = "0.0.1"
20+
app.Usage = "TCP router client"
21+
app.EnableBashCompletion = true
22+
app.Flags = []cli.Flag{
23+
&cli.StringFlag{
24+
Name: "secret",
25+
Usage: "secret to identify the connection",
26+
},
27+
&cli.StringSliceFlag{
28+
Name: "remote",
29+
Usage: "address to the TCP router server, this flag can be used multiple time to connect to multiple server",
30+
},
31+
&cli.StringFlag{
32+
Name: "local",
33+
Usage: "address to the local application",
34+
},
35+
&cli.IntFlag{
36+
Name: "backoff",
37+
Value: 5,
38+
Usage: "backoff in second",
39+
},
40+
}
2341
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
42+
app.Action = func(c *cli.Context) error {
43+
remotes := c.StringSlice("remote")
44+
local := c.String("local")
45+
backoff := c.Int("backoff")
46+
secret := c.String("secret")
47+
48+
cSig := make(chan os.Signal)
49+
signal.Notify(cSig, os.Interrupt, os.Kill)
50+
51+
for _, remote := range remotes {
52+
c := connection{
53+
Secret: secret,
54+
Remote: remote,
55+
Local: local,
56+
Backoff: backoff,
57+
}
58+
go func() {
59+
start(context.TODO(), c)
60+
}()
61+
}
62+
63+
<-cSig
64+
65+
return nil
66+
}
67+
68+
err := app.Run(os.Args)
69+
if err != nil {
70+
log.Fatal().Msg(err.Error())
71+
}
72+
}
73+
74+
type connection struct {
75+
Secret string
76+
Remote string
77+
Local string
78+
Backoff int
79+
}
2480

25-
flag.StringVar(&secret, "secret", "", "secret to identity the connection")
26-
flag.StringVar(&remoteAddr, "remote", "", "address to the TCP router server")
27-
flag.StringVar(&localAddr, "local", "", "address to the local application")
28-
flag.IntVar(&boDuration, "backoff", 5, "backoff in second")
29-
flag.Parse()
81+
func start(ctx context.Context, c connection) {
82+
client := tcprouter.NewClient(c.Secret)
3083

31-
client := tcprouter.NewClient(secret)
3284
op := func() error {
3385
for {
34-
log.Info().
35-
Str("addr", remoteAddr).
36-
Msg("connect to TCP router server")
37-
if err := client.ConnectRemote(remoteAddr); err != nil {
38-
return fmt.Errorf("failed to connect to TCP router server: %w", err)
39-
}
4086

41-
log.Info().Msg("start hanshake")
42-
if err := client.Handshake(); err != nil {
43-
return fmt.Errorf("failed to hanshake with TCP router server: %w", err)
44-
}
45-
log.Info().Msg("hanshake done")
87+
select {
88+
case <-ctx.Done():
89+
log.Info().Msg("context canceled, stopping")
90+
return nil
4691

47-
log.Info().
48-
Str("addr", localAddr).
49-
Msg("connect to local application")
50-
if err := client.ConnectLocal(localAddr); err != nil {
51-
return fmt.Errorf("failed to connect to local application: %w", err)
52-
}
92+
default:
93+
94+
log.Info().
95+
Str("addr", c.Remote).
96+
Msg("connect to TCP router server")
97+
if err := client.ConnectRemote(c.Remote); err != nil {
98+
return fmt.Errorf("failed to connect to TCP router server: %w", err)
99+
}
100+
101+
log.Info().Msg("start hanshake")
102+
if err := client.Handshake(); err != nil {
103+
return fmt.Errorf("failed to hanshake with TCP router server: %w", err)
104+
}
105+
log.Info().Msg("hanshake done")
53106

54-
log.Info().Msg("wait incoming traffic")
55-
client.Forward()
107+
log.Info().
108+
Str("addr", c.Local).
109+
Msg("connect to local application")
110+
if err := client.ConnectLocal(c.Local); err != nil {
111+
return fmt.Errorf("failed to connect to local application: %w", err)
112+
}
113+
114+
log.Info().Msg("wait incoming traffic")
115+
client.Forward()
116+
}
56117
}
57118
}
58119

59-
bo := backoff.NewConstantBackOff(time.Second * time.Duration(boDuration))
120+
bo := backoff.NewConstantBackOff(time.Second * time.Duration(c.Backoff))
60121
notify := func(err error, d time.Duration) {
61122
log.Error().Err(err).Msgf("retry in %s", d)
62123
}

cmds/server/main.go

Lines changed: 59 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@ package main
22

33
import (
44
"context"
5-
"flag"
65
"fmt"
6+
"os/signal"
7+
78
"github.com/rs/zerolog"
89
"github.com/rs/zerolog/log"
9-
"os/signal"
10+
"github.com/urfave/cli/v2"
1011

1112
"os"
1213
"time"
1314

1415
"github.com/abronan/valkeyrie"
1516
"github.com/abronan/valkeyrie/store"
1617
"github.com/abronan/valkeyrie/store/redis"
17-
"github.com/xmonader/tcprouter"
18+
"github.com/threefoldtech/tcprouter"
1819
)
1920

2021
var validBackends = map[string]store.Backend{
@@ -66,51 +67,64 @@ var (
6667
)
6768

6869
func main() {
69-
70-
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
71-
72-
flag.StringVar(&cfgPath, "config", "", "Configuration file path")
73-
flag.Parse()
74-
75-
log.Printf("reading config from: %v", cfgPath)
76-
cfg, err := readConfig(cfgPath)
77-
if err != nil {
78-
log.Fatal().Err(err).Msg("failed to read configuration")
70+
app := cli.NewApp()
71+
app.Version = "0.0.1"
72+
app.Usage = "TCP router client"
73+
app.EnableBashCompletion = true
74+
app.Flags = []cli.Flag{
75+
&cli.StringFlag{
76+
Name: "config",
77+
Usage: "Path to configuration file",
78+
Value: "config.toml",
79+
},
7980
}
80-
log.Printf("main config: %+v", cfg)
81-
82-
if err := initBackend(cfg); err != nil {
83-
log.Fatal().Err(err).Msg("failed to initialize database backend")
81+
app.Action = func(c *cli.Context) error {
82+
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
83+
cfgPath := c.String("config")
84+
log.Printf("reading config from: %v", cfgPath)
85+
cfg, err := readConfig(cfgPath)
86+
if err != nil {
87+
log.Fatal().Err(err).Msg("failed to read configuration")
88+
}
89+
log.Printf("main config: %+v", cfg)
90+
91+
if err := initBackend(cfg); err != nil {
92+
log.Fatal().Err(err).Msg("failed to initialize database backend")
93+
}
94+
95+
backend := cfg.Server.DbBackend.Backend()
96+
addr := cfg.Server.DbBackend.Addr()
97+
kv, err := initStore(backend, addr)
98+
if err != nil {
99+
log.Fatal().
100+
Err(err).
101+
Str("backend type", string(backend)).
102+
Msg("Cannot create backend store")
103+
}
104+
105+
serverOpts := tcprouter.ServerOptions{
106+
ListeningAddr: cfg.Server.Host,
107+
ListeningTLSPort: cfg.Server.Port,
108+
ListeningHTTPPort: cfg.Server.HTTPPort,
109+
ListeningForClientsPort: cfg.Server.ClientsPort,
110+
}
111+
s := tcprouter.NewServer(serverOpts, kv, cfg.Server.Services)
112+
113+
cSig := make(chan os.Signal, 1)
114+
signal.Notify(cSig, os.Interrupt, os.Kill)
115+
116+
ctx, cancel := context.WithCancel(context.Background())
117+
go func() {
118+
// Block until a signal is received.
119+
<-cSig
120+
cancel()
121+
}()
122+
123+
return s.Start(ctx)
84124
}
85125

86-
backend := cfg.Server.DbBackend.Backend()
87-
addr := cfg.Server.DbBackend.Addr()
88-
kv, err := initStore(backend, addr)
126+
err := app.Run(os.Args)
89127
if err != nil {
90-
log.Fatal().
91-
Err(err).
92-
Str("backend type", string(backend)).
93-
Msg("Cannot create backend store")
94-
}
95-
96-
serverOpts := tcprouter.ServerOptions{
97-
ListeningAddr: cfg.Server.Host,
98-
ListeningTLSPort: cfg.Server.Port,
99-
ListeningHTTPPort: cfg.Server.HTTPPort,
100-
ListeningForClientsPort: cfg.Server.ClientsPort,
128+
log.Fatal().Msg(err.Error())
101129
}
102-
s := tcprouter.NewServer(serverOpts, kv, cfg.Server.Services)
103-
104-
c := make(chan os.Signal, 1)
105-
signal.Notify(c, os.Interrupt, os.Kill)
106-
107-
ctx, cancel := context.WithCancel(context.Background())
108-
go func() {
109-
// Block until a signal is received.
110-
<-c
111-
cancel()
112-
}()
113-
114-
s.Start(ctx)
115-
116130
}

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module github.com/xmonader/tcprouter
1+
module github.com/threefoldtech/tcprouter
22

33
go 1.13
44

@@ -9,4 +9,5 @@ require (
99
github.com/magiconair/properties v1.8.1
1010
github.com/rs/zerolog v1.15.0
1111
github.com/stretchr/testify v1.3.0
12+
github.com/urfave/cli/v2 v2.1.1
1213
)

0 commit comments

Comments
 (0)