From bf692de636a3adf980792a33d931f33a88dcdd96 Mon Sep 17 00:00:00 2001 From: nadoo <287492+nadoo@users.noreply.github.com> Date: Sat, 29 Jul 2017 23:20:27 +0800 Subject: [PATCH] change "func GetProxy() Proxy" to "GetProxy(dstAddr string) Proxy" so we could add rule based proxy later --- dnstun.go | 4 +--- http.go | 8 +++----- mixed.go | 6 +++--- proxy.go | 18 +++++++++--------- redir_linux.go | 30 ------------------------------ socks5.go | 10 +++++----- ss.go | 12 ++++++------ strategy.go | 10 +++++----- tcptun.go | 4 +--- 9 files changed, 33 insertions(+), 69 deletions(-) diff --git a/dnstun.go b/dnstun.go index 886a54c..8f96d7f 100644 --- a/dnstun.go +++ b/dnstun.go @@ -25,7 +25,6 @@ const MaxUDPDNSLen = 512 type dnstun struct { *proxy - addr string raddr string } @@ -33,7 +32,6 @@ type dnstun struct { func DNSTunProxy(addr, raddr string, upProxy Proxy) (Proxy, error) { s := &dnstun{ proxy: newProxy(addr, upProxy), - addr: addr, raddr: raddr, } @@ -66,7 +64,7 @@ func (s *dnstun) ListenAndServe() { // TODO: check domain rules and get a proper proxy. domain := getDomain(data) - rc, err := s.GetProxy().Dial("tcp", s.raddr) + rc, err := s.GetProxy(s.raddr).Dial("tcp", s.raddr) if err != nil { logf("failed to connect to server %v: %v", s.raddr, err) return diff --git a/http.go b/http.go index 65d6a86..62cd8b0 100644 --- a/http.go +++ b/http.go @@ -19,14 +19,12 @@ import ( // httpproxy type httpproxy struct { *proxy - addr string } // HTTPProxy returns a http proxy. func HTTPProxy(addr string, upProxy Proxy) (Proxy, error) { s := &httpproxy{ proxy: newProxy(addr, upProxy), - addr: addr, } return s, nil @@ -94,7 +92,7 @@ func (s *httpproxy) Serve(c net.Conn) { tgt += ":80" } - rc, err := s.GetProxy().Dial("tcp", tgt) + rc, err := s.GetProxy(tgt).Dial("tcp", tgt) if err != nil { fmt.Fprintf(c, "%s 502 ERROR\r\n\r\n", proto) logf("failed to dial: %v", err) @@ -150,7 +148,7 @@ func (s *httpproxy) Serve(c net.Conn) { } func (s *httpproxy) servHTTPS(method, requestURI, proto string, c net.Conn) { - rc, err := s.GetProxy().Dial("tcp", requestURI) + rc, err := s.GetProxy(requestURI).Dial("tcp", requestURI) if err != nil { c.Write([]byte(proto)) c.Write([]byte(" 502 ERROR\r\n\r\n")) @@ -173,7 +171,7 @@ func (s *httpproxy) servHTTPS(method, requestURI, proto string, c net.Conn) { // Dial connects to the address addr on the network net via the proxy. func (s *httpproxy) Dial(network, addr string) (net.Conn, error) { - rc, err := s.GetProxy().Dial("tcp", s.addr) + rc, err := s.GetProxy(s.addr).Dial("tcp", s.addr) if err != nil { logf("dial to %s error: %s", s.addr, err) return nil, err diff --git a/mixed.go b/mixed.go index 684ed37..ef99118 100644 --- a/mixed.go +++ b/mixed.go @@ -43,13 +43,13 @@ func MixedProxy(network, addr, user, pass string, upProxy Proxy) (Proxy, error) // mixedproxy . func (p *mixedproxy) ListenAndServe() { - l, err := net.Listen("tcp", p.Addr()) + l, err := net.Listen("tcp", p.addr) if err != nil { - logf("failed to listen on %s: %v", p.Addr(), err) + logf("failed to listen on %s: %v", p.addr, err) return } - logf("listening TCP on %s", p.Addr()) + logf("listening TCP on %s", p.addr) for { c, err := l.Accept() diff --git a/proxy.go b/proxy.go index e3ca974..a088ad3 100644 --- a/proxy.go +++ b/proxy.go @@ -24,7 +24,7 @@ type Proxy interface { CurrentProxy() Proxy // Get a proxy according to the strategy - GetProxy() Proxy + GetProxy(dstAddr string) Proxy // Switch to the next proxy NextProxy() Proxy @@ -55,14 +55,14 @@ func newProxy(addr string, forward Proxy) *proxy { return &proxy{addr: addr, forward: forward, enabled: true} } -func (p *proxy) ListenAndServe() { logf("base proxy ListenAndServe") } -func (p *proxy) Serve(c net.Conn) { logf("base proxy Serve") } -func (p *proxy) CurrentProxy() Proxy { return p.forward } -func (p *proxy) GetProxy() Proxy { return p.forward } -func (p *proxy) NextProxy() Proxy { return p.forward } -func (p *proxy) Enabled() bool { return p.enabled } -func (p *proxy) SetEnable(enable bool) { p.enabled = enable } -func (p *proxy) Addr() string { return p.addr } +func (p *proxy) ListenAndServe() { logf("base proxy ListenAndServe") } +func (p *proxy) Serve(c net.Conn) { logf("base proxy Serve") } +func (p *proxy) CurrentProxy() Proxy { return p.forward } +func (p *proxy) GetProxy(dstAddr string) Proxy { return p.forward } +func (p *proxy) NextProxy() Proxy { return p.forward } +func (p *proxy) Enabled() bool { return p.enabled } +func (p *proxy) SetEnable(enable bool) { p.enabled = enable } +func (p *proxy) Addr() string { return p.addr } func (p *proxy) Dial(network, addr string) (net.Conn, error) { return p.forward.Dial(network, addr) diff --git a/redir_linux.go b/redir_linux.go index cf64e8b..de23ae8 100644 --- a/redir_linux.go +++ b/redir_linux.go @@ -4,7 +4,6 @@ package main import ( - "errors" "net" "syscall" "unsafe" @@ -56,7 +55,6 @@ func (s *redir) ListenAndServe() { c.SetKeepAlive(true) } - // tgt, c, err := getOriginalDstAddr(c) tgt, err := getOrigDst(c, false) if err != nil { logf("failed to get target address: %v", err) @@ -84,34 +82,6 @@ func (s *redir) ListenAndServe() { } } -// Get the original destination of a TCP connection. -func getOrigDst(conn net.Conn, ipv6 bool) (socks.Addr, error) { - c, ok := conn.(*net.TCPConn) - if !ok { - return nil, errors.New("only work with TCP connection") - } - f, err := c.File() - if err != nil { - return nil, err - } - defer f.Close() - - fd := f.Fd() - - // The File() call above puts both the original socket fd and the file fd in blocking mode. - // Set the file fd back to non-blocking mode and the original socket fd will become non-blocking as well. - // Otherwise blocking I/O will waste OS threads. - if err := syscall.SetNonblock(int(fd), true); err != nil { - return nil, err - } - - if ipv6 { - return ipv6_getorigdst(fd) - } - - return getorigdst(fd) -} - // Call getorigdst() from linux/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c func getorigdst(fd uintptr) (socks.Addr, error) { raw := syscall.RawSockaddrInet4{} diff --git a/socks5.go b/socks5.go index aca2365..0414f51 100644 --- a/socks5.go +++ b/socks5.go @@ -57,8 +57,9 @@ var socks5Errors = []string{ type socks5 struct { *proxy - network, addr string - user, password string + network string + user string + password string } // SOCKS5Proxy returns a Proxy that makes SOCKSv5 connections to the given address @@ -66,7 +67,6 @@ type socks5 struct { func SOCKS5Proxy(network, addr, user, pass string, upProxy Proxy) (Proxy, error) { s := &socks5{ proxy: newProxy(addr, upProxy), - addr: addr, user: user, password: pass, } @@ -108,7 +108,7 @@ func (s *socks5) Serve(c net.Conn) { return } - rc, err := s.GetProxy().Dial("tcp", tgt.String()) + rc, err := s.GetProxy(tgt.String()).Dial("tcp", tgt.String()) if err != nil { logf("failed to connect to target: %v", err) return @@ -134,7 +134,7 @@ func (s *socks5) Dial(network, addr string) (net.Conn, error) { return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network) } - c, err := s.GetProxy().Dial(s.network, s.addr) + c, err := s.GetProxy(s.addr).Dial(s.network, s.addr) if err != nil { logf("dial to %s error: %s", s.addr, err) return nil, err diff --git a/ss.go b/ss.go index e3a2ed6..d85ecd7 100644 --- a/ss.go +++ b/ss.go @@ -32,13 +32,13 @@ func SSProxy(addr, method, pass string, upProxy Proxy) (Proxy, error) { // ListenAndServe shadowsocks requests as a server. func (s *ss) ListenAndServe() { - l, err := net.Listen("tcp", s.Addr()) + l, err := net.Listen("tcp", s.addr) if err != nil { - logf("failed to listen on %s: %v", s.Addr(), err) + logf("failed to listen on %s: %v", s.addr, err) return } - logf("listening TCP on %s", s.Addr()) + logf("listening TCP on %s", s.addr) for { c, err := l.Accept() @@ -65,7 +65,7 @@ func (s *ss) Serve(c net.Conn) { return } - rc, err := s.GetProxy().Dial("tcp", tgt.String()) + rc, err := s.GetProxy(tgt.String()).Dial("tcp", tgt.String()) if err != nil { logf("failed to connect to target: %v", err) return @@ -92,9 +92,9 @@ func (s *ss) Dial(network, addr string) (net.Conn, error) { return nil, errors.New("Unable to parse address: " + addr) } - c, err := s.GetProxy().Dial("tcp", s.Addr()) + c, err := s.GetProxy(s.addr).Dial("tcp", s.addr) if err != nil { - logf("dial to %s error: %s", s.Addr(), err) + logf("dial to %s error: %s", s.addr, err) return nil, err } diff --git a/strategy.go b/strategy.go index 4d61580..14dd344 100644 --- a/strategy.go +++ b/strategy.go @@ -46,10 +46,10 @@ func newRRProxy(addr string, forwarders []Proxy) Proxy { return &rrProxy{forwarders: forwarders} } -func (p *rrProxy) ListenAndServe() {} -func (p *rrProxy) Serve(c net.Conn) {} -func (p *rrProxy) CurrentProxy() Proxy { return p.forwarders[p.idx] } -func (p *rrProxy) GetProxy() Proxy { return p.NextProxy() } +func (p *rrProxy) ListenAndServe() {} +func (p *rrProxy) Serve(c net.Conn) {} +func (p *rrProxy) CurrentProxy() Proxy { return p.forwarders[p.idx] } +func (p *rrProxy) GetProxy(dstAddr string) Proxy { return p.NextProxy() } func (p *rrProxy) NextProxy() Proxy { n := len(p.forwarders) @@ -91,7 +91,7 @@ func newHAProxy(addr string, forwarders []Proxy) Proxy { return &haProxy{Proxy: newRRProxy(addr, forwarders)} } -func (p *haProxy) GetProxy() Proxy { +func (p *haProxy) GetProxy(dstAddr string) Proxy { proxy := p.CurrentProxy() if proxy.Enabled() == false { return p.NextProxy() diff --git a/tcptun.go b/tcptun.go index f933aaa..0fbe677 100644 --- a/tcptun.go +++ b/tcptun.go @@ -4,7 +4,6 @@ import "net" type tcptun struct { *proxy - addr string raddr string } @@ -12,7 +11,6 @@ type tcptun struct { func TCPTunProxy(addr, raddr string, upProxy Proxy) (Proxy, error) { s := &tcptun{ proxy: newProxy(addr, upProxy), - addr: addr, raddr: raddr, } @@ -43,7 +41,7 @@ func (s *tcptun) ListenAndServe() { c.SetKeepAlive(true) } - rc, err := s.GetProxy().Dial("tcp", s.raddr) + rc, err := s.GetProxy(s.raddr).Dial("tcp", s.raddr) if err != nil { logf("failed to connect to target: %v", err)