github.com/AntonOrnatskyi/goproxy@v0.0.0-20190205095733-4526a9fa18b4/services/sps/sps.go (about)

     1  package sps
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/md5"
     6  	"crypto/tls"
     7  	"encoding/base64"
     8  	"errors"
     9  	"fmt"
    10  	"io/ioutil"
    11  	logger "log"
    12  	"net"
    13  	"runtime/debug"
    14  	"strconv"
    15  	"strings"
    16  	"sync"
    17  	"time"
    18  
    19  	"github.com/AntonOrnatskyi/goproxy/core/cs/server"
    20  	"github.com/AntonOrnatskyi/goproxy/core/lib/kcpcfg"
    21  	"github.com/AntonOrnatskyi/goproxy/services"
    22  	"github.com/AntonOrnatskyi/goproxy/utils"
    23  	"github.com/AntonOrnatskyi/goproxy/utils/conncrypt"
    24  	cryptool "github.com/AntonOrnatskyi/goproxy/utils/crypt"
    25  	"github.com/AntonOrnatskyi/goproxy/utils/datasize"
    26  	"github.com/AntonOrnatskyi/goproxy/utils/dnsx"
    27  	"github.com/AntonOrnatskyi/goproxy/utils/iolimiter"
    28  	"github.com/AntonOrnatskyi/goproxy/utils/jumper"
    29  	"github.com/AntonOrnatskyi/goproxy/utils/lb"
    30  	"github.com/AntonOrnatskyi/goproxy/utils/mapx"
    31  	"github.com/AntonOrnatskyi/goproxy/utils/sni"
    32  	"github.com/AntonOrnatskyi/goproxy/utils/socks"
    33  	"github.com/AntonOrnatskyi/goproxy/utils/ss"
    34  )
    35  
    36  type SPSArgs struct {
    37  	Parent                *[]string
    38  	CertFile              *string
    39  	KeyFile               *string
    40  	CaCertFile            *string
    41  	CaCertBytes           []byte
    42  	CertBytes             []byte
    43  	KeyBytes              []byte
    44  	Local                 *string
    45  	ParentType            *string
    46  	LocalType             *string
    47  	Timeout               *int
    48  	KCP                   kcpcfg.KCPConfigArgs
    49  	ParentServiceType     *string
    50  	DNSAddress            *string
    51  	DNSTTL                *int
    52  	AuthFile              *string
    53  	Auth                  *[]string
    54  	AuthURL               *string
    55  	AuthURLOkCode         *int
    56  	AuthURLTimeout        *int
    57  	AuthURLRetry          *int
    58  	LocalIPS              *[]string
    59  	ParentAuth            *string
    60  	LocalKey              *string
    61  	ParentKey             *string
    62  	LocalCompress         *bool
    63  	ParentCompress        *bool
    64  	SSMethod              *string
    65  	SSKey                 *string
    66  	ParentSSMethod        *string
    67  	ParentSSKey           *string
    68  	DisableHTTP           *bool
    69  	DisableSocks5         *bool
    70  	DisableSS             *bool
    71  	LoadBalanceMethod     *string
    72  	LoadBalanceTimeout    *int
    73  	LoadBalanceRetryTime  *int
    74  	LoadBalanceHashTarget *bool
    75  	LoadBalanceOnlyHA     *bool
    76  	ParentTLSSingle       *bool
    77  
    78  	RateLimit      *string
    79  	RateLimitBytes float64
    80  	Debug          *bool
    81  	Jumper         *string
    82  }
    83  type SPS struct {
    84  	cfg                   SPSArgs
    85  	domainResolver        dnsx.DomainResolver
    86  	basicAuth             utils.BasicAuth
    87  	serverChannels        []*server.ServerChannel
    88  	userConns             mapx.ConcurrentMap
    89  	log                   *logger.Logger
    90  	localCipher           *ss.Cipher
    91  	parentCipher          *ss.Cipher
    92  	udpRelatedPacketConns mapx.ConcurrentMap
    93  	lb                    *lb.Group
    94  	udpLocalKey           []byte
    95  	udpParentKey          []byte
    96  	jumper                *jumper.Jumper
    97  	parentAuthData        *sync.Map
    98  	parentCipherData      *sync.Map
    99  }
   100  
   101  func NewSPS() services.Service {
   102  	return &SPS{
   103  		cfg:                   SPSArgs{},
   104  		basicAuth:             utils.BasicAuth{},
   105  		serverChannels:        []*server.ServerChannel{},
   106  		userConns:             mapx.NewConcurrentMap(),
   107  		udpRelatedPacketConns: mapx.NewConcurrentMap(),
   108  		parentAuthData:        &sync.Map{},
   109  		parentCipherData:      &sync.Map{},
   110  	}
   111  }
   112  func (s *SPS) CheckArgs() (err error) {
   113  
   114  	if len(*s.cfg.Parent) == 1 && (*s.cfg.Parent)[0] == "" {
   115  		(*s.cfg.Parent) = []string{}
   116  	}
   117  
   118  	if len(*s.cfg.Parent) == 0 {
   119  		err = fmt.Errorf("parent required for %s %s", *s.cfg.LocalType, *s.cfg.Local)
   120  		return
   121  	}
   122  	if *s.cfg.ParentType == "" {
   123  		err = fmt.Errorf("parent type unkown,use -T <tls|tcp|kcp>")
   124  		return
   125  	}
   126  	if *s.cfg.ParentType == "ss" && (*s.cfg.ParentSSKey == "" || *s.cfg.ParentSSMethod == "") {
   127  		err = fmt.Errorf("ss parent need a ss key, set it by : -J <sskey>")
   128  		return
   129  	}
   130  	if *s.cfg.ParentType == "tls" || *s.cfg.LocalType == "tls" {
   131  		if !*s.cfg.ParentTLSSingle {
   132  			s.cfg.CertBytes, s.cfg.KeyBytes, err = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile)
   133  			if err != nil {
   134  				return
   135  			}
   136  		}
   137  		if *s.cfg.CaCertFile != "" {
   138  			s.cfg.CaCertBytes, err = ioutil.ReadFile(*s.cfg.CaCertFile)
   139  			if err != nil {
   140  				err = fmt.Errorf("read ca file error,ERR:%s", err)
   141  				return
   142  			}
   143  		}
   144  	}
   145  	if *s.cfg.RateLimit != "0" && *s.cfg.RateLimit != "" {
   146  		var size uint64
   147  		size, err = datasize.Parse(*s.cfg.RateLimit)
   148  		if err != nil {
   149  			err = fmt.Errorf("parse rate limit size error,ERR:%s", err)
   150  			return
   151  		}
   152  		s.cfg.RateLimitBytes = float64(size)
   153  	}
   154  	s.udpLocalKey = s.LocalUDPKey()
   155  	s.udpParentKey = s.ParentUDPKey()
   156  	if *s.cfg.Jumper != "" {
   157  		if *s.cfg.ParentType != "tls" && *s.cfg.ParentType != "tcp" {
   158  			err = fmt.Errorf("jumper only worked of -T is tls or tcp")
   159  			return
   160  		}
   161  		var j jumper.Jumper
   162  		j, err = jumper.New(*s.cfg.Jumper, time.Millisecond*time.Duration(*s.cfg.Timeout))
   163  		if err != nil {
   164  			err = fmt.Errorf("parse jumper fail, err %s", err)
   165  			return
   166  		}
   167  		s.jumper = &j
   168  	}
   169  	return
   170  }
   171  func (s *SPS) InitService() (err error) {
   172  
   173  	if *s.cfg.DNSAddress != "" {
   174  		s.domainResolver = dnsx.NewDomainResolver(*s.cfg.DNSAddress, *s.cfg.DNSTTL, s.log)
   175  	}
   176  
   177  	if len(*s.cfg.Parent) > 0 {
   178  		err = s.InitLB()
   179  		if err != nil {
   180  			return
   181  		}
   182  	}
   183  
   184  	err = s.InitBasicAuth()
   185  	if *s.cfg.SSMethod != "" && *s.cfg.SSKey != "" {
   186  		s.localCipher, err = ss.NewCipher(*s.cfg.SSMethod, *s.cfg.SSKey)
   187  		if err != nil {
   188  			s.log.Printf("error generating cipher : %s", err)
   189  			return
   190  		}
   191  	}
   192  	if *s.cfg.ParentServiceType == "ss" {
   193  		s.parentCipher, err = ss.NewCipher(*s.cfg.ParentSSMethod, *s.cfg.ParentSSKey)
   194  		if err != nil {
   195  			s.log.Printf("error generating cipher : %s", err)
   196  			return
   197  		}
   198  	}
   199  	return
   200  }
   201  
   202  func (s *SPS) StopService() {
   203  	defer func() {
   204  		e := recover()
   205  		if e != nil {
   206  			s.log.Printf("stop sps service crashed,%s", e)
   207  		} else {
   208  			s.log.Printf("service sps stopped")
   209  		}
   210  		s.basicAuth = utils.BasicAuth{}
   211  		s.cfg = SPSArgs{}
   212  		s.domainResolver = dnsx.DomainResolver{}
   213  		s.lb = nil
   214  		s.localCipher = nil
   215  		s.jumper = nil
   216  		s.log = nil
   217  		s.parentCipher = nil
   218  		s.serverChannels = nil
   219  		s.udpLocalKey = nil
   220  		s.udpParentKey = nil
   221  		s.udpRelatedPacketConns = nil
   222  		s.userConns = nil
   223  		s.parentAuthData = nil
   224  		s.parentCipherData = nil
   225  		s = nil
   226  	}()
   227  	for _, sc := range s.serverChannels {
   228  		if sc.Listener != nil && *sc.Listener != nil {
   229  			(*sc.Listener).Close()
   230  		}
   231  		if sc.UDPListener != nil {
   232  			(*sc.UDPListener).Close()
   233  		}
   234  	}
   235  	for _, c := range s.userConns.Items() {
   236  		if _, ok := c.(*net.Conn); ok {
   237  			(*c.(*net.Conn)).Close()
   238  		}
   239  		if _, ok := c.(**net.Conn); ok {
   240  			(*(*c.(**net.Conn))).Close()
   241  		}
   242  	}
   243  	if s.lb != nil {
   244  		s.lb.Stop()
   245  	}
   246  	for _, c := range s.udpRelatedPacketConns.Items() {
   247  		(*c.(*net.UDPConn)).Close()
   248  	}
   249  }
   250  func (s *SPS) Start(args interface{}, log *logger.Logger) (err error) {
   251  	s.log = log
   252  	s.cfg = args.(SPSArgs)
   253  	if err = s.CheckArgs(); err != nil {
   254  		return
   255  	}
   256  	if err = s.InitService(); err != nil {
   257  		return
   258  	}
   259  
   260  	s.log.Printf("use %s %s parent %v [ %s ]", *s.cfg.ParentType, *s.cfg.ParentServiceType, *s.cfg.Parent, strings.ToUpper(*s.cfg.LoadBalanceMethod))
   261  	for _, addr := range strings.Split(*s.cfg.Local, ",") {
   262  		if addr != "" {
   263  			host, port, _ := net.SplitHostPort(addr)
   264  			p, _ := strconv.Atoi(port)
   265  			sc := server.NewServerChannel(host, p, s.log)
   266  			s.serverChannels = append(s.serverChannels, &sc)
   267  			if *s.cfg.LocalType == "tcp" {
   268  				err = sc.ListenTCP(s.callback)
   269  			} else if *s.cfg.LocalType == "tls" {
   270  				err = sc.ListenTLS(s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes, s.callback)
   271  			} else if *s.cfg.LocalType == "kcp" {
   272  				err = sc.ListenKCP(s.cfg.KCP, s.callback, s.log)
   273  			}
   274  			if err != nil {
   275  				return
   276  			}
   277  			if *s.cfg.ParentServiceType == "socks" {
   278  				err = s.RunSSUDP(addr)
   279  			} else {
   280  				s.log.Println("warn : udp only for socks parent ")
   281  			}
   282  			if err != nil {
   283  				return
   284  			}
   285  			s.log.Printf("%s http(s)+socks+ss proxy on %s", *s.cfg.LocalType, (*sc.Listener).Addr())
   286  		}
   287  	}
   288  	return
   289  }
   290  
   291  func (s *SPS) Clean() {
   292  	s.StopService()
   293  }
   294  func (s *SPS) callback(inConn net.Conn) {
   295  	defer func() {
   296  		if err := recover(); err != nil {
   297  			s.log.Printf("%s conn handler crashed with err : %s \nstack: %s", *s.cfg.LocalType, err, string(debug.Stack()))
   298  		}
   299  	}()
   300  	if *s.cfg.LocalCompress {
   301  		inConn = utils.NewCompConn(inConn)
   302  	}
   303  	if *s.cfg.LocalKey != "" {
   304  		inConn = conncrypt.New(inConn, &conncrypt.Config{
   305  			Password: *s.cfg.LocalKey,
   306  		})
   307  	}
   308  	var err error
   309  	lbAddr := ""
   310  	switch *s.cfg.ParentType {
   311  	case "kcp", "tcp", "tls":
   312  		lbAddr, err = s.OutToTCP(&inConn)
   313  	default:
   314  		err = fmt.Errorf("unkown parent type %s", *s.cfg.ParentType)
   315  	}
   316  	if err != nil {
   317  		s.log.Printf("connect to %s parent %s fail, ERR:%s from %s", *s.cfg.ParentType, lbAddr, err, inConn.RemoteAddr())
   318  		utils.CloseConn(&inConn)
   319  	}
   320  }
   321  func (s *SPS) OutToTCP(inConn *net.Conn) (lbAddr string, err error) {
   322  	enableUDP := *s.cfg.ParentServiceType == "socks"
   323  	udpIP, _, _ := net.SplitHostPort((*inConn).LocalAddr().String())
   324  	if len(*s.cfg.LocalIPS) > 0 {
   325  		udpIP = (*s.cfg.LocalIPS)[0]
   326  	}
   327  	bInConn := utils.NewBufferedConn(*inConn)
   328  	//important
   329  	//action read will regist read event to system,
   330  	//when data arrived , system call process
   331  	//so that we can get buffered bytes count
   332  	//otherwise Buffered() always return 0
   333  	bInConn.ReadByte()
   334  	bInConn.UnreadByte()
   335  
   336  	n := 2048
   337  	if n > bInConn.Buffered() {
   338  		n = bInConn.Buffered()
   339  	}
   340  	h, err := bInConn.Peek(n)
   341  	if err != nil {
   342  		s.log.Printf("peek error %s ", err)
   343  		(*inConn).Close()
   344  		return
   345  	}
   346  	isSNI, _ := sni.ServerNameFromBytes(h)
   347  	*inConn = bInConn
   348  	address := ""
   349  	var auth = socks.Auth{}
   350  	var forwardBytes []byte
   351  	//fmt.Printf("%v", header)
   352  	if utils.IsSocks5(h) {
   353  		if *s.cfg.DisableSocks5 {
   354  			(*inConn).Close()
   355  			return
   356  		}
   357  		//socks5 server
   358  		var serverConn *socks.ServerConn
   359  		if s.IsBasicAuth() {
   360  			serverConn = socks.NewServerConn(inConn, time.Millisecond*time.Duration(*s.cfg.Timeout), &s.basicAuth, enableUDP, udpIP, nil)
   361  		} else {
   362  			serverConn = socks.NewServerConn(inConn, time.Millisecond*time.Duration(*s.cfg.Timeout), nil, enableUDP, udpIP, nil)
   363  		}
   364  		if err = serverConn.Handshake(); err != nil {
   365  			return
   366  		}
   367  		address = serverConn.Target()
   368  		auth = serverConn.AuthData()
   369  		if serverConn.IsUDP() {
   370  			s.proxyUDP(inConn, serverConn)
   371  			return
   372  		}
   373  	} else if utils.IsHTTP(h) || isSNI != "" {
   374  		if *s.cfg.DisableHTTP {
   375  			(*inConn).Close()
   376  			return
   377  		}
   378  		//http
   379  		var request utils.HTTPRequest
   380  		(*inConn).SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
   381  		if s.IsBasicAuth() {
   382  			request, err = utils.NewHTTPRequest(inConn, 1024, true, &s.basicAuth, s.log)
   383  		} else {
   384  			request, err = utils.NewHTTPRequest(inConn, 1024, false, nil, s.log)
   385  		}
   386  		(*inConn).SetDeadline(time.Time{})
   387  		if err != nil {
   388  			s.log.Printf("new http request fail,ERR: %s", err)
   389  			utils.CloseConn(inConn)
   390  			return
   391  		}
   392  		if len(h) >= 7 && strings.ToLower(string(h[:7])) == "connect" {
   393  			//https
   394  			request.HTTPSReply()
   395  			//s.log.Printf("https reply: %s", request.Host)
   396  		} else {
   397  			forwardBytes = request.HeadBuf
   398  		}
   399  		address = request.Host
   400  		var userpass string
   401  		if s.IsBasicAuth() {
   402  			userpass, err = request.GetAuthDataStr()
   403  			if err != nil {
   404  				return
   405  			}
   406  			userpassA := strings.Split(userpass, ":")
   407  			if len(userpassA) == 2 {
   408  				auth = socks.Auth{User: userpassA[0], Password: userpassA[1]}
   409  			}
   410  		}
   411  	} else {
   412  		//ss
   413  		if *s.cfg.DisableSS {
   414  			(*inConn).Close()
   415  			return
   416  		}
   417  		(*inConn).SetDeadline(time.Now().Add(time.Second * 5))
   418  		ssConn := ss.NewConn(*inConn, s.localCipher.Copy())
   419  		address, err = ss.GetRequest(ssConn)
   420  		(*inConn).SetDeadline(time.Time{})
   421  		if err != nil {
   422  			return
   423  		}
   424  		// ensure the host does not contain some illegal characters, NUL may panic on Win32
   425  		if strings.ContainsRune(address, 0x00) {
   426  			err = errors.New("invalid domain name")
   427  			return
   428  		}
   429  		*inConn = ssConn
   430  	}
   431  	if err != nil || address == "" {
   432  		s.log.Printf("unknown request from: %s,%s", (*inConn).RemoteAddr(), string(h))
   433  		(*inConn).Close()
   434  		utils.CloseConn(inConn)
   435  		err = errors.New("unknown request")
   436  		return
   437  	}
   438  	//connect to parent
   439  	var outConn net.Conn
   440  	selectAddr := (*inConn).RemoteAddr().String()
   441  	if utils.LBMethod(*s.cfg.LoadBalanceMethod) == lb.SELECT_HASH && *s.cfg.LoadBalanceHashTarget {
   442  		selectAddr = address
   443  	}
   444  	lbAddr = s.lb.Select(selectAddr, *s.cfg.LoadBalanceOnlyHA)
   445  	outConn, err = s.GetParentConn(lbAddr)
   446  	if err != nil {
   447  		s.log.Printf("connect to %s , err:%s", lbAddr, err)
   448  		utils.CloseConn(inConn)
   449  		return
   450  	}
   451  	ParentAuth := s.getParentAuth(lbAddr)
   452  	if ParentAuth != "" || *s.cfg.ParentSSKey != "" || s.IsBasicAuth() {
   453  		forwardBytes = utils.RemoveProxyHeaders(forwardBytes)
   454  	}
   455  
   456  	//ask parent for connect to target address
   457  	if *s.cfg.ParentServiceType == "http" {
   458  		//http parent
   459  		isHTTPS := false
   460  
   461  		pb := new(bytes.Buffer)
   462  		if len(forwardBytes) == 0 {
   463  			isHTTPS = true
   464  			pb.Write([]byte(fmt.Sprintf("CONNECT %s HTTP/1.1\r\n", address)))
   465  		}
   466  		pb.WriteString(fmt.Sprintf("Host: %s\r\n", address))
   467  		pb.WriteString(fmt.Sprintf("Proxy-Host: %s\r\n", address))
   468  		pb.WriteString("Proxy-Connection: Keep-Alive\r\n")
   469  		pb.WriteString("Connection: Keep-Alive\r\n")
   470  
   471  		u := ""
   472  		if ParentAuth != "" {
   473  			a := strings.Split(ParentAuth, ":")
   474  			if len(a) != 2 {
   475  				err = fmt.Errorf("parent auth data format error")
   476  				return
   477  			}
   478  			u = fmt.Sprintf("%s:%s", a[0], a[1])
   479  		} else {
   480  			if !s.IsBasicAuth() && auth.Password != "" && auth.User != "" {
   481  				u = fmt.Sprintf("%s:%s", auth.User, auth.Password)
   482  			}
   483  		}
   484  		if u != "" {
   485  			pb.Write([]byte(fmt.Sprintf("Proxy-Authorization: Basic %s\r\n", base64.StdEncoding.EncodeToString([]byte(u)))))
   486  		}
   487  
   488  		if isHTTPS {
   489  			pb.Write([]byte("\r\n"))
   490  		} else {
   491  			forwardBytes = utils.InsertProxyHeaders(forwardBytes, string(pb.Bytes()))
   492  			pb.Reset()
   493  			pb.Write(forwardBytes)
   494  			forwardBytes = nil
   495  		}
   496  
   497  		outConn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
   498  		_, err = outConn.Write(pb.Bytes())
   499  		outConn.SetDeadline(time.Time{})
   500  		if err != nil {
   501  			s.log.Printf("write CONNECT to %s , err:%s", lbAddr, err)
   502  			utils.CloseConn(inConn)
   503  			utils.CloseConn(&outConn)
   504  			return
   505  		}
   506  
   507  		if isHTTPS {
   508  			reply := make([]byte, 1024)
   509  			outConn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
   510  			_, err = outConn.Read(reply)
   511  			outConn.SetDeadline(time.Time{})
   512  			if err != nil {
   513  				s.log.Printf("read reply from %s , err:%s", lbAddr, err)
   514  				utils.CloseConn(inConn)
   515  				utils.CloseConn(&outConn)
   516  				return
   517  			}
   518  			//s.log.Printf("reply: %s", string(reply[:n]))
   519  		}
   520  	} else if *s.cfg.ParentServiceType == "socks" {
   521  		s.log.Printf("connect %s", address)
   522  
   523  		//socks client
   524  		_, err = s.HandshakeSocksParent(ParentAuth, &outConn, "tcp", address, auth, false)
   525  		if err != nil {
   526  			s.log.Printf("handshake fail, %s", err)
   527  			return
   528  		}
   529  
   530  	} else if *s.cfg.ParentServiceType == "ss" {
   531  		ra, e := ss.RawAddr(address)
   532  		if e != nil {
   533  			err = fmt.Errorf("build ss raw addr fail, err: %s", e)
   534  			return
   535  		}
   536  
   537  		outConn, err = ss.DialWithRawAddr(&outConn, ra, "", s.getParentCipher(lbAddr))
   538  		if err != nil {
   539  			err = fmt.Errorf("dial ss parent fail, err : %s", err)
   540  			return
   541  		}
   542  	}
   543  
   544  	//forward client data to target,if necessary.
   545  	if len(forwardBytes) > 0 {
   546  		outConn.Write(forwardBytes)
   547  	}
   548  
   549  	if s.cfg.RateLimitBytes > 0 {
   550  		outConn = iolimiter.NewReaderConn(outConn, s.cfg.RateLimitBytes)
   551  	}
   552  
   553  	//bind
   554  	inAddr := (*inConn).RemoteAddr().String()
   555  	outAddr := outConn.RemoteAddr().String()
   556  	utils.IoBind((*inConn), outConn, func(err interface{}) {
   557  		s.log.Printf("conn %s - %s released [%s]", inAddr, outAddr, address)
   558  		s.userConns.Remove(inAddr)
   559  		s.lb.DecreaseConns(lbAddr)
   560  	}, s.log)
   561  	s.log.Printf("conn %s - %s connected [%s]", inAddr, outAddr, address)
   562  
   563  	s.lb.IncreasConns(lbAddr)
   564  
   565  	if c, ok := s.userConns.Get(inAddr); ok {
   566  		(*c.(*net.Conn)).Close()
   567  	}
   568  	s.userConns.Set(inAddr, inConn)
   569  
   570  	return
   571  }
   572  func (s *SPS) InitBasicAuth() (err error) {
   573  	if *s.cfg.DNSAddress != "" {
   574  		s.basicAuth = utils.NewBasicAuth(&(*s).domainResolver, s.log)
   575  	} else {
   576  		s.basicAuth = utils.NewBasicAuth(nil, s.log)
   577  	}
   578  	if *s.cfg.AuthURL != "" {
   579  		s.basicAuth.SetAuthURL(*s.cfg.AuthURL, *s.cfg.AuthURLOkCode, *s.cfg.AuthURLTimeout, *s.cfg.AuthURLRetry)
   580  		s.log.Printf("auth from %s", *s.cfg.AuthURL)
   581  	}
   582  	if *s.cfg.AuthFile != "" {
   583  		var n = 0
   584  		n, err = s.basicAuth.AddFromFile(*s.cfg.AuthFile)
   585  		if err != nil {
   586  			err = fmt.Errorf("auth-file ERR:%s", err)
   587  			return
   588  		}
   589  		s.log.Printf("auth data added from file %d , total:%d", n, s.basicAuth.Total())
   590  	}
   591  	if len(*s.cfg.Auth) > 0 {
   592  		n := s.basicAuth.Add(*s.cfg.Auth)
   593  		s.log.Printf("auth data added %d, total:%d", n, s.basicAuth.Total())
   594  	}
   595  	return
   596  }
   597  func (s *SPS) InitLB() (err error) {
   598  	configs := lb.BackendsConfig{}
   599  	for _, addr := range *s.cfg.Parent {
   600  		var _addrInfo []string
   601  		if strings.Contains(addr, "#") {
   602  			_s := addr[:strings.Index(addr, "#")]
   603  			_auth, err := cryptool.CryptTools.Base64Decode(_s)
   604  			if err != nil {
   605  				s.log.Printf("decoding parent auth data [ %s ] fail , error : %s", _s, err)
   606  				return err
   607  			}
   608  			_addrInfo = strings.Split(addr[strings.Index(addr, "#")+1:], "@")
   609  			if *s.cfg.ParentServiceType == "ss" {
   610  				_s := strings.Split(_auth, ":")
   611  				m := _s[0]
   612  				k := _s[1]
   613  				if m == "" {
   614  					m = *s.cfg.ParentSSMethod
   615  				}
   616  				if k == "" {
   617  					k = *s.cfg.ParentSSKey
   618  				}
   619  				cipher, err := ss.NewCipher(m, k)
   620  				if err != nil {
   621  					s.log.Printf("error generating cipher, ssMethod: %s, ssKey: %s, error : %s", m, k, err)
   622  					return err
   623  				}
   624  				s.parentCipherData.Store(_addrInfo[0], cipher)
   625  			} else {
   626  				s.parentAuthData.Store(_addrInfo[0], _auth)
   627  			}
   628  
   629  		} else {
   630  			_addrInfo = strings.Split(addr, "@")
   631  		}
   632  		_addr := _addrInfo[0]
   633  		weight := 1
   634  		if len(_addrInfo) == 2 {
   635  			weight, _ = strconv.Atoi(_addrInfo[1])
   636  		}
   637  		configs = append(configs, &lb.BackendConfig{
   638  			Address:       _addr,
   639  			Weight:        weight,
   640  			ActiveAfter:   1,
   641  			InactiveAfter: 2,
   642  			Timeout:       time.Duration(*s.cfg.LoadBalanceTimeout) * time.Millisecond,
   643  			RetryTime:     time.Duration(*s.cfg.LoadBalanceRetryTime) * time.Millisecond,
   644  		})
   645  	}
   646  	LB := lb.NewGroup(utils.LBMethod(*s.cfg.LoadBalanceMethod), configs, &s.domainResolver, s.log, *s.cfg.Debug)
   647  	s.lb = &LB
   648  	return
   649  }
   650  func (s *SPS) getParentAuth(lbAddr string) string {
   651  	if v, ok := s.parentAuthData.Load(lbAddr); ok {
   652  		return v.(string)
   653  	}
   654  	return *s.cfg.ParentAuth
   655  }
   656  func (s *SPS) getParentCipher(lbAddr string) *ss.Cipher {
   657  	if v, ok := s.parentCipherData.Load(lbAddr); ok {
   658  		return v.(*ss.Cipher).Copy()
   659  	}
   660  	return s.parentCipher.Copy()
   661  }
   662  func (s *SPS) IsBasicAuth() bool {
   663  	return *s.cfg.AuthFile != "" || len(*s.cfg.Auth) > 0 || *s.cfg.AuthURL != ""
   664  }
   665  func (s *SPS) buildRequest(address string) (buf []byte, err error) {
   666  	host, portStr, err := net.SplitHostPort(address)
   667  	if err != nil {
   668  		return nil, err
   669  	}
   670  
   671  	port, err := strconv.Atoi(portStr)
   672  	if err != nil {
   673  		err = errors.New("proxy: failed to parse port number: " + portStr)
   674  		return
   675  	}
   676  	if port < 1 || port > 0xffff {
   677  		err = errors.New("proxy: port number out of range: " + portStr)
   678  		return
   679  	}
   680  	buf = buf[:0]
   681  	buf = append(buf, 0x05, 0x01, 0 /* reserved */)
   682  
   683  	if ip := net.ParseIP(host); ip != nil {
   684  		if ip4 := ip.To4(); ip4 != nil {
   685  			buf = append(buf, 0x01)
   686  			ip = ip4
   687  		} else {
   688  			buf = append(buf, 0x04)
   689  		}
   690  		buf = append(buf, ip...)
   691  	} else {
   692  		if len(host) > 255 {
   693  			err = errors.New("proxy: destination host name too long: " + host)
   694  			return
   695  		}
   696  		buf = append(buf, 0x03)
   697  		buf = append(buf, byte(len(host)))
   698  		buf = append(buf, host...)
   699  	}
   700  	buf = append(buf, byte(port>>8), byte(port))
   701  	return
   702  }
   703  func (s *SPS) Resolve(address string) string {
   704  	if *s.cfg.DNSAddress == "" {
   705  		return address
   706  	}
   707  	ip, err := s.domainResolver.Resolve(address)
   708  	if err != nil {
   709  		s.log.Printf("dns error %s , ERR:%s", address, err)
   710  		return address
   711  	}
   712  	return ip
   713  }
   714  func (s *SPS) GetParentConn(address string) (conn net.Conn, err error) {
   715  	if *s.cfg.ParentType == "tls" {
   716  		if s.jumper == nil {
   717  			var _conn tls.Conn
   718  			if *s.cfg.ParentTLSSingle {
   719  				_conn, err = utils.SingleTlsConnectHost(address, *s.cfg.Timeout, s.cfg.CaCertBytes)
   720  			} else {
   721  				_conn, err = utils.TlsConnectHost(address, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes)
   722  			}
   723  			if err == nil {
   724  				conn = net.Conn(&_conn)
   725  			}
   726  		} else {
   727  			var conf *tls.Config
   728  			if *s.cfg.ParentTLSSingle {
   729  				conf, err = utils.SingleTlsConfig(s.cfg.CaCertBytes)
   730  			} else {
   731  				conf, err = utils.TlsConfig(s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes)
   732  			}
   733  			if err != nil {
   734  				return nil, err
   735  			}
   736  			var _c net.Conn
   737  			_c, err = s.jumper.Dial(address, time.Millisecond*time.Duration(*s.cfg.Timeout))
   738  			if err == nil {
   739  				conn = net.Conn(tls.Client(_c, conf))
   740  			}
   741  		}
   742  
   743  	} else if *s.cfg.ParentType == "kcp" {
   744  		conn, err = utils.ConnectKCPHost(address, s.cfg.KCP)
   745  	} else {
   746  		if s.jumper == nil {
   747  			conn, err = utils.ConnectHost(address, *s.cfg.Timeout)
   748  		} else {
   749  			conn, err = s.jumper.Dial(address, time.Millisecond*time.Duration(*s.cfg.Timeout))
   750  		}
   751  	}
   752  	if err == nil {
   753  		if *s.cfg.ParentCompress {
   754  			conn = utils.NewCompConn(conn)
   755  		}
   756  		if *s.cfg.ParentKey != "" {
   757  			conn = conncrypt.New(conn, &conncrypt.Config{
   758  				Password: *s.cfg.ParentKey,
   759  			})
   760  		}
   761  	}
   762  	return
   763  }
   764  func (s *SPS) HandshakeSocksParent(parentAuth string, outconn *net.Conn, network, dstAddr string, auth socks.Auth, fromSS bool) (client *socks.ClientConn, err error) {
   765  	if parentAuth != "" {
   766  		a := strings.Split(parentAuth, ":")
   767  		if len(a) != 2 {
   768  			err = fmt.Errorf("parent auth data format error")
   769  			return
   770  		}
   771  		client = socks.NewClientConn(outconn, network, dstAddr, time.Millisecond*time.Duration(*s.cfg.Timeout), &socks.Auth{User: a[0], Password: a[1]}, nil)
   772  	} else {
   773  		if !fromSS && !s.IsBasicAuth() && auth.Password != "" && auth.User != "" {
   774  			client = socks.NewClientConn(outconn, network, dstAddr, time.Millisecond*time.Duration(*s.cfg.Timeout), &auth, nil)
   775  		} else {
   776  			client = socks.NewClientConn(outconn, network, dstAddr, time.Millisecond*time.Duration(*s.cfg.Timeout), nil, nil)
   777  		}
   778  	}
   779  	err = client.Handshake()
   780  	return
   781  }
   782  func (s *SPS) ParentUDPKey() (key []byte) {
   783  	switch *s.cfg.ParentType {
   784  	case "tcp":
   785  		if *s.cfg.ParentKey != "" {
   786  			v := fmt.Sprintf("%x", md5.Sum([]byte(*s.cfg.ParentKey)))
   787  			return []byte(v)[:24]
   788  		}
   789  	case "tls":
   790  		if s.cfg.KeyBytes != nil {
   791  			return s.cfg.KeyBytes[:24]
   792  		}
   793  	case "kcp":
   794  		v := fmt.Sprintf("%x", md5.Sum([]byte(*s.cfg.KCP.Key)))
   795  		return []byte(v)[:24]
   796  	}
   797  	return
   798  }
   799  func (s *SPS) LocalUDPKey() (key []byte) {
   800  	switch *s.cfg.LocalType {
   801  	case "tcp":
   802  		if *s.cfg.LocalKey != "" {
   803  			v := fmt.Sprintf("%x", md5.Sum([]byte(*s.cfg.LocalKey)))
   804  			return []byte(v)[:24]
   805  		}
   806  	case "tls":
   807  		return s.cfg.KeyBytes[:24]
   808  	case "kcp":
   809  		v := fmt.Sprintf("%x", md5.Sum([]byte(*s.cfg.KCP.Key)))
   810  		return []byte(v)[:24]
   811  	}
   812  	return
   813  }