service.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. // Copyright 2017 fatedier, fatedier@gmail.com
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package server
  15. import (
  16. "fmt"
  17. "time"
  18. "github.com/fatedier/frp/assets"
  19. "github.com/fatedier/frp/models/config"
  20. "github.com/fatedier/frp/models/msg"
  21. "github.com/fatedier/frp/utils/log"
  22. frpNet "github.com/fatedier/frp/utils/net"
  23. "github.com/fatedier/frp/utils/util"
  24. "github.com/fatedier/frp/utils/version"
  25. "github.com/fatedier/frp/utils/vhost"
  26. "github.com/xtaci/smux"
  27. )
  28. const (
  29. connReadTimeout time.Duration = 10 * time.Second
  30. )
  31. var ServerService *Service
  32. // Server service.
  33. type Service struct {
  34. // Accept connections from client.
  35. listener frpNet.Listener
  36. // Accept connections using kcp.
  37. kcpListener frpNet.Listener
  38. // For http proxies, route requests to different clients by hostname and other infomation.
  39. VhostHttpMuxer *vhost.HttpMuxer
  40. // For https proxies, route requests to different clients by hostname and other infomation.
  41. VhostHttpsMuxer *vhost.HttpsMuxer
  42. // Manage all controllers.
  43. ctlManager *ControlManager
  44. // Manage all proxies.
  45. pxyManager *ProxyManager
  46. // Manage all vistor listeners.
  47. vistorManager *VistorManager
  48. }
  49. func NewService() (svr *Service, err error) {
  50. svr = &Service{
  51. ctlManager: NewControlManager(),
  52. pxyManager: NewProxyManager(),
  53. vistorManager: NewVistorManager(),
  54. }
  55. // Init assets.
  56. err = assets.Load(config.ServerCommonCfg.AssetsDir)
  57. if err != nil {
  58. err = fmt.Errorf("Load assets error: %v", err)
  59. return
  60. }
  61. // Listen for accepting connections from client.
  62. svr.listener, err = frpNet.ListenTcp(config.ServerCommonCfg.BindAddr, config.ServerCommonCfg.BindPort)
  63. if err != nil {
  64. err = fmt.Errorf("Create server listener error, %v", err)
  65. return
  66. }
  67. log.Info("frps tcp listen on %s:%d", config.ServerCommonCfg.BindAddr, config.ServerCommonCfg.BindPort)
  68. // Listen for accepting connections from client using kcp protocol.
  69. if config.ServerCommonCfg.KcpBindPort > 0 {
  70. svr.kcpListener, err = frpNet.ListenKcp(config.ServerCommonCfg.BindAddr, config.ServerCommonCfg.KcpBindPort)
  71. if err != nil {
  72. err = fmt.Errorf("Listen on kcp address udp [%s:%d] error: %v", config.ServerCommonCfg.BindAddr, config.ServerCommonCfg.KcpBindPort, err)
  73. return
  74. }
  75. log.Info("frps kcp listen on udp %s:%d", config.ServerCommonCfg.BindAddr, config.ServerCommonCfg.BindPort)
  76. }
  77. // Create http vhost muxer.
  78. if config.ServerCommonCfg.VhostHttpPort > 0 {
  79. var l frpNet.Listener
  80. l, err = frpNet.ListenTcp(config.ServerCommonCfg.ProxyBindAddr, config.ServerCommonCfg.VhostHttpPort)
  81. if err != nil {
  82. err = fmt.Errorf("Create vhost http listener error, %v", err)
  83. return
  84. }
  85. svr.VhostHttpMuxer, err = vhost.NewHttpMuxer(l, 30*time.Second)
  86. if err != nil {
  87. err = fmt.Errorf("Create vhost httpMuxer error, %v", err)
  88. return
  89. }
  90. log.Info("http service listen on %s:%d", config.ServerCommonCfg.ProxyBindAddr, config.ServerCommonCfg.VhostHttpPort)
  91. }
  92. // Create https vhost muxer.
  93. if config.ServerCommonCfg.VhostHttpsPort > 0 {
  94. var l frpNet.Listener
  95. l, err = frpNet.ListenTcp(config.ServerCommonCfg.ProxyBindAddr, config.ServerCommonCfg.VhostHttpsPort)
  96. if err != nil {
  97. err = fmt.Errorf("Create vhost https listener error, %v", err)
  98. return
  99. }
  100. svr.VhostHttpsMuxer, err = vhost.NewHttpsMuxer(l, 30*time.Second)
  101. if err != nil {
  102. err = fmt.Errorf("Create vhost httpsMuxer error, %v", err)
  103. return
  104. }
  105. log.Info("https service listen on %s:%d", config.ServerCommonCfg.ProxyBindAddr, config.ServerCommonCfg.VhostHttpsPort)
  106. }
  107. // Create dashboard web server.
  108. if config.ServerCommonCfg.DashboardPort > 0 {
  109. err = RunDashboardServer(config.ServerCommonCfg.BindAddr, config.ServerCommonCfg.DashboardPort)
  110. if err != nil {
  111. err = fmt.Errorf("Create dashboard web server error, %v", err)
  112. return
  113. }
  114. log.Info("Dashboard listen on %s:%d", config.ServerCommonCfg.BindAddr, config.ServerCommonCfg.DashboardPort)
  115. }
  116. return
  117. }
  118. func (svr *Service) Run() {
  119. if config.ServerCommonCfg.KcpBindPort > 0 {
  120. go svr.HandleListener(svr.kcpListener)
  121. }
  122. svr.HandleListener(svr.listener)
  123. }
  124. func (svr *Service) HandleListener(l frpNet.Listener) {
  125. // Listen for incoming connections from client.
  126. for {
  127. c, err := l.Accept()
  128. if err != nil {
  129. log.Warn("Listener for incoming connections from client closed")
  130. return
  131. }
  132. // Start a new goroutine for dealing connections.
  133. go func(frpConn frpNet.Conn) {
  134. dealFn := func(conn frpNet.Conn) {
  135. var rawMsg msg.Message
  136. conn.SetReadDeadline(time.Now().Add(connReadTimeout))
  137. if rawMsg, err = msg.ReadMsg(conn); err != nil {
  138. log.Trace("Failed to read message: %v", err)
  139. conn.Close()
  140. return
  141. }
  142. conn.SetReadDeadline(time.Time{})
  143. switch m := rawMsg.(type) {
  144. case *msg.Login:
  145. err = svr.RegisterControl(conn, m)
  146. // If login failed, send error message there.
  147. // Otherwise send success message in control's work goroutine.
  148. if err != nil {
  149. conn.Warn("%v", err)
  150. msg.WriteMsg(conn, &msg.LoginResp{
  151. Version: version.Full(),
  152. Error: err.Error(),
  153. })
  154. conn.Close()
  155. }
  156. case *msg.NewWorkConn:
  157. svr.RegisterWorkConn(conn, m)
  158. case *msg.NewVistorConn:
  159. if err = svr.RegisterVistorConn(conn, m); err != nil {
  160. conn.Warn("%v", err)
  161. msg.WriteMsg(conn, &msg.NewVistorConnResp{
  162. ProxyName: m.ProxyName,
  163. Error: err.Error(),
  164. })
  165. conn.Close()
  166. } else {
  167. msg.WriteMsg(conn, &msg.NewVistorConnResp{
  168. ProxyName: m.ProxyName,
  169. Error: "",
  170. })
  171. }
  172. default:
  173. log.Warn("Error message type for the new connection [%s]", conn.RemoteAddr().String())
  174. conn.Close()
  175. }
  176. }
  177. if config.ServerCommonCfg.TcpMux {
  178. session, err := smux.Server(frpConn, nil)
  179. if err != nil {
  180. log.Warn("Failed to create mux connection: %v", err)
  181. frpConn.Close()
  182. return
  183. }
  184. for {
  185. stream, err := session.AcceptStream()
  186. if err != nil {
  187. log.Warn("Accept new mux stream error: %v", err)
  188. session.Close()
  189. return
  190. }
  191. wrapConn := frpNet.WrapConn(stream)
  192. go dealFn(wrapConn)
  193. }
  194. } else {
  195. dealFn(frpConn)
  196. }
  197. }(c)
  198. }
  199. }
  200. func (svr *Service) RegisterControl(ctlConn frpNet.Conn, loginMsg *msg.Login) (err error) {
  201. ctlConn.Info("client login info: ip [%s] version [%s] hostname [%s] os [%s] arch [%s]",
  202. ctlConn.RemoteAddr().String(), loginMsg.Version, loginMsg.Hostname, loginMsg.Os, loginMsg.Arch)
  203. // Check client version.
  204. if ok, msg := version.Compat(loginMsg.Version); !ok {
  205. err = fmt.Errorf("%s", msg)
  206. return
  207. }
  208. // Check auth.
  209. nowTime := time.Now().Unix()
  210. if config.ServerCommonCfg.AuthTimeout != 0 && nowTime-loginMsg.Timestamp > config.ServerCommonCfg.AuthTimeout {
  211. err = fmt.Errorf("authorization timeout")
  212. return
  213. }
  214. if util.GetAuthKey(config.ServerCommonCfg.PrivilegeToken, loginMsg.Timestamp) != loginMsg.PrivilegeKey {
  215. err = fmt.Errorf("authorization failed")
  216. return
  217. }
  218. // If client's RunId is empty, it's a new client, we just create a new controller.
  219. // Otherwise, we check if there is one controller has the same run id. If so, we release previous controller and start new one.
  220. if loginMsg.RunId == "" {
  221. loginMsg.RunId, err = util.RandId()
  222. if err != nil {
  223. return
  224. }
  225. }
  226. ctl := NewControl(svr, ctlConn, loginMsg)
  227. if oldCtl := svr.ctlManager.Add(loginMsg.RunId, ctl); oldCtl != nil {
  228. oldCtl.allShutdown.WaitDown()
  229. }
  230. ctlConn.AddLogPrefix(loginMsg.RunId)
  231. ctl.Start()
  232. // for statistics
  233. StatsNewClient()
  234. return
  235. }
  236. // RegisterWorkConn register a new work connection to control and proxies need it.
  237. func (svr *Service) RegisterWorkConn(workConn frpNet.Conn, newMsg *msg.NewWorkConn) {
  238. ctl, exist := svr.ctlManager.GetById(newMsg.RunId)
  239. if !exist {
  240. workConn.Warn("No client control found for run id [%s]", newMsg.RunId)
  241. return
  242. }
  243. ctl.RegisterWorkConn(workConn)
  244. return
  245. }
  246. func (svr *Service) RegisterVistorConn(vistorConn frpNet.Conn, newMsg *msg.NewVistorConn) error {
  247. return svr.vistorManager.NewConn(newMsg.ProxyName, vistorConn, newMsg.Timestamp, newMsg.SignKey,
  248. newMsg.UseEncryption, newMsg.UseCompression)
  249. }
  250. func (svr *Service) RegisterProxy(name string, pxy Proxy) error {
  251. return svr.pxyManager.Add(name, pxy)
  252. }
  253. func (svr *Service) DelProxy(name string) {
  254. svr.pxyManager.Del(name)
  255. }