diff --git a/CHANGELOG.md b/CHANGELOG.md index aa059872..c555c78a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ New release of Oragono! ### Added * Added operator classes, allowing for more finely-grained permissions for operators. * Added automatic client connection limiting, similar to other IRCds. +* Length of channel mode lists (ban / ban-except / invite-except) is now restricted to the limit in config. * Added support for IRCv3 capability [`chghost`](http://ircv3.net/specs/extensions/chghost-3.2.html). ### Changed diff --git a/irc/config.go b/irc/config.go index 93aedce6..0df1cf87 100644 --- a/irc/config.go +++ b/irc/config.go @@ -136,6 +136,7 @@ type Config struct { TopicLen uint `yaml:"topiclen"` WhowasEntries uint `yaml:"whowas-entries"` MonitorEntries uint `yaml:"monitor-entries"` + ChanListModes uint `yaml:"chan-list-modes"` } } diff --git a/irc/modes.go b/irc/modes.go index 9da2bf0a..aa1bdf5f 100644 --- a/irc/modes.go +++ b/irc/modes.go @@ -404,6 +404,9 @@ func cmodeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool { changes = append(changes, &change) } + // so we only output one warning for each list type when full + listFullWarned := make(map[ChannelMode]bool) + for _, change := range changes { switch change.mode { case BanMask, ExceptMask, InviteMask: @@ -428,6 +431,14 @@ func cmodeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool { switch change.op { case Add: + if len(list.masks) >= server.limits.ChanListModes { + if !listFullWarned[change.mode] { + client.Send(nil, server.name, ERR_BANLISTFULL, client.nick, channel.name, change.mode.String(), "Channel list is full") + listFullWarned[change.mode] = true + } + continue + } + list.Add(mask) applied = append(applied, change) diff --git a/irc/server.go b/irc/server.go index 91d0c385..33fe0f1d 100644 --- a/irc/server.go +++ b/irc/server.go @@ -39,6 +39,7 @@ type Limits struct { MonitorEntries int NickLen int TopicLen int + ChanListModes int } // ListenerInterface represents an interface for a listener. @@ -166,6 +167,7 @@ func NewServer(configFilename string, config *Config) *Server { MonitorEntries: int(config.Limits.MonitorEntries), NickLen: int(config.Limits.NickLen), TopicLen: int(config.Limits.TopicLen), + ChanListModes: int(config.Limits.ChanListModes), }, listeners: make(map[string]ListenerInterface), monitoring: make(map[string][]Client), @@ -266,7 +268,7 @@ func (server *Server) setISupport() { server.isupport.Add("EXCEPTS", "") server.isupport.Add("INVEX", "") server.isupport.Add("KICKLEN", strconv.Itoa(server.limits.KickLen)) - // server.isupport.Add("MAXLIST", "") //TODO(dan): Support max list length? + server.isupport.Add("MAXLIST", fmt.Sprintf("beI:%s", strconv.Itoa(server.limits.ChanListModes))) // server.isupport.Add("MODES", "") //TODO(dan): Support max modes? server.isupport.Add("MONITOR", strconv.Itoa(server.limits.MonitorEntries)) server.isupport.Add("NETWORK", server.networkName) @@ -1056,6 +1058,7 @@ func (server *Server) rehash() error { MonitorEntries: int(config.Limits.MonitorEntries), NickLen: int(config.Limits.NickLen), TopicLen: int(config.Limits.TopicLen), + ChanListModes: int(config.Limits.ChanListModes), } server.operclasses = *operclasses server.operators = opers diff --git a/oragono.yaml b/oragono.yaml index 0842d02f..107fc6e6 100644 --- a/oragono.yaml +++ b/oragono.yaml @@ -160,3 +160,6 @@ limits: # whowas entries to store whowas-entries: 100 + + # maximum length of channel lists (beI modes) + chan-list-modes: 60