tcp.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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. "strconv"
  15. "syscall"
  16. )
  17. type TunnelModeServer struct {
  18. BaseServer
  19. process process
  20. listener net.Listener
  21. }
  22. //tcp|http|host
  23. func NewTunnelModeServer(process process, bridge NetBridge, task *file.Tunnel) *TunnelModeServer {
  24. s := new(TunnelModeServer)
  25. s.bridge = bridge
  26. s.process = process
  27. s.task = task
  28. return s
  29. }
  30. //开始
  31. func (s *TunnelModeServer) Start() error {
  32. return conn.NewTcpListenerAndProcess(s.task.ServerIp+":"+strconv.Itoa(s.task.Port), func(c net.Conn) {
  33. if err := s.CheckFlowAndConnNum(s.task.Client); err != nil {
  34. logs.Warn("client id %d, task id %d,error %s, when tcp connection", s.task.Client.Id, s.task.Id, err.Error())
  35. c.Close()
  36. return
  37. }
  38. logs.Trace("new tcp connection,local port %d,client %d,remote address %s", s.task.Port, s.task.Client.Id, c.RemoteAddr())
  39. s.process(conn.NewConn(c), s)
  40. s.task.Client.AddConn()
  41. }, &s.listener)
  42. }
  43. //close
  44. func (s *TunnelModeServer) Close() error {
  45. return s.listener.Close()
  46. }
  47. //web管理方式
  48. type WebServer struct {
  49. BaseServer
  50. }
  51. //开始
  52. func (s *WebServer) Start() error {
  53. p, _ := beego.AppConfig.Int("web_port")
  54. if p == 0 {
  55. stop := make(chan struct{})
  56. <-stop
  57. }
  58. beego.BConfig.WebConfig.Session.SessionOn = true
  59. beego.SetStaticPath("/static", filepath.Join(common.GetRunPath(), "web", "static"))
  60. beego.SetViewsPath(filepath.Join(common.GetRunPath(), "web", "views"))
  61. if l, err := connection.GetWebManagerListener(); err == nil {
  62. beego.InitBeforeHTTPRun()
  63. http.Serve(l, beego.BeeApp.Handlers)
  64. } else {
  65. logs.Error(err)
  66. }
  67. return errors.New("Web management startup failure")
  68. }
  69. func (s *WebServer) Close() error {
  70. return nil
  71. }
  72. //new
  73. func NewWebServer(bridge *bridge.Bridge) *WebServer {
  74. s := new(WebServer)
  75. s.bridge = bridge
  76. return s
  77. }
  78. type process func(c *conn.Conn, s *TunnelModeServer) error
  79. //tcp proxy
  80. func ProcessTunnel(c *conn.Conn, s *TunnelModeServer) error {
  81. targetAddr, err := s.task.Target.GetRandomTarget()
  82. if err != nil {
  83. c.Close()
  84. 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())
  85. return err
  86. }
  87. return s.DealClient(c, s.task.Client, targetAddr, nil, common.CONN_TCP, nil, s.task.Flow, s.task.Target.LocalProxy)
  88. }
  89. //http proxy
  90. func ProcessHttp(c *conn.Conn, s *TunnelModeServer) error {
  91. _, addr, rb, err, r := c.GetHost()
  92. if err != nil {
  93. c.Close()
  94. logs.Info(err)
  95. return err
  96. }
  97. if r.Method == "CONNECT" {
  98. c.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n"))
  99. rb = nil
  100. }
  101. if err := s.auth(r, c, s.task.Client.Cnf.U, s.task.Client.Cnf.P); err != nil {
  102. return err
  103. }
  104. return s.DealClient(c, s.task.Client, addr, rb, common.CONN_TCP, nil, s.task.Flow, s.task.Target.LocalProxy)
  105. }
  106. func HandleTrans(c *conn.Conn, s *TunnelModeServer) error {
  107. if addr, err := getAddress(c.Conn); err != nil {
  108. return err
  109. } else {
  110. return s.DealClient(c, s.task.Client, addr, nil, common.CONN_TCP, nil, s.task.Flow, s.task.Target.LocalProxy)
  111. }
  112. }
  113. const SO_ORIGINAL_DST = 80
  114. func getAddress(conn net.Conn) (string, error) {
  115. sysrawconn, f := conn.(syscall.Conn)
  116. if !f {
  117. return "", nil
  118. }
  119. rawConn, err := sysrawconn.SyscallConn()
  120. if err != nil {
  121. return "", nil
  122. }
  123. var ip string
  124. var port uint16
  125. err = rawConn.Control(func(fd uintptr) {
  126. addr, err := syscall.GetsockoptIPv6Mreq(int(fd), syscall.IPPROTO_IP, SO_ORIGINAL_DST)
  127. if err != nil {
  128. return
  129. }
  130. ip = net.IP(addr.Multiaddr[4:8]).String()
  131. port = uint16(addr.Multiaddr[2])<<8 + uint16(addr.Multiaddr[3])
  132. })
  133. return ip + ":" + strconv.Itoa(int(port)), nil
  134. }