14e29a7bee
This is step one in detaching the Database layer from Headscale (h). The ultimate goal is to have all function that does database operations in its own package, and keep the business logic and writing separate. Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
78 lines
2 KiB
Go
78 lines
2 KiB
Go
package hscontrol
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"io"
|
|
"net/http"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
"gorm.io/gorm"
|
|
"tailscale.com/tailcfg"
|
|
"tailscale.com/types/key"
|
|
)
|
|
|
|
// NoisePollNetMapHandler takes care of /machine/:id/map using the Noise protocol
|
|
//
|
|
// 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 (ns *noiseServer) NoisePollNetMapHandler(
|
|
writer http.ResponseWriter,
|
|
req *http.Request,
|
|
) {
|
|
log.Trace().
|
|
Str("handler", "NoisePollNetMap").
|
|
Msg("PollNetMapHandler called")
|
|
|
|
log.Trace().
|
|
Any("headers", req.Header).
|
|
Msg("Headers")
|
|
|
|
body, _ := io.ReadAll(req.Body)
|
|
|
|
mapRequest := tailcfg.MapRequest{}
|
|
if err := json.Unmarshal(body, &mapRequest); err != nil {
|
|
log.Error().
|
|
Caller().
|
|
Err(err).
|
|
Msg("Cannot parse MapRequest")
|
|
http.Error(writer, "Internal error", http.StatusInternalServerError)
|
|
|
|
return
|
|
}
|
|
|
|
ns.nodeKey = mapRequest.NodeKey
|
|
|
|
machine, err := ns.headscale.db.GetMachineByAnyKey(
|
|
ns.conn.Peer(),
|
|
mapRequest.NodeKey,
|
|
key.NodePublic{},
|
|
)
|
|
if err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
log.Warn().
|
|
Str("handler", "NoisePollNetMap").
|
|
Msgf("Ignoring request, cannot find machine with key %s", mapRequest.NodeKey.String())
|
|
http.Error(writer, "Internal error", http.StatusNotFound)
|
|
|
|
return
|
|
}
|
|
log.Error().
|
|
Str("handler", "NoisePollNetMap").
|
|
Msgf("Failed to fetch machine from the database with node key: %s", mapRequest.NodeKey.String())
|
|
http.Error(writer, "Internal error", http.StatusInternalServerError)
|
|
|
|
return
|
|
}
|
|
log.Debug().
|
|
Str("handler", "NoisePollNetMap").
|
|
Str("machine", machine.Hostname).
|
|
Msg("A machine is entering polling via the Noise protocol")
|
|
|
|
ns.headscale.handlePollCommon(writer, req.Context(), machine, mapRequest, true)
|
|
}
|