make MaxLineLen configurable

This commit is contained in:
Shivaram Lingamneni 2021-05-24 00:38:47 -04:00
parent 297f2af827
commit 7c5a8f2013
7 changed files with 30 additions and 5 deletions

View File

@ -360,6 +360,11 @@ server:
# e.g., `NickServ!NickServ@localhost`. uncomment this to override: # e.g., `NickServ!NickServ@localhost`. uncomment this to override:
#override-services-hostname: "example.network" #override-services-hostname: "example.network"
# in a "closed-loop" system where you control the server and all the clients,
# you may want to increase the maximum (non-tag) length of an IRC line from
# the default value of 512. do not do this on a public server:
# max-line-len: 512
# account options # account options
accounts: accounts:
# is account authentication enabled, i.e., can users log into existing accounts? # is account authentication enabled, i.e., can users log into existing accounts?

View File

@ -31,8 +31,8 @@ import (
) )
const ( const (
// maximum line length not including tags; don't change this for a public server // maximum IRC line length, not including tags
MaxLineLen = 512 DefaultMaxLineLen = 512
// IdentTimeout is how long before our ident (username) check times out. // IdentTimeout is how long before our ident (username) check times out.
IdentTimeout = time.Second + 500*time.Millisecond IdentTimeout = time.Second + 500*time.Millisecond
@ -61,6 +61,10 @@ const (
PingCoalesceThreshold = time.Second PingCoalesceThreshold = time.Second
) )
var (
MaxLineLen = DefaultMaxLineLen
)
// Client is an IRC client. // Client is an IRC client.
type Client struct { type Client struct {
account string account string

View File

@ -590,6 +590,7 @@ type Config struct {
OutputPath string `yaml:"output-path"` OutputPath string `yaml:"output-path"`
IPCheckScript ScriptConfig `yaml:"ip-check-script"` IPCheckScript ScriptConfig `yaml:"ip-check-script"`
OverrideServicesHostname string `yaml:"override-services-hostname"` OverrideServicesHostname string `yaml:"override-services-hostname"`
MaxLineLen int `yaml:"max-line-len"`
} }
Roleplay struct { Roleplay struct {
@ -1132,6 +1133,9 @@ func LoadConfig(filename string) (config *Config, err error) {
if config.Limits.RegistrationMessages == 0 { if config.Limits.RegistrationMessages == 0 {
config.Limits.RegistrationMessages = 1024 config.Limits.RegistrationMessages = 1024
} }
if config.Server.MaxLineLen < DefaultMaxLineLen {
config.Server.MaxLineLen = DefaultMaxLineLen
}
if config.Datastore.MySQL.Enabled { if config.Datastore.MySQL.Enabled {
if config.Limits.NickLen > mysql.MaxTargetLength || config.Limits.ChannelLen > mysql.MaxTargetLength { if config.Limits.NickLen > mysql.MaxTargetLength || config.Limits.ChannelLen > mysql.MaxTargetLength {
return nil, fmt.Errorf("to use MySQL, nick and channel length limits must be %d or lower", mysql.MaxTargetLength) return nil, fmt.Errorf("to use MySQL, nick and channel length limits must be %d or lower", mysql.MaxTargetLength)

View File

@ -16,7 +16,6 @@ import (
) )
const ( const (
maxReadQBytes = ircmsg.MaxlenTagsFromClient + MaxLineLen + 1024
initialBufferSize = 1024 initialBufferSize = 1024
) )
@ -24,6 +23,11 @@ var (
crlf = []byte{'\r', '\n'} crlf = []byte{'\r', '\n'}
) )
// maximum total length, in bytes, of a single IRC message:
func maxReadQBytes() int {
return ircmsg.MaxlenTagsFromClient + MaxLineLen + 1024
}
// IRCConn abstracts away the distinction between a regular // IRCConn abstracts away the distinction between a regular
// net.Conn (which includes both raw TCP and TLS) and a websocket. // net.Conn (which includes both raw TCP and TLS) and a websocket.
// it doesn't expose the net.Conn, io.Reader, or io.Writer interfaces // it doesn't expose the net.Conn, io.Reader, or io.Writer interfaces
@ -51,7 +55,7 @@ type IRCStreamConn struct {
func NewIRCStreamConn(conn *utils.WrappedConn) *IRCStreamConn { func NewIRCStreamConn(conn *utils.WrappedConn) *IRCStreamConn {
var c IRCStreamConn var c IRCStreamConn
c.conn = conn c.conn = conn
c.reader.Initialize(conn.Conn, initialBufferSize, maxReadQBytes) c.reader.Initialize(conn.Conn, initialBufferSize, maxReadQBytes())
return &c return &c
} }

View File

@ -185,7 +185,7 @@ func (wl *WSListener) handle(w http.ResponseWriter, r *http.Request) {
confirmProxyData(wConn, remoteAddr, xff, xfp, config) confirmProxyData(wConn, remoteAddr, xff, xfp, config)
// avoid a DoS attack from buffering excessively large messages: // avoid a DoS attack from buffering excessively large messages:
conn.SetReadLimit(maxReadQBytes) conn.SetReadLimit(int64(maxReadQBytes()))
go wl.server.RunClient(NewIRCWSConn(conn)) go wl.server.RunClient(NewIRCWSConn(conn))
} }

View File

@ -554,6 +554,7 @@ func (server *Server) applyConfig(config *Config) (err error) {
server.nameCasefolded = config.Server.nameCasefolded server.nameCasefolded = config.Server.nameCasefolded
globalCasemappingSetting = config.Server.Casemapping globalCasemappingSetting = config.Server.Casemapping
globalUtf8EnforcementSetting = config.Server.EnforceUtf8 globalUtf8EnforcementSetting = config.Server.EnforceUtf8
MaxLineLen = config.Server.MaxLineLen
} else { } else {
// enforce configs that can't be changed after launch: // enforce configs that can't be changed after launch:
if server.name != config.Server.Name { if server.name != config.Server.Name {
@ -577,6 +578,8 @@ func (server *Server) applyConfig(config *Config) (err error) {
return fmt.Errorf("Cannot change override-services-hostname after launching the server, rehash aborted") return fmt.Errorf("Cannot change override-services-hostname after launching the server, rehash aborted")
} else if !oldConfig.Datastore.MySQL.Enabled && config.Datastore.MySQL.Enabled { } else if !oldConfig.Datastore.MySQL.Enabled && config.Datastore.MySQL.Enabled {
return fmt.Errorf("Cannot enable MySQL after launching the server, rehash aborted") return fmt.Errorf("Cannot enable MySQL after launching the server, rehash aborted")
} else if oldConfig.Server.MaxLineLen != config.Server.MaxLineLen {
return fmt.Errorf("Cannot change max-line-len after launching the server, rehash aborted")
} }
} }

View File

@ -332,6 +332,11 @@ server:
# e.g., `NickServ!NickServ@localhost`. uncomment this to override: # e.g., `NickServ!NickServ@localhost`. uncomment this to override:
#override-services-hostname: "example.network" #override-services-hostname: "example.network"
# in a "closed-loop" system where you control the server and all the clients,
# you may want to increase the maximum (non-tag) length of an IRC line from
# the default value of 512. do not do this on a public server:
# max-line-len: 512
# account options # account options
accounts: accounts:
# is account authentication enabled, i.e., can users log into existing accounts? # is account authentication enabled, i.e., can users log into existing accounts?