Skip to content

Commit 094fde3

Browse files
authored
Merge pull request #31 from juanfont/improving-client-startup
Improving how headscale handles the client startup process
2 parents d1be440 + 4be39f9 commit 094fde3

File tree

1 file changed

+35
-15
lines changed

1 file changed

+35
-15
lines changed

api.go

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func (h *Headscale) RegisterWebAPI(c *gin.Context) {
5151
5252
</body>
5353
</html>
54-
54+
5555
`, mKeyStr)))
5656
}
5757

@@ -215,25 +215,44 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) {
215215
return
216216
}
217217

218-
log.Printf("[%s] sending initial map", m.Name)
219-
pollData <- *data
220-
221218
// We update our peers if the client is not sending ReadOnly in the MapRequest
222219
// so we don't distribute its initial request (it comes with
223220
// empty endpoints to peers)
224-
if !req.ReadOnly {
225-
peers, _ := h.getPeers(m)
226-
h.pollMu.Lock()
227-
for _, p := range *peers {
228-
log.Printf("[%s] notifying peer %s (%s)", m.Name, p.Name, p.Addresses[0])
229-
if pUp, ok := h.clientsPolling[uint64(p.ID)]; ok {
230-
pUp <- []byte{}
231-
} else {
232-
log.Printf("[%s] Peer %s does not appear to be polling", m.Name, p.Name)
233-
}
221+
222+
// Details on the protocol can be found in https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L696
223+
log.Printf("[%s] ReadOnly=%t OmitPeers=%t Stream=%t", m.Name, req.ReadOnly, req.OmitPeers, req.Stream)
224+
225+
if req.ReadOnly {
226+
log.Printf("[%s] Client is starting up. Asking for DERP map", m.Name)
227+
c.Data(200, "application/json; charset=utf-8", *data)
228+
return
229+
}
230+
if req.OmitPeers && !req.Stream {
231+
log.Printf("[%s] Client sent endpoint update and is ok with a response without peer list", m.Name)
232+
c.Data(200, "application/json; charset=utf-8", *data)
233+
return
234+
} else if req.OmitPeers && req.Stream {
235+
log.Printf("[%s] Warning, ignoring request, don't know how to handle it", m.Name)
236+
c.String(http.StatusBadRequest, "")
237+
return
238+
}
239+
240+
log.Printf("[%s] Client is ready to access the tailnet", m.Name)
241+
log.Printf("[%s] Sending initial map", m.Name)
242+
pollData <- *data
243+
244+
log.Printf("[%s] Notifying peers", m.Name)
245+
peers, _ := h.getPeers(m)
246+
h.pollMu.Lock()
247+
for _, p := range *peers {
248+
log.Printf("[%s] Notifying peer %s (%s)", m.Name, p.Name, p.Addresses[0])
249+
if pUp, ok := h.clientsPolling[uint64(p.ID)]; ok {
250+
pUp <- []byte{}
251+
} else {
252+
log.Printf("[%s] Peer %s does not appear to be polling", m.Name, p.Name)
234253
}
235-
h.pollMu.Unlock()
236254
}
255+
h.pollMu.Unlock()
237256

238257
go h.keepAlive(cancelKeepAlive, pollData, mKey, req, m)
239258

@@ -290,6 +309,7 @@ func (h *Headscale) keepAlive(cancel chan []byte, pollData chan []byte, mKey wgc
290309
log.Printf("Error generating the keep alive msg: %s", err)
291310
return
292311
}
312+
log.Printf("[%s] Sending keepalive", m.Name)
293313
pollData <- *data
294314
h.pollMu.Unlock()
295315
time.Sleep(60 * time.Second)

0 commit comments

Comments
 (0)