github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/infra/conf/v5cfg/root.go (about) 1 package v5cfg 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 8 "github.com/golang/protobuf/proto" 9 "google.golang.org/protobuf/types/known/anypb" 10 11 core "github.com/v2fly/v2ray-core/v5" 12 "github.com/v2fly/v2ray-core/v5/app/dispatcher" 13 "github.com/v2fly/v2ray-core/v5/app/proxyman" 14 "github.com/v2fly/v2ray-core/v5/common/platform" 15 "github.com/v2fly/v2ray-core/v5/common/serial" 16 "github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon" 17 "github.com/v2fly/v2ray-core/v5/infra/conf/geodata" 18 "github.com/v2fly/v2ray-core/v5/infra/conf/synthetic/log" 19 ) 20 21 func (c RootConfig) BuildV5(ctx context.Context) (proto.Message, error) { 22 config := &core.Config{ 23 App: []*anypb.Any{ 24 serial.ToTypedMessage(&dispatcher.Config{}), 25 serial.ToTypedMessage(&proxyman.InboundConfig{}), 26 serial.ToTypedMessage(&proxyman.OutboundConfig{}), 27 }, 28 } 29 30 var logConfMsg *anypb.Any 31 if c.LogConfig != nil { 32 logConfMsgUnpacked, err := loadHeterogeneousConfigFromRawJSON("service", "log", c.LogConfig) 33 if err != nil { 34 return nil, newError("failed to parse Log config").Base(err) 35 } 36 logConfMsg = serial.ToTypedMessage(logConfMsgUnpacked) 37 } else { 38 logConfMsg = serial.ToTypedMessage(log.DefaultLogConfig()) 39 } 40 // let logger module be the first App to start, 41 // so that other modules could print log during initiating 42 config.App = append([]*anypb.Any{logConfMsg}, config.App...) 43 44 if c.RouterConfig != nil { 45 routerConfig, err := loadHeterogeneousConfigFromRawJSON("service", "router", c.RouterConfig) 46 if err != nil { 47 return nil, newError("failed to parse Router config").Base(err) 48 } 49 config.App = append(config.App, serial.ToTypedMessage(routerConfig)) 50 } 51 52 if c.DNSConfig != nil { 53 dnsApp, err := loadHeterogeneousConfigFromRawJSON("service", "dns", c.DNSConfig) 54 if err != nil { 55 return nil, newError("failed to parse DNS config").Base(err) 56 } 57 config.App = append(config.App, serial.ToTypedMessage(dnsApp)) 58 } 59 60 for _, rawInboundConfig := range c.Inbounds { 61 ic, err := rawInboundConfig.BuildV5(ctx) 62 if err != nil { 63 return nil, err 64 } 65 config.Inbound = append(config.Inbound, ic.(*core.InboundHandlerConfig)) 66 } 67 68 for _, rawOutboundConfig := range c.Outbounds { 69 ic, err := rawOutboundConfig.BuildV5(ctx) 70 if err != nil { 71 return nil, err 72 } 73 config.Outbound = append(config.Outbound, ic.(*core.OutboundHandlerConfig)) 74 } 75 76 for serviceName, service := range c.Services { 77 servicePackedConfig, err := loadHeterogeneousConfigFromRawJSON("service", serviceName, service) 78 if err != nil { 79 return nil, newError(fmt.Sprintf("failed to parse %v config in Services", serviceName)).Base(err) 80 } 81 config.App = append(config.App, serial.ToTypedMessage(servicePackedConfig)) 82 } 83 return config, nil 84 } 85 86 func loadJSONConfig(data []byte) (*core.Config, error) { 87 rootConfig := &RootConfig{} 88 89 err := json.Unmarshal(data, rootConfig) 90 if err != nil { 91 return nil, newError("unable to load json").Base(err) 92 } 93 94 buildctx := cfgcommon.NewConfigureLoadingContext(context.Background()) 95 96 geoloadername := platform.NewEnvFlag("v2ray.conf.geoloader").GetValue(func() string { 97 return "standard" 98 }) 99 100 if loader, err := geodata.GetGeoDataLoader(geoloadername); err == nil { 101 cfgcommon.SetGeoDataLoader(buildctx, loader) 102 } else { 103 return nil, newError("unable to create geo data loader ").Base(err) 104 } 105 106 message, err := rootConfig.BuildV5(buildctx) 107 if err != nil { 108 return nil, newError("unable to build config").Base(err) 109 } 110 return message.(*core.Config), nil 111 }