Passthrough some ISUPPORT tokens
This commit is contained in:
parent
3f005d481d
commit
fa047123b9
@ -81,6 +81,33 @@ var needAllDownstreamCaps = map[string]string{
|
||||
"multi-prefix": "",
|
||||
}
|
||||
|
||||
// passthroughIsupport is the set of ISUPPORT tokens that are directly passed
|
||||
// through from the upstream server to downstream clients.
|
||||
//
|
||||
// This is only effective in single-upstream mode.
|
||||
var passthroughIsupport = map[string]bool{
|
||||
"AWAYLEN": true,
|
||||
"CHANLIMIT": true,
|
||||
"CHANMODES": true,
|
||||
"CHANNELLEN": true,
|
||||
"CHANTYPES": true,
|
||||
"EXCEPTS": true,
|
||||
"EXTBAN": true,
|
||||
"HOSTLEN": true,
|
||||
"INVEX": true,
|
||||
"KICKLEN": true,
|
||||
"MAXLIST": true,
|
||||
"MAXTARGETS": true,
|
||||
"MODES": true,
|
||||
"NETWORK": true,
|
||||
"NICKLEN": true,
|
||||
"PREFIX": true,
|
||||
"SAFELIST": true,
|
||||
"TARGMAX": true,
|
||||
"TOPICLEN": true,
|
||||
"USERLEN": true,
|
||||
}
|
||||
|
||||
type downstreamConn struct {
|
||||
conn
|
||||
|
||||
@ -880,8 +907,18 @@ func (dc *downstreamConn) welcome() error {
|
||||
fmt.Sprintf("CHATHISTORY=%v", dc.srv.HistoryLimit),
|
||||
}
|
||||
|
||||
if uc := dc.upstream(); uc != nil && uc.isupport["NETWORK"] != nil {
|
||||
isupport = append(isupport, fmt.Sprintf("NETWORK=%v", *uc.isupport["NETWORK"]))
|
||||
if uc := dc.upstream(); uc != nil {
|
||||
for k := range passthroughIsupport {
|
||||
v, ok := uc.isupport[k]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if v != nil {
|
||||
isupport = append(isupport, fmt.Sprintf("%v=%v", k, *v))
|
||||
} else {
|
||||
isupport = append(isupport, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dc.SendMessage(&irc.Message{
|
||||
@ -904,12 +941,9 @@ func (dc *downstreamConn) welcome() error {
|
||||
Command: irc.RPL_MYINFO,
|
||||
Params: []string{dc.nick, dc.srv.Hostname, "soju", "aiwroO", "OovaimnqpsrtklbeI"},
|
||||
})
|
||||
// TODO: other RPL_ISUPPORT tokens
|
||||
dc.SendMessage(&irc.Message{
|
||||
Prefix: dc.srv.prefix(),
|
||||
Command: irc.RPL_ISUPPORT,
|
||||
Params: append(append([]string{dc.nick}, isupport...), "are supported"),
|
||||
})
|
||||
for _, msg := range generateIsupport(dc.srv.prefix(), dc.nick, isupport) {
|
||||
dc.SendMessage(msg)
|
||||
}
|
||||
dc.SendMessage(&irc.Message{
|
||||
Prefix: dc.srv.prefix(),
|
||||
Command: irc.ERR_NOMOTD,
|
||||
|
29
irc.go
29
irc.go
@ -17,7 +17,10 @@ const (
|
||||
err_invalidcapcmd = "410"
|
||||
)
|
||||
|
||||
const maxMessageLength = 512
|
||||
const (
|
||||
maxMessageLength = 512
|
||||
maxMessageParams = 15
|
||||
)
|
||||
|
||||
// The server-time layout, as defined in the IRCv3 spec.
|
||||
const serverTimeLayout = "2006-01-02T15:04:05.000Z"
|
||||
@ -348,6 +351,30 @@ func join(channels, keys []string) []*irc.Message {
|
||||
return msgs
|
||||
}
|
||||
|
||||
func generateIsupport(prefix *irc.Prefix, nick string, tokens []string) []*irc.Message {
|
||||
maxTokens := maxMessageParams - 2 // 2 reserved params: nick + text
|
||||
|
||||
var msgs []*irc.Message
|
||||
for len(tokens) > 0 {
|
||||
var msgTokens []string
|
||||
if len(tokens) > maxTokens {
|
||||
msgTokens = tokens[:maxTokens]
|
||||
tokens = tokens[maxTokens:]
|
||||
} else {
|
||||
msgTokens = tokens
|
||||
tokens = nil
|
||||
}
|
||||
|
||||
msgs = append(msgs, &irc.Message{
|
||||
Prefix: prefix,
|
||||
Command: irc.RPL_ISUPPORT,
|
||||
Params: append(append([]string{nick}, msgTokens...), "are supported"),
|
||||
})
|
||||
}
|
||||
|
||||
return msgs
|
||||
}
|
||||
|
||||
type joinSorter struct {
|
||||
channels []string
|
||||
keys []string
|
||||
|
16
upstream.go
16
upstream.go
@ -613,6 +613,8 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
|
||||
if err := parseMessageParams(msg, nil, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var downstreamIsupport []string
|
||||
for _, token := range msg.Params[1 : len(msg.Params)-1] {
|
||||
parameter := token
|
||||
var negate, hasValue bool
|
||||
@ -658,7 +660,21 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if passthroughIsupport[parameter] {
|
||||
downstreamIsupport = append(downstreamIsupport, token)
|
||||
}
|
||||
}
|
||||
|
||||
uc.forEachDownstream(func(dc *downstreamConn) {
|
||||
if dc.network == nil {
|
||||
return
|
||||
}
|
||||
msgs := generateIsupport(dc.srv.prefix(), dc.nick, downstreamIsupport)
|
||||
for _, msg := range msgs {
|
||||
dc.SendMessage(msg)
|
||||
}
|
||||
})
|
||||
case "BATCH":
|
||||
var tag string
|
||||
if err := parseMessageParams(msg, &tag); err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user