| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- package config
-
- import (
- "bytes"
- "encoding/json"
- "fmt"
- "net"
- "net/url"
-
- "github.com/dolonet/mtg-multi/mtglib"
- )
-
- type Optional struct {
- Enabled TypeBool `json:"enabled"`
- }
-
- type ListConfig struct {
- Optional
-
- DownloadConcurrency TypeConcurrency `json:"downloadConcurrency"`
- URLs []TypeBlocklistURI `json:"urls"`
- UpdateEach TypeDuration `json:"updateEach"`
- }
-
- type Config struct {
- Debug TypeBool `json:"debug"`
- AllowFallbackOnUnknownDC TypeBool `json:"allowFallbackOnUnknownDc"`
- Secret mtglib.Secret `json:"secret"`
- Secrets map[string]mtglib.Secret `json:"secrets"`
- BindTo TypeHostPort `json:"bindTo"`
- ProxyProtocolListener TypeBool `json:"proxyProtocolListener"`
- PreferIP TypePreferIP `json:"preferIp"`
- AutoUpdate TypeBool `json:"autoUpdate"`
- DomainFrontingPort TypePort `json:"domainFrontingPort"`
- DomainFrontingIP TypeIP `json:"domainFrontingIp"`
- DomainFrontingProxyProtocol TypeBool `json:"domainFrontingProxyProtocol"`
- TolerateTimeSkewness TypeDuration `json:"tolerateTimeSkewness"`
- Concurrency TypeConcurrency `json:"concurrency"`
- PublicIPv4 TypeIP `json:"publicIpv4"`
- PublicIPv6 TypeIP `json:"publicIpv6"`
- DomainFronting struct {
- IP TypeIP `json:"ip"`
- Port TypePort `json:"port"`
- ProxyProtocol TypeBool `json:"proxyProtocol"`
- } `json:"domainFronting"`
- Defense struct {
- AntiReplay struct {
- Optional
-
- MaxSize TypeBytes `json:"maxSize"`
- ErrorRate TypeErrorRate `json:"errorRate"`
- } `json:"antiReplay"`
- Blocklist ListConfig `json:"blocklist"`
- Allowlist ListConfig `json:"allowlist"`
- Doppelganger struct {
- URLs []TypeHttpsURL `json:"urls"`
- Repeats TypeConcurrency `json:"repeats_per_raid"`
- UpdateEach TypeDuration `json:"raid_each"`
- DRS TypeBool `json:"drs"`
- } `json:"doppelganger"`
- } `json:"defense"`
- Network struct {
- Timeout struct {
- TCP TypeDuration `json:"tcp"`
- HTTP TypeDuration `json:"http"`
- Idle TypeDuration `json:"idle"`
- } `json:"timeout"`
- DOHIP TypeIP `json:"dohIp"`
- DNS TypeDNSURI `json:"dns"`
- Proxies []TypeProxyURL `json:"proxies"`
- } `json:"network"`
- APIBindTo TypeHostPort `json:"apiBindTo"`
- Throttle struct {
- MaxConnections TypeConcurrency `json:"maxConnections"`
- CheckInterval TypeDuration `json:"checkInterval"`
- } `json:"throttle"`
- Stats struct {
- StatsD struct {
- Optional
-
- Address TypeHostPort `json:"address"`
- MetricPrefix TypeMetricPrefix `json:"metricPrefix"`
- TagFormat TypeStatsdTagFormat `json:"tagFormat"`
- } `json:"statsd"`
- Prometheus struct {
- Optional
-
- BindTo TypeHostPort `json:"bindTo"`
- HTTPPath TypeHTTPPath `json:"httpPath"`
- MetricPrefix TypeMetricPrefix `json:"metricPrefix"`
- } `json:"prometheus"`
- } `json:"stats"`
- }
-
- func (c *Config) GetConcurrency(defaultValue uint) uint {
- if concurrency := c.Concurrency.Get(0); concurrency != 0 {
- return concurrency
- }
- return c.Concurrency.Get(defaultValue)
- }
-
- func (c *Config) GetDNS() *url.URL {
- var dohURL *url.URL
-
- if dohIP := c.Network.DOHIP.Get(nil); dohIP != nil {
- dohURL, _ = url.Parse("https://" + dohIP.String())
- }
-
- return c.Network.DNS.Get(dohURL)
- }
-
- func (c *Config) GetDomainFrontingPort(defaultValue uint) uint {
- if port := c.DomainFronting.Port.Get(0); port != 0 {
- return port
- }
- return c.DomainFrontingPort.Get(defaultValue)
- }
-
- func (c *Config) GetDomainFrontingIP(defaultValue net.IP) string {
- if ip := c.DomainFronting.IP.Get(nil); ip != nil {
- return ip.String()
- }
- if ip := c.DomainFrontingIP.Get(defaultValue); ip != nil {
- return ip.String()
- }
- return ""
- }
-
- func (c *Config) GetDomainFrontingProxyProtocol(defaultValue bool) bool {
- return c.DomainFronting.ProxyProtocol.Get(false) || c.DomainFrontingProxyProtocol.Get(defaultValue)
- }
-
- func (c *Config) Validate() error {
- if len(c.Secrets) == 0 {
- if !c.Secret.Valid() {
- return fmt.Errorf("invalid secret %s", c.Secret.String())
- }
- } else {
- for name, s := range c.Secrets {
- if !s.Valid() {
- return fmt.Errorf("invalid secret %q: %s", name, s.String())
- }
- }
- }
-
- if c.BindTo.Get("") == "" {
- return fmt.Errorf("incorrect bind-to parameter %s", c.BindTo.String())
- }
-
- return nil
- }
-
- // GetSecrets returns all secrets as a map. If the new [secrets] section is used,
- // returns that map. Otherwise, wraps the single Secret as {"default": Secret}.
- func (c *Config) GetSecrets() map[string]mtglib.Secret {
- if len(c.Secrets) > 0 {
- return c.Secrets
- }
-
- return map[string]mtglib.Secret{"default": c.Secret}
- }
-
- func (c *Config) String() string {
- buf := &bytes.Buffer{}
- encoder := json.NewEncoder(buf)
-
- encoder.SetEscapeHTML(false)
-
- if err := encoder.Encode(c); err != nil {
- panic(err)
- }
-
- return buf.String()
- }
|