tcp.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package proxy
  2. import (
  3. "errors"
  4. "github.com/cnlh/nps/bridge"
  5. "github.com/cnlh/nps/lib/common"
  6. "github.com/cnlh/nps/lib/conn"
  7. "github.com/cnlh/nps/lib/file"
  8. "github.com/cnlh/nps/server/connection"
  9. "github.com/cnlh/nps/vender/github.com/astaxie/beego"
  10. "github.com/cnlh/nps/vender/github.com/astaxie/beego/logs"
  11. "net"
  12. "net/http"
  13. "path/filepath"
  14. "strings"
  15. )
  16. type TunnelModeServer struct {
  17. BaseServer
  18. process process
  19. listener *net.TCPListener
  20. }
  21. //tcp|http|host
  22. func NewTunnelModeServer(process process, bridge *bridge.Bridge, task *file.Tunnel) *TunnelModeServer {
  23. s := new(TunnelModeServer)
  24. s.bridge = bridge
  25. s.process = process
  26. s.task = task
  27. return s
  28. }
  29. //开始
  30. func (s *TunnelModeServer) Start() error {
  31. var err error
  32. s.listener, err = net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP("0.0.0.0"), s.task.Port, ""})
  33. if err != nil {
  34. return err
  35. }
  36. for {
  37. c, err := s.listener.AcceptTCP()
  38. if err != nil {
  39. if strings.Contains(err.Error(), "use of closed network connection") {
  40. break
  41. }
  42. logs.Info(err)
  43. continue
  44. }
  45. if err := s.checkFlow(); err != nil {
  46. logs.Warn("client id %d task id %d error %s", s.task.Client.Id, s.task.Id, err.Error())
  47. c.Close()
  48. }
  49. if s.task.Client.GetConn() {
  50. logs.Trace("New tcp connection,local port %d,client %d,remote address %s", s.task.Port, s.task.Client.Id, c.RemoteAddr())
  51. go s.process(conn.NewConn(c), s)
  52. } else {
  53. logs.Info("Connections exceed the current client %d limit", s.task.Client.Id)
  54. c.Close()
  55. }
  56. }
  57. return nil
  58. }
  59. //close
  60. func (s *TunnelModeServer) Close() error {
  61. return s.listener.Close()
  62. }
  63. //web管理方式
  64. type WebServer struct {
  65. BaseServer
  66. }
  67. //开始
  68. func (s *WebServer) Start() error {
  69. p, _ := beego.AppConfig.Int("web_port")
  70. if p == 0 {
  71. stop := make(chan struct{})
  72. <-stop
  73. }
  74. //if !common.TestTcpPort(p) {
  75. // // logs.Error("Web management port %d is occupied", p)
  76. // // os.Exit(0)
  77. // //}
  78. beego.BConfig.WebConfig.Session.SessionOn = true
  79. beego.SetStaticPath("/static", filepath.Join(common.GetRunPath(), "web", "static"))
  80. beego.SetViewsPath(filepath.Join(common.GetRunPath(), "web", "views"))
  81. if l, err := connection.GetWebManagerListener(); err == nil {
  82. beego.InitBeforeHTTPRun()
  83. http.Serve(l, beego.BeeApp.Handlers)
  84. } else {
  85. logs.Error(err)
  86. }
  87. return errors.New("Web management startup failure")
  88. }
  89. func (s *WebServer) Close() error {
  90. return nil
  91. }
  92. //new
  93. func NewWebServer(bridge *bridge.Bridge) *WebServer {
  94. s := new(WebServer)
  95. s.bridge = bridge
  96. return s
  97. }
  98. type process func(c *conn.Conn, s *TunnelModeServer) error
  99. //tcp隧道模式
  100. func ProcessTunnel(c *conn.Conn, s *TunnelModeServer) error {
  101. targetAddr, err := s.task.GetRandomTarget()
  102. if err != nil {
  103. c.Close()
  104. logs.Warn("tcp port %d ,client id %d,task id %d connect error %s", s.task.Port, s.task.Client.Id, s.task.Id, err.Error())
  105. return err
  106. }
  107. return s.DealClient(c, targetAddr, nil, common.CONN_TCP)
  108. }
  109. //http代理模式
  110. func ProcessHttp(c *conn.Conn, s *TunnelModeServer) error {
  111. _, addr, rb, err, r := c.GetHost()
  112. if err != nil {
  113. c.Close()
  114. logs.Info(err)
  115. return err
  116. }
  117. if r.Method == "CONNECT" {
  118. c.Write([]byte("HTTP/1.1 200 Connection Established\r\n"))
  119. rb = nil
  120. }
  121. if err := s.auth(r, c, s.task.Client.Cnf.U, s.task.Client.Cnf.P); err != nil {
  122. return err
  123. }
  124. return s.DealClient(c, addr, rb, common.CONN_TCP)
  125. }