github.com/eagleql/xray-core@v1.4.4/core/functions.go (about)

     1  package core
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  
     7  	"github.com/eagleql/xray-core/common"
     8  	"github.com/eagleql/xray-core/common/net"
     9  	"github.com/eagleql/xray-core/common/net/cnc"
    10  	"github.com/eagleql/xray-core/features/routing"
    11  	"github.com/eagleql/xray-core/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 = context.WithValue(ctx, xrayKey, 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  	dispatcher := v.GetFeature(routing.DispatcherType())
    50  	if dispatcher == nil {
    51  		return nil, newError("routing.Dispatcher is not registered in Xray core")
    52  	}
    53  	r, err := dispatcher.(routing.Dispatcher).Dispatch(ctx, dest)
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  	var readerOpt cnc.ConnectionOption
    58  	if dest.Network == net.Network_TCP {
    59  		readerOpt = cnc.ConnectionOutputMulti(r.Reader)
    60  	} else {
    61  		readerOpt = cnc.ConnectionOutputMultiUDP(r.Reader)
    62  	}
    63  	return cnc.NewConnection(cnc.ConnectionInputMulti(r.Writer), readerOpt), nil
    64  }
    65  
    66  // DialUDP provides a way to exchange UDP packets through Xray instance to remote servers.
    67  // Since it is under a proxy context, the LocalAddr() in returned PacketConn will not show the real address.
    68  //
    69  // TODO: SetDeadline() / SetReadDeadline() / SetWriteDeadline() are not implemented.
    70  //
    71  // xray:api:beta
    72  func DialUDP(ctx context.Context, v *Instance) (net.PacketConn, error) {
    73  	dispatcher := v.GetFeature(routing.DispatcherType())
    74  	if dispatcher == nil {
    75  		return nil, newError("routing.Dispatcher is not registered in Xray core")
    76  	}
    77  	return udp.DialDispatcher(ctx, dispatcher.(routing.Dispatcher))
    78  }