Skip to content

Commit

Permalink
Optimize code
Browse files Browse the repository at this point in the history
  • Loading branch information
wweir committed Mar 22, 2020
1 parent 291ae3f commit f7214bf
Show file tree
Hide file tree
Showing 12 changed files with 65 additions and 99 deletions.
4 changes: 2 additions & 2 deletions conf/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ var (
version, date string

installCmd string
execFile, _ = filepath.Abs(os.Args[0])
execFile, _ = os.Executable()
execDir, _ = filepath.Abs(filepath.Dir(execFile))
// Conf full config, include common and server / client
Conf = struct {
Expand All @@ -57,7 +57,7 @@ func init() {
flag.StringVar(&Conf.Client.Address, "c", "", "remote server domain, eg: aa.bb.cc, socks5h://127.0.0.1:1080")
flag.StringVar(&Conf.Client.HTTPProxy, "http_proxy", ":8080", "http proxy, empty to disable")
flag.IntVar(&Conf.Client.Router.DetectLevel, "level", 2, "dynamic rule detect level: 0~4")
flag.StringVar(&Conf.Client.Router.DetectTimeout, "timeout", "500ms", "dynamic rule detect timeout")
flag.StringVar(&Conf.Client.Router.DetectTimeout, "timeout", "300ms", "dynamic rule detect timeout")
uninstallFlag := flag.Bool("uninstall", false, "uninstall service")
_init() // execute platform init logic

Expand Down
7 changes: 1 addition & 6 deletions conf/conf_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,12 @@ func _init() {
flag.StringVar(&Conf.file, "f", ConfigDir+"/sower.toml", "config file, rewrite all other parameters if set")
}

flag.StringVar(&installCmd, "install", "", "install service with cmd, eg: '-f "+ConfigDir+"/sower.toml'")
flag.StringVar(&installCmd, "install", "", "install service with cmd, eg: '-f \""+ConfigDir+"/sower.toml\"'")
}

func runAsService() {}

func install() {
execFile, err := filepath.Abs(os.Args[0])
if err != nil {
log.Fatalw("get binary path", "err", err)
}

if err := ioutil.WriteFile(svcPath, []byte(fmt.Sprintf(svcFile, execFile, installCmd)), 0644); err != nil {
log.Fatalw("write service file", "err", err)
}
Expand Down
5 changes: 0 additions & 5 deletions conf/conf_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,6 @@ func _init() {
func runAsService() {}

func install() {
execFile, err := filepath.Abs(os.Args[0])
if err != nil {
log.Fatalw("get binary path", "err", err)
}

if err := ioutil.WriteFile(svcPath, []byte(fmt.Sprintf(svcFile, execFile, installCmd)), 0644); err != nil {
log.Fatalw("write service file", "err", err)
}
Expand Down
2 changes: 2 additions & 0 deletions conf/conf_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (
const name = "sower"
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue

var ConfigDir = execDir

func _init() {
flag.StringVar(&Conf.file, "f", filepath.Join(execDir, "sower.toml"), "config file, rewrite all other parameters if set")
flag.StringVar(&installCmd, "install", "", "put any character to install as a service, eg: true")
Expand Down
2 changes: 1 addition & 1 deletion conf/sower.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ password="" # sower password

[client.router]
detect_level = 2 # 0~4, the bigger the harder to add
detect_timeout = "500ms"
detect_timeout = "300ms"
direct_list = [
"**.in-addr.arpa",
"imap.*.*",
Expand Down
8 changes: 3 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
func main() {
switch {
case conf.Conf.Server.Upstream != "":
proxy.StartServer(conf.Conf.Server.Upstream, conf.Conf.Password,
proxy.StartServer(conf.Conf.Server.Upstream, conf.Conf.Password, conf.ConfigDir,
conf.Conf.Server.CertFile, conf.Conf.Server.KeyFile, conf.Conf.Server.CertEmail)

case conf.Conf.Client.Address != "":
Expand All @@ -39,9 +39,7 @@ func main() {
conf.Conf.Client.DNSServeIP != "", conf.Conf.Client.PortForward)

default:
if conf.Conf.Server.Upstream == "" && conf.Conf.Client.Address == "" {
fmt.Println()
flag.Usage()
}
fmt.Println()
flag.Usage()
}
}
45 changes: 14 additions & 31 deletions proxy/http_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,34 @@ package proxy
import (
"context"
"crypto/tls"
"io"
"net"
"net/http"
"net/http/httputil"
"time"

"github.com/wweir/sower/transport"
"github.com/wweir/utils/log"
)

// StartHTTPProxy start http reverse proxy.
// The httputil.ReverseProxy do not supply enough support for https request.
func StartHTTPProxy(httpProxyAddr, serverAddr string, password []byte, shouldProxy func(string) bool) {
proxy := httputil.ReverseProxy{
Director: func(r *http.Request) {},
Transport: &http.Transport{
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
addr, _ = withDefaultPort(addr, "80")
return transport.Dial(serverAddr, addr, password)
}},
}

srv := &http.Server{
Addr: httpProxyAddr,
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodConnect {
httpsProxy(w, r, serverAddr, password, shouldProxy)
} else {
httpProxy(w, r, serverAddr, password, shouldProxy)
proxy.ServeHTTP(w, r)
}
}),
// Disable HTTP/2.
Expand All @@ -31,34 +42,6 @@ func StartHTTPProxy(httpProxyAddr, serverAddr string, password []byte, shouldPro
go log.Fatalw("serve http proxy", "addr", httpProxyAddr, "err", srv.ListenAndServe())
}

func httpProxy(w http.ResponseWriter, r *http.Request,
serverAddr string, password []byte, shouldProxy func(string) bool) {

target, host := withDefaultPort(r.Host, "80")

roundTripper := &http.Transport{}
if shouldProxy(host) {
roundTripper.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
return transport.Dial(serverAddr, target, password)
}
}

resp, err := roundTripper.RoundTrip(r)
if err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
defer resp.Body.Close()

for k, vs := range resp.Header {
for _, v := range vs {
w.Header().Add(k, v)
}
}
w.WriteHeader(resp.StatusCode)
io.Copy(w, resp.Body)
}

func httpsProxy(w http.ResponseWriter, r *http.Request,
serverAddr string, password []byte, shouldProxy func(string) bool) {

Expand All @@ -70,10 +53,10 @@ func httpsProxy(w http.ResponseWriter, r *http.Request,
return
}
conn.(*net.TCPConn).SetKeepAlive(true)
defer conn.Close()

if _, err := conn.Write([]byte(r.Proto + " 200 Connection established\r\n\r\n")); err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
conn.Close()
return
}

Expand Down
41 changes: 0 additions & 41 deletions proxy/parse_tgt.go

This file was deleted.

2 changes: 1 addition & 1 deletion proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func StartClient(serverAddr, password string, enableDNS bool, forwards map[strin
select {}
}

func StartServer(relayTarget, password, certFile, keyFile, email string) {
func StartServer(relayTarget, password, cacheDir, certFile, keyFile, email string) {
dir, _ := os.UserCacheDir()
dir = filepath.Join("/", dir, "sower")
log.Infow("certificate cache dir", "dir", dir)
Expand Down
36 changes: 36 additions & 0 deletions proxy/util.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,49 @@
package proxy

import (
"bufio"
"crypto/tls"
"io"
"net"
"net/http"
"sync"
"sync/atomic"
"time"

"github.com/wweir/sower/util"
)

func ParseHTTP(conn net.Conn) (net.Conn, string, error) {
teeConn := &util.TeeConn{Conn: conn}
defer teeConn.Stop()

resp, err := http.ReadRequest(bufio.NewReader(teeConn))
if err != nil {
return teeConn, "", err
}

if _, _, err := net.SplitHostPort(resp.Host); err != nil {
resp.Host = net.JoinHostPort(resp.Host, "80")
}

return teeConn, resp.Host, nil
}

func ParseHTTPS(conn net.Conn) (net.Conn, string, error) {
teeConn := &util.TeeConn{Conn: conn}
defer teeConn.Stop()

var domain string
tls.Server(teeConn, &tls.Config{
GetConfigForClient: func(hello *tls.ClientHelloInfo) (*tls.Config, error) {
domain = hello.ServerName
return nil, nil
},
}).Handshake()

return teeConn, net.JoinHostPort(domain, "443"), nil
}

func withDefaultPort(addr string, port string) (address, host string) {
host, _, err := net.SplitHostPort(addr)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ func (r *Route) ShouldProxy(domain string) bool {
r.dynamicRule = util.NewNodeFromRules(r.DynamicList...)

if timeout, err := time.ParseDuration(r.DetectTimeout); err != nil {
r.timeout = 200 * time.Millisecond
log.Warnw("parse detect timeout", "err", err, "default", "t.timeout")
r.timeout = 300 * time.Millisecond
log.Warnw("parse detect timeout", "err", err, "default", r.timeout)
} else {
r.timeout = timeout
}
Expand Down
8 changes: 3 additions & 5 deletions transport/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ func Dial(address, target string, password []byte) (net.Conn, error) {
return nil, err
}

return DialTlsProxyConn(net.JoinHostPort(address, "443"), host, uint16(p), &tls.Config{
ServerName: address,
MinVersion: tls.VersionTLS12,
NextProtos: []string{"http/1.1", "h2"},
}, password)
// tls.Config is same as golang http pkg default behavior
return DialTlsProxyConn(net.JoinHostPort(address, "443"),
host, uint16(p), &tls.Config{}, password)
}

0 comments on commit f7214bf

Please sign in to comment.