feat: sync httpdns sdk/platform updates without large binaries

This commit is contained in:
robin
2026-03-04 17:59:14 +08:00
parent 853897a6f8
commit 532891fad0
700 changed files with 6096 additions and 2712 deletions

View File

@@ -1,7 +1,7 @@
package teaconst
const (
Version = "1.4.8"
Version = "1.4.9"
ProductName = "Edge HTTPDNS"
ProcessName = "edge-httpdns"

View File

@@ -157,8 +157,8 @@ func NewResolveServer(quitCh <-chan struct{}, snapshotManager *SnapshotManager)
instance.handler = mux
instance.tlsConfig = &tls.Config{
MinVersion: tls.VersionTLS11,
NextProtos: []string{"http/1.1"},
MinVersion: tls.VersionTLS11,
NextProtos: []string{"http/1.1"},
GetCertificate: instance.getCertificate,
}
@@ -212,7 +212,7 @@ func (s *ResolveServer) getCertificate(_ *tls.ClientHelloInfo) (*tls.Certificate
type snapshotTLSConfig struct {
Listen []*serverconfigs.NetworkAddressConfig `json:"listen"`
SSLPolicy *sslconfigs.SSLPolicy `json:"sslPolicy"`
SSLPolicy *sslconfigs.SSLPolicy `json:"sslPolicy"`
}
func (s *ResolveServer) parseTLSConfig(snapshot *LoadedSnapshot) *snapshotTLSConfig {
@@ -270,23 +270,24 @@ func (s *ResolveServer) desiredAddrs(snapshot *LoadedSnapshot) []string {
func (s *ResolveServer) reloadCertFromSnapshot(snapshot *LoadedSnapshot) {
cfg := s.parseTLSConfig(snapshot)
if cfg == nil || cfg.SSLPolicy == nil || len(cfg.SSLPolicy.Certs) == 0 {
// 没有TLS配置标记已处理不需要重试
s.certMu.Lock()
s.certSnapshotAt = snapshot.LoadedAt
s.certMu.Unlock()
reportRuntimeLog("info", "tls", "resolve", "no TLS policy in cluster snapshot, skipped cert reload", fmt.Sprintf("cert-skip-%d", snapshot.LoadedAt))
return
}
if err := cfg.SSLPolicy.Init(context.Background()); err != nil {
log.Println("[HTTPDNS_NODE][resolve]init SSLPolicy failed:", err.Error())
s.certMu.Lock()
s.certSnapshotAt = snapshot.LoadedAt
s.certMu.Unlock()
reportRuntimeLog("error", "tls", "resolve", "init SSLPolicy failed: "+err.Error(), fmt.Sprintf("cert-err-%d", snapshot.LoadedAt))
// 不更新 certSnapshotAt,下次 watchLoop 会重试
return
}
cert := cfg.SSLPolicy.FirstCert()
if cert == nil {
s.certMu.Lock()
s.certSnapshotAt = snapshot.LoadedAt
s.certMu.Unlock()
log.Println("[HTTPDNS_NODE][resolve]SSLPolicy has no valid certificate after Init")
reportRuntimeLog("error", "tls", "resolve", "SSLPolicy has no valid certificate after Init", fmt.Sprintf("cert-err-%d", snapshot.LoadedAt))
// 不更新 certSnapshotAt下次 watchLoop 会重试
return
}
@@ -295,6 +296,7 @@ func (s *ResolveServer) reloadCertFromSnapshot(snapshot *LoadedSnapshot) {
s.certSnapshotAt = snapshot.LoadedAt
s.certMu.Unlock()
log.Println("[HTTPDNS_NODE][resolve]TLS certificate reloaded from snapshot")
reportRuntimeLog("info", "tls", "resolve", "TLS certificate reloaded from snapshot successfully", fmt.Sprintf("cert-ok-%d", snapshot.LoadedAt))
}
func (s *ResolveServer) startListener(addr string) error {
@@ -561,27 +563,29 @@ func (s *ResolveServer) handleResolve(writer http.ResponseWriter, request *http.
},
})
s.enqueueAccessLog(&pb.HTTPDNSAccessLog{
RequestId: requestID,
ClusterId: snapshot.ClusterID,
NodeId: snapshot.NodeID,
AppId: loadedApp.App.GetAppId(),
AppName: loadedApp.App.GetName(),
Domain: domain,
Qtype: qtype,
ClientIP: clientProfile.IP,
ClientRegion: clientProfile.RegionText,
Carrier: clientProfile.Carrier,
SdkVersion: strings.TrimSpace(query.Get("sdk_version")),
Os: strings.TrimSpace(query.Get("os")),
ResultIPs: strings.Join(resultIPs, ","),
Status: "success",
ErrorCode: "none",
CostMs: int32(time.Since(startAt).Milliseconds()),
CreatedAt: time.Now().Unix(),
Day: time.Now().Format("20060102"),
Summary: summary,
})
if s.isAccessLogEnabled(snapshot) {
s.enqueueAccessLog(&pb.HTTPDNSAccessLog{
RequestId: requestID,
ClusterId: snapshot.ClusterID,
NodeId: snapshot.NodeID,
AppId: loadedApp.App.GetAppId(),
AppName: loadedApp.App.GetName(),
Domain: domain,
Qtype: qtype,
ClientIP: clientProfile.IP,
ClientRegion: clientProfile.RegionText,
Carrier: clientProfile.Carrier,
SdkVersion: strings.TrimSpace(query.Get("sdk_version")),
Os: strings.TrimSpace(query.Get("os")),
ResultIPs: strings.Join(resultIPs, ","),
Status: "success",
ErrorCode: "none",
CostMs: int32(time.Since(startAt).Milliseconds()),
CreatedAt: time.Now().Unix(),
Day: time.Now().Format("20060102"),
Summary: summary,
})
}
}
func pickDefaultTTL(snapshot *LoadedSnapshot, app *pb.HTTPDNSApp) int32 {
@@ -655,27 +659,29 @@ func (s *ResolveServer) writeFailedResolve(
nodeID = snapshot.NodeID
}
s.enqueueAccessLog(&pb.HTTPDNSAccessLog{
RequestId: requestID,
ClusterId: clusterID,
NodeId: nodeID,
AppId: appID,
AppName: appName,
Domain: domain,
Qtype: qtype,
ClientIP: clientProfile.IP,
ClientRegion: clientProfile.RegionText,
Carrier: clientProfile.Carrier,
SdkVersion: strings.TrimSpace(query.Get("sdk_version")),
Os: strings.TrimSpace(query.Get("os")),
ResultIPs: "",
Status: "failed",
ErrorCode: errorCode,
CostMs: int32(time.Since(startAt).Milliseconds()),
CreatedAt: time.Now().Unix(),
Day: time.Now().Format("20060102"),
Summary: summary,
})
if s.isAccessLogEnabled(snapshot) {
s.enqueueAccessLog(&pb.HTTPDNSAccessLog{
RequestId: requestID,
ClusterId: clusterID,
NodeId: nodeID,
AppId: appID,
AppName: appName,
Domain: domain,
Qtype: qtype,
ClientIP: clientProfile.IP,
ClientRegion: clientProfile.RegionText,
Carrier: clientProfile.Carrier,
SdkVersion: strings.TrimSpace(query.Get("sdk_version")),
Os: strings.TrimSpace(query.Get("os")),
ResultIPs: "",
Status: "failed",
ErrorCode: errorCode,
CostMs: int32(time.Since(startAt).Milliseconds()),
CreatedAt: time.Now().Unix(),
Day: time.Now().Format("20060102"),
Summary: summary,
})
}
}
func (s *ResolveServer) writeResolveJSON(writer http.ResponseWriter, status int, resp *resolveResponse) {
@@ -1424,6 +1430,17 @@ func ruleRegionSummary(rule *pb.HTTPDNSCustomRule) string {
return ""
}
func (s *ResolveServer) isAccessLogEnabled(snapshot *LoadedSnapshot) bool {
if snapshot == nil || snapshot.ClusterID <= 0 {
return true
}
cluster := snapshot.Clusters[snapshot.ClusterID]
if cluster == nil {
return true
}
return cluster.GetAccessLogIsOn()
}
func (s *ResolveServer) enqueueAccessLog(item *pb.HTTPDNSAccessLog) {
if item == nil {
return

View File

@@ -37,6 +37,8 @@ type SnapshotManager struct {
locker sync.RWMutex
snapshot *LoadedSnapshot
timezone string
}
func NewSnapshotManager(quitCh <-chan struct{}) *SnapshotManager {
@@ -144,7 +146,7 @@ func (m *SnapshotManager) RefreshNow(reason string) error {
}
snapshot := &LoadedSnapshot{
LoadedAt: time.Now().Unix(),
LoadedAt: time.Now().UnixNano(),
NodeID: nodeResp.GetNode().GetId(),
ClusterID: nodeResp.GetNode().GetClusterId(),
Clusters: clusters,
@@ -156,5 +158,36 @@ func (m *SnapshotManager) RefreshNow(reason string) error {
m.locker.Unlock()
reportRuntimeLog("info", "config", "snapshot", "snapshot refreshed: "+reason, fmt.Sprintf("snapshot-%d", time.Now().UnixNano()))
// timezone sync - prefer current node's cluster timezone
var timeZone string
if snapshot.ClusterID > 0 {
if cluster := clusters[snapshot.ClusterID]; cluster != nil && len(cluster.GetTimeZone()) > 0 {
timeZone = cluster.GetTimeZone()
}
}
// fallback to any non-empty cluster timezone for compatibility
if len(timeZone) == 0 {
for _, cluster := range clusters {
if cluster != nil && len(cluster.GetTimeZone()) > 0 {
timeZone = cluster.GetTimeZone()
break
}
}
}
if len(timeZone) == 0 {
timeZone = "Asia/Shanghai"
}
if m.timezone != timeZone {
location, err := time.LoadLocation(timeZone)
if err != nil {
log.Println("[HTTPDNS_NODE][TIMEZONE]change time zone failed:", err.Error())
} else {
log.Println("[HTTPDNS_NODE][TIMEZONE]change time zone to '" + timeZone + "'")
time.Local = location
m.timezone = timeZone
}
}
return nil
}