parent
c32739ab92
commit
ce203b8f18
120
config.go
120
config.go
|
@ -24,7 +24,6 @@ var configMu sync.RWMutex
|
||||||
var loadConfigOnce sync.Once
|
var loadConfigOnce sync.Once
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
Name string
|
|
||||||
Addr string
|
Addr string
|
||||||
MediaPool string
|
MediaPool string
|
||||||
Fallbacks []string
|
Fallbacks []string
|
||||||
|
@ -44,7 +43,7 @@ type Config struct {
|
||||||
NoTelnet bool
|
NoTelnet bool
|
||||||
TelnetAddr string
|
TelnetAddr string
|
||||||
BindAddr string
|
BindAddr string
|
||||||
Servers []Server
|
Servers map[string]Server
|
||||||
ForceDefaultSrv bool
|
ForceDefaultSrv bool
|
||||||
FallbackServers []string
|
FallbackServers []string
|
||||||
CSMRF struct {
|
CSMRF struct {
|
||||||
|
@ -92,16 +91,17 @@ func Conf() Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PoolServers returns all media pools and their member servers.
|
// PoolServers returns all media pools and their member servers.
|
||||||
func PoolServers() map[string][]Server {
|
func PoolServers() map[string]map[string]Server {
|
||||||
var srvs = make(map[string][]Server)
|
pools := make(map[string]map[string]Server)
|
||||||
conf := Conf()
|
for name, srv := range Conf().Servers {
|
||||||
|
if pools[srv.MediaPool] == nil {
|
||||||
|
pools[srv.MediaPool] = make(map[string]Server)
|
||||||
|
}
|
||||||
|
|
||||||
// map all to.. map of slices
|
pools[srv.MediaPool][name] = srv
|
||||||
for _, srv := range conf.Servers {
|
|
||||||
srvs[srv.MediaPool] = append(srvs[srv.MediaPool], srv)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return srvs
|
return pools
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddServer dynamically configures a new Server at runtime.
|
// 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
|
// The server must be part of a media pool with at least one
|
||||||
// other member. At least one of the other members always
|
// other member. At least one of the other members always
|
||||||
// needs to be reachable.
|
// needs to be reachable.
|
||||||
func AddServer(s Server) bool {
|
func AddServer(name string, s Server) bool {
|
||||||
configMu.Lock()
|
configMu.Lock()
|
||||||
defer configMu.Unlock()
|
defer configMu.Unlock()
|
||||||
|
|
||||||
s.dynamic = true
|
s.dynamic = true
|
||||||
|
|
||||||
for _, srv := range config.Servers {
|
if _, ok := config.Servers[name]; ok {
|
||||||
if srv.Name == s.Name {
|
return false
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var poolMembers bool
|
var poolMembers bool
|
||||||
|
@ -133,7 +131,7 @@ func AddServer(s Server) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
config.Servers = append(config.Servers, s)
|
config.Servers[name] = s
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,52 +142,70 @@ func RmServer(name string) bool {
|
||||||
configMu.Lock()
|
configMu.Lock()
|
||||||
defer configMu.Unlock()
|
defer configMu.Unlock()
|
||||||
|
|
||||||
for i, srv := range config.Servers {
|
s, ok := config.Servers[name]
|
||||||
if srv.Name == name {
|
if !ok {
|
||||||
if srv.dynamic {
|
return true
|
||||||
return false
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Can't remove server if players are connected to it
|
if !s.dynamic {
|
||||||
for cc := range Clts() {
|
return false
|
||||||
if cc.ServerName() == name {
|
}
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
config.Servers = append(config.Servers[:i], config.Servers[1+i:]...)
|
// Can't remove server if players are connected to it
|
||||||
return true
|
for cc := range Clts() {
|
||||||
|
if cc.ServerName() == name {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete(config.Servers, name)
|
||||||
return true
|
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
|
// FallbackServers returns a slice of server names that
|
||||||
// a server can fall back to.
|
// a server can fall back to.
|
||||||
func FallbackServers(server string) []string {
|
func FallbackServers(server string) []string {
|
||||||
configMu.RLock()
|
|
||||||
defer configMu.RUnlock()
|
|
||||||
|
|
||||||
fallbacks := make([]string, 0)
|
|
||||||
|
|
||||||
conf := Conf()
|
conf := Conf()
|
||||||
|
|
||||||
// find server
|
srv, ok := conf.Servers[server]
|
||||||
for _, srv := range conf.Servers {
|
if !ok {
|
||||||
if srv.Name == server {
|
return nil
|
||||||
fallbacks = append(fallbacks, srv.Fallbacks...)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fallbacks := srv.Fallbacks
|
||||||
|
|
||||||
// global fallbacks
|
// global fallbacks
|
||||||
if len(conf.FallbackServers) == 0 {
|
if len(conf.FallbackServers) == 0 {
|
||||||
if len(conf.Servers) == 0 {
|
if len(conf.Servers) == 0 {
|
||||||
return fallbacks
|
return fallbacks
|
||||||
}
|
}
|
||||||
|
|
||||||
return append(fallbacks, conf.Servers[0].Name)
|
return append(fallbacks, conf.DefaultSrvName())
|
||||||
} else {
|
} else {
|
||||||
return append(fallbacks, conf.FallbackServers...)
|
return append(fallbacks, conf.FallbackServers...)
|
||||||
}
|
}
|
||||||
|
@ -235,35 +251,37 @@ func LoadConfig() error {
|
||||||
|
|
||||||
// Dynamic servers shouldn't be deleted silently.
|
// Dynamic servers shouldn't be deleted silently.
|
||||||
DynLoop:
|
DynLoop:
|
||||||
for _, srv := range oldConf.Servers {
|
for name, srv := range oldConf.Servers {
|
||||||
if srv.dynamic {
|
if srv.dynamic {
|
||||||
config.Servers = append(config.Servers, srv)
|
config.Servers[name] = srv
|
||||||
} else {
|
} else {
|
||||||
for _, s := range config.Servers {
|
for name2 := range config.Servers {
|
||||||
if srv.Name == s.Name {
|
if name == name2 {
|
||||||
continue DynLoop
|
continue DynLoop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for cc := range Clts() {
|
for cc := range Clts() {
|
||||||
if cc.ServerName() == srv.Name {
|
if cc.ServerName() == name {
|
||||||
config = oldConf
|
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 name, srv := range config.Servers {
|
||||||
for _, s := range config.Servers {
|
for name2 := range config.Servers {
|
||||||
if srv.Name == s.Name {
|
if name == name2 {
|
||||||
config = oldConf
|
config = oldConf
|
||||||
return fmt.Errorf("duplicate server %s", s.Name)
|
return fmt.Errorf("duplicate server %s", name2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if srv.MediaPool == "" {
|
if srv.MediaPool == "" {
|
||||||
config.Servers[i].MediaPool = srv.Name
|
s := config.Servers[name]
|
||||||
|
s.MediaPool = name
|
||||||
|
config.Servers[name] = s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,8 @@ func connect(conn net.Conn, name string, cc *ClientConn) *ServerConn {
|
||||||
cc.mu.RUnlock()
|
cc.mu.RUnlock()
|
||||||
|
|
||||||
var mediaPool string
|
var mediaPool string
|
||||||
for _, srv := range Conf().Servers {
|
for srvName, srv := range Conf().Servers {
|
||||||
if srv.Name == name {
|
if srvName == name {
|
||||||
mediaPool = srv.MediaPool
|
mediaPool = srv.MediaPool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -501,7 +501,7 @@ PoolLoop:
|
||||||
for _, pool := range PoolServers() {
|
for _, pool := range PoolServers() {
|
||||||
var addr *net.UDPAddr
|
var addr *net.UDPAddr
|
||||||
|
|
||||||
for _, srv := range pool {
|
for name, srv := range pool {
|
||||||
addr, err = net.ResolveUDPAddr("udp", srv.Addr)
|
addr, err = net.ResolveUDPAddr("udp", srv.Addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
|
@ -514,7 +514,7 @@ PoolLoop:
|
||||||
}
|
}
|
||||||
|
|
||||||
var cc *contentConn
|
var cc *contentConn
|
||||||
cc, err = connectContent(conn, srv.Name, userName, srv.MediaPool)
|
cc, err = connectContent(conn, name, userName, srv.MediaPool)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
4
hop.go
4
hop.go
|
@ -24,8 +24,8 @@ func (cc *ClientConn) Hop(serverName string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
var strAddr string
|
var strAddr string
|
||||||
for _, srv := range Conf().Servers {
|
for name, srv := range Conf().Servers {
|
||||||
if srv.Name == serverName {
|
if name == serverName {
|
||||||
strAddr = srv.Addr
|
strAddr = srv.Addr
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
20
run.go
20
run.go
|
@ -100,19 +100,23 @@ func runFunc() {
|
||||||
<-cc.Init()
|
<-cc.Init()
|
||||||
cc.Log("<->", "handshake completed")
|
cc.Log("<->", "handshake completed")
|
||||||
|
|
||||||
srvs := Conf().Servers
|
conf := Conf()
|
||||||
if len(srvs) == 0 {
|
if len(conf.Servers) == 0 {
|
||||||
cc.Log("<-", "no servers")
|
cc.Log("<-", "no servers")
|
||||||
cc.Kick("No servers are configured.")
|
cc.Kick("No servers are configured.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
srv := srvs[0]
|
srv := conf.DefaultSrv()
|
||||||
|
srvName := conf.DefaultSrvName()
|
||||||
|
|
||||||
lastSrv, err := authIface.LastSrv(cc.Name())
|
lastSrv, err := authIface.LastSrv(cc.Name())
|
||||||
if err == nil && !Conf().ForceDefaultSrv && lastSrv != srv.Name {
|
if err == nil && !Conf().ForceDefaultSrv && lastSrv != srvName {
|
||||||
for _, v := range srvs {
|
for name, s := range conf.Servers {
|
||||||
if v.Name == lastSrv {
|
if name == lastSrv {
|
||||||
srv = v
|
srv = s
|
||||||
|
srvName = name
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,7 +136,7 @@ func runFunc() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(conn, srv.Name, cc)
|
connect(conn, srvName, cc)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue