@@ -43,10 +43,7 @@ func (h *Headscale) handleRegister(
43
43
}
44
44
45
45
if regReq .Followup != "" {
46
- // TODO(kradalby): Does this need to return an error of some sort?
47
- // Maybe if the registration fails down the line it can be sent
48
- // on the channel and returned here?
49
- h .waitForFollowup (ctx , regReq )
46
+ return h .waitForFollowup (ctx , regReq )
50
47
}
51
48
52
49
if regReq .Auth != nil && regReq .Auth .AuthKey != "" {
@@ -117,42 +114,51 @@ func (h *Headscale) handleExistingNode(
117
114
h .nodeNotifier .NotifyWithIgnore (ctx , types .StateUpdateExpire (node .ID , requestExpiry ), node .ID )
118
115
}
119
116
117
+ return nodeToRegisterResponse (node ), nil
118
+ }
119
+
120
+ func nodeToRegisterResponse (node * types.Node ) * tailcfg.RegisterResponse {
120
121
return & tailcfg.RegisterResponse {
121
122
// TODO(kradalby): Only send for user-owned nodes
122
123
// and not tagged nodes when tags is working.
123
124
User : * node .User .TailscaleUser (),
124
125
Login : * node .User .TailscaleLogin (),
125
- NodeKeyExpired : expired ,
126
+ NodeKeyExpired : node . IsExpired () ,
126
127
127
128
// Headscale does not implement the concept of machine authorization
128
129
// so we always return true here.
129
130
// Revisit this if #2176 gets implemented.
130
131
MachineAuthorized : true ,
131
- }, nil
132
+ }
132
133
}
133
134
134
135
func (h * Headscale ) waitForFollowup (
135
136
ctx context.Context ,
136
137
regReq tailcfg.RegisterRequest ,
137
- ) {
138
+ ) ( * tailcfg. RegisterResponse , error ) {
138
139
fu , err := url .Parse (regReq .Followup )
139
140
if err != nil {
140
- return
141
+ return nil , NewHTTPError ( http . StatusUnauthorized , "invalid followup URL" , err )
141
142
}
142
143
143
144
followupReg , err := types .RegistrationIDFromString (strings .ReplaceAll (fu .Path , "/register/" , "" ))
144
145
if err != nil {
145
- return
146
+ return nil , NewHTTPError ( http . StatusUnauthorized , "invalid registration ID" , err )
146
147
}
147
148
148
149
if reg , ok := h .registrationCache .Get (followupReg ); ok {
149
150
select {
150
151
case <- ctx .Done ():
151
- return
152
- case <- reg .Registered :
153
- return
152
+ return nil , NewHTTPError (http .StatusUnauthorized , "registration timed out" , err )
153
+ case node := <- reg .Registered :
154
+ if node == nil {
155
+ return nil , NewHTTPError (http .StatusUnauthorized , "node not found" , nil )
156
+ }
157
+ return nodeToRegisterResponse (node ), nil
154
158
}
155
159
}
160
+
161
+ return nil , NewHTTPError (http .StatusNotFound , "followup registration not found" , nil )
156
162
}
157
163
158
164
// canUsePreAuthKey checks if a pre auth key can be used.
@@ -277,7 +283,7 @@ func (h *Headscale) handleRegisterInteractive(
277
283
Hostinfo : regReq .Hostinfo ,
278
284
LastSeen : ptr .To (time .Now ()),
279
285
},
280
- Registered : make (chan struct {} ),
286
+ Registered : make (chan * types. Node ),
281
287
}
282
288
283
289
if ! regReq .Expiry .IsZero () {
0 commit comments