mirror of
https://github.com/ergochat/ergo.git
synced 2025-01-03 16:42:38 +01:00
commit
ec8b25e236
@ -65,12 +65,13 @@ func (am *AccountManager) Initialize(server *Server) {
|
|||||||
am.accountToMethod = make(map[string]NickEnforcementMethod)
|
am.accountToMethod = make(map[string]NickEnforcementMethod)
|
||||||
am.server = server
|
am.server = server
|
||||||
|
|
||||||
am.buildNickToAccountIndex()
|
config := server.Config()
|
||||||
am.initVHostRequestQueue()
|
am.buildNickToAccountIndex(config)
|
||||||
|
am.initVHostRequestQueue(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *AccountManager) buildNickToAccountIndex() {
|
func (am *AccountManager) buildNickToAccountIndex(config *Config) {
|
||||||
if !am.server.AccountConfig().NickReservation.Enabled {
|
if !config.Accounts.NickReservation.Enabled {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,8 +136,8 @@ func (am *AccountManager) buildNickToAccountIndex() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *AccountManager) initVHostRequestQueue() {
|
func (am *AccountManager) initVHostRequestQueue(config *Config) {
|
||||||
if !am.server.AccountConfig().VHosts.Enabled {
|
if !config.Accounts.VHosts.Enabled {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,14 +36,16 @@ func (cm *ChannelManager) Initialize(server *Server) {
|
|||||||
cm.chansSkeletons = make(StringSet)
|
cm.chansSkeletons = make(StringSet)
|
||||||
cm.server = server
|
cm.server = server
|
||||||
|
|
||||||
if server.Config().Channels.Registration.Enabled {
|
cm.loadRegisteredChannels(server.Config())
|
||||||
cm.loadRegisteredChannels()
|
|
||||||
}
|
|
||||||
// purging should work even if registration is disabled
|
// purging should work even if registration is disabled
|
||||||
cm.purgedChannels = cm.server.channelRegistry.PurgedChannels()
|
cm.purgedChannels = cm.server.channelRegistry.PurgedChannels()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cm *ChannelManager) loadRegisteredChannels() {
|
func (cm *ChannelManager) loadRegisteredChannels(config *Config) {
|
||||||
|
if !config.Channels.Registration.Enabled {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
rawNames := cm.server.channelRegistry.AllChannels()
|
rawNames := cm.server.channelRegistry.AllChannels()
|
||||||
registeredChannels := make(StringSet, len(rawNames))
|
registeredChannels := make(StringSet, len(rawNames))
|
||||||
registeredSkeletons := make(StringSet, len(rawNames))
|
registeredSkeletons := make(StringSet, len(rawNames))
|
||||||
|
@ -101,14 +101,7 @@ func NewHistoryBuffer(size int, window time.Duration) (result *Buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (hist *Buffer) Initialize(size int, window time.Duration) {
|
func (hist *Buffer) Initialize(size int, window time.Duration) {
|
||||||
initialSize := size
|
hist.buffer = make([]Item, hist.initialSize(size, window))
|
||||||
if window != 0 {
|
|
||||||
initialSize = initialAutoSize
|
|
||||||
if size < initialSize {
|
|
||||||
initialSize = size // min(initialAutoSize, size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hist.buffer = make([]Item, initialSize)
|
|
||||||
hist.start = -1
|
hist.start = -1
|
||||||
hist.end = -1
|
hist.end = -1
|
||||||
hist.window = window
|
hist.window = window
|
||||||
@ -118,6 +111,18 @@ func (hist *Buffer) Initialize(size int, window time.Duration) {
|
|||||||
hist.setEnabled(size)
|
hist.setEnabled(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compute the initial size for the buffer, taking into account autoresize
|
||||||
|
func (hist *Buffer) initialSize(size int, window time.Duration) (result int) {
|
||||||
|
result = size
|
||||||
|
if window != 0 {
|
||||||
|
result = initialAutoSize
|
||||||
|
if size < result {
|
||||||
|
result = size // min(initialAutoSize, size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (hist *Buffer) setEnabled(size int) {
|
func (hist *Buffer) setEnabled(size int) {
|
||||||
var enabled uint32
|
var enabled uint32
|
||||||
if size != 0 {
|
if size != 0 {
|
||||||
@ -339,12 +344,19 @@ func (list *Buffer) Resize(maximumSize int, window time.Duration) {
|
|||||||
list.maximumSize = maximumSize
|
list.maximumSize = maximumSize
|
||||||
list.window = window
|
list.window = window
|
||||||
|
|
||||||
// if we're not autoresizing, we need to resize now;
|
// three cases where we need to preemptively resize:
|
||||||
// if we are autoresizing, we may need to shrink the buffer down to maximumSize,
|
// (1) we are not autoresizing
|
||||||
// but we don't need to grow it now (we can just grow it on the next Add)
|
// (2) the buffer is currently larger than maximumSize and needs to be shrunk
|
||||||
|
// (3) the buffer is currently smaller than the recommended initial size
|
||||||
|
// (including the case where it is currently disabled and needs to be enabled)
|
||||||
// TODO make it possible to shrink the buffer so that it only contains `window`
|
// TODO make it possible to shrink the buffer so that it only contains `window`
|
||||||
if window == 0 || maximumSize < len(list.buffer) {
|
if window == 0 || maximumSize < len(list.buffer) {
|
||||||
list.resize(maximumSize)
|
list.resize(maximumSize)
|
||||||
|
} else {
|
||||||
|
initialSize := list.initialSize(maximumSize, window)
|
||||||
|
if len(list.buffer) < initialSize {
|
||||||
|
list.resize(initialSize)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,6 +213,35 @@ func TestAutoresize(t *testing.T) {
|
|||||||
assertEqual(atoi(items[len(items)-1].Nick), 271, t)
|
assertEqual(atoi(items[len(items)-1].Nick), 271, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// regression test for #702
|
||||||
|
func TestEnabledByResize(t *testing.T) {
|
||||||
|
now := easyParse("2006-01-01 00:00:00Z")
|
||||||
|
// empty/disabled autoresizing buffer
|
||||||
|
buf := NewHistoryBuffer(0, time.Hour)
|
||||||
|
// enable the buffer as during a rehash
|
||||||
|
buf.Resize(128, time.Hour)
|
||||||
|
// add an item and test that it is stored and retrievable
|
||||||
|
buf.Add(autoItem(0, now))
|
||||||
|
items := buf.Latest(0)
|
||||||
|
assertEqual(len(items), 1, t)
|
||||||
|
assertEqual(atoi(items[0].Nick), 0, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDisabledByResize(t *testing.T) {
|
||||||
|
now := easyParse("2006-01-01 00:00:00Z")
|
||||||
|
// enabled autoresizing buffer
|
||||||
|
buf := NewHistoryBuffer(128, time.Hour)
|
||||||
|
buf.Add(autoItem(0, now))
|
||||||
|
items := buf.Latest(0)
|
||||||
|
assertEqual(len(items), 1, t)
|
||||||
|
assertEqual(atoi(items[0].Nick), 0, t)
|
||||||
|
|
||||||
|
// disable as during a rehash, confirm that nothing can be retrieved
|
||||||
|
buf.Resize(0, time.Hour)
|
||||||
|
items = buf.Latest(0)
|
||||||
|
assertEqual(len(items), 0, t)
|
||||||
|
}
|
||||||
|
|
||||||
func TestRoundUp(t *testing.T) {
|
func TestRoundUp(t *testing.T) {
|
||||||
assertEqual(roundUpToPowerOfTwo(2), 2, t)
|
assertEqual(roundUpToPowerOfTwo(2), 2, t)
|
||||||
assertEqual(roundUpToPowerOfTwo(3), 4, t)
|
assertEqual(roundUpToPowerOfTwo(3), 4, t)
|
||||||
|
104
irc/server.go
104
irc/server.go
@ -611,18 +611,10 @@ func (server *Server) applyConfig(config *Config, initial bool) (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sanity checks complete, start modifying server state
|
|
||||||
server.logger.Info("server", "Using config file", server.configFilename)
|
server.logger.Info("server", "Using config file", server.configFilename)
|
||||||
oldConfig := server.Config()
|
oldConfig := server.Config()
|
||||||
|
|
||||||
// first, reload config sections for functionality implemented in subpackages:
|
// first, reload config sections for functionality implemented in subpackages:
|
||||||
|
|
||||||
server.connectionLimiter.ApplyConfig(&config.Server.IPLimits)
|
|
||||||
|
|
||||||
tlConf := &config.Server.TorListeners
|
|
||||||
server.torLimiter.Configure(tlConf.MaxConnections, tlConf.ThrottleDuration, tlConf.MaxConnectionsPerDuration)
|
|
||||||
|
|
||||||
// reload logging config
|
|
||||||
wasLoggingRawIO := !initial && server.logger.IsLoggingRawIO()
|
wasLoggingRawIO := !initial && server.logger.IsLoggingRawIO()
|
||||||
err = server.logger.ApplyConfig(config.Logging)
|
err = server.logger.ApplyConfig(config.Logging)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -632,6 +624,11 @@ func (server *Server) applyConfig(config *Config, initial bool) (err error) {
|
|||||||
// notify existing clients if raw i/o logging was enabled by a rehash
|
// notify existing clients if raw i/o logging was enabled by a rehash
|
||||||
sendRawOutputNotice := !wasLoggingRawIO && nowLoggingRawIO
|
sendRawOutputNotice := !wasLoggingRawIO && nowLoggingRawIO
|
||||||
|
|
||||||
|
server.connectionLimiter.ApplyConfig(&config.Server.IPLimits)
|
||||||
|
|
||||||
|
tlConf := &config.Server.TorListeners
|
||||||
|
server.torLimiter.Configure(tlConf.MaxConnections, tlConf.ThrottleDuration, tlConf.MaxConnectionsPerDuration)
|
||||||
|
|
||||||
// setup new and removed caps
|
// setup new and removed caps
|
||||||
addedCaps := caps.NewSet()
|
addedCaps := caps.NewSet()
|
||||||
removedCaps := caps.NewSet()
|
removedCaps := caps.NewSet()
|
||||||
@ -641,67 +638,50 @@ func (server *Server) applyConfig(config *Config, initial bool) (err error) {
|
|||||||
server.logger.Debug("server", "Regenerating HELP indexes for new languages")
|
server.logger.Debug("server", "Regenerating HELP indexes for new languages")
|
||||||
server.helpIndexManager.GenerateIndices(config.languageManager)
|
server.helpIndexManager.GenerateIndices(config.languageManager)
|
||||||
|
|
||||||
if oldConfig != nil && config.Server.capValues[caps.Languages] != oldConfig.Server.capValues[caps.Languages] {
|
|
||||||
updatedCaps.Add(caps.Languages)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SASL
|
|
||||||
authPreviouslyEnabled := oldConfig != nil && oldConfig.Accounts.AuthenticationEnabled
|
|
||||||
if config.Accounts.AuthenticationEnabled && (oldConfig == nil || !authPreviouslyEnabled) {
|
|
||||||
// enabling SASL
|
|
||||||
addedCaps.Add(caps.SASL)
|
|
||||||
} else if !config.Accounts.AuthenticationEnabled && (oldConfig == nil || authPreviouslyEnabled) {
|
|
||||||
// disabling SASL
|
|
||||||
removedCaps.Add(caps.SASL)
|
|
||||||
}
|
|
||||||
|
|
||||||
nickReservationPreviouslyDisabled := oldConfig != nil && !oldConfig.Accounts.NickReservation.Enabled
|
|
||||||
nickReservationNowEnabled := config.Accounts.NickReservation.Enabled
|
|
||||||
if nickReservationPreviouslyDisabled && nickReservationNowEnabled {
|
|
||||||
server.accounts.buildNickToAccountIndex()
|
|
||||||
}
|
|
||||||
|
|
||||||
hsPreviouslyDisabled := oldConfig != nil && !oldConfig.Accounts.VHosts.Enabled
|
|
||||||
hsNowEnabled := config.Accounts.VHosts.Enabled
|
|
||||||
if hsPreviouslyDisabled && hsNowEnabled {
|
|
||||||
server.accounts.initVHostRequestQueue()
|
|
||||||
}
|
|
||||||
|
|
||||||
chanRegPreviouslyDisabled := oldConfig != nil && !oldConfig.Channels.Registration.Enabled
|
|
||||||
chanRegNowEnabled := config.Channels.Registration.Enabled
|
|
||||||
if chanRegPreviouslyDisabled && chanRegNowEnabled {
|
|
||||||
server.channels.loadRegisteredChannels()
|
|
||||||
}
|
|
||||||
|
|
||||||
// STS
|
|
||||||
stsPreviouslyEnabled := oldConfig != nil && oldConfig.Server.STS.Enabled
|
|
||||||
stsValue := config.Server.capValues[caps.STS]
|
|
||||||
stsCurrentCapValue := ""
|
|
||||||
if oldConfig != nil {
|
if oldConfig != nil {
|
||||||
stsCurrentCapValue = oldConfig.Server.capValues[caps.STS]
|
// cap changes
|
||||||
}
|
if oldConfig.Server.capValues[caps.Languages] != config.Server.capValues[caps.Languages] {
|
||||||
server.logger.Debug("server", "STS Vals", stsCurrentCapValue, stsValue, fmt.Sprintf("server[%v] config[%v]", stsPreviouslyEnabled, config.Server.STS.Enabled))
|
updatedCaps.Add(caps.Languages)
|
||||||
if (config.Server.STS.Enabled != stsPreviouslyEnabled) || (stsValue != stsCurrentCapValue) {
|
}
|
||||||
// XXX: STS is always removed by CAP NEW sts=duration=0, not CAP DEL
|
|
||||||
// so the appropriate notify is always a CAP NEW; put it in addedCaps for any change
|
|
||||||
addedCaps.Add(caps.STS)
|
|
||||||
}
|
|
||||||
|
|
||||||
if oldConfig != nil && config.Accounts.Bouncer.Enabled != oldConfig.Accounts.Bouncer.Enabled {
|
if !oldConfig.Accounts.AuthenticationEnabled && config.Accounts.AuthenticationEnabled {
|
||||||
if config.Accounts.Bouncer.Enabled {
|
addedCaps.Add(caps.SASL)
|
||||||
|
} else if oldConfig.Accounts.AuthenticationEnabled && !config.Accounts.AuthenticationEnabled {
|
||||||
|
removedCaps.Add(caps.SASL)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !oldConfig.Accounts.Bouncer.Enabled && config.Accounts.Bouncer.Enabled {
|
||||||
addedCaps.Add(caps.Bouncer)
|
addedCaps.Add(caps.Bouncer)
|
||||||
} else {
|
} else if oldConfig.Accounts.Bouncer.Enabled && !config.Accounts.Bouncer.Enabled {
|
||||||
removedCaps.Add(caps.Bouncer)
|
removedCaps.Add(caps.Bouncer)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// resize history buffers as needed
|
if oldConfig.Server.STS.Enabled != config.Server.STS.Enabled || oldConfig.Server.capValues[caps.STS] != config.Server.capValues[caps.STS] {
|
||||||
if oldConfig != nil && oldConfig.History != config.History {
|
// XXX: STS is always removed by CAP NEW sts=duration=0, not CAP DEL
|
||||||
for _, channel := range server.channels.Channels() {
|
// so the appropriate notify is always a CAP NEW; put it in addedCaps for any change
|
||||||
channel.history.Resize(config.History.ChannelLength, config.History.AutoresizeWindow)
|
addedCaps.Add(caps.STS)
|
||||||
}
|
}
|
||||||
for _, client := range server.clients.AllClients() {
|
|
||||||
client.history.Resize(config.History.ClientLength, config.History.AutoresizeWindow)
|
// if certain features were enabled by rehash, we need to load the corresponding data
|
||||||
|
// from the store
|
||||||
|
if !oldConfig.Accounts.NickReservation.Enabled {
|
||||||
|
server.accounts.buildNickToAccountIndex(config)
|
||||||
|
}
|
||||||
|
if !oldConfig.Accounts.VHosts.Enabled {
|
||||||
|
server.accounts.initVHostRequestQueue(config)
|
||||||
|
}
|
||||||
|
if !oldConfig.Channels.Registration.Enabled {
|
||||||
|
server.channels.loadRegisteredChannels(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// resize history buffers as needed
|
||||||
|
if oldConfig.History != config.History {
|
||||||
|
for _, channel := range server.channels.Channels() {
|
||||||
|
channel.history.Resize(config.History.ChannelLength, config.History.AutoresizeWindow)
|
||||||
|
}
|
||||||
|
for _, client := range server.clients.AllClients() {
|
||||||
|
client.history.Resize(config.History.ClientLength, config.History.AutoresizeWindow)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user