-
-
Notifications
You must be signed in to change notification settings - Fork 58
/
config.go
164 lines (142 loc) · 5.34 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package stunner
import (
"context"
"encoding/base64"
"fmt"
"strings"
"github.com/pion/transport/v3"
"github.com/l7mp/stunner/internal/resolver"
stnrv1 "github.com/l7mp/stunner/pkg/apis/v1"
"github.com/l7mp/stunner/pkg/config/client"
)
// Options defines various options for the STUNner server.
type Options struct {
// Name is the identifier of this stunnerd daemon instance. Defaults to hostname.
Name string
// DryRun suppresses sideeffects: STUNner will not initialize listener sockets and bring up
// the TURN server, and it will not fire up the health-check and the metrics
// servers. Intended for testing, default is false.
DryRun bool
// SuppressRollback controls whether to rollback to the last working configuration after a
// failed reconciliation request. Default is false, which means to always do a rollback.
SuppressRollback bool
// LogLevel specifies the required loglevel for STUNner and each of its sub-objects, e.g.,
// "all:TRACE" will force maximal loglevel throughout, "all:ERROR,auth:TRACE,turn:DEBUG"
// will suppress all logs except in the authentication subsystem and the TURN protocol
// logic.
LogLevel string
// Resolver swaps the internal DNS resolver with a custom implementation. Intended for
// testing.
Resolver resolver.DnsResolver
// UDPListenerThreadNum determines the number of readloop threads spawned per UDP listener
// (default is 4, must be >0 integer). TURN allocations will be automatically load-balanced
// by the kernel UDP stack based on the client 5-tuple. This setting controls the maximum
// number of CPU cores UDP listeners can scale to. Note that all other listener protocol
// types (TCP, TLS and DTLS) use per-client threads, so this setting affects only UDP
// listeners. For more info see https://github.com/pion/turn/pull/295.
UDPListenerThreadNum int
// VNet will switch on testing mode, using a vnet.Net instance to run STUNner over an
// emulated data-plane.
Net transport.Net
}
// NewDefaultConfig builds a default configuration from a TURN server URI. Example: the URI
// `turn://user:pass@127.0.0.1:3478?transport=udp` will be parsed into a STUNner configuration with
// a server running on the localhost at UDP port 3478, with plain-text authentication using the
// username/password pair `user:pass`. Health-checks and metric scarping are disabled.
func NewDefaultConfig(uri string) (*stnrv1.StunnerConfig, error) {
u, err := ParseUri(uri)
if err != nil {
return nil, fmt.Errorf("Invalid URI '%s': %s", uri, err)
}
if u.Username == "" || u.Password == "" {
return nil, fmt.Errorf("Username/password must be set: '%s'", uri)
}
h := ""
c := &stnrv1.StunnerConfig{
ApiVersion: stnrv1.ApiVersion,
Admin: stnrv1.AdminConfig{
LogLevel: stnrv1.DefaultLogLevel,
// MetricsEndpoint: "http://:8088",
HealthCheckEndpoint: &h,
},
Auth: stnrv1.AuthConfig{
Type: "plaintext",
Realm: stnrv1.DefaultRealm,
Credentials: map[string]string{
"username": u.Username,
"password": u.Password,
},
},
Listeners: []stnrv1.ListenerConfig{{
Name: "default-listener",
Protocol: u.Protocol,
Addr: u.Address,
Port: u.Port,
Routes: []string{"allow-any"},
}},
Clusters: []stnrv1.ClusterConfig{{
Name: "allow-any",
Type: "STATIC",
Endpoints: []string{"0.0.0.0/0"},
}},
}
p := strings.ToUpper(u.Protocol)
if p == "TLS" || p == "DTLS" || p == "TURN-TLS" || p == "TURN-DTLS" {
certPem, keyPem, err := GenerateSelfSignedKey()
if err != nil {
return nil, err
}
c.Listeners[0].Cert = base64.StdEncoding.EncodeToString(certPem)
c.Listeners[0].Key = base64.StdEncoding.EncodeToString(keyPem)
}
if err := c.Validate(); err != nil {
return nil, err
}
return c, nil
}
// GetConfig returns the configuration of the running STUNner daemon.
func (s *Stunner) GetConfig() *stnrv1.StunnerConfig {
s.log.Tracef("GetConfig")
// singletons, but we want to avoid panics when GetConfig is called on an uninitialized
// STUNner object
adminConf := stnrv1.AdminConfig{}
if len(s.adminManager.Keys()) > 0 {
adminConf = *s.GetAdmin().GetConfig().(*stnrv1.AdminConfig)
}
authConf := stnrv1.AuthConfig{}
if len(s.authManager.Keys()) > 0 {
authConf = *s.GetAuth().GetConfig().(*stnrv1.AuthConfig)
}
listeners := s.listenerManager.Keys()
clusters := s.clusterManager.Keys()
c := stnrv1.StunnerConfig{
ApiVersion: s.version,
Admin: adminConf,
Auth: authConf,
Listeners: make([]stnrv1.ListenerConfig, len(listeners)),
Clusters: make([]stnrv1.ClusterConfig, len(clusters)),
}
for i, name := range listeners {
c.Listeners[i] = *s.GetListener(name).GetConfig().(*stnrv1.ListenerConfig)
}
for i, name := range clusters {
c.Clusters[i] = *s.GetCluster(name).GetConfig().(*stnrv1.ClusterConfig)
}
return &c
}
// LoadConfig loads a configuration from an origin. This is a shim wrapper around ConfigOrigin.Load.
func (s *Stunner) LoadConfig(origin string) (*stnrv1.StunnerConfig, error) {
client, err := client.New(origin, s.name, s.logger)
if err != nil {
return nil, err
}
return client.Load()
}
// WatchConfig watches a configuration from an origin. This is a shim wrapper around ConfigOrigin.Watch.
func (s *Stunner) WatchConfig(ctx context.Context, origin string, ch chan<- *stnrv1.StunnerConfig) error {
client, err := client.New(origin, s.name, s.logger)
if err != nil {
return err
}
return client.Watch(ctx, ch)
}