diff --git a/irc/client.go b/irc/client.go index d0deb063..62ce70c3 100644 --- a/irc/client.go +++ b/irc/client.go @@ -80,6 +80,7 @@ type Client struct { hostname string invitedTo map[string]channelInvite isSTSOnly bool + isKlined bool // #1941: k-line kills are special-cased to suppress some triggered notices/events languages []string lastActive time.Time // last time they sent a command that wasn't PONG or similar lastSeen map[string]time.Time // maps device ID (including "") to time of last received command @@ -1181,6 +1182,7 @@ func (client *Client) destroy(session *Session) { details := client.detailsNoMutex() sessionRemoved := false registered := client.registered + isKlined := client.isKlined // XXX a temporary (reattaching) client can be marked alwaysOn when it logs in, // but then the session attaches to another client and we need to clean it up here alwaysOn := registered && client.alwaysOn @@ -1341,8 +1343,10 @@ func (client *Client) destroy(session *Session) { } if registered { - client.server.snomasks.Send(sno.LocalQuits, fmt.Sprintf(ircfmt.Unescape("%s$r exited the network"), details.nick)) - client.server.logger.Info("quit", fmt.Sprintf("%s is no longer on the server", details.nick)) + if !isKlined { + client.server.snomasks.Send(sno.LocalQuits, fmt.Sprintf(ircfmt.Unescape("%s$r exited the network"), details.nick)) + client.server.logger.Info("quit", fmt.Sprintf("%s is no longer on the server", details.nick)) + } } } diff --git a/irc/getters.go b/irc/getters.go index 761ece18..c50d8ab4 100644 --- a/irc/getters.go +++ b/irc/getters.go @@ -550,6 +550,12 @@ func (client *Client) shouldFlushTimestamps() (result bool) { return } +func (client *Client) setKlined() { + client.stateMutex.Lock() + client.isKlined = true + client.stateMutex.Unlock() +} + func (channel *Channel) Name() string { channel.stateMutex.RLock() defer channel.stateMutex.RUnlock() diff --git a/irc/server.go b/irc/server.go index 955a9337..c2c63161 100644 --- a/irc/server.go +++ b/irc/server.go @@ -373,7 +373,9 @@ func (server *Server) tryRegister(c *Client, session *Session) (exiting bool) { if !session.IP().IsLoopback() || session.isTor { isBanned, info := server.klines.CheckMasks(c.AllNickmasks()...) if isBanned { + c.setKlined() c.Quit(info.BanMessage(c.t("You are banned from this server (%s)")), nil) + server.logger.Info("connect", "Client rejected by k-line", c.NickMaskString()) return true } }