From 85f28daf2da169536d6b9dc39ff115a39a939021 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 12 Mar 2020 21:28:09 +0100 Subject: [PATCH] Auto-save IRC networks --- README.md | 2 ++ downstream.go | 37 ++++++++++++++++++++++++++++++------- server.go | 16 ++++++++++++++++ 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6e061dc..a11df23 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ A user-friendly IRC bouncer. go run ./cmd/jouncectl create-user jounce go run ./cmd/jounce +Then connect with username `jounce@chat.freenode.net` and join `#jounce`. + ## Contributing Send patches on the [mailing list], report bugs on the [issue tracker]. diff --git a/downstream.go b/downstream.go index dc0ec90..e4fd70a 100644 --- a/downstream.go +++ b/downstream.go @@ -1,10 +1,12 @@ package jounce import ( + "crypto/tls" "fmt" "io" "net" "strings" + "time" "golang.org/x/crypto/bcrypt" "gopkg.in/irc.v3" @@ -336,6 +338,15 @@ func (dc *downstreamConn) handleMessageUnregistered(msg *irc.Message) error { return nil } +func sanityCheckServer(addr string) error { + dialer := net.Dialer{Timeout: 30 * time.Second} + conn, err := tls.DialWithDialer(&dialer, "tcp", addr, nil) + if err != nil { + return err + } + return conn.Close() +} + func (dc *downstreamConn) register() error { username := strings.TrimPrefix(dc.username, "~") var networkName string @@ -365,13 +376,25 @@ func (dc *downstreamConn) register() error { if networkName != "" { network = u.getNetwork(networkName) if network == nil { - dc.logger.Printf("failed registration: unknown network %q", networkName) - dc.SendMessage(&irc.Message{ - Prefix: dc.srv.prefix(), - Command: irc.ERR_PASSWDMISMATCH, - Params: []string{"*", fmt.Sprintf("Unknown network %q", networkName)}, - }) - return nil + addr := networkName + if !strings.ContainsRune(addr, ':') { + addr = addr + ":6697" + } + + dc.logger.Printf("trying to connect to new upstream server %q", addr) + if err := sanityCheckServer(addr); err != nil { + dc.logger.Printf("failed to connect to %q: %v", addr, err) + return ircError{&irc.Message{ + Command: irc.ERR_PASSWDMISMATCH, + Params: []string{"*", fmt.Sprintf("Failed to connect to %q", networkName)}, + }} + } + + dc.logger.Printf("auto-adding network %q", networkName) + network, err = u.createNetwork(networkName, dc.nick) + if err != nil { + return err + } } } diff --git a/server.go b/server.go index bc390d9..4004c19 100644 --- a/server.go +++ b/server.go @@ -163,6 +163,22 @@ func (u *user) run() { u.lock.Unlock() } +func (u *user) createNetwork(addr, nick string) (*network, error) { + network := newNetwork(u, &Network{ + Addr: addr, + Nick: nick, + }) + err := u.srv.db.StoreNetwork(u.Username, &network.Network) + if err != nil { + return nil, err + } + u.lock.Lock() + u.networks = append(u.networks, network) + u.lock.Unlock() + go network.run() + return network, nil +} + type Server struct { Hostname string Logger Logger