• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stillya / wg-relay / 17277209982

27 Aug 2025 07:52PM UTC coverage: 13.246% (+8.4%) from 4.874%
17277209982

Pull #3

github

stillya
added prom integration
Pull Request #3: Added metrics support

78 of 293 new or added lines in 11 files covered. (26.62%)

5 existing lines in 4 files now uncovered.

111 of 838 relevant lines covered (13.25%)

0.14 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/pkg/dataplane/config/config.go
1
package config
2

3
import (
4
        "net"
5
        "os"
6
        "time"
7

8
        "github.com/pkg/errors"
9
        "gopkg.in/yaml.v3"
10
)
11

12
// Config represents the dataplane configuration
13
type Config struct {
14
        Daemon     DaemonConfig     `yaml:"daemon"`     // Daemon configuration
15
        Proxy      ProxyConfig      `yaml:"proxy"`      // Proxy configuration
16
        Monitoring MonitoringConfig `yaml:"monitoring"` // Monitoring configuration
17
}
18

19
// DaemonConfig represents daemon-specific configuration
20
type DaemonConfig struct {
21
        Listen string `yaml:"listen"` // Address and port for daemon to bind to
22
}
23

24
// ProxyConfig represents proxy-specific configuration
25
type ProxyConfig struct {
26
        Enabled    bool          `yaml:"enabled"`     // Enable/disable obfuscation
27
        Mode       string        `yaml:"mode"`        // "forward" or "reverse"
28
        Method     string        `yaml:"method"`      // "xor" or "none"
29
        Key        string        `yaml:"key"`         // Obfuscation key (string)
30
        Interfaces []string      `yaml:"interfaces"`  // Network interfaces to attach to
31
        DriverMode string        `yaml:"driver_mode"` // "driver" or "generic" for XDP mode
32
        Forward    ForwardConfig `yaml:"forward"`     // Forward proxy configuration
33
}
34

35
// ForwardConfig represents forward proxy configuration (forward mode)
36
type ForwardConfig struct {
37
        TargetServerIP string `yaml:"target_server_ip"` // Target WireGuard server IP
38
}
39

40
// MonitoringConfig represents monitoring configuration
41
type MonitoringConfig struct {
42
        Prometheus PrometheusConfig `yaml:"prometheus"` // Prometheus HTTP exporter
43
        Statistics StatisticsConfig `yaml:"statistics"` // vnstat-style console output
44
}
45

46
// PrometheusConfig represents Prometheus monitoring configuration
47
type PrometheusConfig struct {
48
        Enabled bool   `yaml:"enabled"` // Enable/disable Prometheus metrics server
49
        Listen  string `yaml:"listen"`  // Address and port for metrics server
50
}
51

52
// StatisticsConfig represents statistics monitoring configuration
53
type StatisticsConfig struct {
54
        Enabled  bool          `yaml:"enabled"`  // Enable/disable statistics display
55
        Interval time.Duration `yaml:"interval"` // Statistics update interval
56
}
57

58
// ObfuscationMethod represents the obfuscation method
59
type ObfuscationMethod uint32
60

61
const (
62
        MethodNone ObfuscationMethod = 0
63
        MethodXOR  ObfuscationMethod = 1
64
)
65

66
// MaxKeySize defines the maximum key size for obfuscation
67
const MaxKeySize = 32
68

69
// validate validates the dataplane configuration
70
func (cfg *Config) validate() error {
×
71
        // Validate mode
×
NEW
72
        if cfg.Proxy.Mode != "forward" && cfg.Proxy.Mode != "reverse" {
×
73
                return errors.New("mode must be 'forward' or 'reverse'")
×
74
        }
×
75

76
        // Validate proxy configuration
NEW
77
        return cfg.Proxy.validate(cfg.Proxy.Mode)
×
78
}
79

80
// validate validates the proxy configuration
NEW
81
func (cfg *ProxyConfig) validate(mode string) error {
×
82
        // Validate method
×
NEW
83
        if cfg.Method != "xor" && cfg.Method != "none" {
×
84
                return errors.New("method must be 'xor' or 'none'")
×
85
        }
×
86

87
        // Validate interfaces
NEW
88
        if len(cfg.Interfaces) == 0 {
×
89
                return errors.New("at least one interface must be specified")
×
90
        }
×
91

92
        // Validate key is required
NEW
93
        if len(cfg.Key) == 0 {
×
94
                return errors.New("key is required")
×
95
        }
×
96

97
        // Validate key length
NEW
98
        if len(cfg.Key) > MaxKeySize {
×
NEW
99
                return errors.Errorf("key too long: %d bytes, max %d", len(cfg.Key), MaxKeySize)
×
UNCOV
100
        }
×
101

102
        // Validate driver mode
NEW
103
        if cfg.DriverMode != "" && cfg.DriverMode != "driver" && cfg.DriverMode != "generic" {
×
104
                return errors.New("driver_mode must be 'driver' or 'generic'")
×
105
        }
×
106

107
        // Forward mode specific validations
108
        if mode == "forward" {
×
NEW
109
                return cfg.Forward.validate()
×
110
        }
×
111

112
        return nil
×
113
}
114

115
// validate validates the forward proxy configuration
116
func (fc *ForwardConfig) validate() error {
×
117
        if fc.TargetServerIP == "" {
×
118
                return errors.New("target_server_ip is required in forward mode")
×
119
        }
×
120

121
        // Validate target server IP
122
        targetIP := net.ParseIP(fc.TargetServerIP)
×
123
        if targetIP == nil {
×
124
                return errors.Errorf("invalid target server IP: %s", fc.TargetServerIP)
×
125
        }
×
126
        if targetIP.To4() == nil {
×
127
                return errors.Errorf("target server IP must be IPv4: %s", fc.TargetServerIP)
×
128
        }
×
129

130
        return nil
×
131
}
132

133
// GetMethod returns the obfuscation method as a constant
NEW
134
func (cfg *ProxyConfig) GetMethod() ObfuscationMethod {
×
NEW
135
        switch cfg.Method {
×
136
        case "xor":
×
137
                return MethodXOR
×
138
        default:
×
139
                return MethodNone
×
140
        }
141
}
142

143
// GetKeyBytes returns the obfuscation key as bytes
NEW
144
func (cfg *ProxyConfig) GetKeyBytes() []byte {
×
NEW
145
        return []byte(cfg.Key)
×
UNCOV
146
}
×
147

148
// GetTargetServerIP returns the target server IP as a uint32 in network byte order
NEW
149
func (cfg *ProxyConfig) GetTargetServerIP() (uint32, error) {
×
NEW
150
        if cfg.Forward.TargetServerIP == "" {
×
151
                return 0, nil
×
152
        }
×
153

NEW
154
        targetIP := net.ParseIP(cfg.Forward.TargetServerIP)
×
155
        if targetIP == nil {
×
NEW
156
                return 0, errors.Errorf("invalid target server IP: %s", cfg.Forward.TargetServerIP)
×
157
        }
×
158

159
        targetIP = targetIP.To4()
×
160
        if targetIP == nil {
×
NEW
161
                return 0, errors.Errorf("target server IP must be IPv4: %s", cfg.Forward.TargetServerIP)
×
162
        }
×
163

164
        // Convert to uint32 in network byte order
165
        return uint32(targetIP[0])<<24 | uint32(targetIP[1])<<16 | uint32(targetIP[2])<<8 | uint32(targetIP[3]), nil
×
166
}
167

168
// NewConfig creates a new dataplane configuration with defaults
169
func NewConfig() *Config {
×
170
        return &Config{
×
171
                Daemon: DaemonConfig{
×
172
                        Listen: ":8080",
×
173
                },
×
174
                Proxy: ProxyConfig{
×
NEW
175
                        Enabled:    true,
×
NEW
176
                        Mode:       "forward",
×
177
                        Method:     "xor",
×
178
                        Interfaces: []string{},
×
179
                        DriverMode: "driver",
×
180
                        Forward:    ForwardConfig{},
×
181
                },
×
NEW
182
                Monitoring: MonitoringConfig{
×
NEW
183
                        Prometheus: PrometheusConfig{
×
NEW
184
                                Enabled: false,
×
NEW
185
                                Listen:  ":9090",
×
NEW
186
                        },
×
NEW
187
                        Statistics: StatisticsConfig{
×
NEW
188
                                Enabled:  true,
×
NEW
189
                                Interval: 30 * time.Second,
×
NEW
190
                        },
×
NEW
191
                },
×
192
        }
×
193
}
×
194

195
// Load loads and validates configuration from a YAML file
196
func Load(filename string) (*Config, error) {
×
197
        data, err := os.ReadFile(filename)
×
198
        if err != nil {
×
199
                return nil, errors.Wrapf(err, "failed to read config file %s", filename)
×
200
        }
×
201

202
        cfg := NewConfig()
×
203
        if err := yaml.Unmarshal(data, cfg); err != nil {
×
204
                return nil, errors.Wrap(err, "failed to parse config file")
×
205
        }
×
206

207
        if err := cfg.validate(); err != nil {
×
208
                return nil, errors.Wrap(err, "configuration validation failed")
×
209
        }
×
210

211
        return cfg, nil
×
212
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc