From cacde72e04cb7a8ab5cc891e11f29384121f5803 Mon Sep 17 00:00:00 2001 From: nadoo <287492+nadoo@users.noreply.github.com> Date: Tue, 18 Jul 2017 17:49:44 +0800 Subject: [PATCH] add simple config file support. --- .gitignore | 3 +-- README.md | 42 ++++++++++++++++++-------------- main.go | 70 +++++++++++++++++++++++++++++------------------------ proxy.go | 8 +++--- strategy.go | 2 +- 5 files changed, 69 insertions(+), 56 deletions(-) diff --git a/.gitignore b/.gitignore index f342182..4e64827 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,6 @@ # custom *.zip - +*.conf glider - doc/ diff --git a/README.md b/README.md index 0e20069..ba2d431 100644 --- a/README.md +++ b/README.md @@ -7,18 +7,21 @@ glider is a forward proxy with several protocols support. ## Usage ```bash -glider v0.1 usage: - -checksite string - proxy check address (default "www.apple.com:443") - -duration int +glider v0.2 usage: + -checkduration int proxy check duration(seconds) (default 30) - -f value + -checkhost string + proxy check address (default "www.apple.com:443") + -config string + config file path + -forward value forward url, format: SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT[,SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT] - -l value + -listen value listen url, format: SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT - -s string + -strategy string forward strategy, default: rr (default "rr") - -v verbose mode + -verbose + verbose mode Available Schemas: mixed: serve as a http/socks5 proxy on the same port. (default) @@ -41,31 +44,34 @@ Available forward strategies: ha: High Availability mode Examples: - glider -l :8443 -v + glider -config glider.conf + -run glider with specified config file. + + glider -listen :8443 -listen on :8443, serve as http/socks5 proxy on the same port. - glider -l ss://AEAD_CHACHA20_POLY1305:pass@:8443 - -listen on 0.0.0.0:8443 as a ss server. + glider -listen ss://AEAD_CHACHA20_POLY1305:pass@:8443 + -listen on 0.0.0.0:8443 as a shadowsocks server. - glider -l socks5://:1080 -v + glider -listen socks5://:1080 -verbose -listen on :1080 as a socks5 proxy server, in verbose mode. - glider -l http://:8080 -f socks5://127.0.0.1:1080 -v + glider -listen http://:8080 -forward socks5://127.0.0.1:1080 -listen on :8080 as a http proxy server, forward all requests via socks5 server. - glider -l redir://:1081 -f ss://method:pass@1.1.1.1:443 + glider -listen redir://:1081 -forward ss://method:pass@1.1.1.1:443 -listen on :1081 as a transparent redirect server, forward all requests via remote ss server. - glider -l tcptun://:80=2.2.2.2:80 -f ss://method:pass@1.1.1.1:443 + glider -listen tcptun://:80=2.2.2.2:80 -forward ss://method:pass@1.1.1.1:443 -listen on :80 and forward all requests to 2.2.2.2:80 via remote ss server. - glider -l socks5://:1080 -l http://:8080 -f ss://method:pass@1.1.1.1:443 + glider -listen socks5://:1080 -listen http://:8080 -forward ss://method:pass@1.1.1.1:443 -listen on :1080 as socks5 server, :8080 as http proxy server, forward all requests via remote ss server. - glider -l redir://:1081 -l dnstun://:53=8.8.8.8:53 -f ss://method:pass@server1:port1,ss://method:pass@server2:port2 + glider -listen redir://:1081 -listen dnstun://:53=8.8.8.8:53 -forward ss://method:pass@server1:port1,ss://method:pass@server2:port2 -listen on :1081 as transparent redirect server, :53 as dns server, use forward chain: server1 -> server2. - glider -l socks5://:1080 -f ss://method:pass@server1:port1 -f ss://method:pass@server2:port2 -s rr + glider -listen socks5://:1080 -forward ss://method:pass@server1:port1 -forward ss://method:pass@server2:port2 -s rr -listen on :1080 as socks5 server, forward requests via server1 and server2 in roundrbin mode. ``` diff --git a/main.go b/main.go index 470bb19..2fa270b 100644 --- a/main.go +++ b/main.go @@ -1,33 +1,40 @@ package main import ( - "flag" "fmt" "log" "os" "os/signal" "strings" "syscall" + + "github.com/nadoo/conflag" ) -const version = "0.1.3" +// VERSION . +const VERSION = "0.2" -var config struct { +var conf struct { Verbose bool Strategy string - CheckSite string + CheckHost string CheckDuration int + Listen arrFlags + Forward arrFlags } +var flag = conflag.New() + func logf(f string, v ...interface{}) { - if config.Verbose { + if conf.Verbose { log.Printf(f, v...) } } func usage() { app := os.Args[0] - fmt.Fprintf(os.Stderr, "%s v%s usage:\n", app, version) + fmt.Fprintf(os.Stderr, "\n") + fmt.Fprintf(os.Stderr, "%s v%s usage:\n", app, VERSION) flag.PrintDefaults() fmt.Fprintf(os.Stderr, "\n") @@ -57,31 +64,34 @@ func usage() { fmt.Fprintf(os.Stderr, "\n") fmt.Fprintf(os.Stderr, "Examples:\n") - fmt.Fprintf(os.Stderr, " "+app+" -l :8443 -v\n") + fmt.Fprintf(os.Stderr, " "+app+" -config glider.conf\n") + fmt.Fprintf(os.Stderr, " -run glider with specified config file.\n") + fmt.Fprintf(os.Stderr, "\n") + fmt.Fprintf(os.Stderr, " "+app+" -listen :8443\n") fmt.Fprintf(os.Stderr, " -listen on :8443, serve as http/socks5 proxy on the same port.\n") fmt.Fprintf(os.Stderr, "\n") - fmt.Fprintf(os.Stderr, " "+app+" -l ss://AEAD_CHACHA20_POLY1305:pass@:8443\n") + fmt.Fprintf(os.Stderr, " "+app+" -listen ss://AEAD_CHACHA20_POLY1305:pass@:8443\n") fmt.Fprintf(os.Stderr, " -listen on 0.0.0.0:8443 as a shadowsocks server.\n") fmt.Fprintf(os.Stderr, "\n") - fmt.Fprintf(os.Stderr, " "+app+" -l socks5://:1080 -v\n") + fmt.Fprintf(os.Stderr, " "+app+" -listen socks5://:1080 -verbose\n") fmt.Fprintf(os.Stderr, " -listen on :1080 as a socks5 proxy server, in verbose mode.\n") fmt.Fprintf(os.Stderr, "\n") - fmt.Fprintf(os.Stderr, " "+app+" -l http://:8080 -f socks5://127.0.0.1:1080 -v\n") + fmt.Fprintf(os.Stderr, " "+app+" -listen http://:8080 -forward socks5://127.0.0.1:1080\n") fmt.Fprintf(os.Stderr, " -listen on :8080 as a http proxy server, forward all requests via socks5 server.\n") fmt.Fprintf(os.Stderr, "\n") - fmt.Fprintf(os.Stderr, " "+app+" -l redir://:1081 -f ss://method:pass@1.1.1.1:443\n") + fmt.Fprintf(os.Stderr, " "+app+" -listen redir://:1081 -forward ss://method:pass@1.1.1.1:443\n") fmt.Fprintf(os.Stderr, " -listen on :1081 as a transparent redirect server, forward all requests via remote ss server.\n") fmt.Fprintf(os.Stderr, "\n") - fmt.Fprintf(os.Stderr, " "+app+" -l tcptun://:80=2.2.2.2:80 -f ss://method:pass@1.1.1.1:443\n") + fmt.Fprintf(os.Stderr, " "+app+" -listen tcptun://:80=2.2.2.2:80 -forward ss://method:pass@1.1.1.1:443\n") fmt.Fprintf(os.Stderr, " -listen on :80 and forward all requests to 2.2.2.2:80 via remote ss server.\n") fmt.Fprintf(os.Stderr, "\n") - fmt.Fprintf(os.Stderr, " "+app+" -l socks5://:1080 -l http://:8080 -f ss://method:pass@1.1.1.1:443\n") + fmt.Fprintf(os.Stderr, " "+app+" -listen socks5://:1080 -listen http://:8080 -forward ss://method:pass@1.1.1.1:443\n") fmt.Fprintf(os.Stderr, " -listen on :1080 as socks5 server, :8080 as http proxy server, forward all requests via remote ss server.\n") fmt.Fprintf(os.Stderr, "\n") - fmt.Fprintf(os.Stderr, " "+app+" -l redir://:1081 -l dnstun://:53=8.8.8.8:53 -f ss://method:pass@server1:port1,ss://method:pass@server2:port2\n") + fmt.Fprintf(os.Stderr, " "+app+" -listen redir://:1081 -listen dnstun://:53=8.8.8.8:53 -forward ss://method:pass@server1:port1,ss://method:pass@server2:port2\n") fmt.Fprintf(os.Stderr, " -listen on :1081 as transparent redirect server, :53 as dns server, use forward chain: server1 -> server2.\n") fmt.Fprintf(os.Stderr, "\n") - fmt.Fprintf(os.Stderr, " "+app+" -l socks5://:1080 -f ss://method:pass@server1:port1 -f ss://method:pass@server2:port2 -s rr\n") + fmt.Fprintf(os.Stderr, " "+app+" -listen socks5://:1080 -forward ss://method:pass@server1:port1 -forward ss://method:pass@server2:port2 -s rr\n") fmt.Fprintf(os.Stderr, " -listen on :1080 as socks5 server, forward requests via server1 and server2 in roundrbin mode.\n") fmt.Fprintf(os.Stderr, "\n") } @@ -101,30 +111,28 @@ func (i *arrFlags) Set(value string) error { func main() { - var flags struct { - Listen arrFlags - Forward arrFlags - } - - flag.BoolVar(&config.Verbose, "v", false, "verbose mode") - flag.StringVar(&config.Strategy, "s", "rr", "forward strategy, default: rr") - flag.StringVar(&config.CheckSite, "checksite", "www.apple.com:443", "proxy check address") - flag.IntVar(&config.CheckDuration, "duration", 30, "proxy check duration(seconds)") - - flag.Var(&flags.Listen, "l", "listen url, format: SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT") - flag.Var(&flags.Forward, "f", "forward url, format: SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT[,SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT]") + flag.BoolVar(&conf.Verbose, "verbose", false, "verbose mode") + flag.StringVar(&conf.Strategy, "strategy", "rr", "forward strategy, default: rr") + flag.StringVar(&conf.CheckHost, "checkhost", "www.apple.com:443", "proxy check address") + flag.IntVar(&conf.CheckDuration, "checkduration", 30, "proxy check duration(seconds)") + flag.Var(&conf.Listen, "listen", "listen url, format: SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT") + flag.Var(&conf.Forward, "forward", "forward url, format: SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT[,SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT]") flag.Usage = usage - flag.Parse() + err := flag.Parse() + if err != nil { + fmt.Fprintf(os.Stderr, "ERROR: %s\n", err) + return + } - if len(flags.Listen) == 0 { + if len(conf.Listen) == 0 { flag.Usage() fmt.Fprintf(os.Stderr, "ERROR: listen url must be specified.\n") return } var forwarders []Proxy - for _, chain := range flags.Forward { + for _, chain := range conf.Forward { var forward Proxy var err error for _, url := range strings.Split(chain, ",") { @@ -136,7 +144,7 @@ func main() { forwarders = append(forwarders, forward) } - for _, listen := range flags.Listen { + for _, listen := range conf.Listen { local, err := ProxyFromURL(listen, forwarders...) if err != nil { log.Fatal(err) diff --git a/proxy.go b/proxy.go index c9983c5..b955ab3 100644 --- a/proxy.go +++ b/proxy.go @@ -93,7 +93,7 @@ func ProxyFromURL(s string, forwarders ...Proxy) (Proxy, error) { } else if len(forwarders) == 1 { proxy = newProxy(addr, forwarders[0]) } else if len(forwarders) > 1 { - switch config.Strategy { + switch conf.Strategy { case "rr": proxy = newRRProxy(addr, forwarders) logf("forward to remote servers in round robin mode.") @@ -101,7 +101,7 @@ func ProxyFromURL(s string, forwarders ...Proxy) (Proxy, error) { proxy = newHAProxy(addr, forwarders) logf("forward to remote servers in high availability mode.") default: - logf("not supported forward mode '%s', just use the first forward server.", config.Strategy) + logf("not supported forward mode '%s', just use the first forward server.", conf.Strategy) proxy = newProxy(addr, forwarders[0]) } } @@ -141,7 +141,7 @@ func check(p Proxy, target string, duration int) { startTime := time.Now() c, err := p.Dial("tcp", target) if err != nil { - logf("proxy-check %s -> %s, set to DISABLED. error: %s", p.Addr(), config.CheckSite, err) + logf("proxy-check %s -> %s, set to DISABLED. error: %s", p.Addr(), conf.CheckHost, err) p.SetEnable(false) continue } @@ -150,6 +150,6 @@ func check(p Proxy, target string, duration int) { // TODO: choose the fastest proxy. dialTime := time.Since(startTime) - logf("proxy-check: %s -> %s, connect time: %s", p.Addr(), config.CheckSite, dialTime.String()) + logf("proxy-check: %s -> %s, connect time: %s", p.Addr(), conf.CheckHost, dialTime.String()) } } diff --git a/strategy.go b/strategy.go index acddc56..3716679 100644 --- a/strategy.go +++ b/strategy.go @@ -21,7 +21,7 @@ func newStrategyProxy(addr string, forwarders []Proxy) Proxy { } for _, forward := range forwarders { - go check(forward, config.CheckSite, config.CheckDuration) + go check(forward, conf.CheckHost, conf.CheckDuration) } return &strategyProxy{addr: addr, forwarders: forwarders}