Merge pull request #840 from slingamn/issue812_again

fix 3 separate bugs contributing to #812
This commit is contained in:
Shivaram Lingamneni 2020-03-02 01:04:01 -08:00 committed by GitHub
commit fecd8203d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 24 additions and 16 deletions

View File

@ -1152,6 +1152,7 @@ func (am *AccountManager) Unregister(account string) error {
} }
for _, client := range clients { for _, client := range clients {
if config.Accounts.RequireSasl.Enabled { if config.Accounts.RequireSasl.Enabled {
client.Logout()
client.Quit(client.t("You are no longer authorized to be on this server"), nil) client.Quit(client.t("You are no longer authorized to be on this server"), nil)
// destroy acquires a semaphore so we can't call it while holding a lock // destroy acquires a semaphore so we can't call it while holding a lock
go client.destroy(nil) go client.destroy(nil)

View File

@ -359,7 +359,7 @@ func (channel *Channel) Transfer(client *Client, target string, hasPrivs bool) (
status = channelTransferFailed status = channelTransferFailed
defer func() { defer func() {
if status == channelTransferComplete && err == nil { if status == channelTransferComplete && err == nil {
channel.Store(IncludeAllChannelAttrs) channel.Store(IncludeAllAttrs)
} }
}() }()
@ -400,7 +400,7 @@ func (channel *Channel) transferOwnership(newOwner string) {
func (channel *Channel) AcceptTransfer(client *Client) (err error) { func (channel *Channel) AcceptTransfer(client *Client) (err error) {
defer func() { defer func() {
if err == nil { if err == nil {
channel.Store(IncludeAllChannelAttrs) channel.Store(IncludeAllAttrs)
} }
}() }()
@ -720,7 +720,7 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
channel.AddHistoryItem(histItem) channel.AddHistoryItem(histItem)
} }
client.addChannel(channel) client.addChannel(channel, rb == nil)
if rb == nil { if rb == nil {
return return

View File

@ -198,7 +198,7 @@ func (cm *ChannelManager) SetRegistered(channelName string, account string) (err
defer func() { defer func() {
if err == nil && channel != nil { if err == nil && channel != nil {
// registration was successful: make the database reflect it // registration was successful: make the database reflect it
err = channel.Store(IncludeAllChannelAttrs) err = channel.Store(IncludeAllAttrs)
} }
}() }()
@ -272,7 +272,7 @@ func (cm *ChannelManager) Rename(name string, newName string) (err error) {
var info RegisteredChannel var info RegisteredChannel
defer func() { defer func() {
if channel != nil && info.Founder != "" { if channel != nil && info.Founder != "" {
channel.Store(IncludeAllChannelAttrs) channel.Store(IncludeAllAttrs)
// we just flushed the channel under its new name, therefore this delete // we just flushed the channel under its new name, therefore this delete
// cannot be overwritten by a write to the old name: // cannot be overwritten by a write to the old name:
cm.server.channelRegistry.Delete(info) cm.server.channelRegistry.Delete(info)

View File

@ -70,7 +70,7 @@ const (
// this is an OR of all possible flags // this is an OR of all possible flags
const ( const (
IncludeAllChannelAttrs = ^uint(0) IncludeAllAttrs = ^uint(0)
) )
// RegisteredChannel holds details about a given registered channel. // RegisteredChannel holds details about a given registered channel.

View File

@ -263,6 +263,7 @@ func (server *Server) RunClient(conn clientConn, proxyLine string) {
nickCasefolded: "*", nickCasefolded: "*",
nickMaskString: "*", // * is used until actual nick is given nickMaskString: "*", // * is used until actual nick is given
} }
client.writerSemaphore.Initialize(1)
client.history.Initialize(config.History.ClientLength, config.History.AutoresizeWindow) client.history.Initialize(config.History.ClientLength, config.History.AutoresizeWindow)
client.brbTimer.Initialize(client) client.brbTimer.Initialize(client)
session := &Session{ session := &Session{
@ -307,16 +308,16 @@ func (server *Server) RunClient(conn clientConn, proxyLine string) {
client.run(session, proxyLine) client.run(session, proxyLine)
} }
func (server *Server) AddAlwaysOnClient(account ClientAccount, chnames []string, lastActive time.Time) { func (server *Server) AddAlwaysOnClient(account ClientAccount, chnames []string, lastSeen time.Time) {
now := time.Now().UTC() now := time.Now().UTC()
config := server.Config() config := server.Config()
if lastActive.IsZero() { if lastSeen.IsZero() {
lastActive = now lastSeen = now
} }
client := &Client{ client := &Client{
lastSeen: now, lastSeen: lastSeen,
lastActive: lastActive, lastActive: now,
channels: make(ChannelSet), channels: make(ChannelSet),
ctime: now, ctime: now,
languages: server.Languages().Default(), languages: server.Languages().Default(),
@ -1496,13 +1497,15 @@ func (session *Session) Notice(text string) {
session.Send(nil, session.client.server.name, "NOTICE", session.client.Nick(), text) session.Send(nil, session.client.server.name, "NOTICE", session.client.Nick(), text)
} }
func (client *Client) addChannel(channel *Channel) { // `simulated` is for the fake join of an always-on client
// (we just read the channel name from the database, there's no need to write it back)
func (client *Client) addChannel(channel *Channel, simulated bool) {
client.stateMutex.Lock() client.stateMutex.Lock()
client.channels[channel] = true client.channels[channel] = true
alwaysOn := client.alwaysOn alwaysOn := client.alwaysOn
client.stateMutex.Unlock() client.stateMutex.Unlock()
if alwaysOn { if alwaysOn && !simulated {
client.markDirty(IncludeChannels) client.markDirty(IncludeChannels)
} }
} }
@ -1621,6 +1624,7 @@ func (client *Client) performWrite() {
dirtyBits := client.dirtyBits dirtyBits := client.dirtyBits
client.dirtyBits = 0 client.dirtyBits = 0
account := client.account account := client.account
lastSeen := client.lastSeen
client.stateMutex.Unlock() client.stateMutex.Unlock()
if account == "" { if account == "" {
@ -1637,9 +1641,6 @@ func (client *Client) performWrite() {
client.server.accounts.saveChannels(account, channelNames) client.server.accounts.saveChannels(account, channelNames)
} }
if (dirtyBits & IncludeLastSeen) != 0 { if (dirtyBits & IncludeLastSeen) != 0 {
client.stateMutex.RLock()
lastSeen := client.lastSeen
client.stateMutex.RUnlock()
client.server.accounts.saveLastSeen(account, lastSeen) client.server.accounts.saveLastSeen(account, lastSeen)
} }
} }

View File

@ -321,13 +321,19 @@ func (client *Client) AccountSettings() (result AccountSettings) {
} }
func (client *Client) SetAccountSettings(settings AccountSettings) { func (client *Client) SetAccountSettings(settings AccountSettings) {
// we mark dirty if the client is transitioning to always-on
markDirty := false
alwaysOn := persistenceEnabled(client.server.Config().Accounts.Multiclient.AlwaysOn, settings.AlwaysOn) alwaysOn := persistenceEnabled(client.server.Config().Accounts.Multiclient.AlwaysOn, settings.AlwaysOn)
client.stateMutex.Lock() client.stateMutex.Lock()
client.accountSettings = settings client.accountSettings = settings
if client.registered { if client.registered {
markDirty = !client.alwaysOn && alwaysOn
client.alwaysOn = alwaysOn client.alwaysOn = alwaysOn
} }
client.stateMutex.Unlock() client.stateMutex.Unlock()
if markDirty {
client.markDirty(IncludeAllAttrs)
}
} }
func (client *Client) Languages() (languages []string) { func (client *Client) Languages() (languages []string) {