Skip to content

Commit 1423235

Browse files
author
Carlos Ibáñez
committed
[main] Add -- cmd flag separator to start different Gost instances
1 parent 1bead18 commit 1423235

File tree

1 file changed

+125
-67
lines changed

1 file changed

+125
-67
lines changed

cmd/gost/main.go

+125-67
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"fmt"
88
"net/http"
99
"os"
10+
"sync"
11+
"strings"
1012
"runtime"
1113

1214
_ "net/http/pprof"
@@ -16,56 +18,148 @@ import (
1618
)
1719

1820
var (
19-
configureFile string
20-
baseCfg = &baseConfig{}
21-
pprofAddr string
2221
pprofEnabled = os.Getenv("PROFILING") != ""
2322
)
2423

2524
func init() {
2625
gost.SetLogger(&gost.LogLogger{})
2726

27+
// TODO - Generate different certificates for each worker
28+
generateTLSCertificate()
29+
}
30+
31+
func main() {
32+
var wg sync.WaitGroup
33+
wg.Add(1) // Gost must exit if any of the workers exit
34+
35+
// Split os.Args using -- and create a worker with each slice
36+
args := strings.Split(" " + strings.Join(os.Args[1:], " ") + " ", " -- ")
37+
if strings.Join(args, "") == "" {
38+
// Fix to show gost help if the resulting array is empty
39+
args[0] = " "
40+
}
41+
for wid, wargs := range args {
42+
if wargs != "" {
43+
go worker(wid, wargs, &wg)
44+
}
45+
}
46+
wg.Wait()
47+
}
48+
49+
func worker(id int, args string, wg *sync.WaitGroup) {
50+
defer wg.Done()
51+
2852
var (
29-
printVersion bool
53+
configureFile string
54+
baseCfg = &baseConfig{}
55+
pprofAddr string
3056
)
3157

32-
flag.Var(&baseCfg.route.ChainNodes, "F", "forward address, can make a forward chain")
33-
flag.Var(&baseCfg.route.ServeNodes, "L", "listen address, can listen on multiple ports (required)")
34-
flag.StringVar(&configureFile, "C", "", "configure file")
35-
flag.BoolVar(&baseCfg.Debug, "D", false, "enable debug log")
36-
flag.BoolVar(&printVersion, "V", false, "print version")
37-
if pprofEnabled {
38-
flag.StringVar(&pprofAddr, "P", ":6060", "profiling HTTP server address")
39-
}
40-
flag.Parse()
58+
init := func () error {
59+
var printVersion bool
60+
61+
wf := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
62+
63+
wf.Var(&baseCfg.route.ChainNodes, "F", "forward address, can make a forward chain")
64+
wf.Var(&baseCfg.route.ServeNodes, "L", "listen address, can listen on multiple ports (required)")
65+
wf.StringVar(&configureFile, "C", "", "configure file")
66+
wf.BoolVar(&baseCfg.Debug, "D", false, "enable debug log")
67+
wf.BoolVar(&printVersion, "V", false, "print version")
68+
69+
if pprofEnabled {
70+
// Every worker uses a different profiling server by default
71+
wf.StringVar(&pprofAddr, "P", fmt.Sprintf(":606%d", id), "profiling HTTP server address")
72+
}
73+
74+
wf.Parse(strings.Fields(args))
75+
76+
if printVersion {
77+
fmt.Fprintf(os.Stdout, "gost %s (%s %s/%s)\n", gost.Version, runtime.Version(), runtime.GOOS, runtime.GOARCH)
78+
os.Exit(0)
79+
} else if wf.NFlag() == 0 {
80+
wf.Usage()
81+
os.Exit(0)
82+
} else if configureFile != "" {
83+
err := parseBaseConfig(configureFile, baseCfg)
84+
if err != nil {
85+
return err
86+
}
87+
}
4188

42-
if printVersion {
43-
fmt.Fprintf(os.Stdout, "gost %s (%s %s/%s)\n",
44-
gost.Version, runtime.Version(), runtime.GOOS, runtime.GOARCH)
45-
os.Exit(0)
89+
if baseCfg.route.ServeNodes.String() == "[]" {
90+
configErrMsg := ""
91+
if configureFile != "" {
92+
configErrMsg = " or ServeNodes inside config file (-C)"
93+
}
94+
fmt.Fprintf(os.Stderr, "\n[!] Error: Missing -L flag%s\n\n", configErrMsg)
95+
wf.Usage()
96+
os.Exit(1)
97+
}
98+
99+
return nil
46100
}
47101

48-
if configureFile != "" {
49-
_, err := parseBaseConfig(configureFile)
102+
start := func () error {
103+
// TODO - Make debug worker independent
104+
if ! gost.Debug {
105+
gost.Debug = baseCfg.Debug
106+
}
107+
108+
var routers []router
109+
rts, err := baseCfg.route.GenRouters()
50110
if err != nil {
51-
log.Log(err)
52-
os.Exit(1)
111+
return err
112+
}
113+
routers = append(routers, rts...)
114+
115+
for _, route := range baseCfg.Routes {
116+
rts, err := route.GenRouters()
117+
if err != nil {
118+
return err
119+
}
120+
routers = append(routers, rts...)
121+
}
122+
123+
if len(routers) == 0 {
124+
return errors.New("invalid config")
53125
}
126+
for i := range routers {
127+
go routers[i].Serve()
128+
}
129+
130+
return nil
54131
}
55-
if flag.NFlag() == 0 {
56-
flag.PrintDefaults()
57-
os.Exit(0)
132+
133+
main := func () error {
134+
if pprofEnabled {
135+
go func() {
136+
log.Log("profiling server on", pprofAddr)
137+
log.Log(http.ListenAndServe(pprofAddr, nil))
138+
}()
139+
}
140+
141+
err := start()
142+
return err
58143
}
59-
}
60144

61-
func main() {
62-
if pprofEnabled {
63-
go func() {
64-
log.Log("profiling server on", pprofAddr)
65-
log.Log(http.ListenAndServe(pprofAddr, nil))
66-
}()
145+
if err := init(); err != nil {
146+
log.Log(err)
147+
return
148+
}
149+
if err := main(); err != nil {
150+
log.Log(err)
151+
return
67152
}
68153

154+
// Allow local functions to be garbage-collected
155+
init = nil
156+
main = nil
157+
start = nil
158+
159+
select {}
160+
}
161+
162+
func generateTLSCertificate() {
69163
// NOTE: as of 2.6, you can use custom cert/key files to initialize the default certificate.
70164
tlsConfig, err := tlsConfig(defaultCertFile, defaultKeyFile, "")
71165
if err != nil {
@@ -81,41 +175,5 @@ func main() {
81175
} else {
82176
log.Log("load TLS certificate files OK")
83177
}
84-
85178
gost.DefaultTLSConfig = tlsConfig
86-
87-
if err := start(); err != nil {
88-
log.Log(err)
89-
os.Exit(1)
90-
}
91-
92-
select {}
93-
}
94-
95-
func start() error {
96-
gost.Debug = baseCfg.Debug
97-
98-
var routers []router
99-
rts, err := baseCfg.route.GenRouters()
100-
if err != nil {
101-
return err
102-
}
103-
routers = append(routers, rts...)
104-
105-
for _, route := range baseCfg.Routes {
106-
rts, err := route.GenRouters()
107-
if err != nil {
108-
return err
109-
}
110-
routers = append(routers, rts...)
111-
}
112-
113-
if len(routers) == 0 {
114-
return errors.New("invalid config")
115-
}
116-
for i := range routers {
117-
go routers[i].Serve()
118-
}
119-
120-
return nil
121179
}

0 commit comments

Comments
 (0)