mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-10-28 10:51:44 +01:00 
			
		
		
		
	Working on common codebase for poll, starting with legacy
This commit is contained in:
		
							parent
							
								
									f4bab6b290
								
							
						
					
					
						commit
						df8ecdb603
					
				@ -2,17 +2,12 @@ package headscale
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"io"
 | 
					 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/gorilla/mux"
 | 
					 | 
				
			||||||
	"github.com/rs/zerolog/log"
 | 
						"github.com/rs/zerolog/log"
 | 
				
			||||||
	"gorm.io/gorm"
 | 
					 | 
				
			||||||
	"tailscale.com/tailcfg"
 | 
						"tailscale.com/tailcfg"
 | 
				
			||||||
	"tailscale.com/types/key"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@ -23,83 +18,13 @@ type contextKey string
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const machineNameContextKey = contextKey("machineName")
 | 
					const machineNameContextKey = contextKey("machineName")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PollNetMapHandler takes care of /machine/:id/map
 | 
					func (h *Headscale) handlePollCommon(
 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// This is the busiest endpoint, as it keeps the HTTP long poll that updates
 | 
					 | 
				
			||||||
// the clients when something in the network changes.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// The clients POST stuff like HostInfo and their Endpoints here, but
 | 
					 | 
				
			||||||
// only after their first request (marked with the ReadOnly field).
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// At this moment the updates are sent in a quite horrendous way, but they kinda work.
 | 
					 | 
				
			||||||
func (h *Headscale) PollNetMapHandler(
 | 
					 | 
				
			||||||
	writer http.ResponseWriter,
 | 
						writer http.ResponseWriter,
 | 
				
			||||||
	req *http.Request,
 | 
						req *http.Request,
 | 
				
			||||||
 | 
						machine *Machine,
 | 
				
			||||||
 | 
						mapRequest tailcfg.MapRequest,
 | 
				
			||||||
 | 
						isNoise bool,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
	vars := mux.Vars(req)
 | 
					 | 
				
			||||||
	machineKeyStr, ok := vars["mkey"]
 | 
					 | 
				
			||||||
	if !ok || machineKeyStr == "" {
 | 
					 | 
				
			||||||
		log.Error().
 | 
					 | 
				
			||||||
			Str("handler", "PollNetMap").
 | 
					 | 
				
			||||||
			Msg("No machine key in request")
 | 
					 | 
				
			||||||
		http.Error(writer, "No machine key in request", http.StatusBadRequest)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	log.Trace().
 | 
					 | 
				
			||||||
		Str("handler", "PollNetMap").
 | 
					 | 
				
			||||||
		Str("id", machineKeyStr).
 | 
					 | 
				
			||||||
		Msg("PollNetMapHandler called")
 | 
					 | 
				
			||||||
	body, _ := io.ReadAll(req.Body)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var machineKey key.MachinePublic
 | 
					 | 
				
			||||||
	err := machineKey.UnmarshalText([]byte(MachinePublicKeyEnsurePrefix(machineKeyStr)))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Error().
 | 
					 | 
				
			||||||
			Str("handler", "PollNetMap").
 | 
					 | 
				
			||||||
			Err(err).
 | 
					 | 
				
			||||||
			Msg("Cannot parse client key")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		http.Error(writer, "Cannot parse client key", http.StatusBadRequest)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	mapRequest := tailcfg.MapRequest{}
 | 
					 | 
				
			||||||
	err = decode(body, &mapRequest, &machineKey, h.privateKey)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Error().
 | 
					 | 
				
			||||||
			Str("handler", "PollNetMap").
 | 
					 | 
				
			||||||
			Err(err).
 | 
					 | 
				
			||||||
			Msg("Cannot decode message")
 | 
					 | 
				
			||||||
		http.Error(writer, "Cannot decode message", http.StatusBadRequest)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	machine, err := h.GetMachineByMachineKey(machineKey)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		if errors.Is(err, gorm.ErrRecordNotFound) {
 | 
					 | 
				
			||||||
			log.Warn().
 | 
					 | 
				
			||||||
				Str("handler", "PollNetMap").
 | 
					 | 
				
			||||||
				Msgf("Ignoring request, cannot find machine with key %s", machineKey.String())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			http.Error(writer, "", http.StatusUnauthorized)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		log.Error().
 | 
					 | 
				
			||||||
			Str("handler", "PollNetMap").
 | 
					 | 
				
			||||||
			Msgf("Failed to fetch machine from the database with Machine key: %s", machineKey.String())
 | 
					 | 
				
			||||||
		http.Error(writer, "", http.StatusInternalServerError)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	log.Trace().
 | 
					 | 
				
			||||||
		Str("handler", "PollNetMap").
 | 
					 | 
				
			||||||
		Str("id", machineKeyStr).
 | 
					 | 
				
			||||||
		Str("machine", machine.Hostname).
 | 
					 | 
				
			||||||
		Msg("Found machine in database")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	machine.Hostname = mapRequest.Hostinfo.Hostname
 | 
						machine.Hostname = mapRequest.Hostinfo.Hostname
 | 
				
			||||||
	machine.HostInfo = HostInfo(*mapRequest.Hostinfo)
 | 
						machine.HostInfo = HostInfo(*mapRequest.Hostinfo)
 | 
				
			||||||
	machine.DiscoKey = DiscoPublicKeyStripPrefix(mapRequest.DiscoKey)
 | 
						machine.DiscoKey = DiscoPublicKeyStripPrefix(mapRequest.DiscoKey)
 | 
				
			||||||
@ -107,7 +32,7 @@ func (h *Headscale) PollNetMapHandler(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// update ACLRules with peer informations (to update server tags if necessary)
 | 
						// update ACLRules with peer informations (to update server tags if necessary)
 | 
				
			||||||
	if h.aclPolicy != nil {
 | 
						if h.aclPolicy != nil {
 | 
				
			||||||
		err = h.UpdateACLRules()
 | 
							err := h.UpdateACLRules()
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			log.Error().
 | 
								log.Error().
 | 
				
			||||||
				Caller().
 | 
									Caller().
 | 
				
			||||||
@ -133,7 +58,7 @@ func (h *Headscale) PollNetMapHandler(
 | 
				
			|||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			log.Error().
 | 
								log.Error().
 | 
				
			||||||
				Str("handler", "PollNetMap").
 | 
									Str("handler", "PollNetMap").
 | 
				
			||||||
				Str("id", machineKeyStr).
 | 
									Str("node_key", machine.NodeKey).
 | 
				
			||||||
				Str("machine", machine.Hostname).
 | 
									Str("machine", machine.Hostname).
 | 
				
			||||||
				Err(err).
 | 
									Err(err).
 | 
				
			||||||
				Msg("Failed to persist/update machine in the database")
 | 
									Msg("Failed to persist/update machine in the database")
 | 
				
			||||||
@ -143,11 +68,11 @@ func (h *Headscale) PollNetMapHandler(
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data, err := h.getLegacyMapResponseData(machineKey, mapRequest, machine)
 | 
						mapResp, err := h.getMapResponseData(mapRequest, machine, isNoise)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Error().
 | 
							log.Error().
 | 
				
			||||||
			Str("handler", "PollNetMap").
 | 
								Str("handler", "PollNetMap").
 | 
				
			||||||
			Str("id", machineKeyStr).
 | 
								Str("node_key", machine.NodeKey).
 | 
				
			||||||
			Str("machine", machine.Hostname).
 | 
								Str("machine", machine.Hostname).
 | 
				
			||||||
			Err(err).
 | 
								Err(err).
 | 
				
			||||||
			Msg("Failed to get Map response")
 | 
								Msg("Failed to get Map response")
 | 
				
			||||||
@ -163,7 +88,6 @@ func (h *Headscale) PollNetMapHandler(
 | 
				
			|||||||
	// Details on the protocol can be found in https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L696
 | 
						// Details on the protocol can be found in https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L696
 | 
				
			||||||
	log.Debug().
 | 
						log.Debug().
 | 
				
			||||||
		Str("handler", "PollNetMap").
 | 
							Str("handler", "PollNetMap").
 | 
				
			||||||
		Str("id", machineKeyStr).
 | 
					 | 
				
			||||||
		Str("machine", machine.Hostname).
 | 
							Str("machine", machine.Hostname).
 | 
				
			||||||
		Bool("readOnly", mapRequest.ReadOnly).
 | 
							Bool("readOnly", mapRequest.ReadOnly).
 | 
				
			||||||
		Bool("omitPeers", mapRequest.OmitPeers).
 | 
							Bool("omitPeers", mapRequest.OmitPeers).
 | 
				
			||||||
@ -178,7 +102,7 @@ func (h *Headscale) PollNetMapHandler(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		writer.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
							writer.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
				
			||||||
		writer.WriteHeader(http.StatusOK)
 | 
							writer.WriteHeader(http.StatusOK)
 | 
				
			||||||
		_, err := writer.Write(data)
 | 
							_, err := writer.Write(mapResp)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			log.Error().
 | 
								log.Error().
 | 
				
			||||||
				Caller().
 | 
									Caller().
 | 
				
			||||||
@ -186,6 +110,10 @@ func (h *Headscale) PollNetMapHandler(
 | 
				
			|||||||
				Msg("Failed to write response")
 | 
									Msg("Failed to write response")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if f, ok := writer.(http.Flusher); ok {
 | 
				
			||||||
 | 
								f.Flush()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -198,8 +126,7 @@ func (h *Headscale) PollNetMapHandler(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// Only create update channel if it has not been created
 | 
						// Only create update channel if it has not been created
 | 
				
			||||||
	log.Trace().
 | 
						log.Trace().
 | 
				
			||||||
		Str("handler", "PollNetMap").
 | 
							Caller().
 | 
				
			||||||
		Str("id", machineKeyStr).
 | 
					 | 
				
			||||||
		Str("machine", machine.Hostname).
 | 
							Str("machine", machine.Hostname).
 | 
				
			||||||
		Msg("Loading or creating update channel")
 | 
							Msg("Loading or creating update channel")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -218,7 +145,7 @@ func (h *Headscale) PollNetMapHandler(
 | 
				
			|||||||
			Msg("Client sent endpoint update and is ok with a response without peer list")
 | 
								Msg("Client sent endpoint update and is ok with a response without peer list")
 | 
				
			||||||
		writer.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
							writer.Header().Set("Content-Type", "application/json; charset=utf-8")
 | 
				
			||||||
		writer.WriteHeader(http.StatusOK)
 | 
							writer.WriteHeader(http.StatusOK)
 | 
				
			||||||
		_, err := writer.Write(data)
 | 
							_, err := writer.Write(mapResp)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			log.Error().
 | 
								log.Error().
 | 
				
			||||||
				Caller().
 | 
									Caller().
 | 
				
			||||||
@ -250,7 +177,7 @@ func (h *Headscale) PollNetMapHandler(
 | 
				
			|||||||
		Str("handler", "PollNetMap").
 | 
							Str("handler", "PollNetMap").
 | 
				
			||||||
		Str("machine", machine.Hostname).
 | 
							Str("machine", machine.Hostname).
 | 
				
			||||||
		Msg("Sending initial map")
 | 
							Msg("Sending initial map")
 | 
				
			||||||
	pollDataChan <- data
 | 
						pollDataChan <- mapResp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	log.Info().
 | 
						log.Info().
 | 
				
			||||||
		Str("handler", "PollNetMap").
 | 
							Str("handler", "PollNetMap").
 | 
				
			||||||
@ -260,35 +187,34 @@ func (h *Headscale) PollNetMapHandler(
 | 
				
			|||||||
		Inc()
 | 
							Inc()
 | 
				
			||||||
	updateChan <- struct{}{}
 | 
						updateChan <- struct{}{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	h.PollNetMapStream(
 | 
						h.pollNetMapStream(
 | 
				
			||||||
		writer,
 | 
							writer,
 | 
				
			||||||
		req,
 | 
							req,
 | 
				
			||||||
		machine,
 | 
							machine,
 | 
				
			||||||
		mapRequest,
 | 
							mapRequest,
 | 
				
			||||||
		machineKey,
 | 
					 | 
				
			||||||
		pollDataChan,
 | 
							pollDataChan,
 | 
				
			||||||
		keepAliveChan,
 | 
							keepAliveChan,
 | 
				
			||||||
		updateChan,
 | 
							updateChan,
 | 
				
			||||||
 | 
							isNoise,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	log.Trace().
 | 
						log.Trace().
 | 
				
			||||||
		Str("handler", "PollNetMap").
 | 
							Str("handler", "PollNetMap").
 | 
				
			||||||
		Str("id", machineKeyStr).
 | 
					 | 
				
			||||||
		Str("machine", machine.Hostname).
 | 
							Str("machine", machine.Hostname).
 | 
				
			||||||
		Msg("Finished stream, closing PollNetMap session")
 | 
							Msg("Finished stream, closing PollNetMap session")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PollNetMapStream takes care of /machine/:id/map
 | 
					// pollNetMapStream stream logic for /machine/map,
 | 
				
			||||||
// stream logic, ensuring we communicate updates and data
 | 
					// ensuring we communicate updates and data to the connected clients.
 | 
				
			||||||
// to the connected clients.
 | 
					func (h *Headscale) pollNetMapStream(
 | 
				
			||||||
func (h *Headscale) PollNetMapStream(
 | 
					 | 
				
			||||||
	writer http.ResponseWriter,
 | 
						writer http.ResponseWriter,
 | 
				
			||||||
	req *http.Request,
 | 
						req *http.Request,
 | 
				
			||||||
	machine *Machine,
 | 
						machine *Machine,
 | 
				
			||||||
	mapRequest tailcfg.MapRequest,
 | 
						mapRequest tailcfg.MapRequest,
 | 
				
			||||||
	machineKey key.MachinePublic,
 | 
					 | 
				
			||||||
	pollDataChan chan []byte,
 | 
						pollDataChan chan []byte,
 | 
				
			||||||
	keepAliveChan chan []byte,
 | 
						keepAliveChan chan []byte,
 | 
				
			||||||
	updateChan chan struct{},
 | 
						updateChan chan struct{},
 | 
				
			||||||
 | 
						isNoise bool,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
	h.pollNetMapStreamWG.Add(1)
 | 
						h.pollNetMapStreamWG.Add(1)
 | 
				
			||||||
	defer h.pollNetMapStreamWG.Done()
 | 
						defer h.pollNetMapStreamWG.Done()
 | 
				
			||||||
@ -302,9 +228,9 @@ func (h *Headscale) PollNetMapStream(
 | 
				
			|||||||
		ctx,
 | 
							ctx,
 | 
				
			||||||
		updateChan,
 | 
							updateChan,
 | 
				
			||||||
		keepAliveChan,
 | 
							keepAliveChan,
 | 
				
			||||||
		machineKey,
 | 
					 | 
				
			||||||
		mapRequest,
 | 
							mapRequest,
 | 
				
			||||||
		machine,
 | 
							machine,
 | 
				
			||||||
 | 
							isNoise,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	log.Trace().
 | 
						log.Trace().
 | 
				
			||||||
@ -491,7 +417,7 @@ func (h *Headscale) PollNetMapStream(
 | 
				
			|||||||
					Time("last_successful_update", lastUpdate).
 | 
										Time("last_successful_update", lastUpdate).
 | 
				
			||||||
					Time("last_state_change", h.getLastStateChange(machine.Namespace.Name)).
 | 
										Time("last_state_change", h.getLastStateChange(machine.Namespace.Name)).
 | 
				
			||||||
					Msgf("There has been updates since the last successful update to %s", machine.Hostname)
 | 
										Msgf("There has been updates since the last successful update to %s", machine.Hostname)
 | 
				
			||||||
				data, err := h.getLegacyMapResponseData(machineKey, mapRequest, machine)
 | 
									data, err := h.getMapResponseData(mapRequest, machine, false)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					log.Error().
 | 
										log.Error().
 | 
				
			||||||
						Str("handler", "PollNetMapStream").
 | 
											Str("handler", "PollNetMapStream").
 | 
				
			||||||
@ -637,9 +563,9 @@ func (h *Headscale) scheduledPollWorker(
 | 
				
			|||||||
	ctx context.Context,
 | 
						ctx context.Context,
 | 
				
			||||||
	updateChan chan struct{},
 | 
						updateChan chan struct{},
 | 
				
			||||||
	keepAliveChan chan []byte,
 | 
						keepAliveChan chan []byte,
 | 
				
			||||||
	machineKey key.MachinePublic,
 | 
					 | 
				
			||||||
	mapRequest tailcfg.MapRequest,
 | 
						mapRequest tailcfg.MapRequest,
 | 
				
			||||||
	machine *Machine,
 | 
						machine *Machine,
 | 
				
			||||||
 | 
						isNoise bool,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
	keepAliveTicker := time.NewTicker(keepAliveInterval)
 | 
						keepAliveTicker := time.NewTicker(keepAliveInterval)
 | 
				
			||||||
	updateCheckerTicker := time.NewTicker(h.cfg.NodeUpdateCheckInterval)
 | 
						updateCheckerTicker := time.NewTicker(h.cfg.NodeUpdateCheckInterval)
 | 
				
			||||||
@ -661,7 +587,7 @@ func (h *Headscale) scheduledPollWorker(
 | 
				
			|||||||
			return
 | 
								return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case <-keepAliveTicker.C:
 | 
							case <-keepAliveTicker.C:
 | 
				
			||||||
			data, err := h.getMapKeepAliveResponse(machineKey, mapRequest)
 | 
								data, err := h.getMapKeepAliveResponseData(mapRequest, machine, isNoise)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				log.Error().
 | 
									log.Error().
 | 
				
			||||||
					Str("func", "keepAlive").
 | 
										Str("func", "keepAlive").
 | 
				
			||||||
							
								
								
									
										94
									
								
								protocol_legacy_poll.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								protocol_legacy_poll.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,94 @@
 | 
				
			|||||||
 | 
					package headscale
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/gorilla/mux"
 | 
				
			||||||
 | 
						"github.com/rs/zerolog/log"
 | 
				
			||||||
 | 
						"gorm.io/gorm"
 | 
				
			||||||
 | 
						"tailscale.com/tailcfg"
 | 
				
			||||||
 | 
						"tailscale.com/types/key"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PollNetMapHandler takes care of /machine/:id/map
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This is the busiest endpoint, as it keeps the HTTP long poll that updates
 | 
				
			||||||
 | 
					// the clients when something in the network changes.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The clients POST stuff like HostInfo and their Endpoints here, but
 | 
				
			||||||
 | 
					// only after their first request (marked with the ReadOnly field).
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// At this moment the updates are sent in a quite horrendous way, but they kinda work.
 | 
				
			||||||
 | 
					func (h *Headscale) PollNetMapHandler(
 | 
				
			||||||
 | 
						writer http.ResponseWriter,
 | 
				
			||||||
 | 
						req *http.Request,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
						vars := mux.Vars(req)
 | 
				
			||||||
 | 
						machineKeyStr, ok := vars["mkey"]
 | 
				
			||||||
 | 
						if !ok || machineKeyStr == "" {
 | 
				
			||||||
 | 
							log.Error().
 | 
				
			||||||
 | 
								Str("handler", "PollNetMap").
 | 
				
			||||||
 | 
								Msg("No machine key in request")
 | 
				
			||||||
 | 
							http.Error(writer, "No machine key in request", http.StatusBadRequest)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						log.Trace().
 | 
				
			||||||
 | 
							Str("handler", "PollNetMap").
 | 
				
			||||||
 | 
							Str("id", machineKeyStr).
 | 
				
			||||||
 | 
							Msg("PollNetMapHandler called")
 | 
				
			||||||
 | 
						body, _ := io.ReadAll(req.Body)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var machineKey key.MachinePublic
 | 
				
			||||||
 | 
						err := machineKey.UnmarshalText([]byte(MachinePublicKeyEnsurePrefix(machineKeyStr)))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Error().
 | 
				
			||||||
 | 
								Str("handler", "PollNetMap").
 | 
				
			||||||
 | 
								Err(err).
 | 
				
			||||||
 | 
								Msg("Cannot parse client key")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							http.Error(writer, "Cannot parse client key", http.StatusBadRequest)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						mapRequest := tailcfg.MapRequest{}
 | 
				
			||||||
 | 
						err = decode(body, &mapRequest, &machineKey, h.privateKey)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Error().
 | 
				
			||||||
 | 
								Str("handler", "PollNetMap").
 | 
				
			||||||
 | 
								Err(err).
 | 
				
			||||||
 | 
								Msg("Cannot decode message")
 | 
				
			||||||
 | 
							http.Error(writer, "Cannot decode message", http.StatusBadRequest)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						machine, err := h.GetMachineByMachineKey(machineKey)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							if errors.Is(err, gorm.ErrRecordNotFound) {
 | 
				
			||||||
 | 
								log.Warn().
 | 
				
			||||||
 | 
									Str("handler", "PollNetMap").
 | 
				
			||||||
 | 
									Msgf("Ignoring request, cannot find machine with key %s", machineKey.String())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								http.Error(writer, "", http.StatusUnauthorized)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							log.Error().
 | 
				
			||||||
 | 
								Str("handler", "PollNetMap").
 | 
				
			||||||
 | 
								Msgf("Failed to fetch machine from the database with Machine key: %s", machineKey.String())
 | 
				
			||||||
 | 
							http.Error(writer, "", http.StatusInternalServerError)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						log.Trace().
 | 
				
			||||||
 | 
							Str("handler", "PollNetMap").
 | 
				
			||||||
 | 
							Str("id", machineKeyStr).
 | 
				
			||||||
 | 
							Str("machine", machine.Hostname).
 | 
				
			||||||
 | 
							Msg("Found machine in database")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						h.handlePollCommon(writer, req, machine, mapRequest, false)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user