Export tcp multiplexing into new proxy type
This commit is contained in:
parent
5f79740354
commit
8e3b6fcc53
@ -72,6 +72,11 @@ func NewProxy(ctx context.Context, pxyConf config.ProxyConf, clientCfg config.Cl
|
|||||||
BaseProxy: &baseProxy,
|
BaseProxy: &baseProxy,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
}
|
}
|
||||||
|
case *config.TcpHttpTunnelProxyConf:
|
||||||
|
pxy = &TcpHttpTunnelProxy{
|
||||||
|
BaseProxy: &baseProxy,
|
||||||
|
cfg: cfg,
|
||||||
|
}
|
||||||
case *config.UdpProxyConf:
|
case *config.UdpProxyConf:
|
||||||
pxy = &UdpProxy{
|
pxy = &UdpProxy{
|
||||||
BaseProxy: &baseProxy,
|
BaseProxy: &baseProxy,
|
||||||
@ -141,6 +146,35 @@ func (pxy *TcpProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
|||||||
conn, []byte(pxy.clientCfg.Token), m)
|
conn, []byte(pxy.clientCfg.Token), m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TCP HTTP Tunnel
|
||||||
|
type TcpHttpTunnelProxy struct {
|
||||||
|
*BaseProxy
|
||||||
|
|
||||||
|
cfg *config.TcpHttpTunnelProxyConf
|
||||||
|
proxyPlugin plugin.Plugin
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pxy *TcpHttpTunnelProxy) Run() (err error) {
|
||||||
|
if pxy.cfg.Plugin != "" {
|
||||||
|
pxy.proxyPlugin, err = plugin.Create(pxy.cfg.Plugin, pxy.cfg.PluginParams)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pxy *TcpHttpTunnelProxy) Close() {
|
||||||
|
if pxy.proxyPlugin != nil {
|
||||||
|
pxy.proxyPlugin.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pxy *TcpHttpTunnelProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||||
|
HandleTcpWorkConnection(pxy.ctx, &pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, pxy.limiter,
|
||||||
|
conn, []byte(pxy.clientCfg.Token), m)
|
||||||
|
}
|
||||||
|
|
||||||
// HTTP
|
// HTTP
|
||||||
type HttpProxy struct {
|
type HttpProxy struct {
|
||||||
*BaseProxy
|
*BaseProxy
|
||||||
|
89
cmd/frpc/sub/tcphttptunnel.go
Normal file
89
cmd/frpc/sub/tcphttptunnel.go
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// Copyright 2018 fatedier, fatedier@gmail.com
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package sub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/fatedier/frp/models/config"
|
||||||
|
"github.com/fatedier/frp/models/consts"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
tcpHttpTunnelCmd.PersistentFlags().StringVarP(&serverAddr, "server_addr", "s", "127.0.0.1:7000", "frp server's address")
|
||||||
|
tcpHttpTunnelCmd.PersistentFlags().StringVarP(&user, "user", "u", "", "user")
|
||||||
|
tcpHttpTunnelCmd.PersistentFlags().StringVarP(&protocol, "protocol", "p", "tcp", "tcp or kcp or websocket")
|
||||||
|
tcpHttpTunnelCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
|
||||||
|
tcpHttpTunnelCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
|
||||||
|
tcpHttpTunnelCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "console or file path")
|
||||||
|
tcpHttpTunnelCmd.PersistentFlags().IntVarP(&logMaxDays, "log_max_days", "", 3, "log file reversed days")
|
||||||
|
tcpHttpTunnelCmd.PersistentFlags().BoolVarP(&disableLogColor, "disable_log_color", "", false, "disable log color in console")
|
||||||
|
|
||||||
|
tcpHttpTunnelCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name")
|
||||||
|
tcpHttpTunnelCmd.PersistentFlags().StringVarP(&localIp, "local_ip", "i", "127.0.0.1", "local ip")
|
||||||
|
tcpHttpTunnelCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port")
|
||||||
|
tcpHttpTunnelCmd.PersistentFlags().StringVarP(&customDomains, "custom_domain", "d", "", "custom domain")
|
||||||
|
tcpHttpTunnelCmd.PersistentFlags().StringVarP(&subDomain, "sd", "", "", "sub domain")
|
||||||
|
tcpHttpTunnelCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption")
|
||||||
|
tcpHttpTunnelCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression")
|
||||||
|
|
||||||
|
rootCmd.AddCommand(tcpHttpTunnelCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
var tcpHttpTunnelCmd = &cobra.Command{
|
||||||
|
Use: "tcphttptunnel",
|
||||||
|
Short: "Run frpc with a single tcphttptunnel proxy",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
clientCfg, err := parseClientCommonCfg(CfgFileTypeCmd, "")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := &config.TcpHttpTunnelProxyConf{}
|
||||||
|
var prefix string
|
||||||
|
if user != "" {
|
||||||
|
prefix = user + "."
|
||||||
|
}
|
||||||
|
cfg.ProxyName = prefix + proxyName
|
||||||
|
cfg.ProxyType = consts.TcpHttpTunnelProxy
|
||||||
|
cfg.LocalIp = localIp
|
||||||
|
cfg.LocalPort = localPort
|
||||||
|
cfg.CustomDomains = strings.Split(customDomains, ",")
|
||||||
|
cfg.SubDomain = subDomain
|
||||||
|
cfg.UseEncryption = useEncryption
|
||||||
|
cfg.UseCompression = useCompression
|
||||||
|
|
||||||
|
err = cfg.CheckForCli()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
proxyConfs := map[string]config.ProxyConf{
|
||||||
|
cfg.ProxyName: cfg,
|
||||||
|
}
|
||||||
|
err = startService(clientCfg, proxyConfs, nil, "")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
@ -34,6 +34,7 @@ var (
|
|||||||
func init() {
|
func init() {
|
||||||
proxyConfTypeMap = make(map[string]reflect.Type)
|
proxyConfTypeMap = make(map[string]reflect.Type)
|
||||||
proxyConfTypeMap[consts.TcpProxy] = reflect.TypeOf(TcpProxyConf{})
|
proxyConfTypeMap[consts.TcpProxy] = reflect.TypeOf(TcpProxyConf{})
|
||||||
|
proxyConfTypeMap[consts.TcpHttpTunnelProxy] = reflect.TypeOf(TcpHttpTunnelProxyConf{})
|
||||||
proxyConfTypeMap[consts.UdpProxy] = reflect.TypeOf(UdpProxyConf{})
|
proxyConfTypeMap[consts.UdpProxy] = reflect.TypeOf(UdpProxyConf{})
|
||||||
proxyConfTypeMap[consts.HttpProxy] = reflect.TypeOf(HttpProxyConf{})
|
proxyConfTypeMap[consts.HttpProxy] = reflect.TypeOf(HttpProxyConf{})
|
||||||
proxyConfTypeMap[consts.HttpsProxy] = reflect.TypeOf(HttpsProxyConf{})
|
proxyConfTypeMap[consts.HttpsProxy] = reflect.TypeOf(HttpsProxyConf{})
|
||||||
@ -530,7 +531,6 @@ func (cfg *HealthCheckConf) checkForCli() error {
|
|||||||
type TcpProxyConf struct {
|
type TcpProxyConf struct {
|
||||||
BaseProxyConf
|
BaseProxyConf
|
||||||
BindInfoConf
|
BindInfoConf
|
||||||
DomainConf
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *TcpProxyConf) Compare(cmp ProxyConf) bool {
|
func (cfg *TcpProxyConf) Compare(cmp ProxyConf) bool {
|
||||||
@ -540,8 +540,7 @@ func (cfg *TcpProxyConf) Compare(cmp ProxyConf) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
|
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
|
||||||
!cfg.BindInfoConf.compare(&cmpConf.BindInfoConf) ||
|
!cfg.BindInfoConf.compare(&cmpConf.BindInfoConf) {
|
||||||
!cfg.DomainConf.compare(&cmpConf.DomainConf) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -550,7 +549,6 @@ func (cfg *TcpProxyConf) Compare(cmp ProxyConf) bool {
|
|||||||
func (cfg *TcpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
func (cfg *TcpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||||
cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
|
cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
|
||||||
cfg.BindInfoConf.UnmarshalFromMsg(pMsg)
|
cfg.BindInfoConf.UnmarshalFromMsg(pMsg)
|
||||||
cfg.DomainConf.UnmarshalFromMsg(pMsg)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *TcpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
func (cfg *TcpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||||
@ -560,16 +558,12 @@ func (cfg *TcpProxyConf) UnmarshalFromIni(prefix string, name string, section in
|
|||||||
if err = cfg.BindInfoConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
if err = cfg.BindInfoConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = cfg.DomainConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *TcpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
func (cfg *TcpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||||
cfg.BaseProxyConf.MarshalToMsg(pMsg)
|
cfg.BaseProxyConf.MarshalToMsg(pMsg)
|
||||||
cfg.BindInfoConf.MarshalToMsg(pMsg)
|
cfg.BindInfoConf.MarshalToMsg(pMsg)
|
||||||
cfg.DomainConf.MarshalToMsg(pMsg)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *TcpProxyConf) CheckForCli() (err error) {
|
func (cfg *TcpProxyConf) CheckForCli() (err error) {
|
||||||
@ -579,9 +573,64 @@ func (cfg *TcpProxyConf) CheckForCli() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *TcpProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
|
func (cfg *TcpProxyConf) CheckForSvr(serverCfg ServerCommonConf) error { return nil }
|
||||||
if (len(cfg.CustomDomains) > 0 || cfg.SubDomain != "") && serverCfg.VhostTcpPort == 0 {
|
|
||||||
return fmt.Errorf("custom domain or subdomain can't be configured on type [tcp] without vhost_http_port")
|
// TCP HTTP Tunnel
|
||||||
|
type TcpHttpTunnelProxyConf struct {
|
||||||
|
BaseProxyConf
|
||||||
|
DomainConf
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *TcpHttpTunnelProxyConf) Compare(cmp ProxyConf) bool {
|
||||||
|
cmpConf, ok := cmp.(*TcpHttpTunnelProxyConf)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
|
||||||
|
!cfg.DomainConf.compare(&cmpConf.DomainConf) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *TcpHttpTunnelProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||||
|
cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
|
||||||
|
cfg.DomainConf.UnmarshalFromMsg(pMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *TcpHttpTunnelProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||||
|
if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = cfg.DomainConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *TcpHttpTunnelProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||||
|
cfg.BaseProxyConf.MarshalToMsg(pMsg)
|
||||||
|
cfg.DomainConf.MarshalToMsg(pMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *TcpHttpTunnelProxyConf) CheckForCli() (err error) {
|
||||||
|
if err = cfg.BaseProxyConf.checkForCli(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = cfg.DomainConf.checkForCli(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *TcpHttpTunnelProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
|
||||||
|
if serverCfg.TcpHttpTunnelPort == 0 {
|
||||||
|
return fmt.Errorf("type [tcphttptunnel] not support when tcp_http_tunnel_port is not set")
|
||||||
|
}
|
||||||
|
if err = cfg.DomainConf.checkForSvr(serverCfg); err != nil {
|
||||||
|
err = fmt.Errorf("proxy [%s] domain conf check error: %v", cfg.ProxyName, err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -57,11 +57,11 @@ type ServerCommonConf struct {
|
|||||||
// requests. By default, this value is 0.
|
// requests. By default, this value is 0.
|
||||||
VhostHttpsPort int `json:"vhost_https_port"`
|
VhostHttpsPort int `json:"vhost_https_port"`
|
||||||
|
|
||||||
// VhostTcpPort specifies the port that the server listens for TCP Vhost
|
// TcpHttpTunnelPort specifies the port that the server listens for TCP Vhost
|
||||||
// requests. If the value is 0, the server will not multiplex TCP requests
|
// requests. If the value is 0, the server will not multiplex TCP requests
|
||||||
// on one single port. If it's not - it will listen on this value for HTTP
|
// on one single port. If it's not - it will listen on this value for HTTP
|
||||||
// CONNECT requests. By default, this value is 0.
|
// CONNECT requests. By default, this value is 0.
|
||||||
VhostTcpPort int `json:"vhost_tcp_port"`
|
TcpHttpTunnelPort int `json:"tcp_http_tunnel_port"`
|
||||||
|
|
||||||
// VhostHttpTimeout specifies the response header timeout for the Vhost
|
// VhostHttpTimeout specifies the response header timeout for the Vhost
|
||||||
// HTTP server, in seconds. By default, this value is 60.
|
// HTTP server, in seconds. By default, this value is 60.
|
||||||
@ -162,7 +162,7 @@ func GetDefaultServerConf() ServerCommonConf {
|
|||||||
ProxyBindAddr: "0.0.0.0",
|
ProxyBindAddr: "0.0.0.0",
|
||||||
VhostHttpPort: 0,
|
VhostHttpPort: 0,
|
||||||
VhostHttpsPort: 0,
|
VhostHttpsPort: 0,
|
||||||
VhostTcpPort: 0,
|
TcpHttpTunnelPort: 0,
|
||||||
VhostHttpTimeout: 60,
|
VhostHttpTimeout: 60,
|
||||||
DashboardAddr: "0.0.0.0",
|
DashboardAddr: "0.0.0.0",
|
||||||
DashboardPort: 0,
|
DashboardPort: 0,
|
||||||
@ -266,15 +266,15 @@ func UnmarshalServerConfFromIni(content string) (cfg ServerCommonConf, err error
|
|||||||
cfg.VhostHttpsPort = 0
|
cfg.VhostHttpsPort = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if tmpStr, ok = conf.Get("common", "vhost_tcp_port"); ok {
|
if tmpStr, ok = conf.Get("common", "tcp_http_tunnel_port"); ok {
|
||||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||||
err = fmt.Errorf("Parse conf error: invalid vhost_tcp_port")
|
err = fmt.Errorf("Parse conf error: invalid tcp_http_tunnel_port")
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
cfg.VhostTcpPort = int(v)
|
cfg.TcpHttpTunnelPort = int(v)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cfg.VhostTcpPort = 0
|
cfg.TcpHttpTunnelPort = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if tmpStr, ok = conf.Get("common", "vhost_http_timeout"); ok {
|
if tmpStr, ok = conf.Get("common", "vhost_http_timeout"); ok {
|
||||||
|
@ -23,10 +23,11 @@ var (
|
|||||||
Offline string = "offline"
|
Offline string = "offline"
|
||||||
|
|
||||||
// proxy type
|
// proxy type
|
||||||
TcpProxy string = "tcp"
|
TcpProxy string = "tcp"
|
||||||
UdpProxy string = "udp"
|
UdpProxy string = "udp"
|
||||||
HttpProxy string = "http"
|
TcpHttpTunnelProxy string = "tcphttptunnel"
|
||||||
HttpsProxy string = "https"
|
HttpProxy string = "http"
|
||||||
StcpProxy string = "stcp"
|
HttpsProxy string = "https"
|
||||||
XtcpProxy string = "xtcp"
|
StcpProxy string = "stcp"
|
||||||
|
XtcpProxy string = "xtcp"
|
||||||
)
|
)
|
||||||
|
@ -45,7 +45,7 @@ type ResourceController struct {
|
|||||||
VhostHttpsMuxer *vhost.HttpsMuxer
|
VhostHttpsMuxer *vhost.HttpsMuxer
|
||||||
|
|
||||||
// For tcp proxies, route requests to different proxies based on HTTP CONNECT header
|
// For tcp proxies, route requests to different proxies based on HTTP CONNECT header
|
||||||
VhostTcpMuxer *vhost.TcpMuxer
|
VhostTcpMuxer *vhost.TcpHttpTunnelMuxer
|
||||||
|
|
||||||
// Controller for nat hole connections
|
// Controller for nat hole connections
|
||||||
NatHoleController *nathole.NatHoleController
|
NatHoleController *nathole.NatHoleController
|
||||||
|
@ -95,6 +95,11 @@ type TcpOutConf struct {
|
|||||||
RemotePort int `json:"remote_port"`
|
RemotePort int `json:"remote_port"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TcpHttpTunnelOutConf struct {
|
||||||
|
BaseOutConf
|
||||||
|
config.DomainConf
|
||||||
|
}
|
||||||
|
|
||||||
type UdpOutConf struct {
|
type UdpOutConf struct {
|
||||||
BaseOutConf
|
BaseOutConf
|
||||||
RemotePort int `json:"remote_port"`
|
RemotePort int `json:"remote_port"`
|
||||||
@ -124,6 +129,8 @@ func getConfByType(proxyType string) interface{} {
|
|||||||
switch proxyType {
|
switch proxyType {
|
||||||
case consts.TcpProxy:
|
case consts.TcpProxy:
|
||||||
return &TcpOutConf{}
|
return &TcpOutConf{}
|
||||||
|
case consts.TcpHttpTunnelProxy:
|
||||||
|
return &TcpHttpTunnelOutConf{}
|
||||||
case consts.UdpProxy:
|
case consts.UdpProxy:
|
||||||
return &UdpOutConf{}
|
return &UdpOutConf{}
|
||||||
case consts.HttpProxy:
|
case consts.HttpProxy:
|
||||||
|
@ -176,6 +176,11 @@ func NewProxy(ctx context.Context, runId string, rc *controller.ResourceControll
|
|||||||
BaseProxy: &basePxy,
|
BaseProxy: &basePxy,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
}
|
}
|
||||||
|
case *config.TcpHttpTunnelProxyConf:
|
||||||
|
pxy = &TcpHttpTunnelProxy{
|
||||||
|
BaseProxy: &basePxy,
|
||||||
|
cfg: cfg,
|
||||||
|
}
|
||||||
case *config.HttpProxyConf:
|
case *config.HttpProxyConf:
|
||||||
pxy = &HttpProxy{
|
pxy = &HttpProxy{
|
||||||
BaseProxy: &basePxy,
|
BaseProxy: &basePxy,
|
||||||
|
@ -19,7 +19,6 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/fatedier/frp/models/config"
|
"github.com/fatedier/frp/models/config"
|
||||||
"github.com/fatedier/frp/utils/vhost"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type TcpProxy struct {
|
type TcpProxy struct {
|
||||||
@ -46,52 +45,22 @@ func (pxy *TcpProxy) Run() (remoteAddr string, err error) {
|
|||||||
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 {
|
||||||
if pxy.serverCfg.VhostTcpPort > 0 && (len(pxy.cfg.CustomDomains) > 0 || pxy.cfg.SubDomain != "") {
|
pxy.realPort, err = pxy.rc.TcpPortManager.Acquire(pxy.name, pxy.cfg.RemotePort)
|
||||||
pxy.realPort = pxy.serverCfg.VhostTcpPort
|
if err != nil {
|
||||||
routeConfig := &vhost.VhostRouteConfig{}
|
return
|
||||||
for _, domain := range pxy.cfg.CustomDomains {
|
|
||||||
if domain == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
routeConfig.Domain = domain
|
|
||||||
l, errRet := pxy.rc.VhostTcpMuxer.Listen(pxy.ctx, routeConfig)
|
|
||||||
if errRet != nil {
|
|
||||||
err = errRet
|
|
||||||
return
|
|
||||||
}
|
|
||||||
xl.Info("http tunnel server (tcp proxy) listen for host [%s]", routeConfig.Domain)
|
|
||||||
pxy.listeners = append(pxy.listeners, l)
|
|
||||||
}
|
|
||||||
|
|
||||||
if pxy.cfg.SubDomain != "" {
|
|
||||||
routeConfig.Domain = pxy.cfg.SubDomain + "." + pxy.serverCfg.SubDomainHost
|
|
||||||
l, errRet := pxy.rc.VhostTcpMuxer.Listen(pxy.ctx, routeConfig)
|
|
||||||
if errRet != nil {
|
|
||||||
err = errRet
|
|
||||||
return
|
|
||||||
}
|
|
||||||
xl.Info("http tunnel server (tcp proxy) listen for host [%s]", routeConfig.Domain)
|
|
||||||
pxy.listeners = append(pxy.listeners, l)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pxy.realPort, err = pxy.rc.TcpPortManager.Acquire(pxy.name, pxy.cfg.RemotePort)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
pxy.rc.TcpPortManager.Release(pxy.realPort)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
listener, errRet := net.Listen("tcp", fmt.Sprintf("%s:%d", pxy.serverCfg.ProxyBindAddr, pxy.realPort))
|
|
||||||
if errRet != nil {
|
|
||||||
err = errRet
|
|
||||||
return
|
|
||||||
}
|
|
||||||
pxy.listeners = append(pxy.listeners, listener)
|
|
||||||
xl.Info("tcp proxy listen port [%d]", pxy.cfg.RemotePort)
|
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
pxy.rc.TcpPortManager.Release(pxy.realPort)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
listener, errRet := net.Listen("tcp", fmt.Sprintf("%s:%d", pxy.serverCfg.ProxyBindAddr, pxy.realPort))
|
||||||
|
if errRet != nil {
|
||||||
|
err = errRet
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pxy.listeners = append(pxy.listeners, listener)
|
||||||
|
xl.Info("tcp proxy listen port [%d]", pxy.cfg.RemotePort)
|
||||||
}
|
}
|
||||||
|
|
||||||
pxy.cfg.RemotePort = pxy.realPort
|
pxy.cfg.RemotePort = pxy.realPort
|
||||||
|
@ -215,21 +215,21 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) {
|
|||||||
log.Info("https service listen on %s:%d", cfg.ProxyBindAddr, cfg.VhostHttpsPort)
|
log.Info("https service listen on %s:%d", cfg.ProxyBindAddr, cfg.VhostHttpsPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create tcp vhost muxer.
|
// Create tcp http tunnel muxer.
|
||||||
if cfg.VhostTcpPort > 0 {
|
if cfg.TcpHttpTunnelPort > 0 {
|
||||||
var l net.Listener
|
var l net.Listener
|
||||||
l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", cfg.ProxyBindAddr, cfg.VhostTcpPort))
|
l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", cfg.ProxyBindAddr, cfg.TcpHttpTunnelPort))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Create server listener error, %v", err)
|
err = fmt.Errorf("Create server listener error, %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
svr.rc.VhostTcpMuxer, err = vhost.NewTcpMuxer(l, 30*time.Second)
|
svr.rc.VhostTcpMuxer, err = vhost.NewTcpHttpTunnelMuxer(l, 30*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Create vhost tcpMuxer error, %v", err)
|
err = fmt.Errorf("Create vhost tcpMuxer error, %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Info("tcp service listen on %s:%d", cfg.ProxyBindAddr, cfg.VhostTcpPort)
|
log.Info("tcp http tunnel service listen on %s:%d", cfg.ProxyBindAddr, cfg.TcpHttpTunnelPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
// frp tls listener
|
// frp tls listener
|
||||||
|
@ -23,13 +23,13 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TcpMuxer struct {
|
type TcpHttpTunnelMuxer struct {
|
||||||
*VhostMuxer
|
*VhostMuxer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTcpMuxer(listener net.Listener, timeout time.Duration) (*TcpMuxer, error) {
|
func NewTcpHttpTunnelMuxer(listener net.Listener, timeout time.Duration) (*TcpHttpTunnelMuxer, error) {
|
||||||
mux, err := NewVhostMuxer(listener, getTcpServiceName, nil, sendHttpOk, timeout)
|
mux, err := NewVhostMuxer(listener, getHostFromHttpConnect, nil, sendHttpOk, timeout)
|
||||||
return &TcpMuxer{mux}, err
|
return &TcpHttpTunnelMuxer{mux}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func readHttpConnectRequest(rd io.Reader) (host string, err error) {
|
func readHttpConnectRequest(rd io.Reader) (host string, err error) {
|
||||||
@ -55,7 +55,7 @@ func sendHttpOk(c net.Conn, _ string) (_ net.Conn, err error) {
|
|||||||
return c, err
|
return c, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTcpServiceName(c net.Conn) (_ net.Conn, _ map[string]string, err error) {
|
func getHostFromHttpConnect(c net.Conn) (_ net.Conn, _ map[string]string, err error) {
|
||||||
reqInfoMap := make(map[string]string, 0)
|
reqInfoMap := make(map[string]string, 0)
|
||||||
host, err := readHttpConnectRequest(c)
|
host, err := readHttpConnectRequest(c)
|
||||||
if err != nil {
|
if err != nil {
|
Loading…
Reference in New Issue
Block a user