tcp.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package proxy
  2. import (
  3. "net"
  4. "runtime/debug"
  5. "strconv"
  6. )
  7. var _ TCP = (*tcp)(nil)
  8. type TCPArgs struct {
  9. Local string //监听地址
  10. Parent string //被代理地址
  11. Timeout int //拨号超时(毫秒)
  12. PoolSize int //代理池数
  13. CheckParentInterval int //检查被代理连接间隔(秒)
  14. OutCallback func() bool //回调 //是否允许代理
  15. }
  16. type TCP interface {
  17. Start() (err error)
  18. Close()
  19. cleanOutPool()
  20. callback(inConn net.Conn)
  21. outToTCP(inConn *net.Conn) (err error)
  22. initOutConnPool()
  23. }
  24. type tcp struct {
  25. inConn *net.Conn
  26. outPool OutPool
  27. listen ServerChannel
  28. cfg TCPArgs
  29. }
  30. func (s *tcp) Start() (err error) {
  31. s.initOutConnPool()
  32. host, port, _ := net.SplitHostPort(s.cfg.Local)
  33. p, _ := strconv.Atoi(port)
  34. s.listen = NewServerChannel(host, p)
  35. err = s.listen.ListenTCP(s.callback)
  36. if err != nil {
  37. return
  38. }
  39. return
  40. }
  41. func (s *tcp) Close() {
  42. if s.inConn != nil {
  43. CloseConn(s.inConn)
  44. }
  45. s.cleanOutPool()
  46. _ = s.listen.CloseListen()
  47. }
  48. func (s *tcp) cleanOutPool() {
  49. if s.outPool.Pool != nil {
  50. s.outPool.Pool.ReleaseAll()
  51. }
  52. }
  53. func (s *tcp) callback(inConn net.Conn) {
  54. defer func() {
  55. if err := recover(); err != nil {
  56. logger.Sugar().Infof("conn handler crashed with err : %s \nstack: %s", err, string(debug.Stack()))
  57. }
  58. }()
  59. if s.cfg.OutCallback != nil {
  60. if !s.cfg.OutCallback() {
  61. CloseConn(&inConn)
  62. return
  63. }
  64. }
  65. err := s.outToTCP(&inConn)
  66. if err != nil {
  67. CloseConn(&inConn)
  68. }
  69. s.inConn = &inConn
  70. }
  71. func (s *tcp) outToTCP(inConn *net.Conn) (err error) {
  72. var outConn net.Conn
  73. var _outConn any
  74. _outConn, err = s.outPool.Pool.Get()
  75. if err == nil {
  76. outConn = _outConn.(net.Conn)
  77. }
  78. if err != nil {
  79. CloseConn(inConn)
  80. return
  81. }
  82. inAddr := (*inConn).RemoteAddr().String()
  83. inLocalAddr := (*inConn).LocalAddr().String()
  84. outAddr := outConn.RemoteAddr().String()
  85. outLocalAddr := outConn.LocalAddr().String()
  86. IoBind(*inConn, outConn, func(isSrcErr bool, err error) {
  87. logger.Sugar().Infof("conn %s - %s - %s -%s released", inAddr, inLocalAddr, outLocalAddr, outAddr)
  88. CloseConn(inConn)
  89. CloseConn(&outConn)
  90. }, func(n int, d bool) {}, 0)
  91. logger.Sugar().Infof("conn %s - %s - %s -%s connected", inAddr, inLocalAddr, outLocalAddr, outAddr)
  92. return
  93. }
  94. func (s *tcp) initOutConnPool() {
  95. s.outPool = NewOutPool(s.cfg.CheckParentInterval, s.cfg.Parent, s.cfg.Timeout, s.cfg.PoolSize, s.cfg.PoolSize*2)
  96. }