Skip to content

Commit 18a2af4

Browse files
authored
frpc: support multiple confs (fatedier#2873)
1 parent 305e40f commit 18a2af4

File tree

5 files changed

+66
-32
lines changed

5 files changed

+66
-32
lines changed

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ file:
1616
fmt:
1717
go fmt ./...
1818

19+
vet:
20+
go vet ./...
21+
1922
frps:
2023
env CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o bin/frps ./cmd/frps
2124

@@ -37,7 +40,7 @@ e2e:
3740
e2e-trace:
3841
DEBUG=true LOG_LEVEL=trace ./hack/run-e2e.sh
3942

40-
alltest: gotest e2e
43+
alltest: vet gotest e2e
4144

4245
clean:
4346
rm -f ./bin/frpc

client/service.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ import (
1919
"crypto/tls"
2020
"fmt"
2121
"io"
22+
"math/rand"
2223
"net"
2324
"runtime"
2425
"strconv"
26+
"strings"
2527
"sync"
2628
"sync/atomic"
2729
"time"
@@ -36,11 +38,17 @@ import (
3638
"github.com/fatedier/frp/pkg/util/util"
3739
"github.com/fatedier/frp/pkg/util/version"
3840
"github.com/fatedier/frp/pkg/util/xlog"
41+
"github.com/fatedier/golib/crypto"
3942
libdial "github.com/fatedier/golib/net/dial"
4043

4144
fmux "github.com/hashicorp/yamux"
4245
)
4346

47+
func init() {
48+
crypto.DefaultSalt = "frp"
49+
rand.Seed(time.Now().UnixNano())
50+
}
51+
4452
// Service is a client service.
4553
type Service struct {
4654
// uniq id got from frps, attach it in loginMsg
@@ -98,6 +106,21 @@ func (svr *Service) GetController() *Control {
98106
func (svr *Service) Run() error {
99107
xl := xlog.FromContextSafe(svr.ctx)
100108

109+
// set custom DNSServer
110+
if svr.cfg.DNSServer != "" {
111+
dnsAddr := svr.cfg.DNSServer
112+
if !strings.Contains(dnsAddr, ":") {
113+
dnsAddr += ":53"
114+
}
115+
// Change default dns server for frpc
116+
net.DefaultResolver = &net.Resolver{
117+
PreferGo: true,
118+
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
119+
return net.Dial("udp", dnsAddr)
120+
},
121+
}
122+
}
123+
101124
// login to frps
102125
for {
103126
conn, session, err := svr.login()

cmd/frpc/main.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,10 @@
1515
package main
1616

1717
import (
18-
"math/rand"
19-
"time"
20-
2118
_ "github.com/fatedier/frp/assets/frpc"
2219
"github.com/fatedier/frp/cmd/frpc/sub"
23-
24-
"github.com/fatedier/golib/crypto"
2520
)
2621

2722
func main() {
28-
crypto.DefaultSalt = "frp"
29-
rand.Seed(time.Now().UnixNano())
30-
3123
sub.Execute()
3224
}

cmd/frpc/sub/root.go

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@
1515
package sub
1616

1717
import (
18-
"context"
1918
"fmt"
19+
"io/fs"
2020
"net"
2121
"os"
2222
"os/signal"
23+
"path/filepath"
2324
"strconv"
24-
"strings"
25+
"sync"
2526
"syscall"
2627
"time"
2728

@@ -41,6 +42,7 @@ const (
4142

4243
var (
4344
cfgFile string
45+
cfgDir string
4446
showVersion bool
4547

4648
serverAddr string
@@ -72,15 +74,12 @@ var (
7274
bindPort int
7375

7476
tlsEnable bool
75-
76-
kcpDoneCh chan struct{}
7777
)
7878

7979
func init() {
8080
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "./frpc.ini", "config file of frpc")
81+
rootCmd.PersistentFlags().StringVarP(&cfgDir, "config_dir", "", "", "config directory, run one frpc service for each file in config directory")
8182
rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of frpc")
82-
83-
kcpDoneCh = make(chan struct{})
8483
}
8584

8685
func RegisterCommonFlags(cmd *cobra.Command) {
@@ -104,6 +103,31 @@ var rootCmd = &cobra.Command{
104103
return nil
105104
}
106105

106+
// If cfgDir is not empty, run multiple frpc service for each config file in cfgDir.
107+
// Note that it's only designed for testing. It's not guaranteed to be stable.
108+
if cfgDir != "" {
109+
var wg sync.WaitGroup
110+
filepath.WalkDir(cfgDir, func(path string, d fs.DirEntry, err error) error {
111+
if err != nil {
112+
return nil
113+
}
114+
if d.IsDir() {
115+
return nil
116+
}
117+
wg.Add(1)
118+
go func() {
119+
defer wg.Done()
120+
err := runClient(path)
121+
if err != nil {
122+
fmt.Printf("frpc service error for config file [%s]\n", path)
123+
}
124+
}()
125+
return nil
126+
})
127+
wg.Wait()
128+
return nil
129+
}
130+
107131
// Do not show command usage here.
108132
err := runClient(cfgFile)
109133
if err != nil {
@@ -120,12 +144,12 @@ func Execute() {
120144
}
121145
}
122146

123-
func handleSignal(svr *client.Service) {
124-
ch := make(chan os.Signal)
147+
func handleSignal(svr *client.Service, doneCh chan struct{}) {
148+
ch := make(chan os.Signal, 1)
125149
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
126150
<-ch
127151
svr.GracefulClose(500 * time.Millisecond)
128-
close(kcpDoneCh)
152+
close(doneCh)
129153
}
130154

131155
func parseClientCommonCfgFromCmd() (cfg config.ClientCommonConf, err error) {
@@ -182,28 +206,20 @@ func startService(
182206
log.InitLog(cfg.LogWay, cfg.LogFile, cfg.LogLevel,
183207
cfg.LogMaxDays, cfg.DisableLogColor)
184208

185-
if cfg.DNSServer != "" {
186-
s := cfg.DNSServer
187-
if !strings.Contains(s, ":") {
188-
s += ":53"
189-
}
190-
// Change default dns server for frpc
191-
net.DefaultResolver = &net.Resolver{
192-
PreferGo: true,
193-
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
194-
return net.Dial("udp", s)
195-
},
196-
}
209+
if cfgFile != "" {
210+
log.Trace("start frpc service for config file [%s]", cfgFile)
211+
defer log.Trace("frpc service for config file [%s] stopped", cfgFile)
197212
}
198213
svr, errRet := client.NewService(cfg, pxyCfgs, visitorCfgs, cfgFile)
199214
if errRet != nil {
200215
err = errRet
201216
return
202217
}
203218

219+
kcpDoneCh := make(chan struct{})
204220
// Capture the exit signal if we use kcp.
205221
if cfg.Protocol == "kcp" {
206-
go handleSignal(svr)
222+
go handleSignal(svr, kcpDoneCh)
207223
}
208224

209225
err = svr.Run()

test/e2e/plugin/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ var _ = Describe("[Feature: Server-Plugins]", func() {
150150
type = tcp
151151
local_port = {{ .%s }}
152152
remote_port = 0
153-
`, framework.TCPEchoServerPort, remotePort)
153+
`, framework.TCPEchoServerPort)
154154

155155
f.RunProcesses([]string{serverConf}, []string{clientConf})
156156

0 commit comments

Comments
 (0)