config: add PeerConfig; validate upstream and peer public keys
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Idc445352143f257020c88926a8f4759c6a6a6964
This commit is contained in:
parent
2da17e456f
commit
a8106a6c5e
1 changed files with 28 additions and 6 deletions
|
|
@ -1,9 +1,11 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
|
@ -37,7 +39,7 @@ func (d *Duration) UnmarshalYAML(value *yaml.Node) error {
|
||||||
type UpstreamConfig struct {
|
type UpstreamConfig struct {
|
||||||
URL string `yaml:"url"`
|
URL string `yaml:"url"`
|
||||||
Priority int `yaml:"priority"`
|
Priority int `yaml:"priority"`
|
||||||
PublicKey string `yaml:"public_key"`
|
PublicKey string `yaml:"public_key"` // Nix signing key "name:base64(key)"
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServerConfig struct {
|
type ServerConfig struct {
|
||||||
|
|
@ -53,10 +55,16 @@ type CacheConfig struct {
|
||||||
LatencyAlpha float64 `yaml:"latency_alpha"`
|
LatencyAlpha float64 `yaml:"latency_alpha"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mesh peer with its ed25519 public key for gossip message verification.
|
||||||
|
type PeerConfig struct {
|
||||||
|
Addr string `yaml:"addr"`
|
||||||
|
PublicKey string `yaml:"public_key"` // hex-encoded ed25519 public key (32 bytes)
|
||||||
|
}
|
||||||
|
|
||||||
type MeshConfig struct {
|
type MeshConfig struct {
|
||||||
Enabled bool `yaml:"enabled"`
|
Enabled bool `yaml:"enabled"`
|
||||||
BindAddr string `yaml:"bind_addr"`
|
BindAddr string `yaml:"bind_addr"`
|
||||||
Peers []string `yaml:"peers"`
|
Peers []PeerConfig `yaml:"peers"`
|
||||||
PrivateKeyPath string `yaml:"private_key"`
|
PrivateKeyPath string `yaml:"private_key"`
|
||||||
GossipInterval Duration `yaml:"gossip_interval"`
|
GossipInterval Duration `yaml:"gossip_interval"`
|
||||||
}
|
}
|
||||||
|
|
@ -113,6 +121,9 @@ func (c *Config) Validate() error {
|
||||||
if _, err := url.ParseRequestURI(u.URL); err != nil {
|
if _, err := url.ParseRequestURI(u.URL); err != nil {
|
||||||
return fmt.Errorf("upstream[%d]: invalid URL %q: %w", i, u.URL, err)
|
return fmt.Errorf("upstream[%d]: invalid URL %q: %w", i, u.URL, err)
|
||||||
}
|
}
|
||||||
|
if u.PublicKey != "" && !strings.Contains(u.PublicKey, ":") {
|
||||||
|
return fmt.Errorf("upstream[%d]: public_key must be in 'name:base64(key)' Nix format", i)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if c.Server.Listen == "" {
|
if c.Server.Listen == "" {
|
||||||
return fmt.Errorf("server.listen is empty")
|
return fmt.Errorf("server.listen is empty")
|
||||||
|
|
@ -129,6 +140,17 @@ func (c *Config) Validate() error {
|
||||||
if c.Mesh.Enabled && len(c.Mesh.Peers) == 0 {
|
if c.Mesh.Enabled && len(c.Mesh.Peers) == 0 {
|
||||||
return fmt.Errorf("mesh.enabled is true but no peers configured")
|
return fmt.Errorf("mesh.enabled is true but no peers configured")
|
||||||
}
|
}
|
||||||
|
for i, peer := range c.Mesh.Peers {
|
||||||
|
if peer.Addr == "" {
|
||||||
|
return fmt.Errorf("mesh.peers[%d]: addr is empty", i)
|
||||||
|
}
|
||||||
|
if peer.PublicKey != "" {
|
||||||
|
b, err := hex.DecodeString(peer.PublicKey)
|
||||||
|
if err != nil || len(b) != 32 {
|
||||||
|
return fmt.Errorf("mesh.peers[%d]: public_key must be a hex-encoded 32-byte ed25519 key", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue