1 Commits

Author SHA1 Message Date
James Mills
165fa6ef5b Fixed bug with RPL_ENDOFWHOIS (/WHOIS) response missing nick component 2017-11-26 10:31:27 -08:00
9 changed files with 24 additions and 117 deletions

View File

@@ -35,9 +35,9 @@ Discussion at:
* /server irc.mills.io +6697 (*use TLS/SSL*)
* /join #lobby
Or (**not recommended**):
Or (*not recommended*)P
* /server irc.mills.io (*default port 6667, non-TLS*)
* /server irc.mills.io (*default port 6667, non-TLS)
* /join #lobby
## Features
@@ -54,7 +54,6 @@ Or (**not recommended**):
* Simple IRC operator privileges (*overrides most things*)
* Secure connection tracking (+z) and SecureOnly user mode (+Z)
* Secure channels (+Z)
* Three layers of channel privacy, Public, Private (+p) and Secret (s)
## Quick Start
@@ -138,17 +137,13 @@ $ docker stack deploy -c docker-compose.yml eris
Which assumes a `ircd.yml` coniguration file in the current directory which Docker will use to distribute as the configuration. The `docker-compose.yml` (*Docker Stackfile*) is available at the root of this repository.
## Related Projects
## Related Proejcts
There are a number of supported accompanying services that are being developed alongside Eris:
* [Soter](https://github.com/prologic/soter) -- An IRC Bot that persists channel modes and topics.
* [Cadmus](https://github.com/prologic/cadmus) -- An IRC Bot that logs channels and provides an interface for viewing and searching logs
## Recommended Mobile clients
* [Palaver (iOS)](https://palaverapp.com/) -- SASL, TLS, Server Password, Push Notifications, IRCv3 (*Also supports custom image upload service(s) for better privacy of shared photos/images over IRC*)
## License
eris is licensed under the MIT License.

View File

@@ -374,7 +374,7 @@ func (channel *Channel) applyMode(client *Client, change *ChannelModeChange) boo
return channel.applyModeMask(client, change.mode, change.op,
NewName(change.arg))
case InviteOnly, Moderated, NoOutside, OpOnlyTopic, Private, Secret, SecureChan:
case InviteOnly, Moderated, NoOutside, OpOnlyTopic, Private, SecureChan:
return channel.applyModeFlag(client, change.mode, change.op)
case Key:

View File

@@ -222,12 +222,6 @@ func (client *Client) destroy() {
// clean up server
if _, ok := client.socket.conn.(*tls.Conn); ok {
client.server.metrics.GaugeVec("server", "clients").WithLabelValues("secure").Dec()
} else {
client.server.metrics.GaugeVec("server", "clients").WithLabelValues("insecure").Dec()
}
client.server.connections.Dec()
client.server.clients.Remove(client)
@@ -241,7 +235,6 @@ func (client *Client) destroy() {
}
close(client.replies)
client.replies = nil
client.socket.Close()
@@ -358,9 +351,7 @@ func (client *Client) ChangeNickname(nickname Name) {
}
func (client *Client) Reply(reply string) {
if client.replies != nil {
client.replies <- reply
}
client.replies <- reply
}
func (client *Client) Quit(message Text) {

View File

@@ -20,7 +20,6 @@ var DefObjectives = map[float64]float64{
type Metrics struct {
namespace string
metrics map[string]prometheus.Metric
gaugevecs map[string]*prometheus.GaugeVec
sumvecs map[string]*prometheus.SummaryVec
}
@@ -28,7 +27,6 @@ func NewMetrics(namespace string) *Metrics {
return &Metrics{
namespace: namespace,
metrics: make(map[string]prometheus.Metric),
gaugevecs: make(map[string]*prometheus.GaugeVec),
sumvecs: make(map[string]*prometheus.SummaryVec),
}
}
@@ -103,24 +101,6 @@ func (m *Metrics) NewGaugeFunc(subsystem, name, help string, f func() float64) p
return guage
}
func (m *Metrics) NewGaugeVec(subsystem, name, help string, labels []string) *prometheus.GaugeVec {
gauagevec := prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: m.namespace,
Subsystem: subsystem,
Name: name,
Help: help,
},
labels,
)
key := fmt.Sprintf("%s_%s", subsystem, name)
m.gaugevecs[key] = gauagevec
prometheus.MustRegister(gauagevec)
return gauagevec
}
func (m *Metrics) NewSummary(subsystem, name, help string) prometheus.Summary {
summary := prometheus.NewSummary(
prometheus.SummaryOpts{
@@ -168,11 +148,6 @@ func (m *Metrics) Gauge(subsystem, name string) prometheus.Gauge {
return m.metrics[key].(prometheus.Gauge)
}
func (m *Metrics) GaugeVec(subsystem, name string) *prometheus.GaugeVec {
key := fmt.Sprintf("%s_%s", subsystem, name)
return m.gaugevecs[key]
}
func (m *Metrics) Summary(subsystem, name string) prometheus.Summary {
key := fmt.Sprintf("%s_%s", subsystem, name)
return m.metrics[key].(prometheus.Summary)

View File

@@ -70,6 +70,7 @@ var (
)
const (
Anonymous ChannelMode = 'a' // flag
BanMask ChannelMode = 'b' // arg
ChannelCreator ChannelMode = 'O' // flag
ChannelOperator ChannelMode = 'o' // arg
@@ -81,6 +82,8 @@ const (
NoOutside ChannelMode = 'n' // flag
OpOnlyTopic ChannelMode = 't' // flag
Private ChannelMode = 'p' // flag
Quiet ChannelMode = 'q' // flag
ReOp ChannelMode = 'r' // flag
Secret ChannelMode = 's' // flag, deprecated
UserLimit ChannelMode = 'l' // flag arg
Voice ChannelMode = 'v' // arg
@@ -90,7 +93,7 @@ const (
var (
SupportedChannelModes = ChannelModes{
BanMask, ExceptMask, InviteMask, InviteOnly, Key, NoOutside,
OpOnlyTopic, Private, UserLimit, Secret, SecureChan,
OpOnlyTopic, Private, UserLimit, SecureChan,
}
)

View File

@@ -1,22 +0,0 @@
package irc
func CanSeeChannel(client *Client, channel *Channel) bool {
isPrivate := channel.flags.Has(Private)
isSecret := channel.flags.Has(Secret)
isMember := channel.members.Has(client)
isOperator := client.flags[Operator]
isRegistered := client.flags[Registered]
isSecure := client.flags[SecureConn]
if !(isSecret || isPrivate) {
return true
}
if isSecret && (isMember || isOperator) {
return true
}
if isPrivate && (isMember || isOperator || (isRegistered && isSecure)) {
return true
}
return false
}

View File

@@ -489,13 +489,8 @@ func (target *Client) RplMOTDEnd() {
}
func (target *Client) RplList(channel *Channel) {
target.NumericReply(
RPL_LIST,
"%s %d :%s",
channel,
channel.members.Count(),
channel.topic,
)
target.NumericReply(RPL_LIST,
"%s %d :%s", channel, channel.members.Count(), channel.topic)
}
func (target *Client) RplListEnd(server *Server) {
@@ -509,12 +504,8 @@ func (target *Client) RplNamReply(channel *Channel) {
}
func (target *Client) RplWhoisChannels(client *Client) {
target.MultilineReply(
client.WhoisChannelsNames(target),
RPL_WHOISCHANNELS,
"%s :%s",
client.Nick(),
)
target.MultilineReply(client.WhoisChannelsNames(), RPL_WHOISCHANNELS,
"%s :%s", client.Nick())
}
func (target *Client) RplVersion() {

View File

@@ -44,16 +44,13 @@ type Server struct {
accounts PasswordStore
password []byte
signals chan os.Signal
done chan bool
whoWas *WhoWasList
ids map[string]*Identity
}
var (
SERVER_SIGNALS = []os.Signal{
syscall.SIGINT, syscall.SIGHUP,
syscall.SIGTERM, syscall.SIGQUIT,
}
SERVER_SIGNALS = []os.Signal{syscall.SIGINT, syscall.SIGHUP,
syscall.SIGTERM, syscall.SIGQUIT}
)
func NewServer(config *Config) *Server {
@@ -73,7 +70,6 @@ func NewServer(config *Config) *Server {
operators: config.Operators(),
accounts: NewMemoryPasswordStore(config.Accounts(), PasswordStoreOpts{}),
signals: make(chan os.Signal, len(SERVER_SIGNALS)),
done: make(chan bool),
whoWas: NewWhoWasList(100),
ids: make(map[string]*Identity),
}
@@ -127,22 +123,15 @@ func NewServer(config *Config) *Server {
},
)
// server registered (clients) gauge
// server clients gauge
server.metrics.NewGaugeFunc(
"server", "registered",
"server", "clients",
"Number of registered clients connected",
func() float64 {
return float64(server.clients.Count())
},
)
// server clients gauge (by secure/insecire)
server.metrics.NewGaugeVec(
"server", "clients",
"Number of registered clients connected (by secure/insecure)",
[]string{"secure"},
)
// server channels gauge
server.metrics.NewGaugeFunc(
"server", "channels",
@@ -203,17 +192,12 @@ func (server *Server) Shutdown() {
}
func (server *Server) Run() {
for {
done := false
for !done {
select {
case <-server.done:
return
case <-server.signals:
server.Shutdown()
// Give at least 1s for clients to see the shutdown
go func() {
time.Sleep(1 * time.Second)
server.done <- true
}()
done = true
case conn := <-server.newConns:
go NewClient(server, conn)
@@ -233,12 +217,6 @@ func (s *Server) acceptor(listener net.Listener) {
}
log.Debugf("%s accept: %s", s, conn.RemoteAddr())
if _, ok := conn.(*tls.Conn); ok {
s.metrics.GaugeVec("server", "clients").WithLabelValues("secure").Inc()
} else {
s.metrics.GaugeVec("server", "clients").WithLabelValues("insecure").Inc()
}
s.connections.Inc()
s.newConns <- conn
}
@@ -625,14 +603,10 @@ func (msg *PrivMsgCommand) HandleServer(server *Server) {
}
}
func (client *Client) WhoisChannelsNames(target *Client) []string {
func (client *Client) WhoisChannelsNames() []string {
chstrs := make([]string, client.channels.Count())
index := 0
client.channels.Range(func(channel *Channel) bool {
if !CanSeeChannel(target, channel) {
return true
}
switch {
case channel.members.Get(client).Has(ChannelOperator):
chstrs[index] = "@" + channel.name.String()
@@ -839,7 +813,7 @@ func (msg *ListCommand) HandleServer(server *Server) {
if len(msg.channels) == 0 {
server.channels.Range(func(name Name, channel *Channel) bool {
if !CanSeeChannel(client, channel) {
if !client.flags[Operator] && channel.flags.Has(Private) {
return true
}
client.RplList(channel)
@@ -848,7 +822,7 @@ func (msg *ListCommand) HandleServer(server *Server) {
} else {
for _, chname := range msg.channels {
channel := server.channels.Get(chname)
if channel == nil || !CanSeeChannel(client, channel) {
if channel == nil || (!client.flags[Operator] && channel.flags.Has(Private)) {
client.ErrNoSuchChannel(chname)
continue
}

View File

@@ -9,7 +9,7 @@ var (
Package = "eris"
// Version release version
Version = "1.6.3"
Version = "1.6.2"
// Build will be overwritten automatically by the build system
Build = "dev"