diff --git a/infra/conf/v5cfg/inbound.go b/infra/conf/v5cfg/inbound.go new file mode 100644 index 000000000..4c063a4f1 --- /dev/null +++ b/infra/conf/v5cfg/inbound.go @@ -0,0 +1,75 @@ +package v5cfg + +import ( + "context" + "github.com/golang/protobuf/proto" + core "github.com/v2fly/v2ray-core/v4" + "github.com/v2fly/v2ray-core/v4/app/proxyman" + "github.com/v2fly/v2ray-core/v4/common/serial" + "github.com/v2fly/v2ray-core/v4/proxy/dokodemo" + "github.com/v2fly/v2ray-core/v4/transport/internet" +) + +func (c InboundConfig) BuildV5(ctx context.Context) (proto.Message, error) { + receiverSettings := &proxyman.ReceiverConfig{} + + if c.ListenOn == nil { + // Listen on anyip, must set PortRange + if c.PortRange == nil { + return nil, newError("Listen on AnyIP but no Port(s) set in InboundDetour.") + } + receiverSettings.PortRange = c.PortRange.Build() + } else { + // Listen on specific IP or Unix Domain Socket + receiverSettings.Listen = c.ListenOn.Build() + listenDS := c.ListenOn.Family().IsDomain() && (c.ListenOn.Domain()[0] == '/' || c.ListenOn.Domain()[0] == '@') + listenIP := c.ListenOn.Family().IsIP() || (c.ListenOn.Family().IsDomain() && c.ListenOn.Domain() == "localhost") + switch { + case listenIP: + // Listen on specific IP, must set PortRange + if c.PortRange == nil { + return nil, newError("Listen on specific ip without port in InboundDetour.") + } + // Listen on IP:Port + receiverSettings.PortRange = c.PortRange.Build() + case listenDS: + if c.PortRange != nil { + // Listen on Unix Domain Socket, PortRange should be nil + receiverSettings.PortRange = nil + } + default: + return nil, newError("unable to listen on domain address: ", c.ListenOn.Domain()) + } + } + + if c.StreamSetting != nil { + ss, err := c.StreamSetting.BuildV5(ctx) + if err != nil { + return nil, err + } + receiverSettings.StreamSettings = ss.(*internet.StreamConfig) + } + + if c.SniffingConfig != nil { + s, err := c.SniffingConfig.Build() + if err != nil { + return nil, newError("failed to build sniffing config").Base(err) + } + receiverSettings.SniffingSettings = s + } + + inboundConfigPack, err := loadHeterogeneousConfigFromRawJson("inbound", c.Protocol, c.Settings) + if err != nil { + return nil, newError("unable to load inbound protocol config").Base(err) + } + + if content, ok := inboundConfigPack.(*dokodemo.Config); ok { + receiverSettings.ReceiveOriginalDestination = content.FollowRedirect + } + + return &core.InboundHandlerConfig{ + Tag: c.Tag, + ReceiverSettings: serial.ToTypedMessage(receiverSettings), + ProxySettings: serial.ToTypedMessage(inboundConfigPack), + }, nil +} diff --git a/infra/conf/v5cfg/skeleton.go b/infra/conf/v5cfg/skeleton.go index ebda68202..6059b1585 100644 --- a/infra/conf/v5cfg/skeleton.go +++ b/infra/conf/v5cfg/skeleton.go @@ -25,9 +25,8 @@ type InboundConfig struct { Protocol string `json:"protocol"` PortRange *cfgcommon.PortRange `json:"port"` ListenOn *cfgcommon.Address `json:"listen"` - Settings *json.RawMessage `json:"settings"` + Settings json.RawMessage `json:"settings"` Tag string `json:"tag"` - DomainOverride *cfgcommon.StringList `json:"domainOverride"` SniffingConfig *sniffer.SniffingConfig `json:"sniffing"` StreamSetting *StreamConfig `json:"streamSettings"` }