From aaa55fc9d2dd91e70bb8595d724ea31e1cabe8ff Mon Sep 17 00:00:00 2001 From: Shelikhoo Date: Sun, 28 Feb 2021 17:50:45 +0000 Subject: [PATCH 1/9] Add definition for transport layer chained proxy --- transport/internet/config.proto | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/transport/internet/config.proto b/transport/internet/config.proto index d23b5a6bd..139ef83cc 100644 --- a/transport/internet/config.proto +++ b/transport/internet/config.proto @@ -47,7 +47,11 @@ message StreamConfig { SocketConfig socket_settings = 6; } -message ProxyConfig { string tag = 1; } +message ProxyConfig { + string tag = 1; + + bool transportLayerProxy = 2; +} // SocketConfig is options to be applied on network sockets. message SocketConfig { From 8980cf2fccf507878c9cbb70bf6fe8b0f50ba4fc Mon Sep 17 00:00:00 2001 From: Shelikhoo Date: Sun, 28 Feb 2021 17:52:16 +0000 Subject: [PATCH 2/9] Regenerate protobuf for transport layer chain proxy --- transport/internet/config.pb.go | 107 ++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 48 deletions(-) diff --git a/transport/internet/config.pb.go b/transport/internet/config.pb.go index 33f044c1d..9cc31fbd0 100644 --- a/transport/internet/config.pb.go +++ b/transport/internet/config.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.25.0 -// protoc v3.14.0 +// protoc v3.13.0 // source: transport/internet/config.proto package internet @@ -357,7 +357,8 @@ type ProxyConfig struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` + Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` + TransportLayerProxy bool `protobuf:"varint,2,opt,name=transportLayerProxy,proto3" json:"transportLayerProxy,omitempty"` } func (x *ProxyConfig) Reset() { @@ -399,6 +400,13 @@ func (x *ProxyConfig) GetTag() string { return "" } +func (x *ProxyConfig) GetTransportLayerProxy() bool { + if x != nil { + return x.TransportLayerProxy + } + return false +} + // SocketConfig is options to be applied on network sockets. type SocketConfig struct { state protoimpl.MessageState @@ -549,53 +557,56 @@ var file_transport_internet_config_proto_rawDesc = []byte{ 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x73, 0x6f, 0x63, 0x6b, 0x65, - 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x1f, 0x0a, 0x0b, 0x50, 0x72, 0x6f, + 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x51, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x22, 0xe1, 0x03, 0x0a, 0x0c, 0x53, - 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6d, - 0x61, 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x12, - 0x4e, 0x0a, 0x03, 0x74, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3c, 0x2e, 0x76, - 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x53, 0x6f, 0x63, - 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x43, 0x50, 0x46, 0x61, 0x73, - 0x74, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x03, 0x74, 0x66, 0x6f, 0x12, - 0x4e, 0x0a, 0x06, 0x74, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x36, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, - 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x50, 0x72, - 0x6f, 0x78, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x06, 0x74, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x12, - 0x41, 0x0a, 0x1d, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x6f, 0x72, 0x69, 0x67, 0x69, - 0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x4f, - 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x44, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x69, 0x6e, 0x64, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x70, 0x6f, - 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x50, 0x6f, - 0x72, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x5f, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x13, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x35, 0x0a, 0x10, 0x54, 0x43, 0x50, 0x46, 0x61, 0x73, - 0x74, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x73, - 0x49, 0x73, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x10, 0x01, - 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x10, 0x02, 0x22, 0x2f, 0x0a, - 0x0a, 0x54, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x4f, - 0x66, 0x66, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x54, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x10, 0x01, - 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x10, 0x02, 0x2a, 0x5a, - 0x0a, 0x11, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6c, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x43, 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, - 0x55, 0x44, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x4b, 0x43, 0x50, 0x10, 0x02, 0x12, - 0x0d, 0x0a, 0x09, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x10, 0x03, 0x12, 0x08, - 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x10, 0x04, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x6f, 0x6d, 0x61, - 0x69, 0x6e, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x10, 0x05, 0x42, 0x78, 0x0a, 0x21, 0x63, 0x6f, - 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x50, - 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, - 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, - 0x34, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0xaa, 0x02, 0x1d, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, - 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x30, 0x0a, 0x13, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x78, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, + 0x72, 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x22, 0xe1, 0x03, 0x0a, + 0x0c, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, + 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x6d, 0x61, 0x72, + 0x6b, 0x12, 0x4e, 0x0a, 0x03, 0x74, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3c, + 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x53, + 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x43, 0x50, 0x46, + 0x61, 0x73, 0x74, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x03, 0x74, 0x66, + 0x6f, 0x12, 0x4e, 0x0a, 0x06, 0x74, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x36, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x2e, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, + 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x06, 0x74, 0x70, 0x72, 0x6f, 0x78, + 0x79, 0x12, 0x41, 0x0a, 0x1d, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x6f, 0x72, 0x69, + 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, + 0x65, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x44, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x69, 0x6e, 0x64, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x69, 0x6e, 0x64, 0x5f, + 0x70, 0x6f, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x62, 0x69, 0x6e, 0x64, + 0x50, 0x6f, 0x72, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x5f, 0x70, + 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x13, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x35, 0x0a, 0x10, 0x54, 0x43, 0x50, 0x46, + 0x61, 0x73, 0x74, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x08, 0x0a, 0x04, + 0x41, 0x73, 0x49, 0x73, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x10, 0x02, 0x22, + 0x2f, 0x0a, 0x0a, 0x54, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x07, 0x0a, + 0x03, 0x4f, 0x66, 0x66, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x54, 0x50, 0x72, 0x6f, 0x78, 0x79, + 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x10, 0x02, + 0x2a, 0x5a, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x43, 0x50, 0x10, 0x00, 0x12, 0x07, + 0x0a, 0x03, 0x55, 0x44, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x4b, 0x43, 0x50, 0x10, + 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x10, 0x03, + 0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x10, 0x04, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x10, 0x05, 0x42, 0x78, 0x0a, 0x21, + 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, + 0x2f, 0x76, 0x34, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0xaa, 0x02, 0x1d, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, + 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( From dd51d32250f822030cd96c22c473abe0771efb21 Mon Sep 17 00:00:00 2001 From: Shelikhoo Date: Sun, 28 Feb 2021 18:47:31 +0000 Subject: [PATCH 3/9] Added Transport Layer Chained Proxy Support --- app/dispatcher/default.go | 13 ++++++++++++ app/proxyman/outbound/handler.go | 8 +++++++- common/session/context.go | 16 +++++++++++++++ infra/conf/transport_internet.go | 6 ++++-- transport/internet/dialer.go | 34 ++++++++++++++++++++++++++++++++ 5 files changed, 74 insertions(+), 3 deletions(-) diff --git a/app/dispatcher/default.go b/app/dispatcher/default.go index e6e21f0ba..a1f58db18 100644 --- a/app/dispatcher/default.go +++ b/app/dispatcher/default.go @@ -294,6 +294,19 @@ func sniffer(ctx context.Context, cReader *cachedReader, metadataOnly bool) (Sni func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.Link, destination net.Destination) { var handler outbound.Handler + if forcedOutboundTag := session.GetForcedOutboundTagFromContext(ctx); forcedOutboundTag != "" { + session.SetForcedOutboundTagToContext(ctx, "") + if h := d.ohm.GetHandler(forcedOutboundTag); h != nil { + newError("taking platform initialized detour [", forcedOutboundTag, "] for [", destination, "]").WriteToLog(session.ExportIDToError(ctx)) + handler = h + } else { + newError("non existing tag for platform initialized detour: ", forcedOutboundTag).AtError().WriteToLog(session.ExportIDToError(ctx)) + common.Close(link.Writer) + common.Interrupt(link.Reader) + return + } + } + if d.router != nil { if route, err := d.router.PickRoute(routing_session.AsRoutingContext(ctx)); err == nil { tag := route.GetOutboundTag() diff --git a/app/proxyman/outbound/handler.go b/app/proxyman/outbound/handler.go index 5e5ba1216..66477c2d4 100644 --- a/app/proxyman/outbound/handler.go +++ b/app/proxyman/outbound/handler.go @@ -159,7 +159,7 @@ func (h *Handler) Address() net.Address { // Dial implements internet.Dialer. func (h *Handler) Dial(ctx context.Context, dest net.Destination) (internet.Connection, error) { if h.senderSettings != nil { - if h.senderSettings.ProxySettings.HasTag() { + if h.senderSettings.ProxySettings.HasTag() && !h.senderSettings.ProxySettings.TransportLayerProxy { tag := h.senderSettings.ProxySettings.Tag handler := h.outboundManager.GetHandler(tag) if handler != nil { @@ -196,6 +196,12 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (internet.Conn } } + if h.senderSettings.ProxySettings.HasTag() && h.senderSettings.ProxySettings.TransportLayerProxy { + tag := h.senderSettings.ProxySettings.Tag + newError("transport layer proxying to ", tag, " for dest ", dest).AtDebug().WriteToLog(session.ExportIDToError(ctx)) + session.SetTransportLayerProxyTagToContext(ctx, tag) + } + conn, err := internet.Dial(ctx, dest, h.streamSettings) return h.getStatCouterConnection(conn), err } diff --git a/common/session/context.go b/common/session/context.go index 7f1d7df9b..116c52a90 100644 --- a/common/session/context.go +++ b/common/session/context.go @@ -84,3 +84,19 @@ func SockoptFromContext(ctx context.Context) *Sockopt { } return nil } + +func GetTransportLayerProxyTagFromContext(ctx context.Context) string { + return ContentFromContext(ctx).Attribute("transportLayerOutgoingTag") +} + +func SetTransportLayerProxyTagToContext(ctx context.Context, tag string) { + ContentFromContext(ctx).SetAttribute("transportLayerOutgoingTag", tag) +} + +func GetForcedOutboundTagFromContext(ctx context.Context) string { + return ContentFromContext(ctx).Attribute("forcedOutboundTag") +} + +func SetForcedOutboundTagToContext(ctx context.Context, tag string) { + ContentFromContext(ctx).SetAttribute("forcedOutboundTag", tag) +} diff --git a/infra/conf/transport_internet.go b/infra/conf/transport_internet.go index 9a1a04d06..301f324de 100644 --- a/infra/conf/transport_internet.go +++ b/infra/conf/transport_internet.go @@ -485,7 +485,8 @@ func (c *StreamConfig) Build() (*internet.StreamConfig, error) { } type ProxyConfig struct { - Tag string `json:"tag"` + Tag string `json:"tag"` + TransportLayerProxy bool `json:"transportLayer"` } // Build implements Buildable. @@ -494,6 +495,7 @@ func (v *ProxyConfig) Build() (*internet.ProxyConfig, error) { return nil, newError("Proxy tag is not set.") } return &internet.ProxyConfig{ - Tag: v.Tag, + Tag: v.Tag, + TransportLayerProxy: v.TransportLayerProxy, }, nil } diff --git a/transport/internet/dialer.go b/transport/internet/dialer.go index 78a45fdf8..8a93bf3ad 100644 --- a/transport/internet/dialer.go +++ b/transport/internet/dialer.go @@ -2,6 +2,8 @@ package internet import ( "context" + core "github.com/v2fly/v2ray-core/v4" + "github.com/v2fly/v2ray-core/v4/features/routing" "github.com/v2fly/v2ray-core/v4/common/net" "github.com/v2fly/v2ray-core/v4/common/session" @@ -68,5 +70,37 @@ func DialSystem(ctx context.Context, dest net.Destination, sockopt *SocketConfig if outbound := session.OutboundFromContext(ctx); outbound != nil { src = outbound.Gateway } + + if transportLayerOutgoingTag := session.GetTransportLayerProxyTagFromContext(ctx); transportLayerOutgoingTag != "" { + return DialTaggedOutbound(ctx, dest, transportLayerOutgoingTag) + } + return effectiveSystemDialer.Dial(ctx, src, dest, sockopt) } + +func DialTaggedOutbound(ctx context.Context, dest net.Destination, tag string) (net.Conn, error) { + var dispatcher routing.Dispatcher + if err := core.RequireFeatures(ctx, func(dispatcherInstance routing.Dispatcher) { + dispatcher = dispatcherInstance + }); err != nil { + return nil, newError("Required Feature dispatcher not resolved").Base(err) + } + + content := new(session.Content) + content.SkipDNSResolve = true + session.SetForcedOutboundTagToContext(ctx, tag) + + ctx = session.ContextWithContent(ctx, content) + + r, err := dispatcher.Dispatch(ctx, dest) + if err != nil { + return nil, err + } + var readerOpt net.ConnectionOption + if dest.Network == net.Network_TCP { + readerOpt = net.ConnectionOutputMulti(r.Reader) + } else { + readerOpt = net.ConnectionOutputMultiUDP(r.Reader) + } + return net.NewConnection(net.ConnectionInputMulti(r.Writer), readerOpt), nil +} From 5f3851df39a4aed9e3150ca8bfb42e5dec9508d7 Mon Sep 17 00:00:00 2001 From: Shelikhoo Date: Sun, 28 Feb 2021 19:10:38 +0000 Subject: [PATCH 4/9] Fix dependency cycle caused by core import in internet package --- main/distro/all/all.go | 2 + transport/internet/dialer.go | 29 ++----------- transport/internet/tagged/tagged.go | 10 +++++ transport/internet/tagged/taggedimpl/impl.go | 41 +++++++++++++++++++ .../internet/tagged/taggedimpl/taggedimpl.go | 3 ++ 5 files changed, 60 insertions(+), 25 deletions(-) create mode 100644 transport/internet/tagged/tagged.go create mode 100644 transport/internet/tagged/taggedimpl/impl.go create mode 100644 transport/internet/tagged/taggedimpl/taggedimpl.go diff --git a/main/distro/all/all.go b/main/distro/all/all.go index 9c6e1b0fb..5351a54cb 100644 --- a/main/distro/all/all.go +++ b/main/distro/all/all.go @@ -23,6 +23,8 @@ import ( _ "github.com/v2fly/v2ray-core/v4/app/router" _ "github.com/v2fly/v2ray-core/v4/app/stats" + _ "github.com/v2fly/v2ray-core/v4/transport/internet/tagged/taggedimpl" + // Inbound and outbound proxies. _ "github.com/v2fly/v2ray-core/v4/proxy/blackhole" _ "github.com/v2fly/v2ray-core/v4/proxy/dns" diff --git a/transport/internet/dialer.go b/transport/internet/dialer.go index 8a93bf3ad..66af2f0e5 100644 --- a/transport/internet/dialer.go +++ b/transport/internet/dialer.go @@ -2,8 +2,7 @@ package internet import ( "context" - core "github.com/v2fly/v2ray-core/v4" - "github.com/v2fly/v2ray-core/v4/features/routing" + "github.com/v2fly/v2ray-core/v4/transport/internet/tagged" "github.com/v2fly/v2ray-core/v4/common/net" "github.com/v2fly/v2ray-core/v4/common/session" @@ -79,28 +78,8 @@ func DialSystem(ctx context.Context, dest net.Destination, sockopt *SocketConfig } func DialTaggedOutbound(ctx context.Context, dest net.Destination, tag string) (net.Conn, error) { - var dispatcher routing.Dispatcher - if err := core.RequireFeatures(ctx, func(dispatcherInstance routing.Dispatcher) { - dispatcher = dispatcherInstance - }); err != nil { - return nil, newError("Required Feature dispatcher not resolved").Base(err) + if tagged.Dialer == nil { + return nil, newError("tagged dial not enabled") } - - content := new(session.Content) - content.SkipDNSResolve = true - session.SetForcedOutboundTagToContext(ctx, tag) - - ctx = session.ContextWithContent(ctx, content) - - r, err := dispatcher.Dispatch(ctx, dest) - if err != nil { - return nil, err - } - var readerOpt net.ConnectionOption - if dest.Network == net.Network_TCP { - readerOpt = net.ConnectionOutputMulti(r.Reader) - } else { - readerOpt = net.ConnectionOutputMultiUDP(r.Reader) - } - return net.NewConnection(net.ConnectionInputMulti(r.Writer), readerOpt), nil + return tagged.Dialer(ctx, dest, tag) } diff --git a/transport/internet/tagged/tagged.go b/transport/internet/tagged/tagged.go new file mode 100644 index 000000000..a99a7b88d --- /dev/null +++ b/transport/internet/tagged/tagged.go @@ -0,0 +1,10 @@ +package tagged + +import ( + "context" + "github.com/v2fly/v2ray-core/v4/common/net" +) + +type DialFunc func(ctx context.Context, dest net.Destination, tag string) (net.Conn, error) + +var Dialer DialFunc diff --git a/transport/internet/tagged/taggedimpl/impl.go b/transport/internet/tagged/taggedimpl/impl.go new file mode 100644 index 000000000..21a00a4fb --- /dev/null +++ b/transport/internet/tagged/taggedimpl/impl.go @@ -0,0 +1,41 @@ +package taggedimpl + +import ( + "context" + core "github.com/v2fly/v2ray-core/v4" + "github.com/v2fly/v2ray-core/v4/common/net" + "github.com/v2fly/v2ray-core/v4/common/session" + "github.com/v2fly/v2ray-core/v4/features/routing" + "github.com/v2fly/v2ray-core/v4/transport/internet/tagged" +) + +func DialTaggedOutbound(ctx context.Context, dest net.Destination, tag string) (net.Conn, error) { + var dispatcher routing.Dispatcher + if err := core.RequireFeatures(ctx, func(dispatcherInstance routing.Dispatcher) { + dispatcher = dispatcherInstance + }); err != nil { + return nil, newError("Required Feature dispatcher not resolved").Base(err) + } + + content := new(session.Content) + content.SkipDNSResolve = true + session.SetForcedOutboundTagToContext(ctx, tag) + + ctx = session.ContextWithContent(ctx, content) + + r, err := dispatcher.Dispatch(ctx, dest) + if err != nil { + return nil, err + } + var readerOpt net.ConnectionOption + if dest.Network == net.Network_TCP { + readerOpt = net.ConnectionOutputMulti(r.Reader) + } else { + readerOpt = net.ConnectionOutputMultiUDP(r.Reader) + } + return net.NewConnection(net.ConnectionInputMulti(r.Writer), readerOpt), nil +} + +func init() { + tagged.Dialer = DialTaggedOutbound +} diff --git a/transport/internet/tagged/taggedimpl/taggedimpl.go b/transport/internet/tagged/taggedimpl/taggedimpl.go new file mode 100644 index 000000000..1597c7b75 --- /dev/null +++ b/transport/internet/tagged/taggedimpl/taggedimpl.go @@ -0,0 +1,3 @@ +package taggedimpl + +//go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen From 6925870600c11b42d7f9f6a2d71a814da5130aab Mon Sep 17 00:00:00 2001 From: Shelikhoo Date: Sun, 28 Feb 2021 19:57:21 +0000 Subject: [PATCH 5/9] Fix forced outbound tag not set correctly --- transport/internet/tagged/taggedimpl/impl.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transport/internet/tagged/taggedimpl/impl.go b/transport/internet/tagged/taggedimpl/impl.go index 21a00a4fb..d1e1a56bd 100644 --- a/transport/internet/tagged/taggedimpl/impl.go +++ b/transport/internet/tagged/taggedimpl/impl.go @@ -19,9 +19,9 @@ func DialTaggedOutbound(ctx context.Context, dest net.Destination, tag string) ( content := new(session.Content) content.SkipDNSResolve = true - session.SetForcedOutboundTagToContext(ctx, tag) ctx = session.ContextWithContent(ctx, content) + session.SetForcedOutboundTagToContext(ctx, tag) r, err := dispatcher.Dispatch(ctx, dest) if err != nil { From 9722488fd60bc32ff9325513801658a111b65d4d Mon Sep 17 00:00:00 2001 From: Shelikhoo Date: Sun, 28 Feb 2021 19:57:57 +0000 Subject: [PATCH 6/9] Disable routing for platform initialized detour --- app/dispatcher/default.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/app/dispatcher/default.go b/app/dispatcher/default.go index a1f58db18..40beed96d 100644 --- a/app/dispatcher/default.go +++ b/app/dispatcher/default.go @@ -305,19 +305,19 @@ func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport. common.Interrupt(link.Reader) return } - } - - if d.router != nil { - if route, err := d.router.PickRoute(routing_session.AsRoutingContext(ctx)); err == nil { - tag := route.GetOutboundTag() - if h := d.ohm.GetHandler(tag); h != nil { - newError("taking detour [", tag, "] for [", destination, "]").WriteToLog(session.ExportIDToError(ctx)) - handler = h + } else { + if d.router != nil { + if route, err := d.router.PickRoute(routing_session.AsRoutingContext(ctx)); err == nil { + tag := route.GetOutboundTag() + if h := d.ohm.GetHandler(tag); h != nil { + newError("taking detour [", tag, "] for [", destination, "]").WriteToLog(session.ExportIDToError(ctx)) + handler = h + } else { + newError("non existing tag: ", tag).AtWarning().WriteToLog(session.ExportIDToError(ctx)) + } } else { - newError("non existing tag: ", tag).AtWarning().WriteToLog(session.ExportIDToError(ctx)) + newError("default route for ", destination).WriteToLog(session.ExportIDToError(ctx)) } - } else { - newError("default route for ", destination).WriteToLog(session.ExportIDToError(ctx)) } } From bf6e8f23891bef77b5455e2bf2965c560bd8c8e9 Mon Sep 17 00:00:00 2001 From: Shelikhoo Date: Sun, 28 Feb 2021 19:58:22 +0000 Subject: [PATCH 7/9] Added Auto generated file --- transport/internet/tagged/taggedimpl/errors.generated.go | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 transport/internet/tagged/taggedimpl/errors.generated.go diff --git a/transport/internet/tagged/taggedimpl/errors.generated.go b/transport/internet/tagged/taggedimpl/errors.generated.go new file mode 100644 index 000000000..88339a09c --- /dev/null +++ b/transport/internet/tagged/taggedimpl/errors.generated.go @@ -0,0 +1,9 @@ +package taggedimpl + +import "github.com/v2fly/v2ray-core/v4/common/errors" + +type errPathObjHolder struct{} + +func newError(values ...interface{}) *errors.Error { + return errors.New(values...).WithPathObj(errPathObjHolder{}) +} From e532085d3ca21b6f9a67f6d29c9864beabae71c1 Mon Sep 17 00:00:00 2001 From: Shelikhoo Date: Sun, 28 Feb 2021 19:59:45 +0000 Subject: [PATCH 8/9] don't build tagged outbound dial on configure setting --- transport/internet/tagged/taggedimpl/impl.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/transport/internet/tagged/taggedimpl/impl.go b/transport/internet/tagged/taggedimpl/impl.go index d1e1a56bd..5688c58e7 100644 --- a/transport/internet/tagged/taggedimpl/impl.go +++ b/transport/internet/tagged/taggedimpl/impl.go @@ -1,3 +1,5 @@ +// +build !confonly + package taggedimpl import ( From 616b0d122efeab8704b7e964c36d9e939104b55f Mon Sep 17 00:00:00 2001 From: Shelikhoo Date: Sun, 28 Feb 2021 20:42:32 +0000 Subject: [PATCH 9/9] Fix for context with empty content --- app/proxyman/outbound/handler.go | 2 +- common/session/context.go | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/proxyman/outbound/handler.go b/app/proxyman/outbound/handler.go index 66477c2d4..46c564630 100644 --- a/app/proxyman/outbound/handler.go +++ b/app/proxyman/outbound/handler.go @@ -196,7 +196,7 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (internet.Conn } } - if h.senderSettings.ProxySettings.HasTag() && h.senderSettings.ProxySettings.TransportLayerProxy { + if h.senderSettings != nil && h.senderSettings.ProxySettings != nil && h.senderSettings.ProxySettings.HasTag() && h.senderSettings.ProxySettings.TransportLayerProxy { tag := h.senderSettings.ProxySettings.Tag newError("transport layer proxying to ", tag, " for dest ", dest).AtDebug().WriteToLog(session.ExportIDToError(ctx)) session.SetTransportLayerProxyTagToContext(ctx, tag) diff --git a/common/session/context.go b/common/session/context.go index 116c52a90..8fdb01fa6 100644 --- a/common/session/context.go +++ b/common/session/context.go @@ -86,6 +86,9 @@ func SockoptFromContext(ctx context.Context) *Sockopt { } func GetTransportLayerProxyTagFromContext(ctx context.Context) string { + if ContentFromContext(ctx) == nil { + return "" + } return ContentFromContext(ctx).Attribute("transportLayerOutgoingTag") } @@ -94,6 +97,9 @@ func SetTransportLayerProxyTagToContext(ctx context.Context, tag string) { } func GetForcedOutboundTagFromContext(ctx context.Context) string { + if ContentFromContext(ctx) == nil { + return "" + } return ContentFromContext(ctx).Attribute("forcedOutboundTag") }