openwrt-dnsforwarder: remove luci
This commit is contained in:
parent
7d1a154584
commit
c0a008438d
@ -9,10 +9,8 @@ PKG_SOURCE_URL:=https://github.com/holmium/dnsforwarder.git
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_SOURCE_VERSION:=587e61ae4d75dc976f538088b715a3c8ee26c144
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-6
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/$(PKG_NAME)
|
||||
@ -27,35 +25,12 @@ define Package/$(PKG_NAME)/description
|
||||
Forwarding queries to customized domains (and their subdomains) to specified servers over a specified protocol (UDP or TCP). non-standard ports are supported.
|
||||
endef
|
||||
|
||||
|
||||
define Package/$(PKG_NAME)/postinst
|
||||
#!/bin/sh
|
||||
rm -rf /tmp/luci*
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/conffiles
|
||||
/etc/dnsforwarder/dnsforwarder.conf
|
||||
/etc/dnsforwarder/china-banned
|
||||
/etc/dnsforwarder/base-gfwlist.txt
|
||||
/etc/dnsforwarder/userlist
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
$(Build/Prepare/Default)
|
||||
$(foreach po,$(wildcard ${CURDIR}/i18n/zh-cn/*.po), \
|
||||
po2lmo $(po) $(PKG_BUILD_DIR)/$(patsubst %.po,%.lmo,$(notdir $(po)));)
|
||||
endef
|
||||
|
||||
|
||||
CONFIGURE_ARGS += --enable-downloader=wget
|
||||
|
||||
|
||||
define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/dnsforwarder $(1)/usr/bin/dnsforwarder
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/*.*.lmo $(1)/usr/lib/lua/luci/i18n/
|
||||
$(CP) ./files/* $(1)/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
||||
|
||||
@ -1,75 +0,0 @@
|
||||
# openwrt-dnsforwarder
|
||||
为OpenWRT路由器编译运行[dnsforwarder][A]编写的Makefile和luci界面
|
||||
|
||||
|
||||
|
||||
简介
|
||||
---
|
||||
|
||||
本软件包为OpenWRT路由器使用dnsforwarder配置企业级DNS服务器并与dnsmasq配合进行智能黑名单解析的工具
|
||||
|
||||
1、支持在Web界面编辑dnsforwarder配置文件
|
||||
|
||||
2、支持在Web界面编辑GFWList名单和自定义的黑白名单
|
||||
|
||||
3、可以控制iptables对客户端发来的DNS请求进行劫持
|
||||
|
||||
4、与DNSMasq配合进行给予黑白名单的DNS请求转发
|
||||
|
||||
5、与DNSMasq配合将黑白名单中的域名解析完成后添加到ipset,为SSR路由提供依据
|
||||
|
||||
6、支持一键升级GFWList黑名单
|
||||
|
||||
|
||||
|
||||
依赖
|
||||
---
|
||||
|
||||
显式依赖 `wget`,用于加载网络上的host文件
|
||||
|
||||
|
||||
配置
|
||||
---
|
||||
|
||||
配置文件地址 "/etc/dnsforwarer/dnsfrowarder.conf"
|
||||
|
||||
GFWList地址 "/etc/dnsforwarer/base-gfwlist.txt"
|
||||
|
||||
用户自定义黑名单 “/etc/dnsforwarer/userlist”
|
||||
|
||||
用户自定义白名单 “etc/dnsforwarer/whitelist”
|
||||
|
||||
|
||||
编译
|
||||
---
|
||||
|
||||
从 OpenWrt 的 [SDK][openwrt-sdk] 编译
|
||||
```bash
|
||||
# 解压下载好的 SDK
|
||||
tar xjf OpenWrt-SDK-ar71xx-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2.tar.bz2
|
||||
cd OpenWrt-SDK-ar71xx-*
|
||||
# Clone 项目
|
||||
git clone https://github.com/AlexZhuo/openwrt-dnsforwarder/ package/dnsforwarder
|
||||
# 编译 po2lmo (如果有po2lmo可跳过)
|
||||
pushd package/dnsforwarder/tools/po2lmo
|
||||
make && sudo make install
|
||||
popd
|
||||
# 选择要编译的包 Network -> dnsforwarder
|
||||
make menuconfig
|
||||
# 开始编译
|
||||
make package/dnsforwarder/compile V=99
|
||||
```
|
||||
|
||||
截图
|
||||
---
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
[A]: https://github.com/holmium/dnsforwarder
|
||||
[openwrt-sdk]: https://wiki.openwrt.org/doc/howto/obtain.firmware.sdk
|
||||
@ -1,5 +0,0 @@
|
||||
|
||||
config arguments
|
||||
option enabled '0'
|
||||
option redir '0'
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,434 +0,0 @@
|
||||
# DNS 转发器的配置文件
|
||||
# Configuration File for dnsforwarder
|
||||
# 此配置文件最好是 ANSI 编码的
|
||||
|
||||
# 相对路径的写法
|
||||
# Windows:
|
||||
# 支持用 `% %' 包围起来的相对路径,比如 `%SYSTEMROOT%\System32\drivers\etc\hosts'。
|
||||
# `%PROGRAMDIRECTORY%' 表示程序所在的文件夹。
|
||||
# `%CONFIGFILEDIRECTORY%' 表示配置文件所在的文件夹。 (since 6.1.3)
|
||||
#
|
||||
# Linux:
|
||||
# 支持类似 `${HOME}' 的变量,比如 `${HOME}/hosts'。
|
||||
# `${PROGRAMDIRECTORY}' 表示程序的配置文件夹,一般为 `/root/.dnsforwarder/',执行 `dnsforwarder -p' 可以获得具体的位置。
|
||||
# `${CONFIGFILEDIRECTORY}' 表示配置文件所在的文件夹。 (since 6.1.3)
|
||||
|
||||
##################################################
|
||||
#
|
||||
# 日志文件设置
|
||||
#
|
||||
##################################################
|
||||
|
||||
# LogOn <BOOLEAN>
|
||||
# 是否打开文件日志输出 (since 5.0.4)
|
||||
LogOn true
|
||||
|
||||
# LogFileThresholdLength <NUM>
|
||||
# 单个日志文件大小的临界值(字节)(since 5.0.4)
|
||||
# 当日志文件大小超过这个临界值后,当前的日志文件将会被重命名,然后建立一个新的日志文件,继续记录日志
|
||||
LogFileThresholdLength 102400
|
||||
|
||||
# LogFileFolder <PATH>
|
||||
# 设定日志文件所在的文件夹 (since 5.0.4)
|
||||
# 日志文件初始的文件名为 `dnsforwarder.log',当超过临界值之后,将会被重命名为 `dnsforwarder.log.1'、`dnsforwarder.log.2' 等等,然后重新建立一个 dnsforwarder.log' 文件
|
||||
# 此路径的默认值为程序所在的文件夹(Windows)或程序的配置文件夹(Linux)
|
||||
LogFileFolder /var/log
|
||||
|
||||
##################################################
|
||||
#
|
||||
# 本地
|
||||
#
|
||||
##################################################
|
||||
|
||||
# UDPLocal <IP[:PORT]>,<IP[:PORT]>,...
|
||||
# 设置在本地开启的接口的IP地址和端口,可以是本地回环地址 (127.0.0.1) ,本地局域网,以及互联网 (since 6.0.0)
|
||||
# 如果是 IPv6 地址,请在IP两端加上方括号(不包含端口部分),例如 [::1]:53 (本地回环)、[fe80::699c:f79a:9bb6:1]:5353 (since 6.0.0)
|
||||
# 可以设置多个地址,用半角逗号(`,')分割
|
||||
# 如果不指定端口,则默认为 53
|
||||
#
|
||||
# 示例:
|
||||
# UDPLocal 127.0.0.1:53,[::1]:53
|
||||
UDPLocal 0.0.0.0:5053
|
||||
|
||||
# 这一版本暂时不支持在本地开启 TCP 端口,以后会加上
|
||||
|
||||
##################################################
|
||||
#
|
||||
# IP 选择策略
|
||||
#
|
||||
##################################################
|
||||
|
||||
#########################
|
||||
# 服务器地址
|
||||
#########################
|
||||
|
||||
# UDPGroup <IP1[:PORT],IP2[:PORT],...> <DOMAIN1,DOMAIN2,...> <on|off>
|
||||
# 设置一个 UDP 上游服务器组,并指定通过这些上游服务器查询的域名 (since 6.0.0)
|
||||
# 第一部分参数“<IP1[:PORT],IP2[:PORT],...>”,用于指定 UDP 上游服务器,不写端口则默认使用 53 端口
|
||||
# 第二部分参数“<DOMAIN1,DOMAIN2,...>”,用于指定通过这些 UDP 上游服务器查询的域名,可以包含通配符
|
||||
# 第三部分参数“<on|off>”,用于指定是否开启并发查询,`on' 为开启,`off' 为不开启
|
||||
# 并发查询指的是,向所有指定的 UDP 服务器发送查询请求,取最先接受到的未屏蔽的回复作为查询结果,并丢弃其余的回复
|
||||
# 可以有多条 `UDPGroup' 选项
|
||||
UDPGroup 1.0.0.1,1.1.1.1,4.2.2.1,4.2.2.2,1.2.4.8,210.2.4.8,8.8.4.4,8.8.8.8,9.9.9.9,119.29.29.29,119.28.28.28,223.5.5.5,223.6.6.6,114.114.114.114,114.114.115.115,180.76.76.76,208.67.222.222,208.67.220.220,1.0.0.1:443,1.1.1.1:443,1.0.0.1:853,1.1.1.1:853,208.67.222.222:443,208.67.220.220:443,208.67.222.222:5353,208.67.220.220:5353,127.0.0.1:5353,240c::6666,240c::6644,2001:4860:4860::8844,2001:4860:4860::8888,2606:4700:4700::1111,2606:4700:4700::1001 * on
|
||||
|
||||
# TCPGroup <IP1[:PORT],IP2[:PORT],...> <DOMAIN1,DOMAIN2,...> <no|PROXY1[:PORT],PROXY2[:PORT],...>
|
||||
# 设置一个 TCP 上游服务器组,并指定通过这些上游服务器查询的域名 (since 6.0.0)
|
||||
# 第一部分参数“<IP1[:PORT],IP2[:PORT],...>”,用于指定 TCP 上游服务器,不写端口则默认使用 53 端口
|
||||
# 第二部分参数“<DOMAIN1,DOMAIN2,...>”,用于指定通过这些 TCP 上游服务器查询的域名,可以包含通配符
|
||||
# 第三部分参数“<no|PROXY1[:PORT],PROXY2[:PORT],...>”,用于指定查询时使用的 Socks5 代理,不写端口则默认使用 1080 端口。`no' 代表不使用代理
|
||||
# 可以有多条 `TCPGroup' 选项
|
||||
#
|
||||
# 示例一:
|
||||
# TCPGroup 1.2.4.8:53,114.114.114.114 *.example.com 192.168.50.5:8080,192.168.50.6:8080
|
||||
# `*.example.com' 将通过 192.168.50.5:8080 或 192.168.50.6:8080 两个 Socks5 代理,使用 TCP 协议向 1.2.4.8:53 或 114.114.114.114 进行查询
|
||||
# 示例二:
|
||||
# TCPGroup 8.8.8.8,114.114.114.114:53 * no
|
||||
# `*.example.com' 将使用 TCP 协议直接向 8.8.8.8 或 114.114.114.114:53 进行查询,不使用代理
|
||||
TCPGroup 1.0.0.1,1.1.1.1,4.2.2.1,4.2.2.2,1.2.4.8,210.2.4.8,8.8.4.4,8.8.8.8,9.9.9.9,119.29.29.29,119.28.28.28,223.5.5.5,223.6.6.6,114.114.114.114,114.114.115.115,180.76.76.76,208.67.222.222,208.67.220.220,1.0.0.1:443,1.1.1.1:443,1.0.0.1:853,1.1.1.1:853,208.67.222.222:443,208.67.220.220:443,208.67.222.222:5353,208.67.220.220:5353,240c::6666,240c::6644,2001:4860:4860::8844,2001:4860:4860::8888,2606:4700:4700::1111,2606:4700:4700::1001 * no
|
||||
|
||||
# GroupFile <PATH>
|
||||
# 从文件加载服务器组 (since 6.1.3)
|
||||
# 服务器组文件的写法请参阅:https://github.com/holmium/dnsforwarder/wiki/GroupFile-%E7%9A%84%E5%86%99%E6%B3%95-%7C-How-to-write-GroupFiles
|
||||
# 可以有多条 `GroupFile' 选项
|
||||
#
|
||||
# 示例一:
|
||||
# GroupFile D:\group.txt
|
||||
#
|
||||
# 示例二:
|
||||
# GroupFile /etc/group.txt
|
||||
GroupFile
|
||||
|
||||
# 注意:
|
||||
# 1.对于没有指定服务器的域名,会随机选择一个服务器组进行查询。
|
||||
# 2.如果某域名匹配多个服务器组,则选择的顺序如下:
|
||||
# (1) 优先选择不含通配符的匹配项,如果仍然有多条匹配,则选择匹配度最高的那个,
|
||||
# 如果匹配度相同的情况下仍然有多条匹配,则选择最后一个。
|
||||
# (例如 `ipv6.microsoft.com' 比 `microsoft.com' 对于域名 `teredo.ipv6.microsoft.com' 的匹配度更高)
|
||||
# (2) 然后选择包含通配符的匹配项,如果有多条匹配,则选择第一个;
|
||||
|
||||
# 组合示例:
|
||||
# 一、以 microsoft.com 或 office.com 结尾的域名通过 UDP 服务器 1.2.4.8 查询,其它域名通过 TCP 服务器 8.8.4.4 查询:
|
||||
# UDPGroup 1.2.4.8 microsoft.com,office.com on
|
||||
# TCPGroup 8.8.4.4 * no
|
||||
# 两行顺序请保持一致
|
||||
|
||||
|
||||
#########################
|
||||
# 服务器选项
|
||||
#########################
|
||||
|
||||
# BlockIP <IP1>,<IP2>,.....
|
||||
# 阻挡含有以下 IP 地址(支持 IPv4 和 IPv6 地址)的 DNS 数据包 (since 6.0.0)
|
||||
# IPv6 地址不用加方括号
|
||||
BlockIP 243.185.187.39,46.82.174.68,37.61.54.158,93.46.8.89,59.24.3.173,203.98.7.65,8.7.198.45,78.16.49.15,159.106.121.75,69.63.187.12,31.13.76.8,31.13.64.49
|
||||
|
||||
# IPSubstituting <IP1 IP'1>,<IP2 IP'2>,.....
|
||||
# 替换 DNS 数据包中的 IP 地址(只支持 IPv4 地址) (since 5.0.1)
|
||||
# 例如:
|
||||
# IPSubstituting 127.0.0.1 1.2.0.127
|
||||
# 的效果是把 DNS 数据包中所有的 127.0.0.1 地址替换为 1.2.0.127
|
||||
# 仅替换通过服务器(TCP 和 UDP)查询而来的 DNS 数据包,对于缓存中和 Hosts 中的结果无效
|
||||
# 多条替换项目用半角逗号 (`,') 分隔,也可以写多行 `IPSubstituting'
|
||||
IPSubstituting
|
||||
|
||||
# BlockNegativeResponse <BOOLEAN>
|
||||
# 是否过滤来自上游服务器的查询未成功的响应 (since 6.1.1)
|
||||
# 查询未成功指:格式错误、服务器错误、域名不存在和服务器拒绝请求等
|
||||
# 参见 RFC 6895,`2.3. RCODE Assignment'
|
||||
BlockNegativeResponse false
|
||||
|
||||
#########################
|
||||
# IP 列表(仅支持 IPv4 地址)
|
||||
#########################
|
||||
# IP 列表用于自动检测一组 IP 地址,将相应最快的 IP 地址甄选出来
|
||||
|
||||
# GoodIPList <NAME> <INTERVAL>
|
||||
# 定义一个 IP 列表,<NAME> 为改列表的名称,<INTERVAL> 为检测列表中 IP 地址有效性的间隔时间(毫秒)
|
||||
# 例如:
|
||||
# GoodIPList list1 60000
|
||||
|
||||
# GoodIPListAddIP <LIST_NAME> <IP:PORT>
|
||||
# 向一个 IP 列表中添加 IP 地址
|
||||
# 例如:
|
||||
# GoodIPListAddIP list1 120.0.0.1:80
|
||||
|
||||
#########################
|
||||
# Hosts
|
||||
#########################
|
||||
|
||||
# Hosts <STRING>
|
||||
# Hosts 文件的 URL,可以是本地 Hosts 文件 (以 file:// 开头,支持相对路径),也可以是网络上的 Hosts 文件 (以 http:// 或者 https:// 开头)。 (since 5.0.5)
|
||||
# 例如 file://C:/Windows/System32/drivers/etc/hosts 或 file:///etc/hosts 或 http://xxx.com/hosts
|
||||
# 写多条 `Hosts' 可以指定多个 Hosts 文件,路径两头不要加引号
|
||||
# 在 Hosts 文件中,支持通配符 (`*' 和 `?') (只能在域名中出现通配符)
|
||||
# Hosts 文件必须是原始格式,不能是压缩文件或者 HTML 文件
|
||||
# Hosts 文件最好是 ANSI 编码的
|
||||
# Hosts 中的 IPv6 地址不用加方括号
|
||||
# 如果保留为空,则不从文件载入 Hosts
|
||||
Hosts
|
||||
|
||||
# HostsUpdateInterval <NUM>
|
||||
# 重新载入 Hosts 文件的间隔时间,秒 (since 2.2)
|
||||
# -1 表示不重新载入
|
||||
# 如果保留为空,则使用默认值 (18000)
|
||||
HostsUpdateInterval 18000
|
||||
|
||||
# HostsDownloadPath <PATH>
|
||||
# Hosts 文件的下载到本地文件的路径 (不是文件夹路径) (since 2.2)
|
||||
# 例如 C:\Windows\Temp\hosts 或者 /tmp/hosts
|
||||
# 支持相对路径 (since 5.0.3)
|
||||
# 如果文件存在则覆盖
|
||||
# 如果保留为空,则默认在与程序所在相同的文件夹内(Windows)或程序的配置文件夹内(Linux)
|
||||
HostsDownloadPath
|
||||
|
||||
# HostsScript <PATH>
|
||||
# 在每次下载完 Hosts 文件后、加载 Hosts 文件之前执行的脚本 (since 2.2)
|
||||
# 支持相对路径 (since 5.0.3)
|
||||
# 如果保留为空,则不执行脚本
|
||||
HostsScript
|
||||
|
||||
# HostsRetryInterval <NUM>
|
||||
# 当网络 Hosts 下载失败后的重试时间,秒 (since 2.2.2)
|
||||
# 仅对网络 Hosts 有效
|
||||
# 如果保留为空,则使用默认值 (30)
|
||||
HostsRetryInterval 30
|
||||
|
||||
# AppendHosts <HOSTS>,<HOSTS>,...
|
||||
# 附加的 hosts,即使 `Hosts' 选项为空也照样载入 (since 2.2.2)
|
||||
# <HOSTS> 的写法与文件中的一样,同样支持通配符
|
||||
# IPv6 地址不用加方括号
|
||||
# 多条 hosts 可以用半角逗号分隔开,也可以写多条 `AppendHosts'
|
||||
# 比如可以写成:
|
||||
# AppendHosts 127.0.0.1 123.com,127.0.0.1 456.com,1.2.3.4 foobar.*
|
||||
# 也可以分多条写:
|
||||
# AppendHosts 127.0.0.1 123.com
|
||||
# AppendHosts 127.0.0.1 456.com
|
||||
# AppendHosts 1.2.3.4 foobar.*
|
||||
#
|
||||
# 也可以定义指向一个 IP 列表的 Hosts 项(仅支持 IPv4 地址),例如:
|
||||
# AppendHosts <list1> www.123.com
|
||||
# 此时 www.123.com 将会指向 list1 中最快的 IP 地址。
|
||||
#
|
||||
# 也可以定义 CName 的 Hosts 项,例如:
|
||||
# AppendHosts www.google.cn *.google.com
|
||||
# 这样所有匹配 *.google.com 的域名都将指向 www.google.cn 的 IP 地址 (since 2.3)
|
||||
#
|
||||
# 如果使某些域名跳过在 hosts 中的查询,可以
|
||||
# AppendHosts @@ *.012345.com
|
||||
# 这样所有匹配 *.012345.com 的域名都不会在 hosts 中查询
|
||||
#
|
||||
# 各种 hosts 的优先级从高到低
|
||||
# 带 `@@' 的禁止项
|
||||
# 一般 hosts 项
|
||||
# CName hosts 项
|
||||
AppendHosts
|
||||
|
||||
# BlockIpv6WhenIpv4Exists <BOOLEAN>
|
||||
# 如果一个域名在 Hosts 被指定了一个 IPv4 地址(包括文件 Hosts 和 `AppendHosts' 指定的 Hosts),那么拒绝对这个域名的 IPv6 地址查询 (since 5.0.12, renamed after 6.0.0)
|
||||
BlockIpv6WhenIpv4Exists false
|
||||
|
||||
##################################################
|
||||
#
|
||||
# 缓存控制
|
||||
#
|
||||
##################################################
|
||||
|
||||
# UseCache <BOOLEAN>
|
||||
# 是否使用缓存(默认为文件缓存) (since 2.2)
|
||||
# 可选值:`false' 或 `true'
|
||||
UseCache false
|
||||
|
||||
# CacheSize <NUM>
|
||||
# 缓存大小 (字节)
|
||||
# 缓存大小不能小于 102400 (100KB) (since 2.3)
|
||||
CacheSize 1048576
|
||||
|
||||
# MemoryCache <BOOLEAN>
|
||||
# 是否使用内存缓存,而不是文件缓存 (since 2.3.2)
|
||||
# 如果 `UseCache' 为 `false',此选项无效
|
||||
# 可选值:`false' 或 `true'
|
||||
MemoryCache true
|
||||
|
||||
# CacheFile <PATH>
|
||||
# 手工指定缓存文件 (不是文件夹) (since 2.3)
|
||||
# 支持相对路径 (since 5.0.3)
|
||||
# 如果保留为空,则默认在与程序所在相同的文件夹内(Windows)或程序的配置文件夹内(Linux)
|
||||
# 如果 `MemoryCache' 为 `true',此选项无效
|
||||
CacheFile
|
||||
|
||||
# IgnoreTTL <BOOLEAN>
|
||||
# 是否忽略 TTL (since 2.2)
|
||||
# 可选值:`false' 或 `true'
|
||||
# 为 `true' 时将忽略 TTL,此时所有的缓存条目将不会被移除
|
||||
# 为 `false' 时不忽略 TTL,缓存条目将会按照 TTL 的时间来移除
|
||||
# 当 `UseCache' 的值为 `false' 时,此选项无效
|
||||
IgnoreTTL false
|
||||
|
||||
# OverrideTTL <NUM>
|
||||
# 强制使所有缓存的条目的 TTL 为 <NUM> (since 2.2)
|
||||
# 若 <NUM> 为 -1,则表示不进行强制
|
||||
# 当 `UseCache' 的值为 `false' 时,此选项无效
|
||||
# 此选项等同于 `CacheControl * fixed <NUM>' (since 5.0.18)
|
||||
OverrideTTL -1
|
||||
|
||||
# MultipleTTL <NUM>
|
||||
# 将所有缓存条目的 TTL 加倍,倍数为 <NUM> (since 2.2)
|
||||
# 当 `UseCache' 的值为 `false' 时,此选项无效
|
||||
# 当 `IgnoreTTL' 的值为 `true' 时,此选项无效
|
||||
# 此选项等同于 `CacheControl * vari <NUM>x+0' (since 5.0.18)
|
||||
MultipleTTL 1
|
||||
|
||||
# CacheControl <DOMAIN> [$[$]]<TYPE> [ARGUMENT]
|
||||
# 控制域名 <DOMAIN> 的缓存行为 (since 5.0.18)
|
||||
# 如果缓存未开启,则此选项无效
|
||||
# <DOMAIN> 是域名;[$[$]] 是传染设定;<TYPE> 是类型;[ARGUMENT] 是参数
|
||||
# <DOMAIN> 支持通配符,支持尾部匹配
|
||||
# <TYPE> 有以下可选项(均为小写):
|
||||
# orig : 使用原先的 TTL,即不改变指定域名记录的 TTL,此类型无需 [ARGUMENT] 参数
|
||||
# nocache : 不缓存指定域名记录,此类型无需 [ARGUMENT] 参数
|
||||
# fixed : 将指定域名记录的 TTL 修改为一个预先指定的常数值,这个值通过 [ARGUMENT] 参数指定
|
||||
# vari : 将指定域名记录的 TTL 修改为一个预先规定的变量,这个变量通过 [ARGUMENT] 参数指定,此时 [ARGUMENT] 参数的格式为 `ax+b',其中 a、b 为非负整数(需用户手工指定),x 为记录原先的 TTL 值(不需要用户指定)。此选项必须为 `ax+b' 的形式,不能是 `ax-b' 或者其它的变体形式
|
||||
#
|
||||
# 示例:
|
||||
# CacheControl baidu.com orig # 不改变以 `baidu.com' 结尾的域名的 TTL
|
||||
# CacheControl 163.com nocache # 不缓存以 `163.com' 结尾的域名
|
||||
# CacheControl qq.com fixed 500 # 把所有以 `qq.com' 结尾的域名的 TTL 修改为 500
|
||||
# CacheControl sina.com.cn vari 2x+200 # 把所有以 `sina.com.cn' 结尾的域名的 TTL 的值修改为 2x+200,其中 x 是域名记录原先的 TTL 值
|
||||
#
|
||||
# 传染机制:
|
||||
# 某些域名有 CName 记录,例如 www.windowsupdate.com:
|
||||
# ;; QUESTION SECTION:
|
||||
# ;www.windowsupdate.com. IN A
|
||||
#
|
||||
# ;; ANSWER SECTION:
|
||||
# www.windowsupdate.com. 3585 IN CNAME windowsupdate.microsoft.nsatc.net. (记录一)
|
||||
# windowsupdate.microsoft.nsatc.net. 285 IN CNAME www.update.microsoft.com.nsatc.net. (记录二)
|
||||
# www.update.microsoft.com.nsatc.net. 285 IN A 134.170.58.222 (记录三)
|
||||
# www.update.microsoft.com.nsatc.net. 285 IN A 65.55.50.157 (记录四)
|
||||
#
|
||||
# 如果仅仅指定了 `www.windowsupdate.com' 的缓存控制,那么 `windowsupdate.microsoft.nsatc.net' 和 `www.update.microsoft.com.nsatc.net' 的记录以什么规则进行处理?是继承 `www.windowsupdate.com' 的缓存设置,还是使用自己专门的设置(如果有的话)?
|
||||
# 可以指定传染机制来解决这个问题
|
||||
# 有以下传染机制(以 `www.windowsupdate.com' 为例):
|
||||
# 主动传染 : 所有的域名记录不论是否存在单独指定的控制条目,均使用 `www.windowsupdate.com' 的控制条目
|
||||
# 被动传染 : 如果存在单独指定的控制条目,那么使用单独指定的控制条目,否则使用 `www.windowsupdate.com' 的控制条目
|
||||
# 不传染 : 如果存在单独指定的控制条目,那么使用单独指定的控制条目,如果没有则不修改记录的 TTL 值
|
||||
# 只有被查询的域名控制条目才具有传染性质
|
||||
# 写法:
|
||||
# 主动传染 (此为默认情况):
|
||||
# CacheControl www.windowsupdate.com fixed 1000
|
||||
# CacheControl 163.com orig
|
||||
# 被动传染(<TYPE> 前加一个 `$'):
|
||||
# CacheControl www.windowsupdate.com $fixed 1500
|
||||
# CacheControl sina.com.cn $nocache
|
||||
# 不传染(<TYPE> 前加两个 `$'):
|
||||
# CacheControl www.windowsupdate.com $$fixed 2000
|
||||
# CacheControl windowsupdate.microsoft.nsatc.net $$vari 2x+100
|
||||
#
|
||||
# 示例(仍然以 `www.windowsupdate.com' 为例):
|
||||
# CacheControl www.windowsupdate.com fixed 1000
|
||||
# CacheControl windowsupdate.microsoft.nsatc.net fixed 500
|
||||
# 效果是:记录一、二、三和四的 TTL 都会被修改为 1000
|
||||
#
|
||||
# CacheControl www.windowsupdate.com $fixed 1000
|
||||
# CacheControl windowsupdate.microsoft.nsatc.net fixed 500
|
||||
# 效果是:记录一、三和四的 TTL 会被修改为 1000,记录二的 TTL 会被修改为 500
|
||||
#
|
||||
# CacheControl www.windowsupdate.com $$fixed 1000
|
||||
# CacheControl windowsupdate.microsoft.nsatc.net fixed 500
|
||||
# 效果是:记录一的 TTL 会被修改为 1000,记录二的 TTL 会被修改为 500,记录三和四的 TTL 不会被修改
|
||||
|
||||
# ReloadCache <BOOLEAN>
|
||||
# 当程序启动时是否重新载入已有的文件缓存 (since 2.2.3)
|
||||
# 已有的缓存大小必须和 `CacheSize' 所指定的大小相等
|
||||
# 可选值:`false' 或 `true'
|
||||
# 如果 `MemoryCache' 的值为 `true',此选项无效
|
||||
ReloadCache false
|
||||
|
||||
# OverwriteCache <BOOLEAN>
|
||||
# 如果已有的文件缓存无法重载,是否直接将其覆盖掉 (since 2.3)
|
||||
# 可选值:`false' 或 `true'
|
||||
# 如果 `MemoryCache' 的值为 `true',此选项无效
|
||||
# 如果 `ReloadCache' 的值为 `false',此选项无效
|
||||
OverwriteCache false
|
||||
|
||||
##################################################
|
||||
#
|
||||
# 杂项
|
||||
#
|
||||
##################################################
|
||||
|
||||
# DisabledType <NUM1>,<NUM2>,.....
|
||||
# 禁止查询的 DNS 类型列表,每个类型(用数字代表)之间用半角逗号 (`,') 分隔 (since 2.2)
|
||||
# 所有的 DNS 类型:
|
||||
# A 1 IPv4 地址
|
||||
# AAAA 28 IPv6 地址
|
||||
# APL 42
|
||||
# CERT 37
|
||||
# CNAME 5
|
||||
# DHCID 49
|
||||
# DLV 32769
|
||||
# DNAME 39
|
||||
# DNSKEY 48
|
||||
# DS 43
|
||||
# HIP 55
|
||||
# IPSECKEY 45
|
||||
# KEY 25
|
||||
# KX 36
|
||||
# LOC 29
|
||||
# MX 15
|
||||
# NAPTR 35
|
||||
# NS 2 Name Server
|
||||
# NSEC 47
|
||||
# NSEC3 50
|
||||
# NSEC3PARAM 51
|
||||
# PTR 12 Domain pointer
|
||||
# RRSIG 46
|
||||
# RP 17
|
||||
# SIG 24
|
||||
# SOA 6 start of authority record
|
||||
# SPF 99
|
||||
# SRV 33
|
||||
# SSHFP 44
|
||||
# TA 32768
|
||||
# TKEY 249
|
||||
# TSIG 250
|
||||
# TXT 16
|
||||
# ANY 255
|
||||
# AXFR 252
|
||||
# IXFR 251
|
||||
# OPT 41
|
||||
DisabledType
|
||||
|
||||
# DisabledDomain <DOMAIN1>,<DOMAIN2>,.....
|
||||
# 禁止查询的域列表,每个域之间用半角逗号 (`,') 分隔 (since 2.2)
|
||||
# 支持通配符。 (since 2.2.2)
|
||||
# 一个项目如果不含通配符,则从域名尾部开始匹配,例如 `123.com' 则会匹配所有以 `123.com' 结尾的域名。
|
||||
# 如果含通配符则严格按照通配符来匹配。
|
||||
# 可以有多条DisabledDomain (since 2.2.2)
|
||||
DisabledDomain
|
||||
|
||||
# DisabledList <PATH>
|
||||
# 从文件载入到禁用列表 (since 5.0.3)
|
||||
# 写多条 `DisabledList' 可以加载多个文件,路径两头不要加引号
|
||||
DisabledList
|
||||
|
||||
# DomainStatistic <BOOLEAN>
|
||||
# 是否启用域名统计 (since 2.5 b1)
|
||||
# 域名信息统计会依照模板文件记录域名的查询情况
|
||||
# 记录的结果在与程序所在相同的文件夹内(Windows)或程序的配置文件夹内(Linux)的`statistic.html'文件内
|
||||
# 可选值:`false' 或 `true'
|
||||
DomainStatistic false
|
||||
|
||||
# DomainStatisticTempletFile <PATH>
|
||||
# 域名统计的模板文件路径 (since 5.0.23)
|
||||
# 如果保留为空,则默认为与程序所在相同的文件夹内(Windows)或程序的配置文件夹内(Linux)的`StatisticTemplate.html'文件
|
||||
DomainStatisticTempletFile
|
||||
|
||||
# StatisticInsertionPosition <STRING>
|
||||
# 指定在模板文件中写入的位置 (since 5.0.23)
|
||||
# 如果保留为空,则默认为`<!-- INSERT HERE -->'
|
||||
# StatisticInsertionPosition <!-- INSERT HERE -->
|
||||
|
||||
# StatisticUpdateInterval <NUM>
|
||||
# 域名统计刷新时间间隔(秒) (since 2.5 b1)
|
||||
StatisticUpdateInterval 29
|
||||
@ -1,29 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
generate_china_banned()
|
||||
{
|
||||
if [ ! -f /tmp/gfwlist.txt ]; then
|
||||
wget-ssl --no-check-certificate https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt -O /tmp/gfwlist.b64 >&2
|
||||
cat /tmp/gfwlist.b64 | base64 -d > /tmp/gfwlist.txt
|
||||
rm -f /tmp/gfwlist.b64
|
||||
fi
|
||||
|
||||
cat /tmp/gfwlist.txt | sort -u |
|
||||
sed 's#!.\+##; s#|##g; s#@##g; s#http:\/\/##; s#https:\/\/##;' |
|
||||
sed '/\*/d; /apple\.com/d; /sina\.cn/d; /sina\.com\.cn/d; /baidu\.com/d; /byr\.cn/d; /jlike\.com/d; /weibo\.com/d; /zhongsou\.com/d; /youdao\.com/d; /sogou\.com/d; /so\.com/d; /soso\.com/d; /aliyun\.com/d; /taobao\.com/d; /jd\.com/d; /qq\.com/d' |
|
||||
sed '/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/d' |
|
||||
grep '^[0-9a-zA-Z\.-]\+$' | grep '\.' | sed 's#^\.\+##' | sort -u |
|
||||
awk '
|
||||
BEGIN { prev = "________"; } {
|
||||
cur = $0;
|
||||
if (index(cur, prev) == 1 && substr(cur, 1 + length(prev) ,1) == ".") {
|
||||
} else {
|
||||
print cur;
|
||||
prev = cur;
|
||||
}
|
||||
}' | sort -u
|
||||
|
||||
}
|
||||
|
||||
|
||||
generate_china_banned
|
||||
@ -1,19 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
/etc/dnsforwarder/gen-gfwlist.sh > /tmp/ol-gfw.txt
|
||||
|
||||
if [ -s "/tmp/ol-gfw.txt" ];then
|
||||
sort -u /etc/dnsforwarder/base-gfwlist.txt /tmp/ol-gfw.txt > /tmp/china-banned
|
||||
if ( ! cmp -s /tmp/china-banned /etc/dnsforwarder/china-banned );then
|
||||
if [ -s "/tmp/china-banned" ];then
|
||||
mv /tmp/china-banned /etc/dnsforwarder/china-banned
|
||||
echo "Update GFW-List Done!"
|
||||
fi
|
||||
else
|
||||
echo "GFW-List No Change!"
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -f /tmp/gfwlist.txt
|
||||
rm -f /tmp/ol-gfw.txt
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
telegram.com
|
||||
telegram.org
|
||||
@ -1,2 +0,0 @@
|
||||
youku.com
|
||||
iqiyi.com
|
||||
@ -1,196 +0,0 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=99
|
||||
|
||||
DNSFORWARDER_CONF=/etc/dnsforwarder/dnsforwarder.conf
|
||||
PID_PATH=/var/run/dnsforwarder/
|
||||
PID_FILE=dns.pid
|
||||
|
||||
start()
|
||||
{
|
||||
echo luci for dnsforwarder
|
||||
local vt_enabled=`uci get dnsforwarder.@arguments[0].enabled 2>/dev/null`
|
||||
if [ $vt_enabled = 0 ]; then
|
||||
echo dnsforwarder is not enabled
|
||||
exit
|
||||
fi
|
||||
dnsforwarder -f $DNSFORWARDER_CONF -d
|
||||
mkdir -p $PID_PATH
|
||||
pid=`ps | awk '$5 ~ /\[dnsforwarder\]/ {print $1}'`
|
||||
echo dnsforwarder running pid is $pid
|
||||
logger -t alex the pid of dnsforwarder is $PID_PATH/$PID_FILE $pid
|
||||
echo $pid > $PID_PATH/$PID_FILE
|
||||
/etc/init.d/dnsforwarder enable
|
||||
local redir=`uci get dnsforwarder.@arguments[0].redir 2>/dev/null`
|
||||
local port=`uci get dnsforwarder.@arguments[0].port 2>/dev/null`
|
||||
local dnsmasq=`uci get dnsforwarder.@arguments[0].dnsmasq 2>/dev/null`
|
||||
local mode=`uci get dnsforwarder.@arguments[0].mode 2>/dev/null`
|
||||
local addr=`uci get dnsforwarder.@arguments[0].addr 2>/dev/null`
|
||||
local ipset=`uci get dnsforwarder.@arguments[0].ipset 2>/dev/null`
|
||||
local ipset_name=`uci get dnsforwarder.@arguments[0].ipset_name 2>/dev/null`
|
||||
local white=`uci get dnsforwarder.@arguments[0].white 2>/dev/null`
|
||||
local whiteset=`uci get dnsforwarder.@arguments[0].whiteset 2>/dev/null`
|
||||
local whitedns=`uci get dnsforwarder.@arguments[0].whitedns 2>/dev/null`
|
||||
[ -n "$addr" ] && addr=${addr/:/#}
|
||||
[ -n "$whitedns" ] && whitedns=${whitedns/:/#}
|
||||
iptables -t nat -N DNSFORWARDER
|
||||
iptables -t nat -F DNSFORWARDER
|
||||
if [ $redir = 1 ]; then
|
||||
iptables -t nat -A DNSFORWARDER -p udp --dport 53 -j REDIRECT --to-ports $port
|
||||
iptables -t nat -I PREROUTING -j DNSFORWARDER
|
||||
fi
|
||||
|
||||
mkdir -p /tmp/dnsmasq.d
|
||||
mkdir -p /etc/dnsmasq.d
|
||||
cat > /tmp/dnsmasq.d/dnsmasq-go.conf <<EOF
|
||||
conf-dir=/var/etc/dnsmasq-go.d
|
||||
EOF
|
||||
cat > /etc/dnsmasq.d/dnsmasq-go.conf <<EOF
|
||||
conf-dir=/var/etc/dnsmasq-go.d
|
||||
EOF
|
||||
|
||||
if [ $ipset = 1 ]; then
|
||||
ipset destroy $ipset_name 2>/dev/null
|
||||
ipset create $ipset_name hash:net family inet hashsize 1024 maxelem 65536
|
||||
fi
|
||||
mkdir -p /var/etc/dnsmasq-go.d
|
||||
if [ $dnsmasq = 1 ]; then
|
||||
case $mode in
|
||||
gfwlist)
|
||||
echo gfwlist!!
|
||||
awk -vs=$addr '!/^$/&&!/^#/{printf("server=/%s/%s\n",$0,s)}' \
|
||||
/etc/dnsforwarder/china-banned > /var/etc/dnsmasq-go.d/01-pollution.conf
|
||||
[ $ipset = 1 ] && {
|
||||
awk '!/^$/&&!/^#/{printf("ipset=/%s/'$ipset_name'\n",$0)}' \
|
||||
/etc/dnsforwarder/china-banned > /var/etc/dnsmasq-go.d/01-ipset.conf
|
||||
}
|
||||
;;
|
||||
userlist)
|
||||
echo user!!
|
||||
awk -vs=$addr '!/^$/&&!/^#/{printf("server=/%s/%s\n",$0,s)}' \
|
||||
/etc/dnsforwarder/userlist >> /var/etc/dnsmasq-go.d/02-user.conf
|
||||
[ $ipset = 1 ] && {
|
||||
awk '!/^$/&&!/^#/{printf("ipset=/%s/'$ipset_name'\n",$0)}' \
|
||||
/etc/dnsforwarder/userlist > /var/etc/dnsmasq-go.d/02-ipset.conf
|
||||
}
|
||||
;;
|
||||
gfw_user)
|
||||
awk -vs=$addr '!/^$/&&!/^#/{printf("server=/%s/%s\n",$0,s)}' \
|
||||
/etc/dnsforwarder/china-banned > /var/etc/dnsmasq-go.d/01-pollution.conf
|
||||
|
||||
awk -vs=$addr '!/^$/&&!/^#/{printf("server=/%s/%s\n",$0,s)}' \
|
||||
/etc/dnsforwarder/userlist >> /var/etc/dnsmasq-go.d/02-user.conf
|
||||
|
||||
[ $ipset = 1 ] && {
|
||||
awk '!/^$/&&!/^#/{printf("ipset=/%s/'$ipset_name'\n",$0)}' \
|
||||
/etc/dnsforwarder/china-banned > /var/etc/dnsmasq-go.d/01-ipset.conf
|
||||
|
||||
awk '!/^$/&&!/^#/{printf("ipset=/%s/'$ipset_name'\n",$0)}' \
|
||||
/etc/dnsforwarder/userlist > /var/etc/dnsmasq-go.d/02-ipset.conf
|
||||
}
|
||||
;;
|
||||
all)
|
||||
uci delete dhcp.@dnsmasq[0].server
|
||||
uci add_list dhcp.@dnsmasq[0].server=$addr
|
||||
uci delete dhcp.@dnsmasq[0].resolvfile
|
||||
uci set dhcp.@dnsmasq[0].noresolv=1
|
||||
uci commit dhcp
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
[ "$mode" = "gfwlist" ] || [ "$mode" = "userlist" ] || [ "$mode" = "gfw_user" ] && {
|
||||
iptables -t nat -A DNSFORWARDER -p udp --dport 53 -j REDIRECT --to-ports 53
|
||||
iptables -t nat -I PREROUTING -j DNSFORWARDER
|
||||
}
|
||||
|
||||
if [ $white = 1 ]; then
|
||||
logger -t alex enable white list
|
||||
echo enable white list
|
||||
[ -z "$whiteset" ] && whiteset="whiteset"
|
||||
[ -n "$whitedns" ] && [ -f "/etc/dnsforwarder/whitelist" ] && { #强制不走代理到DNSMasq
|
||||
echo whiteset is $whiteset
|
||||
ipset create $whiteset hash:net family inet hashsize 1024 maxelem 65536
|
||||
|
||||
awk '!/^$/&&!/^#/{printf("ipset=/%s/'$whiteset'\n",$0)}' \
|
||||
/etc/dnsforwarder/whitelist > /var/etc/dnsmasq-go.d/03-ipset.conf
|
||||
|
||||
awk -vs=$whitedns '!/^$/&&!/^#/{printf("server=/%s/%s\n",$0,s)}' \
|
||||
/etc/dnsforwarder/whitelist >> /var/etc/dnsmasq-go.d/03-white.conf
|
||||
}
|
||||
fi
|
||||
|
||||
/etc/init.d/dnsmasq restart
|
||||
|
||||
fi
|
||||
|
||||
|
||||
}
|
||||
|
||||
stop()
|
||||
{
|
||||
logger -t alex stopping dnsforwarder
|
||||
local addr=`uci get dnsforwarder.@arguments[0].addr 2>/dev/null`
|
||||
addr=${addr/:/#}
|
||||
uci del_list dhcp.@dnsmasq[0].server=$addr 2>/dev/null
|
||||
uci set dhcp.@dnsmasq[0].resolvfile=/tmp/resolv.conf.auto 2>/dev/null
|
||||
uci delete dhcp.@dnsmasq[0].noresolv 2>/dev/null
|
||||
uci commit dhcp
|
||||
rm -rf /var/etc/dnsmasq-go.d
|
||||
rm -f /tmp/dnsmasq.d/dnsmasq-go.conf
|
||||
[ -e $PID_PATH/$PID_FILE ] && {
|
||||
pid=`cat $PID_PATH/$PID_FILE`
|
||||
logger -t alex killing dnsforwarder pid $pid
|
||||
echo killing dnsforwarder pid $pid
|
||||
kill $pid
|
||||
rm -f $PID_PATH/$PID_FILE
|
||||
} || {
|
||||
logger -t alex cannot find dnsforwarder pid file
|
||||
}
|
||||
iptables -t nat -F DNSFORWARDER 2>/dev/null
|
||||
while iptables -t nat -D PREROUTING -j DNSFORWARDER 2>/dev/null; do :; done
|
||||
iptables -t nat -X DNSFORWARDER 2>/dev/null
|
||||
local ipset=`uci get dnsforwarder.@arguments[0].ipset 2>/dev/null`
|
||||
local ipset_name=`uci get dnsforwarder.@arguments[0].ipset_name 2>/dev/null`
|
||||
[ $ipset = 1 ] && {
|
||||
echo destroying ipset $ipset_name
|
||||
ipset destroy $ipset_name 2>/dev/null
|
||||
}
|
||||
local white=`uci get dnsforwarder.@arguments[0].white 2>/dev/null`
|
||||
local whiteset=`uci get dnsforwarder.@arguments[0].whiteset 2>/dev/null`
|
||||
[ $white = 1 ] && ipset destroy $whiteset 2>/dev/null
|
||||
/etc/init.d/dnsmasq restart
|
||||
}
|
||||
|
||||
restart()
|
||||
{
|
||||
|
||||
pid=`cat $PID_PATH/$PID_FILE 2>/dev/null`
|
||||
echo dnsforwarder pid file is $pid
|
||||
[ -n "$pid" ] && {
|
||||
echo stopping pid $pid
|
||||
logger -t alex there is dnsforwarder pid $pid
|
||||
stop
|
||||
} || {
|
||||
logger -t alex dnsforwarder is not running
|
||||
}
|
||||
sleep 1s
|
||||
local vt_enabled=`uci get dnsforwarder.@arguments[0].enabled 2>/dev/null`
|
||||
echo dnsforwarder status is $vt_enabled
|
||||
logger -t alex dnsforwarder is initializing enabled is $vt_enabled
|
||||
if [ $vt_enabled = 1 ]; then
|
||||
[ -n "$pid" ] && {
|
||||
logger -t alex there is dnsforwarder pid $pid
|
||||
stop
|
||||
} || {
|
||||
logger -t alex dnsforwarder is not running
|
||||
}
|
||||
|
||||
logger -t alex restarting dnsforwarder
|
||||
start
|
||||
else
|
||||
/etc/init.d/dnsforwarder disable
|
||||
fi
|
||||
|
||||
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
module("luci.controller.dnsforwarder", package.seeall)
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/dnsforwarder") then
|
||||
return
|
||||
end
|
||||
entry({"admin", "services", "dnsforwarder"},alias("admin", "services", "dnsforwarder","general"),_("dnsforwarder")).dependent = true
|
||||
entry({"admin", "services", "dnsforwarder","general"}, cbi("dnsforwarder/general"),_("General"),10).leaf = true
|
||||
entry({"admin", "services", "dnsforwarder","gfwlist"}, cbi("dnsforwarder/gfwlist"),_("GFWlist"),20).leaf = true
|
||||
entry({"admin", "services", "dnsforwarder","log"}, cbi("dnsforwarder/log"),_("LOG"),30).leaf = true
|
||||
|
||||
end
|
||||
@ -1,97 +0,0 @@
|
||||
--Alex<1886090@gmail.com>
|
||||
local fs = require "nixio.fs"
|
||||
local CONFIG_FILE = "/etc/dnsforwarder/dnsforwarder.conf";
|
||||
|
||||
function sync_value_to_file(value, file)
|
||||
value = value:gsub("\r\n?", "\n")
|
||||
local old_value = nixio.fs.readfile(file)
|
||||
if value ~= old_value then
|
||||
nixio.fs.writefile(file, value)
|
||||
end
|
||||
|
||||
end
|
||||
local state_msg = ""
|
||||
|
||||
local dnsforwarder_on = (luci.sys.call("pidof dnsforwarder > /dev/null") == 0)
|
||||
local resolv_file = luci.sys.exec("uci get dhcp.@dnsmasq[0].resolvfile")
|
||||
local listen_port = luci.sys.exec("uci get dhcp.@dnsmasq[0].server")
|
||||
|
||||
if dnsforwarder_on then
|
||||
state_msg = "<b><font color=\"green\">" .. translate("Running") .. "</font></b>"
|
||||
else
|
||||
state_msg = "<b><font color=\"red\">" .. translate("Not running") .. "</font></b>"
|
||||
end
|
||||
|
||||
|
||||
if dnsforwarder_on and string.sub(listen_port,1,14) == "127.0.0.1#5053" then
|
||||
state_msg=state_msg .. ",DNSmasq已经将流量定向至本软件"
|
||||
elseif dnsforwarder_on then
|
||||
state_msg=state_msg .. "<b><font color=\"red\"></font></b>"
|
||||
end
|
||||
|
||||
if resolv_file=="" then
|
||||
|
||||
else if dnsforwarder_on then
|
||||
state_msg=state_msg .. "<b><font color=\"red\"></font></b>"
|
||||
end
|
||||
end
|
||||
m=Map("dnsforwarder",translate("dnsforwarder"),translate("dnsforwarder是企业级DNS服务器,可以通过TCP协议进行DNS解析,可以方便的使用iptables进行透明代理,配合ipset、GFWList使用效果更佳。默认上游服务器为114DNS,SSR和Redsocks的GFWList模式要依赖本软件包提供的功能").. "<br><br>状态 - " .. state_msg)
|
||||
s=m:section(TypedSection,"arguments","")
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
view_enable = s:option(Flag,"enabled",translate("Enable"))
|
||||
view_redir = s:option(Flag,"redir",translate("劫持所有DNS请求"),translate("自动将所有客户端的DNS请求都劫持到dnsforwarder的端口"))
|
||||
view_port = s:option(Value,"port",translate("dnsforwarder监听端口"),translate("请根据下面的配置文件填写端口,默认5053"))
|
||||
view_port:depends({redir=1})
|
||||
view_port.default="5053"
|
||||
view_port.datatype="uinteger"
|
||||
view_dnsmasq = s:option(Flag,"dnsmasq",translate("设置成DNSmasq的上游服务器"),translate("让DNSMasq从本软件获得解析结果,支持GFWList模式"))
|
||||
view_dnsmasq:depends({redir=0})
|
||||
view_mode=s:option(ListValue,"mode",translate("DNSmasq转发模式"),translate("dnsmasq可以将全部请求发送至本软件,也可以只发送GFWList登记部分,其余由系统默认DNS解析"))
|
||||
view_mode:value("gfwlist",translate("只转发GFWList"))
|
||||
view_mode:value("userlist",translate("只转发用户自定义列表"))
|
||||
view_mode:value("gfw_user",translate("转发gfwlist+用户自定义列表"))
|
||||
view_mode:value("all",translate("全部转发给dnsforwarder"))
|
||||
view_mode:depends({dnsmasq=1})
|
||||
view_addr = s:option(Value,"addr",translate("转发地址"),translate("请填写dnsforwarder的监听地址,默认127.0.0.1:5053,如果填写<b><font color=\"red\">208.67.222.222:5353</font></b>那么可不通过该软件获得无污染结果"))
|
||||
view_addr:depends({dnsmasq=1})
|
||||
view_addr.default = "127.0.0.1:5053"
|
||||
view_ipset = s:option(Flag,"ipset",translate("将查询结果放入ipset"),translate("为SSR,Redsocks的GFWList模式提供依据"))
|
||||
view_ipset:depends({mode="userlist"})
|
||||
view_ipset:depends({mode="gfwlist"})
|
||||
view_ipset:depends({mode="gfw_user"})
|
||||
view_ipsetname = s:option(Value,"ipset_name",translate("ipset名字"))
|
||||
view_ipsetname.default = "china-banned"
|
||||
view_ipsetname:depends({ipset=1})
|
||||
|
||||
view_white = s:option(Flag,"white",translate("启用强制不走代理列表"),translate("配合SSR使用,设置某些域名不走代理"))
|
||||
view_white:depends({mode="userlist"})
|
||||
view_white:depends({mode="gfwlist"})
|
||||
view_white:depends({mode="gfw_user"})
|
||||
whitedns = s:option(Value,"whitedns",translate("白名单专用DNS"),translate("白名单内的列表都会用此DNS进行解析,并由DNSMasq转发,最终不走SSR代理"))
|
||||
whitedns.default="114.114.114.114:53"
|
||||
whitedns:depends({white=1})
|
||||
whiteipset = s:option(Value,"whiteset",translate("白名单ipset"),translate("设置收集到的白名单的域名的ipset列表名字"))
|
||||
whiteipset:depends({white=1})
|
||||
whiteipset.default="whiteset"
|
||||
|
||||
|
||||
|
||||
view_cfg = s:option(TextValue, "1", nil)
|
||||
view_cfg.rmempty = false
|
||||
view_cfg.rows = 43
|
||||
|
||||
function view_cfg.cfgvalue()
|
||||
return nixio.fs.readfile(CONFIG_FILE) or ""
|
||||
end
|
||||
function view_cfg.write(self, section, value)
|
||||
sync_value_to_file(value, CONFIG_FILE)
|
||||
end
|
||||
|
||||
-- ---------------------------------------------------
|
||||
local apply = luci.http.formvalue("cbi.apply")
|
||||
if apply then
|
||||
os.execute("/etc/init.d/dnsforwarder restart >/dev/null 2>&1 &")
|
||||
end
|
||||
|
||||
return m
|
||||
@ -1,69 +0,0 @@
|
||||
local fs = require "nixio.fs"
|
||||
local banned = "/etc/dnsforwarder/china-banned"
|
||||
local user = "/etc/dnsforwarder/userlist"
|
||||
local whitedomin = "/etc/dnsforwarder/whitelist"
|
||||
function sync_value_to_file(value, file)
|
||||
value = value:gsub("\r\n?", "\n")
|
||||
local old_value = nixio.fs.readfile(file)
|
||||
if value ~= old_value then
|
||||
nixio.fs.writefile(file, value)
|
||||
end
|
||||
end
|
||||
|
||||
m = Map("dnsforwarder", translate("Domain Lists Settings"),translate("‘GFWList黑名单’可以观察当前域名黑名单,更新后会发生变化;<br>‘用户自定义黑名单’不会被GFWList更新所覆盖,可以手动添加一些强制走代理的网站。<br>注意:点击更新按钮后需要等浏览器自动刷新后才算完成,请勿重复点击"))
|
||||
s=m:section(TypedSection,"arguments","")
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
button_update_gfwlist = s:option (Button, "_button_update_gfwlist", translate("更新GFWList"),translate("点击后请静待30秒,然后刷新本页面"))
|
||||
local gfw_count = luci.sys.exec("grep -c '' " .. banned)
|
||||
button_update_gfwlist.inputtitle = translate ( "当前规则数目" .. gfw_count .. ",点击更新")
|
||||
button_update_gfwlist.inputstyle = "apply"
|
||||
function button_update_gfwlist.write (self, section, value)
|
||||
luci.sys.call("nohup sh /etc/dnsforwarder/up-gfwlist.sh > /tmp/gfwupdate.log 2>&1 &")
|
||||
end
|
||||
|
||||
|
||||
gfwlist = s:option(TextValue, "gfwlist", translate("被GFW屏蔽的名单"), nil)
|
||||
gfwlist.description = translate("该列表内的内容会随着GFWList更新而覆盖")
|
||||
gfwlist.rows = 13
|
||||
gfwlist.wrap = "off"
|
||||
gfwlist.cfgvalue = function(self, section)
|
||||
return fs.readfile(banned) or ""
|
||||
end
|
||||
gfwlist.write = function(self, section, value)
|
||||
fs.writefile(banned, value:gsub("\r\n", "\n"))
|
||||
end
|
||||
|
||||
userlist = s:option(TextValue, "users", translate("用户自定义黑名单"), nil)
|
||||
userlist.description = translate("该列表的内容不会随着GFWList的更新而改变")
|
||||
userlist.rows = 13
|
||||
userlist.wrap = "off"
|
||||
userlist.cfgvalue = function(self, section)
|
||||
return fs.readfile(user) or ""
|
||||
end
|
||||
userlist.write = function(self, section, value)
|
||||
fs.writefile(user, value:gsub("\r\n", "\n"))
|
||||
end
|
||||
|
||||
goods = s:option(TextValue, "fafa", translate("强制不走代理白名单"), nil)
|
||||
goods.description = translate("一般填写国内的CDN服务器地址,需配合SSR的GFWList自动代理模式使用")
|
||||
goods.rows = 13
|
||||
goods.wrap = "off"
|
||||
goods.cfgvalue = function(self, section)
|
||||
return fs.readfile(whitedomin) or ""
|
||||
end
|
||||
goods.write = function(self, section, value)
|
||||
fs.writefile(whitedomin, value:gsub("\r\n", "\n"))
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
-- ---------------------------------------------------
|
||||
local apply = luci.http.formvalue("cbi.apply")
|
||||
if apply then
|
||||
os.execute("/etc/init.d/dnsforwarder restart >/dev/null 2>&1 &")
|
||||
end
|
||||
|
||||
return m
|
||||
@ -1,31 +0,0 @@
|
||||
local fs = require "nixio.fs"
|
||||
local log = "/var/log/dnsforwarder.log"
|
||||
|
||||
function sync_value_to_file(value, file)
|
||||
value = value:gsub("\r\n?", "\n")
|
||||
local old_value = nixio.fs.readfile(file)
|
||||
if value ~= old_value then
|
||||
nixio.fs.writefile(file, value)
|
||||
end
|
||||
end
|
||||
|
||||
m = Map("dnsforwarder", translate("运行日志"),translate("如果想观察日志,需要在配置文件中写明LogOn true 和 LogFileFolder /var/log"))
|
||||
s=m:section(TypedSection,"arguments","")
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
|
||||
|
||||
|
||||
gfwlist = s:option(TextValue, "gfwlist", translate("日志"), nil)
|
||||
gfwlist.description = translate("-------------------------------------------------------------日志文件默认位置:" .. log)
|
||||
gfwlist.rows = 30
|
||||
gfwlist.wrap = "off"
|
||||
gfwlist.cfgvalue = function(self, section)
|
||||
return fs.readfile(log) or ""
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
return m
|
||||
@ -1,8 +0,0 @@
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "Running"
|
||||
msgstr "运行中"
|
||||
|
||||
msgid "Not running"
|
||||
msgstr "未运行"
|
||||
@ -1,12 +0,0 @@
|
||||
|
||||
INSTALL = install
|
||||
PREFIX = /usr/bin
|
||||
|
||||
po2lmo: src/po2lmo.o src/template_lmo.o
|
||||
$(CC) $(LDFLAGS) -o src/po2lmo src/po2lmo.o src/template_lmo.o
|
||||
|
||||
install:
|
||||
$(INSTALL) -m 755 src/po2lmo $(PREFIX)
|
||||
|
||||
clean:
|
||||
$(RM) src/po2lmo src/*.o
|
||||
Binary file not shown.
@ -1,247 +0,0 @@
|
||||
/*
|
||||
* lmo - Lua Machine Objects - PO to LMO conversion tool
|
||||
*
|
||||
* Copyright (C) 2009-2012 Jo-Philipp Wich <xm@subsignal.org>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "template_lmo.h"
|
||||
|
||||
static void die(const char *msg)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void usage(const char *name)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s input.po output.lmo\n", name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void print(const void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
{
|
||||
if( fwrite(ptr, size, nmemb, stream) == 0 )
|
||||
die("Failed to write stdout");
|
||||
}
|
||||
|
||||
static int extract_string(const char *src, char *dest, int len)
|
||||
{
|
||||
int pos = 0;
|
||||
int esc = 0;
|
||||
int off = -1;
|
||||
|
||||
for( pos = 0; (pos < strlen(src)) && (pos < len); pos++ )
|
||||
{
|
||||
if( (off == -1) && (src[pos] == '"') )
|
||||
{
|
||||
off = pos + 1;
|
||||
}
|
||||
else if( off >= 0 )
|
||||
{
|
||||
if( esc == 1 )
|
||||
{
|
||||
switch (src[pos])
|
||||
{
|
||||
case '"':
|
||||
case '\\':
|
||||
off++;
|
||||
break;
|
||||
}
|
||||
dest[pos-off] = src[pos];
|
||||
esc = 0;
|
||||
}
|
||||
else if( src[pos] == '\\' )
|
||||
{
|
||||
dest[pos-off] = src[pos];
|
||||
esc = 1;
|
||||
}
|
||||
else if( src[pos] != '"' )
|
||||
{
|
||||
dest[pos-off] = src[pos];
|
||||
}
|
||||
else
|
||||
{
|
||||
dest[pos-off] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (off > -1) ? strlen(dest) : -1;
|
||||
}
|
||||
|
||||
static int cmp_index(const void *a, const void *b)
|
||||
{
|
||||
uint32_t x = ((const lmo_entry_t *)a)->key_id;
|
||||
uint32_t y = ((const lmo_entry_t *)b)->key_id;
|
||||
|
||||
if (x < y)
|
||||
return -1;
|
||||
else if (x > y)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_uint32(uint32_t x, FILE *out)
|
||||
{
|
||||
uint32_t y = htonl(x);
|
||||
print(&y, sizeof(uint32_t), 1, out);
|
||||
}
|
||||
|
||||
static void print_index(void *array, int n, FILE *out)
|
||||
{
|
||||
lmo_entry_t *e;
|
||||
|
||||
qsort(array, n, sizeof(*e), cmp_index);
|
||||
|
||||
for (e = array; n > 0; n--, e++)
|
||||
{
|
||||
print_uint32(e->key_id, out);
|
||||
print_uint32(e->val_id, out);
|
||||
print_uint32(e->offset, out);
|
||||
print_uint32(e->length, out);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char line[4096];
|
||||
char key[4096];
|
||||
char val[4096];
|
||||
char tmp[4096];
|
||||
int state = 0;
|
||||
int offset = 0;
|
||||
int length = 0;
|
||||
int n_entries = 0;
|
||||
void *array = NULL;
|
||||
lmo_entry_t *entry = NULL;
|
||||
uint32_t key_id, val_id;
|
||||
|
||||
FILE *in;
|
||||
FILE *out;
|
||||
|
||||
if( (argc != 3) || ((in = fopen(argv[1], "r")) == NULL) || ((out = fopen(argv[2], "w")) == NULL) )
|
||||
usage(argv[0]);
|
||||
|
||||
memset(line, 0, sizeof(key));
|
||||
memset(key, 0, sizeof(val));
|
||||
memset(val, 0, sizeof(val));
|
||||
|
||||
while( (NULL != fgets(line, sizeof(line), in)) || (state >= 2 && feof(in)) )
|
||||
{
|
||||
if( state == 0 && strstr(line, "msgid \"") == line )
|
||||
{
|
||||
switch(extract_string(line, key, sizeof(key)))
|
||||
{
|
||||
case -1:
|
||||
die("Syntax error in msgid");
|
||||
case 0:
|
||||
state = 1;
|
||||
break;
|
||||
default:
|
||||
state = 2;
|
||||
}
|
||||
}
|
||||
else if( state == 1 || state == 2 )
|
||||
{
|
||||
if( strstr(line, "msgstr \"") == line || state == 2 )
|
||||
{
|
||||
switch(extract_string(line, val, sizeof(val)))
|
||||
{
|
||||
case -1:
|
||||
state = 4;
|
||||
break;
|
||||
default:
|
||||
state = 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(extract_string(line, tmp, sizeof(tmp)))
|
||||
{
|
||||
case -1:
|
||||
state = 2;
|
||||
break;
|
||||
default:
|
||||
strcat(key, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( state == 3 )
|
||||
{
|
||||
switch(extract_string(line, tmp, sizeof(tmp)))
|
||||
{
|
||||
case -1:
|
||||
state = 4;
|
||||
break;
|
||||
default:
|
||||
strcat(val, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
if( state == 4 )
|
||||
{
|
||||
if( strlen(key) > 0 && strlen(val) > 0 )
|
||||
{
|
||||
key_id = sfh_hash(key, strlen(key));
|
||||
val_id = sfh_hash(val, strlen(val));
|
||||
|
||||
if( key_id != val_id )
|
||||
{
|
||||
n_entries++;
|
||||
array = realloc(array, n_entries * sizeof(lmo_entry_t));
|
||||
entry = (lmo_entry_t *)array + n_entries - 1;
|
||||
|
||||
if (!array)
|
||||
die("Out of memory");
|
||||
|
||||
entry->key_id = key_id;
|
||||
entry->val_id = val_id;
|
||||
entry->offset = offset;
|
||||
entry->length = strlen(val);
|
||||
|
||||
length = strlen(val) + ((4 - (strlen(val) % 4)) % 4);
|
||||
|
||||
print(val, length, 1, out);
|
||||
offset += length;
|
||||
}
|
||||
}
|
||||
|
||||
state = 0;
|
||||
memset(key, 0, sizeof(key));
|
||||
memset(val, 0, sizeof(val));
|
||||
}
|
||||
|
||||
memset(line, 0, sizeof(line));
|
||||
}
|
||||
|
||||
print_index(array, n_entries, out);
|
||||
|
||||
if( offset > 0 )
|
||||
{
|
||||
print_uint32(offset, out);
|
||||
fsync(fileno(out));
|
||||
fclose(out);
|
||||
}
|
||||
else
|
||||
{
|
||||
fclose(out);
|
||||
unlink(argv[2]);
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
return(0);
|
||||
}
|
||||
@ -1,328 +0,0 @@
|
||||
/*
|
||||
* lmo - Lua Machine Objects - Base functions
|
||||
*
|
||||
* Copyright (C) 2009-2010 Jo-Philipp Wich <xm@subsignal.org>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "template_lmo.h"
|
||||
|
||||
/*
|
||||
* Hash function from http://www.azillionmonkeys.com/qed/hash.html
|
||||
* Copyright (C) 2004-2008 by Paul Hsieh
|
||||
*/
|
||||
|
||||
uint32_t sfh_hash(const char *data, int len)
|
||||
{
|
||||
uint32_t hash = len, tmp;
|
||||
int rem;
|
||||
|
||||
if (len <= 0 || data == NULL) return 0;
|
||||
|
||||
rem = len & 3;
|
||||
len >>= 2;
|
||||
|
||||
/* Main loop */
|
||||
for (;len > 0; len--) {
|
||||
hash += sfh_get16(data);
|
||||
tmp = (sfh_get16(data+2) << 11) ^ hash;
|
||||
hash = (hash << 16) ^ tmp;
|
||||
data += 2*sizeof(uint16_t);
|
||||
hash += hash >> 11;
|
||||
}
|
||||
|
||||
/* Handle end cases */
|
||||
switch (rem) {
|
||||
case 3: hash += sfh_get16(data);
|
||||
hash ^= hash << 16;
|
||||
hash ^= data[sizeof(uint16_t)] << 18;
|
||||
hash += hash >> 11;
|
||||
break;
|
||||
case 2: hash += sfh_get16(data);
|
||||
hash ^= hash << 11;
|
||||
hash += hash >> 17;
|
||||
break;
|
||||
case 1: hash += *data;
|
||||
hash ^= hash << 10;
|
||||
hash += hash >> 1;
|
||||
}
|
||||
|
||||
/* Force "avalanching" of final 127 bits */
|
||||
hash ^= hash << 3;
|
||||
hash += hash >> 5;
|
||||
hash ^= hash << 4;
|
||||
hash += hash >> 17;
|
||||
hash ^= hash << 25;
|
||||
hash += hash >> 6;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
uint32_t lmo_canon_hash(const char *str, int len)
|
||||
{
|
||||
char res[4096];
|
||||
char *ptr, prev;
|
||||
int off;
|
||||
|
||||
if (!str || len >= sizeof(res))
|
||||
return 0;
|
||||
|
||||
for (prev = ' ', ptr = res, off = 0; off < len; prev = *str, off++, str++)
|
||||
{
|
||||
if (isspace(*str))
|
||||
{
|
||||
if (!isspace(prev))
|
||||
*ptr++ = ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr++ = *str;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ptr > res) && isspace(*(ptr-1)))
|
||||
ptr--;
|
||||
|
||||
return sfh_hash(res, ptr - res);
|
||||
}
|
||||
|
||||
lmo_archive_t * lmo_open(const char *file)
|
||||
{
|
||||
int in = -1;
|
||||
uint32_t idx_offset = 0;
|
||||
struct stat s;
|
||||
|
||||
lmo_archive_t *ar = NULL;
|
||||
|
||||
if (stat(file, &s) == -1)
|
||||
goto err;
|
||||
|
||||
if ((in = open(file, O_RDONLY)) == -1)
|
||||
goto err;
|
||||
|
||||
if ((ar = (lmo_archive_t *)malloc(sizeof(*ar))) != NULL)
|
||||
{
|
||||
memset(ar, 0, sizeof(*ar));
|
||||
|
||||
ar->fd = in;
|
||||
ar->size = s.st_size;
|
||||
|
||||
fcntl(ar->fd, F_SETFD, fcntl(ar->fd, F_GETFD) | FD_CLOEXEC);
|
||||
|
||||
if ((ar->mmap = mmap(NULL, ar->size, PROT_READ, MAP_SHARED, ar->fd, 0)) == MAP_FAILED)
|
||||
goto err;
|
||||
|
||||
idx_offset = ntohl(*((const uint32_t *)
|
||||
(ar->mmap + ar->size - sizeof(uint32_t))));
|
||||
|
||||
if (idx_offset >= ar->size)
|
||||
goto err;
|
||||
|
||||
ar->index = (lmo_entry_t *)(ar->mmap + idx_offset);
|
||||
ar->length = (ar->size - idx_offset - sizeof(uint32_t)) / sizeof(lmo_entry_t);
|
||||
ar->end = ar->mmap + ar->size;
|
||||
|
||||
return ar;
|
||||
}
|
||||
|
||||
err:
|
||||
if (in > -1)
|
||||
close(in);
|
||||
|
||||
if (ar != NULL)
|
||||
{
|
||||
if ((ar->mmap != NULL) && (ar->mmap != MAP_FAILED))
|
||||
munmap(ar->mmap, ar->size);
|
||||
|
||||
free(ar);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void lmo_close(lmo_archive_t *ar)
|
||||
{
|
||||
if (ar != NULL)
|
||||
{
|
||||
if ((ar->mmap != NULL) && (ar->mmap != MAP_FAILED))
|
||||
munmap(ar->mmap, ar->size);
|
||||
|
||||
close(ar->fd);
|
||||
free(ar);
|
||||
|
||||
ar = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
lmo_catalog_t *_lmo_catalogs = NULL;
|
||||
lmo_catalog_t *_lmo_active_catalog = NULL;
|
||||
|
||||
int lmo_load_catalog(const char *lang, const char *dir)
|
||||
{
|
||||
DIR *dh = NULL;
|
||||
char pattern[16];
|
||||
char path[PATH_MAX];
|
||||
struct dirent *de = NULL;
|
||||
|
||||
lmo_archive_t *ar = NULL;
|
||||
lmo_catalog_t *cat = NULL;
|
||||
|
||||
if (!lmo_change_catalog(lang))
|
||||
return 0;
|
||||
|
||||
if (!dir || !(dh = opendir(dir)))
|
||||
goto err;
|
||||
|
||||
if (!(cat = malloc(sizeof(*cat))))
|
||||
goto err;
|
||||
|
||||
memset(cat, 0, sizeof(*cat));
|
||||
|
||||
snprintf(cat->lang, sizeof(cat->lang), "%s", lang);
|
||||
snprintf(pattern, sizeof(pattern), "*.%s.lmo", lang);
|
||||
|
||||
while ((de = readdir(dh)) != NULL)
|
||||
{
|
||||
if (!fnmatch(pattern, de->d_name, 0))
|
||||
{
|
||||
snprintf(path, sizeof(path), "%s/%s", dir, de->d_name);
|
||||
ar = lmo_open(path);
|
||||
|
||||
if (ar)
|
||||
{
|
||||
ar->next = cat->archives;
|
||||
cat->archives = ar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dh);
|
||||
|
||||
cat->next = _lmo_catalogs;
|
||||
_lmo_catalogs = cat;
|
||||
|
||||
if (!_lmo_active_catalog)
|
||||
_lmo_active_catalog = cat;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
if (dh) closedir(dh);
|
||||
if (cat) free(cat);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int lmo_change_catalog(const char *lang)
|
||||
{
|
||||
lmo_catalog_t *cat;
|
||||
|
||||
for (cat = _lmo_catalogs; cat; cat = cat->next)
|
||||
{
|
||||
if (!strncmp(cat->lang, lang, sizeof(cat->lang)))
|
||||
{
|
||||
_lmo_active_catalog = cat;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static lmo_entry_t * lmo_find_entry(lmo_archive_t *ar, uint32_t hash)
|
||||
{
|
||||
unsigned int m, l, r;
|
||||
uint32_t k;
|
||||
|
||||
l = 0;
|
||||
r = ar->length - 1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
m = l + ((r - l) / 2);
|
||||
|
||||
if (r < l)
|
||||
break;
|
||||
|
||||
k = ntohl(ar->index[m].key_id);
|
||||
|
||||
if (k == hash)
|
||||
return &ar->index[m];
|
||||
|
||||
if (k > hash)
|
||||
{
|
||||
if (!m)
|
||||
break;
|
||||
|
||||
r = m - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = m + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int lmo_translate(const char *key, int keylen, char **out, int *outlen)
|
||||
{
|
||||
uint32_t hash;
|
||||
lmo_entry_t *e;
|
||||
lmo_archive_t *ar;
|
||||
|
||||
if (!key || !_lmo_active_catalog)
|
||||
return -2;
|
||||
|
||||
hash = lmo_canon_hash(key, keylen);
|
||||
|
||||
for (ar = _lmo_active_catalog->archives; ar; ar = ar->next)
|
||||
{
|
||||
if ((e = lmo_find_entry(ar, hash)) != NULL)
|
||||
{
|
||||
*out = ar->mmap + ntohl(e->offset);
|
||||
*outlen = ntohl(e->length);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void lmo_close_catalog(const char *lang)
|
||||
{
|
||||
lmo_archive_t *ar, *next;
|
||||
lmo_catalog_t *cat, *prev;
|
||||
|
||||
for (prev = NULL, cat = _lmo_catalogs; cat; prev = cat, cat = cat->next)
|
||||
{
|
||||
if (!strncmp(cat->lang, lang, sizeof(cat->lang)))
|
||||
{
|
||||
if (prev)
|
||||
prev->next = cat->next;
|
||||
else
|
||||
_lmo_catalogs = cat->next;
|
||||
|
||||
for (ar = cat->archives; ar; ar = next)
|
||||
{
|
||||
next = ar->next;
|
||||
lmo_close(ar);
|
||||
}
|
||||
|
||||
free(cat);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* lmo - Lua Machine Objects - General header
|
||||
*
|
||||
* Copyright (C) 2009-2012 Jo-Philipp Wich <xm@subsignal.org>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _TEMPLATE_LMO_H_
|
||||
#define _TEMPLATE_LMO_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fnmatch.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
|
||||
#if (defined(__GNUC__) && defined(__i386__))
|
||||
#define sfh_get16(d) (*((const uint16_t *) (d)))
|
||||
#else
|
||||
#define sfh_get16(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
|
||||
+(uint32_t)(((const uint8_t *)(d))[0]) )
|
||||
#endif
|
||||
|
||||
|
||||
struct lmo_entry {
|
||||
uint32_t key_id;
|
||||
uint32_t val_id;
|
||||
uint32_t offset;
|
||||
uint32_t length;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct lmo_entry lmo_entry_t;
|
||||
|
||||
|
||||
struct lmo_archive {
|
||||
int fd;
|
||||
int length;
|
||||
uint32_t size;
|
||||
lmo_entry_t *index;
|
||||
char *mmap;
|
||||
char *end;
|
||||
struct lmo_archive *next;
|
||||
};
|
||||
|
||||
typedef struct lmo_archive lmo_archive_t;
|
||||
|
||||
|
||||
struct lmo_catalog {
|
||||
char lang[6];
|
||||
struct lmo_archive *archives;
|
||||
struct lmo_catalog *next;
|
||||
};
|
||||
|
||||
typedef struct lmo_catalog lmo_catalog_t;
|
||||
|
||||
|
||||
uint32_t sfh_hash(const char *data, int len);
|
||||
uint32_t lmo_canon_hash(const char *data, int len);
|
||||
|
||||
lmo_archive_t * lmo_open(const char *file);
|
||||
void lmo_close(lmo_archive_t *ar);
|
||||
|
||||
|
||||
extern lmo_catalog_t *_lmo_catalogs;
|
||||
extern lmo_catalog_t *_lmo_active_catalog;
|
||||
|
||||
int lmo_load_catalog(const char *lang, const char *dir);
|
||||
int lmo_change_catalog(const char *lang);
|
||||
int lmo_translate(const char *key, int keylen, char **out, int *outlen);
|
||||
void lmo_close_catalog(const char *lang);
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue
Block a user