blob: 6427ec6c6fd2c73c9b7d730f08a75ec0e68e5d45 [file] [log] [blame]
Sergiusz Bazanskia8854882020-01-05 00:34:38 +01001package irc
2
3import (
4 "context"
5 "fmt"
6 "time"
7
8 "github.com/golang/glog"
9)
10
11var (
12 errBanned = fmt.Errorf("user is shitlisted")
13)
14
15// getconn either gets a connection by username, or creates a new one (after
16// evicting the least recently used connection).
17func (m *Manager) getconn(ctx context.Context, user string) (*ircconn, error) {
18 // Is the user shitlisted?
19 if t, ok := m.shitlist[user]; ok && time.Now().Before(t) {
20 return nil, errBanned
21 }
22 // Do we already have a connection?
23 c, ok := m.conns[user]
24 if ok {
25 // Bump and return.
26 c.last = time.Now()
27 return c, nil
28 }
29
30 // Are we at the limit of allowed connections?
31 if len(m.conns) >= m.max {
32 // Evict least recently used
33 evict := ""
34 lru := time.Now()
35 for _, c := range m.conns {
36 if c.last.Before(lru) {
37 evict = c.user
38 lru = c.last
39 }
40 }
41 if evict == "" {
42 glog.Exitf("could not find connection to evict, %v", m.conns)
43 }
44 m.conns[evict].Evict()
45 delete(m.conns, evict)
46 }
47
48 // Allocate new connection
49 return m.newconn(ctx, user, false)
50}
51
52// newconn creates a new IRC connection as a given user, and saves it to the
53// conns map.
54func (m *Manager) newconn(ctx context.Context, user string, backup bool) (*ircconn, error) {
55 c, err := NewConn(m.server, m.channel, user, backup, m.Event)
56 if err != nil {
57 return nil, err
58 }
59 m.conns[user] = c
60
61 go c.Run(m.runctx)
62
63 return c, nil
64}