Skip to main content

Source facts

Repository
ffsshhttiikk/opencode-agents-skills
Last source activity
February 28, 2026 at 22:49
Detected SKILL.md language
English
Stars
3
Forks
2

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
dns
description
DNS protocol and domain name resolution
category
networking
difficulty
intermediate
tags
["dns","domain","resolution","nameserver"]
author
OpenCode Community
version
1
last_updated
2024-01-15T00:00:00.000Z
# DNS (Domain Name System) ## What I Do I am DNS, the hierarchical naming system translating human-readable domain names into machine-readable IP addresses. I provide distributed, scalable hostname resolution through a global network of authoritative name servers, recursive resolvers, and caching servers. I support multiple record types (A, AAAA, CNAME, MX, TXT, NS, SRV) for various purposes. I implement caching at multiple levels to improve performance and reduce load. I support DNSSEC for authenticated responses, DNS-over-HTTPS for encrypted queries, and dynamic updates for real-time record management. I form the foundation of internet addressing, enabling users to access services using memorable names rather than numeric IP addresses. ## When to Use Me - Implementing custom DNS resolution - Configuring DNS records for services - Building DNS-based service discovery - DNS troubleshooting and diagnostics - High-availability DNS infrastructure - DNS-based load balancing (GeoDNS, latency-based) - Domain registration and management - DNSSEC implementation - Private DNS zones ## Core Concepts **Record Types**: A (IPv4), AAAA (IPv6), CNAME (alias), MX (mail), TXT (text), NS (nameserver), SRV (service), SOA (authority). **DNS Hierarchy**: Root servers → TLD servers → Authoritative servers → Recursive resolvers. **Caching**: TTL (Time to Live) controlling how long records are cached. **Zones**: Portions of the DNS namespace managed by authoritative servers. **DNSSEC**: DNS Security Extensions providing authentication for DNS responses. **Anycast**: Multiple servers sharing the same IP for geographic distribution. **Round-Robin**: Multiple IP addresses rotated for load distribution. ## Code Examples ### Example 1: DNS Client with Cache (Python) ```python import socket import struct import time import threading from typing import Optional, Dict, List from dataclasses import dataclass, field from enum import Enum class DNSRecordType(Enum): A = 1 AAAA = 28 CNAME = 5 MX = 15 NS = 2 TXT = 16 SOA = 6 SRV = 33 @dataclass class DNSRecord: name: str rtype: DNSRecordType rdata: str ttl: int timestamp: float = field(default_factory=time.time) class DNSCache: def __init__(self, max_size: int = 1000, default_ttl: int = 300): self.cache: Dict[str, List[DNSRecord]] = {} self.lock = threading.RLock() self.max_size = max_size self.default_ttl = default_ttl def get(self, name: str, rtype: DNSRecordType) -> Optional[List[DNSRecord]]: with self.lock: key = f"{name}:{rtype.name}" if key not in self.cache: return None records = self.cache[key] now = time.time() valid = [r for r in records if r.ttl == 0 or (now - r.timestamp) < r.ttl] if not valid: del self.cache[key] return None if len(valid) < len(records): self.cache[key] = valid return valid def set(self, name: str, rtype: DNSRecordType, records: List[DNSRecord]): with self.lock: key = f"{name}:{rtype.name}" if len(self.cache) >= self.max_size: self.evict_oldest() self.cache[key] = records def evict_oldest(self): if not self.cache: return oldest_key = min(self.cache.keys(), key=lambda k: min(r.timestamp for r in self.cache[k])) del self.cache[oldest_key] def clear(self): with self.lock: self.cache.clear() def get_stats(self) -> Dict: with self.lock: return { 'entries': len(self.cache), 'records': sum(len(v) for v in self.cache.values()) } class DNSClient: DNS_SERVER = '8.8.8.8' DNS_PORT = 53 TIMEOUT = 5.0 def __init__(self, server: str = None, cache: DNSCache = None): self.server = server or self.DNS_SERVER self.cache = cache or DNSCache() self.socket = None def _create_socket(self): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.settimeout(self.TIMEOUT) return sock def resolve(self, name: str, rtype: DNSRecordType = DNSRecordType.A, use_cache: bool = True) -> List[DNSRecord]: if use_cache: cached = self.cache.get(name, rtype) if cached: return cached records = self._query(name, rtype) if use_cache and records: self.cache.set(name, rtype, records) return records def _query(self, name: str, rtype: DNSRecordType) -> List[DNSRecord]]: sock = self._create_socket() try: # Build DNS query transaction_id = struct.pack("!H", 0x1234) flags = struct.pack("!H", 0x0100) # Standard query, RD=1 qdcount = struct.pack("!H", 1) ancount = struct.pack("!H", 0) nscount = struct.pack("!H", 0) arcount = struct.pack("!H", 0) # Encode domain name qname = b'' for label in name.split('.'): qname += struct.pack("!B", len(label)) + label.encode() qname += b'\x00' # Question type and class qtype = struct.pack("!H", rtype.value) qclass = struct.pack("!H", 1) # IN class query = transaction_id + flags + qdcount nscount + + ancount + arcount + qname + qtype + qclass sock.sendto(query, (self.server, self.DNS_PORT)) response = sock.recv(512) finally: sock.close() return self._parse_response(response, name) def _parse_response(self, response: bytes, original_name: str) -> List[DNSRecord]: records = [] transaction_id = struct.unpack("!H", response[0:2])[0] flags = struct.unpack("!H", response[2:4])[0] qdcount = struct.unpack("!H", response[4:6])[0] ancount = struct.unpack("!H", response[6:8])[0] offset = 12 # Skip question section for _ in range(qdcount): while response[offset] != 0: offset += 1 + response[offset] offset += 5 # Parse answer records for _ in range(ancount): name, offset = self._parse_name(response, offset) rtype = DNSRecordType(struct.unpack("!H", response[offset:offset+2])[0]) offset += 2 rclass = struct.unpack("!H", response[offset:offset+2])[0] offset += 2 ttl = struct.unpack("!I", response[offset:offset+4])[0] offset += 4 rdlength = struct.unpack("!H", response[offset:offset+2])[0] offset += 2 rdata = response[offset:offset+rdlength] offset += rdlength parsed_rdata = self._parse_rdata(rdata, rtype, original_name) records.append(DNSRecord( name=name, rtype=rtype, rdata=parsed_rdata, ttl=ttl )) return records def _parse_name(self, response: bytes, offset: int) -> (str, int): name = [] original_offset = offset while True: length = response[offset] if length == 0: offset += 1 break if (length & 0xC0) == 0xC0: # Compression pointer pointer = struct.unpack("!H", response[offset:offset+2])[0] & 0x3FFF pointed_name, _ = self._parse_name(response, pointer) name.append(pointed_name) offset += 2 break else: offset += 1 name.append(response[offset:offset+length].decode()) offset += length return '.'.join(name), offset def _parse_rdata(self, rdata: bytes, rtype: DNSRecordType, original_name: str) -> str: if rtype == DNSRecordType.A: return '.'.join(str(b) for b in rdata) elif rtype == DNSRecordType.AAAA: return ':'.join(f'{b:02x}{b+1:02x}' for b in rdata[::2]) elif rtype == DNSRecordType.CNAME: name, _ = self._parse_name(rdata, 0) return name elif rtype == DNSRecordType.MX: preference = struct.unpack("!H", rdata[0:2])[0] name, _ = self._parse_name(rdata, 2) return f"{preference} {name}" elif rtype == DNSRecordType.TXT: length = rdata[0] return rdata[1:1+length].decode('utf-8') else: return rdata.hex() def resolve_a(self, name: str, use_cache: bool = True) -> List[str]: records = self.resolve(name, DNSRecordType.A, use_cache) return [r.rdata for r in records] def resolve_aaaa(self, name: str, use_cache: bool = True) -> List[str]: records = self.resolve(name, DNSRecordType.AAAA, use_cache) return [r.rdata for r in records] def resolve_mx(self, name: str, use_cache: bool = True) -> List[tuple]: records = self.resolve(name, DNSRecordType.MX, use_cache) return [(int(r.rdata.split()[0]), r.rdata.split()[1]) for r in records] def resolve_txt(self, name: str, use_cache: bool = True) -> List[str]: records = self.resolve(name, DNSRecordType.TXT, use_cache) return [r.rdata for r in records] if __name__ == "__main__": client = DNSClient() # Resolve various record types print("Resolving A records for google.com:") a_records = client.resolve_a("google.com") for ip in a_records: print(f" {ip}") print("\nResolving MX records for example.com:") mx_records = client.resolve_mx("example.com") for pref, server in mx_records: print(f" Priority {pref}: {server}") print("\nCache statistics:") print(client.cache.get_stats()) ``` ### Example 2: DNS Server with Zone Files (Go) ```go package main import ( "bufio" "bytes" "encoding/json" "fmt" "log" "net" "os" "strings" "sync" "time" ) type DNSRecord struct { Name string Type string RData string TTL int } type Zone struct { Origin string Records []DNSRecord SOA DNSRecord mutex sync.RWMutex } type DNSServer struct { zones map[string]*Zone cache map[string][]DNSRecord cacheMutex sync.RWMutex udpSocket *net.UDPConn tcpListener *net.TCPListener } const ( TYPE_A = 1 TYPE_NS = 2 TYPE_CNAME = 5 TYPE_SOA = 6 TYPE_PTR = 12 TYPE_MX = 15 TYPE_TXT = 16 TYPE_AAAA = 28 TYPE_SRV = 33 ) func NewDNSServer() *DNSServer { return &DNSServer{ zones: make(map[string]*Zone), cache: make(map[string][]DNSRecord), } } func (s *DNSServer) LoadZoneFile(filename string, origin string) error { file, err := os.Open(filename) if err != nil { return fmt.Errorf("failed to open zone file: %w", err) } defer file.Close() zone := &Zone{ Origin: origin, Records: make([]DNSRecord, 0), } scanner := bufio.NewScanner(file) for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) if line == "" || strings.HasPrefix(line, ";") { continue } parts := strings.Fields(line) if len(parts) < 5 { continue } record := DNSRecord{ Name: parts[0], Type: strings.ToUpper(parts[2]), RData: strings.Join(parts[4:], " "), TTL: 3600, } if parts[1] != "IN" { continue } zone.Records = append(zone.Records, record) } s.zones[origin] = zone return nil } func (s *DNSServer) StartUDP(address string) error { addr, err := net.ResolveUDPAddr("udp", address) if err != nil { return fmt.Errorf("failed to resolve address: %w", err) } s.udpSocket, err = net.ListenUDP("udp", addr) if err != nil { return fmt.Errorf("failed to listen: %w", err) } go s.handleUDP() return nil } func (s *DNSServer) StartTCP(address string) error { addr, err := net.ResolveTCPAddr("tcp", address) if err != nil { return fmt.Errorf("failed to resolve address: %w", err) } s.tcpListener, err = net.ListenTCP("tcp", addr) if err != nil { return fmt.Errorf("failed to listen: %w", err) } go s.handleTCP() return nil } func (s *DNSServer) handleUDP() { buffer := make([]byte, 512) for { n, clientAddr, err := s.udpSocket.ReadFromUDP(buffer)
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub