aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHimbeerserverDE <himbeerserverde@gmail.com>2022-05-02 21:57:38 +0200
committerHimbeerserverDE <himbeerserverde@gmail.com>2022-05-02 21:57:38 +0200
commitce203b8f18424ef17710c7b9795e8c65aef32ea6 (patch)
treee73aa2ba3ed7b9fea9a3f1c3ff06f4b0bde75ee2
parentc32739ab924021009338f27833fda7f67d660979 (diff)
Store servers in a map
Closes #100
-rw-r--r--config.go120
-rw-r--r--connect.go4
-rw-r--r--content.go4
-rw-r--r--hop.go4
-rw-r--r--run.go20
5 files changed, 87 insertions, 65 deletions
diff --git a/config.go b/config.go
index c3f8dfd..6a02f26 100644
--- a/config.go
+++ b/config.go
@@ -24,7 +24,6 @@ var configMu sync.RWMutex
var loadConfigOnce sync.Once
type Server struct {
- Name string
Addr string
MediaPool string
Fallbacks []string
@@ -44,7 +43,7 @@ type Config struct {
NoTelnet bool
TelnetAddr string
BindAddr string
- Servers []Server
+ Servers map[string]Server
ForceDefaultSrv bool
FallbackServers []string
CSMRF struct {
@@ -92,16 +91,17 @@ func Conf() Config {
}
// PoolServers returns all media pools and their member servers.
-func PoolServers() map[string][]Server {
- var srvs = make(map[string][]Server)
- conf := Conf()
+func PoolServers() map[string]map[string]Server {
+ pools := make(map[string]map[string]Server)
+ for name, srv := range Conf().Servers {
+ if pools[srv.MediaPool] == nil {
+ pools[srv.MediaPool] = make(map[string]Server)
+ }
- // map all to.. map of slices
- for _, srv := range conf.Servers {
- srvs[srv.MediaPool] = append(srvs[srv.MediaPool], srv)
+ pools[srv.MediaPool][name] = srv
}
- return srvs
+ return pools
}
// AddServer dynamically configures a new Server at runtime.
@@ -110,16 +110,14 @@ func PoolServers() map[string][]Server {
// The server must be part of a media pool with at least one
// other member. At least one of the other members always
// needs to be reachable.
-func AddServer(s Server) bool {
+func AddServer(name string, s Server) bool {
configMu.Lock()
defer configMu.Unlock()
s.dynamic = true
- for _, srv := range config.Servers {
- if srv.Name == s.Name {
- return false
- }
+ if _, ok := config.Servers[name]; ok {
+ return false
}
var poolMembers bool
@@ -133,7 +131,7 @@ func AddServer(s Server) bool {
return false
}
- config.Servers = append(config.Servers, s)
+ config.Servers[name] = s
return true
}
@@ -144,52 +142,70 @@ func RmServer(name string) bool {
configMu.Lock()
defer configMu.Unlock()
- for i, srv := range config.Servers {
- if srv.Name == name {
- if srv.dynamic {
- return false
- }
+ s, ok := config.Servers[name]
+ if !ok {
+ return true
+ }
- // Can't remove server if players are connected to it
- for cc := range Clts() {
- if cc.ServerName() == name {
- return false
- }
- }
+ if !s.dynamic {
+ return false
+ }
- config.Servers = append(config.Servers[:i], config.Servers[1+i:]...)
- return true
+ // Can't remove server if players are connected to it
+ for cc := range Clts() {
+ if cc.ServerName() == name {
+ return false
}
}
+ delete(config.Servers, name)
return true
}
+func (cnf Config) defaultSrvInfo() (string, Server) {
+ for name, srv := range Conf().Servers {
+ return name, srv
+ }
+
+ // No servers are configured.
+ return "", Server{}
+}
+
+// DefaultSrvName returns the name of the default server.
+// If no servers exist it returns an empty string.
+func (cnf Config) DefaultSrvName() string {
+ name, _ := cnf.defaultSrvInfo()
+ return name
+}
+
+// DefaultSrv returns information about the default server.
+// If no servers exist the returned struct will be uninitialized.
+// This is a faster shortcut for Config.Servers[Config.DefaultSrvName].
+// You should thus only use this method.
+func (cnf Config) DefaultSrv() Server {
+ _, srv := cnf.defaultSrvInfo()
+ return srv
+}
+
// FallbackServers returns a slice of server names that
// a server can fall back to.
func FallbackServers(server string) []string {
- configMu.RLock()
- defer configMu.RUnlock()
-
- fallbacks := make([]string, 0)
-
conf := Conf()
- // find server
- for _, srv := range conf.Servers {
- if srv.Name == server {
- fallbacks = append(fallbacks, srv.Fallbacks...)
- break
- }
+ srv, ok := conf.Servers[server]
+ if !ok {
+ return nil
}
+ fallbacks := srv.Fallbacks
+
// global fallbacks
if len(conf.FallbackServers) == 0 {
if len(conf.Servers) == 0 {
return fallbacks
}
- return append(fallbacks, conf.Servers[0].Name)
+ return append(fallbacks, conf.DefaultSrvName())
} else {
return append(fallbacks, conf.FallbackServers...)
}
@@ -235,35 +251,37 @@ func LoadConfig() error {
// Dynamic servers shouldn't be deleted silently.
DynLoop:
- for _, srv := range oldConf.Servers {
+ for name, srv := range oldConf.Servers {
if srv.dynamic {
- config.Servers = append(config.Servers, srv)
+ config.Servers[name] = srv
} else {
- for _, s := range config.Servers {
- if srv.Name == s.Name {
+ for name2 := range config.Servers {
+ if name == name2 {
continue DynLoop
}
}
for cc := range Clts() {
- if cc.ServerName() == srv.Name {
+ if cc.ServerName() == name {
config = oldConf
- return fmt.Errorf("can't delete server %s with players", srv.Name)
+ return fmt.Errorf("can't delete server %s with players", name)
}
}
}
}
- for i, srv := range config.Servers {
- for _, s := range config.Servers {
- if srv.Name == s.Name {
+ for name, srv := range config.Servers {
+ for name2 := range config.Servers {
+ if name == name2 {
config = oldConf
- return fmt.Errorf("duplicate server %s", s.Name)
+ return fmt.Errorf("duplicate server %s", name2)
}
}
if srv.MediaPool == "" {
- config.Servers[i].MediaPool = srv.Name
+ s := config.Servers[name]
+ s.MediaPool = name
+ config.Servers[name] = s
}
}
diff --git a/connect.go b/connect.go
index 746caa7..0a73929 100644
--- a/connect.go
+++ b/connect.go
@@ -18,8 +18,8 @@ func connect(conn net.Conn, name string, cc *ClientConn) *ServerConn {
cc.mu.RUnlock()
var mediaPool string
- for _, srv := range Conf().Servers {
- if srv.Name == name {
+ for srvName, srv := range Conf().Servers {
+ if srvName == name {
mediaPool = srv.MediaPool
}
}
diff --git a/content.go b/content.go
index 9c1c146..33998d5 100644
--- a/content.go
+++ b/content.go
@@ -501,7 +501,7 @@ PoolLoop:
for _, pool := range PoolServers() {
var addr *net.UDPAddr
- for _, srv := range pool {
+ for name, srv := range pool {
addr, err = net.ResolveUDPAddr("udp", srv.Addr)
if err != nil {
continue
@@ -514,7 +514,7 @@ PoolLoop:
}
var cc *contentConn
- cc, err = connectContent(conn, srv.Name, userName, srv.MediaPool)
+ cc, err = connectContent(conn, name, userName, srv.MediaPool)
if err != nil {
continue
}
diff --git a/hop.go b/hop.go
index 7dc56b6..ffff511 100644
--- a/hop.go
+++ b/hop.go
@@ -24,8 +24,8 @@ func (cc *ClientConn) Hop(serverName string) error {
}
var strAddr string
- for _, srv := range Conf().Servers {
- if srv.Name == serverName {
+ for name, srv := range Conf().Servers {
+ if name == serverName {
strAddr = srv.Addr
break
}
diff --git a/run.go b/run.go
index f7c1d72..794a299 100644
--- a/run.go
+++ b/run.go
@@ -100,19 +100,23 @@ func runFunc() {
<-cc.Init()
cc.Log("<->", "handshake completed")
- srvs := Conf().Servers
- if len(srvs) == 0 {
+ conf := Conf()
+ if len(conf.Servers) == 0 {
cc.Log("<-", "no servers")
cc.Kick("No servers are configured.")
return
}
- srv := srvs[0]
+ srv := conf.DefaultSrv()
+ srvName := conf.DefaultSrvName()
+
lastSrv, err := authIface.LastSrv(cc.Name())
- if err == nil && !Conf().ForceDefaultSrv && lastSrv != srv.Name {
- for _, v := range srvs {
- if v.Name == lastSrv {
- srv = v
+ if err == nil && !Conf().ForceDefaultSrv && lastSrv != srvName {
+ for name, s := range conf.Servers {
+ if name == lastSrv {
+ srv = s
+ srvName = name
+
break
}
}
@@ -132,7 +136,7 @@ func runFunc() {
return
}
- connect(conn, srv.Name, cc)
+ connect(conn, srvName, cc)
}()
}