1
0

manager.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // Copyright 2019 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 plugin
  15. import (
  16. "context"
  17. "errors"
  18. "fmt"
  19. "github.com/fatedier/frp/utils/util"
  20. "github.com/fatedier/frp/utils/xlog"
  21. )
  22. type Manager struct {
  23. loginPlugins []Plugin
  24. newProxyPlugins []Plugin
  25. pingPlugins []Plugin
  26. newWorkConnPlugins []Plugin
  27. }
  28. func NewManager() *Manager {
  29. return &Manager{
  30. loginPlugins: make([]Plugin, 0),
  31. newProxyPlugins: make([]Plugin, 0),
  32. pingPlugins: make([]Plugin, 0),
  33. newWorkConnPlugins: make([]Plugin, 0),
  34. }
  35. }
  36. func (m *Manager) Register(p Plugin) {
  37. if p.IsSupport(OpLogin) {
  38. m.loginPlugins = append(m.loginPlugins, p)
  39. }
  40. if p.IsSupport(OpNewProxy) {
  41. m.newProxyPlugins = append(m.newProxyPlugins, p)
  42. }
  43. if p.IsSupport(OpPing) {
  44. m.pingPlugins = append(m.pingPlugins, p)
  45. }
  46. if p.IsSupport(OpNewWorkConn) {
  47. m.pingPlugins = append(m.pingPlugins, p)
  48. }
  49. }
  50. func (m *Manager) Login(content *LoginContent) (*LoginContent, error) {
  51. if len(m.loginPlugins) == 0 {
  52. return content, nil
  53. }
  54. var (
  55. res = &Response{
  56. Reject: false,
  57. Unchange: true,
  58. }
  59. retContent interface{}
  60. err error
  61. )
  62. reqid, _ := util.RandId()
  63. xl := xlog.New().AppendPrefix("reqid: " + reqid)
  64. ctx := xlog.NewContext(context.Background(), xl)
  65. ctx = NewReqidContext(ctx, reqid)
  66. for _, p := range m.loginPlugins {
  67. res, retContent, err = p.Handle(ctx, OpLogin, *content)
  68. if err != nil {
  69. xl.Warn("send Login request to plugin [%s] error: %v", p.Name(), err)
  70. return nil, errors.New("send Login request to plugin error")
  71. }
  72. if res.Reject {
  73. return nil, fmt.Errorf("%s", res.RejectReason)
  74. }
  75. if !res.Unchange {
  76. content = retContent.(*LoginContent)
  77. }
  78. }
  79. return content, nil
  80. }
  81. func (m *Manager) NewProxy(content *NewProxyContent) (*NewProxyContent, error) {
  82. if len(m.newProxyPlugins) == 0 {
  83. return content, nil
  84. }
  85. var (
  86. res = &Response{
  87. Reject: false,
  88. Unchange: true,
  89. }
  90. retContent interface{}
  91. err error
  92. )
  93. reqid, _ := util.RandId()
  94. xl := xlog.New().AppendPrefix("reqid: " + reqid)
  95. ctx := xlog.NewContext(context.Background(), xl)
  96. ctx = NewReqidContext(ctx, reqid)
  97. for _, p := range m.newProxyPlugins {
  98. res, retContent, err = p.Handle(ctx, OpNewProxy, *content)
  99. if err != nil {
  100. xl.Warn("send NewProxy request to plugin [%s] error: %v", p.Name(), err)
  101. return nil, errors.New("send NewProxy request to plugin error")
  102. }
  103. if res.Reject {
  104. return nil, fmt.Errorf("%s", res.RejectReason)
  105. }
  106. if !res.Unchange {
  107. content = retContent.(*NewProxyContent)
  108. }
  109. }
  110. return content, nil
  111. }
  112. func (m *Manager) Ping(content *PingContent) (*PingContent, error) {
  113. if len(m.pingPlugins) == 0 {
  114. return content, nil
  115. }
  116. var (
  117. res = &Response{
  118. Reject: false,
  119. Unchange: true,
  120. }
  121. retContent interface{}
  122. err error
  123. )
  124. reqid, _ := util.RandId()
  125. xl := xlog.New().AppendPrefix("reqid: " + reqid)
  126. ctx := xlog.NewContext(context.Background(), xl)
  127. ctx = NewReqidContext(ctx, reqid)
  128. for _, p := range m.pingPlugins {
  129. res, retContent, err = p.Handle(ctx, OpPing, *content)
  130. if err != nil {
  131. xl.Warn("send Ping request to plugin [%s] error: %v", p.Name(), err)
  132. return nil, errors.New("send Ping request to plugin error")
  133. }
  134. if res.Reject {
  135. return nil, fmt.Errorf("%s", res.RejectReason)
  136. }
  137. if !res.Unchange {
  138. content = retContent.(*PingContent)
  139. }
  140. }
  141. return content, nil
  142. }
  143. func (m *Manager) NewWorkConn(content *NewWorkConnContent) (*NewWorkConnContent, error) {
  144. if len(m.newWorkConnPlugins) == 0 {
  145. return content, nil
  146. }
  147. var (
  148. res = &Response{
  149. Reject: false,
  150. Unchange: true,
  151. }
  152. retContent interface{}
  153. err error
  154. )
  155. reqid, _ := util.RandId()
  156. xl := xlog.New().AppendPrefix("reqid: " + reqid)
  157. ctx := xlog.NewContext(context.Background(), xl)
  158. ctx = NewReqidContext(ctx, reqid)
  159. for _, p := range m.pingPlugins {
  160. res, retContent, err = p.Handle(ctx, OpPing, *content)
  161. if err != nil {
  162. xl.Warn("send NewWorkConn request to plugin [%s] error: %v", p.Name(), err)
  163. return nil, errors.New("send NewWorkConn request to plugin error")
  164. }
  165. if res.Reject {
  166. return nil, fmt.Errorf("%s", res.RejectReason)
  167. }
  168. if !res.Unchange {
  169. content = retContent.(*NewWorkConnContent)
  170. }
  171. }
  172. return content, nil
  173. }