github.com/AntonOrnatskyi/goproxy@v0.0.0-20190205095733-4526a9fa18b4/services/socks/socks.go (about) 1 package socks 2 3 import ( 4 "crypto/tls" 5 "fmt" 6 "io" 7 "io/ioutil" 8 logger "log" 9 "net" 10 "runtime/debug" 11 "strconv" 12 "strings" 13 "time" 14 15 server "github.com/AntonOrnatskyi/goproxy/core/cs/server" 16 "github.com/AntonOrnatskyi/goproxy/core/lib/kcpcfg" 17 "github.com/AntonOrnatskyi/goproxy/services" 18 "github.com/AntonOrnatskyi/goproxy/utils" 19 "github.com/AntonOrnatskyi/goproxy/utils/conncrypt" 20 "github.com/AntonOrnatskyi/goproxy/utils/datasize" 21 "github.com/AntonOrnatskyi/goproxy/utils/dnsx" 22 "github.com/AntonOrnatskyi/goproxy/utils/iolimiter" 23 "github.com/AntonOrnatskyi/goproxy/utils/lb" 24 "github.com/AntonOrnatskyi/goproxy/utils/mapx" 25 "github.com/AntonOrnatskyi/goproxy/utils/socks" 26 27 "golang.org/x/crypto/ssh" 28 ) 29 30 type SocksArgs struct { 31 Parent *[]string 32 ParentType *string 33 Local *string 34 LocalType *string 35 CertFile *string 36 KeyFile *string 37 CaCertFile *string 38 CaCertBytes []byte 39 CertBytes []byte 40 KeyBytes []byte 41 SSHKeyFile *string 42 SSHKeyFileSalt *string 43 SSHPassword *string 44 SSHUser *string 45 SSHKeyBytes []byte 46 SSHAuthMethod ssh.AuthMethod 47 Timeout *int 48 Always *bool 49 Interval *int 50 Blocked *string 51 Direct *string 52 ParentAuth *string 53 AuthFile *string 54 Auth *[]string 55 AuthURL *string 56 AuthURLOkCode *int 57 AuthURLTimeout *int 58 AuthURLRetry *int 59 KCP kcpcfg.KCPConfigArgs 60 LocalIPS *[]string 61 DNSAddress *string 62 DNSTTL *int 63 LocalKey *string 64 ParentKey *string 65 LocalCompress *bool 66 ParentCompress *bool 67 Intelligent *string 68 LoadBalanceMethod *string 69 LoadBalanceTimeout *int 70 LoadBalanceRetryTime *int 71 LoadBalanceHashTarget *bool 72 LoadBalanceOnlyHA *bool 73 74 RateLimit *string 75 RateLimitBytes float64 76 BindListen *bool 77 Debug *bool 78 } 79 type Socks struct { 80 cfg SocksArgs 81 checker utils.Checker 82 basicAuth utils.BasicAuth 83 sshClient *ssh.Client 84 lockChn chan bool 85 udpSC server.ServerChannel 86 sc *server.ServerChannel 87 domainResolver dnsx.DomainResolver 88 isStop bool 89 userConns mapx.ConcurrentMap 90 log *logger.Logger 91 lb *lb.Group 92 udpRelatedPacketConns mapx.ConcurrentMap 93 udpLocalKey []byte 94 udpParentKey []byte 95 } 96 97 func NewSocks() services.Service { 98 return &Socks{ 99 cfg: SocksArgs{}, 100 checker: utils.Checker{}, 101 basicAuth: utils.BasicAuth{}, 102 lockChn: make(chan bool, 1), 103 isStop: false, 104 userConns: mapx.NewConcurrentMap(), 105 udpRelatedPacketConns: mapx.NewConcurrentMap(), 106 } 107 } 108 109 func (s *Socks) CheckArgs() (err error) { 110 111 if *s.cfg.LocalType == "tls" || (len(*s.cfg.Parent) > 0 && *s.cfg.ParentType == "tls") { 112 s.cfg.CertBytes, s.cfg.KeyBytes, err = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile) 113 if err != nil { 114 return 115 } 116 if *s.cfg.CaCertFile != "" { 117 s.cfg.CaCertBytes, err = ioutil.ReadFile(*s.cfg.CaCertFile) 118 if err != nil { 119 err = fmt.Errorf("read ca file error,ERR:%s", err) 120 return 121 } 122 } 123 } 124 125 if len(*s.cfg.Parent) == 1 && (*s.cfg.Parent)[0] == "" { 126 (*s.cfg.Parent) = []string{} 127 } 128 129 if len(*s.cfg.Parent) > 0 { 130 if *s.cfg.ParentType == "" { 131 err = fmt.Errorf("parent type unkown,use -T <tls|tcp|ssh|kcp>") 132 return 133 } 134 if *s.cfg.ParentType == "ssh" { 135 if *s.cfg.SSHUser == "" { 136 err = fmt.Errorf("ssh user required") 137 return 138 } 139 if *s.cfg.SSHKeyFile == "" && *s.cfg.SSHPassword == "" { 140 err = fmt.Errorf("ssh password or key required") 141 return 142 } 143 if *s.cfg.SSHPassword != "" { 144 s.cfg.SSHAuthMethod = ssh.Password(*s.cfg.SSHPassword) 145 } else { 146 var SSHSigner ssh.Signer 147 s.cfg.SSHKeyBytes, err = ioutil.ReadFile(*s.cfg.SSHKeyFile) 148 if err != nil { 149 err = fmt.Errorf("read key file ERR: %s", err) 150 return 151 } 152 if *s.cfg.SSHKeyFileSalt != "" { 153 SSHSigner, err = ssh.ParsePrivateKeyWithPassphrase(s.cfg.SSHKeyBytes, []byte(*s.cfg.SSHKeyFileSalt)) 154 } else { 155 SSHSigner, err = ssh.ParsePrivateKey(s.cfg.SSHKeyBytes) 156 } 157 if err != nil { 158 err = fmt.Errorf("parse ssh private key fail,ERR: %s", err) 159 return 160 } 161 s.cfg.SSHAuthMethod = ssh.PublicKeys(SSHSigner) 162 } 163 } 164 } 165 if *s.cfg.RateLimit != "0" && *s.cfg.RateLimit != "" { 166 var size uint64 167 size, err = datasize.Parse(*s.cfg.RateLimit) 168 if err != nil { 169 err = fmt.Errorf("parse rate limit size error,ERR:%s", err) 170 return 171 } 172 s.cfg.RateLimitBytes = float64(size) 173 } 174 s.udpLocalKey = s.LocalUDPKey() 175 s.udpParentKey = s.ParentUDPKey() 176 return 177 } 178 func (s *Socks) InitService() (err error) { 179 s.InitBasicAuth() 180 if *s.cfg.DNSAddress != "" { 181 (*s).domainResolver = dnsx.NewDomainResolver(*s.cfg.DNSAddress, *s.cfg.DNSTTL, s.log) 182 } 183 if len(*s.cfg.Parent) > 0 { 184 s.checker = utils.NewChecker(*s.cfg.Timeout, int64(*s.cfg.Interval), *s.cfg.Blocked, *s.cfg.Direct, s.log, *s.cfg.Intelligent) 185 s.InitLB() 186 } 187 if *s.cfg.ParentType == "ssh" { 188 e := s.ConnectSSH(s.Resolve(s.lb.Select("", *s.cfg.LoadBalanceOnlyHA))) 189 if e != nil { 190 err = fmt.Errorf("init service fail, ERR: %s", e) 191 return 192 } 193 go func() { 194 defer func() { 195 if e := recover(); e != nil { 196 fmt.Printf("crashed, err: %s\nstack:\n%s", e, string(debug.Stack())) 197 } 198 }() 199 //循环检查ssh网络连通性 200 for { 201 if s.isStop { 202 return 203 } 204 conn, err := utils.ConnectHost(s.Resolve(s.lb.Select("", *s.cfg.LoadBalanceOnlyHA)), *s.cfg.Timeout*2) 205 if err == nil { 206 conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout))) 207 _, err = conn.Write([]byte{0}) 208 conn.SetDeadline(time.Time{}) 209 } 210 if err != nil { 211 if s.sshClient != nil { 212 s.sshClient.Close() 213 } 214 s.log.Printf("ssh offline, retrying...") 215 s.ConnectSSH(s.Resolve(s.lb.Select("", *s.cfg.LoadBalanceOnlyHA))) 216 } else { 217 conn.Close() 218 } 219 time.Sleep(time.Second * 3) 220 } 221 }() 222 } 223 if *s.cfg.ParentType == "ssh" { 224 s.log.Printf("warn: socks udp not suppored for ssh") 225 } 226 return 227 } 228 func (s *Socks) StopService() { 229 defer func() { 230 e := recover() 231 if e != nil { 232 s.log.Printf("stop socks service crashed,%s", e) 233 } else { 234 s.log.Printf("service socks stopped") 235 } 236 s.basicAuth = utils.BasicAuth{} 237 s.cfg = SocksArgs{} 238 s.checker = utils.Checker{} 239 s.domainResolver = dnsx.DomainResolver{} 240 s.lb = nil 241 s.lockChn = nil 242 s.log = nil 243 s.sc = nil 244 s.sshClient = nil 245 s.udpLocalKey = nil 246 s.udpParentKey = nil 247 s.udpRelatedPacketConns = nil 248 s.udpSC = server.ServerChannel{} 249 s.userConns = nil 250 s = nil 251 }() 252 s.isStop = true 253 if len(*s.cfg.Parent) > 0 { 254 s.checker.Stop() 255 } 256 if s.sshClient != nil { 257 s.sshClient.Close() 258 } 259 if s.udpSC.UDPListener != nil { 260 s.udpSC.UDPListener.Close() 261 } 262 if s.sc != nil && (*s.sc).Listener != nil { 263 (*(*s.sc).Listener).Close() 264 } 265 for _, c := range s.userConns.Items() { 266 (*c.(*net.Conn)).Close() 267 } 268 if s.lb != nil { 269 s.lb.Stop() 270 } 271 for _, c := range s.udpRelatedPacketConns.Items() { 272 (*c.(*net.UDPConn)).Close() 273 } 274 } 275 func (s *Socks) Start(args interface{}, log *logger.Logger) (err error) { 276 s.log = log 277 //start() 278 s.cfg = args.(SocksArgs) 279 if err = s.CheckArgs(); err != nil { 280 return 281 } 282 if err = s.InitService(); err != nil { 283 s.InitService() 284 } 285 if len(*s.cfg.Parent) > 0 { 286 s.log.Printf("use %s parent %v [ %s ]", *s.cfg.ParentType, *s.cfg.Parent, strings.ToUpper(*s.cfg.LoadBalanceMethod)) 287 } 288 sc := server.NewServerChannelHost(*s.cfg.Local, s.log) 289 if *s.cfg.LocalType == "tcp" { 290 err = sc.ListenTCP(s.socksConnCallback) 291 } else if *s.cfg.LocalType == "tls" { 292 err = sc.ListenTLS(s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes, s.socksConnCallback) 293 } else if *s.cfg.LocalType == "kcp" { 294 err = sc.ListenKCP(s.cfg.KCP, s.socksConnCallback, s.log) 295 } 296 if err != nil { 297 return 298 } 299 s.sc = &sc 300 s.log.Printf("%s socks proxy on %s", *s.cfg.LocalType, (*sc.Listener).Addr()) 301 return 302 } 303 func (s *Socks) Clean() { 304 s.StopService() 305 } 306 307 func (s *Socks) socksConnCallback(inConn net.Conn) { 308 defer func() { 309 if err := recover(); err != nil { 310 s.log.Printf("socks conn handler crashed with err : %s \nstack: %s", err, string(debug.Stack())) 311 inConn.Close() 312 } 313 }() 314 if *s.cfg.LocalCompress { 315 inConn = utils.NewCompConn(inConn) 316 } 317 if *s.cfg.LocalKey != "" { 318 inConn = conncrypt.New(inConn, &conncrypt.Config{ 319 Password: *s.cfg.LocalKey, 320 }) 321 } 322 323 //socks5 server 324 var serverConn *socks.ServerConn 325 udpIP, _, _ := net.SplitHostPort(inConn.LocalAddr().String()) 326 if s.IsBasicAuth() { 327 serverConn = socks.NewServerConn(&inConn, time.Millisecond*time.Duration(*s.cfg.Timeout), &s.basicAuth, true, udpIP, nil) 328 } else { 329 serverConn = socks.NewServerConn(&inConn, time.Millisecond*time.Duration(*s.cfg.Timeout), nil, true, udpIP, nil) 330 } 331 if err := serverConn.Handshake(); err != nil { 332 if !strings.HasSuffix(err.Error(), "EOF") { 333 s.log.Printf("handshake fail, ERR: %s", err) 334 } 335 inConn.Close() 336 return 337 } 338 if serverConn.IsUDP() { 339 s.proxyUDP(&inConn, serverConn) 340 } else if serverConn.IsTCP() { 341 s.proxyTCP(&inConn, serverConn) 342 } 343 } 344 345 func (s *Socks) proxyTCP(inConn *net.Conn, serverConn *socks.ServerConn) { 346 var outConn net.Conn 347 var err interface{} 348 lbAddr := "" 349 useProxy := true 350 tryCount := 0 351 maxTryCount := 5 352 //防止死循环 353 if s.IsDeadLoop((*inConn).LocalAddr().String(), serverConn.Host()) { 354 utils.CloseConn(inConn) 355 s.log.Printf("dead loop detected , %s", serverConn.Host()) 356 utils.CloseConn(inConn) 357 return 358 } 359 for { 360 if s.isStop { 361 return 362 } 363 364 if *s.cfg.Always { 365 selectAddr := (*inConn).RemoteAddr().String() 366 if utils.LBMethod(*s.cfg.LoadBalanceMethod) == lb.SELECT_HASH && *s.cfg.LoadBalanceHashTarget { 367 selectAddr = serverConn.Target() 368 } 369 lbAddr = s.lb.Select(selectAddr, *s.cfg.LoadBalanceOnlyHA) 370 //lbAddr = s.lb.Select((*inConn).RemoteAddr().String()) 371 outConn, err = s.GetParentConn(lbAddr, serverConn) 372 if err != nil { 373 s.log.Printf("connect to parent fail, %s", err) 374 return 375 } 376 //handshake 377 //socks client 378 _, err = s.HandshakeSocksParent(&outConn, "tcp", serverConn.Target(), serverConn.AuthData(), false) 379 if err != nil { 380 if err != io.EOF { 381 s.log.Printf("handshake fail, %s", err) 382 } 383 return 384 } 385 } else { 386 if len(*s.cfg.Parent) > 0 { 387 host, _, _ := net.SplitHostPort(serverConn.Target()) 388 useProxy := false 389 if utils.IsInternalIP(host, *s.cfg.Always) { 390 useProxy = false 391 } else { 392 var isInMap bool 393 useProxy, isInMap, _, _ = s.checker.IsBlocked(serverConn.Target()) 394 if !isInMap { 395 s.checker.Add(serverConn.Target(), s.Resolve(serverConn.Target())) 396 } 397 } 398 if useProxy { 399 selectAddr := (*inConn).RemoteAddr().String() 400 if utils.LBMethod(*s.cfg.LoadBalanceMethod) == lb.SELECT_HASH && *s.cfg.LoadBalanceHashTarget { 401 selectAddr = serverConn.Target() 402 } 403 lbAddr = s.lb.Select(selectAddr, *s.cfg.LoadBalanceOnlyHA) 404 //lbAddr = s.lb.Select((*inConn).RemoteAddr().String()) 405 outConn, err = s.GetParentConn(lbAddr, serverConn) 406 if err != nil { 407 s.log.Printf("connect to parent fail, %s", err) 408 return 409 } 410 //handshake 411 //socks client 412 _, err = s.HandshakeSocksParent(&outConn, "tcp", serverConn.Target(), serverConn.AuthData(), false) 413 if err != nil { 414 s.log.Printf("handshake fail, %s", err) 415 return 416 } 417 } else { 418 outConn, err = s.GetDirectConn(s.Resolve(serverConn.Target()), (*inConn).LocalAddr().String()) 419 } 420 } else { 421 outConn, err = s.GetDirectConn(s.Resolve(serverConn.Target()), (*inConn).LocalAddr().String()) 422 useProxy = false 423 } 424 } 425 tryCount++ 426 if err == nil || tryCount > maxTryCount || len(*s.cfg.Parent) == 0 { 427 break 428 } else { 429 s.log.Printf("get out conn fail,%s,retrying...", err) 430 time.Sleep(time.Second * 2) 431 } 432 } 433 if err != nil { 434 s.log.Printf("get out conn fail,%s", err) 435 return 436 } 437 438 s.log.Printf("use proxy %v : %s", useProxy, serverConn.Target()) 439 440 inAddr := (*inConn).RemoteAddr().String() 441 //outRemoteAddr := outConn.RemoteAddr().String() 442 //inLocalAddr := (*inConn).LocalAddr().String() 443 444 if s.cfg.RateLimitBytes > 0 { 445 outConn = iolimiter.NewReaderConn(outConn, s.cfg.RateLimitBytes) 446 } 447 448 utils.IoBind(*inConn, outConn, func(err interface{}) { 449 s.log.Printf("conn %s - %s released", inAddr, serverConn.Target()) 450 s.userConns.Remove(inAddr) 451 if len(*s.cfg.Parent) > 0 { 452 s.lb.DecreaseConns(lbAddr) 453 } 454 }, s.log) 455 if c, ok := s.userConns.Get(inAddr); ok { 456 (*c.(*net.Conn)).Close() 457 s.userConns.Remove(inAddr) 458 } 459 s.userConns.Set(inAddr, inConn) 460 if len(*s.cfg.Parent) > 0 { 461 s.lb.IncreasConns(lbAddr) 462 } 463 s.log.Printf("conn %s - %s connected", inAddr, serverConn.Target()) 464 } 465 func (s *Socks) GetParentConn(parentAddress string, serverConn *socks.ServerConn) (outConn net.Conn, err interface{}) { 466 switch *s.cfg.ParentType { 467 case "kcp", "tls", "tcp": 468 if *s.cfg.ParentType == "tls" { 469 var _conn tls.Conn 470 _conn, err = utils.TlsConnectHost(parentAddress, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes) 471 if err == nil { 472 outConn = net.Conn(&_conn) 473 } 474 } else if *s.cfg.ParentType == "kcp" { 475 outConn, err = utils.ConnectKCPHost(parentAddress, s.cfg.KCP) 476 } else { 477 outConn, err = utils.ConnectHost(parentAddress, *s.cfg.Timeout) 478 } 479 if err != nil { 480 err = fmt.Errorf("connect fail,%s", err) 481 return 482 } 483 if *s.cfg.ParentCompress { 484 outConn = utils.NewCompConn(outConn) 485 } 486 if *s.cfg.ParentKey != "" { 487 outConn = conncrypt.New(outConn, &conncrypt.Config{ 488 Password: *s.cfg.ParentKey, 489 }) 490 } 491 case "ssh": 492 maxTryCount := 1 493 tryCount := 0 494 RETRY: 495 if tryCount >= maxTryCount || s.isStop { 496 return 497 } 498 wait := make(chan bool, 1) 499 go func() { 500 defer func() { 501 if err == nil { 502 err = recover() 503 } 504 wait <- true 505 }() 506 outConn, err = s.sshClient.Dial("tcp", serverConn.Target()) 507 }() 508 select { 509 case <-wait: 510 case <-time.After(time.Millisecond * time.Duration(*s.cfg.Timeout) * 2): 511 err = fmt.Errorf("ssh dial %s timeout", serverConn.Target()) 512 s.sshClient.Close() 513 } 514 if err != nil { 515 s.log.Printf("connect ssh fail, ERR: %s, retrying...", err) 516 e := s.ConnectSSH(parentAddress) 517 if e == nil { 518 tryCount++ 519 time.Sleep(time.Second * 3) 520 goto RETRY 521 } else { 522 err = e 523 } 524 } 525 } 526 527 return 528 } 529 func (s *Socks) ConnectSSH(lbAddr string) (err error) { 530 select { 531 case s.lockChn <- true: 532 default: 533 err = fmt.Errorf("can not connect at same time") 534 return 535 } 536 config := ssh.ClientConfig{ 537 Timeout: time.Duration(*s.cfg.Timeout) * time.Millisecond, 538 User: *s.cfg.SSHUser, 539 Auth: []ssh.AuthMethod{s.cfg.SSHAuthMethod}, 540 HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error { 541 return nil 542 }, 543 } 544 if s.sshClient != nil { 545 s.sshClient.Close() 546 } 547 s.sshClient, err = ssh.Dial("tcp", s.Resolve(lbAddr), &config) 548 <-s.lockChn 549 return 550 } 551 func (s *Socks) InitBasicAuth() (err error) { 552 if *s.cfg.DNSAddress != "" { 553 s.basicAuth = utils.NewBasicAuth(&(*s).domainResolver, s.log) 554 } else { 555 s.basicAuth = utils.NewBasicAuth(nil, s.log) 556 } 557 if *s.cfg.AuthURL != "" { 558 s.basicAuth.SetAuthURL(*s.cfg.AuthURL, *s.cfg.AuthURLOkCode, *s.cfg.AuthURLTimeout, *s.cfg.AuthURLRetry) 559 s.log.Printf("auth from %s", *s.cfg.AuthURL) 560 } 561 if *s.cfg.AuthFile != "" { 562 var n = 0 563 n, err = s.basicAuth.AddFromFile(*s.cfg.AuthFile) 564 if err != nil { 565 err = fmt.Errorf("auth-file ERR:%s", err) 566 return 567 } 568 s.log.Printf("auth data added from file %d , total:%d", n, s.basicAuth.Total()) 569 } 570 if len(*s.cfg.Auth) > 0 { 571 n := s.basicAuth.Add(*s.cfg.Auth) 572 s.log.Printf("auth data added %d, total:%d", n, s.basicAuth.Total()) 573 } 574 return 575 } 576 func (s *Socks) InitLB() { 577 configs := lb.BackendsConfig{} 578 for _, addr := range *s.cfg.Parent { 579 _addrInfo := strings.Split(addr, "@") 580 _addr := _addrInfo[0] 581 weight := 1 582 if len(_addrInfo) == 2 { 583 weight, _ = strconv.Atoi(_addrInfo[1]) 584 } 585 configs = append(configs, &lb.BackendConfig{ 586 Address: _addr, 587 Weight: weight, 588 ActiveAfter: 1, 589 InactiveAfter: 2, 590 Timeout: time.Duration(*s.cfg.LoadBalanceTimeout) * time.Millisecond, 591 RetryTime: time.Duration(*s.cfg.LoadBalanceRetryTime) * time.Millisecond, 592 }) 593 } 594 LB := lb.NewGroup(utils.LBMethod(*s.cfg.LoadBalanceMethod), configs, &s.domainResolver, s.log, *s.cfg.Debug) 595 s.lb = &LB 596 } 597 func (s *Socks) IsBasicAuth() bool { 598 return *s.cfg.AuthFile != "" || len(*s.cfg.Auth) > 0 || *s.cfg.AuthURL != "" 599 } 600 func (s *Socks) IsDeadLoop(inLocalAddr string, host string) bool { 601 inIP, inPort, err := net.SplitHostPort(inLocalAddr) 602 if err != nil { 603 return false 604 } 605 outDomain, outPort, err := net.SplitHostPort(host) 606 if err != nil { 607 return false 608 } 609 if inPort == outPort { 610 var outIPs []net.IP 611 if *s.cfg.DNSAddress != "" { 612 outIPs = []net.IP{net.ParseIP(s.Resolve(outDomain))} 613 } else { 614 outIPs, err = utils.LookupIP(outDomain) 615 } 616 if err == nil { 617 for _, ip := range outIPs { 618 if ip.String() == inIP { 619 return true 620 } 621 } 622 } 623 interfaceIPs, err := utils.GetAllInterfaceAddr() 624 for _, ip := range *s.cfg.LocalIPS { 625 interfaceIPs = append(interfaceIPs, net.ParseIP(ip).To4()) 626 } 627 if err == nil { 628 for _, localIP := range interfaceIPs { 629 for _, outIP := range outIPs { 630 if localIP.Equal(outIP) { 631 return true 632 } 633 } 634 } 635 } 636 } 637 return false 638 } 639 func (s *Socks) Resolve(address string) string { 640 if *s.cfg.DNSAddress == "" { 641 return address 642 } 643 ip, err := s.domainResolver.Resolve(address) 644 if err != nil { 645 s.log.Printf("dns error %s , ERR:%s", address, err) 646 return address 647 } 648 return ip 649 } 650 func (s *Socks) GetDirectConn(address string, localAddr string) (conn net.Conn, err error) { 651 if !*s.cfg.BindListen { 652 return utils.ConnectHost(address, *s.cfg.Timeout) 653 } 654 ip, _, _ := net.SplitHostPort(localAddr) 655 if utils.IsInternalIP(ip, false) { 656 return utils.ConnectHost(address, *s.cfg.Timeout) 657 } 658 local, _ := net.ResolveTCPAddr("tcp", ip+":0") 659 d := net.Dialer{ 660 Timeout: time.Millisecond * time.Duration(*s.cfg.Timeout), 661 LocalAddr: local, 662 } 663 conn, err = d.Dial("tcp", address) 664 return 665 } 666 func (s *Socks) HandshakeSocksParent(outconn *net.Conn, network, dstAddr string, auth socks.Auth, fromSS bool) (client *socks.ClientConn, err error) { 667 if *s.cfg.ParentAuth != "" { 668 a := strings.Split(*s.cfg.ParentAuth, ":") 669 if len(a) != 2 { 670 err = fmt.Errorf("parent auth data format error") 671 return 672 } 673 client = socks.NewClientConn(outconn, network, dstAddr, time.Millisecond*time.Duration(*s.cfg.Timeout), &socks.Auth{User: a[0], Password: a[1]}, nil) 674 } else { 675 if !fromSS && !s.IsBasicAuth() && auth.Password != "" && auth.User != "" { 676 client = socks.NewClientConn(outconn, network, dstAddr, time.Millisecond*time.Duration(*s.cfg.Timeout), &auth, nil) 677 } else { 678 client = socks.NewClientConn(outconn, network, dstAddr, time.Millisecond*time.Duration(*s.cfg.Timeout), nil, nil) 679 } 680 } 681 err = client.Handshake() 682 return 683 }