Skip to content

Tailscale server support #5

Description

@Rodrigodd

I am trying to get this project to work with a free account on tailscale.com, but I still haven’t been able to get it working. I am not sure where the problem is, as I couldn’t really tell from the logs. But communication with the DERP server does not appear to be working, I couldn’t find any logs showing data being received from the DERP server, although I did see data being sent and one timeout error.

I tested with a local headscale server, and it worked, but the server and the peer were on the same IP and in the same local network. In that setup, I can at least see the DERP server derp1g.tailscale.com:3478 responding to a STUN request (albeit with an “Unexpected STUN message type” message), while the test with Tailscale’s server results in the DERP server derp1h.tailscale.com:3478 timing out.

My configuration is as follows:

tailscale_auth_key: "<a reusable key generated at https://login.tailscale.com/admin/settings/keys>"
headscale_url: "https://controlplane.tailscale.com"

I’m afraid I can’t share my logs here due to sensitive information, but I can provide them privately if you’re interested.

I fixed two bugs in the code in #4 while testing the project. But I also made the two changes below when testing, but I not sure if they are suitable for upstreaming as they are. One is that /machine/map returns a JSON with PeersChanged instead of Peers, and the other is that my esp32-c3 was running out of memory so I decrease a buffer size from 64KiB to 32KiB:

commit d6540cfcc1aae6db5190b1e0f5ac62751b8b9f07
Author: Rodrigo Batista de Moraes <rodrigobatsmoraes@hotmail.com>
Date:   Sat Dec 13 23:47:27 2025 -0300

    fix: search for PeersChanged

diff --git a/components/tailscale/map_response_parser.cpp b/components/tailscale/map_response_parser.cpp
index e2f5a17..3cee349 100644
--- a/components/tailscale/map_response_parser.cpp
+++ b/components/tailscale/map_response_parser.cpp
@@ -304,7 +304,7 @@ bool parse_map_response_streaming(const char *json, size_t len, MapResponseData
   }
 
   // ========== Extract Peers Array ==========
-  const char* peers_start = find_str(json, end, "\"Peers\":[");
+  const char* peers_start = find_str(json, end, "\"PeersChanged\":[");
   if (peers_start) {
     ESP_LOGI(TAG, "Found Peers section");
 
@@ -562,7 +562,7 @@ bool parse_map_static(const char *json, size_t len, StaticMapResponse &out,
   }
 
   // ========== Extract Peers (with optional filtering) ==========
-  const char* peers_start = find_str(json, end, "\"Peers\":[");
+  const char* peers_start = find_str(json, end, "\"PeersChanged\":[");
   if (peers_start) {
     if (allowed_peers && !allowed_peers->empty()) {
       ESP_LOGI(TAG, "Found Peers section (filtering enabled, up to %d matches)", MAX_PEERS);

commit c62dd686f46db4e7011ca04f85324a9f640443cf
Author: Rodrigo Batista de Moraes <rodrigobatsmoraes@hotmail.com>
Date:   Sat Dec 13 23:46:48 2025 -0300

    fix: decrease buffer size for Http2Session

diff --git a/components/tailscale/http2_session.h b/components/tailscale/http2_session.h
index 287b805..5b76752 100644
--- a/components/tailscale/http2_session.h
+++ b/components/tailscale/http2_session.h
@@ -60,7 +60,7 @@ class Http2Session {
 
   // Streaming JSON parser to extract only Node field (discards 56KB DERPMap)
   JsonStreamParser json_parser_;
-  static constexpr size_t kFilteredBufferSize = 65536;  // 64KB for full MapResponse (Node + Peers + DERPMap)
+  static constexpr size_t kFilteredBufferSize = 32768;  // 32KB for full MapResponse (Node + Peers + DERPMap)
   char filtered_json_buffer_[kFilteredBufferSize];
   bool parsing_json_{false};
   bool json_complete_{false};

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions