move derp.go to derp module

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
Kristoffer Dalby 2023-06-06 10:41:30 +02:00 committed by Kristoffer Dalby
parent 2289a2acbf
commit 8c4c4c8633
6 changed files with 57 additions and 56 deletions

View file

@ -24,6 +24,7 @@ import (
"github.com/juanfont/headscale" "github.com/juanfont/headscale"
v1 "github.com/juanfont/headscale/gen/go/headscale/v1" v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
"github.com/juanfont/headscale/hscontrol/db" "github.com/juanfont/headscale/hscontrol/db"
"github.com/juanfont/headscale/hscontrol/derp"
"github.com/juanfont/headscale/hscontrol/policy" "github.com/juanfont/headscale/hscontrol/policy"
"github.com/juanfont/headscale/hscontrol/types" "github.com/juanfont/headscale/hscontrol/types"
"github.com/juanfont/headscale/hscontrol/util" "github.com/juanfont/headscale/hscontrol/util"
@ -59,18 +60,12 @@ var (
) )
const ( const (
AuthPrefix = "Bearer " AuthPrefix = "Bearer "
updateInterval = 5000 updateInterval = 5000
HTTPReadTimeout = 30 * time.Second privateKeyFileMode = 0o600
HTTPShutdownTimeout = 3 * time.Second
privateKeyFileMode = 0o600
registerCacheExpiration = time.Minute * 15 registerCacheExpiration = time.Minute * 15
registerCacheCleanup = time.Minute * 20 registerCacheCleanup = time.Minute * 20
DisabledClientAuth = "disabled"
RelaxedClientAuth = "relaxed"
EnforcedClientAuth = "enforced"
) )
// Headscale represents the base app of the service. // Headscale represents the base app of the service.
@ -241,6 +236,31 @@ func (h *Headscale) expireExpiredMachines(milliSeconds int64) {
} }
} }
// scheduledDERPMapUpdateWorker refreshes the DERPMap stored on the global object
// at a set interval
func (h *Headscale) scheduledDERPMapUpdateWorker(cancelChan <-chan struct{}) {
log.Info().
Dur("frequency", h.cfg.DERP.UpdateFrequency).
Msg("Setting up a DERPMap update worker")
ticker := time.NewTicker(h.cfg.DERP.UpdateFrequency)
for {
select {
case <-cancelChan:
return
case <-ticker.C:
log.Info().Msg("Fetching DERPMap updates")
h.DERPMap = derp.GetDERPMap(h.cfg.DERP)
if h.cfg.DERP.ServerEnabled {
h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region
}
h.setLastStateChangeToNow()
}
}
}
func (h *Headscale) failoverSubnetRoutes(milliSeconds int64) { func (h *Headscale) failoverSubnetRoutes(milliSeconds int64) {
ticker := time.NewTicker(time.Duration(milliSeconds) * time.Millisecond) ticker := time.NewTicker(time.Duration(milliSeconds) * time.Millisecond)
for range ticker.C { for range ticker.C {
@ -455,7 +475,7 @@ func (h *Headscale) Serve() error {
var err error var err error
// Fetch an initial DERP Map before we start serving // Fetch an initial DERP Map before we start serving
h.DERPMap = GetDERPMap(h.cfg.DERP) h.DERPMap = derp.GetDERPMap(h.cfg.DERP)
if h.cfg.DERP.ServerEnabled { if h.cfg.DERP.ServerEnabled {
// When embedded DERP is enabled we always need a STUN server // When embedded DERP is enabled we always need a STUN server
@ -615,7 +635,7 @@ func (h *Headscale) Serve() error {
httpServer := &http.Server{ httpServer := &http.Server{
Addr: h.cfg.Addr, Addr: h.cfg.Addr,
Handler: router, Handler: router,
ReadTimeout: HTTPReadTimeout, ReadTimeout: types.HTTPReadTimeout,
// Go does not handle timeouts in HTTP very well, and there is // Go does not handle timeouts in HTTP very well, and there is
// no good way to handle streaming timeouts, therefore we need to // no good way to handle streaming timeouts, therefore we need to
// keep this at unlimited and be careful to clean up connections // keep this at unlimited and be careful to clean up connections
@ -645,7 +665,7 @@ func (h *Headscale) Serve() error {
promHTTPServer := &http.Server{ promHTTPServer := &http.Server{
Addr: h.cfg.MetricsAddr, Addr: h.cfg.MetricsAddr,
Handler: promMux, Handler: promMux,
ReadTimeout: HTTPReadTimeout, ReadTimeout: types.HTTPReadTimeout,
WriteTimeout: 0, WriteTimeout: 0,
} }
@ -709,7 +729,7 @@ func (h *Headscale) Serve() error {
// Gracefully shut down servers // Gracefully shut down servers
ctx, cancel := context.WithTimeout( ctx, cancel := context.WithTimeout(
context.Background(), context.Background(),
HTTPShutdownTimeout, types.HTTPShutdownTimeout,
) )
if err := promHTTPServer.Shutdown(ctx); err != nil { if err := promHTTPServer.Shutdown(ctx); err != nil {
log.Error().Err(err).Msg("Failed to shutdown prometheus http") log.Error().Err(err).Msg("Failed to shutdown prometheus http")
@ -792,7 +812,7 @@ func (h *Headscale) getTLSSettings() (*tls.Config, error) {
server := &http.Server{ server := &http.Server{
Addr: h.cfg.TLS.LetsEncrypt.Listen, Addr: h.cfg.TLS.LetsEncrypt.Listen,
Handler: certManager.HTTPHandler(http.HandlerFunc(h.redirect)), Handler: certManager.HTTPHandler(http.HandlerFunc(h.redirect)),
ReadTimeout: HTTPReadTimeout, ReadTimeout: types.HTTPReadTimeout,
} }
go func() { go func() {

View file

@ -1,4 +1,4 @@
package hscontrol package derp
import ( import (
"context" "context"
@ -7,7 +7,6 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
"time"
"github.com/juanfont/headscale/hscontrol/types" "github.com/juanfont/headscale/hscontrol/types"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
@ -32,7 +31,7 @@ func loadDERPMapFromPath(path string) (*tailcfg.DERPMap, error) {
} }
func loadDERPMapFromURL(addr url.URL) (*tailcfg.DERPMap, error) { func loadDERPMapFromURL(addr url.URL) (*tailcfg.DERPMap, error) {
ctx, cancel := context.WithTimeout(context.Background(), HTTPReadTimeout) ctx, cancel := context.WithTimeout(context.Background(), types.HTTPReadTimeout)
defer cancel() defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, addr.String(), nil) req, err := http.NewRequestWithContext(ctx, http.MethodGet, addr.String(), nil)
@ -41,7 +40,7 @@ func loadDERPMapFromURL(addr url.URL) (*tailcfg.DERPMap, error) {
} }
client := http.Client{ client := http.Client{
Timeout: HTTPReadTimeout, Timeout: types.HTTPReadTimeout,
} }
resp, err := client.Do(req) resp, err := client.Do(req)
@ -133,26 +132,3 @@ func GetDERPMap(cfg types.DERPConfig) *tailcfg.DERPMap {
return derpMap return derpMap
} }
func (h *Headscale) scheduledDERPMapUpdateWorker(cancelChan <-chan struct{}) {
log.Info().
Dur("frequency", h.cfg.DERP.UpdateFrequency).
Msg("Setting up a DERPMap update worker")
ticker := time.NewTicker(h.cfg.DERP.UpdateFrequency)
for {
select {
case <-cancelChan:
return
case <-ticker.C:
log.Info().Msg("Fetching DERPMap updates")
h.DERPMap = GetDERPMap(h.cfg.DERP)
if h.cfg.DERP.ServerEnabled {
h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region
}
h.setLastStateChangeToNow()
}
}
}

View file

@ -7,6 +7,7 @@ import (
"net/http" "net/http"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/juanfont/headscale/hscontrol/types"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"golang.org/x/net/http2" "golang.org/x/net/http2"
"golang.org/x/net/http2/h2c" "golang.org/x/net/http2/h2c"
@ -100,12 +101,12 @@ func (h *Headscale) NoiseUpgradeHandler(
router.HandleFunc("/machine/map", noiseServer.NoisePollNetMapHandler) router.HandleFunc("/machine/map", noiseServer.NoisePollNetMapHandler)
server := http.Server{ server := http.Server{
ReadTimeout: HTTPReadTimeout, ReadTimeout: types.HTTPReadTimeout,
} }
noiseServer.httpBaseConfig = &http.Server{ noiseServer.httpBaseConfig = &http.Server{
Handler: router, Handler: router,
ReadHeaderTimeout: HTTPReadTimeout, ReadHeaderTimeout: types.HTTPReadTimeout,
} }
noiseServer.http2Server = &http2.Server{} noiseServer.http2Server = &http2.Server{}

View file

@ -23,12 +23,6 @@ import (
) )
const ( const (
TlsALPN01ChallengeType = "TLS-ALPN-01"
Http01ChallengeType = "HTTP-01"
JSONLogFormat = "json"
TextLogFormat = "text"
defaultOIDCExpiryTime = 180 * 24 * time.Hour // 180 Days defaultOIDCExpiryTime = 180 * 24 * time.Hour // 180 Days
maxDuration time.Duration = 1<<63 - 1 maxDuration time.Duration = 1<<63 - 1
) )

16
hscontrol/types/const.go Normal file
View file

@ -0,0 +1,16 @@
package types
import "time"
const (
HTTPReadTimeout = 30 * time.Second
HTTPShutdownTimeout = 3 * time.Second
TlsALPN01ChallengeType = "TLS-ALPN-01"
Http01ChallengeType = "HTTP-01"
JSONLogFormat = "json"
TextLogFormat = "text"
KeepAliveInterval = 60 * time.Second
MaxHostnameLength = 255
)

View file

@ -17,12 +17,6 @@ import (
"tailscale.com/types/key" "tailscale.com/types/key"
) )
const (
// TODO(kradalby): Move out of here when we got circdeps under control.
keepAliveInterval = 60 * time.Second
MaxHostnameLength = 255
)
var ( var (
ErrMachineAddressesInvalid = errors.New("failed to parse machine addresses") ErrMachineAddressesInvalid = errors.New("failed to parse machine addresses")
ErrHostnameTooLong = errors.New("hostname too long") ErrHostnameTooLong = errors.New("hostname too long")
@ -160,7 +154,7 @@ func (machine *Machine) IsOnline() bool {
return false return false
} }
return machine.LastSeen.After(time.Now().Add(-keepAliveInterval)) return machine.LastSeen.After(time.Now().Add(-KeepAliveInterval))
} }
// IsEphemeral returns if the machine is registered as an Ephemeral node. // IsEphemeral returns if the machine is registered as an Ephemeral node.