mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-09-01 06:54:03 +03:00
Add new config
This commit is contained in:
@@ -0,0 +1,275 @@
|
||||
package config2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/juju/errors"
|
||||
statsd "gopkg.in/alexcesaro/statsd.v2"
|
||||
)
|
||||
|
||||
type SecretType byte
|
||||
|
||||
func (s SecretType) String() string {
|
||||
switch s {
|
||||
case SecretTypeMain:
|
||||
return "main"
|
||||
case SecretTypeSecured:
|
||||
return "secured"
|
||||
default:
|
||||
return "tls"
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
SecretTypeMain = 1 << iota
|
||||
SecretTypeSecured
|
||||
SecretTypeTLS
|
||||
)
|
||||
|
||||
const (
|
||||
FlagDebug = "debug"
|
||||
FlagVerbose = "verbose"
|
||||
|
||||
FlagBindIP = "bind-ip"
|
||||
FlagBindPort = "bind-port"
|
||||
FlagPublicIPv4 = "public-ipv4"
|
||||
FlagPublicIPv4Port = "public-ipv4-port"
|
||||
FlagPublicIPv6 = "public-ipv6"
|
||||
FlagPublicIPv6Port = "public-ipv6-port"
|
||||
FlagStatsIP = "stats-ip"
|
||||
FlagStatsPort = "stats-port"
|
||||
|
||||
FlagStatsdIP = "statsd-ip"
|
||||
FlagStatsdPort = "statsd-port"
|
||||
FlagStatsdNetwork = "statsd-network"
|
||||
FlagStatsdPrefix = "statsd-prefix"
|
||||
FlagStatsdTagsFormat = "statsd-tags-format"
|
||||
FlagStatsdTags = "statsd-tags"
|
||||
|
||||
FlagPrometheusPrefix = "prometheus-prefix"
|
||||
|
||||
FlagWriteBufferSize = "write-buffer"
|
||||
FlagReadBufferSize = "read-buffer"
|
||||
|
||||
FlagSecureOnly = "secure-only"
|
||||
|
||||
FlagAntiReplayMaxSize = "anti-replay-max-size"
|
||||
FlagAntiReplayEvictionTime = "anti-replay-eviction-time"
|
||||
|
||||
FlagSecret = "secret"
|
||||
FlagAdtag = "adtag"
|
||||
)
|
||||
|
||||
type BufferSize struct {
|
||||
Read int `json:"read"`
|
||||
Write int `json:"write"`
|
||||
}
|
||||
|
||||
type AntiReplay struct {
|
||||
MaxSize int `json:"max_size"`
|
||||
EvictionTime time.Duration `json:"duration"`
|
||||
}
|
||||
|
||||
type Stats struct {
|
||||
Prefix string `json:"prefix"`
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
type StatsdStats struct {
|
||||
Stats
|
||||
|
||||
Addr Addr `json:"addr"`
|
||||
Tags map[string]string `json:"tags"`
|
||||
TagsFormat statsd.TagFormat `json:"format"`
|
||||
}
|
||||
|
||||
type PrometheusStats struct {
|
||||
Stats
|
||||
}
|
||||
|
||||
type Addr struct {
|
||||
IP net.IP `json:"ip"`
|
||||
Port int `json:"port"`
|
||||
net string
|
||||
}
|
||||
|
||||
func (a Addr) Network() string {
|
||||
if a.net == "" {
|
||||
return "tcp"
|
||||
}
|
||||
return a.net
|
||||
}
|
||||
|
||||
func (a Addr) String() string {
|
||||
return net.JoinHostPort(a.IP.String(), strconv.Itoa(a.Port))
|
||||
}
|
||||
|
||||
func (a Addr) MarshalJSON() ([]byte, error) {
|
||||
data := map[string]string{
|
||||
"network": a.Network(),
|
||||
"addr": a.String(),
|
||||
}
|
||||
return json.Marshal(data)
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
BufferSize BufferSize `json:"buffer_size"`
|
||||
AntiReplay AntiReplay `json:"anti_replay"`
|
||||
|
||||
ListenAddr Addr `json:"listen_addr"`
|
||||
PublicIPv4Addr Addr `json:"public_ipv4_addr"`
|
||||
PublicIPv6Addr Addr `json:"public_ipv6_addr"`
|
||||
StatsAddr Addr `json:"stats_addr"`
|
||||
|
||||
StatsdStats StatsdStats `json:"stats_statsd"`
|
||||
PrometheusStats PrometheusStats `json:"stats_prometheus"`
|
||||
|
||||
Debug bool `json:"debug"`
|
||||
Verbose bool `json:"verbose"`
|
||||
SecureOnly bool `json:"secure_only"`
|
||||
SecretType SecretType `json:"secret_type"`
|
||||
Secret []byte `json:"secret"`
|
||||
AdTag []byte `json:"adtag"`
|
||||
}
|
||||
|
||||
func (c Config) String() string {
|
||||
data, _ := json.Marshal(c)
|
||||
return string(data)
|
||||
}
|
||||
|
||||
type ConfigOpt struct {
|
||||
Name string
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
var C = Config{}
|
||||
|
||||
func Init(options ...ConfigOpt) error { // nolint: gocyclo
|
||||
for _, opt := range options {
|
||||
switch opt.Name {
|
||||
case FlagDebug:
|
||||
C.Debug = opt.Value.(bool)
|
||||
case FlagVerbose:
|
||||
C.Verbose = opt.Value.(bool)
|
||||
case FlagBindIP:
|
||||
C.ListenAddr.IP = opt.Value.(net.IP)
|
||||
case FlagBindPort:
|
||||
C.ListenAddr.Port = opt.Value.(int)
|
||||
case FlagPublicIPv4:
|
||||
C.PublicIPv4Addr.IP = opt.Value.(net.IP)
|
||||
case FlagPublicIPv4Port:
|
||||
C.PublicIPv4Addr.Port = opt.Value.(int)
|
||||
case FlagPublicIPv6:
|
||||
C.PublicIPv6Addr.IP = opt.Value.(net.IP)
|
||||
case FlagPublicIPv6Port:
|
||||
C.PublicIPv6Addr.Port = opt.Value.(int)
|
||||
case FlagStatsIP:
|
||||
C.StatsAddr.IP = opt.Value.(net.IP)
|
||||
case FlagStatsPort:
|
||||
C.StatsAddr.Port = opt.Value.(int)
|
||||
case FlagStatsdIP:
|
||||
C.StatsdStats.Addr.IP = opt.Value.(net.IP)
|
||||
case FlagStatsdPort:
|
||||
C.StatsdStats.Addr.Port = opt.Value.(int)
|
||||
case FlagStatsdNetwork:
|
||||
C.StatsdStats.Addr.net = opt.Value.(string)
|
||||
case FlagStatsdPrefix:
|
||||
C.StatsdStats.Prefix = opt.Value.(string)
|
||||
case FlagStatsdTagsFormat:
|
||||
value := opt.Value.(string)
|
||||
switch value {
|
||||
case "datadog":
|
||||
C.StatsdStats.TagsFormat = statsd.Datadog
|
||||
case "influxdb":
|
||||
C.StatsdStats.TagsFormat = statsd.InfluxDB
|
||||
default:
|
||||
return errors.Errorf("Incorrect statsd tag %s", value)
|
||||
}
|
||||
case FlagStatsdTags:
|
||||
C.StatsdStats.Tags = opt.Value.(map[string]string)
|
||||
case FlagPrometheusPrefix:
|
||||
C.PrometheusStats.Prefix = opt.Value.(string)
|
||||
case FlagWriteBufferSize:
|
||||
C.BufferSize.Write = opt.Value.(int)
|
||||
case FlagReadBufferSize:
|
||||
C.BufferSize.Read = opt.Value.(int)
|
||||
case FlagAntiReplayMaxSize:
|
||||
C.AntiReplay.MaxSize = opt.Value.(int)
|
||||
case FlagAntiReplayEvictionTime:
|
||||
C.AntiReplay.EvictionTime = opt.Value.(time.Duration)
|
||||
case FlagSecureOnly:
|
||||
C.SecureOnly = opt.Value.(bool)
|
||||
case FlagSecret:
|
||||
C.Secret = opt.Value.([]byte)
|
||||
case FlagAdtag:
|
||||
C.AdTag = opt.Value.([]byte)
|
||||
}
|
||||
}
|
||||
|
||||
var defaultStatsdTags statsd.TagFormat
|
||||
if C.StatsdStats.TagsFormat == defaultStatsdTags {
|
||||
C.StatsdStats.TagsFormat = statsd.Datadog
|
||||
}
|
||||
if C.StatsdStats.Addr.net == "" {
|
||||
C.StatsdStats.Addr.net = "udp"
|
||||
}
|
||||
|
||||
switch {
|
||||
case len(C.Secret) == 17 && bytes.HasPrefix(C.Secret, []byte{0xdd}):
|
||||
C.SecretType = SecretTypeSecured
|
||||
C.Secret = bytes.TrimPrefix(C.Secret, []byte{0xdd})
|
||||
case len(C.Secret) == 16:
|
||||
C.SecretType = SecretTypeMain
|
||||
default:
|
||||
return errors.New("Incorrect secret")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func InitPublicAddress() error {
|
||||
if C.PublicIPv4Addr.Port == 0 {
|
||||
C.PublicIPv4Addr.Port = C.ListenAddr.Port
|
||||
}
|
||||
if C.PublicIPv6Addr.Port == 0 {
|
||||
C.PublicIPv6Addr.Port = C.ListenAddr.Port
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
wg := &sync.WaitGroup{}
|
||||
done := make(chan struct{})
|
||||
|
||||
if C.PublicIPv4Addr.IP == nil {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
getGlobalIPv4(ctx, cancel)
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
if C.PublicIPv6Addr.IP == nil {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
getGlobalIPv6(ctx, cancel)
|
||||
wg.Done()
|
||||
|
||||
}()
|
||||
}
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(done)
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
return nil
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user