Compare commits
1 Commits
fix_bad_la
...
cloacks#23
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0a40f30956 |
@@ -46,4 +46,4 @@ $ git push -u origin my-feature
|
||||
|
||||
When describing your bug report; please be concise and as detailed as you can
|
||||
so we can easily work out what the problem is. It's also very helpful if you
|
||||
are able to provide a test case that repeatedly demonstrates the bug at hand.
|
||||
are able to provide a test case that repeatedly demonstrates the bug at hand:
|
||||
|
2
Makefile
2
Makefile
@@ -6,7 +6,7 @@ APP=eris
|
||||
PACKAGE=irc
|
||||
REPO?=prologic/$(APP)
|
||||
TAG?=latest
|
||||
BUILD?=dev
|
||||
BUILD?=-dev
|
||||
|
||||
all: dev
|
||||
|
||||
|
55
README.md
55
README.md
@@ -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,41 +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
|
||||
|
||||
```#!bash
|
||||
$ go get github.com/prologic/eris
|
||||
$ cat > ircd.yml <<EOF
|
||||
network:
|
||||
name: Test
|
||||
server:
|
||||
name: Test
|
||||
listen:
|
||||
- ":6667"
|
||||
EOF
|
||||
$ eris
|
||||
```
|
||||
|
||||
If you want TLS (**recommended**) then:
|
||||
|
||||
```#!bash
|
||||
$ go get github.com/prologic/mksslcert
|
||||
$ mksslcert
|
||||
```
|
||||
|
||||
This generates a self-signed cert `cert.pem` and `key.pem` into the `$PWD`.
|
||||
|
||||
Then add a `tlslisten` block to your config:
|
||||
|
||||
```#!yaml
|
||||
server:
|
||||
tlslisten:
|
||||
":6697":
|
||||
key: key.pem
|
||||
cert: cert.pem
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -108,14 +73,6 @@ $ go install github.com/prologic/mkpasswd
|
||||
$ mkpasswd
|
||||
```
|
||||
|
||||
Self-signed certificates can also be generated using the `mksslcert` tool
|
||||
from [prologic/mksslcert](https://github.com/prologic/mksslcert):
|
||||
|
||||
```#!bash
|
||||
$ go install github.com/prologic/mksslcert
|
||||
$ mksslcert
|
||||
```
|
||||
|
||||
## Deployment
|
||||
|
||||
To run simply run the `eris` binary (*assuming a `ircd.yml` in the current directory*):
|
||||
@@ -136,19 +93,15 @@ You may want to customize the configuration however and create your own image ba
|
||||
$ 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.
|
||||
Which assumes a `ircd.yml` coniguration fiel int he 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.
|
||||
|
@@ -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:
|
||||
|
@@ -119,6 +119,13 @@ func (client *Client) readloop() {
|
||||
}
|
||||
|
||||
func (client *Client) processCommand(cmd Command) {
|
||||
client.server.metrics.Counter("client", "commands").Inc()
|
||||
|
||||
defer func(t time.Time) {
|
||||
v := client.server.metrics.SummaryVec("client", "command_duration_seconds")
|
||||
v.WithLabelValues(cmd.Code().String()).Observe(time.Now().Sub(t).Seconds())
|
||||
}(time.Now())
|
||||
|
||||
cmd.SetClient(client)
|
||||
|
||||
if !client.registered {
|
||||
@@ -137,13 +144,6 @@ func (client *Client) processCommand(cmd Command) {
|
||||
return
|
||||
}
|
||||
|
||||
client.server.metrics.Counter("client", "commands").Inc()
|
||||
|
||||
defer func(t time.Time) {
|
||||
v := client.server.metrics.SummaryVec("client", "command_duration_seconds")
|
||||
v.WithLabelValues(cmd.Code().String()).Observe(time.Now().Sub(t).Seconds())
|
||||
}(time.Now())
|
||||
|
||||
switch srvCmd.(type) {
|
||||
case *PingCommand, *PongCommand:
|
||||
client.Touch()
|
||||
@@ -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) {
|
||||
|
@@ -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)
|
||||
|
@@ -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,
|
||||
}
|
||||
)
|
||||
|
||||
|
@@ -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
|
||||
}
|
28
irc/reply.go
28
irc/reply.go
@@ -260,7 +260,7 @@ func (target *Client) RplWhois(client *Client) {
|
||||
}
|
||||
target.RplWhoisServer(client)
|
||||
target.RplWhoisLoggedIn(client)
|
||||
target.RplEndOfWhois(client)
|
||||
target.RplEndOfWhois()
|
||||
}
|
||||
|
||||
func (target *Client) RplWhoisUser(client *Client) {
|
||||
@@ -324,12 +324,9 @@ func (target *Client) RplWhoisServer(client *Client) {
|
||||
)
|
||||
}
|
||||
|
||||
func (target *Client) RplEndOfWhois(client *Client) {
|
||||
target.NumericReply(
|
||||
RPL_ENDOFWHOIS,
|
||||
"%s :End of WHOIS list",
|
||||
client.Nick(),
|
||||
)
|
||||
func (target *Client) RplEndOfWhois() {
|
||||
target.NumericReply(RPL_ENDOFWHOIS,
|
||||
":End of WHOIS list")
|
||||
}
|
||||
|
||||
func (target *Client) RplChannelModeIs(channel *Channel) {
|
||||
@@ -489,13 +486,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 +501,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() {
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -1,18 +1,14 @@
|
||||
package irc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var (
|
||||
//PackageName package name
|
||||
Package = "eris"
|
||||
|
||||
// Version release version
|
||||
Version = "1.6.3"
|
||||
Version = "1.6.0"
|
||||
|
||||
// Build will be overwritten automatically by the build system
|
||||
Build = "dev"
|
||||
Build = "-dev"
|
||||
|
||||
// GitCommit will be overwritten automatically by the build system
|
||||
GitCommit = "HEAD"
|
||||
@@ -20,5 +16,5 @@ var (
|
||||
|
||||
// FullVersion display the full version and build
|
||||
func FullVersion() string {
|
||||
return fmt.Sprintf("%s-%s-%s@%s", Package, Version, Build, GitCommit)
|
||||
return Package + " v" + Version + Build + " (" + GitCommit + ")"
|
||||
}
|
||||
|
Reference in New Issue
Block a user