Maintain a list of downstream connections
This commit is contained in:
parent
726d7cb54b
commit
8bbba42aef
@ -42,6 +42,8 @@ type downstreamConn struct {
|
||||
net net.Conn
|
||||
irc *irc.Conn
|
||||
srv *Server
|
||||
logger Logger
|
||||
|
||||
registered bool
|
||||
closed bool
|
||||
nick string
|
||||
@ -49,6 +51,45 @@ type downstreamConn struct {
|
||||
realname string
|
||||
}
|
||||
|
||||
func newDownstreamConn(srv *Server, netConn net.Conn) *downstreamConn {
|
||||
return &downstreamConn{
|
||||
net: netConn,
|
||||
irc: irc.NewConn(netConn),
|
||||
srv: srv,
|
||||
logger: &prefixLogger{srv.Logger, fmt.Sprintf("downstream %q: ", netConn.RemoteAddr())},
|
||||
}
|
||||
}
|
||||
|
||||
func (c *downstreamConn) readMessages() error {
|
||||
c.logger.Printf("new connection")
|
||||
defer c.Close()
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
err = c.handleMessage(msg)
|
||||
if ircErr, ok := err.(ircError); ok {
|
||||
ircErr.Message.Prefix = c.srv.prefix()
|
||||
if err := c.WriteMessage(ircErr.Message); err != nil {
|
||||
return fmt.Errorf("failed to write IRC reply: %v", err)
|
||||
}
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("failed to handle IRC command %q: %v", msg.Command, err)
|
||||
}
|
||||
|
||||
if c.closed {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return c.Close()
|
||||
}
|
||||
|
||||
func (c *downstreamConn) Close() error {
|
||||
if err := c.net.Close(); err != nil {
|
||||
return err
|
||||
@ -95,6 +136,7 @@ func (c *downstreamConn) handleMessageUnregistered(msg *irc.Message) error {
|
||||
case "QUIT":
|
||||
return c.Close()
|
||||
default:
|
||||
c.logger.Printf("unhandled message: %v", msg)
|
||||
return newUnknownCommandError(msg.Command)
|
||||
}
|
||||
if c.username != "" && c.nick != "" {
|
||||
@ -162,38 +204,7 @@ func (c *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
|
||||
case "QUIT":
|
||||
return c.Close()
|
||||
default:
|
||||
c.logger.Printf("unhandled message: %v", msg)
|
||||
return newUnknownCommandError(msg.Command)
|
||||
}
|
||||
}
|
||||
|
||||
func handleConn(s *Server, netConn net.Conn) error {
|
||||
s.Logger.Printf("Handling connection from %v", netConn.RemoteAddr())
|
||||
|
||||
c := downstreamConn{net: netConn, irc: irc.NewConn(netConn), srv: s}
|
||||
defer c.Close()
|
||||
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)
|
||||
}
|
||||
s.Logger.Printf("Downstream message: %v", msg)
|
||||
|
||||
err = c.handleMessage(msg)
|
||||
if ircErr, ok := err.(ircError); ok {
|
||||
ircErr.Message.Prefix = s.prefix()
|
||||
if err := c.WriteMessage(ircErr.Message); err != nil {
|
||||
return fmt.Errorf("failed to write IRC reply: %v", err)
|
||||
}
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("failed to handle IRC command %q: %v", msg.Command, err)
|
||||
}
|
||||
|
||||
if c.closed {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return c.Close()
|
||||
}
|
||||
|
10
server.go
10
server.go
@ -41,6 +41,8 @@ type Server struct {
|
||||
Hostname string
|
||||
Logger Logger
|
||||
Upstreams []Upstream // TODO: per-user
|
||||
|
||||
downstreamConns []*downstreamConn
|
||||
}
|
||||
|
||||
func (s *Server) prefix() *irc.Prefix {
|
||||
@ -61,14 +63,16 @@ func (s *Server) Run() {
|
||||
|
||||
func (s *Server) Serve(ln net.Listener) error {
|
||||
for {
|
||||
c, err := ln.Accept()
|
||||
netConn, err := ln.Accept()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to accept connection: %v", err)
|
||||
}
|
||||
|
||||
conn := newDownstreamConn(s, netConn)
|
||||
s.downstreamConns = append(s.downstreamConns, conn)
|
||||
go func() {
|
||||
if err := handleConn(s, c); err != nil {
|
||||
s.Logger.Printf("Error handling connection: %v", err)
|
||||
if err := conn.readMessages(); err != nil {
|
||||
conn.logger.Printf("Error handling messages: %v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user