mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-21 09:36:34 -05:00
protobuf for stream settings
This commit is contained in:
parent
5ec948f690
commit
1d13f47f9c
@ -28,8 +28,8 @@ func TestDnsAdd(t *testing.T) {
|
|||||||
space,
|
space,
|
||||||
&proxy.OutboundHandlerMeta{
|
&proxy.OutboundHandlerMeta{
|
||||||
Address: v2net.AnyIP,
|
Address: v2net.AnyIP,
|
||||||
StreamSettings: &internet.StreamSettings{
|
StreamSettings: &internet.StreamConfig{
|
||||||
Type: internet.StreamConnectionTypeRawTCP,
|
Network: v2net.Network_RawTCP,
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, outboundHandlerManager)
|
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, outboundHandlerManager)
|
||||||
|
@ -68,7 +68,7 @@ func NewNetworkList(networks collect.StringList) *NetworkList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HashNetwork returns true if the given network is in this NetworkList.
|
// HashNetwork returns true if the given network is in this NetworkList.
|
||||||
func (this *NetworkList) HasNetwork(network Network) bool {
|
func (this NetworkList) HasNetwork(network Network) bool {
|
||||||
for _, value := range this.Network {
|
for _, value := range this.Network {
|
||||||
if string(value) == string(network) {
|
if string(value) == string(network) {
|
||||||
return true
|
return true
|
||||||
@ -76,3 +76,7 @@ func (this *NetworkList) HasNetwork(network Network) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this NetworkList) Get(idx int) Network {
|
||||||
|
return this.Network[idx]
|
||||||
|
}
|
||||||
|
@ -8,6 +8,15 @@ import (
|
|||||||
"v2ray.com/core/common/collect"
|
"v2ray.com/core/common/collect"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (this *Network) UnmarshalJSON(data []byte) error {
|
||||||
|
var str string
|
||||||
|
if err := json.Unmarshal(data, &str); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*this = ParseNetwork(str)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (this *NetworkList) UnmarshalJSON(data []byte) error {
|
func (this *NetworkList) UnmarshalJSON(data []byte) error {
|
||||||
var strlist collect.StringList
|
var strlist collect.StringList
|
||||||
if err := json.Unmarshal(data, &strlist); err != nil {
|
if err := json.Unmarshal(data, &strlist); err != nil {
|
||||||
|
@ -10,6 +10,15 @@ import (
|
|||||||
"v2ray.com/core/testing/assert"
|
"v2ray.com/core/testing/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestStringNetwork(t *testing.T) {
|
||||||
|
assert := assert.On(t)
|
||||||
|
|
||||||
|
var network Network
|
||||||
|
err := json.Unmarshal([]byte(`"tcp"`), &network)
|
||||||
|
assert.Error(err).IsNil()
|
||||||
|
assert.Bool(network == Network_TCP).IsTrue()
|
||||||
|
}
|
||||||
|
|
||||||
func TestArrayNetworkList(t *testing.T) {
|
func TestArrayNetworkList(t *testing.T) {
|
||||||
assert := assert.On(t)
|
assert := assert.On(t)
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
v2net "v2ray.com/core/common/net"
|
v2net "v2ray.com/core/common/net"
|
||||||
"v2ray.com/core/proxy"
|
"v2ray.com/core/proxy"
|
||||||
"v2ray.com/core/proxy/registry"
|
"v2ray.com/core/proxy/registry"
|
||||||
"v2ray.com/core/transport/internet"
|
|
||||||
"v2ray.com/core/transport/ray"
|
"v2ray.com/core/transport/ray"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -40,8 +39,10 @@ func (this *BlackHole) Dispatch(destination v2net.Destination, payload *alloc.Bu
|
|||||||
|
|
||||||
type Factory struct{}
|
type Factory struct{}
|
||||||
|
|
||||||
func (this *Factory) StreamCapability() internet.StreamConnectionType {
|
func (this *Factory) StreamCapability() v2net.NetworkList {
|
||||||
return internet.StreamConnectionTypeRawTCP
|
return v2net.NetworkList{
|
||||||
|
Network: []v2net.Network{v2net.Network_RawTCP},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Factory) Create(space app.Space, config interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
func (this *Factory) Create(space app.Space, config interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
||||||
|
@ -194,8 +194,10 @@ func (this *DokodemoDoor) HandleTCPConnection(conn internet.Connection) {
|
|||||||
|
|
||||||
type Factory struct{}
|
type Factory struct{}
|
||||||
|
|
||||||
func (this *Factory) StreamCapability() internet.StreamConnectionType {
|
func (this *Factory) StreamCapability() v2net.NetworkList {
|
||||||
return internet.StreamConnectionTypeRawTCP
|
return v2net.NetworkList{
|
||||||
|
Network: []v2net.Network{v2net.Network_RawTCP},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
func (this *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
||||||
|
@ -44,8 +44,8 @@ func TestDokodemoTCP(t *testing.T) {
|
|||||||
space,
|
space,
|
||||||
&proxy.OutboundHandlerMeta{
|
&proxy.OutboundHandlerMeta{
|
||||||
Address: v2net.LocalHostIP,
|
Address: v2net.LocalHostIP,
|
||||||
StreamSettings: &internet.StreamSettings{
|
StreamSettings: &internet.StreamConfig{
|
||||||
Type: internet.StreamConnectionTypeRawTCP,
|
Network: v2net.Network_RawTCP,
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, ohm)
|
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, ohm)
|
||||||
@ -65,8 +65,8 @@ func TestDokodemoTCP(t *testing.T) {
|
|||||||
}, space, &proxy.InboundHandlerMeta{
|
}, space, &proxy.InboundHandlerMeta{
|
||||||
Address: v2net.LocalHostIP,
|
Address: v2net.LocalHostIP,
|
||||||
Port: port,
|
Port: port,
|
||||||
StreamSettings: &internet.StreamSettings{
|
StreamSettings: &internet.StreamConfig{
|
||||||
Type: internet.StreamConnectionTypeRawTCP,
|
Network: v2net.Network_RawTCP,
|
||||||
}})
|
}})
|
||||||
defer dokodemo.Close()
|
defer dokodemo.Close()
|
||||||
|
|
||||||
@ -119,8 +119,8 @@ func TestDokodemoUDP(t *testing.T) {
|
|||||||
space,
|
space,
|
||||||
&proxy.OutboundHandlerMeta{
|
&proxy.OutboundHandlerMeta{
|
||||||
Address: v2net.AnyIP,
|
Address: v2net.AnyIP,
|
||||||
StreamSettings: &internet.StreamSettings{
|
StreamSettings: &internet.StreamConfig{
|
||||||
Type: internet.StreamConnectionTypeRawTCP,
|
Network: v2net.Network_RawTCP,
|
||||||
}}))
|
}}))
|
||||||
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, ohm)
|
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, ohm)
|
||||||
|
|
||||||
@ -139,8 +139,8 @@ func TestDokodemoUDP(t *testing.T) {
|
|||||||
}, space, &proxy.InboundHandlerMeta{
|
}, space, &proxy.InboundHandlerMeta{
|
||||||
Address: v2net.LocalHostIP,
|
Address: v2net.LocalHostIP,
|
||||||
Port: port,
|
Port: port,
|
||||||
StreamSettings: &internet.StreamSettings{
|
StreamSettings: &internet.StreamConfig{
|
||||||
Type: internet.StreamConnectionTypeRawTCP,
|
Network: v2net.Network_RawTCP,
|
||||||
}})
|
}})
|
||||||
defer dokodemo.Close()
|
defer dokodemo.Close()
|
||||||
|
|
||||||
|
@ -129,8 +129,10 @@ func (this *FreedomConnection) Dispatch(destination v2net.Destination, payload *
|
|||||||
|
|
||||||
type FreedomFactory struct{}
|
type FreedomFactory struct{}
|
||||||
|
|
||||||
func (this *FreedomFactory) StreamCapability() internet.StreamConnectionType {
|
func (this *FreedomFactory) StreamCapability() v2net.NetworkList {
|
||||||
return internet.StreamConnectionTypeRawTCP
|
return v2net.NetworkList{
|
||||||
|
Network: []v2net.Network{v2net.Network_RawTCP},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *FreedomFactory) Create(space app.Space, config interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
func (this *FreedomFactory) Create(space app.Space, config interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
||||||
|
@ -40,8 +40,8 @@ func TestSinglePacket(t *testing.T) {
|
|||||||
space,
|
space,
|
||||||
&proxy.OutboundHandlerMeta{
|
&proxy.OutboundHandlerMeta{
|
||||||
Address: v2net.AnyIP,
|
Address: v2net.AnyIP,
|
||||||
StreamSettings: &internet.StreamSettings{
|
StreamSettings: &internet.StreamConfig{
|
||||||
Type: internet.StreamConnectionTypeRawTCP,
|
Network: v2net.Network_RawTCP,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
space.Initialize()
|
space.Initialize()
|
||||||
@ -68,8 +68,8 @@ func TestUnreachableDestination(t *testing.T) {
|
|||||||
app.NewSpace(),
|
app.NewSpace(),
|
||||||
&proxy.OutboundHandlerMeta{
|
&proxy.OutboundHandlerMeta{
|
||||||
Address: v2net.AnyIP,
|
Address: v2net.AnyIP,
|
||||||
StreamSettings: &internet.StreamSettings{
|
StreamSettings: &internet.StreamConfig{
|
||||||
Type: internet.StreamConnectionTypeRawTCP,
|
Network: v2net.Network_RawTCP,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
traffic := ray.NewRay()
|
traffic := ray.NewRay()
|
||||||
@ -104,8 +104,8 @@ func TestIPResolution(t *testing.T) {
|
|||||||
space,
|
space,
|
||||||
&proxy.OutboundHandlerMeta{
|
&proxy.OutboundHandlerMeta{
|
||||||
Address: v2net.AnyIP,
|
Address: v2net.AnyIP,
|
||||||
StreamSettings: &internet.StreamSettings{
|
StreamSettings: &internet.StreamConfig{
|
||||||
Type: internet.StreamConnectionTypeRawTCP,
|
Network: v2net.Network_RawTCP,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -264,8 +264,10 @@ func (this *Server) handlePlainHTTP(request *http.Request, session *proxy.Sessio
|
|||||||
|
|
||||||
type ServerFactory struct{}
|
type ServerFactory struct{}
|
||||||
|
|
||||||
func (this *ServerFactory) StreamCapability() internet.StreamConnectionType {
|
func (this *ServerFactory) StreamCapability() v2net.NetworkList {
|
||||||
return internet.StreamConnectionTypeRawTCP
|
return v2net.NetworkList{
|
||||||
|
Network: []v2net.Network{v2net.Network_RawTCP},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
func (this *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
||||||
|
@ -63,8 +63,8 @@ func TestNormalGetRequest(t *testing.T) {
|
|||||||
&proxy.InboundHandlerMeta{
|
&proxy.InboundHandlerMeta{
|
||||||
Address: v2net.LocalHostIP,
|
Address: v2net.LocalHostIP,
|
||||||
Port: port,
|
Port: port,
|
||||||
StreamSettings: &internet.StreamSettings{
|
StreamSettings: &internet.StreamConfig{
|
||||||
Type: internet.StreamConnectionTypeRawTCP,
|
Network: v2net.Network_RawTCP,
|
||||||
}})
|
}})
|
||||||
defer httpProxy.Close()
|
defer httpProxy.Close()
|
||||||
|
|
||||||
|
@ -27,13 +27,13 @@ type InboundHandlerMeta struct {
|
|||||||
Address v2net.Address
|
Address v2net.Address
|
||||||
Port v2net.Port
|
Port v2net.Port
|
||||||
AllowPassiveConnection bool
|
AllowPassiveConnection bool
|
||||||
StreamSettings *internet.StreamSettings
|
StreamSettings *internet.StreamConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
type OutboundHandlerMeta struct {
|
type OutboundHandlerMeta struct {
|
||||||
Tag string
|
Tag string
|
||||||
Address v2net.Address
|
Address v2net.Address
|
||||||
StreamSettings *internet.StreamSettings
|
StreamSettings *internet.StreamConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// An InboundHandler handles inbound network connections to V2Ray.
|
// An InboundHandler handles inbound network connections to V2Ray.
|
||||||
|
@ -2,16 +2,16 @@ package registry
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"v2ray.com/core/app"
|
"v2ray.com/core/app"
|
||||||
|
v2net "v2ray.com/core/common/net"
|
||||||
"v2ray.com/core/proxy"
|
"v2ray.com/core/proxy"
|
||||||
"v2ray.com/core/transport/internet"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type InboundHandlerFactory interface {
|
type InboundHandlerFactory interface {
|
||||||
StreamCapability() internet.StreamConnectionType
|
StreamCapability() v2net.NetworkList
|
||||||
Create(space app.Space, config interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error)
|
Create(space app.Space, config interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type OutboundHandlerFactory interface {
|
type OutboundHandlerFactory interface {
|
||||||
StreamCapability() internet.StreamConnectionType
|
StreamCapability() v2net.NetworkList
|
||||||
Create(space app.Space, config interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error)
|
Create(space app.Space, config interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package registry
|
package registry
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
"v2ray.com/core/app"
|
"v2ray.com/core/app"
|
||||||
"v2ray.com/core/common"
|
"v2ray.com/core/common"
|
||||||
"v2ray.com/core/proxy"
|
"v2ray.com/core/proxy"
|
||||||
@ -46,11 +48,13 @@ func CreateInboundHandler(name string, space app.Space, rawConfig []byte, meta *
|
|||||||
return nil, common.ErrObjectNotFound
|
return nil, common.ErrObjectNotFound
|
||||||
}
|
}
|
||||||
if meta.StreamSettings == nil {
|
if meta.StreamSettings == nil {
|
||||||
meta.StreamSettings = &internet.StreamSettings{
|
meta.StreamSettings = &internet.StreamConfig{
|
||||||
Type: creator.StreamCapability(),
|
Network: creator.StreamCapability().Get(0),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
meta.StreamSettings.Type &= creator.StreamCapability()
|
if !creator.StreamCapability().HasNetwork(meta.StreamSettings.Network) {
|
||||||
|
return nil, errors.New("Proxy|Registry: Invalid network: " + meta.StreamSettings.Network.String())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(rawConfig) > 0 {
|
if len(rawConfig) > 0 {
|
||||||
@ -69,11 +73,13 @@ func CreateOutboundHandler(name string, space app.Space, rawConfig []byte, meta
|
|||||||
return nil, common.ErrObjectNotFound
|
return nil, common.ErrObjectNotFound
|
||||||
}
|
}
|
||||||
if meta.StreamSettings == nil {
|
if meta.StreamSettings == nil {
|
||||||
meta.StreamSettings = &internet.StreamSettings{
|
meta.StreamSettings = &internet.StreamConfig{
|
||||||
Type: creator.StreamCapability(),
|
Network: creator.StreamCapability().Get(0),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
meta.StreamSettings.Type &= creator.StreamCapability()
|
if !creator.StreamCapability().HasNetwork(meta.StreamSettings.Network) {
|
||||||
|
return nil, errors.New("Proxy|Registry: Invalid network: " + meta.StreamSettings.Network.String())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(rawConfig) > 0 {
|
if len(rawConfig) > 0 {
|
||||||
|
@ -278,8 +278,10 @@ func (this *Server) handleConnection(conn internet.Connection) {
|
|||||||
|
|
||||||
type ServerFactory struct{}
|
type ServerFactory struct{}
|
||||||
|
|
||||||
func (this *ServerFactory) StreamCapability() internet.StreamConnectionType {
|
func (this *ServerFactory) StreamCapability() v2net.NetworkList {
|
||||||
return internet.StreamConnectionTypeRawTCP
|
return v2net.NetworkList{
|
||||||
|
Network: []v2net.Network{v2net.Network_RawTCP},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
func (this *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
||||||
|
@ -315,8 +315,10 @@ func (this *Server) transport(reader io.Reader, writer io.Writer, session *proxy
|
|||||||
|
|
||||||
type ServerFactory struct{}
|
type ServerFactory struct{}
|
||||||
|
|
||||||
func (this *ServerFactory) StreamCapability() internet.StreamConnectionType {
|
func (this *ServerFactory) StreamCapability() v2net.NetworkList {
|
||||||
return internet.StreamConnectionTypeRawTCP
|
return v2net.NetworkList{
|
||||||
|
Network: []v2net.Network{v2net.Network_RawTCP},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
func (this *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
||||||
|
@ -249,8 +249,10 @@ func (this *VMessInboundHandler) HandleConnection(connection internet.Connection
|
|||||||
|
|
||||||
type Factory struct{}
|
type Factory struct{}
|
||||||
|
|
||||||
func (this *Factory) StreamCapability() internet.StreamConnectionType {
|
func (this *Factory) StreamCapability() v2net.NetworkList {
|
||||||
return internet.StreamConnectionTypeRawTCP | internet.StreamConnectionTypeTCP | internet.StreamConnectionTypeKCP | internet.StreamConnectionTypeWebSocket
|
return v2net.NetworkList{
|
||||||
|
Network: []v2net.Network{v2net.Network_TCP, v2net.Network_KCP, v2net.Network_WebSocket},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
func (this *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
||||||
|
@ -160,8 +160,10 @@ func (this *VMessOutboundHandler) handleResponse(session *encoding.ClientSession
|
|||||||
|
|
||||||
type Factory struct{}
|
type Factory struct{}
|
||||||
|
|
||||||
func (this *Factory) StreamCapability() internet.StreamConnectionType {
|
func (this *Factory) StreamCapability() v2net.NetworkList {
|
||||||
return internet.StreamConnectionTypeRawTCP | internet.StreamConnectionTypeTCP | internet.StreamConnectionTypeKCP | internet.StreamConnectionTypeWebSocket
|
return v2net.NetworkList{
|
||||||
|
Network: []v2net.Network{v2net.Network_TCP, v2net.Network_KCP, v2net.Network_WebSocket},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
func (this *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
type InboundConnectionConfig struct {
|
type InboundConnectionConfig struct {
|
||||||
Port v2net.Port
|
Port v2net.Port
|
||||||
ListenOn v2net.Address
|
ListenOn v2net.Address
|
||||||
StreamSettings *internet.StreamSettings
|
StreamSettings *internet.StreamConfig
|
||||||
Protocol string
|
Protocol string
|
||||||
Settings []byte
|
Settings []byte
|
||||||
AllowPassiveConnection bool
|
AllowPassiveConnection bool
|
||||||
@ -22,7 +22,7 @@ type InboundConnectionConfig struct {
|
|||||||
type OutboundConnectionConfig struct {
|
type OutboundConnectionConfig struct {
|
||||||
Protocol string
|
Protocol string
|
||||||
SendThrough v2net.Address
|
SendThrough v2net.Address
|
||||||
StreamSettings *internet.StreamSettings
|
StreamSettings *internet.StreamConfig
|
||||||
Settings []byte
|
Settings []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ type InboundDetourConfig struct {
|
|||||||
ListenOn v2net.Address
|
ListenOn v2net.Address
|
||||||
Tag string
|
Tag string
|
||||||
Allocation *InboundDetourAllocationConfig
|
Allocation *InboundDetourAllocationConfig
|
||||||
StreamSettings *internet.StreamSettings
|
StreamSettings *internet.StreamConfig
|
||||||
Settings []byte
|
Settings []byte
|
||||||
AllowPassiveConnection bool
|
AllowPassiveConnection bool
|
||||||
}
|
}
|
||||||
@ -58,7 +58,7 @@ type InboundDetourConfig struct {
|
|||||||
type OutboundDetourConfig struct {
|
type OutboundDetourConfig struct {
|
||||||
Protocol string
|
Protocol string
|
||||||
SendThrough v2net.Address
|
SendThrough v2net.Address
|
||||||
StreamSettings *internet.StreamSettings
|
StreamSettings *internet.StreamConfig
|
||||||
Tag string
|
Tag string
|
||||||
Settings []byte
|
Settings []byte
|
||||||
}
|
}
|
||||||
|
@ -73,12 +73,12 @@ func (this *Config) UnmarshalJSON(data []byte) error {
|
|||||||
|
|
||||||
func (this *InboundConnectionConfig) UnmarshalJSON(data []byte) error {
|
func (this *InboundConnectionConfig) UnmarshalJSON(data []byte) error {
|
||||||
type JsonConfig struct {
|
type JsonConfig struct {
|
||||||
Port uint16 `json:"port"`
|
Port uint16 `json:"port"`
|
||||||
Listen *v2net.AddressPB `json:"listen"`
|
Listen *v2net.AddressPB `json:"listen"`
|
||||||
Protocol string `json:"protocol"`
|
Protocol string `json:"protocol"`
|
||||||
StreamSetting *internet.StreamSettings `json:"streamSettings"`
|
StreamSetting *internet.StreamConfig `json:"streamSettings"`
|
||||||
Settings json.RawMessage `json:"settings"`
|
Settings json.RawMessage `json:"settings"`
|
||||||
AllowPassive bool `json:"allowPassive"`
|
AllowPassive bool `json:"allowPassive"`
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonConfig := new(JsonConfig)
|
jsonConfig := new(JsonConfig)
|
||||||
@ -105,10 +105,10 @@ func (this *InboundConnectionConfig) UnmarshalJSON(data []byte) error {
|
|||||||
|
|
||||||
func (this *OutboundConnectionConfig) UnmarshalJSON(data []byte) error {
|
func (this *OutboundConnectionConfig) UnmarshalJSON(data []byte) error {
|
||||||
type JsonConnectionConfig struct {
|
type JsonConnectionConfig struct {
|
||||||
Protocol string `json:"protocol"`
|
Protocol string `json:"protocol"`
|
||||||
SendThrough *v2net.AddressPB `json:"sendThrough"`
|
SendThrough *v2net.AddressPB `json:"sendThrough"`
|
||||||
StreamSetting *internet.StreamSettings `json:"streamSettings"`
|
StreamSetting *internet.StreamConfig `json:"streamSettings"`
|
||||||
Settings json.RawMessage `json:"settings"`
|
Settings json.RawMessage `json:"settings"`
|
||||||
}
|
}
|
||||||
jsonConfig := new(JsonConnectionConfig)
|
jsonConfig := new(JsonConnectionConfig)
|
||||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||||
@ -194,7 +194,7 @@ func (this *InboundDetourConfig) UnmarshalJSON(data []byte) error {
|
|||||||
Settings json.RawMessage `json:"settings"`
|
Settings json.RawMessage `json:"settings"`
|
||||||
Tag string `json:"tag"`
|
Tag string `json:"tag"`
|
||||||
Allocation *InboundDetourAllocationConfig `json:"allocate"`
|
Allocation *InboundDetourAllocationConfig `json:"allocate"`
|
||||||
StreamSetting *internet.StreamSettings `json:"streamSettings"`
|
StreamSetting *internet.StreamConfig `json:"streamSettings"`
|
||||||
AllowPassive bool `json:"allowPassive"`
|
AllowPassive bool `json:"allowPassive"`
|
||||||
}
|
}
|
||||||
jsonConfig := new(JsonInboundDetourConfig)
|
jsonConfig := new(JsonInboundDetourConfig)
|
||||||
@ -232,11 +232,11 @@ func (this *InboundDetourConfig) UnmarshalJSON(data []byte) error {
|
|||||||
|
|
||||||
func (this *OutboundDetourConfig) UnmarshalJSON(data []byte) error {
|
func (this *OutboundDetourConfig) UnmarshalJSON(data []byte) error {
|
||||||
type JsonOutboundDetourConfig struct {
|
type JsonOutboundDetourConfig struct {
|
||||||
Protocol string `json:"protocol"`
|
Protocol string `json:"protocol"`
|
||||||
SendThrough *v2net.AddressPB `json:"sendThrough"`
|
SendThrough *v2net.AddressPB `json:"sendThrough"`
|
||||||
Tag string `json:"tag"`
|
Tag string `json:"tag"`
|
||||||
Settings json.RawMessage `json:"settings"`
|
Settings json.RawMessage `json:"settings"`
|
||||||
StreamSetting *internet.StreamSettings `json:"streamSettings"`
|
StreamSetting *internet.StreamConfig `json:"streamSettings"`
|
||||||
}
|
}
|
||||||
jsonConfig := new(JsonOutboundDetourConfig)
|
jsonConfig := new(JsonOutboundDetourConfig)
|
||||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||||
|
@ -1,26 +1,11 @@
|
|||||||
package transport
|
package transport
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"v2ray.com/core/transport/internet/kcp"
|
"v2ray.com/core/transport/internet"
|
||||||
"v2ray.com/core/transport/internet/tcp"
|
|
||||||
"v2ray.com/core/transport/internet/ws"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config for V2Ray transport layer.
|
|
||||||
type Config struct {
|
|
||||||
tcpConfig *tcp.Config
|
|
||||||
kcpConfig kcp.Config
|
|
||||||
wsConfig *ws.Config
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply applies this Config.
|
// Apply applies this Config.
|
||||||
func (this *Config) Apply() error {
|
func (this *Config) Apply() error {
|
||||||
if this.tcpConfig != nil {
|
internet.ApplyGlobalNetworkSettings(this.NetworkSettings)
|
||||||
this.tcpConfig.Apply()
|
|
||||||
}
|
|
||||||
this.kcpConfig.Apply()
|
|
||||||
if this.wsConfig != nil {
|
|
||||||
this.wsConfig.Apply()
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
67
transport/config.pb.go
Normal file
67
transport/config.pb.go
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Code generated by protoc-gen-go.
|
||||||
|
// source: v2ray.com/core/transport/config.proto
|
||||||
|
// DO NOT EDIT!
|
||||||
|
|
||||||
|
/*
|
||||||
|
Package transport is a generated protocol buffer package.
|
||||||
|
|
||||||
|
It is generated from these files:
|
||||||
|
v2ray.com/core/transport/config.proto
|
||||||
|
|
||||||
|
It has these top-level messages:
|
||||||
|
Config
|
||||||
|
*/
|
||||||
|
package transport
|
||||||
|
|
||||||
|
import proto "github.com/golang/protobuf/proto"
|
||||||
|
import fmt "fmt"
|
||||||
|
import math "math"
|
||||||
|
import v2ray_core_transport_internet "v2ray.com/core/transport/internet"
|
||||||
|
|
||||||
|
// Reference imports to suppress errors if they are not otherwise used.
|
||||||
|
var _ = proto.Marshal
|
||||||
|
var _ = fmt.Errorf
|
||||||
|
var _ = math.Inf
|
||||||
|
|
||||||
|
// This is a compile-time assertion to ensure that this generated file
|
||||||
|
// is compatible with the proto package it is being compiled against.
|
||||||
|
// A compilation error at this line likely means your copy of the
|
||||||
|
// proto package needs to be updated.
|
||||||
|
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
NetworkSettings []*v2ray_core_transport_internet.NetworkSettings `protobuf:"bytes,1,rep,name=network_settings,json=networkSettings" json:"network_settings,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Config) Reset() { *m = Config{} }
|
||||||
|
func (m *Config) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*Config) ProtoMessage() {}
|
||||||
|
func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
|
||||||
|
|
||||||
|
func (m *Config) GetNetworkSettings() []*v2ray_core_transport_internet.NetworkSettings {
|
||||||
|
if m != nil {
|
||||||
|
return m.NetworkSettings
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
proto.RegisterType((*Config)(nil), "v2ray.core.transport.Config")
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() { proto.RegisterFile("v2ray.com/core/transport/config.proto", fileDescriptor0) }
|
||||||
|
|
||||||
|
var fileDescriptor0 = []byte{
|
||||||
|
// 165 bytes of a gzipped FileDescriptorProto
|
||||||
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x52, 0x2d, 0x33, 0x2a, 0x4a,
|
||||||
|
0xac, 0xd4, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x2f, 0x29, 0x4a, 0xcc, 0x2b,
|
||||||
|
0x2e, 0xc8, 0x2f, 0x2a, 0xd1, 0x4f, 0xce, 0xcf, 0x4b, 0xcb, 0x4c, 0xd7, 0x2b, 0x28, 0xca, 0x2f,
|
||||||
|
0xc9, 0x17, 0x12, 0x81, 0x29, 0x2b, 0x4a, 0xd5, 0x83, 0x2b, 0x91, 0xd2, 0xc3, 0xa9, 0x39, 0x33,
|
||||||
|
0xaf, 0x24, 0xb5, 0x28, 0x2f, 0x15, 0xd5, 0x14, 0xa5, 0x64, 0x2e, 0x36, 0x67, 0x30, 0x5f, 0x28,
|
||||||
|
0x92, 0x4b, 0x20, 0x2f, 0xb5, 0xa4, 0x3c, 0xbf, 0x28, 0x3b, 0xbe, 0x38, 0xb5, 0xa4, 0x24, 0x33,
|
||||||
|
0x2f, 0xbd, 0x58, 0x82, 0x51, 0x81, 0x59, 0x83, 0xdb, 0x48, 0x4f, 0x0f, 0x9b, 0x55, 0x7a, 0x30,
|
||||||
|
0x03, 0xf5, 0xfc, 0x20, 0xda, 0x82, 0xa1, 0xba, 0x82, 0xf8, 0xf3, 0x50, 0x05, 0x9c, 0x8c, 0xb8,
|
||||||
|
0x24, 0x92, 0xf3, 0x73, 0xb1, 0x9a, 0xe2, 0xc4, 0x0d, 0xb1, 0x3e, 0x00, 0xe4, 0x9a, 0x28, 0x4e,
|
||||||
|
0xb8, 0x78, 0x12, 0x1b, 0xd8, 0x7d, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0c, 0xfb, 0x2d,
|
||||||
|
0x01, 0x0e, 0x01, 0x00, 0x00,
|
||||||
|
}
|
@ -5,6 +5,8 @@ option go_package = "transport";
|
|||||||
option java_package = "com.v2ray.core.transport";
|
option java_package = "com.v2ray.core.transport";
|
||||||
option java_outer_classname = "ConfigProto";
|
option java_outer_classname = "ConfigProto";
|
||||||
|
|
||||||
|
import "v2ray.com/core/transport/internet/config.proto";
|
||||||
|
|
||||||
message Config {
|
message Config {
|
||||||
|
repeated v2ray.core.transport.internet.NetworkSettings network_settings = 1;
|
||||||
}
|
}
|
@ -5,23 +5,57 @@ package transport
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
|
v2net "v2ray.com/core/common/net"
|
||||||
|
"v2ray.com/core/transport/internet"
|
||||||
"v2ray.com/core/transport/internet/kcp"
|
"v2ray.com/core/transport/internet/kcp"
|
||||||
"v2ray.com/core/transport/internet/tcp"
|
"v2ray.com/core/transport/internet/tcp"
|
||||||
"v2ray.com/core/transport/internet/ws"
|
"v2ray.com/core/transport/internet/ws"
|
||||||
|
|
||||||
|
"github.com/golang/protobuf/ptypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *Config) UnmarshalJSON(data []byte) error {
|
func (this *Config) UnmarshalJSON(data []byte) error {
|
||||||
type JsonConfig struct {
|
type JsonConfig struct {
|
||||||
TCPConfig *tcp.Config `json:"tcpSettings"`
|
TCPConfig *tcp.Config `json:"tcpSettings"`
|
||||||
KCPConfig kcp.Config `json:"kcpSettings"`
|
KCPConfig *kcp.Config `json:"kcpSettings"`
|
||||||
WSConfig *ws.Config `json:"wsSettings"`
|
WSConfig *ws.Config `json:"wsSettings"`
|
||||||
}
|
}
|
||||||
jsonConfig := &JsonConfig{}
|
jsonConfig := &JsonConfig{}
|
||||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
this.tcpConfig = jsonConfig.TCPConfig
|
|
||||||
this.kcpConfig = jsonConfig.KCPConfig
|
if jsonConfig.TCPConfig != nil {
|
||||||
this.wsConfig = jsonConfig.WSConfig
|
any, err := ptypes.MarshalAny(jsonConfig.TCPConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
this.NetworkSettings = append(this.NetworkSettings, &internet.NetworkSettings{
|
||||||
|
Network: v2net.Network_TCP,
|
||||||
|
Settings: any,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if jsonConfig.KCPConfig != nil {
|
||||||
|
any, err := ptypes.MarshalAny(jsonConfig.KCPConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
this.NetworkSettings = append(this.NetworkSettings, &internet.NetworkSettings{
|
||||||
|
Network: v2net.Network_KCP,
|
||||||
|
Settings: any,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if jsonConfig.WSConfig != nil {
|
||||||
|
any, err := ptypes.MarshalAny(jsonConfig.WSConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
this.NetworkSettings = append(this.NetworkSettings, &internet.NetworkSettings{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
Settings: any,
|
||||||
|
})
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,13 @@ Package internet is a generated protocol buffer package.
|
|||||||
|
|
||||||
It is generated from these files:
|
It is generated from these files:
|
||||||
v2ray.com/core/transport/internet/authenticator.proto
|
v2ray.com/core/transport/internet/authenticator.proto
|
||||||
|
v2ray.com/core/transport/internet/config.proto
|
||||||
|
|
||||||
It has these top-level messages:
|
It has these top-level messages:
|
||||||
AuthenticatorConfig
|
AuthenticatorConfig
|
||||||
|
SecuritySettings
|
||||||
|
NetworkSettings
|
||||||
|
StreamConfig
|
||||||
*/
|
*/
|
||||||
package internet
|
package internet
|
||||||
|
|
||||||
|
108
transport/internet/config.go
Normal file
108
transport/internet/config.go
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
package internet
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"v2ray.com/core/common/log"
|
||||||
|
v2net "v2ray.com/core/common/net"
|
||||||
|
v2tls "v2ray.com/core/transport/internet/tls"
|
||||||
|
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
"github.com/golang/protobuf/ptypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
type NetworkConfigCreator func() proto.Message
|
||||||
|
|
||||||
|
var (
|
||||||
|
globalNetworkConfigCreatorCache = make(map[v2net.Network]NetworkConfigCreator)
|
||||||
|
globalSecurityConfigCreatorCache = make(map[SecurityType]NetworkConfigCreator)
|
||||||
|
|
||||||
|
globalNetworkSettings []*NetworkSettings
|
||||||
|
|
||||||
|
ErrUnconfiguredNetwork = errors.New("Network config creator not set.")
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegisterNetworkConfigCreator(network v2net.Network, creator NetworkConfigCreator) error {
|
||||||
|
// TODO: check duplicate
|
||||||
|
globalNetworkConfigCreatorCache[network] = creator
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateNetworkConfig(network v2net.Network) (proto.Message, error) {
|
||||||
|
creator, ok := globalNetworkConfigCreatorCache[network]
|
||||||
|
if !ok {
|
||||||
|
log.Warning("Internet: Network config creator not found: ", network)
|
||||||
|
return nil, ErrUnconfiguredNetwork
|
||||||
|
}
|
||||||
|
return creator(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterSecurityConfigCreator(securityType SecurityType, creator NetworkConfigCreator) error {
|
||||||
|
globalSecurityConfigCreatorCache[securityType] = creator
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateSecurityConfig(securityType SecurityType) (proto.Message, error) {
|
||||||
|
creator, ok := globalSecurityConfigCreatorCache[securityType]
|
||||||
|
if !ok {
|
||||||
|
log.Warning("Internet: Security config creator not found: ", securityType)
|
||||||
|
return nil, ErrUnconfiguredNetwork
|
||||||
|
}
|
||||||
|
return creator(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *NetworkSettings) GetTypedSettings() (interface{}, error) {
|
||||||
|
message, err := CreateNetworkConfig(this.Network)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := ptypes.UnmarshalAny(this.Settings, message); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return message, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *SecuritySettings) GetTypeSettings() (interface{}, error) {
|
||||||
|
message, err := CreateSecurityConfig(this.Type)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := ptypes.UnmarshalAny(this.Settings, message); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return message, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *StreamConfig) GetEffectiveNetworkSettings() (interface{}, error) {
|
||||||
|
for _, settings := range this.NetworkSettings {
|
||||||
|
if settings.Network == this.Network {
|
||||||
|
return settings.GetTypedSettings()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, settings := range globalNetworkSettings {
|
||||||
|
if settings.Network == this.Network {
|
||||||
|
return settings.GetTypedSettings()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CreateNetworkConfig(this.Network)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *StreamConfig) GetEffectiveSecuritySettings() (interface{}, error) {
|
||||||
|
for _, settings := range this.SecuritySettings {
|
||||||
|
if settings.Type == this.SecurityType {
|
||||||
|
return settings.GetTypeSettings()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CreateSecurityConfig(this.SecurityType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ApplyGlobalNetworkSettings(settings []*NetworkSettings) error {
|
||||||
|
globalNetworkSettings = settings
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterSecurityConfigCreator(SecurityType_TLS, func() proto.Message {
|
||||||
|
return new(v2tls.Config)
|
||||||
|
})
|
||||||
|
}
|
132
transport/internet/config.pb.go
Normal file
132
transport/internet/config.pb.go
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
// Code generated by protoc-gen-go.
|
||||||
|
// source: v2ray.com/core/transport/internet/config.proto
|
||||||
|
// DO NOT EDIT!
|
||||||
|
|
||||||
|
package internet
|
||||||
|
|
||||||
|
import proto "github.com/golang/protobuf/proto"
|
||||||
|
import fmt "fmt"
|
||||||
|
import math "math"
|
||||||
|
import v2ray_core_common_net "v2ray.com/core/common/net"
|
||||||
|
import google_protobuf "github.com/golang/protobuf/ptypes/any"
|
||||||
|
|
||||||
|
// Reference imports to suppress errors if they are not otherwise used.
|
||||||
|
var _ = proto.Marshal
|
||||||
|
var _ = fmt.Errorf
|
||||||
|
var _ = math.Inf
|
||||||
|
|
||||||
|
type SecurityType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
SecurityType_None SecurityType = 0
|
||||||
|
SecurityType_TLS SecurityType = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
var SecurityType_name = map[int32]string{
|
||||||
|
0: "None",
|
||||||
|
1: "TLS",
|
||||||
|
}
|
||||||
|
var SecurityType_value = map[string]int32{
|
||||||
|
"None": 0,
|
||||||
|
"TLS": 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x SecurityType) String() string {
|
||||||
|
return proto.EnumName(SecurityType_name, int32(x))
|
||||||
|
}
|
||||||
|
func (SecurityType) EnumDescriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
|
||||||
|
|
||||||
|
type SecuritySettings struct {
|
||||||
|
Type SecurityType `protobuf:"varint,1,opt,name=type,enum=v2ray.core.transport.internet.SecurityType" json:"type,omitempty"`
|
||||||
|
Settings *google_protobuf.Any `protobuf:"bytes,2,opt,name=settings" json:"settings,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *SecuritySettings) Reset() { *m = SecuritySettings{} }
|
||||||
|
func (m *SecuritySettings) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*SecuritySettings) ProtoMessage() {}
|
||||||
|
func (*SecuritySettings) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
|
||||||
|
|
||||||
|
func (m *SecuritySettings) GetSettings() *google_protobuf.Any {
|
||||||
|
if m != nil {
|
||||||
|
return m.Settings
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type NetworkSettings struct {
|
||||||
|
Network v2ray_core_common_net.Network `protobuf:"varint,1,opt,name=network,enum=v2ray.core.common.net.Network" json:"network,omitempty"`
|
||||||
|
Settings *google_protobuf.Any `protobuf:"bytes,2,opt,name=settings" json:"settings,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *NetworkSettings) Reset() { *m = NetworkSettings{} }
|
||||||
|
func (m *NetworkSettings) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*NetworkSettings) ProtoMessage() {}
|
||||||
|
func (*NetworkSettings) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} }
|
||||||
|
|
||||||
|
func (m *NetworkSettings) GetSettings() *google_protobuf.Any {
|
||||||
|
if m != nil {
|
||||||
|
return m.Settings
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type StreamConfig struct {
|
||||||
|
Network v2ray_core_common_net.Network `protobuf:"varint,1,opt,name=network,enum=v2ray.core.common.net.Network" json:"network,omitempty"`
|
||||||
|
NetworkSettings []*NetworkSettings `protobuf:"bytes,2,rep,name=network_settings,json=networkSettings" json:"network_settings,omitempty"`
|
||||||
|
SecurityType SecurityType `protobuf:"varint,3,opt,name=security_type,json=securityType,enum=v2ray.core.transport.internet.SecurityType" json:"security_type,omitempty"`
|
||||||
|
SecuritySettings []*SecuritySettings `protobuf:"bytes,4,rep,name=security_settings,json=securitySettings" json:"security_settings,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *StreamConfig) Reset() { *m = StreamConfig{} }
|
||||||
|
func (m *StreamConfig) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*StreamConfig) ProtoMessage() {}
|
||||||
|
func (*StreamConfig) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{2} }
|
||||||
|
|
||||||
|
func (m *StreamConfig) GetNetworkSettings() []*NetworkSettings {
|
||||||
|
if m != nil {
|
||||||
|
return m.NetworkSettings
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *StreamConfig) GetSecuritySettings() []*SecuritySettings {
|
||||||
|
if m != nil {
|
||||||
|
return m.SecuritySettings
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
proto.RegisterType((*SecuritySettings)(nil), "v2ray.core.transport.internet.SecuritySettings")
|
||||||
|
proto.RegisterType((*NetworkSettings)(nil), "v2ray.core.transport.internet.NetworkSettings")
|
||||||
|
proto.RegisterType((*StreamConfig)(nil), "v2ray.core.transport.internet.StreamConfig")
|
||||||
|
proto.RegisterEnum("v2ray.core.transport.internet.SecurityType", SecurityType_name, SecurityType_value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() { proto.RegisterFile("v2ray.com/core/transport/internet/config.proto", fileDescriptor1) }
|
||||||
|
|
||||||
|
var fileDescriptor1 = []byte{
|
||||||
|
// 347 bytes of a gzipped FileDescriptorProto
|
||||||
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xa4, 0x91, 0x4f, 0x4b, 0xc3, 0x40,
|
||||||
|
0x10, 0xc5, 0x4d, 0x5b, 0x6c, 0x99, 0x56, 0x1b, 0x83, 0x87, 0x5a, 0x50, 0xda, 0x5e, 0x0c, 0x8a,
|
||||||
|
0xbb, 0x12, 0x2f, 0xde, 0x44, 0xbd, 0x4a, 0x91, 0xa4, 0x17, 0x45, 0x28, 0x69, 0x98, 0x86, 0xa0,
|
||||||
|
0xd9, 0x09, 0x9b, 0xad, 0x92, 0x83, 0x47, 0x3f, 0xa1, 0x5f, 0x48, 0x9a, 0x7f, 0x84, 0x1c, 0xea,
|
||||||
|
0xbf, 0xdb, 0x6e, 0xf2, 0xe6, 0xcd, 0x6f, 0xdf, 0x03, 0xf6, 0x6a, 0x49, 0x37, 0x61, 0x1e, 0x85,
|
||||||
|
0xdc, 0x23, 0x89, 0x5c, 0x49, 0x57, 0xc4, 0x11, 0x49, 0xc5, 0x03, 0xa1, 0x50, 0x0a, 0x54, 0xdc,
|
||||||
|
0x23, 0xb1, 0x0c, 0x7c, 0x16, 0x49, 0x52, 0x64, 0x1c, 0x16, 0x7a, 0x89, 0xac, 0xd4, 0xb2, 0x42,
|
||||||
|
0x3b, 0x3c, 0xae, 0xd9, 0x79, 0x14, 0x86, 0x24, 0xf8, 0xda, 0x46, 0xa0, 0x7a, 0x23, 0xf9, 0x9c,
|
||||||
|
0xf9, 0x0c, 0x0f, 0x7c, 0x22, 0xff, 0x05, 0x79, 0x7a, 0x5b, 0xac, 0x96, 0xdc, 0x15, 0x49, 0xf6,
|
||||||
|
0x6b, 0xf2, 0xa1, 0x81, 0xee, 0xa0, 0xb7, 0x92, 0x81, 0x4a, 0x1c, 0x54, 0x2a, 0x10, 0x7e, 0x6c,
|
||||||
|
0x5c, 0x41, 0x4b, 0x25, 0x11, 0x0e, 0xb4, 0x91, 0x66, 0xee, 0x5a, 0xa7, 0x6c, 0x23, 0x06, 0x2b,
|
||||||
|
0xc6, 0x67, 0x49, 0x84, 0x76, 0x3a, 0x68, 0x9c, 0x43, 0x27, 0xce, 0xcd, 0x06, 0x8d, 0x91, 0x66,
|
||||||
|
0x76, 0xad, 0x7d, 0x96, 0x31, 0xb0, 0x82, 0x81, 0x5d, 0x8b, 0xc4, 0x2e, 0x55, 0x93, 0x77, 0xe8,
|
||||||
|
0x4f, 0x33, 0xe6, 0x92, 0xe2, 0x12, 0xda, 0xf9, 0x33, 0x72, 0x90, 0xa3, 0x2a, 0x48, 0xf6, 0x58,
|
||||||
|
0xb6, 0x06, 0xc8, 0x07, 0xed, 0x42, 0xfe, 0x87, 0xf5, 0x9f, 0x0d, 0xe8, 0x39, 0x4a, 0xa2, 0x1b,
|
||||||
|
0xde, 0xa6, 0x05, 0xfc, 0x63, 0xf9, 0x03, 0xe8, 0xf9, 0x71, 0x5e, 0x81, 0x68, 0x9a, 0x5d, 0x8b,
|
||||||
|
0x7d, 0x13, 0x64, 0x2d, 0x00, 0xbb, 0x2f, 0x6a, 0x89, 0xdc, 0xc3, 0x4e, 0x9c, 0x87, 0x3d, 0x4f,
|
||||||
|
0x0b, 0x6a, 0xfe, 0xbe, 0xa0, 0x5e, 0x5c, 0xb9, 0x19, 0x4f, 0xb0, 0x57, 0x3a, 0x96, 0xb4, 0xad,
|
||||||
|
0x94, 0x96, 0xff, 0xd0, 0xb5, 0xc4, 0xd5, 0xe3, 0xda, 0x97, 0x93, 0x31, 0xf4, 0xaa, 0xbb, 0x8d,
|
||||||
|
0x0e, 0xb4, 0xa6, 0x24, 0x50, 0xdf, 0x32, 0xda, 0xd0, 0x9c, 0xdd, 0x39, 0xba, 0x76, 0x73, 0x06,
|
||||||
|
0x63, 0x8f, 0xc2, 0xcd, 0xab, 0x1e, 0x3b, 0xc5, 0x69, 0xb1, 0x9d, 0xf6, 0x77, 0xf1, 0x15, 0x00,
|
||||||
|
0x00, 0xff, 0xff, 0xb2, 0x2e, 0x36, 0x52, 0x4a, 0x03, 0x00, 0x00,
|
||||||
|
}
|
31
transport/internet/config.proto
Normal file
31
transport/internet/config.proto
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package v2ray.core.transport.internet;
|
||||||
|
option go_package = "internet";
|
||||||
|
option java_package = "com.v2ray.core.transport.internet";
|
||||||
|
|
||||||
|
import "v2ray.com/core/common/net/network.proto";
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
|
||||||
|
enum SecurityType {
|
||||||
|
None = 0;
|
||||||
|
TLS = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SecuritySettings {
|
||||||
|
SecurityType type = 1;
|
||||||
|
google.protobuf.Any settings = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message NetworkSettings {
|
||||||
|
v2ray.core.common.net.Network network = 1;
|
||||||
|
google.protobuf.Any settings = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StreamConfig {
|
||||||
|
v2ray.core.common.net.Network network = 1;
|
||||||
|
repeated NetworkSettings network_settings = 2;
|
||||||
|
SecurityType security_type = 3;
|
||||||
|
repeated SecuritySettings security_settings = 4;
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package internet
|
package internet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
|
||||||
"net"
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -12,56 +11,6 @@ type Reusable interface {
|
|||||||
SetReusable(reuse bool)
|
SetReusable(reuse bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
type StreamConnectionType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
StreamConnectionTypeRawTCP StreamConnectionType = 1
|
|
||||||
StreamConnectionTypeTCP StreamConnectionType = 2
|
|
||||||
StreamConnectionTypeKCP StreamConnectionType = 4
|
|
||||||
StreamConnectionTypeWebSocket StreamConnectionType = 8
|
|
||||||
)
|
|
||||||
|
|
||||||
type StreamSecurityType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
StreamSecurityTypeNone StreamSecurityType = 0
|
|
||||||
StreamSecurityTypeTLS StreamSecurityType = 1
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
globalSessionCache = tls.NewLRUClientSessionCache(128)
|
|
||||||
)
|
|
||||||
|
|
||||||
type TLSSettings struct {
|
|
||||||
AllowInsecure bool
|
|
||||||
Certs []tls.Certificate
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *TLSSettings) GetTLSConfig() *tls.Config {
|
|
||||||
config := &tls.Config{
|
|
||||||
ClientSessionCache: globalSessionCache,
|
|
||||||
}
|
|
||||||
if this == nil {
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
config.InsecureSkipVerify = this.AllowInsecure
|
|
||||||
config.Certificates = this.Certs
|
|
||||||
config.BuildNameToCertificate()
|
|
||||||
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
type StreamSettings struct {
|
|
||||||
Type StreamConnectionType
|
|
||||||
Security StreamSecurityType
|
|
||||||
TLSSettings *TLSSettings
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *StreamSettings) IsCapableOf(streamType StreamConnectionType) bool {
|
|
||||||
return (this.Type & streamType) == streamType
|
|
||||||
}
|
|
||||||
|
|
||||||
type Connection interface {
|
type Connection interface {
|
||||||
net.Conn
|
net.Conn
|
||||||
Reusable
|
Reusable
|
||||||
|
@ -3,65 +3,42 @@
|
|||||||
package internet
|
package internet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"errors"
|
||||||
|
"github.com/golang/protobuf/ptypes"
|
||||||
v2net "v2ray.com/core/common/net"
|
v2net "v2ray.com/core/common/net"
|
||||||
|
v2tls "v2ray.com/core/transport/internet/tls"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *TLSSettings) UnmarshalJSON(data []byte) error {
|
func (this *StreamConfig) UnmarshalJSON(data []byte) error {
|
||||||
type JSONCertConfig struct {
|
|
||||||
CertFile string `json:"certificateFile"`
|
|
||||||
KeyFile string `json:"keyFile"`
|
|
||||||
}
|
|
||||||
type JSONConfig struct {
|
type JSONConfig struct {
|
||||||
Insecure bool `json:"allowInsecure"`
|
Network *v2net.Network `json:"network"`
|
||||||
Certs []*JSONCertConfig `json:"certificates"`
|
Security string `json:"security"`
|
||||||
|
TLSSettings *v2tls.Config `json:"tlsSettings"`
|
||||||
}
|
}
|
||||||
|
this.Network = v2net.Network_RawTCP
|
||||||
jsonConfig := new(JSONConfig)
|
jsonConfig := new(JSONConfig)
|
||||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
this.Certs = make([]tls.Certificate, len(jsonConfig.Certs))
|
if jsonConfig.Network != nil {
|
||||||
for idx, certConf := range jsonConfig.Certs {
|
this.Network = *jsonConfig.Network
|
||||||
cert, err := tls.LoadX509KeyPair(certConf.CertFile, certConf.KeyFile)
|
|
||||||
if err != nil {
|
|
||||||
return errors.New("Internet|TLS: Failed to load certificate file: " + err.Error())
|
|
||||||
}
|
|
||||||
this.Certs[idx] = cert
|
|
||||||
}
|
}
|
||||||
this.AllowInsecure = jsonConfig.Insecure
|
this.SecurityType = SecurityType_None
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *StreamSettings) UnmarshalJSON(data []byte) error {
|
|
||||||
type JSONConfig struct {
|
|
||||||
Network v2net.NetworkList `json:"network"`
|
|
||||||
Security string `json:"security"`
|
|
||||||
TLSSettings *TLSSettings `json:"tlsSettings"`
|
|
||||||
}
|
|
||||||
this.Type = StreamConnectionTypeRawTCP
|
|
||||||
jsonConfig := new(JSONConfig)
|
|
||||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if jsonConfig.Network.HasNetwork(v2net.Network_KCP) {
|
|
||||||
this.Type |= StreamConnectionTypeKCP
|
|
||||||
}
|
|
||||||
if jsonConfig.Network.HasNetwork(v2net.Network_WebSocket) {
|
|
||||||
this.Type |= StreamConnectionTypeWebSocket
|
|
||||||
}
|
|
||||||
if jsonConfig.Network.HasNetwork(v2net.Network_TCP) {
|
|
||||||
this.Type |= StreamConnectionTypeTCP
|
|
||||||
}
|
|
||||||
this.Security = StreamSecurityTypeNone
|
|
||||||
if strings.ToLower(jsonConfig.Security) == "tls" {
|
if strings.ToLower(jsonConfig.Security) == "tls" {
|
||||||
this.Security = StreamSecurityTypeTLS
|
this.SecurityType = SecurityType_TLS
|
||||||
}
|
}
|
||||||
if jsonConfig.TLSSettings != nil {
|
if jsonConfig.TLSSettings != nil {
|
||||||
this.TLSSettings = jsonConfig.TLSSettings
|
anyTLSSettings, err := ptypes.MarshalAny(jsonConfig.TLSSettings)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("Internet: Failed to parse TLS settings: " + err.Error())
|
||||||
|
}
|
||||||
|
this.SecuritySettings = append(this.SecuritySettings, &SecuritySettings{
|
||||||
|
Type: SecurityType_TLS,
|
||||||
|
Settings: anyTLSSettings,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type DialerOptions struct {
|
type DialerOptions struct {
|
||||||
Stream *StreamSettings
|
Stream *StreamConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
type Dialer func(src v2net.Address, dest v2net.Destination, options DialerOptions) (Connection, error)
|
type Dialer func(src v2net.Address, dest v2net.Destination, options DialerOptions) (Connection, error)
|
||||||
@ -25,7 +25,7 @@ var (
|
|||||||
WSDialer Dialer
|
WSDialer Dialer
|
||||||
)
|
)
|
||||||
|
|
||||||
func Dial(src v2net.Address, dest v2net.Destination, settings *StreamSettings) (Connection, error) {
|
func Dial(src v2net.Address, dest v2net.Destination, settings *StreamConfig) (Connection, error) {
|
||||||
|
|
||||||
var connection Connection
|
var connection Connection
|
||||||
var err error
|
var err error
|
||||||
@ -33,16 +33,16 @@ func Dial(src v2net.Address, dest v2net.Destination, settings *StreamSettings) (
|
|||||||
Stream: settings,
|
Stream: settings,
|
||||||
}
|
}
|
||||||
if dest.Network == v2net.Network_TCP {
|
if dest.Network == v2net.Network_TCP {
|
||||||
switch {
|
switch settings.Network {
|
||||||
case settings.IsCapableOf(StreamConnectionTypeTCP):
|
case v2net.Network_TCP:
|
||||||
connection, err = TCPDialer(src, dest, dialerOptions)
|
connection, err = TCPDialer(src, dest, dialerOptions)
|
||||||
case settings.IsCapableOf(StreamConnectionTypeKCP):
|
case v2net.Network_KCP:
|
||||||
connection, err = KCPDialer(src, dest, dialerOptions)
|
connection, err = KCPDialer(src, dest, dialerOptions)
|
||||||
case settings.IsCapableOf(StreamConnectionTypeWebSocket):
|
case v2net.Network_WebSocket:
|
||||||
connection, err = WSDialer(src, dest, dialerOptions)
|
connection, err = WSDialer(src, dest, dialerOptions)
|
||||||
|
|
||||||
// This check has to be the last one.
|
// This check has to be the last one.
|
||||||
case settings.IsCapableOf(StreamConnectionTypeRawTCP):
|
case v2net.Network_RawTCP:
|
||||||
connection, err = RawTCPDialer(src, dest, dialerOptions)
|
connection, err = RawTCPDialer(src, dest, dialerOptions)
|
||||||
default:
|
default:
|
||||||
return nil, ErrUnsupportedStreamType
|
return nil, ErrUnsupportedStreamType
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
package kcp
|
package kcp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
v2net "v2ray.com/core/common/net"
|
||||||
"v2ray.com/core/transport/internet"
|
"v2ray.com/core/transport/internet"
|
||||||
|
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *MTU) GetValue() uint32 {
|
func (this *MTU) GetValue() uint32 {
|
||||||
@ -46,10 +49,6 @@ func (this *ReadBuffer) GetSize() uint32 {
|
|||||||
return this.Size
|
return this.Size
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Config) Apply() {
|
|
||||||
effectiveConfig = *this
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *Config) GetAuthenticator() (internet.Authenticator, error) {
|
func (this *Config) GetAuthenticator() (internet.Authenticator, error) {
|
||||||
auth := NewSimpleAuthenticator()
|
auth := NewSimpleAuthenticator()
|
||||||
if this.HeaderConfig != nil {
|
if this.HeaderConfig != nil {
|
||||||
@ -86,6 +85,8 @@ func (this *Config) GetReceivingBufferSize() uint32 {
|
|||||||
return this.GetReceivingInFlightSize() + this.ReadBuffer.GetSize()/this.Mtu.GetValue()
|
return this.GetReceivingInFlightSize() + this.ReadBuffer.GetSize()/this.Mtu.GetValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
func init() {
|
||||||
effectiveConfig Config
|
internet.RegisterNetworkConfigCreator(v2net.Network_KCP, func() proto.Message {
|
||||||
)
|
return new(Config)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -129,6 +129,7 @@ type Connection struct {
|
|||||||
since int64
|
since int64
|
||||||
dataInputCond *sync.Cond
|
dataInputCond *sync.Cond
|
||||||
dataOutputCond *sync.Cond
|
dataOutputCond *sync.Cond
|
||||||
|
Config *Config
|
||||||
|
|
||||||
conv uint16
|
conv uint16
|
||||||
state State
|
state State
|
||||||
@ -149,7 +150,7 @@ type Connection struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewConnection create a new KCP connection between local and remote.
|
// NewConnection create a new KCP connection between local and remote.
|
||||||
func NewConnection(conv uint16, writerCloser io.WriteCloser, local *net.UDPAddr, remote *net.UDPAddr, block internet.Authenticator) *Connection {
|
func NewConnection(conv uint16, writerCloser io.WriteCloser, local *net.UDPAddr, remote *net.UDPAddr, block internet.Authenticator, config *Config) *Connection {
|
||||||
log.Info("KCP|Connection: creating connection ", conv)
|
log.Info("KCP|Connection: creating connection ", conv)
|
||||||
|
|
||||||
conn := new(Connection)
|
conn := new(Connection)
|
||||||
@ -160,10 +161,12 @@ func NewConnection(conv uint16, writerCloser io.WriteCloser, local *net.UDPAddr,
|
|||||||
conn.since = nowMillisec()
|
conn.since = nowMillisec()
|
||||||
conn.dataInputCond = sync.NewCond(new(sync.Mutex))
|
conn.dataInputCond = sync.NewCond(new(sync.Mutex))
|
||||||
conn.dataOutputCond = sync.NewCond(new(sync.Mutex))
|
conn.dataOutputCond = sync.NewCond(new(sync.Mutex))
|
||||||
|
conn.Config = config
|
||||||
|
|
||||||
authWriter := &AuthenticationWriter{
|
authWriter := &AuthenticationWriter{
|
||||||
Authenticator: block,
|
Authenticator: block,
|
||||||
Writer: writerCloser,
|
Writer: writerCloser,
|
||||||
|
Config: config,
|
||||||
}
|
}
|
||||||
conn.conv = conv
|
conn.conv = conv
|
||||||
conn.output = NewSegmentWriter(authWriter)
|
conn.output = NewSegmentWriter(authWriter)
|
||||||
@ -171,12 +174,12 @@ func NewConnection(conv uint16, writerCloser io.WriteCloser, local *net.UDPAddr,
|
|||||||
conn.mss = authWriter.Mtu() - DataSegmentOverhead
|
conn.mss = authWriter.Mtu() - DataSegmentOverhead
|
||||||
conn.roundTrip = &RoundTripInfo{
|
conn.roundTrip = &RoundTripInfo{
|
||||||
rto: 100,
|
rto: 100,
|
||||||
minRtt: effectiveConfig.Tti.GetValue(),
|
minRtt: config.Tti.GetValue(),
|
||||||
}
|
}
|
||||||
conn.interval = effectiveConfig.Tti.GetValue()
|
conn.interval = config.Tti.GetValue()
|
||||||
conn.receivingWorker = NewReceivingWorker(conn)
|
conn.receivingWorker = NewReceivingWorker(conn)
|
||||||
conn.fastresend = 2
|
conn.fastresend = 2
|
||||||
conn.congestionControl = effectiveConfig.Congestion
|
conn.congestionControl = config.Congestion
|
||||||
conn.sendingWorker = NewSendingWorker(conn)
|
conn.sendingWorker = NewSendingWorker(conn)
|
||||||
|
|
||||||
go conn.updateTask()
|
go conn.updateTask()
|
||||||
@ -366,7 +369,7 @@ func (this *Connection) updateTask() {
|
|||||||
for this.State() != StateTerminated {
|
for this.State() != StateTerminated {
|
||||||
this.flush()
|
this.flush()
|
||||||
|
|
||||||
interval := time.Duration(effectiveConfig.Tti.GetValue()) * time.Millisecond
|
interval := time.Duration(this.Config.Tti.GetValue()) * time.Millisecond
|
||||||
if this.State() == StateTerminating {
|
if this.State() == StateTerminating {
|
||||||
interval = time.Second
|
interval = time.Second
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ func (this *NoOpWriteCloser) Close() error {
|
|||||||
func TestConnectionReadTimeout(t *testing.T) {
|
func TestConnectionReadTimeout(t *testing.T) {
|
||||||
assert := assert.On(t)
|
assert := assert.On(t)
|
||||||
|
|
||||||
conn := NewConnection(1, &NoOpWriteCloser{}, nil, nil, NewSimpleAuthenticator())
|
conn := NewConnection(1, &NoOpWriteCloser{}, nil, nil, NewSimpleAuthenticator(), &Config{})
|
||||||
conn.SetReadDeadline(time.Now().Add(time.Second))
|
conn.SetReadDeadline(time.Now().Add(time.Second))
|
||||||
|
|
||||||
b := make([]byte, 1024)
|
b := make([]byte, 1024)
|
||||||
@ -44,10 +44,10 @@ func TestConnectionReadWrite(t *testing.T) {
|
|||||||
|
|
||||||
auth := internet.NewAuthenticatorChain(srtp.SRTPFactory{}.Create(nil), NewSimpleAuthenticator())
|
auth := internet.NewAuthenticatorChain(srtp.SRTPFactory{}.Create(nil), NewSimpleAuthenticator())
|
||||||
|
|
||||||
connClient := NewConnection(1, upWriter, &net.UDPAddr{IP: v2net.LocalHostIP.IP(), Port: 1}, &net.UDPAddr{IP: v2net.LocalHostIP.IP(), Port: 2}, auth)
|
connClient := NewConnection(1, upWriter, &net.UDPAddr{IP: v2net.LocalHostIP.IP(), Port: 1}, &net.UDPAddr{IP: v2net.LocalHostIP.IP(), Port: 2}, auth, &Config{})
|
||||||
connClient.FetchInputFrom(downReader)
|
connClient.FetchInputFrom(downReader)
|
||||||
|
|
||||||
connServer := NewConnection(1, downWriter, &net.UDPAddr{IP: v2net.LocalHostIP.IP(), Port: 2}, &net.UDPAddr{IP: v2net.LocalHostIP.IP(), Port: 1}, auth)
|
connServer := NewConnection(1, downWriter, &net.UDPAddr{IP: v2net.LocalHostIP.IP(), Port: 2}, &net.UDPAddr{IP: v2net.LocalHostIP.IP(), Port: 1}, auth, &Config{})
|
||||||
connServer.FetchInputFrom(upReader)
|
connServer.FetchInputFrom(upReader)
|
||||||
|
|
||||||
totalWritten := 1024 * 1024
|
totalWritten := 1024 * 1024
|
||||||
|
@ -25,20 +25,32 @@ func DialKCP(src v2net.Address, dest v2net.Destination, options internet.DialerO
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cpip, err := effectiveConfig.GetAuthenticator()
|
networkSettings, err := options.Stream.GetEffectiveNetworkSettings()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("KCP|Dialer: Failed to get KCP settings: ", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
kcpSettings := networkSettings.(*Config)
|
||||||
|
|
||||||
|
cpip, err := kcpSettings.GetAuthenticator()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("KCP|Dialer: Failed to create authenticator: ", err)
|
log.Error("KCP|Dialer: Failed to create authenticator: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
conv := uint16(atomic.AddUint32(&globalConv, 1))
|
conv := uint16(atomic.AddUint32(&globalConv, 1))
|
||||||
session := NewConnection(conv, conn, conn.LocalAddr().(*net.UDPAddr), conn.RemoteAddr().(*net.UDPAddr), cpip)
|
session := NewConnection(conv, conn, conn.LocalAddr().(*net.UDPAddr), conn.RemoteAddr().(*net.UDPAddr), cpip, kcpSettings)
|
||||||
session.FetchInputFrom(conn)
|
session.FetchInputFrom(conn)
|
||||||
|
|
||||||
var iConn internet.Connection
|
var iConn internet.Connection
|
||||||
iConn = session
|
iConn = session
|
||||||
|
|
||||||
if options.Stream != nil && options.Stream.Security == internet.StreamSecurityTypeTLS {
|
if options.Stream != nil && options.Stream.SecurityType == internet.SecurityType_TLS {
|
||||||
config := options.Stream.TLSSettings.GetTLSConfig()
|
securitySettings, err := options.Stream.GetEffectiveSecuritySettings()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("KCP|Dialer: Failed to apply TLS config: ", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config := securitySettings.(*v2tls.Config).GetTLSConfig()
|
||||||
if dest.Address.Family().IsDomain() {
|
if dest.Address.Family().IsDomain() {
|
||||||
config.ServerName = dest.Address.Domain()
|
config.ServerName = dest.Address.Domain()
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,28 @@ import (
|
|||||||
"v2ray.com/core/testing/assert"
|
"v2ray.com/core/testing/assert"
|
||||||
"v2ray.com/core/transport/internet"
|
"v2ray.com/core/transport/internet"
|
||||||
. "v2ray.com/core/transport/internet/kcp"
|
. "v2ray.com/core/transport/internet/kcp"
|
||||||
|
|
||||||
|
"github.com/golang/protobuf/ptypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDialAndListen(t *testing.T) {
|
func TestDialAndListen(t *testing.T) {
|
||||||
assert := assert.On(t)
|
assert := assert.On(t)
|
||||||
|
|
||||||
listerner, err := NewListener(v2net.LocalHostIP, v2net.Port(0), internet.ListenOptions{})
|
kcpSettings := new(Config)
|
||||||
|
anySettings, err := ptypes.MarshalAny(kcpSettings)
|
||||||
|
assert.Error(err).IsNil()
|
||||||
|
|
||||||
|
listerner, err := NewListener(v2net.LocalHostIP, v2net.Port(0), internet.ListenOptions{
|
||||||
|
Stream: &internet.StreamConfig{
|
||||||
|
Network: v2net.Network_KCP,
|
||||||
|
NetworkSettings: []*internet.NetworkSettings{
|
||||||
|
{
|
||||||
|
Network: v2net.Network_KCP,
|
||||||
|
Settings: anySettings,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
port := v2net.Port(listerner.Addr().(*net.UDPAddr).Port)
|
port := v2net.Port(listerner.Addr().(*net.UDPAddr).Port)
|
||||||
|
|
||||||
@ -46,7 +62,17 @@ func TestDialAndListen(t *testing.T) {
|
|||||||
|
|
||||||
wg := new(sync.WaitGroup)
|
wg := new(sync.WaitGroup)
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
clientConn, err := DialKCP(v2net.LocalHostIP, v2net.UDPDestination(v2net.LocalHostIP, port), internet.DialerOptions{})
|
clientConn, err := DialKCP(v2net.LocalHostIP, v2net.UDPDestination(v2net.LocalHostIP, port), internet.DialerOptions{
|
||||||
|
Stream: &internet.StreamConfig{
|
||||||
|
Network: v2net.Network_KCP,
|
||||||
|
NetworkSettings: []*internet.NetworkSettings{
|
||||||
|
{
|
||||||
|
Network: v2net.Network_KCP,
|
||||||
|
Settings: anySettings,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
|
||||||
|
@ -25,10 +25,18 @@ type Listener struct {
|
|||||||
awaitingConns chan *Connection
|
awaitingConns chan *Connection
|
||||||
hub *udp.UDPHub
|
hub *udp.UDPHub
|
||||||
tlsConfig *tls.Config
|
tlsConfig *tls.Config
|
||||||
|
config *Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewListener(address v2net.Address, port v2net.Port, options internet.ListenOptions) (*Listener, error) {
|
func NewListener(address v2net.Address, port v2net.Port, options internet.ListenOptions) (*Listener, error) {
|
||||||
auth, err := effectiveConfig.GetAuthenticator()
|
networkSettings, err := options.Stream.GetEffectiveNetworkSettings()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("KCP|Listener: Failed to get KCP settings: ", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
kcpSettings := networkSettings.(*Config)
|
||||||
|
|
||||||
|
auth, err := kcpSettings.GetAuthenticator()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -37,9 +45,15 @@ func NewListener(address v2net.Address, port v2net.Port, options internet.Listen
|
|||||||
sessions: make(map[string]*Connection),
|
sessions: make(map[string]*Connection),
|
||||||
awaitingConns: make(chan *Connection, 64),
|
awaitingConns: make(chan *Connection, 64),
|
||||||
running: true,
|
running: true,
|
||||||
|
config: kcpSettings,
|
||||||
}
|
}
|
||||||
if options.Stream != nil && options.Stream.Security == internet.StreamSecurityTypeTLS {
|
if options.Stream != nil && options.Stream.SecurityType == internet.SecurityType_TLS {
|
||||||
l.tlsConfig = options.Stream.TLSSettings.GetTLSConfig()
|
securitySettings, err := options.Stream.GetEffectiveSecuritySettings()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("KCP|Listener: Failed to apply TLS config: ", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
l.tlsConfig = securitySettings.(*v2tls.Config).GetTLSConfig()
|
||||||
}
|
}
|
||||||
hub, err := udp.ListenUDP(address, port, udp.ListenOption{Callback: l.OnReceive})
|
hub, err := udp.ListenUDP(address, port, udp.ListenOption{Callback: l.OnReceive})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -89,11 +103,11 @@ func (this *Listener) OnReceive(payload *alloc.Buffer, session *proxy.SessionInf
|
|||||||
IP: src.Address.IP(),
|
IP: src.Address.IP(),
|
||||||
Port: int(src.Port),
|
Port: int(src.Port),
|
||||||
}
|
}
|
||||||
auth, err := effectiveConfig.GetAuthenticator()
|
auth, err := this.config.GetAuthenticator()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("KCP|Listener: Failed to create authenticator: ", err)
|
log.Error("KCP|Listener: Failed to create authenticator: ", err)
|
||||||
}
|
}
|
||||||
conn = NewConnection(conv, writer, this.Addr().(*net.UDPAddr), srcAddr, auth)
|
conn = NewConnection(conv, writer, this.Addr().(*net.UDPAddr), srcAddr, auth, this.config)
|
||||||
select {
|
select {
|
||||||
case this.awaitingConns <- conn:
|
case this.awaitingConns <- conn:
|
||||||
case <-time.After(time.Second * 5):
|
case <-time.After(time.Second * 5):
|
||||||
|
@ -62,6 +62,7 @@ func (this *BufferedSegmentWriter) Flush() {
|
|||||||
type AuthenticationWriter struct {
|
type AuthenticationWriter struct {
|
||||||
Authenticator internet.Authenticator
|
Authenticator internet.Authenticator
|
||||||
Writer io.Writer
|
Writer io.Writer
|
||||||
|
Config *Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *AuthenticationWriter) Write(payload *alloc.Buffer) error {
|
func (this *AuthenticationWriter) Write(payload *alloc.Buffer) error {
|
||||||
@ -75,5 +76,5 @@ func (this *AuthenticationWriter) Write(payload *alloc.Buffer) error {
|
|||||||
func (this *AuthenticationWriter) Release() {}
|
func (this *AuthenticationWriter) Release() {}
|
||||||
|
|
||||||
func (this *AuthenticationWriter) Mtu() uint32 {
|
func (this *AuthenticationWriter) Mtu() uint32 {
|
||||||
return effectiveConfig.Mtu.GetValue() - uint32(this.Authenticator.Overhead())
|
return this.Config.Mtu.GetValue() - uint32(this.Authenticator.Overhead())
|
||||||
}
|
}
|
||||||
|
@ -124,8 +124,8 @@ type ReceivingWorker struct {
|
|||||||
func NewReceivingWorker(kcp *Connection) *ReceivingWorker {
|
func NewReceivingWorker(kcp *Connection) *ReceivingWorker {
|
||||||
worker := &ReceivingWorker{
|
worker := &ReceivingWorker{
|
||||||
conn: kcp,
|
conn: kcp,
|
||||||
window: NewReceivingWindow(effectiveConfig.GetReceivingBufferSize()),
|
window: NewReceivingWindow(kcp.Config.GetReceivingBufferSize()),
|
||||||
windowSize: effectiveConfig.GetReceivingInFlightSize(),
|
windowSize: kcp.Config.GetReceivingInFlightSize(),
|
||||||
}
|
}
|
||||||
worker.acklist = NewAckList(worker)
|
worker.acklist = NewAckList(worker)
|
||||||
return worker
|
return worker
|
||||||
|
@ -185,9 +185,9 @@ func NewSendingWorker(kcp *Connection) *SendingWorker {
|
|||||||
conn: kcp,
|
conn: kcp,
|
||||||
fastResend: 2,
|
fastResend: 2,
|
||||||
remoteNextNumber: 32,
|
remoteNextNumber: 32,
|
||||||
controlWindow: effectiveConfig.GetSendingInFlightSize(),
|
controlWindow: kcp.Config.GetSendingInFlightSize(),
|
||||||
}
|
}
|
||||||
worker.window = NewSendingWindow(effectiveConfig.GetSendingBufferSize(), worker, worker.OnPacketLoss)
|
worker.window = NewSendingWindow(kcp.Config.GetSendingBufferSize(), worker, worker.OnPacketLoss)
|
||||||
return worker
|
return worker
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,7 +291,7 @@ func (this *SendingWorker) Write(seg Segment) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *SendingWorker) OnPacketLoss(lossRate uint32) {
|
func (this *SendingWorker) OnPacketLoss(lossRate uint32) {
|
||||||
if !effectiveConfig.Congestion || this.conn.roundTrip.Timeout() == 0 {
|
if !this.conn.Config.Congestion || this.conn.roundTrip.Timeout() == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,8 +303,8 @@ func (this *SendingWorker) OnPacketLoss(lossRate uint32) {
|
|||||||
if this.controlWindow < 16 {
|
if this.controlWindow < 16 {
|
||||||
this.controlWindow = 16
|
this.controlWindow = 16
|
||||||
}
|
}
|
||||||
if this.controlWindow > 2*effectiveConfig.GetSendingInFlightSize() {
|
if this.controlWindow > 2*this.conn.Config.GetSendingInFlightSize() {
|
||||||
this.controlWindow = 2 * effectiveConfig.GetSendingInFlightSize()
|
this.controlWindow = 2 * this.conn.Config.GetSendingInFlightSize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,11 +312,11 @@ func (this *SendingWorker) Flush(current uint32) {
|
|||||||
this.Lock()
|
this.Lock()
|
||||||
defer this.Unlock()
|
defer this.Unlock()
|
||||||
|
|
||||||
cwnd := this.firstUnacknowledged + effectiveConfig.GetSendingInFlightSize()
|
cwnd := this.firstUnacknowledged + this.conn.Config.GetSendingInFlightSize()
|
||||||
if cwnd > this.remoteNextNumber {
|
if cwnd > this.remoteNextNumber {
|
||||||
cwnd = this.remoteNextNumber
|
cwnd = this.remoteNextNumber
|
||||||
}
|
}
|
||||||
if effectiveConfig.Congestion && cwnd > this.firstUnacknowledged+this.controlWindow {
|
if this.conn.Config.Congestion && cwnd > this.firstUnacknowledged+this.controlWindow {
|
||||||
cwnd = this.firstUnacknowledged + this.controlWindow
|
cwnd = this.firstUnacknowledged + this.controlWindow
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
package tcp
|
package tcp
|
||||||
|
|
||||||
type Config struct {
|
import (
|
||||||
ConnectionReuse bool
|
v2net "v2ray.com/core/common/net"
|
||||||
}
|
"v2ray.com/core/transport/internet"
|
||||||
|
|
||||||
func (this *Config) Apply() {
|
"github.com/golang/protobuf/proto"
|
||||||
effectiveConfig = this
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
effectiveConfig = &Config{
|
|
||||||
ConnectionReuse: true,
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
internet.RegisterNetworkConfigCreator(v2net.Network_TCP, func() proto.Message {
|
||||||
|
return new(Config)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
58
transport/internet/tcp/config.pb.go
Normal file
58
transport/internet/tcp/config.pb.go
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
// Code generated by protoc-gen-go.
|
||||||
|
// source: v2ray.com/core/transport/internet/tcp/config.proto
|
||||||
|
// DO NOT EDIT!
|
||||||
|
|
||||||
|
/*
|
||||||
|
Package tcp is a generated protocol buffer package.
|
||||||
|
|
||||||
|
It is generated from these files:
|
||||||
|
v2ray.com/core/transport/internet/tcp/config.proto
|
||||||
|
|
||||||
|
It has these top-level messages:
|
||||||
|
Config
|
||||||
|
*/
|
||||||
|
package tcp
|
||||||
|
|
||||||
|
import proto "github.com/golang/protobuf/proto"
|
||||||
|
import fmt "fmt"
|
||||||
|
import math "math"
|
||||||
|
|
||||||
|
// Reference imports to suppress errors if they are not otherwise used.
|
||||||
|
var _ = proto.Marshal
|
||||||
|
var _ = fmt.Errorf
|
||||||
|
var _ = math.Inf
|
||||||
|
|
||||||
|
// This is a compile-time assertion to ensure that this generated file
|
||||||
|
// is compatible with the proto package it is being compiled against.
|
||||||
|
// A compilation error at this line likely means your copy of the
|
||||||
|
// proto package needs to be updated.
|
||||||
|
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
ConnectionReuse bool `protobuf:"varint,1,opt,name=connection_reuse,json=connectionReuse" json:"connection_reuse,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Config) Reset() { *m = Config{} }
|
||||||
|
func (m *Config) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*Config) ProtoMessage() {}
|
||||||
|
func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
proto.RegisterType((*Config)(nil), "v2ray.core.transport.internet.tcp.Config")
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() { proto.RegisterFile("v2ray.com/core/transport/internet/tcp/config.proto", fileDescriptor0) }
|
||||||
|
|
||||||
|
var fileDescriptor0 = []byte{
|
||||||
|
// 158 bytes of a gzipped FileDescriptorProto
|
||||||
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x84, 0x8e, 0xb1, 0x0a, 0xc2, 0x50,
|
||||||
|
0x0c, 0x45, 0x29, 0x42, 0x91, 0xe7, 0xa0, 0x74, 0x72, 0x54, 0x41, 0xd0, 0x25, 0x0f, 0xda, 0xc9,
|
||||||
|
0xb5, 0xfe, 0x80, 0x74, 0x74, 0x91, 0x1a, 0xa2, 0x74, 0x68, 0x12, 0xd2, 0x28, 0xf8, 0xf7, 0xd2,
|
||||||
|
0x4a, 0x75, 0x74, 0xbd, 0xdc, 0x73, 0x38, 0x21, 0x7f, 0xe6, 0x56, 0xbf, 0x00, 0xa5, 0x8d, 0x28,
|
||||||
|
0x46, 0xd1, 0xad, 0xe6, 0x4e, 0xc5, 0x3c, 0x36, 0xec, 0x64, 0x4c, 0x1e, 0x1d, 0x35, 0xa2, 0xf0,
|
||||||
|
0xad, 0xb9, 0x83, 0x9a, 0xb8, 0x64, 0xeb, 0x91, 0x31, 0x82, 0xef, 0x1f, 0xc6, 0x3f, 0x38, 0xea,
|
||||||
|
0xa6, 0x08, 0xe9, 0x71, 0x40, 0xb2, 0x7d, 0x58, 0xa0, 0x30, 0x13, 0x7a, 0x23, 0x7c, 0x31, 0x7a,
|
||||||
|
0x74, 0xb4, 0x4c, 0x56, 0xc9, 0x6e, 0x5a, 0xcd, 0x7f, 0x7b, 0xd5, 0xcf, 0xe5, 0x21, 0x6c, 0x51,
|
||||||
|
0x5a, 0xf8, 0x6b, 0x2f, 0x67, 0x1f, 0xf7, 0xa9, 0xaf, 0x39, 0x4f, 0x1c, 0xf5, 0x9a, 0x0e, 0x65,
|
||||||
|
0xc5, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa0, 0xa8, 0x3f, 0xcf, 0x00, 0x00, 0x00,
|
||||||
|
}
|
10
transport/internet/tcp/config.proto
Normal file
10
transport/internet/tcp/config.proto
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package v2ray.core.transport.internet.tcp;
|
||||||
|
option go_package = "tcp";
|
||||||
|
option java_package = "com.v2ray.core.transport.internet.tcp";
|
||||||
|
option java_outer_classname = "ConfigProto";
|
||||||
|
|
||||||
|
message Config {
|
||||||
|
bool connection_reuse = 1;
|
||||||
|
}
|
@ -31,14 +31,16 @@ type Connection struct {
|
|||||||
conn net.Conn
|
conn net.Conn
|
||||||
listener ConnectionManager
|
listener ConnectionManager
|
||||||
reusable bool
|
reusable bool
|
||||||
|
config *Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConnection(dest string, conn net.Conn, manager ConnectionManager) *Connection {
|
func NewConnection(dest string, conn net.Conn, manager ConnectionManager, config *Config) *Connection {
|
||||||
return &Connection{
|
return &Connection{
|
||||||
dest: dest,
|
dest: dest,
|
||||||
conn: conn,
|
conn: conn,
|
||||||
listener: manager,
|
listener: manager,
|
||||||
reusable: effectiveConfig.ConnectionReuse,
|
reusable: config.ConnectionReuse,
|
||||||
|
config: config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +93,7 @@ func (this *Connection) SetWriteDeadline(t time.Time) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *Connection) SetReusable(reusable bool) {
|
func (this *Connection) SetReusable(reusable bool) {
|
||||||
if !effectiveConfig.ConnectionReuse {
|
if !this.config.ConnectionReuse {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.reusable = reusable
|
this.reusable = reusable
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"v2ray.com/core/common/log"
|
"v2ray.com/core/common/log"
|
||||||
v2net "v2ray.com/core/common/net"
|
v2net "v2ray.com/core/common/net"
|
||||||
"v2ray.com/core/transport/internet"
|
"v2ray.com/core/transport/internet"
|
||||||
|
v2tls "v2ray.com/core/transport/internet/tls"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -18,9 +19,15 @@ func Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOpti
|
|||||||
if src == nil {
|
if src == nil {
|
||||||
src = v2net.AnyIP
|
src = v2net.AnyIP
|
||||||
}
|
}
|
||||||
|
networkSettings, err := options.Stream.GetEffectiveNetworkSettings()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tcpSettings := networkSettings.(*Config)
|
||||||
|
|
||||||
id := src.String() + "-" + dest.NetAddr()
|
id := src.String() + "-" + dest.NetAddr()
|
||||||
var conn net.Conn
|
var conn net.Conn
|
||||||
if dest.Network == v2net.Network_TCP && effectiveConfig.ConnectionReuse {
|
if dest.Network == v2net.Network_TCP && tcpSettings.ConnectionReuse {
|
||||||
conn = globalCache.Get(id)
|
conn = globalCache.Get(id)
|
||||||
}
|
}
|
||||||
if conn == nil {
|
if conn == nil {
|
||||||
@ -30,14 +37,19 @@ func Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOpti
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if options.Stream != nil && options.Stream.Security == internet.StreamSecurityTypeTLS {
|
if options.Stream != nil && options.Stream.SecurityType == internet.SecurityType_TLS {
|
||||||
config := options.Stream.TLSSettings.GetTLSConfig()
|
securitySettings, err := options.Stream.GetEffectiveSecuritySettings()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("TCP: Failed to apply TLS config: ", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config := securitySettings.(*v2tls.Config).GetTLSConfig()
|
||||||
if dest.Address.Family().IsDomain() {
|
if dest.Address.Family().IsDomain() {
|
||||||
config.ServerName = dest.Address.Domain()
|
config.ServerName = dest.Address.Domain()
|
||||||
}
|
}
|
||||||
conn = tls.Client(conn, config)
|
conn = tls.Client(conn, config)
|
||||||
}
|
}
|
||||||
return NewConnection(id, conn, globalCache), nil
|
return NewConnection(id, conn, globalCache, tcpSettings), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DialRaw(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) {
|
func DialRaw(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) {
|
||||||
|
@ -7,8 +7,10 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"v2ray.com/core/common/log"
|
||||||
v2net "v2ray.com/core/common/net"
|
v2net "v2ray.com/core/common/net"
|
||||||
"v2ray.com/core/transport/internet"
|
"v2ray.com/core/transport/internet"
|
||||||
|
v2tls "v2ray.com/core/transport/internet/tls"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -26,6 +28,7 @@ type TCPListener struct {
|
|||||||
listener *net.TCPListener
|
listener *net.TCPListener
|
||||||
awaitingConns chan *ConnectionWithError
|
awaitingConns chan *ConnectionWithError
|
||||||
tlsConfig *tls.Config
|
tlsConfig *tls.Config
|
||||||
|
config *Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListenTCP(address v2net.Address, port v2net.Port, options internet.ListenOptions) (internet.Listener, error) {
|
func ListenTCP(address v2net.Address, port v2net.Port, options internet.ListenOptions) (internet.Listener, error) {
|
||||||
@ -36,13 +39,25 @@ func ListenTCP(address v2net.Address, port v2net.Port, options internet.ListenOp
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
networkSettings, err := options.Stream.GetEffectiveNetworkSettings()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tcpSettings := networkSettings.(*Config)
|
||||||
|
|
||||||
l := &TCPListener{
|
l := &TCPListener{
|
||||||
acccepting: true,
|
acccepting: true,
|
||||||
listener: listener,
|
listener: listener,
|
||||||
awaitingConns: make(chan *ConnectionWithError, 32),
|
awaitingConns: make(chan *ConnectionWithError, 32),
|
||||||
|
config: tcpSettings,
|
||||||
}
|
}
|
||||||
if options.Stream != nil && options.Stream.Security == internet.StreamSecurityTypeTLS {
|
if options.Stream != nil && options.Stream.SecurityType == internet.SecurityType_TLS {
|
||||||
l.tlsConfig = options.Stream.TLSSettings.GetTLSConfig()
|
securitySettings, err := options.Stream.GetEffectiveSecuritySettings()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("TCP: Failed to apply TLS config: ", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
l.tlsConfig = securitySettings.(*v2tls.Config).GetTLSConfig()
|
||||||
}
|
}
|
||||||
go l.KeepAccepting()
|
go l.KeepAccepting()
|
||||||
return l, nil
|
return l, nil
|
||||||
@ -62,7 +77,7 @@ func (this *TCPListener) Accept() (internet.Connection, error) {
|
|||||||
if this.tlsConfig != nil {
|
if this.tlsConfig != nil {
|
||||||
conn = tls.Server(conn, this.tlsConfig)
|
conn = tls.Server(conn, this.tlsConfig)
|
||||||
}
|
}
|
||||||
return NewConnection("", conn, this), nil
|
return NewConnection("", conn, this, this.config), nil
|
||||||
case <-time.After(time.Second * 2):
|
case <-time.After(time.Second * 2):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ var (
|
|||||||
|
|
||||||
type ListenFunc func(address v2net.Address, port v2net.Port, options ListenOptions) (Listener, error)
|
type ListenFunc func(address v2net.Address, port v2net.Port, options ListenOptions) (Listener, error)
|
||||||
type ListenOptions struct {
|
type ListenOptions struct {
|
||||||
Stream *StreamSettings
|
Stream *StreamConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
type Listener interface {
|
type Listener interface {
|
||||||
@ -36,23 +36,23 @@ type TCPHub struct {
|
|||||||
accepting bool
|
accepting bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListenTCP(address v2net.Address, port v2net.Port, callback ConnectionHandler, settings *StreamSettings) (*TCPHub, error) {
|
func ListenTCP(address v2net.Address, port v2net.Port, callback ConnectionHandler, settings *StreamConfig) (*TCPHub, error) {
|
||||||
var listener Listener
|
var listener Listener
|
||||||
var err error
|
var err error
|
||||||
options := ListenOptions{
|
options := ListenOptions{
|
||||||
Stream: settings,
|
Stream: settings,
|
||||||
}
|
}
|
||||||
switch {
|
switch settings.Network {
|
||||||
case settings.IsCapableOf(StreamConnectionTypeTCP):
|
case v2net.Network_TCP:
|
||||||
listener, err = TCPListenFunc(address, port, options)
|
listener, err = TCPListenFunc(address, port, options)
|
||||||
case settings.IsCapableOf(StreamConnectionTypeKCP):
|
case v2net.Network_KCP:
|
||||||
listener, err = KCPListenFunc(address, port, options)
|
listener, err = KCPListenFunc(address, port, options)
|
||||||
case settings.IsCapableOf(StreamConnectionTypeWebSocket):
|
case v2net.Network_WebSocket:
|
||||||
listener, err = WSListenFunc(address, port, options)
|
listener, err = WSListenFunc(address, port, options)
|
||||||
case settings.IsCapableOf(StreamConnectionTypeRawTCP):
|
case v2net.Network_RawTCP:
|
||||||
listener, err = RawTCPListenFunc(address, port, options)
|
listener, err = RawTCPListenFunc(address, port, options)
|
||||||
default:
|
default:
|
||||||
log.Error("Internet|Listener: Unknown stream type: ", settings.Type)
|
log.Error("Internet|Listener: Unknown stream type: ", settings.Network)
|
||||||
err = ErrUnsupportedStreamType
|
err = ErrUnsupportedStreamType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
39
transport/internet/tls/config.go
Normal file
39
transport/internet/tls/config.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package tls
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
|
||||||
|
"v2ray.com/core/common/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
globalSessionCache = tls.NewLRUClientSessionCache(128)
|
||||||
|
)
|
||||||
|
|
||||||
|
func (this *Config) BuildCertificates() []tls.Certificate {
|
||||||
|
certs := make([]tls.Certificate, 0, len(this.Certificate))
|
||||||
|
for _, entry := range this.Certificate {
|
||||||
|
keyPair, err := tls.X509KeyPair(entry.Certificate, entry.Key)
|
||||||
|
if err != nil {
|
||||||
|
log.Warning("TLS: ignoring invalid X509 key pair: ", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
certs = append(certs, keyPair)
|
||||||
|
}
|
||||||
|
return certs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Config) GetTLSConfig() *tls.Config {
|
||||||
|
config := &tls.Config{
|
||||||
|
ClientSessionCache: globalSessionCache,
|
||||||
|
}
|
||||||
|
if this == nil {
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
config.InsecureSkipVerify = this.AllowInsecure
|
||||||
|
config.Certificates = this.BuildCertificates()
|
||||||
|
config.BuildNameToCertificate()
|
||||||
|
|
||||||
|
return config
|
||||||
|
}
|
82
transport/internet/tls/config.pb.go
Normal file
82
transport/internet/tls/config.pb.go
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
// Code generated by protoc-gen-go.
|
||||||
|
// source: v2ray.com/core/transport/internet/tls/config.proto
|
||||||
|
// DO NOT EDIT!
|
||||||
|
|
||||||
|
/*
|
||||||
|
Package tls is a generated protocol buffer package.
|
||||||
|
|
||||||
|
It is generated from these files:
|
||||||
|
v2ray.com/core/transport/internet/tls/config.proto
|
||||||
|
|
||||||
|
It has these top-level messages:
|
||||||
|
Certificate
|
||||||
|
Config
|
||||||
|
*/
|
||||||
|
package tls
|
||||||
|
|
||||||
|
import proto "github.com/golang/protobuf/proto"
|
||||||
|
import fmt "fmt"
|
||||||
|
import math "math"
|
||||||
|
|
||||||
|
// Reference imports to suppress errors if they are not otherwise used.
|
||||||
|
var _ = proto.Marshal
|
||||||
|
var _ = fmt.Errorf
|
||||||
|
var _ = math.Inf
|
||||||
|
|
||||||
|
// This is a compile-time assertion to ensure that this generated file
|
||||||
|
// is compatible with the proto package it is being compiled against.
|
||||||
|
// A compilation error at this line likely means your copy of the
|
||||||
|
// proto package needs to be updated.
|
||||||
|
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||||
|
|
||||||
|
type Certificate struct {
|
||||||
|
Certificate []byte `protobuf:"bytes,1,opt,name=Certificate,json=certificate,proto3" json:"Certificate,omitempty"`
|
||||||
|
Key []byte `protobuf:"bytes,2,opt,name=Key,json=key,proto3" json:"Key,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Certificate) Reset() { *m = Certificate{} }
|
||||||
|
func (m *Certificate) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*Certificate) ProtoMessage() {}
|
||||||
|
func (*Certificate) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
AllowInsecure bool `protobuf:"varint,1,opt,name=allow_insecure,json=allowInsecure" json:"allow_insecure,omitempty"`
|
||||||
|
Certificate []*Certificate `protobuf:"bytes,2,rep,name=certificate" json:"certificate,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Config) Reset() { *m = Config{} }
|
||||||
|
func (m *Config) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*Config) ProtoMessage() {}
|
||||||
|
func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
|
||||||
|
|
||||||
|
func (m *Config) GetCertificate() []*Certificate {
|
||||||
|
if m != nil {
|
||||||
|
return m.Certificate
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
proto.RegisterType((*Certificate)(nil), "v2ray.core.transport.internet.tls.Certificate")
|
||||||
|
proto.RegisterType((*Config)(nil), "v2ray.core.transport.internet.tls.Config")
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() { proto.RegisterFile("v2ray.com/core/transport/internet/tls/config.proto", fileDescriptor0) }
|
||||||
|
|
||||||
|
var fileDescriptor0 = []byte{
|
||||||
|
// 219 bytes of a gzipped FileDescriptorProto
|
||||||
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x84, 0x90, 0xb1, 0x4b, 0x43, 0x31,
|
||||||
|
0x10, 0xc6, 0x79, 0x0d, 0x14, 0x49, 0x54, 0x24, 0xd3, 0x1b, 0x9f, 0x85, 0x42, 0xa7, 0x0b, 0x3c,
|
||||||
|
0x27, 0x47, 0xdb, 0x49, 0x5c, 0x4a, 0x47, 0x17, 0x89, 0xe1, 0x2a, 0xc1, 0x34, 0x57, 0x2e, 0xa7,
|
||||||
|
0xf2, 0x46, 0xff, 0x73, 0x31, 0xb5, 0xf2, 0x3a, 0x75, 0xbc, 0xef, 0xbe, 0xfb, 0xee, 0xc7, 0xa7,
|
||||||
|
0xfb, 0xcf, 0x9e, 0xfd, 0x00, 0x81, 0x76, 0x2e, 0x10, 0xa3, 0x13, 0xf6, 0xb9, 0xec, 0x89, 0xc5,
|
||||||
|
0xc5, 0x2c, 0xc8, 0x19, 0xc5, 0x49, 0x2a, 0x2e, 0x50, 0xde, 0xc6, 0x37, 0xd8, 0x33, 0x09, 0xd9,
|
||||||
|
0xdb, 0xe3, 0x0d, 0x23, 0xfc, 0xfb, 0xe1, 0xe8, 0x07, 0x49, 0x65, 0xf6, 0xa0, 0xcd, 0x0a, 0x59,
|
||||||
|
0xe2, 0x36, 0x06, 0x2f, 0x68, 0xbb, 0x93, 0xb1, 0x6d, 0xba, 0x66, 0x71, 0xb9, 0x31, 0x61, 0xe4,
|
||||||
|
0xb8, 0xd1, 0xea, 0x09, 0x87, 0x76, 0x52, 0x37, 0xea, 0x1d, 0x87, 0xd9, 0x77, 0xa3, 0xa7, 0xab,
|
||||||
|
0xfa, 0xd6, 0xce, 0xf5, 0xb5, 0x4f, 0x89, 0xbe, 0x5e, 0x62, 0x2e, 0x18, 0x3e, 0xf8, 0x90, 0x70,
|
||||||
|
0xb1, 0xb9, 0xaa, 0xea, 0xe3, 0x9f, 0x68, 0xd7, 0x7a, 0x1c, 0xd9, 0x4e, 0x3a, 0xb5, 0x30, 0x3d,
|
||||||
|
0xc0, 0x59, 0x5a, 0x18, 0xb1, 0x9d, 0x50, 0x2d, 0xef, 0xf5, 0x3c, 0xd0, 0xee, 0x7c, 0xc2, 0xd2,
|
||||||
|
0x1c, 0x48, 0xd7, 0xbf, 0xfd, 0x3c, 0x2b, 0x49, 0xe5, 0x75, 0x5a, 0xbb, 0xba, 0xfb, 0x09, 0x00,
|
||||||
|
0x00, 0xff, 0xff, 0xbb, 0x82, 0x9d, 0x49, 0x61, 0x01, 0x00, 0x00,
|
||||||
|
}
|
16
transport/internet/tls/config.proto
Normal file
16
transport/internet/tls/config.proto
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package v2ray.core.transport.internet.tls;
|
||||||
|
option go_package = "tls";
|
||||||
|
option java_package = "com.v2ray.core.transport.internet.tls";
|
||||||
|
option java_outer_classname = "ConfigProto";
|
||||||
|
|
||||||
|
message Certificate {
|
||||||
|
bytes Certificate = 1;
|
||||||
|
bytes Key = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Config {
|
||||||
|
bool allow_insecure = 1;
|
||||||
|
repeated Certificate certificate = 2;
|
||||||
|
}
|
41
transport/internet/tls/config_json.go
Normal file
41
transport/internet/tls/config_json.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// +build json
|
||||||
|
|
||||||
|
package tls
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"io/ioutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (this *Config) UnmarshalJSON(data []byte) error {
|
||||||
|
type JSONCertConfig struct {
|
||||||
|
CertFile string `json:"certificateFile"`
|
||||||
|
KeyFile string `json:"keyFile"`
|
||||||
|
}
|
||||||
|
type JSONConfig struct {
|
||||||
|
Insecure bool `json:"allowInsecure"`
|
||||||
|
Certs []*JSONCertConfig `json:"certificates"`
|
||||||
|
}
|
||||||
|
jsonConfig := new(JSONConfig)
|
||||||
|
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
this.Certificate = make([]*Certificate, len(jsonConfig.Certs))
|
||||||
|
for idx, certConf := range jsonConfig.Certs {
|
||||||
|
cert, err := ioutil.ReadFile(certConf.CertFile)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("TLS: Failed to load certificate file: " + err.Error())
|
||||||
|
}
|
||||||
|
key, err := ioutil.ReadFile(certConf.KeyFile)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("TLS: Failed to load key file: " + err.Error())
|
||||||
|
}
|
||||||
|
this.Certificate[idx] = &Certificate{
|
||||||
|
Key: key,
|
||||||
|
Certificate: cert,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.AllowInsecure = jsonConfig.Insecure
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,17 +1,14 @@
|
|||||||
package ws
|
package ws
|
||||||
|
|
||||||
type Config struct {
|
import (
|
||||||
ConnectionReuse bool
|
v2net "v2ray.com/core/common/net"
|
||||||
Path string
|
"v2ray.com/core/transport/internet"
|
||||||
}
|
|
||||||
|
|
||||||
func (this *Config) Apply() {
|
"github.com/golang/protobuf/proto"
|
||||||
effectiveConfig = this
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
effectiveConfig = &Config{
|
|
||||||
ConnectionReuse: true,
|
|
||||||
Path: "",
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
internet.RegisterNetworkConfigCreator(v2net.Network_WebSocket, func() proto.Message {
|
||||||
|
return new(Config)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
60
transport/internet/ws/config.pb.go
Normal file
60
transport/internet/ws/config.pb.go
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// Code generated by protoc-gen-go.
|
||||||
|
// source: v2ray.com/core/transport/internet/ws/config.proto
|
||||||
|
// DO NOT EDIT!
|
||||||
|
|
||||||
|
/*
|
||||||
|
Package ws is a generated protocol buffer package.
|
||||||
|
|
||||||
|
It is generated from these files:
|
||||||
|
v2ray.com/core/transport/internet/ws/config.proto
|
||||||
|
|
||||||
|
It has these top-level messages:
|
||||||
|
Config
|
||||||
|
*/
|
||||||
|
package ws
|
||||||
|
|
||||||
|
import proto "github.com/golang/protobuf/proto"
|
||||||
|
import fmt "fmt"
|
||||||
|
import math "math"
|
||||||
|
|
||||||
|
// Reference imports to suppress errors if they are not otherwise used.
|
||||||
|
var _ = proto.Marshal
|
||||||
|
var _ = fmt.Errorf
|
||||||
|
var _ = math.Inf
|
||||||
|
|
||||||
|
// This is a compile-time assertion to ensure that this generated file
|
||||||
|
// is compatible with the proto package it is being compiled against.
|
||||||
|
// A compilation error at this line likely means your copy of the
|
||||||
|
// proto package needs to be updated.
|
||||||
|
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
ConnectionReuse bool `protobuf:"varint,1,opt,name=connection_reuse,json=connectionReuse" json:"connection_reuse,omitempty"`
|
||||||
|
Path string `protobuf:"bytes,2,opt,name=path" json:"path,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Config) Reset() { *m = Config{} }
|
||||||
|
func (m *Config) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*Config) ProtoMessage() {}
|
||||||
|
func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
proto.RegisterType((*Config)(nil), "v2ray.core.transport.internet.ws.Config")
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() { proto.RegisterFile("v2ray.com/core/transport/internet/ws/config.proto", fileDescriptor0) }
|
||||||
|
|
||||||
|
var fileDescriptor0 = []byte{
|
||||||
|
// 174 bytes of a gzipped FileDescriptorProto
|
||||||
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x32, 0x2c, 0x33, 0x2a, 0x4a,
|
||||||
|
0xac, 0xd4, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x2f, 0x29, 0x4a, 0xcc, 0x2b,
|
||||||
|
0x2e, 0xc8, 0x2f, 0x2a, 0xd1, 0xcf, 0xcc, 0x2b, 0x49, 0x2d, 0xca, 0x4b, 0x2d, 0xd1, 0x2f, 0x2f,
|
||||||
|
0xd6, 0x4f, 0xce, 0xcf, 0x4b, 0xcb, 0x4c, 0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x52, 0x80,
|
||||||
|
0x69, 0x29, 0x4a, 0xd5, 0x83, 0x2b, 0xd7, 0x83, 0x29, 0xd7, 0x2b, 0x2f, 0x56, 0x72, 0xe7, 0x62,
|
||||||
|
0x73, 0x06, 0xeb, 0x10, 0xd2, 0xe4, 0x12, 0x48, 0xce, 0xcf, 0xcb, 0x4b, 0x4d, 0x2e, 0xc9, 0xcc,
|
||||||
|
0xcf, 0x8b, 0x2f, 0x4a, 0x2d, 0x2d, 0x4e, 0x95, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x08, 0xe2, 0x47,
|
||||||
|
0x88, 0x07, 0x81, 0x84, 0x85, 0x84, 0xb8, 0x58, 0x0a, 0x12, 0x4b, 0x32, 0x24, 0x98, 0x14, 0x18,
|
||||||
|
0x35, 0x38, 0x83, 0xc0, 0x6c, 0x27, 0x73, 0x2e, 0x95, 0xe4, 0xfc, 0x5c, 0x3d, 0x42, 0x16, 0x3a,
|
||||||
|
0x71, 0x43, 0xac, 0x0b, 0x00, 0xb9, 0x2f, 0x8a, 0xa9, 0xbc, 0x38, 0x89, 0x0d, 0xec, 0x54, 0x63,
|
||||||
|
0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf1, 0x69, 0xf5, 0xaf, 0xdf, 0x00, 0x00, 0x00,
|
||||||
|
}
|
11
transport/internet/ws/config.proto
Normal file
11
transport/internet/ws/config.proto
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package v2ray.core.transport.internet.ws;
|
||||||
|
option go_package = "ws";
|
||||||
|
option java_package = "com.v2ray.core.transport.internet.ws";
|
||||||
|
option java_outer_classname = "ConfigProto";
|
||||||
|
|
||||||
|
message Config {
|
||||||
|
bool connection_reuse = 1;
|
||||||
|
string path = 2;
|
||||||
|
}
|
@ -20,14 +20,16 @@ type Connection struct {
|
|||||||
conn *wsconn
|
conn *wsconn
|
||||||
listener ConnectionManager
|
listener ConnectionManager
|
||||||
reusable bool
|
reusable bool
|
||||||
|
config *Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConnection(dest string, conn *wsconn, manager ConnectionManager) *Connection {
|
func NewConnection(dest string, conn *wsconn, manager ConnectionManager, config *Config) *Connection {
|
||||||
return &Connection{
|
return &Connection{
|
||||||
dest: dest,
|
dest: dest,
|
||||||
conn: conn,
|
conn: conn,
|
||||||
listener: manager,
|
listener: manager,
|
||||||
reusable: effectiveConfig.ConnectionReuse,
|
reusable: config.ConnectionReuse,
|
||||||
|
config: config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +82,7 @@ func (this *Connection) SetWriteDeadline(t time.Time) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *Connection) SetReusable(reusable bool) {
|
func (this *Connection) SetReusable(reusable bool) {
|
||||||
if !effectiveConfig.ConnectionReuse {
|
if !this.config.ConnectionReuse {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.reusable = reusable
|
this.reusable = reusable
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"v2ray.com/core/common/log"
|
"v2ray.com/core/common/log"
|
||||||
v2net "v2ray.com/core/common/net"
|
v2net "v2ray.com/core/common/net"
|
||||||
"v2ray.com/core/transport/internet"
|
"v2ray.com/core/transport/internet"
|
||||||
|
v2tls "v2ray.com/core/transport/internet/tls"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -20,9 +21,15 @@ func Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOpti
|
|||||||
if src == nil {
|
if src == nil {
|
||||||
src = v2net.AnyIP
|
src = v2net.AnyIP
|
||||||
}
|
}
|
||||||
|
networkSettings, err := options.Stream.GetEffectiveNetworkSettings()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
wsSettings := networkSettings.(*Config)
|
||||||
|
|
||||||
id := src.String() + "-" + dest.NetAddr()
|
id := src.String() + "-" + dest.NetAddr()
|
||||||
var conn *wsconn
|
var conn *wsconn
|
||||||
if dest.Network == v2net.Network_TCP && effectiveConfig.ConnectionReuse {
|
if dest.Network == v2net.Network_TCP && wsSettings.ConnectionReuse {
|
||||||
connt := globalCache.Get(id)
|
connt := globalCache.Get(id)
|
||||||
if connt != nil {
|
if connt != nil {
|
||||||
conn = connt.(*wsconn)
|
conn = connt.(*wsconn)
|
||||||
@ -36,7 +43,7 @@ func Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOpti
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NewConnection(id, conn, globalCache), nil
|
return NewConnection(id, conn, globalCache, wsSettings), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -44,6 +51,12 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func wsDial(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (*wsconn, error) {
|
func wsDial(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (*wsconn, error) {
|
||||||
|
networkSettings, err := options.Stream.GetEffectiveNetworkSettings()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
wsSettings := networkSettings.(*Config)
|
||||||
|
|
||||||
commonDial := func(network, addr string) (net.Conn, error) {
|
commonDial := func(network, addr string) (net.Conn, error) {
|
||||||
return internet.DialToDest(src, dest)
|
return internet.DialToDest(src, dest)
|
||||||
}
|
}
|
||||||
@ -56,9 +69,14 @@ func wsDial(src v2net.Address, dest v2net.Destination, options internet.DialerOp
|
|||||||
|
|
||||||
protocol := "ws"
|
protocol := "ws"
|
||||||
|
|
||||||
if options.Stream != nil && options.Stream.Security == internet.StreamSecurityTypeTLS {
|
if options.Stream != nil && options.Stream.SecurityType == internet.SecurityType_TLS {
|
||||||
protocol = "wss"
|
protocol = "wss"
|
||||||
dialer.TLSClientConfig = options.Stream.TLSSettings.GetTLSConfig()
|
securitySettings, err := options.Stream.GetEffectiveSecuritySettings()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("WebSocket: Failed to create apply TLS config: ", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dialer.TLSClientConfig = securitySettings.(*v2tls.Config).GetTLSConfig()
|
||||||
if dest.Address.Family().IsDomain() {
|
if dest.Address.Family().IsDomain() {
|
||||||
dialer.TLSClientConfig.ServerName = dest.Address.Domain()
|
dialer.TLSClientConfig.ServerName = dest.Address.Domain()
|
||||||
}
|
}
|
||||||
@ -66,7 +84,7 @@ func wsDial(src v2net.Address, dest v2net.Destination, options internet.DialerOp
|
|||||||
|
|
||||||
uri := func(dst v2net.Destination, pto string, path string) string {
|
uri := func(dst v2net.Destination, pto string, path string) string {
|
||||||
return fmt.Sprintf("%v://%v/%v", pto, dst.NetAddr(), path)
|
return fmt.Sprintf("%v://%v/%v", pto, dst.NetAddr(), path)
|
||||||
}(dest, protocol, effectiveConfig.Path)
|
}(dest, protocol, wsSettings.Path)
|
||||||
|
|
||||||
conn, resp, err := dialer.Dial(uri, nil)
|
conn, resp, err := dialer.Dial(uri, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -77,7 +95,11 @@ func wsDial(src v2net.Address, dest v2net.Destination, options internet.DialerOp
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return func() internet.Connection {
|
return func() internet.Connection {
|
||||||
connv2ray := &wsconn{wsc: conn, connClosing: false}
|
connv2ray := &wsconn{
|
||||||
|
wsc: conn,
|
||||||
|
connClosing: false,
|
||||||
|
config: wsSettings,
|
||||||
|
}
|
||||||
connv2ray.setup()
|
connv2ray.setup()
|
||||||
return connv2ray
|
return connv2ray
|
||||||
}().(*wsconn), nil
|
}().(*wsconn), nil
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"v2ray.com/core/common/log"
|
"v2ray.com/core/common/log"
|
||||||
v2net "v2ray.com/core/common/net"
|
v2net "v2ray.com/core/common/net"
|
||||||
"v2ray.com/core/transport/internet"
|
"v2ray.com/core/transport/internet"
|
||||||
|
v2tls "v2ray.com/core/transport/internet/tls"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -30,26 +31,37 @@ type WSListener struct {
|
|||||||
awaitingConns chan *ConnectionWithError
|
awaitingConns chan *ConnectionWithError
|
||||||
listener *StoppableListener
|
listener *StoppableListener
|
||||||
tlsConfig *tls.Config
|
tlsConfig *tls.Config
|
||||||
|
config *Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListenWS(address v2net.Address, port v2net.Port, options internet.ListenOptions) (internet.Listener, error) {
|
func ListenWS(address v2net.Address, port v2net.Port, options internet.ListenOptions) (internet.Listener, error) {
|
||||||
|
networkSettings, err := options.Stream.GetEffectiveNetworkSettings()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
wsSettings := networkSettings.(*Config)
|
||||||
|
|
||||||
l := &WSListener{
|
l := &WSListener{
|
||||||
acccepting: true,
|
acccepting: true,
|
||||||
awaitingConns: make(chan *ConnectionWithError, 32),
|
awaitingConns: make(chan *ConnectionWithError, 32),
|
||||||
|
config: wsSettings,
|
||||||
}
|
}
|
||||||
if options.Stream != nil && options.Stream.Security == internet.StreamSecurityTypeTLS {
|
if options.Stream != nil && options.Stream.SecurityType == internet.SecurityType_TLS {
|
||||||
l.tlsConfig = options.Stream.TLSSettings.GetTLSConfig()
|
securitySettings, err := options.Stream.GetEffectiveSecuritySettings()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("WebSocket: Failed to create apply TLS config: ", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
l.tlsConfig = securitySettings.(*v2tls.Config).GetTLSConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
err := l.listenws(address, port)
|
err = l.listenws(address, port)
|
||||||
|
|
||||||
return l, err
|
return l, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wsl *WSListener) listenws(address v2net.Address, port v2net.Port) error {
|
func (wsl *WSListener) listenws(address v2net.Address, port v2net.Port) error {
|
||||||
|
http.HandleFunc("/"+wsl.config.Path, func(w http.ResponseWriter, r *http.Request) {
|
||||||
http.HandleFunc("/"+effectiveConfig.Path, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
con, err := wsl.converttovws(w, r)
|
con, err := wsl.converttovws(w, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warning("WebSocket|Listener: Failed to convert connection: ", err)
|
log.Warning("WebSocket|Listener: Failed to convert connection: ", err)
|
||||||
@ -140,7 +152,7 @@ func (this *WSListener) Accept() (internet.Connection, error) {
|
|||||||
if connErr.err != nil {
|
if connErr.err != nil {
|
||||||
return nil, connErr.err
|
return nil, connErr.err
|
||||||
}
|
}
|
||||||
return NewConnection("", connErr.conn.(*wsconn), this), nil
|
return NewConnection("", connErr.conn.(*wsconn), this, this.config), nil
|
||||||
case <-time.After(time.Second * 2):
|
case <-time.After(time.Second * 2):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,43 @@
|
|||||||
package ws_test
|
package ws_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"io/ioutil"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
v2net "v2ray.com/core/common/net"
|
v2net "v2ray.com/core/common/net"
|
||||||
"v2ray.com/core/testing/assert"
|
"v2ray.com/core/testing/assert"
|
||||||
"v2ray.com/core/transport/internet"
|
"v2ray.com/core/transport/internet"
|
||||||
|
v2tls "v2ray.com/core/transport/internet/tls"
|
||||||
. "v2ray.com/core/transport/internet/ws"
|
. "v2ray.com/core/transport/internet/ws"
|
||||||
|
|
||||||
|
"github.com/golang/protobuf/ptypes"
|
||||||
|
"github.com/golang/protobuf/ptypes/any"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func MarshalSettings(config *Config, assert *assert.Assert) *any.Any {
|
||||||
|
anySettings, err := ptypes.MarshalAny(config)
|
||||||
|
assert.Error(err).IsNil()
|
||||||
|
|
||||||
|
return anySettings
|
||||||
|
}
|
||||||
|
|
||||||
func Test_Connect_ws(t *testing.T) {
|
func Test_Connect_ws(t *testing.T) {
|
||||||
assert := assert.On(t)
|
assert := assert.On(t)
|
||||||
(&Config{Path: ""}).Apply()
|
|
||||||
conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 80), internet.DialerOptions{})
|
conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 80), internet.DialerOptions{
|
||||||
|
Stream: &internet.StreamConfig{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
NetworkSettings: []*internet.NetworkSettings{
|
||||||
|
{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
Settings: MarshalSettings(&Config{
|
||||||
|
Path: "",
|
||||||
|
}, assert),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
conn.Write([]byte("echo"))
|
conn.Write([]byte("echo"))
|
||||||
s := make(chan int)
|
s := make(chan int)
|
||||||
@ -33,10 +56,18 @@ func Test_Connect_ws(t *testing.T) {
|
|||||||
|
|
||||||
func Test_Connect_wss(t *testing.T) {
|
func Test_Connect_wss(t *testing.T) {
|
||||||
assert := assert.On(t)
|
assert := assert.On(t)
|
||||||
(&Config{Path: ""}).Apply()
|
|
||||||
conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443), internet.DialerOptions{
|
conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443), internet.DialerOptions{
|
||||||
Stream: &internet.StreamSettings{
|
Stream: &internet.StreamConfig{
|
||||||
Security: internet.StreamSecurityTypeTLS,
|
Network: v2net.Network_WebSocket,
|
||||||
|
NetworkSettings: []*internet.NetworkSettings{
|
||||||
|
{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
Settings: MarshalSettings(&Config{
|
||||||
|
Path: "",
|
||||||
|
}, assert),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SecurityType: internet.SecurityType_TLS,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
@ -57,10 +88,18 @@ func Test_Connect_wss(t *testing.T) {
|
|||||||
|
|
||||||
func Test_Connect_wss_1_nil(t *testing.T) {
|
func Test_Connect_wss_1_nil(t *testing.T) {
|
||||||
assert := assert.On(t)
|
assert := assert.On(t)
|
||||||
(&Config{Path: ""}).Apply()
|
|
||||||
conn, err := Dial(nil, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443), internet.DialerOptions{
|
conn, err := Dial(nil, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443), internet.DialerOptions{
|
||||||
Stream: &internet.StreamSettings{
|
Stream: &internet.StreamConfig{
|
||||||
Security: internet.StreamSecurityTypeTLS,
|
Network: v2net.Network_WebSocket,
|
||||||
|
NetworkSettings: []*internet.NetworkSettings{
|
||||||
|
{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
Settings: MarshalSettings(&Config{
|
||||||
|
Path: "",
|
||||||
|
}, assert),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SecurityType: internet.SecurityType_TLS,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
@ -81,8 +120,19 @@ func Test_Connect_wss_1_nil(t *testing.T) {
|
|||||||
|
|
||||||
func Test_Connect_ws_guess(t *testing.T) {
|
func Test_Connect_ws_guess(t *testing.T) {
|
||||||
assert := assert.On(t)
|
assert := assert.On(t)
|
||||||
(&Config{Path: ""}).Apply()
|
conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 80), internet.DialerOptions{
|
||||||
conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 80), internet.DialerOptions{})
|
Stream: &internet.StreamConfig{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
NetworkSettings: []*internet.NetworkSettings{
|
||||||
|
{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
Settings: MarshalSettings(&Config{
|
||||||
|
Path: "",
|
||||||
|
}, assert),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
conn.Write([]byte("echo"))
|
conn.Write([]byte("echo"))
|
||||||
s := make(chan int)
|
s := make(chan int)
|
||||||
@ -101,10 +151,18 @@ func Test_Connect_ws_guess(t *testing.T) {
|
|||||||
|
|
||||||
func Test_Connect_wss_guess(t *testing.T) {
|
func Test_Connect_wss_guess(t *testing.T) {
|
||||||
assert := assert.On(t)
|
assert := assert.On(t)
|
||||||
(&Config{Path: ""}).Apply()
|
|
||||||
conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443), internet.DialerOptions{
|
conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443), internet.DialerOptions{
|
||||||
Stream: &internet.StreamSettings{
|
Stream: &internet.StreamConfig{
|
||||||
Security: internet.StreamSecurityTypeTLS,
|
Network: v2net.Network_WebSocket,
|
||||||
|
NetworkSettings: []*internet.NetworkSettings{
|
||||||
|
{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
Settings: MarshalSettings(&Config{
|
||||||
|
Path: "",
|
||||||
|
}, assert),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SecurityType: internet.SecurityType_TLS,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
@ -125,10 +183,18 @@ func Test_Connect_wss_guess(t *testing.T) {
|
|||||||
|
|
||||||
func Test_Connect_wss_guess_fail(t *testing.T) {
|
func Test_Connect_wss_guess_fail(t *testing.T) {
|
||||||
assert := assert.On(t)
|
assert := assert.On(t)
|
||||||
(&Config{Path: ""}).Apply()
|
|
||||||
_, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("static.kkdev.org"), 443), internet.DialerOptions{
|
_, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("static.kkdev.org"), 443), internet.DialerOptions{
|
||||||
Stream: &internet.StreamSettings{
|
Stream: &internet.StreamConfig{
|
||||||
Security: internet.StreamSecurityTypeTLS,
|
Network: v2net.Network_WebSocket,
|
||||||
|
NetworkSettings: []*internet.NetworkSettings{
|
||||||
|
{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
Settings: MarshalSettings(&Config{
|
||||||
|
Path: "",
|
||||||
|
}, assert),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SecurityType: internet.SecurityType_TLS,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
assert.Error(err).IsNotNil()
|
assert.Error(err).IsNotNil()
|
||||||
@ -136,12 +202,21 @@ func Test_Connect_wss_guess_fail(t *testing.T) {
|
|||||||
|
|
||||||
func Test_Connect_wss_guess_reuse(t *testing.T) {
|
func Test_Connect_wss_guess_reuse(t *testing.T) {
|
||||||
assert := assert.On(t)
|
assert := assert.On(t)
|
||||||
(&Config{Path: "", ConnectionReuse: true}).Apply()
|
|
||||||
i := 3
|
i := 3
|
||||||
for i != 0 {
|
for i != 0 {
|
||||||
conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443), internet.DialerOptions{
|
conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443), internet.DialerOptions{
|
||||||
Stream: &internet.StreamSettings{
|
Stream: &internet.StreamConfig{
|
||||||
Security: internet.StreamSecurityTypeTLS,
|
Network: v2net.Network_WebSocket,
|
||||||
|
NetworkSettings: []*internet.NetworkSettings{
|
||||||
|
{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
Settings: MarshalSettings(&Config{
|
||||||
|
Path: "",
|
||||||
|
ConnectionReuse: true,
|
||||||
|
}, assert),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SecurityType: internet.SecurityType_TLS,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
@ -170,8 +245,19 @@ func Test_Connect_wss_guess_reuse(t *testing.T) {
|
|||||||
|
|
||||||
func Test_listenWSAndDial(t *testing.T) {
|
func Test_listenWSAndDial(t *testing.T) {
|
||||||
assert := assert.On(t)
|
assert := assert.On(t)
|
||||||
(&Config{Path: "ws"}).Apply()
|
listen, err := ListenWS(v2net.DomainAddress("localhost"), 13142, internet.ListenOptions{
|
||||||
listen, err := ListenWS(v2net.DomainAddress("localhost"), 13142, internet.ListenOptions{})
|
Stream: &internet.StreamConfig{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
NetworkSettings: []*internet.NetworkSettings{
|
||||||
|
{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
Settings: MarshalSettings(&Config{
|
||||||
|
Path: "ws",
|
||||||
|
}, assert),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
go func() {
|
go func() {
|
||||||
conn, err := listen.Accept()
|
conn, err := listen.Accept()
|
||||||
@ -185,15 +271,51 @@ func Test_listenWSAndDial(t *testing.T) {
|
|||||||
conn.Close()
|
conn.Close()
|
||||||
listen.Close()
|
listen.Close()
|
||||||
}()
|
}()
|
||||||
conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13142), internet.DialerOptions{})
|
conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13142), internet.DialerOptions{
|
||||||
|
Stream: &internet.StreamConfig{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
NetworkSettings: []*internet.NetworkSettings{
|
||||||
|
{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
Settings: MarshalSettings(&Config{
|
||||||
|
Path: "ws",
|
||||||
|
}, assert),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
conn.Close()
|
conn.Close()
|
||||||
<-time.After(time.Second * 5)
|
<-time.After(time.Second * 5)
|
||||||
conn, err = Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13142), internet.DialerOptions{})
|
conn, err = Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13142), internet.DialerOptions{
|
||||||
|
Stream: &internet.StreamConfig{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
NetworkSettings: []*internet.NetworkSettings{
|
||||||
|
{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
Settings: MarshalSettings(&Config{
|
||||||
|
Path: "ws",
|
||||||
|
}, assert),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
conn.Close()
|
conn.Close()
|
||||||
<-time.After(time.Second * 15)
|
<-time.After(time.Second * 15)
|
||||||
conn, err = Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13142), internet.DialerOptions{})
|
conn, err = Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13142), internet.DialerOptions{
|
||||||
|
Stream: &internet.StreamConfig{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
NetworkSettings: []*internet.NetworkSettings{
|
||||||
|
{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
Settings: MarshalSettings(&Config{
|
||||||
|
Path: "ws",
|
||||||
|
}, assert),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
conn.Close()
|
conn.Close()
|
||||||
}
|
}
|
||||||
@ -204,14 +326,34 @@ func Test_listenWSAndDial_TLS(t *testing.T) {
|
|||||||
<-time.After(time.Second * 5)
|
<-time.After(time.Second * 5)
|
||||||
assert.Fail("Too slow")
|
assert.Fail("Too slow")
|
||||||
}()
|
}()
|
||||||
(&Config{Path: "wss", ConnectionReuse: true}).Apply()
|
tlsSettings := &v2tls.Config{
|
||||||
|
AllowInsecure: true,
|
||||||
|
Certificate: []*v2tls.Certificate{
|
||||||
|
{
|
||||||
|
Certificate: ReadFile("./../../../testing/tls/cert.pem", assert),
|
||||||
|
Key: ReadFile("./../../../testing/tls/key.pem", assert),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
anyTlsSettings, err := ptypes.MarshalAny(tlsSettings)
|
||||||
|
assert.Error(err).IsNil()
|
||||||
|
|
||||||
listen, err := ListenWS(v2net.DomainAddress("localhost"), 13143, internet.ListenOptions{
|
listen, err := ListenWS(v2net.DomainAddress("localhost"), 13143, internet.ListenOptions{
|
||||||
Stream: &internet.StreamSettings{
|
Stream: &internet.StreamConfig{
|
||||||
Security: internet.StreamSecurityTypeTLS,
|
SecurityType: internet.SecurityType_TLS,
|
||||||
TLSSettings: &internet.TLSSettings{
|
SecuritySettings: []*internet.SecuritySettings{{
|
||||||
AllowInsecure: true,
|
Type: internet.SecurityType_TLS,
|
||||||
Certs: LoadTestCert(assert),
|
Settings: anyTlsSettings,
|
||||||
|
}},
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
NetworkSettings: []*internet.NetworkSettings{
|
||||||
|
{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
Settings: MarshalSettings(&Config{
|
||||||
|
Path: "wss",
|
||||||
|
ConnectionReuse: true,
|
||||||
|
}, assert),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -223,11 +365,21 @@ func Test_listenWSAndDial_TLS(t *testing.T) {
|
|||||||
listen.Close()
|
listen.Close()
|
||||||
}()
|
}()
|
||||||
conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13143), internet.DialerOptions{
|
conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13143), internet.DialerOptions{
|
||||||
Stream: &internet.StreamSettings{
|
Stream: &internet.StreamConfig{
|
||||||
Security: internet.StreamSecurityTypeTLS,
|
SecurityType: internet.SecurityType_TLS,
|
||||||
TLSSettings: &internet.TLSSettings{
|
SecuritySettings: []*internet.SecuritySettings{{
|
||||||
AllowInsecure: true,
|
Type: internet.SecurityType_TLS,
|
||||||
Certs: LoadTestCert(assert),
|
Settings: anyTlsSettings,
|
||||||
|
}},
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
NetworkSettings: []*internet.NetworkSettings{
|
||||||
|
{
|
||||||
|
Network: v2net.Network_WebSocket,
|
||||||
|
Settings: MarshalSettings(&Config{
|
||||||
|
Path: "wss",
|
||||||
|
ConnectionReuse: true,
|
||||||
|
}, assert),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -235,8 +387,8 @@ func Test_listenWSAndDial_TLS(t *testing.T) {
|
|||||||
conn.Close()
|
conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadTestCert(assert *assert.Assert) []tls.Certificate {
|
func ReadFile(file string, assert *assert.Assert) []byte {
|
||||||
cert, err := tls.LoadX509KeyPair("./../../../testing/tls/cert.pem", "./../../../testing/tls/key.pem")
|
b, err := ioutil.ReadFile(file)
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
return []tls.Certificate{cert}
|
return b
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ type wsconn struct {
|
|||||||
reusable bool
|
reusable bool
|
||||||
rlock *sync.Mutex
|
rlock *sync.Mutex
|
||||||
wlock *sync.Mutex
|
wlock *sync.Mutex
|
||||||
|
config *Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ws *wsconn) Read(b []byte) (n int, err error) {
|
func (ws *wsconn) Read(b []byte) (n int, err error) {
|
||||||
@ -164,7 +165,7 @@ func (ws *wsconn) Reusable() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ws *wsconn) SetReusable(reusable bool) {
|
func (ws *wsconn) SetReusable(reusable bool) {
|
||||||
if !effectiveConfig.ConnectionReuse {
|
if !ws.config.ConnectionReuse {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ws.reusable = reusable
|
ws.reusable = reusable
|
||||||
|
Loading…
Reference in New Issue
Block a user