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 }