tcp multiplexing over http connect tunnel

This commit is contained in:
fatedier
2020-03-05 21:47:49 +08:00
committed by GitHub
parent 0b9124d4fd
commit 1db091b381
22 changed files with 565 additions and 26 deletions

View File

@@ -34,6 +34,7 @@ var (
func init() {
proxyConfTypeMap = make(map[string]reflect.Type)
proxyConfTypeMap[consts.TcpProxy] = reflect.TypeOf(TcpProxyConf{})
proxyConfTypeMap[consts.TcpMuxProxy] = reflect.TypeOf(TcpMuxProxyConf{})
proxyConfTypeMap[consts.UdpProxy] = reflect.TypeOf(UdpProxyConf{})
proxyConfTypeMap[consts.HttpProxy] = reflect.TypeOf(HttpProxyConf{})
proxyConfTypeMap[consts.HttpsProxy] = reflect.TypeOf(HttpsProxyConf{})
@@ -574,6 +575,84 @@ func (cfg *TcpProxyConf) CheckForCli() (err error) {
func (cfg *TcpProxyConf) CheckForSvr(serverCfg ServerCommonConf) error { return nil }
// TCP Multiplexer
type TcpMuxProxyConf struct {
BaseProxyConf
DomainConf
Multiplexer string `json:"multiplexer"`
}
func (cfg *TcpMuxProxyConf) Compare(cmp ProxyConf) bool {
cmpConf, ok := cmp.(*TcpMuxProxyConf)
if !ok {
return false
}
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
!cfg.DomainConf.compare(&cmpConf.DomainConf) ||
cfg.Multiplexer != cmpConf.Multiplexer {
return false
}
return true
}
func (cfg *TcpMuxProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
cfg.DomainConf.UnmarshalFromMsg(pMsg)
cfg.Multiplexer = pMsg.Multiplexer
}
func (cfg *TcpMuxProxyConf) 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
}
cfg.Multiplexer = section["multiplexer"]
if cfg.Multiplexer != consts.HttpConnectTcpMultiplexer {
return fmt.Errorf("parse conf error: proxy [%s] incorrect multiplexer [%s]", name, cfg.Multiplexer)
}
return
}
func (cfg *TcpMuxProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
cfg.BaseProxyConf.MarshalToMsg(pMsg)
cfg.DomainConf.MarshalToMsg(pMsg)
pMsg.Multiplexer = cfg.Multiplexer
}
func (cfg *TcpMuxProxyConf) CheckForCli() (err error) {
if err = cfg.BaseProxyConf.checkForCli(); err != nil {
return err
}
if err = cfg.DomainConf.checkForCli(); err != nil {
return err
}
if cfg.Multiplexer != consts.HttpConnectTcpMultiplexer {
return fmt.Errorf("parse conf error: incorrect multiplexer [%s]", cfg.Multiplexer)
}
return
}
func (cfg *TcpMuxProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
if cfg.Multiplexer != consts.HttpConnectTcpMultiplexer {
return fmt.Errorf("proxy [%s] incorrect multiplexer [%s]", cfg.ProxyName, cfg.Multiplexer)
}
if cfg.Multiplexer == consts.HttpConnectTcpMultiplexer && serverCfg.TcpMuxHttpConnectPort == 0 {
return fmt.Errorf("proxy [%s] type [tcpmux] with multiplexer [httpconnect] requires tcpmux_httpconnect_port configuration", cfg.ProxyName)
}
if err = cfg.DomainConf.checkForSvr(serverCfg); err != nil {
err = fmt.Errorf("proxy [%s] domain conf check error: %v", cfg.ProxyName, err)
return
}
return
}
// UDP
type UdpProxyConf struct {
BaseProxyConf

View File

@@ -59,6 +59,12 @@ type ServerCommonConf struct {
// requests. By default, this value is 0.
VhostHttpsPort int `json:"vhost_https_port"`
// TcpMuxHttpConnectPort specifies the port that the server listens for TCP
// HTTP CONNECT 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 CONNECT requests. By default, this value is 0.
TcpMuxHttpConnectPort int `json:"tcpmux_httpconnect_port"`
// VhostHttpTimeout specifies the response header timeout for the Vhost
// HTTP server, in seconds. By default, this value is 60.
VhostHttpTimeout int64 `json:"vhost_http_timeout"`
@@ -155,6 +161,7 @@ func GetDefaultServerConf() ServerCommonConf {
ProxyBindAddr: "0.0.0.0",
VhostHttpPort: 0,
VhostHttpsPort: 0,
TcpMuxHttpConnectPort: 0,
VhostHttpTimeout: 60,
DashboardAddr: "0.0.0.0",
DashboardPort: 0,
@@ -259,6 +266,17 @@ func UnmarshalServerConfFromIni(content string) (cfg ServerCommonConf, err error
cfg.VhostHttpsPort = 0
}
if tmpStr, ok = conf.Get("common", "tcpmux_httpconnect_port"); ok {
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
err = fmt.Errorf("Parse conf error: invalid tcpmux_httpconnect_port")
return
} else {
cfg.TcpMuxHttpConnectPort = int(v)
}
} else {
cfg.TcpMuxHttpConnectPort = 0
}
if tmpStr, ok = conf.Get("common", "vhost_http_timeout"); ok {
v, errRet := strconv.ParseInt(tmpStr, 10, 64)
if errRet != nil || v < 0 {