proxy.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. package server
  2. import (
  3. "fmt"
  4. "io"
  5. "github.com/fatedier/frp/models/config"
  6. "github.com/fatedier/frp/models/msg"
  7. "github.com/fatedier/frp/models/proto/tcp"
  8. "github.com/fatedier/frp/utils/log"
  9. "github.com/fatedier/frp/utils/net"
  10. )
  11. type Proxy interface {
  12. Run() error
  13. GetControl() *Control
  14. GetName() string
  15. GetConf() config.ProxyConf
  16. Close()
  17. log.Logger
  18. }
  19. type BaseProxy struct {
  20. name string
  21. ctl *Control
  22. listeners []net.Listener
  23. log.Logger
  24. }
  25. func (pxy *BaseProxy) GetName() string {
  26. return pxy.name
  27. }
  28. func (pxy *BaseProxy) GetControl() *Control {
  29. return pxy.ctl
  30. }
  31. func (pxy *BaseProxy) Close() {
  32. pxy.Info("proxy closing")
  33. for _, l := range pxy.listeners {
  34. l.Close()
  35. }
  36. }
  37. func NewProxy(ctl *Control, pxyConf config.ProxyConf) (pxy Proxy, err error) {
  38. basePxy := BaseProxy{
  39. name: pxyConf.GetName(),
  40. ctl: ctl,
  41. listeners: make([]net.Listener, 0),
  42. Logger: log.NewPrefixLogger(ctl.runId),
  43. }
  44. switch cfg := pxyConf.(type) {
  45. case *config.TcpProxyConf:
  46. pxy = &TcpProxy{
  47. BaseProxy: basePxy,
  48. cfg: cfg,
  49. }
  50. case *config.HttpProxyConf:
  51. pxy = &HttpProxy{
  52. BaseProxy: basePxy,
  53. cfg: cfg,
  54. }
  55. case *config.HttpsProxyConf:
  56. pxy = &HttpsProxy{
  57. BaseProxy: basePxy,
  58. cfg: cfg,
  59. }
  60. case *config.UdpProxyConf:
  61. pxy = &UdpProxy{
  62. BaseProxy: basePxy,
  63. cfg: cfg,
  64. }
  65. default:
  66. return pxy, fmt.Errorf("proxy type not support")
  67. }
  68. pxy.AddLogPrefix(pxy.GetName())
  69. return
  70. }
  71. type TcpProxy struct {
  72. BaseProxy
  73. cfg *config.TcpProxyConf
  74. }
  75. func (pxy *TcpProxy) Run() error {
  76. listener, err := net.ListenTcp(config.ServerCommonCfg.BindAddr, int64(pxy.cfg.RemotePort))
  77. if err != nil {
  78. return err
  79. }
  80. pxy.listeners = append(pxy.listeners, listener)
  81. go func(l net.Listener) {
  82. for {
  83. // block
  84. // if listener is closed, err returned
  85. c, err := l.Accept()
  86. if err != nil {
  87. pxy.Info("listener is closed")
  88. return
  89. }
  90. pxy.Debug("got one user connection [%s]", c.RemoteAddr().String())
  91. go HandleUserTcpConnection(pxy, c)
  92. }
  93. }(listener)
  94. return nil
  95. }
  96. func (pxy *TcpProxy) GetConf() config.ProxyConf {
  97. return pxy.cfg
  98. }
  99. func (pxy *TcpProxy) Close() {
  100. pxy.BaseProxy.Close()
  101. }
  102. type HttpProxy struct {
  103. BaseProxy
  104. cfg *config.HttpProxyConf
  105. }
  106. func (pxy *HttpProxy) Run() (err error) {
  107. return
  108. }
  109. func (pxy *HttpProxy) GetConf() config.ProxyConf {
  110. return pxy.cfg
  111. }
  112. func (pxy *HttpProxy) Close() {
  113. pxy.BaseProxy.Close()
  114. }
  115. type HttpsProxy struct {
  116. BaseProxy
  117. cfg *config.HttpsProxyConf
  118. }
  119. func (pxy *HttpsProxy) Run() (err error) {
  120. return
  121. }
  122. func (pxy *HttpsProxy) GetConf() config.ProxyConf {
  123. return pxy.cfg
  124. }
  125. func (pxy *HttpsProxy) Close() {
  126. pxy.BaseProxy.Close()
  127. }
  128. type UdpProxy struct {
  129. BaseProxy
  130. cfg *config.UdpProxyConf
  131. }
  132. func (pxy *UdpProxy) Run() (err error) {
  133. return
  134. }
  135. func (pxy *UdpProxy) GetConf() config.ProxyConf {
  136. return pxy.cfg
  137. }
  138. func (pxy *UdpProxy) Close() {
  139. pxy.BaseProxy.Close()
  140. }
  141. // HandleUserTcpConnection is used for incoming tcp user connections.
  142. // It can be used for tcp, http, https type.
  143. func HandleUserTcpConnection(pxy Proxy, userConn net.Conn) {
  144. defer userConn.Close()
  145. ctl := pxy.GetControl()
  146. var (
  147. workConn net.Conn
  148. err error
  149. )
  150. // try all connections from the pool
  151. for i := 0; i < ctl.poolCount+1; i++ {
  152. if workConn, err = ctl.GetWorkConn(); err != nil {
  153. pxy.Warn("failed to get work connection: %v", err)
  154. return
  155. }
  156. defer workConn.Close()
  157. pxy.Info("get one new work connection: %s", workConn.RemoteAddr().String())
  158. workConn.AddLogPrefix(pxy.GetName())
  159. err := msg.WriteMsg(workConn, &msg.StartWorkConn{
  160. ProxyName: pxy.GetName(),
  161. })
  162. if err != nil {
  163. workConn.Warn("failed to send message to work connection from pool: %v, times: %d", err, i)
  164. workConn.Close()
  165. } else {
  166. break
  167. }
  168. }
  169. if err != nil {
  170. pxy.Error("try to get work connection failed in the end")
  171. return
  172. }
  173. var (
  174. local io.ReadWriteCloser
  175. remote io.ReadWriteCloser
  176. )
  177. local = workConn
  178. remote = userConn
  179. cfg := pxy.GetConf().GetBaseInfo()
  180. if cfg.UseEncryption {
  181. local, err = tcp.WithEncryption(local, []byte(config.ServerCommonCfg.PrivilegeToken))
  182. if err != nil {
  183. pxy.Error("create encryption stream error: %v", err)
  184. return
  185. }
  186. }
  187. if cfg.UseCompression {
  188. local = tcp.WithCompression(local)
  189. }
  190. tcp.Join(local, remote)
  191. }