diff --git a/infra/conf/mtproto.go b/infra/conf/mtproto.go deleted file mode 100644 index 88b02af5..00000000 --- a/infra/conf/mtproto.go +++ /dev/null @@ -1,67 +0,0 @@ -package conf - -import ( - "encoding/hex" - "encoding/json" - - "github.com/golang/protobuf/proto" - "github.com/xtls/xray-core/common/protocol" - "github.com/xtls/xray-core/common/serial" - "github.com/xtls/xray-core/proxy/mtproto" -) - -type MTProtoAccount struct { - Secret string `json:"secret"` -} - -// Build implements Buildable -func (a *MTProtoAccount) Build() (*mtproto.Account, error) { - if len(a.Secret) != 32 { - return nil, newError("MTProto secret must have 32 chars") - } - secret, err := hex.DecodeString(a.Secret) - if err != nil { - return nil, newError("failed to decode secret: ", a.Secret).Base(err) - } - return &mtproto.Account{ - Secret: secret, - }, nil -} - -type MTProtoServerConfig struct { - Users []json.RawMessage `json:"users"` -} - -func (c *MTProtoServerConfig) Build() (proto.Message, error) { - config := &mtproto.ServerConfig{} - - if len(c.Users) == 0 { - return nil, newError("zero MTProto users configured.") - } - config.User = make([]*protocol.User, len(c.Users)) - for idx, rawData := range c.Users { - user := new(protocol.User) - if err := json.Unmarshal(rawData, user); err != nil { - return nil, newError("invalid MTProto user").Base(err) - } - account := new(MTProtoAccount) - if err := json.Unmarshal(rawData, account); err != nil { - return nil, newError("invalid MTProto user").Base(err) - } - accountProto, err := account.Build() - if err != nil { - return nil, newError("failed to parse MTProto user").Base(err) - } - user.Account = serial.ToTypedMessage(accountProto) - config.User[idx] = user - } - - return config, nil -} - -type MTProtoClientConfig struct{} - -func (c *MTProtoClientConfig) Build() (proto.Message, error) { - config := new(mtproto.ClientConfig) - return config, nil -} diff --git a/infra/conf/mtproto_test.go b/infra/conf/mtproto_test.go deleted file mode 100644 index f44cb19a..00000000 --- a/infra/conf/mtproto_test.go +++ /dev/null @@ -1,40 +0,0 @@ -package conf_test - -import ( - "testing" - - "github.com/xtls/xray-core/common/protocol" - "github.com/xtls/xray-core/common/serial" - . "github.com/xtls/xray-core/infra/conf" - "github.com/xtls/xray-core/proxy/mtproto" -) - -func TestMTProtoServerConfig(t *testing.T) { - creator := func() Buildable { - return new(MTProtoServerConfig) - } - - runMultiTestCase(t, []TestCase{ - { - Input: `{ - "users": [{ - "email": "love@example.com", - "level": 1, - "secret": "b0cbcef5a486d9636472ac27f8e11a9d" - }] - }`, - Parser: loadJSON(creator), - Output: &mtproto.ServerConfig{ - User: []*protocol.User{ - { - Email: "love@example.com", - Level: 1, - Account: serial.ToTypedMessage(&mtproto.Account{ - Secret: []byte{176, 203, 206, 245, 164, 134, 217, 99, 100, 114, 172, 39, 248, 225, 26, 157}, - }), - }, - }, - }, - }, - }) -} diff --git a/infra/conf/xray.go b/infra/conf/xray.go index 8b6d05f4..7bfc53e3 100644 --- a/infra/conf/xray.go +++ b/infra/conf/xray.go @@ -24,7 +24,6 @@ var ( "vless": func() interface{} { return new(VLessInboundConfig) }, "vmess": func() interface{} { return new(VMessInboundConfig) }, "trojan": func() interface{} { return new(TrojanServerConfig) }, - "mtproto": func() interface{} { return new(MTProtoServerConfig) }, }, "protocol", "settings") outboundConfigLoader = NewJSONConfigLoader(ConfigCreatorCache{ @@ -37,7 +36,6 @@ var ( "vless": func() interface{} { return new(VLessOutboundConfig) }, "vmess": func() interface{} { return new(VMessOutboundConfig) }, "trojan": func() interface{} { return new(TrojanClientConfig) }, - "mtproto": func() interface{} { return new(MTProtoClientConfig) }, "dns": func() interface{} { return new(DNSOutboundConfig) }, "wireguard": func() interface{} { return new(WireGuardConfig) }, }, "protocol", "settings") diff --git a/main/distro/all/all.go b/main/distro/all/all.go index 0e38fcf6..d383e043 100644 --- a/main/distro/all/all.go +++ b/main/distro/all/all.go @@ -40,7 +40,6 @@ import ( _ "github.com/xtls/xray-core/proxy/freedom" _ "github.com/xtls/xray-core/proxy/http" _ "github.com/xtls/xray-core/proxy/loopback" - _ "github.com/xtls/xray-core/proxy/mtproto" _ "github.com/xtls/xray-core/proxy/shadowsocks" _ "github.com/xtls/xray-core/proxy/socks" _ "github.com/xtls/xray-core/proxy/trojan" diff --git a/proxy/mtproto/auth.go b/proxy/mtproto/auth.go deleted file mode 100644 index cdd66d6f..00000000 --- a/proxy/mtproto/auth.go +++ /dev/null @@ -1,148 +0,0 @@ -package mtproto - -import ( - "context" - "crypto/rand" - "crypto/sha256" - "io" - "sync" - - "github.com/xtls/xray-core/common" -) - -const ( - HeaderSize = 64 -) - -type SessionContext struct { - ConnectionType [4]byte - DataCenterID uint16 -} - -func DefaultSessionContext() SessionContext { - return SessionContext{ - ConnectionType: [4]byte{0xef, 0xef, 0xef, 0xef}, - DataCenterID: 0, - } -} - -type contextKey int32 - -const ( - sessionContextKey contextKey = iota -) - -func ContextWithSessionContext(ctx context.Context, c SessionContext) context.Context { - return context.WithValue(ctx, sessionContextKey, c) -} - -func SessionContextFromContext(ctx context.Context) SessionContext { - if c := ctx.Value(sessionContextKey); c != nil { - return c.(SessionContext) - } - return DefaultSessionContext() -} - -type Authentication struct { - Header [HeaderSize]byte - DecodingKey [32]byte - EncodingKey [32]byte - DecodingNonce [16]byte - EncodingNonce [16]byte -} - -func (a *Authentication) DataCenterID() uint16 { - x := ((int16(a.Header[61]) << 8) | int16(a.Header[60])) - if x < 0 { - x = -x - } - return uint16(x) - 1 -} - -func (a *Authentication) ConnectionType() [4]byte { - var x [4]byte - copy(x[:], a.Header[56:60]) - return x -} - -func (a *Authentication) ApplySecret(b []byte) { - a.DecodingKey = sha256.Sum256(append(a.DecodingKey[:], b...)) - a.EncodingKey = sha256.Sum256(append(a.EncodingKey[:], b...)) -} - -func generateRandomBytes(random []byte, connType [4]byte) { - for { - common.Must2(rand.Read(random)) - - if random[0] == 0xef { - continue - } - - val := (uint32(random[3]) << 24) | (uint32(random[2]) << 16) | (uint32(random[1]) << 8) | uint32(random[0]) - if val == 0x44414548 || val == 0x54534f50 || val == 0x20544547 || val == 0x4954504f || val == 0xeeeeeeee { - continue - } - - if (uint32(random[7])<<24)|(uint32(random[6])<<16)|(uint32(random[5])<<8)|uint32(random[4]) == 0x00000000 { - continue - } - - copy(random[56:60], connType[:]) - - return - } -} - -func NewAuthentication(sc SessionContext) *Authentication { - auth := getAuthenticationObject() - random := auth.Header[:] - generateRandomBytes(random, sc.ConnectionType) - copy(auth.EncodingKey[:], random[8:]) - copy(auth.EncodingNonce[:], random[8+32:]) - keyivInverse := Inverse(random[8 : 8+32+16]) - copy(auth.DecodingKey[:], keyivInverse) - copy(auth.DecodingNonce[:], keyivInverse[32:]) - return auth -} - -func ReadAuthentication(reader io.Reader) (*Authentication, error) { - auth := getAuthenticationObject() - - if _, err := io.ReadFull(reader, auth.Header[:]); err != nil { - putAuthenticationObject(auth) - return nil, err - } - - copy(auth.DecodingKey[:], auth.Header[8:]) - copy(auth.DecodingNonce[:], auth.Header[8+32:]) - keyivInverse := Inverse(auth.Header[8 : 8+32+16]) - copy(auth.EncodingKey[:], keyivInverse) - copy(auth.EncodingNonce[:], keyivInverse[32:]) - - return auth, nil -} - -// Inverse returns a new byte array. It is a sequence of bytes when the input is read from end to beginning.Inverse -// Visible for testing only. -func Inverse(b []byte) []byte { - lenb := len(b) - b2 := make([]byte, lenb) - for i, v := range b { - b2[lenb-i-1] = v - } - return b2 -} - -var authPool = sync.Pool{ - New: func() interface{} { - return new(Authentication) - }, -} - -func getAuthenticationObject() *Authentication { - return authPool.Get().(*Authentication) -} - -func putAuthenticationObject(auth *Authentication) { - authPool.Put(auth) -} diff --git a/proxy/mtproto/auth_test.go b/proxy/mtproto/auth_test.go deleted file mode 100644 index a05bc743..00000000 --- a/proxy/mtproto/auth_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package mtproto_test - -import ( - "bytes" - "crypto/rand" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/xtls/xray-core/common" - . "github.com/xtls/xray-core/proxy/mtproto" -) - -func TestInverse(t *testing.T) { - const size = 64 - b := make([]byte, 64) - for b[0] == b[size-1] { - common.Must2(rand.Read(b)) - } - - bi := Inverse(b) - if b[0] == bi[0] { - t.Fatal("seems bytes are not inversed: ", b[0], "vs", bi[0]) - } - - bii := Inverse(bi) - if r := cmp.Diff(bii, b); r != "" { - t.Fatal(r) - } -} - -func TestAuthenticationReadWrite(t *testing.T) { - a := NewAuthentication(DefaultSessionContext()) - b := bytes.NewReader(a.Header[:]) - a2, err := ReadAuthentication(b) - common.Must(err) - - if r := cmp.Diff(a.EncodingKey[:], a2.DecodingKey[:]); r != "" { - t.Error("decoding key: ", r) - } - - if r := cmp.Diff(a.EncodingNonce[:], a2.DecodingNonce[:]); r != "" { - t.Error("decoding nonce: ", r) - } - - if r := cmp.Diff(a.DecodingKey[:], a2.EncodingKey[:]); r != "" { - t.Error("encoding key: ", r) - } - - if r := cmp.Diff(a.DecodingNonce[:], a2.EncodingNonce[:]); r != "" { - t.Error("encoding nonce: ", r) - } -} diff --git a/proxy/mtproto/client.go b/proxy/mtproto/client.go deleted file mode 100644 index 6825fdae..00000000 --- a/proxy/mtproto/client.go +++ /dev/null @@ -1,76 +0,0 @@ -package mtproto - -import ( - "context" - - "github.com/xtls/xray-core/common" - "github.com/xtls/xray-core/common/buf" - "github.com/xtls/xray-core/common/crypto" - "github.com/xtls/xray-core/common/net" - "github.com/xtls/xray-core/common/session" - "github.com/xtls/xray-core/common/task" - "github.com/xtls/xray-core/transport" - "github.com/xtls/xray-core/transport/internet" -) - -type Client struct{} - -func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) { - return &Client{}, nil -} - -func (c *Client) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error { - outbound := session.OutboundFromContext(ctx) - if outbound == nil || !outbound.Target.IsValid() { - return newError("unknown destination.") - } - dest := outbound.Target - if dest.Network != net.Network_TCP { - return newError("not TCP traffic", dest) - } - - conn, err := dialer.Dial(ctx, dest) - if err != nil { - return newError("failed to dial to ", dest).Base(err).AtWarning() - } - defer conn.Close() - - sc := SessionContextFromContext(ctx) - auth := NewAuthentication(sc) - defer putAuthenticationObject(auth) - - request := func() error { - encryptor := crypto.NewAesCTRStream(auth.EncodingKey[:], auth.EncodingNonce[:]) - - var header [HeaderSize]byte - encryptor.XORKeyStream(header[:], auth.Header[:]) - copy(header[:56], auth.Header[:]) - - if _, err := conn.Write(header[:]); err != nil { - return newError("failed to write auth header").Base(err) - } - - connWriter := buf.NewWriter(crypto.NewCryptionWriter(encryptor, conn)) - return buf.Copy(link.Reader, connWriter) - } - - response := func() error { - decryptor := crypto.NewAesCTRStream(auth.DecodingKey[:], auth.DecodingNonce[:]) - - connReader := buf.NewReader(crypto.NewCryptionReader(decryptor, conn)) - return buf.Copy(connReader, link.Writer) - } - - responseDoneAndCloseWriter := task.OnSuccess(response, task.Close(link.Writer)) - if err := task.Run(ctx, request, responseDoneAndCloseWriter); err != nil { - return newError("connection ends").Base(err) - } - - return nil -} - -func init() { - common.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { - return NewClient(ctx, config.(*ClientConfig)) - })) -} diff --git a/proxy/mtproto/config.go b/proxy/mtproto/config.go deleted file mode 100644 index fcd203d7..00000000 --- a/proxy/mtproto/config.go +++ /dev/null @@ -1,24 +0,0 @@ -package mtproto - -import ( - "github.com/xtls/xray-core/common/protocol" -) - -func (a *Account) Equals(another protocol.Account) bool { - aa, ok := another.(*Account) - if !ok { - return false - } - - if len(a.Secret) != len(aa.Secret) { - return false - } - - for i, v := range a.Secret { - if v != aa.Secret[i] { - return false - } - } - - return true -} diff --git a/proxy/mtproto/config.pb.go b/proxy/mtproto/config.pb.go deleted file mode 100644 index 425c7672..00000000 --- a/proxy/mtproto/config.pb.go +++ /dev/null @@ -1,272 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.12 -// source: proxy/mtproto/config.proto - -package mtproto - -import ( - protocol "github.com/xtls/xray-core/common/protocol" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Account struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Secret []byte `protobuf:"bytes,1,opt,name=secret,proto3" json:"secret,omitempty"` -} - -func (x *Account) Reset() { - *x = Account{} - if protoimpl.UnsafeEnabled { - mi := &file_proxy_mtproto_config_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Account) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Account) ProtoMessage() {} - -func (x *Account) ProtoReflect() protoreflect.Message { - mi := &file_proxy_mtproto_config_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Account.ProtoReflect.Descriptor instead. -func (*Account) Descriptor() ([]byte, []int) { - return file_proxy_mtproto_config_proto_rawDescGZIP(), []int{0} -} - -func (x *Account) GetSecret() []byte { - if x != nil { - return x.Secret - } - return nil -} - -type ServerConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // User is a list of users that allowed to connect to this inbound. - // Although this is a repeated field, only the first user is effective for - // now. - User []*protocol.User `protobuf:"bytes,1,rep,name=user,proto3" json:"user,omitempty"` -} - -func (x *ServerConfig) Reset() { - *x = ServerConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_proxy_mtproto_config_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ServerConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ServerConfig) ProtoMessage() {} - -func (x *ServerConfig) ProtoReflect() protoreflect.Message { - mi := &file_proxy_mtproto_config_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ServerConfig.ProtoReflect.Descriptor instead. -func (*ServerConfig) Descriptor() ([]byte, []int) { - return file_proxy_mtproto_config_proto_rawDescGZIP(), []int{1} -} - -func (x *ServerConfig) GetUser() []*protocol.User { - if x != nil { - return x.User - } - return nil -} - -type ClientConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *ClientConfig) Reset() { - *x = ClientConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_proxy_mtproto_config_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ClientConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ClientConfig) ProtoMessage() {} - -func (x *ClientConfig) ProtoReflect() protoreflect.Message { - mi := &file_proxy_mtproto_config_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ClientConfig.ProtoReflect.Descriptor instead. -func (*ClientConfig) Descriptor() ([]byte, []int) { - return file_proxy_mtproto_config_proto_rawDescGZIP(), []int{2} -} - -var File_proxy_mtproto_config_proto protoreflect.FileDescriptor - -var file_proxy_mtproto_config_proto_rawDesc = []byte{ - 0x0a, 0x1a, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x6d, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x78, 0x72, - 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x6d, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x1a, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x21, 0x0a, 0x07, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, - 0x3e, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x2e, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, - 0x0e, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, - 0x58, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x2e, 0x6d, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, - 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x6d, 0x74, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0xaa, 0x02, 0x12, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x50, 0x72, 0x6f, 0x78, - 0x79, 0x2e, 0x4d, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, -} - -var ( - file_proxy_mtproto_config_proto_rawDescOnce sync.Once - file_proxy_mtproto_config_proto_rawDescData = file_proxy_mtproto_config_proto_rawDesc -) - -func file_proxy_mtproto_config_proto_rawDescGZIP() []byte { - file_proxy_mtproto_config_proto_rawDescOnce.Do(func() { - file_proxy_mtproto_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_proxy_mtproto_config_proto_rawDescData) - }) - return file_proxy_mtproto_config_proto_rawDescData -} - -var file_proxy_mtproto_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3) -var file_proxy_mtproto_config_proto_goTypes = []interface{}{ - (*Account)(nil), // 0: xray.proxy.mtproto.Account - (*ServerConfig)(nil), // 1: xray.proxy.mtproto.ServerConfig - (*ClientConfig)(nil), // 2: xray.proxy.mtproto.ClientConfig - (*protocol.User)(nil), // 3: xray.common.protocol.User -} -var file_proxy_mtproto_config_proto_depIdxs = []int32{ - 3, // 0: xray.proxy.mtproto.ServerConfig.user:type_name -> xray.common.protocol.User - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_proxy_mtproto_config_proto_init() } -func file_proxy_mtproto_config_proto_init() { - if File_proxy_mtproto_config_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_proxy_mtproto_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Account); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proxy_mtproto_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ServerConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proxy_mtproto_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ClientConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_proxy_mtproto_config_proto_rawDesc, - NumEnums: 0, - NumMessages: 3, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_proxy_mtproto_config_proto_goTypes, - DependencyIndexes: file_proxy_mtproto_config_proto_depIdxs, - MessageInfos: file_proxy_mtproto_config_proto_msgTypes, - }.Build() - File_proxy_mtproto_config_proto = out.File - file_proxy_mtproto_config_proto_rawDesc = nil - file_proxy_mtproto_config_proto_goTypes = nil - file_proxy_mtproto_config_proto_depIdxs = nil -} diff --git a/proxy/mtproto/config.proto b/proxy/mtproto/config.proto deleted file mode 100644 index 65997bc0..00000000 --- a/proxy/mtproto/config.proto +++ /dev/null @@ -1,22 +0,0 @@ -syntax = "proto3"; - -package xray.proxy.mtproto; -option csharp_namespace = "Xray.Proxy.Mtproto"; -option go_package = "github.com/xtls/xray-core/proxy/mtproto"; -option java_package = "com.xray.proxy.mtproto"; -option java_multiple_files = true; - -import "common/protocol/user.proto"; - -message Account { - bytes secret = 1; -} - -message ServerConfig { - // User is a list of users that allowed to connect to this inbound. - // Although this is a repeated field, only the first user is effective for - // now. - repeated xray.common.protocol.User user = 1; -} - -message ClientConfig {} diff --git a/proxy/mtproto/errors.generated.go b/proxy/mtproto/errors.generated.go deleted file mode 100644 index 012202d6..00000000 --- a/proxy/mtproto/errors.generated.go +++ /dev/null @@ -1,9 +0,0 @@ -package mtproto - -import "github.com/xtls/xray-core/common/errors" - -type errPathObjHolder struct{} - -func newError(values ...interface{}) *errors.Error { - return errors.New(values...).WithPathObj(errPathObjHolder{}) -} diff --git a/proxy/mtproto/mtproto.go b/proxy/mtproto/mtproto.go deleted file mode 100644 index af7983a5..00000000 --- a/proxy/mtproto/mtproto.go +++ /dev/null @@ -1,3 +0,0 @@ -package mtproto - -//go:generate go run github.com/xtls/xray-core/common/errors/errorgen diff --git a/proxy/mtproto/server.go b/proxy/mtproto/server.go deleted file mode 100644 index 2079df1f..00000000 --- a/proxy/mtproto/server.go +++ /dev/null @@ -1,160 +0,0 @@ -package mtproto - -import ( - "bytes" - "context" - "time" - - "github.com/xtls/xray-core/common" - "github.com/xtls/xray-core/common/buf" - "github.com/xtls/xray-core/common/crypto" - "github.com/xtls/xray-core/common/net" - "github.com/xtls/xray-core/common/protocol" - "github.com/xtls/xray-core/common/session" - "github.com/xtls/xray-core/common/signal" - "github.com/xtls/xray-core/common/task" - "github.com/xtls/xray-core/core" - "github.com/xtls/xray-core/features/policy" - "github.com/xtls/xray-core/features/routing" - "github.com/xtls/xray-core/transport/internet/stat" -) - -var dcList = []net.Address{ - net.ParseAddress("149.154.175.50"), - net.ParseAddress("149.154.167.51"), - net.ParseAddress("149.154.175.100"), - net.ParseAddress("149.154.167.91"), - net.ParseAddress("149.154.171.5"), -} - -type Server struct { - user *protocol.User - account *Account - policy policy.Manager -} - -func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) { - if len(config.User) == 0 { - return nil, newError("no user configured.") - } - - user := config.User[0] - rawAccount, err := config.User[0].GetTypedAccount() - if err != nil { - return nil, newError("invalid account").Base(err) - } - account, ok := rawAccount.(*Account) - if !ok { - return nil, newError("not a MTProto account") - } - - v := core.MustFromContext(ctx) - - return &Server{ - user: user, - account: account, - policy: v.GetFeature(policy.ManagerType()).(policy.Manager), - }, nil -} - -func (s *Server) Network() []net.Network { - return []net.Network{net.Network_TCP} -} - -var ( - ctype1 = []byte{0xef, 0xef, 0xef, 0xef} - ctype2 = []byte{0xee, 0xee, 0xee, 0xee} -) - -func isValidConnectionType(c [4]byte) bool { - if bytes.Equal(c[:], ctype1) { - return true - } - if bytes.Equal(c[:], ctype2) { - return true - } - return false -} - -func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Connection, dispatcher routing.Dispatcher) error { - sPolicy := s.policy.ForLevel(s.user.Level) - - if err := conn.SetDeadline(time.Now().Add(sPolicy.Timeouts.Handshake)); err != nil { - newError("failed to set deadline").Base(err).WriteToLog(session.ExportIDToError(ctx)) - } - auth, err := ReadAuthentication(conn) - if err != nil { - return newError("failed to read authentication header").Base(err) - } - defer putAuthenticationObject(auth) - - if err := conn.SetDeadline(time.Time{}); err != nil { - newError("failed to clear deadline").Base(err).WriteToLog(session.ExportIDToError(ctx)) - } - - auth.ApplySecret(s.account.Secret) - - decryptor := crypto.NewAesCTRStream(auth.DecodingKey[:], auth.DecodingNonce[:]) - decryptor.XORKeyStream(auth.Header[:], auth.Header[:]) - - ct := auth.ConnectionType() - if !isValidConnectionType(ct) { - return newError("invalid connection type: ", ct) - } - - dcID := auth.DataCenterID() - if dcID >= uint16(len(dcList)) { - return newError("invalid datacenter id: ", dcID) - } - - dest := net.Destination{ - Network: net.Network_TCP, - Address: dcList[dcID], - Port: net.Port(443), - } - - ctx, cancel := context.WithCancel(ctx) - timer := signal.CancelAfterInactivity(ctx, cancel, sPolicy.Timeouts.ConnectionIdle) - ctx = policy.ContextWithBufferPolicy(ctx, sPolicy.Buffer) - - sc := SessionContext{ - ConnectionType: ct, - DataCenterID: dcID, - } - ctx = ContextWithSessionContext(ctx, sc) - - link, err := dispatcher.Dispatch(ctx, dest) - if err != nil { - return newError("failed to dispatch request to: ", dest).Base(err) - } - - request := func() error { - defer timer.SetTimeout(sPolicy.Timeouts.DownlinkOnly) - - reader := buf.NewReader(crypto.NewCryptionReader(decryptor, conn)) - return buf.Copy(reader, link.Writer, buf.UpdateActivity(timer)) - } - - response := func() error { - defer timer.SetTimeout(sPolicy.Timeouts.UplinkOnly) - - encryptor := crypto.NewAesCTRStream(auth.EncodingKey[:], auth.EncodingNonce[:]) - writer := buf.NewWriter(crypto.NewCryptionWriter(encryptor, conn)) - return buf.Copy(link.Reader, writer, buf.UpdateActivity(timer)) - } - - responseDoneAndCloseWriter := task.OnSuccess(response, task.Close(link.Writer)) - if err := task.Run(ctx, request, responseDoneAndCloseWriter); err != nil { - common.Interrupt(link.Reader) - common.Interrupt(link.Writer) - return newError("connection ends").Base(err) - } - - return nil -} - -func init() { - common.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { - return NewServer(ctx, config.(*ServerConfig)) - })) -}