1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-12-21 17:46:58 -05:00

able to redirect to another destination in freedom

This commit is contained in:
Darien Raymond 2017-01-26 23:05:24 +01:00
parent 8151a4a2dc
commit 9462f710a5
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
5 changed files with 159 additions and 21 deletions

View File

@ -3,6 +3,7 @@ package freedom
import proto "github.com/golang/protobuf/proto" import proto "github.com/golang/protobuf/proto"
import fmt "fmt" import fmt "fmt"
import math "math" import math "math"
import v2ray_core_common_protocol1 "v2ray.com/core/common/protocol"
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal var _ = proto.Marshal
@ -34,17 +35,34 @@ var Config_DomainStrategy_value = map[string]int32{
func (x Config_DomainStrategy) String() string { func (x Config_DomainStrategy) String() string {
return proto.EnumName(Config_DomainStrategy_name, int32(x)) return proto.EnumName(Config_DomainStrategy_name, int32(x))
} }
func (Config_DomainStrategy) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} } func (Config_DomainStrategy) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 0} }
type DestinationOverride struct {
Server *v2ray_core_common_protocol1.ServerEndpoint `protobuf:"bytes,1,opt,name=server" json:"server,omitempty"`
}
func (m *DestinationOverride) Reset() { *m = DestinationOverride{} }
func (m *DestinationOverride) String() string { return proto.CompactTextString(m) }
func (*DestinationOverride) ProtoMessage() {}
func (*DestinationOverride) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *DestinationOverride) GetServer() *v2ray_core_common_protocol1.ServerEndpoint {
if m != nil {
return m.Server
}
return nil
}
type Config struct { type Config struct {
DomainStrategy Config_DomainStrategy `protobuf:"varint,1,opt,name=domainStrategy,enum=v2ray.core.proxy.freedom.Config_DomainStrategy" json:"domainStrategy,omitempty"` DomainStrategy Config_DomainStrategy `protobuf:"varint,1,opt,name=domain_strategy,json=domainStrategy,enum=v2ray.core.proxy.freedom.Config_DomainStrategy" json:"domain_strategy,omitempty"`
Timeout uint32 `protobuf:"varint,2,opt,name=timeout" json:"timeout,omitempty"` Timeout uint32 `protobuf:"varint,2,opt,name=timeout" json:"timeout,omitempty"`
DestinationOverride *DestinationOverride `protobuf:"bytes,3,opt,name=destination_override,json=destinationOverride" json:"destination_override,omitempty"`
} }
func (m *Config) Reset() { *m = Config{} } func (m *Config) Reset() { *m = Config{} }
func (m *Config) String() string { return proto.CompactTextString(m) } func (m *Config) String() string { return proto.CompactTextString(m) }
func (*Config) ProtoMessage() {} func (*Config) ProtoMessage() {}
func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *Config) GetDomainStrategy() Config_DomainStrategy { func (m *Config) GetDomainStrategy() Config_DomainStrategy {
if m != nil { if m != nil {
@ -60,7 +78,15 @@ func (m *Config) GetTimeout() uint32 {
return 0 return 0
} }
func (m *Config) GetDestinationOverride() *DestinationOverride {
if m != nil {
return m.DestinationOverride
}
return nil
}
func init() { func init() {
proto.RegisterType((*DestinationOverride)(nil), "v2ray.core.proxy.freedom.DestinationOverride")
proto.RegisterType((*Config)(nil), "v2ray.core.proxy.freedom.Config") proto.RegisterType((*Config)(nil), "v2ray.core.proxy.freedom.Config")
proto.RegisterEnum("v2ray.core.proxy.freedom.Config_DomainStrategy", Config_DomainStrategy_name, Config_DomainStrategy_value) proto.RegisterEnum("v2ray.core.proxy.freedom.Config_DomainStrategy", Config_DomainStrategy_name, Config_DomainStrategy_value)
} }
@ -68,19 +94,26 @@ func init() {
func init() { proto.RegisterFile("v2ray.com/core/proxy/freedom/config.proto", fileDescriptor0) } func init() { proto.RegisterFile("v2ray.com/core/proxy/freedom/config.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 217 bytes of a gzipped FileDescriptorProto // 324 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xd2, 0x2c, 0x33, 0x2a, 0x4a, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x74, 0x90, 0xcf, 0x4a, 0xf3, 0x40,
0xac, 0xd4, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x2f, 0x28, 0xca, 0xaf, 0xa8, 0x14, 0xc5, 0xbf, 0xf4, 0xc3, 0x14, 0x6f, 0xb1, 0x96, 0xa9, 0x8b, 0x20, 0x2e, 0x4a, 0x37, 0x56,
0xd4, 0x4f, 0x2b, 0x4a, 0x4d, 0x4d, 0x01, 0x0b, 0xe5, 0xa5, 0x65, 0xa6, 0xeb, 0x15, 0x14, 0xe5, 0xc1, 0x89, 0xc4, 0x27, 0xb0, 0x7f, 0x84, 0xae, 0x5a, 0x12, 0x14, 0x75, 0x13, 0x63, 0xe6, 0xb6,
0x97, 0xe4, 0x0b, 0x49, 0xc0, 0x94, 0x16, 0xa5, 0xea, 0x81, 0x95, 0xe9, 0x41, 0x95, 0x29, 0x2d, 0x0c, 0x98, 0xb9, 0x61, 0x32, 0x16, 0xf3, 0x04, 0xbe, 0x8b, 0x4f, 0x29, 0x9d, 0xa4, 0x68, 0xd5,
0x61, 0xe4, 0x62, 0x73, 0x06, 0x2b, 0x15, 0x0a, 0xe7, 0xe2, 0x4b, 0xc9, 0xcf, 0x4d, 0xcc, 0xcc, 0x2e, 0xe7, 0xce, 0xf9, 0x9d, 0x7b, 0xcf, 0x81, 0xb3, 0x55, 0xa0, 0x93, 0x92, 0xa7, 0x94, 0xf9,
0x0b, 0x2e, 0x29, 0x4a, 0x2c, 0x49, 0x4d, 0xaf, 0x94, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x33, 0xd2, 0x29, 0x69, 0xf4, 0x73, 0x4d, 0x6f, 0xa5, 0xbf, 0xd0, 0x88, 0xc2, 0x8e, 0xd4, 0x42, 0x2e, 0x79,
0xd7, 0xc3, 0xa5, 0x5b, 0x0f, 0xa2, 0x53, 0xcf, 0x05, 0x45, 0x5b, 0x10, 0x9a, 0x31, 0x42, 0x12, 0xae, 0xc9, 0x10, 0xf3, 0x36, 0x52, 0x8d, 0xdc, 0xca, 0x78, 0x2d, 0x3b, 0xbe, 0xfc, 0x61, 0x92,
0x5c, 0xec, 0x25, 0x99, 0xb9, 0xa9, 0xf9, 0xa5, 0x25, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0xbc, 0x41, 0x52, 0x96, 0x91, 0xf2, 0x2d, 0x96, 0xd2, 0x8b, 0x5f, 0xa0, 0x5e, 0xa1, 0x8e, 0x8b, 0x1c, 0xd3,
0x30, 0xae, 0x92, 0x3a, 0x17, 0x1f, 0xaa, 0x5e, 0x21, 0x4e, 0x2e, 0x56, 0xc7, 0xe0, 0x78, 0xcf, 0xca, 0xab, 0xff, 0x00, 0xdd, 0x31, 0x16, 0x46, 0xaa, 0xc4, 0x48, 0x52, 0xb3, 0x15, 0x6a, 0x2d,
0x60, 0x01, 0x06, 0x21, 0x2e, 0x2e, 0xb6, 0xd0, 0x60, 0xd7, 0x78, 0xcf, 0x00, 0x01, 0x46, 0x27, 0x05, 0xb2, 0x21, 0xb8, 0x95, 0xd6, 0x73, 0x7a, 0xce, 0xa0, 0x15, 0x9c, 0xf3, 0x6f, 0x3b, 0x2b,
0x7f, 0x2e, 0x99, 0xe4, 0xfc, 0x5c, 0x9c, 0x0e, 0x71, 0xe2, 0x86, 0xb8, 0x24, 0x00, 0xe4, 0xdb, 0x57, 0xbe, 0x71, 0xe5, 0x91, 0x55, 0x4e, 0x94, 0xc8, 0x49, 0x2a, 0x13, 0xd6, 0x64, 0xff, 0xbd,
0x28, 0x76, 0xa8, 0xe8, 0x2a, 0x26, 0x89, 0x30, 0xa3, 0xa0, 0xc4, 0x4a, 0x3d, 0x67, 0x90, 0x86, 0x01, 0xee, 0xc8, 0xde, 0xcd, 0xee, 0xe1, 0x50, 0x50, 0x96, 0x48, 0x15, 0x17, 0x46, 0x27, 0x06,
0x00, 0xb0, 0x06, 0x37, 0x88, 0x54, 0x12, 0x1b, 0x38, 0x60, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0x97, 0xa5, 0xf5, 0x6d, 0x07, 0x3e, 0xdf, 0x95, 0x85, 0x57, 0x28, 0x1f, 0x5b, 0x2e, 0xaa, 0xb1,
0xff, 0xae, 0x54, 0x8c, 0x36, 0x45, 0x01, 0x00, 0x00, 0xb0, 0x2d, 0xb6, 0xde, 0xcc, 0x83, 0xa6, 0x91, 0x19, 0xd2, 0xab, 0xf1, 0x1a, 0x3d, 0x67, 0x70,
0x10, 0x6e, 0x9e, 0xec, 0x09, 0x8e, 0xc4, 0x57, 0xb2, 0x98, 0xea, 0x68, 0xde, 0x7f, 0x1b, 0xe8,
0x62, 0xf7, 0xe2, 0x3f, 0xfa, 0x08, 0xbb, 0xe2, 0xf7, 0xb0, 0x7f, 0x0a, 0xed, 0xed, 0xeb, 0xd8,
0x3e, 0xec, 0x5d, 0x47, 0xf1, 0x34, 0xea, 0xfc, 0x63, 0x00, 0xee, 0x6d, 0x34, 0x89, 0xa7, 0xf3,
0x8e, 0x33, 0x9c, 0xc1, 0x49, 0x4a, 0xd9, 0xce, 0x8d, 0xc3, 0x56, 0x95, 0x75, 0xbe, 0x2e, 0xf4,
0xb1, 0x59, 0x4f, 0x3f, 0x1a, 0xde, 0x5d, 0x10, 0x26, 0x25, 0x1f, 0xad, 0x81, 0xb9, 0x05, 0x6e,
0xaa, 0xaf, 0x67, 0xd7, 0x76, 0x7f, 0xf5, 0x19, 0x00, 0x00, 0xff, 0xff, 0xa0, 0x1e, 0xb5, 0x64,
0x35, 0x02, 0x00, 0x00,
} }

View File

@ -6,11 +6,18 @@ option go_package = "freedom";
option java_package = "com.v2ray.core.proxy.freedom"; option java_package = "com.v2ray.core.proxy.freedom";
option java_outer_classname = "ConfigProto"; option java_outer_classname = "ConfigProto";
import "v2ray.com/core/common/protocol/server_spec.proto";
message DestinationOverride {
v2ray.core.common.protocol.ServerEndpoint server = 1;
}
message Config { message Config {
enum DomainStrategy { enum DomainStrategy {
AS_IS = 0; AS_IS = 0;
USE_IP = 1; USE_IP = 1;
} }
DomainStrategy domainStrategy = 1; DomainStrategy domain_strategy = 1;
uint32 timeout = 2; uint32 timeout = 2;
} DestinationOverride destination_override = 3;
}

View File

@ -23,6 +23,7 @@ type Handler struct {
domainStrategy Config_DomainStrategy domainStrategy Config_DomainStrategy
timeout uint32 timeout uint32
dns dns.Server dns dns.Server
destOverride *DestinationOverride
} }
func New(ctx context.Context, config *Config) (*Handler, error) { func New(ctx context.Context, config *Config) (*Handler, error) {
@ -33,6 +34,7 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
f := &Handler{ f := &Handler{
domainStrategy: config.DomainStrategy, domainStrategy: config.DomainStrategy,
timeout: config.Timeout, timeout: config.Timeout,
destOverride: config.DestinationOverride,
} }
space.OnInitialize(func() error { space.OnInitialize(func() error {
if config.DomainStrategy == Config_USE_IP { if config.DomainStrategy == Config_USE_IP {
@ -71,6 +73,14 @@ func (v *Handler) ResolveIP(destination net.Destination) net.Destination {
func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay) error { func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay) error {
destination := proxy.DestinationFromContext(ctx) destination := proxy.DestinationFromContext(ctx)
if v.destOverride != nil {
server := v.destOverride.Server
destination = net.Destination{
Network: destination.Network,
Address: server.Address.AsAddress(),
Port: net.Port(server.Port),
}
}
log.Info("Freedom: Opening connection to ", destination) log.Info("Freedom: Opening connection to ", destination)
input := outboundRay.OutboundInput() input := outboundRay.OutboundInput()

View File

@ -4,6 +4,7 @@ import (
"net" "net"
"testing" "testing"
xproxy "golang.org/x/net/proxy"
"v2ray.com/core" "v2ray.com/core"
"v2ray.com/core/app/proxyman" "v2ray.com/core/app/proxyman"
"v2ray.com/core/app/router" "v2ray.com/core/app/router"
@ -14,6 +15,7 @@ import (
"v2ray.com/core/proxy/blackhole" "v2ray.com/core/proxy/blackhole"
"v2ray.com/core/proxy/dokodemo" "v2ray.com/core/proxy/dokodemo"
"v2ray.com/core/proxy/freedom" "v2ray.com/core/proxy/freedom"
"v2ray.com/core/proxy/socks"
"v2ray.com/core/proxy/vmess" "v2ray.com/core/proxy/vmess"
"v2ray.com/core/proxy/vmess/inbound" "v2ray.com/core/proxy/vmess/inbound"
"v2ray.com/core/proxy/vmess/outbound" "v2ray.com/core/proxy/vmess/outbound"
@ -498,3 +500,68 @@ func TestBlackhole(t *testing.T) {
CloseAllServers() CloseAllServers()
} }
func TestForward(t *testing.T) {
assert := assert.On(t)
tcpServer := tcp.Server{
MsgProcessor: xor,
}
dest, err := tcpServer.Start()
assert.Error(err).IsNil()
defer tcpServer.Close()
serverPort := pickPort()
serverConfig := &core.Config{
Inbound: []*proxyman.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: v2net.SinglePortRange(serverPort),
Listen: v2net.NewIPOrDomain(v2net.LocalHostIP),
}),
ProxySettings: serial.ToTypedMessage(&socks.ServerConfig{
AuthType: socks.AuthType_NO_AUTH,
Accounts: map[string]string{
"Test Account": "Test Password",
},
Address: v2net.NewIPOrDomain(v2net.LocalHostIP),
UdpEnabled: false,
}),
},
},
Outbound: []*proxyman.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{
DestinationOverride: &freedom.DestinationOverride{
Server: &protocol.ServerEndpoint{
Address: v2net.NewIPOrDomain(v2net.LocalHostIP),
Port: uint32(dest.Port),
},
},
}),
},
},
}
assert.Error(InitializeServerConfig(serverConfig)).IsNil()
{
noAuthDialer, err := xproxy.SOCKS5("tcp", v2net.TCPDestination(v2net.LocalHostIP, serverPort).NetAddr(), nil, xproxy.Direct)
assert.Error(err).IsNil()
conn, err := noAuthDialer.Dial("tcp", "google.com:80")
assert.Error(err).IsNil()
payload := "test payload"
nBytes, err := conn.Write([]byte(payload))
assert.Error(err).IsNil()
assert.Int(nBytes).Equals(len(payload))
response := make([]byte, 1024)
nBytes, err = conn.Read(response)
assert.Error(err).IsNil()
assert.Bytes(response[:nBytes]).Equals(xor([]byte(payload)))
assert.Error(conn.Close()).IsNil()
}
CloseAllServers()
}

View File

@ -1,8 +1,12 @@
package conf package conf
import ( import (
"net"
"strings" "strings"
"v2ray.com/core/common/errors"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/common/protocol"
"v2ray.com/core/common/serial" "v2ray.com/core/common/serial"
"v2ray.com/core/proxy/freedom" "v2ray.com/core/proxy/freedom"
) )
@ -10,6 +14,7 @@ import (
type FreedomConfig struct { type FreedomConfig struct {
DomainStrategy string `json:"domainStrategy"` DomainStrategy string `json:"domainStrategy"`
Timeout uint32 `json:"timeout"` Timeout uint32 `json:"timeout"`
Redirect string `json:"redirect"`
} }
func (v *FreedomConfig) Build() (*serial.TypedMessage, error) { func (v *FreedomConfig) Build() (*serial.TypedMessage, error) {
@ -20,5 +25,21 @@ func (v *FreedomConfig) Build() (*serial.TypedMessage, error) {
config.DomainStrategy = freedom.Config_USE_IP config.DomainStrategy = freedom.Config_USE_IP
} }
config.Timeout = v.Timeout config.Timeout = v.Timeout
if len(v.Redirect) > 0 {
host, portStr, err := net.SplitHostPort(v.Redirect)
if err != nil {
return nil, errors.Base(err).Message("Config: Invalid redirect address: ", v.Redirect, ": ", err)
}
port, err := v2net.PortFromString(portStr)
if err != nil {
return nil, errors.Base(err).Message("Config: Invalid redirect port: ", v.Redirect, ": ", err)
}
config.DestinationOverride = &freedom.DestinationOverride{
Server: &protocol.ServerEndpoint{
Address: v2net.NewIPOrDomain(v2net.ParseAddress(host)),
Port: uint32(port),
},
}
}
return serial.ToTypedMessage(config), nil return serial.ToTypedMessage(config), nil
} }