github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/proxy/mtproto/server.go (about)

     1  // +build !confonly
     2  
     3  package mtproto
     4  
     5  import (
     6  	"bytes"
     7  	"context"
     8  	"time"
     9  
    10  	"v2ray.com/core"
    11  	"v2ray.com/core/common"
    12  	"v2ray.com/core/common/buf"
    13  	"v2ray.com/core/common/crypto"
    14  	"v2ray.com/core/common/net"
    15  	"v2ray.com/core/common/protocol"
    16  	"v2ray.com/core/common/session"
    17  	"v2ray.com/core/common/signal"
    18  	"v2ray.com/core/common/task"
    19  	"v2ray.com/core/features/policy"
    20  	"v2ray.com/core/features/routing"
    21  	"v2ray.com/core/transport/internet"
    22  )
    23  
    24  var (
    25  	dcList = []net.Address{
    26  		net.ParseAddress("149.154.175.50"),
    27  		net.ParseAddress("149.154.167.51"),
    28  		net.ParseAddress("149.154.175.100"),
    29  		net.ParseAddress("149.154.167.91"),
    30  		net.ParseAddress("149.154.171.5"),
    31  	}
    32  )
    33  
    34  type Server struct {
    35  	user    *protocol.User
    36  	account *Account
    37  	policy  policy.Manager
    38  }
    39  
    40  func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
    41  	if len(config.User) == 0 {
    42  		return nil, newError("no user configured.")
    43  	}
    44  
    45  	user := config.User[0]
    46  	rawAccount, err := config.User[0].GetTypedAccount()
    47  	if err != nil {
    48  		return nil, newError("invalid account").Base(err)
    49  	}
    50  	account, ok := rawAccount.(*Account)
    51  	if !ok {
    52  		return nil, newError("not a MTProto account")
    53  	}
    54  
    55  	v := core.MustFromContext(ctx)
    56  
    57  	return &Server{
    58  		user:    user,
    59  		account: account,
    60  		policy:  v.GetFeature(policy.ManagerType()).(policy.Manager),
    61  	}, nil
    62  }
    63  
    64  func (s *Server) Network() []net.Network {
    65  	return []net.Network{net.Network_TCP}
    66  }
    67  
    68  var ctype1 = []byte{0xef, 0xef, 0xef, 0xef}
    69  var ctype2 = []byte{0xee, 0xee, 0xee, 0xee}
    70  
    71  func isValidConnectionType(c [4]byte) bool {
    72  	if bytes.Equal(c[:], ctype1) {
    73  		return true
    74  	}
    75  	if bytes.Equal(c[:], ctype2) {
    76  		return true
    77  	}
    78  	return false
    79  }
    80  
    81  func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher routing.Dispatcher) error {
    82  	sPolicy := s.policy.ForLevel(s.user.Level)
    83  
    84  	if err := conn.SetDeadline(time.Now().Add(sPolicy.Timeouts.Handshake)); err != nil {
    85  		newError("failed to set deadline").Base(err).WriteToLog(session.ExportIDToError(ctx))
    86  	}
    87  	auth, err := ReadAuthentication(conn)
    88  	if err != nil {
    89  		return newError("failed to read authentication header").Base(err)
    90  	}
    91  	defer putAuthenticationObject(auth)
    92  
    93  	if err := conn.SetDeadline(time.Time{}); err != nil {
    94  		newError("failed to clear deadline").Base(err).WriteToLog(session.ExportIDToError(ctx))
    95  	}
    96  
    97  	auth.ApplySecret(s.account.Secret)
    98  
    99  	decryptor := crypto.NewAesCTRStream(auth.DecodingKey[:], auth.DecodingNonce[:])
   100  	decryptor.XORKeyStream(auth.Header[:], auth.Header[:])
   101  
   102  	ct := auth.ConnectionType()
   103  	if !isValidConnectionType(ct) {
   104  		return newError("invalid connection type: ", ct)
   105  	}
   106  
   107  	dcID := auth.DataCenterID()
   108  	if dcID >= uint16(len(dcList)) {
   109  		return newError("invalid datacenter id: ", dcID)
   110  	}
   111  
   112  	dest := net.Destination{
   113  		Network: net.Network_TCP,
   114  		Address: dcList[dcID],
   115  		Port:    net.Port(443),
   116  	}
   117  
   118  	ctx, cancel := context.WithCancel(ctx)
   119  	timer := signal.CancelAfterInactivity(ctx, cancel, sPolicy.Timeouts.ConnectionIdle)
   120  	ctx = policy.ContextWithBufferPolicy(ctx, sPolicy.Buffer)
   121  
   122  	sc := SessionContext{
   123  		ConnectionType: ct,
   124  		DataCenterID:   dcID,
   125  	}
   126  	ctx = ContextWithSessionContext(ctx, sc)
   127  
   128  	link, err := dispatcher.Dispatch(ctx, dest)
   129  	if err != nil {
   130  		return newError("failed to dispatch request to: ", dest).Base(err)
   131  	}
   132  
   133  	request := func() error {
   134  		defer timer.SetTimeout(sPolicy.Timeouts.DownlinkOnly)
   135  
   136  		reader := buf.NewReader(crypto.NewCryptionReader(decryptor, conn))
   137  		return buf.Copy(reader, link.Writer, buf.UpdateActivity(timer))
   138  	}
   139  
   140  	response := func() error {
   141  		defer timer.SetTimeout(sPolicy.Timeouts.UplinkOnly)
   142  
   143  		encryptor := crypto.NewAesCTRStream(auth.EncodingKey[:], auth.EncodingNonce[:])
   144  		writer := buf.NewWriter(crypto.NewCryptionWriter(encryptor, conn))
   145  		return buf.Copy(link.Reader, writer, buf.UpdateActivity(timer))
   146  	}
   147  
   148  	var responseDoneAndCloseWriter = task.OnSuccess(response, task.Close(link.Writer))
   149  	if err := task.Run(ctx, request, responseDoneAndCloseWriter); err != nil {
   150  		common.Interrupt(link.Reader)
   151  		common.Interrupt(link.Writer)
   152  		return newError("connection ends").Base(err)
   153  	}
   154  
   155  	return nil
   156  }
   157  
   158  func init() {
   159  	common.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
   160  		return NewServer(ctx, config.(*ServerConfig))
   161  	}))
   162  }