From 2db6cf7cce19d5c7800e1dd7a67f98bc9577f702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Thu, 7 May 2026 15:00:07 +0300 Subject: [PATCH 1/6] docs: add docstrings to health monitor and DNS service - health_monitor.go: document runChecks, probeRecord, probeHTTP, probeTCP - dns_service.go: document CreateZone, CreateRecord, Resolve, ListZones, ListRecordsForZone, DeleteZone, DeleteRecord, ImportZone, audit, filterHealthy --- internal/core/services/dns_service.go | 10 ++++++++++ internal/core/services/health_monitor.go | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/internal/core/services/dns_service.go b/internal/core/services/dns_service.go index 7b7b314..017185f 100644 --- a/internal/core/services/dns_service.go +++ b/internal/core/services/dns_service.go @@ -29,6 +29,7 @@ func NewDNSService(repo ports.DNSRepository, cache ports.CacheInvalidator) ports } } +// CreateZone creates a new DNS zone with default SOA and NS records. func (s *dnsService) CreateZone(ctx context.Context, zone *domain.Zone) error { zone.ID = uuid.New().String() zone.CreatedAt = time.Now() @@ -77,6 +78,7 @@ func (s *dnsService) CreateZone(ctx context.Context, zone *domain.Zone) error { return nil } +// CreateRecord creates a new DNS record and invalidates the cache. func (s *dnsService) CreateRecord(ctx context.Context, record *domain.Record) error { record.ID = uuid.New().String() record.CreatedAt = time.Now() @@ -101,6 +103,7 @@ func (s *dnsService) CreateRecord(ctx context.Context, record *domain.Record) er return nil } +// audit logs an action to the audit trail via the repository. func (s *dnsService) audit(ctx context.Context, tenantID, action, resType, resID, details string) { logEntry := &domain.AuditLog{ ID: uuid.New().String(), @@ -116,6 +119,7 @@ func (s *dnsService) audit(ctx context.Context, tenantID, action, resType, resID } } +// Resolve looks up DNS records for a name and type, checking direct and wildcard matches. func (s *dnsService) Resolve(ctx context.Context, name string, qType domain.RecordType, clientIP string) ([]domain.Record, error) { // 1. Direct Match records, err := s.repo.GetRecords(ctx, name, qType, clientIP) @@ -150,6 +154,7 @@ func (s *dnsService) Resolve(ctx context.Context, name string, qType domain.Reco return nil, nil } +// filterHealthy returns only records that are not marked unhealthy, or all records if all are unhealthy. func (s *dnsService) filterHealthy(records []domain.Record) []domain.Record { var healthy []domain.Record for _, rec := range records { @@ -165,14 +170,17 @@ func (s *dnsService) filterHealthy(records []domain.Record) []domain.Record { return healthy } +// ListZones returns all zones belonging to a tenant. func (s *dnsService) ListZones(ctx context.Context, tenantID string) ([]domain.Zone, error) { return s.repo.ListZones(ctx, tenantID) } +// ListRecordsForZone returns all records in a zone for a given tenant. func (s *dnsService) ListRecordsForZone(ctx context.Context, zoneID string, tenantID string) ([]domain.Record, error) { return s.repo.ListRecordsForZone(ctx, zoneID, tenantID) } +// DeleteZone deletes a zone and all its records for a tenant. func (s *dnsService) DeleteZone(ctx context.Context, zoneID string, tenantID string) error { if err := s.repo.DeleteZone(ctx, zoneID, tenantID); err != nil { return err @@ -181,6 +189,7 @@ func (s *dnsService) DeleteZone(ctx context.Context, zoneID string, tenantID str return nil } +// DeleteRecord deletes a DNS record and invalidates the cache. func (s *dnsService) DeleteRecord(ctx context.Context, recordID string, zoneID string, tenantID string) error { // Fetch record details to invalidate the cache record, err := s.repo.GetRecord(ctx, recordID, zoneID, tenantID) @@ -206,6 +215,7 @@ func (s *dnsService) DeleteRecord(ctx context.Context, recordID string, zoneID s return nil } +// ImportZone parses a zone file and imports it for a tenant. func (s *dnsService) ImportZone(ctx context.Context, tenantID string, r io.Reader) (*domain.Zone, error) { parser := master.New() data, err := parser.Parse(r) diff --git a/internal/core/services/health_monitor.go b/internal/core/services/health_monitor.go index 1a823a1..1f600dd 100644 --- a/internal/core/services/health_monitor.go +++ b/internal/core/services/health_monitor.go @@ -64,6 +64,7 @@ func (m *HealthMonitor) Start(ctx context.Context, interval time.Duration) { } } +// runChecks fetches records in batches and probes their health status concurrently. func (m *HealthMonitor) runChecks(ctx context.Context) { const batchSize = 100 @@ -121,6 +122,7 @@ func (m *HealthMonitor) runChecks(ctx context.Context) { } } +// probeRecord checks a record's health and updates its status in the repository. func (m *HealthMonitor) probeRecord(ctx context.Context, rec domain.Record) { var status domain.HealthStatus var errMsg string @@ -139,6 +141,7 @@ func (m *HealthMonitor) probeRecord(ctx context.Context, rec domain.Record) { } } +// probeHTTP performs an HTTP health check and returns status and error message. func (m *HealthMonitor) probeHTTP(ctx context.Context, target string) (domain.HealthStatus, string) { req, err := http.NewRequestWithContext(ctx, http.MethodGet, target, nil) if err != nil { @@ -157,6 +160,7 @@ func (m *HealthMonitor) probeHTTP(ctx context.Context, target string) (domain.He return domain.HealthStatusUnhealthy, fmt.Sprintf("HTTP status: %d", resp.StatusCode) } +// probeTCP attempts a TCP connection func (m *HealthMonitor) probeTCP(ctx context.Context, target string) (domain.HealthStatus, string) { dialer := &net.Dialer{Timeout: 3 * time.Second} conn, err := dialer.DialContext(ctx, "tcp", target) From 33e1099e02528564a5e02e84ffa848f932cc4fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Thu, 7 May 2026 15:00:17 +0300 Subject: [PATCH 2/6] docs: add docstrings to DNS server handlers and utilities Document: generateServerCookie, padResponse, automateDNSSEC, startInvalidationListener, handleDoH, udpWorker, handleUDPConnection, handleTCPConnection, handleAXFR, sendTCPError, handlePacket, handleNotify, handleUpdate, handleIXFR, signResponse, groupRecords, sendSingleRecordResponse, sendUpdateResponse, checkPrerequisite, notifySlaves, generateNSEC, generateNSEC3, generateTypeBitMap, queryTypeToRecordType, refreshZone, performIXFR, performAXFR, newRateLimiter, Allow, fnv32, lockKey --- internal/dns/server/client.go | 3 +++ internal/dns/server/ratelimit.go | 2 ++ internal/dns/server/server.go | 26 ++++++++++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/internal/dns/server/client.go b/internal/dns/server/client.go index 1d69e1f..acc4620 100644 --- a/internal/dns/server/client.go +++ b/internal/dns/server/client.go @@ -13,6 +13,7 @@ import ( "github.com/poyrazK/cloudDNS/internal/dns/packet" ) +// refreshZone initiates a zone refresh for a slave zone by querying the master for SOA. func (s *Server) refreshZone(ctx context.Context, zone *domain.Zone) { if zone.MasterServer == "" { s.Logger.Warn("slave zone has no master server configured", "zone", zone.Name) @@ -80,6 +81,7 @@ func (s *Server) refreshZone(ctx context.Context, zone *domain.Zone) { } } +// performIXFR performs an incremental zone transfer from the master server. func (s *Server) performIXFR(ctx context.Context, zone *domain.Zone, masterAddr string, localSerial uint32) error { conn, err := net.DialTimeout("tcp", masterAddr, 10*time.Second) if err != nil { @@ -257,6 +259,7 @@ func (s *Server) performIXFR(ctx context.Context, zone *domain.Zone, masterAddr return nil } +// performAXFR performs a full zone transfer from the master server. func (s *Server) performAXFR(ctx context.Context, zone *domain.Zone, masterAddr string) error { s.Logger.Info("starting AXFR", "zone", zone.Name, "master", masterAddr) diff --git a/internal/dns/server/ratelimit.go b/internal/dns/server/ratelimit.go index e795be0..63f6792 100644 --- a/internal/dns/server/ratelimit.go +++ b/internal/dns/server/ratelimit.go @@ -47,6 +47,7 @@ func (h *bucketIdleHeap) Pop() any { return item } +// newRateLimiter creates a new rate limiter with the given token rate, burst, and max bucket count. func newRateLimiter(rate float64, burst int, maxBuckets int) *rateLimiter { h := bucketIdleHeap{} heap.Init(&h) @@ -59,6 +60,7 @@ func newRateLimiter(rate float64, burst int, maxBuckets int) *rateLimiter { } } +// Allow checks if a request from the given IP is allowed under the token bucket limits. func (rl *rateLimiter) Allow(ip string) bool { rl.mu.Lock() defer rl.mu.Unlock() diff --git a/internal/dns/server/server.go b/internal/dns/server/server.go index 2619aa2..327c790 100644 --- a/internal/dns/server/server.go +++ b/internal/dns/server/server.go @@ -55,12 +55,14 @@ type cacheLockTable [cacheLockShardCount]cacheLockShard var globalCacheLocks cacheLockTable +// fnv32 returns a 32-bit FNV-1a hash of the key for cache lock sharding. func fnv32(key string) uint32 { h := fnv.New32a() h.Write([]byte(key)) // #nosec G104 return h.Sum32() } +// lockKey returns the cache lock shard for the given key using FNV hashing. func (t *cacheLockTable) lockKey(key string) *cacheLockShard { return &t[fnv32(key)%cacheLockShardCount] } @@ -185,6 +187,7 @@ func NewServer(addr string, repo ports.DNSRepository, logger *slog.Logger) *Serv return s } +// generateServerCookie creates a DNS COOKIE (RFC 9013) server cookie from a client cookie and client IP. func (s *Server) generateServerCookie(clientCookie []byte, clientIP string) []byte { h := hmac.New(sha256.New, s.CookieSecret) h.Write(clientCookie) @@ -192,6 +195,7 @@ func (s *Server) generateServerCookie(clientCookie []byte, clientIP string) []by return h.Sum(nil)[:16] // Return 16 bytes of server cookie } +// padResponse pads a DNS response to a multiple of blockSize for privacy (RFC 9276). func (s *Server) padResponse(response *packet.DNSPacket, blockSize int) { // Find OPT record var opt *packet.DNSRecord @@ -233,6 +237,7 @@ func (s *Server) padResponse(response *packet.DNSPacket, blockSize int) { opt.SetOption(packet.EdnsOptionPadding, padding) } +// automateDNSSEC runs periodic DNSSEC key lifecycle management for all zones. func (s *Server) automateDNSSEC() { ctx := s.lifecycleCtx // Get all zones @@ -248,6 +253,7 @@ func (s *Server) automateDNSSEC() { } } +// startInvalidationListener listens for cache invalidation events from Redis pub/sub. func (s *Server) startInvalidationListener(ctx context.Context) { pubsub := s.Redis.Subscribe(ctx) defer func() { @@ -582,6 +588,7 @@ func (s *Server) Run(ctx context.Context) error { return nil // async shutdown handles cleanup in background } +// handleDoH handles DNS-over-HTTPS requests (RFC 8484). func (s *Server) handleDoH(w http.ResponseWriter, r *http.Request) { var dnsMsg []byte var errDoH error @@ -627,6 +634,7 @@ func (s *Server) handleDoH(w http.ResponseWriter, r *http.Request) { } } +// udpWorker processes UDP DNS tasks from the server's task queue. func (s *Server) udpWorker() { defer s.wg.Done() for { @@ -641,6 +649,7 @@ func (s *Server) udpWorker() { } } +// handleUDPConnection processes a single UDP DNS packet and sends the response back. func (s *Server) handleUDPConnection(ctx context.Context, pc net.PacketConn, addr net.Addr, data []byte) { if errHandle := s.handlePacket(ctx, data, addr, func(resp []byte) error { _, errWrite := pc.WriteTo(resp, addr) @@ -650,6 +659,7 @@ func (s *Server) handleUDPConnection(ctx context.Context, pc net.PacketConn, add } } +// handleTCPConnection reads DNS messages from a TCP connection until the connection closes. func (s *Server) handleTCPConnection(ctx context.Context, conn net.Conn) { defer func() { _ = conn.Close() }() for { @@ -692,6 +702,7 @@ func (s *Server) handleTCPConnection(ctx context.Context, conn net.Conn) { } } +// handleAXFR processes a DNS zone transfer (AXFR) request over TCP. func (s *Server) handleAXFR(ctx context.Context, conn net.Conn, request *packet.DNSPacket, rawData []byte) { q := request.Questions[0] if !strings.HasSuffix(q.Name, ".") { @@ -812,6 +823,7 @@ func (s *Server) sendAXFRRecord(conn net.Conn, id uint16, q packet.DNSQuestion, packet.PutBuffer(resBuffer) } +// sendTCPError sends a TCP DNS error response with the given RCODE. func (s *Server) sendTCPError(conn net.Conn, id uint16, rcode uint8) { response := packet.NewDNSPacket() response.Header.ID = id @@ -826,6 +838,7 @@ func (s *Server) sendTCPError(conn net.Conn, id uint16, rcode uint8) { packet.PutBuffer(resBuffer) } +// handlePacket parses and dispatches a DNS packet to the appropriate handler. func (s *Server) handlePacket(ctx context.Context, data []byte, srcAddr interface{}, sendFn func([]byte) error, protocol string) error { start := time.Now() defer func() { @@ -1283,6 +1296,7 @@ func (s *Server) handlePacket(ctx context.Context, data []byte, srcAddr interfac return sendFn(resData) } +// handleNotify processes a DNS NOTIFY (RFC 1996) and triggers a zone refresh if needed. func (s *Server) handleNotify(ctx context.Context, request *packet.DNSPacket, clientIP string, sendFn func([]byte) error) error { if len(request.Questions) == 0 { s.Logger.Warn("received NOTIFY without questions", "from", clientIP) @@ -1322,6 +1336,7 @@ func (s *Server) handleNotify(ctx context.Context, request *packet.DNSPacket, cl return s.sendUpdateResponse(response, sendFn) } +// handleUpdate processes a DNS dynamic update (RFC 2136) request. func (s *Server) handleUpdate(ctx context.Context, request *packet.DNSPacket, rawData []byte, clientIP string, sendFn func([]byte) error) error { s.Logger.Info("handling dynamic update", "id", request.Header.ID, "client", clientIP) @@ -1438,6 +1453,7 @@ func (s *Server) handleUpdate(ctx context.Context, request *packet.DNSPacket, ra return s.sendUpdateResponse(response, sendFn) } +// handleIXFR processes an incremental zone transfer (IXFR) request over TCP. func (s *Server) handleIXFR(ctx context.Context, conn net.Conn, request *packet.DNSPacket, rawData []byte) { q := request.Questions[0] if !strings.HasSuffix(q.Name, ".") { @@ -1682,6 +1698,7 @@ func (s *Server) handleIXFR(ctx context.Context, conn net.Conn, request *packet. s.Logger.Info("IXFR completed", "zone", zone.Name) } +// signResponse signs a DNS response with the zone's DNSSEC keys. func (s *Server) signResponse(ctx context.Context, zone *domain.Zone, response *packet.DNSPacket) { // Sign Answers if len(response.Answers) > 0 { @@ -1860,6 +1877,7 @@ func (s *Server) fetchDNSKEYFromNetwork(_ context.Context, zoneName string) ([]p return dnskeys, nil } +// groupRecords groups DNS records by name and type for response assembly. func (s *Server) groupRecords(records []packet.DNSRecord) [][]packet.DNSRecord { groups := make(map[string][]packet.DNSRecord) var keys []string @@ -1881,6 +1899,7 @@ func (s *Server) groupRecords(records []packet.DNSRecord) [][]packet.DNSRecord { return res } +// sendSingleRecordResponse sends a TCP DNS response containing a single resource record. func (s *Server) sendSingleRecordResponse(conn net.Conn, id uint16, q packet.DNSQuestion, rec packet.DNSRecord) { resp := packet.NewDNSPacket() resp.Header.ID = id @@ -1899,6 +1918,7 @@ func (s *Server) sendSingleRecordResponse(conn net.Conn, id uint16, q packet.DNS packet.PutBuffer(resBuffer) } +// sendUpdateResponse serializes and sends a DNS UPDATE response. func (s *Server) sendUpdateResponse(resp *packet.DNSPacket, sendFn func([]byte) error) error { resBuffer := packet.GetBuffer() defer packet.PutBuffer(resBuffer) @@ -1913,6 +1933,7 @@ type updateError struct { func (e updateError) Error() string { return e.msg } +// checkPrerequisite evaluates a DNS UPDATE prerequisite record (RFC 2136 Section 2.4). func (s *Server) checkPrerequisite(ctx context.Context, pr packet.DNSRecord) error { qTypeStr := queryTypeToRecordType(pr.Type) records, errRecs := s.Repo.GetRecords(ctx, pr.Name, qTypeStr, "") @@ -2024,6 +2045,7 @@ func (s *Server) prepareUpdate(zoneID string, up packet.DNSRecord) (domain.Updat return op, change, nil } +// notifySlaves sends DNS NOTIFY messages to all slave servers configured for a zone. func (s *Server) notifySlaves(ctx context.Context, zoneName string) { select { case <-ctx.Done(): @@ -2089,6 +2111,7 @@ func (s *Server) notifySlaves(ctx context.Context, zoneName string) { } } +// generateNSEC creates an NSEC record proving no records exist for a name (DNSSEC). func (s *Server) generateNSEC(ctx context.Context, zone *domain.Zone, queryName string) (packet.DNSRecord, error) { iter, errZoneRecs := s.Repo.ListRecordsForZoneStreaming(ctx, zone.ID, zone.TenantID) if errZoneRecs != nil { @@ -2167,6 +2190,7 @@ func (s *Server) generateNSEC(ctx context.Context, zone *domain.Zone, queryName return nsec, nil } +// generateNSEC3 creates an NSEC3 record for a query name (DNSSEC with NSEC3). func (s *Server) generateNSEC3(ctx context.Context, zone *domain.Zone, queryName string, wildcardName string) (packet.DNSRecord, error) { params, errParams := s.Repo.GetRecords(ctx, zone.Name, "NSEC3PARAM", "") if errParams != nil || len(params) == 0 { @@ -2331,6 +2355,7 @@ type hashEntry struct { hash []byte } +// generateTypeBitMap creates the NSEC3 type bitmap window blocks. func (s *Server) generateTypeBitMap(types []domain.RecordType) []byte { bits := make([]byte, 32) maxType := 0 @@ -2362,6 +2387,7 @@ func (s *Server) generateTypeBitMap(types []domain.RecordType) []byte { return res } +// queryTypeToRecordType converts a packet query type to a domain record type. func queryTypeToRecordType(qType packet.QueryType) domain.RecordType { switch qType { case packet.A: From fde23d32e80102693e0fa7a23b74f5f947f6facd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Thu, 7 May 2026 15:00:27 +0300 Subject: [PATCH 3/6] docs: add docstrings to recursive resolver and packet utilities Document: newRecursiveResolver, getShuffledRoots, resolveRecursive, generateTransactionID, sendQuery, sendQueryInternal, sendTCPQuery, findNextNS, setReusePort, countLabels --- internal/dns/packet/dnssec.go | 1 + internal/dns/server/recursive.go | 8 ++++++++ internal/dns/server/reuseport_windows.go | 1 + 3 files changed, 10 insertions(+) diff --git a/internal/dns/packet/dnssec.go b/internal/dns/packet/dnssec.go index 3581cf5..3d23827 100644 --- a/internal/dns/packet/dnssec.go +++ b/internal/dns/packet/dnssec.go @@ -227,6 +227,7 @@ func SignRRSet(records []DNSRecord, privKey any, algorithm uint8, signerName str return sig, nil } +// countLabels returns the number of DNS name labels (e.g., "www.example.com." has 3). func countLabels(name string) int { name = strings.TrimSuffix(name, ".") if name == "" { diff --git a/internal/dns/server/recursive.go b/internal/dns/server/recursive.go index 09079fc..76f188e 100644 --- a/internal/dns/server/recursive.go +++ b/internal/dns/server/recursive.go @@ -22,6 +22,7 @@ type recursiveResolver struct { // Defaults to 30s but can be overridden in tests. var recursiveTimeout = 30 * time.Second +// newRecursiveResolver creates a recursive resolver with IANA root server hints and fallback resolvers. func newRecursiveResolver() *recursiveResolver { return &recursiveResolver{ rootHints: []string{ @@ -46,6 +47,7 @@ func newRecursiveResolver() *recursiveResolver { } } +// getShuffledRoots returns root hints rotated by a random offset for unpredictable ordering. func (r *recursiveResolver) getShuffledRoots() []string { shuffled := make([]string, len(r.rootHints)) copy(shuffled, r.rootHints) @@ -59,6 +61,7 @@ func (r *recursiveResolver) getShuffledRoots() []string { return result } +// resolveRecursive performs iterative DNS resolution starting from root servers. func (s *Server) resolveRecursive(name string, qType packet.QueryType) (*packet.DNSPacket, error) { // Total timeout to prevent indefinite blocking on failing root servers const errRecursiveTimeout = "recursive resolution timeout" @@ -192,16 +195,19 @@ func (s *Server) resolveRecursive(name string, qType packet.QueryType) (*packet. return nil, fmt.Errorf("recursion failed after trying roots and fallbacks: %w", lastErr) } +// generateTransactionID returns a cryptographically random 16-bit DNS transaction ID. func generateTransactionID() uint16 { var id uint16 _ = binary.Read(rand.Reader, binary.BigEndian, &id) return id } +// sendQuery sends a UDP DNS query to the specified server without recursion desired. func (s *Server) sendQuery(server string, name string, qType packet.QueryType) (*packet.DNSPacket, error) { return s.sendQueryInternal(server, name, qType, false) } +// sendQueryInternal sends a DNS query and validates the transaction ID in the response. func (s *Server) sendQueryInternal(server string, name string, qType packet.QueryType, recursive bool) (*packet.DNSPacket, error) { conn, err := net.DialTimeout("udp", server, 5*time.Second) if err != nil { @@ -250,6 +256,7 @@ func (s *Server) sendQueryInternal(server string, name string, qType packet.Quer return resp, nil } +// sendTCPQuery sends a TCP DNS query with a 2-byte length prefix. func (s *Server) sendTCPQuery(server string, name string, qType packet.QueryType) (*packet.DNSPacket, error) { conn, err := net.DialTimeout("tcp", server, 5*time.Second) if err != nil { @@ -297,6 +304,7 @@ func (s *Server) sendTCPQuery(server string, name string, qType packet.QueryType return resp, nil } +// findNextNS extracts the next nameserver address from a DNS response's authority and additional sections. func (s *Server) findNextNS(resp *packet.DNSPacket) (string, bool) { // 1. Look for NS records in the Authority section and their corresponding glue in Additional for _, auth := range resp.Authorities { diff --git a/internal/dns/server/reuseport_windows.go b/internal/dns/server/reuseport_windows.go index a5ade4f..1f08f7e 100644 --- a/internal/dns/server/reuseport_windows.go +++ b/internal/dns/server/reuseport_windows.go @@ -2,6 +2,7 @@ package server +// setReusePort is a no-op on Windows (SO_REUSEPORT is not supported). func setReusePort(fd uintptr) error { return nil } From 2f8d7dcdc8a1f3e6fd26f02d59c1dca03a53e34b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Thu, 7 May 2026 15:00:36 +0300 Subject: [PATCH 4/6] docs: add docstrings to main entry point and routing adapter Document: main, run, getEnvUint32 in cmd/clouddns; Run, handleUnsupportedOS in routing --- cmd/clouddns/main.go | 3 +++ internal/adapters/routing/system_vip.go | 2 ++ 2 files changed, 5 insertions(+) diff --git a/cmd/clouddns/main.go b/cmd/clouddns/main.go index 25394d3..7fefcb7 100644 --- a/cmd/clouddns/main.go +++ b/cmd/clouddns/main.go @@ -26,6 +26,7 @@ import ( "github.com/poyrazK/cloudDNS/internal/infrastructure/metrics" ) +// main is the entry point for the cloudDNS daemon. func main() { ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() @@ -36,6 +37,7 @@ func main() { } } +// run is the main entry point for the cloudDNS daemon, initializing all components. func run(ctx context.Context) error { runCtx, cancel := context.WithCancel(ctx) defer cancel() @@ -352,6 +354,7 @@ func run(ctx context.Context) error { return nil } +// getEnvUint32 returns an environment variable as uint32, or a default if unset/invalid. func getEnvUint32(key string, def uint32) uint32 { val := os.Getenv(key) if val == "" { diff --git a/internal/adapters/routing/system_vip.go b/internal/adapters/routing/system_vip.go index 2ee11db..76b1d47 100644 --- a/internal/adapters/routing/system_vip.go +++ b/internal/adapters/routing/system_vip.go @@ -19,6 +19,7 @@ type commandExecutor interface { type realExecutor struct{} +// Run executes a system command and returns its combined stdout/stderr output. func (e *realExecutor) Run(ctx context.Context, name string, arg ...string) ([]byte, error) { return exec.CommandContext(ctx, name, arg...).CombinedOutput() } @@ -114,6 +115,7 @@ func (a *SystemVIPAdapter) Unbind(ctx context.Context, vip, iface string) error return nil } +// handleUnsupportedOS returns an error indicating the current OS is not supported for VIP management. func (a *SystemVIPAdapter) handleUnsupportedOS() error { return fmt.Errorf("unsupported OS for VIP management: %s", a.os) } From 22d67c5711300aa487a006fcb5cb1138af97ce37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Thu, 7 May 2026 15:13:44 +0300 Subject: [PATCH 5/6] fix: repair probeTCP ctx parameter and syntax error in health_monitor The stash conflict resolution introduced a syntax error ( Date: Thu, 7 May 2026 15:15:12 +0300 Subject: [PATCH 6/6] ci: trigger Go CI