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 upstream connections. You will need to manually configure each upstream
connection using the the special `BouncerServ` user. 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. 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 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 - Multiple upstream mode: one downstream connection maps to multiple upstream
connections. Channels and nicks are suffixed with the network name. To join 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 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 For per-client history to work, clients need to indicate their name. This can
be done by adding a "@<client>" suffix to the username. 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() remoteAddr := dc.conn.RemoteAddr().String()
dc.logger = &prefixLogger{dc.srv.Logger, fmt.Sprintf("user %q: downstream %q: ", dc.user.Username, remoteAddr)} 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 // 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 // instead, but we'll potentially be adding a new network and this must be
// done in the user goroutine. // done in the user goroutine.
@ -1375,10 +1386,6 @@ func (dc *downstreamConn) welcome(ctx context.Context) error {
return err return err
} }
if dc.network == nil && !dc.caps.IsEnabled("soju.im/bouncer-networks") && dc.srv.Config().MultiUpstream {
dc.isMultiUpstream = true
}
dc.updateSupportedCaps() dc.updateSupportedCaps()
isupport := []string{ isupport := []string{

View File

@ -460,6 +460,9 @@ func (fs *networkFlagSet) update(network *Network) error {
network.Addr = *fs.Addr network.Addr = *fs.Addr
} }
if fs.Name != nil { 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 network.Name = *fs.Name
} }
if fs.Nick != nil { if fs.Nick != nil {