Connect to upstream servers

This commit is contained in:
Simon Ser 2020-02-06 16:03:07 +01:00
parent 06cd1ce44f
commit 56d793543e
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
2 changed files with 77 additions and 7 deletions

View File

@ -15,11 +15,19 @@ func main() {
log.Fatalf("failed to start listener: %v", err)
}
// TODO: load from config/DB
s := jounce.Server{
Hostname: "localhost",
Logger: log.New(log.Writer(), "", log.LstdFlags),
Logger: log.New(log.Writer(), "", log.LstdFlags),
Upstreams: []jounce.Upstream{{
Addr: "chat.freenode.net:6697",
Nick: "jounce",
Username: "jounce",
Realname: "jounce",
}},
}
log.Printf("Server listening on %v", addr)
go s.Run()
log.Fatal(s.Serve(ln))
}

View File

@ -1,6 +1,7 @@
package jounce
import (
"crypto/tls"
"fmt"
"io"
"log"
@ -74,7 +75,7 @@ func (c *downstreamConn) handleMessage(msg *irc.Message) error {
// TODO: handle params
return c.WriteMessage(&irc.Message{
Command: "PONG",
Params: []string{c.srv.Hostname},
Params: []string{c.srv.Hostname},
})
default:
if c.registered {
@ -146,7 +147,7 @@ func (c *downstreamConn) register() error {
err = c.WriteMessage(&irc.Message{
Command: irc.ERR_NOMOTD,
Params: []string{c.nick, "No MOTD"},
Params: []string{c.nick, "No MOTD"},
})
if err != nil {
return err
@ -172,9 +173,23 @@ func (c *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
}
}
type Server struct{
Hostname string
Logger Logger
type upstreamConn struct {
net net.Conn
irc *irc.Conn
srv *Server
}
type Upstream struct {
Addr string
Nick string
Username string
Realname string
}
type Server struct {
Hostname string
Logger Logger
Upstreams []Upstream // TODO: per-user
}
func (s *Server) prefix() *irc.Prefix {
@ -193,7 +208,7 @@ func (s *Server) handleConn(netConn net.Conn) error {
} else if err != nil {
return fmt.Errorf("failed to read IRC command: %v", err)
}
s.Logger.Print(msg)
s.Logger.Printf("Downstream message: %v", msg)
err = c.handleMessage(msg)
if ircErr, ok := err.(ircError); ok {
@ -213,6 +228,53 @@ func (s *Server) handleConn(netConn net.Conn) error {
return c.Close()
}
func (s *Server) connect(upstream *Upstream) error {
s.Logger.Printf("Connecting to %v", upstream.Addr)
netConn, err := tls.Dial("tcp", upstream.Addr, nil)
if err != nil {
return fmt.Errorf("failed to dial %q: %v", upstream.Addr, err)
}
c := upstreamConn{net: netConn, irc: irc.NewConn(netConn), srv: s}
defer netConn.Close()
err = c.irc.WriteMessage(&irc.Message{
Command: "NICK",
Params: []string{upstream.Nick},
})
if err != nil {
return err
}
err = c.irc.WriteMessage(&irc.Message{
Command: "USER",
Params: []string{upstream.Username, "0", "*", upstream.Realname},
})
if err != nil {
return err
}
for {
msg, err := c.irc.ReadMessage()
if err == io.EOF {
break
} else if err != nil {
return fmt.Errorf("failed to read IRC command: %v", err)
}
log.Printf("Upstream message: %v", msg)
}
return netConn.Close()
}
func (s *Server) Run() {
for i := range s.Upstreams {
// TODO: retry connecting
go s.connect(&s.Upstreams[i])
}
}
func (s *Server) Serve(ln net.Listener) error {
for {
c, err := ln.Accept()