service.go 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  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. "net"
  18. "net/http"
  19. "time"
  20. "github.com/fatedier/frp/assets"
  21. "github.com/fatedier/frp/models/config"
  22. "github.com/fatedier/frp/models/msg"
  23. "github.com/fatedier/frp/utils/log"
  24. frpNet "github.com/fatedier/frp/utils/net"
  25. "github.com/fatedier/frp/utils/util"
  26. "github.com/fatedier/frp/utils/version"
  27. "github.com/fatedier/frp/utils/vhost"
  28. "github.com/xtaci/smux"
  29. )
  30. const (
  31. connReadTimeout time.Duration = 10 * time.Second
  32. )
  33. var ServerService *Service
  34. // Server service.
  35. type Service struct {
  36. // Accept connections from client.
  37. listener frpNet.Listener
  38. // Accept connections using kcp.
  39. kcpListener frpNet.Listener
  40. // For https proxies, route requests to different clients by hostname and other infomation.
  41. VhostHttpsMuxer *vhost.HttpsMuxer
  42. httpReverseProxy *vhost.HttpReverseProxy
  43. // Manage all controllers.
  44. ctlManager *ControlManager
  45. // Manage all proxies.
  46. pxyManager *ProxyManager
  47. // Manage all visitor listeners.
  48. visitorManager *VisitorManager
  49. // Manage all tcp ports.
  50. tcpPortManager *PortManager
  51. // Manage all udp ports.
  52. udpPortManager *PortManager
  53. // Controller for nat hole connections.
  54. natHoleController *NatHoleController
  55. }
  56. func NewService() (svr *Service, err error) {
  57. cfg := config.ServerCommonCfg
  58. svr = &Service{
  59. ctlManager: NewControlManager(),
  60. pxyManager: NewProxyManager(),
  61. visitorManager: NewVisitorManager(),
  62. tcpPortManager: NewPortManager("tcp", cfg.ProxyBindAddr, cfg.PrivilegeAllowPorts),
  63. udpPortManager: NewPortManager("udp", cfg.ProxyBindAddr, cfg.PrivilegeAllowPorts),
  64. }
  65. // Init assets.
  66. err = assets.Load(cfg.AssetsDir)
  67. if err != nil {
  68. err = fmt.Errorf("Load assets error: %v", err)
  69. return
  70. }
  71. // Listen for accepting connections from client.
  72. svr.listener, err = frpNet.ListenTcp(cfg.BindAddr, cfg.BindPort)
  73. if err != nil {
  74. err = fmt.Errorf("Create server listener error, %v", err)
  75. return
  76. }
  77. log.Info("frps tcp listen on %s:%d", cfg.BindAddr, cfg.BindPort)
  78. // Listen for accepting connections from client using kcp protocol.
  79. if cfg.KcpBindPort > 0 {
  80. svr.kcpListener, err = frpNet.ListenKcp(cfg.BindAddr, cfg.KcpBindPort)
  81. if err != nil {
  82. err = fmt.Errorf("Listen on kcp address udp [%s:%d] error: %v", cfg.BindAddr, cfg.KcpBindPort, err)
  83. return
  84. }
  85. log.Info("frps kcp listen on udp %s:%d", cfg.BindAddr, cfg.KcpBindPort)
  86. }
  87. // Create http vhost muxer.
  88. if cfg.VhostHttpPort > 0 {
  89. rp := vhost.NewHttpReverseProxy()
  90. svr.httpReverseProxy = rp
  91. address := fmt.Sprintf("%s:%d", cfg.ProxyBindAddr, cfg.VhostHttpPort)
  92. server := &http.Server{
  93. Addr: address,
  94. Handler: rp,
  95. }
  96. var l net.Listener
  97. l, err = net.Listen("tcp", address)
  98. if err != nil {
  99. err = fmt.Errorf("Create vhost http listener error, %v", err)
  100. return
  101. }
  102. go server.Serve(l)
  103. log.Info("http service listen on %s:%d", cfg.ProxyBindAddr, cfg.VhostHttpPort)
  104. }
  105. // Create https vhost muxer.
  106. if cfg.VhostHttpsPort > 0 {
  107. var l frpNet.Listener
  108. l, err = frpNet.ListenTcp(cfg.ProxyBindAddr, cfg.VhostHttpsPort)
  109. if err != nil {
  110. err = fmt.Errorf("Create vhost https listener error, %v", err)
  111. return
  112. }
  113. svr.VhostHttpsMuxer, err = vhost.NewHttpsMuxer(l, 30*time.Second)
  114. if err != nil {
  115. err = fmt.Errorf("Create vhost httpsMuxer error, %v", err)
  116. return
  117. }
  118. log.Info("https service listen on %s:%d", cfg.ProxyBindAddr, cfg.VhostHttpsPort)
  119. }
  120. // Create nat hole controller.
  121. if cfg.BindUdpPort > 0 {
  122. var nc *NatHoleController
  123. addr := fmt.Sprintf("%s:%d", cfg.BindAddr, cfg.BindUdpPort)
  124. nc, err = NewNatHoleController(addr)
  125. if err != nil {
  126. err = fmt.Errorf("Create nat hole controller error, %v", err)
  127. return
  128. }
  129. svr.natHoleController = nc
  130. log.Info("nat hole udp service listen on %s:%d", cfg.BindAddr, cfg.BindUdpPort)
  131. }
  132. // Create dashboard web server.
  133. if cfg.DashboardPort > 0 {
  134. err = RunDashboardServer(cfg.DashboardAddr, cfg.DashboardPort)
  135. if err != nil {
  136. err = fmt.Errorf("Create dashboard web server error, %v", err)
  137. return
  138. }
  139. log.Info("Dashboard listen on %s:%d", cfg.DashboardAddr, cfg.DashboardPort)
  140. }
  141. return
  142. }
  143. func (svr *Service) Run() {
  144. if svr.natHoleController != nil {
  145. go svr.natHoleController.Run()
  146. }
  147. if config.ServerCommonCfg.KcpBindPort > 0 {
  148. go svr.HandleListener(svr.kcpListener)
  149. }
  150. svr.HandleListener(svr.listener)
  151. }
  152. func (svr *Service) HandleListener(l frpNet.Listener) {
  153. // Listen for incoming connections from client.
  154. for {
  155. c, err := l.Accept()
  156. if err != nil {
  157. log.Warn("Listener for incoming connections from client closed")
  158. return
  159. }
  160. // Start a new goroutine for dealing connections.
  161. go func(frpConn frpNet.Conn) {
  162. dealFn := func(conn frpNet.Conn) {
  163. var rawMsg msg.Message
  164. conn.SetReadDeadline(time.Now().Add(connReadTimeout))
  165. if rawMsg, err = msg.ReadMsg(conn); err != nil {
  166. log.Trace("Failed to read message: %v", err)
  167. conn.Close()
  168. return
  169. }
  170. conn.SetReadDeadline(time.Time{})
  171. switch m := rawMsg.(type) {
  172. case *msg.Login:
  173. err = svr.RegisterControl(conn, m)
  174. // If login failed, send error message there.
  175. // Otherwise send success message in control's work goroutine.
  176. if err != nil {
  177. conn.Warn("%v", err)
  178. msg.WriteMsg(conn, &msg.LoginResp{
  179. Version: version.Full(),
  180. Error: err.Error(),
  181. })
  182. conn.Close()
  183. }
  184. case *msg.NewWorkConn:
  185. svr.RegisterWorkConn(conn, m)
  186. case *msg.NewVisitorConn:
  187. if err = svr.RegisterVisitorConn(conn, m); err != nil {
  188. conn.Warn("%v", err)
  189. msg.WriteMsg(conn, &msg.NewVisitorConnResp{
  190. ProxyName: m.ProxyName,
  191. Error: err.Error(),
  192. })
  193. conn.Close()
  194. } else {
  195. msg.WriteMsg(conn, &msg.NewVisitorConnResp{
  196. ProxyName: m.ProxyName,
  197. Error: "",
  198. })
  199. }
  200. default:
  201. log.Warn("Error message type for the new connection [%s]", conn.RemoteAddr().String())
  202. conn.Close()
  203. }
  204. }
  205. if config.ServerCommonCfg.TcpMux {
  206. session, err := smux.Server(frpConn, nil)
  207. if err != nil {
  208. log.Warn("Failed to create mux connection: %v", err)
  209. frpConn.Close()
  210. return
  211. }
  212. for {
  213. stream, err := session.AcceptStream()
  214. if err != nil {
  215. log.Warn("Accept new mux stream error: %v", err)
  216. session.Close()
  217. return
  218. }
  219. wrapConn := frpNet.WrapConn(stream)
  220. go dealFn(wrapConn)
  221. }
  222. } else {
  223. dealFn(frpConn)
  224. }
  225. }(c)
  226. }
  227. }
  228. func (svr *Service) RegisterControl(ctlConn frpNet.Conn, loginMsg *msg.Login) (err error) {
  229. ctlConn.Info("client login info: ip [%s] version [%s] hostname [%s] os [%s] arch [%s]",
  230. ctlConn.RemoteAddr().String(), loginMsg.Version, loginMsg.Hostname, loginMsg.Os, loginMsg.Arch)
  231. // Check client version.
  232. if ok, msg := version.Compat(loginMsg.Version); !ok {
  233. err = fmt.Errorf("%s", msg)
  234. return
  235. }
  236. // Check auth.
  237. nowTime := time.Now().Unix()
  238. if config.ServerCommonCfg.AuthTimeout != 0 && nowTime-loginMsg.Timestamp > config.ServerCommonCfg.AuthTimeout {
  239. err = fmt.Errorf("authorization timeout")
  240. return
  241. }
  242. if util.GetAuthKey(config.ServerCommonCfg.PrivilegeToken, loginMsg.Timestamp) != loginMsg.PrivilegeKey {
  243. err = fmt.Errorf("authorization failed")
  244. return
  245. }
  246. // If client's RunId is empty, it's a new client, we just create a new controller.
  247. // Otherwise, we check if there is one controller has the same run id. If so, we release previous controller and start new one.
  248. if loginMsg.RunId == "" {
  249. loginMsg.RunId, err = util.RandId()
  250. if err != nil {
  251. return
  252. }
  253. }
  254. ctl := NewControl(svr, ctlConn, loginMsg)
  255. if oldCtl := svr.ctlManager.Add(loginMsg.RunId, ctl); oldCtl != nil {
  256. oldCtl.allShutdown.WaitDone()
  257. }
  258. ctlConn.AddLogPrefix(loginMsg.RunId)
  259. ctl.Start()
  260. // for statistics
  261. StatsNewClient()
  262. return
  263. }
  264. // RegisterWorkConn register a new work connection to control and proxies need it.
  265. func (svr *Service) RegisterWorkConn(workConn frpNet.Conn, newMsg *msg.NewWorkConn) {
  266. ctl, exist := svr.ctlManager.GetById(newMsg.RunId)
  267. if !exist {
  268. workConn.Warn("No client control found for run id [%s]", newMsg.RunId)
  269. return
  270. }
  271. ctl.RegisterWorkConn(workConn)
  272. return
  273. }
  274. func (svr *Service) RegisterVisitorConn(visitorConn frpNet.Conn, newMsg *msg.NewVisitorConn) error {
  275. return svr.visitorManager.NewConn(newMsg.ProxyName, visitorConn, newMsg.Timestamp, newMsg.SignKey,
  276. newMsg.UseEncryption, newMsg.UseCompression)
  277. }
  278. func (svr *Service) RegisterProxy(name string, pxy Proxy) error {
  279. return svr.pxyManager.Add(name, pxy)
  280. }
  281. func (svr *Service) DelProxy(name string) {
  282. svr.pxyManager.Del(name)
  283. }