Fix sending messages from detached channels

Currently, a downstream receives MODE, RPL_CHANNELMODEIS and
RPL_CREATIONTIME messages from soju for detached channels. It should not
be sent any of these messages.

This adds a detach check to the handling of these messages to avoid
receiving these messages.
This commit is contained in:
delthas 2020-06-12 14:35:26 +02:00 committed by Simon Ser
parent ccf9cff351
commit 2232b3128b

View File

@ -858,24 +858,27 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
} }
uc.appendLog(ch.Name, msg) uc.appendLog(ch.Name, msg)
uc.forEachDownstream(func(dc *downstreamConn) {
params := make([]string, len(msg.Params))
params[0] = dc.marshalEntity(uc.network, name)
params[1] = modeStr
copy(params[2:], msg.Params[2:]) if ch, ok := uc.network.channels[name]; !ok || !ch.Detached {
for i, modeParam := range params[2:] { uc.forEachDownstream(func(dc *downstreamConn) {
if _, ok := needMarshaling[i]; ok { params := make([]string, len(msg.Params))
params[2+i] = dc.marshalEntity(uc.network, modeParam) params[0] = dc.marshalEntity(uc.network, name)
params[1] = modeStr
copy(params[2:], msg.Params[2:])
for i, modeParam := range params[2:] {
if _, ok := needMarshaling[i]; ok {
params[2+i] = dc.marshalEntity(uc.network, modeParam)
}
} }
}
dc.SendMessage(&irc.Message{ dc.SendMessage(&irc.Message{
Prefix: dc.marshalUserPrefix(uc.network, msg.Prefix), Prefix: dc.marshalUserPrefix(uc.network, msg.Prefix),
Command: "MODE", Command: "MODE",
Params: params, Params: params,
})
}) })
}) }
} }
case irc.RPL_UMODEIS: case irc.RPL_UMODEIS:
if err := parseMessageParams(msg, nil); err != nil { if err := parseMessageParams(msg, nil); err != nil {
@ -912,18 +915,20 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
return err return err
} }
if firstMode { if firstMode {
modeStr, modeParams := ch.modes.Format() if c, ok := uc.network.channels[channel]; !ok || !c.Detached {
modeStr, modeParams := ch.modes.Format()
uc.forEachDownstream(func(dc *downstreamConn) { uc.forEachDownstream(func(dc *downstreamConn) {
params := []string{dc.nick, dc.marshalEntity(uc.network, channel), modeStr} params := []string{dc.nick, dc.marshalEntity(uc.network, channel), modeStr}
params = append(params, modeParams...) params = append(params, modeParams...)
dc.SendMessage(&irc.Message{ dc.SendMessage(&irc.Message{
Prefix: dc.srv.prefix(), Prefix: dc.srv.prefix(),
Command: irc.RPL_CHANNELMODEIS, Command: irc.RPL_CHANNELMODEIS,
Params: params, Params: params,
})
}) })
}) }
} }
case rpl_creationtime: case rpl_creationtime:
var channel, creationTime string var channel, creationTime string
@ -1048,9 +1053,11 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
} }
ch.complete = true ch.complete = true
uc.forEachDownstream(func(dc *downstreamConn) { if c, ok := uc.network.channels[name]; !ok || !c.Detached {
forwardChannel(dc, ch) uc.forEachDownstream(func(dc *downstreamConn) {
}) forwardChannel(dc, ch)
})
}
case irc.RPL_WHOREPLY: case irc.RPL_WHOREPLY:
var channel, username, host, server, nick, mode, trailing string var channel, username, host, server, nick, mode, trailing string
if err := parseMessageParams(msg, nil, &channel, &username, &host, &server, &nick, &mode, &trailing); err != nil { if err := parseMessageParams(msg, nil, &channel, &username, &host, &server, &nick, &mode, &trailing); err != nil {