1
0

proxy_manager.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // Copyright 2023 The frp Authors
  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 proxy
  15. import (
  16. "context"
  17. "fmt"
  18. "net"
  19. "reflect"
  20. "sync"
  21. "github.com/fatedier/frp/client/event"
  22. "github.com/fatedier/frp/pkg/config"
  23. "github.com/fatedier/frp/pkg/msg"
  24. "github.com/fatedier/frp/pkg/transport"
  25. "github.com/fatedier/frp/pkg/util/xlog"
  26. )
  27. type Manager struct {
  28. proxies map[string]*Wrapper
  29. msgTransporter transport.MessageTransporter
  30. closed bool
  31. mu sync.RWMutex
  32. clientCfg config.ClientCommonConf
  33. ctx context.Context
  34. }
  35. func NewManager(
  36. ctx context.Context,
  37. clientCfg config.ClientCommonConf,
  38. msgTransporter transport.MessageTransporter,
  39. ) *Manager {
  40. return &Manager{
  41. proxies: make(map[string]*Wrapper),
  42. msgTransporter: msgTransporter,
  43. closed: false,
  44. clientCfg: clientCfg,
  45. ctx: ctx,
  46. }
  47. }
  48. func (pm *Manager) StartProxy(name string, remoteAddr string, serverRespErr string) error {
  49. pm.mu.RLock()
  50. pxy, ok := pm.proxies[name]
  51. pm.mu.RUnlock()
  52. if !ok {
  53. return fmt.Errorf("proxy [%s] not found", name)
  54. }
  55. err := pxy.SetRunningStatus(remoteAddr, serverRespErr)
  56. if err != nil {
  57. return err
  58. }
  59. return nil
  60. }
  61. func (pm *Manager) Close() {
  62. pm.mu.Lock()
  63. defer pm.mu.Unlock()
  64. for _, pxy := range pm.proxies {
  65. pxy.Stop()
  66. }
  67. pm.proxies = make(map[string]*Wrapper)
  68. }
  69. func (pm *Manager) HandleWorkConn(name string, workConn net.Conn, m *msg.StartWorkConn) {
  70. pm.mu.RLock()
  71. pw, ok := pm.proxies[name]
  72. pm.mu.RUnlock()
  73. if ok {
  74. pw.InWorkConn(workConn, m)
  75. } else {
  76. workConn.Close()
  77. }
  78. }
  79. func (pm *Manager) HandleEvent(payload interface{}) error {
  80. var m msg.Message
  81. switch e := payload.(type) {
  82. case *event.StartProxyPayload:
  83. m = e.NewProxyMsg
  84. case *event.CloseProxyPayload:
  85. m = e.CloseProxyMsg
  86. default:
  87. return event.ErrPayloadType
  88. }
  89. return pm.msgTransporter.Send(m)
  90. }
  91. func (pm *Manager) GetAllProxyStatus() []*WorkingStatus {
  92. ps := make([]*WorkingStatus, 0)
  93. pm.mu.RLock()
  94. defer pm.mu.RUnlock()
  95. for _, pxy := range pm.proxies {
  96. ps = append(ps, pxy.GetStatus())
  97. }
  98. return ps
  99. }
  100. func (pm *Manager) Reload(pxyCfgs map[string]config.ProxyConf) {
  101. xl := xlog.FromContextSafe(pm.ctx)
  102. pm.mu.Lock()
  103. defer pm.mu.Unlock()
  104. delPxyNames := make([]string, 0)
  105. for name, pxy := range pm.proxies {
  106. del := false
  107. cfg, ok := pxyCfgs[name]
  108. if !ok || !reflect.DeepEqual(pxy.Cfg, cfg) {
  109. del = true
  110. }
  111. if del {
  112. delPxyNames = append(delPxyNames, name)
  113. delete(pm.proxies, name)
  114. pxy.Stop()
  115. }
  116. }
  117. if len(delPxyNames) > 0 {
  118. xl.Info("proxy removed: %s", delPxyNames)
  119. }
  120. addPxyNames := make([]string, 0)
  121. for name, cfg := range pxyCfgs {
  122. if _, ok := pm.proxies[name]; !ok {
  123. pxy := NewWrapper(pm.ctx, cfg, pm.clientCfg, pm.HandleEvent, pm.msgTransporter)
  124. pm.proxies[name] = pxy
  125. addPxyNames = append(addPxyNames, name)
  126. pxy.Start()
  127. }
  128. }
  129. if len(addPxyNames) > 0 {
  130. xl.Info("proxy added: %s", addPxyNames)
  131. }
  132. }