Compare commits

..

13 Commits

Author SHA1 Message Date
Nick Peng
4db61f2677 Fix TimeZone issue when static compile 2019-12-15 01:27:14 +08:00
Nick Peng
7746ecb46d Fix script issue on padavan 2019-12-15 01:27:13 +08:00
Nick Peng
4357847641 Add display version 2019-12-15 01:27:12 +08:00
Nick Peng
e7e0a5d4af Fix openssl version issue 2019-12-15 01:27:11 +08:00
Nick Peng
57aa9c013d Fix optware startup script issue 2019-12-15 01:27:10 +08:00
Nick Peng
7216dcf526 Update ReadMe.md 2019-12-15 01:27:09 +08:00
Nick Peng
41e2067628 Fix build issue 2019-12-15 01:27:06 +08:00
Nick Peng
dda785ec5f Support TLS 1.3 2019-12-15 01:27:05 +08:00
Nick Peng
99972c36ad Fix ps bug 2019-12-15 01:27:04 +08:00
Nick Peng
ef50ea9c5e Change rule domain to lowercase 2019-12-15 01:27:03 +08:00
Nick Peng
cb3656cb57 Change config accept-ip to whitelist-ip 2019-12-15 01:27:02 +08:00
Nick Peng
3ef325d75d Support GCC 8.x and support static compile 2019-12-15 01:27:02 +08:00
Nick Peng
a09e63d333 Support IP accept list 2019-12-15 01:27:01 +08:00
24 changed files with 374 additions and 125 deletions

View File

@@ -560,16 +560,17 @@ https://github.com/pymumu/smartdns/releases
|audit-size|审计大小|128K|数字+K,M,G|audit-size 128K
|audit-num|审计归档个数|2|数字|audit-num 2
|conf-file|附加配置文件|无|文件路径|conf-file /etc/smartdns/smartdns.more.conf
|server|上游UDP DNS|无|可重复<br>`[ip][:port]`服务器IP端口可选。<br>`[-blacklist-ip]`blacklist-ip参数指定使用blacklist-ip配置IP过滤结果。<br>`[-group [group] ...]`DNS服务器所属组比如office, foreign和nameserver配套使用。<br>`[-exclude-default-group]`将DNS服务器从默认组中排除| server 8.8.8.8:53 -blacklist-ip -group g1
|server-tcp|上游TCP DNS|无|可重复<br>`[ip][:port]`服务器IP端口可选。<br>`[-blacklist-ip]`blacklist-ip参数指定使用blacklist-ip配置IP过滤结果。<br>`[-group [group] ...]`DNS服务器所属组比如office, foreign和nameserver配套使用。<br>`[-exclude-default-group]`将DNS服务器从默认组中排除| server-tcp 8.8.8.8:53
|server-tls|上游TLS DNS|无|可重复<br>`[ip][:port]`服务器IP端口可选。<br>`[-spki-pin [sha256-pin]]`: TLS合法性校验SPKI值base64编码的sha256 SPKI pin值<br>`[host-name]`TLS SNI名称<br>`[-blacklist-ip]`blacklist-ip参数指定使用blacklist-ip配置IP过滤结果。<br>`[-group [group] ...]`DNS服务器所属组比如office, foreign和nameserver配套使用。<br>`[-exclude-default-group]`将DNS服务器从默认组中排除| server-tls 8.8.8.8:853
|server-https|上游HTTPS DNS|无|可重复<br>`https://[host][:port]/path`服务器IP端口可选。<br>`[-spki-pin [sha256-pin]]`: TLS合法性校验SPKI值base64编码的sha256 SPKI pin值<br>`[host-name]`TLS SNI名称<br>`[http-host]`http协议头主机名<br>`[-blacklist-ip]`blacklist-ip参数指定使用blacklist-ip配置IP过滤结果。<br>`[-group [group] ...]`DNS服务器所属组比如office, foreign和nameserver配套使用。<br>`[-exclude-default-group]`将DNS服务器从默认组中排除| server-https https://cloudflare-dns.com/dns-query
|server|上游UDP DNS|无|可重复<br>`[ip][:port]`服务器IP端口可选。<br>`[-blacklist-ip]`blacklist-ip参数指定使用blacklist-ip配置IP过滤结果。<br>`[-whitelist-ip]`whitelist-ip参数指定仅接受whitelist-ip中配置IP范围。<br>`[-group [group] ...]`DNS服务器所属组比如office, foreign和nameserver配套使用。<br>`[-exclude-default-group]`将DNS服务器从默认组中排除| server 8.8.8.8:53 -blacklist-ip -group g1
|server-tcp|上游TCP DNS|无|可重复<br>`[ip][:port]`服务器IP端口可选。<br>`[-blacklist-ip]`blacklist-ip参数指定使用blacklist-ip配置IP过滤结果。<br>`[-whitelist-ip]`whitelist-ip参数指定仅接受whitelist-ip中配置IP范围。<br>`[-group [group] ...]`DNS服务器所属组比如office, foreign和nameserver配套使用。<br>`[-exclude-default-group]`将DNS服务器从默认组中排除| server-tcp 8.8.8.8:53
|server-tls|上游TLS DNS|无|可重复<br>`[ip][:port]`服务器IP端口可选。<br>`[-spki-pin [sha256-pin]]`: TLS合法性校验SPKI值base64编码的sha256 SPKI pin值<br>`[-host-name]`TLS SNI名称<br>`[-blacklist-ip]`blacklist-ip参数指定使用blacklist-ip配置IP过滤结果。<br>`[-whitelist-ip]`whitelist-ip参数指定仅接受whitelist-ip中配置IP范围。<br>`[-group [group] ...]`DNS服务器所属组比如office, foreign和nameserver配套使用。<br>`[-exclude-default-group]`将DNS服务器从默认组中排除| server-tls 8.8.8.8:853
|server-https|上游HTTPS DNS|无|可重复<br>`https://[host][:port]/path`服务器IP端口可选。<br>`[-spki-pin [sha256-pin]]`: TLS合法性校验SPKI值base64编码的sha256 SPKI pin值<br>`[-host-name]`TLS SNI名称<br>`[-http-host]`http协议头主机名<br>`[-blacklist-ip]`blacklist-ip参数指定使用blacklist-ip配置IP过滤结果。<br>`[-whitelist-ip]`whitelist-ip参数指定仅接受whitelist-ip中配置IP范围。<br>`[-group [group] ...]`DNS服务器所属组比如office, foreign和nameserver配套使用。<br>`[-exclude-default-group]`将DNS服务器从默认组中排除| server-https https://cloudflare-dns.com/dns-query
|address|指定域名IP地址|无|address /domain/[ip\|-\|-4\|-6\|#\|#4\|#6] <br>`-`表示忽略 <br>`#`表示返回SOA <br>`4`表示IPV4 <br>`6`表示IPV6| address /www.example.com/1.2.3.4
|nameserver|指定域名使用server组解析|无|nameserver /domain/[group\|-], `group`为组名,`-`表示忽略此规则配套server中的`-group`参数使用| nameserver /www.example.com/office
|ipset|域名IPSET|None|ipset /domain/[ipset\|-], `-`表示忽略|ipset /www.example.com/pass
|ipset-timeout|设置IPSET超时功能启用|auto|[yes]|ipset-timeout yes
|bogus-nxdomain|假冒IP地址过滤|无|[ip/subnet],可重复| bogus-nxdomain 1.2.3.4/16
|ignore-ip|忽略IP地址|无|[ip/subnet],可重复| ignore-ip 1.2.3.4/16
|whitelist-ip|白名单IP地址|无|[ip/subnet],可重复| whitelist-ip 1.2.3.4/16
|blacklist-ip|黑名单IP地址|无|[ip/subnet],可重复| blacklist-ip 1.2.3.4/16
|force-AAAA-SOA|强制AAAA地址返回SOA|no|[yes\|no]|force-AAAA-SOA yes
|prefetch-domain|域名预先获取功能|no|[yes\|no]|prefetch-domain yes

View File

@@ -555,16 +555,17 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use
|audit-size|audit log size|128K|number+K,M,G|audit-size 128K
|audit-num|archived audit log number|2|Integer|audit-num 2
|conf-file|additional conf file|None|File path|conf-file /etc/smartdns/smartdns.more.conf
|server|Upstream UDP DNS server|None|Repeatable <br>`[ip][:port]`: Server IP, port optional. <br>`[-blacklist-ip]`: The "-blacklist-ip" parameter is to filtering IPs which is configured by "blacklist-ip". <br>`[-group [group] ...]`: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>`[-exclude-default-group]`: Exclude DNS servers from the default group| server 8.8.8.8:53 -blacklist-ip
|server-tcp|Upstream TCP DNS server|None|Repeatable <br>`[ip][:port]`: Server IP, port optional. <br>`[-blacklist-ip]`: The "-blacklist-ip" parameter is to filtering IPs which is configured by "blacklist-ip". <br>`[-group [group] ...]`: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>`[-exclude-default-group]`: Exclude DNS servers from the default group| server-tcp 8.8.8.8:53
|server-tls|Upstream TLS DNS server|None|Repeatable <br>`[ip][:port]`: Server IP, port optional. <br>`[-spki-pin [sha256-pin]]`: TLS verify SPKI value, a base64 encoded SHA256 hash<br>`[host-name]`:TLS Server name<br>`[-blacklist-ip]`: The "-blacklist-ip" parameter is to filtering IPs which is configured by "blacklist-ip". <br>`[-group [group] ...]`: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>`[-exclude-default-group]`: Exclude DNS servers from the default group| server-tls 8.8.8.8:853
|server-https|Upstream HTTPS DNS server|None|Repeatable <br>`https://[host][:port]/path`: Server IP, port optional. <br>`[-spki-pin [sha256-pin]]`: TLS verify SPKI value, a base64 encoded SHA256 hash<br>`[host-name]`:TLS Server name<br>`[http-host]`http header host<br>`[-blacklist-ip]`: The "-blacklist-ip" parameter is to filtering IPs which is configured by "blacklist-ip". <br>`[-group [group] ...]`: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>`[-exclude-default-group]`: Exclude DNS servers from the default group| server-https https://cloudflare-dns.com/dns-query
|server|Upstream UDP DNS server|None|Repeatable <br>`[ip][:port]`: Server IP, port optional. <br>`[-blacklist-ip]`: The "-blacklist-ip" parameter is to filtering IPs which is configured by "blacklist-ip". <br>`[-whitelist-ip]`: whitelist-ip parameter specifies that only the IP range configured in whitelist-ip is accepted. <br>`[-group [group] ...]`: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>`[-exclude-default-group]`: Exclude DNS servers from the default group| server 8.8.8.8:53 -blacklist-ip
|server-tcp|Upstream TCP DNS server|None|Repeatable <br>`[ip][:port]`: Server IP, port optional. <br>`[-blacklist-ip]`: The "-blacklist-ip" parameter is to filtering IPs which is configured by "blacklist-ip". <br>`[-whitelist-ip]`: whitelist-ip parameter specifies that only the IP range configured in whitelist-ip is accepted. <br>`[-group [group] ...]`: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>`[-exclude-default-group]`: Exclude DNS servers from the default group| server-tcp 8.8.8.8:53
|server-tls|Upstream TLS DNS server|None|Repeatable <br>`[ip][:port]`: Server IP, port optional. <br>`[-spki-pin [sha256-pin]]`: TLS verify SPKI value, a base64 encoded SHA256 hash<br>`[-host-name]`:TLS Server name. <br>`[-blacklist-ip]`: The "-blacklist-ip" parameter is to filtering IPs which is configured by "blacklist-ip". <br>`[-whitelist-ip]`: whitelist-ip parameter specifies that only the IP range configured in whitelist-ip is accepted. <br>`[-group [group] ...]`: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>`[-exclude-default-group]`: Exclude DNS servers from the default group| server-tls 8.8.8.8:853
|server-https|Upstream HTTPS DNS server|None|Repeatable <br>`https://[host][:port]/path`: Server IP, port optional. <br>`[-spki-pin [sha256-pin]]`: TLS verify SPKI value, a base64 encoded SHA256 hash<br>`[-host-name]`:TLS Server name<br>`[-http-host]`http header host. <br>`[-blacklist-ip]`: The "-blacklist-ip" parameter is to filtering IPs which is configured by "blacklist-ip". <br>`[-whitelist-ip]`: whitelist-ip parameter specifies that only the IP range configured in whitelist-ip is accepted. <br>`[-group [group] ...]`: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>`[-exclude-default-group]`: Exclude DNS servers from the default group| server-https https://cloudflare-dns.com/dns-query
|address|Domain IP address|None|address /domain/[ip\|-\|-4\|-6\|#\|#4\|#6], `-` for ignore, `#` for return SOA, `4` for IPV4, `6` for IPV6| address /www.example.com/1.2.3.4
|nameserver|To query domain with specific server group|None|nameserver /domain/[group\|-], `group` is the group name, `-` means ignore this rule, use the `-group` parameter in the related server|nameserver /www.example.com/office
|ipset|Domain IPSet|None|ipset /domain/[ipset\|-], `-` for ignore|ipset /www.example.com/pass
|ipset-timeout|ipset timeout enable|auto|[yes]|ipset-timeout yes
|bogus-nxdomain|bogus IP address|None|[IP/subnet], Repeatable| bogus-nxdomain 1.2.3.4/16
|ignore-ip|ignore ip address|None|[ip/subnet], Repeatable| ignore-ip 1.2.3.4/16
|whitelist-ip|ip whitelist|None|[ip/subnet], RepeatableWhen the filtering server responds IPs in the IP whitelist, only result in whitelist will be accepted| whitelist-ip 1.2.3.4/16
|blacklist-ip|ip blacklist|None|[ip/subnet], RepeatableWhen the filtering server responds IPs in the IP blacklist, The result will be discarded directly| blacklist-ip 1.2.3.4/16
|force-AAAA-SOA|force AAAA query return SOA|no|[yes\|no]|force-AAAA-SOA yes
|prefetch-domain|domain prefetch feature|no|[yes\|no]|prefetch-domain yes

View File

@@ -36,6 +36,9 @@ cache-size 512
# List of IPs that will be filtered when nameserver is configured -blacklist-ip parameter
# blacklist-ip [ip/subnet]
# List of IPs that will be accepted when nameserver is configured -whitelist-ip parameter
# whitelist-ip [ip/subnet]
# List of IPs that will be ignored
# ignore-ip [ip/subnet]
@@ -80,30 +83,31 @@ log-level info
# audit-num 2
# remote udp dns server list
# server [IP]:[PORT] [-blacklist-ip] [-check-edns] [-group [group] ...] [-exclude-default-group]
# server [IP]:[PORT] [-blacklist-ip] [-whitelist-ip] [-check-edns] [-group [group] ...] [-exclude-default-group]
# default port is 53
# -blacklist-ip: filter result with blacklist ip
# -whitelist-ip: filter result whth whitelist ip, result in whitelist-ip will be accepted.
# -check-edns: result must exist edns RR, or discard result.
# -group [group]: set server to group, use with nameserver /domain/group.
# -exclude-default-group: exclude this server from default group.
# server 8.8.8.8 -blacklist-ip -check-edns -group g1 -group g2
# remote tcp dns server list
# server-tcp [IP]:[PORT] [-blacklist-ip] [-group [group] ...] [-exclude-default-group]
# server-tcp [IP]:[PORT] [-blacklist-ip] [-whitelist-ip] [-group [group] ...] [-exclude-default-group]
# default port is 53
# server-tcp 8.8.8.8
# remote tls dns server list
# server-tls [IP]:[PORT] [-blacklist-ip] [-spki-pin [sha256-pin]] [-group [group] ...] [-exclude-default-group]
# server-tls [IP]:[PORT] [-blacklist-ip] [-whitelist-ip] [-spki-pin [sha256-pin]] [-group [group] ...] [-exclude-default-group]
# -spki-pin: TLS spki pin to verify.
# Get SKPI with this command:
# Get SPKI with this command:
# echo | openssl s_client -connect '[ip]:853' | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
# default port is 853
# server-tls 8.8.8.8
# server-tls 1.0.0.1
# remote https dns server list
# server-https https://[host]:[port]/path [-blacklist-ip] [-spki-pin [sha256-pin]] [-group [group] ...] [-exclude-default-group]
# server-https https://[host]:[port]/path [-blacklist-ip] [-whitelist-ip] [-spki-pin [sha256-pin]] [-group [group] ...] [-exclude-default-group]
# -spki-pin: TLS spki pin to verify.
# default port is 443
# server-https https://cloudflare-dns.com/dns-query
@@ -126,4 +130,3 @@ log-level info
# ipset /domain/[ipset|-]
# ipset /www.example.com/block, set ipset with ipset name of block
# ipset /www.example.com/-, ignore this domain

View File

@@ -39,14 +39,14 @@ build()
cp $SMARTDNS_DIR/src/smartdns $ROOT/usr/sbin
chmod +x $ROOT/usr/sbin/smartdns
dpkg -b $ROOT $OUTPUTDIR/smartdns.$VER.$ARCH.deb
dpkg -b $ROOT $OUTPUTDIR/smartdns.$VER.$FILEARCH.deb
rm -fr $ROOT/
}
main()
{
OPTS=`getopt -o o:h --long arch:,ver: \
OPTS=`getopt -o o:h --long arch:,ver:,filearch: \
-n "" -- "$@"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
@@ -59,6 +59,9 @@ main()
--arch)
ARCH="$2"
shift 2;;
--filearch)
FILEARCH="$2"
shift 2;;
--ver)
VER="$2"
shift 2;;
@@ -79,6 +82,10 @@ main()
return 1;
fi
if [ -z "$FILEARCH" ]; then
FILEARCH=$ARCH
fi
if [ -z "$OUTPUTDIR" ]; then
OUTPUTDIR=$CURR_DIR;
fi

View File

@@ -61,14 +61,14 @@ build()
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
tar zcf $OUTPUTDIR/luci-app-smartdns.$VER.$FILEARCH.ipk control.tar.gz data.tar.gz debian-binary
rm -fr $ROOT/
}
main()
{
OPTS=`getopt -o o:h --long arch:,ver: \
OPTS=`getopt -o o:h --long arch:,ver:,filearch: \
-n "" -- "$@"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
@@ -81,6 +81,9 @@ main()
--arch)
ARCH="$2"
shift 2;;
--filearch)
FILEARCH="$2"
shift 2;;
--ver)
VER="$2"
shift 2;;
@@ -101,6 +104,10 @@ main()
return 1;
fi
if [ -z "$FILEARCH" ]; then
FILEARCH=$ARCH
fi
if [ -z "$OUTPUTDIR" ]; then
OUTPUTDIR=$CURR_DIR;
fi

View File

@@ -126,6 +126,30 @@ conf_append()
echo "$1 $2" >> $SMARTDNS_CONF_TMP
}
get_tz()
{
SET_TZ=""
if [ -e "/etc/localtime" ]; then
return
fi
for tzfile in /etc/TZ /var/etc/TZ
do
if [ ! -e "$tzfile" ]; then
continue
fi
tz="`cat $tzfile 2>/dev/null`"
done
if [ -z "$tz" ]; then
return
fi
SET_TZ=$tz
}
load_server()
{
local section="$1"
@@ -336,6 +360,11 @@ load_service() {
procd_set_param limits core="unlimited"
fi
get_tz
if [ ! -z "$SET_TZ" ]; then
procd_set_param env TZ="$SET_TZ"
fi
procd_set_param command /usr/sbin/smartdns -f -c $SMARTDNS_CONF $args
if [ "$RESPAWN" = "1" ]; then
procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}

View File

@@ -55,13 +55,13 @@ build()
cd $ROOT
tar zcf $ROOT/data.tar.gz -C root --owner=0 --group=0 .
tar zcf $OUTPUTDIR/smartdns.$VER.$ARCH.ipk --owner=0 --group=0 control.tar.gz data.tar.gz debian-binary
tar zcf $OUTPUTDIR/smartdns.$VER.$FILEARCH.ipk --owner=0 --group=0 control.tar.gz data.tar.gz debian-binary
rm -fr $ROOT/
}
main()
{
OPTS=`getopt -o o:h --long arch:,ver: \
OPTS=`getopt -o o:h --long arch:,ver:,filearch: \
-n "" -- "$@"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
@@ -74,6 +74,9 @@ main()
--arch)
ARCH="$2"
shift 2;;
--filearch)
FILEARCH="$2"
shift 2;;
--ver)
VER="$2"
shift 2;;
@@ -94,6 +97,10 @@ main()
return 1;
fi
if [ -z "$FILEARCH" ]; then
FILEARCH=$ARCH
fi
if [ -z "$OUTPUTDIR" ]; then
OUTPUTDIR=$CURR_DIR;
fi

View File

@@ -2,8 +2,8 @@
SMARTDNS_BIN=/opt/usr/sbin/smartdns
SMARTDNS_CONF=/opt/etc/smartdns/smartdns.conf
DNSMASQ_CONF=/etc/dnsmasq.conf
SMARTDNS_PID="/var/run/smartdns.pid"
DNSMASQ_CONF="/etc/dnsmasq.conf /var/etc/dnsmasq.conf /etc/storage/dnsmasq/dnsmasq.conf"
SMARTDNS_PID=/var/run/smartdns.pid
SMARTDNS_PORT=535
SMARTDNS_OPT=/opt/etc/smartdns/smartdns-opt.conf
# workmode
@@ -54,7 +54,13 @@ restart_dnsmasq()
{
CMD="`ps | grep " dnsmasq" | grep -v grep 2>/dev/null`"
if [ -z "$CMD" ]; then
CMD="`ps ax | grep dnsmasq | grep -v grep 2>/dev/null`"
CMD="`ps | grep "/usr/sbin/dnsmasq" | grep -v grep 2>/dev/null`"
if [ -z "$CMD" ]; then
CMD="`ps ax | grep " dnsmasq" | grep -v grep 2>/dev/null`"
if [ -z "$CMD" ]; then
CMD="`ps ax | grep /usr/sbin/dnsmasq | grep -v grep 2>/dev/null`"
fi
fi
fi
if [ -z "$CMD" ]; then
@@ -77,6 +83,7 @@ restart_dnsmasq()
get_server_ip()
{
CONF_FILE=$1
IPS="`ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F: '{print $2}'`"
LOCAL_SERVER_IP=""
for IP in $IPS
@@ -85,9 +92,9 @@ get_server_ip()
while [ $N -gt 0 ]
do
ADDR=`echo $IP | awk -F. "{for(i=1;i<=$N;i++)printf \\$i\".\"}"`
grep "dhcp-range=" $DNSMASQ_CONF | grep $ADDR >/dev/null 2>&1
grep "dhcp-range=" $CONF_FILE | grep $ADDR >/dev/null 2>&1
if [ $? -eq 0 ]; then
SERVER_TAG="`grep "^dhcp-range *=" $DNSMASQ_CONF | grep $ADDR | awk -F= '{print $2}' | awk -F, '{print $1}'`"
SERVER_TAG="`grep "^dhcp-range *=" $CONF_FILE | grep $ADDR | awk -F= '{print $2}' | awk -F, '{print $1}'`"
LOCAL_SERVER_IP="$IP"
return 0
fi
@@ -98,53 +105,82 @@ get_server_ip()
return 1
}
set_dnsmasq()
set_dnsmasq_conf()
{
local RESTART_DNSMASQ=0
local LOCAL_SERVER_IP=""
local SERVER_TAG=""
get_server_ip
local CONF_FILE=$1
get_server_ip $CONF_FILE
if [ "$LOCAL_SERVER_IP" ] && [ "$SERVER_TAG" ]; then
grep "dhcp-option *=" $DNSMASQ_CONF | grep "$SERVER_TAG,6,$LOCAL_SERVER_IP" > /dev/null 2>&1
grep "dhcp-option *=" $CONF_FILE | grep "$SERVER_TAG,6,$LOCAL_SERVER_IP" > /dev/null 2>&1
if [ $? -ne 0 ]; then
sed -i "/^dhcp-option *=$SERVER_TAG,6,/d" $DNSMASQ_CONF
echo "dhcp-option=$SERVER_TAG,6,$LOCAL_SERVER_IP" >> $DNSMASQ_CONF
sed -i "/^dhcp-option *=$SERVER_TAG,6,/d" $CONF_FILE
echo "dhcp-option=$SERVER_TAG,6,$LOCAL_SERVER_IP" >> $CONF_FILE
RESTART_DNSMASQ=1
fi
fi
grep "^port *=0" $DNSMASQ_CONF > /dev/null 2>&1
grep "^port *=0" $CONF_FILE > /dev/null 2>&1
if [ $? -ne 0 ]; then
sed -i "/^port *=/d" $DNSMASQ_CONF
echo "port=0" >> $DNSMASQ_CONF
sed -i "/^port *=/d" $CONF_FILE
echo "port=0" >> $CONF_FILE
RESTART_DNSMASQ=1
fi
}
set_dnsmasq()
{
local RESTART_DNSMASQ=0
for conf in $DNSMASQ_CONF
do
if [ ! -e "$conf" ]; then
continue
fi
set_dnsmasq_conf $conf
done
if [ $RESTART_DNSMASQ -ne 0 ]; then
restart_dnsmasq
fi
}
clear_dnsmasq_conf()
{
local LOCAL_SERVER_IP=""
local SERVER_TAG=""
local CONF_FILE=$1
get_server_ip $CONF_FILE
if [ "$LOCAL_SERVER_IP" ] && [ "$SERVER_TAG" ]; then
grep "dhcp-option *=" $CONF_FILE | grep "$SERVER_TAG,6,$LOCAL_SERVER_IP" > /dev/null 2>&1
if [ $? -eq 0 ]; then
sed -i "/^dhcp-option *=$SERVER_TAG,6,/d" $CONF_FILE
RESTART_DNSMASQ=1
fi
fi
grep "^port *=" $CONF_FILE > /dev/null 2>&1
if [ $? -eq 0 ]; then
sed -i "/^port *=/d" $CONF_FILE
RESTART_DNSMASQ=1
fi
}
clear_dnsmasq()
{
local RESTART_DNSMASQ=0
local LOCAL_SERVER_IP=""
local SERVER_TAG=""
get_server_ip
if [ "$LOCAL_SERVER_IP" ] && [ "$SERVER_TAG" ]; then
grep "dhcp-option *=" $DNSMASQ_CONF | grep "$SERVER_TAG,6,$LOCAL_SERVER_IP" > /dev/null 2>&1
if [ $? -eq 0 ]; then
sed -i "/^dhcp-option *=$SERVER_TAG,6,/d" $DNSMASQ_CONF
RESTART_DNSMASQ=1
fi
fi
grep "^port *=" $DNSMASQ_CONF > /dev/null 2>&1
if [ $? -eq 0 ]; then
sed -i "/^port *=/d" $DNSMASQ_CONF
RESTART_DNSMASQ=1
fi
for conf in $DNSMASQ_CONF
do
if [ ! -e "$conf" ]; then
continue
fi
clear_dnsmasq_conf $conf
done
if [ $RESTART_DNSMASQ -ne 0 ]; then
restart_dnsmasq
@@ -198,6 +234,28 @@ clear_rule()
fi
}
get_tz()
{
if [ -e "/etc/localtime" ]; then
return
fi
for tzfile in /etc/TZ /var/etc/TZ
do
if [ ! -e "$tzfile" ]; then
continue
fi
tz="`cat $tzfile 2>/dev/null`"
done
if [ -z "$tz" ]; then
return
fi
export TZ=$tz
}
case "$1" in
start)
set_rule
@@ -206,6 +264,7 @@ case "$1" in
fi
set_smartdns_port
get_tz
$SMARTDNS_BIN -c $SMARTDNS_CONF -p $SMARTDNS_PID
if [ $? -ne 0 ]; then
clear_rule

View File

@@ -44,13 +44,13 @@ build()
cd $ROOT
tar zcf data.tar.gz --owner=0 --group=0 opt
tar zcf $OUTPUTDIR/smartdns.$VER.$ARCH.ipk --owner=0 --group=0 control.tar.gz data.tar.gz debian-binary
tar zcf $OUTPUTDIR/smartdns.$VER.$FILEARCH.ipk --owner=0 --group=0 control.tar.gz data.tar.gz debian-binary
rm -fr $ROOT/
}
main()
{
OPTS=`getopt -o o:h --long arch:,ver: \
OPTS=`getopt -o o:h --long arch:,ver:,filearch: \
-n "" -- "$@"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
@@ -63,6 +63,9 @@ main()
--arch)
ARCH="$2"
shift 2;;
--filearch)
FILEARCH="$2"
shift 2;;
--ver)
VER="$2"
shift 2;;
@@ -83,6 +86,10 @@ main()
return 1;
fi
if [ -z "$FILEARCH" ]; then
FILEARCH=$ARCH
fi
if [ -z "$OUTPUTDIR" ]; then
OUTPUTDIR=$CURR_DIR;
fi

View File

@@ -5,9 +5,16 @@ OBJS=smartdns.o fast_ping.o dns_client.o dns_server.o dns.o util.o tlog.o dns_co
CFLAGS +=-O2 -g -Wall -Wstrict-prototypes -fno-omit-frame-pointer -Wstrict-aliasing
CFLAGS +=-Iinclude
CFLAGS += -DBASE_FILE_NAME=\"$(notdir $<)\"
ifdef VER
CFLAGS += -DSMARTDNS_VERION=\"$(VER)\"
endif
CXXFLAGS=-O2 -g -Wall -std=c++11
CXXFLAGS +=-Iinclude
LDFLAGS += -lpthread -lssl -lcrypto
ifeq ($(STATIC), yes)
LDFLAGS += -lssl -lcrypto -Wl,--whole-archive -lpthread -Wl,--no-whole-archive -ldl -static
else
LDFLAGS += -lssl -lcrypto -lpthread
endif
.PHONY: all

View File

@@ -19,6 +19,7 @@
#define _GNU_SOURCE
#include "dns.h"
#include "tlog.h"
#include "stringutil.h"
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
@@ -612,9 +613,9 @@ int dns_add_SOA(struct dns_packet *packet, dns_rr_type type, char *domain, int t
unsigned char data[sizeof(*soa)];
unsigned char *ptr = data;
int len = 0;
strncpy((char *)ptr, soa->mname, DNS_MAX_CNAME_LEN - 1);
safe_strncpy((char *)ptr, soa->mname, DNS_MAX_CNAME_LEN);
ptr += strnlen(soa->mname, DNS_MAX_CNAME_LEN - 1) + 1;
strncpy((char *)ptr, soa->rname, DNS_MAX_CNAME_LEN - 1);
safe_strncpy((char *)ptr, soa->rname, DNS_MAX_CNAME_LEN);
ptr += strnlen(soa->rname, DNS_MAX_CNAME_LEN - 1) + 1;
*((unsigned int *)ptr) = soa->serial;
ptr += 4;
@@ -650,12 +651,12 @@ int dns_get_SOA(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, struct
return -1;
}
strncpy(soa->mname, (char *)ptr, DNS_MAX_CNAME_LEN - 1);
safe_strncpy(soa->mname, (char *)ptr, DNS_MAX_CNAME_LEN - 1);
ptr += strnlen(soa->mname, DNS_MAX_CNAME_LEN - 1) + 1;
if (ptr - data >= len) {
return -1;
}
strncpy(soa->rname, (char *)ptr, DNS_MAX_CNAME_LEN - 1);
safe_strncpy(soa->rname, (char *)ptr, DNS_MAX_CNAME_LEN - 1);
ptr += strnlen(soa->rname, DNS_MAX_CNAME_LEN - 1) + 1;
if (ptr - data + 20 > len) {
return -1;

View File

@@ -1,5 +1,6 @@
#include "dns_cache.h"
#include "tlog.h"
#include "stringutil.h"
#include <pthread.h>
struct dns_cache_head {
@@ -110,7 +111,7 @@ int dns_cache_replace(char *domain, char *cname, int cname_ttl, int ttl, dns_typ
}
if (cname) {
strncpy(dns_cache->cname, cname, DNS_MAX_CNAME_LEN);
safe_strncpy(dns_cache->cname, cname, DNS_MAX_CNAME_LEN);
dns_cache->cname_ttl = cname_ttl;
}
pthread_mutex_unlock(&dns_cache_head.lock);
@@ -154,7 +155,7 @@ int dns_cache_insert(char *domain, char *cname, int cname_ttl, int ttl, dns_type
key = hash_string(domain);
key = jhash(&qtype, sizeof(qtype), key);
strncpy(dns_cache->domain, domain, DNS_MAX_CNAME_LEN);
safe_strncpy(dns_cache->domain, domain, DNS_MAX_CNAME_LEN);
dns_cache->cname[0] = 0;
dns_cache->qtype = qtype;
dns_cache->ttl = ttl;
@@ -178,7 +179,7 @@ int dns_cache_insert(char *domain, char *cname, int cname_ttl, int ttl, dns_type
}
if (cname) {
strncpy(dns_cache->cname, cname, DNS_MAX_CNAME_LEN);
safe_strncpy(dns_cache->cname, cname, DNS_MAX_CNAME_LEN);
dns_cache->cname_ttl = cname_ttl;
}

View File

@@ -435,7 +435,7 @@ static int _dns_client_add_to_pending_group(char *group_name, char *server_ip, i
goto errout;
}
memset(group, 0, sizeof(*group));
strncpy(group->group_name, group_name, DNS_GROUP_NAME_LEN);
safe_strncpy(group->group_name, group_name, DNS_GROUP_NAME_LEN);
pthread_mutex_lock(&pending_server_mutex);
list_add_tail(&group->list, &pending->group_list);
@@ -547,7 +547,7 @@ int dns_client_add_group(char *group_name)
memset(group, 0, sizeof(*group));
INIT_LIST_HEAD(&group->head);
strncpy(group->group_name, group_name, DNS_GROUP_NAME_LEN);
safe_strncpy(group->group_name, group_name, DNS_GROUP_NAME_LEN);
key = hash_string(group_name);
hash_add(client.group, &group->node, key);
@@ -683,9 +683,9 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
spki_data_len = flag_https->spi_len;
if (flag_https->httphost[0] == 0) {
if (server_host) {
strncpy(flag_https->httphost, server_host, DNS_MAX_CNAME_LEN);
safe_strncpy(flag_https->httphost, server_host, DNS_MAX_CNAME_LEN);
} else {
strncpy(flag_https->httphost, server_ip, DNS_MAX_CNAME_LEN);
safe_strncpy(flag_https->httphost, server_ip, DNS_MAX_CNAME_LEN);
}
}
sock_type = SOCK_STREAM;
@@ -731,7 +731,7 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
}
memset(server_info, 0, sizeof(*server_info));
strncpy(server_info->ip, server_ip, sizeof(server_info->ip));
safe_strncpy(server_info->ip, server_ip, sizeof(server_info->ip));
server_info->port = port;
server_info->ai_family = gai->ai_family;
server_info->ai_addrlen = gai->ai_addrlen;
@@ -752,7 +752,11 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
/* if server type is TLS, create ssl context */
if (server_type == DNS_SERVER_TLS || server_type == DNS_SERVER_HTTPS) {
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
server_info->ssl_ctx = SSL_CTX_new(TLS_client_method());
#else
server_info->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
#endif
if (server_info->ssl_ctx == NULL) {
tlog(TLOG_ERROR, "init ssl failed.");
goto errout;
@@ -915,7 +919,7 @@ static int _dns_client_server_pending(char *server_ip, int port, dns_server_type
}
memset(pending, 0, sizeof(*pending));
strncpy(pending->host, server_ip, DNS_HOSTNAME_LEN);
safe_strncpy(pending->host, server_ip, DNS_HOSTNAME_LEN);
pending->port = port;
pending->type = server_type;
pending->ping_time_v4 = -1;
@@ -2375,7 +2379,7 @@ int dns_client_query(char *domain, int qtype, dns_client_callback callback, void
atomic_set(&query->dns_request_sent, 0);
atomic_set(&query->retry_count, DNS_QUERY_RETRY);
hash_init(query->replied_map);
strncpy(query->domain, domain, DNS_MAX_CNAME_LEN);
safe_strncpy(query->domain, domain, DNS_MAX_CNAME_LEN);
query->user_ptr = user_ptr;
query->callback = callback;
query->qtype = qtype;
@@ -2460,14 +2464,14 @@ static int _dns_client_pending_server_resolve(char *domain, dns_rtcode_t rtcode,
pending->ping_time_v4 = -1;
if (rtcode == DNS_RC_NOERROR) {
pending->ping_time_v4 = ping_time;
strncpy(pending->ipv4, ip, DNS_HOSTNAME_LEN);
safe_strncpy(pending->ipv4, ip, DNS_HOSTNAME_LEN);
}
} else if (addr_type == DNS_T_AAAA) {
pending->has_v6 = 1;
pending->ping_time_v6 = -1;
if (rtcode == DNS_RC_NOERROR) {
pending->ping_time_v6 = ping_time;
strncpy(pending->ipv6, ip, DNS_HOSTNAME_LEN);
safe_strncpy(pending->ipv6, ip, DNS_HOSTNAME_LEN);
}
} else {
return -1;

View File

@@ -20,8 +20,9 @@ typedef enum dns_result_type {
} dns_result_type;
#define DNSSERVER_FLAG_BLACKLIST_IP (0x1 << 0)
#define DNSSERVER_FLAG_CHECK_EDNS (0x1 << 1)
#define DNSSERVER_FLAG_CHECK_TTL (0x1 << 2)
#define DNSSERVER_FLAG_WHITELIST_IP (0x1 << 1)
#define DNSSERVER_FLAG_CHECK_EDNS (0x1 << 2)
#define DNSSERVER_FLAG_CHECK_TTL (0x1 << 3)
int dns_client_init(void);

View File

@@ -9,7 +9,7 @@
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <libgen.h>
#include <libgen.h>
#define DEFAULT_DNS_CACHE_SIZE 512
@@ -90,7 +90,7 @@ static struct dns_server_groups *_dns_conf_get_group(const char *group_name)
}
memset(group, 0, sizeof(*group));
strncpy(group->group_name, group_name, DNS_GROUP_NAME_LEN);
safe_strncpy(group->group_name, group_name, DNS_GROUP_NAME_LEN);
hash_add(dns_group_table.group, &group->node, key);
return group;
@@ -168,10 +168,11 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
/* clang-format off */
static struct option long_options[] = {
{"blacklist-ip", no_argument, NULL, 'b'}, /* filtering with blacklist-ip */
{"whitelist-ip", no_argument, NULL, 'w'}, /* filtering with whitelist-ip */
#ifdef FEATURE_CHECK_EDNS
/* experimental feature */
{"check-edns", no_argument, NULL, 'e'}, /* check edns */
#endif
#endif
{"spki-pin", required_argument, NULL, 'p'}, /* check SPKI pin */
{"host-name", required_argument, NULL, 'h'}, /* host name */
{"http-host", required_argument, NULL, 'H'}, /* http host */
@@ -202,8 +203,8 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
if (parse_uri(ip, NULL, server->server, &port, server->path) != 0) {
return -1;
}
strncpy(server->hostname, server->server, sizeof(server->hostname));
strncpy(server->httphost, server->httphost, sizeof(server->hostname));
safe_strncpy(server->hostname, server->server, sizeof(server->hostname));
safe_strncpy(server->httphost, server->server, sizeof(server->httphost));
if (server->path[0] == 0) {
strcpy(server->path, "/");
}
@@ -232,16 +233,20 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
result_flag |= DNSSERVER_FLAG_BLACKLIST_IP;
break;
}
case 'w': {
result_flag |= DNSSERVER_FLAG_WHITELIST_IP;
break;
}
case 'e': {
result_flag |= DNSSERVER_FLAG_CHECK_EDNS;
break;
}
case 'h': {
strncpy(server->hostname, optarg, DNS_MAX_CNAME_LEN);
safe_strncpy(server->hostname, optarg, DNS_MAX_CNAME_LEN);
break;
}
case 'H': {
strncpy(server->httphost, optarg, DNS_MAX_CNAME_LEN);
safe_strncpy(server->httphost, optarg, DNS_MAX_CNAME_LEN);
break;
}
case 'E': {
@@ -256,7 +261,7 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
break;
}
case 'p': {
strncpy(server->spki, optarg, DNS_MAX_SPKI_LEN);
safe_strncpy(server->spki, optarg, DNS_MAX_SPKI_LEN);
break;
}
default:
@@ -339,7 +344,7 @@ static int _config_domain_rule_add(char *domain, enum domain_rule type, void *ru
tlog(TLOG_ERROR, "domain name %s too long", domain);
goto errout;
}
reverse_string(domain_key, domain, len);
reverse_string(domain_key, domain, len, 1);
domain_key[len] = '.';
len++;
domain_key[len] = 0;
@@ -400,7 +405,7 @@ static int _config_domain_rule_flag_set(char *domain, unsigned int flag)
tlog(TLOG_ERROR, "domain %s too long", domain);
return -1;
}
reverse_string(domain_key, domain, len);
reverse_string(domain_key, domain, len, 1);
domain_key[len] = '.';
len++;
domain_key[len] = 0;
@@ -476,7 +481,7 @@ static const char *_dns_conf_get_ipset(const char *ipsetname)
}
key = hash_string(ipsetname);
strncpy(ipset_name->ipsetname, ipsetname, DNS_MAX_IPSET_NAMELEN);
safe_strncpy(ipset_name->ipsetname, ipsetname, DNS_MAX_IPSET_NAMELEN);
hash_add(dns_ipset_table.ipset, &ipset_name->node, key);
return ipset_name->ipsetname;
@@ -492,7 +497,7 @@ static int _config_ipset(void *data, int argc, char *argv[])
{
struct dns_ipset_rule *ipset_rule = NULL;
char domain[DNS_MAX_CONF_CNAME_LEN];
char ipsetname[DNS_MAX_CONF_CNAME_LEN];
char ipsetname[DNS_MAX_IPSET_NAMELEN];
const char *ipset = NULL;
char *begin = NULL;
char *end = NULL;
@@ -539,7 +544,7 @@ static int _config_ipset(void *data, int argc, char *argv[])
/* Process domain option */
if (strncmp(end + 1, "-", sizeof("-")) != 0) {
/* new ipset domain */
strncpy(ipsetname, end + 1, DNS_MAX_IPSET_NAMELEN);
safe_strncpy(ipsetname, end + 1, DNS_MAX_IPSET_NAMELEN);
ipset = _dns_conf_get_ipset(ipsetname);
if (ipset == NULL) {
goto errout;
@@ -794,7 +799,7 @@ static int _config_nameserver(void *data, int argc, char *argv[])
}
if (strncmp(end + 1, "-", sizeof("-")) != 0) {
strncpy(group_name, end + 1, DNS_GROUP_NAME_LEN);
safe_strncpy(group_name, end + 1, DNS_GROUP_NAME_LEN);
group = _dns_conf_get_group_name(group_name);
if (group == NULL) {
goto errout;
@@ -881,11 +886,17 @@ static int _config_iplist_rule(char *subnet, enum address_rule rule)
case ADDRESS_RULE_BLACKLIST:
ip_rule->blacklist = 1;
break;
case ADDRESS_RULE_WHITELIST:
ip_rule->whitelist = 1;
break;
case ADDRESS_RULE_BOGUS:
ip_rule->bogus = 1;
break;
case ADDRESS_RULE_IP_IGNORE:
ip_rule->ip_ignore = 1;
break;
default:
return -1;
}
return 0;
@@ -918,6 +929,15 @@ static int _conf_ip_ignore(void *data, int argc, char *argv[])
return _config_iplist_rule(argv[1], ADDRESS_RULE_IP_IGNORE);
}
static int _conf_whitelist_ip(void *data, int argc, char *argv[])
{
if (argc <= 1) {
return -1;
}
return _config_iplist_rule(argv[1], ADDRESS_RULE_WHITELIST);
}
static int _conf_edns_client_subnet(void *data, int argc, char *argv[])
{
char *slash = NULL;
@@ -958,7 +978,7 @@ static int _conf_edns_client_subnet(void *data, int argc, char *argv[])
goto errout;
}
strncpy(ecs->ip, value, DNS_MAX_IPLEN);
safe_strncpy(ecs->ip, value, DNS_MAX_IPLEN);
ecs->subnet = subnet;
ecs->enable = 1;
@@ -1022,6 +1042,7 @@ static struct config_item _config_item[] = {
CONF_INT("rr-ttl-max", &dns_conf_rr_ttl_max, 0, CONF_INT_MAX),
CONF_YESNO("force-AAAA-SOA", &dns_conf_force_AAAA_SOA),
CONF_CUSTOM("blacklist-ip", _config_blacklist_ip, NULL),
CONF_CUSTOM("whitelist-ip", _conf_whitelist_ip, NULL),
CONF_CUSTOM("bogus-nxdomain", _conf_bogus_nxdomain, NULL),
CONF_CUSTOM("ignore-ip", _conf_ip_ignore, NULL),
CONF_CUSTOM("edns-client-subnet", _conf_edns_client_subnet, NULL),
@@ -1051,11 +1072,13 @@ int config_addtional_file(void *data, int argc, char *argv[])
char file_path_dir[DNS_MAX_PATH];
if (conf_file[0] != '/') {
strncpy(file_path_dir, conf_get_conf_file(), DNS_MAX_PATH);
safe_strncpy(file_path_dir, conf_get_conf_file(), DNS_MAX_PATH);
dirname(file_path_dir);
snprintf(file_path, DNS_MAX_PATH, "%s/%s", file_path_dir, conf_file);
if (snprintf(file_path, DNS_MAX_PATH, "%s/%s", file_path_dir, conf_file) < 0) {
return -1;
}
} else {
strncpy(file_path, conf_file, DNS_MAX_PATH);
safe_strncpy(file_path, conf_file, DNS_MAX_PATH);
}
if (access(file_path, R_OK) != 0) {

View File

@@ -114,12 +114,14 @@ struct dns_bogus_ip_address {
enum address_rule {
ADDRESS_RULE_BLACKLIST = 1,
ADDRESS_RULE_BOGUS = 2,
ADDRESS_RULE_IP_IGNORE = 3,
ADDRESS_RULE_WHITELIST = 2,
ADDRESS_RULE_BOGUS = 3,
ADDRESS_RULE_IP_IGNORE = 4,
};
struct dns_ip_address_rule {
unsigned int blacklist : 1;
unsigned int whitelist : 1;
unsigned int bogus : 1;
unsigned int ip_ignore : 1;
};

View File

@@ -246,11 +246,11 @@ static int _dns_add_rrs(struct dns_packet *packet, struct dns_request *request)
/* if hostname is (none), return smartdns */
if (strncmp(hostname, "(none)", DNS_MAX_CNAME_LEN) == 0) {
strncpy(hostname, "smartdns", DNS_MAX_CNAME_LEN);
safe_strncpy(hostname, "smartdns", DNS_MAX_CNAME_LEN);
}
} else {
/* return configured server name */
strncpy(hostname, dns_conf_server_name, DNS_MAX_CNAME_LEN);
safe_strncpy(hostname, dns_conf_server_name, DNS_MAX_CNAME_LEN);
}
ret = dns_add_PTR(packet, DNS_RRS_AN, request->domain, 30, hostname);
@@ -471,8 +471,8 @@ static int _dns_server_reply_SOA(int rcode, struct dns_request *request, struct
soa = &request->soa;
strncpy(soa->mname, "a.gtld-servers.net", DNS_MAX_CNAME_LEN);
strncpy(soa->rname, "nstld.verisign-grs.com", DNS_MAX_CNAME_LEN);
safe_strncpy(soa->mname, "a.gtld-servers.net", DNS_MAX_CNAME_LEN);
safe_strncpy(soa->rname, "nstld.verisign-grs.com", DNS_MAX_CNAME_LEN);
soa->serial = 1800;
soa->refresh = 1800;
soa->retry = 900;
@@ -962,11 +962,11 @@ static int _dns_server_ip_rule_check(struct dns_request *request, unsigned char
}
if (node == NULL) {
return -1;
goto rule_not_found;
}
if (node->data == NULL) {
return -1;
goto rule_not_found;
}
/* bogux-nxdomain */
@@ -986,7 +986,17 @@ static int _dns_server_ip_rule_check(struct dns_request *request, unsigned char
if (rule->ip_ignore) {
goto skip;
}
rule_not_found:
if (result_flag & DNSSERVER_FLAG_WHITELIST_IP) {
if (rule == NULL) {
goto skip;
}
if (!rule->whitelist) {
goto skip;
}
}
return -1;
skip:
return -2;
@@ -1185,7 +1195,7 @@ static int _dns_server_process_answer(struct dns_request *request, char *domain,
char cname[128];
dns_get_CNAME(rrs, name, 128, &ttl, cname, 128);
tlog(TLOG_DEBUG, "name:%s ttl: %d cname: %s\n", name, ttl, cname);
strncpy(request->cname, cname, DNS_MAX_CNAME_LEN);
safe_strncpy(request->cname, cname, DNS_MAX_CNAME_LEN);
request->ttl_cname = ttl;
request->has_cname = 1;
} break;
@@ -1365,7 +1375,7 @@ static void _dns_server_log_rule(char *domain, unsigned char *rule_key, int rule
return;
}
reverse_string(rule_name, (char *)rule_key, rule_key_len);
reverse_string(rule_name, (char *)rule_key, rule_key_len, 1);
rule_name[rule_key_len] = 0;
tlog(TLOG_INFO, "RULE-MATCH, domain: %s, rule: %s", domain, rule_name);
}
@@ -1380,7 +1390,7 @@ static struct dns_domain_rule *_dns_server_get_domain_rule(char *domain)
/* reverse domain string */
domain_len = strlen(domain);
reverse_string(domain_key, domain, domain_len);
reverse_string(domain_key, domain, domain_len, 1);
domain_key[domain_len] = '.';
domain_len++;
domain_key[domain_len] = 0;
@@ -1553,7 +1563,7 @@ static int _dns_server_process_cache(struct dns_request *request, struct dns_pac
}
if (dns_cache->cname[0] != 0) {
strncpy(request->cname, dns_cache->cname, DNS_MAX_CNAME_LEN);
safe_strncpy(request->cname, dns_cache->cname, DNS_MAX_CNAME_LEN);
request->has_cname = 1;
request->ttl_cname = dns_cache->cname_ttl;
}
@@ -1786,7 +1796,7 @@ static int _dns_server_prefetch_request(char *domain, dns_type_t qtype)
request->id = 0;
hash_init(request->ip_map);
strncpy(request->domain, domain, DNS_MAX_CNAME_LEN);
safe_strncpy(request->domain, domain, DNS_MAX_CNAME_LEN);
/* lookup domain rule */
request->domain_rule = _dns_server_get_domain_rule(request->domain);
@@ -1858,7 +1868,7 @@ int dns_server_query(char *domain, int qtype, dns_result_callback callback, void
request->id = 0;
hash_init(request->ip_map);
strncpy(request->domain, domain, DNS_MAX_CNAME_LEN);
safe_strncpy(request->domain, domain, DNS_MAX_CNAME_LEN);
/* lookup domain rule */
request->domain_rule = _dns_server_get_domain_rule(request->domain);

View File

@@ -867,7 +867,7 @@ struct ping_host_struct *fast_ping_start(PING_TYPE type, const char *host, int c
}
memset(ping_host, 0, sizeof(*ping_host));
strncpy(ping_host->host, host, PING_MAX_HOSTLEN);
safe_strncpy(ping_host->host, host, PING_MAX_HOSTLEN);
ping_host->fd = -1;
ping_host->timeout = timeout;
ping_host->count = count;

23
src/include/stringutil.h Normal file
View File

@@ -0,0 +1,23 @@
#ifndef _GENERIC_STRING_UITL_H
#define _GENERIC_STRING_UITL_H
#include <stddef.h>
#include <string.h>
static inline char *safe_strncpy(char *dest, const char *src, size_t n)
{
#if __GNUC__ > 7
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-truncation"
#endif
char *ret = strncpy(dest, src, n - 1);
if (n > 0) {
dest[n - 1] = '\0';
}
#if __GNUC__ > 7
#pragma GCC diagnostic pop
#endif
return ret;
}
#endif

0
src/lib/stringutil.c Normal file
View File

View File

@@ -59,7 +59,8 @@ static void _help(void)
" -c [conf] config file.\n"
" -p [pid] pid file path\n"
" -S ignore segment fault signal.\n"
" -v verbose screent.\n"
" -x verbose screen.\n"
" -v dispaly version.\n"
" -h show this help message.\n"
"Online help: http://pymumu.github.io/smartdns\n"
@@ -69,6 +70,21 @@ static void _help(void)
printf("%s", help);
}
static void _show_version(void)
{
char str_ver[256] = {0};
#ifdef SMARTDNS_VERION
const char *ver = SMARTDNS_VERION;
snprintf(str_ver, sizeof(str_ver), "%s", ver);
#else
struct tm tm;
get_compiled_time(&tm);
snprintf(str_ver, sizeof(str_ver), "1.%.4d%.2d%.2d-%.2d%.2d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
tm.tm_min);
#endif
printf("smartdns %s\n", str_ver);
}
static int _smartdns_load_from_resolv(void)
{
FILE *fp = NULL;
@@ -108,7 +124,7 @@ static int _smartdns_load_from_resolv(void)
port = DEFAULT_DNS_PORT;
}
strncpy(dns_conf_servers[dns_conf_server_num].server, ns_ip, DNS_MAX_IPLEN);
safe_strncpy(dns_conf_servers[dns_conf_server_num].server, ns_ip, DNS_MAX_IPLEN);
dns_conf_servers[dns_conf_server_num].port = port;
dns_conf_servers[dns_conf_server_num].type = DNS_SERVER_UDP;
dns_conf_server_num++;
@@ -139,14 +155,14 @@ static int _smartdns_add_servers(void)
case DNS_SERVER_HTTPS: {
struct client_dns_server_flag_https *flag_http = &flags.https;
flag_http->spi_len = dns_client_spki_decode(dns_conf_servers[i].spki, (unsigned char *)flag_http->spki);
strncpy(flag_http->hostname, dns_conf_servers[i].hostname, sizeof(flag_http->hostname));
strncpy(flag_http->path, dns_conf_servers[i].path, sizeof(flag_http->path));
strncpy(flag_http->httphost, dns_conf_servers[i].httphost, sizeof(flag_http->httphost));
safe_strncpy(flag_http->hostname, dns_conf_servers[i].hostname, sizeof(flag_http->hostname));
safe_strncpy(flag_http->path, dns_conf_servers[i].path, sizeof(flag_http->path));
safe_strncpy(flag_http->httphost, dns_conf_servers[i].httphost, sizeof(flag_http->httphost));
} break;
case DNS_SERVER_TLS: {
struct client_dns_server_flag_tls *flag_tls = &flags.tls;
flag_tls->spi_len = dns_client_spki_decode(dns_conf_servers[i].spki, (unsigned char *)flag_tls->spki);
strncpy(flag_tls->hostname, dns_conf_servers[i].hostname, sizeof(flag_tls->hostname));
safe_strncpy(flag_tls->hostname, dns_conf_servers[i].hostname, sizeof(flag_tls->hostname));
} break;
break;
case DNS_SERVER_TCP:
@@ -359,10 +375,10 @@ int main(int argc, char *argv[])
char pid_file[MAX_LINE_LEN];
int signal_ignore = 0;
strncpy(config_file, SMARTDNS_CONF_FILE, MAX_LINE_LEN);
strncpy(pid_file, SMARTDNS_PID_FILE, MAX_LINE_LEN);
safe_strncpy(config_file, SMARTDNS_CONF_FILE, MAX_LINE_LEN);
safe_strncpy(pid_file, SMARTDNS_PID_FILE, MAX_LINE_LEN);
while ((opt = getopt(argc, argv, "fhc:p:Sv")) != -1) {
while ((opt = getopt(argc, argv, "fhc:p:Svx")) != -1) {
switch (opt) {
case 'f':
is_forground = 1;
@@ -376,9 +392,13 @@ int main(int argc, char *argv[])
case 'S':
signal_ignore = 1;
break;
case 'v':
case 'x':
verbose_screen = 1;
break;
case 'v':
_show_version();
return 0;
break;
case 'h':
_help();
return 1;

View File

@@ -141,8 +141,9 @@ static int _tlog_mkdir(const char *path)
}
strncpy(path_c, path, sizeof(path_c) - 1);
len = strnlen(path_c, sizeof(path_c) - 1);
path_c[len] = '/';
path_c[sizeof(path_c) - 1] = 0;
len = strnlen(path_c, sizeof(path_c) - 1);
path_c[len] = '/';
path_c[len + 1] = '\0';
path_end = path_c;
@@ -592,9 +593,10 @@ static int _tlog_get_oldest_callback(const char *path, struct dirent *entry, voi
if (oldestlog->mtime == 0 || oldestlog->mtime > sb.st_mtime) {
oldestlog->mtime = sb.st_mtime;
strncpy(oldestlog->name, entry->d_name, sizeof(oldestlog->name));
return 0;
}
strncpy(oldestlog->name, entry->d_name, sizeof(oldestlog->name) - 1);
oldestlog->name[sizeof(oldestlog->name) - 1] = 0;
return 0;
}
return 0;
}
@@ -1197,12 +1199,17 @@ tlog_log *tlog_open(const char *logfile, int maxlogsize, int maxlogcount, int bl
log->is_exit = 0;
log->multi_log = (multiwrite != 0) ? 1 : 0;
strncpy(log_file, logfile, PATH_MAX);
strncpy(log->logdir, dirname(log_file), sizeof(log->logdir));
strncpy(log_file, logfile, PATH_MAX);
strncpy(log->logname, basename(log_file), sizeof(log->logname));
strncpy(log_file, logfile, PATH_MAX - 1);
log_file[PATH_MAX - 1] = 0;
strncpy(log->logdir, dirname(log_file), sizeof(log->logdir) - 1);
log->logdir[sizeof(log->logdir) - 1] = 0;
log->buff = malloc(log->buffsize);
strncpy(log_file, logfile, PATH_MAX - 1);
log_file[PATH_MAX - 1] = 0;
strncpy(log->logname, basename(log_file), sizeof(log->logname));
log->logname[sizeof(log->logname) - 1] = 0;
log->buff = malloc(log->buffsize);
if (log->buff == NULL) {
fprintf(stderr, "malloc log buffer failed, %s\n", strerror(errno));
goto errout;

View File

@@ -350,7 +350,7 @@ int set_fd_nonblock(int fd, int nonblock)
return 0;
}
char *reverse_string(char *output, char *input, int len)
char *reverse_string(char *output, char *input, int len, int to_lower_case)
{
char *begin = output;
if (len <= 0) {
@@ -361,6 +361,12 @@ char *reverse_string(char *output, char *input, int len)
len--;
while (len >= 0) {
*output = *(input + len);
if (to_lower_case) {
if (*output >= 'A' && *output <= 'Z') {
/* To lower case */
*output = *output + 32;
}
}
output++;
len--;
}
@@ -833,3 +839,22 @@ static int parse_server_name_extension(const char *data, size_t data_len, char *
return -2;
}
void get_compiled_time(struct tm *tm)
{
char s_month[5];
int month, day, year;
int hour, min, sec;
static const char *month_names = "JanFebMarAprMayJunJulAugSepOctNovDec";
sscanf(__DATE__, "%s %d %d", s_month, &day, &year);
month = (strstr(month_names, s_month) - month_names) / 3;
sscanf(__TIME__, "%d:%d:%d", &hour, &min, &sec);
tm->tm_year = year - 1900;
tm->tm_mon = month;
tm->tm_mday = day;
tm->tm_isdst = -1;
tm->tm_hour = hour;
tm->tm_min = min;
tm->tm_sec = sec;
}

View File

@@ -4,6 +4,8 @@
#define SMART_DNS_UTIL_H
#include <netdb.h>
#include <time.h>
#include "stringutil.h"
#define PORT_NOT_DEFINED -1
#define MAX_IP_LEN 64
@@ -22,7 +24,7 @@ int parse_uri(char *value, char *scheme, char *host, int *port, char *path);
int set_fd_nonblock(int fd, int nonblock);
char *reverse_string(char *output, char *input, int len);
char *reverse_string(char *output, char *input, int len, int to_lower_case);
void print_stack(void);
@@ -55,4 +57,6 @@ int create_pid_file(const char *pid_file);
*/
int parse_tls_header(const char *data, size_t data_len, char *hostname, const char **hostname_ptr);
void get_compiled_time(struct tm *tm);
#endif