Connect to upstream servers
This commit is contained in:
parent
06cd1ce44f
commit
56d793543e
@ -15,11 +15,19 @@ func main() {
|
|||||||
log.Fatalf("failed to start listener: %v", err)
|
log.Fatalf("failed to start listener: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: load from config/DB
|
||||||
s := jounce.Server{
|
s := jounce.Server{
|
||||||
Hostname: "localhost",
|
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)
|
log.Printf("Server listening on %v", addr)
|
||||||
|
go s.Run()
|
||||||
log.Fatal(s.Serve(ln))
|
log.Fatal(s.Serve(ln))
|
||||||
}
|
}
|
||||||
|
74
server.go
74
server.go
@ -1,6 +1,7 @@
|
|||||||
package jounce
|
package jounce
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
@ -74,7 +75,7 @@ func (c *downstreamConn) handleMessage(msg *irc.Message) error {
|
|||||||
// TODO: handle params
|
// TODO: handle params
|
||||||
return c.WriteMessage(&irc.Message{
|
return c.WriteMessage(&irc.Message{
|
||||||
Command: "PONG",
|
Command: "PONG",
|
||||||
Params: []string{c.srv.Hostname},
|
Params: []string{c.srv.Hostname},
|
||||||
})
|
})
|
||||||
default:
|
default:
|
||||||
if c.registered {
|
if c.registered {
|
||||||
@ -146,7 +147,7 @@ func (c *downstreamConn) register() error {
|
|||||||
|
|
||||||
err = c.WriteMessage(&irc.Message{
|
err = c.WriteMessage(&irc.Message{
|
||||||
Command: irc.ERR_NOMOTD,
|
Command: irc.ERR_NOMOTD,
|
||||||
Params: []string{c.nick, "No MOTD"},
|
Params: []string{c.nick, "No MOTD"},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -172,9 +173,23 @@ func (c *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Server struct{
|
type upstreamConn struct {
|
||||||
Hostname string
|
net net.Conn
|
||||||
Logger Logger
|
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 {
|
func (s *Server) prefix() *irc.Prefix {
|
||||||
@ -193,7 +208,7 @@ func (s *Server) handleConn(netConn net.Conn) error {
|
|||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return fmt.Errorf("failed to read IRC command: %v", err)
|
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)
|
err = c.handleMessage(msg)
|
||||||
if ircErr, ok := err.(ircError); ok {
|
if ircErr, ok := err.(ircError); ok {
|
||||||
@ -213,6 +228,53 @@ func (s *Server) handleConn(netConn net.Conn) error {
|
|||||||
return c.Close()
|
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 {
|
func (s *Server) Serve(ln net.Listener) error {
|
||||||
for {
|
for {
|
||||||
c, err := ln.Accept()
|
c, err := ln.Accept()
|
||||||
|
Loading…
Reference in New Issue
Block a user