From 965d8efdf8efd023acf454b591b13623870afedd Mon Sep 17 00:00:00 2001 From: Jeremy Latt Date: Thu, 13 Feb 2014 13:19:26 -0800 Subject: [PATCH] add a login timout to close dropped connections --- irc/client.go | 33 ++++++++++++++++----------------- irc/constants.go | 7 +++---- irc/net.go | 8 ++++++-- irc/server.go | 1 + 4 files changed, 26 insertions(+), 23 deletions(-) diff --git a/irc/client.go b/irc/client.go index 3b6a955b..ffa943b9 100644 --- a/irc/client.go +++ b/irc/client.go @@ -19,36 +19,31 @@ type Client struct { hostname string idleTimer *time.Timer invisible bool + loginTimer *time.Timer nick string operator bool quitTimer *time.Timer realname string - recv *bufio.Reader registered bool - replies chan<- Reply - send *bufio.Writer + replies chan Reply server *Server serverPass bool username string } func NewClient(server *Server, conn net.Conn) *Client { - replies := make(chan Reply) - client := &Client{ channels: make(ChannelSet), conn: conn, - hostname: AddrLookupHostname(conn.RemoteAddr()), - recv: bufio.NewReader(conn), - replies: replies, - send: bufio.NewWriter(conn), + hostname: IPString(conn.RemoteAddr()), + replies: make(chan Reply), server: server, } + client.loginTimer = time.AfterFunc(LOGIN_TIMEOUT, client.Destroy) go client.readConn() - go client.writeConn(replies) + go client.writeConn() - client.Touch() return client } @@ -89,8 +84,10 @@ func (client *Client) ConnectionClosed() { } func (c *Client) readConn() { + recv := bufio.NewReader(c.conn) + for { - line, err := c.recv.ReadString('\n') + line, err := recv.ReadString('\n') if err != nil { if DEBUG_NET { if err == io.EOF { @@ -138,8 +135,10 @@ func (client *Client) maybeLogWriteError(err error) bool { return false } -func (client *Client) writeConn(replies <-chan Reply) { - for reply := range replies { +func (client *Client) writeConn() { + send := bufio.NewWriter(client.conn) + + for reply := range client.replies { if DEBUG_CLIENT { log.Printf("%s ← %s %s", client, reply.Source(), reply) } @@ -147,13 +146,13 @@ func (client *Client) writeConn(replies <-chan Reply) { if DEBUG_NET { log.Printf("%s ← %s %s", client.conn.RemoteAddr(), client.conn.LocalAddr(), str) } - if _, err := client.send.WriteString(str); client.maybeLogWriteError(err) { + if _, err := send.WriteString(str); client.maybeLogWriteError(err) { break } - if _, err := client.send.WriteString(CRLF); client.maybeLogWriteError(err) { + if _, err := send.WriteString(CRLF); client.maybeLogWriteError(err) { break } - if err := client.send.Flush(); client.maybeLogWriteError(err) { + if err := send.Flush(); client.maybeLogWriteError(err) { break } } diff --git a/irc/constants.go b/irc/constants.go index e68ab1ef..718f3d0a 100644 --- a/irc/constants.go +++ b/irc/constants.go @@ -19,10 +19,9 @@ const ( CRLF = "\r\n" MAX_REPLY_LEN = 512 - len(CRLF) - // how long before a client is considered idle - IDLE_TIMEOUT = time.Minute - // how long after idle before a client is kicked - QUIT_TIMEOUT = time.Minute + LOGIN_TIMEOUT = time.Minute / 2 // how long the client has to login + IDLE_TIMEOUT = time.Minute // how long before a client is considered idle + QUIT_TIMEOUT = time.Minute // how long after idle before a client is kicked // numeric codes RPL_WELCOME = 1 diff --git a/irc/net.go b/irc/net.go index b0eebf78..efadfba3 100644 --- a/irc/net.go +++ b/irc/net.go @@ -5,13 +5,17 @@ import ( "strings" ) -func AddrLookupHostname(addr net.Addr) string { +func IPString(addr net.Addr) string { addrStr := addr.String() ipaddr, _, err := net.SplitHostPort(addrStr) if err != nil { return addrStr } - return LookupHostname(ipaddr) + return ipaddr +} + +func AddrLookupHostname(addr net.Addr) string { + return LookupHostname(IPString(addr)) } func LookupHostname(addr string) string { diff --git a/irc/server.go b/irc/server.go index bcc5ad51..a6e1344b 100644 --- a/irc/server.go +++ b/irc/server.go @@ -147,6 +147,7 @@ func (s *Server) GenerateGuestNick() string { func (s *Server) tryRegister(c *Client) { if !c.registered && c.HasNick() && c.HasUsername() { c.registered = true + c.loginTimer.Stop() c.Reply( RplWelcome(s, c), RplYourHost(s),