ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
tailscale.c
Go to the documentation of this file.
1
7
10
11#include <string.h>
12
13static bool is_tailscale_hostname(const char *hostname) {
14 if (!hostname) {
15 return false;
16 }
17
18 size_t length = strlen(hostname);
19 if (length > 0 && hostname[length - 1] == '.') {
20 length--;
21 }
22 static const char suffix[] = ".ts.net";
23 size_t suffix_length = sizeof(suffix) - 1;
24 if (length <= suffix_length) {
25 return false;
26 }
27
28 const char *suffix_start = hostname + length - suffix_length;
29 for (size_t i = 0; i < suffix_length; i++) {
30 char actual = suffix_start[i];
31 if (actual >= 'A' && actual <= 'Z') {
32 actual = (char)(actual - 'A' + 'a');
33 }
34 if (actual != suffix[i]) {
35 return false;
36 }
37 }
38 return true;
39}
40
41static bool address_resolves_to_tailscale(const char *address, bool numeric_only) {
42 struct addrinfo hints = {0};
43 hints.ai_family = AF_UNSPEC;
44 hints.ai_flags = numeric_only ? AI_NUMERICHOST : AI_CANONNAME;
45
46 struct addrinfo *results = NULL;
47 if (getaddrinfo(address, NULL, &hints, &results) != 0 || !results) {
48 return false;
49 }
50
51 bool tailscale = results->ai_canonname && is_tailscale_hostname(results->ai_canonname);
52 for (struct addrinfo *entry = results; !tailscale && entry; entry = entry->ai_next) {
53 char hostname[NI_MAXHOST] = {0};
54 if (getnameinfo(entry->ai_addr, (socklen_t)entry->ai_addrlen, hostname, sizeof(hostname), NULL, 0,
55 NI_NAMEREQD) == 0) {
56 tailscale = is_tailscale_hostname(hostname);
57 }
58 }
59 freeaddrinfo(results);
60 return tailscale;
61}
62
63bool is_tailscale_host(const char *address) {
64 if (!address || !address[0]) {
65 return false;
66 }
67 if (is_tailscale_hostname(address)) {
68 return true;
69 }
70
71 bool is_numeric = is_valid_ipv4(address) || is_valid_ipv6(address);
72 bool is_short_hostname = !is_numeric && strchr(address, '.') == NULL;
73 return (is_numeric || is_short_hostname) && address_resolves_to_tailscale(address, is_numeric);
74}
int is_valid_ipv4(const char *ip)
Check if a string is a valid IPv4 address.
Definition ip.c:58
int is_valid_ipv6(const char *ip)
Check if a string is a valid IPv6 address.
Definition ip.c:105
🌍 IP Address Parsing and Formatting Utilities
Cross-platform network headers and socket definitions.
bool is_tailscale_host(const char *address)
Determine whether an address belongs to the local Tailscale tailnet.
Definition tailscale.c:63
Tailscale host identity helpers.