control.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. package main
  2. import (
  3. "encoding/json"
  4. "io"
  5. "sync"
  6. "time"
  7. "github.com/fatedier/frp/models/client"
  8. "github.com/fatedier/frp/models/consts"
  9. "github.com/fatedier/frp/models/msg"
  10. "github.com/fatedier/frp/utils/conn"
  11. "github.com/fatedier/frp/utils/log"
  12. )
  13. var isHeartBeatContinue bool = true
  14. func ControlProcess(cli *client.ProxyClient, wait *sync.WaitGroup) {
  15. defer wait.Done()
  16. c := loginToServer(cli)
  17. if c == nil {
  18. log.Error("ProxyName [%s], connect to server failed!", cli.Name)
  19. return
  20. }
  21. defer c.Close()
  22. for {
  23. // ignore response content now
  24. _, err := c.ReadLine()
  25. if err == io.EOF {
  26. isHeartBeatContinue = false
  27. log.Debug("ProxyName [%s], server close this control conn", cli.Name)
  28. var sleepTime time.Duration = 1
  29. for {
  30. log.Debug("ProxyName [%s], try to reconnect to server[%s:%d]...", cli.Name, client.ServerAddr, client.ServerPort)
  31. tmpConn := loginToServer(cli)
  32. if tmpConn != nil {
  33. c.Close()
  34. c = tmpConn
  35. break
  36. }
  37. if sleepTime < 60 {
  38. sleepTime++
  39. }
  40. time.Sleep(sleepTime * time.Second)
  41. }
  42. continue
  43. } else if err != nil {
  44. log.Warn("ProxyName [%s], read from server error, %v", cli.Name, err)
  45. continue
  46. }
  47. cli.StartTunnel(client.ServerAddr, client.ServerPort)
  48. }
  49. }
  50. func loginToServer(cli *client.ProxyClient) (connection *conn.Conn) {
  51. c := &conn.Conn{}
  52. connection = nil
  53. for i := 0; i < 1; i++ {
  54. err := c.ConnectServer(client.ServerAddr, client.ServerPort)
  55. if err != nil {
  56. log.Error("ProxyName [%s], connect to server [%s:%d] error, %v", cli.Name, client.ServerAddr, client.ServerPort, err)
  57. break
  58. }
  59. req := &msg.ClientCtlReq{
  60. Type: consts.CtlConn,
  61. ProxyName: cli.Name,
  62. Passwd: cli.Passwd,
  63. }
  64. buf, _ := json.Marshal(req)
  65. err = c.Write(string(buf) + "\n")
  66. if err != nil {
  67. log.Error("ProxyName [%s], write to server error, %v", cli.Name, err)
  68. break
  69. }
  70. res, err := c.ReadLine()
  71. if err != nil {
  72. log.Error("ProxyName [%s], read from server error, %v", cli.Name, err)
  73. break
  74. }
  75. log.Debug("ProxyName [%s], read [%s]", cli.Name, res)
  76. clientCtlRes := &msg.ClientCtlRes{}
  77. if err = json.Unmarshal([]byte(res), &clientCtlRes); err != nil {
  78. log.Error("ProxyName [%s], format server response error, %v", cli.Name, err)
  79. break
  80. }
  81. if clientCtlRes.Code != 0 {
  82. log.Error("ProxyName [%s], start proxy error, %s", cli.Name, clientCtlRes.Msg)
  83. break
  84. }
  85. connection = c
  86. go startHeartBeat(connection)
  87. log.Debug("ProxyName [%s], connect to server[%s:%d] success!", cli.Name, client.ServerAddr, client.ServerPort)
  88. }
  89. if connection == nil {
  90. c.Close()
  91. }
  92. return
  93. }
  94. func startHeartBeat(con *conn.Conn) {
  95. isHeartBeatContinue = true
  96. log.Debug("Start to send heartbeat")
  97. for {
  98. time.Sleep(time.Duration(client.HeartBeatInterval) * time.Second)
  99. if isHeartBeatContinue {
  100. err := con.Write("\n")
  101. if err != nil {
  102. log.Error("Send hearbeat to server failed! Err:%s", err.Error())
  103. }
  104. } else {
  105. break
  106. }
  107. }
  108. }