diff --git a/cmd/lns/discovery.go b/cmd/lns/discovery.go index 0e9b0de..193b6c1 100644 --- a/cmd/lns/discovery.go +++ b/cmd/lns/discovery.go @@ -98,6 +98,79 @@ func getChainAliases() []ChainAlias { return aliases } +// ParseDNSFromComment extracts DNS records from an alias comment's dns= field. +// Format: dns=A:@:1.2.3.4,AAAA:@:2001:db8::1,CNAME:www:lthn.io +// +// records := ParseDNSFromComment("v=lthn1;type=user;dns=A:@:10.69.69.165,TXT:@:hello") +func ParseDNSFromComment(comment string) *NameRecord { + parsed := parseAliasComment(comment) + dnsField, hasDNS := parsed["dns"] + if !hasDNS || dnsField == "" { + return nil + } + + record := &NameRecord{} + entries := splitComma(dnsField) + for _, entry := range entries { + parts := splitColon(entry, 3) + if len(parts) < 3 { + continue + } + recordType := parts[0] + value := parts[2] + switch recordType { + case "A": + record.A = append(record.A, value) + case "AAAA": + record.AAAA = append(record.AAAA, value) + case "CNAME": + record.A = append(record.A, value) // CNAME stored as A for resolution + case "TXT": + record.TXT = append(record.TXT, value) + case "NS": + record.NS = append(record.NS, value) + } + } + if len(record.A) == 0 && len(record.AAAA) == 0 && len(record.TXT) == 0 && len(record.NS) == 0 { + return nil + } + return record +} + +func splitComma(input string) []string { + parts := make([]string, 0) + current := "" + for _, character := range input { + if character == ',' { + if current != "" { + parts = append(parts, current) + } + current = "" + } else { + current += string(character) + } + } + if current != "" { + parts = append(parts, current) + } + return parts +} + +func splitColon(input string, maxParts int) []string { + parts := make([]string, 0, maxParts) + current := "" + for _, character := range input { + if character == ':' && len(parts) < maxParts-1 { + parts = append(parts, current) + current = "" + } else { + current += string(character) + } + } + parts = append(parts, current) + return parts +} + // parseAliasComment extracts key=value pairs from a v=lthn1 alias comment. // // parseAliasComment("v=lthn1;type=gateway;cap=vpn,dns") diff --git a/cmd/lns/main.go b/cmd/lns/main.go index 97c669c..bcf4a52 100644 --- a/cmd/lns/main.go +++ b/cmd/lns/main.go @@ -121,18 +121,57 @@ var knownNames = []string{ func syncCache() { root := getTreeRoot() - if root == lastRoot && root != "" { - return - } // Discover names from the main chain, fall back to hardcoded list. - names := discoverNames() + aliases := getChainAliases() + names := make([]string, 0) + aliasMap := make(map[string]ChainAlias) - core.Println(core.Sprintf("[%s] Tree root changed — syncing %d names", time.Now().Format("15:04:05"), len(names))) + if len(aliases) > 0 { + seen := make(map[string]bool) + for _, alias := range aliases { + hnsName := alias.Name + comment := parseAliasComment(alias.Comment) + if hns, ok := comment["hns"]; ok && hns != "" { + stripped := core.TrimSuffix(hns, ".lthn") + if stripped != "" { + hnsName = stripped + } + } + if !seen[hnsName] { + seen[hnsName] = true + names = append(names, hnsName) + aliasMap[hnsName] = alias + } + } + } else { + names = knownNames + } + + dnsCount := 0 + for _, a := range aliases { if core.Contains(a.Comment, "dns=") { dnsCount++ } } + core.Println(core.Sprintf("[%s] Syncing %d names (%d with dns=, %d in aliasMap)", time.Now().Format("15:04:05"), len(names), dnsCount, len(aliasMap))) for _, name := range names { + // Try HSD sidechain first record := getNameRecords(name) if record != nil { cache[name] = record + continue + } + + // Fall back to dns= entries in alias comment + if alias, exists := aliasMap[name]; exists && core.Contains(alias.Comment, "dns=") { + record = ParseDNSFromComment(alias.Comment) + core.Println(core.Sprintf("[dns=] %s comment=%s record=%v", name, alias.Comment, record != nil)) + if record != nil { + record.Name = name + // Add the TXT metadata from the comment itself + comment := alias.Comment + if comment != "" && len(record.TXT) == 0 { + record.TXT = append(record.TXT, comment) + } + cache[name] = record + } } } lastRoot = root diff --git a/lns b/lns index 8041155..fea80a0 100755 Binary files a/lns and b/lns differ