Require an explicit * network suffix for multi-upstream

Most users will connect to their server with `<username>` as their
username in order to configure their upstreams.

Multi-upstream can be unintuitive to them and should not be enabled on
that first connection that is usually used for upstream configuration.

Multi-upstream is instead a power-user feature that should be explicitly
enabled with a specific network suffix.

We reserve the network suffix `*` and use it a special case to mean that
it requests multi-upstream mode.
This commit is contained in:
delthas 2022-03-20 14:58:18 +01:00 committed by Simon Ser
parent f5b16dc00c
commit 2ac9bd9c94
4 changed files with 17 additions and 6 deletions

View file

@ -36,7 +36,7 @@ In this mode, a single connection to your soju bouncer can handle multiple
upstream connections. You will need to manually configure each upstream
connection using the the special `BouncerServ` user.
Connect to your soju server by specifying your soju username in the username
Connect to your soju server by specifying `<soju username>/*` in the username
field in your client and your password in the password field.
You should now be able to send private messages to the `BouncerServ`. You can

View file

@ -39,7 +39,8 @@ soju supports two connection modes:
- Multiple upstream mode: one downstream connection maps to multiple upstream
connections. Channels and nicks are suffixed with the network name. To join
a channel, you need to use the suffix too: _/join #channel/network_. Same
applies to messages sent to users.
applies to messages sent to users. To enable this mode, connect to the bouncer
with the username "<username>/*".
For per-client history to work, clients need to indicate their name. This can
be done by adding a "@<client>" suffix to the username.

View file

@ -1368,6 +1368,17 @@ func (dc *downstreamConn) welcome(ctx context.Context) error {
remoteAddr := dc.conn.RemoteAddr().String()
dc.logger = &prefixLogger{dc.srv.Logger, fmt.Sprintf("user %q: downstream %q: ", dc.user.Username, remoteAddr)}
if dc.networkName == "*" {
if !dc.srv.Config().MultiUpstream {
return ircError{&irc.Message{
Command: irc.ERR_PASSWDMISMATCH,
Params: []string{dc.nick, fmt.Sprintf("Multi-upstream mode is disabled on this server")},
}}
}
dc.networkName = ""
dc.isMultiUpstream = true
}
// TODO: doing this might take some time. We should do it in dc.register
// instead, but we'll potentially be adding a new network and this must be
// done in the user goroutine.
@ -1375,10 +1386,6 @@ func (dc *downstreamConn) welcome(ctx context.Context) error {
return err
}
if dc.network == nil && !dc.caps.IsEnabled("soju.im/bouncer-networks") && dc.srv.Config().MultiUpstream {
dc.isMultiUpstream = true
}
dc.updateSupportedCaps()
isupport := []string{

View file

@ -460,6 +460,9 @@ func (fs *networkFlagSet) update(network *Network) error {
network.Addr = *fs.Addr
}
if fs.Name != nil {
if *fs.Name == "*" {
return fmt.Errorf("the network name %q is reserved for multi-upstream mode", *fs.Name)
}
network.Name = *fs.Name
}
if fs.Nick != nil {