1
0
mirror of https://github.com/juanfont/headscale.git synced 2025-08-19 13:48:20 +02:00

return regresp or err after waiting for registration

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
Kristoffer Dalby 2025-02-25 10:33:20 +01:00
parent b4e4b79a71
commit 2504f0de4c
No known key found for this signature in database
4 changed files with 26 additions and 15 deletions

View File

@ -43,10 +43,7 @@ func (h *Headscale) handleRegister(
} }
if regReq.Followup != "" { if regReq.Followup != "" {
// TODO(kradalby): Does this need to return an error of some sort? return h.waitForFollowup(ctx, regReq)
// Maybe if the registration fails down the line it can be sent
// on the channel and returned here?
h.waitForFollowup(ctx, regReq)
} }
if regReq.Auth != nil && regReq.Auth.AuthKey != "" { if regReq.Auth != nil && regReq.Auth.AuthKey != "" {
@ -111,42 +108,51 @@ func (h *Headscale) handleExistingNode(
h.nodeNotifier.NotifyWithIgnore(ctx, types.UpdateExpire(node.ID, requestExpiry), node.ID) h.nodeNotifier.NotifyWithIgnore(ctx, types.UpdateExpire(node.ID, requestExpiry), node.ID)
} }
return nodeToRegisterResponse(node), nil
}
func nodeToRegisterResponse(node *types.Node) *tailcfg.RegisterResponse {
return &tailcfg.RegisterResponse{ return &tailcfg.RegisterResponse{
// TODO(kradalby): Only send for user-owned nodes // TODO(kradalby): Only send for user-owned nodes
// and not tagged nodes when tags is working. // and not tagged nodes when tags is working.
User: *node.User.TailscaleUser(), User: *node.User.TailscaleUser(),
Login: *node.User.TailscaleLogin(), Login: *node.User.TailscaleLogin(),
NodeKeyExpired: expired, NodeKeyExpired: node.IsExpired(),
// Headscale does not implement the concept of machine authorization // Headscale does not implement the concept of machine authorization
// so we always return true here. // so we always return true here.
// Revisit this if #2176 gets implemented. // Revisit this if #2176 gets implemented.
MachineAuthorized: true, MachineAuthorized: true,
}, nil }
} }
func (h *Headscale) waitForFollowup( func (h *Headscale) waitForFollowup(
ctx context.Context, ctx context.Context,
regReq tailcfg.RegisterRequest, regReq tailcfg.RegisterRequest,
) { ) (*tailcfg.RegisterResponse, error) {
fu, err := url.Parse(regReq.Followup) fu, err := url.Parse(regReq.Followup)
if err != nil { if err != nil {
return return nil, NewHTTPError(http.StatusUnauthorized, "invalid followup URL", err)
} }
followupReg, err := types.RegistrationIDFromString(strings.ReplaceAll(fu.Path, "/register/", "")) followupReg, err := types.RegistrationIDFromString(strings.ReplaceAll(fu.Path, "/register/", ""))
if err != nil { if err != nil {
return return nil, NewHTTPError(http.StatusUnauthorized, "invalid registration ID", err)
} }
if reg, ok := h.registrationCache.Get(followupReg); ok { if reg, ok := h.registrationCache.Get(followupReg); ok {
select { select {
case <-ctx.Done(): case <-ctx.Done():
return return nil, NewHTTPError(http.StatusUnauthorized, "registration timed out", err)
case <-reg.Registered: case node := <-reg.Registered:
return if node == nil {
return nil, NewHTTPError(http.StatusUnauthorized, "node not found", nil)
}
return nodeToRegisterResponse(node), nil
} }
} }
return nil, NewHTTPError(http.StatusNotFound, "followup registration not found", nil)
} }
// canUsePreAuthKey checks if a pre auth key can be used. // canUsePreAuthKey checks if a pre auth key can be used.
@ -271,7 +277,7 @@ func (h *Headscale) handleRegisterInteractive(
Hostinfo: regReq.Hostinfo, Hostinfo: regReq.Hostinfo,
LastSeen: ptr.To(time.Now()), LastSeen: ptr.To(time.Now()),
}, },
Registered: make(chan struct{}), Registered: make(chan *types.Node),
} }
if !regReq.Expiry.IsZero() { if !regReq.Expiry.IsZero() {

View File

@ -372,7 +372,12 @@ func (hsdb *HSDatabase) HandleNodeFromAuthPath(
} }
// Signal to waiting clients that the machine has been registered. // Signal to waiting clients that the machine has been registered.
select {
case reg.Registered <- node:
default:
}
close(reg.Registered) close(reg.Registered)
newNode = true newNode = true
return node, err return node, err
} else { } else {

View File

@ -838,7 +838,7 @@ func (api headscaleV1APIServer) DebugCreateNode(
Hostinfo: &hostinfo, Hostinfo: &hostinfo,
}, },
Registered: make(chan struct{}), Registered: make(chan *types.Node),
} }
log.Debug(). log.Debug().

View File

@ -194,5 +194,5 @@ func (r RegistrationID) String() string {
type RegisterNode struct { type RegisterNode struct {
Node Node Node Node
Registered chan struct{} Registered chan *Node
} }