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:
parent
6e0ab99d38
commit
965d8efdf8
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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),
|
||||||
|
Loading…
Reference in New Issue
Block a user