change "func GetProxy() Proxy" to "GetProxy(dstAddr string) Proxy" so we could add rule based proxy later

This commit is contained in:
nadoo 2017-07-29 23:20:27 +08:00
parent 88dda17725
commit bf692de636
9 changed files with 33 additions and 69 deletions

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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)

View File

@ -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{}

View File

@ -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

12
ss.go
View File

@ -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
}

View File

@ -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()

View File

@ -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)