github.com/moqsien/xraycore@v1.8.5/core/functions.go (about)

     1  package core
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  
     7  	"github.com/moqsien/xraycore/common"
     8  	"github.com/moqsien/xraycore/common/net"
     9  	"github.com/moqsien/xraycore/common/net/cnc"
    10  	"github.com/moqsien/xraycore/features/routing"
    11  	"github.com/moqsien/xraycore/transport/internet/udp"
    12  )
    13  
    14  // CreateObject creates a new object based on the given Xray instance and config. The Xray instance may be nil.
    15  func CreateObject(v *Instance, config interface{}) (interface{}, error) {
    16  	ctx := v.ctx
    17  	if v != nil {
    18  		ctx = toContext(v.ctx, v)
    19  	}
    20  	return common.CreateObject(ctx, config)
    21  }
    22  
    23  // StartInstance starts a new Xray instance with given serialized config.
    24  // By default Xray only support config in protobuf format, i.e., configFormat = "protobuf". Caller need to load other packages to add JSON support.
    25  //
    26  // xray:api:stable
    27  func StartInstance(configFormat string, configBytes []byte) (*Instance, error) {
    28  	config, err := LoadConfig(configFormat, bytes.NewReader(configBytes))
    29  	if err != nil {
    30  		return nil, err
    31  	}
    32  	instance, err := New(config)
    33  	if err != nil {
    34  		return nil, err
    35  	}
    36  	if err := instance.Start(); err != nil {
    37  		return nil, err
    38  	}
    39  	return instance, nil
    40  }
    41  
    42  // Dial provides an easy way for upstream caller to create net.Conn through Xray.
    43  // It dispatches the request to the given destination by the given Xray instance.
    44  // Since it is under a proxy context, the LocalAddr() and RemoteAddr() in returned net.Conn
    45  // will not show real addresses being used for communication.
    46  //
    47  // xray:api:stable
    48  func Dial(ctx context.Context, v *Instance, dest net.Destination) (net.Conn, error) {
    49  	ctx = toContext(ctx, v)
    50  
    51  	dispatcher := v.GetFeature(routing.DispatcherType())
    52  	if dispatcher == nil {
    53  		return nil, newError("routing.Dispatcher is not registered in Xray core")
    54  	}
    55  
    56  	r, err := dispatcher.(routing.Dispatcher).Dispatch(ctx, dest)
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  	var readerOpt cnc.ConnectionOption
    61  	if dest.Network == net.Network_TCP {
    62  		readerOpt = cnc.ConnectionOutputMulti(r.Reader)
    63  	} else {
    64  		readerOpt = cnc.ConnectionOutputMultiUDP(r.Reader)
    65  	}
    66  	return cnc.NewConnection(cnc.ConnectionInputMulti(r.Writer), readerOpt), nil
    67  }
    68  
    69  // DialUDP provides a way to exchange UDP packets through Xray instance to remote servers.
    70  // Since it is under a proxy context, the LocalAddr() in returned PacketConn will not show the real address.
    71  //
    72  // TODO: SetDeadline() / SetReadDeadline() / SetWriteDeadline() are not implemented.
    73  //
    74  // xray:api:beta
    75  func DialUDP(ctx context.Context, v *Instance) (net.PacketConn, error) {
    76  	ctx = toContext(ctx, v)
    77  
    78  	dispatcher := v.GetFeature(routing.DispatcherType())
    79  	if dispatcher == nil {
    80  		return nil, newError("routing.Dispatcher is not registered in Xray core")
    81  	}
    82  	return udp.DialDispatcher(ctx, dispatcher.(routing.Dispatcher))
    83  }