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 }