hid: figured out how to port timeouts
This commit is contained in:
parent
a6e6c3aaff
commit
e0b46a8cff
84
hid/main.go
84
hid/main.go
@ -761,7 +761,7 @@ var (
|
|||||||
|
|
||||||
config simpleConfig // server configuration
|
config simpleConfig // server configuration
|
||||||
serverName string // our server name
|
serverName string // our server name
|
||||||
pingInterval uint // ping interval in seconds
|
pingInterval time.Duration // ping interval
|
||||||
maxConnections int // max connections allowed or 0
|
maxConnections int // max connections allowed or 0
|
||||||
motd []string // MOTD (none if empty)
|
motd []string // MOTD (none if empty)
|
||||||
operators = make(map[string]bool) // TLS cert. fingerprints for IRCops
|
operators = make(map[string]bool) // TLS cert. fingerprints for IRCops
|
||||||
@ -773,7 +773,7 @@ var (
|
|||||||
prepared = make(chan preparedEvent)
|
prepared = make(chan preparedEvent)
|
||||||
reads = make(chan readEvent)
|
reads = make(chan readEvent)
|
||||||
writes = make(chan writeEvent)
|
writes = make(chan writeEvent)
|
||||||
timeouts = make(chan *client)
|
timers = make(chan func())
|
||||||
|
|
||||||
tlsConf *tls.Config
|
tlsConf *tls.Config
|
||||||
clients = make(map[*client]bool)
|
clients = make(map[*client]bool)
|
||||||
@ -962,12 +962,7 @@ func (c *client) kill(reason string) {
|
|||||||
_ = c.transport.Close()
|
_ = c.transport.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up the goroutine, although a spurious event may still be sent.
|
c.cancelTimers()
|
||||||
// TODO: Other timers if needed.
|
|
||||||
if c.killTimer != nil {
|
|
||||||
c.killTimer.Stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(clients, c)
|
delete(clients, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -994,9 +989,7 @@ func (c *client) closeLink(reason string) {
|
|||||||
c.closing = true
|
c.closing = true
|
||||||
|
|
||||||
c.unregister(reason)
|
c.unregister(reason)
|
||||||
c.killTimer = time.AfterFunc(3*time.Second, func() {
|
c.setKillTimer()
|
||||||
timeouts <- c
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *client) inMaskList(masks []string) bool {
|
func (c *client) inMaskList(masks []string) bool {
|
||||||
@ -1025,7 +1018,57 @@ func (c *client) getTLSCertFingerprint() string {
|
|||||||
|
|
||||||
// --- Timers ------------------------------------------------------------------
|
// --- Timers ------------------------------------------------------------------
|
||||||
|
|
||||||
// TODO
|
// Free the resources of timers that haven't fired yet and for timers that are
|
||||||
|
// in between firing and being collected by the event loop, mark that the event
|
||||||
|
// should not be acted upon.
|
||||||
|
func (c *client) cancelTimers() {
|
||||||
|
for _, timer := range []**time.Timer{
|
||||||
|
&c.killTimer, &c.timeoutTimer, &c.pingTimer,
|
||||||
|
} {
|
||||||
|
if *timer != nil {
|
||||||
|
(*timer).Stop()
|
||||||
|
*timer = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arrange for a function to be called later from the main goroutine.
|
||||||
|
func (c *client) setTimer(timer **time.Timer, delay time.Duration, cb func()) {
|
||||||
|
c.cancelTimers()
|
||||||
|
|
||||||
|
var identityCapture *time.Timer
|
||||||
|
identityCapture = time.AfterFunc(delay, func() {
|
||||||
|
timers <- func() {
|
||||||
|
// The timer might have been cancelled or even replaced.
|
||||||
|
// When the client is killed, this will be nil.
|
||||||
|
if *timer == identityCapture {
|
||||||
|
cb()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
*timer = identityCapture
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) setKillTimer() {
|
||||||
|
c.setTimer(&c.killTimer, pingInterval, func() {
|
||||||
|
c.kill("Timeout")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) setTimeoutTimer() {
|
||||||
|
c.setTimer(&c.timeoutTimer, pingInterval, func() {
|
||||||
|
c.closeLink(fmt.Sprintf("Ping timeout: >%d seconds",
|
||||||
|
pingInterval/time.Second))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) setPingTimer() {
|
||||||
|
c.setTimer(&c.pingTimer, pingInterval, func() {
|
||||||
|
c.sendf("PING :%s", serverName)
|
||||||
|
c.setTimeoutTimer()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// --- IRC command handling ----------------------------------------------------
|
// --- IRC command handling ----------------------------------------------------
|
||||||
|
|
||||||
@ -1451,7 +1494,7 @@ func ircHandlePONG(msg *message, c *client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set a new timer to send another PING
|
// Set a new timer to send another PING
|
||||||
// TODO
|
c.setPingTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
func ircHandleQUIT(msg *message, c *client) {
|
func ircHandleQUIT(msg *message, c *client) {
|
||||||
@ -2817,6 +2860,7 @@ func (c *client) onPrepared(host string, isTLS bool) {
|
|||||||
// If we tried to send any data before now, we would need to flushSendQ.
|
// If we tried to send any data before now, we would need to flushSendQ.
|
||||||
go read(c)
|
go read(c)
|
||||||
c.reading = true
|
c.reading = true
|
||||||
|
c.setPingTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the results from trying to read from the client connection.
|
// Handle the results from trying to read from the client connection.
|
||||||
@ -2996,6 +3040,9 @@ func processOneEvent() {
|
|||||||
case <-quitTimer:
|
case <-quitTimer:
|
||||||
forceQuit("timeout")
|
forceQuit("timeout")
|
||||||
|
|
||||||
|
case callback := <-timers:
|
||||||
|
callback()
|
||||||
|
|
||||||
case conn := <-conns:
|
case conn := <-conns:
|
||||||
if maxConnections > 0 && len(clients) >= maxConnections {
|
if maxConnections > 0 && len(clients) >= maxConnections {
|
||||||
log.Println("connection limit reached, refusing connection")
|
log.Println("connection limit reached, refusing connection")
|
||||||
@ -3026,6 +3073,9 @@ func processOneEvent() {
|
|||||||
clients[c] = true
|
clients[c] = true
|
||||||
go prepare(c)
|
go prepare(c)
|
||||||
|
|
||||||
|
// The TLS autodetection in prepare needs to have a timeout.
|
||||||
|
c.setKillTimer()
|
||||||
|
|
||||||
case ev := <-prepared:
|
case ev := <-prepared:
|
||||||
log.Println("client is ready:", ev.host)
|
log.Println("client is ready:", ev.host)
|
||||||
if _, ok := clients[ev.client]; ok {
|
if _, ok := clients[ev.client]; ok {
|
||||||
@ -3043,12 +3093,6 @@ func processOneEvent() {
|
|||||||
if _, ok := clients[ev.client]; ok {
|
if _, ok := clients[ev.client]; ok {
|
||||||
ev.client.onWrite(ev.written, ev.err)
|
ev.client.onWrite(ev.written, ev.err)
|
||||||
}
|
}
|
||||||
|
|
||||||
case c := <-timeouts:
|
|
||||||
if _, ok := clients[c]; ok {
|
|
||||||
log.Println("client timeouted")
|
|
||||||
c.kill("TODO")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3147,7 +3191,7 @@ func ircParseConfig() error {
|
|||||||
} else if u < 1 {
|
} else if u < 1 {
|
||||||
return "the value is out of range"
|
return "the value is out of range"
|
||||||
} else {
|
} else {
|
||||||
pingInterval = uint(u)
|
pingInterval = time.Second * time.Duration(u)
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user