mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
This commit extends the documentation effort by adding detailed explanatory comments to key CLI components and core functionality throughout the cmd/ directory. The changes focus on explaining WHY certain logic is needed, not just WHAT the code does, improving code maintainability and helping developers understand complex business decisions. Key improvements: - Main entry points: Document CLI initialization, logging setup, and cache configuration with reasoning for design decisions - DNS proxy core: Explain DNS proxy constants, data structures, and core processing pipeline for handling DNS queries - Service management: Document service command structure, configuration patterns, and platform-specific service handling - Logging infrastructure: Explain log buffer management, level encoders, and log formatting decisions for different use cases - Metrics and monitoring: Document Prometheus metrics structure, HTTP endpoints, and conditional metric collection for performance - Network handling: Explain Linux-specific network interface filtering, virtual interface detection, and DNS configuration management - Hostname validation: Document RFC1123 compliance and DNS naming standards for system compatibility - Mobile integration: Explain HTTP retry logic, fallback mechanisms, and mobile platform integration patterns - Connection management: Document connection wrapper design to prevent log pollution during process lifecycle Technical details: - Added explanatory comments to 11 additional files in cmd/cli/ - Maintained consistent documentation style and format - Preserved all existing functionality while improving code clarity - Enhanced understanding of complex business logic and platform-specific behavior These comments help future developers understand the reasoning behind complex decisions, making the codebase more maintainable and reducing the risk of incorrect modifications during maintenance.
110 lines
3.4 KiB
Go
110 lines
3.4 KiB
Go
package cli
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
// AppCallback provides hooks for injecting certain functionalities
|
|
// from mobile platforms to main ctrld cli.
|
|
// This allows mobile applications to customize behavior without modifying core CLI code
|
|
type AppCallback struct {
|
|
HostName func() string
|
|
LanIp func() string
|
|
MacAddress func() string
|
|
Exit func(error string)
|
|
}
|
|
|
|
// AppConfig allows overwriting ctrld cli flags from mobile platforms.
|
|
// This provides a clean interface for mobile apps to configure ctrld behavior
|
|
type AppConfig struct {
|
|
CdUID string
|
|
HomeDir string
|
|
UpstreamProto string
|
|
Verbose int
|
|
LogPath string
|
|
}
|
|
|
|
// Network and HTTP configuration constants
|
|
const (
|
|
// defaultHTTPTimeout provides reasonable timeout for HTTP operations
|
|
// This prevents hanging requests while allowing sufficient time for network delays
|
|
defaultHTTPTimeout = 30 * time.Second
|
|
|
|
// defaultMaxRetries provides retry attempts for failed HTTP requests
|
|
// This improves reliability in unstable network conditions
|
|
defaultMaxRetries = 3
|
|
|
|
// downloadServerIp is the fallback IP for download operations
|
|
// This ensures downloads work even when DNS resolution fails
|
|
downloadServerIp = "23.171.240.151"
|
|
)
|
|
|
|
// httpClientWithFallback returns an HTTP client configured with timeout and IPv4 fallback
|
|
// This ensures reliable HTTP operations by preferring IPv4 and handling timeouts gracefully
|
|
func httpClientWithFallback(timeout time.Duration) *http.Client {
|
|
return &http.Client{
|
|
Timeout: timeout,
|
|
Transport: &http.Transport{
|
|
// Prefer IPv4 over IPv6
|
|
// This improves compatibility with networks that have IPv6 issues
|
|
DialContext: (&net.Dialer{
|
|
Timeout: 10 * time.Second,
|
|
KeepAlive: 30 * time.Second,
|
|
FallbackDelay: 1 * time.Millisecond, // Very small delay to prefer IPv4
|
|
}).DialContext,
|
|
},
|
|
}
|
|
}
|
|
|
|
// doWithRetry performs an HTTP request with retries
|
|
// This improves reliability by automatically retrying failed requests with exponential backoff
|
|
func doWithRetry(req *http.Request, maxRetries int, ip string) (*http.Response, error) {
|
|
var lastErr error
|
|
client := httpClientWithFallback(defaultHTTPTimeout)
|
|
var ipReq *http.Request
|
|
if ip != "" {
|
|
ipReq = req.Clone(req.Context())
|
|
ipReq.Host = ip
|
|
ipReq.URL.Host = ip
|
|
}
|
|
for attempt := 0; attempt < maxRetries; attempt++ {
|
|
if attempt > 0 {
|
|
// Linear backoff reduces server load and improves success rate
|
|
time.Sleep(time.Second * time.Duration(attempt+1))
|
|
}
|
|
|
|
resp, err := client.Do(req)
|
|
if err == nil {
|
|
return resp, nil
|
|
}
|
|
if ipReq != nil {
|
|
mainLog.Load().Warn().Err(err).Msgf("dial to %q failed", req.Host)
|
|
mainLog.Load().Warn().Msgf("fallback to direct IP to download prod version: %q", ip)
|
|
resp, err = client.Do(ipReq)
|
|
if err == nil {
|
|
return resp, nil
|
|
}
|
|
}
|
|
|
|
lastErr = err
|
|
mainLog.Load().Debug().Err(err).
|
|
Str("method", req.Method).
|
|
Str("url", req.URL.String()).
|
|
Msgf("HTTP request attempt %d/%d failed", attempt+1, maxRetries)
|
|
}
|
|
return nil, fmt.Errorf("failed after %d attempts to %s %s: %v", maxRetries, req.Method, req.URL, lastErr)
|
|
}
|
|
|
|
// Helper for making GET requests with retries
|
|
// This provides a simplified interface for common GET operations with built-in retry logic
|
|
func getWithRetry(url string, ip string) (*http.Response, error) {
|
|
req, err := http.NewRequest(http.MethodGet, url, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return doWithRetry(req, defaultMaxRetries, ip)
|
|
}
|