3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-12-22 18:52:41 +01:00

add a login timout to close dropped connections

This commit is contained in:
Jeremy Latt 2014-02-13 13:19:26 -08:00
parent 6e0ab99d38
commit 965d8efdf8
4 changed files with 26 additions and 23 deletions

View File

@ -19,36 +19,31 @@ type Client struct {
hostname string hostname string
idleTimer *time.Timer idleTimer *time.Timer
invisible bool invisible bool
loginTimer *time.Timer
nick string nick string
operator bool operator bool
quitTimer *time.Timer quitTimer *time.Timer
realname string realname string
recv *bufio.Reader
registered bool registered bool
replies chan<- Reply replies chan Reply
send *bufio.Writer
server *Server server *Server
serverPass bool serverPass bool
username string username string
} }
func NewClient(server *Server, conn net.Conn) *Client { func NewClient(server *Server, conn net.Conn) *Client {
replies := make(chan Reply)
client := &Client{ client := &Client{
channels: make(ChannelSet), channels: make(ChannelSet),
conn: conn, conn: conn,
hostname: AddrLookupHostname(conn.RemoteAddr()), hostname: IPString(conn.RemoteAddr()),
recv: bufio.NewReader(conn), replies: make(chan Reply),
replies: replies,
send: bufio.NewWriter(conn),
server: server, server: server,
} }
client.loginTimer = time.AfterFunc(LOGIN_TIMEOUT, client.Destroy)
go client.readConn() go client.readConn()
go client.writeConn(replies) go client.writeConn()
client.Touch()
return client return client
} }
@ -89,8 +84,10 @@ func (client *Client) ConnectionClosed() {
} }
func (c *Client) readConn() { func (c *Client) readConn() {
recv := bufio.NewReader(c.conn)
for { for {
line, err := c.recv.ReadString('\n') line, err := recv.ReadString('\n')
if err != nil { if err != nil {
if DEBUG_NET { if DEBUG_NET {
if err == io.EOF { if err == io.EOF {
@ -138,8 +135,10 @@ func (client *Client) maybeLogWriteError(err error) bool {
return false return false
} }
func (client *Client) writeConn(replies <-chan Reply) { func (client *Client) writeConn() {
for reply := range replies { send := bufio.NewWriter(client.conn)
for reply := range client.replies {
if DEBUG_CLIENT { if DEBUG_CLIENT {
log.Printf("%s ← %s %s", client, reply.Source(), reply) log.Printf("%s ← %s %s", client, reply.Source(), reply)
} }
@ -147,13 +146,13 @@ func (client *Client) writeConn(replies <-chan Reply) {
if DEBUG_NET { if DEBUG_NET {
log.Printf("%s ← %s %s", client.conn.RemoteAddr(), client.conn.LocalAddr(), str) 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 break
} }
if _, err := client.send.WriteString(CRLF); client.maybeLogWriteError(err) { if _, err := send.WriteString(CRLF); client.maybeLogWriteError(err) {
break break
} }
if err := client.send.Flush(); client.maybeLogWriteError(err) { if err := send.Flush(); client.maybeLogWriteError(err) {
break break
} }
} }

View File

@ -19,10 +19,9 @@ const (
CRLF = "\r\n" CRLF = "\r\n"
MAX_REPLY_LEN = 512 - len(CRLF) MAX_REPLY_LEN = 512 - len(CRLF)
// how long before a client is considered idle LOGIN_TIMEOUT = time.Minute / 2 // how long the client has to login
IDLE_TIMEOUT = time.Minute IDLE_TIMEOUT = time.Minute // how long before a client is considered idle
// how long after idle before a client is kicked QUIT_TIMEOUT = time.Minute // how long after idle before a client is kicked
QUIT_TIMEOUT = time.Minute
// numeric codes // numeric codes
RPL_WELCOME = 1 RPL_WELCOME = 1

View File

@ -5,13 +5,17 @@ import (
"strings" "strings"
) )
func AddrLookupHostname(addr net.Addr) string { func IPString(addr net.Addr) string {
addrStr := addr.String() addrStr := addr.String()
ipaddr, _, err := net.SplitHostPort(addrStr) ipaddr, _, err := net.SplitHostPort(addrStr)
if err != nil { if err != nil {
return addrStr return addrStr
} }
return LookupHostname(ipaddr) return ipaddr
}
func AddrLookupHostname(addr net.Addr) string {
return LookupHostname(IPString(addr))
} }
func LookupHostname(addr string) string { func LookupHostname(addr string) string {

View File

@ -147,6 +147,7 @@ func (s *Server) GenerateGuestNick() string {
func (s *Server) tryRegister(c *Client) { func (s *Server) tryRegister(c *Client) {
if !c.registered && c.HasNick() && c.HasUsername() { if !c.registered && c.HasNick() && c.HasUsername() {
c.registered = true c.registered = true
c.loginTimer.Stop()
c.Reply( c.Reply(
RplWelcome(s, c), RplWelcome(s, c),
RplYourHost(s), RplYourHost(s),