Remove all instances of undefined numbers (gonmd)

This commit is contained in:
Kristoffer Dalby 2021-11-14 18:31:51 +01:00
parent 796072a5a4
commit 85f28a3f4a
No known key found for this signature in database
GPG key ID: 09F62DC067465735
14 changed files with 78 additions and 42 deletions

View file

@ -29,7 +29,6 @@ linters:
- testpackage
- stylecheck
- wrapcheck
- gomnd
- goerr113
- errorlint
- forcetypeassert

24
acls.go
View file

@ -24,6 +24,14 @@ const (
errorInvalidPortFormat = Error("invalid port format")
)
const (
PORT_RANGE_BEGIN = 0
PORT_RANGE_END = 65535
BASE_10 = 10
BIT_SIZE_16 = 16
EXPECTED_TOKEN_ITEMS = 2
)
// LoadACLPolicy loads the ACL policy from the specify path, and generates the ACL rules.
func (h *Headscale) LoadACLPolicy(path string) error {
policyFile, err := os.Open(path)
@ -114,7 +122,7 @@ func (h *Headscale) generateACLPolicyDestPorts(
d string,
) ([]tailcfg.NetPortRange, error) {
tokens := strings.Split(d, ":")
if len(tokens) < 2 || len(tokens) > 3 {
if len(tokens) < EXPECTED_TOKEN_ITEMS || len(tokens) > 3 {
return nil, errorInvalidPortFormat
}
@ -125,7 +133,7 @@ func (h *Headscale) generateACLPolicyDestPorts(
// tag:montreal-webserver:80,443
// tag:api-server:443
// example-host-1:*
if len(tokens) == 2 {
if len(tokens) == EXPECTED_TOKEN_ITEMS {
alias = tokens[0]
} else {
alias = fmt.Sprintf("%s:%s", tokens[0], tokens[1])
@ -248,14 +256,16 @@ func (h *Headscale) expandAlias(s string) ([]string, error) {
func (h *Headscale) expandPorts(s string) (*[]tailcfg.PortRange, error) {
if s == "*" {
return &[]tailcfg.PortRange{{First: 0, Last: 65535}}, nil
return &[]tailcfg.PortRange{
{First: PORT_RANGE_BEGIN, Last: PORT_RANGE_END},
}, nil
}
ports := []tailcfg.PortRange{}
for _, p := range strings.Split(s, ",") {
rang := strings.Split(p, "-")
if len(rang) == 1 {
pi, err := strconv.ParseUint(rang[0], 10, 16)
pi, err := strconv.ParseUint(rang[0], BASE_10, BIT_SIZE_16)
if err != nil {
return nil, err
}
@ -263,12 +273,12 @@ func (h *Headscale) expandPorts(s string) (*[]tailcfg.PortRange, error) {
First: uint16(pi),
Last: uint16(pi),
})
} else if len(rang) == 2 {
start, err := strconv.ParseUint(rang[0], 10, 16)
} else if len(rang) == EXPECTED_TOKEN_ITEMS {
start, err := strconv.ParseUint(rang[0], BASE_10, BIT_SIZE_16)
if err != nil {
return nil, err
}
last, err := strconv.ParseUint(rang[1], 10, 16)
last, err := strconv.ParseUint(rang[1], BASE_10, BIT_SIZE_16)
if err != nil {
return nil, err
}

22
api.go
View file

@ -18,10 +18,12 @@ import (
"tailscale.com/types/wgkey"
)
const RESERVED_RESPONSE_HEADER_SIZE = 4
// KeyHandler provides the Headscale pub key
// Listens in /key.
func (h *Headscale) KeyHandler(c *gin.Context) {
c.Data(200, "text/plain; charset=utf-8", []byte(h.publicKey.HexString()))
c.Data(http.StatusOK, "text/plain; charset=utf-8", []byte(h.publicKey.HexString()))
}
// RegisterWebAPI shows a simple message in the browser to point to the CLI
@ -139,7 +141,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) {
return
}
c.Data(200, "application/json; charset=utf-8", respBody)
c.Data(http.StatusOK, "application/json; charset=utf-8", respBody)
return
}
@ -170,7 +172,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) {
}
machineRegistrations.WithLabelValues("update", "web", "success", m.Namespace.Name).
Inc()
c.Data(200, "application/json; charset=utf-8", respBody)
c.Data(http.StatusOK, "application/json; charset=utf-8", respBody)
return
}
@ -213,7 +215,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) {
}
machineRegistrations.WithLabelValues("new", "web", "success", m.Namespace.Name).
Inc()
c.Data(200, "application/json; charset=utf-8", respBody)
c.Data(http.StatusOK, "application/json; charset=utf-8", respBody)
return
}
@ -239,7 +241,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) {
return
}
c.Data(200, "application/json; charset=utf-8", respBody)
c.Data(http.StatusOK, "application/json; charset=utf-8", respBody)
return
}
@ -275,7 +277,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) {
return
}
c.Data(200, "application/json; charset=utf-8", respBody)
c.Data(http.StatusOK, "application/json; charset=utf-8", respBody)
}
func (h *Headscale) getMapResponse(
@ -360,7 +362,7 @@ func (h *Headscale) getMapResponse(
}
}
// declare the incoming size on the first 4 bytes
data := make([]byte, 4)
data := make([]byte, RESERVED_RESPONSE_HEADER_SIZE)
binary.LittleEndian.PutUint32(data, uint32(len(respBody)))
data = append(data, respBody...)
@ -390,7 +392,7 @@ func (h *Headscale) getMapKeepAliveResponse(
return nil, err
}
}
data := make([]byte, 4)
data := make([]byte, RESERVED_RESPONSE_HEADER_SIZE)
binary.LittleEndian.PutUint32(data, uint32(len(respBody)))
data = append(data, respBody...)
@ -430,7 +432,7 @@ func (h *Headscale) handleAuthKey(
return
}
c.Data(401, "application/json; charset=utf-8", respBody)
c.Data(http.StatusUnauthorized, "application/json; charset=utf-8", respBody)
log.Error().
Str("func", "handleAuthKey").
Str("machine", m.Name).
@ -490,7 +492,7 @@ func (h *Headscale) handleAuthKey(
}
machineRegistrations.WithLabelValues("new", "authkey", "success", m.Namespace.Name).
Inc()
c.Data(200, "application/json; charset=utf-8", respBody)
c.Data(http.StatusOK, "application/json; charset=utf-8", respBody)
log.Info().
Str("func", "handleAuthKey").
Str("machine", m.Name).

9
app.go
View file

@ -50,6 +50,8 @@ const (
AUTH_PREFIX = "Bearer "
POSTGRESQL = "postgresql"
SQLITE = "sqlite3"
UPDATE_RATE_MILLISECONDS = 5000
HTTP_READ_TIMEOUT = 30 * time.Second
)
// Config contains the initial Headscale configuration.
@ -507,14 +509,13 @@ func (h *Headscale) Serve() error {
}
// I HATE THIS
updateMillisecondsWait := int64(5000)
go h.watchForKVUpdates(updateMillisecondsWait)
go h.expireEphemeralNodes(updateMillisecondsWait)
go h.watchForKVUpdates(UPDATE_RATE_MILLISECONDS)
go h.expireEphemeralNodes(UPDATE_RATE_MILLISECONDS)
httpServer := &http.Server{
Addr: h.cfg.Addr,
Handler: r,
ReadTimeout: 30 * time.Second,
ReadTimeout: HTTP_READ_TIMEOUT,
// Go does not handle timeouts in HTTP very well, and there is
// no good way to handle streaming timeouts, therefore we need to
// keep this at unlimited and be careful to clean up connections

View file

@ -195,7 +195,8 @@ var renameNamespaceCmd = &cobra.Command{
Use: "rename OLD_NAME NEW_NAME",
Short: "Renames a namespace",
Args: func(cmd *cobra.Command, args []string) error {
if len(args) < 2 {
expectedArguments := 2
if len(args) < expectedArguments {
return fmt.Errorf("Missing parameters")
}

View file

@ -7,6 +7,7 @@ import (
"time"
survey "github.com/AlecAivazis/survey/v2"
"github.com/juanfont/headscale"
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
"github.com/pterm/pterm"
"github.com/spf13/cobra"
@ -450,7 +451,7 @@ func nodesToPtables(
d = append(
d,
[]string{
strconv.FormatUint(machine.Id, 10),
strconv.FormatUint(machine.Id, headscale.BASE_10),
machine.Name,
nodeKey.ShortString(),
namespace,

View file

@ -12,6 +12,10 @@ import (
"google.golang.org/protobuf/types/known/timestamppb"
)
const (
DEFAULT_PRE_AUTH_KEY_EXPIRY = 24 * time.Hour
)
func init() {
rootCmd.AddCommand(preauthkeysCmd)
preauthkeysCmd.PersistentFlags().StringP("namespace", "n", "", "Namespace")
@ -27,7 +31,7 @@ func init() {
createPreAuthKeyCmd.PersistentFlags().
Bool("ephemeral", false, "Preauthkey for ephemeral nodes")
createPreAuthKeyCmd.Flags().
DurationP("expiration", "e", 24*time.Hour, "Human-readable expiration of the key (30m, 24h, 365d...)")
DurationP("expiration", "e", DEFAULT_PRE_AUTH_KEY_EXPIRY, "Human-readable expiration of the key (30m, 24h, 365d...)")
}
var preauthkeysCmd = &cobra.Command{

View file

@ -32,7 +32,7 @@ func loadDERPMapFromPath(path string) (*tailcfg.DERPMap, error) {
}
func loadDERPMapFromURL(addr url.URL) (*tailcfg.DERPMap, error) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
ctx, cancel := context.WithTimeout(context.Background(), HTTP_READ_TIMEOUT)
defer cancel()
req, err := http.NewRequestWithContext(ctx, "GET", addr.String(), nil)
@ -41,7 +41,7 @@ func loadDERPMapFromURL(addr url.URL) (*tailcfg.DERPMap, error) {
}
client := http.Client{
Timeout: 10 * time.Second,
Timeout: HTTP_READ_TIMEOUT,
}
resp, err := client.Do(req)

8
dns.go
View file

@ -10,6 +10,10 @@ import (
"tailscale.com/util/dnsname"
)
const (
BYTE_SIZE = 8
)
// generateMagicDNSRootDomains generates a list of DNS entries to be included in `Routes` in `MapResponse`.
// This list of reverse DNS entries instructs the OS on what subnets and domains the Tailscale embedded DNS
// server (listening in 100.100.100.100 udp/53) should be used for.
@ -43,10 +47,10 @@ func generateMagicDNSRootDomains(
maskBits, _ := netRange.Mask.Size()
// lastOctet is the last IP byte covered by the mask
lastOctet := maskBits / 8
lastOctet := maskBits / BYTE_SIZE
// wildcardBits is the number of bits not under the mask in the lastOctet
wildcardBits := 8 - maskBits%8
wildcardBits := BYTE_SIZE - maskBits%BYTE_SIZE
// min is the value in the lastOctet byte of the IP
// max is basically 2^wildcardBits - i.e., the value when all the wildcardBits are set to 1

View file

@ -523,7 +523,7 @@ func (m Machine) toNode(
n := tailcfg.Node{
ID: tailcfg.NodeID(m.ID), // this is the actual ID
StableID: tailcfg.StableNodeID(
strconv.FormatUint(m.ID, 10),
strconv.FormatUint(m.ID, BASE_10),
), // in headscale, unlike tailcontrol server, IDs are permanent
Name: hostname,
User: tailcfg.UserID(m.NamespaceID),

View file

@ -320,7 +320,7 @@ func getMapResponseUserProfiles(m Machine, peers Machines) []tailcfg.UserProfile
func (n *Namespace) toProto() *v1.Namespace {
return &v1.Namespace{
Id: strconv.FormatUint(uint64(n.ID), 10),
Id: strconv.FormatUint(uint64(n.ID), BASE_10),
Name: n.Name,
CreatedAt: timestamppb.New(n.CreatedAt),
}

15
oidc.go
View file

@ -17,6 +17,12 @@ import (
"golang.org/x/oauth2"
)
const (
OIDC_STATE_CACHE_EXPIRATION = time.Minute * 5
OIDC_STATE_CACHE_CLEANUP_INTERVAL = time.Minute * 10
RANDOM_BYTE_SIZE = 16
)
type IDTokenClaims struct {
Name string `json:"name,omitempty"`
Groups []string `json:"groups,omitempty"`
@ -50,7 +56,10 @@ func (h *Headscale) initOIDC() error {
// init the state cache if it hasn't been already
if h.oidcStateCache == nil {
h.oidcStateCache = cache.New(time.Minute*5, time.Minute*10)
h.oidcStateCache = cache.New(
OIDC_STATE_CACHE_EXPIRATION,
OIDC_STATE_CACHE_CLEANUP_INTERVAL,
)
}
return nil
@ -67,7 +76,7 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) {
return
}
b := make([]byte, 16)
b := make([]byte, RANDOM_BYTE_SIZE)
if _, err := rand.Read(b); err != nil {
log.Error().Msg("could not read 16 bytes from rand")
c.String(http.StatusInternalServerError, "could not read 16 bytes from rand")
@ -78,7 +87,7 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) {
stateStr := hex.EncodeToString(b)[:32]
// place the machine key into the state cache, so it can be retrieved later
h.oidcStateCache.Set(stateStr, mKeyStr, time.Minute*5)
h.oidcStateCache.Set(stateStr, mKeyStr, OIDC_STATE_CACHE_EXPIRATION)
authUrl := h.oauth2Config.AuthCodeURL(stateStr)
log.Debug().Msgf("Redirecting to %s for authentication", authUrl)

13
poll.go
View file

@ -15,6 +15,11 @@ import (
"tailscale.com/types/wgkey"
)
const (
KEEP_ALIVE_INTERVAL = 60 * time.Second
UPDATE_CHECK_INTERVAL = 10 * time.Second
)
// PollNetMapHandler takes care of /machine/:id/map
//
// This is the busiest endpoint, as it keeps the HTTP long poll that updates
@ -127,7 +132,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) {
Str("handler", "PollNetMap").
Str("machine", m.Name).
Msg("Client is starting up. Probably interested in a DERP map")
c.Data(200, "application/json; charset=utf-8", data)
c.Data(http.StatusOK, "application/json; charset=utf-8", data)
return
}
@ -159,7 +164,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) {
Str("handler", "PollNetMap").
Str("machine", m.Name).
Msg("Client sent endpoint update and is ok with a response without peer list")
c.Data(200, "application/json; charset=utf-8", data)
c.Data(http.StatusOK, "application/json; charset=utf-8", data)
// It sounds like we should update the nodes when we have received a endpoint update
// even tho the comments in the tailscale code dont explicitly say so.
@ -483,8 +488,8 @@ func (h *Headscale) scheduledPollWorker(
req tailcfg.MapRequest,
m *Machine,
) {
keepAliveTicker := time.NewTicker(60 * time.Second)
updateCheckerTicker := time.NewTicker(10 * time.Second)
keepAliveTicker := time.NewTicker(KEEP_ALIVE_INTERVAL)
updateCheckerTicker := time.NewTicker(UPDATE_CHECK_INTERVAL)
for {
select {

View file

@ -156,7 +156,7 @@ func (h *Headscale) generateKey() (string, error) {
func (key *PreAuthKey) toProto() *v1.PreAuthKey {
protoKey := v1.PreAuthKey{
Namespace: key.Namespace.Name,
Id: strconv.FormatUint(key.ID, 10),
Id: strconv.FormatUint(key.ID, BASE_10),
Key: key.Key,
Ephemeral: key.Ephemeral,
Reusable: key.Reusable,