diff --git a/ReadMe.md b/ReadMe.md index 8be6c7c..14c73d0 100755 --- a/ReadMe.md +++ b/ReadMe.md @@ -1,19 +1,174 @@ -Smart DNS +SmartDNS ============== -Smard DNS会根据上级DNS服务返回的IP地址进行检查,如果IP地址无效,则继续进行DNS请求。 - +SmartDNS是一个运行在本地的DNS服务器,SmartDNS接受本地客户端的DNS查询请求,从多个上游DNS服务器获取DNS查询结果,并将访问速度最快的结果返回个客户端,避免DNS污染,提高网络访问速度。 +同时支持指定特定域名IP地址,并高性匹配,达到过滤广告的效果。 特性 -------------- -1. 多级DNS配置 +1. **多DNS上游服务器** + 支持配置多个上游DNS服务器,并同时进行查询,即使其中有DNS服务器异常,也不会影响查询。 + +1. **返回最快IP地址** + 支持从域名所属IP地址列表中查找到访问速度最快的IP地址,并返回给客户端,避免DNS污染,提高网络访问速度。 + +1. **支持非标准端口** + 支持非53端口查询,支持TCP查询,有效避免DNS污染。 + +1. **特定域名IP地址指定** + 支持指定域名的IP地址,达到广告过滤效果,避免恶意网站的效果。 + +1. **域名高性能后缀匹配** + 支持域名后缀匹配模式,简化过滤配置,过滤20万条记录时间<1ms + +1. **Linux多平台支持** + 支持标准Linux系统(树莓派),openwrt系统各种固件,华硕路由器原生固件。 + +1. **支持IPV4, IPV6双栈** + 支持IPV4,IPV6网络,支持查询A, AAAA记录。 + +1. **高性能,占用资源少** + 多线程异步IO模式,cache缓存查询结果。 + +架构 +------------- +![Architecture](doc/architecture.png) +1. SmartDNS接收本地网络设备的DNS查询请求,如PC,手机的查询请求。 +2. SmartDNS将查询请求发送到多个上游DNS服务器,可采用标准UDP查询,非标准端口UDP查询,及TCP查询。 +3. 上游DNS服务器返回域名对应的Server IP地址列表。SmartDNS检测与本地网络访问速度最快的Server IP。 +4. 将访问速度最快的Server IP返回给本地客户端。 使用 ============== +下载配套安装包 +-------------- +下载配套版本的SmartDNS安装包,对应安装包配套关系如下。 + +|系统 |安装包|说明 +|-----|-----|----- +|标准Linux系统(树莓派)| smartdns.xxxxxxxx.armhf.deb|支持树莓派Raspbian stretch,Debian 9系统。 +|华硕原生固件|asusware.mipsbig.tar.gz|支持MIPS大端架构的系统,如RT-AC55U, RT-AC66U. +|openwrt 15.01|smartdns.xxxxxxxx.ar71xx.ipk|支持AR71XX MIPS系统 +|openwrt LEDE|smartdns.1.2xxxxxxxx.mips_24kc.ipk|支持AR71XX MIPS系统。 +|openwrt LEDE|smartdns.1.2xxxxxxxx.mipsel_24kc.ipk|支持 + +标准Linux系统安装(树莓派) +-------------- +1. 安装 +``` +dpkg -i smartdns.xxxxxxxx.armhf.deb +``` +2. 修改配置 +``` +vi /etc/smartdns/smartdns.conf +``` +3. 启动服务 +``` +systemctl enable smartdns +systemctl start smartdns +``` +4. 修改本地路由器DNS指向树莓派 +* 登录到本地网络的路由器中,配置树莓派分配静态IP地址。 +* 修改WAN口或者DHCP DNS为树莓派IP地址。 + 注意: + I. 每款路由器配置方法不尽相同,请百度搜索相关的配置方法。 + II. 华为等路由器可能不支持配置DNS为本地IP,请修改PC端,手机端DNS服务器为树莓派IP。 + + +openwrt/LEDE +-------------- +1. 安装 +将软件使用winscp上传到路由器的/root目录,执行如下命令安装 +``` +opkg install smartdns.xxxxxxxx.xxxx.ipk +``` + +2. 修改配置 +``` +vi /etc/smartdns/smartdns.conf +``` +3. 启动服务 +``` + +``` + +华硕路由器原生固件 +-------------- +在使用此软件时,需要确认路由器是否支持U盘,并准备好U盘一个。 + +1. 解压安装包到U盘根目录,其目录格式如下。(此处仅列出smartdns相关文件) +``` +U盘 + └── asusware.mipsbig + ├── bin + ├── etc + | ├── smartdns + | | └── smartdns.conf + | └── init.d + | └── S50smartdns + ├── lib + ├── sbin + ├── usr + | └── sbin + | └── smartdns + .... +``` +2. 修改配置 +``` +vi asusware.mipsbig/etc/smartdns/smartdns.conf +``` +3. 启动服务 +将U盘插入路由器后方USB插口,并重启路由器。 + +4. 检测DNS服务是否生效 +待路由器启动后,使用nslookup查询域名,看命令结果中的`服务器`项目是否显示为`smartdns`,如显示smartdns则表示生效 +``` +C:\Users\meikechong>nslookup www.baidu.com +服务器: smartdns +Address: 192.168.1.1 + +非权威应答: +名称: www.a.shifen.com +Address: 14.215.177.39 +Aliases: www.baidu.com +``` + +配置参数 +============== +|参数|功能|默认值|配置值|例子| +|--|--|--|--|--| +|server-name|DNS服务器名称|操作系统主机名/smartdns|符合主机名规格的字符串|server-name smartdns +|bind|DNS监听端口号|[::]:53|IP:PORT|bind 192.168.1.1:53 +|cache-size|域名结果缓存个数|512|数字|cache-size 512 +|rr-ttl|域名结果TTL|远程查询结果|大于0的数字|rr-ttl 600 +|rr-ttl-min|允许的最小TTL值|远程查询结果|大于0的数字|rr-ttl-min 60 +|rr-ttl-max|允许的最大TTL值|远程查询结果|大于0的数组|rr-ttl-max 600 +|log-level|设置日志级别|error|error,warn,info,debug|log-level error +|log-file|日志文件路径|/var/log/smartdns.log|路径|log-file /var/log/smartdns.log +|log-size|日志大小|128K|数字+K,M,G|log-size 128K +|log-num|日志归档个数|2|数字|log-num 2 +|server|上游UDP DNS|114.114.114.114|[ip][:port],可重复| server 8.8.8.8:53 +|server-tcp|上游TCP DNS|无|[IP][:port],可重复| server-tcp 8.8.8.8:53 +|address|指定域名IP地址|无|address /domain/ip| address /www.example.com/1.2.3.4 + +捐助 +============== + +* Alipay 支付宝 +![alipay](doc/alipay_donate.jpg) + +* Wechat 微信 +![wechat](doc/wechat_donate.jpg) + +说明 +============== +目前代码未开源,后续根据情况开源。 + + + + + -License -=============== -GPL V2 License diff --git a/doc/alipay_donate.jpg b/doc/alipay_donate.jpg new file mode 100644 index 0000000..73ee72c Binary files /dev/null and b/doc/alipay_donate.jpg differ diff --git a/doc/architecture.png b/doc/architecture.png new file mode 100644 index 0000000..9d83052 Binary files /dev/null and b/doc/architecture.png differ diff --git a/doc/architecture.vsdx b/doc/architecture.vsdx new file mode 100644 index 0000000..b4b2d3c Binary files /dev/null and b/doc/architecture.vsdx differ diff --git a/doc/wechat_donate.jpg b/doc/wechat_donate.jpg new file mode 100644 index 0000000..59dc1fb Binary files /dev/null and b/doc/wechat_donate.jpg differ diff --git a/package/debian/make.sh b/package/debian/make.sh index 7aa19ea..6a49308 100644 --- a/package/debian/make.sh +++ b/package/debian/make.sh @@ -1,30 +1,90 @@ #/bin/sh -CURR_DIR=`pwd` +CURR_DIR=$(cd $(dirname $0);pwd) VER="`date +"1.%Y.%m.%d-%H%M"`" SMARTDNS_DIR=$CURR_DIR/../../ SMARTDNS_BIN=$SMARTDNS_DIR/src/smartdns -ROOT=/tmp/smartdns-deiban -rm -fr $ROOT -mkdir -p $ROOT -cd $ROOT/ -cp $CURR_DIR/DEBIAN $ROOT/ -af -CONTROL=$ROOT/DEBIAN/control -mkdir $ROOT/usr/sbin -p -mkdir $ROOT/etc/smartdns/ -p -mkdir $ROOT/etc/default/ -p -mkdir $ROOT/lib/systemd/system/ -p +showhelp() +{ + echo "Usage: make [OPTION]" + echo "Options:" + echo " -o output directory." + echo " --arch archtecture." + echo " --ver version." + echo " -h show this message." +} -sed -i "s/Version:.*/Version: $VER/" $ROOT/DEBIAN/control -chmod 0755 $ROOT/DEBIAN/prerm +build() +{ + ROOT=/tmp/smartdns-deiban + rm -fr $ROOT + mkdir -p $ROOT + cd $ROOT/ -cp $SMARTDNS_DIR/etc/smartdns/smartdns.conf $ROOT/etc/smartdns/ -cp $SMARTDNS_DIR/etc/default/smartdns $ROOT/etc/default/ -cp $SMARTDNS_DIR/systemd/smartdns.service $ROOT/lib/systemd/system/ -cp $SMARTDNS_DIR/src/smartdns $ROOT/usr/sbin -chmod +x $ROOT/usr/sbin/smartdns + cp $CURR_DIR/DEBIAN $ROOT/ -af + CONTROL=$ROOT/DEBIAN/control + mkdir $ROOT/usr/sbin -p + mkdir $ROOT/etc/smartdns/ -p + mkdir $ROOT/etc/default/ -p + mkdir $ROOT/lib/systemd/system/ -p -dpkg -b $ROOT $CURR_DIR/smartdns.$VER.armhf.deb + sed -i "s/Version:.*/Version: $VER/" $ROOT/DEBIAN/control + sed -i "s/Architecture:.*/Architecture: $ARCH/" $ROOT/DEBIAN/control + chmod 0755 $ROOT/DEBIAN/prerm -rm -fr $ROOT/ \ No newline at end of file + cp $SMARTDNS_DIR/etc/smartdns/smartdns.conf $ROOT/etc/smartdns/ + cp $SMARTDNS_DIR/etc/default/smartdns $ROOT/etc/default/ + cp $SMARTDNS_DIR/systemd/smartdns.service $ROOT/lib/systemd/system/ + cp $SMARTDNS_DIR/src/smartdns $ROOT/usr/sbin + chmod +x $ROOT/usr/sbin/smartdns + + dpkg -b $ROOT $OUTPUTDIR/smartdns.$VER.$ARCH.deb + + rm -fr $ROOT/ +} + +main() +{ + OPTS=`getopt -o o:h --long arch:,ver: \ + -n "" -- "$@"` + + if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi + + # Note the quotes around `$TEMP': they are essential! + eval set -- "$OPTS" + + while true; do + case "$1" in + --arch) + ARCH="$2" + shift 2;; + --ver) + VER="$2" + shift 2;; + -o ) + OUTPUTDIR="$2" + shift 2;; + -h | --help ) + showhelp + return 0 + shift ;; + -- ) shift; break ;; + * ) break ;; + esac + done + + if [ -z "$ARCH" ]; then + echo "please input arch." + return 1; + fi + + if [ -z "$OUTPUTDIR" ]; then + OUTPUTDIR=$CURR_DIR; + fi + + build +} + +main $@ +exit $? diff --git a/package/luci/control/control b/package/luci/control/control new file mode 100644 index 0000000..2cd9e99 --- /dev/null +++ b/package/luci/control/control @@ -0,0 +1,8 @@ +Package: luci-app-smartdns +Version: git-18.201.27126-7bf0367-1 +Depends: libc, smartdns +Source: feeds/luci/applications/luci-app-smartdns +Section: luci +Architecture: all +Installed-Size: 1040 +Description: A smartdns server module diff --git a/package/luci/control/postinst b/package/luci/control/postinst new file mode 100644 index 0000000..e4b3fd0 --- /dev/null +++ b/package/luci/control/postinst @@ -0,0 +1,5 @@ +#!/bin/sh +[ "${IPKG_NO_SCRIPT}" = "1" ] && exit 0 +[ -x ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0 +. ${IPKG_INSTROOT}/lib/functions.sh +default_postinst $0 $@ diff --git a/package/luci/control/postinst-pkg b/package/luci/control/postinst-pkg new file mode 100644 index 0000000..ded67b6 --- /dev/null +++ b/package/luci/control/postinst-pkg @@ -0,0 +1,4 @@ +[ -n "${IPKG_INSTROOT}" ] || { + (. /etc/uci-defaults/50_luci-smartdns) && rm -f /etc/uci-defaults/50_luci-smartdns + exit 0 +} diff --git a/package/luci/control/prerm b/package/luci/control/prerm new file mode 100644 index 0000000..baed906 --- /dev/null +++ b/package/luci/control/prerm @@ -0,0 +1,4 @@ +#!/bin/sh +[ -x ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0 +. ${IPKG_INSTROOT}/lib/functions.sh +default_prerm $0 $@ diff --git a/package/luci/debian-binary b/package/luci/debian-binary new file mode 100644 index 0000000..cd5ac03 --- /dev/null +++ b/package/luci/debian-binary @@ -0,0 +1 @@ +2.0 diff --git a/package/luci/files/etc/uci-defaults/50_luci-smartdns b/package/luci/files/etc/uci-defaults/50_luci-smartdns new file mode 100644 index 0000000..a3a3581 --- /dev/null +++ b/package/luci/files/etc/uci-defaults/50_luci-smartdns @@ -0,0 +1,11 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@smartdns[-1] + add ucitrack smartdns + set ucitrack.@smartdns[-1].init=smartdns + commit ucitrack +EOF + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/package/luci/files/luci/controller/smartdns.lua b/package/luci/files/luci/controller/smartdns.lua new file mode 100644 index 0000000..1b1c148 --- /dev/null +++ b/package/luci/files/luci/controller/smartdns.lua @@ -0,0 +1,14 @@ +-- Copyright 2018 Nick Peng (pymumu@gmail.com) + +module("luci.controller.smartdns", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/smartdns") then + return + end + + local page + + page = entry({"admin", "services", "smartdns"}, cbi("smartdns"), _("SmartDNS"), 60) + page.dependent = true +end diff --git a/package/luci/files/luci/model/cbi/smartdns.lua b/package/luci/files/luci/model/cbi/smartdns.lua new file mode 100644 index 0000000..1ce4438 --- /dev/null +++ b/package/luci/files/luci/model/cbi/smartdns.lua @@ -0,0 +1,120 @@ +-- Copyright 2018 Nick Peng (pymumu@gmail.com) + +require("nixio.fs") +require("luci.http") + +m = Map("smartdns", translate("SmartDNS"), + translate("SmartDNS is a local dns server to find fastest ip.")) + +if luci.sys.call("pidof smartdns >/dev/null") == 0 then + m = Map("smartdns", translate("SmartDNS"), "%s - %s" %{translate("SmartDNS"), translate("RUNNING")}) +else + m = Map("smartdns", translate("SmartDNS"), "%s - %s" %{translate("SmartDNS"), translate("NOT RUNNING")}) +end + +-- Basic +s = m:section(TypedSection, "smartdns", translate("SmartDNS Server")) +s.anonymous = true + +s:tab("settings", translate("Settings")) +s:tab("help", translate("Technical Support")) + +---- Eanble +o = s:taboption("settings", Flag, "enabled", translate("Enable"), translate("Enable or disable smartdns server")) +o.rempty = false + +---- Port +o = s:taboption("settings", Value, "port", translate("Local Port"), translate("Smartdns local server port")) +o.placeholder = 5353 +o.default = 5353 +o.datatype = "port" +o.rempty = false + +o = s:taboption("settings", Flag, "redirect", translate("redirect"), translate("redirect standard dns query from 53 to smartdns")) +o.default = true +o.rempty = false + +---- cache-size +o = s:taboption("settings", Value, "cache_size", translate("Cache Size"), translate("DNS domain result cache size")) +o.rempty = true + +---- rr-ttl +o = s:taboption("settings", Value, "rr_ttl", translate("Domain TTL"), translate("TTL for all domain result.")) +o.rempty = true + +---- rr-ttl-min +o = s:taboption("settings", Value, "rr_ttl_min", translate("Domain TTL Min"), translate("Minimum TTL for all domain result.")) +o.rempty = true + +---- rr-ttl-max +o = s:taboption("settings", Value, "rr_ttl_min", translate("Domain TTL Max"), translate("Maximum TTL for all domain result.")) +o.rempty = true + +o = s:taboption("help", Button, "web") +o.title = translate("SmartDNS official website") +o.inputtitle = translate("open website") +o.inputstyle = "apply" +o.write = function() + luci.http.redirect("https://pymumu.github.io/") +end + +o = s:taboption("help", Button, "Donate") +o.title = translate("Donate to smartdns") +o.inputtitle = translate("Donate") +o.inputstyle = "apply" +o.write = function() + luci.http.redirect("https://pymumu.github.io/smartdns") +end + +-- Upstream servers +s = m:section(TypedSection, "server", translate("Upstream Servers"), translate("Upstream Servers, support UDP, TCP protocol")) +s.anonymous = true +s.addremove = true +s.template = "cbi/tblsection" + +---- name +s:option(Value, "name", translate("Name"), translate("DNS Server name")) +---- IP address +o = s:option(Value, "ip", translate("ip"), translate("DNS Server ip")) +o.datatype = "ipaddr" +o.rmempty = false +---- port +o = s:option(Value, "port", translate("port"), translate("DNS Server port")) +o.placeholder = 53 +o.default = 53 +o.datatype = "port" +o.rempty = false +---- type +o = s:option(ListValue, "type", translate("type"), translate("DNS Server type")) +o.placeholder = "udp" +o:value("udp", translate("udp")) +o:value("tcp", translate("tcp")) +o.default = "udp" +o.rempty = false + +-- Doman addresss +s = m:section(TypedSection, "smartdns", translate("Domain Address"), + translate("DNS Server name")) +s.anonymous = true + +---- address +addr = s:option(Value, "address", + translate(""), + translate("Specify an IP address to return for any host in the given domains " .. + "Queries in the domains are never forwarded and always replied to with the specified IP address which may be IPv4 or IPv6. " .. + "")) + +addr.template = "cbi/tvalue" +addr.rows = 20 + +function addr.cfgvalue(self, section) + return nixio.fs.readfile("/etc/smartdns/address.conf") +end + +function addr.write(self, section, value) + value = value:gsub("\r\n?", "\n") + nixio.fs.writefile("/etc/smartdns/address.conf", value) +end + +return m + diff --git a/package/luci/make.sh b/package/luci/make.sh new file mode 100644 index 0000000..6241172 --- /dev/null +++ b/package/luci/make.sh @@ -0,0 +1,88 @@ +#/bin/sh + +CURR_DIR=$(cd $(dirname $0);pwd) + +VER="`date +"1.%Y.%m.%d-%H%M"`" +SMARTDNS_DIR=$CURR_DIR/../../ + +showhelp() +{ + echo "Usage: make [OPTION]" + echo "Options:" + echo " -o output directory." + echo " --arch archtecture." + echo " --ver version." + echo " -h show this message." +} + +build() +{ + ROOT=/tmp/luci-app-smartdns + rm -fr $ROOT + + mkdir -p $ROOT + cp $CURR_DIR/* $ROOT/ -af + cd $ROOT/ + mkdir $ROOT/root/usr/lib/lua/ -p + cp $ROOT/files/luci $ROOT/root/usr/lib/lua/ -af + cp $ROOT/files/etc $ROOT/root/ -af + + sed -i "s/^Architecture.*/Architecture: $ARCH/g" $ROOT/control/control + sed -i "s/Version:.*/Version: $VER/" $ROOT/control/control + + cd $ROOT/control + chmod +x * + tar zcf ../control.tar.gz ./ + cd $ROOT + + tar zcf $ROOT/data.tar.gz -C root . + tar zcf $OUTPUTDIR/luci-app-smartdns.$VER.$ARCH.ipk control.tar.gz data.tar.gz debian-binary + rm -fr $ROOT/ +} + +main() +{ + OPTS=`getopt -o o:h --long arch:,ver: \ + -n "" -- "$@"` + + if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi + + # Note the quotes around `$TEMP': they are essential! + eval set -- "$OPTS" + + while true; do + case "$1" in + --arch) + ARCH="$2" + shift 2;; + --ver) + VER="$2" + shift 2;; + -o ) + OUTPUTDIR="$2" + shift 2;; + -h | --help ) + showhelp + return 0 + shift ;; + -- ) shift; break ;; + * ) break ;; + esac + done + + if [ -z "$ARCH" ]; then + echo "please input arch." + return 1; + fi + + if [ -z "$OUTPUTDIR" ]; then + OUTPUTDIR=$CURR_DIR; + fi + + build +} + +main $@ +exit $? + + diff --git a/package/openwrt/Makefile b/package/openwrt/Makefile index e5aa7f9..ccfc411 100644 --- a/package/openwrt/Makefile +++ b/package/openwrt/Makefile @@ -1,34 +1,34 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=smarttdns -PKG_VERSION:=2018.7.1.1607 -PKG_RELEASE:=$(PKG_SOURCE_VERSION) - -PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) - -include $(INCLUDE_DIR)/package.mk - -define Package/smartdns - SECTION:=net - CATEGORY:=Network - TITLE:=smartdns - URL:=https://github.com/pymumu/smartdns - MAINTAINER:=Nick Peng - DEPENDS:= -endef - -define Package/smartdns/description - smartdns server, find fastest ip. -endef - -define Build/Prepare - mkdir -p $(PKG_BUILD_DIR) - cp -r ../* $(PKG_BUILD_DIR) -endef - -define Package/smartdns/install - $(INSTALL_DIR) $(1)/usr/sbin - $(INSTALL_BIN) $(PKG_BUILD_DIR)/smartdns $(1)/usr/sbin -endef - -$(eval $(call BuildPackage, smartdns)) +include $(TOPDIR)/rules.mk + +PKG_NAME:=smarttdns +PKG_VERSION:=2018.7.1.1607 +PKG_RELEASE:=$(PKG_SOURCE_VERSION) + +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk + +define Package/smartdns + SECTION:=net + CATEGORY:=Network + TITLE:=smartdns + URL:=https://github.com/pymumu/smartdns + MAINTAINER:=Nick Peng + DEPENDS:= +endef + +define Package/smartdns/description + smartdns server, find fastest ip. +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + cp -r ../* $(PKG_BUILD_DIR) +endef + +define Package/smartdns/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/smartdns $(1)/usr/sbin +endef + +$(eval $(call BuildPackage, smartdns)) diff --git a/package/openwrt/address.conf b/package/openwrt/address.conf new file mode 100644 index 0000000..e69de29 diff --git a/package/openwrt/control/conffiles b/package/openwrt/control/conffiles new file mode 100644 index 0000000..b8dc0cf --- /dev/null +++ b/package/openwrt/control/conffiles @@ -0,0 +1 @@ +/etc/config/smartdns diff --git a/package/openwrt/control/control b/package/openwrt/control/control new file mode 100644 index 0000000..18866e5 --- /dev/null +++ b/package/openwrt/control/control @@ -0,0 +1,11 @@ +Package: smartdns +Architecture: mipsbig +Priority: optional +Section: net +Version: 2018.7.6-1921 +Maintainer: pymumu +Source: http://127.0.0.1/ +Description: A smart dns server +Suggests: +Conflicts: +Enabled: yes diff --git a/package/openwrt/control/postinst b/package/openwrt/control/postinst new file mode 100644 index 0000000..32198f7 --- /dev/null +++ b/package/openwrt/control/postinst @@ -0,0 +1,15 @@ +#!/bin/sh + +chmod +x /usr/sbin/smartdns +chmod +x /etc/init.d/smartdns + +[ "${IPKG_NO_SCRIPT}" = "1" ] && exit 0 +. ${IPKG_INSTROOT}/lib/functions.sh +default_postinst $0 $@ + + + + + + + diff --git a/package/openwrt/control/prerm b/package/openwrt/control/prerm new file mode 100644 index 0000000..e9dda89 --- /dev/null +++ b/package/openwrt/control/prerm @@ -0,0 +1,4 @@ +#!/bin/sh +. ${IPKG_INSTROOT}/lib/functions.sh +default_prerm $0 $@ + diff --git a/package/openwrt/debian-binary b/package/openwrt/debian-binary new file mode 100644 index 0000000..cd5ac03 --- /dev/null +++ b/package/openwrt/debian-binary @@ -0,0 +1 @@ +2.0 diff --git a/package/openwrt/files/etc/config/smartdns b/package/openwrt/files/etc/config/smartdns new file mode 100644 index 0000000..b29e0a2 --- /dev/null +++ b/package/openwrt/files/etc/config/smartdns @@ -0,0 +1,2 @@ +config 'smartdns' + option 'enabled' '0' \ No newline at end of file diff --git a/package/openwrt/files/etc/init.d/smartdns b/package/openwrt/files/etc/init.d/smartdns new file mode 100644 index 0000000..6ed7f64 --- /dev/null +++ b/package/openwrt/files/etc/init.d/smartdns @@ -0,0 +1,116 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2008-2011 OpenWrt.org + +START=50 +SERVICE_USE_PID=1 +SERVICE_WRITE_PID=1 +SERVICE_DAEMONIZE=1 +BASECONFIGFILE="/etc/smartdns/smartdns.conf" +SMARTDNS_CONF="/var/etc/smartdns.conf" +ADDRESS_CONF="/etc/smartdns/address.conf" +SMARTDNS_CONF_TMP="${SMARTDNS_CONF}.tmp" + +set_iptable() +{ + IPS="`ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F: '{print $2}'`" + for IP in $IPS + do + iptables -t nat -A PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $SMARTDNS_PORT >/dev/null 2>&1 + done + +} + +clear_iptable() +{ + IPS="`ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F: '{print $2}'`" + for IP in $IPS + do + iptables -t nat -D PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $SMARTDNS_PORT >/dev/null 2>&1 + done + +} + +conf_append() +{ + echo "$1 $2" >> $SMARTDNS_CONF_TMP +} + +load_server() +{ + local section="$1" + config_get "port" "$section" "port" "53" + config_get "type" "$section" "type" "udp" + config_get "ip" "$section" "ip" "" + + if [ -z "$port" ] || [ -z "$ip" ] || [ -z "$type" ]; then + return + fi + + SERVER="server" + if [ "$type" = "tcp" ]; then + SERVER="server-tcp" + fi + + if [ ! -z "`echo $ip | grep ":"`" ]; then + if [ -z "`echo $ip | grep "\["`" ]; then + ip="[$ip]" + fi + fi + + conf_append "$SERVER" "$ip:$port" + +} + +start_service() { + local section="$1" + args="" + config_get "port" "$section" "port" "5353" + conf_append "bind" "[::]:$port" + SMARTDNS_PORT="$port" + + config_get "cache_size" "$section" "cache_size" "" + if [ ! -z "$cache_size" ]; then + conf_append "cache-size" "$cache_size" + fi + + config_get "rr_ttl" "$section" "rr_ttl" "" + if [ ! -z "$rr_ttl" ]; then + conf_append "rr-ttl" "$rr_ttl" + fi + + config_get "rr_ttl_min" "$section" "rr_ttl_min" "" + if [ ! -z "$rr_ttl_min" ]; then + conf_append "rr-ttl-min" "$rr_ttl_min" + fi + + config_get "rr_ttl_max" "$section" "rr_ttl_max" "" + if [ ! -z "$rr_ttl_max" ]; then + conf_append "rr-ttl-max" "$rr_ttl_max" + fi + + clear_iptable + config_get_bool "redirect" "$section" "redirect" '0' + if [ "$redirect" -eq 1 ]; then + set_iptable + fi + + config_foreach load_server "server" + + echo "# address" >> $SMARTDNS_CONF_TMP + grep "^ *address" $ADDRESS_CONF >> $SMARTDNS_CONF_TMP + + config_get_bool "enabled" "$section" "enabled" '0' + mv $SMARTDNS_CONF_TMP $SMARTDNS_CONF + [ "$enabled" -gt 0 ] || return 1 + service_start /usr/sbin/smartdns $args -c $SMARTDNS_CONF +} + +start() { + config_load "smartdns" + config_foreach start_service "smartdns" +} + +stop() { + service_stop /usr/sbin/smartdns +} + diff --git a/package/openwrt/make.sh b/package/openwrt/make.sh new file mode 100644 index 0000000..95de9e4 --- /dev/null +++ b/package/openwrt/make.sh @@ -0,0 +1,99 @@ +#/bin/sh + +CURR_DIR=$(cd $(dirname $0);pwd) + +VER="`date +"1.%Y.%m.%d-%H%M"`" +SMARTDNS_DIR=$CURR_DIR/../../ +SMARTDNS_BIN=$SMARTDNS_DIR/src/smartdns +SMARTDNS_CONF=$SMARTDNS_DIR/etc/smartdns/smartdns.conf +ADDRESS_CONF=$CURR_DIR/address.conf + +showhelp() +{ + echo "Usage: make [OPTION]" + echo "Options:" + echo " -o output directory." + echo " --arch archtecture." + echo " --ver version." + echo " -h show this message." +} + +build() +{ + ROOT=/tmp/smartdns-openwrt + rm -fr $ROOT + + mkdir -p $ROOT + cp $CURR_DIR/* $ROOT/ -af + cd $ROOT/ + mkdir $ROOT/root/usr/sbin -p + mkdir $ROOT/root/etc/init.d -p + mkdir $ROOT/root/etc/smartdns/ -p + + cp $SMARTDNS_CONF $ROOT/root/etc/smartdns/ + cp $ADDRESS_CONF $ROOT/root/etc/smartdns/ + cp $CURR_DIR/files/etc $ROOT/root/ -af + cp $SMARTDNS_BIN $ROOT/root/usr/sbin + + chmod +x $ROOT/root/etc/init.d/smartdns + + sed -i "s/^Architecture.*/Architecture: $ARCH/g" $ROOT/control/control + sed -i "s/Version:.*/Version: $VER/" $ROOT/control/control + sed -i "s/^\(bind .*\):53/\1:5353/g" $ROOT/root/etc/smartdns/smartdns.conf + + cd $ROOT/control + chmod +x * + tar zcf ../control.tar.gz ./ + cd $ROOT + + tar zcf $ROOT/data.tar.gz -C root . + tar zcf $OUTPUTDIR/smartdns.$VER.$ARCH.ipk control.tar.gz data.tar.gz debian-binary + rm -fr $ROOT/ +} + +main() +{ + OPTS=`getopt -o o:h --long arch:,ver: \ + -n "" -- "$@"` + + if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi + + # Note the quotes around `$TEMP': they are essential! + eval set -- "$OPTS" + + while true; do + case "$1" in + --arch) + ARCH="$2" + shift 2;; + --ver) + VER="$2" + shift 2;; + -o ) + OUTPUTDIR="$2" + shift 2;; + -h | --help ) + showhelp + return 0 + shift ;; + -- ) shift; break ;; + * ) break ;; + esac + done + + if [ -z "$ARCH" ]; then + echo "please input arch." + return 1; + fi + + if [ -z "$OUTPUTDIR" ]; then + OUTPUTDIR=$CURR_DIR; + fi + + build +} + +main $@ +exit $? + + diff --git a/package/optware/make.sh b/package/optware/make.sh index eb9b940..9f84dda 100644 --- a/package/optware/make.sh +++ b/package/optware/make.sh @@ -1,31 +1,92 @@ #/bin/sh -CURR_DIR=`pwd` +CURR_DIR=$(cd $(dirname $0);pwd) VER="`date +"1.%Y.%m.%d-%H%M"`" SMARTDNS_DIR=$CURR_DIR/../../ SMARTDNS_BIN=$SMARTDNS_DIR/src/smartdns SMARTDNS_CONF=$SMARTDNS_DIR/etc/smartdns/smartdns.conf -ROOT=/tmp/smartdns-optware -rm -fr $ROOT -mkdir -p $ROOT -cp * $ROOT/ -af -cd $ROOT/ -mkdir $ROOT/opt/usr/sbin -p -mkdir $ROOT/opt/etc/init.d -p -mkdir $ROOT/opt/etc/smartdns/ -p +showhelp() +{ + echo "Usage: make [OPTION]" + echo "Options:" + echo " -o output directory." + echo " --arch archtecture." + echo " --ver version." + echo " -h show this message." +} -cp $SMARTDNS_CONF $ROOT/opt/etc/smartdns/ -cp S50smartdns $ROOT/opt/etc/init.d/ -cp $SMARTDNS_BIN $ROOT/opt/usr/sbin +build() +{ + ROOT=/tmp/smartdns-optware + rm -fr $ROOT -sed -i "s/^\(bind .*\):53/\1:535/g" $ROOT/opt/etc/smartdns/smartdns.conf + mkdir -p $ROOT + cp $CURR_DIR/* $ROOT/ -af + cd $ROOT/ + mkdir $ROOT/opt/usr/sbin -p + mkdir $ROOT/opt/etc/init.d -p + mkdir $ROOT/opt/etc/smartdns/ -p -cd $ROOT/control -chmod +x * -tar zcf ../control.tar.gz ./ -cd $ROOT + cp $SMARTDNS_CONF $ROOT/opt/etc/smartdns/ + cp $CURR_DIR/S50smartdns $ROOT/opt/etc/init.d/ + cp $SMARTDNS_BIN $ROOT/opt/usr/sbin -tar zcf data.tar.gz opt -tar zcf $CURR_DIR/smartdns.$VER.mipsbig.ipk control.tar.gz data.tar.gz debian-binary -rm -fr $ROOT/ \ No newline at end of file + sed -i "s/^\(bind .*\):53/\1:535/g" $ROOT/opt/etc/smartdns/smartdns.conf + sed -i "s/^Architecture.*/Architecture: $ARCH/g" $ROOT/control/control + sed -i "s/Version:.*/Version: $VER/" $ROOT/control/control + + cd $ROOT/control + chmod +x * + tar zcf ../control.tar.gz ./ + cd $ROOT + + tar zcf data.tar.gz opt + tar zcf $OUTPUTDIR/smartdns.$VER.$ARCH.ipk control.tar.gz data.tar.gz debian-binary + rm -fr $ROOT/ +} + +main() +{ + OPTS=`getopt -o o:h --long arch:,ver: \ + -n "" -- "$@"` + + if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi + + # Note the quotes around `$TEMP': they are essential! + eval set -- "$OPTS" + + while true; do + case "$1" in + --arch) + ARCH="$2" + shift 2;; + --ver) + VER="$2" + shift 2;; + -o ) + OUTPUTDIR="$2" + shift 2;; + -h | --help ) + showhelp + return 0 + shift ;; + -- ) shift; break ;; + * ) break ;; + esac + done + + if [ -z "$ARCH" ]; then + echo "please input arch." + return 1; + fi + + if [ -z "$OUTPUTDIR" ]; then + OUTPUTDIR=$CURR_DIR; + fi + + build +} + +main $@ +exit $? diff --git a/src/dns_cache.h b/src/dns_cache.h index 58365ef..6954d71 100644 --- a/src/dns_cache.h +++ b/src/dns_cache.h @@ -6,6 +6,7 @@ #include "hash.h" #include "list.h" #include "atomic.h" +#include struct dns_cache { struct hlist_node node; diff --git a/src/tlog.c b/src/tlog.c index a9d8427..f880b09 100644 --- a/src/tlog.c +++ b/src/tlog.c @@ -33,6 +33,7 @@ #define TLOG_TMP_LEN 128 #define TLOG_LOG_SIZE (1024 * 1024 * 50) #define TLOG_LOG_COUNT 32 +#define TLOG_LOG_NAME_LEN 128 struct oldest_log { char name[TLOG_TMP_LEN]; @@ -59,7 +60,7 @@ struct tlog { off_t filesize; char logdir[PATH_MAX]; - char logname[PATH_MAX]; + char logname[TLOG_LOG_NAME_LEN]; int logsize; int logcount; int block; @@ -382,7 +383,7 @@ int tlog_ext(tlog_level level, const char *file, int line, const char *func, voi static int _tlog_rename_logfile(const char *gzip_file) { - char archive_file[PATH_MAX]; + char archive_file[PATH_MAX * 2]; struct tlog_time logtime; int i = 0; @@ -460,7 +461,7 @@ static int _tlog_count_log_callback(const char *path, struct dirent *entry, void static int _tlog_get_oldest_callback(const char *path, struct dirent *entry, void *userptr) { struct stat sb; - char filename[PATH_MAX]; + char filename[PATH_MAX * 2]; struct oldest_log *oldestlog = userptr; /* if not a gz file, skip */ @@ -500,7 +501,7 @@ static int _tlog_remove_oldestlog(void) return -1; } - char filename[PATH_MAX]; + char filename[PATH_MAX * 2]; snprintf(filename, sizeof(filename), "%s/%s", tlog.logdir, oldestlog.name); /* delete */ @@ -530,7 +531,7 @@ static int _tlog_remove_oldlog(void) static void _tlog_log_unlock(void) { - char lock_file[PATH_MAX]; + char lock_file[PATH_MAX * 2]; if (tlog.fd_lock <= 0) { return; } @@ -543,7 +544,7 @@ static void _tlog_log_unlock(void) static int _tlog_log_lock(void) { - char lock_file[PATH_MAX]; + char lock_file[PATH_MAX * 2]; int fd; if (tlog.multi_log == 0) { @@ -586,7 +587,7 @@ static void _tlog_wait_pid(int wait_hang) /* gzip process exited */ tlog.zip_pid = -1; - char gzip_file[PATH_MAX]; + char gzip_file[PATH_MAX * 2]; /* rename ziped file */ snprintf(gzip_file, sizeof(gzip_file), "%s/%s.pending.gz", tlog.logdir, tlog.logname); @@ -646,10 +647,10 @@ errout: static int _tlog_archive_log(void) { - char gzip_file[PATH_MAX]; - char gzip_cmd[PATH_MAX]; - char log_file[PATH_MAX]; - char pending_file[PATH_MAX]; + char gzip_file[PATH_MAX * 2]; + char gzip_cmd[PATH_MAX * 2]; + char log_file[PATH_MAX * 2]; + char pending_file[PATH_MAX * 2]; snprintf(gzip_file, sizeof(gzip_file), "%s/%s.pending.gz", tlog.logdir, tlog.logname); snprintf(pending_file, sizeof(pending_file), "%s/%s.pending", tlog.logdir, tlog.logname); @@ -718,7 +719,7 @@ static int _tlog_write_log(char *buff, int bufflen) if (tlog.fd <= 0) { /* open a new log file to write */ - char logfile[PATH_MAX]; + char logfile[PATH_MAX * 2]; if (_tlog_mkdir(tlog.logdir) != 0) { fprintf(stderr, "create log dir %s failed.\n", tlog.logdir); return -1;