github.com/xmplusdev/xmcore@v1.8.11-0.20240412132628-5518b55526af/core/functions.go (about) 1 package core 2 3 import ( 4 "bytes" 5 "context" 6 7 "github.com/xmplusdev/xmcore/common" 8 "github.com/xmplusdev/xmcore/common/net" 9 "github.com/xmplusdev/xmcore/common/net/cnc" 10 "github.com/xmplusdev/xmcore/features/routing" 11 "github.com/xmplusdev/xmcore/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 }