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,
|
||||
&proxy.OutboundHandlerMeta{
|
||||
Address: v2net.AnyIP,
|
||||
StreamSettings: &internet.StreamSettings{
|
||||
Type: internet.StreamConnectionTypeRawTCP,
|
||||
StreamSettings: &internet.StreamConfig{
|
||||
Network: v2net.Network_RawTCP,
|
||||
},
|
||||
}))
|
||||
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.
|
||||
func (this *NetworkList) HasNetwork(network Network) bool {
|
||||
func (this NetworkList) HasNetwork(network Network) bool {
|
||||
for _, value := range this.Network {
|
||||
if string(value) == string(network) {
|
||||
return true
|
||||
@ -76,3 +76,7 @@ func (this *NetworkList) HasNetwork(network Network) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (this NetworkList) Get(idx int) Network {
|
||||
return this.Network[idx]
|
||||
}
|
||||
|
@ -8,6 +8,15 @@ import (
|
||||
"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 {
|
||||
var strlist collect.StringList
|
||||
if err := json.Unmarshal(data, &strlist); err != nil {
|
||||
|
@ -10,6 +10,15 @@ import (
|
||||
"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) {
|
||||
assert := assert.On(t)
|
||||
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/proxy"
|
||||
"v2ray.com/core/proxy/registry"
|
||||
"v2ray.com/core/transport/internet"
|
||||
"v2ray.com/core/transport/ray"
|
||||
)
|
||||
|
||||
@ -40,8 +39,10 @@ func (this *BlackHole) Dispatch(destination v2net.Destination, payload *alloc.Bu
|
||||
|
||||
type Factory struct{}
|
||||
|
||||
func (this *Factory) StreamCapability() internet.StreamConnectionType {
|
||||
return internet.StreamConnectionTypeRawTCP
|
||||
func (this *Factory) StreamCapability() v2net.NetworkList {
|
||||
return v2net.NetworkList{
|
||||
Network: []v2net.Network{v2net.Network_RawTCP},
|
||||
}
|
||||
}
|
||||
|
||||
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{}
|
||||
|
||||
func (this *Factory) StreamCapability() internet.StreamConnectionType {
|
||||
return internet.StreamConnectionTypeRawTCP
|
||||
func (this *Factory) StreamCapability() v2net.NetworkList {
|
||||
return v2net.NetworkList{
|
||||
Network: []v2net.Network{v2net.Network_RawTCP},
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
&proxy.OutboundHandlerMeta{
|
||||
Address: v2net.LocalHostIP,
|
||||
StreamSettings: &internet.StreamSettings{
|
||||
Type: internet.StreamConnectionTypeRawTCP,
|
||||
StreamSettings: &internet.StreamConfig{
|
||||
Network: v2net.Network_RawTCP,
|
||||
},
|
||||
}))
|
||||
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, ohm)
|
||||
@ -65,8 +65,8 @@ func TestDokodemoTCP(t *testing.T) {
|
||||
}, space, &proxy.InboundHandlerMeta{
|
||||
Address: v2net.LocalHostIP,
|
||||
Port: port,
|
||||
StreamSettings: &internet.StreamSettings{
|
||||
Type: internet.StreamConnectionTypeRawTCP,
|
||||
StreamSettings: &internet.StreamConfig{
|
||||
Network: v2net.Network_RawTCP,
|
||||
}})
|
||||
defer dokodemo.Close()
|
||||
|
||||
@ -119,8 +119,8 @@ func TestDokodemoUDP(t *testing.T) {
|
||||
space,
|
||||
&proxy.OutboundHandlerMeta{
|
||||
Address: v2net.AnyIP,
|
||||
StreamSettings: &internet.StreamSettings{
|
||||
Type: internet.StreamConnectionTypeRawTCP,
|
||||
StreamSettings: &internet.StreamConfig{
|
||||
Network: v2net.Network_RawTCP,
|
||||
}}))
|
||||
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, ohm)
|
||||
|
||||
@ -139,8 +139,8 @@ func TestDokodemoUDP(t *testing.T) {
|
||||
}, space, &proxy.InboundHandlerMeta{
|
||||
Address: v2net.LocalHostIP,
|
||||
Port: port,
|
||||
StreamSettings: &internet.StreamSettings{
|
||||
Type: internet.StreamConnectionTypeRawTCP,
|
||||
StreamSettings: &internet.StreamConfig{
|
||||
Network: v2net.Network_RawTCP,
|
||||
}})
|
||||
defer dokodemo.Close()
|
||||
|
||||
|
@ -129,8 +129,10 @@ func (this *FreedomConnection) Dispatch(destination v2net.Destination, payload *
|
||||
|
||||
type FreedomFactory struct{}
|
||||
|
||||
func (this *FreedomFactory) StreamCapability() internet.StreamConnectionType {
|
||||
return internet.StreamConnectionTypeRawTCP
|
||||
func (this *FreedomFactory) StreamCapability() v2net.NetworkList {
|
||||
return v2net.NetworkList{
|
||||
Network: []v2net.Network{v2net.Network_RawTCP},
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
&proxy.OutboundHandlerMeta{
|
||||
Address: v2net.AnyIP,
|
||||
StreamSettings: &internet.StreamSettings{
|
||||
Type: internet.StreamConnectionTypeRawTCP,
|
||||
StreamSettings: &internet.StreamConfig{
|
||||
Network: v2net.Network_RawTCP,
|
||||
},
|
||||
})
|
||||
space.Initialize()
|
||||
@ -68,8 +68,8 @@ func TestUnreachableDestination(t *testing.T) {
|
||||
app.NewSpace(),
|
||||
&proxy.OutboundHandlerMeta{
|
||||
Address: v2net.AnyIP,
|
||||
StreamSettings: &internet.StreamSettings{
|
||||
Type: internet.StreamConnectionTypeRawTCP,
|
||||
StreamSettings: &internet.StreamConfig{
|
||||
Network: v2net.Network_RawTCP,
|
||||
},
|
||||
})
|
||||
traffic := ray.NewRay()
|
||||
@ -104,8 +104,8 @@ func TestIPResolution(t *testing.T) {
|
||||
space,
|
||||
&proxy.OutboundHandlerMeta{
|
||||
Address: v2net.AnyIP,
|
||||
StreamSettings: &internet.StreamSettings{
|
||||
Type: internet.StreamConnectionTypeRawTCP,
|
||||
StreamSettings: &internet.StreamConfig{
|
||||
Network: v2net.Network_RawTCP,
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -264,8 +264,10 @@ func (this *Server) handlePlainHTTP(request *http.Request, session *proxy.Sessio
|
||||
|
||||
type ServerFactory struct{}
|
||||
|
||||
func (this *ServerFactory) StreamCapability() internet.StreamConnectionType {
|
||||
return internet.StreamConnectionTypeRawTCP
|
||||
func (this *ServerFactory) StreamCapability() v2net.NetworkList {
|
||||
return v2net.NetworkList{
|
||||
Network: []v2net.Network{v2net.Network_RawTCP},
|
||||
}
|
||||
}
|
||||
|
||||
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{
|
||||
Address: v2net.LocalHostIP,
|
||||
Port: port,
|
||||
StreamSettings: &internet.StreamSettings{
|
||||
Type: internet.StreamConnectionTypeRawTCP,
|
||||
StreamSettings: &internet.StreamConfig{
|
||||
Network: v2net.Network_RawTCP,
|
||||
}})
|
||||
defer httpProxy.Close()
|
||||
|
||||
|
@ -27,13 +27,13 @@ type InboundHandlerMeta struct {
|
||||
Address v2net.Address
|
||||
Port v2net.Port
|
||||
AllowPassiveConnection bool
|
||||
StreamSettings *internet.StreamSettings
|
||||
StreamSettings *internet.StreamConfig
|
||||
}
|
||||
|
||||
type OutboundHandlerMeta struct {
|
||||
Tag string
|
||||
Address v2net.Address
|
||||
StreamSettings *internet.StreamSettings
|
||||
StreamSettings *internet.StreamConfig
|
||||
}
|
||||
|
||||
// An InboundHandler handles inbound network connections to V2Ray.
|
||||
|
@ -2,16 +2,16 @@ package registry
|
||||
|
||||
import (
|
||||
"v2ray.com/core/app"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/proxy"
|
||||
"v2ray.com/core/transport/internet"
|
||||
)
|
||||
|
||||
type InboundHandlerFactory interface {
|
||||
StreamCapability() internet.StreamConnectionType
|
||||
StreamCapability() v2net.NetworkList
|
||||
Create(space app.Space, config interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error)
|
||||
}
|
||||
|
||||
type OutboundHandlerFactory interface {
|
||||
StreamCapability() internet.StreamConnectionType
|
||||
StreamCapability() v2net.NetworkList
|
||||
Create(space app.Space, config interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error)
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/proxy"
|
||||
@ -46,11 +48,13 @@ func CreateInboundHandler(name string, space app.Space, rawConfig []byte, meta *
|
||||
return nil, common.ErrObjectNotFound
|
||||
}
|
||||
if meta.StreamSettings == nil {
|
||||
meta.StreamSettings = &internet.StreamSettings{
|
||||
Type: creator.StreamCapability(),
|
||||
meta.StreamSettings = &internet.StreamConfig{
|
||||
Network: creator.StreamCapability().Get(0),
|
||||
}
|
||||
} 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 {
|
||||
@ -69,11 +73,13 @@ func CreateOutboundHandler(name string, space app.Space, rawConfig []byte, meta
|
||||
return nil, common.ErrObjectNotFound
|
||||
}
|
||||
if meta.StreamSettings == nil {
|
||||
meta.StreamSettings = &internet.StreamSettings{
|
||||
Type: creator.StreamCapability(),
|
||||
meta.StreamSettings = &internet.StreamConfig{
|
||||
Network: creator.StreamCapability().Get(0),
|
||||
}
|
||||
} 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 {
|
||||
|
@ -278,8 +278,10 @@ func (this *Server) handleConnection(conn internet.Connection) {
|
||||
|
||||
type ServerFactory struct{}
|
||||
|
||||
func (this *ServerFactory) StreamCapability() internet.StreamConnectionType {
|
||||
return internet.StreamConnectionTypeRawTCP
|
||||
func (this *ServerFactory) StreamCapability() v2net.NetworkList {
|
||||
return v2net.NetworkList{
|
||||
Network: []v2net.Network{v2net.Network_RawTCP},
|
||||
}
|
||||
}
|
||||
|
||||
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{}
|
||||
|
||||
func (this *ServerFactory) StreamCapability() internet.StreamConnectionType {
|
||||
return internet.StreamConnectionTypeRawTCP
|
||||
func (this *ServerFactory) StreamCapability() v2net.NetworkList {
|
||||
return v2net.NetworkList{
|
||||
Network: []v2net.Network{v2net.Network_RawTCP},
|
||||
}
|
||||
}
|
||||
|
||||
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{}
|
||||
|
||||
func (this *Factory) StreamCapability() internet.StreamConnectionType {
|
||||
return internet.StreamConnectionTypeRawTCP | internet.StreamConnectionTypeTCP | internet.StreamConnectionTypeKCP | internet.StreamConnectionTypeWebSocket
|
||||
func (this *Factory) StreamCapability() v2net.NetworkList {
|
||||
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) {
|
||||
|
@ -160,8 +160,10 @@ func (this *VMessOutboundHandler) handleResponse(session *encoding.ClientSession
|
||||
|
||||
type Factory struct{}
|
||||
|
||||
func (this *Factory) StreamCapability() internet.StreamConnectionType {
|
||||
return internet.StreamConnectionTypeRawTCP | internet.StreamConnectionTypeTCP | internet.StreamConnectionTypeKCP | internet.StreamConnectionTypeWebSocket
|
||||
func (this *Factory) StreamCapability() v2net.NetworkList {
|
||||
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) {
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
type InboundConnectionConfig struct {
|
||||
Port v2net.Port
|
||||
ListenOn v2net.Address
|
||||
StreamSettings *internet.StreamSettings
|
||||
StreamSettings *internet.StreamConfig
|
||||
Protocol string
|
||||
Settings []byte
|
||||
AllowPassiveConnection bool
|
||||
@ -22,7 +22,7 @@ type InboundConnectionConfig struct {
|
||||
type OutboundConnectionConfig struct {
|
||||
Protocol string
|
||||
SendThrough v2net.Address
|
||||
StreamSettings *internet.StreamSettings
|
||||
StreamSettings *internet.StreamConfig
|
||||
Settings []byte
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ type InboundDetourConfig struct {
|
||||
ListenOn v2net.Address
|
||||
Tag string
|
||||
Allocation *InboundDetourAllocationConfig
|
||||
StreamSettings *internet.StreamSettings
|
||||
StreamSettings *internet.StreamConfig
|
||||
Settings []byte
|
||||
AllowPassiveConnection bool
|
||||
}
|
||||
@ -58,7 +58,7 @@ type InboundDetourConfig struct {
|
||||
type OutboundDetourConfig struct {
|
||||
Protocol string
|
||||
SendThrough v2net.Address
|
||||
StreamSettings *internet.StreamSettings
|
||||
StreamSettings *internet.StreamConfig
|
||||
Tag string
|
||||
Settings []byte
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ func (this *InboundConnectionConfig) UnmarshalJSON(data []byte) error {
|
||||
Port uint16 `json:"port"`
|
||||
Listen *v2net.AddressPB `json:"listen"`
|
||||
Protocol string `json:"protocol"`
|
||||
StreamSetting *internet.StreamSettings `json:"streamSettings"`
|
||||
StreamSetting *internet.StreamConfig `json:"streamSettings"`
|
||||
Settings json.RawMessage `json:"settings"`
|
||||
AllowPassive bool `json:"allowPassive"`
|
||||
}
|
||||
@ -107,7 +107,7 @@ func (this *OutboundConnectionConfig) UnmarshalJSON(data []byte) error {
|
||||
type JsonConnectionConfig struct {
|
||||
Protocol string `json:"protocol"`
|
||||
SendThrough *v2net.AddressPB `json:"sendThrough"`
|
||||
StreamSetting *internet.StreamSettings `json:"streamSettings"`
|
||||
StreamSetting *internet.StreamConfig `json:"streamSettings"`
|
||||
Settings json.RawMessage `json:"settings"`
|
||||
}
|
||||
jsonConfig := new(JsonConnectionConfig)
|
||||
@ -194,7 +194,7 @@ func (this *InboundDetourConfig) UnmarshalJSON(data []byte) error {
|
||||
Settings json.RawMessage `json:"settings"`
|
||||
Tag string `json:"tag"`
|
||||
Allocation *InboundDetourAllocationConfig `json:"allocate"`
|
||||
StreamSetting *internet.StreamSettings `json:"streamSettings"`
|
||||
StreamSetting *internet.StreamConfig `json:"streamSettings"`
|
||||
AllowPassive bool `json:"allowPassive"`
|
||||
}
|
||||
jsonConfig := new(JsonInboundDetourConfig)
|
||||
@ -236,7 +236,7 @@ func (this *OutboundDetourConfig) UnmarshalJSON(data []byte) error {
|
||||
SendThrough *v2net.AddressPB `json:"sendThrough"`
|
||||
Tag string `json:"tag"`
|
||||
Settings json.RawMessage `json:"settings"`
|
||||
StreamSetting *internet.StreamSettings `json:"streamSettings"`
|
||||
StreamSetting *internet.StreamConfig `json:"streamSettings"`
|
||||
}
|
||||
jsonConfig := new(JsonOutboundDetourConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
|
@ -1,26 +1,11 @@
|
||||
package transport
|
||||
|
||||
import (
|
||||
"v2ray.com/core/transport/internet/kcp"
|
||||
"v2ray.com/core/transport/internet/tcp"
|
||||
"v2ray.com/core/transport/internet/ws"
|
||||
"v2ray.com/core/transport/internet"
|
||||
)
|
||||
|
||||
// Config for V2Ray transport layer.
|
||||
type Config struct {
|
||||
tcpConfig *tcp.Config
|
||||
kcpConfig kcp.Config
|
||||
wsConfig *ws.Config
|
||||
}
|
||||
|
||||
// Apply applies this Config.
|
||||
func (this *Config) Apply() error {
|
||||
if this.tcpConfig != nil {
|
||||
this.tcpConfig.Apply()
|
||||
}
|
||||
this.kcpConfig.Apply()
|
||||
if this.wsConfig != nil {
|
||||
this.wsConfig.Apply()
|
||||
}
|
||||
internet.ApplyGlobalNetworkSettings(this.NetworkSettings)
|
||||
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_outer_classname = "ConfigProto";
|
||||
|
||||
message Config {
|
||||
import "v2ray.com/core/transport/internet/config.proto";
|
||||
|
||||
message Config {
|
||||
repeated v2ray.core.transport.internet.NetworkSettings network_settings = 1;
|
||||
}
|
@ -5,23 +5,57 @@ package transport
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/transport/internet"
|
||||
"v2ray.com/core/transport/internet/kcp"
|
||||
"v2ray.com/core/transport/internet/tcp"
|
||||
"v2ray.com/core/transport/internet/ws"
|
||||
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
)
|
||||
|
||||
func (this *Config) UnmarshalJSON(data []byte) error {
|
||||
type JsonConfig struct {
|
||||
TCPConfig *tcp.Config `json:"tcpSettings"`
|
||||
KCPConfig kcp.Config `json:"kcpSettings"`
|
||||
KCPConfig *kcp.Config `json:"kcpSettings"`
|
||||
WSConfig *ws.Config `json:"wsSettings"`
|
||||
}
|
||||
jsonConfig := &JsonConfig{}
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
this.tcpConfig = jsonConfig.TCPConfig
|
||||
this.kcpConfig = jsonConfig.KCPConfig
|
||||
this.wsConfig = jsonConfig.WSConfig
|
||||
|
||||
if jsonConfig.TCPConfig != nil {
|
||||
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
|
||||
}
|
||||
|
@ -7,9 +7,13 @@ Package internet is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
v2ray.com/core/transport/internet/authenticator.proto
|
||||
v2ray.com/core/transport/internet/config.proto
|
||||
|
||||
It has these top-level messages:
|
||||
AuthenticatorConfig
|
||||
SecuritySettings
|
||||
NetworkSettings
|
||||
StreamConfig
|
||||
*/
|
||||
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
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
)
|
||||
|
||||
@ -12,56 +11,6 @@ type Reusable interface {
|
||||
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 {
|
||||
net.Conn
|
||||
Reusable
|
||||
|
@ -3,65 +3,42 @@
|
||||
package internet
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"errors"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
v2tls "v2ray.com/core/transport/internet/tls"
|
||||
)
|
||||
|
||||
func (this *TLSSettings) UnmarshalJSON(data []byte) error {
|
||||
type JSONCertConfig struct {
|
||||
CertFile string `json:"certificateFile"`
|
||||
KeyFile string `json:"keyFile"`
|
||||
}
|
||||
func (this *StreamConfig) UnmarshalJSON(data []byte) error {
|
||||
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.Certs = make([]tls.Certificate, len(jsonConfig.Certs))
|
||||
for idx, certConf := range jsonConfig.Certs {
|
||||
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
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *StreamSettings) UnmarshalJSON(data []byte) error {
|
||||
type JSONConfig struct {
|
||||
Network v2net.NetworkList `json:"network"`
|
||||
Network *v2net.Network `json:"network"`
|
||||
Security string `json:"security"`
|
||||
TLSSettings *TLSSettings `json:"tlsSettings"`
|
||||
TLSSettings *v2tls.Config `json:"tlsSettings"`
|
||||
}
|
||||
this.Type = StreamConnectionTypeRawTCP
|
||||
this.Network = v2net.Network_RawTCP
|
||||
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 != nil {
|
||||
this.Network = *jsonConfig.Network
|
||||
}
|
||||
if jsonConfig.Network.HasNetwork(v2net.Network_WebSocket) {
|
||||
this.Type |= StreamConnectionTypeWebSocket
|
||||
}
|
||||
if jsonConfig.Network.HasNetwork(v2net.Network_TCP) {
|
||||
this.Type |= StreamConnectionTypeTCP
|
||||
}
|
||||
this.Security = StreamSecurityTypeNone
|
||||
this.SecurityType = SecurityType_None
|
||||
if strings.ToLower(jsonConfig.Security) == "tls" {
|
||||
this.Security = StreamSecurityTypeTLS
|
||||
this.SecurityType = SecurityType_TLS
|
||||
}
|
||||
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
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ var (
|
||||
)
|
||||
|
||||
type DialerOptions struct {
|
||||
Stream *StreamSettings
|
||||
Stream *StreamConfig
|
||||
}
|
||||
|
||||
type Dialer func(src v2net.Address, dest v2net.Destination, options DialerOptions) (Connection, error)
|
||||
@ -25,7 +25,7 @@ var (
|
||||
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 err error
|
||||
@ -33,16 +33,16 @@ func Dial(src v2net.Address, dest v2net.Destination, settings *StreamSettings) (
|
||||
Stream: settings,
|
||||
}
|
||||
if dest.Network == v2net.Network_TCP {
|
||||
switch {
|
||||
case settings.IsCapableOf(StreamConnectionTypeTCP):
|
||||
switch settings.Network {
|
||||
case v2net.Network_TCP:
|
||||
connection, err = TCPDialer(src, dest, dialerOptions)
|
||||
case settings.IsCapableOf(StreamConnectionTypeKCP):
|
||||
case v2net.Network_KCP:
|
||||
connection, err = KCPDialer(src, dest, dialerOptions)
|
||||
case settings.IsCapableOf(StreamConnectionTypeWebSocket):
|
||||
case v2net.Network_WebSocket:
|
||||
connection, err = WSDialer(src, dest, dialerOptions)
|
||||
|
||||
// This check has to be the last one.
|
||||
case settings.IsCapableOf(StreamConnectionTypeRawTCP):
|
||||
case v2net.Network_RawTCP:
|
||||
connection, err = RawTCPDialer(src, dest, dialerOptions)
|
||||
default:
|
||||
return nil, ErrUnsupportedStreamType
|
||||
|
@ -1,7 +1,10 @@
|
||||
package kcp
|
||||
|
||||
import (
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/transport/internet"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
)
|
||||
|
||||
func (this *MTU) GetValue() uint32 {
|
||||
@ -46,10 +49,6 @@ func (this *ReadBuffer) GetSize() uint32 {
|
||||
return this.Size
|
||||
}
|
||||
|
||||
func (this *Config) Apply() {
|
||||
effectiveConfig = *this
|
||||
}
|
||||
|
||||
func (this *Config) GetAuthenticator() (internet.Authenticator, error) {
|
||||
auth := NewSimpleAuthenticator()
|
||||
if this.HeaderConfig != nil {
|
||||
@ -86,6 +85,8 @@ func (this *Config) GetReceivingBufferSize() uint32 {
|
||||
return this.GetReceivingInFlightSize() + this.ReadBuffer.GetSize()/this.Mtu.GetValue()
|
||||
}
|
||||
|
||||
var (
|
||||
effectiveConfig Config
|
||||
)
|
||||
func init() {
|
||||
internet.RegisterNetworkConfigCreator(v2net.Network_KCP, func() proto.Message {
|
||||
return new(Config)
|
||||
})
|
||||
}
|
||||
|
@ -129,6 +129,7 @@ type Connection struct {
|
||||
since int64
|
||||
dataInputCond *sync.Cond
|
||||
dataOutputCond *sync.Cond
|
||||
Config *Config
|
||||
|
||||
conv uint16
|
||||
state State
|
||||
@ -149,7 +150,7 @@ type Connection struct {
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
conn := new(Connection)
|
||||
@ -160,10 +161,12 @@ func NewConnection(conv uint16, writerCloser io.WriteCloser, local *net.UDPAddr,
|
||||
conn.since = nowMillisec()
|
||||
conn.dataInputCond = sync.NewCond(new(sync.Mutex))
|
||||
conn.dataOutputCond = sync.NewCond(new(sync.Mutex))
|
||||
conn.Config = config
|
||||
|
||||
authWriter := &AuthenticationWriter{
|
||||
Authenticator: block,
|
||||
Writer: writerCloser,
|
||||
Config: config,
|
||||
}
|
||||
conn.conv = conv
|
||||
conn.output = NewSegmentWriter(authWriter)
|
||||
@ -171,12 +174,12 @@ func NewConnection(conv uint16, writerCloser io.WriteCloser, local *net.UDPAddr,
|
||||
conn.mss = authWriter.Mtu() - DataSegmentOverhead
|
||||
conn.roundTrip = &RoundTripInfo{
|
||||
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.fastresend = 2
|
||||
conn.congestionControl = effectiveConfig.Congestion
|
||||
conn.congestionControl = config.Congestion
|
||||
conn.sendingWorker = NewSendingWorker(conn)
|
||||
|
||||
go conn.updateTask()
|
||||
@ -366,7 +369,7 @@ func (this *Connection) updateTask() {
|
||||
for this.State() != StateTerminated {
|
||||
this.flush()
|
||||
|
||||
interval := time.Duration(effectiveConfig.Tti.GetValue()) * time.Millisecond
|
||||
interval := time.Duration(this.Config.Tti.GetValue()) * time.Millisecond
|
||||
if this.State() == StateTerminating {
|
||||
interval = time.Second
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ func (this *NoOpWriteCloser) Close() error {
|
||||
func TestConnectionReadTimeout(t *testing.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))
|
||||
|
||||
b := make([]byte, 1024)
|
||||
@ -44,10 +44,10 @@ func TestConnectionReadWrite(t *testing.T) {
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
totalWritten := 1024 * 1024
|
||||
|
@ -25,20 +25,32 @@ func DialKCP(src v2net.Address, dest v2net.Destination, options internet.DialerO
|
||||
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 {
|
||||
log.Error("KCP|Dialer: Failed to create authenticator: ", err)
|
||||
return nil, err
|
||||
}
|
||||
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)
|
||||
|
||||
var iConn internet.Connection
|
||||
iConn = session
|
||||
|
||||
if options.Stream != nil && options.Stream.Security == internet.StreamSecurityTypeTLS {
|
||||
config := options.Stream.TLSSettings.GetTLSConfig()
|
||||
if options.Stream != nil && options.Stream.SecurityType == internet.SecurityType_TLS {
|
||||
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() {
|
||||
config.ServerName = dest.Address.Domain()
|
||||
}
|
||||
|
@ -12,12 +12,28 @@ import (
|
||||
"v2ray.com/core/testing/assert"
|
||||
"v2ray.com/core/transport/internet"
|
||||
. "v2ray.com/core/transport/internet/kcp"
|
||||
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
)
|
||||
|
||||
func TestDialAndListen(t *testing.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()
|
||||
port := v2net.Port(listerner.Addr().(*net.UDPAddr).Port)
|
||||
|
||||
@ -46,7 +62,17 @@ func TestDialAndListen(t *testing.T) {
|
||||
|
||||
wg := new(sync.WaitGroup)
|
||||
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()
|
||||
wg.Add(1)
|
||||
|
||||
|
@ -25,10 +25,18 @@ type Listener struct {
|
||||
awaitingConns chan *Connection
|
||||
hub *udp.UDPHub
|
||||
tlsConfig *tls.Config
|
||||
config *Config
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@ -37,9 +45,15 @@ func NewListener(address v2net.Address, port v2net.Port, options internet.Listen
|
||||
sessions: make(map[string]*Connection),
|
||||
awaitingConns: make(chan *Connection, 64),
|
||||
running: true,
|
||||
config: kcpSettings,
|
||||
}
|
||||
if options.Stream != nil && options.Stream.Security == internet.StreamSecurityTypeTLS {
|
||||
l.tlsConfig = options.Stream.TLSSettings.GetTLSConfig()
|
||||
if options.Stream != nil && options.Stream.SecurityType == internet.SecurityType_TLS {
|
||||
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})
|
||||
if err != nil {
|
||||
@ -89,11 +103,11 @@ func (this *Listener) OnReceive(payload *alloc.Buffer, session *proxy.SessionInf
|
||||
IP: src.Address.IP(),
|
||||
Port: int(src.Port),
|
||||
}
|
||||
auth, err := effectiveConfig.GetAuthenticator()
|
||||
auth, err := this.config.GetAuthenticator()
|
||||
if err != nil {
|
||||
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 {
|
||||
case this.awaitingConns <- conn:
|
||||
case <-time.After(time.Second * 5):
|
||||
|
@ -62,6 +62,7 @@ func (this *BufferedSegmentWriter) Flush() {
|
||||
type AuthenticationWriter struct {
|
||||
Authenticator internet.Authenticator
|
||||
Writer io.Writer
|
||||
Config *Config
|
||||
}
|
||||
|
||||
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) 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 {
|
||||
worker := &ReceivingWorker{
|
||||
conn: kcp,
|
||||
window: NewReceivingWindow(effectiveConfig.GetReceivingBufferSize()),
|
||||
windowSize: effectiveConfig.GetReceivingInFlightSize(),
|
||||
window: NewReceivingWindow(kcp.Config.GetReceivingBufferSize()),
|
||||
windowSize: kcp.Config.GetReceivingInFlightSize(),
|
||||
}
|
||||
worker.acklist = NewAckList(worker)
|
||||
return worker
|
||||
|
@ -185,9 +185,9 @@ func NewSendingWorker(kcp *Connection) *SendingWorker {
|
||||
conn: kcp,
|
||||
fastResend: 2,
|
||||
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
|
||||
}
|
||||
|
||||
@ -291,7 +291,7 @@ func (this *SendingWorker) Write(seg Segment) {
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@ -303,8 +303,8 @@ func (this *SendingWorker) OnPacketLoss(lossRate uint32) {
|
||||
if this.controlWindow < 16 {
|
||||
this.controlWindow = 16
|
||||
}
|
||||
if this.controlWindow > 2*effectiveConfig.GetSendingInFlightSize() {
|
||||
this.controlWindow = 2 * effectiveConfig.GetSendingInFlightSize()
|
||||
if this.controlWindow > 2*this.conn.Config.GetSendingInFlightSize() {
|
||||
this.controlWindow = 2 * this.conn.Config.GetSendingInFlightSize()
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,11 +312,11 @@ func (this *SendingWorker) Flush(current uint32) {
|
||||
this.Lock()
|
||||
defer this.Unlock()
|
||||
|
||||
cwnd := this.firstUnacknowledged + effectiveConfig.GetSendingInFlightSize()
|
||||
cwnd := this.firstUnacknowledged + this.conn.Config.GetSendingInFlightSize()
|
||||
if 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
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,14 @@
|
||||
package tcp
|
||||
|
||||
type Config struct {
|
||||
ConnectionReuse bool
|
||||
}
|
||||
import (
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/transport/internet"
|
||||
|
||||
func (this *Config) Apply() {
|
||||
effectiveConfig = this
|
||||
}
|
||||
|
||||
var (
|
||||
effectiveConfig = &Config{
|
||||
ConnectionReuse: true,
|
||||
}
|
||||
"github.com/golang/protobuf/proto"
|
||||
)
|
||||
|
||||
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
|
||||
listener ConnectionManager
|
||||
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{
|
||||
dest: dest,
|
||||
conn: conn,
|
||||
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) {
|
||||
if !effectiveConfig.ConnectionReuse {
|
||||
if !this.config.ConnectionReuse {
|
||||
return
|
||||
}
|
||||
this.reusable = reusable
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"v2ray.com/core/common/log"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/transport/internet"
|
||||
v2tls "v2ray.com/core/transport/internet/tls"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -18,9 +19,15 @@ func Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOpti
|
||||
if src == nil {
|
||||
src = v2net.AnyIP
|
||||
}
|
||||
networkSettings, err := options.Stream.GetEffectiveNetworkSettings()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tcpSettings := networkSettings.(*Config)
|
||||
|
||||
id := src.String() + "-" + dest.NetAddr()
|
||||
var conn net.Conn
|
||||
if dest.Network == v2net.Network_TCP && effectiveConfig.ConnectionReuse {
|
||||
if dest.Network == v2net.Network_TCP && tcpSettings.ConnectionReuse {
|
||||
conn = globalCache.Get(id)
|
||||
}
|
||||
if conn == nil {
|
||||
@ -30,14 +37,19 @@ func Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOpti
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if options.Stream != nil && options.Stream.Security == internet.StreamSecurityTypeTLS {
|
||||
config := options.Stream.TLSSettings.GetTLSConfig()
|
||||
if options.Stream != nil && options.Stream.SecurityType == internet.SecurityType_TLS {
|
||||
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() {
|
||||
config.ServerName = dest.Address.Domain()
|
||||
}
|
||||
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) {
|
||||
|
@ -7,8 +7,10 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"v2ray.com/core/common/log"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/transport/internet"
|
||||
v2tls "v2ray.com/core/transport/internet/tls"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -26,6 +28,7 @@ type TCPListener struct {
|
||||
listener *net.TCPListener
|
||||
awaitingConns chan *ConnectionWithError
|
||||
tlsConfig *tls.Config
|
||||
config *Config
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
networkSettings, err := options.Stream.GetEffectiveNetworkSettings()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tcpSettings := networkSettings.(*Config)
|
||||
|
||||
l := &TCPListener{
|
||||
acccepting: true,
|
||||
listener: listener,
|
||||
awaitingConns: make(chan *ConnectionWithError, 32),
|
||||
config: tcpSettings,
|
||||
}
|
||||
if options.Stream != nil && options.Stream.Security == internet.StreamSecurityTypeTLS {
|
||||
l.tlsConfig = options.Stream.TLSSettings.GetTLSConfig()
|
||||
if options.Stream != nil && options.Stream.SecurityType == internet.SecurityType_TLS {
|
||||
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()
|
||||
return l, nil
|
||||
@ -62,7 +77,7 @@ func (this *TCPListener) Accept() (internet.Connection, error) {
|
||||
if this.tlsConfig != nil {
|
||||
conn = tls.Server(conn, this.tlsConfig)
|
||||
}
|
||||
return NewConnection("", conn, this), nil
|
||||
return NewConnection("", conn, this, this.config), nil
|
||||
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 ListenOptions struct {
|
||||
Stream *StreamSettings
|
||||
Stream *StreamConfig
|
||||
}
|
||||
|
||||
type Listener interface {
|
||||
@ -36,23 +36,23 @@ type TCPHub struct {
|
||||
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 err error
|
||||
options := ListenOptions{
|
||||
Stream: settings,
|
||||
}
|
||||
switch {
|
||||
case settings.IsCapableOf(StreamConnectionTypeTCP):
|
||||
switch settings.Network {
|
||||
case v2net.Network_TCP:
|
||||
listener, err = TCPListenFunc(address, port, options)
|
||||
case settings.IsCapableOf(StreamConnectionTypeKCP):
|
||||
case v2net.Network_KCP:
|
||||
listener, err = KCPListenFunc(address, port, options)
|
||||
case settings.IsCapableOf(StreamConnectionTypeWebSocket):
|
||||
case v2net.Network_WebSocket:
|
||||
listener, err = WSListenFunc(address, port, options)
|
||||
case settings.IsCapableOf(StreamConnectionTypeRawTCP):
|
||||
case v2net.Network_RawTCP:
|
||||
listener, err = RawTCPListenFunc(address, port, options)
|
||||
default:
|
||||
log.Error("Internet|Listener: Unknown stream type: ", settings.Type)
|
||||
log.Error("Internet|Listener: Unknown stream type: ", settings.Network)
|
||||
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
|
||||
|
||||
type Config struct {
|
||||
ConnectionReuse bool
|
||||
Path string
|
||||
}
|
||||
import (
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/transport/internet"
|
||||
|
||||
func (this *Config) Apply() {
|
||||
effectiveConfig = this
|
||||
}
|
||||
|
||||
var (
|
||||
effectiveConfig = &Config{
|
||||
ConnectionReuse: true,
|
||||
Path: "",
|
||||
}
|
||||
"github.com/golang/protobuf/proto"
|
||||
)
|
||||
|
||||
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
|
||||
listener ConnectionManager
|
||||
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{
|
||||
dest: dest,
|
||||
conn: conn,
|
||||
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) {
|
||||
if !effectiveConfig.ConnectionReuse {
|
||||
if !this.config.ConnectionReuse {
|
||||
return
|
||||
}
|
||||
this.reusable = reusable
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"v2ray.com/core/common/log"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/transport/internet"
|
||||
v2tls "v2ray.com/core/transport/internet/tls"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -20,9 +21,15 @@ func Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOpti
|
||||
if src == nil {
|
||||
src = v2net.AnyIP
|
||||
}
|
||||
networkSettings, err := options.Stream.GetEffectiveNetworkSettings()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wsSettings := networkSettings.(*Config)
|
||||
|
||||
id := src.String() + "-" + dest.NetAddr()
|
||||
var conn *wsconn
|
||||
if dest.Network == v2net.Network_TCP && effectiveConfig.ConnectionReuse {
|
||||
if dest.Network == v2net.Network_TCP && wsSettings.ConnectionReuse {
|
||||
connt := globalCache.Get(id)
|
||||
if connt != nil {
|
||||
conn = connt.(*wsconn)
|
||||
@ -36,7 +43,7 @@ func Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOpti
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return NewConnection(id, conn, globalCache), nil
|
||||
return NewConnection(id, conn, globalCache, wsSettings), nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -44,6 +51,12 @@ func init() {
|
||||
}
|
||||
|
||||
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) {
|
||||
return internet.DialToDest(src, dest)
|
||||
}
|
||||
@ -56,9 +69,14 @@ func wsDial(src v2net.Address, dest v2net.Destination, options internet.DialerOp
|
||||
|
||||
protocol := "ws"
|
||||
|
||||
if options.Stream != nil && options.Stream.Security == internet.StreamSecurityTypeTLS {
|
||||
if options.Stream != nil && options.Stream.SecurityType == internet.SecurityType_TLS {
|
||||
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() {
|
||||
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 {
|
||||
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)
|
||||
if err != nil {
|
||||
@ -77,7 +95,11 @@ func wsDial(src v2net.Address, dest v2net.Destination, options internet.DialerOp
|
||||
return nil, err
|
||||
}
|
||||
return func() internet.Connection {
|
||||
connv2ray := &wsconn{wsc: conn, connClosing: false}
|
||||
connv2ray := &wsconn{
|
||||
wsc: conn,
|
||||
connClosing: false,
|
||||
config: wsSettings,
|
||||
}
|
||||
connv2ray.setup()
|
||||
return connv2ray
|
||||
}().(*wsconn), nil
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"v2ray.com/core/common/log"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/transport/internet"
|
||||
v2tls "v2ray.com/core/transport/internet/tls"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -30,26 +31,37 @@ type WSListener struct {
|
||||
awaitingConns chan *ConnectionWithError
|
||||
listener *StoppableListener
|
||||
tlsConfig *tls.Config
|
||||
config *Config
|
||||
}
|
||||
|
||||
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{
|
||||
acccepting: true,
|
||||
awaitingConns: make(chan *ConnectionWithError, 32),
|
||||
config: wsSettings,
|
||||
}
|
||||
if options.Stream != nil && options.Stream.Security == internet.StreamSecurityTypeTLS {
|
||||
l.tlsConfig = options.Stream.TLSSettings.GetTLSConfig()
|
||||
if options.Stream != nil && options.Stream.SecurityType == internet.SecurityType_TLS {
|
||||
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
|
||||
}
|
||||
|
||||
func (wsl *WSListener) listenws(address v2net.Address, port v2net.Port) error {
|
||||
|
||||
http.HandleFunc("/"+effectiveConfig.Path, func(w http.ResponseWriter, r *http.Request) {
|
||||
http.HandleFunc("/"+wsl.config.Path, func(w http.ResponseWriter, r *http.Request) {
|
||||
con, err := wsl.converttovws(w, r)
|
||||
if err != nil {
|
||||
log.Warning("WebSocket|Listener: Failed to convert connection: ", err)
|
||||
@ -140,7 +152,7 @@ func (this *WSListener) Accept() (internet.Connection, error) {
|
||||
if connErr.err != nil {
|
||||
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):
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,43 @@
|
||||
package ws_test
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/testing/assert"
|
||||
"v2ray.com/core/transport/internet"
|
||||
v2tls "v2ray.com/core/transport/internet/tls"
|
||||
. "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) {
|
||||
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()
|
||||
conn.Write([]byte("echo"))
|
||||
s := make(chan int)
|
||||
@ -33,10 +56,18 @@ func Test_Connect_ws(t *testing.T) {
|
||||
|
||||
func Test_Connect_wss(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
(&Config{Path: ""}).Apply()
|
||||
conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443), internet.DialerOptions{
|
||||
Stream: &internet.StreamSettings{
|
||||
Security: internet.StreamSecurityTypeTLS,
|
||||
Stream: &internet.StreamConfig{
|
||||
Network: v2net.Network_WebSocket,
|
||||
NetworkSettings: []*internet.NetworkSettings{
|
||||
{
|
||||
Network: v2net.Network_WebSocket,
|
||||
Settings: MarshalSettings(&Config{
|
||||
Path: "",
|
||||
}, assert),
|
||||
},
|
||||
},
|
||||
SecurityType: internet.SecurityType_TLS,
|
||||
},
|
||||
})
|
||||
assert.Error(err).IsNil()
|
||||
@ -57,10 +88,18 @@ func Test_Connect_wss(t *testing.T) {
|
||||
|
||||
func Test_Connect_wss_1_nil(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
(&Config{Path: ""}).Apply()
|
||||
conn, err := Dial(nil, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443), internet.DialerOptions{
|
||||
Stream: &internet.StreamSettings{
|
||||
Security: internet.StreamSecurityTypeTLS,
|
||||
Stream: &internet.StreamConfig{
|
||||
Network: v2net.Network_WebSocket,
|
||||
NetworkSettings: []*internet.NetworkSettings{
|
||||
{
|
||||
Network: v2net.Network_WebSocket,
|
||||
Settings: MarshalSettings(&Config{
|
||||
Path: "",
|
||||
}, assert),
|
||||
},
|
||||
},
|
||||
SecurityType: internet.SecurityType_TLS,
|
||||
},
|
||||
})
|
||||
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) {
|
||||
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()
|
||||
conn.Write([]byte("echo"))
|
||||
s := make(chan int)
|
||||
@ -101,10 +151,18 @@ func Test_Connect_ws_guess(t *testing.T) {
|
||||
|
||||
func Test_Connect_wss_guess(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
(&Config{Path: ""}).Apply()
|
||||
conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443), internet.DialerOptions{
|
||||
Stream: &internet.StreamSettings{
|
||||
Security: internet.StreamSecurityTypeTLS,
|
||||
Stream: &internet.StreamConfig{
|
||||
Network: v2net.Network_WebSocket,
|
||||
NetworkSettings: []*internet.NetworkSettings{
|
||||
{
|
||||
Network: v2net.Network_WebSocket,
|
||||
Settings: MarshalSettings(&Config{
|
||||
Path: "",
|
||||
}, assert),
|
||||
},
|
||||
},
|
||||
SecurityType: internet.SecurityType_TLS,
|
||||
},
|
||||
})
|
||||
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) {
|
||||
assert := assert.On(t)
|
||||
(&Config{Path: ""}).Apply()
|
||||
_, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("static.kkdev.org"), 443), internet.DialerOptions{
|
||||
Stream: &internet.StreamSettings{
|
||||
Security: internet.StreamSecurityTypeTLS,
|
||||
Stream: &internet.StreamConfig{
|
||||
Network: v2net.Network_WebSocket,
|
||||
NetworkSettings: []*internet.NetworkSettings{
|
||||
{
|
||||
Network: v2net.Network_WebSocket,
|
||||
Settings: MarshalSettings(&Config{
|
||||
Path: "",
|
||||
}, assert),
|
||||
},
|
||||
},
|
||||
SecurityType: internet.SecurityType_TLS,
|
||||
},
|
||||
})
|
||||
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) {
|
||||
assert := assert.On(t)
|
||||
(&Config{Path: "", ConnectionReuse: true}).Apply()
|
||||
i := 3
|
||||
for i != 0 {
|
||||
conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443), internet.DialerOptions{
|
||||
Stream: &internet.StreamSettings{
|
||||
Security: internet.StreamSecurityTypeTLS,
|
||||
Stream: &internet.StreamConfig{
|
||||
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()
|
||||
@ -170,8 +245,19 @@ func Test_Connect_wss_guess_reuse(t *testing.T) {
|
||||
|
||||
func Test_listenWSAndDial(t *testing.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()
|
||||
go func() {
|
||||
conn, err := listen.Accept()
|
||||
@ -185,15 +271,51 @@ func Test_listenWSAndDial(t *testing.T) {
|
||||
conn.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()
|
||||
conn.Close()
|
||||
<-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()
|
||||
conn.Close()
|
||||
<-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()
|
||||
conn.Close()
|
||||
}
|
||||
@ -204,14 +326,34 @@ func Test_listenWSAndDial_TLS(t *testing.T) {
|
||||
<-time.After(time.Second * 5)
|
||||
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{
|
||||
Stream: &internet.StreamSettings{
|
||||
Security: internet.StreamSecurityTypeTLS,
|
||||
TLSSettings: &internet.TLSSettings{
|
||||
AllowInsecure: true,
|
||||
Certs: LoadTestCert(assert),
|
||||
Stream: &internet.StreamConfig{
|
||||
SecurityType: internet.SecurityType_TLS,
|
||||
SecuritySettings: []*internet.SecuritySettings{{
|
||||
Type: internet.SecurityType_TLS,
|
||||
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()
|
||||
}()
|
||||
conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13143), internet.DialerOptions{
|
||||
Stream: &internet.StreamSettings{
|
||||
Security: internet.StreamSecurityTypeTLS,
|
||||
TLSSettings: &internet.TLSSettings{
|
||||
AllowInsecure: true,
|
||||
Certs: LoadTestCert(assert),
|
||||
Stream: &internet.StreamConfig{
|
||||
SecurityType: internet.SecurityType_TLS,
|
||||
SecuritySettings: []*internet.SecuritySettings{{
|
||||
Type: internet.SecurityType_TLS,
|
||||
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()
|
||||
}
|
||||
|
||||
func LoadTestCert(assert *assert.Assert) []tls.Certificate {
|
||||
cert, err := tls.LoadX509KeyPair("./../../../testing/tls/cert.pem", "./../../../testing/tls/key.pem")
|
||||
func ReadFile(file string, assert *assert.Assert) []byte {
|
||||
b, err := ioutil.ReadFile(file)
|
||||
assert.Error(err).IsNil()
|
||||
return []tls.Certificate{cert}
|
||||
return b
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ type wsconn struct {
|
||||
reusable bool
|
||||
rlock *sync.Mutex
|
||||
wlock *sync.Mutex
|
||||
config *Config
|
||||
}
|
||||
|
||||
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) {
|
||||
if !effectiveConfig.ConnectionReuse {
|
||||
if !ws.config.ConnectionReuse {
|
||||
return
|
||||
}
|
||||
ws.reusable = reusable
|
||||
|
Loading…
Reference in New Issue
Block a user