service.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. package server
  2. import (
  3. "fmt"
  4. "time"
  5. "github.com/fatedier/frp/assets"
  6. "github.com/fatedier/frp/models/config"
  7. "github.com/fatedier/frp/models/msg"
  8. "github.com/fatedier/frp/utils/log"
  9. "github.com/fatedier/frp/utils/net"
  10. "github.com/fatedier/frp/utils/util"
  11. "github.com/fatedier/frp/utils/version"
  12. "github.com/fatedier/frp/utils/vhost"
  13. )
  14. // Server service.
  15. type Service struct {
  16. // Accept connections from client.
  17. listener net.Listener
  18. // For http proxies, route requests to different clients by hostname and other infomation.
  19. VhostHttpMuxer *vhost.HttpMuxer
  20. // For https proxies, route requests to different clients by hostname and other infomation.
  21. VhostHttpsMuxer *vhost.HttpsMuxer
  22. // Manage all controllers.
  23. ctlManager *ControlManager
  24. // Manage all proxies.
  25. pxyManager *ProxyManager
  26. }
  27. func NewService() (svr *Service, err error) {
  28. svr = &Service{
  29. ctlManager: NewControlManager(),
  30. pxyManager: NewProxyManager(),
  31. }
  32. // Init assets.
  33. err = assets.Load(config.ServerCommonCfg.AssetsDir)
  34. if err != nil {
  35. err = fmt.Errorf("Load assets error: %v", err)
  36. return
  37. }
  38. // Listen for accepting connections from client.
  39. svr.listener, err = net.ListenTcp(config.ServerCommonCfg.BindAddr, config.ServerCommonCfg.BindPort)
  40. if err != nil {
  41. err = fmt.Errorf("Create server listener error, %v", err)
  42. return
  43. }
  44. // Create http vhost muxer.
  45. if config.ServerCommonCfg.VhostHttpPort != 0 {
  46. var l net.Listener
  47. l, err = net.ListenTcp(config.ServerCommonCfg.BindAddr, config.ServerCommonCfg.VhostHttpPort)
  48. if err != nil {
  49. err = fmt.Errorf("Create vhost http listener error, %v", err)
  50. return
  51. }
  52. svr.VhostHttpMuxer, err = vhost.NewHttpMuxer(l, 30*time.Second)
  53. if err != nil {
  54. err = fmt.Errorf("Create vhost httpMuxer error, %v", err)
  55. return
  56. }
  57. }
  58. // Create https vhost muxer.
  59. if config.ServerCommonCfg.VhostHttpsPort != 0 {
  60. var l net.Listener
  61. l, err = net.ListenTcp(config.ServerCommonCfg.BindAddr, config.ServerCommonCfg.VhostHttpsPort)
  62. if err != nil {
  63. err = fmt.Errorf("Create vhost https listener error, %v", err)
  64. return
  65. }
  66. svr.VhostHttpsMuxer, err = vhost.NewHttpsMuxer(l, 30*time.Second)
  67. if err != nil {
  68. err = fmt.Errorf("Create vhost httpsMuxer error, %v", err)
  69. return
  70. }
  71. }
  72. // Create dashboard web server.
  73. if config.ServerCommonCfg.DashboardPort != 0 {
  74. err = RunDashboardServer(config.ServerCommonCfg.BindAddr, config.ServerCommonCfg.DashboardPort)
  75. if err != nil {
  76. err = fmt.Errorf("Create dashboard web server error, %v", err)
  77. return
  78. }
  79. }
  80. return
  81. }
  82. func (svr *Service) Run() {
  83. // Listen for incoming connections from client.
  84. for {
  85. c, err := svr.listener.Accept()
  86. if err != nil {
  87. log.Warn("Listener for incoming connections from client closed")
  88. return
  89. }
  90. // Start a new goroutine for dealing connections.
  91. go func(frpConn net.Conn) {
  92. var rawMsg msg.Message
  93. if rawMsg, err = msg.ReadMsg(frpConn); err != nil {
  94. log.Warn("Failed to read message: %v", err)
  95. frpConn.Close()
  96. return
  97. }
  98. switch m := rawMsg.(type) {
  99. case *msg.Login:
  100. err = svr.RegisterControl(frpConn, m)
  101. // If login failed, send error message there.
  102. // Otherwise send success message in control's work goroutine.
  103. if err != nil {
  104. frpConn.Warn("%v", err)
  105. msg.WriteMsg(frpConn, &msg.LoginResp{
  106. Version: version.Full(),
  107. Error: err.Error(),
  108. })
  109. frpConn.Close()
  110. }
  111. case *msg.NewWorkConn:
  112. svr.RegisterWorkConn(frpConn, m)
  113. default:
  114. log.Warn("Error message type for the new connection [%s]", frpConn.RemoteAddr().String())
  115. frpConn.Close()
  116. }
  117. }(c)
  118. }
  119. }
  120. func (svr *Service) RegisterControl(ctlConn net.Conn, loginMsg *msg.Login) (err error) {
  121. ctlConn.Info("client login info: ip [%s] version [%s] hostname [%s] os [%s] arch [%s]",
  122. ctlConn.RemoteAddr().String(), loginMsg.Version, loginMsg.Hostname, loginMsg.Os, loginMsg.Arch)
  123. // Check client version.
  124. if ok, msg := version.Compat(loginMsg.Version); !ok {
  125. err = fmt.Errorf("%s", msg)
  126. return
  127. }
  128. // Check auth.
  129. nowTime := time.Now().Unix()
  130. if config.ServerCommonCfg.AuthTimeout != 0 && nowTime-loginMsg.Timestamp > config.ServerCommonCfg.AuthTimeout {
  131. err = fmt.Errorf("authorization timeout")
  132. return
  133. }
  134. if util.GetAuthKey(config.ServerCommonCfg.PrivilegeToken, loginMsg.Timestamp) != loginMsg.PrivilegeKey {
  135. err = fmt.Errorf("authorization failed")
  136. return
  137. }
  138. // If client's RunId is empty, it's a new client, we just create a new controller.
  139. // Otherwise, we check if there is one controller has the same run id. If so, we release previous controller and start new one.
  140. if loginMsg.RunId == "" {
  141. loginMsg.RunId, err = util.RandId()
  142. if err != nil {
  143. return
  144. }
  145. }
  146. ctl := NewControl(svr, ctlConn, loginMsg)
  147. if oldCtl := svr.ctlManager.Add(loginMsg.RunId, ctl); oldCtl != nil {
  148. oldCtl.allShutdown.WaitDown()
  149. }
  150. ctlConn.AddLogPrefix(loginMsg.RunId)
  151. ctl.Start()
  152. return
  153. }
  154. // RegisterWorkConn register a new work connection to control and proxies need it.
  155. func (svr *Service) RegisterWorkConn(workConn net.Conn, newMsg *msg.NewWorkConn) {
  156. ctl, exist := svr.ctlManager.GetById(newMsg.RunId)
  157. if !exist {
  158. workConn.Warn("No client control found for run id [%s]", newMsg.RunId)
  159. return
  160. }
  161. ctl.RegisterWorkConn(workConn)
  162. return
  163. }
  164. func (svr *Service) RegisterProxy(name string, pxy Proxy) error {
  165. err := svr.pxyManager.Add(name, pxy)
  166. return err
  167. }
  168. func (svr *Service) DelProxy(name string) {
  169. svr.pxyManager.Del(name)
  170. }