general: combine cdialer and sdialer

This commit is contained in:
nadoo 2018-03-24 19:55:06 +08:00
parent 6e32720c1c
commit f785fa9d6c
13 changed files with 115 additions and 135 deletions

View File

@ -23,7 +23,7 @@ type Dialer interface {
// DialerFromURL parses url and get a Proxy
// TODO: table
func DialerFromURL(s string, cDialer Dialer) (Dialer, error) {
func DialerFromURL(s string, dialer Dialer) (Dialer, error) {
u, err := url.Parse(s)
if err != nil {
logf("parse err: %s", err)
@ -37,17 +37,17 @@ func DialerFromURL(s string, cDialer Dialer) (Dialer, error) {
pass, _ = u.User.Password()
}
if cDialer == nil {
cDialer = Direct
if dialer == nil {
dialer = Direct
}
switch u.Scheme {
case "http":
return NewHTTP(addr, user, pass, "", cDialer, nil)
return NewHTTP(addr, user, pass, "", dialer)
case "socks5":
return NewSOCKS5(addr, user, pass, cDialer, nil)
return NewSOCKS5(addr, user, pass, dialer)
case "ss":
return NewSS(addr, user, pass, cDialer, nil)
return NewSS(addr, user, pass, dialer)
}
return nil, errors.New("unknown schema '" + u.Scheme + "'")

12
dns.go
View File

@ -139,8 +139,8 @@ type DNSAnswerHandler func(Domain, ip string) error
// DNS .
type DNS struct {
*Forwarder // as proxy client
sDialer Dialer // dialer for server
dialer Dialer
addr string
Tunnel bool
@ -151,10 +151,10 @@ type DNS struct {
}
// NewDNS returns a dns forwarder. client[dns.udp] -> glider[tcp] -> forwarder[dns.tcp] -> remote dns addr
func NewDNS(addr, raddr string, sDialer Dialer, tunnel bool) (*DNS, error) {
func NewDNS(addr, raddr string, dialer Dialer, tunnel bool) (*DNS, error) {
s := &DNS{
Forwarder: NewForwarder(addr, nil),
sDialer: sDialer,
dialer: dialer,
addr: addr,
Tunnel: tunnel,
@ -293,7 +293,7 @@ func (s *DNS) Exchange(reqLen uint16, reqMsg []byte, addr string) (respLen uint1
dnsServer = s.GetServer(query.QNAME)
}
rc, err := s.sDialer.NextDialer(query.QNAME+":53").Dial("tcp", dnsServer)
rc, err := s.dialer.NextDialer(query.QNAME+":53").Dial("tcp", dnsServer)
if err != nil {
logf("proxy-dns failed to connect to server %v: %v", dnsServer, err)
return

View File

@ -4,8 +4,8 @@ package main
// DNSTun struct
type DNSTun struct {
*Forwarder // as client
sDialer Dialer // dialer for server
dialer Dialer
addr string
raddr string
@ -14,15 +14,15 @@ type DNSTun struct {
}
// NewDNSTun returns a dns tunnel forwarder.
func NewDNSTun(addr, raddr string, sDialer Dialer) (*DNSTun, error) {
func NewDNSTun(addr, raddr string, dialer Dialer) (*DNSTun, error) {
s := &DNSTun{
Forwarder: NewForwarder(addr, nil),
sDialer: sDialer,
dialer: dialer,
addr: addr,
raddr: raddr,
}
s.dns, _ = NewDNS(addr, raddr, sDialer, true)
s.dns, _ = NewDNS(addr, raddr, dialer, true)
return s, nil
}

View File

@ -1,36 +0,0 @@
package main
import "net"
// Forwarder struct
type Forwarder struct {
addr string
cDialer Dialer
}
// NewForwarder returns a base forwarder
func NewForwarder(addr string, cDialer Dialer) *Forwarder {
if cDialer == nil {
cDialer = Direct
}
return &Forwarder{addr: addr, cDialer: cDialer}
}
// Addr returns forwarder's address
func (p *Forwarder) Addr() string { return p.addr }
// Dial to remote addr via cDialer
func (p *Forwarder) Dial(network, addr string) (net.Conn, error) {
return p.cDialer.Dial(network, addr)
}
// DialUDP to remote addr via cDialer
func (p *Forwarder) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.Addr, err error) {
return p.cDialer.DialUDP(network, addr)
}
// NextDialer returns the next cDialer
func (p *Forwarder) NextDialer(dstAddr string) Dialer {
return p.cDialer
}

33
http.go
View File

@ -19,9 +19,8 @@ import (
// HTTP struct
type HTTP struct {
*Forwarder // as client
sDialer Dialer // dialer for server
dialer Dialer
addr string
user string
password string
xff bool // X-Forwarded-For
@ -31,14 +30,14 @@ type HTTP struct {
}
// NewHTTP returns a http proxy.
func NewHTTP(addr, user, pass, rawQuery string, cDialer Dialer, sDialer Dialer) (*HTTP, error) {
func NewHTTP(addr, user, pass, rawQuery string, dialer Dialer) (*HTTP, error) {
s := &HTTP{
Forwarder: NewForwarder(addr, cDialer),
sDialer: sDialer,
user: user,
password: pass,
xff: false,
selfip: OutboundIP(),
dialer: dialer,
addr: addr,
user: user,
password: pass,
xff: false,
selfip: OutboundIP(),
}
p, _ := url.ParseQuery(rawQuery)
@ -129,7 +128,7 @@ func (s *HTTP) Serve(c net.Conn) {
tgt += ":80"
}
rc, err := s.sDialer.Dial("tcp", tgt)
rc, err := s.dialer.Dial("tcp", tgt)
if err != nil {
fmt.Fprintf(c, "%s 502 ERROR\r\n\r\n", proto)
logf("failed to dial: %v", err)
@ -189,7 +188,7 @@ func (s *HTTP) Serve(c net.Conn) {
}
func (s *HTTP) servHTTPS(method, requestURI, proto string, c net.Conn) {
rc, err := s.sDialer.Dial("tcp", requestURI)
rc, err := s.dialer.Dial("tcp", requestURI)
if err != nil {
c.Write([]byte(proto))
c.Write([]byte(" 502 ERROR\r\n\r\n"))
@ -199,7 +198,7 @@ func (s *HTTP) servHTTPS(method, requestURI, proto string, c net.Conn) {
c.Write([]byte("HTTP/1.0 200 Connection established\r\n\r\n"))
logf("proxy-https %s <-> %s", c.RemoteAddr(), requestURI)
logf("proxy-http %s <-> %s [connect]", c.RemoteAddr(), requestURI)
_, _, err = relay(c, rc)
if err != nil {
@ -210,9 +209,15 @@ func (s *HTTP) servHTTPS(method, requestURI, proto string, c net.Conn) {
}
}
// Addr returns forwarder's address
func (s *HTTP) Addr() string { return s.addr }
// NextDialer returns the next dialer
func (s *HTTP) NextDialer(dstAddr string) Dialer { return s.dialer }
// Dial connects to the address addr on the network net via the proxy.
func (s *HTTP) Dial(network, addr string) (net.Conn, error) {
rc, err := s.cDialer.Dial(network, s.addr)
rc, err := s.dialer.Dial(network, s.addr)
if err != nil {
logf("dial to %s error: %s", s.addr, err)
return nil, err

View File

@ -19,7 +19,7 @@ var httpMethods = [...][]byte{
// MixedProxy struct
type MixedProxy struct {
sDialer Dialer
dialer Dialer
addr string
http *HTTP
@ -27,14 +27,14 @@ type MixedProxy struct {
}
// NewMixedProxy returns a mixed proxy.
func NewMixedProxy(addr, user, pass, rawQuery string, sDialer Dialer) (*MixedProxy, error) {
func NewMixedProxy(addr, user, pass, rawQuery string, dialer Dialer) (*MixedProxy, error) {
p := &MixedProxy{
sDialer: sDialer,
addr: addr,
dialer: dialer,
addr: addr,
}
p.http, _ = NewHTTP(addr, user, pass, rawQuery, nil, sDialer)
p.socks5, _ = NewSOCKS5(addr, user, pass, nil, sDialer)
p.http, _ = NewHTTP(addr, user, pass, rawQuery, dialer)
p.socks5, _ = NewSOCKS5(addr, user, pass, dialer)
return p, nil
}

View File

@ -14,7 +14,7 @@ type Server interface {
// ServerFromURL parses url and get a Proxy
// TODO: table
func ServerFromURL(s string, sDialer Dialer) (Server, error) {
func ServerFromURL(s string, dialer Dialer) (Server, error) {
if !strings.Contains(s, "://") {
s = "mixed://" + s
}
@ -32,33 +32,33 @@ func ServerFromURL(s string, sDialer Dialer) (Server, error) {
pass, _ = u.User.Password()
}
if sDialer == nil {
sDialer = Direct
if dialer == nil {
dialer = Direct
}
switch u.Scheme {
case "mixed":
return NewMixedProxy(addr, user, pass, u.RawQuery, sDialer)
return NewMixedProxy(addr, user, pass, u.RawQuery, dialer)
case "http":
return NewHTTP(addr, user, pass, u.RawQuery, nil, sDialer)
return NewHTTP(addr, user, pass, u.RawQuery, dialer)
case "socks5":
return NewSOCKS5(addr, user, pass, nil, sDialer)
return NewSOCKS5(addr, user, pass, dialer)
case "ss":
return NewSS(addr, user, pass, nil, sDialer)
return NewSS(addr, user, pass, dialer)
case "redir":
return NewRedirProxy(addr, sDialer)
return NewRedirProxy(addr, dialer)
case "tcptun":
d := strings.Split(addr, "=")
return NewTCPTun(d[0], d[1], sDialer)
return NewTCPTun(d[0], d[1], dialer)
case "udptun":
d := strings.Split(addr, "=")
return NewUDPTun(d[0], d[1], sDialer)
return NewUDPTun(d[0], d[1], dialer)
case "dnstun":
d := strings.Split(addr, "=")
return NewDNSTun(d[0], d[1], sDialer)
return NewDNSTun(d[0], d[1], dialer)
case "uottun":
d := strings.Split(addr, "=")
return NewUoTTun(d[0], d[1], sDialer)
return NewUoTTun(d[0], d[1], dialer)
}
return nil, errors.New("unknown schema '" + u.Scheme + "'")

View File

@ -62,21 +62,20 @@ var socks5Errors = []error{
// SOCKS5 struct
type SOCKS5 struct {
*Forwarder
sDialer Dialer
dialer Dialer
addr string
user string
password string
}
// NewSOCKS5 returns a Proxy that makes SOCKSv5 connections to the given address
// with an optional username and password. See RFC 1928.
func NewSOCKS5(addr, user, pass string, cDialer Dialer, sDialer Dialer) (*SOCKS5, error) {
func NewSOCKS5(addr, user, pass string, dialer Dialer) (*SOCKS5, error) {
s := &SOCKS5{
Forwarder: NewForwarder(addr, cDialer),
sDialer: sDialer,
user: user,
password: pass,
dialer: dialer,
addr: addr,
user: user,
password: pass,
}
return s, nil
@ -137,7 +136,7 @@ func (s *SOCKS5) ServeTCP(c net.Conn) {
return
}
rc, err := s.sDialer.Dial("tcp", tgt.String())
rc, err := s.dialer.Dial("tcp", tgt.String())
if err != nil {
logf("proxy-socks5 failed to connect to target: %v", err)
return
@ -186,7 +185,7 @@ func (s *SOCKS5) ListenAndServeUDP() {
continue
}
lpc, nextHop, err := s.sDialer.DialUDP("udp", c.tgtAddr.String())
lpc, nextHop, err := s.dialer.DialUDP("udp", c.tgtAddr.String())
if err != nil {
logf("proxy-socks5-udp remote dial error: %v", err)
continue
@ -216,6 +215,12 @@ func (s *SOCKS5) ListenAndServeUDP() {
}
// Addr returns forwarder's address
func (s *SOCKS5) Addr() string { return s.addr }
// NextDialer returns the next dialer
func (s *SOCKS5) NextDialer(dstAddr string) Dialer { return s.dialer }
// Dial connects to the address addr on the network net via the SOCKS5 proxy.
func (s *SOCKS5) Dial(network, addr string) (net.Conn, error) {
switch network {
@ -224,7 +229,7 @@ func (s *SOCKS5) Dial(network, addr string) (net.Conn, error) {
return nil, errors.New("proxy-socks5: no support for connection type " + network)
}
c, err := s.cDialer.Dial(network, s.addr)
c, err := s.dialer.Dial(network, s.addr)
if err != nil {
logf("dial to %s error: %s", s.addr, err)
return nil, err
@ -244,7 +249,7 @@ func (s *SOCKS5) Dial(network, addr string) (net.Conn, error) {
// DialUDP connects to the given address via the proxy.
func (s *SOCKS5) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.Addr, err error) {
c, err := s.cDialer.Dial("tcp", s.addr)
c, err := s.dialer.Dial("tcp", s.addr)
if err != nil {
logf("proxy-socks5 dialudp dial tcp to %s error: %s", s.addr, err)
return nil, nil, err
@ -283,7 +288,7 @@ func (s *SOCKS5) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.A
return nil, nil, err
}
pc, nextHop, err := s.cDialer.DialUDP(network, uAddr.String())
pc, nextHop, err := s.dialer.DialUDP(network, uAddr.String())
if err != nil {
logf("proxy-socks5 dialudp to %s error: %s", uAddr.String(), err)
return nil, nil, err

26
ss.go
View File

@ -15,23 +15,23 @@ const udpBufSize = 65536
// SS .
type SS struct {
*Forwarder
sDialer Dialer
dialer Dialer
addr string
core.Cipher
}
// NewSS returns a shadowsocks proxy.
func NewSS(addr, method, pass string, cDialer Dialer, sDialer Dialer) (*SS, error) {
func NewSS(addr, method, pass string, dialer Dialer) (*SS, error) {
ciph, err := core.PickCipher(method, nil, pass)
if err != nil {
log.Fatalf("PickCipher for '%s', error: %s", method, err)
}
s := &SS{
Forwarder: NewForwarder(addr, cDialer),
sDialer: sDialer,
Cipher: ciph,
dialer: dialer,
addr: addr,
Cipher: ciph,
}
return s, nil
@ -79,7 +79,7 @@ func (s *SS) ServeTCP(c net.Conn) {
return
}
dialer := s.sDialer.NextDialer(tgt.String())
dialer := s.dialer.NextDialer(tgt.String())
// udp over tcp?
uot := UoT(tgt[0])
@ -166,7 +166,7 @@ func (s *SS) ListenAndServeUDP() {
var pc *PktConn
v, ok := nm.Load(raddr.String())
if !ok && v == nil {
lpc, nextHop, err := s.sDialer.DialUDP("udp", c.tgtAddr.String())
lpc, nextHop, err := s.dialer.DialUDP("udp", c.tgtAddr.String())
if err != nil {
logf("proxy-ss-udp remote dial error: %v", err)
continue
@ -200,6 +200,12 @@ func ListCipher() string {
return strings.Join(core.ListCipher(), " ")
}
// Addr returns forwarder's address
func (s *SS) Addr() string { return s.addr }
// NextDialer returns the next dialer
func (s *SS) NextDialer(dstAddr string) Dialer { return s.dialer }
// Dial connects to the address addr on the network net via the proxy.
func (s *SS) Dial(network, addr string) (net.Conn, error) {
target := ParseAddr(addr)
@ -211,7 +217,7 @@ func (s *SS) Dial(network, addr string) (net.Conn, error) {
target[0] = target[0] | 0x8
}
c, err := s.cDialer.Dial("tcp", s.addr)
c, err := s.dialer.Dial("tcp", s.addr)
if err != nil {
logf("dial to %s error: %s", s.addr, err)
return nil, err
@ -233,7 +239,7 @@ func (s *SS) Dial(network, addr string) (net.Conn, error) {
// DialUDP connects to the given address via the proxy.
func (s *SS) DialUDP(network, addr string) (net.PacketConn, net.Addr, error) {
pc, nextHop, err := s.cDialer.DialUDP(network, s.addr)
pc, nextHop, err := s.dialer.DialUDP(network, s.addr)
if err != nil {
logf("proxy-ss dialudp to %s error: %s", s.addr, err)
return nil, nil, err

View File

@ -4,18 +4,18 @@ import "net"
// TCPTun struct
type TCPTun struct {
*Forwarder
sDialer Dialer
dialer Dialer
addr string
raddr string
}
// NewTCPTun returns a tcptun proxy.
func NewTCPTun(addr, raddr string, sDialer Dialer) (*TCPTun, error) {
func NewTCPTun(addr, raddr string, dialer Dialer) (*TCPTun, error) {
s := &TCPTun{
Forwarder: NewForwarder(addr, nil),
sDialer: sDialer,
raddr: raddr,
dialer: dialer,
addr: addr,
raddr: raddr,
}
return s, nil
@ -45,7 +45,7 @@ func (s *TCPTun) ListenAndServe() {
c.SetKeepAlive(true)
}
rc, err := s.sDialer.Dial("tcp", s.raddr)
rc, err := s.dialer.Dial("tcp", s.raddr)
if err != nil {
logf("failed to connect to target: %v", err)

View File

@ -17,15 +17,15 @@ import (
// TProxy struct
type TProxy struct {
*Forwarder // as client
sDialer Dialer // dialer for server
dialer Dialer
addr string
}
// NewTProxy returns a tproxy.
func NewTProxy(addr string, sDialer Dialer) (*TProxy, error) {
func NewTProxy(addr string, dialer Dialer) (*TProxy, error) {
s := &TProxy{
Forwarder: NewForwarder(addr, nil),
sDialer: sDialer,
dialer: dialer,
addr: addr,
}
return s, nil

View File

@ -8,18 +8,18 @@ import (
// UDPTun struct
type UDPTun struct {
*Forwarder
sDialer Dialer
dialer Dialer
addr string
raddr string
}
// NewUDPTun returns a UDPTun proxy.
func NewUDPTun(addr, raddr string, sDialer Dialer) (*UDPTun, error) {
func NewUDPTun(addr, raddr string, dialer Dialer) (*UDPTun, error) {
s := &UDPTun{
Forwarder: NewForwarder(addr, nil),
sDialer: sDialer,
raddr: raddr,
dialer: dialer,
addr: addr,
raddr: raddr,
}
return s, nil
@ -52,7 +52,7 @@ func (s *UDPTun) ListenAndServe() {
v, ok := nm.Load(raddr.String())
if !ok && v == nil {
pc, writeAddr, err = s.sDialer.DialUDP("udp", s.raddr)
pc, writeAddr, err = s.dialer.DialUDP("udp", s.raddr)
if err != nil {
logf("proxy-udptun remote dial error: %v", err)
continue

View File

@ -8,18 +8,18 @@ import (
// UoTTun udp over tcp tunnel
type UoTTun struct {
*Forwarder
sDialer Dialer
dialer Dialer
addr string
raddr string
}
// NewUoTTun returns a UoTTun proxy.
func NewUoTTun(addr, raddr string, sDialer Dialer) (*UoTTun, error) {
func NewUoTTun(addr, raddr string, dialer Dialer) (*UoTTun, error) {
s := &UoTTun{
Forwarder: NewForwarder(addr, nil),
sDialer: sDialer,
raddr: raddr,
dialer: dialer,
addr: addr,
raddr: raddr,
}
return s, nil
@ -45,7 +45,7 @@ func (s *UoTTun) ListenAndServe() {
continue
}
rc, err := s.sDialer.Dial("uot", s.raddr)
rc, err := s.dialer.Dial("uot", s.raddr)
if err != nil {
logf("proxy-uottun failed to connect to server %v: %v", s.raddr, err)
continue