1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-09-05 19:44:32 -04:00
v2fly/tools/conf/v2ray.go

388 lines
11 KiB
Go
Raw Normal View History

2016-10-16 08:22:21 -04:00
package conf
import (
"encoding/json"
2016-10-17 08:35:13 -04:00
"io"
2016-12-04 03:10:47 -05:00
"strings"
2017-01-07 19:25:35 -05:00
2016-10-17 08:35:13 -04:00
"v2ray.com/core"
"v2ray.com/core/app/proxyman"
2016-10-16 08:22:21 -04:00
v2net "v2ray.com/core/common/net"
2016-12-15 05:51:09 -05:00
"v2ray.com/core/common/serial"
2016-12-14 17:51:03 -05:00
json_reader "v2ray.com/core/tools/conf/json"
2016-10-16 08:22:21 -04:00
)
2016-10-17 08:35:13 -04:00
var (
inboundConfigLoader = NewJSONConfigLoader(ConfigCreatorCache{
"dokodemo-door": func() interface{} { return new(DokodemoConfig) },
"http": func() interface{} { return new(HttpServerConfig) },
"shadowsocks": func() interface{} { return new(ShadowsocksServerConfig) },
"socks": func() interface{} { return new(SocksServerConfig) },
"vmess": func() interface{} { return new(VMessInboundConfig) },
}, "protocol", "settings")
outboundConfigLoader = NewJSONConfigLoader(ConfigCreatorCache{
2016-11-04 20:01:30 -04:00
"blackhole": func() interface{} { return new(BlackholeConfig) },
"freedom": func() interface{} { return new(FreedomConfig) },
"shadowsocks": func() interface{} { return new(ShadowsocksClientConfig) },
"vmess": func() interface{} { return new(VMessOutboundConfig) },
2017-01-07 19:25:35 -05:00
"socks": func() interface{} { return new(SocksClientConfig) },
2016-10-17 08:35:13 -04:00
}, "protocol", "settings")
)
type InboundConnectionConfig struct {
Port uint16 `json:"port"`
Listen *Address `json:"listen"`
Protocol string `json:"protocol"`
StreamSetting *StreamConfig `json:"streamSettings"`
Settings json.RawMessage `json:"settings"`
2016-11-17 17:23:46 -05:00
Tag string `json:"tag"`
2016-10-17 08:35:13 -04:00
}
func (v *InboundConnectionConfig) Build() (*proxyman.InboundHandlerConfig, error) {
receiverConfig := &proxyman.ReceiverConfig{
PortRange: &v2net.PortRange{
From: uint32(v.Port),
To: uint32(v.Port),
},
2016-10-17 08:35:13 -04:00
}
2016-11-27 15:39:09 -05:00
if v.Listen != nil {
if v.Listen.Family().IsDomain() {
2017-04-09 09:04:04 -04:00
return nil, newError("unable to listen on domain address: " + v.Listen.Domain())
2016-10-17 08:35:13 -04:00
}
receiverConfig.Listen = v.Listen.Build()
2016-10-17 08:35:13 -04:00
}
2016-11-27 15:39:09 -05:00
if v.StreamSetting != nil {
ts, err := v.StreamSetting.Build()
2016-10-17 08:35:13 -04:00
if err != nil {
return nil, err
}
receiverConfig.StreamSettings = ts
2016-10-17 08:35:13 -04:00
}
2016-11-27 15:39:09 -05:00
jsonConfig, err := inboundConfigLoader.LoadWithID(v.Settings, v.Protocol)
2016-10-17 08:35:13 -04:00
if err != nil {
2017-04-09 09:04:04 -04:00
return nil, newError("failed to load inbound config.").Base(err)
2016-10-17 08:35:13 -04:00
}
if dokodemoConfig, ok := jsonConfig.(*DokodemoConfig); ok {
receiverConfig.ReceiveOriginalDestination = dokodemoConfig.Redirect
}
2016-10-17 08:35:13 -04:00
ts, err := jsonConfig.(Buildable).Build()
if err != nil {
return nil, err
}
return &proxyman.InboundHandlerConfig{
Tag: v.Tag,
ReceiverSettings: serial.ToTypedMessage(receiverConfig),
ProxySettings: ts,
}, nil
2016-10-17 08:35:13 -04:00
}
2017-04-02 15:30:21 -04:00
type MuxConfig struct {
Enabled bool `json:"enabled"`
}
2016-10-17 08:35:13 -04:00
type OutboundConnectionConfig struct {
Protocol string `json:"protocol"`
SendThrough *Address `json:"sendThrough"`
StreamSetting *StreamConfig `json:"streamSettings"`
2016-11-10 17:41:28 -05:00
ProxySettings *ProxyConfig `json:"proxySettings"`
2016-10-17 08:35:13 -04:00
Settings json.RawMessage `json:"settings"`
2016-11-17 17:23:46 -05:00
Tag string `json:"tag"`
2017-04-02 15:30:21 -04:00
MuxSettings *MuxConfig `json:"mux"`
2016-10-17 08:35:13 -04:00
}
func (v *OutboundConnectionConfig) Build() (*proxyman.OutboundHandlerConfig, error) {
senderSettings := &proxyman.SenderConfig{}
2016-10-17 08:35:13 -04:00
2016-11-27 15:39:09 -05:00
if v.SendThrough != nil {
address := v.SendThrough
2016-10-17 08:35:13 -04:00
if address.Family().IsDomain() {
2017-04-09 09:04:04 -04:00
return nil, newError("invalid sendThrough address: " + address.String())
2016-10-17 08:35:13 -04:00
}
senderSettings.Via = address.Build()
2016-10-17 08:35:13 -04:00
}
2016-11-27 15:39:09 -05:00
if v.StreamSetting != nil {
ss, err := v.StreamSetting.Build()
2016-10-17 08:35:13 -04:00
if err != nil {
return nil, err
}
senderSettings.StreamSettings = ss
2016-10-17 08:35:13 -04:00
}
2016-11-27 15:39:09 -05:00
if v.ProxySettings != nil {
ps, err := v.ProxySettings.Build()
2016-11-10 17:41:28 -05:00
if err != nil {
2017-04-09 09:04:04 -04:00
return nil, newError("invalid outbound proxy settings").Base(err)
2016-11-10 17:41:28 -05:00
}
senderSettings.ProxySettings = ps
}
2017-04-02 15:30:21 -04:00
if v.MuxSettings != nil && v.MuxSettings.Enabled {
senderSettings.MultiplexSettings = &proxyman.MultiplexingConfig{
Enabled: true,
}
}
rawConfig, err := outboundConfigLoader.LoadWithID(v.Settings, v.Protocol)
if err != nil {
2017-04-09 09:04:04 -04:00
return nil, newError("failed to parse outbound config").Base(err)
2016-11-10 17:41:28 -05:00
}
ts, err := rawConfig.(Buildable).Build()
if err != nil {
return nil, err
2016-11-17 17:23:46 -05:00
}
return &proxyman.OutboundHandlerConfig{
SenderSettings: serial.ToTypedMessage(senderSettings),
ProxySettings: ts,
Tag: v.Tag,
}, nil
2016-10-17 08:35:13 -04:00
}
type InboundDetourAllocationConfig struct {
Strategy string `json:"strategy"`
Concurrency *uint32 `json:"concurrency"`
RefreshMin *uint32 `json:"refresh"`
}
func (v *InboundDetourAllocationConfig) Build() (*proxyman.AllocationStrategy, error) {
config := new(proxyman.AllocationStrategy)
2016-11-27 15:39:09 -05:00
switch strings.ToLower(v.Strategy) {
2016-10-17 08:35:13 -04:00
case "always":
config.Type = proxyman.AllocationStrategy_Always
2016-10-17 08:35:13 -04:00
case "random":
config.Type = proxyman.AllocationStrategy_Random
2016-10-17 08:35:13 -04:00
case "external":
config.Type = proxyman.AllocationStrategy_External
2016-10-17 08:35:13 -04:00
default:
2017-04-09 09:04:04 -04:00
return nil, newError("unknown allocation strategy: ", v.Strategy)
2016-10-17 08:35:13 -04:00
}
2016-11-27 15:39:09 -05:00
if v.Concurrency != nil {
config.Concurrency = &proxyman.AllocationStrategy_AllocationStrategyConcurrency{
2016-11-27 15:39:09 -05:00
Value: *v.Concurrency,
2016-10-17 08:35:13 -04:00
}
}
2016-11-27 15:39:09 -05:00
if v.RefreshMin != nil {
config.Refresh = &proxyman.AllocationStrategy_AllocationStrategyRefresh{
2016-11-27 15:39:09 -05:00
Value: *v.RefreshMin,
2016-10-17 08:35:13 -04:00
}
}
return config, nil
}
type InboundDetourConfig struct {
Protocol string `json:"protocol"`
PortRange *PortRange `json:"port"`
ListenOn *Address `json:"listen"`
Settings json.RawMessage `json:"settings"`
Tag string `json:"tag"`
Allocation *InboundDetourAllocationConfig `json:"allocate"`
StreamSetting *StreamConfig `json:"streamSettings"`
}
func (v *InboundDetourConfig) Build() (*proxyman.InboundHandlerConfig, error) {
receiverSettings := &proxyman.ReceiverConfig{}
2016-11-27 15:39:09 -05:00
if v.PortRange == nil {
2017-04-09 09:04:04 -04:00
return nil, newError("port range not specified in InboundDetour.")
2016-10-17 08:35:13 -04:00
}
receiverSettings.PortRange = v.PortRange.Build()
2016-10-17 08:35:13 -04:00
2016-11-27 15:39:09 -05:00
if v.ListenOn != nil {
if v.ListenOn.Family().IsDomain() {
2017-04-09 09:04:04 -04:00
return nil, newError("unable to listen on domain address: ", v.ListenOn.Domain())
2016-10-17 08:35:13 -04:00
}
receiverSettings.Listen = v.ListenOn.Build()
2016-10-17 08:35:13 -04:00
}
2016-11-27 15:39:09 -05:00
if v.Allocation != nil {
as, err := v.Allocation.Build()
2016-10-17 08:35:13 -04:00
if err != nil {
return nil, err
}
receiverSettings.AllocationStrategy = as
2016-10-17 08:35:13 -04:00
}
2016-11-27 15:39:09 -05:00
if v.StreamSetting != nil {
ss, err := v.StreamSetting.Build()
2016-10-17 08:35:13 -04:00
if err != nil {
return nil, err
}
receiverSettings.StreamSettings = ss
2016-10-17 08:35:13 -04:00
}
2016-11-27 15:39:09 -05:00
rawConfig, err := inboundConfigLoader.LoadWithID(v.Settings, v.Protocol)
2016-10-17 08:35:13 -04:00
if err != nil {
2017-04-09 09:04:04 -04:00
return nil, newError("failed to load inbound detour config.").Base(err)
2016-10-17 08:35:13 -04:00
}
if dokodemoConfig, ok := rawConfig.(*DokodemoConfig); ok {
receiverSettings.ReceiveOriginalDestination = dokodemoConfig.Redirect
}
2016-10-17 08:35:13 -04:00
ts, err := rawConfig.(Buildable).Build()
if err != nil {
return nil, err
}
return &proxyman.InboundHandlerConfig{
Tag: v.Tag,
ReceiverSettings: serial.ToTypedMessage(receiverSettings),
ProxySettings: ts,
}, nil
2016-10-17 08:35:13 -04:00
}
type OutboundDetourConfig struct {
Protocol string `json:"protocol"`
SendThrough *Address `json:"sendThrough"`
Tag string `json:"tag"`
Settings json.RawMessage `json:"settings"`
StreamSetting *StreamConfig `json:"streamSettings"`
2016-11-10 17:41:28 -05:00
ProxySettings *ProxyConfig `json:"proxySettings"`
2017-04-02 15:30:21 -04:00
MuxSettings *MuxConfig `json:"mux"`
2016-10-17 08:35:13 -04:00
}
func (v *OutboundDetourConfig) Build() (*proxyman.OutboundHandlerConfig, error) {
senderSettings := &proxyman.SenderConfig{}
2016-10-17 08:35:13 -04:00
2016-11-27 15:39:09 -05:00
if v.SendThrough != nil {
address := v.SendThrough
2016-10-17 08:35:13 -04:00
if address.Family().IsDomain() {
2017-04-09 09:04:04 -04:00
return nil, newError("unable to send through: " + address.String())
2016-10-17 08:35:13 -04:00
}
senderSettings.Via = address.Build()
2016-10-17 08:35:13 -04:00
}
2016-11-27 15:39:09 -05:00
if v.StreamSetting != nil {
ss, err := v.StreamSetting.Build()
2016-10-17 08:35:13 -04:00
if err != nil {
return nil, err
}
senderSettings.StreamSettings = ss
}
if v.ProxySettings != nil {
ps, err := v.ProxySettings.Build()
if err != nil {
2017-04-09 09:04:04 -04:00
return nil, newError("invalid outbound detour proxy settings.").Base(err)
}
senderSettings.ProxySettings = ps
2016-10-17 08:35:13 -04:00
}
2017-04-02 15:30:21 -04:00
if v.MuxSettings != nil && v.MuxSettings.Enabled {
senderSettings.MultiplexSettings = &proxyman.MultiplexingConfig{
Enabled: true,
}
}
2016-11-27 15:39:09 -05:00
rawConfig, err := outboundConfigLoader.LoadWithID(v.Settings, v.Protocol)
2016-10-17 08:35:13 -04:00
if err != nil {
2017-04-09 09:04:04 -04:00
return nil, newError("failed to parse to outbound detour config.").Base(err)
2016-10-17 08:35:13 -04:00
}
ts, err := rawConfig.(Buildable).Build()
if err != nil {
return nil, err
}
2016-11-10 17:41:28 -05:00
return &proxyman.OutboundHandlerConfig{
SenderSettings: serial.ToTypedMessage(senderSettings),
Tag: v.Tag,
ProxySettings: ts,
}, nil
2016-10-17 08:35:13 -04:00
}
2016-10-16 08:22:21 -04:00
type Config struct {
Port uint16 `json:"port"` // Port of this Point server.
LogConfig *LogConfig `json:"log"`
2016-10-17 08:35:13 -04:00
RouterConfig *RouterConfig `json:"routing"`
DNSConfig *DnsConfig `json:"dns"`
2016-10-16 08:22:21 -04:00
InboundConfig *InboundConnectionConfig `json:"inbound"`
OutboundConfig *OutboundConnectionConfig `json:"outbound"`
2016-10-17 08:35:13 -04:00
InboundDetours []InboundDetourConfig `json:"inboundDetour"`
OutboundDetours []OutboundDetourConfig `json:"outboundDetour"`
Transport *TransportConfig `json:"transport"`
}
2016-11-27 15:39:09 -05:00
func (v *Config) Build() (*core.Config, error) {
2016-10-17 08:35:13 -04:00
config := new(core.Config)
2016-11-27 15:39:09 -05:00
if v.LogConfig != nil {
2017-02-01 15:35:40 -05:00
config.App = append(config.App, serial.ToTypedMessage(v.LogConfig.Build()))
2016-10-17 08:35:13 -04:00
}
2016-11-27 15:39:09 -05:00
if v.Transport != nil {
ts, err := v.Transport.Build()
2016-10-17 08:35:13 -04:00
if err != nil {
return nil, err
}
config.Transport = ts
}
2016-11-27 15:39:09 -05:00
if v.RouterConfig != nil {
routerConfig, err := v.RouterConfig.Build()
2016-10-17 08:35:13 -04:00
if err != nil {
return nil, err
}
2016-12-15 05:51:09 -05:00
config.App = append(config.App, serial.ToTypedMessage(routerConfig))
2016-10-17 08:35:13 -04:00
}
2016-11-27 15:39:09 -05:00
if v.DNSConfig != nil {
2016-12-15 05:51:09 -05:00
config.App = append(config.App, serial.ToTypedMessage(v.DNSConfig.Build()))
2016-10-17 08:35:13 -04:00
}
2016-11-27 15:39:09 -05:00
if v.InboundConfig == nil {
2017-04-09 09:04:04 -04:00
return nil, newError("no inbound config specified")
2016-10-17 08:35:13 -04:00
}
2016-11-27 15:39:09 -05:00
if v.InboundConfig.Port == 0 && v.Port > 0 {
v.InboundConfig.Port = v.Port
2016-10-17 08:35:13 -04:00
}
2016-11-27 15:39:09 -05:00
ic, err := v.InboundConfig.Build()
2016-10-17 08:35:13 -04:00
if err != nil {
return nil, err
}
config.Inbound = append(config.Inbound, ic)
2016-11-27 15:39:09 -05:00
for _, rawInboundConfig := range v.InboundDetours {
2016-10-17 08:35:13 -04:00
ic, err := rawInboundConfig.Build()
if err != nil {
return nil, err
}
config.Inbound = append(config.Inbound, ic)
}
2017-02-01 06:15:18 -05:00
if v.OutboundConfig == nil {
2017-04-09 09:04:04 -04:00
return nil, newError("no outbound config specified")
2017-02-01 06:15:18 -05:00
}
2016-11-27 15:39:09 -05:00
oc, err := v.OutboundConfig.Build()
2016-10-17 08:35:13 -04:00
if err != nil {
return nil, err
}
config.Outbound = append(config.Outbound, oc)
2016-11-27 15:39:09 -05:00
for _, rawOutboundConfig := range v.OutboundDetours {
2016-10-17 08:35:13 -04:00
oc, err := rawOutboundConfig.Build()
if err != nil {
return nil, err
}
config.Outbound = append(config.Outbound, oc)
}
return config, nil
}
func init() {
core.RegisterConfigLoader(core.ConfigFormat_JSON, func(input io.Reader) (*core.Config, error) {
jsonConfig := &Config{}
2016-12-14 17:51:03 -05:00
decoder := json.NewDecoder(&json_reader.Reader{
Reader: input,
})
2016-10-17 08:35:13 -04:00
err := decoder.Decode(jsonConfig)
if err != nil {
2017-04-09 09:04:04 -04:00
return nil, newError("invalid V2Ray config").Base(err)
2016-10-17 08:35:13 -04:00
}
return jsonConfig.Build()
})
2016-10-16 08:22:21 -04:00
}