Set timeout, add lastupdate field
This commit makes two reasonably major changes: Set a default timeout for the go HTTP server (which gin uses), which allows us to actually have broken long poll sessions fail so we can have the client re-establish them. The current 10s number is chosen randomly and we need more testing to ensure that the feature work as intended. The second is adding a last updated field to keep track of the last time we had an update that needs to be propagated to all of our clients/nodes. This will be used to keep track of our machines and if they are up to date or need us to push an update.
This commit is contained in:
parent
2f883410d2
commit
57b79aa852
1 changed files with 40 additions and 12 deletions
34
app.go
34
app.go
|
@ -58,7 +58,10 @@ type Headscale struct {
|
||||||
aclPolicy *ACLPolicy
|
aclPolicy *ACLPolicy
|
||||||
aclRules *[]tailcfg.FilterRule
|
aclRules *[]tailcfg.FilterRule
|
||||||
|
|
||||||
clientsPolling sync.Map
|
clientsUpdateChannels sync.Map
|
||||||
|
|
||||||
|
lastStateChangeMutex sync.RWMutex
|
||||||
|
lastStateChange time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHeadscale returns the Headscale app
|
// NewHeadscale returns the Headscale app
|
||||||
|
@ -91,6 +94,7 @@ func NewHeadscale(cfg Config) (*Headscale, error) {
|
||||||
privateKey: privKey,
|
privateKey: privKey,
|
||||||
publicKey: &pubKey,
|
publicKey: &pubKey,
|
||||||
aclRules: &tailcfg.FilterAllowAll, // default allowall
|
aclRules: &tailcfg.FilterAllowAll, // default allowall
|
||||||
|
lastStateChange: time.Now().UTC(),
|
||||||
}
|
}
|
||||||
|
|
||||||
err = h.initDB()
|
err = h.initDB()
|
||||||
|
@ -168,6 +172,13 @@ func (h *Headscale) Serve() error {
|
||||||
go h.watchForKVUpdates(5000)
|
go h.watchForKVUpdates(5000)
|
||||||
go h.expireEphemeralNodes(5000)
|
go h.expireEphemeralNodes(5000)
|
||||||
|
|
||||||
|
s := &http.Server{
|
||||||
|
Addr: h.cfg.Addr,
|
||||||
|
Handler: r,
|
||||||
|
ReadTimeout: 10 * time.Second,
|
||||||
|
WriteTimeout: 10 * time.Second,
|
||||||
|
}
|
||||||
|
|
||||||
if h.cfg.TLSLetsEncryptHostname != "" {
|
if h.cfg.TLSLetsEncryptHostname != "" {
|
||||||
if !strings.HasPrefix(h.cfg.ServerURL, "https://") {
|
if !strings.HasPrefix(h.cfg.ServerURL, "https://") {
|
||||||
log.Warn().Msg("Listening with TLS but ServerURL does not start with https://")
|
log.Warn().Msg("Listening with TLS but ServerURL does not start with https://")
|
||||||
|
@ -182,6 +193,8 @@ func (h *Headscale) Serve() error {
|
||||||
Addr: h.cfg.Addr,
|
Addr: h.cfg.Addr,
|
||||||
TLSConfig: m.TLSConfig(),
|
TLSConfig: m.TLSConfig(),
|
||||||
Handler: r,
|
Handler: r,
|
||||||
|
ReadTimeout: 10 * time.Second,
|
||||||
|
WriteTimeout: 10 * time.Second,
|
||||||
}
|
}
|
||||||
if h.cfg.TLSLetsEncryptChallengeType == "TLS-ALPN-01" {
|
if h.cfg.TLSLetsEncryptChallengeType == "TLS-ALPN-01" {
|
||||||
// Configuration via autocert with TLS-ALPN-01 (https://tools.ietf.org/html/rfc8737)
|
// Configuration via autocert with TLS-ALPN-01 (https://tools.ietf.org/html/rfc8737)
|
||||||
|
@ -206,12 +219,27 @@ func (h *Headscale) Serve() error {
|
||||||
if !strings.HasPrefix(h.cfg.ServerURL, "http://") {
|
if !strings.HasPrefix(h.cfg.ServerURL, "http://") {
|
||||||
log.Warn().Msg("Listening without TLS but ServerURL does not start with http://")
|
log.Warn().Msg("Listening without TLS but ServerURL does not start with http://")
|
||||||
}
|
}
|
||||||
err = r.Run(h.cfg.Addr)
|
err = s.ListenAndServe()
|
||||||
} else {
|
} else {
|
||||||
if !strings.HasPrefix(h.cfg.ServerURL, "https://") {
|
if !strings.HasPrefix(h.cfg.ServerURL, "https://") {
|
||||||
log.Warn().Msg("Listening with TLS but ServerURL does not start with https://")
|
log.Warn().Msg("Listening with TLS but ServerURL does not start with https://")
|
||||||
}
|
}
|
||||||
err = r.RunTLS(h.cfg.Addr, h.cfg.TLSCertPath, h.cfg.TLSKeyPath)
|
err = s.ListenAndServeTLS(h.cfg.TLSCertPath, h.cfg.TLSKeyPath)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Headscale) setLastStateChangeToNow() {
|
||||||
|
h.lastStateChangeMutex.Lock()
|
||||||
|
|
||||||
|
now := time.Now().UTC()
|
||||||
|
h.lastStateChange = now
|
||||||
|
|
||||||
|
h.lastStateChangeMutex.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Headscale) getLastStateChange() time.Time {
|
||||||
|
h.lastStateChangeMutex.RLock()
|
||||||
|
defer h.lastStateChangeMutex.RUnlock()
|
||||||
|
return h.lastStateChange
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue