实现缓存功能
This commit is contained in:
@@ -12,6 +12,7 @@ type DNSConfig struct {
|
||||
Timeout int `json:"timeout"`
|
||||
StatsFile string `json:"statsFile"` // 统计数据持久化文件
|
||||
SaveInterval int `json:"saveInterval"` // 数据保存间隔(秒)
|
||||
CacheTTL int `json:"cacheTTL"` // DNS缓存过期时间(分钟)
|
||||
}
|
||||
|
||||
// HTTPConfig HTTP控制台配置
|
||||
@@ -88,6 +89,10 @@ func LoadConfig(path string) (*Config, error) {
|
||||
if config.DNS.SaveInterval == 0 {
|
||||
config.DNS.SaveInterval = 300 // 默认5分钟保存一次
|
||||
}
|
||||
// 默认DNS缓存TTL为30分钟
|
||||
if config.DNS.CacheTTL == 0 {
|
||||
config.DNS.CacheTTL = 30 // 默认30分钟
|
||||
}
|
||||
if config.HTTP.Port == 0 {
|
||||
config.HTTP.Port = 8080
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# Netscape HTTP Cookie File
|
||||
# https://curl.se/docs/http-cookies.html
|
||||
# This file was generated by libcurl! Edit at your own risk.
|
||||
|
||||
#HttpOnly_localhost FALSE / FALSE 1764565364 session_id 1764478964904488810_0
|
||||
@@ -1,3 +0,0 @@
|
||||
# Hosts文件
|
||||
# 格式:IP 域名
|
||||
# 例如:127.0.0.1 localhost
|
||||
95405
data/querylog.json
95405
data/querylog.json
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,734 +0,0 @@
|
||||
!Title: AWAvenue Ads Rule
|
||||
!--------------------------------------
|
||||
!Total lines: 725
|
||||
!Version: 1.5.5-release
|
||||
|
||||
!Homepage: https://github.com/TG-Twilight/AWAvenue-Ads-Rule
|
||||
!License: https://github.com/TG-Twilight/AWAvenue-Ads-Rule/blob/main/LICENSE
|
||||
|
||||
|
||||
||1010pic.com^
|
||||
||16dd-advertise-1252317822.file.myqcloud.com^
|
||||
||16dd-advertise-1252317822.image.myqcloud.com^
|
||||
||8le8le.com^
|
||||
||a0.app.xiaomi.com^
|
||||
||aaid.umeng.com^
|
||||
||abtest-ch.snssdk.com^
|
||||
||ad-cache.dopool.com^
|
||||
||ad-cdn.qingting.fm^
|
||||
||ad-cmp.hismarttv.com^
|
||||
||ad-download.hismarttv.com^
|
||||
||ad-imp.hismarttv.com^
|
||||
||ad-scope.com^
|
||||
||ad-scope.com.cn^
|
||||
||ad-sdk-config.youdao.com^
|
||||
||ad-sdk.huxiu.com^
|
||||
||ad.12306.cn^
|
||||
||ad.51wnl.com^
|
||||
||ad.bwton.com^
|
||||
||ad.cctv.com^
|
||||
||ad.cyapi.cn^
|
||||
||ad.doubleclick.net^
|
||||
||ad.partner.gifshow.com^
|
||||
||ad.qingting.fm^
|
||||
||ad.qq.com^
|
||||
||ad.richmob.cn^
|
||||
||ad.tencentmusic.com^
|
||||
||ad.toutiao.com^
|
||||
||ad.v3mh.com^
|
||||
||ad.winrar.com.cn^
|
||||
||ad.xelements.cn^
|
||||
||ad.xiaomi.com^
|
||||
||ad.ximalaya.com^
|
||||
||ad.zijieapi.com^
|
||||
||adapi.izuiyou.com^
|
||||
||adapi.yynetwk.com^
|
||||
||adashbc.ut.taobao.com^
|
||||
||adc.hpplay.cn^
|
||||
||adcdn.hpplay.cn^
|
||||
||adcdn.tencentmusic.com^
|
||||
||adclick.g.doubleclick.net^
|
||||
||adclick.tencentmusic.com^
|
||||
||adcolony.com^
|
||||
||adexpo.tencentmusic.com^
|
||||
||adfilter.imtt.qq.com^
|
||||
||adfstat.yandex.ru^
|
||||
||adguanggao.eee114.com^
|
||||
||adjust.cn^
|
||||
||adjust.com^
|
||||
||adkwai.com^
|
||||
||adlink-api.huan.tv^
|
||||
||adm.funshion.com^
|
||||
||ads-api-o.api.leiniao.com^
|
||||
||ads-api.tiktok.com^
|
||||
||ads-api.twitter.com^
|
||||
||ads-img-qc.xhscdn.com^
|
||||
||ads-jp.tiktok.com^
|
||||
||ads-marketing-vivofs.vivo.com.cn^
|
||||
||ads-sg.tiktok.com^
|
||||
||ads-us.tiktok.com^
|
||||
||ads-video-al.xhscdn.com^
|
||||
||ads-video-qc.xhscdn.com^
|
||||
||ads.95516.com^
|
||||
||ads.google.cn^
|
||||
||ads.heytapmobi.com^
|
||||
||ads.huan.tv^
|
||||
||ads.huantest.com^
|
||||
||ads.icloseli.cn^
|
||||
||ads.linkedin.com^
|
||||
||ads.music.126.net^
|
||||
||ads.oppomobile.com^
|
||||
||ads.pinterest.com^
|
||||
||ads.servebom.com^
|
||||
||ads.service.kugou.com^
|
||||
||ads.tiktok.com^
|
||||
||ads.v3mh.com^
|
||||
||ads.youtube.com^
|
||||
||ads3-normal-hl.zijieapi.com^
|
||||
||ads3-normal-lf.zijieapi.com^
|
||||
||ads3-normal-lq.zijieapi.com^
|
||||
||ads3-normal.zijieapi.com^
|
||||
||ads5-normal-hl.zijieapi.com^
|
||||
||ads5-normal-lf.zijieapi.com^
|
||||
||ads5-normal-lq.zijieapi.com^
|
||||
||ads5-normal.zijieapi.com^
|
||||
||adse.test.ximalaya.com^
|
||||
||adse.wsa.ximalaya.com^
|
||||
||adse.ximalaya.com^
|
||||
||adsebs.ximalaya.com^
|
||||
||adsense.google.cn^
|
||||
||adserver.unityads.unity3d.com^
|
||||
||adservice.google.cn^
|
||||
||adservice.google.com^
|
||||
||adserviceretry.kugou.com^
|
||||
||adsfile.bssdlbig.kugou.com^
|
||||
||adsfile.qq.com^
|
||||
||adsfilebssdlbig.ali.kugou.com^
|
||||
||adsfileretry.service.kugou.com^
|
||||
||adsfs-sdkconfig.heytapimage.com^
|
||||
||adsfs.oppomobile.com^
|
||||
||adslvfile.qq.com^
|
||||
||adsmart.konka.com^
|
||||
||adsmind.gdtimg.com^
|
||||
||adsmind.ugdtimg.com^
|
||||
||adsp.xunlei.com^
|
||||
||adstats.tencentmusic.com^
|
||||
||adstore-1252524079.file.myqcloud.com^
|
||||
||adstore-index-1252524079.file.myqcloud.com^
|
||||
||adtago.s3.amazonaws.com^
|
||||
||adtech.yahooinc.com^
|
||||
||adtrack.quark.cn^
|
||||
||adukwai.com^
|
||||
||adv.fjtv.net^
|
||||
||adv.sec.intl.miui.com^
|
||||
||adv.sec.miui.com^
|
||||
||advertiseonbing.azureedge.net^
|
||||
||advertising-api-eu.amazon.com^
|
||||
||advertising-api-fe.amazon.com^
|
||||
||advertising-api.amazon.com^
|
||||
||advertising.apple.com^
|
||||
||advertising.yahoo.com^
|
||||
||advertising.yandex.ru^
|
||||
||advice-ads.s3.amazonaws.com^
|
||||
||adview.cn^
|
||||
||adx-ad.smart-tv.cn^
|
||||
||adx-bj.anythinktech.com^
|
||||
||adx-cn.anythinktech.com^
|
||||
||adx-drcn.op.dbankcloud.cn^
|
||||
||adx-open-service.youku.com^
|
||||
||adx-os.anythinktech.com^
|
||||
||adx.ads.heytapmobi.com^
|
||||
||adx.ads.oppomobile.com^
|
||||
||adxlog-adnet.vivo.com.cn^
|
||||
||adxlog-adnet.vivo.com.cn.dsa.dnsv1.com.cn^
|
||||
||adxserver.ad.cmvideo.cn^
|
||||
||aegis.qq.com^
|
||||
||afs.googlesyndication.com^
|
||||
||aiseet.aa.atianqi.com^
|
||||
||ali-ad.a.yximgs.com^
|
||||
||alog.umeng.com^
|
||||
||als.baidu.com^
|
||||
||amdcopen.m.taobao.com^
|
||||
||amdcopen.m.umeng.com^
|
||||
||an.facebook.com^
|
||||
||analysis.yozocloud.cn^
|
||||
||analytics-api.samsunghealthcn.com^
|
||||
||analytics.126.net^
|
||||
||analytics.95516.com^
|
||||
||analytics.google.com^
|
||||
||analytics.pinterest.com^
|
||||
||analytics.pointdrive.linkedin.com^
|
||||
||analytics.query.yahoo.com^
|
||||
||analytics.rayjump.com^
|
||||
||analytics.s3.amazonaws.com^
|
||||
||analytics.tiktok.com^
|
||||
||analytics.woozooo.com^
|
||||
||analyticsengine.s3.amazonaws.com^
|
||||
||analyze.lemurbrowser.com^
|
||||
||andrqd.play.aiseet.atianqi.com^
|
||||
||ap.dongqiudi.com^
|
||||
||apd-pcdnwxlogin.teg.tencent-cloud.net^
|
||||
||apd-pcdnwxnat.teg.tencent-cloud.net^
|
||||
||apd-pcdnwxstat.teg.tencent-cloud.net^
|
||||
||api-access.pangolin-sdk-toutiao.com^
|
||||
||api-access.pangolin-sdk-toutiao1.com^
|
||||
||api-access.pangolin-sdk-toutiao2.com^
|
||||
||api-access.pangolin-sdk-toutiao3.com^
|
||||
||api-access.pangolin-sdk-toutiao4.com^
|
||||
||api-access.pangolin-sdk-toutiao5.com^
|
||||
||api-ad-product.huxiu.com^
|
||||
||api-adservices.apple.com^
|
||||
||api-gd.hiaiabc.com^
|
||||
||api-htp.beizi.biz^
|
||||
||api.ad.xiaomi.com^
|
||||
||api.e.kuaishou.com^
|
||||
||api.htp.hubcloud.com.cn^
|
||||
||api.hzsanjiaomao.com^
|
||||
||api.installer.xiaomi.com^
|
||||
||api.jietuhb.com^
|
||||
||api.kingdata.ksyun.com^
|
||||
||api.statsig.com^
|
||||
||api5-normal-quic-lf.ixigua.com^
|
||||
||apiyd.my91app.com^
|
||||
||apks.webxiaobai.top^
|
||||
||app-measurement.com^
|
||||
||appcloud2.in.zhihu.com^
|
||||
||applog.lc.quark.cn^
|
||||
||applog.uc.cn^
|
||||
||applog.zijieapi.com^
|
||||
||ata-sdk-uuid-report.dreport.meituan.net^
|
||||
||auction.unityads.unity3d.com^
|
||||
||audid-api.taobao.com^
|
||||
||audid.umeng.com^
|
||||
||azr.footprintdns.com^
|
||||
||b1-data.ads.heytapmobi.com^
|
||||
||baichuan-sdk.alicdn.com^
|
||||
||baichuan-sdk.taobao.com^
|
||||
||bdad.123pan.cn^
|
||||
||bdapi-ads.realmemobile.com^
|
||||
||bdapi-in-ads.realmemobile.com^
|
||||
||bdapi.ads.oppomobile.com^
|
||||
||beacon-api.aliyuncs.com^
|
||||
||beacon.qq.com^
|
||||
||beaconcdn.qq.com^
|
||||
||beacons.gvt2.com^
|
||||
||beizi.biz^
|
||||
||bes-mtj.baidu.com^
|
||||
||bgg.baidu.com^
|
||||
||bianxian.com^
|
||||
||bingads.microsoft.com^
|
||||
||bj.ad.track.66mobi.com^
|
||||
||books-analytics-events.apple.com^
|
||||
||browsercfg-drcn.cloud.dbankcloud.cn^
|
||||
||bsrv.qq.com^
|
||||
||bugly.qq.com^
|
||||
||business-api.tiktok.com^
|
||||
||c.bidtoolads.com^
|
||||
||c.evidon.com^
|
||||
||c.gj.qq.com^
|
||||
||c.kuaiduizuoye.com^
|
||||
||c.sayhi.360.cn^
|
||||
||c2.gdt.qq.com^
|
||||
||canvas-cdn.gdt.qq.com^
|
||||
||catalog.fjwhcbsh.com^
|
||||
||cbjs.baidu.com^
|
||||
||ccs.umeng.com^
|
||||
||cctv.adsunion.com^
|
||||
||cdn-ad.wtzw.com^
|
||||
||cdn-ads.oss-cn-shanghai.aliyuncs.com^
|
||||
||cdn-plugin-sync-upgrade-juui.hismarttv.com^
|
||||
||cdn.ad.xiaomi.com^
|
||||
||cdn.ynuf.aliapp.org^
|
||||
||cfg.imtt.qq.com^
|
||||
||chat1.jd.com^
|
||||
||chiq-cloud.com^
|
||||
||cj.qidian.com^
|
||||
||ck.ads.oppomobile.com^
|
||||
||click.googleanalytics.com^
|
||||
||click.oneplus.cn^
|
||||
||clog.miguvideo.com^
|
||||
||cnlogs.umeng.com^
|
||||
||cnlogs.umengcloud.com^
|
||||
||cnzz.com^
|
||||
||collect.kugou.com^
|
||||
||commdata.v.qq.com^
|
||||
||config.chsmarttv.com^
|
||||
||config.unityads.unity3d.com^
|
||||
||cpro.baidustatic.com^
|
||||
||crashlytics.com^
|
||||
||crashlyticsreports-pa.googleapis.com^
|
||||
||csjplatform.com^
|
||||
||cws-cctv.conviva.com^
|
||||
||data.ads.oppomobile.com^
|
||||
||data.chsmarttv.com^
|
||||
||data.mistat.india.xiaomi.com^
|
||||
||data.mistat.rus.xiaomi.com^
|
||||
||data.mistat.xiaomi.com^
|
||||
||diagnosis.ad.xiaomi.com^
|
||||
||dig.bdurl.net^
|
||||
||dl.zuimeitianqi.com^
|
||||
||dlogs.bwton.com^
|
||||
||dm.toutiao.com^
|
||||
||domain.aishengji.com^
|
||||
||doubleclick-cn.net^
|
||||
||download.changhong.upgrade2.huan.tv^
|
||||
||downloadxml.changhong.upgrade2.huan.tv^
|
||||
||drcn-weather.cloud.huawei.com^
|
||||
||dsp-x.jd.com^
|
||||
||dsp.fcbox.com^
|
||||
||dualstack-logs.amap.com^
|
||||
||dutils.com^
|
||||
||dxp.baidu.com^
|
||||
||e.ad.xiaomi.com^
|
||||
||eclick.baidu.com^
|
||||
||edge.ads.twitch.tv^
|
||||
||ef-dongfeng.tanx.com^
|
||||
||entry.baidu.com^
|
||||
||errlog.umeng.com^
|
||||
||errnewlog.umeng.com^
|
||||
||event.tradplusad.com^
|
||||
||events-drcn.op.dbankcloud.cn^
|
||||
||events.reddit.com^
|
||||
||events.redditmedia.com^
|
||||
||firebaselogging-pa.googleapis.com^
|
||||
||flurry.com^
|
||||
||g-adnet.hiaiabc.com^
|
||||
||g-staic.ganjingworld.com^
|
||||
||g2.ganjing.world^
|
||||
||game.loveota.com^
|
||||
||gdfp.gifshow.com^
|
||||
||gemini.yahoo.com^
|
||||
||geo.yahoo.com^
|
||||
||getui.cn^
|
||||
||getui.com^
|
||||
||getui.net^
|
||||
||ggx.cmvideo.cn^
|
||||
||ggx01.miguvideo.com^
|
||||
||ggx03.miguvideo.com^
|
||||
||globalapi.ad.xiaomi.com^
|
||||
||google-analytics.com^
|
||||
||googleads.g.doubleclick.net^
|
||||
||googleadservices-cn.com^
|
||||
||googleadservices.com^
|
||||
||googletagservices-cn.com^
|
||||
||googletagservices.com^
|
||||
||gorgon.youdao.com^
|
||||
||gromore.pangolin-sdk-toutiao.com^
|
||||
||grs.dbankcloud.com^
|
||||
||grs.hicloud.com^
|
||||
||grs.platform.dbankcloud.ru^
|
||||
||h-adashx.ut.taobao.com^
|
||||
||h.trace.qq.com^
|
||||
||hanlanad.com^
|
||||
||hexagon-analytics.com^
|
||||
||hm.baidu.com^
|
||||
||hmma.baidu.com^
|
||||
||houyi.kkmh.com^
|
||||
||hpplay.cn^
|
||||
||httpdns.bcelive.com^
|
||||
||httpdns.ocloud.oppomobile.com^
|
||||
||hugelog.fcbox.com^
|
||||
||huichuan.sm.cn^
|
||||
||hw-ot-ad.a.yximgs.com^
|
||||
||hw.zuimeitianqi.com^
|
||||
||hwpub-s01-drcn.cloud.dbankcloud.cn^
|
||||
||hya.comp.360os.com^
|
||||
||hybrid.miniapp.taobao.com^
|
||||
||hye.comp.360os.com^
|
||||
||hyt.comp.360os.com^
|
||||
||i.snssdk.com^
|
||||
||iad.apple.com^
|
||||
||iadctest.qwapi.com^
|
||||
||iadsdk.apple.com^
|
||||
||iadworkbench.apple.com^
|
||||
||ifacelog.iqiyi.com^
|
||||
||ifs.tanx.com^
|
||||
||igexin.com^
|
||||
||ii.gdt.qq.com^
|
||||
||imag8.pubmatic.com^
|
||||
||imag86.pubmatic.com^
|
||||
||image-ad.sm.cn^
|
||||
||imageplus.baidu.com^
|
||||
||images.outbrainimg.com^
|
||||
||images.pinduoduo.com^
|
||||
||img-c.heytapimage.com^
|
||||
||img.adnyg.com^
|
||||
||img.adnyg.com.w.kunlungr.com^
|
||||
||imtmp.net^
|
||||
||iot-eu-logser.realme.com^
|
||||
||iot-logser.realme.com^
|
||||
||ipv4.kkmh.com^
|
||||
||irc.qubiankeji.com^
|
||||
||itv2-up.openspeech.cn^
|
||||
||ixav-cse.avlyun.com^
|
||||
||iyfbodn.com^
|
||||
||janapi.jd.com^
|
||||
||jiguang.cn^
|
||||
||jpush.cn^
|
||||
||jpush.html5.qq.com^
|
||||
||jpush.io^
|
||||
||jswebcollects.kugou.com^
|
||||
||kepler.jd.com^
|
||||
||kl.67it.com^
|
||||
||knicks.jd.com^
|
||||
||ks.pull.yximgs.com^
|
||||
||launcher.smart-tv.cn^
|
||||
||launcherimg.smart-tv.cn^
|
||||
||lf3-ad-union-sdk.pglstatp-toutiao.com^
|
||||
||lf6-ad-union-sdk.pglstatp-toutiao.com^
|
||||
||litchiads.com^
|
||||
||liveats-vod.video.ptqy.gitv.tv^
|
||||
||livemonitor.huan.tv^
|
||||
||livep.l.aiseet.atianqi.com^
|
||||
||lives.l.aiseet.atianqi.com^
|
||||
||lives.l.ott.video.qq.com^
|
||||
||lm10111.jtrincc.cn^
|
||||
||log-api-mn.huxiu.com^
|
||||
||log-api.huxiu.com^
|
||||
||log-api.pangolin-sdk-toutiao-b.com^
|
||||
||log-api.pangolin-sdk-toutiao.com^
|
||||
||log-report.com^
|
||||
||log-sdk.gifshow.com^
|
||||
||log-upload-os.hoyoverse.com^
|
||||
||log-upload.mihoyo.com^
|
||||
||log.ad.xiaomi.com^
|
||||
||log.aispeech.com^
|
||||
||log.amemv.com^
|
||||
||log.appstore3.huan.tv^
|
||||
||log.avlyun.com^
|
||||
||log.avlyun.sec.intl.miui.com^
|
||||
||log.byteoversea.com^
|
||||
||log.fc.yahoo.com^
|
||||
||log.kuwo.cn^
|
||||
||log.pinterest.com^
|
||||
||log.snssdk.com^
|
||||
||log.stat.kugou.com^
|
||||
||log.tagtic.cn^
|
||||
||log.tbs.qq.com^
|
||||
||log.vcgame.cn^
|
||||
||log.web.kugou.com^
|
||||
||log.zijieapi.com^
|
||||
||log1.cmpassport.com^
|
||||
||logbak.hicloud.com^
|
||||
||logs.amap.com^
|
||||
||logservice.hicloud.com^
|
||||
||logservice1.hicloud.com^
|
||||
||logtj.kugou.com^
|
||||
||logupdate.avlyun.sec.miui.com^
|
||||
||m-adnet.hiaiabc.com^
|
||||
||m.ad.zhangyue.com^
|
||||
||m.atm.youku.com^
|
||||
||m.kubiqq.com^
|
||||
||m1.ad.10010.com^
|
||||
||mapi.m.jd.com^
|
||||
||masdkv6.3g.qq.com^
|
||||
||mazu.m.qq.com^
|
||||
||mbdlog.iqiyi.com^
|
||||
||metrics.apple.com^
|
||||
||metrics.data.hicloud.com^
|
||||
||metrics.icloud.com^
|
||||
||metrics.mzstatic.com^
|
||||
||metrics2.data.hicloud.com^
|
||||
||metrika.yandex.ru^
|
||||
||mi.gdt.qq.com^
|
||||
||miav-cse.avlyun.com^
|
||||
||mime.baidu.com^
|
||||
||mine.baidu.com^
|
||||
||mission-pub.smart-tv.cn^
|
||||
||miui-fxcse.avlyun.com^
|
||||
||mnqlog.ldmnq.com^
|
||||
||mobads-logs.baidu.com^
|
||||
||mobads-pre-config.cdn.bcebos.com^
|
||||
||mobads.baidu.com^
|
||||
||mobile.da.mgtv.com^
|
||||
||mobilelog.upqzfile.com^
|
||||
||mobileservice.cn^
|
||||
||mon.zijieapi.com^
|
||||
||monitor-ads-test.huan.tv^
|
||||
||monitor-uu.play.aiseet.atianqi.com^
|
||||
||monitor.music.qq.com^
|
||||
||monitor.uu.qq.com^
|
||||
||monsetting.toutiao.com^
|
||||
||mssdk.volces.com^
|
||||
||mssdk.zijieapi.com^
|
||||
||mtj.baidu.com^
|
||||
||newvoice.chiq5.smart-tv.cn^
|
||||
||nmetrics.samsung.com^
|
||||
||notes-analytics-events.apple.com^
|
||||
||nsclick.baidu.com^
|
||||
||o2o.api.xiaomi.com^
|
||||
||oauth-login-drcn.platform.dbankcloud.com^
|
||||
||offerwall.yandex.net^
|
||||
||omgmta.play.aiseet.atianqi.com^
|
||||
||open.e.kuaishou.cn^
|
||||
||open.e.kuaishou.com^
|
||||
||open.kuaishouzt.com^
|
||||
||open.kwaishouzt.com^
|
||||
||open.kwaizt.com^
|
||||
||optimus-ads.amap.com^
|
||||
||orbit.jd.com^
|
||||
||oth.eve.mdt.qq.com^
|
||||
||oth.str.mdt.qq.com^
|
||||
||otheve.play.aiseet.atianqi.com^
|
||||
||outlookads.live.com^
|
||||
||p.l.qq.com^
|
||||
||p.s.360.cn^
|
||||
||p1-be-pack-sign.pglstatp-toutiao.com^
|
||||
||p1-lm.adkwai.com^
|
||||
||p2-be-pack-sign.pglstatp-toutiao.com^
|
||||
||p2-lm.adkwai.com^
|
||||
||p2p.huya.com^
|
||||
||p3-be-pack-sign.pglstatp-toutiao.com^
|
||||
||p3-lm.adkwai.com^
|
||||
||p3-tt.byteimg.com^
|
||||
||p4-be-pack-sign.pglstatp-toutiao.com^
|
||||
||p5-be-pack-sign.pglstatp-toutiao.com^
|
||||
||p6-be-pack-sign.pglstatp-toutiao.com^
|
||||
||pagead2.googleadservices.com^
|
||||
||pagead2.googlesyndication.com^
|
||||
||pangolin-sdk-toutiao-b.com^
|
||||
||pay.sboot.cn^
|
||||
||pgdt.ugdtimg.com^
|
||||
||pglstatp-toutiao.com^
|
||||
||pig.pupuapi.com^
|
||||
||pixon.ads-pixiv.net^
|
||||
||pkoplink.com^
|
||||
||plbslog.umeng.com^
|
||||
||pms.mb.qq.com^
|
||||
||policy.video.ptqy.gitv.tv^
|
||||
||pos.baidu.com^
|
||||
||proxy.advp.apple.com^
|
||||
||public.gdtimg.com^
|
||||
||q.i.gdt.qq.com^
|
||||
||qqdata.ab.qq.com^
|
||||
||qwapi.apple.com^
|
||||
||qzs.gdtimg.com^
|
||||
||recommend-drcn.hms.dbankcloud.cn^
|
||||
||report.tv.kohesport.qq.com^
|
||||
||res.hubcloud.com.cn^
|
||||
||res1.hubcloud.com.cn^
|
||||
||res2.hubcloud.com.cn^
|
||||
||res3.hubcloud.com.cn^
|
||||
||resolve.umeng.com^
|
||||
||review.gdtimg.com^
|
||||
||rms-drcn.platform.dbankcloud.cn^
|
||||
||roi.soulapp.cn^
|
||||
||rpt.gdt.qq.com^
|
||||
||rtb.voiceads.cn^
|
||||
||s.amazon-adsystem.com^
|
||||
||s1.qq.com^
|
||||
||s2.qq.com^
|
||||
||s3.qq.com^
|
||||
||saad.ms.zhangyue.net^
|
||||
||samsung-com.112.2o7.net^
|
||||
||samsungads.com^
|
||||
||sanme2.taisantech.com^
|
||||
||saveu5-normal-lq.zijieapi.com^
|
||||
||scdown.qq.com^
|
||||
||scs.openspeech.cn^
|
||||
||sdk-ab-config.qquanquan.com^
|
||||
||sdk-cache.video.ptqy.gitv.tv^
|
||||
||sdk.1rtb.net^
|
||||
||sdk.beizi.biz^
|
||||
||sdk.cferw.com^
|
||||
||sdk.e.qq.com^
|
||||
||sdk.hzsanjiaomao.com^
|
||||
||sdk.markmedia.com.cn^
|
||||
||sdk.mobads.adwangmai.com^
|
||||
||sdkconf.avlyun.com^
|
||||
||sdkconfig.ad.intl.xiaomi.com^
|
||||
||sdkconfig.ad.xiaomi.com^
|
||||
||sdkconfig.play.aiseet.atianqi.com^
|
||||
||sdkconfig.video.qq.com^
|
||||
||sdkoptedge.chinanetcenter.com^
|
||||
||sdktmp.hubcloud.com.cn^
|
||||
||sdownload.stargame.com^
|
||||
||search.ixigua.com^
|
||||
||search3-search.ixigua.com^
|
||||
||search5-search-hl.ixigua.com^
|
||||
||search5-search.ixigua.com^
|
||||
||securemetrics.apple.com^
|
||||
||securepubads.g.doubleclick.net^
|
||||
||sensors-log.dongqiudi.com^
|
||||
||service.changhong.upgrade2.huan.tv^
|
||||
||service.vmos.cn^
|
||||
||sf16-static.i18n-pglstatp.com^
|
||||
||sf3-fe-tos.pglstatp-toutiao.com^
|
||||
||shouji.sogou.com^
|
||||
||sigmob.cn^
|
||||
||sigmob.com^
|
||||
||skdisplay.jd.com^
|
||||
||slb-p2p.vcloud.ks-live.com^
|
||||
||smad.ms.zhangyue.net^
|
||||
||smart-tv.cn^
|
||||
||smartad.10010.com^
|
||||
||smetrics.samsung.com^
|
||||
||sms.ads.oppomobile.com^
|
||||
||sngmta.qq.com^
|
||||
||snowflake.qq.com^
|
||||
||stat.dongqiudi.com^
|
||||
||stat.y.qq.com^
|
||||
||static.ads-twitter.com^
|
||||
||statics.woozooo.com^
|
||||
||stats.qiumibao.com^
|
||||
||stats.wp.com^
|
||||
||statsigapi.net^
|
||||
||stg-data.ads.heytapmobi.com^
|
||||
||success.ctobsnssdk.com^
|
||||
||syh-imp.cdnjtzy.com^
|
||||
||szbdyd.com^
|
||||
||t-dsp.pinduoduo.com^
|
||||
||t.l.qq.com^
|
||||
||t.track.ad.xiaomi.com^
|
||||
||t002.ottcn.com^
|
||||
||t1.a.market.xiaomi.com^
|
||||
||t2.a.market.xiaomi.com^
|
||||
||t3.a.market.xiaomi.com^
|
||||
||tangram.e.qq.com^
|
||||
||tdc.qq.com^
|
||||
||tdsdk.cpatrk.net^
|
||||
||tdsdk.xdrig.com^
|
||||
||tencent-dtv.m.cn.miaozhen.com^
|
||||
||terms-drcn.platform.dbankcloud.cn^
|
||||
||test.ad.xiaomi.com^
|
||||
||test.e.ad.xiaomi.com^
|
||||
||tj.b.qq.com^
|
||||
||tj.video.qq.com^
|
||||
||tmead.y.qq.com^
|
||||
||tmeadcomm.y.qq.com^
|
||||
||tmfmazu-wangka.m.qq.com^
|
||||
||tmfmazu.m.qq.com^
|
||||
||tmfsdk.m.qq.com^
|
||||
||tmfsdktcpv4.m.qq.com^
|
||||
||tnc3-aliec1.toutiaoapi.com^
|
||||
||tnc3-aliec2.bytedance.com^
|
||||
||tnc3-aliec2.toutiaoapi.com^
|
||||
||tnc3-alisc1.bytedance.com^
|
||||
||tnc3-alisc1.zijieapi.com^
|
||||
||tnc3-alisc2.zijieapi.com^
|
||||
||tnc3-bjlgy.bytedance.com^
|
||||
||tnc3-bjlgy.toutiaoapi.com^
|
||||
||tnc3-bjlgy.zijieapi.com^
|
||||
||toblog.ctobsnssdk.com^
|
||||
||trace.qq.com^
|
||||
||tracelog-debug.qquanquan.com^
|
||||
||track.lc.quark.cn^
|
||||
||track.uc.cn^
|
||||
||tracker.ai.xiaomi.com^
|
||||
||tracker.gitee.com^
|
||||
||tracking.miui.com^
|
||||
||tracking.rus.miui.com^
|
||||
||tsvrv.com^
|
||||
||tvuser-ch.cedock.com^
|
||||
||tx-ad.a.yximgs.com^
|
||||
||tx-kmpaudio.pull.yximgs.com^
|
||||
||tz.sec.xiaomi.com^
|
||||
||uapi.ads.heytapmobi.com^
|
||||
||udc.yahoo.com^
|
||||
||udcm.yahoo.com^
|
||||
||uedas.qidian.com^
|
||||
||ulog-sdk.gifshow.com^
|
||||
||ulogjs.gifshow.com^
|
||||
||ulogs.umeng.com^
|
||||
||ulogs.umengcloud.com^
|
||||
||umengacs.m.taobao.com^
|
||||
||umengjmacs.m.taobao.com^
|
||||
||umini.shujupie.com^
|
||||
||umsns.com^
|
||||
||union.baidu.cn^
|
||||
||union.baidu.com^
|
||||
||update.avlyun.sec.miui.com^
|
||||
||update.lejiao.tv^
|
||||
||upgrade-update.hismarttv.com^
|
||||
||us.l.qq.com^
|
||||
||v.adintl.cn^
|
||||
||v.adx.hubcloud.com.cn^
|
||||
||v1-ad.video.yximgs.com^
|
||||
||v2-ad.video.yximgs.com^
|
||||
||v2-api-channel-launcher.hismarttv.com^
|
||||
||v2.gdt.qq.com^
|
||||
||v2mi.gdt.qq.com^
|
||||
||v3-ad.video.yximgs.com^
|
||||
||v3.gdt.qq.com^
|
||||
||video-ad.sm.cn^
|
||||
||video-dsp.pddpic.com^
|
||||
||video.dispatch.tc.qq.com^
|
||||
||virusinfo-cloudscan-cn.heytapmobi.com^
|
||||
||vlive.qqvideo.tc.qq.com^
|
||||
||volc.bj.ad.track.66mobi.com^
|
||||
||vungle.com^
|
||||
||w.l.qq.com^
|
||||
||w1.askwai.com^
|
||||
||w1.bskwai.com^
|
||||
||w1.cskwai.com^
|
||||
||w1.dskwai.com^
|
||||
||w1.eskwai.com^
|
||||
||w1.fskwai.com^
|
||||
||w1.gskwai.com^
|
||||
||w1.hskwai.com^
|
||||
||w1.iskwai.com^
|
||||
||w1.jskwai.com^
|
||||
||w1.kskwai.com^
|
||||
||w1.lskwai.com^
|
||||
||w1.mskwai.com^
|
||||
||w1.nskwai.com^
|
||||
||w1.oskwai.com^
|
||||
||w1.pskwai.com^
|
||||
||w1.qskwai.com^
|
||||
||w1.rskwai.com^
|
||||
||w1.sskwai.com^
|
||||
||w1.tskwai.com^
|
||||
||w1.uskwai.com^
|
||||
||w1.vskwai.com^
|
||||
||w1.wskwai.com^
|
||||
||w1.xskwai.com^
|
||||
||w1.yskwai.com^
|
||||
||w1.zskwai.com^
|
||||
||watson.microsoft.com^
|
||||
||watson.telemetry.microsoft.com^
|
||||
||weather-analytics-events.apple.com^
|
||||
||weather-community-drcn.weather.dbankcloud.cn^
|
||||
||webstat.qiumibao.com^
|
||||
||webview.unityads.unity3d.com^
|
||||
||widgets.outbrain.com^
|
||||
||widgets.pinterest.com^
|
||||
||win.gdt.qq.com^
|
||||
||wn.x.jd.com^
|
||||
||ws-keyboard.shouji.sogou.com^
|
||||
||ws.sj.qq.com^
|
||||
||www42.zskwai.com^
|
||||
||wxa.wxs.qq.com^
|
||||
||wximg.wxs.qq.com^
|
||||
||wxsmw.wxs.qq.com^
|
||||
||wxsnsad.tc.qq.com^
|
||||
||wxsnsdy.wxs.qq.com^
|
||||
||wxsnsdythumb.wxs.qq.com^
|
||||
||xc.gdt.qq.com^
|
||||
||xiaomi-dtv.m.cn.miaozhen.com^
|
||||
||xiaoshuo.wtzw.com^
|
||||
||xlivrdr.com^
|
||||
||xlmzc.cnjp-exp.com^
|
||||
||xlog.jd.com^
|
||||
||xlviiirdr.com^
|
||||
||xlviirdr.com^
|
||||
||yk-ssp.ad.youku.com^
|
||||
||ykad-data.youku.com^
|
||||
||ykad-gateway.youku.com^
|
||||
||youku-acs.m.taobao.com^
|
||||
||youxi.kugou.com^
|
||||
||zeus.ad.xiaomi.com^
|
||||
||zhihu-web-analytics.zhihu.com^
|
||||
/.*\.*\.shouji\.sogou\.com/
|
||||
/.*\.[a-zA-Z0-9.-]skwai\.com/
|
||||
/.*\.a\.market\.xiaomi\.com/
|
||||
/.*\.data\.hicloud\.com/
|
||||
/.*\.log\.aliyuncs\.com/
|
||||
/[a-zA-Z0-9.-]*-ad-[a-zA-Z0-9.-]*\.byteimg\.com/
|
||||
/[a-zA-Z0-9.-]*-ad\.sm\.cn/
|
||||
/[a-zA-Z0-9.-]*-ad\.video\.yximgs\.com/
|
||||
/[a-zA-Z0-9.-]*-ad\.wtzw\.com/
|
||||
/[a-zA-Z0-9.-]*-be-pack-sign\.pglstatp-toutiao\.com/
|
||||
/[a-zA-Z0-9.-]*-lm\.adkwai\.com/
|
||||
/[a-zA-Z0-9.-]*-normal-[a-zA-Z0-9.-]*\.zijieapi\.com/
|
||||
/[a-zA-Z0-9.-]*-normal\.zijieapi\.com/
|
||||
/cloudinject[a-zA-Z0-9.-]*-dev\.*\.[a-zA-Z0-9.-]*-[a-zA-Z0-9.-]*-[a-zA-Z0-9.-]*\.amazonaws\.com/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
||||
/ciceknoktasi/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
# 本地规则文件
|
||||
# 格式:域名
|
||||
# 例如:example.com
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"blockedDomainsCount": {},
|
||||
"resolvedDomainsCount": {},
|
||||
"lastSaved": "2025-11-30T13:30:26.385263173+08:00"
|
||||
}
|
||||
4098
data/stats.json
4098
data/stats.json
File diff suppressed because it is too large
Load Diff
BIN
dns-server
BIN
dns-server
Binary file not shown.
127
dns/cache.go
Normal file
127
dns/cache.go
Normal file
@@ -0,0 +1,127 @@
|
||||
package dns
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// DNSCacheItem 表示缓存中的DNS响应项
|
||||
type DNSCacheItem struct {
|
||||
Response *dns.Msg // DNS响应消息
|
||||
Expiry time.Time // 过期时间
|
||||
}
|
||||
|
||||
// DNSCache DNS缓存结构
|
||||
type DNSCache struct {
|
||||
cache map[string]*DNSCacheItem // 缓存映射表
|
||||
mutex sync.RWMutex // 读写锁,保护缓存
|
||||
defaultTTL time.Duration // 默认缓存TTL
|
||||
}
|
||||
|
||||
// NewDNSCache 创建新的DNS缓存实例
|
||||
func NewDNSCache(defaultTTL time.Duration) *DNSCache {
|
||||
cache := &DNSCache{
|
||||
cache: make(map[string]*DNSCacheItem),
|
||||
defaultTTL: defaultTTL,
|
||||
}
|
||||
|
||||
// 启动缓存清理协程
|
||||
go cache.startCleanupLoop()
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
// cacheKey 生成缓存键
|
||||
func cacheKey(qName string, qType uint16) string {
|
||||
return qName + "|" + dns.TypeToString[qType]
|
||||
}
|
||||
|
||||
// Set 设置缓存项
|
||||
func (c *DNSCache) Set(qName string, qType uint16, response *dns.Msg, ttl time.Duration) {
|
||||
if ttl <= 0 {
|
||||
ttl = c.defaultTTL
|
||||
}
|
||||
|
||||
key := cacheKey(qName, qType)
|
||||
item := &DNSCacheItem{
|
||||
Response: response.Copy(), // 复制响应以避免外部修改
|
||||
Expiry: time.Now().Add(ttl),
|
||||
}
|
||||
|
||||
c.mutex.Lock()
|
||||
c.cache[key] = item
|
||||
c.mutex.Unlock()
|
||||
}
|
||||
|
||||
// Get 获取缓存项
|
||||
func (c *DNSCache) Get(qName string, qType uint16) (*dns.Msg, bool) {
|
||||
key := cacheKey(qName, qType)
|
||||
|
||||
c.mutex.RLock()
|
||||
item, found := c.cache[key]
|
||||
if !found {
|
||||
c.mutex.RUnlock()
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// 检查是否过期
|
||||
if time.Now().After(item.Expiry) {
|
||||
c.mutex.RUnlock()
|
||||
// 过期了,删除缓存项(在写锁中)
|
||||
c.delete(key)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// 返回缓存的响应副本
|
||||
response := item.Response.Copy()
|
||||
c.mutex.RUnlock()
|
||||
|
||||
return response, true
|
||||
}
|
||||
|
||||
// delete 删除缓存项
|
||||
func (c *DNSCache) delete(key string) {
|
||||
c.mutex.Lock()
|
||||
delete(c.cache, key)
|
||||
c.mutex.Unlock()
|
||||
}
|
||||
|
||||
// Clear 清空缓存
|
||||
func (c *DNSCache) Clear() {
|
||||
c.mutex.Lock()
|
||||
c.cache = make(map[string]*DNSCacheItem)
|
||||
c.mutex.Unlock()
|
||||
}
|
||||
|
||||
// Size 获取缓存大小
|
||||
func (c *DNSCache) Size() int {
|
||||
c.mutex.RLock()
|
||||
defer c.mutex.RUnlock()
|
||||
return len(c.cache)
|
||||
}
|
||||
|
||||
// startCleanupLoop 启动定期清理过期缓存的协程
|
||||
func (c *DNSCache) startCleanupLoop() {
|
||||
ticker := time.NewTicker(time.Minute * 5) // 每5分钟清理一次
|
||||
defer ticker.Stop()
|
||||
|
||||
for range ticker.C {
|
||||
c.cleanupExpired()
|
||||
}
|
||||
}
|
||||
|
||||
// cleanupExpired 清理过期的缓存项
|
||||
func (c *DNSCache) cleanupExpired() {
|
||||
now := time.Now()
|
||||
|
||||
c.mutex.Lock()
|
||||
defer c.mutex.Unlock()
|
||||
|
||||
for key, item := range c.cache {
|
||||
if now.After(item.Expiry) {
|
||||
delete(c.cache, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,6 +56,7 @@ type QueryLog struct {
|
||||
Result string // 查询结果(allowed, blocked, error)
|
||||
BlockRule string // 屏蔽规则(如果被屏蔽)
|
||||
BlockType string // 屏蔽类型(如果被屏蔽)
|
||||
FromCache bool // 是否来自缓存
|
||||
}
|
||||
|
||||
// StatsData 用于持久化的统计数据结构
|
||||
@@ -107,6 +108,9 @@ type Server struct {
|
||||
ipGeolocationCache map[string]*IPGeolocation // IP地址到地理位置的映射
|
||||
ipGeolocationCacheMutex sync.RWMutex // 保护IP地理位置缓存的互斥锁
|
||||
ipGeolocationCacheTTL time.Duration // 缓存有效期
|
||||
|
||||
// DNS查询缓存
|
||||
dnsCache *DNSCache // DNS响应缓存
|
||||
}
|
||||
|
||||
// Stats DNS服务器统计信息
|
||||
@@ -126,6 +130,10 @@ type Stats struct {
|
||||
// NewServer 创建DNS服务器实例
|
||||
func NewServer(config *config.DNSConfig, shieldConfig *config.ShieldConfig, shieldManager *shield.ShieldManager) *Server {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
// 从配置中读取DNS缓存TTL值(分钟)
|
||||
cacheTTL := time.Duration(config.CacheTTL) * time.Minute
|
||||
|
||||
server := &Server{
|
||||
config: config,
|
||||
shieldConfig: shieldConfig,
|
||||
@@ -161,6 +169,8 @@ func NewServer(config *config.DNSConfig, shieldConfig *config.ShieldConfig, shie
|
||||
// IP地理位置缓存初始化
|
||||
ipGeolocationCache: make(map[string]*IPGeolocation),
|
||||
ipGeolocationCacheTTL: 24 * time.Hour, // 缓存有效期24小时
|
||||
// DNS查询缓存初始化
|
||||
dnsCache: NewDNSCache(cacheTTL),
|
||||
}
|
||||
|
||||
// 加载已保存的统计数据
|
||||
@@ -291,6 +301,7 @@ func (s *Server) handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||
// 获取查询域名和类型
|
||||
var domain string
|
||||
var queryType string
|
||||
var qType uint16
|
||||
if len(r.Question) > 0 {
|
||||
domain = r.Question[0].Name
|
||||
// 移除末尾的点
|
||||
@@ -299,6 +310,7 @@ func (s *Server) handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||
}
|
||||
// 获取查询类型
|
||||
queryType = dns.TypeToString[r.Question[0].Qtype]
|
||||
qType = r.Question[0].Qtype
|
||||
// 更新查询类型统计
|
||||
s.updateStats(func(stats *Stats) {
|
||||
stats.QueryTypes[queryType]++
|
||||
@@ -325,7 +337,7 @@ func (s *Server) handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||
})
|
||||
|
||||
// 添加查询日志
|
||||
s.addQueryLog(sourceIP, domain, queryType, responseTime, "error", "", "")
|
||||
s.addQueryLog(sourceIP, domain, queryType, responseTime, "error", "", "", false)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -342,7 +354,7 @@ func (s *Server) handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||
})
|
||||
|
||||
// 添加查询日志
|
||||
s.addQueryLog(sourceIP, domain, queryType, responseTime, "allowed", "", "")
|
||||
s.addQueryLog(sourceIP, domain, queryType, responseTime, "allowed", "", "", false)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -364,12 +376,18 @@ func (s *Server) handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||
})
|
||||
|
||||
// 添加查询日志
|
||||
s.addQueryLog(sourceIP, domain, queryType, responseTime, "blocked", blockRule, blockType)
|
||||
s.addQueryLog(sourceIP, domain, queryType, responseTime, "blocked", blockRule, blockType, false)
|
||||
return
|
||||
}
|
||||
|
||||
// 转发到上游DNS服务器
|
||||
s.forwardDNSRequest(w, r, domain)
|
||||
// 检查缓存中是否有响应(增强版缓存查询)
|
||||
if cachedResponse, found := s.dnsCache.Get(r.Question[0].Name, qType); found {
|
||||
// 缓存命中,直接返回缓存的响应
|
||||
cachedResponseCopy := cachedResponse.Copy() // 创建响应副本避免并发修改问题
|
||||
cachedResponseCopy.Id = r.Id // 更新ID以匹配请求
|
||||
cachedResponseCopy.Compress = true
|
||||
w.WriteMsg(cachedResponseCopy)
|
||||
|
||||
// 计算响应时间
|
||||
responseTime := time.Since(startTime).Milliseconds()
|
||||
s.updateStats(func(stats *Stats) {
|
||||
@@ -379,8 +397,40 @@ func (s *Server) handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||
}
|
||||
})
|
||||
|
||||
// 添加查询日志
|
||||
s.addQueryLog(sourceIP, domain, queryType, responseTime, "allowed", "", "")
|
||||
// 添加查询日志 - 标记为缓存
|
||||
s.addQueryLog(sourceIP, domain, queryType, responseTime, "allowed", "", "", true)
|
||||
logger.Debug("从缓存返回DNS响应", "domain", domain, "type", queryType)
|
||||
return
|
||||
}
|
||||
|
||||
// 缓存未命中,转发到上游DNS服务器
|
||||
response, _ := s.forwardDNSRequestWithCache(r, domain)
|
||||
if response != nil {
|
||||
// 写入响应给客户端
|
||||
w.WriteMsg(response)
|
||||
}
|
||||
|
||||
// 计算响应时间
|
||||
responseTime := time.Since(startTime).Milliseconds()
|
||||
s.updateStats(func(stats *Stats) {
|
||||
stats.TotalResponseTime += responseTime
|
||||
if stats.Queries > 0 {
|
||||
stats.AvgResponseTime = float64(stats.TotalResponseTime) / float64(stats.Queries)
|
||||
}
|
||||
})
|
||||
|
||||
// 如果响应成功,缓存结果(增强版缓存存储)
|
||||
if response != nil && response.Rcode == dns.RcodeSuccess {
|
||||
// 创建响应副本以避免后续修改影响缓存
|
||||
responseCopy := response.Copy()
|
||||
// 设置合理的TTL,不超过默认的30分钟
|
||||
defaultCacheTTL := 30 * time.Minute
|
||||
s.dnsCache.Set(r.Question[0].Name, qType, responseCopy, defaultCacheTTL)
|
||||
logger.Debug("DNS响应已缓存", "domain", domain, "type", queryType, "ttl", defaultCacheTTL)
|
||||
}
|
||||
|
||||
// 添加查询日志 - 标记为实时
|
||||
s.addQueryLog(sourceIP, domain, queryType, responseTime, "allowed", "", "", false)
|
||||
}
|
||||
|
||||
// handleHostsResponse 处理hosts文件匹配的响应
|
||||
@@ -484,7 +534,8 @@ func (s *Server) handleBlockedResponse(w dns.ResponseWriter, r *dns.Msg, domain
|
||||
}
|
||||
|
||||
// forwardDNSRequest 转发DNS请求到上游服务器
|
||||
func (s *Server) forwardDNSRequest(w dns.ResponseWriter, r *dns.Msg, domain string) {
|
||||
// forwardDNSRequestWithCache 转发DNS请求到上游服务器并返回响应
|
||||
func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg, time.Duration) {
|
||||
// 尝试所有上游DNS服务器
|
||||
for _, upstream := range s.config.UpstreamDNS {
|
||||
response, rtt, err := s.resolver.Exchange(r, upstream)
|
||||
@@ -492,7 +543,6 @@ func (s *Server) forwardDNSRequest(w dns.ResponseWriter, r *dns.Msg, domain stri
|
||||
// 设置递归可用标志
|
||||
response.RecursionAvailable = true
|
||||
|
||||
w.WriteMsg(response)
|
||||
logger.Debug("DNS查询成功", "domain", domain, "rtt", rtt, "server", upstream)
|
||||
|
||||
// 记录解析域名统计
|
||||
@@ -501,7 +551,7 @@ func (s *Server) forwardDNSRequest(w dns.ResponseWriter, r *dns.Msg, domain stri
|
||||
s.updateStats(func(stats *Stats) {
|
||||
stats.Allowed++
|
||||
})
|
||||
return
|
||||
return response, rtt
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,12 +560,18 @@ func (s *Server) forwardDNSRequest(w dns.ResponseWriter, r *dns.Msg, domain stri
|
||||
response.SetReply(r)
|
||||
response.RecursionAvailable = true
|
||||
response.SetRcode(r, dns.RcodeServerFailure)
|
||||
w.WriteMsg(response)
|
||||
|
||||
logger.Error("DNS查询失败", "domain", domain)
|
||||
s.updateStats(func(stats *Stats) {
|
||||
stats.Errors++
|
||||
})
|
||||
return response, 0
|
||||
}
|
||||
|
||||
// forwardDNSRequest 转发DNS请求到上游服务器
|
||||
func (s *Server) forwardDNSRequest(w dns.ResponseWriter, r *dns.Msg, domain string) {
|
||||
response, _ := s.forwardDNSRequestWithCache(r, domain)
|
||||
w.WriteMsg(response)
|
||||
}
|
||||
|
||||
// updateBlockedDomainStats 更新被屏蔽域名统计
|
||||
@@ -599,7 +655,7 @@ func (s *Server) updateStats(update func(*Stats)) {
|
||||
}
|
||||
|
||||
// addQueryLog 添加查询日志
|
||||
func (s *Server) addQueryLog(clientIP, domain, queryType string, responseTime int64, result, blockRule, blockType string) {
|
||||
func (s *Server) addQueryLog(clientIP, domain, queryType string, responseTime int64, result, blockRule, blockType string, fromCache bool) {
|
||||
// 获取IP地理位置
|
||||
location := s.getIpGeolocation(clientIP)
|
||||
|
||||
@@ -614,6 +670,7 @@ func (s *Server) addQueryLog(clientIP, domain, queryType string, responseTime in
|
||||
Result: result,
|
||||
BlockRule: blockRule,
|
||||
BlockType: blockType,
|
||||
FromCache: fromCache,
|
||||
}
|
||||
|
||||
// 添加到日志列表
|
||||
|
||||
14
go.mod
14
go.mod
@@ -8,31 +8,17 @@ require (
|
||||
github.com/gorilla/websocket v1.5.1
|
||||
github.com/miekg/dns v1.1.68
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/swaggo/http-swagger v1.2.0
|
||||
)
|
||||
|
||||
// 清理不需要的依赖
|
||||
// 之前的go.sum可能包含lumberjack的记录,但现在已经不再使用
|
||||
|
||||
require (
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||
github.com/go-openapi/spec v0.20.4 // indirect
|
||||
github.com/go-openapi/swag v0.19.15 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.6 // indirect
|
||||
github.com/stretchr/testify v1.10.0 // indirect
|
||||
github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2 // indirect
|
||||
github.com/swaggo/swag v1.7.8 // indirect
|
||||
golang.org/x/mod v0.25.0 // indirect
|
||||
golang.org/x/net v0.42.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/sys v0.35.0 // indirect
|
||||
golang.org/x/text v0.27.0 // indirect
|
||||
golang.org/x/tools v0.34.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
||||
94
go.sum
94
go.sum
@@ -1,126 +1,32 @@
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/agiledragon/gomonkey/v2 v2.3.1 h1:k+UnUY0EMNYUFUAQVETGY9uUTxjMdnUkP0ARyJS1zzs=
|
||||
github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
|
||||
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
|
||||
github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
|
||||
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
|
||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/miekg/dns v1.1.68 h1:jsSRkNozw7G/mnmXULynzMNIsgY2dHC8LO6U6Ij2JEA=
|
||||
github.com/miekg/dns v1.1.68/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE=
|
||||
github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U=
|
||||
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
|
||||
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
|
||||
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
|
||||
github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2 h1:+iNTcqQJy0OZ5jk6a5NLib47eqXK8uYcPX+O4+cBpEM=
|
||||
github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w=
|
||||
github.com/swaggo/http-swagger v1.2.0 h1:G5EBD5nvw379l2sFhact660YDT++eLviczLPrgNw/lU=
|
||||
github.com/swaggo/http-swagger v1.2.0/go.mod h1:P7+V1SLG2zloe+VvAGL7WgFimhJACaBLAv2N7YQ0ikI=
|
||||
github.com/swaggo/swag v1.7.8 h1:w249t0l/kc/DKMGlS0fppNJQxKyJ8heNaUWB6nsH3zc=
|
||||
github.com/swaggo/swag v1.7.8/go.mod h1:gZ+TJ2w/Ve1RwQsA2IRoSOTidHz6DX+PIG8GWvbnoLU=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
|
||||
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
||||
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
|
||||
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
|
||||
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -15,7 +17,7 @@ var (
|
||||
)
|
||||
|
||||
// InitLogger 初始化日志系统
|
||||
func InitLogger(logFile, level string, maxSize, maxBackups, maxAge int) error {
|
||||
func InitLogger(logFile, level string, maxSize, maxBackups, maxAge int, _ bool) error {
|
||||
logMutex.Lock()
|
||||
defer logMutex.Unlock()
|
||||
|
||||
@@ -30,21 +32,42 @@ func InitLogger(logFile, level string, maxSize, maxBackups, maxAge int) error {
|
||||
FullTimestamp: true,
|
||||
})
|
||||
|
||||
// 创建日志目录
|
||||
if logFile != "" {
|
||||
logDir := filepath.Dir(logFile)
|
||||
if logDir != "." {
|
||||
if err := os.MkdirAll(logDir, 0755); err != nil {
|
||||
return fmt.Errorf("创建日志目录失败: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 设置输出目标
|
||||
outputTargets := []io.Writer{}
|
||||
|
||||
if logFile != "" {
|
||||
// 使用标准库打开文件,支持追加写入
|
||||
file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
|
||||
if err != nil {
|
||||
logrus.Warn("无法打开日志文件,将使用标准输出", "error", err)
|
||||
log.SetOutput(os.Stdout)
|
||||
// 无法打开日志文件时,回退到标准输出
|
||||
log.Println("无法打开日志文件,将使用标准输出:", err)
|
||||
} else {
|
||||
// 同时输出到文件和标准输出
|
||||
log.SetOutput(io.MultiWriter(file, os.Stdout))
|
||||
outputTargets = append(outputTargets, file)
|
||||
defer file.Sync() // 确保日志内容被写入磁盘
|
||||
}
|
||||
}
|
||||
|
||||
// 无论是否指定日志文件,都同时输出到标准输出
|
||||
if len(outputTargets) > 0 {
|
||||
outputTargets = append(outputTargets, os.Stdout)
|
||||
} else {
|
||||
log.SetOutput(os.Stdout)
|
||||
// 如果没有指定日志文件,仅使用标准输出
|
||||
outputTargets = append(outputTargets, os.Stdout)
|
||||
}
|
||||
|
||||
// 设置日志输出
|
||||
log.SetOutput(io.MultiWriter(outputTargets...))
|
||||
|
||||
// 设置日志级别
|
||||
logLevel, err := logrus.ParseLevel(level)
|
||||
if err != nil {
|
||||
@@ -61,13 +84,20 @@ func Close() {
|
||||
logMutex.Lock()
|
||||
defer logMutex.Unlock()
|
||||
|
||||
if !initialized {
|
||||
if !initialized || log == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 执行日志刷新
|
||||
log.Warn("日志系统已关闭")
|
||||
|
||||
// 确保日志被写入磁盘
|
||||
if loggerOutput, ok := log.Out.(*os.File); ok {
|
||||
loggerOutput.Sync()
|
||||
}
|
||||
|
||||
initialized = false
|
||||
log = nil
|
||||
}
|
||||
|
||||
// Info 记录信息级别日志
|
||||
@@ -122,6 +152,20 @@ func Warn(msg string, fields ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// Fatal 记录致命级别日志并退出程序
|
||||
func Fatal(msg string, fields ...interface{}) {
|
||||
if !initialized {
|
||||
// 如果日志系统未初始化,使用标准库log
|
||||
log.Fatal(msg)
|
||||
}
|
||||
|
||||
if len(fields) > 0 {
|
||||
log.WithFields(toFields(fields)).Fatal(msg)
|
||||
} else {
|
||||
log.Fatal(msg)
|
||||
}
|
||||
}
|
||||
|
||||
// toFields 将键值对转换为logrus字段
|
||||
func toFields(keyValues []interface{}) logrus.Fields {
|
||||
fields := make(logrus.Fields)
|
||||
|
||||
41682
logs/dns-server.log
41682
logs/dns-server.log
File diff suppressed because it is too large
Load Diff
91
main.go
91
main.go
@@ -148,20 +148,9 @@ func createRequiredFiles(cfg *config.Config) error {
|
||||
func main() {
|
||||
// 命令行参数解析
|
||||
var configFile string
|
||||
var daemonMode bool
|
||||
flag.StringVar(&configFile, "config", "config.json", "配置文件路径")
|
||||
flag.BoolVar(&daemonMode, "daemon", false, "以守护进程模式运行")
|
||||
flag.Parse()
|
||||
|
||||
// 如果是守护进程模式,创建守护进程
|
||||
if daemonMode {
|
||||
if err := daemonize(); err != nil {
|
||||
log.Fatalf("创建守护进程失败: %v", err)
|
||||
}
|
||||
// 父进程退出
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// 检查配置文件是否存在,如果不存在则创建默认配置文件
|
||||
if _, err := os.Stat(configFile); os.IsNotExist(err) {
|
||||
log.Printf("配置文件 %s 不存在,正在创建默认配置文件...", configFile)
|
||||
@@ -187,7 +176,7 @@ func main() {
|
||||
log.Println("所需文件和文件夹创建成功")
|
||||
|
||||
// 初始化日志系统
|
||||
if err := logger.InitLogger(cfg.Log.File, cfg.Log.Level, 0, 0, 0); err != nil {
|
||||
if err := logger.InitLogger(cfg.Log.File, cfg.Log.Level, 0, 0, 0, false); err != nil {
|
||||
log.Fatalf("初始化日志系统失败: %v", err)
|
||||
}
|
||||
defer logger.Close()
|
||||
@@ -227,84 +216,10 @@ func main() {
|
||||
<-sigCh
|
||||
|
||||
// 清理资源
|
||||
log.Println("正在关闭服务...")
|
||||
logger.Info("正在关闭服务...")
|
||||
dnsServer.Stop()
|
||||
httpServer.Stop()
|
||||
shieldManager.StopAutoUpdate()
|
||||
// 守护进程模式下不需要删除PID文件
|
||||
|
||||
log.Println("服务已关闭")
|
||||
}
|
||||
|
||||
// daemonize 创建守护进程
|
||||
func daemonize() error {
|
||||
// 1. 第一次fork,创建子进程,父进程退出
|
||||
pid, err := syscall.Fork()
|
||||
if err != nil {
|
||||
return fmt.Errorf("第一次fork失败: %w", err)
|
||||
}
|
||||
if pid > 0 {
|
||||
// 父进程退出
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// 2. 设置文件权限掩码
|
||||
syscall.Umask(0)
|
||||
|
||||
// 3. 创建新会话
|
||||
_, err = syscall.Setsid()
|
||||
if err != nil {
|
||||
return fmt.Errorf("创建新会话失败: %w", err)
|
||||
}
|
||||
|
||||
// 4. 第二次fork,确保进程不是会话组长,避免获取控制终端
|
||||
pid, err = syscall.Fork()
|
||||
if err != nil {
|
||||
return fmt.Errorf("第二次fork失败: %w", err)
|
||||
}
|
||||
if pid > 0 {
|
||||
// 父进程退出
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// 5. 切换工作目录到根目录
|
||||
err = syscall.Chdir("/")
|
||||
if err != nil {
|
||||
return fmt.Errorf("切换工作目录失败: %w", err)
|
||||
}
|
||||
|
||||
// 6. 关闭所有打开的文件描述符
|
||||
for fd := 0; fd < 1024; fd++ {
|
||||
syscall.Close(fd)
|
||||
}
|
||||
|
||||
// 7. 重定向标准输入、输出、错误到/dev/null
|
||||
nullFile, err := os.OpenFile("/dev/null", os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("打开/dev/null失败: %w", err)
|
||||
}
|
||||
defer nullFile.Close()
|
||||
|
||||
// 重定向标准输入、输出、错误
|
||||
syscall.Dup2(int(nullFile.Fd()), 0) // stdin
|
||||
syscall.Dup2(int(nullFile.Fd()), 1) // stdout
|
||||
syscall.Dup2(int(nullFile.Fd()), 2) // stderr
|
||||
|
||||
// 8. 处理SIGCHLD信号,避免产生僵尸进程
|
||||
syscall.Signal(syscall.SIGCHLD, syscall.SIG_IGN)
|
||||
|
||||
// 9. 写入PID文件
|
||||
pid = syscall.Getpid()
|
||||
pidFile, err := os.OpenFile("/var/run/dns-server.pid", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("打开PID文件失败: %w", err)
|
||||
}
|
||||
_, err = fmt.Fprintf(pidFile, "%d\n", pid)
|
||||
if err != nil {
|
||||
pidFile.Close()
|
||||
return fmt.Errorf("写入PID文件失败: %w", err)
|
||||
}
|
||||
pidFile.Close()
|
||||
|
||||
return nil
|
||||
logger.Info("服务已关闭")
|
||||
}
|
||||
|
||||
41
server.log
41
server.log
@@ -1,41 +0,0 @@
|
||||
2025/11/30 11:09:05 正在创建所需的文件和文件夹...
|
||||
2025/11/30 11:09:05 所需文件和文件夹创建成功
|
||||
time="2025-11-30T11:09:05+08:00" level=debug msg="尝试加载Shield统计数据" file=/root/dnsbak/data/shield_stats.json
|
||||
time="2025-11-30T11:09:05+08:00" level=info msg="Shield计数数据加载成功" blocked_entries=0 resolved_entries=0
|
||||
time="2025-11-30T11:09:05+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/filter.txt"
|
||||
time="2025-11-30T11:09:05+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/hosts/adaway.txt"
|
||||
time="2025-11-30T11:09:06+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt"
|
||||
time="2025-11-30T11:09:06+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/costomize.txt"
|
||||
time="2025-11-30T11:09:06+08:00" level=info msg="从缓存加载远程规则" url="http://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/hosts/dsjh.txt"
|
||||
time="2025-11-30T11:09:06+08:00" level=info msg="从缓存加载远程规则" url="http://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/hate-and-junk-extended.txt"
|
||||
time="2025-11-30T11:09:06+08:00" level=info msg="从缓存加载远程规则" url="http://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/hosts/costomize.txt"
|
||||
time="2025-11-30T11:09:06+08:00" level=info msg="从缓存加载远程规则" url="http://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/hosts/anti-remoterequests.txt"
|
||||
time="2025-11-30T11:09:07+08:00" level=info msg="从缓存加载远程规则" url="http://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/url-based-adguard.txt"
|
||||
time="2025-11-30T11:09:07+08:00" level=info msg="从缓存加载远程规则" url="http://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/ads-and-trackers.txt"
|
||||
time="2025-11-30T11:09:08+08:00" level=info msg="从缓存加载远程规则" url="http://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/malware.txt"
|
||||
time="2025-11-30T11:09:09+08:00" level=info msg="从缓存加载远程规则" url="http://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/hosts/costomize.txt"
|
||||
time="2025-11-30T11:09:09+08:00" level=info msg="从缓存加载远程规则" url="http://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/rules/AWAvenue-Ads-Rule.txt"
|
||||
time="2025-11-30T11:09:09+08:00" level=info msg="从缓存加载远程规则" url="https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/cheat.txt"
|
||||
time="2025-11-30T11:09:10+08:00" level=info msg="规则加载完成,域名规则: 189895, 排除规则: 653, 正则规则: 24094, hosts规则: 0"
|
||||
time="2025-11-30T11:09:10+08:00" level=info msg="统计数据加载成功"
|
||||
time="2025-11-30T11:09:10+08:00" level=info msg="查询日志加载成功" count=8608
|
||||
time="2025-11-30T11:09:10+08:00" level=info msg="DNS服务器已启动,监听端口: 5353"
|
||||
time="2025-11-30T11:09:10+08:00" level=info msg="HTTP控制台已启动,监听端口: 8081"
|
||||
time="2025-11-30T11:09:10+08:00" level=info msg="DNS TCP服务器启动,监听端口: 5353"
|
||||
time="2025-11-30T11:09:10+08:00" level=info msg="启动Shield计数数据自动保存功能" file=./data/shield_stats.json interval=60
|
||||
time="2025-11-30T11:09:10+08:00" level=info msg="HTTP控制台服务器启动,监听地址: 0.0.0.0:8081"
|
||||
time="2025-11-30T11:09:10+08:00" level=info msg="规则自动更新已启动" interval=3600
|
||||
time="2025-11-30T11:09:10+08:00" level=info msg="DNS UDP服务器启动,监听端口: 5353"
|
||||
time="2025-11-30T11:09:10+08:00" level=info msg="启动统计数据自动保存功能" file=data/stats.json interval=300
|
||||
time="2025-11-30T11:09:10+08:00" level=error msg="DNS UDP服务器启动失败" error="listen udp :5353: bind: address already in use"
|
||||
time="2025-11-30T11:09:10+08:00" level=info msg="Shield计数数据保存成功" blocked_entries=0 file=/root/dnsbak/data/shield_stats.json resolved_entries=0
|
||||
2025/11/30 11:09:18 正在关闭服务...
|
||||
time="2025-11-30T11:09:18+08:00" level=info msg="统计数据保存成功" file=/root/dnsbak/data/stats.json
|
||||
time="2025-11-30T11:09:18+08:00" level=info msg="查询日志保存成功" file=/root/dnsbak/data/querylog.json
|
||||
time="2025-11-30T11:09:18+08:00" level=info msg="DNS服务器已停止"
|
||||
time="2025-11-30T11:09:18+08:00" level=error msg="HTTP控制台服务器启动失败" error="http: Server closed"
|
||||
time="2025-11-30T11:09:18+08:00" level=info msg="HTTP控制台服务器已停止"
|
||||
time="2025-11-30T11:09:18+08:00" level=info msg="Shield计数数据保存成功" blocked_entries=0 file=/root/dnsbak/data/shield_stats.json resolved_entries=0
|
||||
time="2025-11-30T11:09:18+08:00" level=info msg="规则自动更新已停止"
|
||||
2025/11/30 11:09:18 服务已关闭
|
||||
time="2025-11-30T11:09:18+08:00" level=warning msg="日志系统已关闭"
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"blockedDomainsCount": {},
|
||||
"resolvedDomainsCount": {},
|
||||
"lastSaved": "2025-11-29T02:08:50.6341349+08:00"
|
||||
}
|
||||
@@ -384,6 +384,10 @@ function updateLogsTable(logs) {
|
||||
}
|
||||
|
||||
// 构建行内容 - 两行显示,时间列显示时间和日期,请求列显示域名和类型状态
|
||||
// 添加缓存状态显示
|
||||
const cacheStatusClass = log.FromCache ? 'text-primary' : 'text-gray-500';
|
||||
const cacheStatusText = log.FromCache ? '缓存' : '非缓存';
|
||||
|
||||
row.innerHTML = `
|
||||
<td class="py-3 px-4">
|
||||
<div class="text-sm font-medium">${formattedTime}</div>
|
||||
@@ -395,7 +399,7 @@ function updateLogsTable(logs) {
|
||||
</td>
|
||||
<td class="py-3 px-4 text-sm">
|
||||
<div class="font-medium">${log.Domain}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">类型: ${log.QueryType}, <span class="${statusClass}">${statusText}</span></div>
|
||||
<div class="text-xs text-gray-500 mt-1">类型: ${log.QueryType}, <span class="${statusClass}">${statusText}</span>, <span class="${cacheStatusClass}">${log.FromCache ? '缓存' : '实时'}</span></div>
|
||||
</td>
|
||||
<td class="py-3 px-4 text-sm">${log.ResponseTime}ms</td>
|
||||
<td class="py-3 px-4 text-sm text-gray-500">${log.BlockRule || '-'}</td>
|
||||
|
||||
Reference in New Issue
Block a user