mirror of
https://github.com/fatedier/frp.git
synced 2025-02-02 07:54:23 +00:00
server/proxy: simplify the code (#3488)
This commit is contained in:
parent
9ba6a06470
commit
e1cef053be
@ -130,6 +130,7 @@ func (c *Controller) ListenClient(name string, sk string, allowUsers []string) c
|
|||||||
}
|
}
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
|
// TODO(fatedier): return error if name already exists
|
||||||
c.clientCfgs[name] = cfg
|
c.clientCfgs[name] = cfg
|
||||||
return cfg.sidCh
|
return cfg.sidCh
|
||||||
}
|
}
|
||||||
|
@ -17,10 +17,10 @@ package proxy
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
libio "github.com/fatedier/golib/io"
|
libio "github.com/fatedier/golib/io"
|
||||||
"golang.org/x/time/rate"
|
|
||||||
|
|
||||||
"github.com/fatedier/frp/pkg/config"
|
"github.com/fatedier/frp/pkg/config"
|
||||||
"github.com/fatedier/frp/pkg/util/limit"
|
"github.com/fatedier/frp/pkg/util/limit"
|
||||||
@ -30,6 +30,10 @@ import (
|
|||||||
"github.com/fatedier/frp/server/metrics"
|
"github.com/fatedier/frp/server/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterProxyFactory(reflect.TypeOf(&config.HTTPProxyConf{}), NewHTTPProxy)
|
||||||
|
}
|
||||||
|
|
||||||
type HTTPProxy struct {
|
type HTTPProxy struct {
|
||||||
*BaseProxy
|
*BaseProxy
|
||||||
cfg *config.HTTPProxyConf
|
cfg *config.HTTPProxyConf
|
||||||
@ -37,6 +41,17 @@ type HTTPProxy struct {
|
|||||||
closeFuncs []func()
|
closeFuncs []func()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewHTTPProxy(baseProxy *BaseProxy, cfg config.ProxyConf) Proxy {
|
||||||
|
unwrapped, ok := cfg.(*config.HTTPProxyConf)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &HTTPProxy{
|
||||||
|
BaseProxy: baseProxy,
|
||||||
|
cfg: unwrapped,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (pxy *HTTPProxy) Run() (remoteAddr string, err error) {
|
func (pxy *HTTPProxy) Run() (remoteAddr string, err error) {
|
||||||
xl := pxy.xl
|
xl := pxy.xl
|
||||||
routeConfig := vhost.RouteConfig{
|
routeConfig := vhost.RouteConfig{
|
||||||
@ -137,10 +152,6 @@ func (pxy *HTTPProxy) GetConf() config.ProxyConf {
|
|||||||
return pxy.cfg
|
return pxy.cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pxy *HTTPProxy) GetLimiter() *rate.Limiter {
|
|
||||||
return pxy.limiter
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pxy *HTTPProxy) GetRealConn(remoteAddr string) (workConn net.Conn, err error) {
|
func (pxy *HTTPProxy) GetRealConn(remoteAddr string) (workConn net.Conn, err error) {
|
||||||
xl := pxy.xl
|
xl := pxy.xl
|
||||||
rAddr, errRet := net.ResolveTCPAddr("tcp", remoteAddr)
|
rAddr, errRet := net.ResolveTCPAddr("tcp", remoteAddr)
|
||||||
|
@ -15,20 +15,34 @@
|
|||||||
package proxy
|
package proxy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"golang.org/x/time/rate"
|
|
||||||
|
|
||||||
"github.com/fatedier/frp/pkg/config"
|
"github.com/fatedier/frp/pkg/config"
|
||||||
"github.com/fatedier/frp/pkg/util/util"
|
"github.com/fatedier/frp/pkg/util/util"
|
||||||
"github.com/fatedier/frp/pkg/util/vhost"
|
"github.com/fatedier/frp/pkg/util/vhost"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterProxyFactory(reflect.TypeOf(&config.HTTPSProxyConf{}), NewHTTPSProxy)
|
||||||
|
}
|
||||||
|
|
||||||
type HTTPSProxy struct {
|
type HTTPSProxy struct {
|
||||||
*BaseProxy
|
*BaseProxy
|
||||||
cfg *config.HTTPSProxyConf
|
cfg *config.HTTPSProxyConf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewHTTPSProxy(baseProxy *BaseProxy, cfg config.ProxyConf) Proxy {
|
||||||
|
unwrapped, ok := cfg.(*config.HTTPSProxyConf)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &HTTPSProxy{
|
||||||
|
BaseProxy: baseProxy,
|
||||||
|
cfg: unwrapped,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (pxy *HTTPSProxy) Run() (remoteAddr string, err error) {
|
func (pxy *HTTPSProxy) Run() (remoteAddr string, err error) {
|
||||||
xl := pxy.xl
|
xl := pxy.xl
|
||||||
routeConfig := &vhost.RouteConfig{}
|
routeConfig := &vhost.RouteConfig{}
|
||||||
@ -67,7 +81,7 @@ func (pxy *HTTPSProxy) Run() (remoteAddr string, err error) {
|
|||||||
addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, pxy.serverCfg.VhostHTTPSPort))
|
addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, pxy.serverCfg.VhostHTTPSPort))
|
||||||
}
|
}
|
||||||
|
|
||||||
pxy.startListenHandler(pxy, HandleUserTCPConnection)
|
pxy.startCommonTCPListenersHandler()
|
||||||
remoteAddr = strings.Join(addrs, ",")
|
remoteAddr = strings.Join(addrs, ",")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -76,10 +90,6 @@ func (pxy *HTTPSProxy) GetConf() config.ProxyConf {
|
|||||||
return pxy.cfg
|
return pxy.cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pxy *HTTPSProxy) GetLimiter() *rate.Limiter {
|
|
||||||
return pxy.limiter
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pxy *HTTPSProxy) Close() {
|
func (pxy *HTTPSProxy) Close() {
|
||||||
pxy.BaseProxy.Close()
|
pxy.BaseProxy.Close()
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -36,6 +37,12 @@ import (
|
|||||||
"github.com/fatedier/frp/server/metrics"
|
"github.com/fatedier/frp/server/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var proxyFactoryRegistry = map[reflect.Type]func(*BaseProxy, config.ProxyConf) Proxy{}
|
||||||
|
|
||||||
|
func RegisterProxyFactory(proxyConfType reflect.Type, factory func(*BaseProxy, config.ProxyConf) Proxy) {
|
||||||
|
proxyFactoryRegistry[proxyConfType] = factory
|
||||||
|
}
|
||||||
|
|
||||||
type GetWorkConnFn func() (net.Conn, error)
|
type GetWorkConnFn func() (net.Conn, error)
|
||||||
|
|
||||||
type Proxy interface {
|
type Proxy interface {
|
||||||
@ -63,6 +70,7 @@ type BaseProxy struct {
|
|||||||
limiter *rate.Limiter
|
limiter *rate.Limiter
|
||||||
userInfo plugin.UserInfo
|
userInfo plugin.UserInfo
|
||||||
loginMsg *msg.Login
|
loginMsg *msg.Login
|
||||||
|
pxyConf config.ProxyConf
|
||||||
|
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
xl *xlog.Logger
|
xl *xlog.Logger
|
||||||
@ -93,6 +101,10 @@ func (pxy *BaseProxy) GetLoginMsg() *msg.Login {
|
|||||||
return pxy.loginMsg
|
return pxy.loginMsg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pxy *BaseProxy) GetLimiter() *rate.Limiter {
|
||||||
|
return pxy.limiter
|
||||||
|
}
|
||||||
|
|
||||||
func (pxy *BaseProxy) Close() {
|
func (pxy *BaseProxy) Close() {
|
||||||
xl := xlog.FromContextSafe(pxy.ctx)
|
xl := xlog.FromContextSafe(pxy.ctx)
|
||||||
xl.Info("proxy closing")
|
xl.Info("proxy closing")
|
||||||
@ -155,10 +167,8 @@ func (pxy *BaseProxy) GetWorkConnFromPool(src, dst net.Addr) (workConn net.Conn,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// startListenHandler start a goroutine handler for each listener.
|
// startCommonTCPListenersHandler start a goroutine handler for each listener.
|
||||||
// p: p will just be passed to handler(Proxy, utilnet.Conn).
|
func (pxy *BaseProxy) startCommonTCPListenersHandler() {
|
||||||
// handler: each proxy type can set different handler function to deal with connections accepted from listeners.
|
|
||||||
func (pxy *BaseProxy) startListenHandler(p Proxy, handler func(Proxy, net.Conn, config.ServerCommonConf)) {
|
|
||||||
xl := xlog.FromContextSafe(pxy.ctx)
|
xl := xlog.FromContextSafe(pxy.ctx)
|
||||||
for _, listener := range pxy.listeners {
|
for _, listener := range pxy.listeners {
|
||||||
go func(l net.Listener) {
|
go func(l net.Listener) {
|
||||||
@ -187,12 +197,72 @@ func (pxy *BaseProxy) startListenHandler(p Proxy, handler func(Proxy, net.Conn,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
xl.Info("get a user connection [%s]", c.RemoteAddr().String())
|
xl.Info("get a user connection [%s]", c.RemoteAddr().String())
|
||||||
go handler(p, c, pxy.serverCfg)
|
go pxy.handleUserTCPConnection(c)
|
||||||
}
|
}
|
||||||
}(listener)
|
}(listener)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandleUserTCPConnection is used for incoming user TCP connections.
|
||||||
|
func (pxy *BaseProxy) handleUserTCPConnection(userConn net.Conn) {
|
||||||
|
xl := xlog.FromContextSafe(pxy.Context())
|
||||||
|
defer userConn.Close()
|
||||||
|
|
||||||
|
serverCfg := pxy.serverCfg
|
||||||
|
cfg := pxy.pxyConf.GetBaseConfig()
|
||||||
|
// server plugin hook
|
||||||
|
rc := pxy.GetResourceController()
|
||||||
|
content := &plugin.NewUserConnContent{
|
||||||
|
User: pxy.GetUserInfo(),
|
||||||
|
ProxyName: pxy.GetName(),
|
||||||
|
ProxyType: cfg.ProxyType,
|
||||||
|
RemoteAddr: userConn.RemoteAddr().String(),
|
||||||
|
}
|
||||||
|
_, err := rc.PluginManager.NewUserConn(content)
|
||||||
|
if err != nil {
|
||||||
|
xl.Warn("the user conn [%s] was rejected, err:%v", content.RemoteAddr, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// try all connections from the pool
|
||||||
|
workConn, err := pxy.GetWorkConnFromPool(userConn.RemoteAddr(), userConn.LocalAddr())
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer workConn.Close()
|
||||||
|
|
||||||
|
var local io.ReadWriteCloser = workConn
|
||||||
|
xl.Trace("handler user tcp connection, use_encryption: %t, use_compression: %t", cfg.UseEncryption, cfg.UseCompression)
|
||||||
|
if cfg.UseEncryption {
|
||||||
|
local, err = libio.WithEncryption(local, []byte(serverCfg.Token))
|
||||||
|
if err != nil {
|
||||||
|
xl.Error("create encryption stream error: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if cfg.UseCompression {
|
||||||
|
local = libio.WithCompression(local)
|
||||||
|
}
|
||||||
|
|
||||||
|
if pxy.GetLimiter() != nil {
|
||||||
|
local = libio.WrapReadWriteCloser(limit.NewReader(local, pxy.GetLimiter()), limit.NewWriter(local, pxy.GetLimiter()), func() error {
|
||||||
|
return local.Close()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
xl.Debug("join connections, workConn(l[%s] r[%s]) userConn(l[%s] r[%s])", workConn.LocalAddr().String(),
|
||||||
|
workConn.RemoteAddr().String(), userConn.LocalAddr().String(), userConn.RemoteAddr().String())
|
||||||
|
|
||||||
|
name := pxy.GetName()
|
||||||
|
proxyType := cfg.ProxyType
|
||||||
|
metrics.Server.OpenConnection(name, proxyType)
|
||||||
|
inCount, outCount, _ := libio.Join(local, userConn)
|
||||||
|
metrics.Server.CloseConnection(name, proxyType)
|
||||||
|
metrics.Server.AddTrafficIn(name, proxyType, inCount)
|
||||||
|
metrics.Server.AddTrafficOut(name, proxyType, outCount)
|
||||||
|
xl.Debug("join connections closed")
|
||||||
|
}
|
||||||
|
|
||||||
func NewProxy(ctx context.Context, userInfo plugin.UserInfo, rc *controller.ResourceController, poolCount int,
|
func NewProxy(ctx context.Context, userInfo plugin.UserInfo, rc *controller.ResourceController, poolCount int,
|
||||||
getWorkConnFn GetWorkConnFn, pxyConf config.ProxyConf, serverCfg config.ServerCommonConf, loginMsg *msg.Login,
|
getWorkConnFn GetWorkConnFn, pxyConf config.ProxyConf, serverCfg config.ServerCommonConf, loginMsg *msg.Login,
|
||||||
) (pxy Proxy, err error) {
|
) (pxy Proxy, err error) {
|
||||||
@ -216,114 +286,18 @@ func NewProxy(ctx context.Context, userInfo plugin.UserInfo, rc *controller.Reso
|
|||||||
ctx: xlog.NewContext(ctx, xl),
|
ctx: xlog.NewContext(ctx, xl),
|
||||||
userInfo: userInfo,
|
userInfo: userInfo,
|
||||||
loginMsg: loginMsg,
|
loginMsg: loginMsg,
|
||||||
|
pxyConf: pxyConf,
|
||||||
}
|
}
|
||||||
switch cfg := pxyConf.(type) {
|
|
||||||
case *config.TCPProxyConf:
|
factory := proxyFactoryRegistry[reflect.TypeOf(pxyConf)]
|
||||||
basePxy.usedPortsNum = 1
|
if factory == nil {
|
||||||
pxy = &TCPProxy{
|
|
||||||
BaseProxy: &basePxy,
|
|
||||||
cfg: cfg,
|
|
||||||
}
|
|
||||||
case *config.TCPMuxProxyConf:
|
|
||||||
pxy = &TCPMuxProxy{
|
|
||||||
BaseProxy: &basePxy,
|
|
||||||
cfg: cfg,
|
|
||||||
}
|
|
||||||
case *config.HTTPProxyConf:
|
|
||||||
pxy = &HTTPProxy{
|
|
||||||
BaseProxy: &basePxy,
|
|
||||||
cfg: cfg,
|
|
||||||
}
|
|
||||||
case *config.HTTPSProxyConf:
|
|
||||||
pxy = &HTTPSProxy{
|
|
||||||
BaseProxy: &basePxy,
|
|
||||||
cfg: cfg,
|
|
||||||
}
|
|
||||||
case *config.UDPProxyConf:
|
|
||||||
basePxy.usedPortsNum = 1
|
|
||||||
pxy = &UDPProxy{
|
|
||||||
BaseProxy: &basePxy,
|
|
||||||
cfg: cfg,
|
|
||||||
}
|
|
||||||
case *config.STCPProxyConf:
|
|
||||||
pxy = &STCPProxy{
|
|
||||||
BaseProxy: &basePxy,
|
|
||||||
cfg: cfg,
|
|
||||||
}
|
|
||||||
case *config.XTCPProxyConf:
|
|
||||||
pxy = &XTCPProxy{
|
|
||||||
BaseProxy: &basePxy,
|
|
||||||
cfg: cfg,
|
|
||||||
}
|
|
||||||
case *config.SUDPProxyConf:
|
|
||||||
pxy = &SUDPProxy{
|
|
||||||
BaseProxy: &basePxy,
|
|
||||||
cfg: cfg,
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return pxy, fmt.Errorf("proxy type not support")
|
return pxy, fmt.Errorf("proxy type not support")
|
||||||
}
|
}
|
||||||
return
|
pxy = factory(&basePxy, pxyConf)
|
||||||
}
|
if pxy == nil {
|
||||||
|
return nil, fmt.Errorf("proxy not created")
|
||||||
// HandleUserTCPConnection is used for incoming user TCP connections.
|
|
||||||
// It can be used for tcp, http, https type.
|
|
||||||
func HandleUserTCPConnection(pxy Proxy, userConn net.Conn, serverCfg config.ServerCommonConf) {
|
|
||||||
xl := xlog.FromContextSafe(pxy.Context())
|
|
||||||
defer userConn.Close()
|
|
||||||
|
|
||||||
// server plugin hook
|
|
||||||
rc := pxy.GetResourceController()
|
|
||||||
content := &plugin.NewUserConnContent{
|
|
||||||
User: pxy.GetUserInfo(),
|
|
||||||
ProxyName: pxy.GetName(),
|
|
||||||
ProxyType: pxy.GetConf().GetBaseConfig().ProxyType,
|
|
||||||
RemoteAddr: userConn.RemoteAddr().String(),
|
|
||||||
}
|
}
|
||||||
_, err := rc.PluginManager.NewUserConn(content)
|
return pxy, nil
|
||||||
if err != nil {
|
|
||||||
xl.Warn("the user conn [%s] was rejected, err:%v", content.RemoteAddr, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// try all connections from the pool
|
|
||||||
workConn, err := pxy.GetWorkConnFromPool(userConn.RemoteAddr(), userConn.LocalAddr())
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer workConn.Close()
|
|
||||||
|
|
||||||
var local io.ReadWriteCloser = workConn
|
|
||||||
cfg := pxy.GetConf().GetBaseConfig()
|
|
||||||
xl.Trace("handler user tcp connection, use_encryption: %t, use_compression: %t", cfg.UseEncryption, cfg.UseCompression)
|
|
||||||
if cfg.UseEncryption {
|
|
||||||
local, err = libio.WithEncryption(local, []byte(serverCfg.Token))
|
|
||||||
if err != nil {
|
|
||||||
xl.Error("create encryption stream error: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if cfg.UseCompression {
|
|
||||||
local = libio.WithCompression(local)
|
|
||||||
}
|
|
||||||
|
|
||||||
if pxy.GetLimiter() != nil {
|
|
||||||
local = libio.WrapReadWriteCloser(limit.NewReader(local, pxy.GetLimiter()), limit.NewWriter(local, pxy.GetLimiter()), func() error {
|
|
||||||
return local.Close()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
xl.Debug("join connections, workConn(l[%s] r[%s]) userConn(l[%s] r[%s])", workConn.LocalAddr().String(),
|
|
||||||
workConn.RemoteAddr().String(), userConn.LocalAddr().String(), userConn.RemoteAddr().String())
|
|
||||||
|
|
||||||
name := pxy.GetName()
|
|
||||||
proxyType := pxy.GetConf().GetBaseConfig().ProxyType
|
|
||||||
metrics.Server.OpenConnection(name, proxyType)
|
|
||||||
inCount, outCount, _ := libio.Join(local, userConn)
|
|
||||||
metrics.Server.CloseConnection(name, proxyType)
|
|
||||||
metrics.Server.AddTrafficIn(name, proxyType, inCount)
|
|
||||||
metrics.Server.AddTrafficOut(name, proxyType, outCount)
|
|
||||||
xl.Debug("join connections closed")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Manager struct {
|
type Manager struct {
|
||||||
|
@ -15,16 +15,31 @@
|
|||||||
package proxy
|
package proxy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"golang.org/x/time/rate"
|
"reflect"
|
||||||
|
|
||||||
"github.com/fatedier/frp/pkg/config"
|
"github.com/fatedier/frp/pkg/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterProxyFactory(reflect.TypeOf(&config.STCPProxyConf{}), NewSTCPProxy)
|
||||||
|
}
|
||||||
|
|
||||||
type STCPProxy struct {
|
type STCPProxy struct {
|
||||||
*BaseProxy
|
*BaseProxy
|
||||||
cfg *config.STCPProxyConf
|
cfg *config.STCPProxyConf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewSTCPProxy(baseProxy *BaseProxy, cfg config.ProxyConf) Proxy {
|
||||||
|
unwrapped, ok := cfg.(*config.STCPProxyConf)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &STCPProxy{
|
||||||
|
BaseProxy: baseProxy,
|
||||||
|
cfg: unwrapped,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (pxy *STCPProxy) Run() (remoteAddr string, err error) {
|
func (pxy *STCPProxy) Run() (remoteAddr string, err error) {
|
||||||
xl := pxy.xl
|
xl := pxy.xl
|
||||||
allowUsers := pxy.cfg.AllowUsers
|
allowUsers := pxy.cfg.AllowUsers
|
||||||
@ -40,7 +55,7 @@ func (pxy *STCPProxy) Run() (remoteAddr string, err error) {
|
|||||||
pxy.listeners = append(pxy.listeners, listener)
|
pxy.listeners = append(pxy.listeners, listener)
|
||||||
xl.Info("stcp proxy custom listen success")
|
xl.Info("stcp proxy custom listen success")
|
||||||
|
|
||||||
pxy.startListenHandler(pxy, HandleUserTCPConnection)
|
pxy.startCommonTCPListenersHandler()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,10 +63,6 @@ func (pxy *STCPProxy) GetConf() config.ProxyConf {
|
|||||||
return pxy.cfg
|
return pxy.cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pxy *STCPProxy) GetLimiter() *rate.Limiter {
|
|
||||||
return pxy.limiter
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pxy *STCPProxy) Close() {
|
func (pxy *STCPProxy) Close() {
|
||||||
pxy.BaseProxy.Close()
|
pxy.BaseProxy.Close()
|
||||||
pxy.rc.VisitorManager.CloseListener(pxy.GetName())
|
pxy.rc.VisitorManager.CloseListener(pxy.GetName())
|
||||||
|
@ -15,16 +15,31 @@
|
|||||||
package proxy
|
package proxy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"golang.org/x/time/rate"
|
"reflect"
|
||||||
|
|
||||||
"github.com/fatedier/frp/pkg/config"
|
"github.com/fatedier/frp/pkg/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterProxyFactory(reflect.TypeOf(&config.SUDPProxyConf{}), NewSUDPProxy)
|
||||||
|
}
|
||||||
|
|
||||||
type SUDPProxy struct {
|
type SUDPProxy struct {
|
||||||
*BaseProxy
|
*BaseProxy
|
||||||
cfg *config.SUDPProxyConf
|
cfg *config.SUDPProxyConf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewSUDPProxy(baseProxy *BaseProxy, cfg config.ProxyConf) Proxy {
|
||||||
|
unwrapped, ok := cfg.(*config.SUDPProxyConf)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &SUDPProxy{
|
||||||
|
BaseProxy: baseProxy,
|
||||||
|
cfg: unwrapped,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (pxy *SUDPProxy) Run() (remoteAddr string, err error) {
|
func (pxy *SUDPProxy) Run() (remoteAddr string, err error) {
|
||||||
xl := pxy.xl
|
xl := pxy.xl
|
||||||
allowUsers := pxy.cfg.AllowUsers
|
allowUsers := pxy.cfg.AllowUsers
|
||||||
@ -40,7 +55,7 @@ func (pxy *SUDPProxy) Run() (remoteAddr string, err error) {
|
|||||||
pxy.listeners = append(pxy.listeners, listener)
|
pxy.listeners = append(pxy.listeners, listener)
|
||||||
xl.Info("sudp proxy custom listen success")
|
xl.Info("sudp proxy custom listen success")
|
||||||
|
|
||||||
pxy.startListenHandler(pxy, HandleUserTCPConnection)
|
pxy.startCommonTCPListenersHandler()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,10 +63,6 @@ func (pxy *SUDPProxy) GetConf() config.ProxyConf {
|
|||||||
return pxy.cfg
|
return pxy.cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pxy *SUDPProxy) GetLimiter() *rate.Limiter {
|
|
||||||
return pxy.limiter
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pxy *SUDPProxy) Close() {
|
func (pxy *SUDPProxy) Close() {
|
||||||
pxy.BaseProxy.Close()
|
pxy.BaseProxy.Close()
|
||||||
pxy.rc.VisitorManager.CloseListener(pxy.GetName())
|
pxy.rc.VisitorManager.CloseListener(pxy.GetName())
|
||||||
|
@ -17,24 +17,39 @@ package proxy
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"golang.org/x/time/rate"
|
|
||||||
|
|
||||||
"github.com/fatedier/frp/pkg/config"
|
"github.com/fatedier/frp/pkg/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterProxyFactory(reflect.TypeOf(&config.TCPProxyConf{}), NewTCPProxy)
|
||||||
|
}
|
||||||
|
|
||||||
type TCPProxy struct {
|
type TCPProxy struct {
|
||||||
*BaseProxy
|
*BaseProxy
|
||||||
cfg *config.TCPProxyConf
|
cfg *config.TCPProxyConf
|
||||||
|
|
||||||
realPort int
|
realBindPort int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTCPProxy(baseProxy *BaseProxy, cfg config.ProxyConf) Proxy {
|
||||||
|
unwrapped, ok := cfg.(*config.TCPProxyConf)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
baseProxy.usedPortsNum = 1
|
||||||
|
return &TCPProxy{
|
||||||
|
BaseProxy: baseProxy,
|
||||||
|
cfg: unwrapped,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pxy *TCPProxy) Run() (remoteAddr string, err error) {
|
func (pxy *TCPProxy) Run() (remoteAddr string, err error) {
|
||||||
xl := pxy.xl
|
xl := pxy.xl
|
||||||
if pxy.cfg.Group != "" {
|
if pxy.cfg.Group != "" {
|
||||||
l, realPort, errRet := pxy.rc.TCPGroupCtl.Listen(pxy.name, pxy.cfg.Group, pxy.cfg.GroupKey, pxy.serverCfg.ProxyBindAddr, pxy.cfg.RemotePort)
|
l, realBindPort, errRet := pxy.rc.TCPGroupCtl.Listen(pxy.name, pxy.cfg.Group, pxy.cfg.GroupKey, pxy.serverCfg.ProxyBindAddr, pxy.cfg.RemotePort)
|
||||||
if errRet != nil {
|
if errRet != nil {
|
||||||
err = errRet
|
err = errRet
|
||||||
return
|
return
|
||||||
@ -44,20 +59,20 @@ func (pxy *TCPProxy) Run() (remoteAddr string, err error) {
|
|||||||
l.Close()
|
l.Close()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
pxy.realPort = realPort
|
pxy.realBindPort = realBindPort
|
||||||
pxy.listeners = append(pxy.listeners, l)
|
pxy.listeners = append(pxy.listeners, l)
|
||||||
xl.Info("tcp proxy listen port [%d] in group [%s]", pxy.cfg.RemotePort, pxy.cfg.Group)
|
xl.Info("tcp proxy listen port [%d] in group [%s]", pxy.cfg.RemotePort, pxy.cfg.Group)
|
||||||
} else {
|
} else {
|
||||||
pxy.realPort, err = pxy.rc.TCPPortManager.Acquire(pxy.name, pxy.cfg.RemotePort)
|
pxy.realBindPort, err = pxy.rc.TCPPortManager.Acquire(pxy.name, pxy.cfg.RemotePort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pxy.rc.TCPPortManager.Release(pxy.realPort)
|
pxy.rc.TCPPortManager.Release(pxy.realBindPort)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
listener, errRet := net.Listen("tcp", net.JoinHostPort(pxy.serverCfg.ProxyBindAddr, strconv.Itoa(pxy.realPort)))
|
listener, errRet := net.Listen("tcp", net.JoinHostPort(pxy.serverCfg.ProxyBindAddr, strconv.Itoa(pxy.realBindPort)))
|
||||||
if errRet != nil {
|
if errRet != nil {
|
||||||
err = errRet
|
err = errRet
|
||||||
return
|
return
|
||||||
@ -66,9 +81,9 @@ func (pxy *TCPProxy) Run() (remoteAddr string, err error) {
|
|||||||
xl.Info("tcp proxy listen port [%d]", pxy.cfg.RemotePort)
|
xl.Info("tcp proxy listen port [%d]", pxy.cfg.RemotePort)
|
||||||
}
|
}
|
||||||
|
|
||||||
pxy.cfg.RemotePort = pxy.realPort
|
pxy.cfg.RemotePort = pxy.realBindPort
|
||||||
remoteAddr = fmt.Sprintf(":%d", pxy.realPort)
|
remoteAddr = fmt.Sprintf(":%d", pxy.realBindPort)
|
||||||
pxy.startListenHandler(pxy, HandleUserTCPConnection)
|
pxy.startCommonTCPListenersHandler()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,13 +91,9 @@ func (pxy *TCPProxy) GetConf() config.ProxyConf {
|
|||||||
return pxy.cfg
|
return pxy.cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pxy *TCPProxy) GetLimiter() *rate.Limiter {
|
|
||||||
return pxy.limiter
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pxy *TCPProxy) Close() {
|
func (pxy *TCPProxy) Close() {
|
||||||
pxy.BaseProxy.Close()
|
pxy.BaseProxy.Close()
|
||||||
if pxy.cfg.Group == "" {
|
if pxy.cfg.Group == "" {
|
||||||
pxy.rc.TCPPortManager.Release(pxy.realPort)
|
pxy.rc.TCPPortManager.Release(pxy.realBindPort)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,21 +17,35 @@ package proxy
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"golang.org/x/time/rate"
|
|
||||||
|
|
||||||
"github.com/fatedier/frp/pkg/config"
|
"github.com/fatedier/frp/pkg/config"
|
||||||
"github.com/fatedier/frp/pkg/consts"
|
"github.com/fatedier/frp/pkg/consts"
|
||||||
"github.com/fatedier/frp/pkg/util/util"
|
"github.com/fatedier/frp/pkg/util/util"
|
||||||
"github.com/fatedier/frp/pkg/util/vhost"
|
"github.com/fatedier/frp/pkg/util/vhost"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterProxyFactory(reflect.TypeOf(&config.TCPMuxProxyConf{}), NewTCPMuxProxy)
|
||||||
|
}
|
||||||
|
|
||||||
type TCPMuxProxy struct {
|
type TCPMuxProxy struct {
|
||||||
*BaseProxy
|
*BaseProxy
|
||||||
cfg *config.TCPMuxProxyConf
|
cfg *config.TCPMuxProxyConf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewTCPMuxProxy(baseProxy *BaseProxy, cfg config.ProxyConf) Proxy {
|
||||||
|
unwrapped, ok := cfg.(*config.TCPMuxProxyConf)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &TCPMuxProxy{
|
||||||
|
BaseProxy: baseProxy,
|
||||||
|
cfg: unwrapped,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (pxy *TCPMuxProxy) httpConnectListen(
|
func (pxy *TCPMuxProxy) httpConnectListen(
|
||||||
domain, routeByHTTPUser, httpUser, httpPwd string, addrs []string) ([]string, error,
|
domain, routeByHTTPUser, httpUser, httpPwd string, addrs []string) ([]string, error,
|
||||||
) {
|
) {
|
||||||
@ -78,7 +92,7 @@ func (pxy *TCPMuxProxy) httpConnectRun() (remoteAddr string, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pxy.startListenHandler(pxy, HandleUserTCPConnection)
|
pxy.startCommonTCPListenersHandler()
|
||||||
remoteAddr = strings.Join(addrs, ",")
|
remoteAddr = strings.Join(addrs, ",")
|
||||||
return remoteAddr, err
|
return remoteAddr, err
|
||||||
}
|
}
|
||||||
@ -101,10 +115,6 @@ func (pxy *TCPMuxProxy) GetConf() config.ProxyConf {
|
|||||||
return pxy.cfg
|
return pxy.cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pxy *TCPMuxProxy) GetLimiter() *rate.Limiter {
|
|
||||||
return pxy.limiter
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pxy *TCPMuxProxy) Close() {
|
func (pxy *TCPMuxProxy) Close() {
|
||||||
pxy.BaseProxy.Close()
|
pxy.BaseProxy.Close()
|
||||||
}
|
}
|
||||||
|
@ -19,12 +19,12 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fatedier/golib/errors"
|
"github.com/fatedier/golib/errors"
|
||||||
libio "github.com/fatedier/golib/io"
|
libio "github.com/fatedier/golib/io"
|
||||||
"golang.org/x/time/rate"
|
|
||||||
|
|
||||||
"github.com/fatedier/frp/pkg/config"
|
"github.com/fatedier/frp/pkg/config"
|
||||||
"github.com/fatedier/frp/pkg/msg"
|
"github.com/fatedier/frp/pkg/msg"
|
||||||
@ -34,11 +34,15 @@ import (
|
|||||||
"github.com/fatedier/frp/server/metrics"
|
"github.com/fatedier/frp/server/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterProxyFactory(reflect.TypeOf(&config.UDPProxyConf{}), NewUDPProxy)
|
||||||
|
}
|
||||||
|
|
||||||
type UDPProxy struct {
|
type UDPProxy struct {
|
||||||
*BaseProxy
|
*BaseProxy
|
||||||
cfg *config.UDPProxyConf
|
cfg *config.UDPProxyConf
|
||||||
|
|
||||||
realPort int
|
realBindPort int
|
||||||
|
|
||||||
// udpConn is the listener of udp packages
|
// udpConn is the listener of udp packages
|
||||||
udpConn *net.UDPConn
|
udpConn *net.UDPConn
|
||||||
@ -59,21 +63,33 @@ type UDPProxy struct {
|
|||||||
isClosed bool
|
isClosed bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewUDPProxy(baseProxy *BaseProxy, cfg config.ProxyConf) Proxy {
|
||||||
|
unwrapped, ok := cfg.(*config.UDPProxyConf)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
baseProxy.usedPortsNum = 1
|
||||||
|
return &UDPProxy{
|
||||||
|
BaseProxy: baseProxy,
|
||||||
|
cfg: unwrapped,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (pxy *UDPProxy) Run() (remoteAddr string, err error) {
|
func (pxy *UDPProxy) Run() (remoteAddr string, err error) {
|
||||||
xl := pxy.xl
|
xl := pxy.xl
|
||||||
pxy.realPort, err = pxy.rc.UDPPortManager.Acquire(pxy.name, pxy.cfg.RemotePort)
|
pxy.realBindPort, err = pxy.rc.UDPPortManager.Acquire(pxy.name, pxy.cfg.RemotePort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("acquire port %d error: %v", pxy.cfg.RemotePort, err)
|
return "", fmt.Errorf("acquire port %d error: %v", pxy.cfg.RemotePort, err)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pxy.rc.UDPPortManager.Release(pxy.realPort)
|
pxy.rc.UDPPortManager.Release(pxy.realBindPort)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
remoteAddr = fmt.Sprintf(":%d", pxy.realPort)
|
remoteAddr = fmt.Sprintf(":%d", pxy.realBindPort)
|
||||||
pxy.cfg.RemotePort = pxy.realPort
|
pxy.cfg.RemotePort = pxy.realBindPort
|
||||||
addr, errRet := net.ResolveUDPAddr("udp", net.JoinHostPort(pxy.serverCfg.ProxyBindAddr, strconv.Itoa(pxy.realPort)))
|
addr, errRet := net.ResolveUDPAddr("udp", net.JoinHostPort(pxy.serverCfg.ProxyBindAddr, strconv.Itoa(pxy.realBindPort)))
|
||||||
if errRet != nil {
|
if errRet != nil {
|
||||||
err = errRet
|
err = errRet
|
||||||
return
|
return
|
||||||
@ -233,10 +249,6 @@ func (pxy *UDPProxy) GetConf() config.ProxyConf {
|
|||||||
return pxy.cfg
|
return pxy.cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pxy *UDPProxy) GetLimiter() *rate.Limiter {
|
|
||||||
return pxy.limiter
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pxy *UDPProxy) Close() {
|
func (pxy *UDPProxy) Close() {
|
||||||
pxy.mu.Lock()
|
pxy.mu.Lock()
|
||||||
defer pxy.mu.Unlock()
|
defer pxy.mu.Unlock()
|
||||||
@ -254,5 +266,5 @@ func (pxy *UDPProxy) Close() {
|
|||||||
close(pxy.readCh)
|
close(pxy.readCh)
|
||||||
close(pxy.sendCh)
|
close(pxy.sendCh)
|
||||||
}
|
}
|
||||||
pxy.rc.UDPPortManager.Release(pxy.realPort)
|
pxy.rc.UDPPortManager.Release(pxy.realBindPort)
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,18 @@ package proxy
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
"github.com/fatedier/golib/errors"
|
"github.com/fatedier/golib/errors"
|
||||||
"golang.org/x/time/rate"
|
|
||||||
|
|
||||||
"github.com/fatedier/frp/pkg/config"
|
"github.com/fatedier/frp/pkg/config"
|
||||||
"github.com/fatedier/frp/pkg/msg"
|
"github.com/fatedier/frp/pkg/msg"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterProxyFactory(reflect.TypeOf(&config.XTCPProxyConf{}), NewXTCPProxy)
|
||||||
|
}
|
||||||
|
|
||||||
type XTCPProxy struct {
|
type XTCPProxy struct {
|
||||||
*BaseProxy
|
*BaseProxy
|
||||||
cfg *config.XTCPProxyConf
|
cfg *config.XTCPProxyConf
|
||||||
@ -31,6 +35,17 @@ type XTCPProxy struct {
|
|||||||
closeCh chan struct{}
|
closeCh chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewXTCPProxy(baseProxy *BaseProxy, cfg config.ProxyConf) Proxy {
|
||||||
|
unwrapped, ok := cfg.(*config.XTCPProxyConf)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &XTCPProxy{
|
||||||
|
BaseProxy: baseProxy,
|
||||||
|
cfg: unwrapped,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (pxy *XTCPProxy) Run() (remoteAddr string, err error) {
|
func (pxy *XTCPProxy) Run() (remoteAddr string, err error) {
|
||||||
xl := pxy.xl
|
xl := pxy.xl
|
||||||
|
|
||||||
@ -72,10 +87,6 @@ func (pxy *XTCPProxy) GetConf() config.ProxyConf {
|
|||||||
return pxy.cfg
|
return pxy.cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pxy *XTCPProxy) GetLimiter() *rate.Limiter {
|
|
||||||
return pxy.limiter
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pxy *XTCPProxy) Close() {
|
func (pxy *XTCPProxy) Close() {
|
||||||
pxy.BaseProxy.Close()
|
pxy.BaseProxy.Close()
|
||||||
pxy.rc.NatHoleController.CloseClient(pxy.GetName())
|
pxy.rc.NatHoleController.CloseClient(pxy.GetName())
|
||||||
|
Loading…
Reference in New Issue
Block a user