github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/functions.go (about)

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