|
本帖最后由 flippy 于 2018-9-26 15:03 编辑
手上有k2p A2版,刷了openwrt cc 1.7.x版,然后又搞了几个ar71xx的tplink路由,用lean提供的源码编译固件。
然后在使用过程中发现xxxpro的G&F&W模式存在一定问题,刚启动后不能连,需要一段时间才正常,导致有时会误认为该模式不工作。
后来仔细分析了相关源码,发现几个问题:
1. ip路径问题: lede 17.01源码的ip-full,其路径为/usr/sbin/ip,而lean的源码里,ip路径定为/sbin/ip,这导致用17.01源码编译的固件使用下来有问题,简单修改代码,可以自动识别ip命令所在的路径:
if [ -x "/usr/sbin/ip" ];then
IP="/usr/sbin/ip"
elif [ -x "/sbin/ip" ];then
IP="/sbin/ip"
elif [ -x "/usr/bin/ip" ];then
IP="/usr/bin/ip"
else
IP="/bin/ip"
fi
再把代码中用到/usr/bin/ip的地方改为引用$IP变量即可。
2.pdnsd的默认参数:
proc_limit = 2;
procq_limit = 8;
第1个参数是指定并发线程数,第2个是指定等待队列数,查阅了pdnsd的文档,发现proc_limit的官方默认值是40,procq_limit的官方默认值是60,所以我认为这两个参数调的太低了,还是应该调高些,在我的脚本中,改回了40和60的默认值,实测在WR841n上可以正常运行。
3. pdnsd的缓存不生效
系统日志会报: Cache file /var/pdnsd/pdnsd.cache ignored because of incompatible version identifier 这个错误
pdnsd.cache的大小总是4byte
经分析源码,发现pdnsd.cache初始化时应该是8字节,其中前4字节为版本标识符,对应于1.2.9这个版本,其标识符应该是 pd13,后4个字节为十六进制0
代码:
[ -d /var/etc ] || mkdir -p /var/etc
if [ ! -d /var/pdnsd ];then
mkdir -p /var/pdnsd
echo -ne "pd13\000\000\000\000" >/var/pdnsd/pdnsd.cache
chown -R nobody:nogroup /var/pdnsd
fi
4.pdnsd的缓存大小问题
源码中的默认值是: perm_cache = 10240; (10MB)
这对于内存比较小,比如32M或64M的路由器来说,显得过大了,官方默认值是2048(2M),我打算把这个改成自动调整的:
相关代码:
local min_cache_size=512
local ex_cache_size=$(du -k /var/pdnsd/pdnsd.cache 2>/dev/null | awk '{print $1}')
[ -z "$ex_cache_size" ] && ex_cache_size=0
# max cache size set to 1/8 of avaiable disk size
local max_cache_size=$(df -k /var | awk '$4~/^[0-9]+$/ {print int($4/8)}')
local cache_size
let cache_size=max_cache_size+ex_cache_size
[ $cache_size -lt $min_cache_size ] && cache_size=$min_cache_size
原理:检查/var的可用空间大小, 默认设置为1/8可用空间,最小值512,这个算法可以自己调整,我认为还算比较合理吧,在64M内存时,大约能分到3M多缓存空间。
5.还是关于缓存的问题,即使按上述几条修改之后,pdnsc.cache还是不会自动增长,通过查询源码,发现:
原来pdnsd只有在正常退出时才把内存缓存写入文件缓存,而S-S Rpro脚本中在stop的时候总是用kill -9强行杀死pdnsd进程,下一次start又重新初始化,我认为这样一来,pdnsd的缓存就没用了,所以需要修改
kill $(cat /var/run/pdnsd.pid) >/dev/null 2>&1 || killall -9 pdnsd >/dev/null 2>&1
把原来kill -9 改为kill,如果不成功再加-9
另外,stop_pdnsd不再删除/var/pdnsd目录
根据L大的回复,我又优化了一下脚本:
当pdnsd启动完成后,把pdnsd.cache重置为8节字的空文件。
原因是:pdnsd运行过程中,缓存是在内存里的,而pdnsd停止时,内存的缓存被持久化到磁盘里,以便下次启动时重新载入内存, 载入完毕后pdnsd.cache就可以清空了。这样的好处是明显的:路由器一般是长期不重启的,但S-S Rpro是有可能重启的,如果不进行缓存持久化操作,那么每次S-S Rpro重启后,之前查过的域名资料就浪费了,得重新查询,而国外的DNS一般是比较慢的,能少查一点总是好的,既省流量又省时间。
另一方面,openwrt的/var目录实质上是内存虚拟出来的,我上一版的算法,当pdnsd运行时,既占了内存缓存,也占了磁盘缓存,经改进之后算是两全其美了。
结果: S-S Rpro运行一段时间后, 运行/etc/init.d/S-S Rpro stop, 这时/var/pdnsd/pdnsd.cache应大于8字节;
而/etc/init.d/S-S Rpro start之后, /var/pdnsd/pdnsd.cache应该是8字节
网盘已更新了代码,之前下载过的朋友可以重新下载一次,或是手工修改也可以(红色的3行是新增的代码):
/usr/sbin/pdnsd -c /var/etc/pdnsd.conf -d
# After pdnsd started, empty disk cache to save memory space
echo -ne "pd13\000\000\000\000" >/var/pdnsd/pdnsd.cache
chown nobody:nogroup /var/pdnsd/pdnsd.cache
总之,改完以后,效果还是比较明显的,GFW模式正常,仅重启***pro不会删除缓存,重启路由器才会。直接放出我改过的代码吧,懂的人一看就知道了,不懂的话可以直接用我的代码替换原始代码
1. 如果已经刷好机的,用我的代码直接覆盖/etc/init.d/xxxpro同名文件即可
(注意对应版本,我改了两个版本,分别对应k2p a版的opencc 1.7.x,以及对应lede版的lean源码)
2. 如果需要自己编译固件的,用我的代码替换 package/lean/luci-app-xxx-pro/root/etc/init.d/xxxpro
链接:https://pan.baidu.com/s/1qfrXUVsazfEn89yMIc6Uow 密码:nrks
|
评分
-
查看全部评分
|