diff --git a/package/lean/adbyby/Makefile b/package/lean/adbyby/Makefile new file mode 100644 index 000000000..770559084 --- /dev/null +++ b/package/lean/adbyby/Makefile @@ -0,0 +1,70 @@ +# +# Copyright (C) 2015-2016 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v3. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=adbyby +PKG_VERSION:=2.7 +PKG_RELEASE:=20170823 + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME) + SECTION:=net + CATEGORY:=Network + TITLE:=Powerful adblock module to block ad. + DEPENDS:= + URL:=http://www.adbyby.com/ +endef + +define Package/$(PKG_NAME)/description +Adbyby is a powerful adblock module to block ad,just like adblock. +endef + +define Build/Prepare +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/usr/share/adbyby + $(INSTALL_BIN) ./files/adbyby.sh $(1)/usr/share/adbyby/ + $(INSTALL_BIN) ./files/adbybyfirst.sh $(1)/usr/share/adbyby/ + $(INSTALL_BIN) ./files/adbybyupdate.sh $(1)/usr/share/adbyby/ + $(INSTALL_CONF) ./files/adhook.ini $(1)/usr/share/adbyby/ + $(INSTALL_CONF) ./files/user.action $(1)/usr/share/adbyby/ + + $(INSTALL_DIR) $(1)/usr/share/adbyby/data + $(INSTALL_DATA) ./files/data/* $(1)/usr/share/adbyby/data/ + + $(INSTALL_DIR) $(1)/usr/share/adbyby/doc + $(INSTALL_DATA) ./files/doc/* $(1)/usr/share/adbyby/doc/ + +ifeq ($(ARCH),mipsel) + $(INSTALL_BIN) ./files/7620n/adbyby $(1)/usr/share/adbyby/ +endif +ifeq ($(ARCH),mips) + $(INSTALL_BIN) ./files/ar71xx/adbyby $(1)/usr/share/adbyby/ +endif +ifeq ($(ARCH),i386) + $(INSTALL_BIN) ./files/x86/adbyby $(1)/usr/share/adbyby/ +endif +ifeq ($(ARCH),x86_64) + $(INSTALL_BIN) ./files/x86_64/adbyby $(1)/usr/share/adbyby/ +endif +ifeq ($(ARCH),arm) + $(INSTALL_BIN) ./files/arm/adbyby $(1)/usr/share/adbyby/ +endif +ifeq ($(ARCH),aarch64) + $(INSTALL_BIN) ./files/armv7/adbyby $(1)/usr/share/adbyby/ +endif +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/package/lean/adbyby/files/7620n/adbyby b/package/lean/adbyby/files/7620n/adbyby new file mode 100755 index 000000000..39ab0a1eb Binary files /dev/null and b/package/lean/adbyby/files/7620n/adbyby differ diff --git a/package/lean/adbyby/files/adbyby.sh b/package/lean/adbyby/files/adbyby.sh new file mode 100755 index 000000000..146a070d1 --- /dev/null +++ b/package/lean/adbyby/files/adbyby.sh @@ -0,0 +1,16 @@ +#!/bin/sh +PROG_PATH=/usr/share/adbyby +err=0 +until [ $err -ge 5 ]; do + if [ -n "$(pgrep $PROG_PATH/adbyby)" ]; then + iptables-save | grep ADBYBY >/dev/null || \ + /etc/init.d/adbyby add_rule + sleep 10 + err=0 + else + $PROG_PATH/adbyby --no-daemon &>/dev/null & + sleep 1 + err=$((err+1)) + fi +done +/etc/init.d/adbyby del_rule diff --git a/package/lean/adbyby/files/adbybyfirst.sh b/package/lean/adbyby/files/adbybyfirst.sh new file mode 100755 index 000000000..c677d1bec --- /dev/null +++ b/package/lean/adbyby/files/adbybyfirst.sh @@ -0,0 +1,11 @@ +#!/bin/sh +PROG_PATH=/usr/share/adbyby +if [ -z "$(dnsmasq --version | grep no-ipset)" ]; then + [ $(uci get adbyby.@adbyby[-1].wan_mode) -ne 2 ] && \ + [ $(awk -F= '/^ipset/{print $2}' $PROG_PATH/adhook.ini) -eq 1 ] && \ + { + sed -i 's/adbyby_list/adbyby_wan/' /tmp/adbyby_host.conf + echo conf-file=/tmp/adbyby_host.conf >> /etc/dnsmasq.conf + /etc/init.d/dnsmasq restart + } +fi diff --git a/package/lean/adbyby/files/adbybyupdate.sh b/package/lean/adbyby/files/adbybyupdate.sh new file mode 100755 index 000000000..bdde944a2 --- /dev/null +++ b/package/lean/adbyby/files/adbybyupdate.sh @@ -0,0 +1,11 @@ +#!/bin/sh +PROG_PATH=/usr/share/adbyby +if [ -z "$(dnsmasq --version | grep no-ipset)" ]; then + [ $(uci get adbyby.@adbyby[-1].wan_mode) -ne 2 ] && \ + [ $(awk -F= '/^ipset/{print $2}' $PROG_PATH/adhook.ini) -eq 1 ] && \ + { + sed -i 's/adbyby_list/adbyby_wan/' /tmp/adbyby_host.conf + ipset -F adbyby_wan 2>/dev/null + /etc/init.d/dnsmasq restart + } +fi diff --git a/package/lean/adbyby/files/adhook.ini b/package/lean/adbyby/files/adhook.ini new file mode 100644 index 000000000..6a7613ea8 --- /dev/null +++ b/package/lean/adbyby/files/adhook.ini @@ -0,0 +1,14 @@ +[cfg] +### 2.1 ### +listen-address=0.0.0.0:8118 +buffer-limit=1024 +keep-alive-timeout=30 +socket-timeout=60 +### 2.5 ### +max_client_connections=0 +### 2.6 ### +stack_size=200 +auto_restart=0 +### 2.7 ### +debug=0 +ipset=0 diff --git a/package/lean/adbyby/files/ar71xx/adbyby b/package/lean/adbyby/files/ar71xx/adbyby new file mode 100755 index 000000000..6c8edf1cb Binary files /dev/null and b/package/lean/adbyby/files/ar71xx/adbyby differ diff --git a/package/lean/adbyby/files/arm/adbyby b/package/lean/adbyby/files/arm/adbyby new file mode 100755 index 000000000..a7da1900d Binary files /dev/null and b/package/lean/adbyby/files/arm/adbyby differ diff --git a/package/lean/adbyby/files/armv7/adbyby b/package/lean/adbyby/files/armv7/adbyby new file mode 100755 index 000000000..98dbfbe54 Binary files /dev/null and b/package/lean/adbyby/files/armv7/adbyby differ diff --git a/package/lean/adbyby/files/data/adclear.ini b/package/lean/adbyby/files/data/adclear.ini new file mode 100644 index 000000000..369186258 --- /dev/null +++ b/package/lean/adbyby/files/data/adclear.ini @@ -0,0 +1,121 @@ +//IE6、7、8、9, from adsafe +%USERPROFILE%\Local Settings\Temporary Internet Files\*.html +%USERPROFILE%\Local Settings\Temporary Internet Files\*.js +%USERPROFILE%\Local Settings\Temporary Internet Files\*.htm +%USERPROFILE%\Local Settings\Temporary Internet Files\*.xml +%USERPROFILE%\Local Settings\Temporary Internet Files\*.css +%USERPROFILE%\Local Settings\Temporary Internet Files\*.swf +%USERPROFILE%\Local Settings\Temporary Internet Files\*.flv +%USERPROFILE%\Local Settings\Temporary Internet Files\*.mp4 +%USERPROFILE%\Local Settings\Temporary Internet Files\Content.IE5\*.* +%USERPROFILE%\AppData\Local\Microsoft\Windows\Temporary Internet Files\*.* +%USERPROFILE%\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\*.* + +//360安全浏览器 +%USERPROFILE%\Application Data\360se\ie8data\Temporary Internet Files\*.* + +//chrome +%USERPROFILE%\AppData\Local\Google\Chrome\User Data\Default\Cache\*.* + +//360极速浏览器 +%USERPROFILE%\Local Settings\Application Data\360Chrome\Chrome\User Data\Default\CacheIE\*.* +%USERPROFILE%\Local Settings\Application Data\360Chrome\Chrome\User Data\Default\Cache\*.* +%USERPROFILE%\AppData\Local\360Chrome\Chrome\User Data\Default\Cache\*.* +%USERPROFILE%\Local Settings\Application Data\360Chrome\Chrome\User Data\Default\CacheIE\Content.IE5\*.* + +//搜狗浏览器 +%USERPROFILE%\Application Data\SogouExplorer\Webkit\Default\Cache\*.* +%USERPROFILE%\AppData\Roaming\SogouExplorer\Webkit\Default\Cache\*.* + +//opera浏览器 +%USERPROFILE%\AppData\Local\Opera\Opera\cache\*.* +%USERPROFILE%\Local Settings\Application Data\Opera\Opera\cache\*.* +%USERPROFILE%\Local Settings\Application Data\Opera\Opera\application_cache\mcache\*.* +%USERPROFILE%\Local Settings\Application Data\Opera\Opera\application_cache\cache_groups.xml +%USERPROFILE%\Local Settings\Application Data\Opera\Opera\opcache\*.* + +//淘宝浏览器 +%USERPROFILE%\AppData\Local\TaoBrowser\User Data\Default\Cache\*.* +%USERPROFILE%\AppData\Local\TaoBrowser\User Data\Default\JumpListIcons\*.* +%USERPROFILE%\Local Settings\Application Data\TaoBrowser\User Data\Default\Cache\*.* + +//百度浏览器 +%USERPROFILE%\Application Data\Baidu\browser\DiskCache\*.* +%USERPROFILE%\AppData\Roaming\Baidu\browser\DiskCache\*.* + +//猎豹浏览器 +%USERPROFILE%\Local Settings\Application Data\liebao\User Data\Default\Cache\*.* +%USERPROFILE%\Local Settings\Application Data\liebao\User Data\iecache\Content.IE5\*.* +%USERPROFILE%\AppData\Local\liebao\User Data\Default\Cache\*.* +%USERPROFILE%\AppData\Local\liebao\User Data\Default\JumpListIcons\*.* + +//Letv +%USERPROFILE%\Application Data\Letv\Logg\*.log + +//PPSStream +%APPDATA%\PPStream\adsys\*.* +%APPDATA%\PPStream\banner\*.* +%APPDATA%\PPStream\notice\*.* +%APPDATA%\PPStream\CLCache\*.pld +%APPDATA%\PPStream\FDSCache\*.blf + +//PPTV +%APPDATA%\PPLive\PPTV\cache\*.* + +//风行 +%USERPROFILE%\funshion\cache\*.* + + +//youku +-s%appdata%\Macromedia\Flash Player\#SharedObjects\YOUKU_FSO_PROXY.sol +-s%APPDATA%\Roaming\Macromedia\Flash Player\#SharedObjects\YOUKU_FSO_PROXY.sol + + +//letv +-s%appdata%\Macromedia\Flash Player\#SharedObjects\com.letv.sol + +//iqiyi +-s%appdata%\Macromedia\Flash Player\#SharedObjects\qiyi_statistics.sol + +//chrome YOUKU +-s%USERPROFILE%\AppData\Local\Google\Chrome\User Data\Default\Pepper Data\Shockwave Flash\WritableRoot\#SharedObjects\YOUKU_FSO_PROXY.sol + +//chrome LeTv +-s%USERPROFILE%\AppData\Local\Google\Chrome\User Data\Default\Pepper Data\Shockwave Flash\WritableRoot\#SharedObjects\com.letv.sol + +//chrome iqiyi +-s%USERPROFILE%\AppData\Local\Google\Chrome\User Data\Default\Pepper Data\Shockwave Flash\WritableRoot\#SharedObjects\qiyi_statistics.sol + +//360 youku +-s%USERPROFILE%\AppData\Local\360Chrome\Chrome\User Data\Default\Pepper Data\Shockwave Flash\WritableRoot\#SharedObjects\YOUKU_FSO_PROXY.sol + +//360 letv +-s%USERPROFILE%\AppData\Local\360Chrome\Chrome\User Data\Default\Pepper Data\Shockwave Flash\WritableRoot\#SharedObjects\com.letv.sol + +//360 iqiyi +-s%USERPROFILE%\AppData\Local\360Chrome\Chrome\User Data\Default\Pepper Data\Shockwave Flash\WritableRoot\#SharedObjects\qiyi_statistics.sol + + +//暴风影音5 +%ALLUSERSPROFILE%\Baofeng\StormPlayer\Profiles\md\*.* +%ALLUSERSPROFILE%\Baofeng\StormPlayer\Profiles\vod\*.* +%ALLUSERSPROFILE%\Application Data\Baofeng\StormPlayer\Profiles\md\*.* +%ALLUSERSPROFILE%\Application Data\Baofeng\StormPlayer\Profiles\vod\*.* +%ALLUSERSPROFILE%\Baofeng\Application Data\StormPlayer\Profiles\md\*.* +%ALLUSERSPROFILE%\Baofeng\Application Data\StormPlayer\Profiles\vod\*.* + +//pptv +%ALLUSERSPROFILE%\PPLive\PPTV\Cache\pluginad\*.* +%ALLUSERSPROFILE%\Application Data\PPLive\PPTV\Cache\pluginad\*.* +%ALLUSERSPROFILE%\Application Data\PPLive\PPTV\screensaver\*.* + + +//多米 +C:\Program Files\DuoMi\dmdeskinfo.exe + +//UUSEE +%TEMP%\UUFile\*.* + +//iqiyi +%ALLUSERSPROFILE%\Application Data\Qiyi\qiyiclient\cache\*.* + diff --git a/package/lean/adbyby/files/data/clean.ini b/package/lean/adbyby/files/data/clean.ini new file mode 100644 index 000000000..6b69b1492 --- /dev/null +++ b/package/lean/adbyby/files/data/clean.ini @@ -0,0 +1,43 @@ +//youku +-y%appdata%\Macromedia\Flash Player\#SharedObjects\YOUKU_FSO_PROXY.sol +//youku win7 +-y%APPDATA%\Roaming\Macromedia\Flash Player\#SharedObjects\YOUKU_FSO_PROXY.sol +//chrome YOUKU +-y%USERPROFILE%\AppData\Local\Google\Chrome\User Data\Default\Pepper Data\Shockwave Flash\WritableRoot\#SharedObjects\YOUKU_FSO_PROXY.sol +//360 youku +-y%USERPROFILE%\AppData\Local\360Chrome\Chrome\User Data\Default\Pepper Data\Shockwave Flash\WritableRoot\#SharedObjects\YOUKU_FSO_PROXY.sol +//sougou youku +-y%appdata%\SogouExplorer\Webkit\Default\Pepper Data\Shockwave Flash\WritableRoot\#SharedObjects\YOUKU_FSO_PROXY.sol + +-y%userprofile%\Local Settings\Application Data\Google\Chrome\User Data\Default\Pepper Data\Shockwave Flash\WritableRoot\#SharedObjects\YOUKU_FSO_PROXY.sol +-y%userprofile%\Local Settings\Application Data\UCBrowser\User Data\Default\Pepper Data\Shockwave Flash\WritableRoot\#SharedObjects\YOUKU_FSO_PROXY.sol +-y%userprofile%\Local Settings\Application Data\360Chrome\Chrome\User Data\Default\Pepper Data\Shockwave Flash\WritableRoot\#SharedObjects\YOUKU_FSO_PROXY.sol + +//qq +%appdata%\Tencent\QQ\Misc\com.tencent.advertisement\*.* +%appdata%\Tencent\QQ\Misc\com.tencent.advertisement\GDT_0\*.* + +//letv +-s%appdata%\Macromedia\Flash Player\#SharedObjects\com.letv.sol + +//letv1 +-s%APPDATA%\Roaming\Macromedia\Flash Player\#SharedObjects\com.letv.sol + +//iqiyi +-s%appdata%\Macromedia\Flash Player\#SharedObjects\qiyi_statistics.sol + +//iqiyi1 +-s%APPDATA%\Roaming\Macromedia\Flash Player\#SharedObjects\qiyi_statistics.sol + + +//chrome LeTv +-s%USERPROFILE%\AppData\Local\Google\Chrome\User Data\Default\Pepper Data\Shockwave Flash\WritableRoot\#SharedObjects\com.letv.sol + +//chrome iqiyi +-s%USERPROFILE%\AppData\Local\Google\Chrome\User Data\Default\Pepper Data\Shockwave Flash\WritableRoot\#SharedObjects\qiyi_statistics.sol + +//360 letv +-s%USERPROFILE%\AppData\Local\360Chrome\Chrome\User Data\Default\Pepper Data\Shockwave Flash\WritableRoot\#SharedObjects\com.letv.sol + +//360 iqiyi +-s%USERPROFILE%\AppData\Local\360Chrome\Chrome\User Data\Default\Pepper Data\Shockwave Flash\WritableRoot\#SharedObjects\qiyi_statistics.sol diff --git a/package/lean/adbyby/files/data/lazy.bin b/package/lean/adbyby/files/data/lazy.bin new file mode 100644 index 000000000..8cd519270 Binary files /dev/null and b/package/lean/adbyby/files/data/lazy.bin differ diff --git a/package/lean/adbyby/files/data/lazy.txt b/package/lean/adbyby/files/data/lazy.txt new file mode 100644 index 000000000..52aa40a8b --- /dev/null +++ b/package/lean/adbyby/files/data/lazy.txt @@ -0,0 +1 @@ +! -----更新时间: 2017-1-2 00:12:25 by:xwhyc----- \ No newline at end of file diff --git a/package/lean/adbyby/files/data/rules.txt b/package/lean/adbyby/files/data/rules.txt new file mode 100644 index 000000000..441b56527 --- /dev/null +++ b/package/lean/adbyby/files/data/rules.txt @@ -0,0 +1,15 @@ +! ------------------------------ ADByby 鑷畾涔夎繃婊よ娉曠畝琛--------------------------------- +! -------------- 瑙勫垯鍩轰簬abp瑙勫垯锛屽苟杩涜浜嗗瓧绗︽浛鎹㈤儴鍒嗙殑鎵╁睍----------------------------- +! ABP瑙勫垯璇峰弬鑰僪ttps://adblockplus.org/zh_CN/filters锛屼笅闈负澶ц嚧鎽樿 +! "!" 涓鸿娉ㄩ噴绗︼紝娉ㄩ噴琛屼互璇ョ鍙疯捣濮嬩綔涓轰竴琛屾敞閲婅涔夛紝鐢ㄤ簬瑙勫垯鎻忚堪 +! "*" 涓哄瓧绗﹂氶厤绗︼紝鑳藉鍖归厤0闀垮害鎴栦换鎰忛暱搴︾殑瀛楃涓诧紝璇ラ氶厤绗︿笉鑳戒笌姝e垯璇硶娣风敤銆 +! "^" 涓哄垎闅旂锛屽彲浠ユ槸闄や簡瀛楁瘝銆佹暟瀛楁垨鑰 _ - . % 涔嬪鐨勪换浣曞瓧绗︺ +! "|" 涓虹绾跨鍙凤紝鏉ヨ〃绀哄湴鍧鐨勬渶鍓嶇鎴栨渶鏈 +! "||" 涓哄瓙鍩熼氶厤绗︼紝鏂逛究鍖归厤涓诲煙鍚嶄笅鐨勬墍鏈夊瓙鍩熴 +! "~" 涓烘帓闄ゆ爣璇嗙锛岄氶厤绗﹁兘杩囨护澶у鏁板箍鍛婏紝浣嗗悓鏃跺瓨鍦ㄨ鏉, 鍙互閫氳繃鎺掗櫎鏍囪瘑绗︿慨姝h鏉閾炬帴銆 +! "##" 涓哄厓绱犻夋嫨鍣ㄦ爣璇嗙锛屽悗闈㈣窡闇瑕侀殣钘忓厓绱犵殑CSS鏍峰紡渚嬪 #ad_id .ad_class +!! 鍏冪礌闅愯棌鏆備笉鏀寔鍏ㄥ眬瑙勫垯鍜屾帓闄よ鍒 +!! 瀛楃鏇挎崲鎵╁睍 +! 鏂囨湰鏇挎崲閫夋嫨鍣ㄦ爣璇嗙锛屽悗闈㈣窡闇瑕佹浛鎹㈢殑鏂囨湰鏁版嵁锛屾牸寮忥細$s@妯″紡瀛楃涓睝鏇挎崲鍚庣殑鏂囨湰@ +! 鏀寔閫氶厤绗*鍜岋紵 +! ------------------------------------------------------------------------------------------- diff --git a/package/lean/adbyby/files/data/user.txt b/package/lean/adbyby/files/data/user.txt new file mode 100644 index 000000000..e69de29bb diff --git a/package/lean/adbyby/files/data/video.txt b/package/lean/adbyby/files/data/video.txt new file mode 100644 index 000000000..a97ba337c --- /dev/null +++ b/package/lean/adbyby/files/data/video.txt @@ -0,0 +1,17 @@ +! -----更新时间: 2016-12-31 23:40:12 by:xwhyc----------------------------------------------- +! -----广告反馈:http://www.adbyby.com/help.htm QQ群: 79547134(满), 364066294(满),470705224,534897434,438394572-------------- + + + +!------------------------------------------- + + +!----------------------- + + + +!---------adbyby--------- +!|http://bbs.kafan.cn/$s@@@ +thegreatdaily.com/cat##.col-lg-8.col-md-8{width:1190px;} +!www.baidu.com,news.baidu.com###content_right,[srcid="6835"],[class="result-op xpath-log"] +!www.baidu.com,news.baidu.com###content_left,.c-container,.result{width:860px}.c-span-last{width:720px} diff --git a/package/lean/adbyby/files/doc/hidecss.js b/package/lean/adbyby/files/doc/hidecss.js new file mode 100644 index 000000000..93c21f5fe --- /dev/null +++ b/package/lean/adbyby/files/doc/hidecss.js @@ -0,0 +1 @@ +(function(global){var DOC=global.document,w3c_css=global.getComputedStyle,undef=void 0,reg_combinator=/^\s*([>+~,\s])\s*(\*|(?:[-\w*]|[^\x00-\xa0]|\\.)*)/,trimLeft=/^\s+/,trimRight=/\s+$/,reg_comma=/^\s*,\s*/,reg_sequence=/^([#\.:]|\[\s*)((?:[-\w]|[^\x00-\xa0]|\\.)+)/,reg_pseudo=/^\(\s*("([^"]*)"|'([^']*)'|[^\(\)]*(\([^\(\)]*\))?)\s*\)/,reg_attrib=/^\s*(?:(\S?=)\s*(?:(['"])(.*?)\2|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,reg_attrval=/\\([0-9a-fA-F]{2,2})/g,reg_sensitive=/^(?:title|id|name|class|for|href|src)$/,reg_backslash=/\\/g,reg_tag=/^((?:[-\w\*]|[^\x00-\xa0]|\\.)+)/,reg_parse_pseudo=/(-?)(\d*)n([-+]?\d*)/,reg_quick=/^(^|[#.])((?:[-\w]|[^\x00-\xa0]|\\.)+)$/,has_in=function(a,b){return(a in b)},dom={html:DOC.documentElement,mix:function(target,source){var args=[].slice.call(arguments),key,ride=typeof args[args.length-1]=="boolean"?args.pop():true;target=target||{};for(var i=1;source=args[i++];){for(key in source){if(ride||!has_in(key,target)){target[key]=source[key]}}}return target},rword:/[^, ]+/g,uuid:1,getUid:w3c_css?function(node){return node.uniqueNumber||(node.uniqueNumber=dom.uuid++)}:function(node){var uid=node.getAttribute("uniqueNumber");if(!uid){uid=dom.uuid++;node.setAttribute("uniqueNumber",uid)}return uid},oneObject:function(array,val){if(typeof array=="string"){array=array.match(dom.rword)||[]}var result={},value=val!==undef?val:1;for(var i=0,n=array.length;i=0);(found^flag_not)&&(result[ri++]=el)}return result}}},onePosition=dom.oneObject("eq,gt,lt,first,last,even,odd"),siblingCheck=function(a,b,ret){if(a===b){return ret}var cur=a.nextSibling;while(cur){if(cur===b){return -1}cur=cur.nextSibling}return 1},sortOrder1=function(a,b){if(a===b){sortOrder1.hasDuplicate=true;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition){return a.compareDocumentPosition?-1:1}return a.compareDocumentPosition(b)&4?-1:1},sortOrder2=function(a,b){if(a===b){sortOrder2.hasDuplicate=true;return 0}var al,bl,ap=[],bp=[],aup=a.parentNode,bup=b.parentNode,cur=aup;if(aup===bup){return siblingCheck(a,b)}else{if(!aup){return -1}else{if(!bup){return 1}}}while(cur){ap.unshift(cur);cur=cur.parentNode}cur=bup;while(cur){bp.unshift(cur);cur=cur.parentNode}al=ap.length;bl=bp.length;for(var i=0;i0&&els.length&&els[0].lookupNamespaceURI){var arr=tagName.split(":");prefix=arr[0];tagName=arr[1];method="getElementsByTagNameNS";prefix=els[0].lookupNamespaceURI(prefix)}switch(els.length){case 0:return elems;case 1:var all=prefix?els[0][method](prefix,tagName):els[0][method](tagName);for(var i=0,ri=0,el;el=all[i++];){if(el.nodeType===1){elems[ri++]=el}}return elems;default:for(var nodes,i=0,ri=0;el=els[i++];){nodes=prefix?el[method](prefix,tagName):el[method](tagName);for(var uid,j=0,node;node=nodes[j++];){uid=dom.getUid(node);if(!uniqResult[uid]){uniqResult[uid]=elems[ri++]=node}}}return elems}},getElementsByXPath=function(xpath,context,doc){var result=[];try{if(global.DOMParser){var nodes=doc.evaluate(xpath,context,null,7,null);for(var i=0,n=nodes.snapshotLength;i";root.insertBefore(form,root.firstChild);fixById=!!DOC.getElementById(id);root.removeChild(form)})();try{slice.call(dom.html.childNodes,0)[0].nodeType}catch(e){makeArray=function(nodes,result,flag_multi){var ret=result||[],ri=ret.length;for(var i=0,el;el=nodes[i++];){ret[ri++]=el}return flag_multi?dom.unique(ret):ret}}var Icarus=dom.query=function(expr,contexts,result,lastResult,flag_xml,flag_multi,flag_dirty){result=result||[];contexts=contexts||DOC;var pushResult=makeArray;if(!contexts.nodeType){contexts=pushResult(contexts);if(!contexts.length){return result}}else{contexts=[contexts]}var rrelative=reg_combinator,rBackslash=reg_backslash,rcomma=reg_comma,context=contexts[0],doc=context.ownerDocument||context,rtag=reg_tag,flag_all,uniqResult,elems,nodes,tagName,last,ri,uid;expr=expr.replace(trimLeft,"").replace(trimRight,"");flag_xml=flag_xml!==undef?flag_xml:dom.isXML(doc);if(flag_xml&&expr==="body"&&context.body){return pushResult([context.body],result,flag_multi)}if(!flag_xml&&doc.querySelectorAll){var query=expr,fix_icarus_sqa="fix_icarus_sqa";if(contexts.length>2||doc.documentMode==8&&context.nodeType==1){if(contexts.length>2){context=doc}query="."+fix_icarus_sqa+" "+query;for(var i=0,node;node=contexts[i++];){if(node.nodeType===1){node.className=fix_icarus_sqa+" "+node.className}}}if(doc.documentMode!==8||context.nodeName.toLowerCase()!=="object"){try{return pushResult(context.querySelectorAll(query),result,flag_multi)}catch(e){}finally{if(!query.indexOf("."+fix_icarus_sqa)){for(i=0;node=contexts[i++];){if(node.nodeType===1){node.className=node.className.replace(fix_icarus_sqa+" ","")}}}}}}var match=expr.match(reg_quick);if(match){var value=match[2].replace(rBackslash,""),key=match[1];if(key==""){nodes=getElementsByTagName(value,contexts,flag_xml)}else{if(key==="."&&contexts.length===1){if(flag_xml){nodes=getElementsByXPath("//*[@class='"+value+"']",context,doc)}else{if(context.getElementsByClassName){nodes=context.getElementsByClassName(value)}}}else{if(key==="#"&&contexts.length===1){if(flag_xml){nodes=getElementsByXPath("//*[@id='"+value+"']",context,doc)}else{if(context.nodeType==Math.pow(3,2)){node=doc.getElementById(value);nodes=!node?[]:!fixById?[node]:node.getAttributeNode("id").nodeValue===value?[node]:false}}}}}if(nodes){return pushResult(nodes,result,flag_multi)}}lastResult=contexts;if(lastResult.length){loop:while(expr&&last!==expr){flag_dirty=false;elems=null;uniqResult={};if((match=expr.match(rrelative))){expr=RegExp.rightContext;elems=[];tagName=(flag_xml?match[2]:match[2].toUpperCase()).replace(rBackslash,"")||"*";i=0;ri=0;flag_all=tagName==="*";switch(match[1]){case" ":if(expr.length||match[2]){elems=getElementsByTagName(tagName,lastResult,flag_xml)}else{elems=lastResult;break loop}break;case">":while((node=lastResult[i++])){for(node=node.firstChild;node;node=node.nextSibling){if(node.nodeType===1&&(flag_all||tagName===node.nodeName)){elems[ri++]=node}}}break;case"+":while((node=lastResult[i++])){while((node=node.nextSibling)){if(node.nodeType===1){if(flag_all||tagName===node.nodeName){elems[ri++]=node}break}}}break;case"~":while((node=lastResult[i++])){while((node=node.nextSibling)){if(node.nodeType===1&&(flag_all||tagName===node.nodeName)){uid=dom.getUid(node);if(uniqResult[uid]){break}else{uniqResult[uid]=elems[ri++]=node}}}}elems=dom.unique(elems);break}}else{if((match=expr.match(rtag))){expr=RegExp.rightContext;elems=getElementsByTagName(match[1].replace(rBackslash,""),lastResult,flag_xml)}}if(expr){var arr=Icarus.filter(expr,elems,lastResult,doc,flag_xml);expr=arr[0];elems=arr[1];if(!elems){flag_dirty=true;elems=getElementsByTagName("*",lastResult,flag_xml)}if((match=expr.match(rcomma))){expr=RegExp.rightContext;pushResult(elems,result);return Icarus(expr,contexts,result,[],flag_xml,true,flag_dirty)}else{lastResult=elems}}}}if(flag_multi){if(elems.length){return pushResult(elems,result,flag_multi)}}else{if(DOC!==doc||fixByTag&&flag_dirty){for(result=[],ri=0,i=0;node=elems[i++];){if(node.nodeType===1){result[ri++]=node}}return result}}return elems},filterPseudoNoExp=function(name,isLast,isOnly){var A="for(var result=[],flag_not=A.not,node,el,tagName,i=0,ri=0,found=0;node=el=B[i++];found=0){",B="{0}while(!found&&(node=node.{1})){(node.{2}==={3})&&++found}",C="node=el;while(!found&&(node=node.previousSibling)){node.{2}==={3}&&++found}",D="!found^flag_not&&(result[ri++]=el)}return result",start=isLast?"nextSibling":"previousSibling",fills={type:["tagName=el.nodeName;",start,"nodeName","tagName"],child:["",start,"nodeType","1"]}[name],body=A+B+(isOnly?C:"")+D;return{exec:new Function("A","B",body.replace(/{(\d)}/g,function($,$1){return fills[$1]}))}};dom.mix(Icarus,{getAttribute:!fixGetAttribute?function(elem,name){return elem.getAttribute(name)||""}:function(elem,name,flag_xml){if(flag_xml){return elem.getAttribute(name)||""}name=name.toLowerCase();if(attrURL[name]){return elem.getAttribute(name,2)||""}if(elem.tagName==="INPUT"&&name=="type"){return elem.getAttribute("type")||elem.type}var attr=boolOne[name]?(elem.getAttribute(name)?name:""):(elem=elem.getAttributeNode(name))&&elem.value||"";return reg_sensitive.test(name)?attr:attr.toLowerCase()},hasAttribute:!fixHasAttribute?function(elem,name,flag_xml){return flag_xml?!!elem.getAttribute(name):elem.hasAttribute(name)}:function(elem,name){elem=elem.getAttributeNode(name.toLowerCase());return !!(elem&&(elem.specified||elem.nodeValue))},filter:function(expr,elems,lastResult,doc,flag_xml,flag_get){var rsequence=reg_sequence,rattrib=reg_attrib,rpseudo=reg_pseudo,rBackslash=reg_backslash,rattrval=reg_attrval,pushResult=makeArray,toHex=_toHex,_hash_op=hash_operator,parsePseudo=parse_pseudo,match,key,tmp;while((match=expr.match(rsequence))){expr=RegExp.rightContext;key=(match[2]||"").replace(rBackslash,"");if(!elems){if(lastResult.length===1&&lastResult[0]===doc){switch(match[1]){case"#":if(!flag_xml){tmp=doc.getElementById(key);if(!tmp){elems=[];continue}if(fixById?tmp.id===key:tmp.getAttributeNode("id").nodeValue===key){elems=[tmp];continue}}break;case":":switch(key){case"root":elems=[doc.documentElement];continue;case"link":elems=pushResult(doc.links||[]);continue}break}}elems=getElementsByTagName("*",lastResult,flag_xml)}var filter=0,flag_not=false,args;switch(match[1]){case"#":filter=["id","=",key];break;case".":filter=["class","~=",key];break;case":":tmp=Icarus.hook[key];if((match=expr.match(rpseudo))){expr=RegExp.rightContext;args=parsePseudo(key,match)}if(tmp){filter=tmp}else{if(key==="not"){flag_not=true;if(args==="*"){elems=[]}else{if(reg_tag.test(args)){tmp=[];match=flag_xml?args:args.toUpperCase();for(var i=0,ri=0,elem;elem=elems[i++];){if(match!==elem.nodeName){tmp[ri++]=elem}}elems=tmp}else{var obj=Icarus.filter(args,elems,lastResult,doc,flag_xml,true);filter=obj.filter;args=obj.args}}}else{throw"!"}}break;default:filter=[key.toLowerCase()];if((match=expr.match(rattrib))){expr=RegExp.rightContext;if(match[1]){filter[1]=match[1];filter[2]=match[3]||match[4];filter[2]=filter[2]?filter[2].replace(rattrval,toHex).replace(rBackslash,""):""}}break}if(flag_get){return{filter:filter,args:args}}if(elems.length&&filter){tmp=[];i=0;ri=0;if(typeof filter==="function"){if(onePosition[key]){args=args===undef?elems.length-1:~~args;for(;elem=elems[i];){if(filter(i++,args)^flag_not){tmp[ri++]=elem}}}else{while((elem=elems[i++])){if((!!filter(elem,args))^flag_not){tmp[ri++]=elem}}}}else{if(typeof filter.exec==="function"){tmp=filter.exec({not:flag_not,xml:flag_xml},elems,args,doc)}else{var name=filter[0],op=_hash_op[filter[1]],val=filter[2]||"",flag,attr,className;if(!flag_xml&&name==="class"&&op===4){val=" "+val+" ";while((elem=elems[i++])){className=elem.className;if(!!(className&&~(" "+className+" ").indexOf(val))^flag_not){tmp[ri++]=elem}}}else{if(!flag_xml&&op&&val&&!reg_sensitive.test(name)){val=val.toLowerCase()}if(op===4){val=" "+val+" "}while((elem=elems[i++])){if(!op){flag=Icarus.hasAttribute(elem,name,flag_xml)}else{if(val===""&&op>3){flag=false}else{attr=Icarus.getAttribute(elem,name,flag_xml);switch(op){case 1:(flag=attr===val);break;case 2:(flag=attr!==val);break;case 3:(flag=attr===val||attr.substr(0,val.length+1)===val+"-");break;case 4:(flag=attr!==""&&!!~(" "+attr+" ").indexOf(val));break;case 5:(flag=attr!==""&&!attr.indexOf(val));break;case 6:(flag=attr!==""&&attr.substr(attr.length-val.length)===val);break;case 7:(flag=attr!==""&&!!~attr.indexOf(val));break}}}if(flag^flag_not){tmp[ri++]=elem}}}}}elems=tmp}}return[expr,elems]}});Icarus.hook={root:function(el){return el===(el.ownerDocument||el.document).documentElement},"first-child":filterPseudoNoExp("child",false,false),"last-child":filterPseudoNoExp("child",true,false),"only-child":filterPseudoNoExp("child",true,true),"nth-child":filterPseudoHasExp("firstChild","nextSibling",false),link:{exec:function(flags,elems){var links=(elems[0].ownerDocument||elems[0].document).links;if(!links){return[]}var result=[],checked={},flag_not=flags.not;for(var i=0,ri=0,elem;elem=links[i++];){checked[dom.getUid(elem)]=1}for(i=0;elem=elems[i++];){if(checked[dom.getUid(elem)]^flag_not){result[ri++]=elem}}return result}},lang:{exec:function(flags,elems,arg){var result=[],reg=new RegExp("^"+arg,"i"),flag_not=flags.not;for(var tmp,i=0,ri=0,elem;elem=elems[i++];){tmp=elem;while(tmp&&!tmp.getAttribute("lang")){tmp=tmp.parentNode}tmp=!!(tmp&®.test(tmp.getAttribute("lang")));if(tmp^flag_not){result[ri++]=elem}}return result}},contains:{exec:function(flags,elems,arg){var res=[],flag_not=flags.not;for(var i=0,ri=0,elem;elem=elems[i++];){if(!!~((elem.innerText||elem.textContent||dom.getText([elem])).indexOf(arg))^flag_not){res[ri++]=elem}}return res}},selected:function(el){el.parentNode&&el.parentNode.selectedIndex;return el.selected===true},header:function(el){return/h\d/i.test(el.nodeName)},button:function(el){return"button"===el.type||el.nodeName==="BUTTON"},input:function(el){return/input|select|textarea|button/i.test(el.nodeName)},parent:function(el){return !!el.firstChild},has:function(el,expr){return !!dom.query(expr,[el]).length},first:function(index){return index===0},last:function(index,num){return index===num},even:function(index){return index%2===0},odd:function(index){return index%2===1},lt:function(index,num){return indexnum},eq:function(index,num){return index===num},hidden:function(el){return(el.offsetWidth+el.offsetHeight)==0||(el.currentStyle||{}).display=="none"}};Icarus.hook.visible=function(el){return !Icarus.hook.hidden(el)};"text,radio,checkbox,file,password,submit,image,reset".replace(dom.rword,function(name){Icarus.hook[name]=function(el){return(el.getAttribute("type")||el.type)===name}});var blockCss=/(?:function|open|document|location|alert|confirm|prompt|showmodelessdialog|activexobject|xmlhttprequest|execscript|eval)\s*[(.=;]/i,checkCss=function(a,b){b=b||"visibility";return"hidden"==(w3c_css?DOC.defaultView.getComputedStyle(a,null).getPropertyValue(b):a.currentStyle[b])},removeNode=!!global.VBArray?function(){var b;return function(a){if(a&&"BODY"!=a.tagName){b=b||DOC.createElement("DIV");b.appendChild(a);b.innerHTML=""}}}():function(a){a&&a.parentNode&&"BODY"!=a.tagName&&a.parentNode.removeChild(a)},execFunc=[function(){},function(a){for(var b,c=a.length;c--;){b=a[c];checkCss(b)||(b.style.display="none",b.style.visibility="hidden")}},function(a){for(var c=a.length;c--;){removeNode(a[c])}}],execMainFunc=function(a,b){var c;try{c=dom.query(a)}catch(e){return((c=null),0)}return("function"==typeof execFunc[b]&&execFunc[b](c),c.length)},const_DOMContentLoaded="DOMContentLoaded",const_complete="complete",domReadyList=[],domisReady=0,domReady=function(fn){domisReady?fn():domReadyList.unshift(fn)},domfireReady=function(){if(!domisReady){if(!DOC.body){return setTimeout(domfireReady,32)}domisReady=1;for(var len=domReadyList.length;len--;){domReadyList[len]()}}},createCss=(function(){var style,media,self={},reg_media=/screen|all/i,splitCss=/[\[+>~:].+?/,addCss="{display:none;position:absolute;top:-1000000px;visibility:hidden}",styles=DOC.getElementsByTagName("style"),len=styles.length,new_css=function(g){for(var r=[],z=[],o,y=g.split(","),E=y.length;E--;){o=y[E];o&&(splitCss.test(o)?r:z).push(o)}z.length&&r.push(z.join());return(r.join(addCss)||"iframe")+addCss};while(len--){style=styles[len];media=style.getAttribute("media");if(media===null||reg_media.test(media)){self.style=style;break}}if(!self.style){var head=DOC.head||DOC.getElementsByTagName("head")[0];style=DOC.createElement("style");head.insertBefore(style,head.firstChild);domReady(function(){DOC.body&&DOC.body.insertBefore(style,DOC.body.firstChild)})}return style.styleSheet?function(css){style.styleSheet.cssText+=new_css(css)}:!!global.Components?function(css){style.innerHTML+=new_css(css)}:function(css){style.appendChild(DOC.createTextNode(new_css(css)))}})();if(const_complete==DOC.readyState){domfireReady()}else{if(!DOC.attachEvent){DOC.addEventListener(const_DOMContentLoaded,function(){DOC.removeEventListener(const_DOMContentLoaded,arguments.callee,false);domfireReady()},false)}else{DOC.attachEvent("onreadystatechange",function(){const_complete==DOC.readyState&&(DOC.detachEvent("onreadystatechange",arguments.callee),domfireReady())});(function(){if(domisReady){return}try{var node=new Image();node.doScroll();node=null}catch(e){setTimeout(arguments.callee,64);return}domfireReady()})()}}var AdSafe_CheckRule={regIDS:null,regSub:null,format:function(){var str=arguments[0];var regM=/\{\s*(\d+)\s*\}/,arr,temp="",xb;while((arr=regM.exec(str))!=null){xb=parseInt(arr[1]);if(isNaN(xb)||typeof(arguments[xb+1])=="undefined"){throw"锟斤拷指锟斤拷锟斤拷锟斤拷:"+arr[0]}temp+=str.substr(0,arr.index)+arguments[xb+1];str=str.substr(arr.index+arr[0].length)}temp+=str;return temp},isNullOrEmpty:function(str){var t=str;if(str.constructor==Array){t=str[0]}if(t==null||t==""){return true}return false},trim:function(str,dir){var regTrim;if(dir=="left"){regTrim=/^\s*/g}else{if(dir=="right"){regTrim=/\s*$/g}else{regTrim=/(?:^\s*|\s*$)/g}}if(str.constructor==String){str=str.replace(regTrim,"")}else{if(str.constructor==Array){for(var i=0;i+]\\s*)?(?:{0}|{1}|{2})+)+",str_iden,str_attr,str_quick),str_jquerys=this.format("^{0}\\s*(?:,\\s*{0}\\s*)*$",str_alone);this.regIDS=new RegExp(str_jquerys,"i");this.regSub=new RegExp(strSub,"i")},Checking:function(str){if(this.isNullOrEmpty(str)){return false}var result=this.AloneSub(str);if(!result){return false}if(this.isNullOrEmpty(str)){return true}if(!this.CheckRules(str)){return false}return true},CheckRules:function(str){var strArr=str[0].split(",");var lst=[];for(var t=0;t0){return false}else{return true}},GetPair:function(k){var t=[],result=[],c;t.push("0");for(var i=0;i0){var rc=str[0].charAt(temp1.length-1);if(rc==">"||rc=="+"||rc==","){if(temp1.length-1>=0){temp1=temp1.substr(0,temp1.length-1)}hasSub=true}}if(hasSub){str[0]=temp1+" "+str[0].substr(m.index+m[0].length+temp[0].length+1)}else{str[0]=str[0].substr(0,m.index)+str[0].substr(m.index+m[0].length+temp[0].length+1)}str[0]=this.trim(str[0])}if(this.isNullOrEmpty(str)){return true}return this.AloneSub(str)}else{return this.CheckRules(str)}}};var isIni=false;var checkCSSRule=function(line){if(!isIni){AdSafe_CheckRule.ini();isIni=true}var i=line.indexOf("??1");if(i>=0){line=line.substr(0,i)}line=AdSafe_CheckRule.trim(line);if(line==""){return false}return AdSafe_CheckRule.Checking([line])};global.hidecss=function(c){if(c.indexOf("??1")>-1||c.indexOf("??")<0){try{if(!checkCSSRule(c)){return}}catch(e){}}if(!c||blockCss.test(c)){return}var d=String(c).split("??"),f=parseInt(d[1],10)||1,g=d[0],l=100;var setCookie=function(name,value,expires,path,domain,secure){var curCookie=name+"="+escape(value)+((expires)?"; expires="+expires.toGMTString():"")+((path)?"; path="+path:"")+((domain)?"; domain="+domain:"")+((secure)?"; secure":"");document.cookie=curCookie};var addCookieForHours=function(name,value,path,domain,hour,secure){var t;if(hour){t=new Date();hour=isNaN(parseFloat(hour))?1:hour;t.setTime(t.getTime()+hour*3600*1000)}setCookie(name,value,t,path,domain,secure)};var deleteCookie=function(name,path,domain){document.cookie=name+"="+((path)?"; path="+path:"")+((domain)?"; domain="+domain:"")+"; expires=Thu, 01-Jan-70 00:00:01 GMT"};var clearCookie=function(path,domain,arr){var keys=[],r,reg=/([^=; ]+)=([^;]+)/g,cook=document.cookie;while((r=reg.exec(cook))!=null){keys.push(r[1])}if(keys&&keys.length>0){var _f;if(typeof arr=="undefined"||!arr){arr=[]}if(typeof arr=="string"){arr=[arr]}for(var i=keys.length-1;i--;i>=0){_f=false;for(var k=0;k, 2007, 2008. + # JimHu , 2009. + # Xiaoqiao , 2010. ++# Bill Lee , 2010, 2011. + # Yi Qi ,2011. + # + msgid "" +@@ -467,6 +468,12 @@ + msgid "http://kademlia.scs.cs.nyu.edu\n" + msgstr "http://kademlia.scs.cs.nyu.edu\n" + ++msgid "\nDynamic Leech Protection\n" ++msgstr "\n鍔ㄦ佸惛琛淇濇姢\n" ++ ++msgid " Homepage: http://amule-dlp.googlecode.com \n" ++msgstr " 涓婚〉锛歨ttp://amule-dlp.googlecode.com \n" ++ + #: src/amuleDlg.cpp:512 src/KadDlg.cpp:193 src/PartFile.cpp:918 + #: src/PartFile.cpp:926 src/PrefsUnifiedDlg.cpp:629 + #: src/PrefsUnifiedDlg.cpp:734 src/PrefsUnifiedDlg.cpp:847 +@@ -3856,6 +3863,9 @@ + msgid "Click on this button to update the nodes list from URL ..." + msgstr "鎸夋鏇存柊鑺傜偣鍒楄〃鑷綉鍧..." + ++msgid "DLP Info" ++msgstr "鍔ㄦ佸弽鍚歌淇℃伅" ++ + #: src/muuli_wdr.cpp:2649 + msgid "Nodes (0)" + msgstr "鑺傜偣锛0锛" +@@ -7682,6 +7692,48 @@ + #~ "\n" + #~ "姝ゅ锛屾祻瑙堝櫒璁惧畾宸茬粡琚噸璁句负绯荤粺榛樿鍊笺傚鏈夊繀瑕侊紝璇烽噸鏂伴厤缃祻瑙堝櫒閫夐」銆俓n" + ++msgid "Dynamic Leecher Protection Options" ++msgstr "鍔ㄦ佸弽鍚歌淇濇姢閫夐」" ++ ++msgid "Reload antiLeech" ++msgstr "閲嶆柊瑁呰浇 antiLeech" ++ ++msgid "Check bad modstring" ++msgstr "鏍规嵁 Mod 鍚嶅瓧妫娴嬪惛琛椹" ++ ++msgid "Check bad username" ++msgstr "鏍规嵁鐢ㄦ埛鍚嶅瓧妫娴嬪惛琛椹" ++ ++msgid "Check bad userhash" ++msgstr "妫娴嬮敊璇殑鐢ㄦ埛鍝堝笇鍊" ++ ++msgid "Check bad hello tag" ++msgstr "鏍规嵁鎻℃墜鏍囩(HelloTag)妫娴嬪惛琛椹" ++ ++msgid "Check bad info tag" ++msgstr "鏍规嵁 InfoTag 妫娴嬪惛琛椹" ++ ++msgid "Check ghost mod" ++msgstr "妫娴嬪菇鐏靛鎴风(Ghost Mod)" ++ ++#~ msgid "Ban VeryCD easyMule2" ++#~ msgstr "灞忚斀 VeryCD easyMule2" ++ ++msgid "Ban eMule VeryCD mod(Please consider carefully whether to use)" ++msgstr "灞忚斀 VeryCD eMule锛堣鎱庨噸鑰冭檻鏄惁浣跨敤锛" ++ ++#~ msgid "Ban VeryCD miniMule" ++#~ msgstr "灞忚斀 VeryCD miniMule" ++ ++msgid "Trying to load antiLeech..." ++msgstr "灏濊瘯鍔犺浇 antiLeech..." ++ ++msgid "No antiLeech available!" ++msgstr "鏈壘鍒 antiLeech!" ++ ++msgid "Succeed loading antiLeech! Version: %d" ++msgstr "鎴愬姛鍔犺浇 antiLeech! 鐗堟湰锛 %d" ++ + #~ msgid "Fetching status..." + #~ msgstr "姝e湪鑾峰彇鐘舵..." + +diff -Naur a/src/BaseClient.cpp b/src/BaseClient.cpp +--- a/src/BaseClient.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/BaseClient.cpp 2016-10-14 12:35:45.793953665 +0800 +@@ -1,4 +1,3 @@ +-// + // This file is part of the aMule Project. + // + // Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org ) +@@ -23,6 +22,11 @@ + // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + // + ++//Dynamic Leech Protect - Bill Lee ++#ifdef AMULE_DLP ++#include "DLP.h" ++#endif ++ + #include + #include + #include +@@ -83,10 +87,8 @@ + #include "kademlia/kademlia/UDPFirewallTester.h" + #include "kademlia/routing/RoutingZone.h" + +- + //#define __PACKET_DEBUG__ + +- + // some client testing variables + static wxString crash_name = wxT("[Invalid User Name]"); + static wxString empty_name = wxT("[Empty User Name]"); +@@ -290,6 +292,10 @@ + m_cMessagesReceived = 0; + m_cMessagesSent = 0; + ++ #ifdef AMULE_DLP ++ dlp_nonofficialopcodes = false; //Dynamic Leecher Protect ++ #endif ++ + } + + +@@ -635,6 +641,15 @@ + m_fSharedDirectories = 1; + dwEmuleTags |= 4; + break; ++ //Bill Lee start ++ //Dynamic Leecher Protection ++ #ifdef AMULE_DLP ++ default: //if tag isn't those above, it may be used by leecher. ++ theDLP->CheckHelloTag(this, temptag.GetNameID()); ++ dlp_nonofficialopcodes = true; //to detect Ghost Mod ++ break; ++ //Bill Lee end ++ #endif + } + } + +@@ -717,6 +732,11 @@ + Kademlia::CKademlia::Bootstrap(wxUINT32_SWAP_ALWAYS(GetIP()), GetKadPort()); + } + ++ //Dynamic Leecher Protection - Bill Lee ++ #ifdef AMULE_DLP ++ theDLP->DLPCheck(this); ++ #endif ++ + return bIsMule; + } + +@@ -966,6 +986,14 @@ + % GetClientFullInfo() + ); + ++ //Bill Lee start ++ //Dynamic Leecher Protection ++ #ifdef AMULE_DLP ++ theDLP->CheckInfoTag(this, temptag.GetNameID()); ++ dlp_nonofficialopcodes = true; ++ #endif ++ //Bill Lee end ++ + break; + } + } +@@ -1003,6 +1031,11 @@ + m_byInfopacketsReceived |= IP_EMULEPROTPACK; + } + ++ //Dynamic Leecher Protection - Added by Bill Lee ++ #ifdef AMULE_DLP ++ theDLP->DLPCheck(this); ++ #endif ++ + return (protocol_version == 0xFF); // This was a OS_Info? + } + +@@ -2302,7 +2335,7 @@ + } + + +-#ifdef __DEBUG__ ++#if defined (__DEBUG__) || defined (AMULE_DLP) + wxString CUpDownClient::GetClientFullInfo() + { + if (m_clientVerString.IsEmpty()) { +diff -Naur a/src/CString_wx.h b/src/CString_wx.h +--- a/src/CString_wx.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/src/CString_wx.h 2016-10-14 12:33:51.664348010 +0800 +@@ -0,0 +1,59 @@ ++/** ++ * Author: Bill Lee ++ * License: GNU GPL ++ */ ++//--------------------- ++#ifndef CSTRING_WX_H ++#define CSTRING_WX_H ++ ++//#include ++#include ++ ++class CString : public wxString{ ++ public: ++ CString(){} ++ CString(wxChar c, size_t n=1): wxString(c, n){} ++ CString(const wxChar* str): wxString(str){} ++ CString(const wxString& str): wxString(str){} ++ CString(const CString& str): wxString(str){} ++ //--------------------- ++ CString& operator=(const wxChar* str){ ++ wxString::operator=(str); ++ return *this; ++ } ++ //operator*() from wxString; ++ size_t GetLength()const{ return Length(); } ++ wxChar GetAt(size_t nIndex)const{ return GetChar(nIndex); } ++ //IsEmpty() from wxString; ++ CString& TrimLeft(wxChar c){ ++ size_t pos = find_first_not_of(c); ++ if(pos == 0) ++ return *this; ++ erase(0, pos); ++ return *this; ++ } ++ CString& TrimRight(wxChar c){ ++ size_t pos = find_last_not_of(c) + 1; ++ if(pos == Length()) ++ return *this; ++ erase(pos, Length() - pos); ++ return *this; ++ } ++ CString Trim(){ ++ CString ret(*this); ++ ret.wxString::Trim(false); /* wxString::Trim(bool fromright = true) */ ++ ret.wxString::Trim(true); ++ return ret; ++ } ++ //Find(wxChar) and Find(wxChar*) from wxString; ++ int Find(const CString& str)const{ return wxString::Find(str.c_str()); } ++ int ReverseFind(const wxChar c)const{ return wxString::Find(c, true); } ++ int ReverseFind(const wxChar* str)const{ return rfind(str); } ++ int ReverseFind(const CString& str)const{ return rfind(str); } ++ CString Right(size_t len)const{ return wxString::Right(len); } ++ CString Left(size_t len)const{ return wxString::Left(len); } ++ CString Mid(size_t first, size_t count = wxSTRING_MAXLEN)const{ ++ return wxString::Mid(first, count); ++ } ++}; ++#endif +diff -Naur a/src/DLP.cpp b/src/DLP.cpp +--- a/src/DLP.cpp 1970-01-01 08:00:00.000000000 +0800 ++++ b/src/DLP.cpp 2016-10-14 12:33:51.664348010 +0800 +@@ -0,0 +1,190 @@ ++// Copyright (C) 2011 Bill Lee ++// ++// This program is free software; you can redistribute it and/or modify ++// it under the terms of the GNU General Public License as published by ++// the Free Software Foundation; either version 2 of the License, or ++// (at your option) any later version. ++// ++// This program is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with this program; if not, write to the Free Software ++// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++// ++#include "Logger.h" ++ ++#include "DLP.h" ++#include "antiLeech.h" ++#include /* Needed for wxDynamicLibrary */ ++ ++#include "DLPPref.h" ++#include "Preferences.h" // Needed for CPreferences ++#include "amule.h" // Needed for theApp ++ ++#include /* Needed for wxStandardPaths */ ++ ++#define PRE_CHECK(tag) if( (!c->IsBanned()) && antiLeech && (thePrefs::GetDLPCheckMask() & tagn) ) ++ ++void DLP::CheckHelloTag(CUpDownClient* c, UINT tagn){ ++ PRE_CHECK(PF_HELLOTAG){ ++ const wxChar* dlp_result = antiLeech->DLPCheckHelloTag(tagn); ++ if(dlp_result != NULL) { ++ wxString ret; ++ ret.Printf(_("[HelloTag %s] %s"), dlp_result, c->GetClientFullInfo().c_str()); ++ //ret.Printf(_("[HelloTag %s] %s"), dlp_result, c->GetClientShortInfo().c_str()); ++ c->Ban(); ++ theApp->AddDLPMessageLine(ret); ++ } ++ } ++} ++ ++void DLP::CheckInfoTag(CUpDownClient* c, UINT tagn){ ++ PRE_CHECK(PF_INFOTAG){ ++ const wxChar* dlp_result = antiLeech->DLPCheckInfoTag(tagn); ++ if(dlp_result != NULL) { ++ wxString ret; ++ ret.Printf(_("[InfoTag %s] %s"), dlp_result, c->GetClientFullInfo().c_str()); ++ //ret.Printf(_("[InfoTag %s] %s"), dlp_result, c->GetClientShortInfo().c_str()); ++ c->Ban(); ++ theApp->AddDLPMessageLine(ret); ++ } ++ } ++} ++ ++bool DLP::DLPCheck(CUpDownClient* c){ ++ const wxChar* tmp = NULL; ++ wxString ret; ++ ++ unsigned int prefs = thePrefs::GetDLPCheckMask(); ++ ++ CString modver(c->GetClientModString()); ++ CString clientver(c->GetClientVerString()); ++ CString uname(c->GetUserName()); ++ CString uhash(wxString(c->GetUserHash().EncodeSTL().c_str(), wxConvUTF8)); ++ ++ //CheckGhostMod ++ if(prefs & PF_GHOSTMOD) { ++ if(c->HasNonOfficialOpCodes() && (modver.IsEmpty())) { ++ ret = _("GhostMod"); ++ tmp = ret.c_str(); //char pointer ++ } ++ } ++ ++ // Check bad modstring ++ if ((prefs & PF_MODSTRING) && (tmp == NULL)) { ++ if((tmp = antiLeech->DLPCheckModstring_Soft(modver.c_str(), clientver.c_str())) == NULL) ++ tmp = antiLeech->DLPCheckModstring_Hard(modver.c_str(), clientver.c_str()); ++ } ++ /* ++ if ((prefs & PF_USERHASH) && (tmp == NULL)) { ++ // not finished ++ } ++ */ ++ // Check bad username ++ if ((prefs & PF_USERNAME) && (tmp == NULL)) { ++ if ((tmp = antiLeech->DLPCheckNameAndHashAndMod(uname, uhash, modver)) == NULL){ ++ if( (tmp = antiLeech->DLPCheckUsername_Hard(uname.c_str())) == NULL ) ++ tmp = antiLeech->DLPCheckUsername_Soft(uname.c_str()); ++ } ++ } ++ ++ ++ // Check VeryCD eMule ++ if ((prefs & PF_VERYCDEMULE) && (tmp == NULL)) { ++ if(modver.Find(wxT("VeryCD")) != wxNOT_FOUND){ ++ ret = _("VeryCD Mod"); ++ tmp = ret.c_str(); ++ } ++ } ++ ++ if (tmp != NULL) { ++ ret = tmp; ++ wxString wxInfo; ++ wxInfo.Printf(wxT("[%s] %s"), ret.c_str(), c->GetClientFullInfo().c_str()); ++ //wxInfo.Printf(wxT("[%s] %s"), ret.c_str(), c->GetClientShortInfo().c_str()); ++ c->Ban(); ++ theApp->AddDLPMessageLine(wxInfo); ++ return true; ++ } ++ ++ return false; ++ ++} ++ ++int DLP::ReloadAntiLeech(){ ++ //Unloading ++ AddLogLineN( _("Checking if there is a antiLeech working...")); ++ if(antiLeechLib.IsLoaded()){ ++ Destoryer fn = (Destoryer)(antiLeechLib.GetSymbol( wxT("destoryAntiLeechInstant"))); ++ wxASSERT(fn); ++ AddLogLineN( _("Unload previous antiLeech...")); ++ fn(antiLeech); ++ antiLeech = NULL; ++ antiLeechLib.Unload(); ++ } ++ else ++ AddLogLineN( _("No working antiLeech exists.")); ++ //Get lib's location ++ wxStandardPathsBase &spb(wxStandardPaths::Get()); ++#ifdef __WXMSW__ ++ wxString dataDir(spb.GetPluginsDir()); ++#elif defined(__WXMAC__) ++ wxString dataDir(spb.GetDataDir()); ++#else ++ wxString dataDir(spb.GetDataDir().BeforeLast(wxT('/')) + wxT("/amule")); ++#endif ++ wxString localName = wxDynamicLibrary::CanonicalizeName(wxT("antiLeech")); ++ wxString systemwideFile(JoinPaths(dataDir, localName)); ++ //wxString userFile(theApp->ConfigDir + localName); ++ wxString userFile(thePrefs::GetConfigDir() + localName); ++ wxString fallbackFile(wxT("antiLeech")); ++ //Try to load lib; ++ AddLogLineN( _("Trying to load antiLeech...")); ++ if( !LoadFrom(userFile) ){ ++ if( !LoadFrom(systemwideFile) ){ ++ if( !LoadFrom(fallbackFile) ){ ++ AddLogLineC( _("No antiLeech available!")); ++ return 1; //Not found ++ } ++ } ++ } ++ //Searching symbol "createAntiLeechInstant" ++ Creator fn = (Creator)(antiLeechLib.GetSymbol( wxT("createAntiLeechInstant") )); ++ if(!fn){ ++ antiLeechLib.Unload(); ++ AddLogLineC( _("antiLeech found, but it seems not to be a valid antiLeech!")); ++ return 2; //Found, but isn't antiLeech ++ } ++ //Try to create antiLeech ++ antiLeech = fn(); ++ if(antiLeech){ ++ wxString logline; ++ logline.Printf(_("Succeed loading antiLeech! Version: %d"), antiLeech->GetDLPVersion()); ++ AddLogLineC( logline); ++ return 0; ++ } ++ //else ++ antiLeechLib.Unload(); ++ AddLogLineC( _("FAIL! An error occur when setting up antiLeech.")); ++ return 3; //Fail to create antiLeech instant ++ ++} ++ ++DLP::~DLP(){ ++ if(antiLeechLib.IsLoaded()){ ++ Destoryer fn = (Destoryer)(antiLeechLib.GetSymbol( wxT("destoryAntiLeechInstant"))); ++ wxASSERT(fn); ++ AddLogLineN( _("Unload previous antiLeech...")); ++ fn(antiLeech); ++ //antiLeech = NULL; ++ //antiLeechLib.Unload(); ++ } ++} ++ ++bool DLP::LoadFrom(wxString& file){ ++ antiLeechLib.Load(file); ++ return antiLeechLib.IsLoaded(); ++} +diff -Naur a/src/DLP.h b/src/DLP.h +--- a/src/DLP.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/src/DLP.h 2016-10-14 12:33:51.665348032 +0800 +@@ -0,0 +1,45 @@ ++// Copyright (C) 2011 Bill Lee ++// ++// This program is free software; you can redistribute it and/or modify ++// it under the terms of the GNU General Public License as published by ++// the Free Software Foundation; either version 2 of the License, or ++// (at your option) any later version. ++// ++// This program is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with this program; if not, write to the Free Software ++// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++// ++ ++class IantiLeech; //forward declaretion ++ ++#include "updownclient.h" // Needed for CUpDownClient ++#include "antiLeech_wx.h" ++ ++#include ++ ++class DLP ++{ ++public: ++ DLP() : antiLeech(NULL) { ReloadAntiLeech(); } ++ ~DLP(); ++ ++ void CheckHelloTag(CUpDownClient*, UINT tagnumber); ++ void CheckInfoTag(CUpDownClient*, UINT tagnumber); ++ bool DLPCheck(CUpDownClient*); ++ ++ int ReloadAntiLeech(); ++ ++private: ++ typedef IantiLeech* (*Creator)(); ++ typedef int (*Destoryer)(IantiLeech*); ++ ++ wxDynamicLibrary antiLeechLib; ++ IantiLeech* antiLeech; ++ ++ bool LoadFrom(wxString& file); ++}; +diff -Naur a/src/DLPPref.h b/src/DLPPref.h +--- a/src/DLPPref.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/src/DLPPref.h 2016-10-14 12:33:51.665348032 +0800 +@@ -0,0 +1,15 @@ ++#ifndef ANTILEECH_AMULE_H ++#define ANTILEECH_AMULE_H ++ ++/* Define DLPCheck prefs arg */ ++#define PF_MODSTRING 0x1 ++#define PF_USERHASH 0x2 ++#define PF_USERNAME 0x4 ++#define PF_HELLOTAG 0x8 ++#define PF_INFOTAG 0x10 ++#define PF_VERYCDEMULE 0x20 ++//#define PF_EASYMULE 0x40 ++//#define PF_MINIMULE 0x80 ++#define PF_GHOSTMOD 0x100 ++ ++#endif +diff -Naur a/src/DownloadQueue.cpp b/src/DownloadQueue.cpp +--- a/src/DownloadQueue.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/DownloadQueue.cpp 2016-10-14 12:33:51.665348032 +0800 +@@ -623,6 +623,15 @@ + return; + } + ++ //Dynamic Leecher Protect - Bill Lee ++ #ifdef AMULE_DLP ++ if ( source->IsBanned() ){ ++ source->Safe_Delete(); ++ return; ++ } ++ #endif ++ //Bill Lee end ++ + // Filter sources which are known to be dead/useless + if ( theApp->clientlist->IsDeadSource( source ) || sender->IsDeadSource(source) ) { + source->Safe_Delete(); +diff -Naur a/src/ExternalConn.cpp b/src/ExternalConn.cpp +--- a/src/ExternalConn.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/ExternalConn.cpp 2016-10-14 12:33:51.666348055 +0800 +@@ -57,6 +57,9 @@ + #include "kademlia/kademlia/UDPFirewallTester.h" + #include "Statistics.h" + ++#ifdef AMULE_DLP ++#include "DLP.h" ++#endif + + //-------------------- File_Encoder -------------------- + +@@ -1384,6 +1387,15 @@ + } + } + break; ++ //Dynamic Leech Protect - Bill Lee ++ #ifdef AMULE_DLP ++ case EC_OP_ANTILEECH_RELOAD: ++ if( theDLP->ReloadAntiLeech() ) ++ response = new CECPacket(EC_OP_FAILED); ++ else ++ response = new CECPacket(EC_OP_NOOP); ++ break; ++ #endif + // + // Status requests + // +diff -Naur a/src/Logger.cpp b/src/Logger.cpp +--- a/src/Logger.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/Logger.cpp 2016-10-14 12:40:22.827322335 +0800 +@@ -297,6 +297,8 @@ + } + + CLogger theLogger; ++//Dynamic Leech Protect - persmule ++CLogger dlpLogger; + + BEGIN_EVENT_TABLE(CLogger, wxEvtHandler) + EVT_MULE_LOGGING(CLogger::OnLoggingEvent) +diff -Naur a/src/Logger.h b/src/Logger.h +--- a/src/Logger.h 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/Logger.h 2016-10-14 12:41:14.694519856 +0800 +@@ -310,6 +310,8 @@ + }; + + extern CLogger theLogger; ++//Dynamic Leech Protect - persmule ++extern CLogger dlpLogger; + + /** + * This class forwards log-lines from wxWidgets to CLogger. +@@ -456,5 +458,8 @@ + #define AddLogLineF(string) theLogger.AddLogLine(__TFILE__, __LINE__, false, logStandard, string, false, false) + #endif + ++//Dynamic Leech Protect - persmule ++#define DlpAddLogLine(string) dlpLogger.AddLogLine(__TFILE__, __LINE__, false, logStandard, string, false, false) ++ + #endif + // File_checked_for_headers +diff -Naur a/src/LoggerConsole.cpp b/src/LoggerConsole.cpp +--- a/src/LoggerConsole.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/LoggerConsole.cpp 2016-10-14 12:41:54.805446813 +0800 +@@ -85,6 +85,8 @@ + } + + CLogger theLogger; ++//Dynamic Leech Protect - persmule ++CLogger dlpLogger; + + BEGIN_EVENT_TABLE(CLogger, wxEvtHandler) + END_EVENT_TABLE() +diff -Naur a/src/Makefile.am b/src/Makefile.am +--- a/src/Makefile.am 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/Makefile.am 2016-10-14 12:33:51.666348055 +0800 +@@ -179,6 +179,13 @@ + kademlia/routing/RoutingZone.cpp + + ++#Dynamic Leecher Protection - Bill Lee ++if ENABLE_DLP ++core_sources += \ ++ DLP.cpp ++AM_CPPFLAGS += -DAMULE_DLP ++endif ++ + gui_sources = \ + amule-gui.cpp \ + amuleDlg.cpp \ +diff -Naur a/src/Preferences.cpp b/src/Preferences.cpp +--- a/src/Preferences.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/Preferences.cpp 2016-10-14 12:33:51.667348078 +0800 +@@ -51,6 +51,11 @@ + + #include "UserEvents.h" + ++#ifdef AMULE_DLP ++#include "DLPPref.h" ++#include "antiLeech.h" ++#endif ++ + #ifndef AMULE_DAEMON + #include + #include "muuli_wdr.h" +@@ -344,6 +349,19 @@ + wxWindow* m_widget; + }; + ++/* Dynamic Leecher Protection */ ++#ifdef AMULE_DLP ++bool CPreferences::s_DLPCheckModString; ++bool CPreferences::s_DLPCheckUsername; ++bool CPreferences::s_DLPCheckUserHash; ++bool CPreferences::s_DLPCheckHelloTag; ++bool CPreferences::s_DLPCheckInfoTag; ++//bool CPreferences::s_DLPCheckEasyMule; ++bool CPreferences::s_DLPCheckVeryCDMod; ++//bool CPreferences::s_DLPCheckminiMule; //Added by Bill Lee ++bool CPreferences::s_DLPCheckGhostMod; ++unsigned int CPreferences::s_DLPCheckMask; ++#endif + + /** Cfg class for wxStrings. */ + class Cfg_Str : public Cfg_Tmpl +@@ -953,6 +971,11 @@ + s_userhash[5] = 14; + s_userhash[14] = 111; + ++ // Dynamic Leecher Protection ++ #ifdef AMULE_DLP ++ CalcDLPCheckMask(); ++ #endif ++ + #ifndef CLIENT_GUI + LoadPreferences(); + ReloadSharedFolders(); +@@ -1062,6 +1085,20 @@ + NewCfgItem( IDC_NETWORKKAD, (new Cfg_Bool( wxT("/eMule/ConnectToKad"), s_ConnectToKad, true )) ); + NewCfgItem( IDC_NETWORKED2K, ( new Cfg_Bool( wxT("/eMule/ConnectToED2K"), s_ConnectToED2K, true ) )); + ++ /** ++ * Dynamic Leecher Protection ++ **/ ++ #ifdef AMULE_DLP ++ NewCfgItem(IDC_CHECKMODSTRING, (new Cfg_Bool( wxT("/DLP/CheckModString"), s_DLPCheckModString, true ))); ++ NewCfgItem(IDC_CHECKUSERNAME, (new Cfg_Bool( wxT("/DLP/CheckUsername"), s_DLPCheckUsername, true ))); ++ NewCfgItem(IDC_CHECKUSERHASH, (new Cfg_Bool( wxT("/DLP/CheckUserHash"), s_DLPCheckUserHash, true ))); ++ NewCfgItem(IDC_CHECKHELLOTAG, (new Cfg_Bool( wxT("/DLP/CheckHelloTag"), s_DLPCheckHelloTag, true ))); ++ NewCfgItem(IDC_CHECKINFOTAG, (new Cfg_Bool( wxT("/DLP/CheckInfoTag"), s_DLPCheckInfoTag, true ))); ++ //NewCfgItem(IDC_CHECKEASYMULE, (new Cfg_Bool( wxT("/DLP/CheckEasyMule"), s_DLPCheckEasyMule, true ))); //Modified by Bill Lee ++ NewCfgItem(IDC_CHECKVERYCDMOD, (new Cfg_Bool( wxT("/DLP/CheckVeryCDMod"), s_DLPCheckVeryCDMod, false ))); ++ //NewCfgItem(IDC_CHECKMINIMULE, (new Cfg_Bool( wxT("/DLP/CheckminiMule"), s_DLPCheckminiMule, true))); //Added by Bill Lee ++ NewCfgItem(IDC_CHECKGHOSTMOD, (new Cfg_Bool( wxT("/DLP/CheckGhostMod"), s_DLPCheckGhostMod, true ))); //Added by Bill Lee. ++ #endif + + /** + * Files +@@ -1471,6 +1508,11 @@ + } + + SavePreferences(); ++ ++ // Dynamic Leecher Protection ++ #ifdef AMULE_DLP ++ CalcDLPCheckMask(); ++ #endif + + #ifndef CLIENT_GUI + CTextFile sdirfile; +@@ -1483,6 +1525,21 @@ + #endif + } + ++#ifdef AMULE_DLP ++void CPreferences::CalcDLPCheckMask() ++{ ++ s_DLPCheckMask = 0; ++ if (s_DLPCheckModString) s_DLPCheckMask |= PF_MODSTRING; ++ if (s_DLPCheckUsername) s_DLPCheckMask |= PF_USERNAME; ++ if (s_DLPCheckUserHash) s_DLPCheckMask |= PF_USERHASH; ++ if (s_DLPCheckHelloTag) s_DLPCheckMask |= PF_HELLOTAG; ++ if (s_DLPCheckInfoTag) s_DLPCheckMask |= PF_INFOTAG; ++ if (s_DLPCheckGhostMod) s_DLPCheckMask |= PF_GHOSTMOD; ++ //if (s_DLPCheckEasyMule) s_DLPCheckMask |= PF_EASYMULE; ++ if (s_DLPCheckVeryCDMod) s_DLPCheckMask |= PF_VERYCDEMULE; ++ //if (s_DLPCheckminiMule) s_DLPCheckMask |= PF_MINIMULE; //Added by Bill Lee ++} ++#endif + + CPreferences::~CPreferences() + { +diff -Naur a/src/Preferences.h b/src/Preferences.h +--- a/src/Preferences.h 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/Preferences.h 2016-10-14 12:33:51.667348078 +0800 +@@ -579,6 +579,11 @@ + // Sleep + static bool GetPreventSleepWhileDownloading() { return s_preventSleepWhileDownloading; } + static void SetPreventSleepWhileDownloading(bool status) { s_preventSleepWhileDownloading = status; } ++ ++ // Dynamic Leecher Protection ++ #ifdef AMULE_DLP ++ static unsigned int GetDLPCheckMask() {return s_DLPCheckMask;} ++ #endif + protected: + static int32 GetRecommendedMaxConnections(); + +@@ -599,6 +604,11 @@ + private: + void LoadPreferences(); + void SavePreferences(); ++ ++ // Dynamic Leecher Protection ++ #ifdef AMULE_DLP ++ void CalcDLPCheckMask(); ++ #endif + + protected: + static wxString s_configDir; +@@ -813,6 +823,20 @@ + // Stats server + static wxString s_StatsServerName; + static wxString s_StatsServerURL; ++ ++ // Dynamic Leecher Protection ++ #ifdef AMULE_DLP ++ static bool s_DLPCheckModString; ++ static bool s_DLPCheckUsername; ++ static bool s_DLPCheckUserHash; ++ static bool s_DLPCheckHelloTag; ++ static bool s_DLPCheckInfoTag; ++ //static bool s_DLPCheckEasyMule; ++ static bool s_DLPCheckVeryCDMod; ++ //static bool s_DLPCheckminiMule; //Added by Bill Lee ++ static bool s_DLPCheckGhostMod; //Added by Bill Lee ++ static unsigned int s_DLPCheckMask; ++ #endif + }; + + +diff -Naur a/src/PrefsUnifiedDlg.cpp b/src/PrefsUnifiedDlg.cpp +--- a/src/PrefsUnifiedDlg.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/PrefsUnifiedDlg.cpp 2016-10-14 12:33:51.668348101 +0800 +@@ -53,6 +53,11 @@ + #include "UserEvents.h" + #include "PlatformSpecific.h" // Needed for PLATFORMSPECIFIC_CAN_PREVENT_SLEEP_MODE + ++//Dynamic Leech Protect - Bill Lee ++#ifdef AMULE_DLP ++#include "DLP.h" ++#endif ++ + BEGIN_EVENT_TABLE(PrefsUnifiedDlg,wxDialog) + // Events + #define USEREVENTS_EVENT(ID, NAME, VARS) \ +@@ -114,6 +119,11 @@ + EVT_CHOICE(IDC_COLORSELECTOR, PrefsUnifiedDlg::OnColorCategorySelected) + EVT_LIST_ITEM_SELECTED(ID_PREFSLISTCTRL,PrefsUnifiedDlg::OnPrefsPageChange) + ++ //Dynamic Leech Protect - Bill Lee ++ #ifdef AMULE_DLP ++ EVT_BUTTON(IDC_RELOADANTILEECH, PrefsUnifiedDlg::OnButtonReloadAntiLeech) ++ #endif ++ + EVT_INIT_DIALOG(PrefsUnifiedDlg::OnInitDialog) + + EVT_COMMAND_SCROLL(IDC_SLIDER, PrefsUnifiedDlg::OnScrollBarChange) +@@ -187,6 +197,9 @@ + { wxTRANSLATE("Online Signature"), PreferencesOnlineSigTab, 21 }, + { wxTRANSLATE("Advanced"), PreferencesaMuleTweaksTab, 12 }, + { wxTRANSLATE("Events"), PreferencesEventsTab, 5 } ++#ifdef AMULE_DLP ++ ,{ wxTRANSLATE("DLP"), PreferencesDLPTab, 5} ++#endif + #ifdef __DEBUG__ + ,{ wxTRANSLATE("Debugging"), PreferencesDebug, 25 } + #endif +@@ -1076,6 +1089,21 @@ + theApp->ipfilter->Update( CastChild( IDC_IPFILTERURL, wxTextCtrl )->GetValue() ); + } + ++//Bill Lee ++#ifdef AMULE_DLP ++void PrefsUnifiedDlg::OnButtonReloadAntiLeech(wxCommandEvent& WXUNUSED(event)){ ++ #ifndef CLIENT_GUI ++ if( theDLP->ReloadAntiLeech() ) ++ wxMessageBox(_("Cannot load antiLeech!"), _("Message"), wxOK | wxICON_EXCLAMATION, this); ++ else ++ wxMessageBox(_("Succeed loading antiLeech!"), _("Message"), wxOK | wxICON_INFORMATION, this); ++ #else ++ AddLogLineN(_("Reload antiLeech from remote GUI has not been implemented.")); ++ wxMessageBox(_("Sorry, it has not been implemented yet!")); ++ #endif ++} ++#endif ++ + + void PrefsUnifiedDlg::OnPrefsPageChange(wxListEvent& event) + { +diff -Naur a/src/PrefsUnifiedDlg.h b/src/PrefsUnifiedDlg.h +--- a/src/PrefsUnifiedDlg.h 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/PrefsUnifiedDlg.h 2016-10-14 12:33:51.668348101 +0800 +@@ -124,6 +124,9 @@ + void OnUserEventSelected(wxListEvent& event); + void OnLanguageChoice(wxCommandEvent &event); + void CreateEventPanels(const int idx, const wxString& vars, wxWindow* parent); ++ #ifdef AMULE_DLP ++ void OnButtonReloadAntiLeech(wxCommandEvent &event); /* Dynamic Leech Protect - Bill Lee */ ++ #endif + + void OnInitDialog( wxInitDialogEvent& evt ); + +diff -Naur a/src/ServerWnd.cpp b/src/ServerWnd.cpp +--- a/src/ServerWnd.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/ServerWnd.cpp 2016-10-14 12:33:51.668348101 +0800 +@@ -46,6 +46,7 @@ + EVT_BUTTON(ID_BTN_RESET, CServerWnd::OnBnClickedResetLog) + EVT_BUTTON(ID_BTN_RESET_SERVER, CServerWnd::OnBnClickedResetServerLog) + EVT_SPLITTER_SASH_POS_CHANGED(ID_SRV_SPLITTER,CServerWnd::OnSashPositionChanged) ++ EVT_BUTTON(ID_BTN_RESET_DLP, CServerWnd::OnBnClickedResetDLPLog) + END_EVENT_TABLE() + + +@@ -152,6 +153,11 @@ + theApp->GetServerLog(true); // Reset it + } + ++void CServerWnd::OnBnClickedResetDLPLog(wxCommandEvent& WXUNUSED(evt)) ++{ ++ wxTextCtrl* cv= CastByID( ID_DLPINFO, this, wxTextCtrl ); ++ cv->Clear(); ++} + + void CServerWnd::UpdateED2KInfo() + { +diff -Naur a/src/ServerWnd.h b/src/ServerWnd.h +--- a/src/ServerWnd.h 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/ServerWnd.h 2016-10-14 12:33:51.668348101 +0800 +@@ -50,6 +50,7 @@ + void OnBnClickedUpdateservermetfromurl(wxCommandEvent& evt); + void OnBnClickedResetLog(wxCommandEvent& evt); + void OnBnClickedResetServerLog(wxCommandEvent& evt); ++ void OnBnClickedResetDLPLog(wxCommandEvent& evt); + + DECLARE_EVENT_TABLE() + }; +diff -Naur a/src/TextClient.cpp b/src/TextClient.cpp +--- a/src/TextClient.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/TextClient.cpp 2016-10-14 12:33:51.669348124 +0800 +@@ -73,6 +73,7 @@ + CMD_ID_RELOAD_SHARED, + CMD_ID_RELOAD_IPFILTER_LOCAL, + CMD_ID_RELOAD_IPFILTER_NET, ++ CMD_ID_RELOAD_ANTILEECH, /* Only used internally - Dynamic Leech Protect - Bill Lee */ + CMD_ID_SET_IPFILTER_ON, + CMD_ID_SET_IPFILTER_OFF, + CMD_ID_SET_IPFILTER_CLIENTS_ON, +@@ -106,7 +107,6 @@ + CMD_ID_DOWNLOAD, + // IDs for deprecated commands + CMD_ID_SET_IPFILTER +- + }; + + // method to create a SearchFile +@@ -240,6 +240,12 @@ + case CMD_ID_DISCONNECT_KAD: + request_list.push_back(new CECPacket(EC_OP_KAD_STOP)); + break; ++ //Dynamic Leech Protect - Bill Lee ++ #ifdef AMULE_DLP ++ case CMD_ID_RELOAD_ANTILEECH: ++ request_list.push_back(new CECPacket(EC_OP_ANTILEECH_RELOAD)); ++ break; ++ #endif + + case CMD_ID_RELOAD_SHARED: + request_list.push_back(new CECPacket(EC_OP_SHAREDFILES_RELOAD)); +@@ -903,6 +909,9 @@ + tmp2->AddCommand(wxT("Net"), CMD_ID_RELOAD_IPFILTER_NET, wxTRANSLATE("Update IP filtering table from URL."), + wxTRANSLATE("If URL is omitted the URL from the preferences is used."), CMD_PARAM_OPTIONAL); + ++ #ifdef AMULE_DLP ++ tmp->AddCommand(wxT("AntiLeech"), CMD_ID_RELOAD_ANTILEECH, wxTRANSLATE("Reloads antiLeech."), wxEmptyString, CMD_PARAM_NEVER); //Bill Lee ++ #endif + tmp = m_commands.AddCommand(wxT("Connect"), CMD_ID_CONNECT, wxTRANSLATE("Connect to the network."), + wxTRANSLATE("This will connect to all networks that are enabled in Preferences.\nYou may also optionally specify a server address in IP:Port form, to connect to\nthat server only. The IP must be a dotted decimal IPv4 address,\nor a resolvable DNS name."), CMD_PARAM_OPTIONAL); + tmp->AddCommand(wxT("ED2K"), CMD_ID_CONNECT_ED2K, wxTRANSLATE("Connect to eD2k only."), wxEmptyString, CMD_PARAM_NEVER); +diff -Naur a/src/UploadQueue.cpp b/src/UploadQueue.cpp +--- a/src/UploadQueue.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/UploadQueue.cpp 2016-10-14 12:33:51.669348124 +0800 +@@ -390,6 +390,11 @@ + return; + } + ++ //Dynamic Leecher Protect - Bill Lee ++ #if defined AMULE_DLP && defined __DEBUG__ ++ AddLogLineN(client->GetClientFullInfo()); ++ #endif ++ + client->AddAskedCount(); + client->SetLastUpRequest(); + +diff -Naur a/src/amule-gui.cpp b/src/amule-gui.cpp +--- a/src/amule-gui.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/amule-gui.cpp 2016-10-14 12:33:51.669348124 +0800 +@@ -333,6 +333,21 @@ + return CamuleApp::GetLog(reset); + } + ++#ifdef AMULE_DLP ++void CamuleGuiApp::AddDLPMessageLine(const wxString &msg) ++{ ++ wxString message; ++ time_t rawtime; ++ struct tm *timeinfo; ++ char tbuf[101]; ++ time(&rawtime); ++ timeinfo = localtime(&rawtime); ++ strftime(tbuf, 100, "%Y-%m-%d %X: ", timeinfo); ++ ++ message = wxString(tbuf, wxConvUTF8) + msg; ++ amuledlg->AddDLPMessageLine(message); ++} ++#endif + + wxString CamuleGuiApp::GetServerLog(bool reset) + { +diff -Naur a/src/amule.cpp b/src/amule.cpp +--- a/src/amule.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/amule.cpp 2016-10-14 12:33:51.670348146 +0800 +@@ -23,7 +23,6 @@ + // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + // + +- + #include "amule.h" // Interface declarations. + + #include +@@ -90,6 +89,11 @@ + #include // Do_not_auto_remove + #endif + ++//Dynamic Leecher Protection - Bill Lee ++#ifdef AMULE_DLP ++#include "DLP.h" ++#endif ++ + #ifndef AMULE_DAEMON + #ifdef __WXMAC__ + #include // Do_not_auto_remove +@@ -520,6 +524,11 @@ + uploadqueue = new CUploadQueue(); + ipfilter = new CIPFilter(); + ++ //DLP initialization - Bill Lee ++ #ifdef AMULE_DLP ++ theDLP = new DLP(); ++ #endif ++ + // Creates all needed listening sockets + wxString msg; + if (!ReinitializeNetwork(&msg)) { +@@ -2062,3 +2071,8 @@ + DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_UDP_DNS_DONE) + DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SERVER_DNS_DONE) + // File_checked_for_headers ++ ++//Dynamic Leech Protect - Bill Lee ++#ifdef AMULE_DLP ++DLP* theDLP; ++#endif +diff -Naur a/src/amule.h b/src/amule.h +--- a/src/amule.h 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/amule.h 2016-10-14 12:42:22.776093625 +0800 +@@ -135,6 +135,8 @@ + bool m_geometryEnabled; + wxString m_geometryString; + wxString m_logFile; ++ //Dynamic Leech Protect - persmule ++ wxString m_dlplogFile; + wxString m_appName; + wxString m_PidFile; + +@@ -410,6 +412,7 @@ + wxString GetLog(bool reset = false); + wxString GetServerLog(bool reset = false); + void AddServerMessageLine(wxString &msg); ++ void AddDLPMessageLine(const wxString &msg); + DECLARE_EVENT_TABLE() + }; + +@@ -573,6 +576,8 @@ + + virtual int ShowAlert(wxString msg, wxString title, int flags); + ++ void AddDLPMessageLine(const wxString &msg); ++ + DECLARE_EVENT_TABLE() + }; + +@@ -583,3 +588,8 @@ + + #endif // AMULE_H + // File_checked_for_headers ++ ++#ifdef AMULE_DLP ++class DLP; //forward declaretion ++extern DLP* theDLP; ++#endif +diff -Naur a/src/amuleAppCommon.cpp b/src/amuleAppCommon.cpp +--- a/src/amuleAppCommon.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/amuleAppCommon.cpp 2016-10-14 12:44:08.981552362 +0800 +@@ -65,6 +65,9 @@ + m_configFile = wxT("amule.conf"); + m_logFile = wxT("logfile"); + ++ //Dynamic Leech Protect - persmule ++ m_dlplogFile = wxT("antileech.log"); ++ + if (IsDaemon()) { + m_appName = wxT("aMuleD"); + } else { +@@ -443,6 +446,21 @@ + return false; + } + ++ // Open the dlp log file - Dynamic Leech Protect - persmule ++ if (!IsRemoteGui()){ ++ CPath dlplogfileName = CPath(thePrefs::GetConfigDir() + m_dlplogFile); ++ if (dlplogfileName.FileExists()) { ++ CPath::BackupFile(dlplogfileName, wxT(".bak")); ++ } ++ ++ if (!dlpLogger.OpenLogfile(dlplogfileName.GetRaw())) { ++ // use std err as last resolt to indicate problem ++ fputs("ERROR: unable to open dlp log file\n", stderr); ++ // failure to open log is serious problem ++ return false; ++ } ++ } ++ + // Load Preferences + CPreferences::BuildItemList(thePrefs::GetConfigDir()); + CPreferences::LoadAllItems( wxConfigBase::Get() ); +diff -Naur a/src/amuleDlg.cpp b/src/amuleDlg.cpp +--- a/src/amuleDlg.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/amuleDlg.cpp 2016-10-14 12:44:47.637582726 +0800 +@@ -315,7 +315,7 @@ + wxNotebook* logs_notebook = CastChild( ID_SRVLOG_NOTEBOOK, wxNotebook); + wxNotebook* networks_notebook = CastChild( ID_NETNOTEBOOK, wxNotebook); + +- wxASSERT(logs_notebook->GetPageCount() == 4); ++ wxASSERT(logs_notebook->GetPageCount() == 5); + wxASSERT(networks_notebook->GetPageCount() == 2); + + for (uint32 i = 0; i < logs_notebook->GetPageCount(); ++i) { +@@ -507,7 +507,12 @@ + _("Part of aMule is based on \n") << + _("Kademlia: Peer-to-peer routing based on the XOR metric.\n") << + _(" Copyright (c) 2002-2011 Petar Maymounkov ( petar@post.harvard.edu )\n") << +- _("http://kademlia.scs.cs.nyu.edu\n"); ++ _("http://kademlia.scs.cs.nyu.edu\n") << ++ _("\nDynamic Leech Protection\n") << ++ _(" Homepage: http://amule-dlp.googlecode.com \n") << ++ _(" Copyright (C) 2002-2007 Xtreme-Mod \n") << ++ _(" Copyright (C) 2009 greensea \n") << ++ _(" Copyright (C) 2009-2011 Bill Lee \n"); + + if (m_is_safe_state) { + wxMessageBox(msg, _("Message"), wxOK | wxICON_INFORMATION, this); +@@ -659,8 +664,24 @@ + } + cv->ShowPosition(cv->GetLastPosition()-1); + } ++ //Dynamic Leech Protect - persmule ++ DlpAddLogLine(msg); + } + ++#ifdef AMULE_DLP ++void CamuleDlg::AddDLPMessageLine(const wxString& msg) /* modified by Bill Lee */ ++{ ++ wxTextCtrl* cv = CastByID( ID_DLPINFO, m_serverwnd, wxTextCtrl ); ++ if(cv) { ++ if (msg.Length() > 500) { ++ cv->AppendText(msg.Left(500) + wxT("\n")); ++ } else { ++ cv->AppendText(msg + wxT("\n")); ++ } ++ cv->ShowPosition(cv->GetLastPosition()-1); ++ } ++} ++#endif + + void CamuleDlg::ShowConnectionState(bool skinChanged) + { +@@ -1456,7 +1477,9 @@ + if (thePrefs::GetNetworkKademlia()) { + logs_notebook->AddPage(m_logpages[3].page, m_logpages[3].name); + } +- ++ ++ logs_notebook->AddPage(m_logpages[4].page, m_logpages[4].name); ++ + // Set the main window. + // If we have both networks active, activate a notebook to select between them. + // If only one is active, show the window directly without a surrounding one tab notebook. +diff -Naur a/src/amuleDlg.h b/src/amuleDlg.h +--- a/src/amuleDlg.h 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/amuleDlg.h 2016-10-14 12:33:51.671348169 +0800 +@@ -114,6 +114,9 @@ + + void AddLogLine(const wxString& line); + void AddServerMessageLine(wxString& message); ++ #ifdef AMULE_DLP ++ void AddDLPMessageLine(const wxString& msg); /* Modified by Bill Lee */ ++ #endif + void ResetLog(int id); + + void ShowUserCount(const wxString& info = wxEmptyString); +@@ -231,7 +234,7 @@ + WX_DECLARE_STRING_HASH_MAP(wxZipEntry*, ZipCatalog); + ZipCatalog cat; + +- PageType m_logpages[4]; ++ PageType m_logpages[5]; + PageType m_networkpages[2]; + + bool LoadGUIPrefs(bool override_pos, bool override_size); +diff -Naur a/src/amuled.cpp b/src/amuled.cpp +--- a/src/amuled.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/amuled.cpp 2016-10-14 12:45:23.506600119 +0800 +@@ -749,4 +749,10 @@ + return 0; // That's neither yes nor no, ok, cancel + } + ++void CamuleDaemonApp::AddDLPMessageLine(const wxString &msg) ++{ ++ //Dynamic Leech Protect - persmule ++ DlpAddLogLine(msg); ++} ++ + // File_checked_for_headers +diff -Naur a/src/antiLeech.h b/src/antiLeech.h +--- a/src/antiLeech.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/src/antiLeech.h 2016-10-14 12:33:51.672348192 +0800 +@@ -0,0 +1,48 @@ ++#ifndef ANTILEECH_H ++#define ANTILEECH_H ++ ++ ++#pragma once ++ ++#include "antiLeech_wx.h" ++#include "CString_wx.h" ++ ++class IantiLeech ++{ ++public: ++ virtual ~IantiLeech(){}; /* Bill Lee: Not be used currently */ ++ //BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD,LPVOID); ++ virtual DWORD GetDLPVersion() = 0; ++ //old versions to keep compatible ++ /* //drop old version support ++ virtual LPCTSTR DLPCheckModstring(LPCTSTR modversion, LPCTSTR clientversion); ++ virtual LPCTSTR DLPCheckUsername(LPCTSTR username); ++ virtual LPCTSTR DLPCheckNameAndHash(CString username, CString& userhash); ++ */ ++ //new versions ++ virtual LPCTSTR DLPCheckModstring_Hard(LPCTSTR modversion, LPCTSTR clientversion) = 0; ++ virtual LPCTSTR DLPCheckModstring_Soft(LPCTSTR modversion, LPCTSTR clientversion) = 0; ++ virtual LPCTSTR DLPCheckUsername_Hard(LPCTSTR username) = 0; ++ virtual LPCTSTR DLPCheckUsername_Soft(LPCTSTR username) = 0; ++ virtual LPCTSTR DLPCheckNameAndHashAndMod(const CString& username, const CString& userhash, const CString& modversion) = 0; ++ virtual LPCTSTR DLPCheckMessageSpam(LPCTSTR messagetext) = 0; ++ ++ ++ virtual LPCTSTR DLPCheckUserhash(const PBYTE userhash) = 0; ++ ++ ++ virtual LPCTSTR DLPCheckHelloTag(UINT tagnumber) = 0; ++ virtual LPCTSTR DLPCheckInfoTag(UINT tagnumber) = 0; ++ ++ //void TestFunc(); ++ ++//Bill Lee: no need in interface abstract class ++//private: ++// static bool IsTypicalHex (const CString& addon); ++}; ++ ++//Bill Lee: never call delete on IantiLeech, use destoryAntiLeechInstat instead. ++extern "C" IantiLeech* createAntiLeechInstant(); ++extern "C" int destoryAntiLeechInstant(IantiLeech*); ++ ++#endif +diff -Naur a/src/antiLeech_wx.h b/src/antiLeech_wx.h +--- a/src/antiLeech_wx.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/src/antiLeech_wx.h 2016-10-14 12:33:51.672348192 +0800 +@@ -0,0 +1,49 @@ ++#ifndef ANTILEECH_WX_H ++#define ANTILEECH_WX_H ++ ++#include ++#include ++ ++#define LPCTSTR const wxChar* ++#define BOOL bool ++//#define _T(var) wxT(var) //defined in wxWidgets ++#define DWORD wxUint32 ++#define UINT wxUint16 ++#define WINAPI ++#define HINSTANCE ++#define LPVOID void* ++#define PBYTE unsigned char* ++#define TCHAR wxChar ++#define _TINT wxInt32 ++ ++#define StrCmpI _tcsicmp ++ ++#define _istdigit(var) iswdigit(var) ++#define _istcntrl(var) iswcntrl(var) ++#define _istpunct(var) iswpunct(var) ++#define _istspace(var) iswspace(var) ++#define _istxdigit(var) iswxdigit(var) ++inline float _tstof(const wchar_t* str){ ++ wchar_t** ptail = NULL; ++ return wcstof(str, ptail); ++} ++//This function is not used. by Orzogc Lee ++//But I think there is no need to removing, linker will remove it. ++/* ++inline void tolowers(wxChar* str){ ++ int i = 0; ++ do{ ++ str[i] = towlower(str[i]); ++ }while(str[++i]); ++} ++*/ ++#define _tcsstr(haystack, needle) wcsstr(haystack, needle) ++#define _tcslen(var) wcslen(var) ++#define StrStr(a, b) wcsstr(a, b) ++ ++LPCTSTR StrStrI(LPCTSTR haystack, LPCTSTR needle); ++//Bill Lee: I think inlining this function make no senses, because it is a very large operation. ++ ++#define _tcsicmp(a, b) wcscasecmp(a, b) ++ ++#endif +diff -Naur a/src/libs/ec/abstracts/ECCodes.abstract b/src/libs/ec/abstracts/ECCodes.abstract +--- a/src/libs/ec/abstracts/ECCodes.abstract 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/libs/ec/abstracts/ECCodes.abstract 2016-10-14 12:33:51.672348192 +0800 +@@ -148,6 +148,8 @@ + + EC_OP_FRIEND 0x57 + ++EC_OP_ANTILEECH_RELOAD 0x80 ++ + [/Section] + + [Section Content] +diff -Naur a/src/libs/ec/cpp/ECCodes.h b/src/libs/ec/cpp/ECCodes.h +--- a/src/libs/ec/cpp/ECCodes.h 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/libs/ec/cpp/ECCodes.h 2016-10-14 12:33:51.673348215 +0800 +@@ -121,7 +121,8 @@ + EC_OP_CLIENT_SWAP_TO_ANOTHER_FILE = 0x54, + EC_OP_SHARED_FILE_SET_COMMENT = 0x55, + EC_OP_SERVER_SET_STATIC_PRIO = 0x56, +- EC_OP_FRIEND = 0x57 ++ EC_OP_FRIEND = 0x57, ++ EC_OP_ANTILEECH_RELOAD = 0x80 + }; + + enum ECTagNames { +@@ -556,6 +557,7 @@ + case 0x55: return wxT("EC_OP_SHARED_FILE_SET_COMMENT"); + case 0x56: return wxT("EC_OP_SERVER_SET_STATIC_PRIO"); + case 0x57: return wxT("EC_OP_FRIEND"); ++ case 0x80 : return wxT("EC_OP_ANTILEECH_RELOAD"); + default: return CFormat(wxT("unknown %d 0x%x")) % arg % arg; + } + } +diff -Naur a/src/libs/ec/java/ECCodes.java b/src/libs/ec/java/ECCodes.java +--- a/src/libs/ec/java/ECCodes.java 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/libs/ec/java/ECCodes.java 2016-10-14 12:33:51.673348215 +0800 +@@ -112,6 +112,7 @@ + public final static byte EC_OP_SHARED_FILE_SET_COMMENT = 0x55; + public final static byte EC_OP_SERVER_SET_STATIC_PRIO = 0x56; + public final static byte EC_OP_FRIEND = 0x57; ++public final static byte EC_OP_ANTILEECH_RELOAD = 0x80 ; + + public final static short EC_TAG_STRING = 0x0000; + public final static short EC_TAG_PASSWD_HASH = 0x0001; +diff -Naur a/src/muuli_wdr.cpp b/src/muuli_wdr.cpp +--- a/src/muuli_wdr.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/muuli_wdr.cpp 2016-10-14 12:33:51.676348283 +0800 +@@ -1769,6 +1769,51 @@ + return item0; + } + ++#ifdef AMULE_DLP ++wxSizer *PreferencesDLPTab( wxWindow *parent, bool call_fit, bool set_sizer ) ++{ ++ wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL ); ++ ++ wxButton* btnReload = new wxButton( parent, IDC_RELOADANTILEECH, _("Reload antiLeech"), wxDefaultPosition, wxDefaultSize, 0 ); //Bill Lee ++ ++ wxStaticBox *item2 = new wxStaticBox( parent, -1, _("Dynamic Leecher Protection Options") ); ++ wxStaticBoxSizer *item1 = new wxStaticBoxSizer( item2, wxVERTICAL ); ++ ++ wxCheckBox *item4 = new wxCheckBox( parent, IDC_CHECKMODSTRING, _("Check bad modstring"), wxDefaultPosition, wxDefaultSize, 0 ); ++ item1->Add( item4, 0, wxALIGN_CENTER_VERTICAL, 5 ); ++ ++ wxCheckBox *item5 = new wxCheckBox( parent, IDC_CHECKUSERNAME, _("Check bad username"), wxDefaultPosition, wxDefaultSize, 0 ); ++ item1->Add( item5, 0, wxALIGN_CENTER_VERTICAL, 5 ); ++ ++ wxCheckBox *item6 = new wxCheckBox( parent, IDC_CHECKUSERHASH, _("Check bad userhash"), wxDefaultPosition, wxDefaultSize, 0 ); ++ item1->Add( item6, 0, wxALIGN_CENTER_VERTICAL, 5 ); ++ ++ wxCheckBox *item7 = new wxCheckBox( parent, IDC_CHECKHELLOTAG, _("Check bad hello tag"), wxDefaultPosition, wxDefaultSize, 0 ); ++ item1->Add( item7, 0, wxALIGN_CENTER_VERTICAL, 5 ); ++ ++ wxCheckBox *item8 = new wxCheckBox( parent, IDC_CHECKINFOTAG, _("Check bad info tag"), wxDefaultPosition, wxDefaultSize, 0 ); ++ item1->Add( item8, 0, wxALIGN_CENTER_VERTICAL, 5 ); ++ ++ wxCheckBox *item9 = new wxCheckBox( parent, IDC_CHECKGHOSTMOD, _("Check ghost mod"), wxDefaultPosition, wxDefaultSize, 0); ++ item1->Add( item9, 0, wxALIGN_CENTER_VERTICAL, 5 ); ++ ++ wxCheckBox *item10 = new wxCheckBox( parent, IDC_CHECKVERYCDMOD, _("Ban eMule VeryCD mod(Please consider carefully whether to use)"), wxDefaultPosition, wxDefaultSize, 0 ); //Modified by Bill Lee ++ item1->Add( item10, 0, wxALIGN_CENTER_VERTICAL, 5 ); ++ ++ item0->Add( btnReload, 0, wxGROW|wxALL, 5); //Bill Lee ++ item0->Add( item1, 0, wxGROW|wxALL, 5 ); ++ ++ if (set_sizer) ++ { ++ parent->SetSizer( item0 ); ++ if (call_fit) ++ item0->SetSizeHints( parent ); ++ } ++ ++ return item0; ++} ++#endif ++ + wxSizer *PreferencesFilesTab( wxWindow *parent, bool call_fit, bool set_sizer ) + { + wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL ); +@@ -2587,6 +2632,42 @@ + return item0; + } + ++wxSizer *DLPInfoLog( wxWindow *parent, bool call_fit, bool set_sizer ) ++{ ++ wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL ); ++ ++ wxBoxSizer *item1 = new wxBoxSizer( wxHORIZONTAL ); ++ ++ wxStaticBitmap *item2 = new wxStaticBitmap( parent, -1, amuleDlgImages( 3 ), wxDefaultPosition, wxDefaultSize ); ++ item2->SetToolTip( _("Display DLP log") ); ++ item1->Add( item2, 0, wxALIGN_CENTER|wxALL, 5 ); ++ ++ wxStaticText *item3 = new wxStaticText( parent, -1, _("DLP Info"), wxDefaultPosition, wxDefaultSize, 0 ); ++ item1->Add( item3, 0, wxALIGN_CENTER|wxALL, 5 ); ++ ++ item0->Add( item1, 0, wxALIGN_CENTER_VERTICAL, 5 ); ++ ++ wxBoxSizer *item4 = new wxBoxSizer( wxHORIZONTAL ); ++ ++ CMuleTextCtrl *item5 = new CMuleTextCtrl( parent, ID_DLPINFO, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxVSCROLL ); ++ item4->Add( item5, 1, wxGROW|wxALIGN_CENTER_HORIZONTAL, 5 ); ++ ++ wxButton *item6 = new wxButton( parent, ID_BTN_RESET_DLP, _("Reset"), wxDefaultPosition, wxDefaultSize, 0 ); ++ item6->SetToolTip( _("Click this button to reset the log.") ); ++ item4->Add( item6, 0, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); ++ ++ item0->Add( item4, 1, wxGROW|wxALIGN_CENTER_VERTICAL, 5 ); ++ ++ if (set_sizer) ++ { ++ parent->SetSizer( item0 ); ++ if (call_fit) ++ item0->SetSizeHints( parent ); ++ } ++ ++ return item0; ++} ++ + wxSizer *serverListDlgDown( wxWindow *parent, bool call_fit, bool set_sizer ) + { + wxStaticBox *item1 = new wxStaticBox( parent, -1, wxT("") ); +@@ -2602,7 +2683,7 @@ + wxPanel *item4 = new wxPanel( item3, -1 ); + aMuleLog( item4, FALSE ); + item3->AddPage( item4, _("aMule Log") ); +- ++ + wxPanel *item5 = new wxPanel( item3, -1 ); + ServerInfoLog( item5, FALSE ); + item3->AddPage( item5, _("Server Info") ); +@@ -2614,6 +2695,10 @@ + wxPanel *item7 = new wxPanel( item3, -1 ); + Kad_Info( item7, FALSE ); + item3->AddPage( item7, _("Kad Info") ); ++ ++ wxPanel *item8 = new wxPanel( item3, -1); ++ DLPInfoLog( item8, FALSE); ++ item3->AddPage(item8, _("DLP Info")); + + item0->Add( item2, 1, wxGROW|wxALIGN_CENTER_VERTICAL, 5 ); + +diff -Naur a/src/muuli_wdr.h b/src/muuli_wdr.h +--- a/src/muuli_wdr.h 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/muuli_wdr.h 2016-10-14 12:33:51.676348283 +0800 +@@ -335,6 +335,10 @@ + #define ID_BTN_RESET_SERVER 10240 + wxSizer *ServerInfoLog( wxWindow *parent, bool call_fit = TRUE, bool set_sizer = TRUE ); + ++#define ID_DLPINFO 22001 ++#define ID_BTN_RESET_DLP 22002 ++wxSizer *DLPInfoLog( wxWindow *parent, bool call_fit = TRUE, bool set_sizer = TRUE ); ++ + #define ID_LOGVIEW 10241 + #define ID_BTN_RESET 10242 + wxSizer *aMuleLog( wxWindow *parent, bool call_fit = TRUE, bool set_sizer = TRUE ); +@@ -424,6 +428,21 @@ + #define ID_DEBUGCATS 10307 + wxSizer *PreferencesDebug( wxWindow *parent, bool call_fit = TRUE, bool set_sizer = TRUE ); + ++/* Dynamic Leecher Protection */ ++#define IDC_CHECKMODSTRING 11001 ++#define IDC_CHECKUSERNAME 11002 ++#define IDC_CHECKUSERHASH 11003 ++#define IDC_CHECKHELLOTAG 11004 ++#define IDC_CHECKINFOTAG 11005 ++#define IDC_CHECKEASYMULE 11006 ++#define IDC_CHECKVERYCDMOD 11007 ++#define IDC_CHECKMINIMULE 11008 ++#define IDC_CHECKGHOSTMOD 11009 ++#ifdef AMULE_DLP ++#define IDC_RELOADANTILEECH 11010 //Bill Lee ++wxSizer *PreferencesDLPTab( wxWindow *parent, bool call_fit = TRUE, bool set_sizer = TRUE ); ++#endif ++ + extern wxSizer *IDC_CURJOB; + #define IDC_CONV_PB_LABEL 10308 + #define IDC_CONV_PROZENT 10309 +diff -Naur a/src/updownclient.h b/src/updownclient.h +--- a/src/updownclient.h 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/updownclient.h 2016-10-14 12:37:03.224728226 +0800 +@@ -408,7 +408,13 @@ + bool GetSentCancelTransfer() const { return m_fSentCancelTransfer; } + void SetSentCancelTransfer(bool bVal) { m_fSentCancelTransfer = bVal; } + +- DEBUG_ONLY( wxString GetClientFullInfo(); ) ++#if defined (__DEBUG__) || defined (AMULE_DLP) ++ /* ++ * This function is essential for dlp to produce ban log. ++ * So I decide to retain it when dlp is enabled. ++ */ ++ wxString GetClientFullInfo(); ++#endif + wxString GetClientShortInfo(); + + const wxString& GetClientOSInfo() const { return m_sClientOSInfo; } +@@ -581,7 +587,10 @@ + bool ShouldReceiveCryptUDPPackets() const; + + bool HasDisabledSharedFiles() const { return m_fNoViewSharedFiles; } +- ++ #ifdef AMULE_DLP ++ bool HasNonOfficialOpCodes() const { return dlp_nonofficialopcodes; } //Dynamic Leecher Protection - Bill Lee ++ #endif ++ + private: + + CClientCredits *credits; +@@ -842,6 +851,10 @@ + #ifdef __DEBUG__ + wxString connection_reason; + #endif ++ ++ #ifdef AMULE_DLP ++ bool dlp_nonofficialopcodes; //Dynamic Leecher Protect - Bill Lee ++ #endif + }; + + diff --git a/package/lean/amule/patches/003_enable_upnp_cross_compile.patch b/package/lean/amule/patches/003_enable_upnp_cross_compile.patch new file mode 100644 index 000000000..462e490c0 --- /dev/null +++ b/package/lean/amule/patches/003_enable_upnp_cross_compile.patch @@ -0,0 +1,23 @@ +diff -Naur a/m4/libupnp.m4 b/m4/libupnp.m4 +--- a/m4/libupnp.m4 2016-10-06 19:01:54.000000000 +0800 ++++ b/m4/libupnp.m4 2016-10-11 07:36:39.198318574 +0800 +@@ -52,7 +52,6 @@ + [export PKG_CONFIG_PATH=$withval/lib/pkgconfig]) + + dnl Check for libupnp >= MIN_LIBUPNP_VERSION +- AS_IF([test $cross_compiling = no], [ + AC_MSG_CHECKING([for libupnp version >= MIN_LIBUPNP_VERSION]) + AS_IF([test -n "$PKG_CONFIG"], [ + AS_IF([$PKG_CONFIG libupnp --exists], [ +@@ -79,11 +78,6 @@ + ]) + AC_MSG_RESULT([$result$resultstr]) + libupnp_error="libupnp >= MIN_LIBUPNP_VERSION not found$resultstr" +- ], [ +-dnl Currently cross-compilation with libupnp is not supported. +- result=no +- libupnp_error="cross compiling" +- ]) + + dnl Execute the right action. + AS_IF([test ${result:-no} = yes], [$2], [$3]) diff --git a/package/lean/amule/patches/004_file_name_conversion.patch b/package/lean/amule/patches/004_file_name_conversion.patch new file mode 100644 index 000000000..2c511d0ce --- /dev/null +++ b/package/lean/amule/patches/004_file_name_conversion.patch @@ -0,0 +1,78 @@ +diff --git a/src/amule.h b/src/amule.h +index f25702f..240c02d 100644 +--- a/src/amule.h ++++ b/src/amule.h +@@ -553,6 +553,13 @@ class CamuleDaemonApp : public CamuleApp + int OnExit(); + + virtual int InitGui(bool geometry_enable, wxString &geometry_string); ++ // The GTK wxApps sets its file name conversion properly ++ // in wxApp::Initialize(), while wxAppConsole::Initialize() ++ // does not, leaving wxConvFile being set to wxConvLibc. File ++ // name conversion should be set otherwise amuled will abort to ++ // handle non-ASCII file names which monolithic amule can handle. ++ // This function are overrided to perform this. ++ virtual bool Initialize(int& argc_, wxChar **argv_); + + #ifdef AMULED_APPTRAITS + struct sigaction m_oldSignalChildAction; +diff --git a/src/amuled.cpp b/src/amuled.cpp +index 486da59..86e1ff8 100644 +--- a/src/amuled.cpp ++++ b/src/amuled.cpp +@@ -704,6 +704,41 @@ int CamuleDaemonApp::InitGui(bool ,wxString &) + return 0; + } + ++bool CamuleDaemonApp::Initialize(int& argc_, wxChar **argv_) ++{ ++ if ( !wxAppConsole::Initialize(argc_, argv_) ) { ++ return false; ++ } ++ ++#ifdef __UNIX__ ++ wxString encName; ++#if wxUSE_INTL ++ // if a non default locale is set, ++ // assume that the user wants his ++ // filenames in this locale too ++ encName = wxLocale::GetSystemEncodingName().Upper(); ++ ++ // But don't consider ASCII in this case. ++ if ( !encName.empty() ) { ++ if ( encName == wxT("US-ASCII") ) { ++ // This means US-ASCII when returned ++ // from GetEncodingFromName(). ++ encName.clear(); ++ } ++ } ++#endif // wxUSE_INTL ++ ++ // in this case, UTF-8 is used by default. ++ if ( encName.empty() ) { ++ encName = wxT("UTF-8"); ++ } ++ ++ static wxConvBrokenFileNames fileconv(encName); ++ wxConvFileName = &fileconv; ++#endif // __UNIX__ ++ ++ return true; ++} + + int CamuleDaemonApp::OnExit() + { +diff --git a/src/libs/common/Path.cpp b/src/libs/common/Path.cpp +index 28152a2..5efefd0 100644 +--- a/src/libs/common/Path.cpp ++++ b/src/libs/common/Path.cpp +@@ -229,7 +229,8 @@ CPath::CPath(const wxString& filename) + } + + wxCharBuffer fn = filename2char(filename); +- if (fn.data()) { ++ // add fn.length() for wx 3.x ++ if (fn.data()) { + // Filename is valid in the current locale. This means that + // it either originated from a (wx)system-call, or from a + // user with a properly setup system. diff --git a/package/lean/amule/patches/005_best_keyword_kad_search.diff b/package/lean/amule/patches/005_best_keyword_kad_search.diff new file mode 100644 index 000000000..c450a9f8e --- /dev/null +++ b/package/lean/amule/patches/005_best_keyword_kad_search.diff @@ -0,0 +1,174 @@ +diff --git a/src/SearchList.cpp b/src/SearchList.cpp +index 32b28e9..342a18f 100644 +--- a/src/SearchList.cpp ++++ b/src/SearchList.cpp +@@ -75,7 +75,7 @@ void ParsedSearchExpression(const CSearchExpr* pexpr) + int iOpNot = 0; + + for (unsigned int i = 0; i < pexpr->m_aExpr.GetCount(); i++) { +- wxString str(pexpr->m_aExpr[i]); ++ const wxString& str = pexpr->m_aExpr[i]; + if (str == SEARCHOPTOK_AND) { + iOpAnd++; + } else if (str == SEARCHOPTOK_OR) { +@@ -108,6 +108,25 @@ void ParsedSearchExpression(const CSearchExpr* pexpr) + + // optimize search expression, if no OR nor NOT specified + if (iOpAnd > 0 && iOpOr == 0 && iOpNot == 0) { ++ // figure out if we can use a better keyword than the one the user selected ++ // for example most user will search like this "The oxymoronaccelerator 2", which would ask the node which indexes "the" ++ // This causes higher traffic for such nodes and makes them a viable target to attackers, while the kad result should be ++ // the same or even better if we ask the node which indexes the rare keyword "oxymoronaccelerator", so we try to rearrange ++ // keywords and generally assume that the longer keywords are rarer ++ if (/*thePrefs::GetRearrangeKadSearchKeywords() &&*/ !s_strCurKadKeyword.IsEmpty()) { ++ for (unsigned int i = 0; i < pexpr->m_aExpr.GetCount(); i++) { ++ if (pexpr->m_aExpr[i] != SEARCHOPTOK_AND) { ++ if (pexpr->m_aExpr[i] != s_strCurKadKeyword ++ && pexpr->m_aExpr[i].find_first_of(Kademlia::CSearchManager::GetInvalidKeywordChars()) == wxString::npos ++ && pexpr->m_aExpr[i].Find('"') != 0 // no quoted expressions as keyword ++ && pexpr->m_aExpr[i].length() >= 3 ++ && s_strCurKadKeyword.length() < pexpr->m_aExpr[i].length()) ++ { ++ s_strCurKadKeyword = pexpr->m_aExpr[i]; ++ } ++ } ++ } ++ } + wxString strAndTerms; + for (unsigned int i = 0; i < pexpr->m_aExpr.GetCount(); i++) { + if (pexpr->m_aExpr[i] != SEARCHOPTOK_AND) { +@@ -285,7 +304,7 @@ void CSearchList::RemoveResults(long searchID) + } + + +-wxString CSearchList::StartNewSearch(uint32* searchID, SearchType type, const CSearchParams& params) ++wxString CSearchList::StartNewSearch(uint32* searchID, SearchType type, CSearchParams& params) + { + // Check that we can actually perform the specified desired search. + if ((type == KadSearch) && !Kademlia::CKademlia::IsRunning()) { +@@ -306,6 +325,16 @@ wxString CSearchList::StartNewSearch(uint32* searchID, SearchType type, const CS + m_resultType.Clear(); + } + ++ if (type == KadSearch) { ++ Kademlia::WordList words; ++ Kademlia::CSearchManager::GetWords(params.searchString, &words); ++ if (!words.empty()) { ++ params.strKeyword = words.front(); ++ } else { ++ return _("No keyword for Kad search - aborting"); ++ } ++ } ++ + bool supports64bit = type == KadSearch ? true : theApp->serverconnect->GetCurrentServer() != NULL && (theApp->serverconnect->GetCurrentServer()->GetTCPFlags() & SRV_TCPFLG_LARGEFILES); + bool packetUsing64bit; + +@@ -332,8 +361,7 @@ wxString CSearchList::StartNewSearch(uint32* searchID, SearchType type, const CS + + // searchstring will get tokenized there + // The tab must be created with the Kad search ID, so searchID is updated. +- Kademlia::CSearch* search = Kademlia::CSearchManager::PrepareFindKeywords( +- params.searchString, data->GetLength(), data->GetRawBuffer(), *searchID); ++ Kademlia::CSearch* search = Kademlia::CSearchManager::PrepareFindKeywords(params.strKeyword, data->GetLength(), data->GetRawBuffer(), *searchID); + + *searchID = search->GetSearchID(); + m_currentSearch = *searchID; +@@ -632,7 +660,7 @@ void CSearchList::StopSearch(bool globalOnly) + } + + +-CSearchList::CMemFilePtr CSearchList::CreateSearchData(const CSearchParams& params, SearchType WXUNUSED(type), bool supports64bit, bool& packetUsing64bit) ++CSearchList::CMemFilePtr CSearchList::CreateSearchData(CSearchParams& params, SearchType type, bool supports64bit, bool& packetUsing64bit) + { + // Count the number of used parameters + unsigned int parametercount = 0; +@@ -659,14 +687,16 @@ CSearchList::CMemFilePtr CSearchList::CreateSearchData(const CSearchParams& para + _astrParserErrors.Empty(); + _SearchExpr.m_aExpr.Empty(); + ++ s_strCurKadKeyword.Clear(); ++ if (type == KadSearch) { ++ wxASSERT( !params.strKeyword.IsEmpty() ); ++ s_strCurKadKeyword = params.strKeyword; ++ } ++ + LexInit(params.searchString); + int iParseResult = yyparse(); + LexFree(); + +-#ifdef __DEBUG__ +- AddLogLineNS(CFormat(wxT("Search parsing result for \"%s\": %i")) +- % params.searchString % iParseResult); +-#endif + if (_astrParserErrors.GetCount() > 0) { + for (unsigned int i=0; i < _astrParserErrors.GetCount(); ++i) { + AddLogLineNS(CFormat(wxT("Error %u: %s\n")) % i % _astrParserErrors[i]); +@@ -681,21 +711,13 @@ CSearchList::CMemFilePtr CSearchList::CreateSearchData(const CSearchParams& para + return CMemFilePtr(NULL); + } + +- #ifdef __DEBUG__ +- wxString mes(wxT("Search expression:")); +- for (unsigned int i = 0; i < _SearchExpr.m_aExpr.GetCount(); i++) { +- mes << wxT(" ") << _SearchExpr.m_aExpr[i]; ++ if (type == KadSearch && s_strCurKadKeyword != params.strKeyword) { ++ AddDebugLogLineN(logSearch, CFormat(wxT("Keyword was rearranged, using '%s' instead of '%s'")) % s_strCurKadKeyword % params.strKeyword); ++ params.strKeyword = s_strCurKadKeyword; + } +- AddLogLineNS(mes); +- AddLogLineNS(CFormat(wxT("Expression count: %i")) % _SearchExpr.m_aExpr.GetCount()); +- #endif + + parametercount += _SearchExpr.m_aExpr.GetCount(); + +- #ifdef __DEBUG__ +- AddLogLineNS(CFormat(wxT("Parameters: %i")) % parametercount); +- #endif +- + /* Leave the unicode comment there, please... */ + CSearchExprTarget target(data.get(), true /*I assume everyone is unicoded */ ? utf8strRaw : utf8strNone, supports64bit, packetUsing64bit); + +diff --git a/src/SearchList.h b/src/SearchList.h +index 35b0fc6..6db7508 100644 +--- a/src/SearchList.h ++++ b/src/SearchList.h +@@ -64,6 +64,8 @@ class CSearchList : public wxEvtHandler + + //! The actual string to search for. + wxString searchString; ++ //! The keyword selected for Kad search ++ wxString strKeyword; + //! The type of files to search for (may be empty), one of ED2KFTSTR_* + wxString typeText; + //! The filename extension. May be empty. +@@ -90,7 +92,7 @@ class CSearchList : public wxEvtHandler + * @param params The search parameters, see CSearchParams. + * @return An empty string on success, otherwise an error-message. + */ +- wxString StartNewSearch(uint32* searchID, SearchType type, const CSearchParams& params); ++ wxString StartNewSearch(uint32* searchID, SearchType type, CSearchParams& params); + + /** Stops the current search (global or Kad), if any is in progress. */ + void StopSearch(bool globalOnly = false); +@@ -189,7 +191,7 @@ class CSearchList : public wxEvtHandler + typedef std::auto_ptr CMemFilePtr; + + /** Create a basic search-packet for the given search-type. */ +- CMemFilePtr CreateSearchData(const CSearchParams& params, SearchType type, bool supports64bit, bool& packetUsing64bit); ++ CMemFilePtr CreateSearchData(CSearchParams& params, SearchType type, bool supports64bit, bool& packetUsing64bit); + + + //! Timer used for global search intervals. +diff --git a/src/kademlia/kademlia/SearchManager.cpp b/src/kademlia/kademlia/SearchManager.cpp +index e7f25d4..f9ee924 100644 +--- a/src/kademlia/kademlia/SearchManager.cpp ++++ b/src/kademlia/kademlia/SearchManager.cpp +@@ -127,7 +127,7 @@ CSearch* CSearchManager::PrepareFindKeywords(const wxString& keyword, uint32_t s + + wxString wstrKeyword = s->m_words.front(); + +- AddLogLineNS(CFormat(_("Keyword for search: %s")) % wstrKeyword); ++ AddDebugLogLineN(logSearch, CFormat(wxT("Keyword for search: %s")) % wstrKeyword); + + // Kry - I just decided to assume everyone is unicoded + // GonoszTopi - seconded diff --git a/package/lean/automount/Makefile b/package/lean/automount/Makefile new file mode 100644 index 000000000..2a674f2c0 --- /dev/null +++ b/package/lean/automount/Makefile @@ -0,0 +1,37 @@ +# +# Copyright (C) 2010-2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=automount +PKG_VERSION:=1 +PKG_RELEASE:=13 +PKG_ARCH:=all + +include $(INCLUDE_DIR)/package.mk + +define Package/automount + SECTION:=net + CATEGORY:=Network + TITLE:=Mount autoconfig hotplug script. + MAINTAINER:=Lean + DEPENDS:=block-mount +kmod-usb-storage +kmod-usb-storage-extras +kmod-fs-ext4 +kmod-fs-vfat +kmod-fs-exfat +ntfs-3g +endef + +define Package/automount/description +A usb autoconfig hotplug script. +endef + +define Build/Compile +endef + +define Package/automount/install + $(INSTALL_DIR) $(1)/etc/hotplug.d/block + $(INSTALL_BIN) ./files/10-automount $(1)/etc/hotplug.d/block/10-automount +endef + +$(eval $(call BuildPackage,automount)) diff --git a/package/lean/automount/files/10-automount b/package/lean/automount/files/10-automount new file mode 100755 index 000000000..1948d75a0 --- /dev/null +++ b/package/lean/automount/files/10-automount @@ -0,0 +1,26 @@ +#!/bin/sh + +# Copyright (C) 2015 OpenWrt.org + +# 0 yes blockdevice handles this - 1 no it is not there +blkdev=`dirname $DEVPATH` +basename=`basename $blkdev` +device=`basename $DEVPATH` +skip=`block info | sed 's/\(.*\): .*/\1/' | grep -q $device ; echo $?` +path=$DEVPATH + +if [ $basename != "block" ] && [ -z "${device##sd*}" ] && [ $skip -eq 1 ]; then + mntpnt=$device + case "$ACTION" in + add) + mkdir -p /mnt/$mntpnt + # Try to be gentle on solid state devices + mount -o rw,noatime,discard /dev/$device /mnt/$mntpnt + ;; + remove) + # Once the device is removed, the /dev entry disappear. We need mountpoint + mountpoint=`mount |grep /dev/$device | sed 's/.* on \(.*\) type.*/\1/'` + umount -l $mountpoint + ;; + esac +fi \ No newline at end of file diff --git a/package/lean/autosamba/Makefile b/package/lean/autosamba/Makefile new file mode 100644 index 000000000..b4d87638c --- /dev/null +++ b/package/lean/autosamba/Makefile @@ -0,0 +1,37 @@ +# +# Copyright (C) 2010-2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=autosamba +PKG_VERSION:=1 +PKG_RELEASE:=8 +PKG_ARCH:=all + +include $(INCLUDE_DIR)/package.mk + +define Package/autosamba + SECTION:=net + CATEGORY:=Network + TITLE:=Samba autoconfig hotplug script. + MAINTAINER:=Lean + DEPENDS:=+luci-app-samba +endef + +define Package/autosamba/description +A hotplug script to config Samba share automatically. +endef + +define Build/Compile +endef + +define Package/autosamba/install + $(INSTALL_DIR) $(1)/etc/hotplug.d/block + $(INSTALL_BIN) ./files/20-smb $(1)/etc/hotplug.d/block/20-smb +endef + +$(eval $(call BuildPackage,autosamba)) diff --git a/package/lean/autosamba/files/20-smb b/package/lean/autosamba/files/20-smb new file mode 100755 index 000000000..7a2056cd0 --- /dev/null +++ b/package/lean/autosamba/files/20-smb @@ -0,0 +1,105 @@ +#!/bin/sh +# +# D-Team Technology Co.,Ltd. ShenZhen +# 浣滆:Vic +# +# +# 璀﹀憡:瀵圭潃灞忓箷鐨勫摜浠,鎴戜滑鍏佽浣犱娇鐢ㄦ鑴氭湰锛屼絾涓嶅厑璁镐綘鎶瑰幓浣滆呯殑淇℃伅,璇蜂繚鐣欒繖娈佃瘽銆 +# +. /lib/functions.sh +. /lib/functions/service.sh + +global=0 +config_file="/etc/config/samba" + +wait_for_init() { + for i in `seq 30` + do + [ -e /tmp/procd.done ] || { + sleep 1; continue; + } + return + done +} + +smb_handle() { + config_get path $1 path + if [ "$path" = "$2" ] ;then + global=1 + fi +} + +chk_en() { + config_get_bool autoshare $1 autoshare 1 + [ $autoshare -eq 0 ] && exit +} + +config_load samba +config_foreach chk_en samba + +device=`basename $DEVPATH` + +case "$ACTION" in + add) + + case "$device" in + sd*) ;; + md*) ;; + hd*);; + mmcblk*);; + *) return;; + esac + + path="/dev/$device" + + wait_for_init + + cat /proc/mounts | while read j + do + str=${j%% *} + if [ "$str" == $path ];then + strr=${j#* } + target=${strr%% *} + global=0 + config_foreach smb_handle sambashare $target + name=${target#*/mnt/} + + if [ $global -eq 0 ] ;then + echo -e "\n\nconfig sambashare" >> $config_file + echo -e "\toption auto '1'" >> $config_file + echo -e "\toption name '$name'" >> $config_file + echo -e "\toption path '$target'" >> $config_file + echo -e "\toption read_only 'no'" >> $config_file + echo -e "\toption guest_ok 'yes'" >> $config_file + echo -e "\toption create_mask '0666'" >> $config_file + echo -e "\toption dir_mask '0777'" >> $config_file + echo -e "\toption device '$device'" >> $config_file + /etc/init.d/samba reload + return + fi + fi + done + ;; + remove) + i=0 + while true + do + + dev=`uci get samba.@sambashare[$i].device` + [ $? -ne 0 ] && break + + [ "$dev" = "$device" ] && { + auto=`uci get samba.@sambashare[$i].auto` + [ $auto = "1" ] && { + mount_dir=`uci get samba.@sambashare[$i].name` + rm -rf /mnt/$device /mnt/$mount_dir + uci delete samba.@sambashare[$i] + uci commit + /etc/init.d/samba reload + return + } + } + let i+=1 + done + ;; +esac diff --git a/package/lean/default-settings/Makefile b/package/lean/default-settings/Makefile new file mode 100644 index 000000000..0ca08a846 --- /dev/null +++ b/package/lean/default-settings/Makefile @@ -0,0 +1,48 @@ +# +# Copyright (C) 2016-2017 GitHub +# +# This is free software, licensed under the GNU General Public License v3. +# See /LICENSE for more information. + +include $(TOPDIR)/rules.mk + +PKG_NAME:=default-settings +PKG_VERSION:=1.0 +PKG_RELEASE:=20 +PKG_LICENSE:=GPLv3 +PKG_LICENSE_FILES:=LICENSE + +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) + +include $(INCLUDE_DIR)/package.mk + +define Package/default-settings + SECTION:=luci + CATEGORY:=LuCI + TITLE:=LuCI support for Default Settings + PKGARCH:=all +endef + +define Package/default-settings/description + Language Support Packages. +endef + +define Build/Prepare + $(foreach po,$(wildcard ${CURDIR}/i18n/*.po), \ + po2lmo $(po) $(PKG_BUILD_DIR)/$(patsubst %.po,%.lmo,$(notdir $(po)));) +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/default-settings/install + $(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_DATA) $(PKG_BUILD_DIR)/*.lmo $(1)/usr/lib/lua/luci/i18n/ + $(INSTALL_BIN) ./files/zzz-default-settings $(1)/etc/uci-defaults/99-default-settings +endef + +$(eval $(call BuildPackage,default-settings)) diff --git a/package/lean/default-settings/files/zzz-default-settings b/package/lean/default-settings/files/zzz-default-settings new file mode 100755 index 000000000..1c83c8b08 --- /dev/null +++ b/package/lean/default-settings/files/zzz-default-settings @@ -0,0 +1,52 @@ +#!/bin/sh + +uci set luci.main.lang=zh_cn +uci commit luci + +uci set system.@system[0].hostname=LEDE +uci set system.@system[0].timezone=CST-8 +uci set system.@system[0].zonename=Asia/Shanghai +uci commit system + +uci set fstab.@global[0].anon_mount=1 +uci commit fstab + +rm -f /usr/lib/lua/luci/view/admin_status/index/mwan.htm +rm -f /usr/lib/lua/luci/view/admin_status/index/upnp.htm +rm -f /usr/lib/lua/luci/view/admin_status/index/ddns.htm +rm -f /usr/lib/lua/luci/view/admin_status/index/minidlna.htm + +sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/aria2.lua +sed -i 's/services/nas/g' /usr/lib/lua/luci/view/aria2/overview_status.htm +sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/hd_idle.lua +sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/samba.lua +sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/minidlna.lua +sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/transmission.lua +sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/mjpg-streamer.lua +sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/p910nd.lua +sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/usb_printer.lua +sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/xunlei.lua + +[ ! -f /usr/bin/ip ] && ln -sf /sbin/ip /usr/bin/ip +(opkg list-installed | grep ip-full >/dev/null 2>&1) && ln -sf /usr/sbin/ip /usr/bin/ip + +rm -rf /tmp/luci-modulecache/ +rm -f /tmp/luci-indexcache + +sed -i 's/downloads.openwrt.org/openwrt.proxy.ustclug.org/g' /etc/opkg/distfeeds.conf +sed -i 's/root::0:0:99999:7:::/root:$1$V4UetPzk$CYXluq4wUazHjmCDBCqXF.:0:0:99999:7:::/g' /etc/shadow + +sed -i "s/# //g" /etc/opkg/distfeeds.conf + +sed -i '/REDIRECT --to-ports 53/d' /etc/firewall.user +echo "iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 53" >> /etc/firewall.user +echo "iptables -t nat -A PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 53" >> /etc/firewall.user + +sed -i '/option disabled/d' /etc/config/wireless +sed -i '/set wireless.radio${devidx}.disabled/d' /lib/wifi/mac80211.sh +wifi up + +exit 0 + + + diff --git a/package/lean/default-settings/i18n/advanced-reboot.zh-cn.po b/package/lean/default-settings/i18n/advanced-reboot.zh-cn.po new file mode 100644 index 000000000..e592ee58e --- /dev/null +++ b/package/lean/default-settings/i18n/advanced-reboot.zh-cn.po @@ -0,0 +1,102 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "Action" +msgstr "鍔ㄤ綔" + +msgid "Advanced Reboot" +msgstr "鍙屽垎鍖哄惎鍔ㄥ垏鎹" + +msgid "Alternative" +msgstr "澶囬" + +msgid "Cancel" +msgstr "鍙栨秷" + +msgid "Confirm" +msgstr "纭畾" + +msgid "Current" +msgstr "褰撳墠" + +msgid "Firmware/OS (Kernel)" +msgstr "鍥轰欢/绯荤粺 (鍐呮牳)" + +msgid "Partition" +msgstr "鍒嗗尯" + +msgid "Partitions" +msgstr "鍒嗗尯" + +msgid "Perform power off..." +msgstr "鐐瑰嚮鍏虫満..." + +msgid "Power Off Device" +msgstr "鍏抽棴璁惧" + +msgid "Proceed" +msgstr "澶勭悊" + +msgid "Reboot Device to an Alternative Partition" +msgstr "閲嶅惎璁惧鍒板閫夊垎鍖" + +msgid "Reboot to alternative partition..." +msgstr "閲嶅惎鍒板閫夊垎鍖" + +msgid "Reboot to current partition" +msgstr "閲嶅惎鍒板綋鍓嶅垎鍖" + +msgid "Rebooting..." +msgstr "姝e湪閲嶅惎..." + +msgid "Shutting down..." +msgstr "姝e湪鍏抽棴..." + +msgid "Status" +msgstr "鐘舵" + +msgid "" +"The system is rebooting now.
DO NOT POWER OFF THE DEVICE!
Wait a " +"few minutes before you try to reconnect. It might be necessary to renew the " +"address of your computer to reach the device again, depending on your " +"settings." +msgstr "" + +msgid "" +"The system is rebooting to an alternative partition now.
DO NOT POWER " +"OFF THE DEVICE!
Wait a few minutes before you try to reconnect. It " +"might be necessary to renew the address of your computer to reach the device " +"again, depending on your settings." +msgstr "" + +msgid "" +"The system is shutting down now.
DO NOT POWER OFF THE DEVICE!
It " +"might be necessary to renew the address of your computer to reach the device " +"again, depending on your settings." +msgstr "" + +msgid "" +"WARNING: An alternative partition might have its own settings and completely " +"different firmware.

As your network configuration and WiFi SSID/" +"password on alternative partition might be different, you might have to " +"adjust your computer settings to be able to access your device once it " +"reboots.

Please also be aware that alternative partition " +"firmware might not provide an easy way to switch active partition and boot " +"back to the currently active partition.

Click \"Proceed\" below " +"to reboot device to an alternative partition." +msgstr "" + +msgid "" +"WARNING: Power off might result in a reboot on a device which doesn't " +"support power off.

Click \"Proceed\" below to power off your " +"device." +msgstr "" + +msgid "Warning: There are unsaved changes that will get lost on reboot!" +msgstr "璀﹀憡锛氭煇浜涜缃病鏈変繚瀛橈紝閲嶅惎灏嗗鑷翠涪澶辫繖浜涢厤缃紒" + +msgid "Warning: This system does not have two partitions!" +msgstr "璀﹀憡锛氬綋鍓嶇郴缁熸病鏈夊寘鎷袱涓垎鍖!" + +msgid "Warning: This system does not support powering off!" +msgstr "璀﹀憡锛氭湰绯荤粺涓嶆敮鎸佽蒋鍏虫満!" diff --git a/package/lean/default-settings/i18n/default.zh-cn.po b/package/lean/default-settings/i18n/default.zh-cn.po new file mode 100644 index 000000000..0597e5af5 --- /dev/null +++ b/package/lean/default-settings/i18n/default.zh-cn.po @@ -0,0 +1,10 @@ +msgid "Processor" +msgstr "澶勭悊鍣" + +msgid "Architecture" +msgstr "鏋舵瀯" + +msgid "CPU Temperature" +msgstr "CPU娓╁害" + + diff --git a/package/lean/default-settings/i18n/more.zh-cn.po b/package/lean/default-settings/i18n/more.zh-cn.po new file mode 100644 index 000000000..1e0f34f08 --- /dev/null +++ b/package/lean/default-settings/i18n/more.zh-cn.po @@ -0,0 +1,563 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Last-Translator: Hsing-Wang Liao \n" + +msgid "%d hour" +msgstr "%d 灏忔椂" + +msgid "%d minute" +msgstr "%d 鍒嗛挓" + +msgid "%d minutes" +msgstr "%d 鍒嗛挓" + +msgid "%d second" +msgstr "%d 绉" + +msgid "%d seconds" +msgstr "%d 绉" + +msgid "" +"Acceptable values: 1-100. This many Tracking IP addresses must respond for " +"the link to be deemed up" +msgstr "" +"鍙栧艰寖鍥: 1-100銆傝繖涓缃」鎸囧畾浜嗗綋澶氬皯涓 IP 鍦板潃鑳藉杩為氭椂鎺ュ彛浼氳璁や负鍦ㄧ嚎" + +msgid "Acceptable values: 1-1000. Defaults to 1 if not set" +msgstr "鍙栧艰寖鍥: 1-100銆傚鏋滀笉濉啓锛岄粯璁ゅ间负 1" + +msgid "Advanced" +msgstr "楂樼骇" + +msgid "Check IP rules" +msgstr "妫鏌 IP 瑙勫垯" + +msgid "Check routing table" +msgstr "妫鏌ヨ矾鐢辫〃" + +msgid "Collecting data..." +msgstr "姝e湪鏀堕泦鏁版嵁..." + +msgid "Configuration" +msgstr "閰嶇疆" + +msgid "Currently Configured Interfaces" +msgstr "褰撳墠閰嶇疆鐨勬帴鍙" + +msgid "Currently Configured Members" +msgstr "褰撳墠閰嶇疆鐨勬垚鍛" + +msgid "Currently Configured Policies" +msgstr "褰撳墠閰嶇疆鐨勭瓥鐣" + +msgid "Destination address" +msgstr "鐩爣鍦板潃" + +msgid "Destination port" +msgstr "鐩爣绔彛" + +msgid "Detailed Status" +msgstr "璇︾粏鐘舵" + +msgid "Diagnostic Results" +msgstr "璇婃柇缁撴灉" + +msgid "Diagnostics" +msgstr "璇婃柇" + +msgid "Disabled" +msgstr "绂佺敤" + +msgid "" +"Downed interface will be deemed up after this many successful ping tests" +msgstr "褰 Ping 鎴愬姛娆℃暟杈惧埌杩欎釜鏁板煎悗锛屽凡缁忚璁や负绂荤嚎鐨勬帴鍙e皢浼氶噸鏂颁笂绾" + +msgid "Enabled" +msgstr "鍚敤" + +msgid "Error collecting troubleshooting information" +msgstr "鏀堕泦鏁呴殰鎺掗櫎淇℃伅鏃跺嚭閿" + +msgid "Errors" +msgstr "閿欒" + +msgid "Failure interval" +msgstr "鏁呴殰妫娴嬮棿闅" + +msgid "Flush conntrack table" +msgstr "鍒锋柊杩炴帴璺熻釜琛" + +msgid "Flush global firewall conntrack table on interface events" +msgstr "鍦ㄦ帴鍙d簨浠惰Е鍙戞椂鍒锋柊鍏ㄥ眬闃茬伀澧欒繛鎺ヨ窡韪〃" + +msgid "Hotplug Script" +msgstr "Hotplug 鑴氭湰" + +msgid "Hotplug ifdown" +msgstr "Hotplug ifdown" + +msgid "Hotplug ifup" +msgstr "Hotplug ifup" + +msgid "IPset" +msgstr "IPset" + +msgid "IPv4" +msgstr "IPv4" + +msgid "IPv6" +msgstr "IPv6" + +msgid "Interface" +msgstr "鎺ュ彛" + +msgid "Interface Status" +msgstr "鎺ュ彛鐘舵" + +msgid "Interface down" +msgstr "鎺ュ彛绂荤嚎" + +msgid "Interface up" +msgstr "鎺ュ彛涓婄嚎" + +msgid "Interface will be deemed down after this many failed ping tests" +msgstr "褰 Ping 澶辫触娆℃暟杈惧埌杩欎釜鏁板煎悗鎺ュ彛浼氳璁や负绂荤嚎" + +msgid "Interfaces" +msgstr "鎺ュ彛" + +msgid "Internet Protocol" +msgstr "浜掕仈缃戝崗璁" + +msgid "Last 50 MWAN systemlog entries. Newest entries sorted at the top :" +msgstr "鏈杩 50 鏉 MWAN 绯荤粺鏃ュ織锛屾渶鏂版潯鐩帓鍦ㄩ《閮:" + +msgid "Last resort" +msgstr "澶囩敤鎴愬憳" + +msgid "Load Balancing" +msgstr "璐熻浇鍧囪 " + +msgid "Loading" +msgstr "杞藉叆涓" + +msgid "MWAN Config" +msgstr "MWAN 閰嶇疆鏂囦欢" + +msgid "MWAN Detailed Status" +msgstr "MWAN 璇︾粏鐘舵" + +msgid "MWAN Interface Configuration" +msgstr "MWAN 鎺ュ彛閰嶇疆" + +msgid "MWAN Interface Configuration - %s" +msgstr "MWAN 鎺ュ彛閰嶇疆 - %s" + +msgid "MWAN Interface Diagnostics" +msgstr "MWAN 鎺ュ彛璇婃柇" + +msgid "MWAN Interface Live Status" +msgstr "MWAN 鎺ュ彛瀹炴椂鐘舵" + +msgid "MWAN Interface Systemlog" +msgstr "MWAN 鎺ュ彛绯荤粺鏃ュ織" + +msgid "MWAN Member Configuration" +msgstr "MWAN 鎴愬憳閰嶇疆" + +msgid "MWAN Member Configuration - %s" +msgstr "MWAN 鎴愬憳閰嶇疆 - %s" + +msgid "MWAN Policy Configuration" +msgstr "MWAN 绛栫暐閰嶇疆" + +msgid "MWAN Policy Configuration - %s" +msgstr "MWAN 绛栫暐閰嶇疆 - %s" + +msgid "MWAN Rule Configuration" +msgstr "MWAN 瑙勫垯閰嶇疆" + +msgid "MWAN Rule Configuration - %s" +msgstr "MWAN 瑙勫垯閰嶇疆 - %s" + +msgid "MWAN Service Control" +msgstr "MWAN 鏈嶅姟鎺у埗" + +msgid "" +"MWAN supports up to 250 physical and/or logical interfaces
MWAN " +"requires that all interfaces have a unique metric configured in /etc/config/" +"network
Names must match the interface name found in /etc/config/" +"network (see advanced tab)
Names may contain characters A-Z, a-z, 0-9, " +"_ and no spaces
Interfaces may not share the same name as configured " +"members, policies or rules" +msgstr "" +"MWAN 鏀寔鏈澶 250 涓墿鐞嗘垨閫昏緫鎺ュ彛銆
MWAN 瑕佹眰鎵鏈夋帴鍙e繀椤诲湪 /etc/" +"config/network 涓瀹氬敮涓鐨勭綉鍏宠穬鐐广
鍚嶇О蹇呴』涓 /etc/config/network 涓" +"鐨勬帴鍙e悕绉板尮閰嶃傦紙鍙煡鐪嬧滈珮绾р濋夐」鍗★級
鍚嶇О鍏佽鍖呮嫭A-Z銆乤-z銆0-9銆乢 浣嗘槸" +"涓嶈兘鏈夌┖鏍笺
鎺ュ彛涓嶅簲璇ヤ笌鎴愬憳銆佺瓥鐣ャ佽鍒欎腑鐨勪换鎰忎竴涓缃」浣跨敤鐩稿悓鐨勫悕" +"绉" + +msgid "" +"May be entered as a single or multiple port(s) (eg \"22\" or \"80,443\") or " +"as a portrange (eg \"1024:2048\") without quotes" +msgstr "" +"鍙互杈撳叆涓涓垨澶氫釜绔彛锛堜緥濡 \"22\" 鎴栬 \"80,443\"锛夋垨鑰呮槸涓涓鍙h寖鍥达紙渚" +"濡 \"1024:2048\"锛変笉鍚紩鍙" + +msgid "Member" +msgstr "鎴愬憳" + +msgid "Member used" +msgstr "浣跨敤鐨勬垚鍛" + +msgid "Members" +msgstr "鎴愬憳" + +msgid "" +"Members are profiles attaching a metric and weight to an MWAN interface
Names may contain characters A-Z, a-z, 0-9, _ and no spaces
Members " +"may not share the same name as configured interfaces, policies or rules" +msgstr "" +"鈥滄垚鍛樷濈敤鏉ヨ缃瘡涓涓 MWAN 鎺ュ彛鐨勮穬鐐规暟锛堝嵆鎺ュ彛浼樺厛绾э級鍜屾墍鍗犳瘮閲嶃
鍚嶇О" +"鍏佽鍖呮嫭 A-Z銆 a-銆0-9銆乢 浣嗘槸涓嶈兘鏈夌┖鏍笺
鎴愬憳涓嶅簲璇ヤ笌鎺ュ彛銆佺瓥鐣ャ佽鍒" +"涓殑浠绘剰涓涓缃」浣跨敤鐩稿悓鐨勫悕绉" + +msgid "Members assigned" +msgstr "鍒嗛厤鐨勬垚鍛" + +msgid "Metric" +msgstr "璺冪偣鏁" + +msgid "" +"Name of IPset rule. Requires IPset rule in /etc/dnsmasq.conf (eg \"ipset=/" +"youtube.com/youtube\")" +msgstr "" +"鍖归厤 IPset 瑙勫垯鍒楄〃鍚嶇О銆傞渶瑕佸厛閰嶇疆 /etc/dnsmasq.conf 涓殑 IPset 瑙勫垯 (渚嬪: " +"\"ipset=/youtube.com/youtube\")" + +msgid "Network Config" +msgstr "缃戠粶閰嶇疆鏂囦欢" + +msgid "No" +msgstr "鍚" + +msgid "No MWAN interfaces found" +msgstr "娌℃湁鎵惧埌 MWAN 鎺ュ彛" + +msgid "No MWAN systemlog history found" +msgstr "娌℃湁鍦ㄧ郴缁熸棩蹇椾腑鎵惧埌 MWAN 鍘嗗彶淇℃伅" + +msgid "No detailed status information available" +msgstr "娌℃湁鐘舵佽缁嗕俊鎭彲鐢" + +msgid "No diagnostic results returned" +msgstr "娌℃湁杩斿洖璇婃柇缁撴灉" + +msgid "No protocol specified" +msgstr "鏈寚瀹氬崗璁" + +msgid "Offline" +msgstr "绂荤嚎" + +msgid "Online (tracking active)" +msgstr "鍦ㄧ嚎锛堣拷韪惎鐢ㄤ腑锛" + +msgid "Online (tracking off)" +msgstr "鍦ㄧ嚎锛堣拷韪凡鍏抽棴锛" + +msgid "Overview" +msgstr "姒傚喌" + +msgid "Ping count" +msgstr "Ping 璁℃暟" + +msgid "Ping default gateway" +msgstr "Ping 榛樿缃戝叧" + +msgid "Ping interval" +msgstr "Ping 闂撮殧" + +msgid "Ping interval during failure detection" +msgstr "鏁呴殰妫娴嬫湡闂寸殑 Ping 闂撮殧" + +msgid "Ping interval during failure recovering" +msgstr "鏁呴殰鎭㈠鏈熼棿鐨 Ping 闂撮殧" + +msgid "Ping size" +msgstr "Ping 澶у皬" + +msgid "Ping timeout" +msgstr "Ping 瓒呮椂" + +msgid "Ping tracking IP" +msgstr "Ping 璺熻釜 IP" + +msgid "Policies" +msgstr "绛栫暐" + +msgid "" +"Policies are profiles grouping one or more members controlling how MWAN " +"distributes traffic
Member interfaces with lower metrics are used " +"first. Interfaces with the same metric load-balance
Load-balanced " +"member interfaces distribute more traffic out those with higher weights
Names may contain characters A-Z, a-z, 0-9, _ and no spaces. Names must be " +"15 characters or less
Policies may not share the same name as " +"configured interfaces, members or rules" +msgstr "" +"鈥滅瓥鐣モ濇妸鎴愬憳杩涜鍒嗙粍锛屽憡璇 MWAN 濡備綍鍒嗛厤鈥滆鍒欌濅腑浣跨敤杩欎竴绛栫暐鐨勬祦閲
鎷ユ湁" +"杈冧綆璺冪偣鏁扮殑鎴愬憳灏嗕細琚紭鍏堜娇鐢ㄣ傛嫢鏈夌浉鍚岃穬鐐规暟鐨勬垚鍛樻妸娴侀噺杩涜璐熻浇鍧囪 銆
杩涜璐熻浇鍧囪 鐨勬垚鍛樹箣闂存嫢鏈夎緝楂樻瘮閲嶇殑鎴愬憳灏嗕細琚垎閰嶅埌鏇村娴侀噺銆
鍚嶇О鍏佽" +"鍖呮嫭A-Z銆乤-z銆0-9銆乢 浣嗘槸涓嶈兘鏈夌┖鏍笺傚悕绉板簲璇ュ湪 15 涓瓧绗︿互鍐
绛栫暐涓嶅簲璇" +"涓庢帴鍙c佹垚鍛樸佽鍒欎腑鐨勪换鎰忎竴涓缃」浣跨敤鐩稿悓鐨勫悕绉" + +msgid "Policy" +msgstr "绛栫暐" + +msgid "Policy assigned" +msgstr "鍒嗛厤鐨勭瓥鐣" + +msgid "Protocol" +msgstr "閫氫俊鍗忚" + +msgid "Recovery interval" +msgstr "鏁呴殰鎭㈠闂撮殧" + +msgid "Restart MWAN" +msgstr "閲嶅惎 MWAN" + +msgid "Restore default hotplug script" +msgstr "鎭㈠榛樿鐨 hotplug 鑴氭湰" + +msgid "Restore..." +msgstr "鎭㈠..." + +msgid "Rule" +msgstr "瑙勫垯" + +msgid "Rules" +msgstr "瑙勫垯" + +msgid "" +"Rules specify which traffic will use a particular MWAN policy based on IP " +"address, port or protocol
Rules are matched from top to bottom. Rules " +"below a matching rule are ignored. Traffic not matching any rule is routed " +"using the main routing table
Traffic destined for known (other than " +"default) networks is handled by the main routing table. Traffic matching a " +"rule, but all WAN interfaces for that policy are down will be blackholed
Names may contain characters A-Z, a-z, 0-9, _ and no spaces
Rules may " +"not share the same name as configured interfaces, members or policies" +msgstr "" +"鈥滆鍒欌濆熀浜 IP 鍦板潃銆佸崗璁佺鍙f妸娴侀噺鍒掑垎鍒版寚瀹氱殑鈥滅瓥鐣モ濅腑銆
瑙勫垯鎸夌収浠庝笂" +"鍒颁笅鐨勯『搴忚繘琛屽尮閰嶃傞櫎浜嗙涓鏉¤兘澶熷尮閰嶄竴娆¢氫俊鐨勮鍒欎互澶栵紝鍏跺畠瑙勫垯灏嗚蹇界暐銆" +"涓嶅尮閰嶄换浣曡鍒欑殑閫氫俊灏嗕細鐢辩郴缁熼粯璁よ矾鐢辫〃杩涜銆
鏉ヨ嚜宸茬煡鐨勭綉缁滅殑杞彂娴侀噺" +"鐢辩郴缁熼粯璁よ矾鐢辫〃鎺ユ墜锛岀劧鍚 MWAN 浠庝腑鍖归厤鍑虹浉搴旂殑娴侀噺骞惰浆绉诲埌 MWAN 鑷繁鐨勮矾鐢" +"琛ㄣ備絾鏄墍鏈夎鍒掑垎鍒颁竴涓棤娉曚娇鐢ㄧ殑绛栫暐鐨勬祦閲忓皢浼氭棤娉曟甯歌繘琛岃矾鐢便
鍚嶇О" +"鍏佽鍖呮嫭A-Z銆乤-z銆0-9銆乢 浣嗘槸涓嶈兘鏈夌┖鏍笺
瑙勫垯涓嶅簲璇ヤ笌鎺ュ彛銆佹垚鍛樸佺瓥鐣ヤ腑" +"鐨勪换鎰忎竴涓缃」浣跨敤鐩稿悓鐨勫悕绉" + +msgid "Seconds. Acceptable values: 1-1000000. Defaults to 600 if not set" +msgstr "鍗曚綅涓虹銆傛帴鍙楃殑鍊: 1-1000000銆傜暀绌哄垯浣跨敤榛樿鍊 600 绉" + +msgid "Source address" +msgstr "婧愬湴鍧" + +msgid "Source port" +msgstr "婧愮鍙" + +msgid "Start MWAN" +msgstr "鍚姩 MWAN" + +msgid "Sticky" +msgstr "绮樻粸妯″紡" + +msgid "Sticky timeout" +msgstr "绮樻粸瓒呮椂" + +msgid "Stop MWAN" +msgstr "鍋滄 MWAN" + +msgid "Supports CIDR notation (eg \"192.168.100.0/24\") without quotes" +msgstr "鏀寔 CIDR 璁版硶锛堜緥濡: \"192.168.100.0/24\"锛変笉鍚紩鍙" + +msgid "There are currently %d of 250 supported interfaces configured" +msgstr "褰撳墠宸查厤缃 %d 涓帴鍙o紝鏈澶ф敮鎸 250 涓" + +msgid "" +"This displays the metric assigned to this interface in /etc/config/network" +msgstr "杩欓噷鏄剧ず浜嗚繖涓帴鍙e湪 /etc/config/network 涓厤缃殑璺冪偣鏁" + +msgid "" +"This hostname or IP address will be pinged to determine if the link is up or " +"down. Leave blank to assume interface is always online" +msgstr "閫氳繃 ping 姝や富鏈烘垨 IP 鍦板潃鏉ョ‘瀹氶摼璺槸鍚﹀湪绾裤傜暀绌哄垯璁や负鎺ュ彛濮嬬粓鍦ㄧ嚎" + +msgid "This section allows you to modify the contents of /etc/config/mwan3" +msgstr "杩欓噷鍏佽浣犱慨鏀 /etc/config/mwan3 鐨勫唴瀹" + +msgid "This section allows you to modify the contents of /etc/config/network" +msgstr "杩欓噷鍏佽浣犱慨鏀 /etc/config/network 鐨勫唴瀹" + +msgid "This section allows you to modify the contents of /etc/config/wireless" +msgstr "杩欓噷鍏佽浣犱慨鏀 /etc/config/wireless 鐨勫唴瀹" + +msgid "" +"This section allows you to modify the contents of /etc/hotplug.d/iface/16-" +"mwancustom
This is useful for running system commands and/or scripts " +"based on interface ifup or ifdown hotplug events

Notes:
The " +"first line of the script must be "#!/bin/sh" without quotes
Lines beginning with # are comments and are not executed

Available variables:
$ACTION is the hotplug event (ifup, ifdown)
" +"$INTERFACE is the interface name (wan1, wan2, etc.)
$DEVICE is the " +"device name attached to the interface (eth0.1, eth1, etc.)" +msgstr "" +"杩欓噷鍏佽浣犱慨鏀 /etc/hotplug.d/iface/16-mwancustom 鐨勫唴瀹
杩欏彲浠ュ湪鎺ュ彛 " +"ifup 鎴 ifdown Hotplug 浜嬩欢鏃惰繍琛岀郴缁熷懡浠ゆ垨鑴氭湰

娉ㄦ剰:
鑴氭湰鐨" +"绗竴琛屽繀椤绘槸 "#!/bin/sh" 涓嶅惈寮曞彿
浠ワ純寮澶寸殑琛屾槸娉ㄩ噴锛屼笉浼氭墽琛" +"

鍙敤鍙橀噺:
$ACTION 鏄 Hotplug 浜嬩欢锛坕fup, ifdown锛
" +"$INTERFACE 鏄帴鍙e悕绉帮紙wan1銆亀an2 绛夛級
$DEVICE 鏄繛鎺ュ埌鎺ュ彛鐨勮澶囧悕绉 " +"锛坋th0.1銆乪th1 绛夛級" + +msgid "Tracking IP" +msgstr "杩借釜鐨 IP" + +msgid "Tracking hostname or IP address" +msgstr "杩借釜鐨勪富鏈烘垨 IP 鍦板潃" + +msgid "Tracking reliability" +msgstr "杩借釜鍙潬鎬" + +msgid "Traffic Rules" +msgstr "娴侀噺瑙勫垯" + +msgid "" +"Traffic from the same source IP address that previously matched this rule " +"within the sticky timeout period will use the same WAN interface" +msgstr "" +"鏉ヨ嚜鐩稿悓婧 IP 鐨勬祦閲忥紝濡傛灉宸茬粡鍖归厤杩囨瑙勫垯骞朵笖鍦ㄧ矘婊炶秴鏃舵椂闂村唴锛屽皢浼氫娇鐢ㄧ浉鍚" +"鐨 WAN 鎺ュ彛" + +msgid "Troubleshooting" +msgstr "鏁呴殰鎺掗櫎" + +msgid "Troubleshooting Data" +msgstr "鏁呴殰鎺掗櫎鏁版嵁" + +msgid "View the contents of /etc/protocols for protocol descriptions" +msgstr "璇锋煡鐪 /etc/protocols 鑾峰彇鍙夊崗璁鎯" + +msgid "WARNING: %d interfaces are configured exceeding the maximum of 250!" +msgstr "璀﹀憡: 宸查厤缃 %d 涓帴鍙o紝瓒呰繃鏈澶у 250锛" + +msgid "" +"WARNING: Some policies have names exceeding the maximum of 15 characters!" +msgstr "璀﹀憡: 鏌愪簺绛栫暐鐨勫悕绉拌秴杩囦簡 15 涓瓧绗︼紒" + +msgid "" +"WARNING: some interfaces are configured incorrectly or not at all in /etc/" +"config/network!" +msgstr "璀﹀憡: 鏌愪簺鎺ュ彛閰嶇疆涓嶆纭垨鏈厤缃埌 /etc/config/network锛" + +msgid "" +"WARNING: some interfaces have a higher reliability requirement than there " +"are tracking IP addresses!" +msgstr "璀﹀憡: 鏌愪簺鎺ュ彛鐨勮拷韪彲闈犳ц姹傚ぇ浜庝簡杩借釜 IP 鍦板潃鎬绘暟锛" + +msgid "" +"WARNING: some interfaces have duplicate metrics configured in /etc/config/" +"network!" +msgstr "璀﹀憡: 鏌愪簺鎺ュ彛鍦 /etc/config/network 涓厤缃簡鐩稿悓鐨勮穬鐐规暟锛" + +msgid "" +"WARNING: some interfaces have no default route in the main routing table!" +msgstr "璀﹀憡: 鏌愪簺鎺ュ彛鍦ㄤ富璺敱琛ㄤ腑娌℃湁榛樿璺敱锛" + +msgid "" +"WARNING: some interfaces have no metric configured in /etc/config/network!" +msgstr "璀﹀憡: 鏌愪簺鎺ュ彛娌℃湁鍦 /etc/config/network 涓厤缃穬鐐规暟锛" + +msgid "" +"WARNING: some rules have a port configured with no or improper protocol " +"specified! Please configure a specific protocol!" +msgstr "" +"璀﹀憡: 鏌愪簺瑙勫垯鎸囧畾浜嗙鍙e嵈娌℃湁閰嶇疆鎴栭厤缃簡涓嶆纭殑鍗忚锛岃閲嶆柊鎸囧畾鍗忚锛" + +msgid "" +"WARNING: this and other interfaces have duplicate metrics configured in /etc/" +"config/network!" +msgstr "璀﹀憡: 姝ゆ帴鍙e拰鍏朵粬鎺ュ彛鍦 /etc/config/network 涓厤缃簡鐩稿悓鐨勮穬鐐规暟锛" + +msgid "" +"WARNING: this interface has a higher reliability requirement than there are " +"tracking IP addresses!" +msgstr "璀﹀憡: 姝ゆ帴鍙g殑杩借釜鍙潬鎬ц姹傚ぇ浜庝簡杩借釜 IP 鍦板潃鎬绘暟锛" + +msgid "WARNING: this interface has no default route in the main routing table!" +msgstr "璀﹀憡: 姝ゆ帴鍙e湪涓昏矾鐢辫〃涓病鏈夐粯璁よ矾鐢憋紒" + +msgid "" +"WARNING: this interface has no metric configured in /etc/config/network!" +msgstr "璀﹀憡: 姝ゆ帴鍙f病鏈夊湪 /etc/config/network 涓厤缃穬鐐规暟锛" + +msgid "" +"WARNING: this interface is configured incorrectly or not at all in /etc/" +"config/network!" +msgstr "璀﹀憡: 姝ゆ帴鍙i厤缃笉姝g‘鎴栨湭閰嶇疆鍒 /etc/config/network锛" + +msgid "" +"WARNING: this policy's name is %d characters exceeding the maximum of 15!" +msgstr "璀﹀憡: 姝ょ瓥鐣ョ殑鍚嶇О鍏锋湁 %d 涓瓧绗︼紝瓒呰繃浜 15 涓瓧绗︼紒" + +msgid "" +"WARNING: this rule is incorrectly configured with no or improper protocol " +"specified! Please configure a specific protocol!" +msgstr "璀﹀憡: 姝よ鍒欐病鏈夐厤缃垨閰嶇疆浜嗕笉姝g‘鐨勫崗璁紝璇烽噸鏂版寚瀹氬崗璁紒" + +msgid "Waiting for MWAN to %s..." +msgstr "绛夊緟 MWAN %s..." + +msgid "Waiting for diagnostic results..." +msgstr "绛夊緟璇婃柇缁撴灉..." + +msgid "Weight" +msgstr "姣旈噸" + +msgid "" +"When all policy members are offline use this behavior for matched traffic" +msgstr "褰撴墍鏈夌瓥鐣ユ垚鍛橀兘鏃犳硶浣跨敤鐨勬椂鍊欙紝瀵逛娇鐢ㄨ绛栫暐鐨勬祦閲忎娇鐢ㄨ繖涓搷浣" + +msgid "Wireless Config" +msgstr "鏃犵嚎閰嶇疆" + +msgid "Yes" +msgstr "鏄" + +msgid "always" +msgstr "鎬绘槸" + +msgid "blackhole (drop)" +msgstr "榛戞礊锛堜涪寮冿級" + +msgid "default (use main routing table)" +msgstr "榛樿锛堜娇鐢ㄤ富璺敱琛級" + +msgid "ifdown" +msgstr "ifdown" + +msgid "ifup" +msgstr "ifup" + +msgid "never" +msgstr "浠庝笉" + +msgid "restart" +msgstr "" + +msgid "start" +msgstr "" + +msgid "stop" +msgstr "" + +msgid "unreachable (reject)" +msgstr "涓嶅彲杈撅紙鎷掔粷锛" diff --git a/package/lean/default-settings/i18n/sqm.zh-cn.po b/package/lean/default-settings/i18n/sqm.zh-cn.po new file mode 100644 index 000000000..02a706de5 --- /dev/null +++ b/package/lean/default-settings/i18n/sqm.zh-cn.po @@ -0,0 +1,203 @@ +msgid "" +msgstr "" +"Project-Id-Version: luci-i18n-sqm\n" +"POT-Creation-Date: 2017-03-28 04:14+0800\n" +"PO-Revision-Date: 2017-03-28 04:15+0800\n" +"Last-Translator: \n" +"Language-Team: player131 \n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.10\n" +"X-Poedit-Basepath: .\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Poedit-KeywordsList: translate\n" +"X-Poedit-SearchPath-0: .\n" + +#: usr/lib/lua/luci/controller/sqm.lua:24 +msgid "SQM QoS" +msgstr "SQM QoS" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:25 +msgid "Smart Queue Management" +msgstr "鏅鸿兘闃熷垪绠$悊" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:26 +msgid "" +"With SQM you can enable " +"traffic shaping, better mixing (Fair Queueing), active queue length " +"management (AQM) and prioritisation on one network interface." +msgstr "" +"浣跨敤 SQM 浣犲彲浠ュ惎鐢ㄦ祦閲忔暣褰紝鏇村ソ鐨勬贩鍚" +"(鍏钩鍒楅槦)涓诲姩鍒楅槦绠$悊(AQM) 骞惰缃綉缁滄帴鍙d紭鍏堢骇銆" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:32 +msgid "Queues" +msgstr "闃熷垪" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:33 +msgid "Basic Settings" +msgstr "鍩烘湰璁剧疆" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:34 +msgid "Queue Discipline" +msgstr "鍒楅槦瑙勫垯" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:35 +msgid "Link Layer Adaptation" +msgstr "閾捐矾灞傞傞厤" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:40 +msgid "Enable this SQM instance." +msgstr "鍚敤姝QM瀹炰緥" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:54 +msgid "" +"The SQM GUI has just enabled the sqm initscript on your behalf. Remember to " +"disable the sqm initscript manually under System Startup menu in case this " +"change was not wished for." +msgstr "" +"浣犲垰鍒氬紑鍚簡SQM闅忔満鍚姩鍔熻兘锛屽鏋滀綘涓嶅笇鏈汼QM闅忔満鍚姩锛屽彲浠ュ湪绯荤粺鍚姩鑿滃崟涓嬫墜" +"鍔ㄧ鐢ㄣ" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:60 +msgid "Interface name" +msgstr "鎺ュ彛鍚嶇О" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:70 +msgid "" +"Download speed (kbit/s) (ingress) set to 0 to selectively disable ingress " +"shaping:" +msgstr "涓嬭浇閫熷害(kbit/s)(鍏ュ彛)
璁剧疆涓0鍏抽棴鍏ュ彛鎺у埗锛" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:74 +msgid "" +"Upload speed (kbit/s) (egress) set to 0 to selectively disable egress " +"shaping:" +msgstr "涓婁紶閫熷害(kbit/s)(鍑哄彛)
璁剧疆涓0鍏抽棴鍑哄彛鎺у埗锛" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:78 +msgid "" +"Create log file for this SQM instance under /var/run/sqm/${Inerface_name}." +"debug.log. Make sure to delete log files manually." +msgstr "" +"鍒涘缓鏃ュ織鏂囦欢鍒/var/run/sqm/
${Inerface_name}.debug.log銆
璇峰姟蹇呮墜鍔" +"鍒犻櫎鏃ュ織鏂囦欢銆" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:82 +msgid "Verbosity of SQM's output into the system log." +msgstr "SQM杈撳嚭鍒扮郴缁熸棩蹇楃殑璇︾粏绋嬪害銆" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:86 usr/lib/lua/luci/model/cbi/sqm.lua:99 +#: usr/lib/lua/luci/model/cbi/sqm.lua:148 +#: usr/lib/lua/luci/model/cbi/sqm.lua:155 +#: usr/lib/lua/luci/model/cbi/sqm.lua:202 +#: usr/lib/lua/luci/model/cbi/sqm.lua:243 +msgid "default" +msgstr "榛樿" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:98 +msgid "" +"Queuing disciplines useable on this system. After installing a new qdisc, " +"you need to restart the router to see updates!" +msgstr "绯荤粺涓婂彲鐢ㄧ殑鍒楅槦瑙勫垯銆傚畨瑁呮柊鐨勯槦鍒楄鍒欏悗锛岄噸鏂板惎鍔ㄨ矾鐢卞櫒鎵嶄細鐪嬪埌鏇存柊锛" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:112 +msgid "Queue setup script" +msgstr "闃熷垪鑴氭湰璁剧疆" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:129 +msgid "" +"Show and Use Advanced Configuration. Advanced options will only be used as " +"long as this box is checked." +msgstr "閫変腑璇ュ閫夋鏄剧ず楂樼骇閰嶇疆銆" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:133 +msgid "Squash DSCP on inbound packets (ingress):" +msgstr "鍏ョ珯鏁版嵁鍖呭帇缂〥SCP:" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:140 +msgid "Ignore DSCP on ingress:" +msgstr "蹇界暐鍏ョ珯DSCP" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:147 +msgid "" +"Explicit congestion notification (ECN) status on inbound packets (ingress):" +msgstr "鍏ョ珯鏁版嵁鍖呯殑鏄惧紡鎷ュ閫氱煡锛圗CN锛夌姸鎬" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:154 +msgid "" +"Explicit congestion notification (ECN) status on outbound packets (egress)." +msgstr "鍑虹珯鏁版嵁鍖呯殑鏄惧紡鎷ュ閫氱煡锛圗CN锛夌姸鎬" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:161 +msgid "" +"Show and Use Dangerous Configuration. Dangerous options will only be used as " +"long as this box is checked." +msgstr "閫変腑璇ュ閫夋鏄剧ず鍗遍櫓閰嶇疆銆" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:166 +msgid "Hard limit on ingress queues; leave empty for default." +msgstr "鍏ョ珯闃熷垪涓ユ牸闄愬埗锛涚暀绌轰负榛樿銆" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:173 +msgid "Hard limit on egress queues; leave empty for default." +msgstr "鍑虹珯闃熷垪涓ユ牸闄愬埗锛涚暀绌轰负榛樿銆" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:180 +msgid "Latency target for ingress, e.g 5ms [units: s, ms, or us]; leave empty for automatic selection, put in the word default for the qdisc's default." +msgstr "鍏ョ珯寤惰繜鐩爣锛屼緥濡 5ms [鍗曚綅: s, ms, 鎴 us]锛涚暀绌轰负鑷姩閫夋嫨锛宒efault涓哄垪闃熻鍒欓粯璁ゅ笺" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:185 +msgid "Latency target for egress, e.g. 5ms [units: s, ms, or us]; leave empty for automatic selection, put in the word default for the qdisc's default." +msgstr "鍑虹珯寤惰繜鐩爣锛屼緥濡 5ms [鍗曚綅: s, ms, 鎴 us]锛涚暀绌轰负鑷姩閫夋嫨锛宒efault涓哄垪闃熻鍒欓粯璁ゅ笺" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:192 +msgid "" +"Advanced option string to pass to the ingress queueing disciplines; no error " +"checking, use very carefully." +msgstr "浼犻掑埌鍏ョ珯闃熷垪瑙勫垯鐨勯珮绾ч夐」瀛楃涓诧紱娌℃湁閿欒妫鏌ャ傝璋ㄦ厧浣跨敤锛" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:196 +msgid "" +"Advanced option string to pass to the egress queueing disciplines; no error " +"checking, use very carefully." +msgstr "浼犻掑埌鍑虹珯闃熷垪瑙勫垯鐨勯珮绾ч夐」瀛楃涓诧紱娌℃湁閿欒妫鏌ャ傝璋ㄦ厧浣跨敤锛" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:201 +msgid "Which link layer to account for:" +msgstr "瀵瑰摢涓摼璺眰鐢熸晥:" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:207 +msgid "Per Packet Overhead (byte):" +msgstr "姣忎釜鏁版嵁鍖呭紑閿" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:216 +msgid "" +"Show Advanced Linklayer Options, (only needed if MTU > 1500). Advanced " +"options will only be used as long as this box is checked." +msgstr "" +"鏄剧ず楂樼骇閾捐矾閫夐」锛岋紙浠呭湪MTU> 1500鏃舵墠闇瑕侊級銆 鍙湁閫変腑姝ゆ鏃讹紝鎵嶄細浣跨敤楂樼骇閫" +"椤广" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:221 +msgid "" +"Maximal Size for size and rate calculations, tcMTU (byte); needs to be >= " +"interface MTU + overhead:" +msgstr "澶у皬鍜岄熺巼璁$畻鐨勬渶澶у昂瀵革紝tcMTU锛坆yte锛; 闇瑕> =鎺ュ彛MTU +寮閿锛" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:228 +msgid "" +"Number of entries in size/rate tables, TSIZE; for ATM choose TSIZE = (tcMTU " +"+ 1) / 16:" +msgstr "澶у皬/閫熺巼琛ㄤ腑鐨勬潯鐩暟锛孴SIZE; 瀵逛簬ATM閫夋嫨TSIZE =锛坱cMTU + 1锛/ 16锛" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:235 +msgid "" +"Minimal packet size, MPU (byte); needs to be > 0 for ethernet size tables:" +msgstr "鏈灏忔暟鎹寘澶у皬锛孧PU锛坆yte锛; 鍦ㄤ互澶綉涓渶瑕>0锛" + +#: usr/lib/lua/luci/model/cbi/sqm.lua:242 +msgid "Which linklayer adaptation mechanism to use; for testing only" +msgstr "浣跨敤鍝釜閾捐矾閫傚簲鏈哄埗; 浠呯敤浜庢祴璇" \ No newline at end of file diff --git a/package/lean/default-settings/tools/po2lmo/Makefile b/package/lean/default-settings/tools/po2lmo/Makefile new file mode 100644 index 000000000..ad2c13320 --- /dev/null +++ b/package/lean/default-settings/tools/po2lmo/Makefile @@ -0,0 +1,12 @@ + +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 diff --git a/package/lean/default-settings/tools/po2lmo/src/po2lmo b/package/lean/default-settings/tools/po2lmo/src/po2lmo new file mode 100644 index 000000000..134a59c27 Binary files /dev/null and b/package/lean/default-settings/tools/po2lmo/src/po2lmo differ diff --git a/package/lean/default-settings/tools/po2lmo/src/po2lmo.c b/package/lean/default-settings/tools/po2lmo/src/po2lmo.c new file mode 100644 index 000000000..0da792b68 --- /dev/null +++ b/package/lean/default-settings/tools/po2lmo/src/po2lmo.c @@ -0,0 +1,247 @@ +/* + * lmo - Lua Machine Objects - PO to LMO conversion tool + * + * Copyright (C) 2009-2012 Jo-Philipp Wich + * + * 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); +} diff --git a/package/lean/default-settings/tools/po2lmo/src/po2lmo.o b/package/lean/default-settings/tools/po2lmo/src/po2lmo.o new file mode 100644 index 000000000..536fa413b Binary files /dev/null and b/package/lean/default-settings/tools/po2lmo/src/po2lmo.o differ diff --git a/package/lean/default-settings/tools/po2lmo/src/template_lmo.c b/package/lean/default-settings/tools/po2lmo/src/template_lmo.c new file mode 100644 index 000000000..27205a722 --- /dev/null +++ b/package/lean/default-settings/tools/po2lmo/src/template_lmo.c @@ -0,0 +1,328 @@ +/* + * lmo - Lua Machine Objects - Base functions + * + * Copyright (C) 2009-2010 Jo-Philipp Wich + * + * 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; + } + } +} diff --git a/package/lean/default-settings/tools/po2lmo/src/template_lmo.h b/package/lean/default-settings/tools/po2lmo/src/template_lmo.h new file mode 100644 index 000000000..57f59aa56 --- /dev/null +++ b/package/lean/default-settings/tools/po2lmo/src/template_lmo.h @@ -0,0 +1,92 @@ +/* + * lmo - Lua Machine Objects - General header + * + * Copyright (C) 2009-2012 Jo-Philipp Wich + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 diff --git a/package/lean/default-settings/tools/po2lmo/src/template_lmo.o b/package/lean/default-settings/tools/po2lmo/src/template_lmo.o new file mode 100644 index 000000000..b24714ad4 Binary files /dev/null and b/package/lean/default-settings/tools/po2lmo/src/template_lmo.o differ diff --git a/package/lean/ipset-lists/Makefile b/package/lean/ipset-lists/Makefile new file mode 100644 index 000000000..a6b71382b --- /dev/null +++ b/package/lean/ipset-lists/Makefile @@ -0,0 +1,48 @@ +# +# Copyright (c) 2015 Justin Liu +# Author: Justin Liu +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=ipset-lists +PKG_VERSION:=20161112 +PKG_RELEASE:= + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk + +define Package/ipset-lists + CATEGORY:=Network + TITLE:=Service for IPSET address tables + MAINTAINER:=Justin Liu + DEPENDS:=+ipset +luci +endef + +define Package/ipset-lists/conffiles +/etc/gfwlist/china-banned +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Compile/Default + +endef +Build/Compile = $(Build/Compile/Default) + +define Package/ipset-lists/install + $(CP) -a files/* $(1)/ +endef + +define Package/ipset-lists/postinst +#!/bin/sh +if [ -e /etc/openwrt_release ]; then + /etc/init.d/ipset.sh restart + /etc/init.d/ipset.sh enable || : +fi +endef + +$(eval $(call BuildPackage,ipset-lists)) diff --git a/package/lean/ipset-lists/files/etc/gfwlist/china-banned b/package/lean/ipset-lists/files/etc/gfwlist/china-banned new file mode 100644 index 000000000..f1bc03de9 --- /dev/null +++ b/package/lean/ipset-lists/files/etc/gfwlist/china-banned @@ -0,0 +1,4802 @@ +0rz.tw +0to255.com +1000giri.net +100ke.org +10conditionsoflove.com +10musume.com +123rf.com +12bet.com +12vpn.com +12vpn.net +141hongkong.com +141tube.com +1688.com.au +173ng.com +177pic.info +17t17p.com +18onlygirls.com +18virginsex.com +1949er.org +1984bbs.com +1984bbs.org +1989report.hkja.org.hk +1998cdp.org +1bao.org +1dumb.com +1e100.net +1eew.com +1mobile.com +1pondo.tv +2000fun.com +2008xianzhang.info +2017.hk +21andy.com +21pron.com +21sextury.com +228.net.tw +247realmedia.com +24hrs.ca +24smile.org +25u.com +2-hand.info +2lipstube.com +2mdn.net +2shared.com +2waky.com +301works.org +30boxes.com +315lz.com +32red.com +365singles.com.ar +36rain.com +3a5a.com +3-a.net +3arabtv.com +3boys2girls.com +3d-game.com +3ren.ca +3tui.net +4bluestones.biz +4chan.org +4dq.com +4everproxy.com +4irc.com +4mydomain.com +4pu.com +4rbtv.com +4shared.com +4sq.com +4tern.com +51.ca +51luoben.com +56cun04.jigsy.com +5aimiku.com +5i01.com +5isotoi5.org +5maodang.com +63i.com +64museum.org +64tianwang.com +64wiki.com +666kb.com +66.ca +6park.com +7capture.com +7cow.com +85cc.net +85st.com +881903.com +888.com +888poker.com +89-64.org +8-d.com +8news.com.tw +8z1.net +9001700.com +91porn.com +92ccav.com +991.com +99btgc01.com +99cn.info +9bis.com +9bis.net +9city.me +a248.e.akamai.net +a5.com.ru +aamacau.com +abc.com +abchinese.com +abc.pp.ru +abc.xyz +abitno.linpie.com +ablwang.com +aboluowang.com +aboutgfw.com +abs.edu +accim.org +aceros-de-hispania.com +acevpn.com +acg18.me +acgkj.com +ac.jiruan.net +acmetoy.com +ac.playstation.net +actimes.com.au +activpn.com +aculo.us +addictedtocoffee.de +admob.com +adorama.com +adpl.org.hk +adultfriendfinder.com +adultkeep.net +adult-sex-games.com +advanscene.com +advertfan.com +ae.hao123.com +aenhancers.com +ae.org +afantibbs.com +af.mil +agnesb.fr +agoogleaday.com +ai-kan.net +aiph.net +airconsole.com +airvpn.org +aisex.com +ait.org.tw +aiweiweiblog.com +aiweiwei.com +ai-wen.net +ajaxplorer.info +akamaihd.net +akiba-online.com +akiba-web.com +alabout.com +alanhou.com +alasbarricadas.org +alexlur.org +alforattv.net +alhayat.com +aliengu.com +alien-ufos.com +aliyun.com +alkasir.com +allaboutalpha.com +allconnected.co +alldrawnsex.com +allfinegirls.com +allgirlsallowed.org +alliance.org.hk +allinfa.com +allinfo.com +alljackpotscasino.com +allmovie.com +all-that-is-interesting.com +almostmy.com +alphaporno.com +al-qimmah.net +alternate-tools.com +altrec.com +alvinalexander.com +alwaysdata.com +alwaysdata.net +alwaysvpn.com +am730.com.hk +amazonaws.com +ameblo.jp +americangreencard.com +americanunfinished.com +amiblockedornot.com +amigobbs.net +amitabhafoundation.us +amnesty.org +amnesty.tw +amnestyusa.org +amnyemachen.org +amoiist.com +ampproject.org +amzs.me +analyze-v.com +anchorfree.com +ancsconf.org +andfaraway.net +android.com +androidify.com +android-x86.org +angularjs.org +animecrazy.net +animeshippuuden.com +aniscartujo.com +anobii.com +anontext.com +anonymitynetwork.com +anonymizer.com +a-normal-day.com +anpopo.com +answering-islam.org +anthonycalzadilla.com +anti.anti.cnn.googlepages.com +antidrm.hpg.ig.com.br +antiwave.net +anysex.com +aobo.com.au +aofriend.com +aofriend.com.au +aojiao.org +aolchannels.aol.com +aomiwang.com +apetube.com +apiary.io +apidocs.linksalpha.com +apigee.com +api.linksalpha.com +api.proxlet.com +api.supertweet.net +apk-dl.com +apkpure.com +app.box.com +app.heywire.com +appledaily.com +appledaily.com.tw +apps.hloli.net +appsocks.net +appspot.com +appsto.re +archive.is +archive.org +archives.gov +arctosia.com +areca-backup.org +arena.taipei +arethusa.su +ar.hao123.com +arlingtoncemetery.mil +army.mil +arstechnica.com +art4tibet1998.org +artofpeacefoundation.org +art-or-porn.com +artsy.net +asacp.org +asahichinese.com +asdfg.jp +asg.to +asiafriendfinder.com +asia-gaming.com +asiaharvest.org +asianews.it +asiansexdiary.com +asianspiss.com +asianwomensfilm.de +asiatgp.com +askstudent.com +askynz.net +assembla.com +astonmartinnews.com +astrill.com +atchinese.com +atc.org.au +atdmt.com +atgfw.org +athenaeizou.com +atj.org.tw +atlaspost.com +atnext.com +authorizeddns.net +authorizeddns.org +authorizeddns.us +autoproxy.org +avaaz.org +avcity.tv +avcool.com +avdb.in +avdb.tv +avfantasy.com +avidemux.org +avmoo.com +avmoo.net +avmoo.pw +avmo.pw +av.nightlife141.com +avoision.com +avyahoo.com +awardwinningfjords.com +axureformac.com +azerbaycan.tv +azerimix.com +azubu.tv +b0ne.com +babynet.com.hk +backchina.com +backpackers.com.tw +backtotiananmen.com +badassjs.com +badjojo.com +badoo.com +baidu.jp +bailandaily.com +baixing.me +bakgeekhome.tk +banana-vpn.com +bandwagonhost.com +bangbrosnetwork.com +bangchen.net +bangyoulater.com +bannedbook.org +bannednews.org +barenakedislam.com +barnabu.co.uk +barracuda.com +bartvpn.com +basetimesheightdividedby2.com +bayvoice.net +bbcchinese.com +bbc.com +bbc.co.uk +bb-chat.tv +bbchat.tv +bbci.co.uk +bbcimg.co.uk +bbc.in +bbg.gov +bbnradio.org +bbs2.newsgroup.la +bbs.brockbbs.com +bbs.ecstart.com +bbsfeed.com +bbs.hasi.wang +bbs.kimy.com.tw +bbsland.com +bbsmo.com +bbs.morbell.com +bbs.mychat.to +bbs.netbig.com +bbs.newsgroup.la +bbsone.com +bbs.qmzdd.com +bbs.sina.com +bbs.skykiwi.com +bbs.sou-tong.org +bbs.tuitui.info +bbs-tw.com +bbtoystore.com +bb.ttv.com.tw +bcast.co.nz +bcc.com.tw +bcchinese.net +bcmorning.com +bdsmvideos.net +bd.zhe.la +beaconevents.com +bebo.com +beeg.com +beevpn.com +behindkink.com +beijing1989.com +beijingspring.com +belamionline.com +bell.wiki +bemywife.cc +benjaminste.in +beric.me +berlintwitterwall.com +berm.co.nz +bestforchina.org +bestvpn.com +bestvpnserver.com +bestvpnservice.com +bestvpnusa.com +bet365.com +beta.iset.com.tw +beta.usejump.com +betfair.com +bettervpn.com +bettween.com +betvictor.com +bewww.net +beyondfirewall.com +bfnn.org +bfsh.hk +bgvpn.com +biantailajiao.com +biantailajiao.in +biblesforamerica.org +bic2011.org +bigfools.com +bigjapanesesex.com +bigmoney.biz +bignews.org +bigsound.org +bill2-software.com +billywr.com +bill.zhong.pp.ru +bipic.net +bitcointalk.org +bit.do +bit.ly +bitly.com +bitshare.com +bitsnoop.com +bizhat.com +bjnewlife.org +bjzc.org +blacklogic.com +blackvpn.com +bl-doujinsouko.com +blinkx.com +blinw.com +blip.tv +blockcn.com +blog.birdhouseapp.com +blogblog.com +blog.boxcar.io +blog.calibre-ebook.com +blogcatalog.com +blogcity.me +blog.cnyes.com +blog.davidziegler.net +blog.dayoneapp.com +blog.de +blog.dribbble.com +blog.exblog.co.jp +blog.excite.co.jp +blog.expofutures.com +blog.fizzik.com +blog.foolsmountain.com +blogger.com +blog.gowalla.com +blog.hotpotato.com +blog.ifttt.com +blogimg.jp +blog.inoreader.com +blog.instapaper.com +blog.iphone-dev.org +blog.istef.info +blog.jackjia.com +blog.joeyrobert.org +blog.jp +blog.kangye.org +blog.kickstarter.com +blog.kl.am +blog.klip.me +blog.lester850.info +blog.lightbox.com +bloglines.com +bloglovin.com +blog.martinoei.com +blog.mongodb.org +blog.openinkpot.org +blog.palm.com +blog.path.com +blog.pathtosharepoint.com +blog.pentalogic.net +blog.pikchur.com +blog.pilotmoon.com +blog.redren.com +blog.rockmelt.com +blog.romanandreg.com +blog.s135.com +blogs.icerocket.com +blog.sogoo.org +blog.sparrowmailapp.com +blogspot.com +blogspot.co.uk +blogspot.de +blogspot.fr +blogspot.in +blogspot.jp +blogs.tampabay.com +blogs.yahoo.co.jp +blog.syx86.cn +blog.syx86.com +blog.taragana.com +blogtd.net +blogtd.org +blog.tiney.com +blog.topify.com +blog.usa.gov +blog.xuite.net +blog.youthwant.com.tw +bloodshed.net +bloomberg.cn +bloomberg.com +bloomberg.de +bloombergview.com +bloomfortune.com +blueangellive.com +bmediaasia.com +bmfinn.com +bnrmetal.com +boardreader.com +bobulate.com +bod.asia +bodog88.com +bolehvpn.net +bolin.netfirms.com +bonbonme.com +bonbonsex.com +bongacams.com +bonjourlesgeeks.com +boobstagram.com +book.com.tw +bookepub.com +books.com.tw +bookshelfporn.com +book.zi5.me +botanwang.com +bot.nu +bowenpress.com +boxpn.com +boxunblog.com +boxunclub.com +boxun.com +boxun.tv +boyangu.com +boyfriendtv.com +boysfood.com +boysmaster.com +bralio.com +branch.com +brandonhutchinson.com +braumeister.org +bravotube.net +brazzers.com +break.com +breakgfw.com +breakingtweets.com +breakwall.net +br.hao123.com +briefdream.com +brightcove.com +brightkite.com +brizzly.com +broadbook.com +broadpressinc.com +br.st +brucewang.net +brutaltgp.com +bt2mag.com +bt95.com +btaia.com +bt.byr.cn +btdigg.org +btku.me +btku.org +bt.neu6.edu.cn +btrd.net +btspread.com +budaedu.org +buddhistchannel.tv +buffered.com +bugclub.org +builtwithbootstrap.com +bullogger.com +bullog.org +bunbunhk.com +busayari.com +businesstimes.com.cn +businessweek.com +busytrade.com +buugaa.com +buy.yahoo.com.tw +buzzhand.com +buzzhand.net +buzzurl.jp +bwbx.io +bwsj.hk +bx.tl +c100tibet.org +c1522.mooo.com +cablegatesearch.net +cachinese.com +cacnw.com +cactusvpn.com +cafepress.com +cahr.org.tw +calameo.com +calebelston.com +calgarychinese.ca +calgarychinese.com +calgarychinese.net +cam4.com +cam4.jp +cam4.sg +camfrog.com +cams.com +cams.org.sg +canadameet.com +canyu.org +caobian.info +caochangqing.com +cao.im +cap.org.hk +carabinasypistolas.com +cardinalkungfoundation.org +carfax.com +caribbeancom.com +cari.com.my +carmotorshow.com +cartoonmovement.com +casadeltibetbcn.org +casatibet.org.mx +casinobellini.com +casinoking.com +casinoriva.com +casino.williamhill.com +catch22.net +catfightpayperview.xxx +catholic.org.hk +catholic.org.tw +cathvoice.org.tw +cattt.com +cbc.ca +cbs.ntu.edu.tw +cbtc.org.hk +cc9007.spaces.live.com +ccavtop10.com +cccat.cc +ccdtr.org +cchere.com +ccim.org +cclife.ca +cclifefl.org +cclife.org +ccthere.com +cctongbao.com +ccue.ca +ccue.com +ccvoice.ca +ccw.org.tw +cdbook.org +cdd.me +cdef.org +cdig.info +cdjp.org +cdn1.lp.saboom.com +cdnews.com.tw +cdn.helixstudios.net +cdninstagram.com +cdn.printfriendly.com +cdn.softlayer.net +cdp1989.org +cdp1998.org +cdp2006.org +cdpa.url.tw +cdpeu.org +cdp.sinica.edu.tw +cdpusa.org +cdpweb.org +cdpwu.org +cdw.com +cecc.gov +cellulo.info +cenci.tk +cenews.eu +centauro.com.br +centerforhumanreprod.com +centralnation.com +centurys.net +certificate.revocationcheck.com +certificate-transparency.org +c-est-simple.com +cfhks.org.hk +cftfc.com +cgdepot.org +cgst.edu +chandoo.org +changeip.name +changeip.net +changeip.org +change.org +changp.com +changsa.net +chaos.e-spacy.com +chapm25.com +chartbeat.net +chatnook.com +chaturbate.com +chengmingmag.com +chenguangcheng.com +chenpokong.com +chenpokong.net +chenyehao.spaces.live.com +cherrysave.com +chevronwp7.com +chhongbi.org +chicagoncmtv.com +china101.com +china18.org +china21.com +china21.org +china5000.us +chinaaffairs.org +chinaaid.me +chinaaid.net +chinaaid.org +chinaaid.us +chinachange.org +chinachannel.hk +chinacitynews.be +chinacomments.org +chinadialogue.net +chinadigitaltimes.net +chinaelections.org +chinaeweekly.com +chinafreepress.org +chinagate.com +chinageeks.org +chinagfw.org +chinagreenparty.org +china-green-party.spaces.live.com +china.hket.com +chinahorizon.org +chinahush.com +chinainperspective.com +chinainperspective.net +chinainperspective.org +chinainterimgov.org +chinalaborwatch.org +chinalawandpolicy.com +chinalawtranslate.com +china-mmm.jp.net +china-mmm.net +china-mmm.sa.com +chinamule.com +chinamz.org +chinapress.com.my +chinarightsia.org +chinasocialdemocraticparty.com +chinaso.com +chinasoul.org +chinasucks.net +chinatimes.com +chinatopsex.com +chinatown.com.au +chinatweeps.com +chinaway.org +china-week.com +chinaworker.info +chinaxchina.com +chinayouth.org.hk +chinayuanmin.org +chinesedaily.com +chinesedailynews.com +chinesedemocracy.com +chinese.engadget.com +chinesegay.org +chinese-hermit.net +chinese.irib.ir +chinese-leaders.org +chinese-memorial.org +chinesen.de +chinesenewsnet.com +chinesepen.org +chinese.soifind.com +chinesetalks.net +chingcheong.com +chinman.net +chithu.org +chn.chosun.com +chrdnet.com +chrispederick.com +chrispederick.net +christianfreedom.org +christianstudy.com +christiantimes.org.hk +christusrex.org +chrlawyers.hk +chrlcg-hk.org +chromeadblock.com +chromecast.com +chrome.com +chromeexperiments.com +chromercise.com +chromestatus.com +chromium.org +ch.shvoong.com +chuang-yen.org +chubun.com +chuizi.net +cineastentreff.de +cipfg.org +circlethebayfortibet.org +citizenlab.org +citizenscommission.hk +citizensradio.org +city365.ca +city9x.com +civicparty.hk +civilhrfront.org +civiliangunner.com +civilmedia.tw +cjb.net +ck101.com +classicalguitarblog.net +clb.org.hk +cl.d0z.net +cleansite.biz +cleansite.info +cleansite.us +clearharmony.net +clearwisdom.net +clementine-player.org +clientsfromhell.net +cling.omy.sg +clinica-tibet.ru +clipfish.de +cl.ly +cloakpoint.com +cloudfront.net +club1069.com +cmi.org.tw +cmp.hku.hk +cms.gov +cmule.com +cmule.org +cn2.streetvoice.com +cn6.eu +cnabc.com +cna.com.tw +cnavista.com.tw +cn.dayabook.com +cnd.org +cnex.org.cn +cn.fmnnow.com +cn.freeones.com +cn.ibtimes.com +cnineu.com +cnn.com +cn.nytstyle.com +cnpolitics.org +cn-proxy.com +cnproxy.com +cn.sandscotaicentral.com +cn.shafaqna.com +cn.streetvoice.com +cn.uncyclopedia.wikia.com +cn.voa.mobi +coat.co.jp +cochina.co +cochina.org +cocoapods.org +cocoa.zonble.net +code1984.com +codeboxapp.com +codeshare.io +codeskulptor.org +collateralmurder.com +collateralmurder.org +comefromchina.com +com.google +comic-mega.me +commandarms.com +commentshk.com +communistcrimes.org +communitychoicecu.com +compileheart.com +compress.to +co.ng.mil +conoyo.com +contactmagazine.net +contests.twilio.com +convio.net +conviva.com +coobay.com +cookingtothegoodlife.com +coolaler.com +coolder.com +coolloud.org.tw +coolncute.com +corpus4u.org +corumcollege.com +cos-moe.com +cotweet.com +couchdbwiki.com +coveringweb.com +cpj.org +crackle.com +crchina.org +crd-net.org +creaders.net +creadersnet.com +cristyli.com +crocotube.com +crossfire.co.kr +crossthewall.net +csdparty.com +c-spanvideo.org +css.pixnet.in +csuchen.de +ctao.org +ctfriend.net +ctitv.com.tw +cts.com.tw +cubicle17.com +cuhkacs.org +cuihua.org +cuiweiping.net +culture.tw +cumlouder.com +curvefish.com +cusu.hk +cw.com.tw +cyanogenmod.org +cyberghost.natado.com +cyberghostvpn.com +cydia.ifuckgfw.com +cynscribe.com +cytode.us +d100.net +d2bay.com +dabr.co.uk +dabr.eu +dabr.me +dabr.mobi +dadazim.com +dadi360.com +dafagood.com +dafahao.com +daidostup.ru +dailidaili.com +dailymotion.com +dailynews.sina.com +daiphapinfo.net +dajiyuan.com +dajiyuan.de +dajiyuan.eu +dajusha.baywords.com +dalailama80.org +dalailama-archives.org +dalailamacenter.org +dalailama.com +dalailamafellows.org +dalailamafilm.com +dalailamafoundation.org +dalailamahindi.com +dalailamainaustralia.org +dalailamajapanese.com +dalailama.mn +dalailamaprotesters.info +dalailamaquotes.org +dalailama.ru +dalailamatrust.org +dalailama.usc.edu +dalailamavisit.org.nz +dalailamaworld.com +dalianmeng.org +daliulian.org +danke4china.net +danwei.org +daodu14.jigsy.com +daolan.net +darktech.org +darktoy.net +darpa.mil +dastrassi.org +data-vocabulary.org +date.fm +david-kilgour.com +davidslog.com +daxa.cn +dayaarmongol.ning.com +daylife.com +db.tt +dcard.tw +dcmilitary.com +ddc.com.tw +ddhw.info +ddns.info +ddns.me.uk +ddns.mobi +ddns.ms +ddns.name +ddns.net +ddns.us +deaftone.com +deck.ly +decodet.co +deepmind.com +default.secureserver.net +definebabe.com +deja.com +delcamp.net +delicious.com +democrats.org +demo.opera-mini.net +derekhsu.homeip.net +de-sci.org +desc.se +designerol.com +desipro.de +dessci.com +destiny.xfiles.to +destroy-china.jp +deutsche-welle.de +dev102.com +developers.box.net +deviantart.com +deviantart.net +devio.us +devpn.com +dfas.mil +dfn.org +dharamsalanet.com +dharmakara.net +dhcp.biz +diaoyuislands.org +digisfera.com +digitalnomadsproject.org +diigo.com +dilber.se +dipity.com +directcreative.com +discuss4u.com +discuss.com.hk +dish.com +disp.cc +disqus.com +dit-inc.us +dizhidizhi.com +dizhuzhishang.com +djangosnippets.org +djorz.com +dl.box.net +dl-laby.jp +dl.playstation.net +dlsite.com +dmcdn.net +dmm.co.jp +dns04.com +dns05.com +dns1.us +dns2go.com +dns2.us +dnscrypt.org +dns-dns.com +dnset.com +dnsrd.com +dnssec.net +dns-stuff.com +docstoc.com +doctorvoice.org +dojin.com +dok-forum.net +dolc.de +dolf.org.hk +dollf.com +domain.club.tw +domainhelp.search.com +domains.google +domaintoday.com.au +dongde.com +dongtaiwang.com +dongtaiwang.net +dongyangjing.com +dontfilter.us +dontmovetochina.com +dorjeshugden.com +dotheyfolloweachother.com +dotplane.com +dotsub.com +doubleaf.com +doubleclick.net +dougscripts.com +doujincafe.com +dowei.org +download.aircrack-ng.org +download.ithome.com.tw +download.syniumsoftware.com +doxygen.org +dphk.org +dpp.org.tw +dpr.info +dragonsprings.org +draw.io +dreammask.org +drepung.org +drewolanoff.com +drgan.net +drmingxia.org +dropbox.com +dropboxusercontent.com +drsunacademy.com +drtuber.com +dscn.info +dsmtp.com +dstk.dk +dtdns.net +dtiblog.com +dtic.mil +dtiserv2.com +dtwang.org +duanzhihu.com +duckdns.org +duckduckgo.com +duckload.com +duckmylife.com +duga.jp +duihuahrjournal.org +duihua.org +dumb1.com +duoweitimes.com +duping.net +duplicati.com +dupola.com +dupola.net +dushi.ca +dvorak.org +dw.com +dw.de +dwnews.com +dwnews.net +dw-world.com +dw-world.de +dy24k.info +dynamicdns.biz +dynamicdns.co.uk +dynamicdns.me.uk +dynamic-dns.net +dynamicdns.org.uk +dynawebinc.com +dyndns.org +dyndns.pro +dynssl.com +dzze.com +e123.hk +eamonnbrennan.com +earlytibet.com +earthcam.com +earthquake.usgs.gov +earthvpn.com +eastern-ark.com +easternlightning.org +eastturkestan.com +eastturkistancc.org +eastturkistangovernmentinexile.us +eastturkistan-gov.org +easyca.ca +easypic.com +easy-share.com +ebony-beauty.com +ebookbrowse.com +ebookee.com +ebook.hyread.com.tw +ecfa.org.tw +echofon.com +e-classical.com.tw +ecministry.net +economist.com +edgecastcdn.net +edicypages.com +edmontonchina.cn +edmontonservice.com +edns.biz +edoors.com +edubridge.com +edupro.org +eesti.ee +eevpn.com +efcc.org.hk +effers.com +efksoft.com +efmoe.com +efukt.com +e-gold.com +eic-av.com +e-info.org.tw +eisbb.com +eksisozluk.com +electionsmeter.com +elephantvpn.com +elgoog.im +elpais.com +eltondisney.com +emacsblog.org +embr.in +emilylau.org.hk +emory.edu +empfil.com +emule-ed2k.com +emulefans.com +emuparadise.me +enewstree.com +enfal.de +en.favotter.net +englishforeveryone.org +englishfromengland.co.uk +englishpen.org +en.hao123.com +enlighten.org.tw +entermap.com +entnt.com +epac.to +episcopalchurch.org +epochhk.com +epochtimes-bg.com +epochtimes.co.il +epochtimes.co.kr +epochtimes.com +epochtimes.cz +epochtimes.de +epochtimes.fr +epochtimes.ie +epochtimes.it +epochtimes.jp +epochtimes-romania.com +epochtimes.ru +epochtimes.se +epochtimestr.com +epochweek.com +epochweekly.com +eporner.com +equinenow.com +erabaru.net +eraysoft.com.tr +erepublik.com +erepublik.net +erights.net +eriversoft.com +erktv.com +ernestmandel.org +erodaizensyu.com +erodoujinworld.com +eromangadouzin.com +eromanga-kingdom.com +eromon.net +eroprofile.com +eroticsaloon.net +esmtp.biz +etaa.org.au +etaiwannews.com +etizer.org +etokki.com +etools.ncol.com +etowns.net +etowns.org +e-traderland.net +ettoday.net +etvonline.hk +eucasino.com +eulam.com +eu.org +evchk.wikia.com +eventful.com +everyday-carry.com +evschool.net +exblog.jp +exchristian.hk +exmormon.org +expatshield.com +expekt.com +experts-univers.com +exploader.net +expressvpn.com +extmatrix.com +extremetube.com +eyespirit.info +eyevio.jp +eyny.com +ezpc.tk +ezpeer.com +ezua.com +facebook.br +facebook.com +facebook.design +facebook.hu +facebook.in +facebook.net +facebook.nl +facebookquotes4u.com +facebook.se +faceless.me +facesofnyfw.com +facesoftibetanselfimmolators.info +fail.hk +faith100.org +faithfuleye.com +faiththedog.info +fakku.net +falsefire.com +falunart.org +falunasia.info +falun.caltech.edu +falun-co.org +falundafa-dc.org +falundafa-florida.org +falundafaindia.org +falundafamuseum.org +falundafa-nc.org +falundafa.org +falundafa-pa.net +falungong.de +falungong.org.uk +falunhr.org +faluninfo.de +faluninfo.net +falun-ny.net +falunpilipinas.net +falunworld.net +familyfed.org +famunion.com +fangbinxing.com +fangeming.com +fanglizhi.info +fangmincn.org +fangong.forums-free.com +fangongheike.com +fangong.org +fan-qiang.com +fanqianghou.com +fanqiang.tk +fanqiangyakexi.net +fanqiangzhe.com +fanswong.com +fanyue.info +fapdu.com +faproxy.com +faqserv.com +fartit.com +farwestchina.com +farxian.com +fastpic.ru +fastssh.com +faststone.org +fast.wistia.com +favorious.com +favstar.fm +fawanghuihui.org +faydao.com +fbcdn.net +fb.com +fb.me +fbsbx.com +fc2blog.net +fc2china.com +fc2cn.com +fc2.com +fdc89.jp +feedbooks.mobi +feedburner.com +feeds.fileforum.com +feedzshare.com +feelssh.com +feer.com +feifeiss.com +feitianacademy.org +feitian-california.org +felixcat.net +feministteacher.com +fengzhenghu.com +fengzhenghu.net +fetchvideo.com +fevernet.com +fffff.at +ff.im +fflick.com +fgmtv.net +fgmtv.org +fhreports.net +filefactory.com +fileflyer.com +files2me.com +fileserve.com +filesor.com +fillthesquare.org +filmingfortibet.org +filthdump.com +finalion.jp +financetwitter.com +finchvpn.com +findbook.tw +findmespot.com +findmima.com +fingerdaily.com +finler.net +firefoxfan.cc +fireofliberty.org +firetweet.io +firstfivefollowers.com +flagsonline.it +flecheinthepeche.fr +fleshbot.com +fleursdeslettres.com +flgg.us +flickr.com +flickrhivemind.net +flightcaster.com +fling.com +flipboard.com +flipkart.com +flitto.com +flnet.org +flowerofhappiness.spaces.live.com +fochk.org +focustaiwan.tw +focusvpn.com +fofg-europe.net +fofg.org +fofldfradio.org +fooooo.com +footwiball.com +forum4hk.com +forum.baby-kingdom.com +forum.cyberctm.com +forum.idsam.com +forum.iset.com.tw +forum.my903.com +forum.mymaji.com +forum.newsgroup.la +forum.omy.sg +forum.palmislife.com +forum.setty.com.tw +forum.sina.com.hk +forum.slime.com.tw +forum.tvb.com +fotile.me +fotop.net +fourface.nodesnoop.com +fourthinternational.org +foxdie.us +foxgay.com +foxsub.com +foxtang.com +fpmtmexico.org +fpmt.org +fpmt-osel.org +fpmt.tw +fqok.org +fqrouter.com +franklc.com +freakshare.com +fredwilson.vc +free4u.com.ar +freealim.com +freebrowser.org +freechal.com +freechina.net +freeddns.com +freedomchina.info +freedomhouse.org +freedomsherald.org +freeforums.org +freefq.com +free.fr +freefuckvids.com +freegao.com +freegateget.googlepages.com +free-gate.org +free-hada-now.org +freeilhamtohti.org +freelotto.com +freeman2.com +freemoren.com +freemorenews.com +freenet-china.org +freenetproject.org +freenewscn.com +freeopenvpn.com +freeoz.org +free-ssh.com +freessh.us +freetcp.com +freetibetanheroes.org +freetibet.net +freetibet.org +freeviewmovies.com +freevpn.me +freevpn.nl +freewallpaper4.me +freewebs.com +freeweibo.com +freewww.biz +freewww.info +freexinwen.com +freeyellow.com +freeyoutubeproxy.net +friendfeed.com +friendfeed-media.com +friends-of-tibet.org +friendsoftibet.org +fring.com +fringenetwork.com +fromchinatousa.net +frommel.net +frontlinedefenders.org +fscked.org +fsurf.com +ftchinese.com +ftp1.biz +ftpserver.biz +fucd.com +fuckcnnic.net +fuckgfw.com +fuckgfw.org +fullerconsideration.com +fulue.com +funf.tw +funkyimg.com +funp.com +fuq.com +furbo.org +furhhdl.org +furinkan.com +furl.net +futurechinaforum.org +futureme.org +futuremessage.org +fux.com +fuyindiantai.org +fuyin.net +fuyu.org.tw +fw.cm +fxnetworks.com +fzh999.com +fzh999.net +fzlm.com +g6hentai.com +gabocorp.com +gaeproxy.com +gaforum.org +galaxymacau.com +galenwu.com +galstars.net +game735.com +gamebase.com.tw +gamejolt.com +gamer.com.tw +gamez.com.tw +gamousa.com +ganges.com +gaoming.net +gaopi.net +gaozhisheng.net +gaozhisheng.org +gardennetworks.com +gardennetworks.org +gartlive.com +gather.com +gati.org.tw +gaybubble.com +gaycn.net +gaymap.cc +gaytube.com +gazotube.com +gcc.org.hk +gclooney.com +g.co +gcpnews.com +gcr.io +gdbt.net +gdzf.org +geek-art.net +geekerhome.com +geekheart.info +geekmade.co.uk +geekmanuals.com +g.e-hentai.org +gelbooru.com +generesis.com +genuitec.com +geocities.co.jp +geocities.com +geocities.jp +geohot.com +geometrictools.com +gerefoundation.org +getchu.com +getcloak.com +getcloudapp.com +get-digital-help.com +getfoxyproxy.org +getfreedur.com +getgom.com +get.how +getiton.com +getjetso.com +getlantern.org +getmdl.io +getsmartlinks.com +getsocialscope.com +gettrials.com +gettyimages.com +getuploader.com +gfbv.de +gfgold.com.hk +gfsale.com +gfw.org.ua +gfw.press +ggpht.com +ggssl.com +ghost.org +ghostpath.com +ghut.org +giga-web.jp +gigporno.ru +gimpshop.com +girlbanker.com +github.com +git.io +git-scm.com +givemesomethingtoread.com +gizlen.net +gjczz.com +glass8.eu +glennhilton.com +globaljihad.net +globalmediaoutreach.com +globalmuseumoncommunism.org +globalrescue.net +globaltm.org +globalvoicesonline.org +glock.com +gloryhole.com +glype.com +gmail.com +gmbd.cn +gmhz.org +gmll.org +gmodules.com +gmozomg.izihost.org +gnci.org.hk +go141.com +goagent.biz +goagent.codeplex.com +goagentplus.com +gobet.cc +godfootsteps.org +godns.work +godoc.org +godsdirectcontact.co.uk +godsdirectcontact.org +godsdirectcontact.org.tw +godsimmediatecontact.com +gogotunnel.com +gohappy.com.tw +gojet.krtco.com.tw +gokbayrak.com +golang.org +goldbet.com +goldbetsports.com +goldenfrog.com +goldstep.net +goldwave.com +gongmeng.info +gongm.in +gongminliliang.com +gongwt.com +gooddns.info +goodreaders.com +goodreads.com +goodtv.com.tw +goodtv.tv +goofind.com +goo.gl +googleadservices.com +google.ae +google.am +google-analytics.com +googleapis.com +googleapps.com +googleartproject.com +google.as +googleblog.com +googlebot.com +googlecapital.com +google.cat +google.cd +google.ci +googlecode.com +google.co.id +google.co.jp +google.co.kr +google.com +google.co.ma +google.com.hk +googlecommerce.com +google.com.sg +google.com.tw +google.com.uk +google.co.uk +google.de +google.dj +google.dk +googledomains.com +googledrive.com +googleearth.com +google.es +google.fi +google.fm +google.fr +google.gg +googlegroups.com +googlehosted.com +googleideas.com +google.ie +google.is +google.it +googlelabs.com +googlemail.com +google.ms +google.nl +google.no +google.nu +googleplay.com +googleplus.com +google.ro +google.sc +googlesile.com +google.sk +google.sm +googlesource.com +googlesyndication.com +googletagmanager.com +googletagservices.com +google.tk +google.to +google.tt +googleusercontent.com +googlevideo.com +google.vu +google.ws +googlezip.net +gopetition.com +go-pki.com +goproxing.net +gospelherald.com +got-game.org +gotgeeks.com +gotrusted.com +gotw.ca +gov.cn +gov.tw +gpass1.com +g-queen.com +gr8domain.biz +gr8name.biz +grammaly.com +grandtrial.org +grangorz.org +graphis.ne.jp +gravatar.com +graylog2.org +greasespot.net +greatfire.org +greatfire.us7.list-manage.com +greatfirewall.biz +great-firewall.com +greatfirewallofchina.net +greatfirewallofchina.org +great-roc.org +greatroc.org +greatroc.tw +greatzhonghua.org +greenfieldbookstore.com.hk +greenparty.org.tw +greenpeace.com.tw +greenpeace.org +greenvpn.net +greenvpn.org +groups.google.cn +gs-discuss.com +gseeker.com +gstatic.com +gtricks.com +guancha.org +guardster.com +gu-chu-sum.org +gufeng521.spaces.live.com +guishan.org +gunsamerica.com +gunsandammo.com +gun-world.net +guomin.us +guruonline.hk +gutteruncensored.com +gvlib.com +gvm.com.tw +gvt0.com +gvt1.com +gvt3.com +gwtproject.org +gyalwarinpoche.com +gyatsostudio.com +gzm.tv +gzone-anime.info +h1n1china.org +h5dm.com +h5galgame.me +hacg.club +hacg.in +hacg.li +hacg.red +hacken.cc +hackthatphone.net +hahlo.com +hakkatv.org.tw +hanunyi.com +haosou.com +happy-vpn.com +hardsextube.com +harunyahya.com +hasaowall.com +hautelookcdn.com +hautelook.com +have8.com +haygo.com +h-china.org +hdtvb.net +hdzog.com +heartyit.com +hecaitou.net +hechaji.com +hec.su +heeact.edu.tw +hegre-art.com +heix.pp.ru +heiyo.info +helloandroid.com +hellonewyork.us +helloqueer.com +hellotxt.com +hellouk.org +helpeachpeople.com +helplinfen.com +help.linksalpha.com +help.opera.com +helpster.de +helpzhuling.org +hen.bao.li +hentai.to +hentaitube.tv +hentaivideoworld.com +heqinglian.net +here4news.com +heungkongdiscuss.com +hexxeh.net +heyzo.com +hgseav.com +hhdcb3office.org +hidden-advent.org +hidecloud.com +hideipvpn.com +hideman.net +hide.me +hideme.nl +hidemyass.com +hidemycomp.com +higfw.com +highpeakspureearth.com +highrockmedia.com +hihiforum.com +hihistory.net +hiitch.com +hikinggfw.org +hilive.tv +himalayan-foundation.org +himalayanglacier.com +himemix.com +himemix.net +hi-on.org.tw +hitomi.la +hizb-ut-tahrir.info +hizb-ut-tahrir.org +hizbuttahrir.org +hjclub.info +hk01.com +hk32168.com +hkatvnews.com +hkbc.net +hkbf.org +hkbookcity.com +hkchurch.org +hkcmi.edu +hkcoc.com +hkcoc.weather.com.hk +hkdailynews.com.hk +hkday.net +hkdf.org +hkej.com +hkepc.com +hkfaa.com +hkfreezone.com +hkfront.org +hkgolden.com +hkgreenradio.org +hk.hao123img.com +hkheadline.com +hkhkhk.com +hkhrc.org.hk +hkhrm.org.hk +hkip.org.uk +hkjc.com +hk.jiepang.com +hkjp.easyweb.hk +hkjp.org +hk.knowledge.yahoo.com +hklft.com +hklts.org.hk +hk.myblog.yahoo.com +hk.news.yahoo.com +hkptu.org +hk-pub.com +hk.rd.yahoo.com +hkreporter.com +hkreporter.loved.hk +hk.search.yahoo.com +hkupop.hku.hk +hkusu.net +hk.video.news.yahoo.com +hkvwet.com +hkwcc.org.hk +hk.yahoo.com +hkzone.org +h-moe.com +hmvdigital.ca +hmvdigital.com +hnjhj.com +hnntube.com +hola.com +hola.org +holymountaincn.com +holyspiritspeaks.org +holz.byethost8.com +homedepot.com +homeperversion.com +homeservershow.com +home.sina.com +home.so-net.net.tw +honeonet.spaces.live.com +hongkongfp.com +hongmeimei.com +hongzhi.li +hootsuite.com +hoovers.com +hopto.org +hornygamer.com +hotav.tv +hotfrog.com.tw +hotgoo.com +hotpornshow.com +hotpot.hk +hotshame.com +hotspotshield.com +hotvpn.com +hougaige.com +howtoforge.com +hqcdp.org +hqjapanesesex.com +hqmovies.com +hrcchina.org +hrcir.com +hrea.org +hrichina.org +hrweb.org +hrw.org +hsjp.net +hsselite.com +hstern.net +hst.net.tw +hstt.net +htkou.net +htl.li +ht.ly +html5rocks.com +htmldog.com +https443.net +https443.org +huaglad.com +huajiadi.spaces.live.com +huanghuagang.org +huangyiyu.com +huaren.us +huaxiabao.org +huaxia-news.com +huaxin.ph +hua-yue.net +huayuworld.org +hudatoriq.web.id +hugoroy.eu +huhaitai.com +huhamhire.com +huiyi.in +hujiachina.spaces.live.com +hulkshare.com +hulu.com +huluim.com +humanities.uchicago.edu +humanrightsbriefing.org +hungerstrikeforaids.org +hung-ya.com +huping.net +hurgokbayrak.com +hurriyet.com.tr +hustlercash.com +hut2.ru +hutianyi.net +hutong9.net +huyandex.com +hwayue.org.tw +hwinfo.com +hxwq.org +hybrid-analysis.com +hyperrate.com +hypeshell.com +i1.hk +i2p2.de +i2runner.com +i818hk.com +ialmostlaugh.com +iam.soy +iask.bz +iask.ca +iav19.com +ibiblio.org +iblist.com +iblogserv-f.net +ibros.org +ibvpn.com +i-cable.com +icams.com +icij.org +icl-fi.org +icoco.com +iconpaper.org +icu-project.org +idemocracy.asia +identi.ca +id.hao123.com +idiomconnection.com +idouga.com +idreamx.com +idv.tw +ieasynews.net +ied2k.net +ieemdai.spaces.live.com +ienergy1.com +ifan.cz.cc +ifanqiang.com +ifanr.com +ifcss.org +ifjc.org +ifreewares.com +ift.tt +igcd.net +igfw.net +igmg.de +ignitedetroit.net +igoogle.com +igotmail.com.tw +igvita.com +ihakka.net +iicns.com +ikwb.com +illusionfactory.com +ilove80.be +ilovelongtoes.com +im88.tw +imageab.com +imagefap.com +imageflea.com +images.comico.tw +imageshack.us +imagevenue.com +imagezilla.net +imb.org +imgchili.net +img.ly +imkev.com +imlive.com +immoral.jp +impact.org.au +impp.mn +imrworldwide.com +im.tv +in99.org +incapdns.net +incloak.com +incredibox.fr +indiandefensenews.in +indiemerch.com +in-disguise.com +info-graf.fr +initiativesforchina.org +inkui.com +inmediahk.net +innermongolia.org +inote.tw +insecam.org +instagram.com +instanthq.com +institut-tibetain.org +interestinglaugh.com +interfaceaddiction.com +internationalrivers.org +internetdefenseleague.org +internetfreedom.org +internetpopculture.com +inxian.com +iownyour.biz +iownyour.org +ipalter.com +i-part.com.tw +ipcf.org.tw +iphone4hongkong.com +iphonehacks.com +iphonetaiwan.org +iphonix.fr +ipicture.ru +ipjetable.net +ipobar.com +iportal.me +ippotv.com +ipredator.se +iptorrents.com +iptv.com.tw +ipvanish.com +iredmail.org +ironbigfools.compython.net +ironicsoftware.com +ironpython.net +isaacmao.com +isasecret.com +is.gd +isgreat.org +islamhouse.com +islamicity.com +islamicpluralism.org +islam.org.hk +islamtoday.net +ismaelan.com +ismalltits.com +ismprofessional.net +isohunt.com +israbox.com +istars.co.nz +istiqlalhewer.com +istockphoto.com +isunaffairs.com +isuntv.com +itaboo.info +italiatibet.org +itasoftware.com +itemdb.com +ithelp.ithome.com.tw +itsaol.com +itshidden.com +itsky.it +itweet.net +iu45.com +iuhrdf.org +iuksky.com +ivacy.com +iverycd.com +ivpn.net +ixquick.com +ixxx.com +iyouport.com +izaobao.us +izlesem.org +izles.net +jamaat.org +jamyangnorbu.com +janwongphoto.com +japan-whores.com +jav68.tv +javakiba.org +javbus.com +javfor.me +javhip.com +javhub.net +javhuge.com +javlibrary.com +javmoo.com +javmoo.xyz +javseen.com +javtag.com +javzoo.com +jayparkinsonmd.com +jbtalks.cc +jbtalks.com +jbtalks.my +jcpenney.com +jdwsy.com +jeanyim.com +jetos.com +jgoodies.com +jiangweiping.com +jiaoyou8.com +jiehua.cz +jieshibaobao.com +jigong1024.com +jike.com +jimoparty.com +jinbushe.org +jingpin.org +jingsim.org +jinpianwang.com +jitouch.com +jizzthis.com +jjgirls.com +jkb.cc +jkforum.net +jkub.com +jma.go.jp +j.mp +joachims.org +jobso.tv +joeedelman.com +journalchretien.net +journalofdemocracy.org +joymiihub.com +jp.hao123.com +jpl.nasa.gov +jpopforum.net +juhuaren.com +juliepost.com +juliereyc.com +junauza.com +june4commemoration.org +junefourth-20.net +jungleheart.com +justdied.com +justfreevpn.com +justicefortenzin.org +justpaste.it +justtristan.com +juyuange.org +juziyue.com +jwmusic.org +jyxf.net +jyzj.waqn.com +k2.xrea.com +kagyuoffice.org +kagyuoffice.org.tw +kaiyuan.de +kakao.com +kankan.today +kannewyork.com +kanshifang.com +kanzhongguo.com +kanzhongguo.eu +kaotic.com +karayou.com +karkhung.com +karmapa.org +karmapa-teachings.org +kat.cr +ka-wai.com +kawaiikawaii.jp +kba-tx.org +kcoolonline.com +kcsoftwares.com +kebrum.com +kechara.com +keepandshare.com +kendincos.net +kenengba.com +keontech.net +kepard.com +keycdn.com +khabdha.org +khatrimaza.org +khmusic.com.tw +kichiku-doujinko.com +killwall.com +kindleren.com +kingdomsalvation.org +kinghost.com +kingstone.com.tw +kink.com +kir.jp +kissbbao.cn +kissyoutube.com +kiwi.kz +kk-whys.co.jp +knowledgerush.com +kodingen.com +kompozer.net +konachan.com +koolsolutions.com +koornk.com +koranmandarin.com +ksnews.com.tw +kt.kcome.org +ktzhk.com +kui.name +kun.im +kurashsultan.com +kurtmunger.com +kusocity.com +kusos.com +kwcg.ca +kwongwah.com.my +kyohk.net +kyoyue.com +kzeng.info +labiennale.org +ladbrokes.com +la-forum.org +lagranepoca.com +lalulalu.com +lamayeshe.com +lamnia.co.uk +lamrim.com +lanterncn.cn +lantosfoundation.org +laod.cn +laogai.org +laomiu.com +laoyang.info +laptoplockdown.com +laqingdan.net +larsgeorge.com +lastcombat.com +lastfm.es +latelinenews.com +latibet.org +latimesblogs.latimes.com +lazarsearlymusic.com +ld.hao123img.com +leafyvpn.net +leecheukyan.org +lefora.com +left21.hk +legalporno.com +legaltech.law.com +leirentv.ca +leisurecafe.ca +leisurepro.com +lematin.ch +lemonde.fr +lenwhite.com +lerosua.org +lesoir.be +lesscss.org +letscorp.net +le-vpn.com +lflink.com +lflinkup.com +lflinkup.net +lflinkup.org +lhakar.org +lhasocialwork.org +liangyou.net +liansi.org +lianyue.net +liaowangxizang.net +liberal.org.hk +libertytimes.com.tw +lich355.megabyet.net +lidecheng.com +life.fly4ever.me +lighten.org.tw +like.com +limiao.net +line.me +linglingfa.com +lingvodics.com +linkideo.com +linkuswell.com +linuxconfig.org +linux-engineer.net +linux.org.hk +linuxreviews.org +linuxtoy.org +lionsroar.com +lipuman.com +listentoyoutube.com +list.ly +listorious.com +lists.debian.org +lists.w3.org +littlebigdetails.com +liudejun.com +liuhanyu.com +liujianshu.com +liu.lu +liuxiaotong.com +livedoor.jp +liveleak.com +livestation.com +livestream.com +livevideo.com +livingonline.us +livingstream.com +liwangyang.com +lizhizhuangbi.com +lkcn.net +load.to +lobsangwangyal.com +localdomain.ws +localpresshk.com +lockdown.com +lockestek.com +lofi.e-hentai.org +logbot.net +logiqx.com +logmike.com +londonchinese.ca +london.neighborhoodr.com +longhair.hk +longmusic.com +longtermly.net +longtoes.com +lookatgame.com +lookingglasstheatre.org +lookpic.com +looktoronto.com +lotuslight.org.hk +lotuslight.org.tw +lovequicksilver.com +lovesphinx.tk +lovetvshow.com +lpsg.com +lrfz.com +lrip.org +lsd.org.hk +lsforum.net +lsmchinese.org +lsmkorean.org +lsm.org +lsmwebcast.com +lsxszzg.com +ltn.com.tw +lua.org +lua-users.org +luke54.com +luke54.org +lupm.org +lushstories.com +luxebc.com +lvhai.org +lvv2.com +lyfhk.net +lyricsquote.com +macgamestore.com +macrovpn.com +macts.com.tw +mad-ar.ch +madewithcode.com +madmenunbuttoned.com +madonna-av.com +madthumbs.com +magic-net.info +mahabodhi.org +ma.hao123.com +maiio.net +mail-archive.com +maildns.xyz +maiplus.com +maizhong.org +makemymood.com +makzhou.warehouse333.com +malaysiakini.com +mangafox.com +mangafox.me +maniash.com +manicur4ik.ru +mansion.com +mansionpoker.com +maplew.com +marc.info +marco.org +marguerite.su +marines.mil +markmilian.com +martau.com +martincartoons.com +martsangkagyuofficial.org +maruta.be +marxist.com +marxist.net +marxists.org +mashable.com +mash.to +maskedip.com +matainja.com +mathable.io +mathiew-badimon.com +matome-plus.com +matome-plus.net +matsushimakaede.com +mattwilcox.net +maturejp.com +maxgif.com +maxing.jp +mayimayi.com +mcadforums.com +mcaf.ee +mcfog.com +mcreasite.com +md-t.org +mediachinese.com +mediafire.com +mediafreakcity.com +media.org.hk +medium.com +meetup.com +mefeedia.com +mefound.com +megaporn.com +megaproxy.com +megarotic.com +megavideo.com +megurineluka.com +meirixiaochao.com +melon-peach.com +meltoday.com +memedia.cn +memehk.com +meme.yahoo.com +memorybbs.com +memrijttm.org +memri.org +mercyprophet.org +meridian-trust.org +meripet.biz +meripet.com +merit-times.com.tw +meshrep.com +mesotw.com +messenger.com +metacafe.com +metarthunter.com +meteorshowersonline.com +metrolife.ca +metroradio.com.hk +meyou.jp +meyul.com +mfxmedia.com +mgoon.com +mgstage.com +mh4u.org +m.hkgalden.com +mhradio.org +michaelanti.com +michaelmarketl.com +middle-way.net +mihk.hk +mihr.com +mihua.org +mike.cz.cc +mikesoltys.com +milph.net +milsurps.com +mimiai.net +mimivip.com +mimivv.com +mindrolling.org +minghui-a.org +minghui-b.org +minghui.org +minghui.or.kr +minghui-school.org +mingjinglishi.com +mingjingnews.com +mingjingtimes.com +mingpaocanada.com +mingpao.com +mingpaomonthly.com +mingpaonews.com +mingpaony.com +mingpaosf.com +mingpaotor.com +mingpaovan.com +mingshengbao.com +minhhue.net +miniforum.org +minimalmac.com +mininova.org +ministrybooks.org +minzhuhua.net +minzhuzhanxian.com +minzhuzhongguo.org +miroguide.com +mirrorbooks.com +mitao.com.tw +mitbbs.com +mixedmedialabs.com +mixero.com +mixpod.com +mixx.com +mizzmona.com +mk5000.com +mlcool.com +mmaaxx.com +m.me +mmmca.com +mobatek.net +mobile01.com +mobileways.de +mobypicture.com +moby.to +modfetish.com +moeerolibrary.com +mofaxiehui.com +mofos.com +mog.com +molihua.org +mondex.org +moneyhome.biz +mo.nightlife141.com +monitorchina.org +monster.com +moodyz.com +moonbbs.com +morningsun.org +moroneta.com +motherless.com +motor4ik.ru +m.oulove.org +mousebreaker.com +movabletype.com +movements.org +moviefap.com +mp3buscador.com +mp3ye.eu +mpettis.com +mpfinance.com +mpinews.com +m.plixi.com +mponline.hk +mrbasic.com +mrbonus.com +mrdoob.com +mrface.com +mrslove.com +mrtweet.com +msguancha.com +m.slandr.net +mswe1.org +m-team.cc +mthruf.com +m.tweete.net +mtw.tl +muchosucko.com +mullvad.net +multiply.com +multiproxy.org +multiupload.com +mummysgold.com +muouju.com +murmur.tw +muselinks.co.jp +musicade.net +muslimvideo.com +muzi.com +muzi.net +muzu.tv +mvg.jp +mx981.com +mx.hao123.com +my03.com +myactimes.com +my-addr.com +myaudiocast.com +myav.com.tw +mybbs.us +myboooks.googlepages.com +myca168.com +mychinamyhome.com +mychinanet.com +mychinanews.com +mycnnews.com +mydad.info +myddns.com +myeasytv.com +myeclipseide.com +my-formosa.com +myforum.com.hk +myforum.com.uk +myfreecams.com +myfreepaysite.com +myfreshnet.com +myftp.info +myftp.name +my.keso.cn +mykomica.org +mylftv.com +my.mail.ru +mymom.info +mymusic.net.tw +mynetav.net +mynetav.org +mynumber.org +myopenid.com +my.opera.com +myparagliding.com +mypicture.info +mypop3.net +mypop3.org +mypopescu.com +my-private-network.co.uk +my-proxy.com +mysecondarydns.com +myshare.url.com.tw +mysinablog.com +myspace.com +mytalkbox.com +mytizi.com +mywww.biz +myz.info +naacoalition.org +naitik.net +nakido.com +nalandabodhi.org +nalandawest.org +namgyalmonastery.org +namgyal.org +namsisi.com +nanyang.com +nanyangpost.com +nanzao.com +naol.ca +national-lottery.co.uk +nationwide.com +naughtyamerica.com +navicat.com +navigeaters.com +navy.mil +nbtvpn.com +nccwatch.org.tw +nch.com.tw +ncn.org +nde.de +ndr.de +ned.org +nekoslovakia.net +netbirds.com +netcolony.com +netflix.com +netme.cc +netsneak.com +network54.com +networkedblogs.com +neverforget8964.org +new-3lunch.net +new96.ca +new-akiba.com +newcenturymc.com +newcenturynews.com +newchen.com +newgrounds.com +newipnow.com +newlandmagazine.com.au +newnews.ca +news100.com.tw +newsancai.com +news.atebits.com +newscn.org +news.cnyes.com +newsdh.com +news.ghostery.com +news.hk.msn.com +news.hkpeanut.com +newsminer.com +news.msn.com.tw +news.now.com +news.omy.sg +newspeak.cc +newspp.org +news.sina.com.hk +news.sinchew.com.my +news.singtao.ca +newstamago.com +newstapa.org +newstarnet.com +news.tvbs.com.tw +newtaiwan.com.tw +newtalk.tw +newyorktimes.com +nexon.com +next11.co.jp +nextmag.com.tw +nextmedia.com +nexton-net.jp +nexttv.com.tw +nf.id.au +nga.mil +ngensis.com +nhentai.net +nic.cz.cc +nic.google +nicovideo.tw +nighost.org +ninecommentaries.com +ninjacloak.com +ninjaproxy.ninja +nintendium.com +nintendowifi.net +ninth.biz +niusnews.com +njactb.org +njuice.com +nlfreevpn.com +nobelprize.org +nobel.se +nobodycanstop.us +no-ip.org +nokogiri.org +nokola.com +noobbox.com +noodlevpn.com +norbulingka.org +nordstrom.com +nordstromimage.com +nordstromrack.com +nordvpn.com +notes.alexdong.com +nottinghampost.com +novelasia.com +nownews.com +nowtorrents.com +noypf.com +npa.go.jp +npnt.me +nps.gov +nrk.no +ns01.biz +ns01.info +ns01.us +ns02.biz +ns02.info +ns02.us +ns1.name +ns2.name +ns3.name +ntd.tv +ntdtv.ca +ntdtv.co +ntdtv.co.kr +ntdtv.com +ntdtv.cz +ntdtvla.com +ntdtv.org +ntdtv.ru +ntrfun.com +nubiles.net +nuexpo.com +nukistream.com +nurgo-software.com +nusatrip.com +nuuvem.com +nuvid.com +nuzcom.com +nvquan.org +nwtca.org +nyaa.eu +nyaa.se +nydus.ca +nylon-angel.com +nylonstockingsonline.com +nysingtao.com +ny.stgloballink.com +nytco.com +nyt.com +nytimes.com +nytimg.com +ny.visiontimes.com +nzchinese.com +nzchinese.net.nz +observechina.net +obutu.com +ocaspro.com +occupytiananmen.com +oclp.hk +ocreampies.com +ocry.com +october-review.org +oculus.com +offbeatchina.com +officeoftibet.com +ogaoga.org +oikos.com.tw +oiktv.com +oizoblog.com +okayfreedom.com +okk.tw +old-cat.net +old.nabble.com +olumpo.com +olympicwatch.org +omgili.com +omni7.jp +omnitalk.com +omnitalk.org +on2.com +on.cc +onedrive.live.com +onedumb.com +one.xthost.info +onion.city +onlinecha.com +online.recoveryversion.org +onlineyoutube.com +onlylady.cn +onmoon.com +onmoon.net +onmypc.biz +onmypc.info +onmypc.net +onmypc.org +onmypc.us +onthehunt.com +ontrac.com +oopsforum.com +ooyala.com +openallweb.com +open.com.hk +opendemocracy.net +opendn.xyz +openervpn.in +openid.net +openleaks.org +openvpn.net +openvpn.org +openwebster.com +opml.radiotime.com +opnir.com +organcare.org.tw +organharvestinvestigation.net +organiccrap.com +orgfree.com +orientaldaily.com.my +orient-doll.com +orn.jp +orzistic.org +osfoora.com +otnd.org +otto.de +otzo.com +ourdearamy.com +ourhobby.com +oursogo.com +oursteps.com.au +oursweb.net +ourtv.hk +overlapr.com +overplay.net +oversea.istarshine.com +owl.li +ow.ly +oyax.com +ozchinese.com +ozxw.com +ozyoyo.com +pachosting.com +pacificpoker.com +packages.debian.org +packetix.net +pacopacomama.com +padmanet.com +page2rss.com +page.bid.yahoo.com +pagodabox.com +paint.net +palacemoon.com +paldengyal.com +paljorpublications.com +paltalk.com +panacom.co.jp +panamapapers.sueddeutsche.de +pandapow.net +pandavpn-jp.com +pandora.com +pandora.tv +panluan.net +panoramio.com +pao-pao.net +paperb.us +paper.li +paper-replika.com +parade.com +paradisepoker.com +parislemon.com +parkansky.com +partycasino.com +partypoker.com +passion.com +passiontimes.hk +pastebin.com +pastie.org +pbs.org +pbwiki.com +pbworks.com +pbxes.com +pbxes.org +pcanywhere.net +pcdiscuss.com +pcdvd.com.tw +pchome.com.tw +pcij.org +pct.org.tw +pcworld.com +pdetails.com +pdproxy.com +pds.nasa.gov +peace.ca +peacefire.org +peacehall.com +pearlher.org +peeasian.com +peerpong.com +pekingduck.org +pemulihan.or.id +penchinese.com +penchinese.net +pengyulong.com +pen.io +penisbot.com +penthouse.com +peoplebookcafe.com +peoplenews.tw +peopo.org +percy.in +perfectgirls.net +perfectvpn.net +perfspot.com +perlhowto.com +persecutionblog.com +pfd.org.hk +phapluan.org +phayul.com +philborges.com +philly.com +phncdn.com +phosphation13.rssing.com +photodharma.net +photofocus.com +photos.dailyme.com +photo.utom.us +phuquocservices.com +picasaweb.com +picidae.net +picturesocial.com +pidown.com +pign.net +pimg.tw +pin6.com +ping.fm +pinoy-n.com +pioneer-worker.forums-free.com +piposay.com +piraattilahti.org +piring.com +pixanalytics.com +pixelqi.com +pixfs.net +pixnet.cc +pixnet.net +pixplug.in +pk.com +placemix.com +planetsuzy.org +playboy.com +playboyplus.com +playno1.com +playpcesor.com +plays.com.tw +plm.org.hk +plunder.com +plurk.com +plurktop.mmdays.com +plus28.com +plusbb.com +pmatehunter.com +pmates.com +po2b.com +podictionary.com +pokerstars.com +pokerstars.net +politicalchina.org +politicalconsultation.org +polymerhk.com +polymer-project.org +popo.tw +popvote.hk +popyard.com +popyard.org +porn2.com +porn5.com +pornbase.org +porn.com +pornerbros.com +pornhd.com +pornhost.com +pornhub.com +pornmm.net +pornoxo.com +pornrapidshare.com +pornsharing.com +pornstarclub.com +porntube.com +porntubenews.com +porntvblog.com +pornvisit.com +port25.biz +portablevpn.nl +portis21.spaces.live.com +pose.com +poskotanews.com +post852.com +postadult.com +post.anyu.org +posterous.com +postimg.org +post.ly +power.com +powercx.com +powerphoto.org +prayforchina.net +premeforwindows7.com +presentationzen.com +prestige-av.com +previewshots.com +prisoneralert.com +pritunl.com +privacybox.de +privateinternetaccess.com +privatepaste.com +privatetunnel.com +privatevpn.com +procopytips.com +program-think.spaces.live.com +prosiben.de +provideocoalition.com +provpnaccounts.com +proxfree.com +proxifier.com +proxomitron.info +proxpn.com +proxyanonimo.es +proxydns.com +proxylist.org.uk +proxynetwork.org.uk +proxy.org +proxypy.net +proxyroad.com +proxytunnel.net +proyectoclubes.com +prozz.net +psblog.name +psiphon3.com +psiphon.ca +psiphon.civisec.org +pts.org.tw +ptt.cc +pttvan.org +pubu.com.tw +puffinbrowser.com +puffstore.com +pullfolio.com +pulse.yahoo.com +pure18.com +pureconcepts.net +pureinsight.org +purepdf.com +purevpn.com +purplelotus.org +pussyspace.com +putihome.org +putlocker.com +putty.org +puuko.com +pwned.com +python.com +python.com.tw +qanote.com +qgirl.com.tw +qhigh.com +qidian.ca +qienkuen.org +qi-gong.me +qiwen.lu +qixianglu.cn +qkshare.com +qoos.com +qpoe.com +qq.co.za +qstatus.com +qtrac.eu +qtweeter.com +quadedge.com +questvisual.com +quitccp.net +quitccp.org +quran.com +quranexplorer.com +qusi8.net +qvodzy.org +qxbbs.org +r18.com +radicalparty.org +radiko.jp +radioaustralia.net.au +radiohilight.net +radiovaticana.org +radiovncr.com +rael.org +ra.gg +raggedbanner.com +raidcall.com.tw +raidtalk.com.tw +raizoji.or.jp +rangwang.biz +rangzen.com +rangzen.net +rangzen.org +ranyunfei.com +rapbull.net +rapidmoviez.com +rapidshare8.com +rapidsharedata.com +rapidvpn.com +raremovie.cc +raremovie.net +rayfme.com +razyboard.com +rcinet.ca +rconversation.blogs.com +rd.com +rdio.com +read100.com +readingtimes.com.tw +readmoo.com +readydown.com +realcourage.org +realforum.zkiz.com +realraptalk.com +rebatesrule.net +recaptcha.net +recordhistory.org +recovery.org.tw +recoveryversion.com.tw +redchinacn.net +redchinacn.org +redhotlabs.com +redtube.com +referer.us +reflectivecode.com +registry.google +relaxbbs.com +relay.com.tw +releaseinternational.org +religioustolerance.org +renminbao.com +renyurenquan.org +retweeteffect.com +retweetist.com +retweetrank.com +reuters.com +revleft.com +revsci.net +revver.com +rfachina.com +rfamobile.org +rfa.org +rfaweb.org +rferl.org +rfi.fr +rhcloud.com +rigpa.org +riku.me +rileyguide.com +ritouki.jp +rlwlw.com +rmjdw132.info +rmjdw.com +rnw.nl +roadshow.hk +robtex.com +robustnessiskey.com +rocket-inc.net +rocmp.org +roc-taiwan.org +rojo.com +rolia.net +ronjoneswriter.com +roodo.com +rosechina.net +rotten.com +rsf-chinese.org +rsf.org +rsgamen.org +rssmeme.com +rtalabel.org +rthk.hk +rthk.org.hk +rti.org.tw +rtycminnesota.org +ruanyifeng.com +rukor.org +rushbee.com +rutube.ru +ruyiseek.com +rxhj.net +s1heng.com +s1.nudezz.com +s1s1s1.com +s8forum.com +sacom.hk +sadistic-v.com +sadpanda.us +safervpn.com +sa.hao123.com +saiq.me +sakuralive.com +sakya.org +salvation.org.hk +samair.ru +sambhota.org +sammyjs.org +samsoff.es +sandnoble.com +sankaizok.com +sanmin.com.tw +sapikachu.net +savemedia.com +savetibet.de +savetibet.fr +savetibet.nl +savetibet.org +savetibet.ru +savevid.com +say2.info +sbme.me +scanscout.com +scasino.com +schema.org +sciencenets.com +scieron.com +scihub.org +scmpchinese.com +scmp.com +scorecardresearch.com +scramble.io +scribd.com +scriptspot.com +s-cute.com +s-dragon.org +seapuff.com +search.aol.com +search.disconnect.me +searchtruth.com +secretchina.com +secretgarden.no +secretsline.biz +secure.hustler.com +secure.logmein.com +securetunnel.com +secure.wikimedia.org +securitykiss.com +seesmic.com +seevpn.com +seezone.net +sejie.com +sellclassics.com +sendoid.com +sendsmtp.com +sendspace.com +serveuser.com +serveusers.com +sesawe.net +sesawe.org +sethwklein.net +setn.com +sevenload.com +sex-11.com +sex3.com +sex8.cc +sexandsubmission.com +sexbot.com +sex.com +sexhuang.com +sexhu.com +sexidude.com +sexinsex.net +sextvx.com +sexxxy.biz +sfileydy.com +sfshibao.com +sftindia.org +sftuk.org +shadow.ma +shadowsky.xyz +shadowsocks.com +shadowsocks.org +shahamat-english.com +shambhalasun.com +shangfang.org +shapeservices.com +sharebee.com +sharecool.org +share.ovi.com +share.skype.com +share.youthwant.com.tw +sharkdolphin.com +sharpdaily.com.hk +sharpdaily.hk +sharpdaily.tw +shat-tibet.com +shaunthesheep.com +sheikyermami.com +shellfire.de +shellmix.com +shenshou.org +shenyun.com +shenyunperformingarts.org +shenzhoufilm.com +sherabgyaltsen.com +shiatv.net +shicheng.org +shinychan.com +shipcamouflage.com +shitaotv.org +shixiao.org +shizhao.org +shkspr.mobi +shodanhq.com +shop2000.com.tw +shopping.com +showbiz.omy.sg +showhaotu.com +showtime.jp +shutterstock.com +shwchurch3.com +shwchurch.org +sidelinesnews.com +sidelinessportseatery.com +sijihuisuo.club +sijihuisuo.com +simplecd.me +simplecd.org +simpleproductivityblog.com +sina.com.tw +singaporepools.com.sg +singfortibet.com +singpao.com.hk +singtao.com +singularitys.spaces.live.com +sinoants.com +sinocast.com +sinocism.com +sino-monthly.com +sinomontreal.ca +sinonet.ca +sinopitt.info +sinoquebec.com +sis001.com +sis001.us +sis.xxx +site90.net +sitebro.tw +sitekreator.com +siteks.uk.to +site.locql.com +sitemaps.org +sites.google.com +sitetag.us +sixth.biz +siyi123123123.spaces.live.com +sjrt.org +sjum.cn +sketchappsources.com +skimtube.com +skybet.com +skyvegas.com +slacker.com +slavasoft.com +slaytizle.com +slheng.com +slickvpn.com +slideshare.net +slinkset.com +slutload.com +slyip.com +slyip.net +smartdnsproxy.com +smchbooks.com +smhric.org +smyxy.org +snapchat.com +snaptu.com +sndcdn.com +sneakme.net +snooper.co.uk +snowlionpub.com +sobees.com +socialwhale.com +sockscap64.com +sockslist.net +soc.mil +so.com +socrec.org +sod.co.jp +softether.co.jp +softether-download.com +softether.org +softwarebychuck.com +softwaredownload.gitbooks.io +so-ga.net +sogclub.com +sogou.com +sogrady.me +sohcradio.com +sohfrance.org +soh.tw +sokamonline.com +solarsystem.nasa.gov +solozorro.tk +somee.com +so-news.com +songjianjun.com +sonicbbs.cc +sonidodelaesperanza.org +sopcast.com +sopcast.org +sorazone.net +sorting-algorithms.com +soso.com +sos.org +sostibet.org +soubory.com +soulcaliburhentai.net +soul-plus.net +soumo.info +soundcloud.com +soundofhope.kr +soundofhope.org +soup.io +soupofmedia.com +sourceforge.net +sourcewadio.com +southnews.com.tw +sowers.org.hk +space-scape.com +spankbang.com +spankwire.com +spb.com +speakerdeck.com +speckleapp.com +specxinzl.jigsy.com +speedpluss.org +spem.at +spencertipping.com +spicevpn.com +spike.com +spinejs.com +sports.williamhill.com +spotflux.com +spotify.com +spring4u.info +springboardplatform.com +sprite.org +sproutcore.com +sproxy.info +squarespace.com +squirly.info +srcf.ucam.org +srocket.us +ssh91.com +ssl443.org +sspro.ml +sss.camp +sstatic.net +sstmlt.net +stage64.hk +standupfortibet.org +starfishfx.com +starp2p.com +startpage.com +statcounter.com +state168.com +static.comico.tw +static.digg.com +static-economist.com +staticflickr.com +statueofdemocracy.org +status.twhirl.org +stc.com.sa +steel-storm.com +stepchina.com +stephaniered.com +sthoo.com +stickam.com +stickeraction.com +stileproject.com +sto.cc +stonegames.net +stoneip.info +stoptibetcrisis.net +storagenewsletter.com +stories.google +storify.com +stormmediagroup.com +storm.mg +stoweboyd.com +stranabg.com +streamingthe.net +strongvpn.com +strongwindpress.com +studentsforafreetibet.org +student.tw +stuffimreading.com +stuffimreading.net +stumbleupon.com +stupidvideos.com +subacme.rerouted.org +sublexical.spaces.live.com +sufeng.org +sugarsync.com +sugobbs.com +suissl.com +summify.com +sumrando.com +sun1911.com +sunmedia.ca +sunporno.com +sunskyforum.com +sunvpn.net +suoluo.org +superpages.com +supervpn.net +suprememastertv.com +surfeasy.com +surfeasy.com.au +suroot.com +surrenderat20.net +suyangg.com +svwind.com +swagbucks.com +sweux.com +swift-tools.net +swissvpn.net +switch1.jp +switchvpn.net +sydneytoday.com +sylfoundation.org +syncback.com +synergyse.com +sysadmin1138.net +sysresccd.org +sytes.net +szbbs.net +szetowah.org.hk +t35.com +t66y.com +t88.ca +taa-usa.org +taaze.tw +tabtter.jp +tacem.org +taconet.com.tw +taedp.org.tw +tafaward.com +tafm.org +tagwalk.com +tagwa.org.au +tahr.org.tw +taipeisociety.org +taiwanbible.com +taiwancon.com +taiwandaily.net +taiwandc.org +taiwanembassy.org +taiwanjustice.com +taiwankiss.com +taiwannation.50webs.com +taiwannation.com +taiwannation.com.tw +taiwanncf.org.tw +taiwannews.com.tw +taiwan-sex.com +taiwantoday.tw +taiwantp.net +taiwantt.org.tw +taiwanus.net +taiwanyes.com +taiwanyes.ning.com +talk853.com +talkboxapp.com +talkonly.net +tamiaode.tk +tanc.org +tangben.com +tangren.us +taoism.net +taolun.info +tap11.com +tapanwap.com +target.com +tascn.com.au +taup.net +taweet.com +tbcollege.org +tbicn.org +tbi.org.hk +tbjyt.org +tbpic.info +tbsec.org +tbskkinabalu.page.tl +tbsmalaysia.org +tbsn.org +tbs-rainbow.org +tbsseattle.org +tbssqh.org +tbswd.org +tbtemple.org.uk +tbthouston.org +tccwonline.org +tcewf.org +tchrd.org +tcnynj.org +t.co +teamamericany.com +teamseesmic.com +teashark.com +techlifeweb.com +techparaiso.com +teck.in +teeniefuck.net +teensinasia.com +telecomspace.com +telegramdownload.com +telegram.org +telegraph.co.uk +tenacy.com +tensorflow.org +tew.org +thaicn.com +theampfactory.com +theappleblog.com +theatrum-belli.com +thebcomplex.com +theblemish.com +thebobs.com +thebodyshop-usa.com +thecenter.mit.edu +thechinabeat.org +thedailywh.at +thedalailamamovie.com +thedieline.com +thedw.us +thegatesnotes.com +thegly.com +thehots.info +thehousenews.com +thehungrydudes.com +thehun.net +theinitium.com +theinternetwishlist.com +thelifeyoucansave.com +thelius.org +thenewslens.com +thepiratebay.org +thepiratebay.se +theportalwiki.com +theqii.info +thereallove.kr +therock.net.nz +thesartorialist.com +thespeeder.com +thestandnews.com +thetibetcenter.org +thetibetconnection.org +thetibetmuseum.org +thetibetpost.com +thetrotskymovie.com +thevivekspot.com +thewgo.org +th.hao123.com +thinkingtaiwan.com +thinkwithgoogle.com +thisav.com +thisiswhyyouarefat.com +thkphoto.com +thlib.org +thomasbernhard.org +threatchaos.com +throughnightsfire.com +thumbzilla.com +thywords.com +thywords.com.tw +tiananmenduizhi.com +tiananmenmother.org +tiananmenuniv.com +tiananmenuniv.net +tiandixing.org +tianhuayuan.com +tianlawoffice.com +tiantibooks.org +tianti.io +tianzhu.org +tibet3rdpole.org +tibetaction.net +tibetaid.org +tibetalk.com +tibetanaidproject.org +tibetan-alliance.org +tibetanarts.org +tibetanbuddhistinstitute.org +tibetancommunityuk.net +tibetanculture.org +tibetanfeministcollective.org +tibetan.fr +tibetanlanguage.org +tibetanliberation.org +tibetanpaintings.com +tibetanphotoproject.com +tibetanpoliticalreview.org +tibetanreview.net +tibetanwomen.org +tibetanyouthcongress.org +tibetanyouth.org +tibet.a.se +tibet.at +tibet.ca +tibetcharity.dk +tibetcharity.in +tibetchild.org +tibetcity.com +tibetcollection.com +tibet.com +tibetcorps.org +tibet-envoy.eu +tibetexpress.net +tibetfocus.com +tibet-foundation.org +tibet.fr +tibetfund.org +tibetgermany.com +tibetgermany.de +tibethaus.com +tibetheritagefund.org +tibethouse.jp +tibethouse.org +tibet-house-trust.co.uk +tibethouse.us +tibet-info.net +tibetinfonet.net +tibet-initiative.de +tibetjustice.org +tibetkomite.dk +tibet-munich.de +tibetmuseum.org +tibet.net +tibetnetwork.org +tibet.nu +tibetoffice.ch +tibetoffice.com.au +tibetoffice.eu +tibetoffice.org +tibetonline.com +tibetonline.tv +tibetoralhistory.org +tibet.org +tibet.org.tw +tibetpolicy.eu +tibetrelieffund.co.uk +tibetsites.com +tibetsociety.com +tibetsun.com +tibetsupportgroup.org +tibetswiss.ch +tibettelegraph.com +tibettimes.net +tibet.to +tibetwrites.org +ticket.com.tw +tidyread.com +tiltbrush.com +timdir.com +time.com +times.hinet.net +timsah.com +tintuc101.com +tiny.cc +tinychat.com +tinypaste.com +tinypng.com +tistory.com +tjholowaychuk.com +tkcs-collins.com +tkforum.tk +tma.co.jp +tmagazine.com +tmdfish.com +tmi.me +tmpp.org +tnaflix.com +t.neolee.cn +tngrnow.com +tngrnow.net +tnp.org +togetter.com +toh.info +tokyo-247.com +tokyocn.com +tokyo-hot.com +tokyo-porn-tube.com +tomayko.com +tomsc.com +tongil.or.kr +tono-oka.jp +tonyyan.net +toodoc.com +toonel.net +top81.ws +topic.youthwant.com.tw +topnews.in +to-porno.com +topshare.us +topshareware.com +topstyle4.com +topsy.com +toptip.ca +tora.to +tor.blingblingsquad.net +torcn.com +torguard.net +torproject.org +torrentcrazy.com +torrentprivacy.com +torrentproject.se +torrenty.org +torrentz.eu +tor.updatestar.com +torvpn.com +t.orzdream.com +tosh.comedycentral.com +totalvpn.com +touch99.com +toutfr.com +towngain.com +toypark.in +toythieves.com +toytractorshow.com +tparents.org +tpi.org.tw +traffichaus.com +transgressionism.org +translate.google.cn +transparency.org +travelinlocal.com +treemall.com.tw +trendsmap.com +trialofccp.org +trickip.net +trickip.org +tripod.com +trouw.nl +trtc.com.tw +trt.net.tr +truebuddha-md.org +trulyergonomic.com +trustedbi.com +truth101.co.tv +truthcn.com +truthontour.org +truveo.com +tsctv.net +tsdr.uspto.gov +tsemtulku.com +tsquare.tv +tsunagarumon.com +tsu.org.tw +tt1069.com +tt-rss.org +tttan.com +tu8964.com +tuanzt.com +tubaholic.com +tube8.com +tube911.com +tubecao.com +tube.com +tubecup.com +tubegals.com +tubeislam.com +tubewolf.com +tuidang.net +tuidang.org +tuidang.se +tui.orzdream.com +tuitwit.com +tumblr.awflasher.com +tumblr.com +tumblweed.org +tumutanzi.com +tunein.com +tunnelbear.com +tuo8.cc +tuo8.club +tuo8.fit +tuo8.hk +tuo8.in +tuo8.ninja +tuo8.org +tuo8.pw +turansam.org +turbobit.net +turbohide.com +turbotwitter.com +turningtorso.com +turntable.fm +tushycash.com +tuvpn.com +tuxtraining.com +tuzaijidi.com +tvants.com +tvboxnow.com +tv.com +tvider.com +tv-intros.com +tvmost.com.hk +tvplayvideos.com +tvunetworks.com +tw01.org +twaitter.com +twapperkeeper.com +twa.sh +twaud.io +twbbs.net.tw +twbbs.org +twbbs.tw +twblogger.com +tweepguide.com +tweeplike.me +tweepmag.com +tweepml.org +tweetbackup.com +tweetboard.com +tweetboner.biz +tweetdeck.com +tweetedtimes.com +tweetmeme.com +tweetmylast.fm +tweetphoto.com +tweetrans.com +tweetree.com +tweettunnel.com +tweetwally.com +tweetymail.com +twerkingbutt.com +twftp.org +tw.gigacircle.com +tw.hao123.com +twibase.com +twibble.de +twibbon.com +twibs.com +twicsy.com +twiends.com +twifan.com +twiffo.com +twiggit.org +twilightsex.com +twilog.org +twimbow.com +twimg.com +twimg.edgesuite.net +twindexx.com +twip.me +twipple.jp +twishort.com +twistar.cc +twisterio.com +twister.net.co +twisternow.com +twistory.net +twit2d.com +twitbrowser.net +twitcause.com +twitese.spaces.live.com +twitgether.com +twitgoo.com +twitiq.com +twitlonger.com +twitmania.com +twitoaster.com +twitonmsn.com +twitpic.com +twitreferral.com +twitstat.com +twittbot.net +twitter4j.org +twitter.com +twittercounter.com +twitterfeed.com +twittergadget.com +twitter.jp +twitterkr.com +twittermail.com +twitterrific.com +twittertim.es +twitthat.com +twitturk.com +twitturly.com +twitvid.com +twitzap.com +twiyia.com +tw.jiepang.com +tw.knowledge.yahoo.com +tw.mall.yahoo.com +tw.mobi.yahoo.com +tw.myblog.yahoo.com +tw.news.yahoo.com +twnorth.org.tw +tw-npo.org +tw.rd.yahoo.com +twreg.info +twstar.net +tw.streetvoice.com +twt.fm +twtkr.com +tw.tomonews.net +twtrland.com +twt.tl +twttr.com +twurl.nl +tw.voa.mobi +twyac.org +tw.yahoo.com +txxx.com +tycool.com +tynsoe.org +typepad.com +tzangms.com +ub0.cc +ubddns.org +uberproxy.net +ucdc1998.org +uc-japan.org +uderzo.it +udn.com +uforadio.com.tw +ufreevpn.com +ugo.com +uhdwallpapers.org +uhrp.org +uighurbiz.net +uighur.narod.ru +uighur.nl +ukcdp.co.uk +ukliferadio.co.uk +ulike.net +ultravpn.fr +ultraxs.com +unblock.cn.com +unblockdmm.com +unblocksit.es +unblock-us.com +uncyclomedia.org +uncyclopedia.hk +uncyclopedia.info +uncyclopedia.tw +underwoodammo.com +unholyknight.com +uni.cc +unicode.org +unification.net +unification.org.tw +uniteddaily.com.my +unitedsocialpress.com +unix100.com +unknownspace.org +unodedos.com +unpo.org +untraceable.us +uocn.org +upcoming.yahoo.com +update.playstation.net +upholdjustice.org +upload4u.info +uploaded.to +uploadstation.com +upload.wikimedia.org +upornia.com +uproxy.org +upwill.org +ur7s.com +urbansurvival.com +urlborg.com +urlparser.com +usacn.com +usaip.eu +userapi.nytlog.com +usfk.mil +usinfo.state.gov +usma.edu +usmc.mil +us.to +ustream.tv +usus.cc +utopianpal.com +uu-gg.com +uushare.com +uvwxyz.xyz +uwants.com +uwants.net +uyghuramerican.org +uyghurcanadiansociety.org +uyghurcongress.org +uyghur.co.uk +uyghurensemble.co.uk +uyghur-j.org +uyghurpen.org +uyghurpress.com +uyghurstudies.org +uygur.org +v2ex.com +v2ray.com +v70.us +vaayoo.com +value-domain.com +van001.com +van698.com +vanemu.cn +vanilla-jp.com +vanpeople.com +vansky.com +vapurl.com +vatn.org +vcfbuilder.org +vcf-online.org +veempiire.com +vegasred.com +vegas.williamhill.com +velkaepocha.sk +venbbs.com +venchina.com +ventureswell.com +veoh.com +verizon.net +vermonttibet.org +versavpn.com +verybs.com +vevo.com +vft.com.tw +viber.com +vica.info +victimsofcommunism.org +vidble.com +video.aol.ca +video.aol.com +video.aol.co.uk +video.ap.org +videobam.com +videodetective.com +video.fdbox.com +video.foxbusiness.com +videomega.tv +videomo.com +videopediaworld.com +video.tiscali.it +video.yahoo.com +vid.me +vidoemo.com +vietdaikynguyen.com +views.fm +vijayatemple.org +viki.com +vimeocdn.com +vimeo.com +vimgolf.com +vimperator.org +vincnd.com +vinniev.com +visibletweets.com +vital247.org +viu.com +vivahentai4u.net +vivatube.com +vivthomas.com +vizvaz.com +vjmedia.com.hk +vllcs.org +vlog.xuite.net +vmixcore.com +vn.hao123.com +voa-11.akacast.akamaistream.net +voacantonese.com +voachineseblog.com +voachinese.com +voagd.com +voanews.com +voatibetan.com +voatibetanenglish.com +vocativ.com +vocn.tv +vot.org +vovo2000.com +voxer.com +voy.com +vpn4all.com +vpnaccount.org +vpnbook.com +vpncoupons.com +vpndada.com +vpnfan.com +vpnfire.com +vpnforgame.net +vpngate.jp +vpngate.net +vpngratis.net +vpnhq.com +vpninja.net +vpnmaster.com +vpnpick.com +vpnpop.com +vpnpronet.com +vpnreactor.com +vpnreviewz.com +vpnsecure.me +vpnsp.com +vpntunnel.com +vpnuk.info +vpnunlimitedapp.com +vpnvip.com +vporn.com +vpser.net +vraiesagesse.net +v-state.org +vtunnel.com +vuku.cc +w3schools.com +waffle1999.com +wahas.com +waigaobu.com +waikeung.org +waiwaier.com +wallornot.org +wallpapercasa.com +wallproxy.com +wallproxy.com.cn +waltermartin.com +waltermartin.org +wanderinghorse.net +wangafu.net +wangjinbo.org +wanglixiong.com +wango.org +wangruoshui.net +wangyi64.spaces.live.com +want-daily.com +wanz-factory.com +wapedia.mobi +warbler.iconfactory.net +waselpro.com +washeng.net +watchinese.com +watchmygf.net +wattpad.com +waveprotocol.org +wav.tv +wdf5.com +wearehairy.com +wearn.com +web2project.net +webbang.net +webevader.org +webfee.tk +webfreer.com +webjb.org +weblagu.com +webmproject.org +webrtc.org +webrush.net +webshots.com +website.informer.com +websitepulse.com +webs-tv.net +webwarper.net +webworkerdaily.com +weeewooo.net +weekmag.info +wefightcensorship.org +wefong.com +weibo.com +weiboleak.com +weiboscope.jmsc.hku.hk +weigegebyc.dreamhosters.com +weijingsheng.org +weiming.info +weiquanwang.org +weisuo.ws +wellplacedpixels.com +welovecock.com +wemigrate.org +wengewang.com +wengewang.org +wenhui.ch +wenku.com +wenxuecity.com +wenyunchao.com +wenyunchao.spaces.live.com +wepn.info +westca.com +westernshugdensociety.org +westernwolves.com +westkit.net +westpoint.edu +wetplace.com +wetpussygames.com +wexiaobo.org +wezhiyong.org +wezone.net +wforum.com +wha.la +whatblocked.com +whatbrowser.org +wheatseeds.org +wheelockslatin.com +whereiswerner.com +wheretowatch.com +whippedass.com +whitebear.freebearblog.org +whodns.xyz +whotalking.com +whydidyoubuymethat.com +whylover.com +whyx.org +w.idaiwan.com +wikaba.com +wiki.cnitter.com +wiki.gamerp.jp +wiki.jqueryui.com +wiki.keso.cn +wikileaks.ch +wikileaks.de +wikileaks.eu +wikileaks-forum.com +wikileaks.lu +wikileaks.org +wikileaks.pl +wikilivres.info +wikimapia.org +wikimedia.org.mo +wiki.moegirl.org +wikinet.org +wiki.oauth.net +wikipedia.org +wiki.phonegap.com +wikiwiki.jp +wikkii.com +wildammo.com +williamlong.spaces.live.com +willw.net +windowsphoneme.com +wingamestore.com +winning11.com +winwhispers.info +wiredbytes.com +wiredpen.com +wireshark.org +wisdompubs.org +wisevid.com +withgoogle.com +witnessleeteaching.com +witopia.net +wizcrafts.net +wjbk.org +wlcnew.jigsy.com +wlx.sowiki.net +wnacg.com +wn.com +woeser.com +wokar.org +wolfax.com +womensrightsofchina.org +woopie.jp +woopie.tv +wordboner.com +wordpress.com +wordsandturds.com +w.org +workatruna.com +workerdemo.org.hk +workersthebig.net +worldcat.org +worldjournal.com +worldvpn.net +worstthingieverate.com +wo.tc +wow.com +wowgirls.com +wowlegacy.ml +wow-life.net +wowporn.com +woxinghuiguo.com +woyaolian.org +wozy.in +wp.com +wpoforum.com +wqlhw.com +wqyd.org +wrchina.org +wretch.cc +writer.zoho.com +wsgzao.github.io +wsj.com +wsjhk.com +wsj.net +wtbn.org +wtfpeople.com +wuala.com +wuerkaixi.com +wufafangwen.com +wufi.org.tw +wuguoguang.com +wujieliulan.com +wujie.net +wukangrui.net +wwitv.com +www1.biz +www.6v6dota.com +www.ajsands.com +www.americorps.gov +www.antd.org +www.aolnews.com +www.bulbous.freeserve.co.uk +www.cmoinc.org +www.dfanning.com +www.dw.com +www.dwheeler.com +www.freetibet.org +www.getyouram.com +www.gmiddle.com +www.gmiddle.net +www.goldenmelody.com.tw +wwwhost.biz +www.idlcoyote.com +www.klip.me +www.lamenhu.com +www.linksalpha.com +www.loiclemeur.com +www.monlamit.org +www.moztw.org +www.m-sport.co.uk +www.mycould.com +www.orchidbbs.com +www.owind.com +www.oxid.it +www.powerpointninja.com +www.s4miniarchive.com +www.stackfile.com +www.supertweet.net +www.taup.org.tw +www.tiffanyarment.com +www.tv.com +www.urbanoutfitters.com +www.vegorpedersen.com +www.vpncup.com +www.wangruowang.org +www.wan-press.org +www.websnapr.com +www.wet123.com +www.zaurus.org.uk +wzyboy.im +x1949x.com +x24hr.com +x365x.com +xanga.com +x-art.com +xa.yimg.com +xbabe.com +x-berry.com +xbookcn.com +xcafe.in +xcity.jp +xcritic.com +xerotica.com +xfinity.com +xfm.pp.ru +xgmyd.com +xh4n.cn +xhamster.com +xianchawang.net +xianjian.tw +xianqiao.net +xiaochuncnjp.com +xiaod.in +xiaohexie.com +xiaolan.me +xiaoma.org +xiezhua.com +xihua.es +xing.com +xinhuanet.org +xinmiao.com.hk +xinqimeng.over-blog.com +xinsheng.net +xinshijue.com +xinyubbs.net +xiongpian.com +xiuren.org +xizang-zhiye.org +xjp.cc +xjtravelguide.com +xlfmtalk.com +xlfmwz.info +xml-training-guide.com +xmovies.com +xmusic.fm +xn--4gq171p.com +xn--p8j9a0d9c9a.xn--q9jyb4c +xnxx.com +xpdo.net +xpud.org +xrentdvd.com +xskywalker.com +xtube.com +xuchao.net +xuchao.org +xuzhiyong.net +xuzhuoer.com +xvedios.com +xvideo.cc +xvideos.com +xvideos.es +x-wall.org +xxbbx.com +xxlmovies.com +xxuz.com +xxx.com +xxxfuckmom.com +xxxx.com.au +xxxy.biz +xxxy.info +xxxymovies.com +xysblogs.org +xys.dxiong.com +xys.org +xyy69.com +xyy69.info +yahoo.cn +yahoo.com.hk +yakbutterblues.com +yam.com +yam.org.tw +yanghengjun.com +yanghengjun.spaces.live.com +yangjianli.com +yasni.co.uk +yasukuni.or.jp +ydy.com +yeahteentube.com +yecl.net +yeelou.com +yeeyi.com +yegle.net +yes123.com.tw +yesasia.com +yesasia.com.hk +yes-news.com +yes.xxx +yezimary.spaces.live.com +yfrog.com +ygto.com +yhcw.net +yibada.com +yibaochina.com +yidio.com +yilubbs.com +yingsuoss.com +yi.org +yipub.com +yobt.com +yogichen.org +yong.hu +yorkbbs.ca +youdao.com +youdontcare.com +youjizz.com +youmaker.com +youpai.org +youporn.com +youporngay.com +yourepeat.com +your-freedom.net +yourlisten.com +yourlust.com +yourprivatevpn.com +yourtrap.com +yousendit.com +youshun12.com +youthbao.com +youthnetradio.org +youtu.be +youtubecn.com +youtube.com +youtubeeducation.com +youtube-nocookie.com +youversion.com +youxu.info +ytht.net +ytimg.com +yuanming.net +yuanzhengtang.org +yulghun.com +yunchao.net +yuvutu.com +yvesgeleyn.com +yx51.net +yyii.org +yymaya.com +yzzk.com +zacebook.com +zalmos.com +zannel.com +zaobao.com +zaobao.com.sg +zaozon.com +zapto.org +zarias.com +zattoo.com +zdnet.com.tw +zello.com +zengjinyan.org +zengjinyan.spaces.live.com +zeutch.com +zfreet.com +zgsddh.com +zgzcjj.net +zhanbin.net +zhangboli.net +zhangtianliang.com +zhao.1984.city +zhao.jinhai.de +zhenghui.org +zhengwunet.org +zhenlibu1984.com +zhenlibu.info +zhenxiang.biz +zhinengluyou.com +zhllg.spaces.live.com +zh.netlog.com +zhonggtuotese.net +zhongguo.ca +zhongguorenquan.org +zhongguotese.net +zhongmeng.org +zhongsou.com +zh.pokerstrategy.com +zhreader.com +zh-tw.justin.tv +zhuanxing.cn +zhuatieba.com +zhuichaguoji.org +zh.uncyclopedia.wikia.com +zh.wikinews.org +zh.wikisource.org +zh.wikivoyage.org +zh.wiktionary.org +ziddu.com +zillionk.com +zinio.com +ziplib.com +ziporn.com +zkaip.com +zmw.cn +zomobo.net +zonaeuropa.com +zonghexinwen.com +zonghexinwen.net +zootool.com +zoozle.net +zozotown.com +zshare.net +zsrhao.com +zuobiao.me +zuo.la +zuola.com +zvereff.com +zynaima.com +zynamics.com +zyns.com +zyzc9.com +zyzg.us +zzcartoon.com +zzux.com diff --git a/package/lean/ipset-lists/files/etc/gfwlist/unblock-youku b/package/lean/ipset-lists/files/etc/gfwlist/unblock-youku new file mode 100644 index 000000000..9306dcefd --- /dev/null +++ b/package/lean/ipset-lists/files/etc/gfwlist/unblock-youku @@ -0,0 +1,95 @@ +v.youku.com +api.youku.com +v2.tudou.com +www.tudou.com +s.plcloud.music.qq.com +i.y.qq.com +hot.vrs.sohu.com +live.tv.sohu.com +pad.tv.sohu.com +my.tv.sohu.com +hot.vrs.letv.com +data.video.qiyi.com +cache.video.qiyi.com +cache.vip.qiyi.com +vv.video.qq.com +tt.video.qq.com +ice.video.qq.com +tjsa.video.qq.com +a10.video.qq.com +xyy.video.qq.com +vcq.video.qq.com +vsh.video.qq.com +vbj.video.qq.com +bobo.video.qq.com +flvs.video.qq.com +bkvv.video.qq.com +info.zb.qq.com +geo.js.kankan.xunlei.com +web-play.pptv.com +web-play.pplive.cn +dyn.ugc.pps.tv +v.pps.tv +inner.kandian.com +ipservice.163.com +so.open.163.com +zb.s.qq.com +ip.kankan.xunlei.com +vxml.56.com +music.sina.com.cn +play.baidu.com +v.iask.com +tv.weibo.com +wtv.v.iask.com +video.sina.com.cn +www.yinyuetai.com +api.letv.com +live.gslb.letv.com +static.itv.letv.com +ip.apps.cntv.cn +vdn.apps.cntv.cn +vdn.live.cntv.cn +vip.sports.cntv.cn +a.play.api.3g.youku.com +i.play.api.3g.youku.com +api.3g.youku.com +tv.api.3g.youku.com +play.api.3g.youku.com +play.api.3g.tudou.com +tv.api.3g.tudou.com +api.3g.tudou.com +api.tv.sohu.com +access.tv.sohu.com +iface.iqiyi.com +iface2.iqiyi.com +cache.m.iqiyi.com +dynamic.app.m.letv.com +dynamic.meizi.app.m.letv.com +dynamic.search.app.m.letv.com +dynamic.live.app.m.letv.com +listso.m.areainfo.ppstream.com +epg.api.pptv.com +play.api.pptv.com +m.letv.com +interface.bilibili.com +3g.music.qq.com +mqqplayer.3g.qq.com +proxy.music.qq.com +proxymc.qq.com +ip2.kugou.com +ip.kugou.com +client.api.ttpod.com +mobi.kuwo.cn +mobilefeedback.kugou.com +tingapi.ting.baidu.com +music.baidu.com +serviceinfo.sdk.duomi.com +music.163.com +www.xiami.com +spark.api.xiami.com +iplocation.geo.qiyi.com +sns.video.qq.com +v5.pc.duomi.com +tms.is.ysten.com +internal.check.duokanbox.com +openapi.youku.com diff --git a/package/lean/ipset-lists/files/etc/init.d/ipset.sh b/package/lean/ipset-lists/files/etc/init.d/ipset.sh new file mode 100755 index 000000000..55f82273b --- /dev/null +++ b/package/lean/ipset-lists/files/etc/init.d/ipset.sh @@ -0,0 +1,29 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2014 Justin Liu + +START=21 + +start() +{ + local file + for file in /etc/ipset/*; do + [ -f $file ] || continue + ipset restore < $file + done +} + +stop() +{ + local file + for file in /etc/ipset/*; do + [ -f $file ] || continue + ipset destroy `basename $file` + done +} + +restart() +{ + stop >/dev/null 2>&1 + start +} + diff --git a/package/lean/ipset-lists/files/etc/ipset/china b/package/lean/ipset-lists/files/etc/ipset/china new file mode 100644 index 000000000..03b1cc9c5 --- /dev/null +++ b/package/lean/ipset-lists/files/etc/ipset/china @@ -0,0 +1,4728 @@ +create china hash:net family inet hashsize 1024 maxelem 65536 +add china 1.0.1.0/24 +add china 1.0.2.0/23 +add china 1.0.8.0/21 +add china 1.0.32.0/19 +add china 1.1.0.0/24 +add china 1.1.2.0/23 +add china 1.1.4.0/22 +add china 1.1.8.0/21 +add china 1.1.16.0/20 +add china 1.1.32.0/19 +add china 1.2.0.0/23 +add china 1.2.2.0/24 +add china 1.2.4.0/22 +add china 1.2.8.0/21 +add china 1.2.16.0/20 +add china 1.2.32.0/19 +add china 1.2.64.0/18 +add china 1.3.0.0/16 +add china 1.4.1.0/24 +add china 1.4.2.0/23 +add china 1.4.4.0/22 +add china 1.4.8.0/21 +add china 1.4.16.0/20 +add china 1.4.32.0/19 +add china 1.4.64.0/18 +add china 1.8.0.0/16 +add china 1.10.0.0/21 +add china 1.10.8.0/23 +add china 1.10.11.0/24 +add china 1.10.12.0/22 +add china 1.10.16.0/20 +add china 1.10.32.0/19 +add china 1.10.64.0/18 +add china 1.12.0.0/14 +add china 1.24.0.0/13 +add china 1.45.0.0/16 +add china 1.48.0.0/14 +add china 1.56.0.0/13 +add china 1.68.0.0/14 +add china 1.80.0.0/12 +add china 1.116.0.0/14 +add china 1.180.0.0/14 +add china 1.184.0.0/15 +add china 1.188.0.0/14 +add china 1.192.0.0/13 +add china 1.202.0.0/15 +add china 1.204.0.0/14 +add china 14.0.0.0/21 +add china 14.0.12.0/22 +add china 14.1.0.0/22 +add china 14.1.24.0/22 +add china 14.1.96.0/22 +add china 14.1.108.0/22 +add china 14.16.0.0/12 +add china 14.102.128.0/22 +add china 14.102.156.0/22 +add china 14.102.180.0/22 +add china 14.103.0.0/16 +add china 14.104.0.0/13 +add china 14.112.0.0/12 +add china 14.130.0.0/15 +add china 14.134.0.0/15 +add china 14.144.0.0/12 +add china 14.192.4.0/22 +add china 14.192.56.0/21 +add china 14.192.76.0/22 +add china 14.196.0.0/15 +add china 14.204.0.0/15 +add china 14.208.0.0/12 +add china 20.134.160.0/20 +add china 20.139.160.0/20 +add china 27.0.128.0/21 +add china 27.0.160.0/21 +add china 27.0.188.0/22 +add china 27.0.204.0/22 +add china 27.0.208.0/21 +add china 27.8.0.0/13 +add china 27.16.0.0/12 +add china 27.34.232.0/21 +add china 27.36.0.0/14 +add china 27.40.0.0/13 +add china 27.50.40.0/21 +add china 27.50.128.0/17 +add china 27.54.72.0/21 +add china 27.54.152.0/21 +add china 27.54.192.0/18 +add china 27.98.208.0/20 +add china 27.98.224.0/19 +add china 27.99.128.0/17 +add china 27.103.0.0/16 +add china 27.106.128.0/18 +add china 27.106.204.0/22 +add china 27.109.32.0/19 +add china 27.109.124.0/22 +add china 27.112.0.0/18 +add china 27.112.80.0/20 +add china 27.112.112.0/21 +add china 27.113.128.0/18 +add china 27.115.0.0/17 +add china 27.116.44.0/22 +add china 27.121.72.0/21 +add china 27.121.120.0/21 +add china 27.123.232.0/22 +add china 27.128.0.0/15 +add china 27.131.220.0/22 +add china 27.144.0.0/16 +add china 27.148.0.0/14 +add china 27.152.0.0/13 +add china 27.184.0.0/13 +add china 27.192.0.0/11 +add china 27.224.0.0/14 +add china 36.0.0.0/22 +add china 36.0.8.0/21 +add china 36.0.16.0/20 +add china 36.0.32.0/19 +add china 36.0.64.0/18 +add china 36.0.128.0/17 +add china 36.1.0.0/16 +add china 36.4.0.0/14 +add china 36.16.0.0/12 +add china 36.32.0.0/14 +add china 36.36.0.0/16 +add china 36.37.0.0/19 +add china 36.37.36.0/23 +add china 36.37.39.0/24 +add china 36.37.40.0/21 +add china 36.37.48.0/20 +add china 36.40.0.0/13 +add china 36.48.0.0/15 +add china 36.51.0.0/16 +add china 36.56.0.0/13 +add china 36.96.0.0/11 +add china 36.128.0.0/10 +add china 36.192.0.0/11 +add china 36.248.0.0/14 +add china 36.254.0.0/16 +add china 36.255.116.0/22 +add china 36.255.128.0/22 +add china 36.255.164.0/22 +add china 36.255.172.0/22 +add china 36.255.176.0/22 +add china 36.255.192.0/22 +add china 39.0.0.0/24 +add china 39.0.2.0/23 +add china 39.0.4.0/22 +add china 39.0.8.0/21 +add china 39.0.16.0/20 +add china 39.0.32.0/19 +add china 39.0.64.0/18 +add china 39.0.128.0/17 +add china 39.64.0.0/11 +add china 39.96.0.0/13 +add china 39.104.0.0/14 +add china 39.108.0.0/16 +add china 39.128.0.0/10 +add china 40.0.176.0/20 +add china 40.0.247.0/24 +add china 40.0.248.0/22 +add china 40.0.252.0/23 +add china 40.0.255.0/24 +add china 40.72.0.0/15 +add china 40.125.128.0/17 +add china 40.126.64.0/18 +add china 40.198.10.0/24 +add china 40.198.16.0/21 +add china 40.198.24.0/23 +add china 40.250.16.0/23 +add china 40.251.227.0/24 +add china 42.0.0.0/22 +add china 42.0.8.0/21 +add china 42.0.16.0/21 +add china 42.0.24.0/22 +add china 42.0.32.0/19 +add china 42.0.128.0/17 +add china 42.1.0.0/19 +add china 42.1.32.0/20 +add china 42.1.48.0/21 +add china 42.1.56.0/22 +add china 42.1.128.0/17 +add china 42.4.0.0/14 +add china 42.48.0.0/13 +add china 42.56.0.0/14 +add china 42.62.0.0/17 +add china 42.62.128.0/19 +add china 42.62.160.0/20 +add china 42.62.180.0/22 +add china 42.62.184.0/21 +add china 42.63.0.0/16 +add china 42.80.0.0/15 +add china 42.83.64.0/20 +add china 42.83.80.0/22 +add china 42.83.88.0/21 +add china 42.83.96.0/19 +add china 42.83.128.0/17 +add china 42.84.0.0/14 +add china 42.88.0.0/13 +add china 42.96.64.0/19 +add china 42.96.96.0/21 +add china 42.96.108.0/22 +add china 42.96.112.0/20 +add china 42.96.128.0/17 +add china 42.97.0.0/16 +add china 42.99.0.0/18 +add china 42.99.64.0/19 +add china 42.99.96.0/20 +add china 42.99.112.0/22 +add china 42.99.120.0/21 +add china 42.100.0.0/14 +add china 42.120.0.0/15 +add china 42.122.0.0/16 +add china 42.123.0.0/19 +add china 42.123.36.0/22 +add china 42.123.40.0/21 +add china 42.123.48.0/20 +add china 42.123.64.0/18 +add china 42.123.128.0/17 +add china 42.128.0.0/12 +add china 42.156.0.0/19 +add china 42.156.36.0/22 +add china 42.156.40.0/21 +add china 42.156.48.0/20 +add china 42.156.64.0/18 +add china 42.156.128.0/17 +add china 42.157.0.0/16 +add china 42.158.0.0/15 +add china 42.160.0.0/12 +add china 42.176.0.0/13 +add china 42.184.0.0/15 +add china 42.186.0.0/16 +add china 42.187.0.0/18 +add china 42.187.64.0/19 +add china 42.187.96.0/20 +add china 42.187.112.0/21 +add china 42.187.120.0/22 +add china 42.187.128.0/17 +add china 42.192.0.0/13 +add china 42.201.0.0/17 +add china 42.202.0.0/15 +add china 42.204.0.0/14 +add china 42.208.0.0/12 +add china 42.224.0.0/12 +add china 42.240.0.0/16 +add china 42.242.0.0/15 +add china 42.244.0.0/14 +add china 42.248.0.0/13 +add china 43.224.12.0/22 +add china 43.224.24.0/22 +add china 43.224.44.0/22 +add china 43.224.52.0/22 +add china 43.224.56.0/22 +add china 43.224.64.0/21 +add china 43.224.72.0/22 +add china 43.224.80.0/22 +add china 43.224.100.0/22 +add china 43.224.144.0/22 +add china 43.224.160.0/22 +add china 43.224.176.0/22 +add china 43.224.184.0/22 +add china 43.224.200.0/21 +add china 43.224.208.0/21 +add china 43.224.216.0/22 +add china 43.224.224.0/22 +add china 43.224.240.0/22 +add china 43.225.76.0/22 +add china 43.225.84.0/22 +add china 43.225.120.0/21 +add china 43.225.140.0/22 +add china 43.225.172.0/22 +add china 43.225.180.0/22 +add china 43.225.184.0/22 +add china 43.225.208.0/22 +add china 43.225.216.0/21 +add china 43.225.224.0/20 +add china 43.225.240.0/21 +add china 43.225.252.0/22 +add china 43.226.32.0/19 +add china 43.226.64.0/19 +add china 43.226.96.0/20 +add china 43.226.112.0/21 +add china 43.226.120.0/22 +add china 43.226.128.0/18 +add china 43.226.192.0/20 +add china 43.226.208.0/21 +add china 43.226.236.0/22 +add china 43.226.240.0/20 +add china 43.227.0.0/21 +add china 43.227.8.0/22 +add china 43.227.32.0/19 +add china 43.227.64.0/19 +add china 43.227.96.0/21 +add china 43.227.104.0/22 +add china 43.227.136.0/21 +add china 43.227.144.0/22 +add china 43.227.152.0/21 +add china 43.227.160.0/20 +add china 43.227.176.0/21 +add china 43.227.188.0/22 +add china 43.227.192.0/19 +add china 43.227.232.0/22 +add china 43.227.248.0/21 +add china 43.228.0.0/18 +add china 43.228.64.0/21 +add china 43.228.76.0/22 +add china 43.228.100.0/22 +add china 43.228.116.0/22 +add china 43.228.120.0/22 +add china 43.228.132.0/22 +add china 43.228.136.0/22 +add china 43.228.148.0/22 +add china 43.228.152.0/22 +add china 43.228.188.0/22 +add china 43.228.204.0/22 +add china 43.228.240.0/22 +add china 43.229.16.0/22 +add china 43.229.40.0/22 +add china 43.229.48.0/22 +add china 43.229.56.0/22 +add china 43.229.96.0/22 +add china 43.229.108.0/22 +add china 43.229.120.0/22 +add china 43.229.136.0/21 +add china 43.229.144.0/22 +add china 43.229.168.0/21 +add china 43.229.176.0/20 +add china 43.229.192.0/21 +add china 43.229.216.0/21 +add china 43.229.232.0/21 +add china 43.230.20.0/22 +add china 43.230.32.0/22 +add china 43.230.68.0/22 +add china 43.230.72.0/22 +add china 43.230.84.0/22 +add china 43.230.124.0/22 +add china 43.230.136.0/22 +add china 43.230.168.0/22 +add china 43.230.220.0/22 +add china 43.230.224.0/19 +add china 43.231.12.0/22 +add china 43.231.32.0/20 +add china 43.231.80.0/20 +add china 43.231.96.0/20 +add china 43.231.136.0/21 +add china 43.231.144.0/20 +add china 43.231.160.0/20 +add china 43.231.176.0/21 +add china 43.236.0.0/15 +add china 43.238.0.0/16 +add china 43.239.0.0/19 +add china 43.239.32.0/20 +add china 43.239.48.0/22 +add china 43.239.116.0/22 +add china 43.239.120.0/22 +add china 43.239.172.0/22 +add china 43.239.176.0/22 +add china 43.240.0.0/22 +add china 43.240.48.0/22 +add china 43.240.56.0/21 +add china 43.240.68.0/22 +add china 43.240.72.0/21 +add china 43.240.84.0/22 +add china 43.240.124.0/22 +add china 43.240.128.0/21 +add china 43.240.136.0/22 +add china 43.240.156.0/22 +add china 43.240.160.0/19 +add china 43.240.192.0/19 +add china 43.240.236.0/22 +add china 43.240.240.0/20 +add china 43.241.0.0/20 +add china 43.241.16.0/21 +add china 43.241.48.0/22 +add china 43.241.76.0/22 +add china 43.241.80.0/20 +add china 43.241.112.0/22 +add china 43.241.168.0/21 +add china 43.241.176.0/21 +add china 43.241.184.0/22 +add china 43.241.196.0/22 +add china 43.241.208.0/20 +add china 43.241.224.0/20 +add china 43.241.240.0/22 +add china 43.241.248.0/21 +add china 43.242.8.0/21 +add china 43.242.16.0/20 +add china 43.242.44.0/22 +add china 43.242.48.0/20 +add china 43.242.64.0/22 +add china 43.242.72.0/21 +add china 43.242.80.0/20 +add china 43.242.96.0/22 +add china 43.242.144.0/20 +add china 43.242.160.0/21 +add china 43.242.168.0/22 +add china 43.242.180.0/22 +add china 43.242.188.0/22 +add china 43.242.192.0/21 +add china 43.242.204.0/22 +add china 43.242.216.0/21 +add china 43.242.252.0/22 +add china 43.243.4.0/22 +add china 43.243.8.0/21 +add china 43.243.16.0/22 +add china 43.243.24.0/22 +add china 43.243.88.0/22 +add china 43.243.128.0/22 +add china 43.243.136.0/22 +add china 43.243.144.0/21 +add china 43.243.156.0/22 +add china 43.243.168.0/22 +add china 43.243.180.0/22 +add china 43.243.188.0/22 +add china 43.243.228.0/22 +add china 43.243.232.0/22 +add china 43.243.244.0/22 +add china 43.246.0.0/18 +add china 43.246.64.0/19 +add china 43.246.96.0/22 +add china 43.246.112.0/22 +add china 43.246.212.0/22 +add china 43.246.228.0/22 +add china 43.247.4.0/22 +add china 43.247.8.0/22 +add china 43.247.44.0/22 +add china 43.247.48.0/22 +add china 43.247.68.0/22 +add china 43.247.76.0/22 +add china 43.247.84.0/22 +add china 43.247.88.0/21 +add china 43.247.96.0/21 +add china 43.247.108.0/22 +add china 43.247.112.0/22 +add china 43.247.148.0/22 +add china 43.247.152.0/22 +add china 43.247.176.0/20 +add china 43.247.196.0/22 +add china 43.247.200.0/21 +add china 43.247.208.0/20 +add china 43.247.224.0/19 +add china 43.248.0.0/21 +add china 43.248.20.0/22 +add china 43.248.28.0/22 +add china 43.248.48.0/22 +add china 43.248.76.0/22 +add china 43.248.80.0/20 +add china 43.248.96.0/19 +add china 43.248.128.0/20 +add china 43.248.144.0/21 +add china 43.248.176.0/20 +add china 43.248.192.0/20 +add china 43.248.208.0/22 +add china 43.248.228.0/22 +add china 43.248.232.0/22 +add china 43.248.244.0/22 +add china 43.249.0.0/21 +add china 43.249.8.0/22 +add china 43.249.24.0/22 +add china 43.249.120.0/22 +add china 43.249.132.0/22 +add china 43.249.136.0/22 +add china 43.249.144.0/20 +add china 43.249.160.0/21 +add china 43.249.168.0/22 +add china 43.249.192.0/22 +add china 43.249.236.0/22 +add china 43.250.4.0/22 +add china 43.250.12.0/22 +add china 43.250.16.0/21 +add china 43.250.28.0/22 +add china 43.250.32.0/21 +add china 43.250.72.0/22 +add china 43.250.96.0/20 +add china 43.250.112.0/21 +add china 43.250.128.0/22 +add china 43.250.144.0/21 +add china 43.250.160.0/22 +add china 43.250.168.0/21 +add china 43.250.176.0/22 +add china 43.250.200.0/22 +add china 43.250.212.0/22 +add china 43.250.216.0/21 +add china 43.250.236.0/22 +add china 43.250.244.0/22 +add china 43.251.4.0/22 +add china 43.251.8.0/21 +add china 43.251.36.0/22 +add china 43.251.116.0/22 +add china 43.251.192.0/22 +add china 43.251.232.0/21 +add china 43.251.244.0/22 +add china 43.252.40.0/22 +add china 43.252.48.0/22 +add china 43.252.56.0/22 +add china 43.252.224.0/22 +add china 43.254.0.0/21 +add china 43.254.8.0/22 +add china 43.254.24.0/22 +add china 43.254.36.0/22 +add china 43.254.44.0/22 +add china 43.254.52.0/22 +add china 43.254.64.0/22 +add china 43.254.72.0/22 +add china 43.254.84.0/22 +add china 43.254.88.0/21 +add china 43.254.100.0/22 +add china 43.254.104.0/22 +add china 43.254.112.0/21 +add china 43.254.128.0/22 +add china 43.254.136.0/21 +add china 43.254.144.0/20 +add china 43.254.168.0/21 +add china 43.254.180.0/22 +add china 43.254.184.0/21 +add china 43.254.192.0/21 +add china 43.254.200.0/22 +add china 43.254.208.0/22 +add china 43.254.220.0/22 +add china 43.254.224.0/20 +add china 43.254.240.0/22 +add china 43.254.248.0/21 +add china 43.255.0.0/21 +add china 43.255.8.0/22 +add china 43.255.16.0/22 +add china 43.255.48.0/22 +add china 43.255.64.0/20 +add china 43.255.84.0/22 +add china 43.255.96.0/22 +add china 43.255.108.0/22 +add china 43.255.144.0/22 +add china 43.255.168.0/22 +add china 43.255.176.0/22 +add china 43.255.184.0/22 +add china 43.255.192.0/22 +add china 43.255.200.0/21 +add china 43.255.208.0/21 +add china 43.255.224.0/21 +add china 43.255.232.0/22 +add china 43.255.244.0/22 +add china 45.65.16.0/20 +add china 45.112.132.0/22 +add china 45.112.188.0/22 +add china 45.112.208.0/20 +add china 45.112.228.0/22 +add china 45.112.232.0/21 +add china 45.113.12.0/22 +add china 45.113.16.0/20 +add china 45.113.40.0/22 +add china 45.113.52.0/22 +add china 45.113.56.0/22 +add china 45.113.72.0/22 +add china 45.113.108.0/22 +add china 45.113.144.0/21 +add china 45.113.168.0/22 +add china 45.113.176.0/22 +add china 45.113.184.0/22 +add china 45.113.200.0/21 +add china 45.113.208.0/20 +add china 45.113.228.0/22 +add china 45.113.240.0/22 +add china 45.113.252.0/22 +add china 45.114.0.0/22 +add china 45.114.12.0/22 +add china 45.114.32.0/22 +add china 45.114.40.0/22 +add china 45.114.52.0/22 +add china 45.114.96.0/22 +add china 45.114.104.0/22 +add china 45.114.136.0/22 +add china 45.114.196.0/22 +add china 45.114.200.0/22 +add china 45.114.228.0/22 +add china 45.114.236.0/22 +add china 45.114.252.0/22 +add china 45.115.44.0/22 +add china 45.115.100.0/22 +add china 45.115.120.0/22 +add china 45.115.132.0/22 +add china 45.115.144.0/22 +add china 45.115.156.0/22 +add china 45.115.164.0/22 +add china 45.115.200.0/22 +add china 45.115.212.0/22 +add china 45.115.216.0/22 +add china 45.115.228.0/22 +add china 45.115.236.0/22 +add china 45.115.244.0/22 +add china 45.115.248.0/22 +add china 45.116.12.0/22 +add china 45.116.16.0/21 +add china 45.116.24.0/22 +add china 45.116.32.0/21 +add china 45.116.52.0/22 +add china 45.116.60.0/22 +add china 45.116.64.0/22 +add china 45.116.96.0/21 +add china 45.116.140.0/22 +add china 45.116.152.0/22 +add china 45.116.208.0/22 +add china 45.117.8.0/22 +add china 45.117.20.0/22 +add china 45.117.40.0/22 +add china 45.117.68.0/22 +add china 45.117.124.0/22 +add china 45.117.252.0/22 +add china 45.119.52.0/22 +add china 45.119.60.0/22 +add china 45.119.64.0/21 +add china 45.119.72.0/22 +add china 45.119.104.0/22 +add china 45.119.116.0/22 +add china 45.119.232.0/22 +add china 45.120.100.0/22 +add china 45.120.140.0/22 +add china 45.120.156.0/22 +add china 45.120.164.0/22 +add china 45.120.220.0/22 +add china 45.120.240.0/22 +add china 45.121.20.0/22 +add china 45.121.52.0/22 +add china 45.121.64.0/21 +add china 45.121.72.0/22 +add china 45.121.92.0/22 +add china 45.121.96.0/22 +add china 45.121.104.0/22 +add china 45.121.172.0/22 +add china 45.121.176.0/22 +add china 45.121.212.0/22 +add china 45.121.240.0/20 +add china 45.122.0.0/19 +add china 45.122.32.0/21 +add china 45.122.40.0/22 +add china 45.122.60.0/22 +add china 45.122.64.0/19 +add china 45.122.96.0/20 +add china 45.122.112.0/21 +add china 45.122.160.0/19 +add china 45.122.192.0/20 +add china 45.122.208.0/21 +add china 45.122.216.0/22 +add china 45.123.28.0/22 +add china 45.123.32.0/21 +add china 45.123.44.0/22 +add china 45.123.48.0/20 +add china 45.123.64.0/20 +add china 45.123.80.0/21 +add china 45.123.88.0/22 +add china 45.123.120.0/22 +add china 45.123.128.0/21 +add china 45.123.136.0/22 +add china 45.123.148.0/22 +add china 45.123.152.0/21 +add china 45.123.164.0/22 +add china 45.123.168.0/21 +add china 45.123.176.0/21 +add china 45.123.184.0/22 +add china 45.123.204.0/22 +add china 45.123.212.0/22 +add china 45.123.224.0/19 +add china 45.124.0.0/22 +add china 45.124.20.0/22 +add china 45.124.28.0/22 +add china 45.124.32.0/21 +add china 45.124.44.0/22 +add china 45.124.68.0/22 +add china 45.124.76.0/22 +add china 45.124.80.0/22 +add china 45.124.100.0/22 +add china 45.124.124.0/22 +add china 45.124.172.0/22 +add china 45.124.176.0/22 +add china 45.124.208.0/22 +add china 45.124.248.0/21 +add china 45.125.12.0/22 +add china 45.125.16.0/22 +add china 45.125.24.0/21 +add china 45.125.32.0/22 +add china 45.125.44.0/22 +add china 45.125.52.0/22 +add china 45.125.56.0/22 +add china 45.125.76.0/22 +add china 45.125.80.0/20 +add china 45.125.96.0/21 +add china 45.125.104.0/22 +add china 45.125.136.0/22 +add china 45.126.48.0/21 +add china 45.126.100.0/22 +add china 45.126.108.0/22 +add china 45.126.112.0/21 +add china 45.126.120.0/22 +add china 45.126.212.0/22 +add china 45.126.220.0/22 +add china 45.127.8.0/21 +add china 45.127.36.0/22 +add china 45.127.96.0/22 +add china 45.127.116.0/22 +add china 45.127.124.0/22 +add china 45.127.128.0/22 +add china 45.127.144.0/21 +add china 45.127.156.0/22 +add china 45.127.216.0/22 +add china 45.221.0.0/16 +add china 45.248.8.0/22 +add china 45.248.80.0/21 +add china 45.248.88.0/22 +add china 45.248.96.0/20 +add china 45.248.128.0/21 +add china 45.248.204.0/22 +add china 45.248.208.0/20 +add china 45.248.224.0/19 +add china 45.249.0.0/21 +add china 45.249.12.0/22 +add china 45.249.16.0/20 +add china 45.249.32.0/21 +add china 45.249.92.0/22 +add china 45.249.112.0/22 +add china 45.249.180.0/22 +add china 45.249.188.0/22 +add china 45.249.192.0/20 +add china 45.249.208.0/21 +add china 45.250.12.0/22 +add china 45.250.16.0/22 +add china 45.250.28.0/22 +add china 45.250.32.0/21 +add china 45.250.40.0/22 +add china 45.250.76.0/22 +add china 45.250.80.0/20 +add china 45.250.96.0/22 +add china 45.250.104.0/21 +add china 45.250.112.0/20 +add china 45.250.128.0/20 +add china 45.250.144.0/21 +add china 45.250.152.0/22 +add china 45.250.164.0/22 +add china 45.250.180.0/22 +add china 45.250.184.0/21 +add china 45.250.192.0/22 +add china 45.251.0.0/22 +add china 45.251.8.0/22 +add china 45.251.16.0/21 +add china 45.251.52.0/22 +add china 45.251.84.0/22 +add china 45.251.88.0/21 +add china 45.251.96.0/21 +add china 45.251.120.0/21 +add china 45.251.136.0/21 +add china 45.251.144.0/20 +add china 45.251.160.0/19 +add china 45.251.192.0/19 +add china 45.251.224.0/22 +add china 45.252.0.0/19 +add china 45.252.32.0/20 +add china 45.252.48.0/22 +add china 45.252.60.0/22 +add china 45.252.84.0/22 +add china 45.252.88.0/21 +add china 45.252.96.0/19 +add china 45.252.128.0/19 +add china 45.252.160.0/20 +add china 45.252.176.0/22 +add china 45.252.192.0/19 +add china 45.252.224.0/21 +add china 45.252.232.0/22 +add china 45.253.0.0/18 +add china 45.253.64.0/20 +add china 45.253.80.0/21 +add china 45.253.92.0/22 +add china 45.253.96.0/20 +add china 45.253.112.0/21 +add china 45.253.120.0/22 +add china 45.253.130.0/23 +add china 45.253.132.0/22 +add china 45.253.136.0/21 +add china 45.253.144.0/20 +add china 45.253.160.0/19 +add china 45.253.192.0/18 +add china 45.254.0.0/19 +add china 45.254.40.0/22 +add china 45.254.48.0/20 +add china 45.254.64.0/18 +add china 45.254.128.0/18 +add china 45.254.192.0/19 +add china 45.254.224.0/21 +add china 45.254.236.0/22 +add china 45.254.240.0/22 +add china 45.254.248.0/22 +add china 45.255.0.0/17 +add china 45.255.132.0/22 +add china 45.255.136.0/21 +add china 45.255.144.0/20 +add china 45.255.160.0/19 +add china 45.255.192.0/19 +add china 45.255.224.0/20 +add china 45.255.240.0/21 +add china 45.255.248.0/22 +add china 47.92.0.0/14 +add china 47.96.0.0/11 +add china 49.4.0.0/14 +add china 49.51.0.0/16 +add china 49.52.0.0/14 +add china 49.64.0.0/11 +add china 49.112.0.0/13 +add china 49.120.0.0/14 +add china 49.128.0.0/24 +add china 49.128.2.0/23 +add china 49.128.4.0/22 +add china 49.140.0.0/15 +add china 49.152.0.0/14 +add china 49.208.0.0/14 +add china 49.220.0.0/14 +add china 49.232.0.0/14 +add china 49.239.0.0/18 +add china 49.239.192.0/18 +add china 49.246.224.0/19 +add china 52.80.0.0/14 +add china 54.222.0.0/15 +add china 54.231.208.0/20 +add china 58.14.0.0/15 +add china 58.16.0.0/13 +add china 58.24.0.0/15 +add china 58.30.0.0/15 +add china 58.32.0.0/11 +add china 58.65.232.0/21 +add china 58.66.0.0/15 +add china 58.68.128.0/17 +add china 58.82.0.0/17 +add china 58.83.0.0/16 +add china 58.87.64.0/18 +add china 58.99.128.0/17 +add china 58.100.0.0/15 +add china 58.116.0.0/14 +add china 58.128.0.0/13 +add china 58.144.0.0/16 +add china 58.154.0.0/15 +add china 58.192.0.0/11 +add china 58.240.0.0/12 +add china 59.32.0.0/11 +add china 59.64.0.0/12 +add china 59.80.0.0/14 +add china 59.107.0.0/16 +add china 59.108.0.0/14 +add china 59.151.0.0/17 +add china 59.152.16.0/20 +add china 59.152.32.0/21 +add china 59.152.64.0/20 +add china 59.152.112.0/21 +add china 59.153.4.0/22 +add china 59.153.32.0/22 +add china 59.153.60.0/22 +add china 59.153.64.0/21 +add china 59.153.72.0/22 +add china 59.153.92.0/22 +add china 59.153.116.0/22 +add china 59.153.136.0/22 +add china 59.153.152.0/21 +add china 59.153.164.0/22 +add china 59.153.168.0/21 +add china 59.153.176.0/20 +add china 59.153.192.0/22 +add china 59.155.0.0/16 +add china 59.172.0.0/14 +add china 59.191.0.0/17 +add china 59.191.240.0/20 +add china 59.192.0.0/10 +add china 60.0.0.0/11 +add china 60.55.0.0/16 +add china 60.63.0.0/16 +add china 60.160.0.0/11 +add china 60.194.0.0/15 +add china 60.200.0.0/13 +add china 60.208.0.0/12 +add china 60.232.0.0/15 +add china 60.235.0.0/16 +add china 60.245.128.0/17 +add china 60.247.0.0/16 +add china 60.252.0.0/16 +add china 60.253.128.0/17 +add china 60.255.0.0/16 +add china 61.4.80.0/20 +add china 61.4.176.0/20 +add china 61.8.160.0/20 +add china 61.14.212.0/22 +add china 61.14.216.0/21 +add china 61.14.240.0/21 +add china 61.28.0.0/17 +add china 61.29.128.0/17 +add china 61.45.128.0/18 +add china 61.45.224.0/20 +add china 61.47.128.0/18 +add china 61.48.0.0/13 +add china 61.87.192.0/18 +add china 61.128.0.0/10 +add china 61.232.0.0/14 +add china 61.236.0.0/15 +add china 61.240.0.0/14 +add china 65.55.209.0/24 +add china 72.163.248.0/22 +add china 87.254.207.0/24 +add china 93.183.14.0/24 +add china 93.183.18.0/24 +add china 101.0.0.0/22 +add china 101.1.0.0/22 +add china 101.2.172.0/22 +add china 101.4.0.0/14 +add china 101.16.0.0/12 +add china 101.32.0.0/12 +add china 101.48.0.0/15 +add china 101.50.8.0/21 +add china 101.50.56.0/22 +add china 101.52.0.0/16 +add china 101.53.100.0/22 +add china 101.54.0.0/16 +add china 101.55.224.0/21 +add china 101.64.0.0/13 +add china 101.72.0.0/14 +add china 101.76.0.0/15 +add china 101.78.0.0/22 +add china 101.78.32.0/19 +add china 101.80.0.0/12 +add china 101.96.0.0/21 +add china 101.96.8.0/22 +add china 101.96.16.0/20 +add china 101.96.128.0/17 +add china 101.99.96.0/19 +add china 101.101.64.0/19 +add china 101.101.100.0/24 +add china 101.101.102.0/23 +add china 101.101.104.0/21 +add china 101.101.112.0/20 +add china 101.102.64.0/19 +add china 101.102.100.0/23 +add china 101.102.102.0/24 +add china 101.102.104.0/21 +add china 101.102.112.0/20 +add china 101.104.0.0/14 +add china 101.110.64.0/19 +add china 101.110.96.0/20 +add china 101.110.116.0/22 +add china 101.110.120.0/21 +add china 101.120.0.0/14 +add china 101.124.0.0/15 +add china 101.126.0.0/16 +add china 101.128.0.0/22 +add china 101.128.8.0/21 +add china 101.128.16.0/20 +add china 101.128.32.0/19 +add china 101.129.0.0/16 +add china 101.130.0.0/15 +add china 101.132.0.0/14 +add china 101.144.0.0/12 +add china 101.192.0.0/13 +add china 101.200.0.0/15 +add china 101.203.128.0/19 +add china 101.203.160.0/21 +add china 101.203.172.0/22 +add china 101.203.176.0/20 +add china 101.204.0.0/14 +add china 101.224.0.0/13 +add china 101.232.0.0/15 +add china 101.234.64.0/21 +add china 101.234.76.0/22 +add china 101.234.80.0/20 +add china 101.234.96.0/19 +add china 101.236.0.0/14 +add china 101.240.0.0/13 +add china 101.248.0.0/15 +add china 101.251.0.0/22 +add china 101.251.8.0/21 +add china 101.251.16.0/20 +add china 101.251.32.0/19 +add china 101.251.64.0/18 +add china 101.251.128.0/17 +add china 101.252.0.0/15 +add china 101.254.0.0/16 +add china 103.1.8.0/22 +add china 103.1.20.0/22 +add china 103.1.24.0/22 +add china 103.1.72.0/22 +add china 103.1.88.0/22 +add china 103.1.168.0/22 +add china 103.2.108.0/22 +add china 103.2.156.0/22 +add china 103.2.164.0/22 +add china 103.2.200.0/21 +add china 103.2.208.0/21 +add china 103.3.84.0/22 +add china 103.3.88.0/21 +add china 103.3.96.0/19 +add china 103.3.128.0/20 +add china 103.3.148.0/22 +add china 103.3.152.0/21 +add china 103.4.56.0/22 +add china 103.4.168.0/22 +add china 103.4.184.0/22 +add china 103.4.224.0/22 +add china 103.5.36.0/22 +add china 103.5.52.0/22 +add china 103.5.56.0/22 +add china 103.5.152.0/22 +add china 103.5.168.0/22 +add china 103.5.192.0/22 +add china 103.5.252.0/22 +add china 103.6.76.0/22 +add china 103.6.108.0/22 +add china 103.6.120.0/22 +add china 103.6.220.0/22 +add china 103.6.228.0/22 +add china 103.7.4.0/22 +add china 103.7.28.0/22 +add china 103.7.120.0/22 +add china 103.7.140.0/22 +add china 103.7.212.0/22 +add china 103.7.216.0/21 +add china 103.8.0.0/21 +add china 103.8.8.0/22 +add china 103.8.32.0/22 +add china 103.8.52.0/22 +add china 103.8.68.0/22 +add china 103.8.108.0/22 +add china 103.8.156.0/22 +add china 103.8.200.0/21 +add china 103.8.220.0/22 +add china 103.9.8.0/22 +add china 103.9.24.0/22 +add china 103.9.108.0/22 +add china 103.9.152.0/22 +add china 103.9.192.0/22 +add china 103.9.248.0/21 +add china 103.10.0.0/22 +add china 103.10.16.0/22 +add china 103.10.84.0/22 +add china 103.10.111.0/24 +add china 103.10.140.0/22 +add china 103.11.16.0/22 +add china 103.11.168.0/22 +add china 103.11.180.0/22 +add china 103.12.32.0/22 +add china 103.12.68.0/22 +add china 103.12.92.0/22 +add china 103.12.136.0/22 +add china 103.12.184.0/22 +add china 103.12.232.0/22 +add china 103.13.12.0/22 +add china 103.13.72.0/23 +add china 103.13.124.0/22 +add china 103.13.144.0/22 +add china 103.13.196.0/22 +add china 103.13.220.0/22 +add china 103.13.244.0/22 +add china 103.14.32.0/22 +add china 103.14.84.0/22 +add china 103.14.100.0/22 +add china 103.14.112.0/22 +add china 103.14.132.0/22 +add china 103.14.136.0/22 +add china 103.14.156.0/22 +add china 103.14.240.0/22 +add china 103.15.4.0/22 +add china 103.15.8.0/22 +add china 103.15.16.0/22 +add china 103.15.96.0/22 +add china 103.15.200.0/22 +add china 103.16.52.0/22 +add china 103.16.80.0/21 +add china 103.16.88.0/22 +add china 103.16.108.0/22 +add china 103.16.124.0/22 +add china 103.17.40.0/22 +add china 103.17.64.0/22 +add china 103.17.120.0/22 +add china 103.17.136.0/22 +add china 103.17.160.0/22 +add china 103.17.204.0/22 +add china 103.17.228.0/22 +add china 103.18.192.0/22 +add china 103.18.208.0/21 +add china 103.18.224.0/22 +add china 103.19.0.0/22 +add china 103.19.12.0/22 +add china 103.19.40.0/21 +add china 103.19.64.0/21 +add china 103.19.72.0/22 +add china 103.19.232.0/22 +add china 103.20.12.0/22 +add china 103.20.32.0/22 +add china 103.20.44.0/22 +add china 103.20.68.0/22 +add china 103.20.112.0/22 +add china 103.20.128.0/22 +add china 103.20.160.0/22 +add china 103.20.248.0/22 +add china 103.21.112.0/21 +add china 103.21.136.0/21 +add china 103.21.176.0/22 +add china 103.21.208.0/22 +add china 103.21.240.0/22 +add china 103.22.0.0/18 +add china 103.22.64.0/19 +add china 103.22.100.0/22 +add china 103.22.104.0/21 +add china 103.22.112.0/20 +add china 103.22.188.0/22 +add china 103.22.228.0/22 +add china 103.22.252.0/22 +add china 103.23.8.0/22 +add china 103.23.56.0/22 +add china 103.23.160.0/21 +add china 103.23.176.0/22 +add china 103.23.228.0/22 +add china 103.24.24.0/22 +add china 103.24.116.0/22 +add china 103.24.128.0/22 +add china 103.24.144.0/22 +add china 103.24.176.0/22 +add china 103.24.184.0/22 +add china 103.24.220.0/22 +add china 103.24.228.0/22 +add china 103.24.248.0/21 +add china 103.25.8.0/23 +add china 103.25.20.0/22 +add china 103.25.24.0/21 +add china 103.25.32.0/21 +add china 103.25.40.0/22 +add china 103.25.48.0/22 +add china 103.25.64.0/21 +add china 103.25.148.0/22 +add china 103.25.156.0/22 +add china 103.25.216.0/22 +add china 103.26.0.0/22 +add china 103.26.64.0/22 +add china 103.26.76.0/22 +add china 103.26.116.0/22 +add china 103.26.132.0/22 +add china 103.26.156.0/22 +add china 103.26.160.0/22 +add china 103.26.228.0/22 +add china 103.26.240.0/22 +add china 103.27.4.0/22 +add china 103.27.12.0/22 +add china 103.27.24.0/22 +add china 103.27.56.0/22 +add china 103.27.96.0/22 +add china 103.27.184.0/22 +add china 103.27.208.0/21 +add china 103.27.240.0/22 +add china 103.28.4.0/22 +add china 103.28.8.0/22 +add china 103.28.184.0/22 +add china 103.28.204.0/22 +add china 103.28.212.0/22 +add china 103.29.0.0/22 +add china 103.29.16.0/22 +add china 103.29.128.0/21 +add china 103.29.136.0/22 +add china 103.30.20.0/22 +add china 103.30.96.0/22 +add china 103.30.148.0/22 +add china 103.30.200.0/22 +add china 103.30.228.0/22 +add china 103.30.234.0/23 +add china 103.30.236.0/22 +add china 103.31.0.0/22 +add china 103.31.48.0/20 +add china 103.31.64.0/21 +add china 103.31.72.0/24 +add china 103.31.148.0/22 +add china 103.31.160.0/22 +add china 103.31.168.0/22 +add china 103.31.200.0/22 +add china 103.31.236.0/22 +add china 103.32.0.0/15 +add china 103.34.0.0/16 +add china 103.35.0.0/19 +add china 103.35.32.0/20 +add china 103.35.48.0/22 +add china 103.35.104.0/22 +add china 103.35.116.0/22 +add china 103.35.180.0/22 +add china 103.35.200.0/22 +add china 103.35.220.0/22 +add china 103.36.20.0/22 +add china 103.36.28.0/22 +add china 103.36.36.0/22 +add china 103.36.56.0/21 +add china 103.36.64.0/22 +add china 103.36.72.0/22 +add china 103.36.96.0/22 +add china 103.36.132.0/22 +add china 103.36.136.0/22 +add china 103.36.160.0/19 +add china 103.36.192.0/19 +add china 103.36.224.0/20 +add china 103.36.240.0/21 +add china 103.37.0.0/22 +add china 103.37.12.0/22 +add china 103.37.16.0/22 +add china 103.37.24.0/22 +add china 103.37.44.0/22 +add china 103.37.52.0/22 +add china 103.37.56.0/22 +add china 103.37.72.0/22 +add china 103.37.100.0/22 +add china 103.37.104.0/22 +add china 103.37.124.0/22 +add china 103.37.136.0/21 +add china 103.37.144.0/20 +add china 103.37.160.0/21 +add china 103.37.172.0/22 +add china 103.37.176.0/22 +add china 103.37.188.0/22 +add china 103.37.208.0/20 +add china 103.37.248.0/21 +add china 103.38.0.0/22 +add china 103.38.32.0/22 +add china 103.38.40.0/21 +add china 103.38.56.0/22 +add china 103.38.76.0/22 +add china 103.38.84.0/22 +add china 103.38.92.0/22 +add china 103.38.96.0/22 +add china 103.38.116.0/22 +add china 103.38.132.0/22 +add china 103.38.140.0/22 +add china 103.38.220.0/22 +add china 103.38.224.0/21 +add china 103.38.232.0/22 +add china 103.38.252.0/22 +add china 103.39.16.0/22 +add china 103.39.64.0/22 +add china 103.39.88.0/22 +add china 103.39.100.0/22 +add china 103.39.104.0/21 +add china 103.39.160.0/19 +add china 103.39.200.0/21 +add china 103.39.208.0/20 +add china 103.39.224.0/21 +add china 103.39.232.0/22 +add china 103.40.12.0/22 +add china 103.40.16.0/20 +add china 103.40.32.0/20 +add china 103.40.88.0/22 +add china 103.40.100.0/22 +add china 103.40.112.0/22 +add china 103.40.192.0/22 +add china 103.40.212.0/22 +add china 103.40.220.0/22 +add china 103.40.228.0/22 +add china 103.40.232.0/21 +add china 103.40.240.0/20 +add china 103.41.0.0/22 +add china 103.41.16.0/22 +add china 103.41.52.0/22 +add china 103.41.140.0/22 +add china 103.41.148.0/22 +add china 103.41.152.0/22 +add china 103.41.160.0/21 +add china 103.41.220.0/22 +add china 103.41.224.0/21 +add china 103.41.232.0/22 +add china 103.42.8.0/22 +add china 103.42.24.0/21 +add china 103.42.32.0/22 +add china 103.42.64.0/21 +add china 103.42.76.0/22 +add china 103.42.104.0/22 +add china 103.42.180.0/22 +add china 103.42.232.0/22 +add china 103.43.16.0/22 +add china 103.43.26.0/23 +add china 103.43.84.0/22 +add china 103.43.96.0/21 +add china 103.43.104.0/22 +add china 103.43.124.0/22 +add china 103.43.132.0/22 +add china 103.43.184.0/22 +add china 103.43.192.0/21 +add china 103.43.208.0/22 +add china 103.43.220.0/22 +add china 103.43.224.0/22 +add china 103.43.232.0/22 +add china 103.43.240.0/22 +add china 103.44.56.0/22 +add china 103.44.80.0/22 +add china 103.44.88.0/22 +add china 103.44.120.0/21 +add china 103.44.132.0/22 +add china 103.44.144.0/22 +add china 103.44.152.0/22 +add china 103.44.168.0/22 +add china 103.44.176.0/20 +add china 103.44.192.0/20 +add china 103.44.224.0/22 +add china 103.44.236.0/22 +add china 103.44.240.0/20 +add china 103.45.0.0/18 +add china 103.45.72.0/21 +add china 103.45.80.0/20 +add china 103.45.96.0/19 +add china 103.45.128.0/18 +add china 103.45.192.0/19 +add china 103.45.224.0/22 +add china 103.45.248.0/22 +add china 103.46.0.0/22 +add china 103.46.12.0/22 +add china 103.46.16.0/20 +add china 103.46.32.0/19 +add china 103.46.64.0/18 +add china 103.46.128.0/21 +add china 103.46.136.0/22 +add china 103.46.152.0/21 +add china 103.46.160.0/20 +add china 103.46.176.0/21 +add china 103.46.244.0/22 +add china 103.46.248.0/22 +add china 103.47.4.0/22 +add china 103.47.20.0/22 +add china 103.47.36.0/22 +add china 103.47.40.0/22 +add china 103.47.48.0/22 +add china 103.47.80.0/22 +add china 103.47.96.0/22 +add china 103.47.108.0/22 +add china 103.47.116.0/22 +add china 103.47.120.0/22 +add china 103.47.136.0/21 +add china 103.47.212.0/22 +add china 103.47.220.0/22 +add china 103.47.248.0/22 +add china 103.48.20.0/22 +add china 103.48.52.0/22 +add china 103.48.92.0/22 +add china 103.48.144.0/20 +add china 103.48.202.0/23 +add china 103.48.216.0/21 +add china 103.48.224.0/20 +add china 103.48.240.0/21 +add china 103.49.12.0/22 +add china 103.49.20.0/22 +add china 103.49.72.0/21 +add china 103.49.92.0/22 +add china 103.49.96.0/22 +add china 103.49.108.0/22 +add china 103.49.128.0/22 +add china 103.49.176.0/21 +add china 103.49.196.0/22 +add china 103.49.248.0/22 +add china 103.50.36.0/22 +add china 103.50.44.0/22 +add china 103.50.48.0/20 +add china 103.50.64.0/21 +add china 103.50.72.0/22 +add china 103.50.92.0/22 +add china 103.50.108.0/22 +add china 103.50.112.0/20 +add china 103.50.132.0/22 +add china 103.50.136.0/21 +add china 103.50.172.0/22 +add china 103.50.176.0/20 +add china 103.50.192.0/21 +add china 103.50.200.0/22 +add china 103.50.220.0/22 +add china 103.50.224.0/20 +add china 103.50.240.0/21 +add china 103.50.248.0/22 +add china 103.52.40.0/22 +add china 103.52.72.0/21 +add china 103.52.80.0/21 +add china 103.52.96.0/21 +add china 103.52.104.0/22 +add china 103.52.160.0/21 +add china 103.52.172.0/22 +add china 103.52.176.0/22 +add china 103.52.184.0/22 +add china 103.52.196.0/22 +add china 103.53.4.0/22 +add china 103.53.64.0/21 +add china 103.53.92.0/22 +add china 103.53.100.0/22 +add china 103.53.124.0/22 +add china 103.53.128.0/20 +add china 103.53.144.0/22 +add china 103.53.160.0/22 +add china 103.53.180.0/22 +add china 103.53.204.0/22 +add china 103.53.208.0/21 +add china 103.53.216.0/22 +add china 103.53.236.0/22 +add china 103.53.248.0/22 +add china 103.54.8.0/22 +add china 103.54.48.0/22 +add china 103.54.60.0/22 +add china 103.54.160.0/21 +add china 103.54.212.0/22 +add china 103.54.228.0/22 +add china 103.54.240.0/22 +add china 103.55.24.0/22 +add china 103.55.80.0/22 +add china 103.55.120.0/22 +add china 103.55.152.0/22 +add china 103.55.172.0/22 +add china 103.55.204.0/22 +add china 103.55.208.0/22 +add china 103.55.228.0/22 +add china 103.55.236.0/22 +add china 103.55.240.0/22 +add china 103.56.8.0/22 +add china 103.56.16.0/21 +add china 103.56.32.0/22 +add china 103.56.52.0/22 +add china 103.56.56.0/21 +add china 103.56.72.0/21 +add china 103.56.100.0/22 +add china 103.56.104.0/22 +add china 103.56.140.0/22 +add china 103.56.152.0/22 +add china 103.56.184.0/22 +add china 103.56.200.0/22 +add china 103.56.216.0/22 +add china 103.57.12.0/22 +add china 103.57.52.0/22 +add china 103.57.56.0/22 +add china 103.57.76.0/22 +add china 103.57.108.0/22 +add china 103.57.136.0/22 +add china 103.57.196.0/22 +add china 103.58.24.0/22 +add china 103.58.182.0/23 +add china 103.59.76.0/22 +add china 103.59.100.0/22 +add china 103.59.112.0/20 +add china 103.59.128.0/22 +add china 103.59.148.0/22 +add china 103.59.164.0/22 +add china 103.60.32.0/22 +add china 103.60.44.0/22 +add china 103.60.164.0/22 +add china 103.60.228.0/22 +add china 103.60.236.0/22 +add china 103.61.60.0/22 +add china 103.61.104.0/22 +add china 103.61.140.0/22 +add china 103.61.152.0/21 +add china 103.61.160.0/22 +add china 103.61.172.0/22 +add china 103.61.176.0/22 +add china 103.61.184.0/21 +add china 103.62.24.0/22 +add china 103.62.52.0/22 +add china 103.62.72.0/21 +add china 103.62.80.0/21 +add china 103.62.88.0/22 +add china 103.62.96.0/19 +add china 103.62.128.0/21 +add china 103.62.156.0/22 +add china 103.62.160.0/19 +add china 103.62.192.0/22 +add china 103.62.204.0/22 +add china 103.62.208.0/20 +add china 103.62.224.0/22 +add china 103.63.32.0/19 +add china 103.63.64.0/20 +add china 103.63.80.0/21 +add china 103.63.88.0/22 +add china 103.63.140.0/22 +add china 103.63.144.0/22 +add china 103.63.152.0/22 +add china 103.63.160.0/20 +add china 103.63.176.0/21 +add china 103.63.184.0/22 +add china 103.63.192.0/20 +add china 103.63.208.0/22 +add china 103.63.240.0/20 +add china 103.64.0.0/21 +add china 103.64.24.0/21 +add china 103.64.32.0/19 +add china 103.64.64.0/18 +add china 103.64.140.0/22 +add china 103.64.144.0/22 +add china 103.64.152.0/21 +add china 103.64.160.0/19 +add china 103.64.192.0/18 +add china 103.65.0.0/20 +add china 103.65.16.0/22 +add china 103.65.36.0/22 +add china 103.65.40.0/22 +add china 103.65.48.0/20 +add china 103.65.64.0/19 +add china 103.65.100.0/22 +add china 103.65.104.0/21 +add china 103.65.112.0/20 +add china 103.65.128.0/21 +add china 103.65.136.0/22 +add china 103.65.144.0/20 +add china 103.65.160.0/20 +add china 103.66.32.0/22 +add china 103.66.40.0/22 +add china 103.66.92.0/22 +add china 103.66.108.0/22 +add china 103.66.200.0/22 +add china 103.66.216.0/22 +add china 103.66.240.0/20 +add china 103.67.0.0/21 +add china 103.67.8.0/22 +add china 103.67.40.0/21 +add china 103.67.48.0/20 +add china 103.67.64.0/18 +add china 103.67.128.0/20 +add china 103.67.144.0/21 +add china 103.67.172.0/22 +add china 103.67.192.0/22 +add china 103.67.212.0/22 +add china 103.67.252.0/22 +add china 103.68.64.0/22 +add china 103.68.88.0/22 +add china 103.68.100.0/22 +add china 103.68.128.0/22 +add china 103.68.192.0/22 +add china 103.69.16.0/22 +add china 103.69.116.0/22 +add china 103.69.132.0/22 +add china 103.69.152.0/22 +add china 103.69.212.0/22 +add china 103.70.8.0/22 +add china 103.70.148.0/22 +add china 103.70.184.0/22 +add china 103.70.220.0/22 +add china 103.70.224.0/22 +add china 103.70.236.0/22 +add china 103.70.252.0/22 +add china 103.71.0.0/22 +add china 103.71.32.0/22 +add china 103.71.48.0/22 +add china 103.71.68.0/22 +add china 103.71.72.0/22 +add china 103.71.80.0/21 +add china 103.71.88.0/22 +add china 103.71.120.0/21 +add china 103.71.128.0/22 +add china 103.71.144.0/22 +add china 103.71.196.0/22 +add china 103.71.200.0/22 +add china 103.71.232.0/22 +add china 103.72.12.0/22 +add china 103.72.16.0/20 +add china 103.72.32.0/20 +add china 103.72.48.0/21 +add china 103.72.112.0/20 +add china 103.72.128.0/21 +add china 103.72.144.0/21 +add china 103.72.164.0/22 +add china 103.72.172.0/22 +add china 103.72.180.0/22 +add china 103.72.224.0/19 +add china 103.73.0.0/19 +add china 103.73.48.0/22 +add china 103.73.88.0/22 +add china 103.73.96.0/22 +add china 103.73.116.0/22 +add china 103.73.120.0/22 +add china 103.73.128.0/20 +add china 103.73.144.0/22 +add china 103.73.168.0/22 +add china 103.73.176.0/22 +add china 103.73.204.0/22 +add china 103.73.208.0/22 +add china 103.73.240.0/21 +add china 103.73.248.0/22 +add china 103.74.24.0/21 +add china 103.74.32.0/20 +add china 103.74.48.0/22 +add china 103.74.56.0/21 +add china 103.74.80.0/22 +add china 103.74.124.0/22 +add china 103.74.148.0/22 +add china 103.74.152.0/21 +add china 103.74.204.0/22 +add china 103.74.232.0/22 +add china 103.75.16.0/22 +add china 103.75.84.0/22 +add china 103.75.88.0/21 +add china 103.75.104.0/21 +add china 103.75.112.0/22 +add china 103.75.120.0/22 +add china 103.75.128.0/22 +add china 103.75.144.0/22 +add china 103.75.152.0/22 +add china 103.75.236.0/24 +add china 103.76.60.0/22 +add china 103.76.64.0/21 +add china 103.76.72.0/22 +add china 103.76.84.0/22 +add china 103.76.92.0/22 +add china 103.76.104.0/22 +add china 103.76.216.0/21 +add china 103.76.224.0/22 +add china 103.77.28.0/22 +add china 103.77.52.0/22 +add china 103.77.56.0/22 +add china 103.77.72.0/22 +add china 103.77.88.0/21 +add china 103.77.132.0/22 +add china 103.77.148.0/22 +add china 103.77.220.0/22 +add china 103.78.56.0/21 +add china 103.78.64.0/21 +add china 103.78.124.0/22 +add china 103.78.172.0/22 +add china 103.78.176.0/22 +add china 103.78.196.0/22 +add china 103.78.228.0/22 +add china 103.79.24.0/21 +add china 103.79.36.0/22 +add china 103.79.40.0/21 +add china 103.192.0.0/19 +add china 103.192.48.0/21 +add china 103.192.56.0/22 +add china 103.192.84.0/22 +add china 103.192.88.0/21 +add china 103.192.96.0/20 +add china 103.192.112.0/22 +add china 103.192.128.0/20 +add china 103.192.144.0/22 +add china 103.192.164.0/22 +add china 103.192.188.0/22 +add china 103.192.208.0/21 +add china 103.192.216.0/22 +add china 103.192.252.0/22 +add china 103.193.40.0/21 +add china 103.193.120.0/21 +add china 103.193.140.0/22 +add china 103.193.144.0/21 +add china 103.193.160.0/22 +add china 103.193.188.0/22 +add china 103.193.192.0/22 +add china 103.193.212.0/22 +add china 103.193.216.0/21 +add china 103.193.224.0/20 +add china 103.193.240.0/22 +add china 103.194.16.0/22 +add china 103.194.230.0/23 +add china 103.195.104.0/22 +add china 103.195.112.0/22 +add china 103.195.136.0/22 +add china 103.195.148.0/22 +add china 103.195.152.0/22 +add china 103.195.160.0/22 +add china 103.195.192.0/22 +add china 103.196.60.0/22 +add china 103.196.64.0/22 +add china 103.196.72.0/22 +add china 103.196.88.0/21 +add china 103.196.96.0/22 +add china 103.196.168.0/22 +add china 103.196.184.0/22 +add china 103.196.204.0/22 +add china 103.197.180.0/22 +add china 103.197.228.0/22 +add china 103.197.252.0/22 +add china 103.198.20.0/22 +add china 103.198.60.0/22 +add china 103.198.64.0/22 +add china 103.198.72.0/22 +add china 103.198.124.0/22 +add china 103.198.156.0/22 +add china 103.198.180.0/22 +add china 103.198.196.0/22 +add china 103.198.200.0/22 +add china 103.198.216.0/21 +add china 103.198.224.0/20 +add china 103.198.240.0/21 +add china 103.199.164.0/22 +add china 103.199.196.0/22 +add china 103.199.228.0/22 +add china 103.199.248.0/21 +add china 103.200.28.0/22 +add china 103.200.32.0/22 +add china 103.200.52.0/22 +add china 103.200.64.0/21 +add china 103.200.136.0/21 +add china 103.200.144.0/20 +add china 103.200.160.0/19 +add china 103.200.192.0/22 +add china 103.200.220.0/22 +add china 103.200.224.0/19 +add china 103.201.0.0/20 +add china 103.201.16.0/21 +add china 103.201.28.0/22 +add china 103.201.32.0/19 +add china 103.201.64.0/22 +add china 103.201.76.0/22 +add china 103.201.80.0/20 +add china 103.201.96.0/20 +add china 103.201.112.0/21 +add china 103.201.120.0/22 +add china 103.201.152.0/21 +add china 103.201.160.0/19 +add china 103.201.192.0/18 +add china 103.202.0.0/19 +add china 103.202.32.0/20 +add china 103.202.56.0/21 +add china 103.202.64.0/18 +add china 103.202.128.0/20 +add china 103.202.144.0/22 +add china 103.202.152.0/21 +add china 103.202.160.0/19 +add china 103.202.192.0/20 +add china 103.202.212.0/22 +add china 103.202.228.0/22 +add china 103.202.236.0/22 +add china 103.202.240.0/20 +add china 103.203.0.0/19 +add china 103.203.32.0/22 +add china 103.203.52.0/22 +add china 103.203.56.0/22 +add china 103.203.96.0/19 +add china 103.203.128.0/22 +add china 103.203.140.0/22 +add china 103.203.164.0/22 +add china 103.203.168.0/22 +add china 103.203.192.0/22 +add china 103.203.200.0/22 +add china 103.203.212.0/22 +add china 103.203.216.0/22 +add china 103.204.24.0/22 +add china 103.204.72.0/22 +add china 103.204.88.0/22 +add china 103.204.112.0/22 +add china 103.204.136.0/21 +add china 103.204.144.0/21 +add china 103.204.152.0/22 +add china 103.204.196.0/22 +add china 103.204.232.0/21 +add china 103.205.4.0/22 +add china 103.205.8.0/22 +add china 103.205.40.0/21 +add china 103.205.52.0/22 +add china 103.205.108.0/22 +add china 103.205.116.0/22 +add china 103.205.120.0/22 +add china 103.205.136.0/22 +add china 103.205.162.0/24 +add china 103.205.188.0/22 +add china 103.205.192.0/21 +add china 103.205.200.0/22 +add china 103.205.236.0/22 +add china 103.205.248.0/21 +add china 103.206.0.0/22 +add china 103.206.44.0/22 +add china 103.206.108.0/22 +add china 103.206.148.0/22 +add china 103.207.48.0/22 +add china 103.207.104.0/22 +add china 103.207.164.0/22 +add china 103.207.184.0/21 +add china 103.207.192.0/20 +add china 103.207.208.0/21 +add china 103.207.220.0/22 +add china 103.207.228.0/22 +add china 103.207.232.0/22 +add china 103.208.12.0/22 +add china 103.208.16.0/22 +add china 103.208.28.0/22 +add china 103.208.40.0/21 +add china 103.208.48.0/22 +add china 103.208.148.0/22 +add china 103.209.112.0/22 +add china 103.209.136.0/22 +add china 103.209.200.0/22 +add china 103.209.208.0/22 +add china 103.209.216.0/22 +add china 103.209.232.0/22 +add china 103.210.0.0/22 +add china 103.210.96.0/22 +add china 103.210.156.0/22 +add china 103.210.160.0/19 +add china 103.210.216.0/22 +add china 103.211.44.0/22 +add china 103.211.96.0/21 +add china 103.211.156.0/22 +add china 103.211.164.0/22 +add china 103.211.168.0/22 +add china 103.211.192.0/22 +add china 103.211.220.0/22 +add china 103.211.224.0/21 +add china 103.211.248.0/22 +add china 103.212.0.0/20 +add china 103.212.32.0/22 +add china 103.212.44.0/22 +add china 103.212.48.0/22 +add china 103.212.84.0/22 +add china 103.212.100.0/22 +add china 103.212.104.0/21 +add china 103.212.148.0/22 +add china 103.212.164.0/22 +add china 103.212.196.0/22 +add china 103.212.200.0/22 +add china 103.212.228.0/22 +add china 103.212.252.0/22 +add china 103.213.40.0/21 +add china 103.213.48.0/20 +add china 103.213.64.0/19 +add china 103.213.96.0/22 +add china 103.213.132.0/22 +add china 103.213.136.0/21 +add china 103.213.144.0/20 +add china 103.213.160.0/19 +add china 103.213.248.0/21 +add china 103.214.32.0/22 +add china 103.214.48.0/22 +add china 103.214.84.0/22 +add china 103.214.168.0/22 +add china 103.214.212.0/22 +add china 103.214.224.0/22 +add china 103.214.240.0/21 +add china 103.215.28.0/22 +add china 103.215.32.0/21 +add china 103.215.44.0/22 +add china 103.215.48.0/22 +add china 103.215.100.0/22 +add china 103.215.104.0/21 +add china 103.215.116.0/22 +add china 103.215.120.0/22 +add china 103.215.140.0/22 +add china 103.215.184.0/22 +add china 103.215.228.0/22 +add china 103.216.4.0/22 +add china 103.216.8.0/21 +add china 103.216.16.0/20 +add china 103.216.32.0/20 +add china 103.216.64.0/22 +add china 103.216.108.0/22 +add china 103.216.136.0/22 +add china 103.216.152.0/22 +add china 103.216.224.0/21 +add china 103.216.240.0/20 +add china 103.217.0.0/18 +add china 103.217.168.0/22 +add china 103.217.180.0/22 +add china 103.217.184.0/21 +add china 103.217.192.0/20 +add china 103.218.0.0/22 +add china 103.218.8.0/21 +add china 103.218.16.0/21 +add china 103.218.28.0/22 +add china 103.218.32.0/19 +add china 103.218.64.0/19 +add china 103.218.184.0/22 +add china 103.218.192.0/20 +add china 103.218.208.0/21 +add china 103.218.216.0/22 +add china 103.219.24.0/21 +add china 103.219.32.0/21 +add china 103.219.64.0/22 +add china 103.219.84.0/22 +add china 103.219.88.0/21 +add china 103.219.96.0/21 +add china 103.219.176.0/22 +add china 103.219.184.0/22 +add china 103.220.48.0/20 +add china 103.220.64.0/22 +add china 103.220.92.0/22 +add china 103.220.96.0/20 +add china 103.220.116.0/22 +add china 103.220.120.0/21 +add china 103.220.128.0/20 +add china 103.220.144.0/21 +add china 103.220.152.0/22 +add china 103.220.160.0/19 +add china 103.220.192.0/21 +add china 103.220.200.0/22 +add china 103.220.240.0/20 +add china 103.221.0.0/19 +add china 103.221.32.0/20 +add china 103.221.48.0/22 +add china 103.221.88.0/21 +add china 103.221.96.0/19 +add china 103.221.128.0/18 +add china 103.221.192.0/20 +add china 103.222.0.0/20 +add china 103.222.16.0/22 +add china 103.222.24.0/21 +add china 103.222.32.0/19 +add china 103.222.64.0/18 +add china 103.222.128.0/18 +add china 103.222.192.0/19 +add china 103.222.224.0/21 +add china 103.222.232.0/22 +add china 103.222.240.0/21 +add china 103.223.16.0/20 +add china 103.223.32.0/19 +add china 103.223.64.0/18 +add china 103.223.128.0/21 +add china 103.223.140.0/22 +add china 103.223.144.0/20 +add china 103.223.160.0/20 +add china 103.223.176.0/21 +add china 103.223.188.0/22 +add china 103.223.192.0/18 +add china 103.224.0.0/22 +add china 103.224.16.0/22 +add china 103.224.40.0/21 +add china 103.224.60.0/22 +add china 103.224.80.0/22 +add china 103.224.220.0/22 +add china 103.224.224.0/21 +add china 103.224.232.0/22 +add china 103.225.84.0/22 +add china 103.226.16.0/22 +add china 103.226.40.0/22 +add china 103.226.56.0/21 +add china 103.226.80.0/22 +add china 103.226.116.0/22 +add china 103.226.132.0/22 +add china 103.226.156.0/22 +add china 103.226.180.0/22 +add china 103.226.196.0/22 +add china 103.227.48.0/22 +add china 103.227.72.0/21 +add china 103.227.80.0/22 +add china 103.227.100.0/22 +add china 103.227.120.0/22 +add china 103.227.132.0/22 +add china 103.227.136.0/22 +add china 103.227.196.0/22 +add china 103.227.204.0/22 +add china 103.227.212.0/22 +add china 103.227.228.0/22 +add china 103.228.12.0/22 +add china 103.228.28.0/22 +add china 103.228.68.0/22 +add china 103.228.88.0/22 +add china 103.228.128.0/22 +add china 103.228.136.0/22 +add china 103.228.160.0/22 +add china 103.228.176.0/22 +add china 103.228.204.0/22 +add china 103.228.208.0/22 +add china 103.228.228.0/22 +add china 103.228.232.0/22 +add china 103.229.20.0/22 +add china 103.229.60.0/22 +add china 103.229.136.0/22 +add china 103.229.148.0/22 +add china 103.229.172.0/22 +add china 103.229.212.0/22 +add china 103.229.216.0/21 +add china 103.229.228.0/22 +add china 103.229.236.0/22 +add china 103.229.240.0/22 +add china 103.230.0.0/22 +add china 103.230.28.0/22 +add china 103.230.40.0/21 +add china 103.230.96.0/22 +add china 103.230.196.0/22 +add china 103.230.200.0/21 +add china 103.230.212.0/22 +add china 103.230.236.0/22 +add china 103.231.16.0/21 +add china 103.231.64.0/21 +add china 103.231.144.0/22 +add china 103.231.180.0/22 +add china 103.231.184.0/22 +add china 103.231.244.0/22 +add china 103.232.4.0/22 +add china 103.232.144.0/22 +add china 103.232.188.0/22 +add china 103.232.212.0/22 +add china 103.233.4.0/22 +add china 103.233.44.0/22 +add china 103.233.52.0/22 +add china 103.233.104.0/22 +add china 103.233.128.0/22 +add china 103.233.136.0/22 +add china 103.233.228.0/22 +add china 103.234.0.0/22 +add china 103.234.20.0/22 +add china 103.234.56.0/22 +add china 103.234.124.0/22 +add china 103.234.128.0/22 +add china 103.234.172.0/22 +add china 103.234.180.0/22 +add china 103.234.244.0/22 +add china 103.235.16.0/22 +add china 103.235.48.0/22 +add china 103.235.56.0/21 +add china 103.235.80.0/21 +add china 103.235.128.0/20 +add china 103.235.144.0/21 +add china 103.235.184.0/22 +add china 103.235.192.0/22 +add china 103.235.200.0/22 +add china 103.235.220.0/22 +add china 103.235.224.0/19 +add china 103.236.0.0/18 +add china 103.236.64.0/19 +add china 103.236.96.0/22 +add china 103.236.120.0/22 +add china 103.236.184.0/22 +add china 103.236.220.0/22 +add china 103.236.232.0/22 +add china 103.236.240.0/20 +add china 103.237.0.0/20 +add china 103.237.24.0/21 +add china 103.237.68.0/22 +add china 103.237.88.0/22 +add china 103.237.152.0/22 +add china 103.237.176.0/20 +add china 103.237.192.0/18 +add china 103.238.0.0/21 +add china 103.238.16.0/20 +add china 103.238.32.0/20 +add china 103.238.48.0/21 +add china 103.238.56.0/22 +add china 103.238.88.0/21 +add china 103.238.96.0/22 +add china 103.238.132.0/22 +add china 103.238.140.0/22 +add china 103.238.144.0/22 +add china 103.238.160.0/19 +add china 103.238.196.0/22 +add china 103.238.204.0/22 +add china 103.238.252.0/22 +add china 103.239.0.0/22 +add china 103.239.44.0/22 +add china 103.239.68.0/22 +add china 103.239.96.0/22 +add china 103.239.152.0/21 +add china 103.239.176.0/21 +add china 103.239.184.0/22 +add china 103.239.192.0/21 +add china 103.239.204.0/22 +add china 103.239.208.0/22 +add china 103.239.224.0/22 +add china 103.239.244.0/22 +add china 103.240.16.0/22 +add china 103.240.36.0/22 +add china 103.240.72.0/22 +add china 103.240.84.0/22 +add china 103.240.124.0/22 +add china 103.240.156.0/22 +add china 103.240.172.0/22 +add china 103.240.188.0/22 +add china 103.240.244.0/22 +add china 103.241.12.0/22 +add china 103.241.72.0/22 +add china 103.241.92.0/22 +add china 103.241.96.0/22 +add china 103.241.160.0/22 +add china 103.241.184.0/21 +add china 103.241.220.0/22 +add china 103.242.8.0/22 +add china 103.242.64.0/22 +add china 103.242.128.0/21 +add china 103.242.160.0/22 +add china 103.242.168.0/21 +add china 103.242.176.0/22 +add china 103.242.200.0/22 +add china 103.242.212.0/22 +add china 103.242.220.0/22 +add china 103.242.240.0/22 +add china 103.243.136.0/22 +add china 103.243.252.0/22 +add china 103.244.16.0/22 +add china 103.244.58.0/23 +add china 103.244.60.0/22 +add china 103.244.64.0/20 +add china 103.244.80.0/21 +add china 103.244.116.0/22 +add china 103.244.164.0/22 +add china 103.244.232.0/22 +add china 103.244.252.0/22 +add china 103.245.23.0/24 +add china 103.245.52.0/22 +add china 103.245.60.0/22 +add china 103.245.80.0/22 +add china 103.245.124.0/22 +add china 103.245.128.0/22 +add china 103.246.8.0/21 +add china 103.246.72.0/22 +add china 103.246.120.0/21 +add china 103.246.132.0/22 +add china 103.246.152.0/21 +add china 103.247.168.0/21 +add china 103.247.176.0/22 +add china 103.247.200.0/22 +add china 103.247.212.0/22 +add china 103.248.0.0/23 +add china 103.248.64.0/22 +add china 103.248.100.0/22 +add china 103.248.124.0/22 +add china 103.248.152.0/22 +add china 103.248.168.0/22 +add china 103.248.192.0/22 +add china 103.248.212.0/22 +add china 103.248.220.0/22 +add china 103.248.224.0/21 +add china 103.249.8.0/21 +add china 103.249.52.0/22 +add china 103.249.104.0/22 +add china 103.249.128.0/22 +add china 103.249.136.0/22 +add china 103.249.144.0/22 +add china 103.249.164.0/22 +add china 103.249.168.0/21 +add china 103.249.176.0/22 +add china 103.249.188.0/22 +add china 103.249.192.0/22 +add china 103.249.244.0/22 +add china 103.249.252.0/22 +add china 103.250.32.0/22 +add china 103.250.104.0/22 +add china 103.250.124.0/22 +add china 103.250.180.0/22 +add china 103.250.192.0/22 +add china 103.250.216.0/22 +add china 103.250.224.0/22 +add china 103.250.236.0/22 +add china 103.250.248.0/21 +add china 103.251.32.0/21 +add china 103.251.84.0/22 +add china 103.251.96.0/22 +add china 103.251.124.0/22 +add china 103.251.128.0/22 +add china 103.251.160.0/22 +add china 103.251.192.0/22 +add china 103.251.204.0/22 +add china 103.251.236.0/22 +add china 103.251.240.0/22 +add china 103.252.28.0/22 +add china 103.252.36.0/22 +add china 103.252.64.0/22 +add china 103.252.96.0/22 +add china 103.252.104.0/22 +add china 103.252.172.0/22 +add china 103.252.204.0/22 +add china 103.252.208.0/22 +add china 103.252.232.0/22 +add china 103.252.248.0/22 +add china 103.253.4.0/22 +add china 103.253.60.0/22 +add china 103.253.204.0/22 +add china 103.253.220.0/22 +add china 103.253.224.0/22 +add china 103.253.232.0/22 +add china 103.254.8.0/22 +add china 103.254.20.0/22 +add china 103.254.64.0/20 +add china 103.254.112.0/22 +add china 103.254.176.0/22 +add china 103.254.188.0/22 +add china 103.254.196.0/24 +add china 103.254.220.0/22 +add china 103.255.56.0/22 +add china 103.255.68.0/22 +add china 103.255.88.0/21 +add china 103.255.136.0/21 +add china 103.255.184.0/22 +add china 103.255.200.0/22 +add china 103.255.208.0/21 +add china 103.255.228.0/22 +add china 106.0.0.0/24 +add china 106.0.2.0/23 +add china 106.0.4.0/22 +add china 106.0.8.0/21 +add china 106.0.16.0/20 +add china 106.0.44.0/22 +add china 106.0.64.0/18 +add china 106.2.0.0/15 +add china 106.4.0.0/14 +add china 106.8.0.0/15 +add china 106.11.0.0/16 +add china 106.12.0.0/14 +add china 106.16.0.0/12 +add china 106.32.0.0/12 +add china 106.48.0.0/15 +add china 106.50.0.0/16 +add china 106.52.0.0/14 +add china 106.56.0.0/13 +add china 106.74.0.0/15 +add china 106.80.0.0/12 +add china 106.108.0.0/14 +add china 106.112.0.0/12 +add china 106.224.0.0/12 +add china 110.6.0.0/15 +add china 110.16.0.0/14 +add china 110.34.40.0/21 +add china 110.40.0.0/14 +add china 110.44.12.0/22 +add china 110.44.144.0/20 +add china 110.48.0.0/16 +add china 110.51.0.0/16 +add china 110.52.0.0/15 +add china 110.56.0.0/13 +add china 110.64.0.0/15 +add china 110.72.0.0/15 +add china 110.75.0.0/16 +add china 110.76.0.0/18 +add china 110.76.132.0/22 +add china 110.76.156.0/22 +add china 110.76.184.0/22 +add china 110.76.192.0/18 +add china 110.77.0.0/17 +add china 110.80.0.0/13 +add china 110.88.0.0/14 +add china 110.92.68.0/22 +add china 110.93.32.0/19 +add china 110.94.0.0/15 +add china 110.96.0.0/11 +add china 110.152.0.0/14 +add china 110.156.0.0/15 +add china 110.165.32.0/19 +add china 110.166.0.0/15 +add china 110.172.192.0/18 +add china 110.173.0.0/19 +add china 110.173.32.0/20 +add china 110.173.64.0/18 +add china 110.173.192.0/19 +add china 110.176.0.0/12 +add china 110.192.0.0/11 +add china 110.228.0.0/14 +add china 110.232.32.0/19 +add china 110.236.0.0/15 +add china 110.240.0.0/12 +add china 111.0.0.0/10 +add china 111.66.0.0/16 +add china 111.67.192.0/20 +add china 111.68.64.0/19 +add china 111.72.0.0/13 +add china 111.85.0.0/16 +add china 111.91.192.0/19 +add china 111.92.248.0/21 +add china 111.112.0.0/14 +add china 111.116.0.0/15 +add china 111.118.200.0/21 +add china 111.119.64.0/18 +add china 111.119.128.0/19 +add china 111.120.0.0/14 +add china 111.124.0.0/16 +add china 111.126.0.0/15 +add china 111.128.0.0/11 +add china 111.160.0.0/13 +add china 111.170.0.0/16 +add china 111.172.0.0/14 +add china 111.176.0.0/13 +add china 111.186.0.0/15 +add china 111.192.0.0/12 +add china 111.208.0.0/13 +add china 111.221.28.0/24 +add china 111.221.128.0/17 +add china 111.222.0.0/16 +add china 111.223.4.0/22 +add china 111.223.8.0/21 +add china 111.223.16.0/22 +add china 111.223.240.0/22 +add china 111.223.248.0/22 +add china 111.224.0.0/13 +add china 111.235.96.0/19 +add china 111.235.156.0/22 +add china 111.235.160.0/19 +add china 112.0.0.0/10 +add china 112.64.0.0/14 +add china 112.73.0.0/16 +add china 112.74.0.0/15 +add china 112.80.0.0/12 +add china 112.96.0.0/13 +add china 112.109.128.0/17 +add china 112.111.0.0/16 +add china 112.112.0.0/14 +add china 112.116.0.0/15 +add china 112.122.0.0/15 +add china 112.124.0.0/14 +add china 112.128.0.0/14 +add china 112.132.0.0/16 +add china 112.137.48.0/21 +add china 112.192.0.0/14 +add china 112.224.0.0/11 +add china 113.0.0.0/13 +add china 113.8.0.0/15 +add china 113.11.192.0/19 +add china 113.12.0.0/14 +add china 113.16.0.0/15 +add china 113.18.0.0/16 +add china 113.21.232.0/21 +add china 113.24.0.0/14 +add china 113.31.0.0/16 +add china 113.44.0.0/14 +add china 113.48.0.0/14 +add china 113.52.160.0/19 +add china 113.52.228.0/22 +add china 113.54.0.0/15 +add china 113.56.0.0/15 +add china 113.58.0.0/16 +add china 113.59.0.0/17 +add china 113.59.224.0/22 +add china 113.62.0.0/15 +add china 113.64.0.0/10 +add china 113.128.0.0/15 +add china 113.130.96.0/20 +add china 113.130.112.0/21 +add china 113.132.0.0/14 +add china 113.136.0.0/13 +add china 113.194.0.0/15 +add china 113.197.100.0/22 +add china 113.200.0.0/15 +add china 113.202.0.0/16 +add china 113.204.0.0/14 +add china 113.208.96.0/19 +add china 113.208.128.0/17 +add china 113.209.0.0/16 +add china 113.212.0.0/18 +add china 113.212.100.0/22 +add china 113.212.184.0/21 +add china 113.213.0.0/17 +add china 113.214.0.0/15 +add china 113.218.0.0/15 +add china 113.220.0.0/14 +add china 113.224.0.0/12 +add china 113.240.0.0/13 +add china 113.248.0.0/14 +add china 114.28.0.0/16 +add china 114.31.64.0/21 +add china 114.54.0.0/15 +add china 114.60.0.0/14 +add china 114.64.0.0/14 +add china 114.68.0.0/16 +add china 114.79.64.0/18 +add china 114.80.0.0/12 +add china 114.96.0.0/13 +add china 114.104.0.0/14 +add china 114.110.0.0/20 +add china 114.110.64.0/18 +add china 114.111.0.0/19 +add china 114.111.160.0/19 +add china 114.112.0.0/13 +add china 114.132.0.0/16 +add china 114.135.0.0/16 +add china 114.138.0.0/15 +add china 114.141.64.0/21 +add china 114.141.80.0/21 +add china 114.141.128.0/18 +add china 114.196.0.0/15 +add china 114.198.248.0/21 +add china 114.208.0.0/12 +add china 114.224.0.0/11 +add china 115.24.0.0/14 +add china 115.28.0.0/15 +add china 115.31.64.0/20 +add china 115.32.0.0/14 +add china 115.42.56.0/22 +add china 115.44.0.0/14 +add china 115.48.0.0/12 +add china 115.69.64.0/20 +add china 115.84.0.0/18 +add china 115.84.192.0/19 +add china 115.85.192.0/18 +add china 115.100.0.0/14 +add china 115.104.0.0/14 +add china 115.120.0.0/14 +add china 115.124.16.0/20 +add china 115.148.0.0/14 +add china 115.152.0.0/13 +add china 115.166.64.0/19 +add china 115.168.0.0/13 +add china 115.180.0.0/14 +add china 115.187.0.0/20 +add china 115.190.0.0/15 +add china 115.192.0.0/11 +add china 115.224.0.0/12 +add china 116.0.8.0/21 +add china 116.0.24.0/21 +add china 116.1.0.0/16 +add china 116.2.0.0/15 +add china 116.4.0.0/14 +add china 116.8.0.0/14 +add china 116.13.0.0/16 +add china 116.16.0.0/12 +add china 116.50.0.0/20 +add china 116.52.0.0/14 +add china 116.56.0.0/15 +add china 116.58.128.0/20 +add china 116.58.208.0/20 +add china 116.60.0.0/14 +add china 116.66.0.0/17 +add china 116.66.176.0/22 +add china 116.68.136.0/21 +add china 116.68.176.0/21 +add china 116.69.0.0/16 +add china 116.70.0.0/17 +add china 116.76.0.0/14 +add china 116.85.0.0/16 +add china 116.89.144.0/20 +add china 116.90.80.0/20 +add china 116.90.184.0/21 +add china 116.95.0.0/16 +add china 116.112.0.0/14 +add china 116.116.0.0/15 +add china 116.128.0.0/10 +add china 116.192.0.0/16 +add china 116.193.16.0/20 +add china 116.193.32.0/19 +add china 116.193.152.0/22 +add china 116.193.164.0/22 +add china 116.193.176.0/21 +add china 116.194.0.0/15 +add china 116.196.0.0/16 +add china 116.197.160.0/21 +add china 116.197.180.0/23 +add china 116.198.0.0/16 +add china 116.199.0.0/17 +add china 116.199.128.0/19 +add china 116.204.0.0/15 +add china 116.207.0.0/16 +add china 116.208.0.0/14 +add china 116.212.160.0/20 +add china 116.213.40.0/21 +add china 116.213.64.0/18 +add china 116.213.128.0/17 +add china 116.214.32.0/19 +add china 116.214.64.0/20 +add china 116.214.128.0/17 +add china 116.215.0.0/16 +add china 116.216.0.0/14 +add china 116.224.0.0/12 +add china 116.242.0.0/15 +add china 116.244.0.0/14 +add china 116.248.0.0/15 +add china 116.251.64.0/18 +add china 116.252.0.0/15 +add china 116.254.104.0/21 +add china 116.254.128.0/17 +add china 116.255.128.0/17 +add china 117.8.0.0/13 +add china 117.21.0.0/16 +add china 117.22.0.0/15 +add china 117.24.0.0/13 +add china 117.32.0.0/13 +add china 117.40.0.0/14 +add china 117.44.0.0/15 +add china 117.48.0.0/14 +add china 117.53.48.0/20 +add china 117.53.176.0/20 +add china 117.57.0.0/16 +add china 117.58.0.0/17 +add china 117.59.0.0/16 +add china 117.60.0.0/14 +add china 117.64.0.0/13 +add china 117.72.0.0/15 +add china 117.74.64.0/19 +add china 117.74.128.0/17 +add china 117.75.0.0/16 +add china 117.76.0.0/14 +add china 117.80.0.0/12 +add china 117.100.0.0/15 +add china 117.103.16.0/20 +add china 117.103.40.0/21 +add china 117.103.72.0/21 +add china 117.103.128.0/20 +add china 117.104.168.0/21 +add china 117.104.188.0/24 +add china 117.106.0.0/15 +add china 117.112.0.0/13 +add china 117.120.64.0/18 +add china 117.120.128.0/17 +add china 117.121.0.0/17 +add china 117.121.128.0/18 +add china 117.121.192.0/21 +add china 117.122.128.0/17 +add china 117.124.0.0/14 +add china 117.128.0.0/10 +add china 118.24.0.0/15 +add china 118.26.0.0/16 +add china 118.28.0.0/14 +add china 118.64.0.0/15 +add china 118.66.0.0/16 +add china 118.67.112.0/20 +add china 118.72.0.0/13 +add china 118.80.0.0/15 +add china 118.84.0.0/15 +add china 118.88.32.0/19 +add china 118.88.64.0/18 +add china 118.88.128.0/17 +add china 118.89.0.0/16 +add china 118.91.240.0/20 +add china 118.102.16.0/20 +add china 118.102.32.0/21 +add china 118.103.164.0/22 +add china 118.103.168.0/21 +add china 118.103.176.0/22 +add china 118.103.244.0/22 +add china 118.112.0.0/13 +add china 118.120.0.0/14 +add china 118.124.0.0/15 +add china 118.126.0.0/16 +add china 118.127.128.0/19 +add china 118.132.0.0/14 +add china 118.144.0.0/14 +add china 118.178.0.0/16 +add china 118.180.0.0/14 +add china 118.184.0.0/16 +add china 118.186.0.0/15 +add china 118.188.0.0/16 +add china 118.190.0.0/15 +add china 118.192.0.0/16 +add china 118.193.0.0/20 +add china 118.193.31.0/24 +add china 118.193.32.0/19 +add china 118.193.64.0/20 +add china 118.193.96.0/19 +add china 118.193.128.0/17 +add china 118.194.0.0/15 +add china 118.196.0.0/14 +add china 118.202.0.0/15 +add china 118.204.0.0/14 +add china 118.212.0.0/15 +add china 118.215.192.0/19 +add china 118.224.0.0/14 +add china 118.228.0.0/15 +add china 118.230.0.0/16 +add china 118.239.0.0/16 +add china 118.242.0.0/16 +add china 118.244.0.0/14 +add china 118.248.0.0/13 +add china 119.0.0.0/15 +add china 119.2.0.0/19 +add china 119.2.128.0/17 +add china 119.3.0.0/16 +add china 119.4.0.0/14 +add china 119.8.0.0/16 +add china 119.10.0.0/17 +add china 119.15.136.0/21 +add china 119.16.0.0/16 +add china 119.18.192.0/20 +add china 119.18.208.0/21 +add china 119.18.224.0/19 +add china 119.19.0.0/16 +add china 119.20.0.0/14 +add china 119.27.64.0/18 +add china 119.27.128.0/17 +add china 119.28.0.0/15 +add china 119.30.48.0/20 +add china 119.31.192.0/19 +add china 119.32.0.0/13 +add china 119.40.0.0/18 +add china 119.40.64.0/20 +add china 119.40.128.0/17 +add china 119.41.0.0/16 +add china 119.42.0.0/19 +add china 119.42.52.0/22 +add china 119.42.128.0/20 +add china 119.42.224.0/19 +add china 119.44.0.0/15 +add china 119.48.0.0/13 +add china 119.57.0.0/16 +add china 119.58.0.0/16 +add china 119.59.128.0/17 +add china 119.60.0.0/15 +add china 119.62.0.0/16 +add china 119.63.32.0/19 +add china 119.75.208.0/20 +add china 119.78.0.0/15 +add china 119.80.0.0/16 +add china 119.82.208.0/20 +add china 119.84.0.0/14 +add china 119.88.0.0/14 +add china 119.96.0.0/13 +add china 119.108.0.0/15 +add china 119.112.0.0/12 +add china 119.128.0.0/12 +add china 119.144.0.0/14 +add china 119.148.160.0/19 +add china 119.151.192.0/18 +add china 119.160.200.0/21 +add china 119.161.120.0/21 +add china 119.161.128.0/17 +add china 119.162.0.0/15 +add china 119.164.0.0/14 +add china 119.176.0.0/12 +add china 119.232.0.0/15 +add china 119.235.128.0/18 +add china 119.248.0.0/14 +add china 119.252.96.0/21 +add china 119.252.240.0/20 +add china 119.253.0.0/16 +add china 119.254.0.0/15 +add china 120.0.0.0/12 +add china 120.24.0.0/14 +add china 120.30.0.0/15 +add china 120.32.0.0/12 +add china 120.48.0.0/15 +add china 120.52.0.0/14 +add china 120.64.0.0/13 +add china 120.72.32.0/19 +add china 120.72.128.0/17 +add china 120.76.0.0/14 +add china 120.80.0.0/13 +add china 120.88.8.0/21 +add china 120.90.0.0/15 +add china 120.92.0.0/16 +add china 120.94.0.0/15 +add china 120.128.0.0/13 +add china 120.136.16.0/21 +add china 120.136.128.0/18 +add china 120.137.0.0/17 +add china 120.143.128.0/19 +add china 120.192.0.0/10 +add china 121.0.8.0/21 +add china 121.0.16.0/20 +add china 121.4.0.0/15 +add china 121.8.0.0/13 +add china 121.16.0.0/12 +add china 121.32.0.0/13 +add china 121.40.0.0/14 +add china 121.46.0.0/18 +add china 121.46.76.0/22 +add china 121.46.128.0/17 +add china 121.47.0.0/16 +add china 121.48.0.0/15 +add china 121.50.8.0/21 +add china 121.51.0.0/16 +add china 121.52.160.0/19 +add china 121.52.208.0/20 +add china 121.52.224.0/19 +add china 121.54.176.0/21 +add china 121.54.188.0/22 +add china 121.55.0.0/18 +add china 121.56.0.0/15 +add china 121.58.0.0/17 +add china 121.58.136.0/21 +add china 121.58.144.0/20 +add china 121.58.160.0/21 +add china 121.59.0.0/16 +add china 121.60.0.0/14 +add china 121.68.0.0/14 +add china 121.76.0.0/15 +add china 121.79.128.0/18 +add china 121.89.0.0/16 +add china 121.100.128.0/17 +add china 121.101.0.0/18 +add china 121.101.208.0/20 +add china 121.192.0.0/13 +add china 121.200.192.0/21 +add china 121.201.0.0/16 +add china 121.204.0.0/14 +add china 121.224.0.0/12 +add china 121.248.0.0/14 +add china 121.255.0.0/16 +add china 122.0.64.0/18 +add china 122.0.128.0/17 +add china 122.4.0.0/14 +add china 122.8.0.0/15 +add china 122.10.0.0/16 +add china 122.11.0.0/17 +add china 122.12.0.0/15 +add china 122.14.0.0/16 +add china 122.48.0.0/16 +add china 122.49.0.0/18 +add china 122.51.0.0/16 +add china 122.64.0.0/11 +add china 122.96.0.0/15 +add china 122.98.144.0/20 +add china 122.98.160.0/21 +add china 122.98.172.0/22 +add china 122.98.176.0/20 +add china 122.98.192.0/21 +add china 122.98.232.0/21 +add china 122.98.240.0/20 +add china 122.102.0.0/20 +add china 122.102.64.0/19 +add china 122.112.0.0/14 +add china 122.119.0.0/16 +add china 122.128.100.0/22 +add china 122.128.120.0/21 +add china 122.136.0.0/13 +add china 122.144.128.0/17 +add china 122.152.192.0/18 +add china 122.156.0.0/14 +add china 122.188.0.0/14 +add china 122.192.0.0/14 +add china 122.198.0.0/16 +add china 122.200.40.0/21 +add china 122.200.64.0/18 +add china 122.201.48.0/20 +add china 122.204.0.0/14 +add china 122.224.0.0/12 +add china 122.240.0.0/13 +add china 122.248.24.0/21 +add china 122.248.48.0/20 +add china 122.255.64.0/21 +add china 123.0.128.0/18 +add china 123.4.0.0/14 +add china 123.8.0.0/13 +add china 123.49.128.0/17 +add china 123.50.160.0/19 +add china 123.52.0.0/14 +add china 123.56.0.0/14 +add china 123.60.0.0/15 +add china 123.62.0.0/16 +add china 123.64.0.0/11 +add china 123.96.0.0/15 +add china 123.98.0.0/17 +add china 123.99.128.0/17 +add china 123.100.0.0/19 +add china 123.100.232.0/24 +add china 123.101.0.0/16 +add china 123.103.0.0/17 +add china 123.108.128.0/20 +add china 123.108.208.0/20 +add china 123.112.0.0/12 +add china 123.128.0.0/13 +add china 123.136.80.0/20 +add china 123.137.0.0/16 +add china 123.138.0.0/15 +add china 123.144.0.0/12 +add china 123.160.0.0/12 +add china 123.176.60.0/22 +add china 123.176.80.0/20 +add china 123.177.0.0/16 +add china 123.178.0.0/15 +add china 123.180.0.0/14 +add china 123.184.0.0/13 +add china 123.196.0.0/15 +add china 123.199.128.0/17 +add china 123.206.0.0/15 +add china 123.232.0.0/14 +add china 123.242.0.0/17 +add china 123.242.192.0/21 +add china 123.244.0.0/14 +add china 123.249.0.0/16 +add china 123.253.0.0/16 +add china 123.254.96.0/21 +add china 124.6.64.0/18 +add china 124.14.0.0/15 +add china 124.16.0.0/15 +add china 124.20.0.0/14 +add china 124.28.192.0/18 +add china 124.29.0.0/17 +add china 124.31.0.0/16 +add china 124.40.112.0/20 +add china 124.40.128.0/18 +add china 124.40.192.0/19 +add china 124.40.240.0/22 +add china 124.42.0.0/16 +add china 124.47.0.0/18 +add china 124.64.0.0/15 +add china 124.66.0.0/17 +add china 124.67.0.0/16 +add china 124.68.0.0/14 +add china 124.72.0.0/13 +add china 124.88.0.0/13 +add china 124.108.8.0/21 +add china 124.108.40.0/21 +add china 124.109.96.0/21 +add china 124.112.0.0/13 +add china 124.126.0.0/15 +add china 124.128.0.0/13 +add china 124.147.128.0/17 +add china 124.150.137.0/24 +add china 124.151.0.0/16 +add china 124.152.0.0/16 +add china 124.156.0.0/16 +add china 124.160.0.0/13 +add china 124.172.0.0/14 +add china 124.192.0.0/15 +add china 124.196.0.0/16 +add china 124.200.0.0/13 +add china 124.220.0.0/14 +add china 124.224.0.0/12 +add china 124.240.0.0/17 +add china 124.240.128.0/18 +add china 124.242.0.0/16 +add china 124.243.192.0/18 +add china 124.248.0.0/17 +add china 124.249.0.0/16 +add china 124.250.0.0/15 +add china 124.254.0.0/18 +add china 125.31.192.0/18 +add china 125.32.0.0/12 +add china 125.58.128.0/17 +add china 125.61.128.0/17 +add china 125.62.0.0/18 +add china 125.64.0.0/11 +add china 125.96.0.0/15 +add china 125.98.0.0/16 +add china 125.104.0.0/13 +add china 125.112.0.0/12 +add china 125.169.0.0/16 +add china 125.171.0.0/16 +add china 125.208.0.0/18 +add china 125.210.0.0/15 +add china 125.213.0.0/17 +add china 125.214.96.0/19 +add china 125.215.0.0/18 +add china 125.216.0.0/13 +add china 125.254.128.0/17 +add china 129.223.254.0/24 +add china 132.237.134.0/24 +add china 132.237.150.0/24 +add china 135.159.208.0/20 +add china 135.244.80.0/20 +add china 137.59.59.0/24 +add china 137.59.88.0/22 +add china 138.32.244.0/22 +add china 139.5.56.0/21 +add china 139.5.80.0/22 +add china 139.5.92.0/22 +add china 139.5.108.0/22 +add china 139.5.128.0/22 +add china 139.5.160.0/22 +add china 139.5.192.0/22 +add china 139.5.204.0/22 +add china 139.5.208.0/21 +add china 139.5.244.0/22 +add china 139.9.0.0/16 +add china 139.129.0.0/16 +add china 139.148.0.0/16 +add china 139.155.0.0/16 +add china 139.159.0.0/16 +add china 139.170.0.0/16 +add china 139.176.0.0/16 +add china 139.183.0.0/16 +add china 139.186.0.0/16 +add china 139.189.0.0/16 +add china 139.196.0.0/14 +add china 139.200.0.0/13 +add china 139.208.0.0/13 +add china 139.217.0.0/16 +add china 139.219.0.0/16 +add china 139.220.0.0/15 +add china 139.224.0.0/16 +add china 139.226.0.0/15 +add china 140.75.0.0/16 +add china 140.101.208.0/24 +add china 140.143.0.0/16 +add china 140.205.0.0/16 +add china 140.206.0.0/15 +add china 140.210.0.0/16 +add china 140.224.0.0/16 +add china 140.237.0.0/16 +add china 140.240.0.0/16 +add china 140.242.216.0/24 +add china 140.242.223.0/24 +add china 140.242.224.0/24 +add china 140.243.0.0/16 +add china 140.246.0.0/16 +add china 140.249.0.0/16 +add china 140.250.0.0/16 +add china 140.255.0.0/16 +add china 144.0.0.0/16 +add china 144.7.0.0/16 +add china 144.12.0.0/16 +add china 144.36.146.0/23 +add china 144.48.8.0/21 +add china 144.48.56.0/22 +add china 144.48.64.0/22 +add china 144.48.88.0/22 +add china 144.48.156.0/22 +add china 144.48.172.0/22 +add china 144.48.180.0/22 +add china 144.48.184.0/22 +add china 144.48.204.0/22 +add china 144.48.208.0/21 +add china 144.48.220.0/22 +add china 144.48.252.0/22 +add china 144.52.0.0/16 +add china 144.123.0.0/16 +add china 144.211.80.0/24 +add china 144.211.138.0/24 +add china 144.255.0.0/16 +add china 146.196.56.0/22 +add china 146.196.68.0/22 +add china 146.196.72.0/21 +add china 146.196.92.0/22 +add china 146.196.112.0/21 +add china 146.196.124.0/22 +add china 146.217.137.0/24 +add china 146.222.79.0/24 +add china 146.222.81.0/24 +add china 146.222.94.0/24 +add china 150.0.0.0/16 +add china 150.115.0.0/16 +add china 150.121.0.0/16 +add china 150.122.0.0/16 +add china 150.129.136.0/22 +add china 150.129.152.0/22 +add china 150.129.192.0/22 +add china 150.129.216.0/22 +add china 150.129.252.0/22 +add china 150.138.0.0/15 +add china 150.223.0.0/16 +add china 150.242.0.0/21 +add china 150.242.8.0/22 +add china 150.242.28.0/22 +add china 150.242.44.0/22 +add china 150.242.48.0/21 +add china 150.242.56.0/22 +add china 150.242.76.0/22 +add china 150.242.80.0/22 +add china 150.242.92.0/22 +add china 150.242.96.0/22 +add china 150.242.112.0/21 +add china 150.242.120.0/22 +add china 150.242.152.0/21 +add china 150.242.160.0/21 +add china 150.242.168.0/22 +add china 150.242.184.0/21 +add china 150.242.192.0/22 +add china 150.242.212.0/22 +add china 150.242.224.0/20 +add china 150.242.240.0/21 +add china 150.242.248.0/22 +add china 150.255.0.0/16 +add china 152.104.128.0/17 +add china 153.0.0.0/16 +add china 153.3.0.0/16 +add china 153.34.0.0/15 +add china 153.36.0.0/15 +add china 153.99.0.0/16 +add china 153.101.0.0/16 +add china 153.118.0.0/15 +add china 157.0.0.0/16 +add china 157.18.0.0/16 +add china 157.61.0.0/16 +add china 157.119.0.0/22 +add china 157.119.8.0/21 +add china 157.119.16.0/22 +add china 157.119.28.0/22 +add china 157.119.68.0/22 +add china 157.119.112.0/22 +add china 157.119.132.0/22 +add china 157.119.136.0/21 +add china 157.119.144.0/20 +add china 157.119.160.0/21 +add china 157.119.172.0/22 +add china 157.119.192.0/21 +add china 157.119.240.0/22 +add china 157.119.252.0/22 +add china 157.122.0.0/16 +add china 157.133.192.0/21 +add china 157.148.0.0/16 +add china 157.156.0.0/16 +add china 157.255.0.0/16 +add china 159.153.120.0/22 +add china 159.226.0.0/16 +add china 160.19.48.0/22 +add china 160.19.208.0/21 +add china 160.19.216.0/22 +add china 160.20.48.0/22 +add china 160.62.10.0/24 +add china 160.83.109.0/24 +add china 160.83.110.0/23 +add china 160.202.60.0/22 +add china 160.202.148.0/22 +add china 160.202.152.0/22 +add china 160.202.168.0/22 +add china 160.202.212.0/22 +add china 160.202.216.0/21 +add china 160.202.224.0/19 +add china 160.238.64.0/22 +add china 161.163.0.0/21 +add china 161.163.28.0/23 +add china 161.163.176.0/24 +add china 161.163.178.0/23 +add china 161.163.180.0/22 +add china 161.207.0.0/16 +add china 162.105.0.0/16 +add china 163.0.0.0/16 +add china 163.47.4.0/22 +add china 163.53.0.0/20 +add china 163.53.36.0/22 +add china 163.53.40.0/21 +add china 163.53.48.0/20 +add china 163.53.64.0/22 +add china 163.53.88.0/21 +add china 163.53.96.0/19 +add china 163.53.128.0/21 +add china 163.53.136.0/22 +add china 163.53.160.0/20 +add china 163.53.188.0/22 +add china 163.53.220.0/22 +add china 163.53.240.0/22 +add china 163.125.0.0/16 +add china 163.142.0.0/16 +add china 163.177.0.0/16 +add china 163.179.0.0/16 +add china 163.204.0.0/16 +add china 163.244.246.0/24 +add china 164.52.0.0/17 +add china 166.111.0.0/16 +add china 167.139.0.0/16 +add china 167.189.0.0/16 +add china 167.220.244.0/22 +add china 168.159.144.0/21 +add china 168.159.152.0/22 +add china 168.159.156.0/23 +add china 168.159.158.0/24 +add china 168.160.0.0/16 +add china 168.230.0.0/24 +add china 170.179.0.0/16 +add china 170.225.224.0/23 +add china 170.252.152.0/21 +add china 171.8.0.0/13 +add china 171.34.0.0/15 +add china 171.36.0.0/14 +add china 171.40.0.0/13 +add china 171.80.0.0/12 +add china 171.104.0.0/13 +add china 171.112.0.0/12 +add china 171.208.0.0/12 +add china 175.0.0.0/12 +add china 175.16.0.0/13 +add china 175.24.0.0/14 +add china 175.30.0.0/15 +add china 175.42.0.0/15 +add china 175.44.0.0/16 +add china 175.46.0.0/15 +add china 175.48.0.0/12 +add china 175.64.0.0/11 +add china 175.102.0.0/16 +add china 175.106.128.0/17 +add china 175.111.108.0/22 +add china 175.111.144.0/20 +add china 175.111.160.0/20 +add china 175.111.184.0/22 +add china 175.146.0.0/15 +add china 175.148.0.0/14 +add china 175.152.0.0/14 +add china 175.158.96.0/22 +add china 175.160.0.0/12 +add china 175.176.156.0/22 +add china 175.176.176.0/22 +add china 175.176.188.0/22 +add china 175.178.0.0/16 +add china 175.184.128.0/18 +add china 175.185.0.0/16 +add china 175.186.0.0/15 +add china 175.188.0.0/14 +add china 180.76.0.0/14 +add china 180.84.0.0/15 +add china 180.86.0.0/16 +add china 180.88.0.0/14 +add china 180.94.56.0/21 +add china 180.94.96.0/20 +add china 180.94.120.0/21 +add china 180.95.128.0/17 +add china 180.96.0.0/11 +add china 180.129.128.0/17 +add china 180.130.0.0/16 +add china 180.136.0.0/13 +add china 180.148.16.0/21 +add china 180.148.152.0/21 +add china 180.148.216.0/21 +add china 180.148.224.0/19 +add china 180.149.128.0/19 +add china 180.149.236.0/22 +add china 180.150.160.0/19 +add china 180.152.0.0/13 +add china 180.160.0.0/12 +add china 180.178.112.0/21 +add china 180.178.192.0/18 +add china 180.184.0.0/14 +add china 180.188.0.0/17 +add china 180.189.148.0/22 +add china 180.200.252.0/22 +add china 180.201.0.0/16 +add china 180.202.0.0/15 +add china 180.208.0.0/15 +add china 180.210.212.0/22 +add china 180.210.224.0/19 +add china 180.212.0.0/15 +add china 180.222.224.0/19 +add china 180.223.0.0/16 +add china 180.233.0.0/18 +add china 180.233.64.0/19 +add china 180.233.144.0/22 +add china 180.235.64.0/19 +add china 180.235.112.0/22 +add china 180.235.136.0/22 +add china 182.16.144.0/21 +add china 182.16.192.0/19 +add china 182.18.0.0/17 +add china 182.23.184.0/21 +add china 182.23.200.0/21 +add china 182.32.0.0/12 +add china 182.48.96.0/19 +add china 182.49.0.0/16 +add china 182.50.0.0/20 +add china 182.50.112.0/20 +add china 182.51.0.0/16 +add china 182.54.0.0/17 +add china 182.54.244.0/22 +add china 182.61.0.0/16 +add china 182.80.0.0/13 +add china 182.88.0.0/14 +add china 182.92.0.0/16 +add china 182.96.0.0/11 +add china 182.128.0.0/12 +add china 182.144.0.0/13 +add china 182.157.0.0/16 +add china 182.160.64.0/19 +add china 182.174.0.0/15 +add china 182.200.0.0/13 +add china 182.236.128.0/17 +add china 182.237.24.0/21 +add china 182.238.0.0/16 +add china 182.239.0.0/19 +add china 182.240.0.0/13 +add china 182.254.0.0/16 +add china 182.255.36.0/22 +add china 182.255.60.0/22 +add china 183.0.0.0/10 +add china 183.64.0.0/13 +add china 183.78.160.0/21 +add china 183.78.180.0/22 +add china 183.81.172.0/22 +add china 183.81.180.0/22 +add china 183.84.0.0/15 +add china 183.91.128.0/22 +add china 183.91.136.0/21 +add china 183.91.144.0/20 +add china 183.92.0.0/14 +add china 183.128.0.0/11 +add china 183.160.0.0/13 +add china 183.168.0.0/15 +add china 183.170.0.0/16 +add china 183.172.0.0/14 +add china 183.182.0.0/19 +add china 183.184.0.0/13 +add china 183.192.0.0/10 +add china 192.11.23.0/24 +add china 192.11.26.0/24 +add china 192.11.39.0/24 +add china 192.11.236.0/24 +add china 192.23.191.0/24 +add china 192.55.10.0/23 +add china 192.55.46.0/23 +add china 192.55.68.0/22 +add china 192.102.204.0/22 +add china 192.124.154.0/24 +add china 192.139.135.0/24 +add china 192.139.136.0/24 +add china 192.140.128.0/21 +add china 192.140.136.0/22 +add china 192.140.156.0/22 +add china 192.140.160.0/19 +add china 192.140.192.0/20 +add china 192.140.208.0/21 +add china 192.163.11.0/24 +add china 192.170.79.0/24 +add china 192.232.97.0/24 +add china 193.20.64.0/22 +add china 194.138.202.0/23 +add china 198.17.7.0/24 +add china 198.175.100.0/22 +add china 198.208.17.0/24 +add china 199.7.72.0/24 +add china 199.65.192.0/21 +add china 199.244.144.0/24 +add china 202.0.100.0/23 +add china 202.0.122.0/23 +add china 202.0.176.0/22 +add china 202.1.105.0/24 +add china 202.1.106.0/24 +add china 202.3.128.0/23 +add china 202.4.128.0/19 +add china 202.4.252.0/22 +add china 202.5.208.0/21 +add china 202.5.216.0/22 +add china 202.6.6.0/23 +add china 202.6.66.0/23 +add china 202.6.72.0/23 +add china 202.6.87.0/24 +add china 202.6.88.0/23 +add china 202.6.92.0/23 +add china 202.6.103.0/24 +add china 202.6.108.0/24 +add china 202.6.110.0/23 +add china 202.6.114.0/24 +add china 202.6.176.0/20 +add china 202.8.0.0/24 +add china 202.8.2.0/23 +add china 202.8.4.0/23 +add china 202.8.12.0/24 +add china 202.8.24.0/24 +add china 202.8.77.0/24 +add china 202.8.128.0/19 +add china 202.8.192.0/20 +add china 202.9.32.0/24 +add china 202.9.34.0/23 +add china 202.9.48.0/23 +add china 202.9.51.0/24 +add china 202.9.52.0/23 +add china 202.9.54.0/24 +add china 202.9.57.0/24 +add china 202.9.58.0/23 +add china 202.10.64.0/20 +add china 202.10.112.0/20 +add china 202.12.1.0/24 +add china 202.12.2.0/24 +add china 202.12.17.0/24 +add china 202.12.18.0/23 +add china 202.12.72.0/24 +add china 202.12.84.0/23 +add china 202.12.96.0/24 +add china 202.12.98.0/23 +add china 202.12.106.0/24 +add china 202.12.111.0/24 +add china 202.12.116.0/24 +add china 202.14.64.0/23 +add china 202.14.69.0/24 +add china 202.14.73.0/24 +add china 202.14.74.0/23 +add china 202.14.76.0/24 +add china 202.14.78.0/23 +add china 202.14.88.0/24 +add china 202.14.97.0/24 +add china 202.14.104.0/23 +add china 202.14.108.0/23 +add china 202.14.111.0/24 +add china 202.14.114.0/23 +add china 202.14.118.0/23 +add china 202.14.124.0/23 +add china 202.14.127.0/24 +add china 202.14.129.0/24 +add china 202.14.135.0/24 +add china 202.14.136.0/24 +add china 202.14.149.0/24 +add china 202.14.151.0/24 +add china 202.14.157.0/24 +add china 202.14.158.0/23 +add china 202.14.169.0/24 +add china 202.14.170.0/23 +add china 202.14.172.0/22 +add china 202.14.176.0/24 +add china 202.14.184.0/23 +add china 202.14.208.0/23 +add china 202.14.213.0/24 +add china 202.14.219.0/24 +add china 202.14.220.0/24 +add china 202.14.222.0/23 +add china 202.14.225.0/24 +add china 202.14.226.0/23 +add china 202.14.231.0/24 +add china 202.14.235.0/24 +add china 202.14.236.0/22 +add china 202.14.246.0/24 +add china 202.14.251.0/24 +add china 202.20.66.0/24 +add china 202.20.79.0/24 +add china 202.20.87.0/24 +add china 202.20.88.0/23 +add china 202.20.90.0/24 +add china 202.20.94.0/23 +add china 202.20.114.0/24 +add china 202.20.117.0/24 +add china 202.20.120.0/24 +add china 202.20.125.0/24 +add china 202.20.126.0/23 +add china 202.21.48.0/20 +add china 202.21.131.0/24 +add china 202.21.132.0/24 +add china 202.21.141.0/24 +add china 202.21.142.0/24 +add china 202.21.147.0/24 +add china 202.21.148.0/24 +add china 202.21.150.0/23 +add china 202.21.152.0/23 +add china 202.21.154.0/24 +add china 202.21.156.0/24 +add china 202.21.208.0/24 +add china 202.22.248.0/21 +add china 202.27.12.0/24 +add china 202.27.14.0/24 +add china 202.27.136.0/23 +add china 202.36.226.0/24 +add china 202.38.0.0/22 +add china 202.38.8.0/21 +add china 202.38.48.0/20 +add china 202.38.64.0/18 +add china 202.38.128.0/21 +add china 202.38.136.0/23 +add china 202.38.138.0/24 +add china 202.38.140.0/22 +add china 202.38.146.0/23 +add china 202.38.149.0/24 +add china 202.38.150.0/23 +add china 202.38.152.0/22 +add china 202.38.156.0/24 +add china 202.38.158.0/23 +add china 202.38.160.0/23 +add china 202.38.164.0/22 +add china 202.38.168.0/22 +add china 202.38.176.0/23 +add china 202.38.184.0/21 +add china 202.38.192.0/18 +add china 202.40.4.0/23 +add china 202.40.7.0/24 +add china 202.40.15.0/24 +add china 202.40.135.0/24 +add china 202.40.136.0/24 +add china 202.40.140.0/24 +add china 202.40.143.0/24 +add china 202.40.144.0/23 +add china 202.40.150.0/24 +add china 202.40.155.0/24 +add china 202.40.156.0/24 +add china 202.40.158.0/23 +add china 202.40.162.0/24 +add china 202.41.8.0/23 +add china 202.41.11.0/24 +add china 202.41.12.0/23 +add china 202.41.128.0/24 +add china 202.41.130.0/23 +add china 202.41.152.0/21 +add china 202.41.192.0/24 +add china 202.41.196.0/22 +add china 202.41.200.0/22 +add china 202.41.240.0/20 +add china 202.43.76.0/22 +add china 202.43.144.0/20 +add china 202.44.16.0/20 +add china 202.44.48.0/22 +add china 202.44.67.0/24 +add china 202.44.74.0/24 +add china 202.44.97.0/24 +add china 202.44.129.0/24 +add china 202.44.132.0/23 +add china 202.44.146.0/23 +add china 202.45.0.0/23 +add china 202.45.2.0/24 +add china 202.45.15.0/24 +add china 202.45.16.0/20 +add china 202.46.16.0/23 +add china 202.46.18.0/24 +add china 202.46.20.0/23 +add china 202.46.32.0/19 +add china 202.46.128.0/24 +add china 202.46.224.0/20 +add china 202.47.82.0/23 +add china 202.47.96.0/20 +add china 202.47.124.0/24 +add china 202.47.126.0/24 +add china 202.47.128.0/24 +add china 202.47.130.0/23 +add china 202.52.33.0/24 +add china 202.52.34.0/24 +add china 202.52.47.0/24 +add china 202.52.143.0/24 +add china 202.52.144.0/24 +add china 202.53.140.0/24 +add china 202.53.143.0/24 +add china 202.57.192.0/20 +add china 202.57.212.0/22 +add china 202.57.216.0/22 +add china 202.57.240.0/20 +add china 202.58.0.0/24 +add china 202.58.104.0/22 +add china 202.58.112.0/22 +add china 202.59.0.0/23 +add china 202.59.212.0/22 +add china 202.59.236.0/24 +add china 202.59.240.0/24 +add china 202.60.48.0/21 +add china 202.60.96.0/21 +add china 202.60.112.0/20 +add china 202.60.132.0/22 +add china 202.60.136.0/21 +add china 202.60.144.0/20 +add china 202.61.68.0/22 +add china 202.61.76.0/22 +add china 202.61.88.0/22 +add china 202.61.123.0/24 +add china 202.61.127.0/24 +add china 202.62.112.0/22 +add china 202.62.248.0/22 +add china 202.62.252.0/24 +add china 202.62.255.0/24 +add china 202.63.80.0/20 +add china 202.63.160.0/19 +add china 202.63.248.0/22 +add china 202.63.253.0/24 +add china 202.65.0.0/21 +add china 202.65.8.0/23 +add china 202.65.96.0/20 +add china 202.66.168.0/22 +add china 202.67.0.0/22 +add china 202.69.4.0/22 +add china 202.69.16.0/20 +add china 202.70.0.0/19 +add china 202.70.96.0/20 +add china 202.70.192.0/20 +add china 202.71.32.0/20 +add china 202.72.40.0/21 +add china 202.72.80.0/20 +add china 202.72.112.0/20 +add china 202.73.128.0/22 +add china 202.73.240.0/20 +add china 202.74.8.0/21 +add china 202.74.36.0/24 +add china 202.74.42.0/24 +add china 202.74.52.0/24 +add china 202.74.80.0/20 +add china 202.74.232.0/22 +add china 202.74.254.0/23 +add china 202.75.208.0/20 +add china 202.75.252.0/22 +add china 202.76.247.0/24 +add china 202.76.252.0/22 +add china 202.77.39.0/24 +add china 202.77.80.0/21 +add china 202.77.92.0/22 +add china 202.78.8.0/21 +add china 202.79.224.0/21 +add china 202.79.248.0/22 +add china 202.80.192.0/20 +add china 202.81.0.0/22 +add china 202.81.176.0/20 +add china 202.83.252.0/22 +add china 202.84.0.0/20 +add china 202.84.16.0/23 +add china 202.84.22.0/24 +add china 202.84.24.0/21 +add china 202.85.208.0/20 +add china 202.86.249.0/24 +add china 202.86.252.0/22 +add china 202.87.80.0/20 +add china 202.88.32.0/22 +add china 202.89.8.0/21 +add china 202.89.96.0/22 +add china 202.89.108.0/22 +add china 202.89.119.0/24 +add china 202.89.232.0/21 +add china 202.90.0.0/22 +add china 202.90.16.0/20 +add china 202.90.37.0/24 +add china 202.90.96.0/19 +add china 202.90.193.0/24 +add china 202.90.196.0/24 +add china 202.90.205.0/24 +add china 202.90.224.0/20 +add china 202.91.0.0/22 +add china 202.91.96.0/20 +add china 202.91.128.0/22 +add china 202.91.176.0/20 +add china 202.91.224.0/19 +add china 202.92.0.0/22 +add china 202.92.8.0/21 +add china 202.92.48.0/20 +add china 202.92.252.0/22 +add china 202.93.0.0/22 +add china 202.93.252.0/22 +add china 202.94.0.0/19 +add china 202.94.74.0/24 +add china 202.94.81.0/24 +add china 202.94.92.0/22 +add china 202.95.0.0/19 +add china 202.95.240.0/21 +add china 202.95.252.0/22 +add china 202.96.0.0/12 +add china 202.112.0.0/13 +add china 202.120.0.0/15 +add china 202.122.0.0/21 +add china 202.122.32.0/21 +add china 202.122.64.0/19 +add china 202.122.112.0/20 +add china 202.122.128.0/24 +add china 202.122.132.0/24 +add china 202.123.96.0/20 +add china 202.123.116.0/22 +add china 202.123.120.0/22 +add china 202.124.16.0/21 +add china 202.124.24.0/22 +add china 202.125.107.0/24 +add china 202.125.109.0/24 +add china 202.125.112.0/20 +add china 202.125.176.0/20 +add china 202.127.0.0/21 +add china 202.127.12.0/22 +add china 202.127.16.0/20 +add china 202.127.40.0/21 +add china 202.127.48.0/20 +add china 202.127.112.0/20 +add china 202.127.128.0/19 +add china 202.127.160.0/21 +add china 202.127.192.0/20 +add china 202.127.208.0/23 +add china 202.127.212.0/22 +add china 202.127.216.0/21 +add china 202.127.224.0/19 +add china 202.129.208.0/24 +add china 202.130.0.0/19 +add china 202.130.39.0/24 +add china 202.130.224.0/19 +add china 202.131.16.0/21 +add china 202.131.48.0/20 +add china 202.131.208.0/20 +add china 202.133.32.0/20 +add china 202.134.58.0/24 +add china 202.134.128.0/20 +add china 202.134.208.0/20 +add china 202.136.48.0/20 +add china 202.136.208.0/20 +add china 202.136.224.0/20 +add china 202.136.248.0/22 +add china 202.136.254.0/23 +add china 202.137.231.0/24 +add china 202.140.140.0/22 +add china 202.140.144.0/20 +add china 202.141.160.0/19 +add china 202.142.16.0/20 +add china 202.143.4.0/22 +add china 202.143.16.0/20 +add china 202.143.32.0/20 +add china 202.143.56.0/21 +add china 202.143.100.0/22 +add china 202.143.104.0/22 +add china 202.146.160.0/20 +add china 202.146.186.0/24 +add china 202.146.188.0/22 +add china 202.146.196.0/22 +add china 202.146.200.0/21 +add china 202.147.144.0/20 +add china 202.148.32.0/20 +add china 202.148.64.0/18 +add china 202.149.32.0/19 +add china 202.149.160.0/19 +add china 202.149.224.0/19 +add china 202.150.16.0/20 +add china 202.150.32.0/20 +add china 202.150.56.0/22 +add china 202.150.192.0/20 +add china 202.150.224.0/19 +add china 202.151.0.0/22 +add china 202.151.33.0/24 +add china 202.151.128.0/19 +add china 202.152.176.0/20 +add china 202.153.0.0/22 +add china 202.153.7.0/24 +add china 202.153.48.0/20 +add china 202.157.192.0/19 +add china 202.158.160.0/19 +add china 202.158.242.0/24 +add china 202.160.140.0/22 +add china 202.160.156.0/22 +add china 202.160.176.0/20 +add china 202.162.67.0/24 +add china 202.162.75.0/24 +add china 202.164.0.0/20 +add china 202.164.96.0/19 +add china 202.165.96.0/20 +add china 202.165.176.0/20 +add china 202.165.208.0/20 +add china 202.165.239.0/24 +add china 202.165.240.0/23 +add china 202.165.243.0/24 +add china 202.165.245.0/24 +add china 202.165.251.0/24 +add china 202.165.252.0/22 +add china 202.166.224.0/19 +add china 202.168.80.0/22 +add china 202.168.128.0/20 +add china 202.168.160.0/19 +add china 202.170.128.0/19 +add china 202.170.216.0/21 +add china 202.170.224.0/19 +add china 202.171.216.0/21 +add china 202.171.232.0/24 +add china 202.171.235.0/24 +add china 202.172.0.0/22 +add china 202.172.7.0/24 +add china 202.173.0.0/22 +add china 202.173.6.0/24 +add china 202.173.8.0/21 +add china 202.173.112.0/22 +add china 202.173.120.0/22 +add china 202.173.224.0/19 +add china 202.174.64.0/20 +add china 202.174.124.0/22 +add china 202.176.224.0/19 +add china 202.179.160.0/20 +add china 202.179.240.0/20 +add china 202.180.128.0/19 +add china 202.180.208.0/21 +add china 202.181.8.0/22 +add china 202.181.28.0/22 +add china 202.181.112.0/20 +add china 202.182.32.0/20 +add china 202.182.192.0/19 +add china 202.189.0.0/18 +add china 202.189.80.0/20 +add china 202.189.184.0/21 +add china 202.191.0.0/24 +add china 202.191.68.0/22 +add china 202.191.72.0/21 +add china 202.191.80.0/20 +add china 202.192.0.0/12 +add china 203.0.4.0/22 +add china 203.0.10.0/23 +add china 203.0.18.0/24 +add china 203.0.24.0/24 +add china 203.0.42.0/23 +add china 203.0.45.0/24 +add china 203.0.46.0/23 +add china 203.0.81.0/24 +add china 203.0.82.0/23 +add china 203.0.90.0/23 +add china 203.0.96.0/23 +add china 203.0.104.0/21 +add china 203.0.114.0/23 +add china 203.0.122.0/24 +add china 203.0.128.0/24 +add china 203.0.130.0/23 +add china 203.0.132.0/22 +add china 203.0.137.0/24 +add china 203.0.142.0/24 +add china 203.0.144.0/24 +add china 203.0.146.0/24 +add china 203.0.148.0/24 +add china 203.0.150.0/23 +add china 203.0.152.0/24 +add china 203.0.177.0/24 +add china 203.0.224.0/24 +add china 203.1.4.0/22 +add china 203.1.18.0/24 +add china 203.1.26.0/23 +add china 203.1.65.0/24 +add china 203.1.66.0/23 +add china 203.1.70.0/23 +add china 203.1.76.0/23 +add china 203.1.90.0/24 +add china 203.1.97.0/24 +add china 203.1.98.0/23 +add china 203.1.100.0/22 +add china 203.1.108.0/24 +add china 203.1.253.0/24 +add china 203.1.254.0/24 +add china 203.2.64.0/21 +add china 203.2.73.0/24 +add china 203.2.112.0/21 +add china 203.2.126.0/23 +add china 203.2.140.0/24 +add china 203.2.150.0/24 +add china 203.2.152.0/22 +add china 203.2.156.0/23 +add china 203.2.160.0/21 +add china 203.2.180.0/23 +add china 203.2.196.0/23 +add china 203.2.209.0/24 +add china 203.2.214.0/23 +add china 203.2.226.0/23 +add china 203.2.229.0/24 +add china 203.2.236.0/23 +add china 203.3.68.0/24 +add china 203.3.72.0/23 +add china 203.3.75.0/24 +add china 203.3.80.0/21 +add china 203.3.96.0/22 +add china 203.3.105.0/24 +add china 203.3.112.0/21 +add china 203.3.120.0/24 +add china 203.3.123.0/24 +add china 203.3.135.0/24 +add china 203.3.139.0/24 +add china 203.3.143.0/24 +add china 203.4.132.0/23 +add china 203.4.134.0/24 +add china 203.4.151.0/24 +add china 203.4.152.0/22 +add china 203.4.174.0/23 +add china 203.4.180.0/24 +add china 203.4.186.0/24 +add china 203.4.205.0/24 +add china 203.4.208.0/22 +add china 203.4.227.0/24 +add china 203.4.230.0/23 +add china 203.5.4.0/23 +add china 203.5.7.0/24 +add china 203.5.8.0/23 +add china 203.5.11.0/24 +add china 203.5.21.0/24 +add china 203.5.22.0/24 +add china 203.5.44.0/24 +add china 203.5.46.0/23 +add china 203.5.52.0/22 +add china 203.5.56.0/23 +add china 203.5.60.0/23 +add china 203.5.114.0/23 +add china 203.5.118.0/24 +add china 203.5.120.0/24 +add china 203.5.172.0/24 +add china 203.5.180.0/23 +add china 203.5.182.0/24 +add china 203.5.185.0/24 +add china 203.5.186.0/24 +add china 203.5.188.0/23 +add china 203.5.190.0/24 +add china 203.5.195.0/24 +add china 203.5.214.0/23 +add china 203.5.218.0/23 +add china 203.6.131.0/24 +add china 203.6.136.0/24 +add china 203.6.138.0/23 +add china 203.6.142.0/24 +add china 203.6.150.0/23 +add china 203.6.157.0/24 +add china 203.6.159.0/24 +add china 203.6.224.0/20 +add china 203.6.248.0/23 +add china 203.7.129.0/24 +add china 203.7.138.0/23 +add china 203.7.147.0/24 +add china 203.7.150.0/23 +add china 203.7.158.0/24 +add china 203.7.192.0/23 +add china 203.7.200.0/24 +add china 203.8.0.0/24 +add china 203.8.8.0/24 +add china 203.8.23.0/24 +add china 203.8.24.0/21 +add china 203.8.70.0/24 +add china 203.8.82.0/24 +add china 203.8.86.0/23 +add china 203.8.91.0/24 +add china 203.8.110.0/23 +add china 203.8.115.0/24 +add china 203.8.166.0/23 +add china 203.8.169.0/24 +add china 203.8.173.0/24 +add china 203.8.184.0/24 +add china 203.8.186.0/23 +add china 203.8.190.0/23 +add china 203.8.192.0/24 +add china 203.8.197.0/24 +add china 203.8.198.0/23 +add china 203.8.203.0/24 +add china 203.8.209.0/24 +add china 203.8.210.0/23 +add china 203.8.212.0/22 +add china 203.8.217.0/24 +add china 203.8.220.0/24 +add china 203.9.32.0/24 +add china 203.9.36.0/23 +add china 203.9.57.0/24 +add china 203.9.63.0/24 +add china 203.9.65.0/24 +add china 203.9.70.0/23 +add china 203.9.72.0/24 +add china 203.9.75.0/24 +add china 203.9.76.0/23 +add china 203.9.96.0/22 +add china 203.9.100.0/23 +add china 203.9.108.0/24 +add china 203.9.158.0/24 +add china 203.10.34.0/24 +add china 203.10.56.0/24 +add china 203.10.74.0/23 +add china 203.10.84.0/22 +add china 203.10.88.0/24 +add china 203.10.95.0/24 +add china 203.10.125.0/24 +add china 203.11.70.0/24 +add china 203.11.76.0/22 +add china 203.11.82.0/24 +add china 203.11.84.0/22 +add china 203.11.100.0/22 +add china 203.11.109.0/24 +add china 203.11.117.0/24 +add china 203.11.122.0/24 +add china 203.11.126.0/24 +add china 203.11.136.0/22 +add china 203.11.141.0/24 +add china 203.11.142.0/23 +add china 203.11.180.0/22 +add china 203.11.208.0/22 +add china 203.12.16.0/24 +add china 203.12.19.0/24 +add china 203.12.24.0/24 +add china 203.12.57.0/24 +add china 203.12.65.0/24 +add china 203.12.66.0/24 +add china 203.12.70.0/23 +add china 203.12.87.0/24 +add china 203.12.88.0/21 +add china 203.12.100.0/23 +add china 203.12.103.0/24 +add china 203.12.114.0/24 +add china 203.12.118.0/24 +add china 203.12.130.0/24 +add china 203.12.137.0/24 +add china 203.12.196.0/22 +add china 203.12.200.0/21 +add china 203.12.211.0/24 +add china 203.12.219.0/24 +add china 203.12.226.0/24 +add china 203.12.240.0/22 +add china 203.13.18.0/24 +add china 203.13.24.0/24 +add china 203.13.44.0/23 +add china 203.13.80.0/21 +add china 203.13.88.0/23 +add china 203.13.92.0/22 +add china 203.13.173.0/24 +add china 203.13.224.0/23 +add china 203.13.227.0/24 +add china 203.13.233.0/24 +add china 203.14.24.0/22 +add china 203.14.33.0/24 +add china 203.14.56.0/24 +add china 203.14.61.0/24 +add china 203.14.62.0/24 +add china 203.14.104.0/24 +add china 203.14.114.0/23 +add china 203.14.118.0/24 +add china 203.14.162.0/24 +add china 203.14.184.0/21 +add china 203.14.192.0/24 +add china 203.14.194.0/23 +add china 203.14.214.0/24 +add china 203.14.231.0/24 +add china 203.14.246.0/24 +add china 203.15.0.0/20 +add china 203.15.20.0/23 +add china 203.15.22.0/24 +add china 203.15.87.0/24 +add china 203.15.88.0/23 +add china 203.15.105.0/24 +add china 203.15.112.0/21 +add china 203.15.130.0/23 +add china 203.15.149.0/24 +add china 203.15.151.0/24 +add china 203.15.156.0/22 +add china 203.15.174.0/24 +add china 203.15.227.0/24 +add china 203.15.232.0/21 +add china 203.15.240.0/23 +add china 203.15.246.0/24 +add china 203.16.10.0/24 +add china 203.16.12.0/23 +add china 203.16.16.0/21 +add china 203.16.27.0/24 +add china 203.16.38.0/24 +add china 203.16.49.0/24 +add china 203.16.50.0/23 +add china 203.16.58.0/24 +add china 203.16.63.0/24 +add china 203.16.133.0/24 +add china 203.16.161.0/24 +add china 203.16.162.0/24 +add china 203.16.186.0/23 +add china 203.16.228.0/24 +add china 203.16.238.0/24 +add china 203.16.240.0/24 +add china 203.16.245.0/24 +add china 203.17.2.0/24 +add china 203.17.18.0/24 +add china 203.17.28.0/24 +add china 203.17.39.0/24 +add china 203.17.56.0/24 +add china 203.17.74.0/23 +add china 203.17.88.0/23 +add china 203.17.136.0/24 +add china 203.17.164.0/24 +add china 203.17.187.0/24 +add china 203.17.190.0/23 +add china 203.17.231.0/24 +add china 203.17.233.0/24 +add china 203.17.248.0/23 +add china 203.17.255.0/24 +add china 203.18.2.0/23 +add china 203.18.4.0/24 +add china 203.18.7.0/24 +add china 203.18.31.0/24 +add china 203.18.37.0/24 +add china 203.18.48.0/23 +add china 203.18.52.0/24 +add china 203.18.72.0/22 +add china 203.18.80.0/23 +add china 203.18.87.0/24 +add china 203.18.100.0/23 +add china 203.18.105.0/24 +add china 203.18.107.0/24 +add china 203.18.110.0/24 +add china 203.18.129.0/24 +add china 203.18.131.0/24 +add china 203.18.132.0/23 +add china 203.18.144.0/24 +add china 203.18.153.0/24 +add china 203.18.199.0/24 +add china 203.18.208.0/24 +add china 203.18.211.0/24 +add china 203.18.215.0/24 +add china 203.19.1.0/24 +add china 203.19.18.0/24 +add china 203.19.24.0/24 +add china 203.19.30.0/24 +add china 203.19.32.0/21 +add china 203.19.41.0/24 +add china 203.19.44.0/23 +add china 203.19.46.0/24 +add china 203.19.58.0/24 +add china 203.19.60.0/23 +add china 203.19.64.0/24 +add china 203.19.68.0/24 +add china 203.19.72.0/24 +add china 203.19.101.0/24 +add china 203.19.111.0/24 +add china 203.19.131.0/24 +add china 203.19.133.0/24 +add china 203.19.144.0/24 +add china 203.19.147.0/24 +add china 203.19.149.0/24 +add china 203.19.156.0/24 +add china 203.19.176.0/24 +add china 203.19.178.0/23 +add china 203.19.208.0/24 +add china 203.19.228.0/22 +add china 203.19.233.0/24 +add china 203.19.242.0/24 +add china 203.19.248.0/23 +add china 203.19.255.0/24 +add china 203.20.17.0/24 +add china 203.20.40.0/23 +add china 203.20.44.0/24 +add china 203.20.48.0/24 +add china 203.20.61.0/24 +add china 203.20.65.0/24 +add china 203.20.84.0/23 +add china 203.20.89.0/24 +add china 203.20.106.0/23 +add china 203.20.115.0/24 +add china 203.20.117.0/24 +add china 203.20.118.0/23 +add china 203.20.122.0/24 +add china 203.20.126.0/23 +add china 203.20.135.0/24 +add china 203.20.136.0/21 +add china 203.20.150.0/24 +add china 203.20.230.0/24 +add china 203.20.232.0/24 +add china 203.20.236.0/24 +add china 203.21.0.0/23 +add china 203.21.2.0/24 +add china 203.21.8.0/24 +add china 203.21.10.0/24 +add china 203.21.18.0/24 +add china 203.21.33.0/24 +add china 203.21.34.0/24 +add china 203.21.41.0/24 +add china 203.21.44.0/24 +add china 203.21.68.0/24 +add china 203.21.82.0/24 +add china 203.21.96.0/22 +add china 203.21.124.0/24 +add china 203.21.136.0/23 +add china 203.21.145.0/24 +add china 203.21.206.0/24 +add china 203.22.24.0/24 +add china 203.22.28.0/23 +add china 203.22.31.0/24 +add china 203.22.68.0/24 +add china 203.22.76.0/24 +add china 203.22.78.0/24 +add china 203.22.84.0/24 +add china 203.22.87.0/24 +add china 203.22.92.0/22 +add china 203.22.99.0/24 +add china 203.22.106.0/24 +add china 203.22.122.0/23 +add china 203.22.131.0/24 +add china 203.22.163.0/24 +add china 203.22.166.0/24 +add china 203.22.170.0/24 +add china 203.22.176.0/21 +add china 203.22.194.0/24 +add china 203.22.242.0/23 +add china 203.22.245.0/24 +add china 203.22.246.0/24 +add china 203.22.252.0/23 +add china 203.23.0.0/24 +add china 203.23.47.0/24 +add china 203.23.61.0/24 +add china 203.23.62.0/23 +add china 203.23.73.0/24 +add china 203.23.85.0/24 +add china 203.23.92.0/22 +add china 203.23.98.0/24 +add china 203.23.107.0/24 +add china 203.23.112.0/24 +add china 203.23.130.0/24 +add china 203.23.140.0/23 +add china 203.23.172.0/24 +add china 203.23.182.0/24 +add china 203.23.186.0/23 +add china 203.23.192.0/24 +add china 203.23.197.0/24 +add china 203.23.198.0/24 +add china 203.23.204.0/22 +add china 203.23.224.0/24 +add china 203.23.226.0/23 +add china 203.23.228.0/22 +add china 203.23.249.0/24 +add china 203.23.251.0/24 +add china 203.24.13.0/24 +add china 203.24.18.0/24 +add china 203.24.27.0/24 +add china 203.24.43.0/24 +add china 203.24.56.0/24 +add china 203.24.58.0/24 +add china 203.24.67.0/24 +add china 203.24.74.0/24 +add china 203.24.79.0/24 +add china 203.24.80.0/23 +add china 203.24.84.0/23 +add china 203.24.86.0/24 +add china 203.24.90.0/24 +add china 203.24.111.0/24 +add china 203.24.112.0/24 +add china 203.24.116.0/24 +add china 203.24.122.0/23 +add china 203.24.145.0/24 +add china 203.24.152.0/23 +add china 203.24.157.0/24 +add china 203.24.161.0/24 +add china 203.24.167.0/24 +add china 203.24.186.0/23 +add china 203.24.199.0/24 +add china 203.24.202.0/24 +add china 203.24.212.0/23 +add china 203.24.217.0/24 +add china 203.24.219.0/24 +add china 203.24.244.0/24 +add china 203.25.19.0/24 +add china 203.25.20.0/23 +add china 203.25.46.0/24 +add china 203.25.48.0/21 +add china 203.25.64.0/23 +add china 203.25.91.0/24 +add china 203.25.99.0/24 +add china 203.25.100.0/24 +add china 203.25.106.0/24 +add china 203.25.131.0/24 +add china 203.25.135.0/24 +add china 203.25.138.0/24 +add china 203.25.147.0/24 +add china 203.25.153.0/24 +add china 203.25.154.0/23 +add china 203.25.164.0/24 +add china 203.25.166.0/24 +add china 203.25.174.0/23 +add china 203.25.180.0/24 +add china 203.25.182.0/24 +add china 203.25.191.0/24 +add china 203.25.199.0/24 +add china 203.25.200.0/24 +add china 203.25.202.0/23 +add china 203.25.208.0/20 +add china 203.25.229.0/24 +add china 203.25.235.0/24 +add china 203.25.236.0/24 +add china 203.25.242.0/24 +add china 203.26.12.0/24 +add china 203.26.34.0/24 +add china 203.26.49.0/24 +add china 203.26.50.0/24 +add china 203.26.55.0/24 +add china 203.26.56.0/23 +add china 203.26.60.0/24 +add china 203.26.65.0/24 +add china 203.26.68.0/24 +add china 203.26.76.0/24 +add china 203.26.80.0/24 +add china 203.26.84.0/24 +add china 203.26.97.0/24 +add china 203.26.102.0/23 +add china 203.26.115.0/24 +add china 203.26.116.0/24 +add china 203.26.129.0/24 +add china 203.26.143.0/24 +add china 203.26.144.0/24 +add china 203.26.148.0/23 +add china 203.26.154.0/24 +add china 203.26.158.0/23 +add china 203.26.161.0/24 +add china 203.26.170.0/24 +add china 203.26.173.0/24 +add china 203.26.176.0/24 +add china 203.26.185.0/24 +add china 203.26.202.0/23 +add china 203.26.210.0/24 +add china 203.26.214.0/24 +add china 203.26.222.0/24 +add china 203.26.224.0/24 +add china 203.26.228.0/24 +add china 203.26.232.0/24 +add china 203.27.0.0/24 +add china 203.27.10.0/24 +add china 203.27.15.0/24 +add china 203.27.16.0/24 +add china 203.27.20.0/24 +add china 203.27.22.0/23 +add china 203.27.40.0/24 +add china 203.27.45.0/24 +add china 203.27.53.0/24 +add china 203.27.65.0/24 +add china 203.27.66.0/24 +add china 203.27.81.0/24 +add china 203.27.88.0/24 +add china 203.27.102.0/24 +add china 203.27.109.0/24 +add china 203.27.117.0/24 +add china 203.27.121.0/24 +add china 203.27.122.0/23 +add china 203.27.125.0/24 +add china 203.27.200.0/24 +add china 203.27.202.0/24 +add china 203.27.233.0/24 +add china 203.27.241.0/24 +add china 203.27.250.0/24 +add china 203.28.10.0/24 +add china 203.28.12.0/24 +add china 203.28.33.0/24 +add china 203.28.34.0/23 +add china 203.28.43.0/24 +add china 203.28.44.0/24 +add china 203.28.54.0/24 +add china 203.28.56.0/24 +add china 203.28.73.0/24 +add china 203.28.74.0/24 +add china 203.28.76.0/24 +add china 203.28.86.0/24 +add china 203.28.88.0/24 +add china 203.28.112.0/24 +add china 203.28.131.0/24 +add china 203.28.136.0/24 +add china 203.28.140.0/24 +add china 203.28.145.0/24 +add china 203.28.165.0/24 +add china 203.28.169.0/24 +add china 203.28.170.0/24 +add china 203.28.178.0/23 +add china 203.28.185.0/24 +add china 203.28.187.0/24 +add china 203.28.196.0/24 +add china 203.28.226.0/23 +add china 203.28.239.0/24 +add china 203.29.2.0/24 +add china 203.29.8.0/23 +add china 203.29.13.0/24 +add china 203.29.14.0/24 +add china 203.29.28.0/24 +add china 203.29.46.0/24 +add china 203.29.57.0/24 +add china 203.29.61.0/24 +add china 203.29.63.0/24 +add china 203.29.69.0/24 +add china 203.29.73.0/24 +add china 203.29.81.0/24 +add china 203.29.90.0/24 +add china 203.29.95.0/24 +add china 203.29.100.0/24 +add china 203.29.103.0/24 +add china 203.29.112.0/24 +add china 203.29.120.0/22 +add china 203.29.182.0/23 +add china 203.29.187.0/24 +add china 203.29.189.0/24 +add china 203.29.190.0/24 +add china 203.29.205.0/24 +add china 203.29.210.0/24 +add china 203.29.217.0/24 +add china 203.29.227.0/24 +add china 203.29.231.0/24 +add china 203.29.233.0/24 +add china 203.29.234.0/24 +add china 203.29.248.0/24 +add china 203.29.254.0/23 +add china 203.30.16.0/23 +add china 203.30.25.0/24 +add china 203.30.27.0/24 +add china 203.30.29.0/24 +add china 203.30.66.0/24 +add china 203.30.81.0/24 +add china 203.30.87.0/24 +add china 203.30.111.0/24 +add china 203.30.121.0/24 +add china 203.30.123.0/24 +add china 203.30.152.0/24 +add china 203.30.156.0/24 +add china 203.30.162.0/24 +add china 203.30.173.0/24 +add china 203.30.175.0/24 +add china 203.30.187.0/24 +add china 203.30.194.0/24 +add china 203.30.217.0/24 +add china 203.30.220.0/24 +add china 203.30.222.0/24 +add china 203.30.232.0/23 +add china 203.30.235.0/24 +add china 203.30.240.0/23 +add china 203.30.246.0/24 +add china 203.30.250.0/23 +add china 203.31.45.0/24 +add china 203.31.46.0/24 +add china 203.31.49.0/24 +add china 203.31.51.0/24 +add china 203.31.54.0/23 +add china 203.31.69.0/24 +add china 203.31.72.0/24 +add china 203.31.80.0/24 +add china 203.31.85.0/24 +add china 203.31.97.0/24 +add china 203.31.105.0/24 +add china 203.31.106.0/24 +add china 203.31.108.0/23 +add china 203.31.124.0/24 +add china 203.31.162.0/24 +add china 203.31.174.0/24 +add china 203.31.177.0/24 +add china 203.31.181.0/24 +add china 203.31.187.0/24 +add china 203.31.189.0/24 +add china 203.31.204.0/24 +add china 203.31.220.0/24 +add china 203.31.222.0/23 +add china 203.31.225.0/24 +add china 203.31.229.0/24 +add china 203.31.248.0/23 +add china 203.31.253.0/24 +add china 203.32.20.0/24 +add china 203.32.48.0/23 +add china 203.32.56.0/24 +add china 203.32.60.0/24 +add china 203.32.62.0/24 +add china 203.32.68.0/23 +add china 203.32.76.0/24 +add china 203.32.81.0/24 +add china 203.32.84.0/23 +add china 203.32.95.0/24 +add china 203.32.102.0/24 +add china 203.32.105.0/24 +add china 203.32.130.0/24 +add china 203.32.133.0/24 +add china 203.32.140.0/24 +add china 203.32.152.0/24 +add china 203.32.186.0/23 +add china 203.32.192.0/24 +add china 203.32.196.0/24 +add china 203.32.203.0/24 +add china 203.32.204.0/23 +add china 203.32.212.0/24 +add china 203.33.4.0/24 +add china 203.33.7.0/24 +add china 203.33.8.0/21 +add china 203.33.21.0/24 +add china 203.33.26.0/24 +add china 203.33.32.0/24 +add china 203.33.63.0/24 +add china 203.33.64.0/24 +add china 203.33.67.0/24 +add china 203.33.68.0/24 +add china 203.33.73.0/24 +add china 203.33.79.0/24 +add china 203.33.100.0/24 +add china 203.33.122.0/24 +add china 203.33.129.0/24 +add china 203.33.131.0/24 +add china 203.33.145.0/24 +add china 203.33.156.0/24 +add china 203.33.158.0/23 +add china 203.33.174.0/24 +add china 203.33.185.0/24 +add china 203.33.200.0/24 +add china 203.33.202.0/23 +add china 203.33.204.0/24 +add china 203.33.206.0/23 +add china 203.33.214.0/23 +add china 203.33.224.0/23 +add china 203.33.226.0/24 +add china 203.33.233.0/24 +add china 203.33.243.0/24 +add china 203.33.250.0/24 +add china 203.34.4.0/24 +add china 203.34.21.0/24 +add china 203.34.27.0/24 +add china 203.34.39.0/24 +add china 203.34.48.0/23 +add china 203.34.54.0/24 +add china 203.34.56.0/23 +add china 203.34.67.0/24 +add china 203.34.69.0/24 +add china 203.34.76.0/24 +add china 203.34.92.0/24 +add china 203.34.106.0/24 +add china 203.34.113.0/24 +add china 203.34.147.0/24 +add china 203.34.150.0/24 +add china 203.34.152.0/23 +add china 203.34.161.0/24 +add china 203.34.162.0/24 +add china 203.34.187.0/24 +add china 203.34.192.0/21 +add china 203.34.204.0/22 +add china 203.34.232.0/24 +add china 203.34.240.0/24 +add china 203.34.242.0/24 +add china 203.34.245.0/24 +add china 203.34.251.0/24 +add china 203.55.2.0/23 +add china 203.55.4.0/24 +add china 203.55.10.0/24 +add china 203.55.13.0/24 +add china 203.55.22.0/24 +add china 203.55.30.0/24 +add china 203.55.93.0/24 +add china 203.55.101.0/24 +add china 203.55.109.0/24 +add china 203.55.110.0/24 +add china 203.55.116.0/23 +add china 203.55.119.0/24 +add china 203.55.128.0/23 +add china 203.55.146.0/23 +add china 203.55.192.0/24 +add china 203.55.196.0/24 +add china 203.55.218.0/23 +add china 203.55.221.0/24 +add china 203.55.224.0/24 +add china 203.56.1.0/24 +add china 203.56.4.0/24 +add china 203.56.12.0/24 +add china 203.56.24.0/24 +add china 203.56.38.0/24 +add china 203.56.40.0/24 +add china 203.56.46.0/24 +add china 203.56.48.0/21 +add china 203.56.68.0/23 +add china 203.56.82.0/23 +add china 203.56.84.0/23 +add china 203.56.95.0/24 +add china 203.56.110.0/24 +add china 203.56.121.0/24 +add china 203.56.161.0/24 +add china 203.56.169.0/24 +add china 203.56.172.0/23 +add china 203.56.175.0/24 +add china 203.56.183.0/24 +add china 203.56.185.0/24 +add china 203.56.187.0/24 +add china 203.56.192.0/24 +add china 203.56.198.0/24 +add china 203.56.201.0/24 +add china 203.56.208.0/23 +add china 203.56.210.0/24 +add china 203.56.214.0/24 +add china 203.56.216.0/24 +add china 203.56.227.0/24 +add china 203.56.228.0/24 +add china 203.56.231.0/24 +add china 203.56.232.0/24 +add china 203.56.240.0/24 +add china 203.56.252.0/24 +add china 203.56.254.0/24 +add china 203.57.5.0/24 +add china 203.57.6.0/24 +add china 203.57.12.0/23 +add china 203.57.28.0/24 +add china 203.57.39.0/24 +add china 203.57.46.0/24 +add china 203.57.58.0/24 +add china 203.57.61.0/24 +add china 203.57.66.0/24 +add china 203.57.69.0/24 +add china 203.57.70.0/23 +add china 203.57.73.0/24 +add china 203.57.90.0/24 +add china 203.57.101.0/24 +add china 203.57.109.0/24 +add china 203.57.123.0/24 +add china 203.57.157.0/24 +add china 203.57.200.0/24 +add china 203.57.202.0/24 +add china 203.57.206.0/24 +add china 203.57.222.0/24 +add china 203.57.224.0/20 +add china 203.57.246.0/23 +add china 203.57.249.0/24 +add china 203.57.253.0/24 +add china 203.57.254.0/23 +add china 203.62.2.0/24 +add china 203.62.131.0/24 +add china 203.62.139.0/24 +add china 203.62.161.0/24 +add china 203.62.197.0/24 +add china 203.62.228.0/22 +add china 203.62.234.0/24 +add china 203.62.246.0/24 +add china 203.65.240.0/22 +add china 203.76.160.0/22 +add china 203.76.168.0/22 +add china 203.76.208.0/21 +add china 203.76.216.0/22 +add china 203.76.240.0/21 +add china 203.77.180.0/22 +add china 203.78.48.0/20 +add china 203.78.156.0/22 +add china 203.79.0.0/20 +add china 203.79.32.0/20 +add china 203.80.4.0/23 +add china 203.80.32.0/20 +add china 203.80.57.0/24 +add china 203.80.129.0/24 +add china 203.80.132.0/22 +add china 203.80.136.0/21 +add china 203.80.144.0/20 +add china 203.81.0.0/21 +add china 203.81.16.0/20 +add china 203.81.244.0/22 +add china 203.82.0.0/23 +add china 203.82.16.0/21 +add china 203.82.112.0/20 +add china 203.82.224.0/20 +add china 203.83.0.0/22 +add china 203.83.8.0/21 +add china 203.83.56.0/21 +add china 203.83.224.0/20 +add china 203.86.0.0/17 +add china 203.86.250.0/24 +add china 203.86.254.0/23 +add china 203.88.32.0/19 +add china 203.88.192.0/19 +add china 203.89.0.0/22 +add china 203.89.8.0/21 +add china 203.89.133.0/24 +add china 203.89.136.0/22 +add china 203.89.144.0/24 +add china 203.90.0.0/22 +add china 203.90.8.0/21 +add china 203.90.128.0/18 +add china 203.90.192.0/19 +add china 203.91.1.0/24 +add china 203.91.32.0/19 +add china 203.91.96.0/20 +add china 203.91.120.0/21 +add china 203.92.0.0/22 +add china 203.92.6.0/24 +add china 203.92.160.0/19 +add china 203.93.0.0/16 +add china 203.94.0.0/19 +add china 203.95.0.0/21 +add china 203.95.96.0/19 +add china 203.95.128.0/18 +add china 203.95.200.0/21 +add china 203.95.208.0/22 +add china 203.95.224.0/19 +add china 203.99.8.0/21 +add china 203.99.16.0/20 +add china 203.99.80.0/20 +add china 203.100.32.0/20 +add china 203.100.48.0/21 +add china 203.100.58.0/24 +add china 203.100.60.0/24 +add china 203.100.63.0/24 +add china 203.100.80.0/20 +add china 203.100.96.0/19 +add china 203.100.192.0/20 +add china 203.104.32.0/20 +add china 203.105.96.0/19 +add china 203.105.128.0/19 +add china 203.107.0.0/17 +add china 203.110.160.0/19 +add china 203.110.208.0/20 +add china 203.110.232.0/23 +add china 203.110.234.0/24 +add china 203.114.80.0/20 +add china 203.114.244.0/22 +add china 203.118.192.0/19 +add china 203.118.241.0/24 +add china 203.118.248.0/22 +add china 203.119.24.0/21 +add china 203.119.32.0/22 +add china 203.119.80.0/22 +add china 203.119.85.0/24 +add china 203.119.113.0/24 +add china 203.119.114.0/23 +add china 203.119.116.0/22 +add china 203.119.120.0/21 +add china 203.119.128.0/17 +add china 203.123.58.0/24 +add china 203.128.32.0/19 +add china 203.128.96.0/19 +add china 203.128.128.0/24 +add china 203.128.224.0/21 +add china 203.129.8.0/21 +add china 203.130.32.0/19 +add china 203.132.32.0/19 +add china 203.134.240.0/21 +add china 203.135.96.0/19 +add china 203.135.160.0/20 +add china 203.142.12.0/23 +add china 203.142.219.0/24 +add china 203.142.224.0/19 +add china 203.144.96.0/19 +add china 203.145.0.0/19 +add china 203.148.0.0/18 +add china 203.148.64.0/20 +add china 203.148.80.0/22 +add china 203.148.86.0/23 +add china 203.149.92.0/22 +add china 203.152.64.0/19 +add china 203.152.128.0/19 +add china 203.153.0.0/22 +add china 203.156.192.0/18 +add china 203.158.16.0/21 +add china 203.160.52.0/22 +add china 203.160.104.0/21 +add china 203.160.129.0/24 +add china 203.160.192.0/19 +add china 203.161.0.0/22 +add china 203.161.180.0/24 +add china 203.161.183.0/24 +add china 203.161.192.0/19 +add china 203.166.160.0/19 +add china 203.167.28.0/22 +add china 203.168.0.0/19 +add china 203.170.58.0/23 +add china 203.171.0.0/22 +add china 203.171.208.0/24 +add china 203.171.224.0/20 +add china 203.174.4.0/24 +add china 203.174.6.0/23 +add china 203.174.96.0/19 +add china 203.175.128.0/19 +add china 203.175.192.0/18 +add china 203.176.0.0/18 +add china 203.176.64.0/19 +add china 203.176.168.0/21 +add china 203.184.80.0/20 +add china 203.185.189.0/24 +add china 203.187.160.0/19 +add china 203.189.0.0/23 +add china 203.189.6.0/23 +add china 203.189.112.0/22 +add china 203.189.192.0/19 +add china 203.189.232.0/21 +add china 203.189.240.0/22 +add china 203.190.96.0/20 +add china 203.190.249.0/24 +add china 203.191.0.0/23 +add china 203.191.2.0/24 +add china 203.191.5.0/24 +add china 203.191.7.0/24 +add china 203.191.16.0/20 +add china 203.191.64.0/18 +add china 203.191.133.0/24 +add china 203.191.144.0/20 +add china 203.192.0.0/19 +add china 203.193.224.0/19 +add china 203.194.120.0/21 +add china 203.195.64.0/19 +add china 203.195.112.0/21 +add china 203.195.128.0/17 +add china 203.196.0.0/20 +add china 203.196.28.0/22 +add china 203.201.181.0/24 +add china 203.201.182.0/24 +add china 203.202.236.0/22 +add china 203.205.64.0/19 +add china 203.205.128.0/17 +add china 203.207.64.0/18 +add china 203.207.128.0/17 +add china 203.208.0.0/20 +add china 203.208.16.0/22 +add china 203.208.32.0/19 +add china 203.209.224.0/19 +add china 203.212.0.0/20 +add china 203.212.80.0/20 +add china 203.215.232.0/21 +add china 203.217.164.0/22 +add china 203.222.192.0/20 +add china 203.223.0.0/20 +add china 203.223.16.0/21 +add china 204.55.160.0/24 +add china 204.74.96.0/24 +add china 204.114.176.0/23 +add china 206.219.44.0/23 +add china 206.219.50.0/23 +add china 206.219.52.0/23 +add china 210.2.0.0/19 +add china 210.5.0.0/19 +add china 210.5.56.0/21 +add china 210.5.128.0/19 +add china 210.7.56.0/21 +add china 210.12.0.0/15 +add china 210.14.64.0/19 +add china 210.14.112.0/20 +add china 210.14.128.0/17 +add china 210.15.0.0/17 +add china 210.15.128.0/18 +add china 210.16.104.0/22 +add china 210.16.128.0/18 +add china 210.21.0.0/16 +add china 210.22.0.0/16 +add china 210.23.32.0/19 +add china 210.25.0.0/16 +add china 210.26.0.0/15 +add china 210.28.0.0/14 +add china 210.32.0.0/12 +add china 210.51.0.0/16 +add china 210.52.0.0/15 +add china 210.56.192.0/19 +add china 210.72.0.0/14 +add china 210.76.0.0/15 +add china 210.78.0.0/16 +add china 210.79.64.0/18 +add china 210.79.224.0/19 +add china 210.82.0.0/15 +add china 210.87.128.0/18 +add china 210.185.192.0/18 +add china 210.192.96.0/19 +add china 211.64.0.0/13 +add china 211.80.0.0/12 +add china 211.96.0.0/13 +add china 211.136.0.0/13 +add china 211.144.0.0/12 +add china 211.160.0.0/13 +add china 216.250.108.0/22 +add china 218.0.0.0/11 +add china 218.56.0.0/13 +add china 218.64.0.0/11 +add china 218.96.0.0/14 +add china 218.100.88.0/21 +add china 218.100.96.0/19 +add china 218.100.128.0/17 +add china 218.104.0.0/14 +add china 218.108.0.0/15 +add china 218.185.192.0/19 +add china 218.185.240.0/21 +add china 218.192.0.0/12 +add china 218.240.0.0/13 +add china 218.249.0.0/16 +add china 219.72.0.0/16 +add china 219.82.0.0/16 +add china 219.83.128.0/17 +add china 219.90.68.0/22 +add china 219.90.72.0/21 +add china 219.128.0.0/11 +add china 219.216.0.0/13 +add china 219.224.0.0/12 +add china 219.242.0.0/15 +add china 219.244.0.0/14 +add china 220.101.192.0/18 +add china 220.112.0.0/14 +add china 220.152.128.0/17 +add china 220.154.0.0/15 +add china 220.158.240.0/22 +add china 220.160.0.0/11 +add china 220.192.0.0/12 +add china 220.231.0.0/18 +add china 220.231.128.0/17 +add china 220.232.64.0/18 +add china 220.234.0.0/16 +add china 220.242.0.0/15 +add china 220.247.136.0/21 +add china 220.248.0.0/14 +add china 220.252.0.0/16 +add china 221.0.0.0/13 +add china 221.8.0.0/14 +add china 221.12.0.0/17 +add china 221.12.128.0/18 +add china 221.13.0.0/16 +add china 221.14.0.0/15 +add china 221.122.0.0/15 +add china 221.128.128.0/17 +add china 221.129.0.0/16 +add china 221.130.0.0/15 +add china 221.133.224.0/19 +add china 221.136.0.0/15 +add china 221.172.0.0/14 +add china 221.176.0.0/13 +add china 221.192.0.0/14 +add china 221.196.0.0/15 +add china 221.198.0.0/16 +add china 221.199.0.0/17 +add china 221.199.128.0/18 +add china 221.199.192.0/20 +add china 221.199.224.0/19 +add china 221.200.0.0/13 +add china 221.208.0.0/12 +add china 221.224.0.0/12 +add china 222.16.0.0/12 +add china 222.32.0.0/11 +add china 222.64.0.0/11 +add china 222.125.0.0/16 +add china 222.126.128.0/17 +add china 222.128.0.0/12 +add china 222.160.0.0/14 +add china 222.168.0.0/13 +add china 222.176.0.0/12 +add china 222.192.0.0/11 +add china 222.240.0.0/13 +add china 222.248.0.0/15 +add china 223.0.0.0/12 +add china 223.20.0.0/15 +add china 223.27.184.0/22 +add china 223.29.208.0/22 +add china 223.29.252.0/22 +add china 223.64.0.0/11 +add china 223.96.0.0/12 +add china 223.112.0.0/14 +add china 223.116.0.0/15 +add china 223.120.0.0/13 +add china 223.128.0.0/15 +add china 223.130.8.0/22 +add china 223.144.0.0/12 +add china 223.160.0.0/14 +add china 223.166.0.0/15 +add china 223.192.0.0/15 +add china 223.198.0.0/15 +add china 223.201.0.0/16 +add china 223.202.0.0/15 +add china 223.208.0.0/13 +add china 223.220.0.0/15 +add china 223.223.176.0/20 +add china 223.223.192.0/20 +add china 223.240.0.0/13 +add china 223.248.0.0/14 +add china 223.252.128.0/17 +add china 223.254.0.0/16 +add china 223.255.0.0/17 +add china 223.255.236.0/22 +add china 223.255.252.0/23 diff --git a/package/lean/ipset-lists/files/etc/ipset/local b/package/lean/ipset-lists/files/etc/ipset/local new file mode 100644 index 000000000..9c1df02ce --- /dev/null +++ b/package/lean/ipset-lists/files/etc/ipset/local @@ -0,0 +1,6 @@ +create local hash:net family inet hashsize 1024 maxelem 65536 +add local 10.0.0.0/8 +add local 127.0.0.0/8 +add local 172.16.0.0/12 +add local 192.168.0.0/16 +add local 224.0.0.0/3 diff --git a/package/lean/ipset-lists/files/usr/lib/lua/luci/controller/gfwlist.lua b/package/lean/ipset-lists/files/usr/lib/lua/luci/controller/gfwlist.lua new file mode 100644 index 000000000..b06fdbd1a --- /dev/null +++ b/package/lean/ipset-lists/files/usr/lib/lua/luci/controller/gfwlist.lua @@ -0,0 +1,14 @@ +--[[ + Customize /etc/gfwlist.list content + Copyright (c) 2015 Justin Liu + Author: Justin Liu + https://github.com/rssnsj/network-feeds +]]-- + +module("luci.controller.gfwlist", package.seeall) + +function index() + local page + page = entry({"admin", "services", "gfwlist"}, cbi("gfwlist"), _("Domain Lists")) + page.dependent = true +end diff --git a/package/lean/ipset-lists/files/usr/lib/lua/luci/i18n/gfwlist.zh-cn.lmo b/package/lean/ipset-lists/files/usr/lib/lua/luci/i18n/gfwlist.zh-cn.lmo new file mode 100644 index 000000000..9bfab206c Binary files /dev/null and b/package/lean/ipset-lists/files/usr/lib/lua/luci/i18n/gfwlist.zh-cn.lmo differ diff --git a/package/lean/ipset-lists/files/usr/lib/lua/luci/model/cbi/gfwlist.lua b/package/lean/ipset-lists/files/usr/lib/lua/luci/model/cbi/gfwlist.lua new file mode 100644 index 000000000..db84754ed --- /dev/null +++ b/package/lean/ipset-lists/files/usr/lib/lua/luci/model/cbi/gfwlist.lua @@ -0,0 +1,33 @@ +--[[ + Customize firewall-banned domain lists - /etc/gfwlist/ + Copyright (c) 2015 Justin Liu + Author: Justin Liu + https://github.com/rssnsj/network-feeds +]]-- + +local fs = require "nixio.fs" + +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 = SimpleForm("gfwlist", translate("Domain Lists Settings")) + +for e in fs.dir("/etc/gfwlist") do + glist = m:field(TextValue, e, e, nil) + glist.rmempty = false + glist.rows = 12 + + function glist.cfgvalue() + return nixio.fs.readfile("/etc/gfwlist/" .. e) or "" + end + function glist.write(self, section, value) + sync_value_to_file(value, "/etc/gfwlist/" .. e) + end +end + +return m diff --git a/package/lean/ipset-lists/po/zh_CN/gfwlist.po b/package/lean/ipset-lists/po/zh_CN/gfwlist.po new file mode 100644 index 000000000..7ce2c1e8d --- /dev/null +++ b/package/lean/ipset-lists/po/zh_CN/gfwlist.po @@ -0,0 +1,9 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "Domain Lists Settings" +msgstr "鍩熷悕鍒楄〃璁剧疆" + +msgid "Domain Lists" +msgstr "鍩熷悕鍒楄〃" + diff --git a/package/lean/ipset-lists/tools/Makefile b/package/lean/ipset-lists/tools/Makefile new file mode 100644 index 000000000..f415b2052 --- /dev/null +++ b/package/lean/ipset-lists/tools/Makefile @@ -0,0 +1,3 @@ +update: + ./gen-china-routes.sh > ../files/etc/ipset/china + ./gen-gfwlist.sh > ../files/etc/gfwlist/china-banned diff --git a/package/lean/ipset-lists/tools/base-gfwlist.txt b/package/lean/ipset-lists/tools/base-gfwlist.txt new file mode 100644 index 000000000..75277f6c0 --- /dev/null +++ b/package/lean/ipset-lists/tools/base-gfwlist.txt @@ -0,0 +1,2941 @@ +0rz.tw +0to255.com +10musume.com +123rf.com +12bet.com +12vpn.com +141hongkong.com +173ng.com +1984bbs.com +1984bbs.org +1-apple.com.tw +1bao.org +1eew.com +1pondo.tv +2000fun.com +2008xianzhang.info +21andy.com +247realmedia.com +24smile.org +2-hand.info +2mdn.net +2shared.com +301works.org +315lz.com +32red.com +365singles.com.ar +36rain.com +4bluestones.biz +4chan.org +4pppc.gov.tw +4shared.com +4sq.com +51.ca +5i01.com +5maodang.com +64tianwang.com +64wiki.com +666kb.com +6park.com +7capture.com +881903.com +888.com +89-64.org +9001700.com +91porn.com +921.gov.tw +92ccav.com +9bis.com +9bis.net +9city.me +a5.com.ru +abc.pp.ru +abitno.linpie.com +ablwang.com +aboluowang.com +aboutgfw.com +acgkj.com +ac.jiruan.net +ac.playstation.net +actimes.com.au +aculo.us +ad1.nownews.com +addictedtocoffee.de +ads.backchina.com +adultfriendfinder.com +adultkeep.net +advanscene.com +advertfan.com +aec.gov.tw +aenhancers.com +af.mil +aftygh.gov.tw +aide.gov.tw +aiph.net +aisex.com +ait.org.tw +aiweiweiblog.com +aiweiwei.com +ajaxplorer.info +akamaihd.net +akiba-online.com +alabout.com +alasbarricadas.org +alexlur.org +aliengu.com +aliyun.com +alkasir.com +allaboutalpha.com +allgirlsallowed.org +alliance.org.hk +allinfa.com +allinfo.com +allmovie.com +allonlinux.free.fr +all-that-is-interesting.com +al-qimmah.net +alternate-tools.com +altrec.com +alvinalexander.com +alwaysdata.com +alwaysdata.net +am730.com.hk +amazonaws.com +ameblo.jp +americangreencard.com +amiblockedornot.com +amnesty.org +amnestyusa.org +amoiist.com +amzs.me +analyze-v.com +anchorfree.com +andfaraway.net +android.com +angularjs.org +animecrazy.net +anobii.com +anontext.com +anonymizer.com +a-normal-day.com +answering-islam.org +anthonycalzadilla.com +anti.anti.cnn.googlepages.com +antidrm.hpg.ig.com.br +antiwave.net +aobo.com.au +aolchannels.aol.com +aomiwang.com +apetube.com +apiary.io +apidocs.linksalpha.com +apigee.com +api.linksalpha.com +api.proxlet.com +api.supertweet.net +app.heywire.com +app.hkatvnews.com +appledaily.com +appledaily.com.tw +apps.hloli.net +appspot.com +archive.is +archive.org +arctosia.com +areca-backup.org +army.mil +arte.gov.tw +art-or-porn.com +artsy.net +asahichinese.com +asdfg.jp +asiafriendfinder.com +asiaharvest.org +asianews.it +asianwomensfilm.de +askstudent.com +askynz.net +assembla.com +astonmartinnews.com +atchinese.com +atc.org.au +atgfw.org +atj.org.tw +atlaspost.com +atnext.com +autoproxy.org +avaaz.org +avdb.in +avidemux.org +avoision.com +awardwinningfjords.com +axureformac.com +babynet.com.hk +backchina.com +backpackers.com.tw +badassjs.com +badoo.com +baidu.jp +baixing.me +bannedbook.org +barnabu.co.uk +basetimesheightdividedby2.com +bayvoice.net +bbcchinese.com +bbc.com +bbc.co.uk +bbci.co.uk +bbcimg.co.uk +bbc.in +bbg.gov +bbs2.newsgroup.la +bbs.ecstart.com +bbsfeed.com +bbs.kimy.com.tw +bbsland.com +bbs.morbell.com +bbs.mychat.to +bbs.newsgroup.la +bbs.ozchinese.com +bbs.qmzdd.com +bbs.sina.com +bbs.skykiwi.com +bbs.tuitui.info +bb.ttv.com.tw +bcc.com.tw +bcchinese.net +bdhr.gov.tw +bd.zhe.la +bebo.com +beeg.com +beijing1989.com +beijingspring.com +benjaminste.in +berlintwitterwall.com +bestforchina.org +bestvpnservice.com +bet365.com +beta.iset.com.tw +beta.usejump.com +betfair.com +bettween.com +betvictor.com +bewww.net +beyondfirewall.com +bfnn.org +biantailajiao.com +biantailajiao.in +bigfools.com +bignews.org +bigsound.org +bill2-software.com +billywr.com +bill.zhong.pp.ru +bipic.net +bitcointalk.org +bit.ly +bitly.com +bitshare.com +bjzc.org +blinkx.com +blinw.com +blip.tv +blockcn.com +blog.birdhouseapp.com +blog.bitly.com +blogblog.com +blog.boxcar.io +blogcatalog.com +blog.davidziegler.net +blog.dayoneapp.com +blog.de +blog.dribbble.com +blog.exblog.co.jp +blog.expofutures.com +blog.fizzik.com +blog.foolsmountain.com +blogger.com +blog.gowalla.com +blog.hotpotato.com +blog.ifttt.com +blogimg.jp +blog.instagram.com +blog.instapaper.com +blog.iphone-dev.org +blog.istef.info +blog.jackjia.com +blog.joeyrobert.org +blog.kangye.org +blog.kickstarter.com +blog.kl.am +blog.klip.me +blog.lester850.info +blog.lightbox.com +bloglines.com +bloglovin.com +blog.mongodb.org +blog.openinkpot.org +blog.palm.com +blog.path.com +blog.pathtosharepoint.com +blog.pchome.com.tw +blog.pentalogic.net +blog.pikchur.com +blog.pilotmoon.com +blog.redren.com +blog.rockmelt.com +blog.romanandreg.com +blog.s135.com +blogs.icerocket.com +blog.sina.com.tw +blog.sogoo.org +blog.sparrowmailapp.com +blogspot.com +blogspot.co.uk +blogspot.de +blogspot.fr +blogspot.in +blogspot.jp +blogs.tampabay.com +blog.summify.com +blogs.yahoo.co.jp +blog.syx86.cn +blog.syx86.com +blog.taragana.com +blogtd.net +blogtd.org +blog.tiney.com +blog.topify.com +blog.usa.gov +blog.xuite.net +blog.youthwant.com.tw +blog.youxu.info +bloodshed.net +bloomberg.cn +bloomberg.com +bloomberg.de +bloomfortune.com +bmediaasia.com +bnrmetal.com +boardreader.com +bobulate.com +bolin.netfirms.com +bonbonme.com +bonjourlesgeeks.com +boobstagram.com +books.com.tw +bookshelfporn.com +botanwang.com +bot.nu +bowenpress.com +boxunblog.com +boxunclub.com +boxun.com +boxun.tv +bralio.com +branch.com +brandonhutchinson.com +braumeister.org +break.com +breakingtweets.com +briefdream.com +brightcove.com +brightkite.com +brizzly.com +broadbook.com +br.st +brucewang.net +bt95.com +btdigg.org +btrd.net +budaedu.org +bugclub.org +builtwithbootstrap.com +bullogger.com +bullog.org +businesstimes.com.cn +businessweek.com +buugaa.com +buy.yahoo.com.tw +buzzurl.jp +bwbx.io +bwsj.hk +bx.tl +c1522.mooo.com +cacnw.com +cactusvpn.com +cafepress.com +cahr.org.tw +calameo.com +calebelston.com +cams.com +cams.org.sg +canadameet.com +canyu.org +caobian.info +caochangqing.com +cao.im +cari.com.my +catch22.net +catfightpayperview.xxx +catholic.org.hk +catholic.org.tw +cbs.ntu.edu.tw +cc9007.spaces.live.com +ccavtop10.com +ccdtr.org +ccim.org +cclife.org +ccthere.com +cctongbao.com +ccue.ca +ccue.com +cdig.info +cdjp.org +cdnews.com.tw +cdn.printfriendly.com +cdp1998.org +cdp2006.org +cdp.sinica.edu.tw +cdpusa.org +cdpweb.org +cdpwu.org +cdw.com +cecc.gov +cellulo.info +cenci.tk +cenews.eu +centralnation.com +centurys.net +c-est-simple.com +cfhks.org.hk +cftfc.com +cgdepot.org +chandoo.org +change.org +changp.com +chaos.e-spacy.com +chapm25.com +chartbeat.net +chaturbate.com +chccc.gov.tw +chengmingmag.com +chenguangcheng.com +chenpokong.com +chenyehao.spaces.live.com +cherrysave.com +chevronwp7.com +chicagoncmtv.com +china101.com +china21.com +china21.org +china5000.us +chinaaffairs.org +chinaaid.me +chinaaid.net +chinaaid.org +chinaaid.us +chinachange.org +chinachannel.hk +chinacomments.org +chinadigitaltimes.net +chinaeweekly.com +chinafreepress.org +chinagate.com +chinageeks.org +chinagfw.org +chinagreenparty.org +china-green-party.spaces.live.com +chinahush.com +chinainperspective.com +chinainperspective.net +chinainperspective.org +chinainterimgov.org +chinalawandpolicy.com +chinalawtranslate.com +chinamule.com +chinamz.org +chinarightsia.org +chinasocialdemocraticparty.com +chinaso.com +chinasoul.org +chinatimes.com +chinatweeps.com +chinaway.org +china-week.com +chinaworker.info +chinaxchina.com +chinayouth.org.hk +chinayuanmin.org +chinesedailynews.com +chinese.engadget.com +chinese-hermit.net +chinese-memorial.org +chinesen.de +chinesenewsnet.com +chinesepen.org +chinese.rnw.nl +chinese.soifind.com +chinesetalks.net +chinese.wsj.com +chingcheong.com +chn.chosun.com +chrispederick.com +chrispederick.net +christianstudy.com +christiantimes.org.hk +christusrex.org +chrlawyers.hk +chrlcg-hk.org +chromeadblock.com +chrome.com +ch.shvoong.com +chubun.com +chuizi.net +chukuang.gov.tw +circlethebayfortibet.org +citizenlab.org +citizensradio.org +city9x.com +civicparty.hk +civilhrfront.org +civilmedia.tw +cjb.net +ck101.com +classicalguitarblog.net +clb.org.hk +cl.d0z.net +clientsfromhell.net +clipfish.de +cl.ly +cloudfront.net +club.backchina.com +cms.gov +cmule.com +cn2.streetvoice.com +cna.com.tw +cnavista.com.tw +cn.calameo.com +cn.dayabook.com +cnd.org +cn.fmnnow.com +cn.ibtimes.com +cnn.com +cn.news.cnyes.com +cn.streetvoice.com +cn.uncyclopedia.wikia.com +cn.voa.mobi +cochina.org +cocoapods.org +cocoa.zonble.net +code1984.com +codeboxapp.com +codeshare.io +collateralmurder.com +collateralmurder.org +comefromchina.com +comnews.gio.gov.tw +compileheart.com +connectedchina.reuters.com +connect.facebook.net +conoyo.com +contactmagazine.net +contests.twilio.com +conviva.com +cookingtothegoodlife.com +coolaler.com +coolder.com +coolloud.org.tw +corpus4u.org +corumcollege.com +cotweet.com +couchdbwiki.com +coveringweb.com +cp-house.gov.tw +cpj.org +crackle.com +crd-net.org +creaders.net +cromotc.nat.gov.tw +crossthewall.net +csdparty.com +c-spanvideo.org +css.pixnet.in +csuchen.de +cts.com.tw +cubicle17.com +cuhkacs.org +cuihua.org +cuiweiping.net +culture.tw +curvefish.com +cwb.gov.tw +cyanogenmod.org +cyberghost.natado.com +cyberghostvpn.com +cycab.gov.tw +cydia.ifuckgfw.com +cynscribe.com +cytode.us +dabr.co.uk +dabr.me +dabr.mobi +dadazim.com +dadi360.com +dafagood.com +dafahao.com +dailidaili.com +dailymotion.com +dailynews.sina.com +dajiyuan.com +dajiyuan.eu +dajusha.baywords.com +dalailama.com +dalailama.ru +dalailamaworld.com +dalianmeng.org +danke4china.net +danwei.org +daolan.net +dapu-house.gov.tw +darpa.mil +date.fm +davidslog.com +daxa.cn +dayaarmongol.ning.com +daylife.com +ddc.com.tw +deck.ly +default.secureserver.net +delcamp.net +delicious.com +democrats.org +demo.opera-mini.net +derekhsu.homeip.net +de-sci.org +designerol.com +destiny.xfiles.to +deutsche-welle.de +dev102.com +developers.box.net +deviantart.com +deviantart.net +devio.us +devpn.com +dfas.mil +df.gov.tw +diaoyuislands.org +digitalnomadsproject.org +diigo.com +dimitrik.free.fr +dipity.com +directcreative.com +discuss.com.hk +disp.cc +dit-inc.us +dizhidizhi.com +djangosnippets.org +dl.box.net +dl-laby.jp +dl.playstation.net +dlsite.com +dmcdn.net +dmtip.gov.tw +dns2go.com +dnscrypt.org +docstoc.com +dojin.com +dok-forum.net +dolc.de +dollf.com +domain.club.tw +domainhelp.search.com +dongde.com +dongtaiwang.com +dongtaiwang.net +dongyangjing.com +dontfilter.us +dontmovetochina.com +dotheyfolloweachother.com +dotplane.com +dotsub.com +doubleaf.com +doubleclick.net +dougscripts.com +dowei.org +download.syniumsoftware.com +doxygen.org +dphk.org +dpp.org.tw +drewolanoff.com +drgan.net +dropbox.com +dropboxusercontent.com +drsunacademy.com +drtuber.com +dscn.info +dtiblog.com +dtic.mil +dtiserv2.com +duckduckgo.com +duckload.com +duckmylife.com +duihuahrjournal.org +duihua.org +duoweitimes.com +duping.net +duplicati.com +dupola.com +dupola.net +dvorak.org +dw.de +dwnews.com +dwnews.net +dw-world.com +dw-world.de +dy24k.info +dynawebinc.com +dyndns.org +dzze.com +e123.hk +eamonnbrennan.com +earthquake.usgs.gov +easy-share.com +ebookbrowse.com +ebookee.com +echofon.com +ecministry.net +edicypages.com +edoors.com +edubridge.com +eevpn.com +efcc.org.hk +efksoft.com +efmoe.com +e-gold.com +eic-av.com +e-info.org.tw +electionsmeter.com +elpais.com +eltondisney.com +emacsblog.org +embr.in +emory.edu +emule-ed2k.com +emuparadise.me +enewstree.com +en.favotter.net +englishfromengland.co.uk +entermap.com +en.wikipedia.org +epochtimes-bg.com +epochtimes.co.il +epochtimes.co.kr +epochtimes.com +epochtimes.de +epochtimes.fr +epochtimes.ie +epochtimes.jp +epochtimes-romania.com +epochtimes.ru +epochtimes.se +epochtimestr.com +epochweekly.com +erabaru.net +erepublik.com +erepublik.net +erights.net +eriversoft.com +ernestmandel.org +etaiwannews.com +etizer.org +etools.ncol.com +e-traderland.net +etraining.gov.tw +ettoday.net +evchk.wikia.com +eventful.com +everyday-carry.com +exblog.jp +expatshield.com +exploader.net +extremetube.com +eyespirit.info +eyevio.jp +eyny.com +ezpc.tk +ezpeer.com +facebook.com +facebook.net +facesofnyfw.com +fail.hk +faiththedog.info +fakku.net +falsefire.com +falunart.org +falundafamuseum.org +falundafa.org +falunhr.org +famunion.com +fangbinxing.com +fangeming.com +fanglizhi.info +fangongheike.com +fangong.org +fan-qiang.com +fanqianghou.com +fanqiangyakexi.net +fanswong.com +fanyue.info +fapdu.com +farwestchina.com +farxian.com +fastpic.ru +faststone.org +favorious.com +favstar.fm +fawanghuihui.org +faydao.com +fbcdn.net +fb.com +fb.me +fbsbx.com +fc2china.com +fc2.com +f.cl.ly +fdc89.jp +feedbooks.mobi +feedburner.com +feeds2.feedburner.com +feeds.feedburner.com +feedzshare.com +feelssh.com +feer.com +felixcat.net +feministteacher.com +fengzhenghu.com +fetchvideo.com +ff.im +fflick.com +fgmtv.net +fgmtv.org +filefactory.com +files2me.com +fileserve.com +fillthesquare.org +finalion.jp +findbook.tw +finler.net +fireofliberty.org +firstfivefollowers.com +flecheinthepeche.fr +fleshbot.com +flickr.com +flickrhivemind.net +flightcaster.com +flowerofhappiness.spaces.live.com +focustaiwan.tw +focusvpn.com +fofg.org +fooooo.com +footwiball.com +forum.baby-kingdom.com +forum.cyberctm.com +forum.idsam.com +forum.iset.com.tw +forum.my903.com +forum.mymaji.com +forum.newsgroup.la +forum.nownews.com +forum.omy.sg +forum.palmislife.com +forum.pchome.com.tw +forum.setty.com.tw +forum.sina.com.hk +forum.slime.com.tw +forum.tvb.com +forum.yorkbbs.ca +fotop.net +fourface.nodesnoop.com +fourthinternational.org +foxdie.us +foxsub.com +foxtang.com +fqrouter.com +franklc.com +freakshare.com +fredwilson.vc +free4u.com.ar +freealim.com +freechal.com +freedomhouse.org +free.fr +freegao.com +freegateget.googlepages.com +free-gate.org +free-hada-now.org +freelotto.com +freeman2.com +freemoren.com +freemorenews.com +freenet-china.org +freenetproject.org +freenewscn.com +freeopenvpn.com +freeoz.org +free-ssh.com +freessh.us +freetibet.org +freevpn.nl +freewallpaper4.me +freewebs.com +freeweibo.com +freexinwen.com +freeyoutubeproxy.net +friendfeed.com +friendfeed-media.com +fring.com +fringenetwork.com +frommel.net +frontlinedefenders.org +fscked.org +fsurf.com +ftchinese.com +fuckcnnic.net +fuckgfw.com +fuckgfw.org +fulue.com +funf.tw +funp.com +furinkan.com +furl.net +futurechinaforum.org +futureme.org +futuremessage.org +fuyin.net +fw.cm +fxnetworks.com +fzh999.com +fzh999.net +gabocorp.com +gaeproxy.com +gaeproxy.googlecode.com +galenwu.com +game735.com +gamebase.com.tw +gamer.com.tw +gamez.com.tw +ganges.com +gaoming.net +gaopi.net +gaozhisheng.net +gaozhisheng.org +gardennetworks.com +gardennetworks.org +gartlive.com +gather.com +gaymap.cc +gazotube.com +gcc.org.hk +gclooney.com +g.co +gcpnews.com +gdbt.net +gdzf.org +geek-art.net +geekerhome.com +geekmade.co.uk +geekmanuals.com +generesis.com +genuitec.com +geocities.co.jp +geocities.com +geocities.jp +geohot.com +geometrictools.com +getchu.com +getcloudapp.com +get-digital-help.com +getfoxyproxy.org +getfreedur.com +getiton.com +getjetso.com +getlantern.org +getsmartlinks.com +getsocialscope.com +gfwinterceptor.googlecode.com +gfw.org.ua +ggpht.com +ggssl.com +ghost.org +ghut.org +giga-web.jp +gigporno.ru +gimpshop.com +girlbanker.com +github.com +git-scm.com +givemesomethingtoread.com +glennhilton.com +globaljihad.net +globalmuseumoncommunism.org +globalrescue.net +globalvoicesonline.org +gmail.com +gmbd.cn +gmhz.org +gmodules.com +gmozomg.izihost.org +gnci.org.hk +goagent.biz +goagent.googlecode.com +goagentplus.com +godfootsteps.org +golang.org +goldbetsports.com +goldwave.com +gongmeng.info +gongm.in +gongminliliang.com +gongwt.com +goodreaders.com +goodreads.com +goofind.com +goo.gl +googleadservices.com +google-analytics.com +googleapis.com +googlecode.com +google.co.jp +google.com +google.com.hk +google.com.sg +google.com.tw +google.com.uk +googledomains.com +googledrive.com +googleearth.com +googlehosted.com +googlelabs.com +googlemail.com +googleplus.com +googlesile.com +googlesource.com +googlesyndication.com +googletagmanager.com +googletagservices.com +googleusercontent.com +googlevideo.com +gopetition.com +gospelherald.com +gov.tw +gpass1.com +grandtrial.org +graphis.ne.jp +gravatar.com +graylog2.org +grb.gov.tw +greatfire.org +greatfirewall.biz +great-firewall.com +greatfirewallofchina.net +greatfirewallofchina.org +great-roc.org +greatroc.org +greatroc.tw +greatzhonghua.org +greenparty.org.tw +greenvpn.net +gs-discuss.com +gseeker.com +gsn-cert.nat.gov.tw +gstatic.com +gtap.googlecode.com +gtricks.com +guancha.org +gufeng521.spaces.live.com +guishan.org +gunsamerica.com +gun-world.net +guomin.us +gutteruncensored.com +gvm.com.tw +gyalwarinpoche.com +gysd.nyc.gov.tw +gzm.tv +gzone-anime.info +h1n1china.org +hacken.cc +hackthatphone.net +hahlo.com +hakkatv.org.tw +hanunyi.com +hardsextube.com +hasaowall.com +have8.com +haygo.com +hcc.gov.tw +hchcc.gov.tw +h-china.org +hdtvb.net +heartyit.com +hecaitou.net +hechaji.com +heix.pp.ru +heiyo.info +helloandroid.com +hellonewyork.us +helloqueer.com +hellotxt.com +hellouk.org +helpeachpeople.com +helplinfen.com +help.linksalpha.com +help.opera.com +helpzhuling.org +hen.bao.li +hengchuen.gov.tw +heqinglian.net +here4news.com +heungkongdiscuss.com +hgseav.com +hidden-advent.org +hidecloud.com +hideipvpn.com +hidemyass.com +higfw.com +highrockmedia.com +hihiforum.com +hihistory.net +hiitch.com +hikinggfw.org +himemix.com +himemix.net +hjclub.info +hk32168.com +hkbc.net +hkbf.org +hkchurch.org +hkdailynews.com.hk +hkday.net +hkej.com +hkepc.com +hkfront.org +hk.geocities.com +hkgolden.com +hkgreenradio.org +hkg.westkit.net +hkheadline.com +hkhkhk.com +hkjc.com +hk.jiepang.com +hkjp.easyweb.hk +hkjp.org +hk.knowledge.yahoo.com +hk.myblog.yahoo.com +hk.news.yahoo.com +hkptu.org +hk-pub.com +hk.rd.yahoo.com +hkreporter.com +hkreporter.loved.hk +hk.search.yahoo.com +hk.video.news.yahoo.com +hkwcc.org.hk +hk.yahoo.com +hkzone.org +hnjhj.com +hola.com +holyspiritspeaks.org +holz.byethost8.com +homeservershow.com +home.sina.com +home.so-net.net.tw +honeonet.spaces.live.com +hongmeimei.com +hongzhi.li +hootsuite.com +hotpot.hk +hotshame.com +hotspotshield.com +hougaige.com +howtoforge.com +hqcdp.org +hrcir.com +hrichina.org +hrw.org +hsinchu-cc.gov.tw +hsjp.net +hsselite.com +htkou.net +htl.li +ht.ly +htmldog.com +huaglad.com +huajiadi.spaces.live.com +huanghuagang.org +huaren.us +huaxia-news.com +huaxin.ph +hua-yue.net +hudatoriq.web.id +hugoroy.eu +huhamhire.com +hujiachina.spaces.live.com +hulu.com +huluim.com +humanities.uchicago.edu +hungerstrikeforaids.org +hung-ya.com +huping.net +hutianyi.net +hutong9.net +hwinfo.com +hyperrate.com +hypeshell.com +i1.hk +i2runner.com +ialmostlaugh.com +iask.bz +iask.ca +ibiblio.org +iblogserv-f.net +ibros.org +icij.org +icl-fi.org +iconpaper.org +icu-project.org +idemocracy.asia +identi.ca +idiomconnection.com +idouga.com +idv.tw +ieasynews.net +ied2k.net +ieemdai.spaces.live.com +ifan.cz.cc +ifanqiang.com +ifanr.com +ifcss.org +ifjc.org +igfw.net +ignitedetroit.net +igvita.com +ihakka.net +iicns.com +illusionfactory.com +ilove80.be +im88.tw +imageflea.com +imagesblog.gio.gov.tw +imageshack.us +imagevenue.com +imagezilla.net +ime.baidu.jp +img.ly +imkev.com +imlive.com +immigration.gov.tw +imrworldwide.com +im.tv +incredibox.fr +iner.gov.tw +initiativesforchina.org +inmediahk.net +innermongolia.org +instagram.com +interestinglaugh.com +interfaceaddiction.com +internationalrivers.org +internetdefenseleague.org +internetfreedom.org +internetpopculture.com +inxian.com +iphone4hongkong.com +iphonehacks.com +iphonix.fr +ipicture.ru +ipobar.com +ippotv.com +iptorrents.com +ipvanish.com +iredmail.org +ironbigfools.compython.net +ironicsoftware.com +ironpython.net +isaacmao.com +isgreat.org +islamicity.com +islam.org.hk +ismprofessional.net +isohunt.com +israbox.com +istockphoto.com +isunaffairs.com +isuntv.com +itaboo.info +ithelp.ithome.com.tw +itrc.gov.tw +itshidden.com +itweet.net +iu45.com +iverycd.com +ixquick.com +izaobao.us +izles.net +japan-whores.com +jayparkinsonmd.com +jbtalks.cc +jbtalks.com +jbtalks.my +jeanyim.com +jgoodies.com +jiaoyou8.com +jiehua.cz +jieshibaobao.com +jike.com +jimoparty.com +jinbushe.org +jingpin.org +jitouch.com +jkforum.net +j.mp +joachims.org +jobso.tv +joeedelman.com +journalofdemocracy.org +jpopforum.net +juliereyc.com +junauza.com +junefourth-20.net +justfreevpn.com +justtristan.com +juziyue.com +jwmusic.org +jyxf.net +jyzj.waqn.com +k2.xrea.com +kagyuoffice.org.tw +kaiyuan.de +kakao.com +kanzhongguo.com +kanzhongguo.eu +karayou.com +ka-wai.com +kcsoftwares.com +kechara.com +keepandshare.com +kendincos.net +kenengba.com +keontech.net +khcc.gov.tw +khms.gov.tw +khmusic.com.tw +killwall.com +kineox.free.fr +kingdomsalvation.org +kinghost.com +kingstone.com.tw +kissbbao.cn +kissyoutube.com +kk.gov.tw +klccab.gov.tw +klra.gov.tw +klsio.gov.tw +kmh.gov.tw +kmseh.gov.tw +knowledgerush.com +kodingen.com +kompozer.net +koolsolutions.com +koornk.com +kt.kcome.org +kui.name +kun.im +kurtmunger.com +kusocity.com +kwongwah.com.my +kyohk.net +kzeng.info +labiennale.org +ladbrokes.com +la-forum.org +lagranepoca.com +lalulalu.com +laogai.org +laomiu.com +laoyang.info +laptoplockdown.com +laqingdan.net +larsgeorge.com +lastfm.es +latelinenews.com +latimesblogs.latimes.com +lazarsearlymusic.com +leecheukyan.org +legaltech.law.com +lematin.ch +lemonde.fr +lenwhite.com +lerosua.org +lesoir.be +lesscss.org +letscorp.net +liansi.org +lianyue.net +liaowangxizang.net +liberal.org.hk +libertytimes.com.tw +lich355.megabyet.net +lidecheng.com +life.fly4ever.me +limiao.net +line.me +linglingfa.com +lingvodics.com +linkideo.com +linuxconfig.org +linux-engineer.net +linuxreviews.org +linuxtoy.org +lipuman.com +listentoyoutube.com +list.ly +listorious.com +lists.debian.org +lists.w3.org +littlebigdetails.com +liudejun.com +liuhanyu.com +liujianshu.com +liu.lu +liuxiaotong.com +liveleak.com +livestation.com +livestream.com +livevideo.com +livingonline.us +livingstream.com +lizhizhuangbi.com +lkcn.net +localpresshk.com +lockdown.com +lockestek.com +logbot.net +logiqx.com +logmike.com +log.riku.me +london.neighborhoodr.com +longhair.hk +longtermly.net +lookatgame.com +lookingglasstheatre.org +lookpic.com +lotuslight.org.tw +lovequicksilver.com +lovesphinx.tk +lrfz.com +lsd.org.hk +lsforum.net +lsmchinese.org +lsmkorean.org +lsm.org +lsxszzg.com +lua.org +lua-users.org +lungtanhr.gov.tw +luntan.zaobao.com +lupm.org +lushstories.com +lvhai.org +lyricsquote.com +mad-ar.ch +madmenunbuttoned.com +magazines.sina.com.tw +maiio.net +mail-archive.com +maiplus.com +makemymood.com +makzhou.warehouse333.com +malaysiakini.com +marc.info +marco.org +marguerite.su +marines.mil +markmilian.com +martau.com +martincartoons.com +maruta.be +marxist.com +marxist.net +marxists.org +mashable.com +mash.to +matainja.com +mathiew-badimon.com +matsu-news.gov.tw +matsushimakaede.com +maxgif.com +mayimayi.com +mcadforums.com +mcfog.com +md-t.org +mediafire.com +meetup.com +mefeedia.com +megaporn.com +megarotic.com +megavideo.com +megurineluka.com +meirixiaochao.com +melon-peach.com +memedia.cn +meme.yahoo.com +memrijttm.org +merit-times.com.tw +mesotw.com +metacafe.com +meteorshowersonline.com +metrolife.ca +mgoon.com +mgstage.com +mh4u.org +mhradio.org +michaelanti.com +michaelmarketl.com +middle-way.net +mihk.hk +mihua.org +mike.cz.cc +mimivip.com +minghui.org +minghui-school.org +mingjinglishi.com +mingjingnews.com +mingpaocanada.com +mingpao.com +mingpaomonthly.com +mingpaonews.com +mingpaony.com +mingpaosf.com +mingpaotor.com +mingpaovan.com +minimalmac.com +mininova.org +minzhuhua.net +minzhuzhongguo.org +miroguide.com +mirrorbooks.com +mitbbs.com +mixedmedialabs.com +mixero.com +mixpod.com +mixx.com +mizzmona.com +mk5000.com +mlcool.com +mmaaxx.com +mmmca.com +mobatek.net +mobile01.com +mobileways.de +mobypicture.com +moby.to +modfetish.com +moe.gov.tw +mog.com +molihua.org +mondex.org +monitorchina.org +moonriver7.files.wordpress.com +morningsun.org +m.oulove.org +movabletype.com +moviefap.com +mp3ye.eu +mpettis.com +mpfinance.com +mpinews.com +m.plixi.com +mrdoob.com +mrtweet.com +msguancha.com +m.slandr.net +m-team.cc +mthruf.com +m.tweete.net +mtw.tl +multiply.com +multiproxy.org +multiupload.com +muouju.com +muselinks.co.jp +music.jwmusic.org +muzi.com +muzi.net +muzu.tv +mvdis.gov.tw +mx981.com +myactimes.com +my-addr.com +myaudiocast.com +myav.com.tw +my.backchina.com +myboooks.googlepages.com +mychinamyhome.com +myeclipseide.com +myforum.com.hk +myforum.com.uk +myfreshnet.com +my.keso.cn +myopenid.com +my.opera.com +mypaper.pchome.com.tw +myparagliding.com +mypopescu.com +my-proxy.com +myshare.url.com.tw +mysinablog.com +myspace.com +myvlog.im.tv +naacoalition.org +naitik.net +nakido.com +namsisi.com +nanyang.com +nanyangpost.com +nanzao.com +naol.ca +national-lottery.co.uk +navicat.com +navigeaters.com +navy.mil +nccwatch.org.tw +ncdr.nat.gov.tw +nch.com.tw +ncn.org +ncree.gov.tw +nde.de +ndr.de +nekoslovakia.net +nerch.gov.tw +ner.gov.tw +nerhl.gov.tw +nertt.gov.tw +netcolony.com +netflix.com +netme.cc +networkedblogs.com +neverforget8964.org +new-3lunch.net +new-akiba.com +newcenturymc.com +newcenturynews.com +newchen.com +newgrounds.com +newlandmagazine.com.au +news100.com.tw +newsancai.com +news.atebits.com +news.backchina.com +news.bbc.co.uk +newscn.org +news.cnyes.com +newsforums.bbc.co.uk +news.ghostery.com +news.google.com.hk +newsminer.com +news.msn.com.tw +news.omy.sg +news.pchome.com.tw +newspeak.cc +newspp.org +news.sina.com.hk +news.sina.com.tw +news.singtao.ca +newstapa.org +newtaiwan.com.tw +newtalk.tw +newyorktimes.com +nexton-net.jp +nexttv.com.tw +nf.id.au +nga.mil +ngensis.com +nhri.gov.tw +nic.cz.cc +nici.nat.gov.tw +nicovideo.tw +nict.gov.tw +nighost.org +nintendium.com +nintendowifi.net +njactb.org +njuice.com +nlfreevpn.com +nmh.gov.tw +nmmba.gov.tw +nmp.gov.tw +nmtl.gov.tw +nmvttc.gov.tw +nobelprize.org +nobel.se +nobodycanstop.us +nokogiri.org +nokola.com +noobbox.com +notes.alexdong.com +novelasia.com +nownews.com +nowtorrents.com +noypf.com +npa.go.jp +npm.gov.tw +nps.gov +nrk.no +nsc.gov.tw +nspo.gov.tw +nstm.gov.tw +ntdmh.gov.tw +ntdtv.ca +ntdtv.co +ntdtv.com +ntdtv.org +ntdtv.ru +ntl.gov.tw +ntsec.gov.tw +ntuh.gov.tw +nuexpo.com +nurgo-software.com +nuvid.com +nuzcom.com +nvquan.org +nvri.gov.tw +nydus.ca +nysingtao.com +nytco.com +nyt.com +nytimes.com +nytimg.com +nzchinese.net.nz +observechina.net +oclp.hk +october-review.org +offbeatchina.com +ogaoga.org +oikos.com.tw +oiktv.com +oizoblog.com +okayfreedom.com +old-cat.net +old.nabble.com +olumpo.com +olympicwatch.org +omgili.com +omnitalk.com +on.cc +one.xthost.info +onlylady.cn +onmoon.com +onmoon.net +oopsforum.com +ooyala.com +open.com.hk +opendemocracy.net +openid.net +openleaks.org +openvpn.net +openvpn.org +openwebster.com +opml.radiotime.com +opnir.com +orientaldaily.com.my +orient-doll.com +orn.jp +orzistic.org +osfoora.com +ourdearamy.com +oursogo.com +oursteps.com.au +overlapr.com +owl.li +ow.ly +oyax.com +ozchinese.com +ozyoyo.com +pabp.gov.tw +pacificpoker.com +packages.debian.org +packetix.net +page2rss.com +page.bid.yahoo.com +pagodabox.com +paint.net +palacemoon.com +pandora.com +pandora.tv +panluan.net +panoramio.com +pao-pao.net +paperb.us +paper.li +paper-replika.com +parade.com +parislemon.com +pastebin.com +pastie.org +patehr.gov.tw +pbs.org +pbwiki.com +pbworks.com +pbxes.com +pbxes.org +pcdiscuss.com +pcdvd.com.tw +pchome.com.tw +pct.org.tw +pcworld.com +pdetails.com +pdproxy.com +peacefire.org +peacehall.com +peeasian.com +peerpong.com +pekingduck.org +penchinese.com +penchinese.net +pengyulong.com +penthouse.com +peopo.org +percy.in +perfectgirls.net +perfectvpn.net +perfspot.com +perlhowto.com +pet.gov.tw +philly.com +photofocus.com +photos.dailyme.com +photo.utom.us +phuquocservices.com +picasaweb.google.com +picidae.net +picturesocial.com +pictures.playboy.com +pidown.com +pign.net +pimg.tw +pin6.com +ping.fm +pinoy-n.com +pioneer-worker.forums-free.com +piring.com +pixanalytics.com +pixelqi.com +pixfs.net +pixnet.cc +pixnet.net +pixplug.in +pk.com +placemix.com +planetsuzy.org +playboy.com +plays.com.tw +plm.org.hk +plunder.com +plurk.com +plurktop.mmdays.com +plus28.com +plusbb.com +pmates.com +po2b.com +podictionary.com +pokerstars.com +politicalchina.org +popvote.hk +popyard.com +popyard.org +porn2.com +pornbase.org +porn.com +pornhub.com +pornmm.net +pornoxo.com +pornrapidshare.com +pornstarclub.com +porntube.com +pornvisit.com +portis21.spaces.live.com +pose.com +postadult.com +post.anyu.org +posterous.com +post.ly +powerapple.com +power.com +powercx.com +prayforchina.net +premeforwindows7.com +presentationzen.com +president.gov.tw +prestige-av.com +previewshots.com +privacybox.de +privateinternetaccess.com +privatepaste.com +privatetunnel.com +procopytips.com +program-think.spaces.live.com +prosiben.de +provideocoalition.com +proxifier.com +proxomitron.info +proxy.org +proxypy.net +proxyroad.com +prozz.net +psblog.name +psiphon.ca +psiphon.civisec.org +pts.org.tw +ptt.cc +pubu.com.tw +puffinbrowser.com +puffstore.com +pullfolio.com +pulse.yahoo.com +pure18.com +pureconcepts.net +purepdf.com +purevpn.com +putlocker.com +puttycm.free.fr +pwned.com +python.com +python.com.tw +qanote.com +qidian.ca +qienkuen.org +qi-gong.me +qiwen.lu +qixianglu.cn +qkshare.com +qoos.com +qq.co.za +qstatus.com +qtrac.eu +qtweeter.com +quadedge.com +qusi8.net +qvodzy.org +qxbbs.org +radicalparty.org +radioaustralia.net.au +radiovaticana.org +radiovncr.com +raidcall.com.tw +rangzen.org +ranyunfei.com +rapbull.net +rapidshare8.com +rapidsharedata.com +rayfme.com +rcinet.ca +rconversation.blogs.com +rdio.com +read100.com +readingtimes.com.tw +readmoo.com +realraptalk.com +recordhistory.org +redchinacn.org +redtube.com +referer.us +reflectivecode.com +relaxbbs.com +renminbao.com +renyurenquan.org +retweeteffect.com +retweetist.com +retweetrank.com +revleft.com +revsci.net +revver.com +rfachina.com +rfamobile.org +rfa.org +rferl.org +rfi.fr +rhcloud.com +riku.me +rileyguide.com +rlwlw.com +rmjdw.com +rnw.nl +robtex.com +robustnessiskey.com +rocmp.org +rojo.com +ronjoneswriter.com +roodo.com +rotten.com +rsf-chinese.org +rsf.org +rssmeme.com +rthk.hk +rthk.org.hk +rti.org.tw +ruanyifeng.com +rushbee.com +rutube.ru +ruyiseek.com +rxhj.net +s1heng.com +s8forum.com +sacom.hk +sadpanda.us +saiq.me +salvation.org.hk +samair.ru +sammyjs.org +samsoff.es +sandnoble.com +sankaizok.com +sanmin.com.tw +sapikachu.net +savemedia.com +savetibet.de +savetibet.fr +savetibet.nl +savetibet.org +savetibet.ru +savevid.com +say2.info +scanscout.com +scmpchinese.com +scmp.com +scorecardresearch.com +scribd.com +scriptspot.com +seapuff.com +secretchina.com +secretgarden.no +secure.wikimedia.org +securitykiss.com +seesmic.com +seevpn.com +seezone.net +sejie.com +sendoid.com +sendspace.com +sesawe.net +sesawe.org +sethwklein.net +sevenload.com +sex-11.com +sex3.com +sex8.cc +sexandsubmission.com +sex.com +sexhuang.com +sexhu.com +sexinsex.net +sfileydy.com +shadow.ma +shadowsocks.org +shahamat-english.com +shangfang.org +shapeservices.com +sharebee.com +sharecool.org +share.ovi.com +share.skype.com +share.youthwant.com.tw +sharkdolphin.com +sharpdaily.com.hk +sharpdaily.hk +shaunthesheep.com +sheikyermami.com +shellmix.com +shenshou.org +shenyunperformingarts.org +shenzhoufilm.com +shifeike.blog125.fc2blog.net +shinychan.com +shitaotv.org +shixiao.org +shizhao.org +shkspr.mobi +shodanhq.com +shopping.com +showbiz.omy.sg +showtime.jp +shwchurch3.com +sidelinesnews.com +sidelinessportseatery.com +simplecd.me +simplecd.org +simpleproductivityblog.com +sina.com.tw +singtao.com +singularitys.spaces.live.com +sinoants.com +sinocast.com +sinocism.com +sino-monthly.com +sinomontreal.ca +sinonet.ca +sinopitt.info +sinoquebec.com +sis001.com +sis001.us +sis.xxx +site90.net +sitebro.tw +siteks.uk.to +site.locql.com +sitemaps.org +sites.google.com +sitetag.us +siyi123123123.spaces.live.com +skimtube.com +skybet.com +skyvegas.com +slacker.com +slavasoft.com +slheng.com +slickvpn.com +slideshare.net +slinkset.com +slutload.com +smhric.org +snapchat.com +snaptu.com +sndcdn.com +sneakme.net +snooper.co.uk +sobees.com +socialwhale.com +sockslist.net +so.com +sod.co.jp +softether.co.jp +softether-download.com +softether.org +softwarebychuck.com +so-ga.net +sogclub.com +sogou.com +sogrady.me +sohcradio.com +sohfrance.org +soh.tw +sokamonline.com +solozorro.tk +somee.com +so-news.com +songjianjun.com +sonidodelaesperanza.org +sopcast.com +sopcast.org +sorting-algorithms.com +soso.com +soumo.info +soundcloud.com +soundofhope.kr +soundofhope.org +soupofmedia.com +sourceforge.net +southnews.com.tw +sowers.org.hk +space-scape.com +spankwire.com +spb.com +speckleapp.com +speedpluss.org +spencertipping.com +spinejs.com +sports.williamhill.com +spotify.com +sproutcore.com +squarespace.com +srcf.ucam.org +ssh91.com +sshtunnel.googlecode.com +sstatic.net +stag.gov.tw +standupfortibet.org +starp2p.com +startpage.com +statcounter.com +state168.com +static.apple.nextmedia.com +static.digg.com +staticflickr.com +static.nownews.com +static.soup.io +static.typepad.com +status.twhirl.org +stdtime.gov.tw +steel-storm.com +sthoo.com +stickam.com +stickeraction.com +stonegames.net +stoneip.info +stoptibetcrisis.net +storagenewsletter.com +stoweboyd.com +streamingthe.net +strongvpn.com +student.tw +stuffimreading.com +stuffimreading.net +stupidvideos.com +subacme.rerouted.org +sublexical.spaces.live.com +sufeng.org +sugarsync.com +summify.com +sun1911.com +suoluo.org +surfeasy.com.au +svwind.com +sweux.com +swift-tools.net +s.xiaod.in +sydneytoday.com +sylfoundation.org +syncback.com +sysadmin1138.net +sysresccd.org +sytes.net +szbbs.net +szetowah.org.hk +t35.com +t66y.com +taa-usa.org +tabtter.jp +tacem.org +tafaward.com +tagwalk.com +taipei.gov.tw +taipeisociety.org +taitung-house.gov.tw +taiwandaily.net +taiwankiss.com +taiwannation.50webs.com +taiwannation.com +taiwannation.com.tw +taiwannews.com.tw +taiwan-sex.com +taiwantt.org.tw +taiwanus.net +taiwanyes.com +taiwanyes.ning.com +tamiaode.tk +tanc.org +tangben.com +taolun.info +taoyuan.gov.tw +tap11.com +target.com +taweet.com +tax.nat.gov.tw +tbpic.info +tbsec.org +tbsn.org +tbsseattle.org +tchb.gov.tw +tchrd.org +t.co +tcsac.gov.tw +teamseesmic.com +teashark.com +techlifeweb.com +techparaiso.com +telecomspace.com +telegraph.co.uk +tenacy.com +thbstc.gov.tw +theampfactory.com +theappleblog.com +theatrum-belli.com +thebcomplex.com +theblemish.com +thebodyshop-usa.com +thechinabeat.org +thedailywh.at +thedieline.com +thedw.us +thegatesnotes.com +thehots.info +thehousenews.com +thehungrydudes.com +thehun.net +theinternetwishlist.com +thelifeyoucansave.com +thelius.org +thepiratebay.org +thepiratebay.se +theqii.info +thereallove.kr +thesartorialist.com +thespeeder.com +the-sun.on.cc +thetibetpost.com +thetrotskymovie.com +thevivekspot.com +thewgo.org +thisav.com +thisiswhyyouarefat.com +thkphoto.com +thomasbernhard.org +threatchaos.com +throughnightsfire.com +t.huhaitai.com +thumbzilla.com +thywords.com +tiananmenmother.org +tiananmenuniv.com +tiananmenuniv.net +tiandixing.org +tianhuayuan.com +tiantibooks.org +tianzhu.org +tibetalk.com +tibetanyouthcongress.org +tibet.at +tibet.com +tibetcorps.org +tibetfund.org +tibetjustice.org +tibet.net +tibetoffice.org +tibetonline.com +tibetonline.tv +tibet.org.tw +tibetsun.com +tibetwrites.org +tidyread.com +time.com +times.hinet.net +tinychat.com +tinypaste.com +tinypng.com +tistory.com +tjholowaychuk.com +tkcs-collins.com +tkforum.tk +t.kun.im +tmagazine.com +tmi.me +tnaflix.com +tncsec.gov.tw +t.neolee.cn +togetter.com +tokyo-247.com +tokyocn.com +tokyo-hot.com +tomayko.com +tomsc.com +tono-oka.jp +tonyyan.net +toodoc.com +toonel.net +topic.youthwant.com.tw +topnews.in +topshare.us +topshareware.com +topstyle4.com +topsy.com +tora.to +tor.blingblingsquad.net +torproject.org +torrentcrazy.com +torrentproject.se +tor.updatestar.com +torvpn.com +t.orzdream.com +tosh.comedycentral.com +touch99.com +toutfr.com +tpde.aide.gov.tw +tphcc.gov.tw +tpi.org.tw +transgressionism.org +transparency.org +travelinlocal.com +trendsmap.com +trialofccp.org +tripod.com +trouw.nl +trtc.com.tw +trt.net.tr +trulyergonomic.com +trustedbi.com +truth101.co.tv +truthcn.com +truveo.com +tsctv.net +tsemtulku.com +tsquare.tv +tsunagarumon.com +tt1069.com +tttan.com +tuanzt.com +tube8.com +tubecao.com +tube.com +tubewolf.com +tuidang.net +tuidang.org +tui.orzdream.com +tuite.googlecode.com +tumblr.awflasher.com +tumblweed.org +tumutanzi.com +tunein.com +tunnelbear.com +turbobit.net +turbotwitter.com +turningtorso.com +turntable.fm +tuxtraining.com +tvants.com +tvboxnow.com +tv.com +tvider.com +tv-intros.com +tv.on.cc +tvunetworks.com +twapperkeeper.com +twa.sh +twaud.io +twbbs.net.tw +twbbs.org +twbbs.tw +twblogger.com +tweepguide.com +tweeplike.me +tweepmag.com +tweepml.org +tweetbackup.com +tweetboard.com +tweetboner.biz +tweetdeck.com +tweetedtimes.com +tweetmeme.com +tweetmylast.fm +tweetphoto.com +tweetrans.com +tweetree.com +tweetwally.com +tweetymail.com +twftp.org +twibase.com +twibble.de +twibbon.com +twibs.com +twicsy.com +twifan.com +twiffo.com +twiggit.org +twilog.org +twimbow.com +twimg.com +twimg.edgesuite.net +tw.img.nextmedia.com +twindexx.com +twipple.jp +twistar.cc +twisternow.com +twistory.net +twit2d.com +twitbrowser.net +twitcause.com +twitese.spaces.live.com +twitgether.com +twitgoo.com +twitiq.com +twitlonger.com +twitoaster.com +twitonmsn.com +twitpic.com +twitreferral.com +twitstat.com +twittbot.net +twitter4j.org +twitter.com +twittercounter.com +twitterfeed.com +twittergadget.com +twitter.jp +twitterkr.com +twittermail.com +twittertim.es +twitthat.com +twitturk.com +twitturly.com +twitvid.com +twitzap.com +twiyia.com +tw.jiepang.com +tw.myblog.yahoo.com +tw.news.yahoo.com +tw-npo.org +tw.rd.yahoo.com +twreg.info +twstar.net +tw.streetvoice.com +twt.fm +twtkr.com +twtr2src.ogaoga.org +twtrland.com +twt.tl +twttr.com +twurl.nl +tw.voa.mobi +twyac.org +tw.yahoo.com +tycool.com +tynsoe.org +typepad.com +tzangms.com +ub0.cc +uberproxy.net +ucdc1998.org +uderzo.it +udn.com +ufreevpn.com +ugo.com +uhrp.org +uighurbiz.net +ukliferadio.co.uk +ulike.net +ultravpn.fr +ultraxs.com +unblock.cn.com +unblocksit.es +uncyclomedia.org +uncyclopedia.info +uncyclopedia.tw +unholyknight.com +uni.cc +unicode.org +uniteddaily.com.my +unix100.com +unknownspace.org +unpo.org +uocn.org +upcoming.yahoo.com +update.playstation.net +upload4u.info +upload.backchina.com +uploaded.to +uploadstation.com +upload.wikimedia.org +urlborg.com +urlparser.com +usacn.com +usfk.mil +usinfo.state.gov +usmc.mil +us.to +ustream.tv +usus.cc +uushare.com +uwants.com +uwants.net +uyghurcongress.org +uygur.org +v70.us +vaayoo.com +value-domain.com +van698.com +vanemu.cn +vanilla-jp.com +vansky.com +vapurl.com +vatn.org +vcfbuilder.org +vcf-online.org +veempiire.com +velkaepocha.sk +venbbs.com +venchina.com +ventureswell.com +veoh.com +verizon.net +verybs.com +vevo.com +vft.com.tw +vghks.gov.tw +vghtc.gov.tw +vghtpe.gov.tw +video.aol.ca +video.aol.com +video.aol.co.uk +video.ap.org +videobam.com +video.fdbox.com +video.foxbusiness.com +videomo.com +video.tiscali.it +video.yahoo.com +vidoemo.com +views.fm +viki.com +vimeocdn.com +vimeo.com +vimgolf.com +vimperator.org +vincnd.com +vinniev.com +vllcs.org +vlog.xuite.net +vmixcore.com +voacantonese.com +voachineseblog.com +voachinese.com +voagd.com +voanews.com +voatibetan.com +vocn.tv +vot.org +vpnbook.com +vpnfire.com +vpngate.jp +vpngate.net +vpnpop.com +vpnpronet.com +v-state.org +vtunnel.com +w3schools.com +waffle1999.com +wahas.com +waigaobu.com +waikeung.org +waiwaier.com +wallornot.org +wallpapercasa.com +wanderinghorse.net +wanfang.gov.tw +wangafu.net +wangjinbo.org +wanglixiong.com +wangruoshui.net +wangyi64.spaces.live.com +want-daily.com +wapedia.mobi +washeng.net +watchmygf.net +wattpad.com +wdf5.com +wearn.com +web2project.net +webbang.net +webfee.tk +weblagu.com +webmproject.org +webshots.com +websitepulse.com +webs-tv.net +webworkerdaily.com +weeewooo.net +weekmag.info +wefong.com +weiboleak.com +weigegebyc.dreamhosters.com +weijingsheng.org +weiming.info +weiquanwang.org +weisuo.ws +wellplacedpixels.com +wengewang.com +wengewang.org +wenhui.ch +wenku.com +wenxuecity.com +wenyunchao.com +wenyunchao.spaces.live.com +wepn.info +westca.com +westernwolves.com +wetplace.com +wetpussygames.com +wexiaobo.org +wezhiyong.org +wezone.net +wforum.com +whatblocked.com +whereiswerner.com +whippedass.com +whitebear.freebearblog.org +whydidyoubuymethat.com +whylover.com +whyx.org +w.idaiwan.com +wiki.cnitter.com +wiki.jqueryui.com +wiki.keso.cn +wikileaks.ch +wikileaks.de +wikileaks.eu +wikileaks.lu +wikileaks.org +wikileaks.pl +wikilivres.info +wikimapia.org +wikimedia.org.mo +wiki.moegirl.org +wikinet.org +wiki.oauth.net +wikipedia.org +wiki.phonegap.com +wikiwiki.jp +wikkii.com +williamlong.spaces.live.com +willw.net +windowsphoneme.com +winwhispers.info +wiredbytes.com +wiredpen.com +wireshark.org +wisevid.com +witnessleeteaching.com +witopia.net +wlx.sowiki.net +woeser.com +wolfax.com +womenbusiness.nyc.gov.tw +womensrightsofchina.org +woopie.jp +woopie.tv +wordboner.com +wordpress.com +wordsandturds.com +w.org +workatruna.com +worldcat.org +worldjournal.com +worstthingieverate.com +wo.tc +wowlegacy.ml +wow-life.net +woxinghuiguo.com +wozy.in +wp.com +wpoforum.com +wqlhw.com +wqyd.org +wrchina.org +wretch.cc +writer.zoho.com +wsj.com +wsj.net +wtfpeople.com +wuala.com +wuerkaixi.com +wufi.org.tw +wuguoguang.com +wujieliulan.com +wujie.net +wukangrui.net +wwitv.com +www.6v6dota.com +www.ajsands.com +www.antd.org +www.aolnews.com +www.bulbous.freeserve.co.uk +www.cmoinc.org +www.dfanning.com +www.dwheeler.com +www.eulam.com +www.exblog.jp +www.forum4hk.com +www.freetibet.org +www.getyouram.com +www.goldenmelody.com.tw +www.idlcoyote.com +www.immigration.gov.tw +www.klip.me +www.kodingen.com +www.linksalpha.com +www.loiclemeur.com +www.macrovpn.com +www.monlamit.org +www.moztw.org +www.mycould.com +www.ned.org +www.nownews.com +www.orchidbbs.com +www.owind.com +www.oxid.it +www.parkansky.com +www.powerpointninja.com +www.rnw.nl +www.somee.com +www.stackfile.com +www.supertweet.net +www.tiffanyarment.com +www.tripod.com +www.tv.com +www.twtrland.com +www.typepad.com +www.urbanoutfitters.com +www.vegorpedersen.com +www.voy.com +www.vpncup.com +www.wangruowang.org +www.wan-press.org +www.wet123.com +www.zaurus.org.uk +wzyboy.im +x1949x.com +x365x.com +xanga.com +x-art.com +xa.yimg.com +xbabe.com +xbookcn.com +xcafe.in +xcritic.com +xfm.pp.ru +xgmyd.com +xh4n.cn +xhamster.com +xiaochuncnjp.com +xiaohexie.com +xiaoma.org +xiezhua.com +xing.com +xinhuanet.org +xinmiao.com.hk +xinqimeng.over-blog.com +xinsheng.net +xinshijue.com +xinyubbs.net +xizang-zhiye.org +xjp.cc +xml-training-guide.com +xmovies.com +xmusic.fm +xnxx.com +xpdo.net +xpud.org +xskywalker.com +xtube.com +xuchao.net +xuchao.org +xuzhiyong.net +xuzhuoer.com +xvedios.com +xvideos.com +x-wall.org +xxbbx.com +x.xcity.jp +xxxx.com.au +xysblogs.org +xys.dxiong.com +xys.org +xyy69.com +xyy69.info +yahoo.cn +yahoo.com.hk +yam.com +yanghengjun.spaces.live.com +yasni.co.uk +yasukuni.or.jp +yatsen.gov.tw +ydy.com +yeelou.com +yeeyi.com +yegle.net +yezimary.spaces.live.com +yfrog.com +yhcw.net +yidio.com +yilubbs.com +yi.org +yipub.com +ym.backchina.com +yogichen.org +yong.hu +yorkbbs.ca +youdao.com +youjizz.com +youmaker.com +youpai.org +youporn.com +your-freedom.net +yousendit.com +youthbao.com +youthnetradio.org +youtu.be +youtubecn.com +youtube.com +youtube-nocookie.com +youversion.com +youxu.info +ytht.net +ytimg.com +yuanming.net +yuming.flnet.org +yunchao.net +yvesgeleyn.com +yvtc.gov.tw +yx51.net +yyii.org +yymaya.com +yzzk.com +zacebook.com +zannel.com +zaobao.com +zaobao.com.sg +zaozon.com +zarias.com +zattoo.com +zdnet.com.tw +zengjinyan.org +zengjinyan.spaces.live.com +zeutch.com +zgzcjj.net +zhanbin.net +zhao.jinhai.de +zhenghui.org +zhenlibu.info +zhinengluyou.com +zhllg.spaces.live.com +zh.m.wikipedia.org +zh.netlog.com +zhonggtuotese.net +zhongguotese.net +zhongmeng.org +zhongsou.com +zh.pokerstrategy.com +zhreader.com +zh-tw.justin.tv +zhuichaguoji.org +zh.uncyclopedia.wikia.com +zh.wikinews.org +zh.wikipedia.org +zh.wikisource.org +ziddu.com +zillionk.com +zinio.com +ziplib.com +zkaip.com +zmw.cn +zomobo.net +zonaeuropa.com +zootool.com +zoozle.net +zozotown.com +zshare.net +zsrhao.com +zuo.la +zuola.com +zvereff.com +zyzc9.com +zyzg.us diff --git a/package/lean/ipset-lists/tools/gen-china-routes.sh b/package/lean/ipset-lists/tools/gen-china-routes.sh new file mode 100755 index 000000000..36fd9ee77 --- /dev/null +++ b/package/lean/ipset-lists/tools/gen-china-routes.sh @@ -0,0 +1,85 @@ +#!/bin/bash -e + +# +# Script for generating China IPv4 route table by merging APNIC.net data and IPIP.net data +# + +china_routes_ipip() +{ + [ -f ipip.txt ] || wget -4 https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt -O ipip.txt >&2 || exit 1 + cat ipip.txt | xargs netmask | awk '{print $1}' +} + +china_routes_apnic() +{ + [ -f apnic.txt ] || wget -4 http://ftp.apnic.net/stats/apnic/delegated-apnic-latest -O apnic.txt >&2 || exit 1 + + cat apnic.txt | awk -F'|' -vc=CN ' +function tobits(c) { for(n=0; c>=2; c/=2) n++; return 32-n; } +$2==c&&$3=="ipv4" { printf("%s/%d\n", $4, tobits($5)) }' | + xargs netmask | awk '{print $1}' +} + +china_routes_merged() +{ + [ -x ./ipv4-merger ] || gcc ipv4_merger.c -o ipv4-merger >&2 + + china_routes_apnic > china.apnic + china_routes_ipip > china.ipip + + # Merge them together + cat china.apnic china.ipip | ./ipv4-merger | sed 's/\-/:/g' | + xargs netmask | awk '{print $1}' | awk -F/ '$2<=24' > china.merged + + cat china.merged +} + +# $1: ipset name +convert_routes_to_ipset() +{ + local ipset_name="$1" + echo "create $ipset_name hash:net family inet hashsize 1024 maxelem 65536" + awk -vt="$ipset_name" '{ printf("add %s %s\n", t, $0) }' +} + + +generate_china_ipset() +{ + china_routes_merged | convert_routes_to_ipset china +} + +generate_inverted_china_routes() +{ + ( + china_routes_merged + echo 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 172.16.0.0/12 192.168.0.0/16 224.0.0.0/3 + ) | + xargs netmask -r | awk '{print $1}' | + awk -F- ' +function iptoint(ip) { split(ip,arr,"."); n=0; for(i=1;i<=4;i++) n=n*256+arr[i]; return n; } +function inttoip(n) { a=int(n/16777216); b=int(n%16777216/65536); c=int(n%65536/256); d=n%256; return a "." b "." c "." d; } +BEGIN { st=0 } +{ x=st; y=iptoint($1); st=iptoint($2)+1; if(y>x) { print inttoip(x) ":" inttoip(y-1); } }' | + xargs netmask | awk '{print $1}' +} + + +## +case "$1" in + "") + generate_china_ipset + ;; + -c) + china_routes_merged + ;; + -r) + generate_inverted_china_routes + ;; + *) + echo "Usage:" + echo " $0 generate China routes in ipset format" + echo " $0 -c generate China routes in IP/prefix format" + echo " $0 -r generate invert China routes" + ;; + *) +esac diff --git a/package/lean/ipset-lists/tools/gen-gfwlist.sh b/package/lean/ipset-lists/tools/gen-gfwlist.sh new file mode 100755 index 000000000..483f6d8b3 --- /dev/null +++ b/package/lean/ipset-lists/tools/gen-gfwlist.sh @@ -0,0 +1,29 @@ +#!/bin/sh -e + +generate_china_banned() +{ + if [ ! -f gfwlist.txt ]; then + wget https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt -O gfwlist.b64 >&2 + cat gfwlist.b64 | base64 -d > gfwlist.txt + rm -f gfwlist.b64 + fi + + cat gfwlist.txt base-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; /qq\.com/d' | + sed '/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/d' | + grep '^[0-9a-zA-Z\.-]\+$' | grep '\.' | sed 's#^\.\+##' | rev | sort -u | + awk ' +BEGIN { prev = "________"; } { + cur = $0; + if (index(cur, prev) == 1 && substr(cur, 1 + length(prev) ,1) == ".") { + } else { + print cur; + prev = cur; + } +}' | rev | sort -u + +} + +generate_china_banned + diff --git a/package/lean/ipset-lists/tools/ipv4_merger.c b/package/lean/ipset-lists/tools/ipv4_merger.c new file mode 100644 index 000000000..0af85ced1 --- /dev/null +++ b/package/lean/ipset-lists/tools/ipv4_merger.c @@ -0,0 +1,339 @@ +#include +#include +#include +#include + +typedef u_int32_t u32; +typedef int bool; +#define true 1 +#define false 0 +typedef unsigned gfp_t; + +static inline char *ipv4_hltos(u32 u, char *s) +{ + static char ss[20]; + if (!s) + s = ss; + sprintf(s, "%d.%d.%d.%d", + (int)(u >> 24) & 0xff, (int)(u >> 16) & 0xff, + (int)(u >> 8) & 0xff, (int)u & 0xff ); + return s; +} + +static inline u32 ipv4_stohl(const char *s) +{ + int u[4]; + if (sscanf(s, "%d.%d.%d.%d", &u[0], &u[1], &u[2], &u[3]) == 4) { + return (((u32)u[0] & 0xff) << 24) | + (((u32)u[1] & 0xff) << 16) | + (((u32)u[2] & 0xff) << 8) | + (((u32)u[3] & 0xff)); + } else + return 0xffffffff; +} + +static inline bool is_ipv4_addr(const char *s) +{ + int u[4]; + if (sscanf(s, "%d.%d.%d.%d", &u[0], &u[1], &u[2], &u[3]) == 4) + return true; + else + return false; +} + + +struct ipv4_range { + u32 start; + u32 end; +}; + +struct sa_open_data { + struct ipv4_range *tmp_base; + size_t tmp_size; + size_t tmp_length; + int errors; +}; + +static int __touch_tmp_base(struct sa_open_data *od, gfp_t gfp) +{ + if (!od->tmp_base) { + /** + * Allocate a temporary table with twice the size of the previous + * table or at least 100, on which new entries can be inserted. + */ + if (od->tmp_size < 100) + od->tmp_size = 100; + od->tmp_base = (struct ipv4_range *)malloc( + sizeof(struct ipv4_range) * od->tmp_size /*, gfp*/ ); + if (!od->tmp_base) { + fprintf(stderr, + "salist: cannot allocate the temporary list for enlarging it.\n"); + return -ENOMEM; + } + od->tmp_length = 0; + } + return 0; +} + +static int ipv4_list_add_range(struct sa_open_data *od, u32 start, + u32 end, gfp_t gfp) +{ + struct ipv4_range *cur; + int ret; + + /* Ignore a new range if it or a larger range already exists */ + //if (salist_check_ipv4(od->table, start, end)) + // return 0; + + if ((ret = __touch_tmp_base(od, gfp)) < 0) + return ret; + + /* Check if the size is efficient. Enlarge it if needed. */ + if (od->tmp_length + 1 >= od->tmp_size) { + size_t old_size = od->tmp_size; + struct ipv4_range *old_base = od->tmp_base; + + od->tmp_size *= 2; + od->tmp_base = (struct ipv4_range *)realloc(od->tmp_base, + sizeof(struct ipv4_range) * od->tmp_size); + if (!od->tmp_base) { + od->tmp_size = old_size; + od->tmp_base = old_base; + return -ENOMEM; + } + } + + cur = &od->tmp_base[od->tmp_length++]; + cur->start = start; + cur->end = end; + + return 0; +} + +static inline int ipv4_list_add_netmask(struct sa_open_data *od, + u32 net, u32 net_mask, gfp_t gfp) +{ + u32 start = net & net_mask; + u32 end = net | ~net_mask; + + return ipv4_list_add_range(od, start, end, gfp); +} + +static int ipv4_list_add_net(struct sa_open_data *od, u32 net, + int net_bits, gfp_t gfp) +{ + u32 net_mask; + + if(net_bits == 0) + net_mask = 0x00000000; + else + net_mask = ~(((u32)1 << (32 - net_bits)) - 1); + //printf("%d: %08x, %08x\n", net_bits, net_mask, net_size); + + return ipv4_list_add_netmask(od, net, net_mask, gfp); +} + +static int salist_cmd_parse(struct sa_open_data *od, char *cmd, gfp_t gfp) +{ + char *a1 = NULL, *a2 = NULL; + char *sep; + char sc; + int n = 32; + + /* Case 3: Append an item */ + + /* Check IP description part: network segment or range? */ + if ((sep = strchr(cmd, '/'))) { } + else if ((sep = strchr(cmd, '-'))) { } + else if ((sep = strchr(cmd, ':'))) { } + + if (sep) { + /* Describes a subnet or range. */ + sc = *sep; + *sep = '\0'; + + a1 = cmd; + a2 = sep + 1; + + if (*a2 == '\0') { + fprintf(stderr, "Nothing after '%c'.\n", sc); + return -EINVAL; + } + } else { + /* Describes a single IP. */ + sc = '\0'; + a1 = cmd; + } + + switch (sc) { + case '/': + /* 10.10.20.0/24 */ + /* ------------------------------------ */ + if (is_ipv4_addr(a2)) { + ipv4_list_add_netmask(od, ipv4_stohl(a1), ipv4_stohl(a2), gfp); + } else { + sscanf(a2, "%d", &n); + ipv4_list_add_net(od, ipv4_stohl(a1), n, gfp); + } + /* ------------------------------------ */ + break; + case ':': + case '-': + /* 10.10.20.0-10.20.0.255 */ + /* ------------------------------------ */ + ipv4_list_add_range(od, ipv4_stohl(a1), ipv4_stohl(a2), gfp); + /* ------------------------------------ */ + break; + default: + if (is_ipv4_addr(a1)) { + /* Single IP address. */ + u32 ip = ipv4_stohl(a1); + /* ------------------------------------ */ + ipv4_list_add_range(od, ip, ip, gfp); + /* ------------------------------------ */ + } else { + fprintf(stderr, "Invalid IP address '%s'.\n", a1); + return -EINVAL; + } + break; + } + return 0; +} + +static int ipv4_range_sort_cmp(const void *a, const void *b) +{ + struct ipv4_range *ra = (struct ipv4_range *)a; + struct ipv4_range *rb = (struct ipv4_range *)b; + + if (ra->start > rb->start) { + return 1; + } else if (ra->start < rb->start) { + return -1; + } else if (ra->end > rb->end) { + return 1; + } else if (ra->end < rb->end) { + return -1; + } else { + return 0; + } +} + +static void ipv4_range_swap(void *a, void *b, int size) +{ + struct ipv4_range *ra = (struct ipv4_range *)a; + struct ipv4_range *rb = (struct ipv4_range *)b; + struct ipv4_range tmp; + tmp = *ra; + *ra = *rb; + *rb = tmp; +} + +static struct sa_open_data *salist_open(void) +{ + struct sa_open_data *od = NULL; + + od = (struct sa_open_data *)malloc(sizeof(*od)); + if (!od) { + fprintf(stderr, "salist: cannot allocate sa_open_data.\n"); + return NULL; + } + memset(od, 0, sizeof(*od)); + od->errors = 0; + + return od; +} + +static int salist_close(struct sa_open_data *od) +{ + size_t ri, wi; + struct ipv4_range *old_base; + + /* Flush the table if any modification has been done */ + if (od->tmp_base) { + /* Sort the table and merge entries as many as possible. */ + if (od->tmp_length >= 2) { + qsort(od->tmp_base, od->tmp_length, sizeof(struct ipv4_range), + ipv4_range_sort_cmp); + + for (wi = 0, ri = 1; ri < od->tmp_length; ri++) { + /* NOTICE: 0xffffffff + 1 ? */ + if (od->tmp_base[wi].end == (u32)(-1)) { + /* Nothing */ + } else if (od->tmp_base[ri].start <= od->tmp_base[wi].end + 1) { + /* The two ranges overlap, so merge the 2nd to the 1st one */ + if (od->tmp_base[ri].end > od->tmp_base[wi].end) + od->tmp_base[wi].end = od->tmp_base[ri].end; + } else { + wi++; + if (wi < ri) + od->tmp_base[wi] = od->tmp_base[ri]; + } + } + + od->tmp_length = wi + 1; + } + + /* Reduce the size */ + if (od->tmp_length < od->tmp_size) { + struct ipv4_range *__tmp = od->tmp_base; + od->tmp_base = (struct ipv4_range *)malloc( + sizeof(struct ipv4_range) * (od->tmp_length ? od->tmp_length : 1)); + if (od->tmp_base) { + memcpy(od->tmp_base, __tmp, + sizeof(struct ipv4_range) * od->tmp_length); + free(__tmp); + } else { + fprintf(stderr, "[%s:%d] Failed to allocate temporary table.\n", + __FUNCTION__, __LINE__); + /* If failed to allocate new memory, do not reduce it. */ + od->tmp_base = __tmp; + } + } + + /* Dump the table instead */ + } + + if (od->errors) { + fprintf(stderr, "[%s] %d errors detected during table operation.\n", + __FUNCTION__, od->errors); + } + + return 0; +} + +static void sa_open_data_dump(struct sa_open_data *od) +{ + size_t i; + char s1[20], s2[20]; + + for (i = 0; i < od->tmp_length; i++) { + printf("%s-%s\n", ipv4_hltos(od->tmp_base[i].start, s1), + ipv4_hltos(od->tmp_base[i].end, s2)); + } +} + +int main(int argc, char *argv[]) +{ + struct sa_open_data *od; + char lbuf[128]; + + od = salist_open(); + + while (fgets(lbuf, sizeof(lbuf), stdin)) { + size_t llen = strlen(lbuf); + if (llen > 0 && lbuf[llen - 1] == '\n') + lbuf[--llen] = '\0'; + if (llen > 0 && lbuf[llen - 1] == '\r') + lbuf[--llen] = '\0'; + if (llen == 0) + continue; + salist_cmd_parse(od, lbuf, 0); + } + + salist_close(od); + + sa_open_data_dump(od); + + return 0; +} + diff --git a/package/lean/k3wifi/Makefile b/package/lean/k3wifi/Makefile new file mode 100644 index 000000000..479628dc0 --- /dev/null +++ b/package/lean/k3wifi/Makefile @@ -0,0 +1,42 @@ +# +# Copyright (C) 2015-2016 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v3. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=k3wifi +PKG_VERSION:=1 +PKG_RELEASE:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME) + TITLE:=k3wifi + DEPENDS:= + URL:=http://www.k3wifi.com/ +endef + +define Package/$(PKG_NAME)/description + k3wifi fw +endef + +define Build/Prepare +endef + +define Build/Configure +endef + +define Build/Compile +endef + + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/lib + $(INSTALL_DIR) $(1)/lib/firmware + $(INSTALL_DIR) $(1)/lib/firmware/brcm + $(INSTALL_DATA) ./files/lib/firmware/brcm/brcmfmac4366c-pcie.bin $(1)/lib/firmware/brcm/brcmfmac4366c-pcie.bin +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/package/lean/k3wifi/files/lib/firmware/brcm/brcmfmac4366c-pcie.bin b/package/lean/k3wifi/files/lib/firmware/brcm/brcmfmac4366c-pcie.bin new file mode 100644 index 000000000..203ce98f0 Binary files /dev/null and b/package/lean/k3wifi/files/lib/firmware/brcm/brcmfmac4366c-pcie.bin differ diff --git a/package/lean/luci-app-adbyby-plus/Makefile b/package/lean/luci-app-adbyby-plus/Makefile new file mode 100644 index 000000000..5c3411e3c --- /dev/null +++ b/package/lean/luci-app-adbyby-plus/Makefile @@ -0,0 +1,18 @@ +# Copyright (C) 2016 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for Adbyby +LUCI_DEPENDS:=+adbyby +wget +ipset +coreutils +coreutils-nohup +dnsmasq-full +LUCI_PKGARCH:=all +PKG_NAME:=luci-app-adbyby-plus +PKG_VERSION:=2.0 +PKG_RELEASE:=17 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature + diff --git a/package/lean/luci-app-adbyby-plus/luasrc/controller/adbyby.lua b/package/lean/luci-app-adbyby-plus/luasrc/controller/adbyby.lua new file mode 100644 index 000000000..ee37e26da --- /dev/null +++ b/package/lean/luci-app-adbyby-plus/luasrc/controller/adbyby.lua @@ -0,0 +1,10 @@ + +module("luci.controller.adbyby", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/adbyby") then + return + end + + entry({"admin", "services", "adbyby"}, cbi("adbyby"), _("ADBYBY Plus +"), 10).dependent = true +end diff --git a/package/lean/luci-app-adbyby-plus/luasrc/model/cbi/adbyby.lua b/package/lean/luci-app-adbyby-plus/luasrc/model/cbi/adbyby.lua new file mode 100644 index 000000000..694dbbb12 --- /dev/null +++ b/package/lean/luci-app-adbyby-plus/luasrc/model/cbi/adbyby.lua @@ -0,0 +1,203 @@ + +local NXFS = require "nixio.fs" +local SYS = require "luci.sys" +local HTTP = require "luci.http" +local DISP = require "luci.dispatcher" + +local m,s,o +local Status + +if SYS.call("pidof adbyby >/dev/null") == 0 then + Status = translate("Adbyby Plus + is Running") +else + Status = translate("Adbyby Plus + is Not Running") +end + +m = Map("adbyby") +m.title = translate("Adbyby Plus +") +m.description = translate("Adbyby Plus + can filter all kinds of banners, popups, video ads, and prevent tracking, privacy theft and a variety of malicious websites
Plus + version combination mode can operation with Adblock Plus Host锛宖iltering ads without losing bandwidth") + +s = m:section(TypedSection, "adbyby") +s.anonymous = true +s.description = translate(string.format("%s

", Status)) + + +s:tab("basic", translate("Base Setting")) + +o = s:taboption("basic", Flag, "enable") +o.title = translate("Enable") +o.default = 0 +o.rmempty = false + +o = s:taboption("basic", ListValue, "wan_mode") +o.title = translate("Running Mode") +o:value("0", translate("Global Mode锛圱he slowest, the best effects锛")) +o:value("1", translate("Plus + Mode锛團ilter domain name list and blacklist website.Recommended锛")) +o:value("2", translate("No filter Mode (Must set in Client Filter Mode Settings manually)")) +o.default = 1 +o.rmempty = false + +o = s:taboption("basic", Button, "proxy") +o.title = translate("Transparent proxy") +if SYS.call("iptables-save | grep ADBYBY >/dev/null") == 0 then + o.inputtitle = translate("Click to disable") + o.inputstyle = "reset" + o.write = function() + SYS.call("/etc/init.d/adbyby del_rule") + HTTP.redirect(DISP.build_url("admin", "services", "adbyby")) + end +else + o.inputtitle = translate("Click to enable") + o.inputstyle = "apply" + o.write = function() + SYS.call('[ -n "$(pgrep adbyby)" ] && /etc/init.d/adbyby add_rule') + HTTP.redirect(DISP.build_url("admin", "services", "adbyby")) + end +end + + +local DL = SYS.exec("head -1 /usr/share/adbyby/data/lazy.txt | awk -F' ' '{print $3,$4}'") +local DV = SYS.exec("head -1 /usr/share/adbyby/data/video.txt | awk -F' ' '{print $3,$4}'") +local NR = SYS.exec("grep -v '^!' /usr/share/adbyby/data/rules.txt | wc -l") +local NU = SYS.exec("cat /usr/share/adbyby/data/user.txt | wc -l") +--local NW = SYS.exec("uci get adbyby.@adbyby[-1].domain 2>/dev/null | wc -l") +local ND = SYS.exec("cat /usr/share/adbyby/dnsmasq.adblock | wc -l") + +o = s:taboption("basic", Button, "restart") +o.title = translate("Adbyby and Rule state") +o.inputtitle = translate("Restart Adbyby") +o.description = translate(string.format("%s

", Status)) +o.description = translate(string.format("Lazy Rule锛%s   Video Rule锛%s
Third Party Subscription Rule锛%d lines  User-defined Rule锛%d lines", DL, DV, math.abs(NR-NU), NR)) +o.inputstyle = "reload" +o.write = function() + SYS.call("/etc/init.d/adbyby restart") + HTTP.redirect(DISP.build_url("admin", "services", "adbyby")) +end + +s:tab("advanced", translate("Advance Setting")) + +o = s:taboption("advanced", Flag, "cron_mode") +o.title = translate("Update the rule at 6 a.m. every morning and restart adbyby") +o.default = 0 +o.rmempty = false +o.description = translate(string.format("Adblock Plus Host List锛 %s Lines

", ND)) + + +updatead = s:taboption("advanced", Button, "updatead", translate("Manually force update
Adblock Plus Host List"), translate("Note: It needs to download and convert the rules. The background process may takes 60-120 seconds to run.
After completed it would automatically refresh, please do not duplicate click!")) +updatead.inputtitle = translate("Manually force update") +updatead.inputstyle = "apply" +updatead.write = function() + SYS.call("nohup sh /usr/share/adbyby/adblock.sh > /tmp/adupdate.log 2>&1 &") +end + +o = s:taboption("advanced", Flag, "block_ios") +o.title = translate("Block Apple iOS OTA update") +o.default = 0 +o.rmempty = false + +mem = s:taboption("advanced", Flag, "mem_mode") +mem.title = translate("RAM Running Mode") +mem.default = 1 +mem.rmempty = false +mem.description = translate("Running Adbyby in RAM.More speed,less disk consumption") + + +s:tab("help", translate("Plus+ Domain List")) + +local conf = "/usr/share/adbyby/adhost.conf" +o = s:taboption("help", TextValue, "conf") +o.description = translate("锛!锛塏ote that you should fill to the domain name ONLY. For example, http://www.baidu.com only needs to write to baidu.com. One line for each") +o.rows = 13 +o.wrap = "off" +o.cfgvalue = function(self, section) + return NXFS.readfile(conf) or "" +end +o.write = function(self, section, value) + NXFS.writefile(conf, value:gsub("\r\n", "\n")) + --SYS.call("/etc/init.d/adbyby restart") +end + +s:tab("esc", translate("Bypass Domain List")) + +local escconf = "/usr/share/adbyby/adesc.conf" +o = s:taboption("esc", TextValue, "escconf") +o.description = translate("锛!锛塛ill Never filter these Domain") +o.rows = 13 +o.wrap = "off" +o.cfgvalue = function(self, section) + return NXFS.readfile(escconf) or "" +end +o.write = function(self, section, value) + NXFS.writefile(escconf, value:gsub("\r\n", "\n")) + --SYS.call("/etc/init.d/adbyby restart") +end + +s:tab("black", translate("Black Domain List")) + +local blackconf = "/usr/share/adbyby/adblack.conf" +o = s:taboption("black", TextValue, "blackconf") +o.description = translate("锛!锛塛ill Always block these Domain") +o.rows = 13 +o.wrap = "off" +o.cfgvalue = function(self, section) + return NXFS.readfile(blackconf) or "" +end +o.write = function(self, section, value) + NXFS.writefile(blackconf, value:gsub("\r\n", "\n")) + --SYS.call("/etc/init.d/adbyby restart") +end + +s:tab("block", translate("Black IP List")) + +local blockconf = "/usr/share/adbyby/blockip.conf" +o = s:taboption("block", TextValue, "blockconf") +o.description = translate("锛!锛塛ill Always block these IP") +o.rows = 13 +o.wrap = "off" +o.cfgvalue = function(self, section) + return NXFS.readfile(blockconf) or " " +end +o.write = function(self, section, value) + NXFS.writefile(blockconf, value:gsub("\r\n", "\n")) + --SYS.call("/etc/init.d/adbyby restart") +end + +s:tab("user", translate("User-defined Rule")) + +local file = "/usr/share/adbyby/rules.txt" +o = s:taboption("user", TextValue, "rules") +o.description = translate("Each line of the beginning exclamation mark is considered an annotation.") +o.rows = 13 +o.wrap = "off" +o.cfgvalue = function(self, section) + return NXFS.readfile(file) or "" +end +o.write = function(self, section, value) + NXFS.writefile(file, value:gsub("\r\n", "\n")) +end + +t=m:section(TypedSection,"acl_rule",translate("Client Filter Mode Settings"), +translate("Filter mode settings can be set to specific LAN clients ( No filter , Global filter ) . Does not need to be set by default.")) +t.template="cbi/tblsection" +t.sortable=true +t.anonymous=true +t.addremove=true + +e=t:option(Value,"ipaddr",translate("IP Address")) +e.width="40%" +e.datatype="ip4addr" +e.placeholder="0.0.0.0/0" +luci.ip.neighbors({ family = 4 }, function(entry) + if entry.reachable then + e:value(entry.dest:string()) + end +end) + +e=t:option(ListValue,"filter_mode",translate("Filter Mode")) +e.width="40%" +e.default="disable" +e.rmempty=false +e:value("disable",translate("No filter")) +e:value("global",translate("Global filter")) + +return m diff --git a/package/lean/luci-app-adbyby-plus/po/zh-cn/adbyby.po b/package/lean/luci-app-adbyby-plus/po/zh-cn/adbyby.po new file mode 100644 index 000000000..045517d21 --- /dev/null +++ b/package/lean/luci-app-adbyby-plus/po/zh-cn/adbyby.po @@ -0,0 +1,118 @@ +msgid "ADBYBY Plus +" +msgstr "骞垮憡灞忚斀澶у笀 Plus+" + +msgid "Adbyby Plus + is Running" +msgstr "骞垮憡灞忚斀澶у笀 Plus + 姝e湪杩愯" + +msgid "Adbyby Plus + is Not Running" +msgstr "骞垮憡灞忚斀澶у笀 Plus + 娌℃湁杩愯" + +msgid "Adbyby Plus + can filter all kinds of banners, popups, video ads, and prevent tracking, privacy theft and a variety of malicious websites
Plus + version combination mode can operation with Adblock Plus Host锛宖iltering ads without losing bandwidth" +msgstr "骞垮憡灞忚斀澶у笀 Plus + 鍙互鍏ㄩ潰杩囨护鍚勭妯箙銆佸脊绐椼佽棰戝箍鍛婏紝鍚屾椂闃绘璺熻釜銆侀殣绉佺獌鍙栧強鍚勭鎭舵剰缃戠珯
Plus + 鐗堟湰鍙互鍜 Adblock Plus Host 缁撳悎鏂瑰紡杩愯锛岃繃婊ゅ箍鍛婁笉鎹熷け甯﹀" + +msgid "Adbyby Plus +" +msgstr "骞垮憡灞忚斀澶у笀 Plus+" + +msgid "Base Setting" +msgstr "鍩烘湰璁剧疆" + +msgid "Running Mode" +msgstr "杩愯妯″紡" + +msgid "Global Mode锛圱he slowest, the best effects锛" +msgstr "鍏ㄥ眬妯″紡锛堟渶鎱, 鏁堟灉鏈濂斤級" + +msgid "Plus + Mode锛團ilter domain name list and blacklist website.Recommended锛" +msgstr "Plus + 妯″紡锛堝彧杩囨护鍒楄〃鍐呭煙鍚嶇粨鍚圓BP鍚嶅崟銆傛帹鑽愶紒锛" + +msgid "No filter Mode (Must set in Client Filter Mode Settings manually)" +msgstr "鎵嬪姩浠g悊妯″紡锛堝繀椤绘墜鍔ㄨ缃祻瑙堝櫒浠g悊锛屾垨鑰呭鎴风杩囨护妯″紡璁剧疆锛" + +msgid "Transparent proxy" +msgstr "閫忔槑浠g悊" + +msgid "Click to disable" +msgstr "鐐瑰嚮鍏抽棴" + +msgid "Click to enable" +msgstr "鐐瑰嚮寮鍚" + +msgid "Adbyby and Rule state" +msgstr "瑙勫垯鐘舵" + +msgid "Restart Adbyby" +msgstr "閲嶅惎Adbyby" + +msgid "Plus+ Domain List" +msgstr "Plus+ 妯″紡杩囨护鐨勫煙鍚" + +msgid "Bypass Domain List" +msgstr "鍩熷悕鐧藉悕鍗" + +msgid "Black Domain List" +msgstr "鍩熷悕榛戝悕鍗" + +msgid "Black IP List" +msgstr "IP榛戝悕鍗" + + +msgid "Advance Setting" +msgstr "楂樼骇璁剧疆" + +msgid "Update the rule at 6 a.m. every morning and restart adbyby" +msgstr "姣忓ぉ鍑屾櫒6鐐规洿鏂拌鍒欏苟閲嶅惎" + +msgid "Manually force update
Adblock Plus Host List" +msgstr "鎵嬪姩寮哄埗鏇存柊
Adblock Plus Host List" + +msgid "Manually force update" +msgstr "鎵嬪姩寮哄埗鏇存柊" + +msgid "Block Apple iOS OTA update" +msgstr "鎷︽埅 Apple iOS 鐨凮TA鏇存柊" + +msgid "RAM Running Mode" +msgstr "鍐呭瓨杩愯妯″紡" + +msgid "Running Adbyby in RAM.More speed,less disk consumption" +msgstr "鍦ㄥ唴瀛樹腑杩愯Adbyby銆傛洿蹇殑閫熷害锛屾洿灏戠殑瀛樺偍绌洪棿鎹熻" + + +msgid "User-defined Rule" +msgstr "鐢ㄦ埛鑷畾涔夎鍒" + +msgid "Client Filter Mode Settings" +msgstr "瀹㈡埛绔繃婊ゆā寮忚缃" + +msgid "Filter mode settings can be set to specific LAN clients ( No filter , Global filter ) . Does not need to be set by default." +msgstr "鍙互涓哄眬鍩熺綉瀹㈡埛绔垎鍒缃笉鍚岀殑杩囨护妯″紡 ( 涓嶈繃婊 , 鍏ㄥ眬杩囨护 ) 銆傞粯璁ゆ棤闇璁剧疆" + +msgid "IP Address" +msgstr "IP鍦板潃" + +msgid "Filter Mode" +msgstr "杩囨护妯″紡" + +msgid "锛!锛塏ote that you should fill to the domain name ONLY. For example, http://www.baidu.com only needs to write to baidu.com. One line for each" +msgstr "杩欎簺鍩熷悕鍦 Plus 妯″紡涓細琚繃婊ゃ備綘闇瑕佽濉啓鍩熷悕鍗冲彲锛屼緥濡 http://www.baidu.com锛屼綘鍐 baidu.com 鍗冲彲銆傛瘡琛屼竴涓煙鍚" + +msgid "锛!锛塛ill Never filter these Domain" +msgstr "姘镐笉杩囨护鐧藉悕鍗曞唴鐨勫煙鍚嶏紙鎵鏈夋ā寮忎腑鐢熸晥锛" + +msgid "锛!锛塛ill Always block these Domain" +msgstr "鎷︽埅榛戝悕鍗曞唴鐨勫煙鍚嶏紙鎵鏈夋ā寮忎腑鐢熸晥锛" + +msgid "锛!锛塛ill Always block these IP" +msgstr "鎷︽埅榛戝悕鍗曞唴鐨処P鍦板潃锛堟墍鏈夋ā寮忎腑鐢熸晥锛" + +msgid "Each line of the beginning exclamation mark is considered an annotation." +msgstr "姣忚涓鏉¤鍒欙紝鎰熷徆鍙峰紑澶寸殑琚涓烘槸娉ㄩ噴" + +msgid "Adblock Plus Host List锛" +msgstr "Adblock Plus Host 鍒楄〃锛" + +msgid "Note: It needs to download and convert the rules. The background process may takes 60-120 seconds to run.
After completed it would automatically refresh, please do not duplicate click!" +msgstr "娉ㄦ剰锛氶渶瑕佷笅杞藉苟杞崲瑙勫垯銆傚悗鍙拌繘绋嬪彲鑳介渶瑕60-120绉掕繍琛屻傚畬鎴愬悗浼氳嚜鍔ㄥ埛鏂帮紝璇蜂笉瑕侀噸澶嶇偣鍑伙紒" + + + diff --git a/package/lean/luci-app-adbyby-plus/root/etc/config/adbyby b/package/lean/luci-app-adbyby-plus/root/etc/config/adbyby new file mode 100644 index 000000000..c928a7577 --- /dev/null +++ b/package/lean/luci-app-adbyby-plus/root/etc/config/adbyby @@ -0,0 +1,10 @@ + +config adbyby + option daemon '2' + option lan_mode '0' + option cron_mode '1' + option block_ios '1' + option enable '1' + option wan_mode '1' + option mem_mode '1' + diff --git a/package/lean/luci-app-adbyby-plus/root/etc/init.d/adbyby b/package/lean/luci-app-adbyby-plus/root/etc/init.d/adbyby new file mode 100755 index 000000000..afbd3a7bc --- /dev/null +++ b/package/lean/luci-app-adbyby-plus/root/etc/init.d/adbyby @@ -0,0 +1,217 @@ +#!/bin/sh /etc/rc.common + +START=99 +STOP=10 + +EXTRA_COMMANDS="add_rule del_rule reload_rule" +PROG_PATH=/usr/share/adbyby +DATA_PATH=$PROG_PATH/data +WAN_FILE=/var/etc/dnsmasq-adbyby.d/03-adbyby-ipset.conf +CRON_FILE=/etc/crontabs/root +CONFIG=adbyby +ipt_n="iptables -t nat" + + +get_config() +{ + config_get_bool enable $1 enable + config_get_bool cron_mode $1 cron_mode + config_get wan_mode $1 wan_mode + config_get_bool block_ios $1 block_ios 0 + config_get_bool mem_mode $1 mem_mode 1 +} + +add_rules() +{ + rm -f $DATA_PATH/user.bin + grep -v ^! $PROG_PATH/rules.txt > $DATA_PATH/user.txt + cp $PROG_PATH/rules.txt $DATA_PATH/rules.txt +} + + +add_cron() +{ + if [ $cron_mode -eq 1 ]; then + sed -i '/adblock.sh/d' $CRON_FILE + echo '0 6 * * * /usr/share/adbyby/adblock.sh > /tmp/adupdate.log 2>&1' >> $CRON_FILE + crontab $CRON_FILE + fi +} + +del_cron() +{ + sed -i '/adblock.sh/d' $CRON_FILE + /etc/init.d/cron restart +} + +ip_rule() +{ + + ipset -N adbyby_esc hash:ip + $ipt_n -A ADBYBY -m set --match-set adbyby_esc dst -j RETURN + + for i in $(seq 0 100) + do + local ip=$(uci_get_by_type acl_rule ipaddr '' $i) + local mode=$(uci_get_by_type acl_rule filter_mode '' $i) + case "$mode" in + disable) + $ipt_n -A ADBYBY -s $ip -j RETURN + ;; + global) + $ipt_n -A ADBYBY -s $ip -p tcp -j REDIRECT --to-ports 8118 + $ipt_n -A ADBYBY -s $ip -j RETURN + ;; + esac + done + + + + case $wan_mode in + 0) + ;; + 1) + ipset -N adbyby_wan hash:ip + $ipt_n -A ADBYBY -m set ! --match-set adbyby_wan dst -j RETURN + ;; + 2) + $ipt_n -I ADBYBY -j RETURN + ;; + esac + + echo "create blockip hash:net family inet hashsize 1024 maxelem 65536" > /tmp/blockip.ipset + awk '!/^$/&&!/^#/{printf("add blockip %s'" "'\n",$0)}' /usr/share/adbyby/blockip.conf >> /tmp/blockip.ipset + ipset -! restore < /tmp/blockip.ipset + iptables -I FORWARD -m set --match-set blockip dst -j DROP + iptables -I OUTPUT -m set --match-set blockip dst -j DROP +} + +add_dns() +{ + mkdir -p /var/etc/dnsmasq-adbyby.d + mkdir -p /tmp/dnsmasq.d + awk '!/^$/&&!/^#/{printf("ipset=/%s/'"adbyby_esc"'\n",$0)}' $PROG_PATH/adesc.conf > /var/etc/dnsmasq-adbyby.d/06-dnsmasq.esc + awk '!/^$/&&!/^#/{printf("address=/%s/'"0.0.0.0"'\n",$0)}' $PROG_PATH/adblack.conf > /var/etc/dnsmasq-adbyby.d/07-dnsmasq.black + cat > /tmp/dnsmasq.d/dnsmasq-adbyby.conf < $WAN_FILE + if ls /var/etc/dnsmasq-adbyby.d/* >/dev/null 2>&1; then + mkdir -p /tmp/dnsmasq.d + cp /usr/share/adbyby/dnsmasq.adblock /var/etc/dnsmasq-adbyby.d/04-dnsmasq.adblock + cp /usr/share/adbyby/dnsmasq.ads /var/etc/dnsmasq-adbyby.d/05-dnsmasq.ads + fi + fi + + sed -i '/mesu.apple.com/d' /etc/dnsmasq.conf && [ $block_ios -eq 1 ] && echo 'address=/mesu.apple.com/0.0.0.0' >> /etc/dnsmasq.conf +} + +del_dns() +{ + rm -f /tmp/dnsmasq.d/dnsmasq-adbyby.conf + rm -f /var/etc/dnsmasq-adbyby.d/* + rm -f /tmp/adbyby_host.conf +} + + +add_rule() +{ + $ipt_n -N ADBYBY + $ipt_n -A ADBYBY -d 0.0.0.0/8 -j RETURN + $ipt_n -A ADBYBY -d 10.0.0.0/8 -j RETURN + $ipt_n -A ADBYBY -d 127.0.0.0/8 -j RETURN + $ipt_n -A ADBYBY -d 169.254.0.0/16 -j RETURN + $ipt_n -A ADBYBY -d 172.16.0.0/12 -j RETURN + $ipt_n -A ADBYBY -d 192.168.0.0/16 -j RETURN + $ipt_n -A ADBYBY -d 224.0.0.0/4 -j RETURN + $ipt_n -A ADBYBY -d 240.0.0.0/4 -j RETURN + ip_rule + $ipt_n -A ADBYBY -p tcp -j REDIRECT --to-ports 8118 + $ipt_n -I PREROUTING -p tcp --dport 80 -j ADBYBY +} + +del_rule() +{ + $ipt_n -D PREROUTING -p tcp --dport 80 -j ADBYBY 2>/dev/null + $ipt_n -F ADBYBY 2>/dev/null + $ipt_n -X ADBYBY 2>/dev/null + iptables -D FORWARD -m set --match-set blockip dst -j DROP 2>/dev/null + iptables -D OUTPUT -m set --match-set blockip dst -j DROP 2>/dev/null + ipset -F adbyby_esc 2>/dev/null + ipset -X adbyby_esc 2>/dev/null + ipset -F adbyby_wan 2>/dev/null + ipset -X adbyby_wan 2>/dev/null + ipset -F blockip 2>/dev/null + ipset -X blockip 2>/dev/null +} + +reload_rule() +{ + config_load adbyby + config_foreach get_config adbyby + del_rule + iptables-save | grep ADBYBY >/dev/null || \ + add_rule +} + +start() +{ + config_load adbyby + config_foreach get_config adbyby + [ $enable -eq 0 ] && exit 0 + add_cron + if [ $mem_mode -eq 1 ]; then + echo "start mem mode" + if mount | grep adbyby >/dev/null 2>&1; then + echo "has mount" + else + echo "mount adbyby" + [ ! -d "/tmp/adbyby" ] && mkdir -p /tmp/adbyby && cp -a $PROG_PATH/data /tmp/adbyby/ + mount --bind /tmp/adbyby/data $PROG_PATH/data + fi + fi + add_rules + $PROG_PATH/adbyby &>/dev/null & + add_dns + iptables-save | grep ADBYBY >/dev/null || \ + add_rule + /etc/init.d/dnsmasq restart +} + +stop() +{ + config_load adbyby + config_foreach get_config adbyby + del_rule + del_cron + del_dns + killall -q adbyby + if [ $mem_mode -eq 1 ]; then + echo "stop mem mode" + if mount | grep adbyby >/dev/null 2>&1; then + echo "umount adbyby" + umount /usr/share/adbyby/data + fi + fi + /etc/init.d/dnsmasq restart +} + + +uci_get_by_name() { + local ret=$(uci get $CONFIG.$1.$2 2>/dev/null) + echo ${ret:=$3} +} + +uci_get_by_type() { + local index=0 + if [ -n $4 ]; then + + index=$4 + fi + local ret=$(uci get $CONFIG.@$1[$index].$2 2>/dev/null) + echo ${ret:=$3} +} + diff --git a/package/lean/luci-app-adbyby-plus/root/etc/uci-defaults/adbyby b/package/lean/luci-app-adbyby-plus/root/etc/uci-defaults/adbyby new file mode 100755 index 000000000..cdf3be3d7 --- /dev/null +++ b/package/lean/luci-app-adbyby-plus/root/etc/uci-defaults/adbyby @@ -0,0 +1,21 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@adbyby[-1] + add ucitrack adbyby + set ucitrack.@adbyby[-1].init=adbyby + commit ucitrack + delete firewall.adbyby + set firewall.adbyby=include + set firewall.adbyby.type=script + set firewall.adbyby.path=/usr/share/adbyby/firewall.include + set firewall.adbyby.reload=1 + commit firewall +EOF + +mkdir -p /etc/dnsmasq.d + +/etc/init.d/adbyby enable + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/adblack.conf b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/adblack.conf new file mode 100644 index 000000000..14a8193c0 --- /dev/null +++ b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/adblack.conf @@ -0,0 +1,15 @@ +stat.pandora.xiaomi.com +upgrade.mishop.pandora.xiaomi.com +logonext.tv.kuyun.com +config.kuyun.com +api.io.mi.com +mishop.pandora.xiaomi.com +dvb.pandora.xiaomi.com +api.ad.xiaomi.com +de.pandora.xiaomi.com +data.mistat.xiaomi.com +jellyfish.pandora.xiaomi.com +gallery.pandora.xiaomi.com +o2o.api.xiaomi.com +bss.pandora.xiaomi.com +gvod.aiseejapp.atianqi.com \ No newline at end of file diff --git a/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/adblock.sh b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/adblock.sh new file mode 100755 index 000000000..ebe7b6e6a --- /dev/null +++ b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/adblock.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +rm -f /tmp/dnsmasq.adblock + +wget-ssl --no-check-certificate -O- https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt | grep ^\|\|[^\*]*\^$ | sed -e 's:||:address\=\/:' -e 's:\^:/0\.0\.0\.0:' > /tmp/dnsmasq.adblock +if [ -s "/tmp/dnsmasq.adblock" ];then + sed -i '/youku.com/d' /tmp/dnsmasq.adblock + if ( ! cmp -s /tmp/dnsmasq.adblock /usr/share/adbyby/dnsmasq.adblock );then + mv /tmp/dnsmasq.adblock /usr/share/adbyby/dnsmasq.adblock + fi +fi + +sh /usr/share/adbyby/adupdate.sh + + + + diff --git a/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/adesc.conf b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/adesc.conf new file mode 100644 index 000000000..c5898a128 --- /dev/null +++ b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/adesc.conf @@ -0,0 +1,3 @@ +weixin.qq.com +qpic.cn +imtt.qq.com diff --git a/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/adhost.conf b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/adhost.conf new file mode 100644 index 000000000..d14a7c50c --- /dev/null +++ b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/adhost.conf @@ -0,0 +1,69 @@ +cbjs.baidu.com +list.video.baidu.com +nsclick.baidu.com +play.baidu.com +sclick.baidu.com +tieba.baidu.com +baidustatic.com +bdimg.com +bdstatic.com +share.baidu.com +hm.baidu.com +v.baidu.com +cpro.baidu.com +1000fr.net +atianqi.com +56.com +v-56.com +acfun.com +acfun.tv +baofeng.com +baofeng.net +cntv.cn +hoopchina.com.cn +funshion.com +fun.tv +hitvs.cn +hljtv.com +iqiyi.com +qiyi.com +agn.aty.sohu.com +itc.cn +kankan.com +ku6.com +letv.com +letvcloud.com +letvimg.com +pplive.cn +pps.tv +ppsimg.com +pptv.com +www.qq.com +l.qq.com +v.qq.com +video.sina.com.cn +tudou.com +wasu.cn +analytics-union.xunlei.com +kankan.xunlei.com +youku.com +hunantv.com +ifeng.com +renren.com +mediav.com +cnbeta.com +mydrivers.com +168f.info +doubleclick.net +126.net +sohu.com +163.com +right.com.cn +50bang.org +you85.cn +jiuzhilan.com +googles.com +cnbetacdn.com +ptqy.gitv.tv +admaster.com.cn +serving-sys.com \ No newline at end of file diff --git a/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/adupdate.sh b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/adupdate.sh new file mode 100755 index 000000000..2f47f35da --- /dev/null +++ b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/adupdate.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +wget -t 1 -T 10 -O /tmp/lazy.txt http://update.adbyby.com/rule3/lazy.jpg +wget -t 1 -T 10 -O /tmp/video.txt http://update.adbyby.com/rule3/video.jpg +wget -t 1 -T 10 -O /tmp/user.action http://update.adbyby.com/rule3/user.action + +[ ! -s "/tmp/lazy.txt" ] && wget --no-check-certificate -O /tmp/lazy.txt https://raw.githubusercontent.com/adbyby/xwhyc-rules/master/lazy.txt +[ ! -s "/tmp/video.txt" ] && wget --no-check-certificate -O /tmp/video.txt https://raw.githubusercontent.com/adbyby/xwhyc-rules/master/video.txt + +[ -s "/tmp/lazy.txt" ] && ( ! cmp -s /tmp/lazy.txt /usr/share/adbyby/data/lazy.txt ) && mv /tmp/lazy.txt /usr/share/adbyby/data/lazy.txt +[ -s "/tmp/video.txt" ] && ( ! cmp -s /tmp/video.txt /usr/share/adbyby/data/video.txt ) && mv /tmp/video.txt /usr/share/adbyby/data/video.txt +[ -s "/tmp/user.action" ] && ( ! cmp -s /tmp/user.action /usr/share/adbyby/user.action ) && mv /tmp/user.action /usr/share/adbyby/user.action + +rm -f /tmp/lazy.txt /tmp/video.txt /tmp/user.action + +/etc/init.d/adbyby restart diff --git a/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/blockip.conf b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/blockip.conf new file mode 100644 index 000000000..66a76058b --- /dev/null +++ b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/blockip.conf @@ -0,0 +1 @@ +1.1.1.1 diff --git a/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/dnsmasq.adblock b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/dnsmasq.adblock new file mode 100644 index 000000000..6f0950609 --- /dev/null +++ b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/dnsmasq.adblock @@ -0,0 +1,940 @@ +address=/a.youdao.com/0.0.0.0 +address=/adrs.sdo.com/0.0.0.0 +address=/hiad.myweb.hinet.net/0.0.0.0 +address=/log.interest.mix.sina.com.cn/0.0.0.0 +address=/tuiguang.178.com/0.0.0.0 +address=/0xxd.com/0.0.0.0 +address=/104.195.62.12/0.0.0.0 +address=/111.175.219.7/0.0.0.0 +address=/111111qb.com/0.0.0.0 +address=/112.124.98.75/0.0.0.0 +address=/116.55.227.242/0.0.0.0 +address=/122.227.254.195/0.0.0.0 +address=/123hala.com/0.0.0.0 +address=/139.159.32.82/0.0.0.0 +address=/182.92.81.104/0.0.0.0 +address=/1l1.cc/0.0.0.0 +address=/201071.com/0.0.0.0 +address=/2012ui.com/0.0.0.0 +address=/211.167.105.131/0.0.0.0 +address=/220.115.251.25/0.0.0.0 +address=/221.204.213.222/0.0.0.0 +address=/2m2n.com/0.0.0.0 +address=/360baidus.com/0.0.0.0 +address=/365bibi.com/0.0.0.0 +address=/365safego.com/0.0.0.0 +address=/366safego.com/0.0.0.0 +address=/36pn.com/0.0.0.0 +address=/3g.990.net/0.0.0.0 +address=/52kmk.com/0.0.0.0 +address=/58.215.179.159/0.0.0.0 +address=/61.152.223.15/0.0.0.0 +address=/68665565.com/0.0.0.0 +address=/6dvip.com/0.0.0.0 +address=/71sem.com/0.0.0.0 +address=/77power.com/0.0.0.0 +address=/7wen.cn/0.0.0.0 +address=/7xz3.com/0.0.0.0 +address=/81c.cn/0.0.0.0 +address=/85tgw.com/0.0.0.0 +address=/88rpg.net/0.0.0.0 +address=/892155.com/0.0.0.0 +address=/91ysa.com/0.0.0.0 +address=/91zgm.com/0.0.0.0 +address=/9377co.com/0.0.0.0 +address=/9377os.com/0.0.0.0 +address=/a907907.com/0.0.0.0 +address=/ad000000.com/0.0.0.0 +address=/adm-cnzz.net/0.0.0.0 +address=/ads.uc.cn/0.0.0.0 +address=/ajaxcdn.org/0.0.0.0 +address=/aliyuncss.com/0.0.0.0 +address=/aliyunxin.com/0.0.0.0 +address=/amazingmagics.com/0.0.0.0 +address=/aralego.com/0.0.0.0 +address=/at98.com/0.0.0.0 +address=/cangnews.com/0.0.0.0 +address=/caob5.info/0.0.0.0 +address=/cb.baidu.com/0.0.0.0 +address=/cbjs.baidu.com/0.0.0.0 +address=/cnxad.net/0.0.0.0 +address=/cnzz.com.so/0.0.0.0 +address=/code668.com/0.0.0.0 +address=/cpcv.cc/0.0.0.0 +address=/cpms.cc/0.0.0.0 +address=/cpro.baidu.com/0.0.0.0 +address=/cpro.baidustatic.com/0.0.0.0 +address=/cpv6.com/0.0.0.0 +address=/cpva.cc/0.0.0.0 +address=/crdrjs.info/0.0.0.0 +address=/csqiulong.com/0.0.0.0 +address=/ctsywy.com/0.0.0.0 +address=/cyacc.com/0.0.0.0 +address=/czpush.com/0.0.0.0 +address=/dashet.com/0.0.0.0 +address=/datafastguru.info/0.0.0.0 +address=/dou777.com/0.0.0.0 +address=/drmcmm.baidu.com/0.0.0.0 +address=/duiwai.baidu.com/0.0.0.0 +address=/dvr8.com/0.0.0.0 +address=/dw998.com/0.0.0.0 +address=/dxssiyi.com/0.0.0.0 +address=/e701.net/0.0.0.0 +address=/e70123.com/0.0.0.0 +address=/e708.net/0.0.0.0 +address=/e719.net/0.0.0.0 +address=/ecuc123.net/0.0.0.0 +address=/eiv.baidu.com/0.0.0.0 +address=/f1190.com/0.0.0.0 +address=/f6ce.com/0.0.0.0 +address=/f70123.com/0.0.0.0 +address=/fd7c.com/0.0.0.0 +address=/fjmeyer.com/0.0.0.0 +address=/fu68.com/0.0.0.0 +address=/fv99.com/0.0.0.0 +address=/gf108.com/0.0.0.0 +address=/gf1352.com/0.0.0.0 +address=/gm682.com/0.0.0.0 +address=/guduopu.com/0.0.0.0 +address=/gzmjnx.cn/0.0.0.0 +address=/gzqudou.com/0.0.0.0 +address=/hao123rt.com/0.0.0.0 +address=/haohaowan8.com/0.0.0.0 +address=/haolew.com/0.0.0.0 +address=/hfjuki.com/0.0.0.0 +address=/hmp33.com/0.0.0.0 +address=/hr44.com/0.0.0.0 +address=/humanding.com/0.0.0.0 +address=/i3818.com/0.0.0.0 +address=/ihualun.com/0.0.0.0 +address=/img80.net/0.0.0.0 +address=/jczzjx.com/0.0.0.0 +address=/jdlhg.com/0.0.0.0 +address=/jhzl001.com/0.0.0.0 +address=/jiyou2014.com/0.0.0.0 +address=/jk939.com/0.0.0.0 +address=/jlssbz.com/0.0.0.0 +address=/jnrsjm.com/0.0.0.0 +address=/johtzj.com/0.0.0.0 +address=/jwqj.net/0.0.0.0 +address=/jxjzny.com/0.0.0.0 +address=/keyyou.net/0.0.0.0 +address=/kingwam.com/0.0.0.0 +address=/kmadou.com/0.0.0.0 +address=/ku9377.com/0.0.0.0 +address=/lajizhan.org/0.0.0.0 +address=/le4le.com/0.0.0.0 +address=/lishuanghao.com/0.0.0.0 +address=/lzmm8.com/0.0.0.0 +address=/mainbx.com/0.0.0.0 +address=/mathads.com/0.0.0.0 +address=/mlt01.com/0.0.0.0 +address=/moodoocrv.com.cn/0.0.0.0 +address=/mscimg.com/0.0.0.0 +address=/nextcps.com/0.0.0.0 +address=/niuxgame77.com/0.0.0.0 +address=/notice.uchome.manyou.com/0.0.0.0 +address=/oikxlcv.wang/0.0.0.0 +address=/okm918.com/0.0.0.0 +address=/p3tt.com/0.0.0.0 +address=/pdsjycm.com/0.0.0.0 +address=/pos.baidu.com/0.0.0.0 +address=/qiqiww.com/0.0.0.0 +address=/qucaigg.com/0.0.0.0 +address=/re.taotaosou.com/0.0.0.0 +address=/ruxianke.com/0.0.0.0 +address=/rwjfs.com/0.0.0.0 +address=/sgbfjs.info/0.0.0.0 +address=/sharedaddomain.com/0.0.0.0 +address=/show.kc.taotaosou.com/0.0.0.0 +address=/si9377.com/0.0.0.0 +address=/socdm.com/0.0.0.0 +address=/spcode.baidu.com/0.0.0.0 +address=/sstc360.com/0.0.0.0 +address=/t70123.com/0.0.0.0 +address=/taat00889.com/0.0.0.0 +address=/tad.suning.com/0.0.0.0 +address=/tc600.com/0.0.0.0 +address=/tdayi.com/0.0.0.0 +address=/tg.1155t.cn/0.0.0.0 +address=/toourbb.com/0.0.0.0 +address=/ubmcmm.baidustatic.com/0.0.0.0 +address=/uoyrsd.com/0.0.0.0 +address=/v707070.com/0.0.0.0 +address=/victorjx.com/0.0.0.0 +address=/w65p.com/0.0.0.0 +address=/wdzsb.com.cn/0.0.0.0 +address=/winvestern.com.cn/0.0.0.0 +address=/wqsph.net/0.0.0.0 +address=/ws341.com/0.0.0.0 +address=/xa9t.com/0.0.0.0 +address=/xabaitai.com/0.0.0.0 +address=/xchgx.com/0.0.0.0 +address=/xcy8.com/0.0.0.0 +address=/xtxa.net/0.0.0.0 +address=/xxad.cc/0.0.0.0 +address=/xzyituo.com/0.0.0.0 +address=/yk0712.com/0.0.0.0 +address=/ymcqb.com/0.0.0.0 +address=/yqw88.com/0.0.0.0 +address=/yule8.net/0.0.0.0 +address=/yyp17.com/0.0.0.0 +address=/zgksb.com/0.0.0.0 +address=/zgunion.cn/0.0.0.0 +address=/zp22938576.com/0.0.0.0 +address=/120.27.34.156/0.0.0.0 +address=/122.228.236.165/0.0.0.0 +address=/125.46.61.28/0.0.0.0 +address=/192.184.10.171/0.0.0.0 +address=/218.65.30.232/0.0.0.0 +address=/27.255.67.120/0.0.0.0 +address=/32345sf.com/0.0.0.0 +address=/360safego.com/0.0.0.0 +address=/3dm.huya.com/0.0.0.0 +address=/5y9nfpes.52pk.com/0.0.0.0 +address=/654mmm.com/0.0.0.0 +address=/6d245gxt.52pk.com/0.0.0.0 +address=/7mad.7m.cn/0.0.0.0 +address=/801.tianyaui.com/0.0.0.0 +address=/86file.megajoy.com/0.0.0.0 +address=/8jkx.com/0.0.0.0 +address=/96.43.97.243/0.0.0.0 +address=/a-m-s.poco.cn/0.0.0.0 +address=/a.baomihua.com/0.0.0.0 +address=/a.xizi.com/0.0.0.0 +address=/a2.b310.com/0.0.0.0 +address=/a4.yeshj.com/0.0.0.0 +address=/a5.yeshj.com/0.0.0.0 +address=/a6.hujiang.com/0.0.0.0 +address=/abc.hkepc.com/0.0.0.0 +address=/acsystem.wasu.cn/0.0.0.0 +address=/ad.17173.com/0.0.0.0 +address=/ad.bjmama.net/0.0.0.0 +address=/adadmin.house365.com/0.0.0.0 +address=/add.dz19.net/0.0.0.0 +address=/adf.dahe.cn/0.0.0.0 +address=/adhome.1fangchan.com/0.0.0.0 +address=/adk.funshion.com/0.0.0.0 +address=/adm.265g.com/0.0.0.0 +address=/adm.72zx.com/0.0.0.0 +address=/adm.86wan.com/0.0.0.0 +address=/adm.bbcss.com/0.0.0.0 +address=/adm.funshion.com/0.0.0.0 +address=/adm.jjj8.cn/0.0.0.0 +address=/adm.qzbbs.com/0.0.0.0 +address=/adm.xmfish.com/0.0.0.0 +address=/adm.zbinfo.net/0.0.0.0 +address=/adm.zzfish.cn/0.0.0.0 +address=/admd.yam.com/0.0.0.0 +address=/adnetpub.yaolan.com/0.0.0.0 +address=/adp.cnool.net/0.0.0.0 +address=/adpub.yaolan.com/0.0.0.0 +address=/adpubs.yaolan.com/0.0.0.0 +address=/adsclick.yx.js.cn/0.0.0.0 +address=/adspending01.bwnet.com.tw/0.0.0.0 +address=/afp.chinanews.com/0.0.0.0 +address=/afp.wasu.cn/0.0.0.0 +address=/afpcreative.wasu.cn/0.0.0.0 +address=/ai.bioon.com/0.0.0.0 +address=/aid.chinayk.com/0.0.0.0 +address=/am.6park.com/0.0.0.0 +address=/am.szhome.com/0.0.0.0 +address=/app.acm.dzwww.com/0.0.0.0 +address=/as.sinahk.net/0.0.0.0 +address=/ashow.pcpop.com/0.0.0.0 +address=/bb345.com/0.0.0.0 +address=/besc.baidustatic.com/0.0.0.0 +address=/biz.gexing.com/0.0.0.0 +address=/biz.weibo.com/0.0.0.0 +address=/btn.onlylady.com/0.0.0.0 +address=/btn.pchome.net/0.0.0.0 +address=/business.92wy.com/0.0.0.0 +address=/by.7avz.com/0.0.0.0 +address=/cacafly.net/0.0.0.0 +address=/cachead.com/0.0.0.0 +address=/cdn.wdlm.cn/0.0.0.0 +address=/chidir.com/0.0.0.0 +address=/cps.okbuy.com/0.0.0.0 +address=/d.107788.com/0.0.0.0 +address=/d.taomato.com/0.0.0.0 +address=/d0.xcar.com.cn/0.0.0.0 +address=/dd.xdnice.com/0.0.0.0 +address=/de.as.pptv.com/0.0.0.0 +address=/dfad.dfdaily.com/0.0.0.0 +address=/dg.073img.com/0.0.0.0 +address=/doubleclick.tv002.com/0.0.0.0 +address=/dvs.china.com/0.0.0.0 +address=/dvser.china.com/0.0.0.0 +address=/e.yycqc.com/0.0.0.0 +address=/eap.big5.enorth.com.cn/0.0.0.0 +address=/eap.enorth.com.cn/0.0.0.0 +address=/ebp.renren.com/0.0.0.0 +address=/ecma.bdimg.com/0.0.0.0 +address=/ecmb.bdimg.com/0.0.0.0 +address=/fun.ynet.com/0.0.0.0 +address=/g.gxorg.com/0.0.0.0 +address=/g.hsw.cn/0.0.0.0 +address=/g.ousns.net/0.0.0.0 +address=/g1.0573ren.com/0.0.0.0 +address=/g2.ousns.net/0.0.0.0 +address=/ganjituiguang.ganji.com/0.0.0.0 +address=/gdt.qq.com/0.0.0.0 +address=/get.766.com/0.0.0.0 +address=/gg.0598yu.com/0.0.0.0 +address=/gg.18183.com/0.0.0.0 +address=/gg.cs090.com/0.0.0.0 +address=/gg.gao7.com/0.0.0.0 +address=/gg.kugou.com/0.0.0.0 +address=/gg.sonhoo.com/0.0.0.0 +address=/gg.yxdown.com/0.0.0.0 +address=/ggg.zj.com/0.0.0.0 +address=/ggw.gusuwang.com/0.0.0.0 +address=/ggw.watertu.com/0.0.0.0 +address=/ggyq.xdkb.net/0.0.0.0 +address=/go.hangzhou.com.cn/0.0.0.0 +address=/goto.www.iciba.com/0.0.0.0 +address=/gqgc.sz.zj.cn/0.0.0.0 +address=/groupa.onlylady.com/0.0.0.0 +address=/gsspcln.jp/0.0.0.0 +address=/gt.yy.com/0.0.0.0 +address=/guess.h.qhimg.com/0.0.0.0 +address=/haxiu.miaotiao.com/0.0.0.0 +address=/hdad.baike.com/0.0.0.0 +address=/hiad.vmall.com/0.0.0.0 +address=/hz.shouyoutv.com/0.0.0.0 +address=/hzhyhm.com/0.0.0.0 +address=/i.syasn.com/0.0.0.0 +address=/iads.xinmin.cn/0.0.0.0 +address=/idcot.com/0.0.0.0 +address=/ifx.aifang.com/0.0.0.0 +address=/image.6park.com/0.0.0.0 +address=/image.9duw.com/0.0.0.0 +address=/image.hh010.com/0.0.0.0 +address=/image.lepan.cc/0.0.0.0 +address=/images.chinaz.com/0.0.0.0 +address=/images.gxsky.com/0.0.0.0 +address=/img.3sjt.com/0.0.0.0 +address=/img.9duw.com/0.0.0.0 +address=/img1.126.net/0.0.0.0 +address=/img2.126.net/0.0.0.0 +address=/img2.www.fmdisk.com/0.0.0.0 +address=/inte.sogou.com/0.0.0.0 +address=/iwanad.baidu.com/0.0.0.0 +address=/j.6avz.com/0.0.0.0 +address=/j.7avz.com/0.0.0.0 +address=/ja.gamersky.com/0.0.0.0 +address=/jmsyzj.com/0.0.0.0 +address=/js-1.pchome.net/0.0.0.0 +address=/js.duotegame.com/0.0.0.0 +address=/js.leshen.com/0.0.0.0 +address=/js.pub.tom.com/0.0.0.0 +address=/js.youxi369.com/0.0.0.0 +address=/jxad.jx163.com/0.0.0.0 +address=/knnwdyou.com/0.0.0.0 +address=/leiqun.snxyf.com/0.0.0.0 +address=/life.e0575.com/0.0.0.0 +address=/lingdian98.com/0.0.0.0 +address=/link.fobshanghai.com/0.0.0.0 +address=/lxting.com/0.0.0.0 +address=/m.aty.sohu.com/0.0.0.0 +address=/manads.static.olcdn.com/0.0.0.0 +address=/manage.wdfans.cn/0.0.0.0 +address=/market.178.com/0.0.0.0 +address=/market.21cn.com/0.0.0.0 +address=/market.duowan.com/0.0.0.0 +address=/media.cheshi-img.com/0.0.0.0 +address=/money.qz828.com/0.0.0.0 +address=/myad.toocle.com/0.0.0.0 +address=/ok.432kkk.com/0.0.0.0 +address=/p.szonline.net/0.0.0.0 +address=/p.zol-img.com.cn/0.0.0.0 +address=/p4p.sina.com.cn/0.0.0.0 +address=/p8u.hinet.net/0.0.0.0 +address=/panda.kdnet.net/0.0.0.0 +address=/pcs1.app.joy.cn/0.0.0.0 +address=/phpad.cqnews.net/0.0.0.0 +address=/pic.0597kk.com/0.0.0.0 +address=/pic.111cn.net/0.0.0.0 +address=/pic.2u.com.cn/0.0.0.0 +address=/pic.ea3w.com/0.0.0.0 +address=/pic.fengniao.com/0.0.0.0 +address=/pic.taian.com/0.0.0.0 +address=/pic.xgo-img.com.cn/0.0.0.0 +address=/playad.xjmg.com/0.0.0.0 +address=/poster.weather.com.cn/0.0.0.0 +address=/pp.7060.la/0.0.0.0 +address=/pro.iweihai.cn/0.0.0.0 +address=/pub.funshion.com/0.0.0.0 +address=/pub.mop.com/0.0.0.0 +address=/publicize.liao1.com/0.0.0.0 +address=/publish.ad.youth.cn/0.0.0.0 +address=/res.hunantv.com/0.0.0.0 +address=/rh.qq.com/0.0.0.0 +address=/same.chinadaily.com.cn/0.0.0.0 +address=/same.eastmoney.com/0.0.0.0 +address=/same.stockstar.com/0.0.0.0 +address=/sc.tom.com/0.0.0.0 +address=/sgg.southcn.com/0.0.0.0 +address=/share.gzdsw.com/0.0.0.0 +address=/shenleyuni.com/0.0.0.0 +address=/shows.21cn.com/0.0.0.0 +address=/so.6949.com/0.0.0.0 +address=/sss.sege.xxx/0.0.0.0 +address=/static.yujiehenaishang.com/0.0.0.0 +address=/sub.powerapple.com/0.0.0.0 +address=/super.cat898.com/0.0.0.0 +address=/super.kdnet.net/0.0.0.0 +address=/synacast.com/0.0.0.0 +address=/tf.360.cn/0.0.0.0 +address=/tg.delnapb.com/0.0.0.0 +address=/tk.504pk.com/0.0.0.0 +address=/tp.sgcn.com/0.0.0.0 +address=/u.63kc.com/0.0.0.0 +address=/u.cnzol.com/0.0.0.0 +address=/union.china.com.cn/0.0.0.0 +address=/untitled.dwstatic.com/0.0.0.0 +address=/up.hiao.com/0.0.0.0 +address=/v-56.com/0.0.0.0 +address=/vas.funshion.com/0.0.0.0 +address=/vupload.duowan.com/0.0.0.0 +address=/web.900.la/0.0.0.0 +address=/xc.macd.cn/0.0.0.0 +address=/xs.houyi.baofeng.net/0.0.0.0 +address=/yktj.yzz.cn/0.0.0.0 +address=/zo66.com/0.0.0.0 +address=/zt2088.com/0.0.0.0 +address=/146.148.85.61/0.0.0.0 +address=/hdapp1003-a.akamaihd.net/0.0.0.0 +address=/hdapp1008-a.akamaihd.net/0.0.0.0 +address=/hdsrc-a.akamaihd.net/0.0.0.0 +address=/46.165.197.153/0.0.0.0 +address=/46.165.197.231/0.0.0.0 +address=/74.117.182.77/0.0.0.0 +address=/78.140.131.214/0.0.0.0 +address=/clkrev.com/0.0.0.0 +address=/a.livesportmedia.eu/0.0.0.0 +address=/a.ucoz.net/0.0.0.0 +address=/a.watershed-publishing.com/0.0.0.0 +address=/a04296f070c0146f314d-0dcad72565cb350972beb3666a86f246.r50.cf5.rackcdn.com/0.0.0.0 +address=/ad.about.co.kr/0.0.0.0 +address=/ad.accessmediaproductions.com/0.0.0.0 +address=/ad.bitmedia.io/0.0.0.0 +address=/ad.flux.com/0.0.0.0 +address=/ad.foxnetworks.com/0.0.0.0 +address=/ad.icasthq.com/0.0.0.0 +address=/ad.idgtn.net/0.0.0.0 +address=/ad.jamba.net/0.0.0.0 +address=/ad.livere.co.kr/0.0.0.0 +address=/ad.mail.ru/0.0.0.0 +address=/ad.mesomorphosis.com/0.0.0.0 +address=/ad.openmultimedia.biz/0.0.0.0 +address=/ad.outsidehub.com/0.0.0.0 +address=/ad.pickple.net/0.0.0.0 +address=/ad.proxy.sh/0.0.0.0 +address=/ad.r.worldssl.net/0.0.0.0 +address=/ad.rambler.ru/0.0.0.0 +address=/ad.reklamport.com/0.0.0.0 +address=/ad.sensismediasmart.com.au/0.0.0.0 +address=/ad.smartclip.net/0.0.0.0 +address=/ad.spielothek.so/0.0.0.0 +address=/ad.vidaroo.com/0.0.0.0 +address=/ad.winningpartner.com/0.0.0.0 +address=/add.bugun.com.tr/0.0.0.0 +address=/adingo.jp.eimg.jp/0.0.0.0 +address=/adn.ebay.com/0.0.0.0 +address=/adplus.goo.mx/0.0.0.0 +address=/ads.mp.mydas.mobi/0.0.0.0 +address=/adscaspion.appspot.com/0.0.0.0 +address=/adss.dotdo.net/0.0.0.0 +address=/adz.zwee.ly/0.0.0.0 +address=/aff.eteachergroup.com/0.0.0.0 +address=/aff.marathonbet.com/0.0.0.0 +address=/aff.svjump.com/0.0.0.0 +address=/affil.mupromo.com/0.0.0.0 +address=/affiliateprogram.keywordspy.com/0.0.0.0 +address=/affiliates.allposters.com/0.0.0.0 +address=/affiliatesmedia.sbobet.com/0.0.0.0 +address=/affiliation.fotovista.com/0.0.0.0 +address=/agenda.complex.com/0.0.0.0 +address=/airpushmarketing.s3.amazonaws.com/0.0.0.0 +address=/ais.abacast.com/0.0.0.0 +address=/analytics.disneyinternational.com/0.0.0.0 +address=/ard.ihookup.com/0.0.0.0 +address=/award.sitekeuring.net/0.0.0.0 +address=/b.babylon.com/0.0.0.0 +address=/b.livesport.eu/0.0.0.0 +address=/b92.putniktravel.com/0.0.0.0 +address=/banner.101xp.com/0.0.0.0 +address=/banner.3ddownloads.com/0.0.0.0 +address=/banner.europacasino.com/0.0.0.0 +address=/banner.telefragged.com/0.0.0.0 +address=/banner.titancasino.com/0.0.0.0 +address=/bl.wavecdn.de/0.0.0.0 +address=/blamads-assets.s3.amazonaws.com/0.0.0.0 +address=/bluhostedbanners.blucigs.com/0.0.0.0 +address=/box.anchorfree.net/0.0.0.0 +address=/btr.domywife.com/0.0.0.0 +address=/c.netu.tv/0.0.0.0 +address=/cas.clickability.com/0.0.0.0 +address=/cash.neweramediaworks.com/0.0.0.0 +address=/cerebral.typn.com/0.0.0.0 +address=/cjmooter.xcache.kinxcdn.com/0.0.0.0 +address=/clarity.abacast.com/0.0.0.0 +address=/click.eyk.net/0.0.0.0 +address=/clickstrip.6wav.es/0.0.0.0 +address=/connect.summit.co.uk/0.0.0.0 +address=/content.livesportmedia.eu/0.0.0.0 +address=/cpm.amateurcommunity.de/0.0.0.0 +address=/creatives.inmotionhosting.com/0.0.0.0 +address=/creatives.summitconnect.co.uk/0.0.0.0 +address=/d13czkep7ax7nj.cloudfront.net/0.0.0.0 +address=/d140sbu1b1m3h0.cloudfront.net/0.0.0.0 +address=/d15565yqt7pv7r.cloudfront.net/0.0.0.0 +address=/d15gt9gwxw5wu0.cloudfront.net/0.0.0.0 +address=/d17f2fxw547952.cloudfront.net/0.0.0.0 +address=/d19972r8wdpby8.cloudfront.net/0.0.0.0 +address=/d1ade4ciw4bqyc.cloudfront.net/0.0.0.0 +address=/d1cl1sqtf3o420.cloudfront.net/0.0.0.0 +address=/d1d95giojjkirt.cloudfront.net/0.0.0.0 +address=/d1ep3cn6qx0l3z.cloudfront.net/0.0.0.0 +address=/d1ey3fksimezm4.cloudfront.net/0.0.0.0 +address=/d1fo96xm8fci0r.cloudfront.net/0.0.0.0 +address=/d1gojtoka5qi10.cloudfront.net/0.0.0.0 +address=/d1k74lgicilrr3.cloudfront.net/0.0.0.0 +address=/d1noellhv8fksc.cloudfront.net/0.0.0.0 +address=/d1pcttwib15k25.cloudfront.net/0.0.0.0 +address=/d1pdpbxj733bb1.cloudfront.net/0.0.0.0 +address=/d1spb7fplenrp4.cloudfront.net/0.0.0.0 +address=/d1vbm0eveofcle.cloudfront.net/0.0.0.0 +address=/d1zgderxoe1a.cloudfront.net/0.0.0.0 +address=/d23guct4biwna6.cloudfront.net/0.0.0.0 +address=/d23nyyb6dc29z6.cloudfront.net/0.0.0.0 +address=/d25ruj6ht8bs1.cloudfront.net/0.0.0.0 +address=/d25xkbr68qqtcn.cloudfront.net/0.0.0.0 +address=/d26dzd2k67we08.cloudfront.net/0.0.0.0 +address=/d26j9bp9bq4uhd.cloudfront.net/0.0.0.0 +address=/d26wy0pxd3qqpv.cloudfront.net/0.0.0.0 +address=/d27jt7xr4fq3e8.cloudfront.net/0.0.0.0 +address=/d287x05ve9a63s.cloudfront.net/0.0.0.0 +address=/d29r6igjpnoykg.cloudfront.net/0.0.0.0 +address=/d2anfhdgjxf8s1.cloudfront.net/0.0.0.0 +address=/d2b2x1ywompm1b.cloudfront.net/0.0.0.0 +address=/d2b65ihpmocv7w.cloudfront.net/0.0.0.0 +address=/d2bgg7rjywcwsy.cloudfront.net/0.0.0.0 +address=/d2cxkkxhecdzsq.cloudfront.net/0.0.0.0 +address=/d2d2lbvq8xirbs.cloudfront.net/0.0.0.0 +address=/d2dxgm96wvaa5j.cloudfront.net/0.0.0.0 +address=/d2gpgaupalra1d.cloudfront.net/0.0.0.0 +address=/d2gtlljtkeiyzd.cloudfront.net/0.0.0.0 +address=/d2gz6iop9uxobu.cloudfront.net/0.0.0.0 +address=/d2hap2bsh1k9lw.cloudfront.net/0.0.0.0 +address=/d2ipklohrie3lo.cloudfront.net/0.0.0.0 +address=/d2mic0r0bo3i6z.cloudfront.net/0.0.0.0 +address=/d2mq0uzafv8ytp.cloudfront.net/0.0.0.0 +address=/d2nlytvx51ywh9.cloudfront.net/0.0.0.0 +address=/d2o307dm5mqftz.cloudfront.net/0.0.0.0 +address=/d2oallm7wrqvmi.cloudfront.net/0.0.0.0 +address=/d2omcicc3a4zlg.cloudfront.net/0.0.0.0 +address=/d2pgy8h4i30on1.cloudfront.net/0.0.0.0 +address=/d2plxos94peuwp.cloudfront.net/0.0.0.0 +address=/d2r359adnh3sfn.cloudfront.net/0.0.0.0 +address=/d2s64zaa9ua7uv.cloudfront.net/0.0.0.0 +address=/d2tgev5wuprbqq.cloudfront.net/0.0.0.0 +address=/d2tnimpzlb191i.cloudfront.net/0.0.0.0 +address=/d2ubicnllnnszy.cloudfront.net/0.0.0.0 +address=/d2ue9k1rhsumed.cloudfront.net/0.0.0.0 +address=/d2v4glj2m8yzg5.cloudfront.net/0.0.0.0 +address=/d2v9ajh2eysdau.cloudfront.net/0.0.0.0 +address=/d2vt6q0n0iy66w.cloudfront.net/0.0.0.0 +address=/d2yhukq7vldf1u.cloudfront.net/0.0.0.0 +address=/d2z1smm3i01tnr.cloudfront.net/0.0.0.0 +address=/d31807xkria1x4.cloudfront.net/0.0.0.0 +address=/d32pxqbknuxsuy.cloudfront.net/0.0.0.0 +address=/d33f10u0pfpplc.cloudfront.net/0.0.0.0 +address=/d33otidwg56k90.cloudfront.net/0.0.0.0 +address=/d34obr29voew8l.cloudfront.net/0.0.0.0 +address=/d34rdvn2ky3gnm.cloudfront.net/0.0.0.0 +address=/d37kzqe5knnh6t.cloudfront.net/0.0.0.0 +address=/d38pxm3dmrdu6d.cloudfront.net/0.0.0.0 +address=/d38r21vtgndgb1.cloudfront.net/0.0.0.0 +address=/d39xqloz8t5a6x.cloudfront.net/0.0.0.0 +address=/d3bvcf24wln03d.cloudfront.net/0.0.0.0 +address=/d3dphmosjk9rot.cloudfront.net/0.0.0.0 +address=/d3f9mcik999dte.cloudfront.net/0.0.0.0 +address=/d3fzrm6pcer44x.cloudfront.net/0.0.0.0 +address=/d3irruagotonpp.cloudfront.net/0.0.0.0 +address=/d3iwjrnl4m67rd.cloudfront.net/0.0.0.0 +address=/d3lvr7yuk4uaui.cloudfront.net/0.0.0.0 +address=/d3lzezfa753mqu.cloudfront.net/0.0.0.0 +address=/d3m41swuqq4sv5.cloudfront.net/0.0.0.0 +address=/d3nvrqlo8rj1kw.cloudfront.net/0.0.0.0 +address=/d3p9ql8flgemg7.cloudfront.net/0.0.0.0 +address=/d3pkae9owd2lcf.cloudfront.net/0.0.0.0 +address=/d3q2dpprdsteo.cloudfront.net/0.0.0.0 +address=/d3qszud4qdthr8.cloudfront.net/0.0.0.0 +address=/d3t2wca0ou3lqz.cloudfront.net/0.0.0.0 +address=/d3t9ip55bsuxrf.cloudfront.net/0.0.0.0 +address=/d3tdefw8pwfkbk.cloudfront.net/0.0.0.0 +address=/d3vc1nm9xbncz5.cloudfront.net/0.0.0.0 +address=/d5pvnbpawsaav.cloudfront.net/0.0.0.0 +address=/d6bdy3eto8fyu.cloudfront.net/0.0.0.0 +address=/d8qy7md4cj3gz.cloudfront.net/0.0.0.0 +address=/dal9hkyfi0m0n.cloudfront.net/0.0.0.0 +address=/dart.clearchannel.com/0.0.0.0 +address=/dasfdasfasdf.no-ip.info/0.0.0.0 +address=/data.neuroxmedia.com/0.0.0.0 +address=/dbam.dashbida.com/0.0.0.0 +address=/ddwht76d9jvfl.cloudfront.net/0.0.0.0 +address=/dew9ckzjyt2gn.cloudfront.net/0.0.0.0 +address=/dff7tx5c2qbxc.cloudfront.net/0.0.0.0 +address=/display.digitalriver.com/0.0.0.0 +address=/disy2s34euyqm.cloudfront.net/0.0.0.0 +address=/dizixdllzznrf.cloudfront.net/0.0.0.0 +address=/djlf5xdlz7m8m.cloudfront.net/0.0.0.0 +address=/dkd69bwkvrht1.cloudfront.net/0.0.0.0 +address=/dkdwv3lcby5zi.cloudfront.net/0.0.0.0 +address=/dl392qndlveq0.cloudfront.net/0.0.0.0 +address=/dl5v5atodo7gn.cloudfront.net/0.0.0.0 +address=/dlupv9uqtjlie.cloudfront.net/0.0.0.0 +address=/dm0acvguygm9h.cloudfront.net/0.0.0.0 +address=/dm8srf206hien.cloudfront.net/0.0.0.0 +address=/dp51h10v6ggpa.cloudfront.net/0.0.0.0 +address=/dpsq2uzakdgqz.cloudfront.net/0.0.0.0 +address=/dq2tgxnc2knif.cloudfront.net/0.0.0.0 +address=/dqhi3ea93ztgv.cloudfront.net/0.0.0.0 +address=/dr8pk6ovub897.cloudfront.net/0.0.0.0 +address=/duct5ntjian71.cloudfront.net/0.0.0.0 +address=/dvf2u7vwmkr5w.cloudfront.net/0.0.0.0 +address=/dvt4pepo9om3r.cloudfront.net/0.0.0.0 +address=/dx5qvhwg92mjd.cloudfront.net/0.0.0.0 +address=/dxq6c0tx3v6mm.cloudfront.net/0.0.0.0 +address=/dxqd86uz345mg.cloudfront.net/0.0.0.0 +address=/dy48bnzanqw0v.cloudfront.net/0.0.0.0 +address=/dycpc40hvg4ki.cloudfront.net/0.0.0.0 +address=/dyl3p6so5yozo.cloudfront.net/0.0.0.0 +address=/epowernetworktrackerimages.s3.amazonaws.com/0.0.0.0 +address=/euwidget.imshopping.com/0.0.0.0 +address=/events.kalooga.com/0.0.0.0 +address=/ext.theglobalweb.com/0.0.0.0 +address=/feeds.logicbuy.com/0.0.0.0 +address=/ft.pnop.com/0.0.0.0 +address=/gateway.fortunelounge.com/0.0.0.0 +address=/gateways.s3.amazonaws.com/0.0.0.0 +address=/geo.connexionsecure.com/0.0.0.0 +address=/geobanner.friendfinder.com/0.0.0.0 +address=/geobanner.passion.com/0.0.0.0 +address=/gfaf-banners.s3.amazonaws.com/0.0.0.0 +address=/homad-global-configs.schneevonmorgen.com/0.0.0.0 +address=/im.ov.yahoo.co.jp/0.0.0.0 +address=/ima3vpaid.appspot.com/0.0.0.0 +address=/indieclick.3janecdn.com/0.0.0.0 +address=/inskin.vo.llnwd.net/0.0.0.0 +address=/k2team.kyiv.ua/0.0.0.0 +address=/mads.aol.com/0.0.0.0 +address=/marketing.888.com/0.0.0.0 +address=/mb.zam.com/0.0.0.0 +address=/mozo-widgets.f2.com.au/0.0.0.0 +address=/network.aufeminin.com/0.0.0.0 +address=/network.business.com/0.0.0.0 +address=/oclasrv.comindex-2.htmlapu.php/0.0.0.0 +address=/odin.goo.mx/0.0.0.0 +address=/on.maxspeedcdn.com/0.0.0.0 +address=/ox-i.cordillera.tv/0.0.0.0 +address=/partner.bargaindomains.com/0.0.0.0 +address=/partner.catchy.com/0.0.0.0 +address=/partner.premiumdomains.com/0.0.0.0 +address=/partnerads.ysm.yahoo.com/0.0.0.0 +address=/partnerads1.ysm.yahoo.com/0.0.0.0 +address=/partners.fshealth.com/0.0.0.0 +address=/partners.optiontide.com/0.0.0.0 +address=/partners.rochen.com/0.0.0.0 +address=/partners.sportingbet.com.au/0.0.0.0 +address=/partners.vouchedfor.co.uk/0.0.0.0 +address=/partners.xpertmarket.com/0.0.0.0 +address=/priceinfo.comuv.com/0.0.0.0 +address=/promos.fling.com/0.0.0.0 +address=/promote.pair.com/0.0.0.0 +address=/promotions.iasbet.com/0.0.0.0 +address=/pub.betclick.com/0.0.0.0 +address=/pubs.hiddennetwork.com/0.0.0.0 +address=/rack.bauermedia.co.uk/0.0.0.0 +address=/res3.feedsportal.com/0.0.0.0 +address=/revealads.appspot.com/0.0.0.0 +address=/rotabanner.kulichki.net/0.0.0.0 +address=/rotator.tradetracker.net/0.0.0.0 +address=/s-yoolk-banner-assets.yoolk.com/0.0.0.0 +address=/s-yoolk-billboard-assets.yoolk.com/0.0.0.0 +address=/secretmedia.s3.amazonaws.com/0.0.0.0 +address=/servedby.keygamesnetwork.com/0.0.0.0 +address=/sitescout-video-cdn.edgesuite.net/0.0.0.0 +address=/slot.union.ucweb.com/0.0.0.0 +address=/smart.styria-digital.com/0.0.0.0 +address=/squarespace.evyy.net/0.0.0.0 +address=/stats.hosting24.com/0.0.0.0 +address=/stats.sitesuite.org/0.0.0.0 +address=/stuff-nzwhistleout.s3.amazonaws.com/0.0.0.0 +address=/survey.g.doubleclick.net/0.0.0.0 +address=/syndication.jsadapi.com/0.0.0.0 +address=/syndication1.viraladnetwork.net/0.0.0.0 +address=/tap.more-results.net/0.0.0.0 +address=/ti.tradetracker.net/0.0.0.0 +address=/track.bcvcmedia.com/0.0.0.0 +address=/twinplan.com/0.0.0.0 +address=/vendor1.fitschigogerl.com/0.0.0.0 +address=/web-jp.ad-v.jp/0.0.0.0 +address=/whistleout.s3.amazonaws.com/0.0.0.0 +address=/widget.crowdignite.com/0.0.0.0 +address=/widget.kelkoo.com/0.0.0.0 +address=/widget.raaze.com/0.0.0.0 +address=/widget.searchschoolsnetwork.com/0.0.0.0 +address=/widget.shopstyle.com.au/0.0.0.0 +address=/widget.solarquotes.com.au/0.0.0.0 +address=/widgets.realestate.com.au/0.0.0.0 +address=/wtpn.twenga.co.uk/0.0.0.0 +address=/wtpn.twenga.de/0.0.0.0 +address=/yb.torchbrowser.com/0.0.0.0 +address=/yeas.yahoo.co.jp/0.0.0.0 +address=/zapads.zapak.com/0.0.0.0 +address=/zeus.qj.net/0.0.0.0 +address=/iadc.qwapi.com/0.0.0.0 +address=/d1nmk7iw7hajjn.cloudfront.net/0.0.0.0 +address=/ad.duga.jp/0.0.0.0 +address=/ad.iloveinterracial.com/0.0.0.0 +address=/ads.videosz.com/0.0.0.0 +address=/affiliates.thrixxx.com/0.0.0.0 +address=/ard.sweetdiscreet.com/0.0.0.0 +address=/bannershotlink.perfectgonzo.com/0.0.0.0 +address=/blaaaa12.googlecode.com/0.0.0.0 +address=/br.blackfling.com/0.0.0.0 +address=/br.fling.com/0.0.0.0 +address=/br.realitykings.com/0.0.0.0 +address=/cpm.amateurcommunity.com/0.0.0.0 +address=/dailyvideo.securejoin.com/0.0.0.0 +address=/desk.cmix.org/0.0.0.0 +address=/feeds.videosz.com/0.0.0.0 +address=/ff.nsg.org.ua/0.0.0.0 +address=/freexxxvideoclip.aebn.net/0.0.0.0 +address=/geo.cliphunter.com/0.0.0.0 +address=/geo.frtya.com/0.0.0.0 +address=/geobanner.adultfriendfinder.com/0.0.0.0 +address=/geobanner.alt.com/0.0.0.0 +address=/geobanner.socialflirt.com/0.0.0.0 +address=/partners.pornerbros.com/0.0.0.0 +address=/s1magnettvcom.maynemyltf.netdna-cdn.com/0.0.0.0 +address=/surv.xbizmedia.com/0.0.0.0 +address=/sweet.game-rust.ru/0.0.0.0 +address=/widgets.comcontent.net/0.0.0.0 +address=/widgetssec.cam-content.com/0.0.0.0 +address=/a.cdngeek.net/0.0.0.0 +address=/a.clipconverter.cc/0.0.0.0 +address=/a.giantrealm.com/0.0.0.0 +address=/a.i-sgcm.com/0.0.0.0 +address=/a.kat.cr/0.0.0.0 +address=/a.kickass.to/0.0.0.0 +address=/a.lolwot.com/0.0.0.0 +address=/ac2.msn.com/0.0.0.0 +address=/access.njherald.com/0.0.0.0 +address=/ad.cooks.com/0.0.0.0 +address=/ad.digitimes.com.tw/0.0.0.0 +address=/ad.directmirror.com/0.0.0.0 +address=/ad.download.cnet.com/0.0.0.0 +address=/ad.evozi.com/0.0.0.0 +address=/ad.fnnews.com/0.0.0.0 +address=/ad.jamster.com/0.0.0.0 +address=/ad.lyricswire.com/0.0.0.0 +address=/ad.mangareader.net/0.0.0.0 +address=/ad.newegg.com/0.0.0.0 +address=/ad.pandora.tv/0.0.0.0 +address=/ad.reachlocal.com/0.0.0.0 +address=/ad.search.ch/0.0.0.0 +address=/ad.services.distractify.com/0.0.0.0 +address=/adcitrus.com/0.0.0.0 +address=/addirector.vindicosuite.com/0.0.0.0 +address=/adds.weatherology.com/0.0.0.0 +address=/adlink.shopsafe.co.nz/0.0.0.0 +address=/admeta.vo.llnwd.net/0.0.0.0 +address=/ads-rolandgarros.com/0.0.0.0 +address=/ads.pof.com/0.0.0.0 +address=/ads.yahoo.com/0.0.0.0 +address=/ads.zynga.com/0.0.0.0 +address=/adsatt.abcnews.starwave.com/0.0.0.0 +address=/adsatt.espn.starwave.com/0.0.0.0 +address=/adshare.freedocast.com/0.0.0.0 +address=/adsor.openrunner.com/0.0.0.0 +address=/adss.yahoo.com/0.0.0.0 +address=/adstil.indiatimes.com/0.0.0.0 +address=/adtest.theonion.com/0.0.0.0 +address=/advertise.twitpic.com/0.0.0.0 +address=/advice-ads-cdn.vice.com/0.0.0.0 +address=/adx.kat.ph/0.0.0.0 +address=/aff.lmgtfy.com/0.0.0.0 +address=/ajnad.aljazeera.net/0.0.0.0 +address=/amz.steamprices.com/0.0.0.0 +address=/analytics.mmosite.com/0.0.0.0 +address=/as.inbox.com/0.0.0.0 +address=/asd.projectfreetv.so/0.0.0.0 +address=/avpa.dzone.com/0.0.0.0 +address=/b.localpages.com/0.0.0.0 +address=/b.thefile.me/0.0.0.0 +address=/ba.ccm2.net/0.0.0.0 +address=/ba.kioskea.net/0.0.0.0 +address=/banner.automotiveworld.com/0.0.0.0 +address=/banner.itweb.co.za/0.0.0.0 +address=/banners.beevpn.com/0.0.0.0 +address=/banners.beted.com/0.0.0.0 +address=/banners.clubworldgroup.com/0.0.0.0 +address=/banners.expressindia.com/0.0.0.0 +address=/banners.i-comers.com/0.0.0.0 +address=/banners.itweb.co.za/0.0.0.0 +address=/banners.playocio.com/0.0.0.0 +address=/beap.gemini.yahoo.com/0.0.0.0 +address=/bizanti.youwatch.org/0.0.0.0 +address=/bnrs.ilm.ee/0.0.0.0 +address=/bwp.theinsider.com.com/0.0.0.0 +address=/cadvv.heraldm.com/0.0.0.0 +address=/cadvv.koreaherald.com/0.0.0.0 +address=/canvas.thenextweb.com/0.0.0.0 +address=/click.livedoor.com/0.0.0.0 +address=/clicks.superpages.com/0.0.0.0 +address=/cnetwidget.creativemark.co.uk/0.0.0.0 +address=/collector.viki.io/0.0.0.0 +address=/creatives.livejasmin.com/0.0.0.0 +address=/d.annarbor.com/0.0.0.0 +address=/d.businessinsider.com/0.0.0.0 +address=/d.gossipcenter.com/0.0.0.0 +address=/d.thelocal.com/0.0.0.0 +address=/dads.new.digg.com/0.0.0.0 +address=/dailydeals.amarillo.com/0.0.0.0 +address=/dailydeals.augustachronicle.com/0.0.0.0 +address=/dailydeals.brainerddispatch.com/0.0.0.0 +address=/dailydeals.lubbockonline.com/0.0.0.0 +address=/dailydeals.onlineathens.com/0.0.0.0 +address=/dailydeals.savannahnow.com/0.0.0.0 +address=/dcad.watersoul.com/0.0.0.0 +address=/deals.ledgertranscript.com/0.0.0.0 +address=/digdug.divxnetworks.com/0.0.0.0 +address=/display.superbay.net/0.0.0.0 +address=/dontblockme.modaco.com/0.0.0.0 +address=/ehow.com/media/ad.html/0.0.0.0 +address=/eva.ucas.com/0.0.0.0 +address=/fan.twitch.tv/0.0.0.0 +address=/fimserve.ign.com/0.0.0.0 +address=/findnsave.idahostatesman.com/0.0.0.0 +address=/g.brothersoft.com/0.0.0.0 +address=/gameads.digyourowngrave.com/0.0.0.0 +address=/geoshopping.nzherald.co.nz/0.0.0.0 +address=/get.thefile.me/0.0.0.0 +address=/gfx.infomine.com/0.0.0.0 +address=/green.virtual-nights.com/0.0.0.0 +address=/hejban.youwatch.org/0.0.0.0 +address=/ibanners.empoweredcomms.com.au/0.0.0.0 +address=/iframe.travel.yahoo.com/0.0.0.0 +address=/imads.rediff.com/0.0.0.0 +address=/kat-ads.torrenticity.com/0.0.0.0 +address=/keepthelighton.vpsboard.com/0.0.0.0 +address=/kermit.macnn.com/0.0.0.0 +address=/life.imagepix.org/0.0.0.0 +address=/ll.a.hulu.com/0.0.0.0 +address=/londonprivaterentals.standard.co.uk/0.0.0.0 +address=/looky.hyves.org/0.0.0.0 +address=/lw2.gamecopyworld.com/0.0.0.0 +address=/mads.dailymail.co.uk/0.0.0.0 +address=/marketingsolutions.yahoo.com/0.0.0.0 +address=/mb.hockeybuzz.com/0.0.0.0 +address=/mealsandsteals.sandiego6.com/0.0.0.0 +address=/media-delivery.armorgames.com/0.0.0.0 +address=/media-mgmt.armorgames.com/0.0.0.0 +address=/mediamgr.ugo.com/0.0.0.0 +address=/nest.youwatch.org/0.0.0.0 +address=/netspidermm.indiatimes.com/0.0.0.0 +address=/network.sofeminine.co.uk/0.0.0.0 +address=/noram.srv.ysm.yahoo.com/0.0.0.0 +address=/oas.autotrader.co.uk/0.0.0.0 +address=/oas.skyscanner.net/0.0.0.0 +address=/oasc07.citywire.co.uk/0.0.0.0 +address=/oascentral.chron.com/0.0.0.0 +address=/oascentral.hosted.ap.org/0.0.0.0 +address=/oascentral.newsmax.com/0.0.0.0 +address=/ox-d.rantsports.com/0.0.0.0 +address=/ox-d.sbnation.com/0.0.0.0 +address=/ox-d.wetransfer.com/0.0.0.0 +address=/ox.furaffinity.net/0.0.0.0 +address=/partners-z.com/0.0.0.0 +address=/photo.net/equipment/pg-160/0.0.0.0 +address=/player.1800coupon.com/0.0.0.0 +address=/player.1stcreditrepairs.com/0.0.0.0 +address=/player.800directories.com/0.0.0.0 +address=/player.accoona.com/0.0.0.0 +address=/player.alloutwedding.com/0.0.0.0 +address=/player.insuranceandhealth.com/0.0.0.0 +address=/pmm.people.com.cn/0.0.0.0 +address=/pop-over.powered-by.justplayzone.com/0.0.0.0 +address=/prerollads.ign.com/0.0.0.0 +address=/promo.fileforum.com/0.0.0.0 +address=/rad.microsoft.com/0.0.0.0 +address=/rad.msn.com/0.0.0.0 +address=/red.bayimg.net/0.0.0.0 +address=/redvase.bravenet.com/0.0.0.0 +address=/richmedia.yimg.com/0.0.0.0 +address=/roia.com/0.0.0.0 +address=/rpt.anchorfree.net/0.0.0.0 +address=/searchignited.com/0.0.0.0 +address=/sebar.thand.info/0.0.0.0 +address=/shoppingpartners2.futurenet.com/0.0.0.0 +address=/sponsors.s2ki.com/0.0.0.0 +address=/sponsors.webosroundup.com/0.0.0.0 +address=/srv.thespacereporter.com/0.0.0.0 +address=/storewidget.pcauthority.com.au/0.0.0.0 +address=/stream.heavenmedia.net/0.0.0.0 +address=/tanzanite.infomine.com/0.0.0.0 +address=/targetedinfo.com/0.0.0.0 +address=/targetedtopic.com/0.0.0.0 +address=/thejesperbay.com/0.0.0.0 +address=/themis.yahoo.com/0.0.0.0 +address=/tmcs.net/0.0.0.0 +address=/tom.itv.com/0.0.0.0 +address=/tracking.hostgator.com/0.0.0.0 +address=/ua.badongo.com/0.0.0.0 +address=/uimserv.net/0.0.0.0 +address=/unicast.ign.com/0.0.0.0 +address=/unicast.msn.com/0.0.0.0 +address=/verdict.abc.go.com/0.0.0.0 +address=/vice-ads-cdn.vice.com/0.0.0.0 +address=/w.homes.yahoo.net/0.0.0.0 +address=/webmaster.extabit.com/0.0.0.0 +address=/widget.directory.dailycommercial.com/0.0.0.0 +address=/x.castanet.net/0.0.0.0 +address=/yea.uploadimagex.com/0.0.0.0 +address=/yesbeby.whies.info/0.0.0.0 +address=/yrt7dgkf.exashare.com/0.0.0.0 +address=/ysm.yahoo.com/0.0.0.0 +address=/zads.care2.com/0.0.0.0 +address=/a.eporner.com/0.0.0.0 +address=/a.heavy-r.com/0.0.0.0 +address=/a.killergram-girls.com/0.0.0.0 +address=/ad.eporner.com/0.0.0.0 +address=/ad.slutload.com/0.0.0.0 +address=/ad.thisav.com/0.0.0.0 +address=/ad.userporn.com/0.0.0.0 +address=/ads.xxxbunker.com/0.0.0.0 +address=/affiliates.goodvibes.com/0.0.0.0 +address=/banner1.pornhost.com/0.0.0.0 +address=/banners.cams.com/0.0.0.0 +address=/bob.crazyshit.com/0.0.0.0 +address=/brcache.madthumbs.com/0.0.0.0 +address=/creatives.cliphunter.com/0.0.0.0 +address=/creatives.pichunter.com/0.0.0.0 +address=/dot.eporner.com/0.0.0.0 +address=/dot2.eporner.com/0.0.0.0 +address=/exit.macandbumble.com/0.0.0.0 +address=/lw1.cdmediaworld.com/0.0.0.0 +address=/m2.xhamster.com/0.0.0.0 +address=/partners.xhamster.com/0.0.0.0 +address=/pr-static.empflix.com/0.0.0.0 +address=/pr-static.tnaflix.com/0.0.0.0 +address=/r.radikal.ru/0.0.0.0 +address=/rev.fapdu.com/0.0.0.0 +address=/site.img.4tube.com/0.0.0.0 +address=/static.kinghost.com/0.0.0.0 +address=/x.eroticity.net/0.0.0.0 +address=/x.vipergirls.to/0.0.0.0 diff --git a/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/dnsmasq.ads b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/dnsmasq.ads new file mode 100644 index 000000000..ec1a22189 --- /dev/null +++ b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/dnsmasq.ads @@ -0,0 +1,4 @@ +address=/p.tanx.com/0.0.0.0 +address=/googlesyndication.com/0.0.0.0 +address=/linkvans.com/0.0.0.0 +server=/valf.atm.youku.com/114.114.114.114 diff --git a/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/dnsmasq.esc b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/dnsmasq.esc new file mode 100644 index 000000000..6cfd87056 --- /dev/null +++ b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/dnsmasq.esc @@ -0,0 +1,3 @@ +ipset=/weixin.qq.com/adbyby_wan +ipset=/qpic.cn/adbyby_wan +ipset=/imtt.qq.com/adbyby_wan diff --git a/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/firewall.include b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/firewall.include new file mode 100755 index 000000000..8cac33c72 --- /dev/null +++ b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/firewall.include @@ -0,0 +1,13 @@ +#!/bin/sh + +adbyby_enable=$(uci get adbyby.@adbyby[0].enable) + +if [ $adbyby_enable -eq 1 ]; then + if pidof adbyby>/dev/null; then + /etc/init.d/adbyby reload_rule + else + /etc/init.d/adbyby restart + fi +fi + + diff --git a/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/rules.txt b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/rules.txt new file mode 100644 index 000000000..5c44b0e8c --- /dev/null +++ b/package/lean/luci-app-adbyby-plus/root/usr/share/adbyby/rules.txt @@ -0,0 +1,15 @@ +! ------------------------------ ADByby 鑷畾涔夎繃婊よ娉曠畝琛--------------------------------- +! -------------- 瑙勫垯鍩轰簬abp瑙勫垯锛屽苟杩涜浜嗗瓧绗︽浛鎹㈤儴鍒嗙殑鎵╁睍----------------------------- +! ABP瑙勫垯璇峰弬鑰僪ttps://adblockplus.org/zh_CN/filters锛屼笅闈负澶ц嚧鎽樿 +! "!" 涓鸿娉ㄩ噴绗︼紝娉ㄩ噴琛屼互璇ョ鍙疯捣濮嬩綔涓轰竴琛屾敞閲婅涔夛紝鐢ㄤ簬瑙勫垯鎻忚堪 +! "*" 涓哄瓧绗﹂氶厤绗︼紝鑳藉鍖归厤0闀垮害鎴栦换鎰忛暱搴︾殑瀛楃涓诧紝璇ラ氶厤绗︿笉鑳戒笌姝e垯璇硶娣风敤銆 +! "^" 涓哄垎闅旂锛屽彲浠ユ槸闄や簡瀛楁瘝銆佹暟瀛楁垨鑰 _ - . % 涔嬪鐨勪换浣曞瓧绗︺ +! "|" 涓虹绾跨鍙凤紝鏉ヨ〃绀哄湴鍧鐨勬渶鍓嶇鎴栨渶鏈 +! "||" 涓哄瓙鍩熼氶厤绗︼紝鏂逛究鍖归厤涓诲煙鍚嶄笅鐨勬墍鏈夊瓙鍩熴 +! "~" 涓烘帓闄ゆ爣璇嗙锛岄氶厤绗﹁兘杩囨护澶у鏁板箍鍛婏紝浣嗗悓鏃跺瓨鍦ㄨ鏉, 鍙互閫氳繃鎺掗櫎鏍囪瘑绗︿慨姝h鏉閾炬帴銆 +! "##" 涓哄厓绱犻夋嫨鍣ㄦ爣璇嗙锛屽悗闈㈣窡闇瑕侀殣钘忓厓绱犵殑CSS鏍峰紡渚嬪 #ad_id .ad_class +!! 鍏冪礌闅愯棌鏆備笉鏀寔鍏ㄥ眬瑙勫垯鍜屾帓闄よ鍒 +!! 瀛楃鏇挎崲鎵╁睍 +! 鏂囨湰鏇挎崲閫夋嫨鍣ㄦ爣璇嗙锛屽悗闈㈣窡闇瑕佹浛鎹㈢殑鏂囨湰鏁版嵁锛屾牸寮忥細$s@妯″紡瀛楃涓睝鏇挎崲鍚庣殑鏂囨湰@ +! 鏀寔閫氶厤绗*鍜岋紵 +! ------------------------------------------------------------------------------------------- diff --git a/package/lean/luci-app-aliddns/Makefile b/package/lean/luci-app-aliddns/Makefile new file mode 100644 index 000000000..e3f10e5d2 --- /dev/null +++ b/package/lean/luci-app-aliddns/Makefile @@ -0,0 +1,19 @@ +# +# Copyright (C) 2008-2014 The LuCI Team +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI for Aliddns +LUCI_DEPENDS:=+wget +openssl-util +LUCI_PKGARCH:=all +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature + + diff --git a/package/lean/luci-app-aliddns/luasrc/controller/aliddns.lua b/package/lean/luci-app-aliddns/luasrc/controller/aliddns.lua new file mode 100644 index 000000000..c62864560 --- /dev/null +++ b/package/lean/luci-app-aliddns/luasrc/controller/aliddns.lua @@ -0,0 +1,4 @@ +module("luci.controller.aliddns",package.seeall) +function index() +entry({"admin","services","aliddns"},cbi("aliddns"),_("Aliddns Client"),101) +end diff --git a/package/lean/luci-app-aliddns/luasrc/model/cbi/aliddns.lua b/package/lean/luci-app-aliddns/luasrc/model/cbi/aliddns.lua new file mode 100644 index 000000000..76b386ef8 --- /dev/null +++ b/package/lean/luci-app-aliddns/luasrc/model/cbi/aliddns.lua @@ -0,0 +1,52 @@ +local a=require"luci.sys" +local e=luci.model.uci.cursor() +local e=require"nixio.fs" +require("luci.sys") +local t,e,o +local m,s +t=Map("aliddns",translate("闃块噷DDNS瀹㈡埛绔"),translate("鍩轰簬闃块噷浜戣В鏋愮殑绉佷汉DDNS瑙e喅鏂规")) + +e=t:section(TypedSection,"base") +e.anonymous=true + +e:tab("basic", translate("璁剧疆")) + +enable=e:taboption("basic",Flag,"enable",translate("寮鍚"),translate("寮鍚垨鍏抽棴aliddns鍔ㄦ佸煙鍚")) +enable.rmempty=false +token=e:taboption("basic",Value,"app_key",translate("APP KEY")) +email=e:taboption("basic",Value,"app_secret",translate("APP SECRET")) +iface=e:taboption("basic",ListValue,"interface",translate("閫夋嫨澶栫綉鎺ュ彛"),translate("闄愬畾瑕佸姩鎬乤liddns鐨勫缃戞帴鍙o紝濡俻ppoe-wan")) +iface:value("",translate("閫夋嫨瑕佸姩鎬佹洿鏂扮殑澶栫綉鎺ュ彛")) +for t,e in ipairs(a.net.devices())do +if e~="lo"then iface:value(e)end +end +iface.rmempty=false +main=e:taboption("basic",Value,"main_domain",translate("涓诲煙鍚"),"鎯宠瑙f瀽鐨勪富鍩熷悕锛屼緥濡:baidu.com") +main.rmempty=false +sub=e:taboption("basic",Value,"sub_domain",translate("瀛愬煙鍚"),"鎯宠瑙f瀽鐨勫瓙鍩熷悕锛屼緥濡:test hehe") +sub.rmempty=false +time=e:taboption("basic",Value,"time",translate("妫鏌ユ椂闂"),"鍩熷悕妫鏌ユ椂闂达紝鍗曚綅鍒嗛挓锛岃寖鍥1-59") +time.rmempty=false + +e:tab("log", translate("鏇存柊璁板綍")) +--e=t:section(TypedSection,"base",translate("鏇存柊璁板綍")) +e.anonymous=true +local a="/var/log/aliddns.log" +tvlog=e:taboption("log",TextValue,"sylogtext") +tvlog.rows=14 +tvlog.readonly="readonly" +tvlog.wrap="off" +function tvlog.cfgvalue(e,e) +sylogtext="" +if a and nixio.fs.access(a)then +sylogtext=luci.sys.exec("tail -n 100 %s"%a) +end +return sylogtext +end +tvlog.write=function(e,e,e) +end +local e=luci.http.formvalue("cbi.apply") +if e then +io.popen("/etc/init.d/aliddns restart") +end +return t diff --git a/package/lean/luci-app-aliddns/po/zh-cn/aliddns.po b/package/lean/luci-app-aliddns/po/zh-cn/aliddns.po new file mode 100644 index 000000000..211e10d2c --- /dev/null +++ b/package/lean/luci-app-aliddns/po/zh-cn/aliddns.po @@ -0,0 +1,4 @@ +msgid "Aliddns Client" +msgstr "闃块噷DDNS瀹㈡埛绔" + + diff --git a/package/lean/luci-app-aliddns/root/etc/config/aliddns b/package/lean/luci-app-aliddns/root/etc/config/aliddns new file mode 100644 index 000000000..3dcd7e75a --- /dev/null +++ b/package/lean/luci-app-aliddns/root/etc/config/aliddns @@ -0,0 +1,10 @@ + +config base 'base' + option time '30' + option enable '0' + option app_key '1' + option app_secret '1' + option interface 'br-lan' + option main_domain '1.com' + option sub_domain '2' + diff --git a/package/lean/luci-app-aliddns/root/etc/init.d/aliddns b/package/lean/luci-app-aliddns/root/etc/init.d/aliddns new file mode 100755 index 000000000..93bb659e6 --- /dev/null +++ b/package/lean/luci-app-aliddns/root/etc/init.d/aliddns @@ -0,0 +1,18 @@ +#!/bin/sh /etc/rc.common + +START=80 + +restart() +{ + /usr/sbin/aliddns +} + +start() +{ + /usr/sbin/aliddns +} + +stop() +{ + /usr/sbin/aliddns +} diff --git a/package/lean/luci-app-aliddns/root/etc/uci-defaults/luci-app-aliddns b/package/lean/luci-app-aliddns/root/etc/uci-defaults/luci-app-aliddns new file mode 100755 index 000000000..c8dcb1e17 --- /dev/null +++ b/package/lean/luci-app-aliddns/root/etc/uci-defaults/luci-app-aliddns @@ -0,0 +1,5 @@ +#!/bin/sh + + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/package/lean/luci-app-aliddns/root/usr/sbin/aliddns b/package/lean/luci-app-aliddns/root/usr/sbin/aliddns new file mode 100755 index 000000000..3c5c5a258 --- /dev/null +++ b/package/lean/luci-app-aliddns/root/usr/sbin/aliddns @@ -0,0 +1,126 @@ +#!/bin/sh + +aliddns_ak=`uci get aliddns.base.app_key 2>/dev/null` +aliddns_sk=`uci get aliddns.base.app_secret 2>/dev/null` +aliddns_record_id=`uci get aliddns.base.record_id 2>/dev/null` +time=`uci get aliddns.base.time 2>/dev/null` +aliddns_enable=`uci get aliddns.base.enable` +aliddns_domain=`uci get aliddns.base.main_domain 2>/dev/null` +aliddns_name=`uci get aliddns.base.sub_domain 2>/dev/null` +interface=`uci get aliddns.base.interface 2>/dev/null` +DATE=$(date +'%Y-%m-%d %H:%M:%S') +timestamp=`date -u "+%Y-%m-%dT%H%%3A%M%%3A%SZ"` +ip=$(ifconfig $interface 2> /dev/null | grep 'inet addr' | awk '{print $2}' | cut -d: -f2 2>/dev/null) + +check_aliddns() { +#ip=`wget -qO- http://whatismyip.akamai.com/ 2>/dev/null` +current_ip=`nslookup $aliddns_name.$aliddns_domain | grep "Address 1"|tail -n1|cut -d' ' -f3 2>/dev/null` +echo "$DATE 褰撳墠璺敱IP: ${ip}" >> /var/log/aliddns.log +echo "$DATE 杩滅▼瑙f瀽IP: ${current_ip}" >> /var/log/aliddns.log +if [ "$ip" = "$current_ip" ] +then + echo "$DATE IP鏈敼鍙橈紝鏃犻渶鏇存柊" >> /var/log/aliddns.log + exit 0 + else + echo "$DATE 鏇存柊涓..." >> /var/log/aliddns.log +fi +} + +urlencode() { + # urlencode + + local length="${#1}" + i=0 + out="" + for i in $(awk "BEGIN { for ( i=0; i<$length; i++ ) { print i; } }") + do + local c="${1:$i:1}" + case $c in + [a-zA-Z0-9._-]) out="$out$c" ;; + *) out="$out`printf '%%%02X' "'$c"`" ;; + esac + i=$(($i + 1)) + done + echo -n $out +} + +send_request() { + local args="AccessKeyId=$aliddns_ak&Action=$1&Format=json&$2&Version=2015-01-09" + local hash=$(urlencode $(echo -n "GET&%2F&$(urlencode $args)" | openssl dgst -sha1 -hmac "$aliddns_sk&" -binary | openssl base64)) + wget -qO- "http://alidns.aliyuncs.com/?$args&Signature=$hash" 2> /dev/null +} + +get_recordid() { + grep -Eo '"RecordId":"[0-9]+"' | cut -d':' -f2 | tr -d '"' +} + +query_recordid() { + send_request "DescribeSubDomainRecords" "SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&SubDomain=$aliddns_name.$aliddns_domain&Timestamp=$timestamp" +} + +update_record() { + send_request "UpdateDomainRecord" "RR=$aliddns_name&RecordId=$1&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&Timestamp=$timestamp&Type=A&Value=$ip" +} + +add_record() { + send_request "AddDomainRecord&DomainName=$aliddns_domain" "RR=$aliddns_name&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&Timestamp=$timestamp&Type=A&Value=$ip" +} + +go_record() { +if [ "$aliddns_record_id" = "" ] +then + aliddns_record_id=`query_recordid | get_recordid` +fi +if [ "$aliddns_record_id" = "" ] +then + aliddns_record_id=`add_record | get_recordid` + echo "$DATE 娣诲姞 record $aliddns_record_id" >> /var/log/aliddns.log +else + update_record $aliddns_record_id + echo "$DATE 鏇存柊 record $aliddns_record_id" >> /var/log/aliddns.log +fi +# save to file +if [ "$aliddns_record_id" = "" ]; then + # failed + echo "$DATE : 鏇存柊鍑洪敊,璇锋鏌ヨ缃紒" >> /var/log/aliddns.log + exit 0 +else + uci set aliddns.base.record_id=$aliddns_record_id + uci commit + echo "$DATE : 鏇存柊鎴愬姛锛($ip)" >> /var/log/aliddns.log +fi +} +#灏嗘墽琛岃剼鏈啓鍏rontab瀹氭椂杩愯 +add_aliddns_cru(){ +wirtecron=$(cat /etc/crontabs/root | grep "$time * * * *" | grep aliddns) +if [ -z "$wirtecron" ];then + sed -i '/aliddns/d' /etc/crontabs/root >/dev/null 2>&1 + echo "*/$time * * * * /usr/sbin/aliddns" >> /etc/crontabs/root +fi +} + +#娓呴櫎杩囧璁板綍 +clean_log(){ +logrow=$(grep -c "" /var/log/aliddns.log) +if [ $logrow -ge 15 ];then + cat /dev/null > /var/log/aliddns.log + echo "$DATE Log鏉℃暟瓒呴檺锛屾竻绌哄鐞嗭紒" >> /var/log/aliddns.log +fi +} + +#鍋滄鏈嶅姟 +stop_aliddns(){ + #鍋滄帀cru閲岀殑浠诲姟 + sed -i '/aliddns/d' /etc/crontabs/root >/dev/null 2>&1 +} + +if [ "$aliddns_enable" != "1" ]; then + stop_aliddns + echo "$DATE : aliddns娌℃湁寮鍚紒" >> /var/log/aliddns.log + else + clean_log + check_aliddns + go_record + add_aliddns_cru +fi + \ No newline at end of file diff --git a/package/lean/luci-app-amule/Makefile b/package/lean/luci-app-amule/Makefile new file mode 100644 index 000000000..bd1e1e63c --- /dev/null +++ b/package/lean/luci-app-amule/Makefile @@ -0,0 +1,15 @@ +# Copyright (C) 2016 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for Amule +LUCI_DEPENDS:=+amule +LUCI_PKGARCH:=all + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature + diff --git a/package/lean/luci-app-amule/luasrc/controller/amule.lua b/package/lean/luci-app-amule/luasrc/controller/amule.lua new file mode 100644 index 000000000..1728c4eaa --- /dev/null +++ b/package/lean/luci-app-amule/luasrc/controller/amule.lua @@ -0,0 +1,160 @@ +--[[ +LuCI - Lua Configuration Interface - amule support + +Copyright 2016 maz-1 + +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 +]]-- + +module("luci.controller.amule", package.seeall) +local uci = luci.model.uci.cursor() +local configdir = uci:get("amule", "main", "config_dir") + +function index() + if not nixio.fs.access("/etc/config/amule") then + return + end + + entry({"admin", "nas"}, firstchild(), "NAS", 45).dependent = false + + local page = entry({"admin", "nas", "amule"}, cbi("amule"), _("aMule Settings")) + page.dependent = true + entry( {"admin", "nas", "amule", "logview"}, call("logread") ).leaf = true + entry( {"admin", "nas", "amule", "status"}, call("get_pid") ).leaf = true + entry( {"admin", "nas", "amule", "amulecmd"}, call("amulecmd") ).leaf = true + entry( {"admin", "nas", "amule", "startstop"}, post("startstop") ).leaf = true + entry( {"admin", "nas", "amule", "down_kad"}, post("down_kad") ).leaf = true + entry( {"admin", "nas", "amule", "down_ed2k"}, post("down_ed2k") ).leaf = true + +end + +-- called by XHR.get from detail_logview.htm +function logread() + -- read application settings + local uci = luci.model.uci.cursor() + local logdir = uci:get("amule", "main", "config_dir") or "/var/run/amule" + uci:unload("amule") + + local ldata=nixio.fs.readfile(logdir .. "/logfile") + if not ldata or #ldata == 0 then + ldata="_nodata_" + end + luci.http.write(ldata) +end + +-- called by XHR.get from detail_startstop.htm +function startstop() + local pid = get_pid(true) + if pid > 0 then + luci.sys.call("/etc/init.d/amule stop") + nixio.nanosleep(1) -- sleep a second + if nixio.kill(pid, 0) then -- still running + nixio.kill(pid, 9) -- send SIGKILL + end + pid = 0 + else + luci.sys.call("/etc/init.d/amule start") + nixio.nanosleep(1) -- sleep a second + pid = tonumber(luci.sys.exec("pidof amuled")) or 0 + if pid > 0 and not nixio.kill(pid, 0) then + pid = 0 -- process did not start + end + end + luci.http.write(tostring(pid)) -- HTTP needs string not number +end + +function down_kad() + url = uci:get("amule", "main", "kad_nodes_url") + data_path = configdir .. "/nodes.dat" + proto = string.gsub(url, "://%S*", "") + proto_opt = ( proto == "https" ) and " --no-check-certificate" or "" + cmd = "wget -O /tmp/down_nodes.dat \"" .. url .. "\"" .. proto_opt .. + " && cat /tmp/down_nodes.dat > " .. "\"" .. data_path .. "\"" + luci.sys.call(cmd) +end + +function down_ed2k() + url = uci:get("amule", "main", "ed2k_servers_url") + data_path = configdir .. "/server.met" + proto = string.gsub(url, "://%S*", "") + proto_opt = ( proto == "https" ) and " --no-check-certificate" or "" + cmd = "wget -O /tmp/down_server.met \"" .. url .. "\"" .. proto_opt .. + " && cat /tmp/down_server.met > " .. "\"" .. data_path .. "\"" + luci.sys.call(cmd) +end + +-- called by XHR.poll from detail_startstop.htm +-- and from lua (with parameter "true") +function get_pid(from_lua) + local pid_amuled = tonumber(luci.sys.exec("pidof amuled")) or 0 + local amuled_stat =false + if pid_amuled > 0 and not nixio.kill(pid_amuled, 0) then + pid_amuled = 0 + end + + if pid_amuled > 0 then + amuled_stat =true + else + amuled_stat =false + end + + local pid_amuleweb = tonumber(luci.sys.exec("pidof amuleweb")) or 0 + local amuleweb_stat = false + if pid_amuleweb > 0 and not nixio.kill(pid_amuleweb, 0) then + pid_amuleweb = 0 + end + + if pid_amuleweb > 0 then + amuleweb_stat =true + else + amuleweb_stat =false + end + + local status = { + amuled = amuled_stat, + amuled_pid = pid_amuled, + amuleweb = amuleweb_stat + } + + if from_lua then + return pid_amuled + else + luci.http.prepare_content("application/json") + luci.http.write_json(status) + end +end + + +function amulecmd() + local re ="" + local rv = { } + local cmd = luci.http.formvalue("cmd") + local full_cmd = "HOME=\""..configdir.. "\" /usr/bin/amulecmd".." -c \""..cmd.."\" 2>&1" + + local shellpipe = io.popen(full_cmd,"rw") + re = shellpipe:read("*a") + shellpipe:close() + if not re then + re="" + end + + re = string.gsub(re, "This is amulecmd %S*\n", "") + re = string.gsub(re, "Creating client%S*\n", "") + re = string.gsub(re, "Succeeded! Connection established to aMule %S*\n", "") + + re = string.gsub(re, "\n", "\r\n") + + rv[#rv+1]=re + + if #rv > 0 then + luci.http.prepare_content("application/json") + luci.http.write_json(rv) + return + end + + luci.http.status(404, "No such device") +end diff --git a/package/lean/luci-app-amule/luasrc/model/cbi/amule.lua b/package/lean/luci-app-amule/luasrc/model/cbi/amule.lua new file mode 100644 index 000000000..b18138f85 --- /dev/null +++ b/package/lean/luci-app-amule/luasrc/model/cbi/amule.lua @@ -0,0 +1,456 @@ +--[[ +LuCI - Lua Configuration Interface - Aria2 support + +Copyright 2016 maz-1 +]]-- + +local sys = require "luci.sys" +local util = require "luci.util" +local uci = require "luci.model.uci".cursor() + +ptype = { + "socks5", + "socks4", + "http", + "socks4a", +} + +whocan = { + "anyone", + "friends", + "nobody", +} + +function titlesplit(Value) + return "

" .. translate(Value) .. "

" +end + +m = Map("amule", translate("aMule"), translate("aMule is a ED2K/KAD client for all platforms.") .. "
luci interface by maz-1") + +m:section(SimpleSection).template = "amule/overview_status" + +s = m:section(TypedSection, "amule", translate("aMule Settings")) +s.addremove = false +s.anonymous = true + +s:tab("general", translate("General")) +s:tab("connection", translate("Connections")) +s:tab("server", translate("Server")) +s:tab("path_and_file", translate("Path And File")) +s:tab("security", translate("Security")) +s:tab("remote", translate("External Control")) +s:tab("template", translate("Edit Template")) +s:tab("logview", translate("Log File Viewer")) +s:tab("amulecmd", translate("aMule command")) + +-- GENERAL -- + +o = s:taboption("general", Flag, "enabled", translate("Enabled")) +o.rmempty = false + +user = s:taboption("general", ListValue, "runasuser", translate("Run daemon as user")) +local p_user +for _, p_user in util.vspairs(util.split(sys.exec("cat /etc/passwd | cut -f 1 -d :"))) do + user:value(p_user) +end + +o = s:taboption("general", Value, "config_dir", translate("Configuration directory")) +o.rmempty = false +o.placeholder = "/var/run/amule" + +o = s:taboption("general", Value, "mem_percentage", translate("Memory Limit"), translate("Percentage")) +o.rmempty = false +o.placeholder = "50" +o.datatype = "range(1, 99)" + +o = s:taboption("general", Value, "nick", translate("Nickname")) +o.placeholder = "http://www.aMule.org" + +o = s:taboption("general", Value, "max_upload", translate("Max upload speed"), translate("Unlimited when set to 0")) +o.datatype = "uinteger" +o.rmempty = false +o.placeholder = "0" + +o = s:taboption("general", Value, "max_download", translate("Max download speed"), translate("Unlimited when set to 0")) +o.datatype = "uinteger" +o.rmempty = false +o.placeholder = "0" + +o = s:taboption("general", Value, "slot_allocation", translate("Slot allocation")) +o.datatype = "uinteger" +o.rmempty = false +o.placeholder = "2" + +o = s:taboption("general", Value, "max_connections", translate("Max connections")) +o.datatype = "uinteger" +o.rmempty = false +o.placeholder = "500" + +o = s:taboption("general", Value, "max_sources_per_file", translate("Max sources per file")) +o.datatype = "uinteger" +o.rmempty = false +o.placeholder = "300" + +-- CONNECTIONS -- + +o = s:taboption("connection", Value, "port", translate("TCP port")) +o.datatype = "port" +o.rmempty = false +o.placeholder = "4662" + +o = s:taboption("connection", Flag, "udp_enable", translate("Enable UDP port")) +o.rmempty = false + +o = s:taboption("connection", Value, "udp_port", translate("UDP port")) +o.datatype = "port" +o.rmempty = false +o.placeholder = "4672" + +o = s:taboption("connection", Flag, "upnp_enabled", translate("Enable UPnP")) +o.rmempty = false + +o = s:taboption("connection", Value, "upnp_tcp_port", translate("UPnP TCP port")) +o.datatype = "port" +o.rmempty = false +o.placeholder = "50000" + +o = s:taboption("connection", Value, "address", translate("Bind Address"), translate("Leave blank to bind all")) +o.datatype = "ip4addr" +o.rmempty = true + +o = s:taboption("connection", Flag, "auto_connect", translate("Automatically connect")) +o.rmempty = false + +o = s:taboption("connection", Flag, "reconnect", translate("Automatically reconnect")) +o.rmempty = false + +o = s:taboption("connection", Flag, "connect_to_kad", translate("Connect to Kad network")) +o.rmempty = false + +o = s:taboption("connection", Flag, "connect_to_ed2k", translate("Connect to ED2K network")) +o.rmempty = false + +s:taboption("connection", DummyValue,"titlesplit1" ,titlesplit(translate("Proxy Configuration"))) + +o = s:taboption("connection", Flag, "proxy_enable_proxy", translate("Enable proxy")) +o.rmempty = false + +o = s:taboption("connection", ListValue, "proxy_type", translate("Proxy type")) +for i,v in ipairs(ptype) do + o:value(v) +end +o.rmempty = false + +o = s:taboption("connection", Value, "proxy_name", translate("Proxy name")) +o.rmempty = true + +o = s:taboption("connection", Value, "proxy_port", translate("Proxy port")) +o.datatype = "port" +o.rmempty = true + +o = s:taboption("connection", Flag, "proxy_enable_password", translate("Proxy requires authentication")) +o.rmempty = true + +o = s:taboption("connection", Value, "proxy_user", translate("Proxy user")) +--o:depends("proxy_enable_password", "1") +o.rmempty = true + +o = s:taboption("connection", Value, "proxy_password", translate("Proxy password")) +o.password = true +o.rmempty = true + +-- SERVER -- + +o = s:taboption("server", Value, "kad_nodes_url", translate("Kad Nodes Url"), "") +o.rmempty = false +o.placeholder = "http://upd.emule-security.org/nodes.dat" + +o = s:taboption("server", Value, "ed2k_servers_url", translate("Ed2k Servers List Url"), "") +o.rmempty = false +o.placeholder = "http://upd.emule-security.org/server.met" + +o = s:taboption("server", Flag, "remove_dead_server", translate("Remove Dead Server")) +o.rmempty = false + +o = s:taboption("server", Value, "dead_server_retry", translate("Dead Server Retry")) +--o:depends("remove_dead_server", "1") +o.datatype = "uinteger" +o.rmempty = false +o.placeholder = "3" +o.default = "3" + +o = s:taboption("server", Flag, "add_server_list_from_server", translate("Update server list when connecting to a server")) +o.rmempty = false + +o = s:taboption("server", Flag, "add_server_list_from_client", translate("Update server list when a client connects")) +o.rmempty = false + +o = s:taboption("server", Flag, "scoresystem", translate("Use priority system")) +o.rmempty = false + +o = s:taboption("server", Flag, "smart_id_check", translate("Use smart LowID check on connect")) +o.rmempty = false + +o = s:taboption("server", Flag, "safe_server_connect", translate("Safe connect")) +o.rmempty = false + +o = s:taboption("server", Flag, "auto_connect_static_only", translate("Auto connect to servers in static list only")) +o.rmempty = false + +o = s:taboption("server", Flag, "manual_high_prio", translate("Set manually added servers to high priority")) +o.rmempty = false + +o = s:taboption("server", Flag, "serverlist", translate("Auto update server list at startup"), translate("addresses.dat file")) +o.rmempty = false + +addr = s:taboption("server", Value, "addresses", translate("Server addresses"), + translate("Content of addresses.dat. One address per line")) +addr:depends("serverlist", "1") +addr.template = "cbi/tvalue" +addr.rows = 5 +addr.rmempty = true +function addr.cfgvalue(self, section) + return nixio.fs.readfile("/etc/amule/addresses.dat") +end + +function addr.write(self, section, value) + value = value:gsub("\r\n?", "\n") + nixio.fs.writefile("//etc/amule/addresses.dat", value) +end + +-- PATH AND FILE -- + +o = s:taboption("path_and_file", Value, "temp_dir", translate("Temporary directory")) +o.rmempty = false +o.placeholder = "/var/run/amule/.aMule/Temp" + +o = s:taboption("path_and_file", Value, "incoming_dir", translate("Incoming directory")) +o.rmempty = false +o.placeholder = "/var/run/amule/.aMule/Incoming" + + +shareddir = s:taboption("path_and_file", Value, "shareddir", translate("Shared directory"), + translate("Content of shareddir.dat. One directory per line")) +shareddir.template = "cbi/tvalue" +shareddir.titleref = luci.dispatcher.build_url("admin", "system", "fstab") +shareddir.rows = 5 +shareddir.rmempty = true +function shareddir.cfgvalue(self, section) + return nixio.fs.readfile("/etc/amule/shareddir.dat") +end + +function shareddir.write(self, section, value) + value = value:gsub("\r\n?", "\n") + nixio.fs.writefile("//etc/amule/shareddir.dat", value) +end + +o = s:taboption("path_and_file", Flag, "ich", translate("Intelligent corruption handling (I.C.H.)")) +o.rmempty = false + +o = s:taboption("path_and_file", Flag, "a_ich_trust", translate("Advanced I.C.H trusts every hash (not recommended)")) +o.rmempty = false + +o = s:taboption("path_and_file", Flag, "add_new_files_paused", translate("Add files to download in pause mode")) +o.rmempty = false + +o = s:taboption("path_and_file", Flag, "dap_pref", translate("Add files to download with auto priority")) +o.rmempty = false + +o = s:taboption("path_and_file", Flag, "start_next_file", translate("Start next paused file when a file completes")) +o.rmempty = false + +o = s:taboption("path_and_file", Flag, "start_next_file_same_cat", translate("Start next paused file from the same category")) +o:depends("start_next_file", "1") +o.rmempty = true + +o = s:taboption("path_and_file", Flag, "start_next_file_alpha", translate("Start next paused file in alphabetic order")) +o:depends("start_next_file", "1") +o.rmempty = true + +o = s:taboption("path_and_file", Flag, "allocate_full_file", translate("Preallocate disk space for new files")) +o.rmempty = false + +o = s:taboption("path_and_file", Value, "min_free_disk_space", translate("Minimum free disk space. in Mbytes")) +o.datatype = "uinteger" +o.placeholder = "1" +o.rmempty = false + +o = s:taboption("path_and_file", Flag, "use_src_seed", translate("Save 10 sources on rare files (< 20 sources)")) +o.rmempty = false + +o = s:taboption("path_and_file", Flag, "uap_pref", translate("Add new shares with auto priority")) +o.rmempty = false + + +-- SECURITY -- + + +o = s:taboption("security", Flag, "use_sec_ident", translate("Use secure user identification")) +o.rmempty = false + +o = s:taboption("security", Flag, "is_crypt_layer_requested", translate("Use obfuscation for outgoing connections")) +o.rmempty = false + +o = s:taboption("security", Flag, "is_client_crypt_layer_required", translate("Accept only obfuscation connections")) +o.rmempty = false + +o = s:taboption("security", ListValue, "see_share", translate("Who can see my shared files")) +for i,v in ipairs(whocan) do + o:value(v) +end +o.rmempty = false + +s:taboption("security", DummyValue,"titlesplit2" ,titlesplit(translate("IP Filter Configuration"))) + +shareddir = s:taboption("security", Value, "ipfilter_static", translate("Static IP list for filtering"), + translate("Content of ipfilter_static.dat")) +shareddir.template = "cbi/tvalue" +shareddir.titleref = luci.dispatcher.build_url("admin", "system", "fstab") +shareddir.rows = 5 +shareddir.rmempty = true +function shareddir.cfgvalue(self, section) + return nixio.fs.readfile("/etc/amule/ipfilter_static.dat") +end + +function shareddir.write(self, section, value) + value = value:gsub("\r\n?", "\n") + nixio.fs.writefile("//etc/amule/ipfilter_static.dat", value) +end + +o = s:taboption("security", Flag, "ip_filter_clients", translate("Filter clients by IP")) +o.rmempty = false + +o = s:taboption("security", Flag, "ip_filter_servers", translate("Filter servers by IP")) +o.rmempty = false + +o = s:taboption("security", Value, "ip_filter_url", translate("IP filter list URL")) +o.rmempty = true + +o = s:taboption("security", Flag, "ip_filter_auto_load", translate("Auto-update ipfilter at startup")) +o.rmempty = false + +o = s:taboption("security", Value, "filter_level", translate("Filtering Level")) +o.datatype = "range(1, 255)" +o.rmempty = false +o.placeholder = "127" + +o = s:taboption("security", Flag, "filter_lan_ips", translate("Always filter LAN IPs")) +o.rmempty = false + +o = s:taboption("security", Flag, "paranoid_filtering", translate("Paranoid handling of non-matching IPs")) +o.rmempty = false + +o = s:taboption("security", Flag, "ip_filter_system", translate("Use system-wide ipfilter.dat if available")) +o.rmempty = false + +-- REMOTE CONTROL -- + +o = s:taboption("remote", Value, "ec_address", translate("IP of the listening interface for external connection")) +o.datatype = "ip4addr" +o.placeholder = "127.0.0.1" +o.rmempty = true + +o = s:taboption("remote", Value, "ec_port", translate("TCP port for EC")) +o.datatype = "port" +o.placeholder = "4712" +o.rmempty = false + +o = s:taboption("remote", Flag, "upnp_ec_enabled", translate("Enable upnp port forwarding on the EC port")) +o.rmempty = false + +o = s:taboption("remote", Value, "ec_password", translate("EC password")) +o.password = true +o.rmempty = false + +s:taboption("remote", DummyValue,"titlesplit3", titlesplit(translate("aMule Web Configuration"))) + +o = s:taboption("remote", Flag, "web_enabled", translate("Enable web server on startup")) +o.rmempty = false + +o = s:taboption("remote", Value, "template", translate("Web template")) +o.rmempty = false +local tpth_suggestions = luci.sys.exec("ls /usr/share/amule/webserver/|sed ':a;N;$!ba;s/\\n/:/g'") +if tpth_suggestions then + for entry in string.gmatch(tpth_suggestions, "[^:]+") do + o:value(entry) + end +end + +o = s:taboption("remote", Value, "web_password", translate("Web full rights password")) +o.password = true +o.rmempty = true + +o = s:taboption("remote", Flag, "use_low_rights_user", translate("Use low rights user")) +o.rmempty = false + +o = s:taboption("remote", Value, "password_low", translate("Web low rights password")) +o.password = true +o.rmempty = true + +o = s:taboption("remote", Value, "web_port", translate("Web TCP port")) +o.datatype = "port" +o.placeholder = "4711" +o.rmempty = false + +o = s:taboption("remote", Flag, "upnp_web_server_enabled", translate("Enable UPnP port forwarding of the web server port")) +o.rmempty = false + +o = s:taboption("remote", Value, "web_upnp_tcp_port", translate("Web UPnP TCP port")) +o.datatype = "port" +o.placeholder = "50001" +o.rmempty = false + +o = s:taboption("remote", Value, "page_refresh_time", translate("Page refresh time(in secs)")) +o.datatype = "range(1, 600)" +o.rmempty = false +o.placeholder = "121" + +o = s:taboption("remote", Flag, "use_gzip", translate("Enable Gzip compression")) +o.rmempty = false + + +-- TEMPLATE -- + + +tmpl = s:taboption("template", Value, "_tmpl", + translate("Edit the template that is used for generating the aMule configuration."), + translate("This is the content of the file '/etc/amule/amule.conf.template' from which your amule configuration will be generated. " .. + "Values enclosed by pipe symbols ('|') should not be changed. They get their values from other tabs.")) + +tmpl.template = "cbi/tvalue" +tmpl.rows = 20 + +function tmpl.cfgvalue(self, section) + return nixio.fs.readfile("/etc/amule/amule.conf.template") +end + +function tmpl.write(self, section, value) + value = value:gsub("\r\n?", "\n") + nixio.fs.writefile("//etc/amule/amule.conf.template", value) +end + +-- LOGVIEW -- + +local lv = s:taboption("logview", DummyValue, "_logview") +lv.template = "amule/detail_logview" +lv.inputtitle = translate("Read / Reread log file") +lv.rows = 50 + +function lv.cfgvalue(self, section) + return translate("Please press [Read] button") +end + +-- AMULECMD -- + +local cmd = s:taboption("amulecmd", DummyValue, "_amulecmd") +cmd.template = "amule/webshell" + +return m diff --git a/package/lean/luci-app-amule/luasrc/view/amule/detail_logview.htm b/package/lean/luci-app-amule/luasrc/view/amule/detail_logview.htm new file mode 100644 index 000000000..8effbacfd --- /dev/null +++ b/package/lean/luci-app-amule/luasrc/view/amule/detail_logview.htm @@ -0,0 +1,56 @@ + + + + +<%+cbi/valueheader%> + +
+ +<% +-- one button on top, one at the buttom +%> + /> + +

+ +<% +-- set a readable style taken from openwrt theme for textarea#syslog +-- in openwrt theme there are problems with a width of 100 so we check for theme and set to lower value +%> + +

+ +<% +-- one button on top, one at the buttom +%> + /> + +<%+cbi/valuefooter%> + diff --git a/package/lean/luci-app-amule/luasrc/view/amule/overview_status.htm b/package/lean/luci-app-amule/luasrc/view/amule/overview_status.htm new file mode 100644 index 000000000..8fd752186 --- /dev/null +++ b/package/lean/luci-app-amule/luasrc/view/amule/overview_status.htm @@ -0,0 +1,94 @@ + + +
+ <%:aMule Status%> +

+ <%:Collecting data...%> +

+

+ <%:Collecting data...%> +

+
diff --git a/package/lean/luci-app-amule/luasrc/view/amule/webshell.htm b/package/lean/luci-app-amule/luasrc/view/amule/webshell.htm new file mode 100644 index 000000000..998fa170a --- /dev/null +++ b/package/lean/luci-app-amule/luasrc/view/amule/webshell.htm @@ -0,0 +1,90 @@ + + + + diff --git a/package/lean/luci-app-amule/po/zh-cn/amule.po b/package/lean/luci-app-amule/po/zh-cn/amule.po new file mode 100644 index 000000000..18f7184d5 --- /dev/null +++ b/package/lean/luci-app-amule/po/zh-cn/amule.po @@ -0,0 +1,360 @@ +msgid "aMule is a ED2K/KAD client for all platforms." +msgstr "aMule鏄竴涓法骞冲彴鐨凟D2K/KAD瀹㈡埛绔" + +msgid "NAS" +msgstr "缃戠粶瀛樺偍" + +msgid "General" +msgstr "甯歌" + +msgid "Connections" +msgstr "杩炴帴" + +msgid "Server" +msgstr "鏈嶅姟鍣" + +msgid "Path And File" +msgstr "璺緞鍜屾枃浠" + +msgid "Security" +msgstr "瀹夊叏" + +msgid "External Control" +msgstr "杩滅▼鎺у埗" + +msgid "Edit Template" +msgstr "缂栬緫閰嶇疆妯$増" + +msgid "Log File Viewer" +msgstr "鏃ュ織鏌ョ湅" + +msgid "aMule Settings" +msgstr "aMule璁剧疆" + +msgid "Run daemon as user" +msgstr "杩愯瀹堟姢杩涚▼鐨勭敤鎴" + +msgid "Configuration directory" +msgstr "閰嶇疆鐩綍" + +msgid "Nickname" +msgstr "鏄电О" + +msgid "Max upload speed" +msgstr "鏈澶т笂浼犻熷害" + +msgid "Max download speed" +msgstr "鏈澶т笅杞介熷害" + +msgid "Unlimited when set to 0" +msgstr "璁句负0鏃朵笉闄愬埗" + +msgid "Slot allocation" +msgstr "妲介熷害" + +msgid "Max connections" +msgstr "鏈澶ц繛鎺ユ暟" + +msgid "Max sources per file" +msgstr "鍗曟枃浠舵渶澶ц繛鎺ユ暟" + +msgid "TCP port" +msgstr "TCP绔彛" + +msgid "UDP port" +msgstr "UDP绔彛" + +msgid "Enable UDP port" +msgstr "鍚敤UDP绔彛" + +msgid "Enable UPnP" +msgstr "鍚敤UPnP" + +msgid "UPnP TCP port" +msgstr "UPnP TCP绔彛" + +msgid "Bind Address" +msgstr "鍦板潃缁戝畾" + +msgid "Leave blank to bind all" +msgstr "鐣欑┖鍒欏叏閮ㄧ粦瀹" + +msgid "Default to bind all" +msgstr "榛樿鍏ㄩ儴缁戝畾" + +msgid "Automatically connect" +msgstr "鑷姩杩炴帴" + +msgid "Automatically reconnect" +msgstr "鑷姩閲嶈繛" + +msgid "Connect to Kad network" +msgstr "杩炴帴鍒癒ad缃戠粶" + +msgid "Connect to ED2K network" +msgstr "杩炴帴鍒癊D2K缃戠粶" + +msgid "Proxy Configuration" +msgstr "浠g悊璁剧疆" + +msgid "Enable proxy" +msgstr "鍚敤浠g悊" + +msgid "Proxy type" +msgstr "浠g悊绫诲瀷" + +msgid "Proxy name" +msgstr "浠g悊鍚嶇О" + +msgid "Proxy port" +msgstr "浠g悊绔彛" + +msgid "Proxy requires authentication" +msgstr "浠g悊闇瑕佽璇" + +msgid "Proxy user" +msgstr "浠g悊鐢ㄦ埛" + +msgid "Proxy password" +msgstr "浠g悊瀵嗙爜" + +msgid "Kad Nodes Url" +msgstr "Kad鑺傜偣URL" + +msgid "Ed2k Servers List Url" +msgstr "Ed2k鏈嶅姟鍣ㄥ垪琛║RL" + +msgid "Remove Dead Server" +msgstr "鍒犻櫎鏃犳晥鏈嶅姟鍣" + +msgid "Dead Server Retry" +msgstr "鍒犻櫎鍓嶉噸杩炴鏁" + +msgid "Update server list when connecting to a server" +msgstr "涓庢湇鍔″櫒杩炴帴鏃舵洿鏂版湇鍔″櫒鍒楄〃" + +msgid "Update server list when a client connects" +msgstr "涓庡叾浠栫敤鎴疯繛鎺ユ椂鏇存柊鏈嶅姟鍣ㄥ垪琛" + +msgid "Use priority system" +msgstr "鍚敤浼樺厛绾х郴缁" + +msgid "Use smart LowID check on connect" +msgstr "鏅鸿兘LOWID妫娴" + +msgid "Safe connect" +msgstr "瀹夊叏杩炴帴" + +msgid "Auto connect to servers in static list only" +msgstr "鍙嚜鍔ㄨ繛鎺ュ埌闈欐佸垪琛ㄤ腑鐨勬湇鍔″櫒" + +msgid "Set manually added servers to high priority" +msgstr "灏嗘墜鍔ㄨ緭鍏ョ殑鏈嶅姟鍣ㄨ涓洪珮浼樺厛绾" + +msgid "Auto update server list at startup" +msgstr "鍚姩鏃惰嚜鍔ㄦ洿鏂版湇鍔″櫒鍒楄〃" + +msgid "addresses.dat file" +msgstr "addresses.dat鏂囦欢" + +msgid "Server addresses" +msgstr "鏈嶅姟鍣ㄥ湴鍧" + +msgid "Content of addresses.dat. One address per line" +msgstr "addresses.dat鐨勫唴瀹. 姣忚涓涓湴鍧." + +msgid "Temporary directory" +msgstr "涓存椂鏂囦欢澶" + +msgid "Incoming directory" +msgstr "涓嬭浇鏂囦欢澶" + +msgid "Shared directory" +msgstr "鍏变韩鏂囦欢澶" + +msgid "Content of shareddir.dat. One directory per line" +msgstr "shareddir.dat鐨勫唴瀹. 姣忚涓涓洰褰." + +msgid "Intelligent corruption handling (I.C.H.)" +msgstr "鏅鸿兘鎹熷潖鏁版嵁澶勭悊(I.C.H.)" + +msgid "Advanced I.C.H trusts every hash (not recommended)" +msgstr "楂樼骇I.C.H锛屼俊浠诲叏閮ㄦ牎楠屽硷紙涓嶆帹鑽愶級" + +msgid "Add files to download in pause mode" +msgstr "娣诲姞鏂颁笅杞芥枃浠舵椂璁句负鏆傚仠" + +msgid "Add files to download with auto priority" +msgstr "娣诲姞鏂颁笅杞芥枃浠舵椂璁惧畾浼樺厛绾т负鑷姩" + +msgid "Start next paused file when a file completes" +msgstr "涓涓枃浠跺畬鎴愭椂寮濮嬩笅涓涓殏鍋滅殑鏂囦欢" + +msgid "Start next paused file from the same category" +msgstr "浠庡悓涓鍒嗙被寮濮嬩笅涓涓殏鍋滅殑鏂囦欢" + +msgid "Start next paused file in alphabetic order" +msgstr "鏍规嵁瀛楁瘝椤哄簭寮濮嬩笅涓涓殏鍋滅殑鏂囦欢" + +msgid "Preallocate disk space for new files" +msgstr "涓烘柊鏂囦欢棰勫垎閰嶇鐩樼┖闂" + +msgid "Minimum free disk space. in Mbytes" +msgstr "鏈浣庡墿浣欑┖闂达紝鍗曚綅MB" + +msgid "Save 10 sources on rare files (< 20 sources)" +msgstr "淇濆瓨绋鏈夋枃浠讹紙灏戜簬20涓簮锛夌殑鍗佷釜婧" + +msgid "Add new shares with auto priority" +msgstr "娣诲姞鏂板叡浜枃浠舵椂璁句紭鍏堢骇涓鸿嚜鍔" + +msgid "Use secure user identification" +msgstr "浣跨敤瀹夊叏鐢ㄦ埛璁よ瘉" + +msgid "Use obfuscation for outgoing connections" +msgstr "涓轰紶鍑鸿繛鎺ヤ娇鐢ㄨ糠鎯戝崗璁" + +msgid "Accept only obfuscation connections" +msgstr "鍙帴鍙楄糠鎯戝崗璁繛鎺" + +msgid "Who can see my shared files" +msgstr "璋佸彲鏌ョ湅鎴戠殑鍏变韩鏂囦欢" + +msgid "IP Filter Configuration" +msgstr "IP杩囨护璁剧疆" + +msgid "Static IP list for filtering" +msgstr "闈欐両P杩囨护鍒楄〃" + +msgid "Content of ipfilter_static.dat" +msgstr "ipfilter_static.dat鐨勫唴瀹" + +msgid "Filter clients by IP" +msgstr "杩囨护鐢ㄦ埛" + +msgid "Filter servers by IP" +msgstr "杩囨护鏈嶅姟鍣" + +msgid "IP filter list URL" +msgstr "杩囨护鍒楄〃URL" + +msgid "Auto-update ipfilter at startup" +msgstr "鑷姩鏇存柊杩囨护鍒楄〃" + +msgid "Filtering Level" +msgstr "杩囨护绾у埆" + +msgid "Always filter LAN IPs" +msgstr "鎬绘槸杩囨护灞鍩熺綉ip鍦板潃" + +msgid "Paranoid handling of non-matching IPs" +msgstr "澶勭悊涓嶅尮閰嶇殑IP" + +msgid "Use system-wide ipfilter.dat if available" +msgstr "鍙敤鎯呭喌涓嬩娇鐢ㄧ郴缁熺骇鐨刬pfilter.dat" + +msgid "IP of the listening interface for external connection" +msgstr "杩滅▼杩炴帴鐩戝惉IP" + +msgid "TCP port for EC" +msgstr "杩滅▼杩炴帴TCP绔彛" + +msgid "Enable upnp port forwarding on the EC port" +msgstr "涓鸿繙绋嬭繛鎺ョ鍙e惎鐢╱pnp" + +msgid "aMule Web Configuration" +msgstr "aMule Web璁剧疆" + +msgid "EC password" +msgstr "杩滅▼杩炴帴瀵嗙爜" + +msgid "Enable web server on startup" +msgstr "鍚姩鏃惰繍琛學eb鏈嶅姟" + +msgid "Web template" +msgstr "Web妯$増" + +msgid "Web full rights password" +msgstr "Web鏈楂樻潈闄愬瘑鐮" + +msgid "Use low rights user" +msgstr "鍚敤浣庢潈闄愮敤鎴" + +msgid "Web low rights password" +msgstr "Web浣庢潈闄愬瘑鐮" + +msgid "Web TCP port" +msgstr "Web TCP绔彛" + +msgid "Enable UPnP port forwarding of the web server port" +msgstr "涓篧eb鏈嶅姟绔彛鍚敤UPnP绔彛杞彂" + +msgid "Web UPnP TCP port" +msgstr "Web鏈嶅姟UPnP鐨凾CP绔彛" + +msgid "Page refresh time(in secs)" +msgstr "椤甸潰鍒锋柊鍛ㄦ湡(绉)" + +msgid "Enable Gzip compression" +msgstr "鍚敤Gzip鍘嬬缉" + +msgid "Edit the template that is used for generating the aMule configuration." +msgstr "缂栬緫鐢ㄦ潵鐢熸垚aMule璁剧疆鐨勬ā鏉" + +msgid "This is the content of the file '/etc/amule/amule.conf.template' from which your amule configuration will be generated. Values enclosed by pipe symbols ('|') should not be changed. They get their values from other tabs." +msgstr "鍒涘缓aMule璁剧疆鐨 '/etc/amule/amule.conf.template' 鏂囦欢鐨勫唴瀹广傝閫氶亾绗鍖呭洿鐨勫间笉搴旇鍦ㄨ繖閲屾敼鍔紝璇峰湪鍏朵粬鏍囩淇敼杩欎簺璁剧疆銆" + +msgid "Read / Reread log file" +msgstr "璇诲彇/閲嶈浇鏃ュ織鏂囦欢" + +msgid "Please press [Read] button" +msgstr "璇风偣鍑籟璇诲彇]鎸夐挳" + +msgid "File not found or empty" +msgstr "鏂囦欢涓嶅瓨鍦ㄦ垨涓虹┖" + +msgid "aMule Status" +msgstr "aMule鐘舵" + +msgid "Open aMuleWeb" +msgstr "鎵撳紑aMuleWeb" + +msgid "aMule daemon is running." +msgstr "aMule瀹堟姢杩涚▼姝e湪杩愯" + +msgid "aMule daemon is not running." +msgstr "aMule瀹堟姢杩涚▼鏈繍琛" + +msgid "Start aMule" +msgstr "鍚姩aMule" + +msgid "aMule command" +msgstr "aMule鍛戒护" + +msgid "aMule Command" +msgstr "aMule鍛戒护" + +msgid "You can call amulecmd commands here to control your amule." +msgstr "浣犲彲浠ュ湪杩欓噷杩愯amulecmd鍛戒护浠ユ帶鍒朵綘鐨刟Mule" + +msgid "Execute 'Help' to get more infomation." +msgstr "鎵ц'Help'鍛戒护浠ヨ幏鍙栨洿澶氫俊鎭" + +msgid "Execute" +msgstr "鎵ц" + +msgid "Clear" +msgstr "娓呯┖" + +msgid "Command: " +msgstr "鍛戒护: " + +msgid "Download now" +msgstr "绔嬪嵆涓嬭浇" + +msgid "Existing file will be overwritten, do you really want to proceed?" +msgstr "宸叉湁鏂囦欢灏嗚瑕嗙洊锛屾槸鍚︾户缁紵" + +msgid "Percentage" +msgstr "鐧惧垎姣" + diff --git a/package/lean/luci-app-amule/root/etc/amule/amule.conf.template b/package/lean/luci-app-amule/root/etc/amule/amule.conf.template new file mode 100644 index 000000000..3ab24a0b0 --- /dev/null +++ b/package/lean/luci-app-amule/root/etc/amule/amule.conf.template @@ -0,0 +1,206 @@ +[eMule] + Nick=|NICK| + MaxUpload=|MAXUPLOAD| + MaxDownload=|MAXDOWNLOAD| + SlotAllocation=|SLOTALLOCATION| + MaxConnections=|MAXCONNECTIONS| + MaxSourcesPerFile=|MAXSOURCESPERFILE| + Port=|PORT| + UDPPort=|UDPPORT| + UDPEnable=|UDPENABLE| + UPnPEnabled=|UPNPENABLED| + UPnPTCPPort=|UPNPTCPPORT| + Address=|ADDRESS| + Autoconnect=|AUTOCONNECT| + Reconnect=|RECONNECT| + ConnectToKad=|CONNECTTOKAD| + ConnectToED2K=|CONNECTTOED2K| + KadNodesUrl=|KADNODESURL| + Ed2kServersUrl=|ED2KSERVERSURL| + RemoveDeadServer=|REMOVEDEADSERVER| + DeadServerRetry=|DEADSERVERRETRY| + AddServerListFromServer=|ADDSERVERLISTFROMSERVER| + AddServerListFromClient=|ADDSERVERLISTFROMCLIENT| + Scoresystem=|SCORESYSTEM| + SmartIdCheck=|SMARTIDCHECK| + SafeServerConnect=|SAFESERVERCONNECT| + AutoConnectStaticOnly=|AUTOCONNECTSTATICONLY| + ManualHighPrio=|MANUALHIGHPRIO| + Serverlist=|SERVERLIST| + TempDir=|TEMPDIR| + IncomingDir=|INCOMINGDIR| + ICH=|ICH| + AICHTrust=|AICHTRUST| + AddNewFilesPaused=|ADDNEWFILESPAUSED| + DAPPref=|DAPPREF| + StartNextFile=|STARTNEXTFILE| + StartNextFileSameCat=|STARTNEXTFILESAMECAT| + StartNextFileAlpha=|STARTNEXTFILEALPHA| + AllocateFullFile=|ALLOCATEFULLFILE| + MinFreeDiskSpace=|MINFREEDISKSPACE| + UAPPref=|UAPPREF| + SeeShare=|SEESHARE| + IPFilterURL=|IPFILTERURL| + IPFilterAutoLoad=|IPFILTERAUTOLOAD| + FilterLevel=|FILTERLANIPS| + FilterLanIPs=|FILTERLANIPS| + ParanoidFiltering=|PARANOIDFILTERING| + IPFilterSystem=|IPFILTERSYSTEM| + + + FilterMessages=1 + FilterAllMessages=0 + MessagesFromFriendsOnly=0 + MessageFromValidSourcesOnly=1 + FilterWordMessages=0 + MessageFilter= + ShowMessagesInLog=1 + FilterComments=0 + CommentFilter= + + AppVersion=SVN + QueueSizePref=50 + MaxConnectionsPerFiveSeconds=20 + ServerKeepAliveTimeout=0 + CheckDiskspace=1 + PreviewPrio=0 + FileBufferSizePref=16 + OSDirectory=/var/run/amule + OnlineSignature=0 + OnlineSignatureUpdate=5 + EnableTrayIcon=0 + MinToTray=0 + ConfirmExit=1 + StartupMinimized=0 + 3DDepth=10 + ToolTipDelay=1 + ShowOverhead=0 + ShowInfoOnCatTabs=1 + VerticalToolbar=0 + GeoIPEnabled=1 + VideoPlayer= + StatGraphsInterval=3 + statsInterval=30 + DownloadCapacity=300 + UploadCapacity=100 + StatsAverageMinutes=5 + VariousStatisticsMaxValue=100 + ShareHiddenFiles=0 + AutoSortDownloads=0 + NewVersionCheck=1 + AdvancedSpamFilter=1 + MessageUseCaptchas=1 + Language= + SplitterbarPosition=75 + YourHostname= + DateTimeFormat=%A, %x, %X + AllcatType=0 + ShowAllNotCats=0 + SmartIdState=0 + DropSlowSources=0 + ShowRatesOnTitle=0 + GeoLiteCountryUpdateUrl=http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz + StatsServerName=Shorty's ED2K stats + StatsServerURL=http://ed2k.shortypower.dyndns.org/?hash= + CreateSparseFiles=1 + +[Browser] + OpenPageInTab=1 + CustomBrowserString= + +[Proxy] + ProxyEnableProxy=|PROXYENABLEPROXY| + ProxyType=|PROXYTYPE| + ProxyName=|PROXYNAME| + ProxyPort=|PROXYPORT| + ProxyEnablePassword=|PROXYENABLEPASSWORD| + ProxyUser=|PROXYUSER| + ProxyPassword=|PROXYPASSWORD| + +[DLP] + CheckModString=1 + CheckUsername=1 + CheckUserHash=1 + CheckHelloTag=1 + CheckInfoTag=1 + CheckVeryCDMod=0 + CheckGhostMod=1 + +[ExternalConnect] + ECAddress=|ECADDRESS| + ECPort=|ECPORT| + UPnPECEnabled=|UPNPECENABLED| + ECPassword=|ECPASSWORD| + UseSrcSeeds=|USESRCSEED| + UseSecIdent=|USESECIDENT| + IpFilterClients=|IPFILTERCLIENTS| + IpFilterServers=|IPFILTERSERVERS| + + AcceptExternalConnections=1 + ShowProgressBar=1 + ShowPercent=1 + TransmitOnlyUploadingClients=0 + +[WebServer] + Enabled=|WEBENABLED| + Template=|TEMPLATE| + Password=|WEBPASSWORD| + UseLowRightsUser=|USELOWRIGHTSUSER| + PasswordLow=|PASSWORDLOW| + Port=|WEBPORT| + UPnPWebServerEnabled=|UPNPWEBSERVERENABLED| + WebUPnPTCPPort=|WEBUPNPTCPPORT| + PageRefreshTime=|PAGEREFRESHTIME| + UseGzip=|USEGZIP| + + Path=amuleweb + + +[GUI] + HideOnClose=0 + +[Razor_Preferences] + FastED2KLinksHandler=1 + +[SkinGUIOptions] + Skin= + +[Statistics] + MaxClientVersions=0 + +[Obfuscation] + IsCryptLayerRequested=|ISCRYPTLAYERREQUESTED| + IsClientCryptLayerRequired=|ISCLIENTCRYPTLAYERREQUIRED| + IsClientCryptLayerSupported=1 + CryptoPaddingLenght=254 + CryptoKadUDPKey=281625462 + +[PowerManagement] + PreventSleepWhileDownloading=0 + + +[UserEvents] +[UserEvents/DownloadCompleted] + CoreEnabled=0 + CoreCommand= + GUIEnabled=0 + GUICommand= +[UserEvents/NewChatSession] + CoreEnabled=0 + CoreCommand= + GUIEnabled=0 + GUICommand= +[UserEvents/OutOfDiskSpace] + CoreEnabled=0 + CoreCommand= + GUIEnabled=0 + GUICommand= +[UserEvents/ErrorOnCompletion] + CoreEnabled=0 + CoreCommand= + GUIEnabled=0 + GUICommand= + + +[HTTPDownload] + URL_1= diff --git a/package/lean/luci-app-amule/root/etc/config/amule b/package/lean/luci-app-amule/root/etc/config/amule new file mode 100644 index 000000000..4e6a110d8 --- /dev/null +++ b/package/lean/luci-app-amule/root/etc/config/amule @@ -0,0 +1,71 @@ + + +config amule 'main' + option enabled '0' + option runasuser 'amule' + option config_dir '/var/run/amule' + option mem_percentage '50' + option nice '10' + option ionice_flags '-c 3' + option nick 'http://www.aMule.org' + option max_upload '0' + option max_download '0' + option slot_allocation '2' + option max_connections '500' + option max_sources_per_file '300' + option port '4662' + option udp_enable '1' + option udp_port '4672' + option upnp_tcp_port '50000' + option auto_connect '1' + option reconnect '1' + option connect_to_kad '1' + option connect_to_ed2k '1' + option kad_nodes_url 'http://upd.emule-security.org/nodes.dat' + option ed2k_servers_url 'http://upd.emule-security.org/server.met' + option remove_dead_server '1' + option dead_server_retry '3' + option scoresystem '1' + option smart_id_check '1' + option use_sec_ident '1' + option is_crypt_layer_requested '1' + option ip_filter_clients '1' + option ip_filter_servers '1' + option ip_filter_auto_load '1' + option filter_level '127' + option filter_lan_ips '1' + option paranoid_filtering '1' + option ec_port '4712' + option ec_password '12345678' + option ich '1' + option dap_pref '1' + option start_next_file '1' + option min_free_disk_space '1' + option use_src_seed '1' + option temp_dir '/var/run/amule/Temp' + option incoming_dir '/var/run/amule/Incoming' + option proxy_enable_proxy '0' + option add_server_list_from_server '0' + option add_server_list_from_client '0' + option safe_server_connect '0' + option auto_connect_static_only '0' + option manual_high_prio '0' + option serverlist '0' + option a_ich_trust '0' + option add_new_files_paused '0' + option allocate_full_file '0' + option uap_pref '0' + option is_client_crypt_layer_required '0' + option see_share 'nobody' + option ip_filter_system '0' + option upnp_ec_enabled '0' + option web_enabled '0' + option upnp_enabled '0' + option proxy_type 'socks5' + option template 'default' + option use_low_rights_user '0' + option web_port '44711' + option upnp_web_server_enabled '0' + option web_upnp_tcp_port '50001' + option page_refresh_time '121' + option use_gzip '0' diff --git a/package/lean/luci-app-amule/root/etc/hotplug.d/iface/20-amule b/package/lean/luci-app-amule/root/etc/hotplug.d/iface/20-amule new file mode 100644 index 000000000..a42adfb0f --- /dev/null +++ b/package/lean/luci-app-amule/root/etc/hotplug.d/iface/20-amule @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright (C) 2007 OpenWrt.org + +/etc/init.d/amule enabled && { + + [ "$ACTION" = "ifup" ] && { + /etc/init.d/amule start + } + + [ "$ACTION" = "ifdown" ] && { + /etc/init.d/amule stop + } + +} diff --git a/package/lean/luci-app-amule/root/etc/init.d/amule b/package/lean/luci-app-amule/root/etc/init.d/amule new file mode 100755 index 000000000..f64202a21 --- /dev/null +++ b/package/lean/luci-app-amule/root/etc/init.d/amule @@ -0,0 +1,175 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2010-2015 OpenWrt.org + +START=99 +USE_PROCD=1 + + +LIST_SEP=" +" + +unregex() { + echo "$1" | sed -e 's/[]\/()$*.^|[]/\\&/g' +} + +option_word_to_digit() { + word=$(grep -ioE "\b$2=\S+" "$1"|awk -F= '{print $2}') + digit=$(echo "$3" |grep -oE "$word/\S+"|awk -F'/' '{print $2}') + sed -i "s/\b$2=$word\b/$2=$digit/g" "$1" +} + +encrypt_password() { + pass_notencryted=$(grep -ioE "\b$2=[^\n]+" "$1"|sed "s/.*$2=//g") + pass_encryted=$(echo -n $pass_notencryted|md5sum|grep -oE "[a-z0-9]{32}") + [[ -z $pass_notencryted ]] || sed -i "s/\b$2=$(unregex $pass_notencryted)/$2=$pass_encryted/g" "$1" +} + +write_dat_file() { + if [[ -s "$1" ]] ; then + cat "$1" > "$2" + else + [[ -s "$2" ]] && cat "$2" > "$1" + fi +} + +set_params() { + cat /etc/amule/amule.conf.template > "$config_file" + local p; local v; local s="$1"; shift + for p in $*; do + config_get v "$s" "$p" + IFS="$LIST_SEP" + for v in $v; do + [ -n "$v" ] && ( + sed -i "s;|$(echo $p|tr '[a-z]' '[A-Z]'|sed -e 's|_||g')|;$(unregex $v);g" "$config_file" + ) + done + unset IFS + done + + #delete unreplaced placeholders + sed -i "s;=|[A-Z0-9]*|;=;g" "$config_file" + + #convert some options to digit + option_word_to_digit "$config_file" "ProxyType" "socks5/0 socks4/1 http/2 socks4a/3" + option_word_to_digit "$config_file" "SeeShare" "anyone/0 friends/1 nobody/2" + + #encrypt password + encrypt_password "$config_file" "ECPassword" + encrypt_password "$config_file" "Password" + encrypt_password "$config_file" "PasswordLow" +} + +section_enabled() { + config_get_bool enabled "$1" 'enabled' 0 + [ $enabled -gt 0 ] +} + +set_owner() { + case $(echo "$1"|grep -oE "^/[^/]+") in + "/var"|"/tmp"|"/mnt"|"root") + cur_user=$(ls -w50 -ld "$1"|awk '{print $3}') + cur_group=$(ls -w50 -ld "$1"|awk '{print $4}') + [[ $cur_user == $2 ]] || ( chown -R $2 "$1" ) + [[ $cur_group == $3 ]] || ( chgrp -R $3 "$1" ) + ;; + *) + false + ;; + esac +} + +amule() { + local cfg="$1" + local USE + + local runasuser + local incoming_dir config_dir temp_dir + local mem_percentage + local config_overwrite nice ionice_flags + local cmdline + + section_enabled "$section" || return 1 + + config_get config_dir "$cfg" 'config_dir' '/var/run/amule' + config_get runasuser "$cfg" 'runasuser' 'daemon' + config_get incoming_dir "$cfg" 'incoming_dir' "$config_dir/Incoming" + config_get temp_dir "$cfg" 'temp_dir' "$config_dir/Temp" + config_get mem_percentage "$cfg" 'mem_percentage' '50' + config_get config_overwrite "$cfg" config_overwrite 1 + config_get nice "$cfg" nice "-19" + config_get ionice_flags "$cfg" ionice_flags '' + group=$(id -Gn $runasuser) + + case $(echo "$config_dir"|grep -oE "^/[^/]+") in + "/var"|"/tmp"|"/mnt"|"/root"|"/home") + true + ;; + *) + echo "You should set config_dir to subfolders under /var, /tmp ,/mnt or /root" + return 1 + ;; + esac + + which ionice > /dev/null || ionice_flags='' + + local MEM=$(sed -ne 's!^MemTotal:[[:space:]]*\([0-9]*\) kB$!\1!p' /proc/meminfo) + if test "$MEM" -gt 1;then + USE=$(expr $MEM \* $mem_percentage \* 10) + fi + + config_file="$config_dir/amule.conf" + #[ -d "$config_dir" ] || { + mkdir -m 0755 -p "$config_dir" + chmod g+s "$config_dir" + chown $group:$runasuser "$config_dir" + touch "$config_file" "$config_dir/addresses.dat" "$config_dir/shareddir.dat" \ + "$config_dir/ipfilter_static.dat" + [ -d "$config_dir/.aMule" ] || ln -s ./ $config_dir/.aMule + #[ -z "$runasuser" ] || set_owner "$config_dir" $runasuser $group + #} + + + touch "$config_file" + write_dat_file /etc/amule/addresses.dat "$config_dir/addresses.dat" + write_dat_file /etc/amule/shareddir.dat "$config_dir/shareddir.dat" + write_dat_file /etc/amule/ipfilter_static.dat "$config_dir/ipfilter_static.dat" + + #[ "$config_overwrite" == 0 ] || { + set_params "$cfg" $(uci show amule|awk -F'[.=]' '{print $3}'|tr '\n' ' ') + #} + + HOME="$config_dir" /usr/bin/amulecmd --create-config-from="$config_file" + + cmdline="/usr/bin/amuled -c $config_dir" + [ "$ionice_flags" ] && cmdline="ionice $ionice_flags $cmdline" + procd_open_instance + procd_set_param command $cmdline + procd_set_param respawn retry=60 + procd_set_param user "$runasuser" + procd_set_param nice "$nice" + if test -z "$USE";then + procd_set_param limits core="0 0" + else + procd_set_param limits core="0 0" as="$USE $USE" + logger -t amule "Starting with $USE virt mem" + fi + + procd_add_jail amule log + procd_add_jail_mount_rw $config_file + procd_add_jail_mount_rw $incoming_dir + procd_add_jail_mount_rw $temp_dir + procd_close_instance +} + +start_service() { + killall -9 amuleweb >/dev/null 2>&1 + config_load 'amule' + config_foreach amule 'amule' +} + +restart() { + stop + sleep 2 + start +} + diff --git a/package/lean/luci-app-amule/root/etc/uci-defaults/luci-amule b/package/lean/luci-app-amule/root/etc/uci-defaults/luci-amule new file mode 100755 index 000000000..11b9b9cda --- /dev/null +++ b/package/lean/luci-app-amule/root/etc/uci-defaults/luci-amule @@ -0,0 +1,26 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@amule[-1] + add ucitrack amule + set ucitrack.@amule[-1].init=amule + commit ucitrack +EOF + +while [ ! $(grep -e "amule" ${IPKG_INSTROOT}/etc/passwd) ] +do + gid=$(awk -v min=1000 -v max=1500 'BEGIN{srand(); print int(min+rand()*(max-min+1))}') + echo amule:x:0:0:99999:7::: >> ${IPKG_INSTROOT}/etc/shadow + grep -e ":$gid:" ${IPKG_INSTROOT}/etc/passwd || ( \ + echo "amule:x:$gid:amule" >> ${IPKG_INSTROOT}/etc/group ; \ + echo "amule:x:$gid:$gid:amule:/var/run/amule:/bin/false" >> ${IPKG_INSTROOT}/etc/passwd ) + sleep 1 +done + +mkdir -p ${IPKG_INSTROOT}/etc/amule/ +touch ${IPKG_INSTROOT}/etc/amule/addresses.dat +touch ${IPKG_INSTROOT}/etc/amule/ipfilter_static.dat +touch ${IPKG_INSTROOT}/etc/amule/shareddir.dat + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/package/lean/luci-app-autoreboot/Makefile b/package/lean/luci-app-autoreboot/Makefile new file mode 100644 index 000000000..b845541de --- /dev/null +++ b/package/lean/luci-app-autoreboot/Makefile @@ -0,0 +1,17 @@ +# Copyright (C) 2016 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for Scheduled Reboot +LUCI_DEPENDS:=+luci +LUCI_PKGARCH:=all +PKG_VERSION:=1.0 +PKG_RELEASE:=7 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature + diff --git a/package/lean/luci-app-autoreboot/luasrc/controller/autoreboot.lua b/package/lean/luci-app-autoreboot/luasrc/controller/autoreboot.lua new file mode 100644 index 000000000..e0429f34f --- /dev/null +++ b/package/lean/luci-app-autoreboot/luasrc/controller/autoreboot.lua @@ -0,0 +1,4 @@ +module("luci.controller.autoreboot",package.seeall) +function index() +entry({"admin","system","autoreboot"},cbi("autoreboot"),_("Scheduled Reboot"),88) +end diff --git a/package/lean/luci-app-autoreboot/luasrc/model/cbi/autoreboot.lua b/package/lean/luci-app-autoreboot/luasrc/model/cbi/autoreboot.lua new file mode 100644 index 000000000..aae6451c3 --- /dev/null +++ b/package/lean/luci-app-autoreboot/luasrc/model/cbi/autoreboot.lua @@ -0,0 +1,30 @@ +require("luci.sys") + +m=Map("autoreboot",translate("Scheduled Reboot"),translate("Scheduled reboot Setting")) + +s=m:section(TypedSection,"login","") +s.addremove=false +s.anonymous=true + +enable=s:option(Flag,"enable",translate("Enable")) + +week=s:option(ListValue,"week",translate("Week Day")) +week:value(0,translate("Everyday")) +for e=1,7 do +week:value(e,translate("Day"..e)) +end +week.default=0 + +pass=s:option(Value,"minute",translate("Minute")) +pass.datatype = "range(0,59)" +pass.rmempty = false + +hour=s:option(Value,"hour",translate("Hour")) +hour.datatype = "range(0,23)" +hour.rmempty = false +local e=luci.http.formvalue("cbi.apply") +if e then + io.popen("/etc/init.d/autoreboot restart") +end + +return m diff --git a/package/lean/luci-app-autoreboot/po/zh-cn/autoreboot.po b/package/lean/luci-app-autoreboot/po/zh-cn/autoreboot.po new file mode 100644 index 000000000..91f55a079 --- /dev/null +++ b/package/lean/luci-app-autoreboot/po/zh-cn/autoreboot.po @@ -0,0 +1,24 @@ +msgid "Scheduled Reboot" +msgstr "瀹氭椂閲嶅惎" + +msgid "Scheduled reboot Setting" +msgstr "瀹氭椂閲嶅惎璁剧疆" + +msgid "Week Day" +msgstr "鏄熸湡" + +msgid "Everyday" +msgstr "姣忓ぉ" + +msgid "Day" +msgstr "澶" + +msgid "Minute" +msgstr "鍒" + +msgid "Hour" +msgstr "鐐" + + + + diff --git a/package/lean/luci-app-autoreboot/root/etc/config/autoreboot b/package/lean/luci-app-autoreboot/root/etc/config/autoreboot new file mode 100644 index 000000000..9947bb9f4 --- /dev/null +++ b/package/lean/luci-app-autoreboot/root/etc/config/autoreboot @@ -0,0 +1,6 @@ + +config login + option minute '0' + option hour '5' + option week '3' + diff --git a/package/lean/luci-app-autoreboot/root/etc/init.d/autoreboot b/package/lean/luci-app-autoreboot/root/etc/init.d/autoreboot new file mode 100755 index 000000000..7973d6c3f --- /dev/null +++ b/package/lean/luci-app-autoreboot/root/etc/init.d/autoreboot @@ -0,0 +1,39 @@ +#!/bin/sh /etc/rc.common +START=50 + +run_reboot() +{ + local enable + config_get_bool enable $1 enable + + if [ $enable = 1 ]; then + local minute + local hour + config_get week $1 week + config_get minute $1 minute + config_get hour $1 hour + if [ $minute = 0 ] ; then + minute="00" + fi + if [ $week = 0 ] ; then + week="*" + fi + sed -i '/reboot/d' /etc/crontabs/root >/dev/null 2>&1 + echo "$minute $hour * * $week sleep 5 && touch /etc/banner && reboot" >> /etc/crontabs/root + echo "Auto REBOOT has started." + else + sed -i '/reboot/d' /etc/crontabs/root >/dev/null 2>&1 + echo "Auto REBOOT has started." + fi +} + +start() +{ + config_load autoreboot + config_foreach run_reboot login +} + +stop() +{ + echo "Auto REBOOT has stoped." +} diff --git a/package/lean/luci-app-filetransfer/Makefile b/package/lean/luci-app-filetransfer/Makefile new file mode 100644 index 000000000..fb9ecc3e9 --- /dev/null +++ b/package/lean/luci-app-filetransfer/Makefile @@ -0,0 +1,16 @@ +# +# Copyright (C) 2008-2014 The LuCI Team +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI page for IPK upload +LUCI_DEPENDS:=+luci-lib-fs + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature + + diff --git a/package/lean/luci-app-filetransfer/luasrc/controller/filetransfer.lua b/package/lean/luci-app-filetransfer/luasrc/controller/filetransfer.lua new file mode 100644 index 000000000..727042786 --- /dev/null +++ b/package/lean/luci-app-filetransfer/luasrc/controller/filetransfer.lua @@ -0,0 +1,12 @@ +--[[ +luci-app-filetransfer +Description: File upload / download +Author: yuleniwo xzm2@qq.com QQ:529698939 +Modify: ayongwifi@126.com www.openwrtdl.com +]]-- + +module("luci.controller.filetransfer", package.seeall) + +function index() + entry({"admin", "system", "filetransfer"}, cbi("updownload"), _("FileTransfer"),89) +end diff --git a/package/lean/luci-app-filetransfer/luasrc/model/cbi/updownload.lua b/package/lean/luci-app-filetransfer/luasrc/model/cbi/updownload.lua new file mode 100644 index 000000000..7b487cb21 --- /dev/null +++ b/package/lean/luci-app-filetransfer/luasrc/model/cbi/updownload.lua @@ -0,0 +1,148 @@ +local fs = require "luci.fs" +local http = luci.http + +ful = SimpleForm("upload", translate("Upload"), nil) +ful.reset = false +ful.submit = false + +sul = ful:section(SimpleSection, "", translate("Upload file to '/tmp/upload/'")) +fu = sul:option(FileUpload, "") +fu.template = "cbi/other_upload" +um = sul:option(DummyValue, "", nil) +um.template = "cbi/other_dvalue" + +fdl = SimpleForm("download", translate("Download"), nil) +fdl.reset = false +fdl.submit = false +sdl = fdl:section(SimpleSection, "", translate("Download file")) +fd = sdl:option(FileUpload, "") +fd.template = "cbi/other_download" +dm = sdl:option(DummyValue, "", nil) +dm.template = "cbi/other_dvalue" + +function Download() + local sPath, sFile, fd, block + sPath = http.formvalue("dlfile") + sFile = nixio.fs.basename(sPath) + if luci.fs.isdirectory(sPath) then + fd = io.popen('tar -C "%s" -cz .' % {sPath}, "r") + sFile = sFile .. ".tar.gz" + else + fd = nixio.open(sPath, "r") + end + if not fd then + dm.value = translate("Couldn't open file: ") .. sPath + return + end + dm.value = nil + http.header('Content-Disposition', 'attachment; filename="%s"' % {sFile}) + http.prepare_content("application/octet-stream") + while true do + block = fd:read(nixio.const.buffersize) + if (not block) or (#block ==0) then + break + else + http.write(block) + end + end + fd:close() + http.close() +end + +local dir, fd +dir = "/tmp/upload/" +nixio.fs.mkdir(dir) +http.setfilehandler( + function(meta, chunk, eof) + if not fd then + if not meta then return end + + if meta and chunk then fd = nixio.open(dir .. meta.file, "w") end + + if not fd then + um.value = translate("Create upload file error.") + return + end + end + if chunk and fd then + fd:write(chunk) + end + if eof and fd then + fd:close() + fd = nil + um.value = translate("File saved to") .. ' "/tmp/upload/' .. meta.file .. '"' + end + end +) + +if luci.http.formvalue("upload") then + + + local f = luci.http.formvalue("ulfile") + if #f <= 0 then + um.value = translate("No specify upload file.") + end +elseif luci.http.formvalue("download") then + Download() +end + +local inits, attr = {} +for i, f in ipairs(fs.glob("/tmp/upload/*")) do + attr = fs.stat(f) + if attr then + inits[i] = {} + inits[i].name = fs.basename(f) + inits[i].mtime = os.date("%Y-%m-%d %H:%M:%S", attr.mtime) + inits[i].modestr = attr.modestr + inits[i].size = tostring(attr.size) + inits[i].remove = 0 + inits[i].install = false + end +end + +form = SimpleForm("filelist", translate("Upload file list"), nil) +form.reset = false +form.submit = false + +tb = form:section(Table, inits) +nm = tb:option(DummyValue, "name", translate("File name")) +mt = tb:option(DummyValue, "mtime", translate("Modify time")) +ms = tb:option(DummyValue, "modestr", translate("Mode string")) +sz = tb:option(DummyValue, "size", translate("Size")) +btnrm = tb:option(Button, "remove", translate("Remove")) +btnrm.render = function(self, section, scope) + self.inputstyle = "remove" + Button.render(self, section, scope) +end + +btnrm.write = function(self, section) + local v = luci.fs.unlink("/tmp/upload/" .. luci.fs.basename(inits[section].name)) + if v then table.remove(inits, section) end + return v +end + +function IsIpkFile(name) + name = name or "" + local ext = string.lower(string.sub(name, -4, -1)) + return ext == ".ipk" +end + +btnis = tb:option(Button, "install", translate("Install")) +btnis.template = "cbi/other_button" +btnis.render = function(self, section, scope) + if not inits[section] then return false end + if IsIpkFile(inits[section].name) then + scope.display = "" + else + scope.display = "none" + end + self.inputstyle = "apply" + Button.render(self, section, scope) +end + +btnis.write = function(self, section) + local r = luci.sys.exec(string.format('opkg --force-depends install "/tmp/upload/%s"', inits[section].name)) + form.description = string.format('%s', r) +end + +return ful, fdl, form diff --git a/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_button.htm b/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_button.htm new file mode 100644 index 000000000..1c391ad98 --- /dev/null +++ b/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_button.htm @@ -0,0 +1,7 @@ +<%+cbi/valueheader%> + <% if self:cfgvalue(section) ~= false then %> + " style="display: <%= display %>" type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> /> + <% else %> + - + <% end %> +<%+cbi/valuefooter%> diff --git a/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_download.htm b/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_download.htm new file mode 100644 index 000000000..c14728632 --- /dev/null +++ b/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_download.htm @@ -0,0 +1,5 @@ +<%+cbi/valueheader%> + + + +<%+cbi/valuefooter%> diff --git a/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_dvalue.htm b/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_dvalue.htm new file mode 100644 index 000000000..296c61e4d --- /dev/null +++ b/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_dvalue.htm @@ -0,0 +1,8 @@ +<%+cbi/valueheader%> + +<% + local val = self:cfgvalue(section) or self.default or "" + write(pcdata(val)) +%> + +<%+cbi/valuefooter%> diff --git a/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_upload.htm b/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_upload.htm new file mode 100644 index 000000000..bb56f444f --- /dev/null +++ b/package/lean/luci-app-filetransfer/luasrc/view/cbi/other_upload.htm @@ -0,0 +1,5 @@ +<%+cbi/valueheader%> + + + +<%+cbi/valuefooter%> diff --git a/package/lean/luci-app-filetransfer/po/zh-cn/filetransfer.po b/package/lean/luci-app-filetransfer/po/zh-cn/filetransfer.po new file mode 100644 index 000000000..829c7d285 --- /dev/null +++ b/package/lean/luci-app-filetransfer/po/zh-cn/filetransfer.po @@ -0,0 +1,56 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "Choose local file:" +msgstr "閫夋嫨鏈湴鏂囦欢锛" + +msgid "Couldn't open file:" +msgstr "鏃犳硶鎵撳紑鏂囦欢锛" + +msgid "Create upload file error." +msgstr "鍒涘缓涓婁紶鏂囦欢澶辫触銆" + +msgid "Download" +msgstr "涓嬭浇" + +msgid "Download file" +msgstr "涓嬭浇鏂囦欢" + +msgid "File name" +msgstr "鏂囦欢鍚" + +msgid "File saved to" +msgstr "鏂囦欢淇濆瓨鍒" + +msgid "FileTransfer" +msgstr "鏂囦欢浼犺緭" + +msgid "Install" +msgstr "瀹夎" + +msgid "Mode string" +msgstr "妯″紡瀛楃涓" + +msgid "Modify time" +msgstr "淇敼鏃堕棿" + +msgid "No specify upload file." +msgstr "鏈寚瀹氫笂浼犳枃浠" + +msgid "Path on Route:" +msgstr "璺敱涓婄洰褰" + +msgid "Remove" +msgstr "绉婚櫎" + +msgid "Size" +msgstr "澶у皬" + +msgid "Upload" +msgstr "涓婁紶" + +msgid "Upload file list" +msgstr "涓婁紶鏂囦欢鍒楄〃" + +msgid "Upload file to '/tmp/upload/'" +msgstr "灏嗘枃浠朵笂浼犲埌'/tmp/upload/'" diff --git a/package/lean/luci-app-ipsec-vpnd/Makefile b/package/lean/luci-app-ipsec-vpnd/Makefile new file mode 100644 index 000000000..cbe1d21d0 --- /dev/null +++ b/package/lean/luci-app-ipsec-vpnd/Makefile @@ -0,0 +1,18 @@ +# Copyright (C) 2016 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for IPSec VPN Server (IKEv1 with PSK and Xauth) +LUCI_DEPENDS:=+strongswan-minimal +strongswan-mod-xauth-generic +LUCI_PKGARCH:=all +PKG_VERSION:=2.0 +PKG_RELEASE:=3 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature + + diff --git a/package/lean/luci-app-ipsec-vpnd/luasrc/controller/ipsec-server.lua b/package/lean/luci-app-ipsec-vpnd/luasrc/controller/ipsec-server.lua new file mode 100644 index 000000000..5e944da0f --- /dev/null +++ b/package/lean/luci-app-ipsec-vpnd/luasrc/controller/ipsec-server.lua @@ -0,0 +1,14 @@ + +module("luci.controller.ipsec-server", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/ipsec") then + return + end + + entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false + + local page + + entry({"admin", "vpn", "ipsec-server"}, cbi("ipsec-server/ipsec-server"), _("IPSec VPN Server"), 80).dependent=false +end diff --git a/package/lean/luci-app-ipsec-vpnd/luasrc/model/cbi/ipsec-server/ipsec-server.lua b/package/lean/luci-app-ipsec-vpnd/luasrc/model/cbi/ipsec-server/ipsec-server.lua new file mode 100644 index 000000000..3ce14e0e0 --- /dev/null +++ b/package/lean/luci-app-ipsec-vpnd/luasrc/model/cbi/ipsec-server/ipsec-server.lua @@ -0,0 +1,166 @@ + +--require("luci.tools.webadmin") + +mp = Map("ipsec", translate("IPSec VPN Server")) +mp.description = translate("IPSec VPN connectivity using the native built-in VPN Client on iOS or Andriod (IKEv1 with PSK and Xauth)") + +s = mp:section(NamedSection, "ipsec", "service") +s.anonymouse = true +--s.addremove = true + +enabled = s:option(Flag, "enabled", translate("Enable")) +enabled.default = 0 +enabled.rmempty = false + +clientip = s:option(Value, "clientip", translate("VPN Client IP")) +clientip.datatype = "ip4addr" +clientip.description = translate("LAN DHCP reserved started IP addresses with the same subnet mask") +clientip.optional = false +clientip.rmempty = false + +clientdns = s:option(Value, "clientdns", translate("VPN Client DNS")) +clientdns.datatype = "ip4addr" +clientdns.description = translate("DNS using in VPN tunnel.Set to the router's LAN IP is recommended") +clientdns.optional = false +clientdns.rmempty = false + +account = s:option(Value, "account", translate("Account")) +account.datatype = "string" + +password = s:option(Value, "password", translate("Password")) +password.password = true + +secret = s:option(Value, "secret", translate("Secret Pre-Shared Key")) +secret.password = true + + +function mp.on_save(self) + require "luci.model.uci" + require "luci.sys" + + local have_ike_rule = false + local have_ipsec_rule = false + local have_ah_rule = false + local have_esp_rule = false + + luci.model.uci.cursor():foreach('firewall', 'rule', + function (section) + if section.name == 'ike' then + have_ike_rule = true + end + if section.name == 'ipsec' then + have_ipsec_rule = true + end + if section.name == 'ah' then + have_ah_rule = true + end + if section.name == 'esp' then + have_esp_rule = true + end + end + ) + + if not have_ike_rule then + local cursor = luci.model.uci.cursor() + local ike_rulename = cursor:add('firewall','rule') + cursor:tset('firewall', ike_rulename, { + ['name'] = 'ike', + ['target'] = 'ACCEPT', + ['src'] = 'wan', + ['proto'] = 'udp', + ['dest_port'] = 500 + }) + cursor:save('firewall') + cursor:commit('firewall') + end + if not have_ipsec_rule then + local cursor = luci.model.uci.cursor() + local ipsec_rulename = cursor:add('firewall','rule') + cursor:tset('firewall', ipsec_rulename, { + ['name'] = 'ipsec', + ['target'] = 'ACCEPT', + ['src'] = 'wan', + ['proto'] = 'udp', + ['dest_port'] = 4500 + }) + cursor:save('firewall') + cursor:commit('firewall') + end + if not have_ah_rule then + local cursor = luci.model.uci.cursor() + local ah_rulename = cursor:add('firewall','rule') + cursor:tset('firewall', ah_rulename, { + ['name'] = 'ah', + ['target'] = 'ACCEPT', + ['src'] = 'wan', + ['proto'] = 'ah' + }) + cursor:save('firewall') + cursor:commit('firewall') + end + if not have_esp_rule then + local cursor = luci.model.uci.cursor() + local esp_rulename = cursor:add('firewall','rule') + cursor:tset('firewall', esp_rulename, { + ['name'] = 'esp', + ['target'] = 'ACCEPT', + ['src'] = 'wan', + ['proto'] = 'esp' + }) + cursor:save('firewall') + cursor:commit('firewall') + end + + +end + + +local pid = luci.util.exec("/usr/bin/pgrep ipsec") + +function ipsec_process_status() + local status = "IPSec VPN Server is not running now " + + if pid ~= "" then + status = "IPSec VPN Server is running with the PID " .. pid .. "" + end + + local status = { status=status } + local table = { pid=status } + return table +end + +t = mp:section(Table, ipsec_process_status()) +t.anonymous = true + +t:option(DummyValue, "status", translate("IPSec VPN Server status")) + +if pid == "" then + start = t:option(Button, "_start", translate("Start")) + start.inputstyle = "apply" + function start.write(self, section) + luci.util.exec("uci set ipsec.ipsec.enabled='1' && uci commit ipsec") + message = luci.util.exec("/etc/init.d/ipsec start 2>&1") + luci.util.exec("sleep 2") + luci.http.redirect( + luci.dispatcher.build_url("admin", "vpn", "ipsec-server") + ) + end +else + stop = t:option(Button, "_stop", translate("Stop")) + stop.inputstyle = "reset" + function stop.write(self, section) + luci.util.exec("uci set ipsec.ipsec.enabled='0' && uci commit ipsec") + luci.util.exec("/etc/init.d/ipsec stop") + luci.util.exec("sleep 2") + luci.http.redirect( + luci.dispatcher.build_url("admin", "vpn", "ipsec-server") + ) + end +end + +function mp.on_after_commit(self) + os.execute("/etc/ipsecvpn restart >/dev/null 2>&1 &") +end + + +return mp diff --git a/package/lean/luci-app-ipsec-vpnd/po/zh-cn/ipsec.po b/package/lean/luci-app-ipsec-vpnd/po/zh-cn/ipsec.po new file mode 100644 index 000000000..0bf6b62aa --- /dev/null +++ b/package/lean/luci-app-ipsec-vpnd/po/zh-cn/ipsec.po @@ -0,0 +1,34 @@ +msgid "IPSec VPN Server" +msgstr "IPSec VPN 鏈嶅姟鍣" + +msgid "IPSec VPN connectivity using the native built-in VPN Client on iOS or Andriod (IKEv1 with PSK and Xauth)" +msgstr "浣跨敤iOS 鎴栬 Andriod (IKEv1 with PSK and Xauth) 鍘熺敓鍐呯疆 IPSec VPN 瀹㈡埛绔繘琛岃繛鎺" + +msgid "VPN Client IP" +msgstr "VPN瀹㈡埛绔湴鍧娈" + +msgid "LAN DHCP reserved started IP addresses with the same subnet mask" +msgstr "VPN瀹㈡埛绔娇鐢―HCP淇濈暀绌轰綑IP鐨勮捣濮嬪湴鍧锛屽繀椤诲拰璺敱鍣↙AN鍚屼竴涓瓙缃戞帺鐮侊紝渚嬪 192.168.0.10/24" + +msgid "VPN Client DNS" +msgstr "VPN瀹㈡埛绔疍NS鏈嶅姟鍣" + +msgid "DNS using in VPN tunnel.Set to the router's LAN IP is recommended" +msgstr "鎸囧畾VPN瀹㈡埛绔殑DNS鍦板潃銆傛帹鑽愯缃负璺敱鍣ㄧ殑LAN IP锛屼緥濡 192.168.0.1" + +msgid "Account" +msgstr "璐︽埛" + +msgid "Secret Pre-Shared Key" +msgstr "PSK瀵嗛挜" + +msgid "IPSec VPN Server status" +msgstr "IPSec VPN 鏈嶅姟鍣ㄨ繍琛岀姸鎬" + +msgid "Disable from startup" +msgstr "绂佹寮鏈哄惎鍔" + +msgid "Enable on startup" +msgstr "鍏佽寮鏈哄惎鍔" + + diff --git a/package/lean/luci-app-ipsec-vpnd/root/etc/config/ipsec b/package/lean/luci-app-ipsec-vpnd/root/etc/config/ipsec new file mode 100644 index 000000000..93c21f278 --- /dev/null +++ b/package/lean/luci-app-ipsec-vpnd/root/etc/config/ipsec @@ -0,0 +1,9 @@ + +config service 'ipsec' + option clientdns '192.168.0.1' + option account 'lean' + option secret 'myopenwrt' + option enabled '0' + option password '12345678' + option clientip '192.168.0.10/24' + diff --git a/package/lean/luci-app-ipsec-vpnd/root/etc/ipsec.include b/package/lean/luci-app-ipsec-vpnd/root/etc/ipsec.include new file mode 100755 index 000000000..84129f643 --- /dev/null +++ b/package/lean/luci-app-ipsec-vpnd/root/etc/ipsec.include @@ -0,0 +1,4 @@ +iptables -I FORWARD -m policy --dir in --pol ipsec --proto esp -j ACCEPT +iptables -I FORWARD -m policy --dir out --pol ipsec --proto esp -j ACCEPT +iptables -I INPUT -m policy --dir in --pol ipsec --proto esp -j ACCEPT +iptables -I OUTPUT -m policy --dir out --pol ipsec --proto esp -j ACCEPT diff --git a/package/lean/luci-app-ipsec-vpnd/root/etc/ipsecvpn b/package/lean/luci-app-ipsec-vpnd/root/etc/ipsecvpn new file mode 100755 index 000000000..023ad2e36 --- /dev/null +++ b/package/lean/luci-app-ipsec-vpnd/root/etc/ipsecvpn @@ -0,0 +1,71 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (C) 2018 Lean +# + +START=99 + +start() +{ + local vt_enabled=`uci get ipsec.@service[0].enabled 2>/dev/null` + local vt_clientip=`uci get ipsec.@service[0].clientip` + local vt_clientdns=`uci get ipsec.@service[0].clientdns` + local vt_account=`uci get ipsec.@service[0].account` + local vt_password=`uci get ipsec.@service[0].password 2>/dev/null` + local vt_secret=`uci get ipsec.@service[0].secret 2>/dev/null` + + # ----------------------------------------------------------------- + if [ "$vt_enabled" = 0 ]; then + /etc/init.d/ipsec disable && /etc/init.d/ipsec stop + echo "WARNING: IPSec VPN is disabled." + return 1 + fi + + cat > /etc/ipsec.conf < /etc/ipsec.secrets </dev/null + delete firewall.ipsecd + set firewall.ipsecd=include + set firewall.ipsecd.type=script + set firewall.ipsecd.path=/etc/ipsec.include + set firewall.ipsecd.reload=1 + commit firewall +EOF + +/etc/init.d/ipsec disable && /etc/init.d/ipsec stop + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/package/lean/luci-app-mproxy/Makefile b/package/lean/luci-app-mproxy/Makefile new file mode 100644 index 000000000..03605de62 --- /dev/null +++ b/package/lean/luci-app-mproxy/Makefile @@ -0,0 +1,17 @@ +# Copyright (C) 2016 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for Mproxy +LUCI_DEPENDS:=+mproxy +LUCI_PKGARCH:=all +PKG_VERSION:=1.0 +PKG_RELEASE:=3 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature + diff --git a/package/lean/luci-app-mproxy/luasrc/controller/mproxy.lua b/package/lean/luci-app-mproxy/luasrc/controller/mproxy.lua new file mode 100644 index 000000000..b93d5190e --- /dev/null +++ b/package/lean/luci-app-mproxy/luasrc/controller/mproxy.lua @@ -0,0 +1,11 @@ +module("luci.controller.mproxy", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/mproxy") then + return + end + local page + page = entry({"admin", "services", "mproxy"}, cbi("mproxy"), _("Mproxy Server"), 100) + page.i18n = "mproxy" + page.dependent = true +end diff --git a/package/lean/luci-app-mproxy/luasrc/model/cbi/mproxy.lua b/package/lean/luci-app-mproxy/luasrc/model/cbi/mproxy.lua new file mode 100644 index 000000000..63d71beb5 --- /dev/null +++ b/package/lean/luci-app-mproxy/luasrc/model/cbi/mproxy.lua @@ -0,0 +1,37 @@ +local m,s,o +local SYS = require "luci.sys" + + +if SYS.call("pidof mproxy >/dev/null") == 0 then + Status = translate("Mproxy is Running") +else + Status = translate("Mproxy is Not Running") +end + +m = Map("mproxy") +m.title = translate("Mproxy Server") +m.description = translate("A mini HTTP/HTTPS Proxy Server for Something") + +s = m:section(TypedSection, "mproxy", "") +s.addremove = false +s.anonymous = true +s.description = translate(string.format("%s

", Status)) + +enable = s:option(Flag, "enabled", translate("Enable")) +enable.default = 0 +enable.rmempty = false + +port = s:option(Value, "port", translate("Port")) +port.datatype = "range(1,65535)" + +redir = s:option(Value, "redir", translate("Redirect to Local Port")) +redir.datatype = "range(1,65535)" +redir.rmempty = false +redir.description = translate("Redirecting traffic incoming to the specified local port") + +function m.on_after_commit(self) + os.execute("uci set firewall.mproxy.dest_port=$(uci get mproxy.config.port) && uci commit firewall && /etc/init.d/firewall restart") + os.execute("/etc/init.d/mproxy restart") +end + +return m diff --git a/package/lean/luci-app-mproxy/po/zh-cn/mproxy.po b/package/lean/luci-app-mproxy/po/zh-cn/mproxy.po new file mode 100644 index 000000000..51f1af802 --- /dev/null +++ b/package/lean/luci-app-mproxy/po/zh-cn/mproxy.po @@ -0,0 +1,26 @@ +msgid "Port" +msgstr "绔彛" + +msgid "Mproxy is Running" +msgstr "Mproxy 姝e湪杩愯" + +msgid "Mproxy is Not Running" +msgstr "Mproxy 鏈繍琛" + +msgid "Mproxy Server" +msgstr "Mproxy 浠g悊鏈嶅姟鍣" + +msgid "A mini HTTP/HTTPS Proxy Server for Something" +msgstr "鏈灏忕殑 HTTP/HTTPS 浠g悊锛屽彲浠ョ敤鏉ュ仛鏌愪簺浜嬫儏" + +msgid "Redirect to Local Port" +msgstr "閲嶅畾鍚戝埌鏈湴绔彛" + +msgid "Redirecting traffic incoming to the specified local port" +msgstr "灏嗘祦閲忔棤鏉′欢杞彂鑷崇壒瀹氭湰鍦扮鍙" + + + + + + diff --git a/package/lean/luci-app-mproxy/root/etc/config/mproxy b/package/lean/luci-app-mproxy/root/etc/config/mproxy new file mode 100644 index 000000000..9e48050e8 --- /dev/null +++ b/package/lean/luci-app-mproxy/root/etc/config/mproxy @@ -0,0 +1,6 @@ + +config mproxy 'config' + option enabled '0' + option redir '1194' + option port '9090' + diff --git a/package/lean/luci-app-mproxy/root/etc/init.d/mproxy b/package/lean/luci-app-mproxy/root/etc/init.d/mproxy new file mode 100755 index 000000000..cc55b4c49 --- /dev/null +++ b/package/lean/luci-app-mproxy/root/etc/init.d/mproxy @@ -0,0 +1,28 @@ +#!/bin/sh /etc/rc.common +# Copyright (c) 2011-2015 OpenWrt.org + +START=90 + +start(){ + enable=$(uci get mproxy.config.enabled 2>/dev/null) + port=$(uci get mproxy.config.port) + redir=$(uci get mproxy.config.redir) + if [ $enable -eq 1 ]; then + [ ! -f /etc/rc.d/S90mproxy ] && /etc/init.d/mproxy enable + /usr/bin/mproxy -l $port -r 127.0.0.1:$redir -d + else + /etc/init.d/mproxy disable + fi +} + +stop(){ + pid=$(ps | grep 'mproxy -l' | grep -v grep | cut -c 0-6) + kill -9 $pid +} + +restart(){ + stop + start +} + + diff --git a/package/lean/luci-app-mproxy/root/etc/uci-defaults/mproxy b/package/lean/luci-app-mproxy/root/etc/uci-defaults/mproxy new file mode 100755 index 000000000..4aec731d7 --- /dev/null +++ b/package/lean/luci-app-mproxy/root/etc/uci-defaults/mproxy @@ -0,0 +1,16 @@ +#!/bin/sh + +uci delete firewall.mproxy +uci add firewall rule +uci rename firewall.@rule[-1]="mproxy" +uci set firewall.@rule[-1].name="mproxy" +uci set firewall.@rule[-1].target="ACCEPT" +uci set firewall.@rule[-1].src="wan" +uci set firewall.@rule[-1].proto="tcp" +uci set firewall.@rule[-1].dest_port="9090" +uci commit firewall; + +/etc/init.d/mproxy enable + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/package/lean/luci-app-n2n_v2/Makefile b/package/lean/luci-app-n2n_v2/Makefile new file mode 100755 index 000000000..a83438003 --- /dev/null +++ b/package/lean/luci-app-n2n_v2/Makefile @@ -0,0 +1,17 @@ +# +# Copyright (C) 2008-2014 The LuCI Team +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=n2n_v2 VPN Configuration module +LUCI_DEPENDS:=+n2n_v2 +LUCI_PKGARCH:=all +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/package/lean/luci-app-n2n_v2/luasrc/controller/n2n_v2.lua b/package/lean/luci-app-n2n_v2/luasrc/controller/n2n_v2.lua new file mode 100644 index 000000000..a1d599886 --- /dev/null +++ b/package/lean/luci-app-n2n_v2/luasrc/controller/n2n_v2.lua @@ -0,0 +1,18 @@ +--[[ +N2N V2 Luci configuration page.Made by 981213 +]]-- + +module("luci.controller.n2n_v2", package.seeall) + +function index() + + if not nixio.fs.access("/etc/config/n2n_v2") then + return + end + + entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false + + local page + page = entry({"admin", "vpn", "n2n_v2"}, cbi("n2n_v2"), _("N2N v2 VPN"), 45) + page.dependent = true +end diff --git a/package/lean/luci-app-n2n_v2/luasrc/model/cbi/n2n_v2.lua b/package/lean/luci-app-n2n_v2/luasrc/model/cbi/n2n_v2.lua new file mode 100644 index 000000000..ec277394d --- /dev/null +++ b/package/lean/luci-app-n2n_v2/luasrc/model/cbi/n2n_v2.lua @@ -0,0 +1,57 @@ +--[[ +--N2N VPN(V2) configuration page. Made by 981213 +-- +]]-- + +local fs = require "nixio.fs" + +m = Map("n2n_v2", translate("N2N v2 VPN"), + translatef("n2n is a layer-two peer-to-peer virtual private network (VPN) which allows users to exploit features typical of P2P applications at network instead of application level.")) + +s = m:section(TypedSection, "edge", translate("N2N Edge Settings")) +s.anonymous = true + +switch = s:option(Flag, "enabled", translate("Enable")) +switch.rmempty = false + +tunname = s:option(Value, "tunname", translate("TUN desvice name")) +tunname.optional = false + +mode = s:option(ListValue, "mode", translate("Interface mode")) +mode:value("dhcp") +mode:value("static") + +ipaddr = s:option(Value, "ipaddr", translate("Interface IP address")) +ipaddr.optional = false + +netmask = s:option(Value, "netmask", translate("Interface netmask")) +netmask.optional = false + +supernode = s:option(Value, "supernode", translate("Supernode IP address")) +supernode.optional = false + +port = s:option(Value, "port", translate("Supernode Port")) +port.datatype = "range(0,65535)" +port.optional = false + +community = s:option(Value, "community", translate("N2N Community name")) +community.optional = false + +s:option(Value, "key", translate("Encryption key")) + +route = s:option(Flag, "route", translate("Enable packet forwarding")) +route.rmempty = false + +s2 = m:section(TypedSection, "supernode", translate("N2N Supernode Settings")) +s2.anonymous = true + +switch = s2:option(Flag, "enabled", translate("Enable")) +switch.rmempty = false + +port = s2:option(Value, "port", translate("Port")) +port.datatype = "range(0,65535)" +port.optional = false + +return m + + diff --git a/package/lean/luci-app-n2n_v2/po/zh-cn/n2n_v2.po b/package/lean/luci-app-n2n_v2/po/zh-cn/n2n_v2.po new file mode 100755 index 000000000..beedc04ae --- /dev/null +++ b/package/lean/luci-app-n2n_v2/po/zh-cn/n2n_v2.po @@ -0,0 +1,54 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-10-01\n" +"PO-Revision-Date: 2014-10-01\n" +"Last-Translator: 981213 \n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "n2n is a layer-two peer-to-peer virtual private network (VPN) which allows users to exploit features typical of P2P applications at network instead of application level." +msgstr "N2N鏄竴涓浜屽眰鐐瑰鐐筕PN绋嬪簭锛屽畠鍙互璁╃敤鎴峰湪缃戠粶灞傝屼笉鏄簲鐢ㄥ眰浣跨敤涓浜涚偣瀵圭偣鏈嶅姟銆" + +msgid "N2N Edge Settings" +msgstr "N2N Edge鑺傜偣璁剧疆" + +msgid "TUN desvice name" +msgstr "闅ч亾璁惧鍚嶇О" + +msgid "Enable" +msgstr "鍚敤" + +msgid "Interface mode" +msgstr "鎺ュ彛妯″紡" + +msgid "Interface IP address" +msgstr "鎺ュ彛IP鍦板潃" + +msgid "Interface netmask" +msgstr "鎺ュ彛瀛愮綉鎺╃爜" + +msgid "Supernode IP address" +msgstr "Supernode鑺傜偣IP鍦板潃" + +msgid "N2N Community name" +msgstr "N2N缃戠粶缁勫悕绉" + +msgid "Enable packet forwarding" +msgstr "鍚敤鏁版嵁鍖呰浆鍙" + +msgid "N2N Supernode Settings" +msgstr "N2N Supernode鑺傜偣璁剧疆" + +msgid "Port" +msgstr "绔彛" + +msgid "Supernode Port" +msgstr "Supernode鑺傜偣绔彛" + +msgid "Encryption key" +msgstr "鍔犲瘑瀵嗛挜" diff --git a/package/lean/luci-app-n2n_v2/root/etc/uci-defaults/luci-n2n_v2 b/package/lean/luci-app-n2n_v2/root/etc/uci-defaults/luci-n2n_v2 new file mode 100755 index 000000000..145579d55 --- /dev/null +++ b/package/lean/luci-app-n2n_v2/root/etc/uci-defaults/luci-n2n_v2 @@ -0,0 +1,11 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@n2n_v2[-1] + add ucitrack n2n_v2 + set ucitrack.@n2n_v2[-1].init=n2n_v2 + commit ucitrack +EOF + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/package/lean/luci-app-ngrokc/Makefile b/package/lean/luci-app-ngrokc/Makefile new file mode 100644 index 000000000..7afd0386a --- /dev/null +++ b/package/lean/luci-app-ngrokc/Makefile @@ -0,0 +1,9 @@ +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for NGROKC +LUCI_DEPENDS:=+ngrokc +LUCI_PKGARCH:=all + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/package/lean/luci-app-ngrokc/luasrc/controller/ngrokc.lua b/package/lean/luci-app-ngrokc/luasrc/controller/ngrokc.lua new file mode 100644 index 000000000..54854c737 --- /dev/null +++ b/package/lean/luci-app-ngrokc/luasrc/controller/ngrokc.lua @@ -0,0 +1,22 @@ +--[[ +LuCI - Lua Configuration Interface - aria2 support + +Copyright 2014 nanpuyue + +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 +]]-- + +module("luci.controller.ngrokc", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/ngrokc") then + return + end + + entry({"admin", "services", "ngrokc"}, cbi("ngrokc/overview"), _("Ngrok Settings")).dependent = true + entry({"admin", "services", "ngrokc", "detail"}, cbi("ngrokc/detail"), nil ).leaf = true +end diff --git a/package/lean/luci-app-ngrokc/luasrc/model/cbi/ngrokc/detail.lua b/package/lean/luci-app-ngrokc/luasrc/model/cbi/ngrokc/detail.lua new file mode 100644 index 000000000..bd267bb80 --- /dev/null +++ b/package/lean/luci-app-ngrokc/luasrc/model/cbi/ngrokc/detail.lua @@ -0,0 +1,77 @@ +-- Copyright 2008 Steven Barth +-- Copyright 2008 Jo-Philipp Wich +-- Copyright 2013 Manuel Munz +-- Copyright 2014-2015 Christian Schoenebeck +-- Licensed to the public under the Apache License 2.0. + +local UCI = (require "luci.model.uci").cursor() +local NX = require "nixio" +local NXFS = require "nixio.fs" +local SYS = require "luci.sys" +local UTIL = require "luci.util" +local DISP = require "luci.dispatcher" +local DTYP = require "luci.cbi.datatypes" + +local apply = luci.http.formvalue("cbi.apply") +if apply then + os.execute("/etc/init.d/ngrokc reload &") -- reload configuration +end + +-- takeover arguments -- ####################################################### +local section = arg[1] + +m = Map("ngrokc") +m.redirect = DISP.build_url("admin", "services", "ngrokc") + +tunnels = m:section( NamedSection, section, "tunnel", "

" .. translate("Details") .. " : " .. section .. "

") +tunnels.instance = section -- arg [1] + +enabled=tunnels:option(Flag, "enabled", translate("Enable")) +enabled.anonymous = true +enabled.addremove = false + +server=tunnels:option(ListValue, "server", translate("Server")) +--server:value("tunnel_mobi", "tunnel.mobi:44433") +--server:value("tunnel_org_cn", "tunnel.org.cn:4443") +UCI.foreach("ngrokc", "servers", function(s) server:value(s['.name'], s['.name'] .. " ( " .. s.host .. ":" .. s.port .. " ) ") end) + + +ptype=tunnels:option(ListValue, "type", translate("Type")) +ptype:value("tcp", translate("TCP")) +ptype:value("http", translate("HTTP")) +ptype:value("https", translate("HTTPS")) + +lhost=tunnels:option(Value, "lhost", translate("Local Address")) +lhost.rmempty = true +lhost.placeholder="127.0.0.1" +lhost.datatype = "ip4addr" + +lport=tunnels:option(Value, "lport", translate("Local Port")) +lport.datatype = "port" +lport.rmempty = false + +custom_domain=tunnels:option(Flag, "custom_domain", translate("Use Custom Domain")) +custom_domain.default = "0" +custom_domain.disabled = "0" +custom_domain.enabled = "1" +custom_domain.rmempty = false +custom_domain:depends("type", "http") +custom_domain:depends("type", "https") + +dname=tunnels:option(Value, "dname", translate("Custom Domain") .. "/" .. translate("SubDomain"), translate("Please set your domain's CNAME or A record to the tunnel server.")) +dname.datatype = "hostname" +--dname.rmempty = false +dname.rmempty = true +dname:depends("type", "http") +dname:depends("type", "https") + +rport=tunnels:option(Value, "rport", translate("Remote Port")) +rport.datatype = "port" +--rport.rmempty = false +rport.rmempty = true +rport:depends("type", "tcp") + +custom_html=tunnels:option(DummyValue, "none") +custom_html.template = "ngrokc/ngrokc_script" + +return m diff --git a/package/lean/luci-app-ngrokc/luasrc/model/cbi/ngrokc/overview.lua b/package/lean/luci-app-ngrokc/luasrc/model/cbi/ngrokc/overview.lua new file mode 100644 index 000000000..c7bd1b7b8 --- /dev/null +++ b/package/lean/luci-app-ngrokc/luasrc/model/cbi/ngrokc/overview.lua @@ -0,0 +1,108 @@ +-- Mantainer : maz-1 < ohmygod19993 at gmail dot com > + + +m = Map("ngrokc", translate("Ngrok"),translate("Secure tunnels to localhost.")) + +local apply = luci.http.formvalue("cbi.apply") +if apply then + os.execute("/etc/init.d/ngrokc reload &") -- reload configuration +end + +local DISP = require "luci.dispatcher" +local CTRL = require "luci.controller.ngrokc" +local HTTP = require "luci.http" +local UCI = (require "luci.model.uci").cursor() + +servers=m:section(TypedSection, "servers", translate("Servers")) +servers.template = "cbi/tblsection" +servers.anonymous = false +servers.addremove = true + + +nhost=servers:option(Value, "host", translate("Ngrok Host")) +nhost.rmempty = false +nhost.datatype = "host" + +hport=servers:option(Value, "port", translate("Ngrok Port")) +hport.rmempty = false +hport.datatype = "port" + +servers:option(Value, "atoken", translate("Auth Token")).rmempty = true + + +tunnel=m:section(TypedSection, "tunnel", translate("Tunnels")) +tunnel.template = "cbi/tblsection" +tunnel.anonymous = false +tunnel.addremove = true + +tunnel.extedit = DISP.build_url("admin", "services", "ngrokc", "detail", "%s") +function tunnel.create(self, name) + AbstractSection.create(self, name) + HTTP.redirect( self.extedit:format(name) ) +end + +ena=tunnel:option(Flag, "enabled", translate("Enabled")) +ena.template = "ngrokc/overview_enabled" +ena.rmempty = false + +lport=tunnel:option(DummyValue, "_lport", translate("Local Port")) +lport.template = "ngrokc/overview_value" +lport.rmempty = false +function lport.set_one(self, section) + local localport = self.map:get(section, "lport") or "" + if localport ~= "" then + return localport + else + return [[]] .. translate("config error") .. [[]] + end +end + + +server=tunnel:option(DummyValue, "_server", translate("Server")) +server.template = "ngrokc/overview_value" +server.rmempty = false +function server.set_one(self, section) + local servername = self.map:get(section, "server") or "" + local host = UCI.get("ngrokc", servername, "host") or "" + local port = UCI.get("ngrokc", servername, "port") or "" + if servername ~= "" or host ~= "" or port ~= "" then + return host .. ":" .. port + else + return [[]] .. translate("config error") .. [[]] + end +end + +type=tunnel:option(DummyValue, "_type", translate("Type")) +type.template = "ngrokc/overview_value" +type.rmempty = false +function type.set_one(self, section) + local tunneltype = self.map:get(section, "type") or "" + if tunneltype ~= "" then + return string.upper(tunneltype) + else + return [[]] .. translate("config error") .. [[]] + end +end + +url=tunnel:option(DummyValue, "_url", translate("URL")) +url.template = "ngrokc/overview_value" +url.rmempty = false +function url.set_one(self, section) + local servername = self.map:get(section, "server") or "" + local host = UCI.get("ngrokc", servername, "host") or "" + local tunneltype = self.map:get(section, "type") or "" + local dname = self.map:get(section, "dname") or "" + local cusdom = self.map:get(section, "custom_domain") or "" + local rport = self.map:get(section, "rport") or "" + if tunneltype == "tcp" and rport ~= "" then + return "tcp://" .. host .. ":" .. rport + elseif cusdom == "1" and dname ~= "" then + return tunneltype .. "://" .. dname + elseif dname ~= "" then + return tunneltype .. "://" .. dname .. "." .. string.gsub(host, "www", "") + else + return [[]] .. translate("config error") .. [[]] + end +end + +return m diff --git a/package/lean/luci-app-ngrokc/luasrc/view/ngrokc/ngrokc_script.htm b/package/lean/luci-app-ngrokc/luasrc/view/ngrokc/ngrokc_script.htm new file mode 100644 index 000000000..e624f836b --- /dev/null +++ b/package/lean/luci-app-ngrokc/luasrc/view/ngrokc/ngrokc_script.htm @@ -0,0 +1,10 @@ + diff --git a/package/lean/luci-app-ngrokc/luasrc/view/ngrokc/overview_enabled.htm b/package/lean/luci-app-ngrokc/luasrc/view/ngrokc/overview_enabled.htm new file mode 100644 index 000000000..0013807fb --- /dev/null +++ b/package/lean/luci-app-ngrokc/luasrc/view/ngrokc/overview_enabled.htm @@ -0,0 +1,15 @@ + + +<%+cbi/valueheader%> + + /> + + /> + +<%+cbi/valuefooter%> + diff --git a/package/lean/luci-app-ngrokc/luasrc/view/ngrokc/overview_value.htm b/package/lean/luci-app-ngrokc/luasrc/view/ngrokc/overview_value.htm new file mode 100644 index 000000000..2a5cd1614 --- /dev/null +++ b/package/lean/luci-app-ngrokc/luasrc/view/ngrokc/overview_value.htm @@ -0,0 +1,8 @@ + + +<%+cbi/valueheader%> + +<%=self:set_one(section)%> + +<%+cbi/valuefooter%> + diff --git a/package/lean/luci-app-ngrokc/po/zh-cn/ngrokc.po b/package/lean/luci-app-ngrokc/po/zh-cn/ngrokc.po new file mode 100644 index 000000000..a542bc672 --- /dev/null +++ b/package/lean/luci-app-ngrokc/po/zh-cn/ngrokc.po @@ -0,0 +1,56 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8\n" + +msgid "Ngrok Settings" +msgstr "Ngrok璁剧疆" + +msgid "Ngrok" +msgstr "Ngrok鍙嶅悜浠g悊" + +msgid "Secure tunnels to localhost." +msgstr "鏄撶敤鑰屽畨鍏ㄧ殑鍙嶅悜浠g悊杞欢" + +msgid "Enable" +msgstr "鍚敤" + +msgid "Ngrok Host" +msgstr "Ngrok鏈嶅姟鍣" + +msgid "Ngrok Port" +msgstr "Ngrok鏈嶅姟鍣ㄧ鍙" + +msgid "Auth Token" +msgstr "浠ょ墝" + +msgid "Type" +msgstr "绫诲瀷" + +msgid "Local Address" +msgstr "鏈湴鍦板潃" + +msgid "Local Port" +msgstr "鏈湴绔彛" + +msgid "Custom Domain" +msgstr "鑷畾涔夊煙鍚" + +msgid "SubDomain" +msgstr "瀛愬煙鍚" + +msgid "Use Custom Domain" +msgstr "浣跨敤鑷畾涔夊煙鍚" + +msgid "Remote Port" +msgstr "杩滅▼绔彛" + +msgid "Please set your domain's CNAME or A record to the tunnel server." +msgstr "璇锋妸鍩熷悕鐨凜NAME璁板綍鎴朅璁板綍鎸囧悜Ngrok闅ч亾鏈嶅姟鍣ㄣ" + +msgid "Servers" +msgstr "鏈嶅姟鍣" + +msgid "Tunnels" +msgstr "閫氶亾" + +msgid "Details" +msgstr "璇︽儏" diff --git a/package/lean/luci-app-ngrokc/root/etc/config/ngrokc b/package/lean/luci-app-ngrokc/root/etc/config/ngrokc new file mode 100644 index 000000000..ad23009d3 --- /dev/null +++ b/package/lean/luci-app-ngrokc/root/etc/config/ngrokc @@ -0,0 +1,4 @@ + +config servers 'ngrok_cc' + option host 'server.ngrok.cc' + option port '4443' \ No newline at end of file diff --git a/package/lean/luci-app-ngrokc/root/etc/init.d/ngrokc b/package/lean/luci-app-ngrokc/root/etc/init.d/ngrokc new file mode 100755 index 000000000..3c693b8ee --- /dev/null +++ b/package/lean/luci-app-ngrokc/root/etc/init.d/ngrokc @@ -0,0 +1,54 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2007 OpenWrt.org + +START=99 + +list_servers() { + SERVER_PARAMS=" -SER[Shost:" + config_get host "$1" 'host' + config_get port "$1" 'port' + config_get atoken "$1" 'atoken' + SERVER_PARAMS="${SERVER_PARAMS}""${host}"",Sport:""${port}" + [ ! $atoken ] && SERVER_PARAMS=${SERVER_PARAMS}"]" || SERVER_PARAMS=${SERVER_PARAMS}",Atoken:${atoken}]" + eval ${1}_PARAMS=\$SERVER_PARAMS +} + +list_tunnels() { + config_get_bool enabled "$1" 'enabled' + config_get type "$1" 'type' + config_get lhost "$1" 'lhost' + config_get server "$1" 'server' + config_get lport "$1" 'lport' + config_get custom_domain "$1" 'custom_domain' + config_get rport "$1" 'rport' + config_get dname "$1" 'dname' + [ -z "$lhost" ] && lhost="127.0.0.1" + if [ "$enabled" = 1 ]; then + TUNNEL_PARAMS=" -AddTun[Type:${type},Lhost:${lhost},Lport:${lport}" + [ "z"$custom_domain = "z1" ] && DTYPE="Hostname" || DTYPE="Sdname" + [ ${type} = "tcp" ] && \ + TUNNEL_PARAMS=${TUNNEL_PARAMS}",Rport:${rport}]" || \ + TUNNEL_PARAMS=${TUNNEL_PARAMS}",${DTYPE}:${dname}]" + echo $server" : ngrokc"$TUNNEL_PARAMS + config_foreach list_servers 'servers' + eval "exec /usr/bin/ngrokc \$${server}_PARAMS \$TUNNEL_PARAMS 2>&1 > /dev/null & echo \$! >> /tmp/ngrokc/${1}.pid" + fi +} + +start() { + mkdir -p /tmp/ngrokc + config_load 'ngrokc' + [ -f /tmp/ngrokc/ngrokc_running ] || \ + ( config_foreach list_tunnels 'tunnel' ; touch /tmp/ngrokc/ngrokc_running ) +} + +stop() { + kill -2 `pidof ngrokc|sed "s/$$//g"` 2>/dev/null + rm -f /tmp/ngrokc/* + sleep 2 +} + +boot() { + sleep 10 + start +} diff --git a/package/lean/luci-app-ngrokc/root/etc/uci-defaults/luci-app-ngrokc b/package/lean/luci-app-ngrokc/root/etc/uci-defaults/luci-app-ngrokc new file mode 100644 index 000000000..e806bbb25 --- /dev/null +++ b/package/lean/luci-app-ngrokc/root/etc/uci-defaults/luci-app-ngrokc @@ -0,0 +1,11 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@ngrokc[-1] + add ucitrack ngrokc + set ucitrack.@ngrokc[-1].init=ngrokc + commit ucitrack +EOF + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/package/lean/luci-app-openvpn-server/Makefile b/package/lean/luci-app-openvpn-server/Makefile new file mode 100644 index 000000000..4c6c00475 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/Makefile @@ -0,0 +1,21 @@ +# Copyright (C) 2016 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for OpenVPN Server +LUCI_DEPENDS:=+openvpn-openssl +openvpn-easy-rsa +LUCI_PKGARCH:=all +PKG_NAME:=luci-app-openvpn-server +PKG_VERSION:=2.0 +PKG_RELEASE:=12 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature + + + + diff --git a/package/lean/luci-app-openvpn-server/luasrc/controller/openvpn-server.lua b/package/lean/luci-app-openvpn-server/luasrc/controller/openvpn-server.lua new file mode 100644 index 000000000..b5eb40a69 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/luasrc/controller/openvpn-server.lua @@ -0,0 +1,14 @@ + +module("luci.controller.openvpn-server", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/openvpn") then + return + end + + entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false + + local page + + entry({"admin", "vpn", "openvpn-server"}, cbi("openvpn-server/openvpn-server"), _("OpenVPN Server"), 80).dependent=false +end diff --git a/package/lean/luci-app-openvpn-server/luasrc/model/cbi/openvpn-server/openvpn-server.lua b/package/lean/luci-app-openvpn-server/luasrc/model/cbi/openvpn-server/openvpn-server.lua new file mode 100644 index 000000000..df795e4c9 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/luasrc/model/cbi/openvpn-server/openvpn-server.lua @@ -0,0 +1,131 @@ + +--require("luci.tools.webadmin") + +mp = Map("openvpn", "OpenVPN Server","") + +s = mp:section(TypedSection, "openvpn", "", translate("An easy config OpenVPN Server Web-UI")) +s.anonymous = true +s.addremove = false + +s:tab("basic", translate("Base Setting")) + +o = s:taboption("basic", Flag, "enabled", translate("Enable")) + +port = s:taboption("basic", Value, "port", translate("Port")) +port.datatype = "range(1,65535)" + +ddns = s:taboption("basic", Value, "ddns", translate("WAN DDNS or IP")) +ddns.datatype = "string" +ddns.default = "exmple.com" +ddns.rmempty = false + +localnet = s:taboption("basic", Value, "server", translate("Client Network")) +localnet.datatype = "string" +localnet.description = translate("VPN Client Network IP with subnet") + +list = s:taboption("basic", DynamicList, "push") +list.title = translate("Client Settings") +list.datatype = "string" +list.description = translate("Set route 192.168.0.0 255.255.255.0 and dhcp-option DNS 192.168.0.1 base on your router") + + +local o +o = s:taboption("basic", Button,"certificate",translate("OpenVPN Client config file")) +o.inputtitle = translate("Download .ovpn file") +o.description = translate("If you are using IOS client, please download this .ovpn file and send it via QQ or Email to your IOS device") +o.inputstyle = "reload" +o.write = function() + luci.sys.call("sh /etc/genovpn.sh 2>&1 >/dev/null") + Download() +end + +s:tab("code", translate("Special Code")) + +local conf = "/etc/ovpnadd.conf" +local NXFS = require "nixio.fs" +o = s:taboption("code", TextValue, "conf") +o.description = translate("(!)Special Code you know that add in to client .ovpn file") +o.rows = 13 +o.wrap = "off" +o.cfgvalue = function(self, section) + return NXFS.readfile(conf) or "" +end +o.write = function(self, section, value) + NXFS.writefile(conf, value:gsub("\r\n", "\n")) +end + + +local pid = luci.util.exec("/usr/bin/pgrep openvpn") + +function openvpn_process_status() + local status = "OpenVPN is not running now " + + if pid ~= "" then + status = "OpenVPN is running with the PID " .. pid .. "" + end + + local status = { status=status } + local table = { pid=status } + return table +end + + + +function Download() + local t,e + t=nixio.open("/tmp/my.ovpn","r") + luci.http.header('Content-Disposition','attachment; filename="my.ovpn"') + luci.http.prepare_content("application/octet-stream") + while true do + e=t:read(nixio.const.buffersize) + if(not e)or(#e==0)then + break + else + luci.http.write(e) + end + end + t:close() + luci.http.close() +end + +t = mp:section(Table, openvpn_process_status()) +t.anonymous = true + +t:option(DummyValue, "status", translate("OpenVPN status")) + +if pid == "" then + start = t:option(Button, "_start", translate("Start")) + start.inputstyle = "apply" + function start.write(self, section) + luci.util.exec("uci set openvpn.myvpn.enabled=='1' && uci commit openvpn") + message = luci.util.exec("/etc/init.d/openvpn start 2>&1") + luci.util.exec("sleep 2") + luci.http.redirect( + luci.dispatcher.build_url("admin", "vpn", "openvpn-server") .. "?message=" .. message + ) + end +else + stop = t:option(Button, "_stop", translate("Stop")) + stop.inputstyle = "reset" + function stop.write(self, section) + luci.util.exec("uci set openvpn.myvpn.enabled=='0' && uci commit openvpn") + luci.util.exec("/etc/init.d/openvpn stop") + luci.util.exec("sleep 2") + luci.http.redirect( + luci.dispatcher.build_url("admin", "vpn", "openvpn-server") + ) + end +end + +function mp.on_after_commit(self) + os.execute("uci set firewall.openvpn.dest_port=$(uci get openvpn.myvpn.port) && uci commit firewall && /etc/init.d/firewall restart") + os.execute("/etc/init.d/openvpn restart") +end + + +--local apply = luci.http.formvalue("cbi.apply") +--if apply then +-- os.execute("/etc/init.d/openvpn restart") +--end + +return mp diff --git a/package/lean/luci-app-openvpn-server/po/zh-cn/openvpn.po b/package/lean/luci-app-openvpn-server/po/zh-cn/openvpn.po new file mode 100644 index 000000000..960ba61b1 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/po/zh-cn/openvpn.po @@ -0,0 +1,50 @@ +msgid "OpenVPN Server" +msgstr "OpenVPN 鏈嶅姟鍣" + +msgid "An easy config OpenVPN Server Web-UI" +msgstr "鏄撲簬浣跨敤鐨 OpenVPN 鏈嶅姟鍣 Web-UI" + +msgid "Base Setting" +msgstr "鍩烘湰璁剧疆" + +msgid "Enable" +msgstr "鍚敤" + +msgid "Port" +msgstr "绔彛" + +msgid "WAN DDNS or IP" +msgstr "WAN鍙g殑 DDNS鍩熷悕 鎴栬 IP" + + +msgid "Client Network" +msgstr "瀹㈡埛绔綉娈" + +msgid "VPN Client Network IP with subnet" +msgstr "瀹㈡埛绔垎閰嶇殑缃戞鍦板潃锛堥粯璁や负 10.8.0.0 255.255.255.0锛" + + +msgid "Client Settings" +msgstr "瀹㈡埛绔帹閫侀厤缃" + +msgid "OpenVPN Client config file" +msgstr "OpenVPN 瀹㈡埛绔厤缃枃浠" + + +msgid "Download .ovpn file" +msgstr "涓閿笅杞 .ovpn 鏂囦欢" + +msgid "If you are using IOS client, please download this .ovpn file and send it via QQ or Email to your IOS device" +msgstr "濡傛灉浣犱娇鐢ㄧ殑鏄 iOS 璁惧锛屼綘鍙互浣跨敤 QQ 鎴栬呴偖浠跺彂閫佸埌鑷繁鐨勮澶囦笂鐢 OpenVPN 瀹㈡埛绔墦寮瀵煎叆" + +msgid "Special Code" +msgstr "鐗规畩浠g爜" + +msgid "(!)Special Code you know that add in to client .ovpn file" +msgstr "(!)鐗规畩浠g爜灏嗚嚜鍔ㄥ悎骞跺埌瀹㈡埛绔殑 .ovpn 閰嶇疆鏂囦欢涓" + +msgid "Set route 192.168.0.0 255.255.255.0 and dhcp-option DNS 192.168.0.1 base on your router" +msgstr "鏍规嵁璺敱鐨勫疄闄匧AN IP 淇敼 route 192.168.0.0 255.255.255.0 鍜 dhcp-option DNS 192.168.0.1 杩欎袱琛" + +msgid "OpenVPN status" +msgstr "OpenVPN 鏈嶅姟鍣ㄨ繍琛岀姸鎬" diff --git a/package/lean/luci-app-openvpn-server/root/etc/config/openvpn b/package/lean/luci-app-openvpn-server/root/etc/config/openvpn new file mode 100644 index 000000000..6a829f4e6 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/config/openvpn @@ -0,0 +1,28 @@ + +config openvpn 'myvpn' + option enabled '0' + option proto 'tcp-server' + option port '1194' + option ddns example.com + option dev 'tun' + option topology 'subnet' + option server '10.8.0.0 255.255.255.0' + option comp_lzo 'adaptive' + option ca '/etc/openvpn/ca.crt' + option dh '/etc/openvpn/dh1024.pem' + option cert '/etc/openvpn/server.crt' + option key '/etc/openvpn/server.key' + option persist_key '1' + option persist_tun '1' + option user 'nobody' + option group 'nogroup' + option max_clients '10' + option keepalive '10 120' + option verb '3' + option status '/var/log/openvpn_status.log' + option log '/tmp/openvpn.log' + list push 'route 192.168.0.0 255.255.255.0' + list push 'comp-lzo adaptive' + list push 'redirect-gateway def1 bypass-dhcp' + list push 'dhcp-option DNS 192.168.0.1' + diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/01.pem b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/01.pem new file mode 100644 index 000000000..a73a757e9 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/01.pem @@ -0,0 +1,74 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=CN, ST=ZJ, L=ZJ, O=ZJ, OU=ZJ, CN=ZJ CA/name=EasyRSA/emailAddress=ZJ@ZJ.com + Validity + Not Before: Aug 23 14:26:42 2017 GMT + Not After : Aug 21 14:26:42 2027 GMT + Subject: C=CN, ST=ZJ, L=ZJ, O=ZJ, OU=ZJ, CN=server/name=EasyRSA/emailAddress=ZJ@ZJ.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: + 00:e0:67:2e:33:ab:4f:4f:a1:78:c6:32:ba:d3:1d: + 71:73:34:ba:45:40:88:87:76:03:fb:87:d8:4e:4e: + 7c:7d:95:22:7d:8e:70:dc:68:10:27:fe:7d:f0:79: + 93:86:83:ef:a9:16:78:ae:86:5e:ea:42:74:38:4d: + 37:0d:c9:34:a6:84:5e:64:ad:dd:91:dd:df:02:bf: + 53:f8:fb:c0:9b:cb:bd:93:7c:26:ab:bd:0a:c6:c3: + 5d:da:5d:b3:c0:ff:72:a1:2f:1e:0b:f6:a6:71:77: + f9:00:38:8a:ae:ab:c0:86:11:ab:12:de:1e:82:13: + e8:c3:d5:bb:6f:2e:bf:6e:c1 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Cert Type: + SSL Server + Netscape Comment: + Easy-RSA Generated Server Certificate + X509v3 Subject Key Identifier: + 1C:06:47:33:61:0E:15:84:D5:08:5A:40:E6:C9:23:EF:87:F3:EE:F9 + X509v3 Authority Key Identifier: + keyid:8D:D5:04:79:10:05:4F:1B:12:63:11:AC:00:D4:FC:CC:31:00:B8:09 + DirName:/C=CN/ST=ZJ/L=ZJ/O=ZJ/OU=ZJ/CN=ZJ CA/name=EasyRSA/emailAddress=ZJ@ZJ.com + serial:AE:18:A1:E1:3D:52:4D:F0 + + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Key Usage: + Digital Signature, Key Encipherment + Signature Algorithm: sha256WithRSAEncryption + aa:b5:0d:7a:b3:09:7a:d4:e6:df:46:0d:54:39:e2:34:da:4f: + 9b:92:d6:41:db:10:b9:ed:66:34:7f:9d:a9:fa:af:6a:80:b4: + 1f:13:d3:39:a6:72:93:5a:6b:e8:4f:ba:95:f9:83:10:58:b3: + fe:12:3f:a9:e8:31:04:e0:8e:d8:4c:c1:f7:7e:fc:7a:ba:17: + d8:2e:76:ab:7c:17:ca:a4:1d:3d:c5:bc:df:02:e5:2e:91:c4: + b2:6c:40:a1:e2:3d:64:15:da:a6:b0:e4:1d:66:11:54:c0:49: + 05:91:c4:69:68:2d:bc:d5:f6:32:43:3c:18:c4:97:54:45:52: + 28:36 +-----BEGIN CERTIFICATE----- +MIIDvzCCAyigAwIBAgIBATANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJDTjEL +MAkGA1UECBMCWkoxCzAJBgNVBAcTAlpKMQswCQYDVQQKEwJaSjELMAkGA1UECxMC +WkoxDjAMBgNVBAMTBVpKIENBMRAwDgYDVQQpEwdFYXN5UlNBMRgwFgYJKoZIhvcN +AQkBFglaSkBaSi5jb20wHhcNMTcwODIzMTQyNjQyWhcNMjcwODIxMTQyNjQyWjB+ +MQswCQYDVQQGEwJDTjELMAkGA1UECBMCWkoxCzAJBgNVBAcTAlpKMQswCQYDVQQK +EwJaSjELMAkGA1UECxMCWkoxDzANBgNVBAMTBnNlcnZlcjEQMA4GA1UEKRMHRWFz +eVJTQTEYMBYGCSqGSIb3DQEJARYJWkpAWkouY29tMIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDgZy4zq09PoXjGMrrTHXFzNLpFQIiHdgP7h9hOTnx9lSJ9jnDc +aBAn/n3weZOGg++pFniuhl7qQnQ4TTcNyTSmhF5krd2R3d8Cv1P4+8Cby72TfCar +vQrGw13aXbPA/3KhLx4L9qZxd/kAOIquq8CGEasS3h6CE+jD1btvLr9uwQIDAQAB +o4IBTDCCAUgwCQYDVR0TBAIwADARBglghkgBhvhCAQEEBAMCBkAwNAYJYIZIAYb4 +QgENBCcWJUVhc3ktUlNBIEdlbmVyYXRlZCBTZXJ2ZXIgQ2VydGlmaWNhdGUwHQYD +VR0OBBYEFBwGRzNhDhWE1QhaQObJI++H8+75MIGwBgNVHSMEgagwgaWAFI3VBHkQ +BU8bEmMRrADU/MwxALgJoYGBpH8wfTELMAkGA1UEBhMCQ04xCzAJBgNVBAgTAlpK +MQswCQYDVQQHEwJaSjELMAkGA1UEChMCWkoxCzAJBgNVBAsTAlpKMQ4wDAYDVQQD +EwVaSiBDQTEQMA4GA1UEKRMHRWFzeVJTQTEYMBYGCSqGSIb3DQEJARYJWkpAWkou +Y29tggkArhih4T1STfAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWg +MA0GCSqGSIb3DQEBCwUAA4GBAKq1DXqzCXrU5t9GDVQ54jTaT5uS1kHbELntZjR/ +nan6r2qAtB8T0zmmcpNaa+hPupX5gxBYs/4SP6noMQTgjthMwfd+/Hq6F9gudqt8 +F8qkHT3FvN8C5S6RxLJsQKHiPWQV2qaw5B1mEVTASQWRxGloLbzV9jJDPBjEl1RF +Uig2 +-----END CERTIFICATE----- diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/02.pem b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/02.pem new file mode 100644 index 000000000..c757880ea --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/02.pem @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=CN, ST=ZJ, L=ZJ, O=ZJ, OU=ZJ, CN=ZJ CA/name=EasyRSA/emailAddress=ZJ@ZJ.com + Validity + Not Before: Aug 23 14:26:58 2017 GMT + Not After : Aug 21 14:26:58 2027 GMT + Subject: C=CN, ST=ZJ, L=ZJ, O=ZJ, OU=ZJ, CN=client1/name=EasyRSA/emailAddress=ZJ@ZJ.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: + 00:b7:6b:40:0b:c1:ef:a7:c3:fa:54:32:c2:d7:87: + fa:ac:85:18:ae:af:44:ba:dd:57:0f:43:73:eb:df: + 37:5e:5e:8f:ad:43:7a:87:dd:a6:bd:6a:0b:68:8d: + 75:0c:fe:49:39:e1:54:11:53:0f:b5:63:10:5b:21: + 98:7f:53:32:b3:d6:b0:3d:23:fc:1d:ad:06:b0:f0: + fb:10:27:83:e1:5e:5a:b4:f6:7c:02:87:4c:73:86: + 7b:79:07:ca:a7:1c:18:2c:70:e3:9d:e6:f0:89:06: + 4b:25:2c:09:39:51:c3:d4:44:ef:81:5e:aa:e0:63: + d8:11:c6:9c:e0:6f:d8:66:11 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + Easy-RSA Generated Certificate + X509v3 Subject Key Identifier: + E8:15:F9:71:C4:A7:C2:41:A3:AF:F5:C5:93:51:8E:5D:67:9B:12:E2 + X509v3 Authority Key Identifier: + keyid:8D:D5:04:79:10:05:4F:1B:12:63:11:AC:00:D4:FC:CC:31:00:B8:09 + DirName:/C=CN/ST=ZJ/L=ZJ/O=ZJ/OU=ZJ/CN=ZJ CA/name=EasyRSA/emailAddress=ZJ@ZJ.com + serial:AE:18:A1:E1:3D:52:4D:F0 + + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + 5b:63:c2:e5:e4:04:ad:f4:b6:76:24:df:94:a5:b0:a2:99:38: + f9:e7:b4:2f:79:91:51:1b:06:4b:33:fc:4c:74:ce:47:3e:54: + 1b:da:ea:43:e3:6d:6e:ec:b4:cd:77:86:ea:ea:48:a1:79:70: + 5c:ff:99:0e:fb:bd:fc:0d:89:a6:2e:13:fe:86:82:69:33:4c: + 28:21:0d:a8:ba:1a:3e:c7:2e:2d:97:0c:5a:ed:e3:af:73:fc: + bb:c9:58:05:c5:26:56:13:1c:3e:8f:90:c7:e8:d9:e5:0b:1f: + 40:9a:fa:15:49:b9:d8:8e:6a:fd:71:f4:3c:df:a1:11:af:fb: + ea:a8 +-----BEGIN CERTIFICATE----- +MIIDpjCCAw+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJDTjEL +MAkGA1UECBMCWkoxCzAJBgNVBAcTAlpKMQswCQYDVQQKEwJaSjELMAkGA1UECxMC +WkoxDjAMBgNVBAMTBVpKIENBMRAwDgYDVQQpEwdFYXN5UlNBMRgwFgYJKoZIhvcN +AQkBFglaSkBaSi5jb20wHhcNMTcwODIzMTQyNjU4WhcNMjcwODIxMTQyNjU4WjB/ +MQswCQYDVQQGEwJDTjELMAkGA1UECBMCWkoxCzAJBgNVBAcTAlpKMQswCQYDVQQK +EwJaSjELMAkGA1UECxMCWkoxEDAOBgNVBAMTB2NsaWVudDExEDAOBgNVBCkTB0Vh +c3lSU0ExGDAWBgkqhkiG9w0BCQEWCVpKQFpKLmNvbTCBnzANBgkqhkiG9w0BAQEF +AAOBjQAwgYkCgYEAt2tAC8Hvp8P6VDLC14f6rIUYrq9Eut1XD0Nz6983Xl6PrUN6 +h92mvWoLaI11DP5JOeFUEVMPtWMQWyGYf1Mys9awPSP8Ha0GsPD7ECeD4V5atPZ8 +AodMc4Z7eQfKpxwYLHDjnebwiQZLJSwJOVHD1ETvgV6q4GPYEcac4G/YZhECAwEA +AaOCATIwggEuMAkGA1UdEwQCMAAwLQYJYIZIAYb4QgENBCAWHkVhc3ktUlNBIEdl +bmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU6BX5ccSnwkGjr/XFk1GOXWeb +EuIwgbAGA1UdIwSBqDCBpYAUjdUEeRAFTxsSYxGsANT8zDEAuAmhgYGkfzB9MQsw +CQYDVQQGEwJDTjELMAkGA1UECBMCWkoxCzAJBgNVBAcTAlpKMQswCQYDVQQKEwJa +SjELMAkGA1UECxMCWkoxDjAMBgNVBAMTBVpKIENBMRAwDgYDVQQpEwdFYXN5UlNB +MRgwFgYJKoZIhvcNAQkBFglaSkBaSi5jb22CCQCuGKHhPVJN8DATBgNVHSUEDDAK +BggrBgEFBQcDAjALBgNVHQ8EBAMCB4AwDQYJKoZIhvcNAQELBQADgYEAW2PC5eQE +rfS2diTflKWwopk4+ee0L3mRURsGSzP8THTORz5UG9rqQ+Ntbuy0zXeG6upIoXlw +XP+ZDvu9/A2Jpi4T/oaCaTNMKCENqLoaPscuLZcMWu3jr3P8u8lYBcUmVhMcPo+Q +x+jZ5QsfQJr6FUm52I5q/XH0PN+hEa/76qg= +-----END CERTIFICATE----- diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/ca.crt b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/ca.crt new file mode 100644 index 000000000..7b7ba5ef8 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/ca.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDXDCCAsWgAwIBAgIJAK4YoeE9Uk3wMA0GCSqGSIb3DQEBCwUAMH0xCzAJBgNV +BAYTAkNOMQswCQYDVQQIEwJaSjELMAkGA1UEBxMCWkoxCzAJBgNVBAoTAlpKMQsw +CQYDVQQLEwJaSjEOMAwGA1UEAxMFWkogQ0ExEDAOBgNVBCkTB0Vhc3lSU0ExGDAW +BgkqhkiG9w0BCQEWCVpKQFpKLmNvbTAeFw0xNzA4MjMxNDE4MDVaFw0yNzA4MjEx +NDE4MDVaMH0xCzAJBgNVBAYTAkNOMQswCQYDVQQIEwJaSjELMAkGA1UEBxMCWkox +CzAJBgNVBAoTAlpKMQswCQYDVQQLEwJaSjEOMAwGA1UEAxMFWkogQ0ExEDAOBgNV +BCkTB0Vhc3lSU0ExGDAWBgkqhkiG9w0BCQEWCVpKQFpKLmNvbTCBnzANBgkqhkiG +9w0BAQEFAAOBjQAwgYkCgYEAsLBNLkjfNUK4Rb3xgJD0EEgzp6b+5zkiibT3wdS9 +SKZqkqJRcM/z7Ifc79LKXDDHrVnajkyc8QSaXOKVW8pTx75fYnoHjNbeU9JZHoTg +9GgRWq5HHUJlxhsdbcGeTxOHrMRz2d+VzvNvs5KOLJaqGkRmm/KMb7nTRnwjhx4A +pWsCAwEAAaOB4zCB4DAdBgNVHQ4EFgQUjdUEeRAFTxsSYxGsANT8zDEAuAkwgbAG +A1UdIwSBqDCBpYAUjdUEeRAFTxsSYxGsANT8zDEAuAmhgYGkfzB9MQswCQYDVQQG +EwJDTjELMAkGA1UECBMCWkoxCzAJBgNVBAcTAlpKMQswCQYDVQQKEwJaSjELMAkG +A1UECxMCWkoxDjAMBgNVBAMTBVpKIENBMRAwDgYDVQQpEwdFYXN5UlNBMRgwFgYJ +KoZIhvcNAQkBFglaSkBaSi5jb22CCQCuGKHhPVJN8DAMBgNVHRMEBTADAQH/MA0G +CSqGSIb3DQEBCwUAA4GBAAAN0aRmQGNsF23CxShEnj3ohgpYA20F2FwEWYmCCWXe +CKxuPGtPZAeLmToIMgn75QlyuvVG+Uoe7I6ylbEK3XoeNStcS61wAXL8hIPfMcUX +fDsImBvc+Bo+LxQMWMSz0r88+B8784KELyaQKOnvPlTrnTuyP9RftjUWpjy23Kjd +-----END CERTIFICATE----- diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/ca.key b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/ca.key new file mode 100644 index 000000000..796fbf10e --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/ca.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALCwTS5I3zVCuEW9 +8YCQ9BBIM6em/uc5Iom098HUvUimapKiUXDP8+yH3O/Sylwwx61Z2o5MnPEEmlzi +lVvKU8e+X2J6B4zW3lPSWR6E4PRoEVquRx1CZcYbHW3Bnk8Th6zEc9nflc7zb7OS +jiyWqhpEZpvyjG+500Z8I4ceAKVrAgMBAAECgYBfiTRyTlzCg6z3qNioV7hgBWpI +wHcbtz0BkKRWXh1q5vDBEJtQkGCoCF5iHmvkpUuSY/9U6gACIicFCk8QLrpVZGzY +1SgOQS796La2gYR0clCvtsf8Kg4BYCKkF40jGDGZTGKtWa9mPuOZXZFhSMZJiCQi +UIfTN3D9Ngt/nLFMwQJBANwavdYXnPxGr/0rL1ct0RUjsZLyd9kmr1gD4Nq+/uwC +FQrNHl/ieXOsSeD0eVNtuTFzmt8sTz963SXmbPv01dMCQQDNgPioq4M/1sluGUdI +yK5bantPAD7A7wTb+uryP7lNMuDSGTXgLsh+RrhBuDlUdi+OPc0dIJV1fTjEiLbI +fLsJAkEAoSSe6Zh+IaDrBfJRBYWQtuZcApasMfqFk227eMsuvcFEgJTt8QtRGeQA +bsbt8Ku7Uz4tG8lH99TPBglurwRwawJAALVrJhnBUB0LgMexiTy37TTGzBTyInQw +jhmlacRyfSOpxs+zcdx3cIgJ5qAeAn6N1227IViVa1xNL9BQ4QwdEQJBAJjLcCYS +twmgoyOj4K5+8+aAuuXWj7lpxEakOZbghrBmy0GytiRKN9wb/x8QF6EtrJAmYltL +wMMDUDE0zd+hc2Q= +-----END PRIVATE KEY----- diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/client1.crt b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/client1.crt new file mode 100644 index 000000000..c757880ea --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/client1.crt @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=CN, ST=ZJ, L=ZJ, O=ZJ, OU=ZJ, CN=ZJ CA/name=EasyRSA/emailAddress=ZJ@ZJ.com + Validity + Not Before: Aug 23 14:26:58 2017 GMT + Not After : Aug 21 14:26:58 2027 GMT + Subject: C=CN, ST=ZJ, L=ZJ, O=ZJ, OU=ZJ, CN=client1/name=EasyRSA/emailAddress=ZJ@ZJ.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: + 00:b7:6b:40:0b:c1:ef:a7:c3:fa:54:32:c2:d7:87: + fa:ac:85:18:ae:af:44:ba:dd:57:0f:43:73:eb:df: + 37:5e:5e:8f:ad:43:7a:87:dd:a6:bd:6a:0b:68:8d: + 75:0c:fe:49:39:e1:54:11:53:0f:b5:63:10:5b:21: + 98:7f:53:32:b3:d6:b0:3d:23:fc:1d:ad:06:b0:f0: + fb:10:27:83:e1:5e:5a:b4:f6:7c:02:87:4c:73:86: + 7b:79:07:ca:a7:1c:18:2c:70:e3:9d:e6:f0:89:06: + 4b:25:2c:09:39:51:c3:d4:44:ef:81:5e:aa:e0:63: + d8:11:c6:9c:e0:6f:d8:66:11 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + Easy-RSA Generated Certificate + X509v3 Subject Key Identifier: + E8:15:F9:71:C4:A7:C2:41:A3:AF:F5:C5:93:51:8E:5D:67:9B:12:E2 + X509v3 Authority Key Identifier: + keyid:8D:D5:04:79:10:05:4F:1B:12:63:11:AC:00:D4:FC:CC:31:00:B8:09 + DirName:/C=CN/ST=ZJ/L=ZJ/O=ZJ/OU=ZJ/CN=ZJ CA/name=EasyRSA/emailAddress=ZJ@ZJ.com + serial:AE:18:A1:E1:3D:52:4D:F0 + + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + 5b:63:c2:e5:e4:04:ad:f4:b6:76:24:df:94:a5:b0:a2:99:38: + f9:e7:b4:2f:79:91:51:1b:06:4b:33:fc:4c:74:ce:47:3e:54: + 1b:da:ea:43:e3:6d:6e:ec:b4:cd:77:86:ea:ea:48:a1:79:70: + 5c:ff:99:0e:fb:bd:fc:0d:89:a6:2e:13:fe:86:82:69:33:4c: + 28:21:0d:a8:ba:1a:3e:c7:2e:2d:97:0c:5a:ed:e3:af:73:fc: + bb:c9:58:05:c5:26:56:13:1c:3e:8f:90:c7:e8:d9:e5:0b:1f: + 40:9a:fa:15:49:b9:d8:8e:6a:fd:71:f4:3c:df:a1:11:af:fb: + ea:a8 +-----BEGIN CERTIFICATE----- +MIIDpjCCAw+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJDTjEL +MAkGA1UECBMCWkoxCzAJBgNVBAcTAlpKMQswCQYDVQQKEwJaSjELMAkGA1UECxMC +WkoxDjAMBgNVBAMTBVpKIENBMRAwDgYDVQQpEwdFYXN5UlNBMRgwFgYJKoZIhvcN +AQkBFglaSkBaSi5jb20wHhcNMTcwODIzMTQyNjU4WhcNMjcwODIxMTQyNjU4WjB/ +MQswCQYDVQQGEwJDTjELMAkGA1UECBMCWkoxCzAJBgNVBAcTAlpKMQswCQYDVQQK +EwJaSjELMAkGA1UECxMCWkoxEDAOBgNVBAMTB2NsaWVudDExEDAOBgNVBCkTB0Vh +c3lSU0ExGDAWBgkqhkiG9w0BCQEWCVpKQFpKLmNvbTCBnzANBgkqhkiG9w0BAQEF +AAOBjQAwgYkCgYEAt2tAC8Hvp8P6VDLC14f6rIUYrq9Eut1XD0Nz6983Xl6PrUN6 +h92mvWoLaI11DP5JOeFUEVMPtWMQWyGYf1Mys9awPSP8Ha0GsPD7ECeD4V5atPZ8 +AodMc4Z7eQfKpxwYLHDjnebwiQZLJSwJOVHD1ETvgV6q4GPYEcac4G/YZhECAwEA +AaOCATIwggEuMAkGA1UdEwQCMAAwLQYJYIZIAYb4QgENBCAWHkVhc3ktUlNBIEdl +bmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU6BX5ccSnwkGjr/XFk1GOXWeb +EuIwgbAGA1UdIwSBqDCBpYAUjdUEeRAFTxsSYxGsANT8zDEAuAmhgYGkfzB9MQsw +CQYDVQQGEwJDTjELMAkGA1UECBMCWkoxCzAJBgNVBAcTAlpKMQswCQYDVQQKEwJa +SjELMAkGA1UECxMCWkoxDjAMBgNVBAMTBVpKIENBMRAwDgYDVQQpEwdFYXN5UlNB +MRgwFgYJKoZIhvcNAQkBFglaSkBaSi5jb22CCQCuGKHhPVJN8DATBgNVHSUEDDAK +BggrBgEFBQcDAjALBgNVHQ8EBAMCB4AwDQYJKoZIhvcNAQELBQADgYEAW2PC5eQE +rfS2diTflKWwopk4+ee0L3mRURsGSzP8THTORz5UG9rqQ+Ntbuy0zXeG6upIoXlw +XP+ZDvu9/A2Jpi4T/oaCaTNMKCENqLoaPscuLZcMWu3jr3P8u8lYBcUmVhMcPo+Q +x+jZ5QsfQJr6FUm52I5q/XH0PN+hEa/76qg= +-----END CERTIFICATE----- diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/client1.csr b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/client1.csr new file mode 100644 index 000000000..a3549ca15 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/client1.csr @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBvzCCASgCAQAwfzELMAkGA1UEBhMCQ04xCzAJBgNVBAgTAlpKMQswCQYDVQQH +EwJaSjELMAkGA1UEChMCWkoxCzAJBgNVBAsTAlpKMRAwDgYDVQQDEwdjbGllbnQx +MRAwDgYDVQQpEwdFYXN5UlNBMRgwFgYJKoZIhvcNAQkBFglaSkBaSi5jb20wgZ8w +DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALdrQAvB76fD+lQywteH+qyFGK6vRLrd +Vw9Dc+vfN15ej61Deofdpr1qC2iNdQz+STnhVBFTD7VjEFshmH9TMrPWsD0j/B2t +BrDw+xAng+FeWrT2fAKHTHOGe3kHyqccGCxw453m8IkGSyUsCTlRw9RE74FequBj +2BHGnOBv2GYRAgMBAAGgADANBgkqhkiG9w0BAQsFAAOBgQBfvn2fP2Tj8FTZH+Xk +9u04rYaQdspSyL61F4QIEiP5UOUzbnSSU/B72KF5gm8b0irXGnTbHlXeMv6WXaAS +VF1fEeM+gsGJIDOvomT5PKfudezr6DpGrUammQnRY3tho078Ao0Mkq8PAWpiVWGV +Z7rsqHhI3mWYLNyne9n8K224pg== +-----END CERTIFICATE REQUEST----- diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/client1.key b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/client1.key new file mode 100644 index 000000000..076ce4e72 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/client1.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALdrQAvB76fD+lQy +wteH+qyFGK6vRLrdVw9Dc+vfN15ej61Deofdpr1qC2iNdQz+STnhVBFTD7VjEFsh +mH9TMrPWsD0j/B2tBrDw+xAng+FeWrT2fAKHTHOGe3kHyqccGCxw453m8IkGSyUs +CTlRw9RE74FequBj2BHGnOBv2GYRAgMBAAECgYBhWatEkkqA4KOczNRdUO7bYkkX +bi8sfw4WK9b6+h6JF+dqLsZ6FkrJfd9QPsRBgTWcYtwb1dogi9PCirJF4gKmSsv1 +h/BISW4lrXJPf08aJAuBF0ym8XZUgVLLptn8KdXX3xc6YF6K336AnNNLZ80X4El8 +m7X4d8Y3F4k3Dj04AQJBAN9NkHYwevaZ8jfv5rZSTKECmdk1DZITd756+sObFAs1 +vX9VfunwVw6xWmaUyMt8oPFqb0wKES9zqrViaMhU9YkCQQDSRqV3ldHcaZJ6sTgm +T8ZKm+UpbC4zat4rGSBYKaoeLRPh5nxP892rOfBAevkoIQzW7LfVfoMImM/i1J6T +lNJJAkAHSOZ/lJFOXjNSs9bY99JcJlOSjHKG42+ynRx1KSf8PaKS9t0PELImXo7O +begnC0fM2GYNGv74h1N4W1+DuZHRAkEAlNov3jSvh+EwMSxs/Cnyy/QJyEXteraH +KWkzDVYJOC1e6sZXb93JKKHuIicrY63pwed2x2o0ZgyO9RrgWsa6CQJBAMogPcRO +jUGjYs3IYXW6Suf1bRJN2aS81gx7lqyLQE3ignH6e9kMxcrzG4AzzePCLouY3waL +HS1KW8V9I5c4qTs= +-----END PRIVATE KEY----- diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/client1.p12 b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/client1.p12 new file mode 100644 index 000000000..1511e1d0a Binary files /dev/null and b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/client1.p12 differ diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/dh1024.pem b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/dh1024.pem new file mode 100644 index 000000000..01eba3e5a --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/dh1024.pem @@ -0,0 +1,5 @@ +-----BEGIN DH PARAMETERS----- +MIGHAoGBAMzJWsEtMQ76G81O8RzEweDaPrio4NihRBo0fmNuh3IjJtFJ++URPW4y +HHtnGOkPoMwQjGQ3GQV+lfcR7QGWojET4NskXOk6mdFU+/nYB9s5YY7RR4qyln9b +dNMp3KnMLtILNH1rJRoqYbSNoz3Z2cS59Ejp1dgXqN8kSP8wiqDjAgEC +-----END DH PARAMETERS----- diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/index.txt b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/index.txt new file mode 100644 index 000000000..4bb34b80f --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/index.txt @@ -0,0 +1,2 @@ +V 270821142642Z 01 unknown /C=CN/ST=ZJ/L=ZJ/O=ZJ/OU=ZJ/CN=server/name=EasyRSA/emailAddress=ZJ@ZJ.com +V 270821142658Z 02 unknown /C=CN/ST=ZJ/L=ZJ/O=ZJ/OU=ZJ/CN=client1/name=EasyRSA/emailAddress=ZJ@ZJ.com diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/index.txt.attr b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/index.txt.attr new file mode 100644 index 000000000..8f7e63a34 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/index.txt.attr @@ -0,0 +1 @@ +unique_subject = yes diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/index.txt.attr.old b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/index.txt.attr.old new file mode 100644 index 000000000..8f7e63a34 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/index.txt.attr.old @@ -0,0 +1 @@ +unique_subject = yes diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/index.txt.old b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/index.txt.old new file mode 100644 index 000000000..d74831ee4 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/index.txt.old @@ -0,0 +1 @@ +V 270821142642Z 01 unknown /C=CN/ST=ZJ/L=ZJ/O=ZJ/OU=ZJ/CN=server/name=EasyRSA/emailAddress=ZJ@ZJ.com diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/serial b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/serial new file mode 100644 index 000000000..75016ea36 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/serial @@ -0,0 +1 @@ +03 diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/serial.old b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/serial.old new file mode 100644 index 000000000..9e22bcb8e --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/serial.old @@ -0,0 +1 @@ +02 diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/server.crt b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/server.crt new file mode 100644 index 000000000..a73a757e9 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/server.crt @@ -0,0 +1,74 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=CN, ST=ZJ, L=ZJ, O=ZJ, OU=ZJ, CN=ZJ CA/name=EasyRSA/emailAddress=ZJ@ZJ.com + Validity + Not Before: Aug 23 14:26:42 2017 GMT + Not After : Aug 21 14:26:42 2027 GMT + Subject: C=CN, ST=ZJ, L=ZJ, O=ZJ, OU=ZJ, CN=server/name=EasyRSA/emailAddress=ZJ@ZJ.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: + 00:e0:67:2e:33:ab:4f:4f:a1:78:c6:32:ba:d3:1d: + 71:73:34:ba:45:40:88:87:76:03:fb:87:d8:4e:4e: + 7c:7d:95:22:7d:8e:70:dc:68:10:27:fe:7d:f0:79: + 93:86:83:ef:a9:16:78:ae:86:5e:ea:42:74:38:4d: + 37:0d:c9:34:a6:84:5e:64:ad:dd:91:dd:df:02:bf: + 53:f8:fb:c0:9b:cb:bd:93:7c:26:ab:bd:0a:c6:c3: + 5d:da:5d:b3:c0:ff:72:a1:2f:1e:0b:f6:a6:71:77: + f9:00:38:8a:ae:ab:c0:86:11:ab:12:de:1e:82:13: + e8:c3:d5:bb:6f:2e:bf:6e:c1 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Cert Type: + SSL Server + Netscape Comment: + Easy-RSA Generated Server Certificate + X509v3 Subject Key Identifier: + 1C:06:47:33:61:0E:15:84:D5:08:5A:40:E6:C9:23:EF:87:F3:EE:F9 + X509v3 Authority Key Identifier: + keyid:8D:D5:04:79:10:05:4F:1B:12:63:11:AC:00:D4:FC:CC:31:00:B8:09 + DirName:/C=CN/ST=ZJ/L=ZJ/O=ZJ/OU=ZJ/CN=ZJ CA/name=EasyRSA/emailAddress=ZJ@ZJ.com + serial:AE:18:A1:E1:3D:52:4D:F0 + + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Key Usage: + Digital Signature, Key Encipherment + Signature Algorithm: sha256WithRSAEncryption + aa:b5:0d:7a:b3:09:7a:d4:e6:df:46:0d:54:39:e2:34:da:4f: + 9b:92:d6:41:db:10:b9:ed:66:34:7f:9d:a9:fa:af:6a:80:b4: + 1f:13:d3:39:a6:72:93:5a:6b:e8:4f:ba:95:f9:83:10:58:b3: + fe:12:3f:a9:e8:31:04:e0:8e:d8:4c:c1:f7:7e:fc:7a:ba:17: + d8:2e:76:ab:7c:17:ca:a4:1d:3d:c5:bc:df:02:e5:2e:91:c4: + b2:6c:40:a1:e2:3d:64:15:da:a6:b0:e4:1d:66:11:54:c0:49: + 05:91:c4:69:68:2d:bc:d5:f6:32:43:3c:18:c4:97:54:45:52: + 28:36 +-----BEGIN CERTIFICATE----- +MIIDvzCCAyigAwIBAgIBATANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJDTjEL +MAkGA1UECBMCWkoxCzAJBgNVBAcTAlpKMQswCQYDVQQKEwJaSjELMAkGA1UECxMC +WkoxDjAMBgNVBAMTBVpKIENBMRAwDgYDVQQpEwdFYXN5UlNBMRgwFgYJKoZIhvcN +AQkBFglaSkBaSi5jb20wHhcNMTcwODIzMTQyNjQyWhcNMjcwODIxMTQyNjQyWjB+ +MQswCQYDVQQGEwJDTjELMAkGA1UECBMCWkoxCzAJBgNVBAcTAlpKMQswCQYDVQQK +EwJaSjELMAkGA1UECxMCWkoxDzANBgNVBAMTBnNlcnZlcjEQMA4GA1UEKRMHRWFz +eVJTQTEYMBYGCSqGSIb3DQEJARYJWkpAWkouY29tMIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDgZy4zq09PoXjGMrrTHXFzNLpFQIiHdgP7h9hOTnx9lSJ9jnDc +aBAn/n3weZOGg++pFniuhl7qQnQ4TTcNyTSmhF5krd2R3d8Cv1P4+8Cby72TfCar +vQrGw13aXbPA/3KhLx4L9qZxd/kAOIquq8CGEasS3h6CE+jD1btvLr9uwQIDAQAB +o4IBTDCCAUgwCQYDVR0TBAIwADARBglghkgBhvhCAQEEBAMCBkAwNAYJYIZIAYb4 +QgENBCcWJUVhc3ktUlNBIEdlbmVyYXRlZCBTZXJ2ZXIgQ2VydGlmaWNhdGUwHQYD +VR0OBBYEFBwGRzNhDhWE1QhaQObJI++H8+75MIGwBgNVHSMEgagwgaWAFI3VBHkQ +BU8bEmMRrADU/MwxALgJoYGBpH8wfTELMAkGA1UEBhMCQ04xCzAJBgNVBAgTAlpK +MQswCQYDVQQHEwJaSjELMAkGA1UEChMCWkoxCzAJBgNVBAsTAlpKMQ4wDAYDVQQD +EwVaSiBDQTEQMA4GA1UEKRMHRWFzeVJTQTEYMBYGCSqGSIb3DQEJARYJWkpAWkou +Y29tggkArhih4T1STfAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWg +MA0GCSqGSIb3DQEBCwUAA4GBAKq1DXqzCXrU5t9GDVQ54jTaT5uS1kHbELntZjR/ +nan6r2qAtB8T0zmmcpNaa+hPupX5gxBYs/4SP6noMQTgjthMwfd+/Hq6F9gudqt8 +F8qkHT3FvN8C5S6RxLJsQKHiPWQV2qaw5B1mEVTASQWRxGloLbzV9jJDPBjEl1RF +Uig2 +-----END CERTIFICATE----- diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/server.csr b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/server.csr new file mode 100644 index 000000000..c83aadabe --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/server.csr @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBvjCCAScCAQAwfjELMAkGA1UEBhMCQ04xCzAJBgNVBAgTAlpKMQswCQYDVQQH +EwJaSjELMAkGA1UEChMCWkoxCzAJBgNVBAsTAlpKMQ8wDQYDVQQDEwZzZXJ2ZXIx +EDAOBgNVBCkTB0Vhc3lSU0ExGDAWBgkqhkiG9w0BCQEWCVpKQFpKLmNvbTCBnzAN +BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4GcuM6tPT6F4xjK60x1xczS6RUCIh3YD ++4fYTk58fZUifY5w3GgQJ/598HmThoPvqRZ4roZe6kJ0OE03Dck0poReZK3dkd3f +Ar9T+PvAm8u9k3wmq70KxsNd2l2zwP9yoS8eC/amcXf5ADiKrqvAhhGrEt4eghPo +w9W7by6/bsECAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4GBAMrytQrG3MGVTD2vsZkw +hJn9U4MYmikqFxEcSJ+JEeDJ0w3NTn95XJmFtmuT/CwsrnP9g+1neSpCXsZewozd +QRisYBF9Rl9qw9fH2o1S/GIVpTDIiTtWjegZA6FPkhQQyY387LU9Lp4vG9hdNbuz +QNDs6cI9T0U53PZiq7R65rGV +-----END CERTIFICATE REQUEST----- diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/server.key b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/server.key new file mode 100644 index 000000000..3aab5cd4b --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/keys/server.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOBnLjOrT0+heMYy +utMdcXM0ukVAiId2A/uH2E5OfH2VIn2OcNxoECf+ffB5k4aD76kWeK6GXupCdDhN +Nw3JNKaEXmSt3ZHd3wK/U/j7wJvLvZN8Jqu9CsbDXdpds8D/cqEvHgv2pnF3+QA4 +iq6rwIYRqxLeHoIT6MPVu28uv27BAgMBAAECgYEAqno4g1BVxG0rT4cin1fy5E7e +Y9YO4ropdGFTVsoRkWZG+ZPI8eisvXV9P79c8AgzfgVwUUYLvXQWzt76QCLnN11x +pBURloJbEReEEzIF6z3LiT9CKgVWY4vtC6f5OW4Kd+EZxXMftFz8kMzRuRQLvOzR +WeU+3GD42mIwYjsXBrECQQD2P6azeZJ1ZIEf+9Ys19tSQ6uxbXyvghlTfhmZfBW3 +bshNRH4+L4lnnbm75pFkWqR0gYSAD3toRymccctN2K9jAkEA6UoRwURTjIER8yZO +6gLTFtzb841jv6TPErOY7CzNZ/TYBUdUBmM/NB4+RgBpBNFXB3uqweNVPO6mhyQP +zB88iwJBAOeH6YGOqTpfiVk9PJ9lRf4PSnvE6htLQ+zQ/9jkZrbWHtcns1tc7uDR +2DToEYQ+BarVrHOMGwhtAJ7sD6/eMOkCQFjn8XxGHdEeH0kbAFgOW4QLB4f6Clmu +5XurFkxrhpxnoyvf0xXcHOov3GuxHFTJsvEXICxkBsgB61T1WU/hV6ECQGzk5Eqo +uik2OAYMOb7NPGYMWS68DpmP11QDuvoj5zm2vdzohXHyBM7mO12MLSrTpxfgjWhQ +pqwEbErchuKkzN4= +-----END PRIVATE KEY----- diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/openssl-1.0.0.cnf b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/openssl-1.0.0.cnf new file mode 100644 index 000000000..93ac6eaba --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/openssl-1.0.0.cnf @@ -0,0 +1,286 @@ +# For use with easy-rsa version 2.0 and OpenSSL 1.0.0* + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $ENV::HOME/.rnd +openssl_conf = openssl_init + +[ openssl_init ] +# Extra OBJECT IDENTIFIER info: +#oid_file = $ENV::HOME/.oid +oid_section = new_oids +engines = engine_section + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] + +# We can add new OIDs in here for use by 'ca' and 'req'. +# Add a simple OID like this: +# testoid1=1.2.3.4 +# Or use config file substitution like this: +# testoid2=${testoid1}.5.6 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = $ENV::KEY_DIR # Where everything is kept +certs = $dir # Where the issued certs are kept +crl_dir = $dir # Where the issued crl are kept +database = $dir/index.txt # database index file. +new_certs_dir = $dir # default place for new certs. + +certificate = $dir/ca.crt # The CA certificate +serial = $dir/serial # The current serial number +crl = $dir/crl.pem # The current CRL +private_key = $dir/ca.key # The private key +RANDFILE = $dir/.rand # private random number file + +x509_extensions = usr_cert # The extentions to add to the cert + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crl_extensions = crl_ext + +default_days = 3650 # how long to certify for +default_crl_days= 30 # how long before next CRL +default_md = sha256 # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_anything + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +name = optional +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +name = optional +emailAddress = optional + +#################################################################### +[ req ] +default_bits = $ENV::KEY_SIZE +default_keyfile = privkey.pem +default_md = sha256 +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extentions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation after 2004). +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +string_mask = nombstr + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = $ENV::KEY_COUNTRY +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = $ENV::KEY_PROVINCE + +localityName = Locality Name (eg, city) +localityName_default = $ENV::KEY_CITY + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = $ENV::KEY_ORG + +# we can do this but it is not needed normally :-) +#1.organizationName = Second Organization Name (eg, company) +#1.organizationName_default = World Wide Web Pty Ltd + +organizationalUnitName = Organizational Unit Name (eg, section) +#organizationalUnitName_default = + +commonName = Common Name (eg, your name or your server\'s hostname) +commonName_max = 64 + +name = Name +name_max = 64 + +emailAddress = Email Address +emailAddress_default = $ENV::KEY_EMAIL +emailAddress_max = 40 + +# JY -- added for batch mode +organizationalUnitName_default = $ENV::KEY_OU +commonName_default = $ENV::KEY_CN +name_default = $ENV::KEY_NAME + + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_min = 4 +challengePassword_max = 20 + +unstructuredName = An optional company name + +[ usr_cert ] + +# These extensions are added when 'ca' signs a request. + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +# nsCertType = server + +# For an object signing certificate this would be used. +# nsCertType = objsign + +# For normal client use this is typical +# nsCertType = client, email + +# and for everything including object signing: +# nsCertType = client, email, objsign + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "Easy-RSA Generated Certificate" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer:always +extendedKeyUsage=clientAuth +keyUsage = digitalSignature + + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy + +# Copy subject details +# issuerAltName=issuer:copy + +#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +[ server ] + +# JY ADDED -- Make a cert with nsCertType set to "server" +basicConstraints=CA:FALSE +nsCertType = server +nsComment = "Easy-RSA Generated Server Certificate" +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer:always +extendedKeyUsage=serverAuth +keyUsage = digitalSignature, keyEncipherment + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] + + +# Extensions for a typical CA + + +# PKIX recommendation. + +subjectKeyIdentifier=hash + +authorityKeyIdentifier=keyid:always,issuer:always + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. However since it will +# prevent it being used as an test self-signed certificate it is best +# left out by default. +# keyUsage = cRLSign, keyCertSign + +# Some might want this also +# nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +# subjectAltName=email:copy +# Copy issuer details +# issuerAltName=issuer:copy + +# DER hex encoding of an extension: beware experts only! +# obj=DER:02:03 +# Where 'obj' is a standard or added object +# You can even override a supported extension: +# basicConstraints= critical, DER:30:03:01:01:FF + +[ crl_ext ] + +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +# issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always,issuer:always + +[ engine_section ] +# +# If you are using PKCS#11 +# Install engine_pkcs11 of opensc (www.opensc.org) +# And uncomment the following +# verify that dynamic_path points to the correct location +# +#pkcs11 = pkcs11_section + +[ pkcs11_section ] +engine_id = pkcs11 +dynamic_path = /usr/lib/engines/engine_pkcs11.so +MODULE_PATH = $ENV::PKCS11_MODULE_PATH +PIN = $ENV::PKCS11_PIN +init = 0 diff --git a/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/vars b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/vars new file mode 100644 index 000000000..4873fbcf7 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/easy-rsa/vars @@ -0,0 +1,19 @@ +export EASY_RSA="/etc/easy-rsa" +export OPENSSL="openssl" +export PKCS11TOOL="pkcs11-tool" +export GREP="grep" +export KEY_CONFIG=`/usr/sbin/whichopensslcnf $EASY_RSA` +export KEY_DIR="$EASY_RSA/keys" +echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR +export PKCS11_MODULE_PATH="dummy" +export PKCS11_PIN="dummy" +export KEY_SIZE=1024 +export CA_EXPIRE=3650 +export KEY_EXPIRE=3650 +export KEY_COUNTRY="CN" +export KEY_PROVINCE="ZJ" +export KEY_CITY="ZJ" +export KEY_ORG="ZJ" +export KEY_EMAIL="ZJ@ZJ.com" +export KEY_OU="ZJ" +export KEY_NAME="EasyRSA" \ No newline at end of file diff --git a/package/lean/luci-app-openvpn-server/root/etc/genovpn.sh b/package/lean/luci-app-openvpn-server/root/etc/genovpn.sh new file mode 100755 index 000000000..964f8e859 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/genovpn.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +ddns=`uci get openvpn.myvpn.ddns` +port=`uci get openvpn.myvpn.port` + +cat > /tmp/my.ovpn <' >> /tmp/my.ovpn +cat /etc/openvpn/ca.crt >> /tmp/my.ovpn +echo '' >> /tmp/my.ovpn +echo '' >> /tmp/my.ovpn +cat /etc/openvpn/client1.crt >> /tmp/my.ovpn +echo '' >> /tmp/my.ovpn +echo '' >> /tmp/my.ovpn +cat /etc/openvpn/client1.key >> /tmp/my.ovpn +echo '' >> /tmp/my.ovpn +[ -f /etc/ovpnadd.conf ] && cat /etc/ovpnadd.conf >> /tmp/my.ovpn diff --git a/package/lean/luci-app-openvpn-server/root/etc/openvpn/ca.crt b/package/lean/luci-app-openvpn-server/root/etc/openvpn/ca.crt new file mode 100644 index 000000000..7b7ba5ef8 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/openvpn/ca.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDXDCCAsWgAwIBAgIJAK4YoeE9Uk3wMA0GCSqGSIb3DQEBCwUAMH0xCzAJBgNV +BAYTAkNOMQswCQYDVQQIEwJaSjELMAkGA1UEBxMCWkoxCzAJBgNVBAoTAlpKMQsw +CQYDVQQLEwJaSjEOMAwGA1UEAxMFWkogQ0ExEDAOBgNVBCkTB0Vhc3lSU0ExGDAW +BgkqhkiG9w0BCQEWCVpKQFpKLmNvbTAeFw0xNzA4MjMxNDE4MDVaFw0yNzA4MjEx +NDE4MDVaMH0xCzAJBgNVBAYTAkNOMQswCQYDVQQIEwJaSjELMAkGA1UEBxMCWkox +CzAJBgNVBAoTAlpKMQswCQYDVQQLEwJaSjEOMAwGA1UEAxMFWkogQ0ExEDAOBgNV +BCkTB0Vhc3lSU0ExGDAWBgkqhkiG9w0BCQEWCVpKQFpKLmNvbTCBnzANBgkqhkiG +9w0BAQEFAAOBjQAwgYkCgYEAsLBNLkjfNUK4Rb3xgJD0EEgzp6b+5zkiibT3wdS9 +SKZqkqJRcM/z7Ifc79LKXDDHrVnajkyc8QSaXOKVW8pTx75fYnoHjNbeU9JZHoTg +9GgRWq5HHUJlxhsdbcGeTxOHrMRz2d+VzvNvs5KOLJaqGkRmm/KMb7nTRnwjhx4A +pWsCAwEAAaOB4zCB4DAdBgNVHQ4EFgQUjdUEeRAFTxsSYxGsANT8zDEAuAkwgbAG +A1UdIwSBqDCBpYAUjdUEeRAFTxsSYxGsANT8zDEAuAmhgYGkfzB9MQswCQYDVQQG +EwJDTjELMAkGA1UECBMCWkoxCzAJBgNVBAcTAlpKMQswCQYDVQQKEwJaSjELMAkG +A1UECxMCWkoxDjAMBgNVBAMTBVpKIENBMRAwDgYDVQQpEwdFYXN5UlNBMRgwFgYJ +KoZIhvcNAQkBFglaSkBaSi5jb22CCQCuGKHhPVJN8DAMBgNVHRMEBTADAQH/MA0G +CSqGSIb3DQEBCwUAA4GBAAAN0aRmQGNsF23CxShEnj3ohgpYA20F2FwEWYmCCWXe +CKxuPGtPZAeLmToIMgn75QlyuvVG+Uoe7I6ylbEK3XoeNStcS61wAXL8hIPfMcUX +fDsImBvc+Bo+LxQMWMSz0r88+B8784KELyaQKOnvPlTrnTuyP9RftjUWpjy23Kjd +-----END CERTIFICATE----- diff --git a/package/lean/luci-app-openvpn-server/root/etc/openvpn/client1.crt b/package/lean/luci-app-openvpn-server/root/etc/openvpn/client1.crt new file mode 100644 index 000000000..c757880ea --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/openvpn/client1.crt @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=CN, ST=ZJ, L=ZJ, O=ZJ, OU=ZJ, CN=ZJ CA/name=EasyRSA/emailAddress=ZJ@ZJ.com + Validity + Not Before: Aug 23 14:26:58 2017 GMT + Not After : Aug 21 14:26:58 2027 GMT + Subject: C=CN, ST=ZJ, L=ZJ, O=ZJ, OU=ZJ, CN=client1/name=EasyRSA/emailAddress=ZJ@ZJ.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: + 00:b7:6b:40:0b:c1:ef:a7:c3:fa:54:32:c2:d7:87: + fa:ac:85:18:ae:af:44:ba:dd:57:0f:43:73:eb:df: + 37:5e:5e:8f:ad:43:7a:87:dd:a6:bd:6a:0b:68:8d: + 75:0c:fe:49:39:e1:54:11:53:0f:b5:63:10:5b:21: + 98:7f:53:32:b3:d6:b0:3d:23:fc:1d:ad:06:b0:f0: + fb:10:27:83:e1:5e:5a:b4:f6:7c:02:87:4c:73:86: + 7b:79:07:ca:a7:1c:18:2c:70:e3:9d:e6:f0:89:06: + 4b:25:2c:09:39:51:c3:d4:44:ef:81:5e:aa:e0:63: + d8:11:c6:9c:e0:6f:d8:66:11 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + Easy-RSA Generated Certificate + X509v3 Subject Key Identifier: + E8:15:F9:71:C4:A7:C2:41:A3:AF:F5:C5:93:51:8E:5D:67:9B:12:E2 + X509v3 Authority Key Identifier: + keyid:8D:D5:04:79:10:05:4F:1B:12:63:11:AC:00:D4:FC:CC:31:00:B8:09 + DirName:/C=CN/ST=ZJ/L=ZJ/O=ZJ/OU=ZJ/CN=ZJ CA/name=EasyRSA/emailAddress=ZJ@ZJ.com + serial:AE:18:A1:E1:3D:52:4D:F0 + + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + 5b:63:c2:e5:e4:04:ad:f4:b6:76:24:df:94:a5:b0:a2:99:38: + f9:e7:b4:2f:79:91:51:1b:06:4b:33:fc:4c:74:ce:47:3e:54: + 1b:da:ea:43:e3:6d:6e:ec:b4:cd:77:86:ea:ea:48:a1:79:70: + 5c:ff:99:0e:fb:bd:fc:0d:89:a6:2e:13:fe:86:82:69:33:4c: + 28:21:0d:a8:ba:1a:3e:c7:2e:2d:97:0c:5a:ed:e3:af:73:fc: + bb:c9:58:05:c5:26:56:13:1c:3e:8f:90:c7:e8:d9:e5:0b:1f: + 40:9a:fa:15:49:b9:d8:8e:6a:fd:71:f4:3c:df:a1:11:af:fb: + ea:a8 +-----BEGIN CERTIFICATE----- +MIIDpjCCAw+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJDTjEL +MAkGA1UECBMCWkoxCzAJBgNVBAcTAlpKMQswCQYDVQQKEwJaSjELMAkGA1UECxMC +WkoxDjAMBgNVBAMTBVpKIENBMRAwDgYDVQQpEwdFYXN5UlNBMRgwFgYJKoZIhvcN +AQkBFglaSkBaSi5jb20wHhcNMTcwODIzMTQyNjU4WhcNMjcwODIxMTQyNjU4WjB/ +MQswCQYDVQQGEwJDTjELMAkGA1UECBMCWkoxCzAJBgNVBAcTAlpKMQswCQYDVQQK +EwJaSjELMAkGA1UECxMCWkoxEDAOBgNVBAMTB2NsaWVudDExEDAOBgNVBCkTB0Vh +c3lSU0ExGDAWBgkqhkiG9w0BCQEWCVpKQFpKLmNvbTCBnzANBgkqhkiG9w0BAQEF +AAOBjQAwgYkCgYEAt2tAC8Hvp8P6VDLC14f6rIUYrq9Eut1XD0Nz6983Xl6PrUN6 +h92mvWoLaI11DP5JOeFUEVMPtWMQWyGYf1Mys9awPSP8Ha0GsPD7ECeD4V5atPZ8 +AodMc4Z7eQfKpxwYLHDjnebwiQZLJSwJOVHD1ETvgV6q4GPYEcac4G/YZhECAwEA +AaOCATIwggEuMAkGA1UdEwQCMAAwLQYJYIZIAYb4QgENBCAWHkVhc3ktUlNBIEdl +bmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU6BX5ccSnwkGjr/XFk1GOXWeb +EuIwgbAGA1UdIwSBqDCBpYAUjdUEeRAFTxsSYxGsANT8zDEAuAmhgYGkfzB9MQsw +CQYDVQQGEwJDTjELMAkGA1UECBMCWkoxCzAJBgNVBAcTAlpKMQswCQYDVQQKEwJa +SjELMAkGA1UECxMCWkoxDjAMBgNVBAMTBVpKIENBMRAwDgYDVQQpEwdFYXN5UlNB +MRgwFgYJKoZIhvcNAQkBFglaSkBaSi5jb22CCQCuGKHhPVJN8DATBgNVHSUEDDAK +BggrBgEFBQcDAjALBgNVHQ8EBAMCB4AwDQYJKoZIhvcNAQELBQADgYEAW2PC5eQE +rfS2diTflKWwopk4+ee0L3mRURsGSzP8THTORz5UG9rqQ+Ntbuy0zXeG6upIoXlw +XP+ZDvu9/A2Jpi4T/oaCaTNMKCENqLoaPscuLZcMWu3jr3P8u8lYBcUmVhMcPo+Q +x+jZ5QsfQJr6FUm52I5q/XH0PN+hEa/76qg= +-----END CERTIFICATE----- diff --git a/package/lean/luci-app-openvpn-server/root/etc/openvpn/client1.key b/package/lean/luci-app-openvpn-server/root/etc/openvpn/client1.key new file mode 100644 index 000000000..076ce4e72 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/openvpn/client1.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALdrQAvB76fD+lQy +wteH+qyFGK6vRLrdVw9Dc+vfN15ej61Deofdpr1qC2iNdQz+STnhVBFTD7VjEFsh +mH9TMrPWsD0j/B2tBrDw+xAng+FeWrT2fAKHTHOGe3kHyqccGCxw453m8IkGSyUs +CTlRw9RE74FequBj2BHGnOBv2GYRAgMBAAECgYBhWatEkkqA4KOczNRdUO7bYkkX +bi8sfw4WK9b6+h6JF+dqLsZ6FkrJfd9QPsRBgTWcYtwb1dogi9PCirJF4gKmSsv1 +h/BISW4lrXJPf08aJAuBF0ym8XZUgVLLptn8KdXX3xc6YF6K336AnNNLZ80X4El8 +m7X4d8Y3F4k3Dj04AQJBAN9NkHYwevaZ8jfv5rZSTKECmdk1DZITd756+sObFAs1 +vX9VfunwVw6xWmaUyMt8oPFqb0wKES9zqrViaMhU9YkCQQDSRqV3ldHcaZJ6sTgm +T8ZKm+UpbC4zat4rGSBYKaoeLRPh5nxP892rOfBAevkoIQzW7LfVfoMImM/i1J6T +lNJJAkAHSOZ/lJFOXjNSs9bY99JcJlOSjHKG42+ynRx1KSf8PaKS9t0PELImXo7O +begnC0fM2GYNGv74h1N4W1+DuZHRAkEAlNov3jSvh+EwMSxs/Cnyy/QJyEXteraH +KWkzDVYJOC1e6sZXb93JKKHuIicrY63pwed2x2o0ZgyO9RrgWsa6CQJBAMogPcRO +jUGjYs3IYXW6Suf1bRJN2aS81gx7lqyLQE3ignH6e9kMxcrzG4AzzePCLouY3waL +HS1KW8V9I5c4qTs= +-----END PRIVATE KEY----- diff --git a/package/lean/luci-app-openvpn-server/root/etc/openvpn/dh1024.pem b/package/lean/luci-app-openvpn-server/root/etc/openvpn/dh1024.pem new file mode 100644 index 000000000..01eba3e5a --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/openvpn/dh1024.pem @@ -0,0 +1,5 @@ +-----BEGIN DH PARAMETERS----- +MIGHAoGBAMzJWsEtMQ76G81O8RzEweDaPrio4NihRBo0fmNuh3IjJtFJ++URPW4y +HHtnGOkPoMwQjGQ3GQV+lfcR7QGWojET4NskXOk6mdFU+/nYB9s5YY7RR4qyln9b +dNMp3KnMLtILNH1rJRoqYbSNoz3Z2cS59Ejp1dgXqN8kSP8wiqDjAgEC +-----END DH PARAMETERS----- diff --git a/package/lean/luci-app-openvpn-server/root/etc/openvpn/server.crt b/package/lean/luci-app-openvpn-server/root/etc/openvpn/server.crt new file mode 100644 index 000000000..a73a757e9 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/openvpn/server.crt @@ -0,0 +1,74 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=CN, ST=ZJ, L=ZJ, O=ZJ, OU=ZJ, CN=ZJ CA/name=EasyRSA/emailAddress=ZJ@ZJ.com + Validity + Not Before: Aug 23 14:26:42 2017 GMT + Not After : Aug 21 14:26:42 2027 GMT + Subject: C=CN, ST=ZJ, L=ZJ, O=ZJ, OU=ZJ, CN=server/name=EasyRSA/emailAddress=ZJ@ZJ.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: + 00:e0:67:2e:33:ab:4f:4f:a1:78:c6:32:ba:d3:1d: + 71:73:34:ba:45:40:88:87:76:03:fb:87:d8:4e:4e: + 7c:7d:95:22:7d:8e:70:dc:68:10:27:fe:7d:f0:79: + 93:86:83:ef:a9:16:78:ae:86:5e:ea:42:74:38:4d: + 37:0d:c9:34:a6:84:5e:64:ad:dd:91:dd:df:02:bf: + 53:f8:fb:c0:9b:cb:bd:93:7c:26:ab:bd:0a:c6:c3: + 5d:da:5d:b3:c0:ff:72:a1:2f:1e:0b:f6:a6:71:77: + f9:00:38:8a:ae:ab:c0:86:11:ab:12:de:1e:82:13: + e8:c3:d5:bb:6f:2e:bf:6e:c1 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Cert Type: + SSL Server + Netscape Comment: + Easy-RSA Generated Server Certificate + X509v3 Subject Key Identifier: + 1C:06:47:33:61:0E:15:84:D5:08:5A:40:E6:C9:23:EF:87:F3:EE:F9 + X509v3 Authority Key Identifier: + keyid:8D:D5:04:79:10:05:4F:1B:12:63:11:AC:00:D4:FC:CC:31:00:B8:09 + DirName:/C=CN/ST=ZJ/L=ZJ/O=ZJ/OU=ZJ/CN=ZJ CA/name=EasyRSA/emailAddress=ZJ@ZJ.com + serial:AE:18:A1:E1:3D:52:4D:F0 + + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Key Usage: + Digital Signature, Key Encipherment + Signature Algorithm: sha256WithRSAEncryption + aa:b5:0d:7a:b3:09:7a:d4:e6:df:46:0d:54:39:e2:34:da:4f: + 9b:92:d6:41:db:10:b9:ed:66:34:7f:9d:a9:fa:af:6a:80:b4: + 1f:13:d3:39:a6:72:93:5a:6b:e8:4f:ba:95:f9:83:10:58:b3: + fe:12:3f:a9:e8:31:04:e0:8e:d8:4c:c1:f7:7e:fc:7a:ba:17: + d8:2e:76:ab:7c:17:ca:a4:1d:3d:c5:bc:df:02:e5:2e:91:c4: + b2:6c:40:a1:e2:3d:64:15:da:a6:b0:e4:1d:66:11:54:c0:49: + 05:91:c4:69:68:2d:bc:d5:f6:32:43:3c:18:c4:97:54:45:52: + 28:36 +-----BEGIN CERTIFICATE----- +MIIDvzCCAyigAwIBAgIBATANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJDTjEL +MAkGA1UECBMCWkoxCzAJBgNVBAcTAlpKMQswCQYDVQQKEwJaSjELMAkGA1UECxMC +WkoxDjAMBgNVBAMTBVpKIENBMRAwDgYDVQQpEwdFYXN5UlNBMRgwFgYJKoZIhvcN +AQkBFglaSkBaSi5jb20wHhcNMTcwODIzMTQyNjQyWhcNMjcwODIxMTQyNjQyWjB+ +MQswCQYDVQQGEwJDTjELMAkGA1UECBMCWkoxCzAJBgNVBAcTAlpKMQswCQYDVQQK +EwJaSjELMAkGA1UECxMCWkoxDzANBgNVBAMTBnNlcnZlcjEQMA4GA1UEKRMHRWFz +eVJTQTEYMBYGCSqGSIb3DQEJARYJWkpAWkouY29tMIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDgZy4zq09PoXjGMrrTHXFzNLpFQIiHdgP7h9hOTnx9lSJ9jnDc +aBAn/n3weZOGg++pFniuhl7qQnQ4TTcNyTSmhF5krd2R3d8Cv1P4+8Cby72TfCar +vQrGw13aXbPA/3KhLx4L9qZxd/kAOIquq8CGEasS3h6CE+jD1btvLr9uwQIDAQAB +o4IBTDCCAUgwCQYDVR0TBAIwADARBglghkgBhvhCAQEEBAMCBkAwNAYJYIZIAYb4 +QgENBCcWJUVhc3ktUlNBIEdlbmVyYXRlZCBTZXJ2ZXIgQ2VydGlmaWNhdGUwHQYD +VR0OBBYEFBwGRzNhDhWE1QhaQObJI++H8+75MIGwBgNVHSMEgagwgaWAFI3VBHkQ +BU8bEmMRrADU/MwxALgJoYGBpH8wfTELMAkGA1UEBhMCQ04xCzAJBgNVBAgTAlpK +MQswCQYDVQQHEwJaSjELMAkGA1UEChMCWkoxCzAJBgNVBAsTAlpKMQ4wDAYDVQQD +EwVaSiBDQTEQMA4GA1UEKRMHRWFzeVJTQTEYMBYGCSqGSIb3DQEJARYJWkpAWkou +Y29tggkArhih4T1STfAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWg +MA0GCSqGSIb3DQEBCwUAA4GBAKq1DXqzCXrU5t9GDVQ54jTaT5uS1kHbELntZjR/ +nan6r2qAtB8T0zmmcpNaa+hPupX5gxBYs/4SP6noMQTgjthMwfd+/Hq6F9gudqt8 +F8qkHT3FvN8C5S6RxLJsQKHiPWQV2qaw5B1mEVTASQWRxGloLbzV9jJDPBjEl1RF +Uig2 +-----END CERTIFICATE----- diff --git a/package/lean/luci-app-openvpn-server/root/etc/openvpn/server.key b/package/lean/luci-app-openvpn-server/root/etc/openvpn/server.key new file mode 100644 index 000000000..3aab5cd4b --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/openvpn/server.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOBnLjOrT0+heMYy +utMdcXM0ukVAiId2A/uH2E5OfH2VIn2OcNxoECf+ffB5k4aD76kWeK6GXupCdDhN +Nw3JNKaEXmSt3ZHd3wK/U/j7wJvLvZN8Jqu9CsbDXdpds8D/cqEvHgv2pnF3+QA4 +iq6rwIYRqxLeHoIT6MPVu28uv27BAgMBAAECgYEAqno4g1BVxG0rT4cin1fy5E7e +Y9YO4ropdGFTVsoRkWZG+ZPI8eisvXV9P79c8AgzfgVwUUYLvXQWzt76QCLnN11x +pBURloJbEReEEzIF6z3LiT9CKgVWY4vtC6f5OW4Kd+EZxXMftFz8kMzRuRQLvOzR +WeU+3GD42mIwYjsXBrECQQD2P6azeZJ1ZIEf+9Ys19tSQ6uxbXyvghlTfhmZfBW3 +bshNRH4+L4lnnbm75pFkWqR0gYSAD3toRymccctN2K9jAkEA6UoRwURTjIER8yZO +6gLTFtzb841jv6TPErOY7CzNZ/TYBUdUBmM/NB4+RgBpBNFXB3uqweNVPO6mhyQP +zB88iwJBAOeH6YGOqTpfiVk9PJ9lRf4PSnvE6htLQ+zQ/9jkZrbWHtcns1tc7uDR +2DToEYQ+BarVrHOMGwhtAJ7sD6/eMOkCQFjn8XxGHdEeH0kbAFgOW4QLB4f6Clmu +5XurFkxrhpxnoyvf0xXcHOov3GuxHFTJsvEXICxkBsgB61T1WU/hV6ECQGzk5Eqo +uik2OAYMOb7NPGYMWS68DpmP11QDuvoj5zm2vdzohXHyBM7mO12MLSrTpxfgjWhQ +pqwEbErchuKkzN4= +-----END PRIVATE KEY----- diff --git a/package/lean/luci-app-openvpn-server/root/etc/openvpncert.sh b/package/lean/luci-app-openvpn-server/root/etc/openvpncert.sh new file mode 100755 index 000000000..61d6f0cb9 --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/openvpncert.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +clean-all +echo -en "\n\n\n\n\n\n\n\n" | build-ca +build-dh +build-key-server server +build-key-pkcs12 client1 +cp /etc/easy-rsa/keys/ca.crt /etc/openvpn/ +cp /etc/easy-rsa/keys/server.crt /etc/openvpn/ +cp /etc/easy-rsa/keys/server.key /etc/openvpn/ +cp /etc/easy-rsa/keys/dh1024.pem /etc/openvpn/ +cp /etc/easy-rsa/keys/client1.crt /etc/openvpn/ +cp /etc/easy-rsa/keys/client1.key /etc/openvpn/ +/etc/init.d/openvpn restart +echo "OpenVPN Cert renew successfully" \ No newline at end of file diff --git a/package/lean/luci-app-openvpn-server/root/etc/ovpnadd.conf b/package/lean/luci-app-openvpn-server/root/etc/ovpnadd.conf new file mode 100644 index 000000000..0d03f345b --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/ovpnadd.conf @@ -0,0 +1,9 @@ +http-proxy-option EXT1 "POST http://rd.go.10086.cn" +http-proxy-option EXT1 "GET http://rd.go.10086.cn" +http-proxy-option EXT1 "X-Online-Host: rd.go.10086.cn" +http-proxy-option EXT1 "POST http://rd.go.10086.cn" +http-proxy-option EXT1 "X-Online-Host: rd.go.10086.cn" +http-proxy-option EXT1 "POST http://rd.go.10086.cn" +http-proxy-option EXT1 "Host: rd.go.10086.cn" +http-proxy-option EXT1 "GET http://rd.go.10086.cn" +http-proxy-option EXT1 "Host: rd.go.10086.cn" \ No newline at end of file diff --git a/package/lean/luci-app-openvpn-server/root/etc/uci-defaults/openvpn b/package/lean/luci-app-openvpn-server/root/etc/uci-defaults/openvpn new file mode 100755 index 000000000..849754dfd --- /dev/null +++ b/package/lean/luci-app-openvpn-server/root/etc/uci-defaults/openvpn @@ -0,0 +1,45 @@ +#!/bin/sh + +uci set network.vpn0="interface" +uci set network.vpn0.ifname="tun0" +uci set network.vpn0.proto="none" +uci commit network; +/etc/init.d/network reload + +uci delete firewall.openvpn +uci add firewall rule +uci rename firewall.@rule[-1]="openvpn" +uci set firewall.@rule[-1].name="openvpn" +uci set firewall.@rule[-1].target="ACCEPT" +uci set firewall.@rule[-1].src="wan" +uci set firewall.@rule[-1].proto="tcp" +uci set firewall.@rule[-1].dest_port="1194" + +uci delete firewall.vpn +uci delete firewall.vpnwan +uci delete firewall.vpnlan +uci commit firewall + +uci add firewall zone +uci rename firewall.@zone[-1]="vpn" +uci set firewall.@zone[-1].name="vpn" +uci set firewall.@zone[-1].input="ACCEPT" +uci set firewall.@zone[-1].forward="ACCEPT" +uci set firewall.@zone[-1].output="ACCEPT" +uci set firewall.@zone[-1].masq="1" +uci set firewall.@zone[-1].network="vpn0" +uci add firewall forwarding +uci rename firewall.@forwarding[-1]="vpnwan" +uci set firewall.@forwarding[-1].src="vpn" +uci set firewall.@forwarding[-1].dest="wan" +uci add firewall forwarding +uci rename firewall.@forwarding[-1]="vpnlan" +uci set firewall.@forwarding[-1].src="vpn" +uci set firewall.@forwarding[-1].dest="lan" +uci commit firewall; +/etc/init.d/firewall restart + +/etc/init.d/openvpn disable && /etc/init.d/openvpn stop + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/package/lean/luci-app-pptp-server/Makefile b/package/lean/luci-app-pptp-server/Makefile new file mode 100644 index 000000000..0c84f20a9 --- /dev/null +++ b/package/lean/luci-app-pptp-server/Makefile @@ -0,0 +1,21 @@ +# Copyright (C) 2016 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for PPTP VPN Server +LUCI_DEPENDS:=+pptpd +kmod-mppe +ppp +LUCI_PKGARCH:=all +PKG_NAME:=luci-app-pptp-server +PKG_VERSION:=2.0 +PKG_RELEASE:=5 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature + + + + diff --git a/package/lean/luci-app-pptp-server/luasrc/controller/pptp-server.lua b/package/lean/luci-app-pptp-server/luasrc/controller/pptp-server.lua new file mode 100644 index 000000000..4274acd4f --- /dev/null +++ b/package/lean/luci-app-pptp-server/luasrc/controller/pptp-server.lua @@ -0,0 +1,14 @@ + +module("luci.controller.pptp-server", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/pptpd") then + return + end + + entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false + + local page + + entry({"admin", "vpn", "pptp-server"}, cbi("pptp-server/pptp-server"), _("PPTP VPN Server"), 80).dependent=false +end diff --git a/package/lean/luci-app-pptp-server/luasrc/model/cbi/pptp-server/pptp-server.lua b/package/lean/luci-app-pptp-server/luasrc/model/cbi/pptp-server/pptp-server.lua new file mode 100644 index 000000000..1bc851a18 --- /dev/null +++ b/package/lean/luci-app-pptp-server/luasrc/model/cbi/pptp-server/pptp-server.lua @@ -0,0 +1,137 @@ + +--require("luci.tools.webadmin") + +mp = Map("pptpd", "PPTP Server","") + +s = mp:section(NamedSection, "pptpd", "service", translate("PPTP Service")) +s.anonymouse = true +--s.addremove = true + +enabled = s:option(Flag, "enabled", translate("Enable")) +enabled.default = 0 +enabled.rmempty = false + +localip = s:option(Value, "localip", translate("Local IP")) +localip.datatype = "ip4addr" + +clientip = s:option(Value, "remoteip", translate("Client IP")) +clientip.datatype = "string" +clientip.description = translate("LAN DHCP reserved start-to-end IP addresses with the same subnet mask") + +remotedns = s:option(Value, "remotedns", translate("Remote Client DNS")) +remotedns.datatype = "ip4addr" + +logging = s:option(Flag, "logwtmp", translate("Debug Logging")) +logging.default = 0 +logging.rmempty = false + +logins = mp:section(NamedSection, "login", "login", translate("PPTP Logins")) +logins.anonymouse = true + +username = logins:option(Value, "username", translate("User name")) +username.datatype = "string" + +password = logins:option(Value, "password", translate("Password")) +password.password = true + +function mp.on_save(self) + require "luci.model.uci" + require "luci.sys" + + local have_pptp_rule = false + local have_gre_rule = false + + luci.model.uci.cursor():foreach('firewall', 'rule', + function (section) + if section.name == 'pptp' then + have_pptp_rule = true + end + if section.name == 'gre' then + have_gre_rule = true + end + end + ) + + if not have_pptp_rule then + local cursor = luci.model.uci.cursor() + local pptp_rulename = cursor:add('firewall','rule') + cursor:tset('firewall', pptp_rulename, { + ['name'] = 'pptp', + ['target'] = 'ACCEPT', + ['src'] = 'wan', + ['proto'] = 'tcp', + ['dest_port'] = 1723 + }) + cursor:save('firewall') + cursor:commit('firewall') + end + if not have_gre_rule then + local cursor = luci.model.uci.cursor() + local gre_rulename = cursor:add('firewall','rule') + cursor:tset('firewall', gre_rulename, { + ['name'] = 'gre', + ['target'] = 'ACCEPT', + ['src'] = 'wan', + ['proto'] = 47 + }) + cursor:save('firewall') + cursor:commit('firewall') + end + + +end + + +local pid = luci.util.exec("/usr/bin/pgrep pptpd") + +function pptpd_process_status() + local status = "PPTPD is not running now " + + if pid ~= "" then + status = "PPTPD is running with the PID " .. pid .. "" + end + + local status = { status=status } + local table = { pid=status } + return table +end + +t = mp:section(Table, pptpd_process_status()) +t.anonymous = true + +t:option(DummyValue, "status", translate("PPTPD status")) + +if pid == "" then + start = t:option(Button, "_start", translate("Start")) + start.inputstyle = "apply" + function start.write(self, section) + luci.util.exec("uci set pptpd.pptpd.enabled='1' && uci commit pptpd") + message = luci.util.exec("/etc/init.d/pptpd start 2>&1") + luci.util.exec("sleep 2") + luci.http.redirect( + luci.dispatcher.build_url("admin", "vpn", "pptp-server") .. "?message=" .. message + ) + end +else + stop = t:option(Button, "_stop", translate("Stop")) + stop.inputstyle = "reset" + function stop.write(self, section) + luci.util.exec("uci set pptpd.pptpd.enabled='0' && uci commit pptpd") + luci.util.exec("/etc/init.d/pptpd stop") + luci.util.exec("sleep 2") + luci.http.redirect( + luci.dispatcher.build_url("admin", "vpn", "pptp-server") + ) + end +end + +function mp.on_before_commit (self) + os.execute("rm /var/etc/chap-secrets") +end + +function mp.on_after_commit(self) + os.execute("/etc/init.d/pptpd restart >/dev/null 2>&1 &") +end + + +return mp diff --git a/package/lean/luci-app-pptp-server/po/zh-cn/pptpd.po b/package/lean/luci-app-pptp-server/po/zh-cn/pptpd.po new file mode 100644 index 000000000..f02496b5b --- /dev/null +++ b/package/lean/luci-app-pptp-server/po/zh-cn/pptpd.po @@ -0,0 +1,42 @@ +msgid "PPTP VPN Server" +msgstr "PPTP VPN 鏈嶅姟鍣" + +msgid "PPTP Service" +msgstr "PPTP 鏈嶅姟璁剧疆" + +msgid "Local IP" +msgstr "PPTP 鏈嶅姟鍣↖P" + +msgid "Client IP" +msgstr "瀹㈡埛绔垎閰嶇殑IP鑼冨洿" + +msgid "LAN DHCP reserved start-to-end IP addresses with the same subnet mask" +msgstr "浣跨敤鍜 LAN 鍚屼竴缃戞銆傝浣跨敤 DHCP鍒嗛厤鍦板潃浠ュ鐨勭┖浣橧P鍦板潃鑼冨洿锛屼緥濡 192.168.0.20-30" + +msgid "Remote Client DNS" +msgstr "瀹㈡埛绔垎閰岻P鐨凞NS鏈嶅姟鍣" + +msgid "Debug Logging" +msgstr "璁板綍鏃ュ織" + +msgid "PPTP Logins" +msgstr "PPTP 鐧诲綍璁剧疆" + +msgid "User name" +msgstr "鐢ㄦ埛鍚" + +msgid "Password" +msgstr "瀵嗙爜" + +msgid "Enable" +msgstr "鍚敤" + +msgid "PPTPD status" +msgstr "PPTPD 鏈嶅姟鐘舵" + +msgid "Start" +msgstr "鍚姩" + +msgid "Stop" +msgstr "鍏抽棴" + diff --git a/package/lean/luci-app-pptp-server/root/etc/config/pptpd b/package/lean/luci-app-pptp-server/root/etc/config/pptpd new file mode 100644 index 000000000..c55cfa60c --- /dev/null +++ b/package/lean/luci-app-pptp-server/root/etc/config/pptpd @@ -0,0 +1,12 @@ + +config service 'pptpd' + option enabled '0' + option remoteip '192.168.0.20-30' + option remotedns '192.168.0.1' + option logwtmp '0' + option localip '192.168.0.1' + +config login 'login' + option username 'lean' + option password 'I234567B' + diff --git a/package/lean/luci-app-pptp-server/root/etc/pptpd.include b/package/lean/luci-app-pptp-server/root/etc/pptpd.include new file mode 100755 index 000000000..e14a2010b --- /dev/null +++ b/package/lean/luci-app-pptp-server/root/etc/pptpd.include @@ -0,0 +1 @@ +iptables -A FORWARD -i ppp+ -j ACCEPT diff --git a/package/lean/luci-app-pptp-server/root/etc/uci-defaults/pptpd b/package/lean/luci-app-pptp-server/root/etc/uci-defaults/pptpd new file mode 100755 index 000000000..eaaae9c15 --- /dev/null +++ b/package/lean/luci-app-pptp-server/root/etc/uci-defaults/pptpd @@ -0,0 +1,15 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete firewall.pptpd + set firewall.pptpd=include + set firewall.pptpd.type=script + set firewall.pptpd.path=/etc/pptpd.include + set firewall.pptpd.reload=1 + commit firewall +EOF + +/etc/init.d/pptpd enable && /etc/init.d/pptpd restart + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/package/lean/luci-app-sfe/Makefile b/package/lean/luci-app-sfe/Makefile new file mode 100644 index 000000000..9d30c703f --- /dev/null +++ b/package/lean/luci-app-sfe/Makefile @@ -0,0 +1,17 @@ +# Copyright (C) 2016 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for SFE +LUCI_DEPENDS:=+kmod-fast-classifier +LUCI_PKGARCH:=all +PKG_VERSION:=1.0 +PKG_RELEASE:=2 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature + diff --git a/package/lean/luci-app-sfe/luasrc/controller/sfe.lua b/package/lean/luci-app-sfe/luasrc/controller/sfe.lua new file mode 100644 index 000000000..b21a71d26 --- /dev/null +++ b/package/lean/luci-app-sfe/luasrc/controller/sfe.lua @@ -0,0 +1,11 @@ +module("luci.controller.sfe", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/sfe") then + return + end + local page + page = entry({"admin", "network", "sfe"}, cbi("sfe"), _("SFE Acceleration"), 100) + page.i18n = "sfe" + page.dependent = true +end diff --git a/package/lean/luci-app-sfe/luasrc/model/cbi/sfe.lua b/package/lean/luci-app-sfe/luasrc/model/cbi/sfe.lua new file mode 100644 index 000000000..0f2368870 --- /dev/null +++ b/package/lean/luci-app-sfe/luasrc/model/cbi/sfe.lua @@ -0,0 +1,38 @@ +local m,s,o +local SYS = require "luci.sys" + + +if SYS.call("lsmod | grep fast_classifier >/dev/null") == 0 then + Status = translate("Shortcut Forwarding Engine is Running") +else + Status = translate("Shortcut Forwarding Engine is Not Running") +end + +m = Map("sfe") +m.title = translate("Shortcut Forwarding Engine Acceleration Settings") +m.description = translate("Add an opensource Qualcomm Shortcut FE driver (Fast Path)") + +s = m:section(TypedSection, "sfe", "") +s.addremove = false +s.anonymous = true +s.description = translate(string.format("%s

", Status)) + +enable = s:option(Flag, "enabled", translate("Enable")) +enable.default = 0 +enable.rmempty = false + +wifi = s:option(Flag, "wifi", translate("Wireless Acceleration")) +wifi.default = 0 +wifi.rmempty = false +wifi.description = translate("Enable Wireless Bridge Acceleration") + +ipv6 = s:option(Flag, "ipv6", translate("IPv6 Acceleration")) +ipv6.default = 0 +ipv6.rmempty = false +ipv6.description = translate("Enable IPv6 Acceleration") + +--function m.on_after_commit(self) + +--end + +return m diff --git a/package/lean/luci-app-sfe/po/zh-cn/sfe.po b/package/lean/luci-app-sfe/po/zh-cn/sfe.po new file mode 100644 index 000000000..da1f5710d --- /dev/null +++ b/package/lean/luci-app-sfe/po/zh-cn/sfe.po @@ -0,0 +1,35 @@ +msgid "SFE Acceleration" +msgstr "SFE 杞彂鍔犻" + +msgid "Shortcut Forwarding Engine is Running" +msgstr "SFE 杞彂鍔犻熷紩鎿庢鍦ㄨ繍琛" + +msgid "Shortcut Forwarding Engine is Not Running" +msgstr "SFE 杞彂鍔犻熷紩鎿庢湭杩愯" + +msgid "Shortcut Forwarding Engine Acceleration Settings" +msgstr "SFE 杞彂鍔犻熷紩鎿庤缃" + +msgid "Add an opensource Qualcomm Shortcut FE driver (Fast Path)" +msgstr "鏉ヨ嚜楂橀氬紑婧愮殑 Shortcut FE 杞彂鍔犻熷紩鎿 (Fast Path)" + +msgid "Enable" +msgstr "鍚敤" + +msgid "Wireless Acceleration" +msgstr "鏃犵嚎鍔犻" + +msgid "Enable Wireless Bridge Acceleration" +msgstr "寮鍚棤绾挎ˉ鎺ュ姞閫" + +msgid "IPv6 Acceleration" +msgstr "IPv6 鍔犻" + +msgid "Enable IPv6 Acceleration" +msgstr "寮鍚疘Pv6鍔犻" + + + + + + diff --git a/package/lean/luci-app-sfe/root/etc/config/sfe b/package/lean/luci-app-sfe/root/etc/config/sfe new file mode 100644 index 000000000..348df9f24 --- /dev/null +++ b/package/lean/luci-app-sfe/root/etc/config/sfe @@ -0,0 +1,6 @@ + +config sfe 'config' + option enabled '1' + option ipv6 '0' + option wifi '0' + diff --git a/package/lean/luci-app-sfe/root/etc/init.d/sfe b/package/lean/luci-app-sfe/root/etc/init.d/sfe new file mode 100755 index 000000000..0e4252612 --- /dev/null +++ b/package/lean/luci-app-sfe/root/etc/init.d/sfe @@ -0,0 +1,42 @@ +#!/bin/sh /etc/rc.common +# Copyright (c) 2011-2015 OpenWrt.org + +START=30 + +start(){ + enable=$(uci get sfe.config.enabled 2>/dev/null) + wifi=$(uci get sfe.config.wifi) + ipv6=$(uci get sfe.config.ipv6) + if [ $enable -eq 1 ]; then + echo "enable" + ! (lsmod | grep fast_classifier >/dev/null) && (modprobe fast_classifier) + if [ $wifi -eq 1 ] ; then + echo "wifi" + echo 1 > /sys/fast_classifier/skip_to_bridge_ingress + else + echo "no wifi" + echo 0 > /sys/fast_classifier/skip_to_bridge_ingress + fi + if [ $ipv6 -eq 1 ]; then + echo "ipv6" + sfe_ipv6=$(cat /sys/sfe_ipv6/debug_dev) + [ -f /dev/sfe_ipv6 ] && mknod /dev/sfe_ipv6 c $sfe_ipv6 0 + else + echo "no ipv6" + rm -f /dev/sfe_ipv6 + fi + fi +} + +stop(){ + enable=$(uci get sfe.config.enabled 2>/dev/null) + [ $enable -ne 1 ] && rmmod fast_classifier + echo "stop" +} + +restart(){ + stop + start +} + + diff --git a/package/lean/luci-app-sfe/root/etc/uci-defaults/sfe b/package/lean/luci-app-sfe/root/etc/uci-defaults/sfe new file mode 100755 index 000000000..fb63e9bee --- /dev/null +++ b/package/lean/luci-app-sfe/root/etc/uci-defaults/sfe @@ -0,0 +1,13 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@sfe[-1] + add ucitrack sfe + set ucitrack.@sfe[-1].init=sfe + commit ucitrack +EOF + +/etc/init.d/sfe enable + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/package/lean/luci-app-shadowsocksr-pro/Makefile b/package/lean/luci-app-shadowsocksr-pro/Makefile new file mode 100644 index 000000000..dd78c05cb --- /dev/null +++ b/package/lean/luci-app-shadowsocksr-pro/Makefile @@ -0,0 +1,18 @@ +# Copyright (C) 2016 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for Shadowsocksr +LUCI_DEPENDS:=+iptables-mod-tproxy +kmod-ipt-tproxy +ip +ipset-lists +shadowsocksr-libev-alt +pdnsd-alt +coreutils +coreutils-base64 +coreutils-nohup +dnsmasq-full +LUCI_PKGARCH:=all +PKG_VERSION:=2.0 +PKG_RELEASE:=13 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature + + diff --git a/package/lean/luci-app-shadowsocksr-pro/luasrc/controller/shadowsocksr.lua b/package/lean/luci-app-shadowsocksr-pro/luasrc/controller/shadowsocksr.lua new file mode 100644 index 000000000..cb035a53a --- /dev/null +++ b/package/lean/luci-app-shadowsocksr-pro/luasrc/controller/shadowsocksr.lua @@ -0,0 +1,9 @@ +module("luci.controller.shadowsocksr", package.seeall) +function index() + if not nixio.fs.access("/etc/config/shadowsocksr") then + return + end + local page + page = entry({"admin", "services", "shadowsocksr"}, cbi("shadowsocksr"), _("ShadowsocksR Pro")) + page.dependent = true +end diff --git a/package/lean/luci-app-shadowsocksr-pro/luasrc/model/cbi/shadowsocksr.lua b/package/lean/luci-app-shadowsocksr-pro/luasrc/model/cbi/shadowsocksr.lua new file mode 100644 index 000000000..6a4395445 --- /dev/null +++ b/package/lean/luci-app-shadowsocksr-pro/luasrc/model/cbi/shadowsocksr.lua @@ -0,0 +1,228 @@ + +local fs = require "nixio.fs" +local NXFS = require "nixio.fs" +local WLFS = require "nixio.fs" +local SYS = require "luci.sys" +local ND = SYS.exec("cat /etc/gfwlist/china-banned | wc -l") +local conf = "/etc/shadowsocksr/base-gfwlist.txt" +local watch = "/tmp/shadowsocksr_watchdog.log" +local dog = "/tmp/ssrpro.log" + +local Status + +if SYS.call("pidof ssr-redir > /dev/null") == 0 then + Status = translate("ShadowsocksR is Running") +else + Status = translate("ShadowsocksR is Not Running") +end + +m = Map("shadowsocksr") +m.title = translate("Shadowsocksr Transparent Proxy") +m.description = translate("A fast secure tunnel proxy that help you get through firewalls on your router") + +s = m:section(TypedSection, "shadowsocksr") +s.anonymous = true +s.description = translate(string.format("%s

", Status)) + +-- --------------------------------------------------- + +s:tab("basic", translate("Base Setting")) + + +switch = s:taboption("basic",Flag, "enabled", translate("Enable")) +switch.rmempty = false + +proxy_mode = s:taboption("basic",ListValue, "proxy_mode", translate("Proxy Mode")) +proxy_mode:value("M", translate("Base on GFW-List Auto Proxy Mode(Recommend)")) +proxy_mode:value("S", translate("Bypassing China Manland IP Mode(Be caution when using P2P download锛)")) +proxy_mode:value("G", translate("Global Mode")) +proxy_mode:value("V", translate("Overseas users watch China video website Mode")) + +cronup = s:taboption("basic", Flag, "cron_mode", translate("Auto Update GFW-List"), + translate(string.format("GFW-List Lines锛 %s Lines", ND))) +cronup.default = 0 +cronup.rmempty = false + +updatead = s:taboption("basic", Button, "updatead", translate("Manually force update GFW-List"), translate("Note: It needs to download and convert the rules. The background process may takes 60-120 seconds to run.
After completed it would automatically refresh, please do not duplicate click!")) +updatead.inputtitle = translate("Manually force update GFW-List") +updatead.inputstyle = "apply" +updatead.write = function() + SYS.call("nohup sh /etc/shadowsocksr/up-gfwlist.sh > /tmp/gfwupdate.log 2>&1 &") +end + +safe_dns_tcp = s:taboption("basic",Flag, "safe_dns_tcp", translate("DNS uses TCP"), + translate("Through the server transfer mode inquires DNS pollution prevention (Safer and recommended)")) +safe_dns_tcp.rmempty = false +-- safe_dns_tcp:depends("more", "1") + +-- more_opt = s:taboption("basic",Flag, "more", translate("More Options"), +-- translate("Options for advanced users")) + +-- timeout = s:taboption("basic",Value, "timeout", translate("Timeout")) +-- timeout.datatype = "range(0,10000)" +-- timeout.placeholder = "60" +-- timeout.optional = false +-- timeout:depends("more", "1") + +-- safe_dns = s:taboption("basic",Value, "safe_dns", translate("Safe DNS"), +-- translate("8.8.8.8 or 8.8.4.4 is recommended")) +-- safe_dns.datatype = "ip4addr" +-- safe_dns.optional = false +-- safe_dns:depends("more", "1") + +-- safe_dns_port = s:taboption("basic",Value, "safe_dns_port", translate("Safe DNS Port"), +-- translate("Foreign DNS on UDP port 53 might be polluted")) +-- safe_dns_port.datatype = "range(1,65535)" +-- safe_dns_port.placeholder = "53" +-- safe_dns_port.optional = false +-- safe_dns_port:depends("more", "1") + +--fast_open =s:taboption("basic",Flag, "fast_open", translate("TCP Fast Open"), +-- translate("Enable TCP fast open, only available on kernel > 3.7.0")) + + + +s:tab("main", translate("Server Setting")) + +server = s:taboption("main",Value, "server", translate("Server Address")) +server.optional = false +server.datatype = "host" +server.rmempty = false + +server_port = s:taboption("main",Value, "server_port", translate("Server Port")) +server_port.datatype = "range(1,65535)" +server_port.optional = false +server_port.rmempty = false + +password = s:taboption("main",Value, "password", translate("Password")) +password.password = true + +method = s:taboption("main",ListValue, "method", translate("Encryption Method")) +method:value("none") +method:value("aes-128-ctr") +method:value("aes-192-ctr") +method:value("aes-256-ctr") +method:value("aes-128-cfb") +method:value("aes-192-cfb") +method:value("aes-256-cfb") +method:value("rc4") +method:value("rc4-md5") +method:value("rc4-md5-6") +method:value("salsa20") +method:value("chacha20") +method:value("chacha20-ietf") + +protocol = s:taboption("main",ListValue, "protocol", translate("Protocol")) +protocol:value("origin") +protocol:value("verify_deflate") +protocol:value("auth_sha1_v4") +protocol:value("auth_aes128_md5") +protocol:value("auth_aes128_sha1") +protocol:value("auth_chain_a") +protocol:value("auth_chain_b") +protocol:value("auth_chain_c") +protocol:value("auth_chain_d") + +obfs = s:taboption("main",ListValue, "obfs", translate("Obfs Param")) +obfs:value("plain") +obfs:value("http_simple") +obfs:value("http_post") +obfs:value("random_head") +obfs:value("tls1.2_ticket_auth") +obfs:value("tls1.2_ticket_fastauth") + +plugin_param = s:taboption("main",Flag, "plugin_param", translate("Plug-in parameters"), + translate("Incorrect use of this parameter will cause IP to be blocked. Please use it with care")) +plugin_param:depends("obfs", "http_simple") +plugin_param:depends("obfs", "http_post") +plugin_param:depends("obfs", "tls1.2_ticket_auth") +plugin_param:depends("obfs", "tls1.2_ticket_fastauth") + +obfs_param = s:taboption("main",Value, "obfs_param", translate("Confusing plug-in parameters")) +obfs_param.rmempty = true +obfs_param.datatype = "host" +obfs_param:depends("plugin_param", "1") + + + +s:tab("list", translate("User-defined GFW-List")) +gfwlist = s:taboption("list", TextValue, "conf") +gfwlist.description = translate("
锛!锛塏ote: When the domain name is entered and will automatically merge with the online GFW-List. Please manually update the GFW-List list after applying.") +gfwlist.rows = 13 +gfwlist.wrap = "off" +gfwlist.cfgvalue = function(self, section) + return NXFS.readfile(conf) or "" +end +gfwlist.write = function(self, section, value) + NXFS.writefile(conf, value:gsub("\r\n", "\n")) +end + +local addipconf = "/etc/shadowsocksr/addinip.txt" + +s:tab("addip", translate("GFW-List Add-in IP")) +gfwaddin = s:taboption("addip", TextValue, "addipconf") +gfwaddin.description = translate("
锛!锛塏ote: IP add-in to GFW-List. Such as Telegram Messenger") +gfwaddin.rows = 13 +gfwaddin.wrap = "off" +gfwaddin.cfgvalue = function(self, section) + return NXFS.readfile(addipconf) or "" +end +gfwaddin.write = function(self, section, value) + NXFS.writefile(addipconf, value:gsub("\r\n", "\n")) +end + +s:tab("status", translate("Status and Tools")) +s:taboption("status", DummyValue,"opennewwindow" , + translate("")) + + +s:tab("watchdog", translate("Watchdog Log")) +log = s:taboption("watchdog", TextValue, "sylogtext") +log.template = "cbi/tvalue" +log.rows = 13 +log.wrap = "off" +log.readonly="readonly" + +function log.cfgvalue(self, section) + SYS.exec("[ -f /tmp/shadowsocksr_watchdog.log ] && sed '1!G;h;$!d' /tmp/shadowsocksr_watchdog.log > /tmp/ssrpro.log") + return nixio.fs.readfile(dog) +end + +function log.write(self, section, value) + value = value:gsub("\r\n?", "\n") + nixio.fs.writefile(dog, value) +end + + + +t=m:section(TypedSection,"acl_rule",translate("Client Proxy Mode Settings"), +translate("Proxy mode settings can be set to specific LAN clients ( No Proxy, Global Proxy, Game Mode) . Does not need to be set by default.")) +t.template="cbi/tblsection" +t.sortable=true +t.anonymous=true +t.addremove=true +e=t:option(Value,"ipaddr",translate("IP Address")) +e.width="40%" +e.datatype="ip4addr" +e.placeholder="0.0.0.0/0" +luci.ip.neighbors({ family = 4 }, function(entry) + if entry.reachable then + e:value(entry.dest:string()) + end +end) + +e=t:option(ListValue,"filter_mode",translate("Proxy Mode")) +e.width="40%" +e.default="disable" +e.rmempty=false +e:value("disable",translate("No Proxy")) +e:value("global",translate("Global Proxy")) +e:value("game",translate("Game Mode")) + +-- --------------------------------------------------- +local apply = luci.http.formvalue("cbi.apply") +if apply then + os.execute("/etc/init.d/ssrpro restart >/dev/null 2>&1 &") +end + +return m diff --git a/package/lean/luci-app-shadowsocksr-pro/po/zh-cn/ssrpro.po b/package/lean/luci-app-shadowsocksr-pro/po/zh-cn/ssrpro.po new file mode 100644 index 000000000..3127e2fbe --- /dev/null +++ b/package/lean/luci-app-shadowsocksr-pro/po/zh-cn/ssrpro.po @@ -0,0 +1,102 @@ +msgid "ShadowsocksR is Running" +msgstr "ShadowsocksR 姝e湪杩愯" + +msgid "ShadowsocksR is Not Running" +msgstr "ShadowsocksR 娌℃湁杩愯" + +msgid "Shadowsocksr Transparent Proxy" +msgstr "ShadowsocksR 閫忔槑浠g悊" + +msgid "A fast secure tunnel proxy that help you get through firewalls on your router" +msgstr "涓涓揩閫熷畨鍏ㄩ毀閬撲唬鐞嗭紝甯姪鎮ㄧ┛杩囬槻鐏" + +msgid "Base Setting" +msgstr "鍩烘湰璁剧疆" + +msgid "Proxy Mode" +msgstr "浠g悊妯″紡" + +msgid "Base on GFW-List Auto Proxy Mode(Recommend)" +msgstr "鍩轰簬GFW-List鑷姩浠g悊(鎺ㄨ崘)" + +msgid "Bypassing China Manland IP Mode(Be caution when using P2P download锛)" +msgstr "缁曡繃涓浗澶ч檰IP鍦板潃(P2P 涓嬭浇鎱庣敤锛)" + +msgid "Global Mode" +msgstr "鍏ㄥ眬浠g悊" + +msgid "Overseas users watch China video website Mode" +msgstr "娴峰鐢ㄦ埛鍥炲浗鐪嬭棰" + +msgid "Auto Update GFW-List" +msgstr "鑷姩鏇存柊GFW-List" + +msgid "Manually force update GFW-List" +msgstr "鎵嬪姩寮哄埗鏇存柊GFW-List" + +msgid "DNS uses TCP" +msgstr "鍚敤DNS TCP闃叉薄鏌" + +msgid "Through the server transfer mode inquires DNS pollution prevention (Safer and recommended)" +msgstr "寰鍥藉鐨凞NS璇锋眰灏嗛氳繃鏈嶅姟鍣ㄤ腑杞彂鍑猴紙鏇村畨鍏紝鎺ㄨ崘锛" + +msgid "Server Setting" +msgstr "鏈嶅姟鍣ㄨ缃" + +msgid "Server Address" +msgstr "鏈嶅姟鍣ㄥ湴鍧锛堟敮鎸佸煙鍚嶏級" + +msgid "Server Port" +msgstr "鏈嶅姟鍣ㄧ鍙" + +msgid "Password" +msgstr "瀵嗙爜" + +msgid "Encryption Method" +msgstr "鍔犲瘑" + +msgid "Protocol" +msgstr "鍗忚" + +msgid "Obfs Param" +msgstr "娣锋穯" + +msgid "Plug-in parameters" +msgstr "鎻掍欢鍙傛暟" + +msgid "Confusing plug-in parameters" +msgstr "娣锋穯鍙傛暟" + +msgid "Incorrect use of this parameter will cause IP to be blocked. Please use it with care" +msgstr "涓嶆纭殑浣跨敤鍙傛暟鍙兘浼氬鑷碔P琚皝锛岃娉ㄦ剰浣跨敤" + +msgid "User-defined GFW-List" +msgstr "鐢ㄦ埛鑷畾涔塆FW-List" + +msgid "
锛!锛塏ote: When the domain name is entered and will automatically merge with the online GFW-List. Please manually update the GFW-List list after applying." +msgstr "鐢ㄦ埛鑷畾涔塆FW-List灏嗕細鍜岃嚜鍔ㄦ洿鏂扮殑鑷姩鍚堝苟銆傚鏋滆鏂板姞鍏ュ煙鍚嶉┈涓婄敓鏁堬紝璇峰簲鐢ㄥ悗鐐瑰嚮鎵嬪姩寮哄埗鏇存柊GFW-List" + +msgid "Status and Tools" +msgstr "鐘舵佷笌宸ュ叿" + +msgid "Watchdog Log" +msgstr "瀹堟姢鏃ュ織" + +msgid "Client Proxy Mode Settings" +msgstr "瀹㈡埛绔唬鐞嗘ā寮忚缃" + +msgid "Proxy mode settings can be set to specific LAN clients ( No Proxy, Global Proxy, Game Mode) . Does not need to be set by default." +msgstr "鍙互涓哄眬鍩熺綉瀹㈡埛绔垎鍒缃笉鍚岀殑浠g悊妯″紡 ( 涓嶄唬鐞, 鍏ㄥ眬浠g悊, 娓告垙妯″紡).榛樿鏃犻渶璁剧疆" + +msgid "GFW-List Add-in IP" +msgstr "GFW-List闄勫姞IP" + +msgid "
锛!锛塏ote: IP add-in to GFW-List. Such as Telegram Messenger" +msgstr "
锛!锛夋敞鎰忥細鏈変簺搴旂敤浣跨敤IP鑰屼笉鏄煙鍚嶏紝渚嬪 Telegram Messenger 锛屾偍闇瑕佹妸IP鍦板潃鍔犲叆杩欓噷" + + + + + + + diff --git a/package/lean/luci-app-shadowsocksr-pro/root/etc/config/shadowsocksr b/package/lean/luci-app-shadowsocksr-pro/root/etc/config/shadowsocksr new file mode 100644 index 000000000..35ed7e5aa --- /dev/null +++ b/package/lean/luci-app-shadowsocksr-pro/root/etc/config/shadowsocksr @@ -0,0 +1,13 @@ + +config shadowsocksr + option gfwlist 'china-banned' + option server 'serv-ro.ddns.info' + option server_port '23143' + option password 'test.TEST' + option method 'aes-256-cfb' + option protocol 'origin' + option obfs 'plain' + option enabled '0' + option proxy_mode 'M' + option safe_dns_tcp '1' + option cron_mode '1' diff --git a/package/lean/luci-app-shadowsocksr-pro/root/etc/init.d/ssrpro b/package/lean/luci-app-shadowsocksr-pro/root/etc/init.d/ssrpro new file mode 100755 index 000000000..e44591b5d --- /dev/null +++ b/package/lean/luci-app-shadowsocksr-pro/root/etc/init.d/ssrpro @@ -0,0 +1,373 @@ +#!/bin/sh /etc/rc.common +# +# + +START=99 + +SS_REDIR_PORT=7070 +SS_REDIR_PIDFILE=/var/run/ssr-redir-go.pid +PDNSD_LOCAL_PORT=7453 +SSRCONF=/etc/shadowsocksr.json +CRON_FILE=/etc/crontabs/root +CONFIG=shadowsocksr + + +# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + + # $covered_subnets, $local_addresses are not required +covered_subnets=`uci get shadowsocksr.@shadowsocksr[0].covered_subnets 2>/dev/null` +local_addresses=`uci get shadowsocksr.@shadowsocksr[0].local_addresses 2>/dev/null` + # Get LAN settings as default parameters + [ -f /lib/functions/network.sh ] && . /lib/functions/network.sh + [ -z "$covered_subnets" ] && network_get_subnet covered_subnets lan + [ -z "$local_addresses" ] && network_get_ipaddr local_addresses lan +vt_np_ipset="china" # Must be global variable + +__gfwlist_by_mode() +{ + case "$1" in + V) echo unblock-youku;; + *) echo china-banned;; + esac +} + + + +# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +start() +{ + local vt_enabled=`uci get shadowsocksr.@shadowsocksr[0].enabled 2>/dev/null` + local vt_server_addr=`uci get shadowsocksr.@shadowsocksr[0].server` + local vt_server_port=`uci get shadowsocksr.@shadowsocksr[0].server_port` + local vt_password=`uci get shadowsocksr.@shadowsocksr[0].password 2>/dev/null` + local vt_method=`uci get shadowsocksr.@shadowsocksr[0].method` + local vt_protocol=`uci get shadowsocksr.@shadowsocksr[0].protocol` + local vt_obfs=`uci get shadowsocksr.@shadowsocksr[0].obfs` + local vt_timeout=`uci get shadowsocksr.@shadowsocksr[0].timeout 2>/dev/null` + local vt_safe_dns=`uci get shadowsocksr.@shadowsocksr[0].safe_dns 2>/dev/null` + local vt_safe_dns_port=`uci get shadowsocksr.@shadowsocksr[0].safe_dns_port 2>/dev/null` + local vt_safe_dns_tcp=`uci get shadowsocksr.@shadowsocksr[0].safe_dns_tcp 2>/dev/null` + local vt_proxy_mode=`uci get shadowsocksr.@shadowsocksr[0].proxy_mode` + local obfs_param=`uci get shadowsocksr.@shadowsocksr[0].obfs_param 2>/dev/null` + local cron_mode=`uci get shadowsocksr.@shadowsocksr[0].cron_mode 2>/dev/null` + local vt_gfwlist=`__gfwlist_by_mode $vt_proxy_mode` + + [ -f /etc/init.d/pdnsd ] && /etc/init.d/pdnsd disable 2>/dev/null + + # ----------------------------------------------------------------- + if [ "$vt_enabled" = 0 ]; then + echo "WARNING: Shadowsocksr is disabled." + return 1 + fi + + if [ -z "$vt_server_addr" -o -z "$vt_server_port" ]; then + echo "WARNING: Shadowsocksr not fully configured, not starting." + return 1 + fi + + [ -z "$vt_proxy_mode" ] && vt_proxy_mode=M + [ -z "$vt_method" ] && vt_method=table + [ -z "$vt_timeout" ] && vt_timeout=60 + case "$vt_proxy_mode" in + M|S|G) + [ -z "$vt_safe_dns" ] && vt_safe_dns="8.8.8.8" + [ -z "$vt_safe_dns_tcp" ] && vt_safe_dns_tcp=1 + ;; + esac + [ -z "$vt_safe_dns_port" ] && vt_safe_dns_port=53 + + # ----------------------------------------------------------------- + ###### shadowsocksr ###### + cat > $SSRCONF < /var/etc/dnsmasq-go.d/01-pollution.conf + else + awk -vs="$vt_safe_dns#$vt_safe_dns_port" '!/^$/&&!/^#/{printf("server=/%s/%s\n",$0,s)}' \ + /etc/gfwlist/$vt_gfwlist > /var/etc/dnsmasq-go.d/01-pollution.conf + fi + else + echo "WARNING: Not using secure DNS, DNS resolution might be polluted if you are in China." + fi + + ###### dnsmasq-to-ipset configuration ###### + case "$vt_proxy_mode" in + M|V) + awk '!/^$/&&!/^#/{printf("ipset=/%s/'"$vt_gfwlist"'\n",$0)}' \ + /etc/gfwlist/$vt_gfwlist > /var/etc/dnsmasq-go.d/02-ipset.conf + ;; + esac + + # ----------------------------------------------------------------- + ###### Restart main 'dnsmasq' service if needed ###### + if ls /var/etc/dnsmasq-go.d/* >/dev/null 2>&1; then + mkdir -p /tmp/dnsmasq.d + cat > /tmp/dnsmasq.d/dnsmasq-go.conf </dev/null + del_cron +} + +restart() +{ + KEEP_GFWLIST=Y + stop + start +} + +reload() +{ + local vt_enabled=`uci get shadowsocksr.@shadowsocksr[0].enabled 2>/dev/null` + local vt_server_addr=`uci get shadowsocksr.@shadowsocksr[0].server` + local vt_server_port=`uci get shadowsocksr.@shadowsocksr[0].server_port` + local vt_safe_dns=`uci get shadowsocksr.@shadowsocksr[0].safe_dns 2>/dev/null` + local vt_safe_dns_port=`uci get shadowsocksr.@shadowsocksr[0].safe_dns_port 2>/dev/null` + local vt_safe_dns_tcp=`uci get shadowsocksr.@shadowsocksr[0].safe_dns_tcp 2>/dev/null` + local vt_proxy_mode=`uci get shadowsocksr.@shadowsocksr[0].proxy_mode` + local vt_gfwlist=`__gfwlist_by_mode $vt_proxy_mode` + KEEP_GFWLIST=Y + del_rule + add_rule + if [ "$vt_safe_dns_tcp" = 1 ]; then + stop_pdnsd + start_pdnsd + fi +} + +# $1: upstream DNS server +start_pdnsd() +{ + local safe_dns="$1" + + local tcp_dns_list="208.67.222.222, 208.67.220.220" + [ -n "$safe_dns" ] && tcp_dns_list="$safe_dns,$tcp_dns_list" + + #killall -9 pdnsd 2>/dev/null && sleep 1 + kill -9 $(cat /var/run/pdnsd.pid) >/dev/null 2>&1 && mkdir -p /var/etc /var/pdnsd + cat > /var/etc/pdnsd.conf </dev/null; then + while iptables -t nat -D OUTPUT -p tcp --dport 53 -j pdnsd_output 2>/dev/null; do :; done + iptables -t nat -X pdnsd_output + fi + killall -9 pdnsd 2>/dev/null + rm -rf /var/pdnsd + rm -f /var/etc/pdnsd.conf +} + +add_cron() +{ + sed -i '/up-gfwlist.sh/d' $CRON_FILE + sed -i '/shadowsocksr_watchdog.log/d' $CRON_FILE + if [ $cron_mode -eq 1 ]; then + echo '0 5 * * * /etc/shadowsocksr/up-gfwlist.sh > /tmp/gfwupdate.log 2>&1' >> $CRON_FILE + fi + echo '0 */1 * * * /etc/shadowsocksr/ssr-watchdog >> /tmp/shadowsocksr_watchdog.log 2>&1' >> $CRON_FILE + echo '0 1 * * 0 echo "" > /tmp/shadowsocksr_watchdog.log' >> $CRON_FILE + crontab $CRON_FILE +} + +del_cron() +{ + sed -i '/up-gfwlist.sh/d' $CRON_FILE + sed -i '/shadowsocksr_watchdog.log/d' $CRON_FILE + /etc/init.d/cron restart +} + + + +uci_get_by_name() { + local ret=$(uci get $CONFIG.$1.$2 2>/dev/null) + echo ${ret:=$3} +} + +uci_get_by_type() { + local index=0 + if [ -n $4 ]; then + index=$4 + fi + local ret=$(uci get $CONFIG.@$1[$index].$2 2>/dev/null) + echo ${ret:=$3} +} + +add_rule() +{ + iptables -t nat -N shadowsocksr_pre + iptables -t nat -F shadowsocksr_pre + iptables -t nat -A shadowsocksr_pre -m set --match-set local dst -j RETURN || { + iptables -t nat -A shadowsocksr_pre -d 10.0.0.0/8 -j RETURN + iptables -t nat -A shadowsocksr_pre -d 127.0.0.0/8 -j RETURN + iptables -t nat -A shadowsocksr_pre -d 172.16.0.0/12 -j RETURN + iptables -t nat -A shadowsocksr_pre -d 192.168.0.0/16 -j RETURN + iptables -t nat -A shadowsocksr_pre -d 127.0.0.0/8 -j RETURN + iptables -t nat -A shadowsocksr_pre -d 224.0.0.0/3 -j RETURN + } + iptables -t nat -A shadowsocksr_pre -d $vt_server_addr -j RETURN + + iptables -N gameboost -t mangle + ipset -! create gameuser hash:ip maxelem 65536 2>/dev/null + /usr/bin/ip rule add fwmark 0x01/0x01 table 100 + /usr/bin/ip route add local 0.0.0.0/0 dev lo table 100 + iptables -t mangle -A gameboost -p udp -m set --match-set local dst -j RETURN + iptables -t mangle -A gameboost -p udp -m set --match-set china dst -j RETURN + iptables -t mangle -A gameboost -p udp --dport 53 -j RETURN + iptables -t mangle -A gameboost -p udp -j TPROXY --on-port 7070 --tproxy-mark 0x01/0x01 + iptables -t mangle -A PREROUTING -m set --match-set gameuser src -j gameboost + + for i in $(seq 0 100) + do + local ip=$(uci_get_by_type acl_rule ipaddr '' $i) + local mode=$(uci_get_by_type acl_rule filter_mode '' $i) + case "$mode" in + disable) + iptables -t nat -A shadowsocksr_pre -s $ip -j RETURN + ;; + global) + iptables -t nat -A shadowsocksr_pre -s $ip -p tcp -j REDIRECT --to $SS_REDIR_PORT + iptables -t nat -A shadowsocksr_pre -s $ip -j RETURN + ;; + game) + iptables -t nat -A shadowsocksr_pre -p tcp -s $ip -m set ! --match-set china dst -j REDIRECT --to $SS_REDIR_PORT + ipset -! add gameuser $ip + ;; + esac + done + + case "$vt_proxy_mode" in + G) : ;; + S) + iptables -t nat -A shadowsocksr_pre -m set --match-set $vt_np_ipset dst -j RETURN + ;; + M) + ipset -! create $vt_gfwlist hash:ip maxelem 65536 2>/dev/null + awk '!/^$/&&!/^#/{printf("add vt_gfwlist %s'" "'\n",$0)}' /etc/shadowsocksr/addinip.txt > /tmp/addinip.ipset + sed -i "s/vt_gfwlist/$vt_gfwlist/g" /tmp/addinip.ipset + ipset -! restore < /tmp/addinip.ipset + iptables -t nat -A shadowsocksr_pre -m set ! --match-set $vt_gfwlist dst -j RETURN + iptables -t nat -A shadowsocksr_pre -m set --match-set $vt_np_ipset dst -j RETURN + ;; + V) + vt_np_ipset="" + ipset -! create $vt_gfwlist hash:ip maxelem 65536 2>/dev/null + iptables -t nat -A shadowsocksr_pre -m set ! --match-set $vt_gfwlist dst -j RETURN + ;; + esac + local subnet + for subnet in $covered_subnets; do + iptables -t nat -A shadowsocksr_pre -s $subnet -p tcp -j REDIRECT --to $SS_REDIR_PORT + done + iptables -t nat -I PREROUTING -p tcp -j shadowsocksr_pre +} + +del_rule() +{ + if iptables -t nat -F shadowsocksr_pre 2>/dev/null; then + while iptables -t nat -D PREROUTING -p tcp -j shadowsocksr_pre 2>/dev/null; do :; done + iptables -t nat -X shadowsocksr_pre 2>/dev/null + fi + + /usr/bin/ip rule del fwmark 0x01/0x01 table 100 + /usr/bin/ip route del local 0.0.0.0/0 dev lo table 100 + if iptables -t mangle -F gameboost 2>/dev/null; then + while iptables -t mangle -D PREROUTING -m set --match-set gameuser src -j gameboost 2>/dev/null; do :; done + iptables -t mangle -X gameboost 2>/dev/null + fi + + ipset destroy gameuser 2>/dev/null + + + # ----------------------------------------------------------------- + [ "$KEEP_GFWLIST" = Y ] || ipset destroy "$vt_gfwlist" 2>/dev/null +} diff --git a/package/lean/luci-app-shadowsocksr-pro/root/etc/shadowsocksr.include b/package/lean/luci-app-shadowsocksr-pro/root/etc/shadowsocksr.include new file mode 100755 index 000000000..1e270c09c --- /dev/null +++ b/package/lean/luci-app-shadowsocksr-pro/root/etc/shadowsocksr.include @@ -0,0 +1,11 @@ +#!/bin/sh + +ssr_enable=$(uci get shadowsocksr.@shadowsocksr[0].enabled 2>/dev/null) + +if [ $ssr_enable -eq 1 ]; then + if pidof ssr-redir>/dev/null; then + /etc/init.d/ssrpro reload + else + /etc/init.d/ssrpro restart + fi +fi diff --git a/package/lean/luci-app-shadowsocksr-pro/root/etc/shadowsocksr/addinip.txt b/package/lean/luci-app-shadowsocksr-pro/root/etc/shadowsocksr/addinip.txt new file mode 100644 index 000000000..64e2f9bb8 --- /dev/null +++ b/package/lean/luci-app-shadowsocksr-pro/root/etc/shadowsocksr/addinip.txt @@ -0,0 +1,7 @@ +149.154.160.0/20 +149.154.164.0/22 +149.154.168.0/21 +67.198.55.0/24 +91.108.4.0/22 +91.108.56.0/22 +109.239.140.0/24 diff --git a/package/lean/luci-app-shadowsocksr-pro/root/etc/shadowsocksr/base-gfwlist.txt b/package/lean/luci-app-shadowsocksr-pro/root/etc/shadowsocksr/base-gfwlist.txt new file mode 100644 index 000000000..75277f6c0 --- /dev/null +++ b/package/lean/luci-app-shadowsocksr-pro/root/etc/shadowsocksr/base-gfwlist.txt @@ -0,0 +1,2941 @@ +0rz.tw +0to255.com +10musume.com +123rf.com +12bet.com +12vpn.com +141hongkong.com +173ng.com +1984bbs.com +1984bbs.org +1-apple.com.tw +1bao.org +1eew.com +1pondo.tv +2000fun.com +2008xianzhang.info +21andy.com +247realmedia.com +24smile.org +2-hand.info +2mdn.net +2shared.com +301works.org +315lz.com +32red.com +365singles.com.ar +36rain.com +4bluestones.biz +4chan.org +4pppc.gov.tw +4shared.com +4sq.com +51.ca +5i01.com +5maodang.com +64tianwang.com +64wiki.com +666kb.com +6park.com +7capture.com +881903.com +888.com +89-64.org +9001700.com +91porn.com +921.gov.tw +92ccav.com +9bis.com +9bis.net +9city.me +a5.com.ru +abc.pp.ru +abitno.linpie.com +ablwang.com +aboluowang.com +aboutgfw.com +acgkj.com +ac.jiruan.net +ac.playstation.net +actimes.com.au +aculo.us +ad1.nownews.com +addictedtocoffee.de +ads.backchina.com +adultfriendfinder.com +adultkeep.net +advanscene.com +advertfan.com +aec.gov.tw +aenhancers.com +af.mil +aftygh.gov.tw +aide.gov.tw +aiph.net +aisex.com +ait.org.tw +aiweiweiblog.com +aiweiwei.com +ajaxplorer.info +akamaihd.net +akiba-online.com +alabout.com +alasbarricadas.org +alexlur.org +aliengu.com +aliyun.com +alkasir.com +allaboutalpha.com +allgirlsallowed.org +alliance.org.hk +allinfa.com +allinfo.com +allmovie.com +allonlinux.free.fr +all-that-is-interesting.com +al-qimmah.net +alternate-tools.com +altrec.com +alvinalexander.com +alwaysdata.com +alwaysdata.net +am730.com.hk +amazonaws.com +ameblo.jp +americangreencard.com +amiblockedornot.com +amnesty.org +amnestyusa.org +amoiist.com +amzs.me +analyze-v.com +anchorfree.com +andfaraway.net +android.com +angularjs.org +animecrazy.net +anobii.com +anontext.com +anonymizer.com +a-normal-day.com +answering-islam.org +anthonycalzadilla.com +anti.anti.cnn.googlepages.com +antidrm.hpg.ig.com.br +antiwave.net +aobo.com.au +aolchannels.aol.com +aomiwang.com +apetube.com +apiary.io +apidocs.linksalpha.com +apigee.com +api.linksalpha.com +api.proxlet.com +api.supertweet.net +app.heywire.com +app.hkatvnews.com +appledaily.com +appledaily.com.tw +apps.hloli.net +appspot.com +archive.is +archive.org +arctosia.com +areca-backup.org +army.mil +arte.gov.tw +art-or-porn.com +artsy.net +asahichinese.com +asdfg.jp +asiafriendfinder.com +asiaharvest.org +asianews.it +asianwomensfilm.de +askstudent.com +askynz.net +assembla.com +astonmartinnews.com +atchinese.com +atc.org.au +atgfw.org +atj.org.tw +atlaspost.com +atnext.com +autoproxy.org +avaaz.org +avdb.in +avidemux.org +avoision.com +awardwinningfjords.com +axureformac.com +babynet.com.hk +backchina.com +backpackers.com.tw +badassjs.com +badoo.com +baidu.jp +baixing.me +bannedbook.org +barnabu.co.uk +basetimesheightdividedby2.com +bayvoice.net +bbcchinese.com +bbc.com +bbc.co.uk +bbci.co.uk +bbcimg.co.uk +bbc.in +bbg.gov +bbs2.newsgroup.la +bbs.ecstart.com +bbsfeed.com +bbs.kimy.com.tw +bbsland.com +bbs.morbell.com +bbs.mychat.to +bbs.newsgroup.la +bbs.ozchinese.com +bbs.qmzdd.com +bbs.sina.com +bbs.skykiwi.com +bbs.tuitui.info +bb.ttv.com.tw +bcc.com.tw +bcchinese.net +bdhr.gov.tw +bd.zhe.la +bebo.com +beeg.com +beijing1989.com +beijingspring.com +benjaminste.in +berlintwitterwall.com +bestforchina.org +bestvpnservice.com +bet365.com +beta.iset.com.tw +beta.usejump.com +betfair.com +bettween.com +betvictor.com +bewww.net +beyondfirewall.com +bfnn.org +biantailajiao.com +biantailajiao.in +bigfools.com +bignews.org +bigsound.org +bill2-software.com +billywr.com +bill.zhong.pp.ru +bipic.net +bitcointalk.org +bit.ly +bitly.com +bitshare.com +bjzc.org +blinkx.com +blinw.com +blip.tv +blockcn.com +blog.birdhouseapp.com +blog.bitly.com +blogblog.com +blog.boxcar.io +blogcatalog.com +blog.davidziegler.net +blog.dayoneapp.com +blog.de +blog.dribbble.com +blog.exblog.co.jp +blog.expofutures.com +blog.fizzik.com +blog.foolsmountain.com +blogger.com +blog.gowalla.com +blog.hotpotato.com +blog.ifttt.com +blogimg.jp +blog.instagram.com +blog.instapaper.com +blog.iphone-dev.org +blog.istef.info +blog.jackjia.com +blog.joeyrobert.org +blog.kangye.org +blog.kickstarter.com +blog.kl.am +blog.klip.me +blog.lester850.info +blog.lightbox.com +bloglines.com +bloglovin.com +blog.mongodb.org +blog.openinkpot.org +blog.palm.com +blog.path.com +blog.pathtosharepoint.com +blog.pchome.com.tw +blog.pentalogic.net +blog.pikchur.com +blog.pilotmoon.com +blog.redren.com +blog.rockmelt.com +blog.romanandreg.com +blog.s135.com +blogs.icerocket.com +blog.sina.com.tw +blog.sogoo.org +blog.sparrowmailapp.com +blogspot.com +blogspot.co.uk +blogspot.de +blogspot.fr +blogspot.in +blogspot.jp +blogs.tampabay.com +blog.summify.com +blogs.yahoo.co.jp +blog.syx86.cn +blog.syx86.com +blog.taragana.com +blogtd.net +blogtd.org +blog.tiney.com +blog.topify.com +blog.usa.gov +blog.xuite.net +blog.youthwant.com.tw +blog.youxu.info +bloodshed.net +bloomberg.cn +bloomberg.com +bloomberg.de +bloomfortune.com +bmediaasia.com +bnrmetal.com +boardreader.com +bobulate.com +bolin.netfirms.com +bonbonme.com +bonjourlesgeeks.com +boobstagram.com +books.com.tw +bookshelfporn.com +botanwang.com +bot.nu +bowenpress.com +boxunblog.com +boxunclub.com +boxun.com +boxun.tv +bralio.com +branch.com +brandonhutchinson.com +braumeister.org +break.com +breakingtweets.com +briefdream.com +brightcove.com +brightkite.com +brizzly.com +broadbook.com +br.st +brucewang.net +bt95.com +btdigg.org +btrd.net +budaedu.org +bugclub.org +builtwithbootstrap.com +bullogger.com +bullog.org +businesstimes.com.cn +businessweek.com +buugaa.com +buy.yahoo.com.tw +buzzurl.jp +bwbx.io +bwsj.hk +bx.tl +c1522.mooo.com +cacnw.com +cactusvpn.com +cafepress.com +cahr.org.tw +calameo.com +calebelston.com +cams.com +cams.org.sg +canadameet.com +canyu.org +caobian.info +caochangqing.com +cao.im +cari.com.my +catch22.net +catfightpayperview.xxx +catholic.org.hk +catholic.org.tw +cbs.ntu.edu.tw +cc9007.spaces.live.com +ccavtop10.com +ccdtr.org +ccim.org +cclife.org +ccthere.com +cctongbao.com +ccue.ca +ccue.com +cdig.info +cdjp.org +cdnews.com.tw +cdn.printfriendly.com +cdp1998.org +cdp2006.org +cdp.sinica.edu.tw +cdpusa.org +cdpweb.org +cdpwu.org +cdw.com +cecc.gov +cellulo.info +cenci.tk +cenews.eu +centralnation.com +centurys.net +c-est-simple.com +cfhks.org.hk +cftfc.com +cgdepot.org +chandoo.org +change.org +changp.com +chaos.e-spacy.com +chapm25.com +chartbeat.net +chaturbate.com +chccc.gov.tw +chengmingmag.com +chenguangcheng.com +chenpokong.com +chenyehao.spaces.live.com +cherrysave.com +chevronwp7.com +chicagoncmtv.com +china101.com +china21.com +china21.org +china5000.us +chinaaffairs.org +chinaaid.me +chinaaid.net +chinaaid.org +chinaaid.us +chinachange.org +chinachannel.hk +chinacomments.org +chinadigitaltimes.net +chinaeweekly.com +chinafreepress.org +chinagate.com +chinageeks.org +chinagfw.org +chinagreenparty.org +china-green-party.spaces.live.com +chinahush.com +chinainperspective.com +chinainperspective.net +chinainperspective.org +chinainterimgov.org +chinalawandpolicy.com +chinalawtranslate.com +chinamule.com +chinamz.org +chinarightsia.org +chinasocialdemocraticparty.com +chinaso.com +chinasoul.org +chinatimes.com +chinatweeps.com +chinaway.org +china-week.com +chinaworker.info +chinaxchina.com +chinayouth.org.hk +chinayuanmin.org +chinesedailynews.com +chinese.engadget.com +chinese-hermit.net +chinese-memorial.org +chinesen.de +chinesenewsnet.com +chinesepen.org +chinese.rnw.nl +chinese.soifind.com +chinesetalks.net +chinese.wsj.com +chingcheong.com +chn.chosun.com +chrispederick.com +chrispederick.net +christianstudy.com +christiantimes.org.hk +christusrex.org +chrlawyers.hk +chrlcg-hk.org +chromeadblock.com +chrome.com +ch.shvoong.com +chubun.com +chuizi.net +chukuang.gov.tw +circlethebayfortibet.org +citizenlab.org +citizensradio.org +city9x.com +civicparty.hk +civilhrfront.org +civilmedia.tw +cjb.net +ck101.com +classicalguitarblog.net +clb.org.hk +cl.d0z.net +clientsfromhell.net +clipfish.de +cl.ly +cloudfront.net +club.backchina.com +cms.gov +cmule.com +cn2.streetvoice.com +cna.com.tw +cnavista.com.tw +cn.calameo.com +cn.dayabook.com +cnd.org +cn.fmnnow.com +cn.ibtimes.com +cnn.com +cn.news.cnyes.com +cn.streetvoice.com +cn.uncyclopedia.wikia.com +cn.voa.mobi +cochina.org +cocoapods.org +cocoa.zonble.net +code1984.com +codeboxapp.com +codeshare.io +collateralmurder.com +collateralmurder.org +comefromchina.com +comnews.gio.gov.tw +compileheart.com +connectedchina.reuters.com +connect.facebook.net +conoyo.com +contactmagazine.net +contests.twilio.com +conviva.com +cookingtothegoodlife.com +coolaler.com +coolder.com +coolloud.org.tw +corpus4u.org +corumcollege.com +cotweet.com +couchdbwiki.com +coveringweb.com +cp-house.gov.tw +cpj.org +crackle.com +crd-net.org +creaders.net +cromotc.nat.gov.tw +crossthewall.net +csdparty.com +c-spanvideo.org +css.pixnet.in +csuchen.de +cts.com.tw +cubicle17.com +cuhkacs.org +cuihua.org +cuiweiping.net +culture.tw +curvefish.com +cwb.gov.tw +cyanogenmod.org +cyberghost.natado.com +cyberghostvpn.com +cycab.gov.tw +cydia.ifuckgfw.com +cynscribe.com +cytode.us +dabr.co.uk +dabr.me +dabr.mobi +dadazim.com +dadi360.com +dafagood.com +dafahao.com +dailidaili.com +dailymotion.com +dailynews.sina.com +dajiyuan.com +dajiyuan.eu +dajusha.baywords.com +dalailama.com +dalailama.ru +dalailamaworld.com +dalianmeng.org +danke4china.net +danwei.org +daolan.net +dapu-house.gov.tw +darpa.mil +date.fm +davidslog.com +daxa.cn +dayaarmongol.ning.com +daylife.com +ddc.com.tw +deck.ly +default.secureserver.net +delcamp.net +delicious.com +democrats.org +demo.opera-mini.net +derekhsu.homeip.net +de-sci.org +designerol.com +destiny.xfiles.to +deutsche-welle.de +dev102.com +developers.box.net +deviantart.com +deviantart.net +devio.us +devpn.com +dfas.mil +df.gov.tw +diaoyuislands.org +digitalnomadsproject.org +diigo.com +dimitrik.free.fr +dipity.com +directcreative.com +discuss.com.hk +disp.cc +dit-inc.us +dizhidizhi.com +djangosnippets.org +dl.box.net +dl-laby.jp +dl.playstation.net +dlsite.com +dmcdn.net +dmtip.gov.tw +dns2go.com +dnscrypt.org +docstoc.com +dojin.com +dok-forum.net +dolc.de +dollf.com +domain.club.tw +domainhelp.search.com +dongde.com +dongtaiwang.com +dongtaiwang.net +dongyangjing.com +dontfilter.us +dontmovetochina.com +dotheyfolloweachother.com +dotplane.com +dotsub.com +doubleaf.com +doubleclick.net +dougscripts.com +dowei.org +download.syniumsoftware.com +doxygen.org +dphk.org +dpp.org.tw +drewolanoff.com +drgan.net +dropbox.com +dropboxusercontent.com +drsunacademy.com +drtuber.com +dscn.info +dtiblog.com +dtic.mil +dtiserv2.com +duckduckgo.com +duckload.com +duckmylife.com +duihuahrjournal.org +duihua.org +duoweitimes.com +duping.net +duplicati.com +dupola.com +dupola.net +dvorak.org +dw.de +dwnews.com +dwnews.net +dw-world.com +dw-world.de +dy24k.info +dynawebinc.com +dyndns.org +dzze.com +e123.hk +eamonnbrennan.com +earthquake.usgs.gov +easy-share.com +ebookbrowse.com +ebookee.com +echofon.com +ecministry.net +edicypages.com +edoors.com +edubridge.com +eevpn.com +efcc.org.hk +efksoft.com +efmoe.com +e-gold.com +eic-av.com +e-info.org.tw +electionsmeter.com +elpais.com +eltondisney.com +emacsblog.org +embr.in +emory.edu +emule-ed2k.com +emuparadise.me +enewstree.com +en.favotter.net +englishfromengland.co.uk +entermap.com +en.wikipedia.org +epochtimes-bg.com +epochtimes.co.il +epochtimes.co.kr +epochtimes.com +epochtimes.de +epochtimes.fr +epochtimes.ie +epochtimes.jp +epochtimes-romania.com +epochtimes.ru +epochtimes.se +epochtimestr.com +epochweekly.com +erabaru.net +erepublik.com +erepublik.net +erights.net +eriversoft.com +ernestmandel.org +etaiwannews.com +etizer.org +etools.ncol.com +e-traderland.net +etraining.gov.tw +ettoday.net +evchk.wikia.com +eventful.com +everyday-carry.com +exblog.jp +expatshield.com +exploader.net +extremetube.com +eyespirit.info +eyevio.jp +eyny.com +ezpc.tk +ezpeer.com +facebook.com +facebook.net +facesofnyfw.com +fail.hk +faiththedog.info +fakku.net +falsefire.com +falunart.org +falundafamuseum.org +falundafa.org +falunhr.org +famunion.com +fangbinxing.com +fangeming.com +fanglizhi.info +fangongheike.com +fangong.org +fan-qiang.com +fanqianghou.com +fanqiangyakexi.net +fanswong.com +fanyue.info +fapdu.com +farwestchina.com +farxian.com +fastpic.ru +faststone.org +favorious.com +favstar.fm +fawanghuihui.org +faydao.com +fbcdn.net +fb.com +fb.me +fbsbx.com +fc2china.com +fc2.com +f.cl.ly +fdc89.jp +feedbooks.mobi +feedburner.com +feeds2.feedburner.com +feeds.feedburner.com +feedzshare.com +feelssh.com +feer.com +felixcat.net +feministteacher.com +fengzhenghu.com +fetchvideo.com +ff.im +fflick.com +fgmtv.net +fgmtv.org +filefactory.com +files2me.com +fileserve.com +fillthesquare.org +finalion.jp +findbook.tw +finler.net +fireofliberty.org +firstfivefollowers.com +flecheinthepeche.fr +fleshbot.com +flickr.com +flickrhivemind.net +flightcaster.com +flowerofhappiness.spaces.live.com +focustaiwan.tw +focusvpn.com +fofg.org +fooooo.com +footwiball.com +forum.baby-kingdom.com +forum.cyberctm.com +forum.idsam.com +forum.iset.com.tw +forum.my903.com +forum.mymaji.com +forum.newsgroup.la +forum.nownews.com +forum.omy.sg +forum.palmislife.com +forum.pchome.com.tw +forum.setty.com.tw +forum.sina.com.hk +forum.slime.com.tw +forum.tvb.com +forum.yorkbbs.ca +fotop.net +fourface.nodesnoop.com +fourthinternational.org +foxdie.us +foxsub.com +foxtang.com +fqrouter.com +franklc.com +freakshare.com +fredwilson.vc +free4u.com.ar +freealim.com +freechal.com +freedomhouse.org +free.fr +freegao.com +freegateget.googlepages.com +free-gate.org +free-hada-now.org +freelotto.com +freeman2.com +freemoren.com +freemorenews.com +freenet-china.org +freenetproject.org +freenewscn.com +freeopenvpn.com +freeoz.org +free-ssh.com +freessh.us +freetibet.org +freevpn.nl +freewallpaper4.me +freewebs.com +freeweibo.com +freexinwen.com +freeyoutubeproxy.net +friendfeed.com +friendfeed-media.com +fring.com +fringenetwork.com +frommel.net +frontlinedefenders.org +fscked.org +fsurf.com +ftchinese.com +fuckcnnic.net +fuckgfw.com +fuckgfw.org +fulue.com +funf.tw +funp.com +furinkan.com +furl.net +futurechinaforum.org +futureme.org +futuremessage.org +fuyin.net +fw.cm +fxnetworks.com +fzh999.com +fzh999.net +gabocorp.com +gaeproxy.com +gaeproxy.googlecode.com +galenwu.com +game735.com +gamebase.com.tw +gamer.com.tw +gamez.com.tw +ganges.com +gaoming.net +gaopi.net +gaozhisheng.net +gaozhisheng.org +gardennetworks.com +gardennetworks.org +gartlive.com +gather.com +gaymap.cc +gazotube.com +gcc.org.hk +gclooney.com +g.co +gcpnews.com +gdbt.net +gdzf.org +geek-art.net +geekerhome.com +geekmade.co.uk +geekmanuals.com +generesis.com +genuitec.com +geocities.co.jp +geocities.com +geocities.jp +geohot.com +geometrictools.com +getchu.com +getcloudapp.com +get-digital-help.com +getfoxyproxy.org +getfreedur.com +getiton.com +getjetso.com +getlantern.org +getsmartlinks.com +getsocialscope.com +gfwinterceptor.googlecode.com +gfw.org.ua +ggpht.com +ggssl.com +ghost.org +ghut.org +giga-web.jp +gigporno.ru +gimpshop.com +girlbanker.com +github.com +git-scm.com +givemesomethingtoread.com +glennhilton.com +globaljihad.net +globalmuseumoncommunism.org +globalrescue.net +globalvoicesonline.org +gmail.com +gmbd.cn +gmhz.org +gmodules.com +gmozomg.izihost.org +gnci.org.hk +goagent.biz +goagent.googlecode.com +goagentplus.com +godfootsteps.org +golang.org +goldbetsports.com +goldwave.com +gongmeng.info +gongm.in +gongminliliang.com +gongwt.com +goodreaders.com +goodreads.com +goofind.com +goo.gl +googleadservices.com +google-analytics.com +googleapis.com +googlecode.com +google.co.jp +google.com +google.com.hk +google.com.sg +google.com.tw +google.com.uk +googledomains.com +googledrive.com +googleearth.com +googlehosted.com +googlelabs.com +googlemail.com +googleplus.com +googlesile.com +googlesource.com +googlesyndication.com +googletagmanager.com +googletagservices.com +googleusercontent.com +googlevideo.com +gopetition.com +gospelherald.com +gov.tw +gpass1.com +grandtrial.org +graphis.ne.jp +gravatar.com +graylog2.org +grb.gov.tw +greatfire.org +greatfirewall.biz +great-firewall.com +greatfirewallofchina.net +greatfirewallofchina.org +great-roc.org +greatroc.org +greatroc.tw +greatzhonghua.org +greenparty.org.tw +greenvpn.net +gs-discuss.com +gseeker.com +gsn-cert.nat.gov.tw +gstatic.com +gtap.googlecode.com +gtricks.com +guancha.org +gufeng521.spaces.live.com +guishan.org +gunsamerica.com +gun-world.net +guomin.us +gutteruncensored.com +gvm.com.tw +gyalwarinpoche.com +gysd.nyc.gov.tw +gzm.tv +gzone-anime.info +h1n1china.org +hacken.cc +hackthatphone.net +hahlo.com +hakkatv.org.tw +hanunyi.com +hardsextube.com +hasaowall.com +have8.com +haygo.com +hcc.gov.tw +hchcc.gov.tw +h-china.org +hdtvb.net +heartyit.com +hecaitou.net +hechaji.com +heix.pp.ru +heiyo.info +helloandroid.com +hellonewyork.us +helloqueer.com +hellotxt.com +hellouk.org +helpeachpeople.com +helplinfen.com +help.linksalpha.com +help.opera.com +helpzhuling.org +hen.bao.li +hengchuen.gov.tw +heqinglian.net +here4news.com +heungkongdiscuss.com +hgseav.com +hidden-advent.org +hidecloud.com +hideipvpn.com +hidemyass.com +higfw.com +highrockmedia.com +hihiforum.com +hihistory.net +hiitch.com +hikinggfw.org +himemix.com +himemix.net +hjclub.info +hk32168.com +hkbc.net +hkbf.org +hkchurch.org +hkdailynews.com.hk +hkday.net +hkej.com +hkepc.com +hkfront.org +hk.geocities.com +hkgolden.com +hkgreenradio.org +hkg.westkit.net +hkheadline.com +hkhkhk.com +hkjc.com +hk.jiepang.com +hkjp.easyweb.hk +hkjp.org +hk.knowledge.yahoo.com +hk.myblog.yahoo.com +hk.news.yahoo.com +hkptu.org +hk-pub.com +hk.rd.yahoo.com +hkreporter.com +hkreporter.loved.hk +hk.search.yahoo.com +hk.video.news.yahoo.com +hkwcc.org.hk +hk.yahoo.com +hkzone.org +hnjhj.com +hola.com +holyspiritspeaks.org +holz.byethost8.com +homeservershow.com +home.sina.com +home.so-net.net.tw +honeonet.spaces.live.com +hongmeimei.com +hongzhi.li +hootsuite.com +hotpot.hk +hotshame.com +hotspotshield.com +hougaige.com +howtoforge.com +hqcdp.org +hrcir.com +hrichina.org +hrw.org +hsinchu-cc.gov.tw +hsjp.net +hsselite.com +htkou.net +htl.li +ht.ly +htmldog.com +huaglad.com +huajiadi.spaces.live.com +huanghuagang.org +huaren.us +huaxia-news.com +huaxin.ph +hua-yue.net +hudatoriq.web.id +hugoroy.eu +huhamhire.com +hujiachina.spaces.live.com +hulu.com +huluim.com +humanities.uchicago.edu +hungerstrikeforaids.org +hung-ya.com +huping.net +hutianyi.net +hutong9.net +hwinfo.com +hyperrate.com +hypeshell.com +i1.hk +i2runner.com +ialmostlaugh.com +iask.bz +iask.ca +ibiblio.org +iblogserv-f.net +ibros.org +icij.org +icl-fi.org +iconpaper.org +icu-project.org +idemocracy.asia +identi.ca +idiomconnection.com +idouga.com +idv.tw +ieasynews.net +ied2k.net +ieemdai.spaces.live.com +ifan.cz.cc +ifanqiang.com +ifanr.com +ifcss.org +ifjc.org +igfw.net +ignitedetroit.net +igvita.com +ihakka.net +iicns.com +illusionfactory.com +ilove80.be +im88.tw +imageflea.com +imagesblog.gio.gov.tw +imageshack.us +imagevenue.com +imagezilla.net +ime.baidu.jp +img.ly +imkev.com +imlive.com +immigration.gov.tw +imrworldwide.com +im.tv +incredibox.fr +iner.gov.tw +initiativesforchina.org +inmediahk.net +innermongolia.org +instagram.com +interestinglaugh.com +interfaceaddiction.com +internationalrivers.org +internetdefenseleague.org +internetfreedom.org +internetpopculture.com +inxian.com +iphone4hongkong.com +iphonehacks.com +iphonix.fr +ipicture.ru +ipobar.com +ippotv.com +iptorrents.com +ipvanish.com +iredmail.org +ironbigfools.compython.net +ironicsoftware.com +ironpython.net +isaacmao.com +isgreat.org +islamicity.com +islam.org.hk +ismprofessional.net +isohunt.com +israbox.com +istockphoto.com +isunaffairs.com +isuntv.com +itaboo.info +ithelp.ithome.com.tw +itrc.gov.tw +itshidden.com +itweet.net +iu45.com +iverycd.com +ixquick.com +izaobao.us +izles.net +japan-whores.com +jayparkinsonmd.com +jbtalks.cc +jbtalks.com +jbtalks.my +jeanyim.com +jgoodies.com +jiaoyou8.com +jiehua.cz +jieshibaobao.com +jike.com +jimoparty.com +jinbushe.org +jingpin.org +jitouch.com +jkforum.net +j.mp +joachims.org +jobso.tv +joeedelman.com +journalofdemocracy.org +jpopforum.net +juliereyc.com +junauza.com +junefourth-20.net +justfreevpn.com +justtristan.com +juziyue.com +jwmusic.org +jyxf.net +jyzj.waqn.com +k2.xrea.com +kagyuoffice.org.tw +kaiyuan.de +kakao.com +kanzhongguo.com +kanzhongguo.eu +karayou.com +ka-wai.com +kcsoftwares.com +kechara.com +keepandshare.com +kendincos.net +kenengba.com +keontech.net +khcc.gov.tw +khms.gov.tw +khmusic.com.tw +killwall.com +kineox.free.fr +kingdomsalvation.org +kinghost.com +kingstone.com.tw +kissbbao.cn +kissyoutube.com +kk.gov.tw +klccab.gov.tw +klra.gov.tw +klsio.gov.tw +kmh.gov.tw +kmseh.gov.tw +knowledgerush.com +kodingen.com +kompozer.net +koolsolutions.com +koornk.com +kt.kcome.org +kui.name +kun.im +kurtmunger.com +kusocity.com +kwongwah.com.my +kyohk.net +kzeng.info +labiennale.org +ladbrokes.com +la-forum.org +lagranepoca.com +lalulalu.com +laogai.org +laomiu.com +laoyang.info +laptoplockdown.com +laqingdan.net +larsgeorge.com +lastfm.es +latelinenews.com +latimesblogs.latimes.com +lazarsearlymusic.com +leecheukyan.org +legaltech.law.com +lematin.ch +lemonde.fr +lenwhite.com +lerosua.org +lesoir.be +lesscss.org +letscorp.net +liansi.org +lianyue.net +liaowangxizang.net +liberal.org.hk +libertytimes.com.tw +lich355.megabyet.net +lidecheng.com +life.fly4ever.me +limiao.net +line.me +linglingfa.com +lingvodics.com +linkideo.com +linuxconfig.org +linux-engineer.net +linuxreviews.org +linuxtoy.org +lipuman.com +listentoyoutube.com +list.ly +listorious.com +lists.debian.org +lists.w3.org +littlebigdetails.com +liudejun.com +liuhanyu.com +liujianshu.com +liu.lu +liuxiaotong.com +liveleak.com +livestation.com +livestream.com +livevideo.com +livingonline.us +livingstream.com +lizhizhuangbi.com +lkcn.net +localpresshk.com +lockdown.com +lockestek.com +logbot.net +logiqx.com +logmike.com +log.riku.me +london.neighborhoodr.com +longhair.hk +longtermly.net +lookatgame.com +lookingglasstheatre.org +lookpic.com +lotuslight.org.tw +lovequicksilver.com +lovesphinx.tk +lrfz.com +lsd.org.hk +lsforum.net +lsmchinese.org +lsmkorean.org +lsm.org +lsxszzg.com +lua.org +lua-users.org +lungtanhr.gov.tw +luntan.zaobao.com +lupm.org +lushstories.com +lvhai.org +lyricsquote.com +mad-ar.ch +madmenunbuttoned.com +magazines.sina.com.tw +maiio.net +mail-archive.com +maiplus.com +makemymood.com +makzhou.warehouse333.com +malaysiakini.com +marc.info +marco.org +marguerite.su +marines.mil +markmilian.com +martau.com +martincartoons.com +maruta.be +marxist.com +marxist.net +marxists.org +mashable.com +mash.to +matainja.com +mathiew-badimon.com +matsu-news.gov.tw +matsushimakaede.com +maxgif.com +mayimayi.com +mcadforums.com +mcfog.com +md-t.org +mediafire.com +meetup.com +mefeedia.com +megaporn.com +megarotic.com +megavideo.com +megurineluka.com +meirixiaochao.com +melon-peach.com +memedia.cn +meme.yahoo.com +memrijttm.org +merit-times.com.tw +mesotw.com +metacafe.com +meteorshowersonline.com +metrolife.ca +mgoon.com +mgstage.com +mh4u.org +mhradio.org +michaelanti.com +michaelmarketl.com +middle-way.net +mihk.hk +mihua.org +mike.cz.cc +mimivip.com +minghui.org +minghui-school.org +mingjinglishi.com +mingjingnews.com +mingpaocanada.com +mingpao.com +mingpaomonthly.com +mingpaonews.com +mingpaony.com +mingpaosf.com +mingpaotor.com +mingpaovan.com +minimalmac.com +mininova.org +minzhuhua.net +minzhuzhongguo.org +miroguide.com +mirrorbooks.com +mitbbs.com +mixedmedialabs.com +mixero.com +mixpod.com +mixx.com +mizzmona.com +mk5000.com +mlcool.com +mmaaxx.com +mmmca.com +mobatek.net +mobile01.com +mobileways.de +mobypicture.com +moby.to +modfetish.com +moe.gov.tw +mog.com +molihua.org +mondex.org +monitorchina.org +moonriver7.files.wordpress.com +morningsun.org +m.oulove.org +movabletype.com +moviefap.com +mp3ye.eu +mpettis.com +mpfinance.com +mpinews.com +m.plixi.com +mrdoob.com +mrtweet.com +msguancha.com +m.slandr.net +m-team.cc +mthruf.com +m.tweete.net +mtw.tl +multiply.com +multiproxy.org +multiupload.com +muouju.com +muselinks.co.jp +music.jwmusic.org +muzi.com +muzi.net +muzu.tv +mvdis.gov.tw +mx981.com +myactimes.com +my-addr.com +myaudiocast.com +myav.com.tw +my.backchina.com +myboooks.googlepages.com +mychinamyhome.com +myeclipseide.com +myforum.com.hk +myforum.com.uk +myfreshnet.com +my.keso.cn +myopenid.com +my.opera.com +mypaper.pchome.com.tw +myparagliding.com +mypopescu.com +my-proxy.com +myshare.url.com.tw +mysinablog.com +myspace.com +myvlog.im.tv +naacoalition.org +naitik.net +nakido.com +namsisi.com +nanyang.com +nanyangpost.com +nanzao.com +naol.ca +national-lottery.co.uk +navicat.com +navigeaters.com +navy.mil +nccwatch.org.tw +ncdr.nat.gov.tw +nch.com.tw +ncn.org +ncree.gov.tw +nde.de +ndr.de +nekoslovakia.net +nerch.gov.tw +ner.gov.tw +nerhl.gov.tw +nertt.gov.tw +netcolony.com +netflix.com +netme.cc +networkedblogs.com +neverforget8964.org +new-3lunch.net +new-akiba.com +newcenturymc.com +newcenturynews.com +newchen.com +newgrounds.com +newlandmagazine.com.au +news100.com.tw +newsancai.com +news.atebits.com +news.backchina.com +news.bbc.co.uk +newscn.org +news.cnyes.com +newsforums.bbc.co.uk +news.ghostery.com +news.google.com.hk +newsminer.com +news.msn.com.tw +news.omy.sg +news.pchome.com.tw +newspeak.cc +newspp.org +news.sina.com.hk +news.sina.com.tw +news.singtao.ca +newstapa.org +newtaiwan.com.tw +newtalk.tw +newyorktimes.com +nexton-net.jp +nexttv.com.tw +nf.id.au +nga.mil +ngensis.com +nhri.gov.tw +nic.cz.cc +nici.nat.gov.tw +nicovideo.tw +nict.gov.tw +nighost.org +nintendium.com +nintendowifi.net +njactb.org +njuice.com +nlfreevpn.com +nmh.gov.tw +nmmba.gov.tw +nmp.gov.tw +nmtl.gov.tw +nmvttc.gov.tw +nobelprize.org +nobel.se +nobodycanstop.us +nokogiri.org +nokola.com +noobbox.com +notes.alexdong.com +novelasia.com +nownews.com +nowtorrents.com +noypf.com +npa.go.jp +npm.gov.tw +nps.gov +nrk.no +nsc.gov.tw +nspo.gov.tw +nstm.gov.tw +ntdmh.gov.tw +ntdtv.ca +ntdtv.co +ntdtv.com +ntdtv.org +ntdtv.ru +ntl.gov.tw +ntsec.gov.tw +ntuh.gov.tw +nuexpo.com +nurgo-software.com +nuvid.com +nuzcom.com +nvquan.org +nvri.gov.tw +nydus.ca +nysingtao.com +nytco.com +nyt.com +nytimes.com +nytimg.com +nzchinese.net.nz +observechina.net +oclp.hk +october-review.org +offbeatchina.com +ogaoga.org +oikos.com.tw +oiktv.com +oizoblog.com +okayfreedom.com +old-cat.net +old.nabble.com +olumpo.com +olympicwatch.org +omgili.com +omnitalk.com +on.cc +one.xthost.info +onlylady.cn +onmoon.com +onmoon.net +oopsforum.com +ooyala.com +open.com.hk +opendemocracy.net +openid.net +openleaks.org +openvpn.net +openvpn.org +openwebster.com +opml.radiotime.com +opnir.com +orientaldaily.com.my +orient-doll.com +orn.jp +orzistic.org +osfoora.com +ourdearamy.com +oursogo.com +oursteps.com.au +overlapr.com +owl.li +ow.ly +oyax.com +ozchinese.com +ozyoyo.com +pabp.gov.tw +pacificpoker.com +packages.debian.org +packetix.net +page2rss.com +page.bid.yahoo.com +pagodabox.com +paint.net +palacemoon.com +pandora.com +pandora.tv +panluan.net +panoramio.com +pao-pao.net +paperb.us +paper.li +paper-replika.com +parade.com +parislemon.com +pastebin.com +pastie.org +patehr.gov.tw +pbs.org +pbwiki.com +pbworks.com +pbxes.com +pbxes.org +pcdiscuss.com +pcdvd.com.tw +pchome.com.tw +pct.org.tw +pcworld.com +pdetails.com +pdproxy.com +peacefire.org +peacehall.com +peeasian.com +peerpong.com +pekingduck.org +penchinese.com +penchinese.net +pengyulong.com +penthouse.com +peopo.org +percy.in +perfectgirls.net +perfectvpn.net +perfspot.com +perlhowto.com +pet.gov.tw +philly.com +photofocus.com +photos.dailyme.com +photo.utom.us +phuquocservices.com +picasaweb.google.com +picidae.net +picturesocial.com +pictures.playboy.com +pidown.com +pign.net +pimg.tw +pin6.com +ping.fm +pinoy-n.com +pioneer-worker.forums-free.com +piring.com +pixanalytics.com +pixelqi.com +pixfs.net +pixnet.cc +pixnet.net +pixplug.in +pk.com +placemix.com +planetsuzy.org +playboy.com +plays.com.tw +plm.org.hk +plunder.com +plurk.com +plurktop.mmdays.com +plus28.com +plusbb.com +pmates.com +po2b.com +podictionary.com +pokerstars.com +politicalchina.org +popvote.hk +popyard.com +popyard.org +porn2.com +pornbase.org +porn.com +pornhub.com +pornmm.net +pornoxo.com +pornrapidshare.com +pornstarclub.com +porntube.com +pornvisit.com +portis21.spaces.live.com +pose.com +postadult.com +post.anyu.org +posterous.com +post.ly +powerapple.com +power.com +powercx.com +prayforchina.net +premeforwindows7.com +presentationzen.com +president.gov.tw +prestige-av.com +previewshots.com +privacybox.de +privateinternetaccess.com +privatepaste.com +privatetunnel.com +procopytips.com +program-think.spaces.live.com +prosiben.de +provideocoalition.com +proxifier.com +proxomitron.info +proxy.org +proxypy.net +proxyroad.com +prozz.net +psblog.name +psiphon.ca +psiphon.civisec.org +pts.org.tw +ptt.cc +pubu.com.tw +puffinbrowser.com +puffstore.com +pullfolio.com +pulse.yahoo.com +pure18.com +pureconcepts.net +purepdf.com +purevpn.com +putlocker.com +puttycm.free.fr +pwned.com +python.com +python.com.tw +qanote.com +qidian.ca +qienkuen.org +qi-gong.me +qiwen.lu +qixianglu.cn +qkshare.com +qoos.com +qq.co.za +qstatus.com +qtrac.eu +qtweeter.com +quadedge.com +qusi8.net +qvodzy.org +qxbbs.org +radicalparty.org +radioaustralia.net.au +radiovaticana.org +radiovncr.com +raidcall.com.tw +rangzen.org +ranyunfei.com +rapbull.net +rapidshare8.com +rapidsharedata.com +rayfme.com +rcinet.ca +rconversation.blogs.com +rdio.com +read100.com +readingtimes.com.tw +readmoo.com +realraptalk.com +recordhistory.org +redchinacn.org +redtube.com +referer.us +reflectivecode.com +relaxbbs.com +renminbao.com +renyurenquan.org +retweeteffect.com +retweetist.com +retweetrank.com +revleft.com +revsci.net +revver.com +rfachina.com +rfamobile.org +rfa.org +rferl.org +rfi.fr +rhcloud.com +riku.me +rileyguide.com +rlwlw.com +rmjdw.com +rnw.nl +robtex.com +robustnessiskey.com +rocmp.org +rojo.com +ronjoneswriter.com +roodo.com +rotten.com +rsf-chinese.org +rsf.org +rssmeme.com +rthk.hk +rthk.org.hk +rti.org.tw +ruanyifeng.com +rushbee.com +rutube.ru +ruyiseek.com +rxhj.net +s1heng.com +s8forum.com +sacom.hk +sadpanda.us +saiq.me +salvation.org.hk +samair.ru +sammyjs.org +samsoff.es +sandnoble.com +sankaizok.com +sanmin.com.tw +sapikachu.net +savemedia.com +savetibet.de +savetibet.fr +savetibet.nl +savetibet.org +savetibet.ru +savevid.com +say2.info +scanscout.com +scmpchinese.com +scmp.com +scorecardresearch.com +scribd.com +scriptspot.com +seapuff.com +secretchina.com +secretgarden.no +secure.wikimedia.org +securitykiss.com +seesmic.com +seevpn.com +seezone.net +sejie.com +sendoid.com +sendspace.com +sesawe.net +sesawe.org +sethwklein.net +sevenload.com +sex-11.com +sex3.com +sex8.cc +sexandsubmission.com +sex.com +sexhuang.com +sexhu.com +sexinsex.net +sfileydy.com +shadow.ma +shadowsocks.org +shahamat-english.com +shangfang.org +shapeservices.com +sharebee.com +sharecool.org +share.ovi.com +share.skype.com +share.youthwant.com.tw +sharkdolphin.com +sharpdaily.com.hk +sharpdaily.hk +shaunthesheep.com +sheikyermami.com +shellmix.com +shenshou.org +shenyunperformingarts.org +shenzhoufilm.com +shifeike.blog125.fc2blog.net +shinychan.com +shitaotv.org +shixiao.org +shizhao.org +shkspr.mobi +shodanhq.com +shopping.com +showbiz.omy.sg +showtime.jp +shwchurch3.com +sidelinesnews.com +sidelinessportseatery.com +simplecd.me +simplecd.org +simpleproductivityblog.com +sina.com.tw +singtao.com +singularitys.spaces.live.com +sinoants.com +sinocast.com +sinocism.com +sino-monthly.com +sinomontreal.ca +sinonet.ca +sinopitt.info +sinoquebec.com +sis001.com +sis001.us +sis.xxx +site90.net +sitebro.tw +siteks.uk.to +site.locql.com +sitemaps.org +sites.google.com +sitetag.us +siyi123123123.spaces.live.com +skimtube.com +skybet.com +skyvegas.com +slacker.com +slavasoft.com +slheng.com +slickvpn.com +slideshare.net +slinkset.com +slutload.com +smhric.org +snapchat.com +snaptu.com +sndcdn.com +sneakme.net +snooper.co.uk +sobees.com +socialwhale.com +sockslist.net +so.com +sod.co.jp +softether.co.jp +softether-download.com +softether.org +softwarebychuck.com +so-ga.net +sogclub.com +sogou.com +sogrady.me +sohcradio.com +sohfrance.org +soh.tw +sokamonline.com +solozorro.tk +somee.com +so-news.com +songjianjun.com +sonidodelaesperanza.org +sopcast.com +sopcast.org +sorting-algorithms.com +soso.com +soumo.info +soundcloud.com +soundofhope.kr +soundofhope.org +soupofmedia.com +sourceforge.net +southnews.com.tw +sowers.org.hk +space-scape.com +spankwire.com +spb.com +speckleapp.com +speedpluss.org +spencertipping.com +spinejs.com +sports.williamhill.com +spotify.com +sproutcore.com +squarespace.com +srcf.ucam.org +ssh91.com +sshtunnel.googlecode.com +sstatic.net +stag.gov.tw +standupfortibet.org +starp2p.com +startpage.com +statcounter.com +state168.com +static.apple.nextmedia.com +static.digg.com +staticflickr.com +static.nownews.com +static.soup.io +static.typepad.com +status.twhirl.org +stdtime.gov.tw +steel-storm.com +sthoo.com +stickam.com +stickeraction.com +stonegames.net +stoneip.info +stoptibetcrisis.net +storagenewsletter.com +stoweboyd.com +streamingthe.net +strongvpn.com +student.tw +stuffimreading.com +stuffimreading.net +stupidvideos.com +subacme.rerouted.org +sublexical.spaces.live.com +sufeng.org +sugarsync.com +summify.com +sun1911.com +suoluo.org +surfeasy.com.au +svwind.com +sweux.com +swift-tools.net +s.xiaod.in +sydneytoday.com +sylfoundation.org +syncback.com +sysadmin1138.net +sysresccd.org +sytes.net +szbbs.net +szetowah.org.hk +t35.com +t66y.com +taa-usa.org +tabtter.jp +tacem.org +tafaward.com +tagwalk.com +taipei.gov.tw +taipeisociety.org +taitung-house.gov.tw +taiwandaily.net +taiwankiss.com +taiwannation.50webs.com +taiwannation.com +taiwannation.com.tw +taiwannews.com.tw +taiwan-sex.com +taiwantt.org.tw +taiwanus.net +taiwanyes.com +taiwanyes.ning.com +tamiaode.tk +tanc.org +tangben.com +taolun.info +taoyuan.gov.tw +tap11.com +target.com +taweet.com +tax.nat.gov.tw +tbpic.info +tbsec.org +tbsn.org +tbsseattle.org +tchb.gov.tw +tchrd.org +t.co +tcsac.gov.tw +teamseesmic.com +teashark.com +techlifeweb.com +techparaiso.com +telecomspace.com +telegraph.co.uk +tenacy.com +thbstc.gov.tw +theampfactory.com +theappleblog.com +theatrum-belli.com +thebcomplex.com +theblemish.com +thebodyshop-usa.com +thechinabeat.org +thedailywh.at +thedieline.com +thedw.us +thegatesnotes.com +thehots.info +thehousenews.com +thehungrydudes.com +thehun.net +theinternetwishlist.com +thelifeyoucansave.com +thelius.org +thepiratebay.org +thepiratebay.se +theqii.info +thereallove.kr +thesartorialist.com +thespeeder.com +the-sun.on.cc +thetibetpost.com +thetrotskymovie.com +thevivekspot.com +thewgo.org +thisav.com +thisiswhyyouarefat.com +thkphoto.com +thomasbernhard.org +threatchaos.com +throughnightsfire.com +t.huhaitai.com +thumbzilla.com +thywords.com +tiananmenmother.org +tiananmenuniv.com +tiananmenuniv.net +tiandixing.org +tianhuayuan.com +tiantibooks.org +tianzhu.org +tibetalk.com +tibetanyouthcongress.org +tibet.at +tibet.com +tibetcorps.org +tibetfund.org +tibetjustice.org +tibet.net +tibetoffice.org +tibetonline.com +tibetonline.tv +tibet.org.tw +tibetsun.com +tibetwrites.org +tidyread.com +time.com +times.hinet.net +tinychat.com +tinypaste.com +tinypng.com +tistory.com +tjholowaychuk.com +tkcs-collins.com +tkforum.tk +t.kun.im +tmagazine.com +tmi.me +tnaflix.com +tncsec.gov.tw +t.neolee.cn +togetter.com +tokyo-247.com +tokyocn.com +tokyo-hot.com +tomayko.com +tomsc.com +tono-oka.jp +tonyyan.net +toodoc.com +toonel.net +topic.youthwant.com.tw +topnews.in +topshare.us +topshareware.com +topstyle4.com +topsy.com +tora.to +tor.blingblingsquad.net +torproject.org +torrentcrazy.com +torrentproject.se +tor.updatestar.com +torvpn.com +t.orzdream.com +tosh.comedycentral.com +touch99.com +toutfr.com +tpde.aide.gov.tw +tphcc.gov.tw +tpi.org.tw +transgressionism.org +transparency.org +travelinlocal.com +trendsmap.com +trialofccp.org +tripod.com +trouw.nl +trtc.com.tw +trt.net.tr +trulyergonomic.com +trustedbi.com +truth101.co.tv +truthcn.com +truveo.com +tsctv.net +tsemtulku.com +tsquare.tv +tsunagarumon.com +tt1069.com +tttan.com +tuanzt.com +tube8.com +tubecao.com +tube.com +tubewolf.com +tuidang.net +tuidang.org +tui.orzdream.com +tuite.googlecode.com +tumblr.awflasher.com +tumblweed.org +tumutanzi.com +tunein.com +tunnelbear.com +turbobit.net +turbotwitter.com +turningtorso.com +turntable.fm +tuxtraining.com +tvants.com +tvboxnow.com +tv.com +tvider.com +tv-intros.com +tv.on.cc +tvunetworks.com +twapperkeeper.com +twa.sh +twaud.io +twbbs.net.tw +twbbs.org +twbbs.tw +twblogger.com +tweepguide.com +tweeplike.me +tweepmag.com +tweepml.org +tweetbackup.com +tweetboard.com +tweetboner.biz +tweetdeck.com +tweetedtimes.com +tweetmeme.com +tweetmylast.fm +tweetphoto.com +tweetrans.com +tweetree.com +tweetwally.com +tweetymail.com +twftp.org +twibase.com +twibble.de +twibbon.com +twibs.com +twicsy.com +twifan.com +twiffo.com +twiggit.org +twilog.org +twimbow.com +twimg.com +twimg.edgesuite.net +tw.img.nextmedia.com +twindexx.com +twipple.jp +twistar.cc +twisternow.com +twistory.net +twit2d.com +twitbrowser.net +twitcause.com +twitese.spaces.live.com +twitgether.com +twitgoo.com +twitiq.com +twitlonger.com +twitoaster.com +twitonmsn.com +twitpic.com +twitreferral.com +twitstat.com +twittbot.net +twitter4j.org +twitter.com +twittercounter.com +twitterfeed.com +twittergadget.com +twitter.jp +twitterkr.com +twittermail.com +twittertim.es +twitthat.com +twitturk.com +twitturly.com +twitvid.com +twitzap.com +twiyia.com +tw.jiepang.com +tw.myblog.yahoo.com +tw.news.yahoo.com +tw-npo.org +tw.rd.yahoo.com +twreg.info +twstar.net +tw.streetvoice.com +twt.fm +twtkr.com +twtr2src.ogaoga.org +twtrland.com +twt.tl +twttr.com +twurl.nl +tw.voa.mobi +twyac.org +tw.yahoo.com +tycool.com +tynsoe.org +typepad.com +tzangms.com +ub0.cc +uberproxy.net +ucdc1998.org +uderzo.it +udn.com +ufreevpn.com +ugo.com +uhrp.org +uighurbiz.net +ukliferadio.co.uk +ulike.net +ultravpn.fr +ultraxs.com +unblock.cn.com +unblocksit.es +uncyclomedia.org +uncyclopedia.info +uncyclopedia.tw +unholyknight.com +uni.cc +unicode.org +uniteddaily.com.my +unix100.com +unknownspace.org +unpo.org +uocn.org +upcoming.yahoo.com +update.playstation.net +upload4u.info +upload.backchina.com +uploaded.to +uploadstation.com +upload.wikimedia.org +urlborg.com +urlparser.com +usacn.com +usfk.mil +usinfo.state.gov +usmc.mil +us.to +ustream.tv +usus.cc +uushare.com +uwants.com +uwants.net +uyghurcongress.org +uygur.org +v70.us +vaayoo.com +value-domain.com +van698.com +vanemu.cn +vanilla-jp.com +vansky.com +vapurl.com +vatn.org +vcfbuilder.org +vcf-online.org +veempiire.com +velkaepocha.sk +venbbs.com +venchina.com +ventureswell.com +veoh.com +verizon.net +verybs.com +vevo.com +vft.com.tw +vghks.gov.tw +vghtc.gov.tw +vghtpe.gov.tw +video.aol.ca +video.aol.com +video.aol.co.uk +video.ap.org +videobam.com +video.fdbox.com +video.foxbusiness.com +videomo.com +video.tiscali.it +video.yahoo.com +vidoemo.com +views.fm +viki.com +vimeocdn.com +vimeo.com +vimgolf.com +vimperator.org +vincnd.com +vinniev.com +vllcs.org +vlog.xuite.net +vmixcore.com +voacantonese.com +voachineseblog.com +voachinese.com +voagd.com +voanews.com +voatibetan.com +vocn.tv +vot.org +vpnbook.com +vpnfire.com +vpngate.jp +vpngate.net +vpnpop.com +vpnpronet.com +v-state.org +vtunnel.com +w3schools.com +waffle1999.com +wahas.com +waigaobu.com +waikeung.org +waiwaier.com +wallornot.org +wallpapercasa.com +wanderinghorse.net +wanfang.gov.tw +wangafu.net +wangjinbo.org +wanglixiong.com +wangruoshui.net +wangyi64.spaces.live.com +want-daily.com +wapedia.mobi +washeng.net +watchmygf.net +wattpad.com +wdf5.com +wearn.com +web2project.net +webbang.net +webfee.tk +weblagu.com +webmproject.org +webshots.com +websitepulse.com +webs-tv.net +webworkerdaily.com +weeewooo.net +weekmag.info +wefong.com +weiboleak.com +weigegebyc.dreamhosters.com +weijingsheng.org +weiming.info +weiquanwang.org +weisuo.ws +wellplacedpixels.com +wengewang.com +wengewang.org +wenhui.ch +wenku.com +wenxuecity.com +wenyunchao.com +wenyunchao.spaces.live.com +wepn.info +westca.com +westernwolves.com +wetplace.com +wetpussygames.com +wexiaobo.org +wezhiyong.org +wezone.net +wforum.com +whatblocked.com +whereiswerner.com +whippedass.com +whitebear.freebearblog.org +whydidyoubuymethat.com +whylover.com +whyx.org +w.idaiwan.com +wiki.cnitter.com +wiki.jqueryui.com +wiki.keso.cn +wikileaks.ch +wikileaks.de +wikileaks.eu +wikileaks.lu +wikileaks.org +wikileaks.pl +wikilivres.info +wikimapia.org +wikimedia.org.mo +wiki.moegirl.org +wikinet.org +wiki.oauth.net +wikipedia.org +wiki.phonegap.com +wikiwiki.jp +wikkii.com +williamlong.spaces.live.com +willw.net +windowsphoneme.com +winwhispers.info +wiredbytes.com +wiredpen.com +wireshark.org +wisevid.com +witnessleeteaching.com +witopia.net +wlx.sowiki.net +woeser.com +wolfax.com +womenbusiness.nyc.gov.tw +womensrightsofchina.org +woopie.jp +woopie.tv +wordboner.com +wordpress.com +wordsandturds.com +w.org +workatruna.com +worldcat.org +worldjournal.com +worstthingieverate.com +wo.tc +wowlegacy.ml +wow-life.net +woxinghuiguo.com +wozy.in +wp.com +wpoforum.com +wqlhw.com +wqyd.org +wrchina.org +wretch.cc +writer.zoho.com +wsj.com +wsj.net +wtfpeople.com +wuala.com +wuerkaixi.com +wufi.org.tw +wuguoguang.com +wujieliulan.com +wujie.net +wukangrui.net +wwitv.com +www.6v6dota.com +www.ajsands.com +www.antd.org +www.aolnews.com +www.bulbous.freeserve.co.uk +www.cmoinc.org +www.dfanning.com +www.dwheeler.com +www.eulam.com +www.exblog.jp +www.forum4hk.com +www.freetibet.org +www.getyouram.com +www.goldenmelody.com.tw +www.idlcoyote.com +www.immigration.gov.tw +www.klip.me +www.kodingen.com +www.linksalpha.com +www.loiclemeur.com +www.macrovpn.com +www.monlamit.org +www.moztw.org +www.mycould.com +www.ned.org +www.nownews.com +www.orchidbbs.com +www.owind.com +www.oxid.it +www.parkansky.com +www.powerpointninja.com +www.rnw.nl +www.somee.com +www.stackfile.com +www.supertweet.net +www.tiffanyarment.com +www.tripod.com +www.tv.com +www.twtrland.com +www.typepad.com +www.urbanoutfitters.com +www.vegorpedersen.com +www.voy.com +www.vpncup.com +www.wangruowang.org +www.wan-press.org +www.wet123.com +www.zaurus.org.uk +wzyboy.im +x1949x.com +x365x.com +xanga.com +x-art.com +xa.yimg.com +xbabe.com +xbookcn.com +xcafe.in +xcritic.com +xfm.pp.ru +xgmyd.com +xh4n.cn +xhamster.com +xiaochuncnjp.com +xiaohexie.com +xiaoma.org +xiezhua.com +xing.com +xinhuanet.org +xinmiao.com.hk +xinqimeng.over-blog.com +xinsheng.net +xinshijue.com +xinyubbs.net +xizang-zhiye.org +xjp.cc +xml-training-guide.com +xmovies.com +xmusic.fm +xnxx.com +xpdo.net +xpud.org +xskywalker.com +xtube.com +xuchao.net +xuchao.org +xuzhiyong.net +xuzhuoer.com +xvedios.com +xvideos.com +x-wall.org +xxbbx.com +x.xcity.jp +xxxx.com.au +xysblogs.org +xys.dxiong.com +xys.org +xyy69.com +xyy69.info +yahoo.cn +yahoo.com.hk +yam.com +yanghengjun.spaces.live.com +yasni.co.uk +yasukuni.or.jp +yatsen.gov.tw +ydy.com +yeelou.com +yeeyi.com +yegle.net +yezimary.spaces.live.com +yfrog.com +yhcw.net +yidio.com +yilubbs.com +yi.org +yipub.com +ym.backchina.com +yogichen.org +yong.hu +yorkbbs.ca +youdao.com +youjizz.com +youmaker.com +youpai.org +youporn.com +your-freedom.net +yousendit.com +youthbao.com +youthnetradio.org +youtu.be +youtubecn.com +youtube.com +youtube-nocookie.com +youversion.com +youxu.info +ytht.net +ytimg.com +yuanming.net +yuming.flnet.org +yunchao.net +yvesgeleyn.com +yvtc.gov.tw +yx51.net +yyii.org +yymaya.com +yzzk.com +zacebook.com +zannel.com +zaobao.com +zaobao.com.sg +zaozon.com +zarias.com +zattoo.com +zdnet.com.tw +zengjinyan.org +zengjinyan.spaces.live.com +zeutch.com +zgzcjj.net +zhanbin.net +zhao.jinhai.de +zhenghui.org +zhenlibu.info +zhinengluyou.com +zhllg.spaces.live.com +zh.m.wikipedia.org +zh.netlog.com +zhonggtuotese.net +zhongguotese.net +zhongmeng.org +zhongsou.com +zh.pokerstrategy.com +zhreader.com +zh-tw.justin.tv +zhuichaguoji.org +zh.uncyclopedia.wikia.com +zh.wikinews.org +zh.wikipedia.org +zh.wikisource.org +ziddu.com +zillionk.com +zinio.com +ziplib.com +zkaip.com +zmw.cn +zomobo.net +zonaeuropa.com +zootool.com +zoozle.net +zozotown.com +zshare.net +zsrhao.com +zuo.la +zuola.com +zvereff.com +zyzc9.com +zyzg.us diff --git a/package/lean/luci-app-shadowsocksr-pro/root/etc/shadowsocksr/gen-gfwlist.sh b/package/lean/luci-app-shadowsocksr-pro/root/etc/shadowsocksr/gen-gfwlist.sh new file mode 100755 index 000000000..050de594c --- /dev/null +++ b/package/lean/luci-app-shadowsocksr-pro/root/etc/shadowsocksr/gen-gfwlist.sh @@ -0,0 +1,29 @@ +#!/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 diff --git a/package/lean/luci-app-shadowsocksr-pro/root/etc/shadowsocksr/ssr-watchdog b/package/lean/luci-app-shadowsocksr-pro/root/etc/shadowsocksr/ssr-watchdog new file mode 100755 index 000000000..66f82b4f7 --- /dev/null +++ b/package/lean/luci-app-shadowsocksr-pro/root/etc/shadowsocksr/ssr-watchdog @@ -0,0 +1,35 @@ +#!/bin/sh + +LOGTIME=$(date "+%Y-%m-%d %H:%M:%S") +GOOGLE=$(ping -4 www.gstatic.com -c 1 -w 5| sed '1{s/[^(]*(//;s/).*//;q}') + +iptables -t nat -I OUTPUT -p tcp -d $GOOGLE -j REDIRECT --to-port 7070 + +sleep 3 + +/usr/bin/wget --spider --quiet --tries=1 --timeout=3 www.gstatic.com/generate_204 + +if [ "$?" == "0" ]; then + echo '['$LOGTIME'] ShadowsocksR No Problem.' +else + /usr/bin/wget --spider --quiet --tries=1 --timeout=3 www.baidu.com + if [ "$?" == "0" ]; then + echo '['$LOGTIME'] Problem decteted, restarting ShadowsocksR...' + /etc/init.d/ssrpro restart + else + echo '['$LOGTIME'] Network Problem. Do nothing.' + fi +fi + +sleep 3 + +iptables -t nat -D OUTPUT -p tcp -d $GOOGLE -j REDIRECT --to-port 7070 + + + + + + + + + diff --git a/package/lean/luci-app-shadowsocksr-pro/root/etc/shadowsocksr/up-gfwlist.sh b/package/lean/luci-app-shadowsocksr-pro/root/etc/shadowsocksr/up-gfwlist.sh new file mode 100755 index 000000000..98f723e21 --- /dev/null +++ b/package/lean/luci-app-shadowsocksr-pro/root/etc/shadowsocksr/up-gfwlist.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +/etc/shadowsocksr/gen-gfwlist.sh > /tmp/ol-gfw.txt + +if [ -s "/tmp/ol-gfw.txt" ];then + sort -u /etc/shadowsocksr/base-gfwlist.txt /tmp/ol-gfw.txt > /tmp/china-banned + if ( ! cmp -s /tmp/china-banned /etc/gfwlist/china-banned );then + if [ -s "/tmp/china-banned" ];then + mv /tmp/china-banned /etc/gfwlist/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 + +/etc/init.d/ssrpro.sh restart + diff --git a/package/lean/luci-app-shadowsocksr-pro/root/etc/uci-defaults/shadowsocksr b/package/lean/luci-app-shadowsocksr-pro/root/etc/uci-defaults/shadowsocksr new file mode 100755 index 000000000..86b57ce08 --- /dev/null +++ b/package/lean/luci-app-shadowsocksr-pro/root/etc/uci-defaults/shadowsocksr @@ -0,0 +1,16 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete firewall.shadowsocksr + set firewall.shadowsocksr=include + set firewall.shadowsocksr.type=script + set firewall.shadowsocksr.path=/etc/shadowsocksr.include + set firewall.shadowsocksr.reload=1 + commit firewall +EOF + +/etc/init.d/shadowsocksr stop +/etc/init.d/shadowsocksr disable + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/package/lean/luci-app-ssrserver-python/Makefile b/package/lean/luci-app-ssrserver-python/Makefile new file mode 100644 index 000000000..757d79e03 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/Makefile @@ -0,0 +1,19 @@ +# +# Copyright (C) 2008-2014 The LuCI Team +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI for SSR Server Python +LUCI_DEPENDS:=+python +LUCI_PKGARCH:=all +PKG_VERSION:=3.2.0 +PKG_RELEASE:=2 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature + + diff --git a/package/lean/luci-app-ssrserver-python/luasrc/controller/ssr_server.lua b/package/lean/luci-app-ssrserver-python/luasrc/controller/ssr_server.lua new file mode 100644 index 000000000..2c0023789 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/luasrc/controller/ssr_server.lua @@ -0,0 +1,21 @@ +module("luci.controller.ssr_server",package.seeall) + +function index() +if not nixio.fs.access("/etc/config/ssr_server")then + return +end + +entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false + +local page + +entry({"admin","vpn","ssr_server"},cbi("ssr_server"),_("SSR Python"),4).dependent=true +entry({"admin","vpn","ssr_server","status"},call("act_status")).leaf=true +end + +function act_status() + local e={} + e.server=luci.sys.call("ps | grep server.py |grep -v grep >/dev/null")==0 + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end diff --git a/package/lean/luci-app-ssrserver-python/luasrc/model/cbi/ssr_server.lua b/package/lean/luci-app-ssrserver-python/luasrc/model/cbi/ssr_server.lua new file mode 100644 index 000000000..a90d7b337 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/luasrc/model/cbi/ssr_server.lua @@ -0,0 +1,97 @@ +local a,t,e +local m, s +local o=require"nixio.fs" +local n={ +"none", +"aes-128-ctr", +"aes-192-ctr", +"aes-256-ctr", +"aes-128-cfb", +"aes-192-cfb", +"aes-256-cfb", +"rc4", +"rc4-md5", +"rc4-md5-6", +} +local s={ +"origin", +"verify_deflate", +"auth_sha1_v4", +"auth_aes128_md5", +"auth_aes128_sha1", +"auth_chain_a", +"auth_chain_b", +"auth_chain_c", +"auth_chain_d", +} +local i={ +"plain", +"http_simple", +"http_post", +"random_head", +"tls1.2_ticket_auth", +"tls1.2_ticket_fastauth", +} +local o={ +"false", +"true", +} + +local running=(luci.sys.call("ps | grep server.py |grep -v grep >/dev/null") == 0) +if running then + a= Map("ssr_server", translate("ShadowSocksR Server Config"), translate("SSR Server is running.")) +else + a = Map("ssr_server", translate("ShadowSocksR Server Config"), translate("SSR Server is not running.")) +end + +t=a:section(TypedSection,"server",translate("")) +t.anonymous=true +t.addremove=false + +e=t:option(Flag,"enable",translate("Enable")) +e.rmempty=false + +e=t:option(Value,"server_port",translate("Server Port")) +e.datatype="port" +e.rmempty=false +e.default=139 + +e=t:option(Value,"password",translate("Password")) +e.password=true +e.rmempty=false + +e=t:option(ListValue,"encrypt_method",translate("Encrypt Method")) +for a,t in ipairs(n)do e:value(t)end +e.rmempty=false + +e=t:option(ListValue,"protocol",translate("Protocol")) +for a,t in ipairs(s)do e:value(t)end +e.rmempty=false + +e=t:option(Value,"protocol_param",translate("Protocol_param")) +e.rmempty=true + +e=t:option(ListValue,"obfs",translate("Obfs")) +for a,t in ipairs(i)do e:value(t)end +e.rmempty=false + +e=t:option(Value,"obfs_param",translate("Obfs_param")) +e.rmempty=true + + + +--e=t:option(Value,"redirect",translate("redirect")) +--e.rmempty=true + +--e=t:option(Value,"timeout",translate("Connection Timeout")) +--e.datatype="uinteger" +--e.default=300 +--e.rmempty=false + +-- --------------------------------------------------- +--local apply = luci.http.formvalue("cbi.apply") +--if apply then + --os.execute("/etc/init.d/ssr_server restart >/dev/null 2>&1 &") +--end + +return a diff --git a/package/lean/luci-app-ssrserver-python/po/zh-cn/ssrserver.po b/package/lean/luci-app-ssrserver-python/po/zh-cn/ssrserver.po new file mode 100644 index 000000000..4e1e0cc50 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/po/zh-cn/ssrserver.po @@ -0,0 +1,35 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8\n" + +msgid "SSR Python" +msgstr "SSR Python 鏈嶅姟鍣" + +msgid "ShadowSocksR Server Config" +msgstr "ShadowsocksR Python 鏈嶅姟鍣ㄨ缃" + +msgid "Global Setting" +msgstr "鍏ㄥ眬璁剧疆" + +msgid "Protocol_param" +msgstr "鍗忚鍙傛暟" + +msgid "Obfs" +msgstr "娣锋穯" + +msgid "Obfs_param" +msgstr "娣锋穯鍙傛暟" + +msgid "redirect" +msgstr "閲嶅畾鍚" + +msgid "Connection Timeout" +msgstr "杩炴帴瓒呮椂鏃堕棿" + +msgid "SSR Server is running." +msgstr "ShadowsocksR 鏈嶅姟鍣ㄨ繍琛屼腑" + +msgid "SSR Server is not running." +msgstr "ShadowsocksR 鏈嶅姟鍣ㄥ凡鍋滄" + + + diff --git a/package/lean/luci-app-ssrserver-python/root/etc/config/ssr_server b/package/lean/luci-app-ssrserver-python/root/etc/config/ssr_server new file mode 100644 index 000000000..b5f8926b3 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/etc/config/ssr_server @@ -0,0 +1,12 @@ + + +config server 'ssrs' + option password '12345678' + option timeout '300' + option fast_open 'true' + option enable '0' + option encrypt_method 'rc4-md5' + option protocol 'auth_sha1_v4' + option obfs 'http_simple' + option server_port '10240' + diff --git a/package/lean/luci-app-ssrserver-python/root/etc/init.d/ssr_server b/package/lean/luci-app-ssrserver-python/root/etc/init.d/ssr_server new file mode 100755 index 000000000..7139a8bd8 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/etc/init.d/ssr_server @@ -0,0 +1,95 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (C) 2015 OpenWrt-dist +# +# This is free software, licensed under the GNU General Public License v3. +# See /LICENSE for more information. +# + +START=91 + +CONFIG=ssr_server +CONFIG_FILE=/var/etc/$CONFIG.json +PID_FILE=/var/run/$CONFIG.pid +LOG_FILE=/var/log/$CONFIG.log + +uci_get_by_type() { + local index=0 + if [ -n $4 ]; then + index=$4 + fi + local ret=$(uci get $CONFIG.@$1[$index].$2 2>/dev/null) + echo ${ret:=$3} +} + +is_true() { + case $1 in + 1|on|true|yes|enabled) echo 0;; + *) echo 1;; + esac +} + +load_config() { + ENABLED=$(uci_get_by_type server enable) + return $(is_true $ENABLED) +} + +start_server() { + mkdir -p /var/etc + /usr/bin/python \ + /usr/share/ssr/shadowsocks/server.py \ + -c $CONFIG_FILE \ + --pid-file $PID_FILE \ + --log-file $LOG_FILE \ + -d start \ + >/dev/null 2>&1 & +} + +gen_config_file() { + cat <<-EOF >$CONFIG_FILE + { + "server": "0.0.0.0", + "server_port": $(uci_get_by_type server server_port), + "local_address":"127.0.0.1", + "local_port":1086, + "password": "$(uci_get_by_type server password)", + "timeout": $(uci_get_by_type server timeout 60), + "method": "$(uci_get_by_type server encrypt_method)", + "protocol": "$(uci_get_by_type server protocol)", + "protocol_param": "$(uci_get_by_type server protocol_param)", + "obfs": "$(uci_get_by_type server obfs)", + "obfs_param": "$(uci_get_by_type server obfs_param)", + "redirect": "$(uci_get_by_type server redirect)", + "fast_open": "$(uci_get_by_type server fast_open)" + } +EOF +} + + +add_rule() { + serverport=$(uci_get_by_type server server_port) + uci set firewall.ssrs.dest_port=$serverport && uci commit firewall && /etc/init.d/firewall restart +} + +del_rule() { + serverport=$(uci_get_by_type server server_port) +} + +start() { + ! load_config && exit 0 + gen_config_file "server" + start_server + add_rule +} + +stop() { + del_rule + /usr/bin/python \ + /usr/share/ssr/shadowsocks/server.py \ + -c $CONFIG_FILE \ + --pid-file $PID_FILE \ + --log-file $LOG_FILE \ + -d stop \ + >/dev/null 2>&1 & + rm -f $LOG_FILE +} \ No newline at end of file diff --git a/package/lean/luci-app-ssrserver-python/root/etc/uci-defaults/luci-app-ssrserver b/package/lean/luci-app-ssrserver-python/root/etc/uci-defaults/luci-app-ssrserver new file mode 100755 index 000000000..d988c4c3e --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/etc/uci-defaults/luci-app-ssrserver @@ -0,0 +1,19 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@ssr_server[-1] + add ucitrack ssr_server + set ucitrack.@ssr_server[-1].init=ssr_server + commit ucitrack + delete firewall.ssrs + add firewall rule + rename firewall.@rule[-1]="ssrs" + set firewall.@rule[-1].name="ssrs" + set firewall.@rule[-1].target="ACCEPT" + set firewall.@rule[-1].src="wan" + set firewall.@rule[-1].proto="tcp" + set firewall.@rule[-1].dest_port="10240" +EOF + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/.gitignore b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/.gitignore new file mode 100644 index 000000000..529cc2587 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/.gitignore @@ -0,0 +1,36 @@ +*.py[co] + +# Packages +*.egg +*.egg-info +dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +htmlcov +.coverage* +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg + +.DS_Store +.idea + +# Ignore user config +user-config.json +userapiconfig.py +usermysql.json diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/.travis.yml b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/.travis.yml new file mode 100644 index 000000000..014fa0714 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/.travis.yml @@ -0,0 +1,21 @@ +language: python +python: + - 2.6 + - 2.7 + - 3.3 + - 3.4 +cache: + directories: + - dante-1.4.0 +before_install: + - sudo apt-get update -qq + - sudo apt-get install -qq build-essential dnsutils iproute nginx bc + - sudo dd if=/dev/urandom of=/usr/share/nginx/www/file bs=1M count=10 + - sudo sh -c "echo '127.0.0.1 localhost' > /etc/hosts" + - sudo service nginx restart + - pip install pep8 pyflakes nose coverage PySocks cymysql + - sudo tests/socksify/install.sh + - sudo tests/libsodium/install.sh + - sudo tests/setup_tc.sh +script: + - tests/jenkins.sh diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/CHANGES b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/CHANGES new file mode 100644 index 000000000..0cd91768e --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/CHANGES @@ -0,0 +1,342 @@ +3.4.0 2017-07-27 +- add auth_chain_b +- add initmudbjson.sh +- allow set speed limit in runtime +- fix bugs & mem leak + +3.3.3 2017-06-03 +- add DNS cache +- add tls1.2_ticket_fastauth +- fix bugs + +3.3.2 2017-05-20 +- revert http reply +- refine tls1.2_ticket_auth error detector + +3.3.1 2017-05-18 +- fix stop script +- Async DNS query under UDP +- fix old version of OpenSSL +- http reply + +3.3.0 2017-05-11 +- connect_log include local addr & port +- fix auth_chain_a UDP bug +- add "additional_ports_only" +- add interface legendsockssr +- run with newest python version +- parse comment in hosts +- update mujson_mgr +- add cymysql setup script +- new speed tester +- fix leaks +- bugs fixed + +3.2.0 2017-04-27 +- add auth_chain_a +- remove auth_aes128, auth_sha1, auth_sha1_v2, verify_simple, auth_simple, verify_sha1 + +3.1.2 2017-04-07 +- display UID +- auto adjust TCP MSS + +3.1.1 2017-03-25 +- add "New session ticket" +- ignore bind 10.0.0.0/8 and 192.168.0.0/16 by default +- improve rand size under auth_aes128_* +- fix bugs + +3.1.0 2017-03-16 +- add "glzjinmod" interface +- rate limit +- add additional_ports in config + +3.0.4 2017-01-08 +- multi-user in single port + +3.0.1 2017-01-03 +- remove auth_aes128_*_compatible + +3.0.0 2016-12-23 +- http_simple fix bugs +- tls1.2_ticket_auth fix bug & defaule time diff set to 86400s + +2.9.7 2016-11-22 +- manage client with LRUCache +- catch bind error +- fix import error of resource on windows +- print RLIMIT_NOFILE +- always close cymysql objects +- add init script + +2.9.6 2016-10-17 +- tls1.2_ticket_auth random packet size + +2.9.5.1 2016-10-16 +- UDP bind address + +2.9.5 2016-10-13 +- add auth_aes128_md5 and auth_aes128_sha1 + +2.9.4 2016-10-11 +- sync client version + +2.6.13 2015-11-02 +- add protocol setting + +2.6.12 2015-10-27 +- IPv6 first +- Fix mem leaks +- auth_simple plugin +- remove FORCE_NEW_PROTOCOL +- optimize code + +2.6.11 2015-10-20 +- Obfs plugin +- Obfs parameters +- UDP over TCP +- TCP over UDP (experimental) +- Fix socket leaks +- Catch abnormal UDP package + +2.6.10 2015-06-08 +- Optimize LRU cache +- Refine logging + +2.6.9 2015-05-19 +- Fix a stability issue on Windows + +2.6.8 2015-02-10 +- Support multiple server ip on client side +- Support --version +- Minor fixes + +2.6.7 2015-02-02 +- Support --user +- Support CIDR format in --forbidden-ip +- Minor fixes + +2.6.6 2015-01-23 +- Fix a crash in forbidden list + +2.6.5 2015-01-18 +- Try both 32 bit and 64 bit dll on Windows + +2.6.4 2015-01-14 +- Also search lib* when searching libraries + +2.6.3 2015-01-12 +- Support --forbidden-ip to ban some IP, i.e. localhost +- Search OpenSSL and libsodium harder +- Now works on OpenWRT + +2.6.2 2015-01-03 +- Log client IP + +2.6.1 2014-12-26 +- Fix a problem with TCP Fast Open on local side +- Fix sometimes daemon_start returns wrong exit status + +2.6 2014-12-21 +- Add daemon support + +2.5 2014-12-11 +- Add salsa20 and chacha20 + +2.4.3 2014-11-10 +- Fix an issue on Python 3 +- Fix an issue with IPv6 + +2.4.2 2014-11-06 +- Fix command line arguments on Python 3 +- Support table on Python 3 +- Fix TCP Fast Open on Python 3 + +2.4.1 2014-11-01 +- Fix setup.py for non-utf8 locales on Python 3 + +2.4 2014-11-01 +- Python 3 support +- Performance improvement +- Fix LRU cache behavior + +2.3.2 2014-10-11 +- Fix OpenSSL on Windows + +2.3.1 2014-10-09 +- Does not require M2Crypto any more + +2.3 2014-09-23 +- Support CFB1, CFB8 and CTR mode of AES +- Do not require password config when using port_password +- Use SIGTERM instead of SIGQUIT on Windows + +2.2.2 2014-09-14 +- Fix when multiple DNS set, IPv6 only sites are broken + +2.2.1 2014-09-10 +- Support graceful shutdown +- Fix some bugs + +2.2.0 2014-09-09 +- Add RC4-MD5 encryption + +2.1.0 2014-08-10 +- Use only IPv4 DNS server +- Does not ship config.json +- Better error message + +2.0.12 2014-07-26 +- Support -q quiet mode +- Exit 0 when showing help with -h + +2.0.11 2014-07-12 +- Prefers IP addresses over hostnames, more friendly with socksify and openvpn + +2.0.10 2014-07-11 +- Fix UDP on local + +2.0.9 2014-07-06 +- Fix EWOULDBLOCK on Windows +- Fix Unicode config problem on some platforms + +2.0.8 2014-06-23 +- Use multiple DNS to query hostnames + +2.0.7 2014-06-21 +- Fix fastopen on local +- Fallback when fastopen is not available +- Add verbose logging mode -vv +- Verify if hostname is valid + +2.0.6 2014-06-19 +- Fix CPU 100% on POLL_HUP +- More friendly logging + +2.0.5 2014-06-18 +- Support a simple config format for multiple ports + +2.0.4 2014-06-12 +- Fix worker master + +2.0.3 2014-06-11 +- Fix table encryption with UDP + +2.0.2 2014-06-11 +- Add asynchronous DNS in TCP relay + +2.0.1 2014-06-05 +- Better logging +- Maybe fix bad file descriptor + +2.0 2014-06-05 +- Use a new event model +- Remove gevent +- Refuse to use default password +- Fix a problem when using multiple passwords with table encryption + +1.4.5 2014-05-24 +- Add timeout in TCP server +- Close sockets in master process + +1.4.4 2014-05-17 +- Support multiple workers + +1.4.3 2014-05-13 +- Fix Windows + +1.4.2 2014-05-10 +- Add salsa20-ctr cipher + +1.4.1 2014-05-03 +- Fix error log +- Fix EINPROGESS with some version of gevent + +1.4.0 2014-05-02 +- Adds UDP relay +- TCP fast open support on Linux 3.7+ + +1.3.7 2014-04-10 +- Fix a typo in help + +1.3.6 2014-04-10 +- Fix a typo in help + +1.3.5 2014-04-07 +- Add help +- Change default local binding address into 127.0.0.1 + +1.3.4 2014-02-17 +- Fix a bug when no config file exists +- Client now support multiple server ports and multiple server/port pairs +- Better error message with bad config.json format and wrong password + +1.3.3 2013-07-09 +- Fix default key length of rc2 + +1.3.2 2013-07-04 +- Server will listen at server IP specified in config +- Check config file and show some warning messages + +1.3.1 2013-06-29 +- Fix -c arg + +1.3.0 2013-06-22 +- Move to pypi + +1.2.3 2013-06-14 +- add bind address + +1.2.2 2013-05-31 +- local can listen at ::0 with -6 arg; bump 1.2.2 + +1.2.1 2013-05-23 +- Fix an OpenSSL crash + +1.2 2013-05-22 +- Use random iv, we finally have strong encryption + +1.1.1 2013-05-21 +- Add encryption, AES, blowfish, etc. + +1.1 2013-05-16 +- Support IPv6 addresses (type 4) +- Drop Python 2.5 support + +1.0 2013-04-03 +- Fix -6 IPv6 + +0.9.4 2013-03-04 +- Support Python 2.5 + +0.9.3 2013-01-14 +- Fix conn termination null data + +0.9.2 2013-01-05 +- Change default timeout + +0.9.1 2013-01-05 +- Add Travis-CI test + +0.9 2012-12-30 +- Replace send with sendall, fix FreeBSD + +0.6 2012-12-06 +- Support args + +0.5 2012-11-08 +- Fix encryption with negative md5sum + +0.4 2012-11-02 +- Move config into a JSON file +- Auto-detect config path + +0.3 2012-06-06 +- Move socks5 negotiation to local + +0.2 2012-05-11 +- Add -6 arg for IPv6 +- Fix socket.error + +0.1 2012-04-20 +- Initial version diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/CONTRIBUTING.md b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/CONTRIBUTING.md new file mode 100644 index 000000000..fbdb9c11b --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/CONTRIBUTING.md @@ -0,0 +1,29 @@ +How to Contribute +================= + +Pull Requests +------------- + +1. Pull requests are welcome. If you would like to add a large feature +or make a significant change, make sure to open an issue to discuss with +people first. +2. Follow PEP8. +3. Make sure to pass the unit tests. Write unit tests for new modules if +needed. + +Issues +------ + +1. Only bugs and feature requests are accepted here. +2. We'll only work on important features. If the feature you're asking only +benefits a few people, you'd better implement the feature yourself and send us +a pull request, or ask some of your friends to do so. +3. We don't answer questions of any other types here. Since very few people +are watching the issue tracker here, you'll probably get no help from here. +Read [Troubleshooting] and get help from forums or [mailing lists]. +4. Issues in languages other than English will be Google translated into English +later. + + +[Troubleshooting]: https://github.com/clowwindy/shadowsocks/wiki/Troubleshooting +[mailing lists]: https://groups.google.com/forum/#!forum/shadowsocks diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/Dockerfile b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/Dockerfile new file mode 100644 index 000000000..ec7b2c6e7 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/Dockerfile @@ -0,0 +1,31 @@ +FROM alpine:3.6 + +ENV SERVER_ADDR 0.0.0.0 +ENV SERVER_PORT 51348 +ENV PASSWORD psw +ENV METHOD aes-128-ctr +ENV PROTOCOL auth_aes128_md5 +ENV PROTOCOLPARAM 32 +ENV OBFS tls1.2_ticket_auth_compatible +ENV TIMEOUT 300 +ENV DNS_ADDR 8.8.8.8 +ENV DNS_ADDR_2 8.8.4.4 + +ARG BRANCH=manyuser +ARG WORK=~ + + +RUN apk --no-cache add python \ + libsodium \ + wget + + +RUN mkdir -p $WORK && \ + wget -qO- --no-check-certificate https://github.com/shadowsocksr/shadowsocksr/archive/$BRANCH.tar.gz | tar -xzf - -C $WORK + + +WORKDIR $WORK/shadowsocksr-$BRANCH/shadowsocks + + +EXPOSE $SERVER_PORT +CMD python server.py -p $SERVER_PORT -k $PASSWORD -m $METHOD -O $PROTOCOL -o $OBFS -G $PROTOCOLPARAM diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/LICENSE b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/MANIFEST.in b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/MANIFEST.in new file mode 100644 index 000000000..1882dd7dc --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/MANIFEST.in @@ -0,0 +1,3 @@ +recursive-include shadowsocks *.py +include README.rst +include LICENSE diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/README.md b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/README.md new file mode 100644 index 000000000..53eafeaa8 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/README.md @@ -0,0 +1,105 @@ +ShadowsocksR +=========== + +[![Build Status]][Travis CI] + +A fast tunnel proxy that helps you bypass firewalls. + +Server +------ + +### Install + +Debian / Ubuntu: + + apt-get install git + git clone https://github.com/shadowsocksr/shadowsocksr.git + +CentOS: + + yum install git + git clone https://github.com/shadowsocksr/shadowsocksr.git + +Windows: + + git clone https://github.com/shadowsocksr/shadowsocksr.git + +### Usage for single user on linux platform + +If you clone it into "~/shadowsocksr" +move to "~/shadowsocksr", then run: + + bash initcfg.sh + +move to "~/shadowsocksr/shadowsocks", then run: + + python server.py -p 443 -k password -m aes-128-cfb -O auth_aes128_md5 -o tls1.2_ticket_auth_compatible + +Check all the options via `-h`. + +You can also use a configuration file instead (recommend), move to "~/shadowsocksr" and edit the file "user-config.json", then move to "~/shadowsocksr/shadowsocks" again, just run: + + python server.py + +To run in the background: + + ./logrun.sh + +To stop: + + ./stop.sh + +To monitor the log: + + ./tail.sh + + +Client +------ + +* [Windows] / [macOS] +* [Android] / [iOS] +* [OpenWRT] + +Use GUI clients on your local PC/phones. Check the README of your client +for more information. + +Documentation +------------- + +You can find all the documentation in the [Wiki]. + +License +------- + +Copyright 2015 clowwindy + +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. + +Bugs and Issues +---------------- + +* [Issue Tracker] + + + +[Android]: https://github.com/shadowsocksr/shadowsocksr-android +[Build Status]: https://travis-ci.org/shadowsocksr/shadowsocksr.svg?branch=manyuser +[Debian sid]: https://packages.debian.org/unstable/python/shadowsocks +[iOS]: https://github.com/shadowsocks/shadowsocks-iOS/wiki/Help +[Issue Tracker]: https://github.com/shadowsocksr/shadowsocksr/issues?state=open +[OpenWRT]: https://github.com/shadowsocks/openwrt-shadowsocks +[macOS]: https://github.com/shadowsocksr/ShadowsocksX-NG +[Travis CI]: https://travis-ci.org/shadowsocksr/shadowsocksr +[Windows]: https://github.com/shadowsocksr/shadowsocksr-csharp +[Wiki]: https://github.com/breakwa11/shadowsocks-rss/wiki diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/README.rst b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/README.rst new file mode 100644 index 000000000..bf2a3ec32 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/README.rst @@ -0,0 +1,113 @@ +shadowsocks +=========== + +|PyPI version| |Build Status| |Coverage Status| + +A fast tunnel proxy that helps you bypass firewalls. + +Server +------ + +Install +~~~~~~~ + +Debian / Ubuntu: + +:: + + apt-get install python-pip + pip install shadowsocks + +CentOS: + +:: + + yum install python-setuptools && easy_install pip + pip install shadowsocks + +Windows: + +See `Install Server on +Windows `__ + +Usage +~~~~~ + +:: + + ssserver -p 443 -k password -m rc4-md5 + +To run in the background: + +:: + + sudo ssserver -p 443 -k password -m rc4-md5 --user nobody -d start + +To stop: + +:: + + sudo ssserver -d stop + +To check the log: + +:: + + sudo less /var/log/shadowsocks.log + +Check all the options via ``-h``. You can also use a +`Configuration `__ +file instead. + +Client +------ + +- `Windows `__ + / `OS + X `__ +- `Android `__ + / `iOS `__ +- `OpenWRT `__ + +Use GUI clients on your local PC/phones. Check the README of your client +for more information. + +Documentation +------------- + +You can find all the documentation in the +`Wiki `__. + +License +------- + +Copyright 2015 clowwindy + +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. + +Bugs and Issues +--------------- + +- `Troubleshooting `__ +- `Issue + Tracker `__ +- `Mailing list `__ + +.. |PyPI version| image:: https://img.shields.io/pypi/v/shadowsocks.svg?style=flat + :target: https://pypi.python.org/pypi/shadowsocks +.. |Build Status| image:: https://img.shields.io/travis/shadowsocks/shadowsocks/master.svg?style=flat + :target: https://travis-ci.org/shadowsocks/shadowsocks +.. |Coverage Status| image:: https://jenkins.shadowvpn.org/result/shadowsocks + :target: https://jenkins.shadowvpn.org/job/Shadowsocks/ws/PYENV/py34/label/linux/htmlcov/index.html diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/apiconfig.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/apiconfig.py new file mode 100644 index 000000000..5ee8be127 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/apiconfig.py @@ -0,0 +1,15 @@ +锘# Config +API_INTERFACE = 'sspanelv2' #mudbjson, sspanelv2, sspanelv3, sspanelv3ssr, glzjinmod, legendsockssr, muapiv2(not support) +UPDATE_TIME = 60 +SERVER_PUB_ADDR = '127.0.0.1' # mujson_mgr need this to generate ssr link + +#mudb +MUDB_FILE = 'mudb.json' + +# Mysql +MYSQL_CONFIG = 'usermysql.json' + +# API +MUAPI_CONFIG = 'usermuapi.json' + + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/asyncmgr.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/asyncmgr.py new file mode 100644 index 000000000..9bf4d0936 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/asyncmgr.py @@ -0,0 +1,99 @@ +锘#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2014 clowwindy +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import time +import os +import socket +import struct +import re +import logging +from shadowsocks import common +from shadowsocks import lru_cache +from shadowsocks import eventloop +import server_pool +import Config + +class ServerMgr(object): + + def __init__(self): + self._loop = None + self._request_id = 1 + self._hosts = {} + self._hostname_status = {} + self._hostname_to_cb = {} + self._cb_to_hostname = {} + self._last_time = time.time() + self._sock = None + self._servers = None + + def add_to_loop(self, loop): + if self._loop: + raise Exception('already add to loop') + self._loop = loop + # TODO when dns server is IPv6 + self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, + socket.SOL_UDP) + self._sock.bind((Config.MANAGE_BIND_IP, Config.MANAGE_PORT)) + self._sock.setblocking(False) + loop.add(self._sock, eventloop.POLL_IN, self) + + def _handle_data(self, sock): + data, addr = sock.recvfrom(128) + #manage pwd:port:passwd:action + args = data.split(':') + if len(args) < 4: + return + if args[0] == Config.MANAGE_PASS: + if args[3] == '0': + server_pool.ServerPool.get_instance().cb_del_server(args[1]) + elif args[3] == '1': + server_pool.ServerPool.get_instance().new_server(args[1], args[2]) + + def handle_event(self, sock, fd, event): + if sock != self._sock: + return + if event & eventloop.POLL_ERR: + logging.error('mgr socket err') + self._loop.remove(self._sock) + self._sock.close() + # TODO when dns server is IPv6 + self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, + socket.SOL_UDP) + self._sock.setblocking(False) + self._loop.add(self._sock, eventloop.POLL_IN, self) + else: + self._handle_data(sock) + + def close(self): + if self._sock: + if self._loop: + self._loop.remove(self._sock) + self._sock.close() + self._sock = None + + +def test(): + pass + +if __name__ == '__main__': + test() diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/config.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/config.json new file mode 100644 index 000000000..55f12b5f4 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/config.json @@ -0,0 +1,25 @@ +{ + "server": "0.0.0.0", + "server_ipv6": "::", + "server_port": 8388, + "local_address": "127.0.0.1", + "local_port": 1080, + + "password": "m", + "method": "aes-128-ctr", + "protocol": "auth_aes128_md5", + "protocol_param": "", + "obfs": "tls1.2_ticket_auth_compatible", + "obfs_param": "", + "speed_limit_per_con": 0, + "speed_limit_per_user": 0, + + "additional_ports" : {}, // only works under multi-user mode + "additional_ports_only" : false, // only works under multi-user mode + "timeout": 120, + "udp_timeout": 60, + "dns_ipv6": false, + "connect_verbose_info": 0, + "redirect": "", + "fast_open": false +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/configloader.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/configloader.py new file mode 100644 index 000000000..cf9d61961 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/configloader.py @@ -0,0 +1,15 @@ +锘#!/usr/bin/python +# -*- coding: UTF-8 -*- +import importloader + +g_config = None + +def load_config(): + global g_config + g_config = importloader.loads(['userapiconfig', 'apiconfig']) + +def get_config(): + return g_config + +load_config() + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/db_transfer.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/db_transfer.py new file mode 100644 index 000000000..67bda6083 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/db_transfer.py @@ -0,0 +1,631 @@ +锘#!/usr/bin/python +# -*- coding: UTF-8 -*- + +import logging +import time +import sys +from server_pool import ServerPool +import traceback +from shadowsocks import common, shell, lru_cache, obfs +from configloader import load_config, get_config +import importloader + +switchrule = None +db_instance = None + +class TransferBase(object): + def __init__(self): + import threading + self.event = threading.Event() + self.key_list = ['port', 'u', 'd', 'transfer_enable', 'passwd', 'enable'] + self.last_get_transfer = {} #涓婁竴娆$殑瀹為檯娴侀噺 + self.last_update_transfer = {} #涓婁竴娆℃洿鏂板埌鐨勬祦閲忥紙灏忎簬绛変簬瀹為檯娴侀噺锛 + self.force_update_transfer = set() #寮哄埗鎺ㄥ叆鏁版嵁搴撶殑ID + self.port_uid_table = {} #绔彛鍒皍id鐨勬槧灏勶紙浠卾3浠ヤ笂鏈夌敤锛 + self.onlineuser_cache = lru_cache.LRUCache(timeout=60*30) #鐢ㄦ埛鍦ㄧ嚎鐘舵佽褰 + self.pull_ok = False #璁板綍鏄惁宸茬粡鎷夊嚭杩囨暟鎹 + self.mu_ports = {} + + def load_cfg(self): + pass + + def push_db_all_user(self): + if self.pull_ok is False: + return + #鏇存柊鐢ㄦ埛娴侀噺鍒版暟鎹簱 + last_transfer = self.last_update_transfer + curr_transfer = ServerPool.get_instance().get_servers_transfer() + #涓婃鍜屾湰娆$殑澧為噺 + dt_transfer = {} + for id in self.force_update_transfer: #姝よ〃涓殑鐢ㄦ埛缁熻涓婃鏈鍏ョ殑娴侀噺 + if id in self.last_get_transfer and id in last_transfer: + dt_transfer[id] = [self.last_get_transfer[id][0] - last_transfer[id][0], self.last_get_transfer[id][1] - last_transfer[id][1]] + + for id in curr_transfer.keys(): + if id in self.force_update_transfer or id in self.mu_ports: + continue + #绠楀嚭涓庝笂娆¤褰曠殑娴侀噺宸硷紝淇濆瓨浜巇t_transfer琛 + if id in last_transfer: + if curr_transfer[id][0] + curr_transfer[id][1] - last_transfer[id][0] - last_transfer[id][1] <= 0: + continue + dt_transfer[id] = [curr_transfer[id][0] - last_transfer[id][0], + curr_transfer[id][1] - last_transfer[id][1]] + else: + if curr_transfer[id][0] + curr_transfer[id][1] <= 0: + continue + dt_transfer[id] = [curr_transfer[id][0], curr_transfer[id][1]] + + #鏈夋祦閲忕殑锛屽厛璁板綍鍦ㄧ嚎鐘舵 + if id in self.last_get_transfer: + if curr_transfer[id][0] + curr_transfer[id][1] > self.last_get_transfer[id][0] + self.last_get_transfer[id][1]: + self.onlineuser_cache[id] = curr_transfer[id][0] + curr_transfer[id][1] + else: + self.onlineuser_cache[id] = curr_transfer[id][0] + curr_transfer[id][1] + + self.onlineuser_cache.sweep() + + update_transfer = self.update_all_user(dt_transfer) #杩斿洖鏈夋洿鏂扮殑琛 + for id in update_transfer.keys(): #鍏跺閲忓姞鍦ㄦ琛 + if id not in self.force_update_transfer: #浣嗘帓闄ゅ湪force_update_transfer鍐呯殑 + last = self.last_update_transfer.get(id, [0,0]) + self.last_update_transfer[id] = [last[0] + update_transfer[id][0], last[1] + update_transfer[id][1]] + self.last_get_transfer = curr_transfer + for id in self.force_update_transfer: + if id in self.last_update_transfer: + del self.last_update_transfer[id] + if id in self.last_get_transfer: + del self.last_get_transfer[id] + self.force_update_transfer = set() + + def del_server_out_of_bound_safe(self, last_rows, rows): + #鍋滄瓒呮祦閲忕殑鏈嶅姟 + #鍚姩娌¤秴娴侀噺鐨勬湇鍔 + try: + switchrule = importloader.load('switchrule') + except Exception as e: + logging.error('load switchrule.py fail') + cur_servers = {} + new_servers = {} + allow_users = {} + mu_servers = {} + config = shell.get_config(False) + for row in rows: + try: + allow = switchrule.isTurnOn(row) and row['enable'] == 1 and row['u'] + row['d'] < row['transfer_enable'] + except Exception as e: + allow = False + + port = row['port'] + passwd = common.to_bytes(row['passwd']) + if hasattr(passwd, 'encode'): + passwd = passwd.encode('utf-8') + cfg = {'password': passwd} + if 'id' in row: + self.port_uid_table[row['port']] = row['id'] + + read_config_keys = ['method', 'obfs', 'obfs_param', 'protocol', 'protocol_param', 'forbidden_ip', 'forbidden_port', 'speed_limit_per_con', 'speed_limit_per_user'] + for name in read_config_keys: + if name in row and row[name]: + cfg[name] = row[name] + + merge_config_keys = ['password'] + read_config_keys + for name in cfg.keys(): + if hasattr(cfg[name], 'encode'): + try: + cfg[name] = cfg[name].encode('utf-8') + except Exception as e: + logging.warning('encode cfg key "%s" fail, val "%s"' % (name, cfg[name])) + + if port not in cur_servers: + cur_servers[port] = passwd + else: + logging.error('more than one user use the same port [%s]' % (port,)) + continue + + if 'protocol' in cfg and 'protocol_param' in cfg and common.to_str(cfg['protocol']) in obfs.mu_protocol(): + if '#' in common.to_str(cfg['protocol_param']): + mu_servers[port] = passwd + allow = True + + if allow: + if port not in mu_servers: + allow_users[port] = cfg + + cfgchange = False + if port in ServerPool.get_instance().tcp_servers_pool: + relay = ServerPool.get_instance().tcp_servers_pool[port] + for name in merge_config_keys: + if name in cfg and not self.cmp(cfg[name], relay._config[name]): + cfgchange = True + break + if not cfgchange and port in ServerPool.get_instance().tcp_ipv6_servers_pool: + relay = ServerPool.get_instance().tcp_ipv6_servers_pool[port] + for name in merge_config_keys: + if (name in cfg) and ((name not in relay._config) or not self.cmp(cfg[name], relay._config[name])): + cfgchange = True + break + + if port in mu_servers: + if ServerPool.get_instance().server_is_run(port) > 0: + if cfgchange: + logging.info('db stop server at port [%s] reason: config changed: %s' % (port, cfg)) + ServerPool.get_instance().cb_del_server(port) + self.force_update_transfer.add(port) + new_servers[port] = (passwd, cfg) + else: + self.new_server(port, passwd, cfg) + else: + if ServerPool.get_instance().server_is_run(port) > 0: + if config['additional_ports_only'] or not allow: + logging.info('db stop server at port [%s]' % (port,)) + ServerPool.get_instance().cb_del_server(port) + self.force_update_transfer.add(port) + else: + if cfgchange: + logging.info('db stop server at port [%s] reason: config changed: %s' % (port, cfg)) + ServerPool.get_instance().cb_del_server(port) + self.force_update_transfer.add(port) + new_servers[port] = (passwd, cfg) + + elif not config['additional_ports_only'] and allow and port > 0 and port < 65536 and ServerPool.get_instance().server_run_status(port) is False: + self.new_server(port, passwd, cfg) + + for row in last_rows: + if row['port'] in cur_servers: + pass + else: + logging.info('db stop server at port [%s] reason: port not exist' % (row['port'])) + ServerPool.get_instance().cb_del_server(row['port']) + self.clear_cache(row['port']) + if row['port'] in self.port_uid_table: + del self.port_uid_table[row['port']] + + if len(new_servers) > 0: + from shadowsocks import eventloop + self.event.wait(eventloop.TIMEOUT_PRECISION + eventloop.TIMEOUT_PRECISION / 2) + for port in new_servers.keys(): + passwd, cfg = new_servers[port] + self.new_server(port, passwd, cfg) + + logging.debug('db allow users %s \nmu_servers %s' % (allow_users, mu_servers)) + for port in mu_servers: + ServerPool.get_instance().update_mu_users(port, allow_users) + + self.mu_ports = mu_servers + + def clear_cache(self, port): + if port in self.force_update_transfer: del self.force_update_transfer[port] + if port in self.last_get_transfer: del self.last_get_transfer[port] + if port in self.last_update_transfer: del self.last_update_transfer[port] + + def new_server(self, port, passwd, cfg): + protocol = cfg.get('protocol', ServerPool.get_instance().config.get('protocol', 'origin')) + method = cfg.get('method', ServerPool.get_instance().config.get('method', 'None')) + obfs = cfg.get('obfs', ServerPool.get_instance().config.get('obfs', 'plain')) + logging.info('db start server at port [%s] pass [%s] protocol [%s] method [%s] obfs [%s]' % (port, passwd, protocol, method, obfs)) + ServerPool.get_instance().new_server(port, cfg) + + def cmp(self, val1, val2): + if type(val1) is bytes: + val1 = common.to_str(val1) + if type(val2) is bytes: + val2 = common.to_str(val2) + return val1 == val2 + + @staticmethod + def del_servers(): + for port in [v for v in ServerPool.get_instance().tcp_servers_pool.keys()]: + if ServerPool.get_instance().server_is_run(port) > 0: + ServerPool.get_instance().cb_del_server(port) + for port in [v for v in ServerPool.get_instance().tcp_ipv6_servers_pool.keys()]: + if ServerPool.get_instance().server_is_run(port) > 0: + ServerPool.get_instance().cb_del_server(port) + + @staticmethod + def thread_db(obj): + import socket + import time + global db_instance + timeout = 60 + socket.setdefaulttimeout(timeout) + last_rows = [] + db_instance = obj() + ServerPool.get_instance() + shell.log_shadowsocks_version() + + try: + import resource + logging.info('current process RLIMIT_NOFILE resource: soft %d hard %d' % resource.getrlimit(resource.RLIMIT_NOFILE)) + except: + pass + + try: + while True: + load_config() + db_instance.load_cfg() + try: + db_instance.push_db_all_user() + rows = db_instance.pull_db_all_user() + if rows: + db_instance.pull_ok = True + config = shell.get_config(False) + for port in config['additional_ports']: + val = config['additional_ports'][port] + val['port'] = int(port) + val['enable'] = 1 + val['transfer_enable'] = 1024 ** 7 + val['u'] = 0 + val['d'] = 0 + if "password" in val: + val["passwd"] = val["password"] + rows.append(val) + db_instance.del_server_out_of_bound_safe(last_rows, rows) + last_rows = rows + except Exception as e: + trace = traceback.format_exc() + logging.error(trace) + #logging.warn('db thread except:%s' % e) + if db_instance.event.wait(get_config().UPDATE_TIME) or not ServerPool.get_instance().thread.is_alive(): + break + except KeyboardInterrupt as e: + pass + db_instance.del_servers() + ServerPool.get_instance().stop() + db_instance = None + + @staticmethod + def thread_db_stop(): + global db_instance + db_instance.event.set() + +class DbTransfer(TransferBase): + def __init__(self): + super(DbTransfer, self).__init__() + self.user_pass = {} #璁板綍鏇存柊姝ょ敤鎴锋祦閲忔椂琚烦杩囧灏戞 + self.cfg = { + "host": "127.0.0.1", + "port": 3306, + "user": "ss", + "password": "pass", + "db": "shadowsocks", + "node_id": 0, + "transfer_mul": 1.0, + "ssl_enable": 0, + "ssl_ca": "", + "ssl_cert": "", + "ssl_key": ""} + self.load_cfg() + + def load_cfg(self): + import json + config_path = get_config().MYSQL_CONFIG + cfg = None + with open(config_path, 'rb+') as f: + cfg = json.loads(f.read().decode('utf8')) + + if cfg: + self.cfg.update(cfg) + + def update_all_user(self, dt_transfer): + import cymysql + update_transfer = {} + + query_head = 'UPDATE user' + query_sub_when = '' + query_sub_when2 = '' + query_sub_in = None + last_time = time.time() + + for id in dt_transfer.keys(): + transfer = dt_transfer[id] + #灏忎簬鏈浣庢洿鏂版祦閲忕殑鍏堜笉鏇存柊 + update_trs = 1024 * (2048 - self.user_pass.get(id, 0) * 64) + if transfer[0] + transfer[1] < update_trs and id not in self.force_update_transfer: + self.user_pass[id] = self.user_pass.get(id, 0) + 1 + continue + if id in self.user_pass: + del self.user_pass[id] + + query_sub_when += ' WHEN %s THEN u+%s' % (id, int(transfer[0] * self.cfg["transfer_mul"])) + query_sub_when2 += ' WHEN %s THEN d+%s' % (id, int(transfer[1] * self.cfg["transfer_mul"])) + update_transfer[id] = transfer + + if query_sub_in is not None: + query_sub_in += ',%s' % id + else: + query_sub_in = '%s' % id + + if query_sub_when == '': + return update_transfer + query_sql = query_head + ' SET u = CASE port' + query_sub_when + \ + ' END, d = CASE port' + query_sub_when2 + \ + ' END, t = ' + str(int(last_time)) + \ + ' WHERE port IN (%s)' % query_sub_in + if self.cfg["ssl_enable"] == 1: + conn = cymysql.connect(host=self.cfg["host"], port=self.cfg["port"], + user=self.cfg["user"], passwd=self.cfg["password"], + db=self.cfg["db"], charset='utf8', + ssl={'ca':self.cfg["ssl_ca"],'cert':self.cfg["ssl_cert"],'key':self.cfg["ssl_key"]}) + else: + conn = cymysql.connect(host=self.cfg["host"], port=self.cfg["port"], + user=self.cfg["user"], passwd=self.cfg["password"], + db=self.cfg["db"], charset='utf8') + + try: + cur = conn.cursor() + try: + cur.execute(query_sql) + except Exception as e: + logging.error(e) + update_transfer = {} + + cur.close() + conn.commit() + except Exception as e: + logging.error(e) + update_transfer = {} + finally: + conn.close() + + return update_transfer + + def pull_db_all_user(self): + import cymysql + #鏁版嵁搴撴墍鏈夌敤鎴蜂俊鎭 + if self.cfg["ssl_enable"] == 1: + conn = cymysql.connect(host=self.cfg["host"], port=self.cfg["port"], + user=self.cfg["user"], passwd=self.cfg["password"], + db=self.cfg["db"], charset='utf8', + ssl={'ca':self.cfg["ssl_ca"],'cert':self.cfg["ssl_cert"],'key':self.cfg["ssl_key"]}) + else: + conn = cymysql.connect(host=self.cfg["host"], port=self.cfg["port"], + user=self.cfg["user"], passwd=self.cfg["password"], + db=self.cfg["db"], charset='utf8') + + try: + rows = self.pull_db_users(conn) + finally: + conn.close() + + if not rows: + logging.warn('no user in db') + return rows + + def pull_db_users(self, conn): + try: + switchrule = importloader.load('switchrule') + keys = switchrule.getKeys(self.key_list) + except Exception as e: + keys = self.key_list + + cur = conn.cursor() + cur.execute("SELECT " + ','.join(keys) + " FROM user") + rows = [] + for r in cur.fetchall(): + d = {} + for column in range(len(keys)): + d[keys[column]] = r[column] + rows.append(d) + cur.close() + return rows + +class Dbv3Transfer(DbTransfer): + def __init__(self): + super(Dbv3Transfer, self).__init__() + self.update_node_state = True if get_config().API_INTERFACE != 'legendsockssr' else False + if self.update_node_state: + self.key_list += ['id'] + self.key_list += ['method'] + if self.update_node_state: + self.ss_node_info_name = 'ss_node_info_log' + if get_config().API_INTERFACE == 'sspanelv3ssr': + self.key_list += ['obfs', 'protocol'] + if get_config().API_INTERFACE == 'glzjinmod': + self.key_list += ['obfs', 'protocol'] + self.ss_node_info_name = 'ss_node_info' + else: + self.key_list += ['obfs', 'protocol'] + self.start_time = time.time() + + def update_all_user(self, dt_transfer): + import cymysql + update_transfer = {} + + query_head = 'UPDATE user' + query_sub_when = '' + query_sub_when2 = '' + query_sub_in = None + last_time = time.time() + + alive_user_count = len(self.onlineuser_cache) + bandwidth_thistime = 0 + + if self.cfg["ssl_enable"] == 1: + conn = cymysql.connect(host=self.cfg["host"], port=self.cfg["port"], + user=self.cfg["user"], passwd=self.cfg["password"], + db=self.cfg["db"], charset='utf8', + ssl={'ca':self.cfg["ssl_ca"],'cert':self.cfg["ssl_cert"],'key':self.cfg["ssl_key"]}) + else: + conn = cymysql.connect(host=self.cfg["host"], port=self.cfg["port"], + user=self.cfg["user"], passwd=self.cfg["password"], + db=self.cfg["db"], charset='utf8') + conn.autocommit(True) + + for id in dt_transfer.keys(): + transfer = dt_transfer[id] + bandwidth_thistime = bandwidth_thistime + transfer[0] + transfer[1] + + update_trs = 1024 * (2048 - self.user_pass.get(id, 0) * 64) + if transfer[0] + transfer[1] < update_trs: + self.user_pass[id] = self.user_pass.get(id, 0) + 1 + continue + if id in self.user_pass: + del self.user_pass[id] + + query_sub_when += ' WHEN %s THEN u+%s' % (id, int(transfer[0] * self.cfg["transfer_mul"])) + query_sub_when2 += ' WHEN %s THEN d+%s' % (id, int(transfer[1] * self.cfg["transfer_mul"])) + update_transfer[id] = transfer + + if self.update_node_state: + cur = conn.cursor() + try: + if id in self.port_uid_table: + cur.execute("INSERT INTO `user_traffic_log` (`id`, `user_id`, `u`, `d`, `node_id`, `rate`, `traffic`, `log_time`) VALUES (NULL, '" + \ + str(self.port_uid_table[id]) + "', '" + str(transfer[0]) + "', '" + str(transfer[1]) + "', '" + \ + str(self.cfg["node_id"]) + "', '" + str(self.cfg["transfer_mul"]) + "', '" + \ + self.traffic_format((transfer[0] + transfer[1]) * self.cfg["transfer_mul"]) + "', unix_timestamp()); ") + except: + logging.warn('no `user_traffic_log` in db') + cur.close() + + if query_sub_in is not None: + query_sub_in += ',%s' % id + else: + query_sub_in = '%s' % id + + if query_sub_when != '': + query_sql = query_head + ' SET u = CASE port' + query_sub_when + \ + ' END, d = CASE port' + query_sub_when2 + \ + ' END, t = ' + str(int(last_time)) + \ + ' WHERE port IN (%s)' % query_sub_in + cur = conn.cursor() + try: + cur.execute(query_sql) + except Exception as e: + logging.error(e) + cur.close() + + if self.update_node_state: + try: + cur = conn.cursor() + try: + cur.execute("INSERT INTO `ss_node_online_log` (`id`, `node_id`, `online_user`, `log_time`) VALUES (NULL, '" + \ + str(self.cfg["node_id"]) + "', '" + str(alive_user_count) + "', unix_timestamp()); ") + except Exception as e: + logging.error(e) + cur.close() + + cur = conn.cursor() + try: + cur.execute("INSERT INTO `" + self.ss_node_info_name + "` (`id`, `node_id`, `uptime`, `load`, `log_time`) VALUES (NULL, '" + \ + str(self.cfg["node_id"]) + "', '" + str(self.uptime()) + "', '" + \ + str(self.load()) + "', unix_timestamp()); ") + except Exception as e: + logging.error(e) + cur.close() + except: + logging.warn('no `ss_node_online_log` or `" + self.ss_node_info_name + "` in db') + + conn.close() + return update_transfer + + def pull_db_users(self, conn): + try: + switchrule = importloader.load('switchrule') + keys = switchrule.getKeys(self.key_list) + except Exception as e: + keys = self.key_list + + cur = conn.cursor() + + if self.update_node_state: + node_info_keys = ['traffic_rate'] + try: + cur.execute("SELECT " + ','.join(node_info_keys) +" FROM ss_node where `id`='" + str(self.cfg["node_id"]) + "'") + nodeinfo = cur.fetchone() + except Exception as e: + logging.error(e) + nodeinfo = None + + if nodeinfo == None: + rows = [] + cur.close() + conn.commit() + logging.warn('None result when select node info from ss_node in db, maybe you set the incorrect node id') + return rows + cur.close() + + node_info_dict = {} + for column in range(len(nodeinfo)): + node_info_dict[node_info_keys[column]] = nodeinfo[column] + self.cfg['transfer_mul'] = float(node_info_dict['traffic_rate']) + + cur = conn.cursor() + try: + rows = [] + cur.execute("SELECT " + ','.join(keys) + " FROM user") + for r in cur.fetchall(): + d = {} + for column in range(len(keys)): + d[keys[column]] = r[column] + rows.append(d) + except Exception as e: + logging.error(e) + cur.close() + return rows + + def load(self): + import os + return os.popen("cat /proc/loadavg | awk '{ print $1\" \"$2\" \"$3 }'").readlines()[0] + + def uptime(self): + return time.time() - self.start_time + + def traffic_format(self, traffic): + if traffic < 1024 * 8: + return str(int(traffic)) + "B"; + + if traffic < 1024 * 1024 * 2: + return str(round((traffic / 1024.0), 2)) + "KB"; + + return str(round((traffic / 1048576.0), 2)) + "MB"; + +class MuJsonTransfer(TransferBase): + def __init__(self): + super(MuJsonTransfer, self).__init__() + + def update_all_user(self, dt_transfer): + import json + rows = None + + config_path = get_config().MUDB_FILE + with open(config_path, 'rb+') as f: + rows = json.loads(f.read().decode('utf8')) + for row in rows: + if "port" in row: + port = row["port"] + if port in dt_transfer: + row["u"] += dt_transfer[port][0] + row["d"] += dt_transfer[port][1] + + if rows: + output = json.dumps(rows, sort_keys=True, indent=4, separators=(',', ': ')) + with open(config_path, 'r+') as f: + f.write(output) + f.truncate() + + return dt_transfer + + def pull_db_all_user(self): + import json + rows = None + + config_path = get_config().MUDB_FILE + with open(config_path, 'rb+') as f: + rows = json.loads(f.read().decode('utf8')) + for row in rows: + try: + if 'forbidden_ip' in row: + row['forbidden_ip'] = common.IPNetwork(row['forbidden_ip']) + except Exception as e: + logging.error(e) + try: + if 'forbidden_port' in row: + row['forbidden_port'] = common.PortRange(row['forbidden_port']) + except Exception as e: + logging.error(e) + + if not rows: + logging.warn('no user in json file') + return rows + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/changelog b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/changelog new file mode 100644 index 000000000..4e7ad163f --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/changelog @@ -0,0 +1,5 @@ +shadowsocks (2.1.0-1) unstable; urgency=low + + * Initial release (Closes: #758900) + + -- Shell.Xu Sat, 23 Aug 2014 00:56:04 +0800 diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/compat b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/compat new file mode 100644 index 000000000..45a4fb75d --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/compat @@ -0,0 +1 @@ +8 diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/config.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/config.json new file mode 100644 index 000000000..35cb14a6c --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/config.json @@ -0,0 +1,11 @@ +{ + "server":"my_server_ip", + "server_port":8388, + "local_address": "127.0.0.1", + "local_port":1080, + "password":"mypassword", + "timeout":300, + "method":"aes-256-cfb", + "fast_open": false, + "workers": 1 +} \ No newline at end of file diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/control b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/control new file mode 100644 index 000000000..da0092004 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/control @@ -0,0 +1,19 @@ +Source: shadowsocks +Section: python +Priority: extra +Maintainer: Shell.Xu +Build-Depends: debhelper (>= 8), python-all (>= 2.6.6-3~), python-setuptools +Standards-Version: 3.9.5 +Homepage: https://github.com/clowwindy/shadowsocks +Vcs-Git: git://github.com/shell909090/shadowsocks.git +Vcs-Browser: http://github.com/shell909090/shadowsocks + +Package: shadowsocks +Architecture: all +Pre-Depends: dpkg (>= 1.15.6~) +Depends: ${misc:Depends}, ${python:Depends}, python-pkg-resources, python-m2crypto +Description: Fast tunnel proxy that helps you bypass firewalls + A secure socks5 proxy, designed to protect your Internet traffic. + . + This package contain local and server part of shadowsocks, a fast, + powerful tunnel proxy to bypass firewalls. \ No newline at end of file diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/copyright b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/copyright new file mode 100644 index 000000000..7be81625e --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/copyright @@ -0,0 +1,30 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: shadowsocks +Source: https://github.com/clowwindy/shadowsocks + +Files: debian/* +Copyright: 2014 Shell.Xu +License: Expat + +Files: * +Copyright: 2014 clowwindy +License: Expat + +License: Expat + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + . + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/docs b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/docs new file mode 100644 index 000000000..0208fc1fe --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/docs @@ -0,0 +1,2 @@ +README.md +README.rst diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/init.d b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/init.d new file mode 100644 index 000000000..2f4f3521e --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/init.d @@ -0,0 +1,149 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: shadowsocks +# Required-Start: $network $local_fs $remote_fs +# Required-Stop: $network $local_fs $remote_fs +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Fast tunnel proxy that helps you bypass firewalls +# Description: A secure socks5 proxy, designed to protect your Internet traffic. +# This package contain local and server part of shadowsocks, a fast, +# powerful tunnel proxy to bypass firewalls. +### END INIT INFO + +# Author: Shell.Xu + +# PATH should only include /usr/* if it runs after the mountnfs.sh script +PATH=/sbin:/usr/sbin:/bin:/usr/bin +DESC=shadowsocks # Introduce a short description here +NAME=shadowsocks # Introduce the short server's name here +DAEMON=/usr/bin/ssserver # Introduce the server's location here +DAEMON_ARGS="" # Arguments to run the daemon with +PIDFILE=/var/run/$NAME.pid +SCRIPTNAME=/etc/init.d/$NAME +LOGFILE=/var/log/$NAME.log + +# Exit if the package is not installed +[ -x $DAEMON ] || exit 0 + +# Read configuration variable file if it is present +[ -r /etc/default/$NAME ] && . /etc/default/$NAME + +# Load the VERBOSE setting and other rcS variables +. /lib/init/vars.sh + +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. +. /lib/lsb/init-functions + +# +# Function that starts the daemon/service +# +do_start() +{ + # Return + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON \ + --background --make-pidfile --chdir / --chuid $USERID --no-close --test > /dev/null \ + || return 1 + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON \ + --background --make-pidfile --chdir / --chuid $USERID --no-close -- \ + $DAEMON_ARGS $DAEMON_OPTS >> $LOGFILE 2>&1 \ + || return 2 + # Add code here, if necessary, that waits for the process to be ready + # to handle requests from services started subsequently which depend + # on this one. As a last resort, sleep for some time. +} + +# +# Function that stops the daemon/service +# +do_stop() +{ + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE + RETVAL="$?" + [ "$RETVAL" = 2 ] && return 2 + # Many daemons don't delete their pidfiles when they exit. + rm -f $PIDFILE + return "$RETVAL" +} + +# +# Function that sends a SIGHUP to the daemon/service +# +do_reload() { + # + # If the daemon can reload its configuration without + # restarting (for example, when it is sent a SIGHUP), + # then implement that here. + # + start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME + return 0 +} + +case "$1" in + start) + [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME" + do_start + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + stop) + [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" + do_stop + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + status) + status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? + ;; + #reload|force-reload) + # + # If do_reload() is not implemented then leave this commented out + # and leave 'force-reload' as an alias for 'restart'. + # + #log_daemon_msg "Reloading $DESC" "$NAME" + #do_reload + #log_end_msg $? + #;; + restart|force-reload) + # + # If the "reload" option is implemented then remove the + # 'force-reload' alias + # + log_daemon_msg "Restarting $DESC" "$NAME" + do_stop + case "$?" in + 0|1) + do_start + case "$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; # Old process is still running + *) log_end_msg 1 ;; # Failed to start + esac + ;; + *) + # Failed to stop + log_end_msg 1 + ;; + esac + ;; + *) + #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 + echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 + exit 3 + ;; +esac + +: diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/install b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/install new file mode 100644 index 000000000..a61486462 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/install @@ -0,0 +1 @@ +debian/config.json etc/shadowsocks/ \ No newline at end of file diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/rules b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/rules new file mode 100755 index 000000000..62e2bb6f6 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/rules @@ -0,0 +1,5 @@ +#!/usr/bin/make -f +# -*- makefile -*- + +%: + dh $@ --with python2 --buildsystem=python_distutils diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/shadowsocks.default b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/shadowsocks.default new file mode 100644 index 000000000..a52060279 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/shadowsocks.default @@ -0,0 +1,12 @@ +# Defaults for shadowsocks initscript +# sourced by /etc/init.d/shadowsocks +# installed at /etc/default/shadowsocks by the maintainer scripts + +USERID="nobody" + +# +# This is a POSIX shell fragment +# + +# Additional options that are passed to the Daemon. +DAEMON_OPTS="-q -c /etc/shadowsocks/config.json" diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/shadowsocks.manpages b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/shadowsocks.manpages new file mode 100644 index 000000000..3df8a3341 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/shadowsocks.manpages @@ -0,0 +1,2 @@ +debian/sslocal.1 +debian/ssserver.1 \ No newline at end of file diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/source/format b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/source/format new file mode 100644 index 000000000..163aaf8d8 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/sslocal.1 b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/sslocal.1 new file mode 100644 index 000000000..0c2cf5165 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/sslocal.1 @@ -0,0 +1,59 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" (C) Copyright 2014 Shell.Xu , +.\" +.TH SHADOWSOCKS 1 "August 23, 2014" +.SH NAME +shadowsocks \- Fast tunnel proxy that helps you bypass firewalls +.SH SYNOPSIS +.B ssserver +.RI [ options ] +.br +.B sslocal +.RI [ options ] +.SH DESCRIPTION +shadowsocks is a tunnel proxy helps you bypass firewall. +.B ssserver +is the server part, and +.B sslocal +is the local part. +.SH OPTIONS +.TP +.B \-h, \-\-help +Show this help message and exit. +.TP +.B \-s SERVER_ADDR +Server address, default: 0.0.0.0. +.TP +.B \-p SERVER_PORT +Server port, default: 8388. +.TP +.B \-k PASSWORD +Password. +.TP +.B \-m METHOD +Encryption method, default: aes-256-cfb. +.TP +.B \-t TIMEOUT +Timeout in seconds, default: 300. +.TP +.B \-c CONFIG +Path to config file. +.TP +.B \-\-fast-open +Use TCP_FASTOPEN, requires Linux 3.7+. +.TP +.B \-\-workers WORKERS +Number of workers, available on Unix/Linux. +.TP +.B \-v, \-vv +Verbose mode. +.TP +.B \-q, \-qq +Quiet mode, only show warnings/errors. +.SH SEE ALSO +.br +The programs are documented fully by +.IR "Shell Xu " +and +.IR "Clowwindy ", +available via the Info system. diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/ssserver.1 b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/ssserver.1 new file mode 100644 index 000000000..0c2cf5165 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/debian/ssserver.1 @@ -0,0 +1,59 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" (C) Copyright 2014 Shell.Xu , +.\" +.TH SHADOWSOCKS 1 "August 23, 2014" +.SH NAME +shadowsocks \- Fast tunnel proxy that helps you bypass firewalls +.SH SYNOPSIS +.B ssserver +.RI [ options ] +.br +.B sslocal +.RI [ options ] +.SH DESCRIPTION +shadowsocks is a tunnel proxy helps you bypass firewall. +.B ssserver +is the server part, and +.B sslocal +is the local part. +.SH OPTIONS +.TP +.B \-h, \-\-help +Show this help message and exit. +.TP +.B \-s SERVER_ADDR +Server address, default: 0.0.0.0. +.TP +.B \-p SERVER_PORT +Server port, default: 8388. +.TP +.B \-k PASSWORD +Password. +.TP +.B \-m METHOD +Encryption method, default: aes-256-cfb. +.TP +.B \-t TIMEOUT +Timeout in seconds, default: 300. +.TP +.B \-c CONFIG +Path to config file. +.TP +.B \-\-fast-open +Use TCP_FASTOPEN, requires Linux 3.7+. +.TP +.B \-\-workers WORKERS +Number of workers, available on Unix/Linux. +.TP +.B \-v, \-vv +Verbose mode. +.TP +.B \-q, \-qq +Quiet mode, only show warnings/errors. +.SH SEE ALSO +.br +The programs are documented fully by +.IR "Shell Xu " +and +.IR "Clowwindy ", +available via the Info system. diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/importloader.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/importloader.py new file mode 100644 index 000000000..c917cb7d9 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/importloader.py @@ -0,0 +1,24 @@ +锘#!/usr/bin/python +# -*- coding: UTF-8 -*- + +def load(name): + try: + obj = __import__(name) + reload(obj) + return obj + except: + pass + + try: + import importlib + obj = importlib.__import__(name) + importlib.reload(obj) + return obj + except: + pass + +def loads(namelist): + for name in namelist: + obj = load(name) + if obj is not None: + return obj diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/initcfg.bat b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/initcfg.bat new file mode 100644 index 000000000..6d0bce695 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/initcfg.bat @@ -0,0 +1,4 @@ +@echo off +If Not Exist "userapiconfig.py" Copy "apiconfig.py" "userapiconfig.py" +If Not Exist "user-config.json" Copy "config.json" "user-config.json" +If Not Exist "usermysql.json" Copy "mysql.json" "usermysql.json" diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/initcfg.sh b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/initcfg.sh new file mode 100755 index 000000000..862d1abed --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/initcfg.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +chmod +x *.sh +chmod +x shadowsocks/*.sh +cp -n apiconfig.py userapiconfig.py +cp -n config.json user-config.json +cp -n mysql.json usermysql.json + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/initmudbjson.sh b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/initmudbjson.sh new file mode 100755 index 000000000..09b07f332 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/initmudbjson.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +bash initcfg.sh +sed -i "s/API_INTERFACE = .\+\?\#/API_INTERFACE = \'mudbjson\' \#/g" userapiconfig.py +ip_addr=`ifconfig -a|grep inet|grep -v inet6|grep -v "127.0.0."|grep -v -e "192\.168\..[0-9]\+\.[0-9]\+"|grep -v -e "10\.[0-9]\+\.[0-9]\+\.[0-9]\+"|awk '{print $2}'|tr -d "addr:"` +ip_count=`echo $ip_addr|grep -e "^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$" -c` + +if [[ $ip_count == 1 ]]; then + ip_addr=`ip a|grep inet|grep -v inet6|grep -v "127.0.0."|grep -v -e "192\.168\..[0-9]\+\.[0-9]\+"|grep -v -e "10\.[0-9]\+\.[0-9]\+\.[0-9]\+"|awk '{print $2}'` + ip_addr=${ip_addr%/*} + ip_count=`echo $ip_addr|grep -e "^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$" -c` +fi +if [[ $ip_count == 1 ]]; then + echo "server IP is "${ip_addr} + sed -i "s/SERVER_PUB_ADDR = .\+/SERVER_PUB_ADDR = \'"${ip_addr}"\'/g" userapiconfig.py + user_count=`python mujson_mgr.py -l|grep -c -e "[0-9]"` + if [[ $user_count == 0 ]]; then + port=`python -c 'import random;print(random.randint(10000, 65536))'` + python mujson_mgr.py -a -p ${port} + fi +else + echo "unable to detect server IP" +fi + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/logrun.sh b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/logrun.sh new file mode 100755 index 000000000..94153fe9e --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/logrun.sh @@ -0,0 +1,7 @@ +#!/bin/bash +cd `dirname $0` +python_ver=$(ls /usr/bin|grep -e "^python[23]\.[1-9]\+$"|tail -1) +eval $(ps -ef | grep "[0-9] ${python_ver} server\\.py m" | awk '{print "kill "$2}') +ulimit -n 512000 +nohup ${python_ver} server.py m>> ssserver.log 2>&1 & + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/mudb.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/mudb.json new file mode 100644 index 000000000..0d4f101c7 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/mudb.json @@ -0,0 +1,2 @@ +[ +] diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/mujson_mgr.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/mujson_mgr.py new file mode 100644 index 000000000..2eb05d59d --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/mujson_mgr.py @@ -0,0 +1,358 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- + +import traceback +from shadowsocks import shell, common +from configloader import load_config, get_config +import random +import getopt +import sys +import json +import base64 + + +class MuJsonLoader(object): + def __init__(self): + self.json = None + + def load(self, path): + l = "[]" + try: + with open(path, 'rb+') as f: + l = f.read().decode('utf8') + except: + pass + self.json = json.loads(l) + + def save(self, path): + if self.json is not None: + output = json.dumps(self.json, sort_keys=True, indent=4, separators=(',', ': ')) + with open(path, 'a'): + pass + with open(path, 'rb+') as f: + f.write(output.encode('utf8')) + f.truncate() + + +class MuMgr(object): + def __init__(self): + self.config_path = get_config().MUDB_FILE + try: + self.server_addr = get_config().SERVER_PUB_ADDR + except: + self.server_addr = '127.0.0.1' + self.data = MuJsonLoader() + + if self.server_addr == '127.0.0.1': + self.server_addr = self.getipaddr() + + def getipaddr(self, ifname='eth0'): + import socket + import struct + ret = '127.0.0.1' + try: + ret = socket.gethostbyname(socket.getfqdn(socket.gethostname())) + except: + pass + if ret == '127.0.0.1': + try: + import fcntl + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + ret = socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s', ifname[:15]))[20:24]) + except: + pass + return ret + + def ssrlink(self, user, encode, muid): + protocol = user.get('protocol', '') + obfs = user.get('obfs', '') + protocol = protocol.replace("_compatible", "") + obfs = obfs.replace("_compatible", "") + protocol_param = '' + if muid is not None: + protocol_param_ = user.get('protocol_param', '') + param = protocol_param_.split('#') + if len(param) == 2: + for row in self.data.json: + if int(row['port']) == muid: + param = str(muid) + ':' + row['passwd'] + protocol_param = '/?protoparam=' + common.to_str(base64.urlsafe_b64encode(common.to_bytes(param))).replace("=", "") + break + link = ("%s:%s:%s:%s:%s:%s" % (self.server_addr, user['port'], protocol, user['method'], obfs, common.to_str(base64.urlsafe_b64encode(common.to_bytes(user['passwd']))).replace("=", ""))) + protocol_param + return "ssr://" + (encode and common.to_str(base64.urlsafe_b64encode(common.to_bytes(link))).replace("=", "") or link) + + def userinfo(self, user, muid = None): + ret = "" + key_list = ['user', 'port', 'method', 'passwd', 'protocol', 'protocol_param', 'obfs', 'obfs_param', 'transfer_enable', 'u', 'd'] + for key in sorted(user): + if key not in key_list: + key_list.append(key) + for key in key_list: + if key in ['enable'] or key not in user: + continue + ret += '\n' + if (muid is not None) and (key in ['protocol_param']): + for row in self.data.json: + if int(row['port']) == muid: + ret += " %s : %s" % (key, str(muid) + ':' + row['passwd']) + break + elif key in ['transfer_enable', 'u', 'd']: + if muid is not None: + for row in self.data.json: + if int(row['port']) == muid: + val = row[key] + break + else: + val = user[key] + if val / 1024 < 4: + ret += " %s : %s" % (key, val) + elif val / 1024 ** 2 < 4: + val /= float(1024) + ret += " %s : %s K Bytes" % (key, val) + elif val / 1024 ** 3 < 4: + val /= float(1024 ** 2) + ret += " %s : %s M Bytes" % (key, val) + else: + val /= float(1024 ** 3) + ret += " %s : %s G Bytes" % (key, val) + else: + ret += " %s : %s" % (key, user[key]) + ret += "\n " + self.ssrlink(user, False, muid) + ret += "\n " + self.ssrlink(user, True, muid) + return ret + + def rand_pass(self): + return ''.join([random.choice('''ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~-_=+(){}[]^&%$@''') for i in range(8)]) + + def add(self, user): + up = {'enable': 1, 'u': 0, 'd': 0, 'method': "aes-128-ctr", + 'protocol': "auth_aes128_md5", + 'obfs': "tls1.2_ticket_auth_compatible", + 'transfer_enable': 9007199254740992} + up['passwd'] = self.rand_pass() + up.update(user) + + self.data.load(self.config_path) + for row in self.data.json: + match = False + if 'user' in user and row['user'] == user['user']: + match = True + if 'port' in user and row['port'] == user['port']: + match = True + if match: + print("user [%s] port [%s] already exist" % (row['user'], row['port'])) + return + self.data.json.append(up) + print("### add user info %s" % self.userinfo(up)) + self.data.save(self.config_path) + + def edit(self, user): + self.data.load(self.config_path) + for row in self.data.json: + match = True + if 'user' in user and row['user'] != user['user']: + match = False + if 'port' in user and row['port'] != user['port']: + match = False + if match: + print("edit user [%s]" % (row['user'],)) + row.update(user) + print("### new user info %s" % self.userinfo(row)) + break + self.data.save(self.config_path) + + def delete(self, user): + self.data.load(self.config_path) + index = 0 + for row in self.data.json: + match = True + if 'user' in user and row['user'] != user['user']: + match = False + if 'port' in user and row['port'] != user['port']: + match = False + if match: + print("delete user [%s]" % row['user']) + del self.data.json[index] + break + index += 1 + self.data.save(self.config_path) + + def clear_ud(self, user): + up = {'u': 0, 'd': 0} + self.data.load(self.config_path) + for row in self.data.json: + match = True + if 'user' in user and row['user'] != user['user']: + match = False + if 'port' in user and row['port'] != user['port']: + match = False + if match: + row.update(up) + print("clear user [%s]" % row['user']) + self.data.save(self.config_path) + + def list_user(self, user): + self.data.load(self.config_path) + if not user: + for row in self.data.json: + print("user [%s] port %s" % (row['user'], row['port'])) + return + for row in self.data.json: + match = True + if 'user' in user and row['user'] != user['user']: + match = False + if 'port' in user and row['port'] != user['port']: + match = False + if match: + muid = None + if 'muid' in user: + muid = user['muid'] + print("### user [%s] info %s" % (row['user'], self.userinfo(row, muid))) + + +def print_server_help(): + print('''usage: python mujson_manage.py -a|-d|-e|-c|-l [OPTION]... + +Actions: + -a add/edit a user + -d delete a user + -e edit a user + -c set u&d to zero + -l display a user infomation or all users infomation + +Options: + -u USER the user name + -p PORT server port (only this option must be set if add a user) + -k PASSWORD password + -m METHOD encryption method, default: aes-128-ctr + -O PROTOCOL protocol plugin, default: auth_aes128_md5 + -o OBFS obfs plugin, default: tls1.2_ticket_auth_compatible + -G PROTOCOL_PARAM protocol plugin param + -g OBFS_PARAM obfs plugin param + -t TRANSFER max transfer for G bytes, default: 8388608 (8 PB or 8192 TB) + -f FORBID set forbidden ports. Example (ban 1~79 and 81~100): -f "1-79,81-100" + -i MUID set sub id to display (only work with -l) + -s SPEED set speed_limit_per_con + -S SPEED set speed_limit_per_user + +General options: + -h, --help show this help message and exit +''') + + +def main(): + shortopts = 'adeclu:i:p:k:O:o:G:g:m:t:f:hs:S:' + longopts = ['help'] + action = None + user = {} + fast_set_obfs = {'0': 'plain', + '+1': 'http_simple_compatible', + '1': 'http_simple', + '+2': 'tls1.2_ticket_auth_compatible', + '2': 'tls1.2_ticket_auth'} + fast_set_protocol = {'0': 'origin', + 's4': 'auth_sha1_v4', + '+s4': 'auth_sha1_v4_compatible', + 'am': 'auth_aes128_md5', + 'as': 'auth_aes128_sha1', + 'ca': 'auth_chain_a', + } + fast_set_method = {'0': 'none', + 'a1c': 'aes-128-cfb', + 'a2c': 'aes-192-cfb', + 'a3c': 'aes-256-cfb', + 'r': 'rc4-md5', + 'r6': 'rc4-md5-6', + 'c': 'chacha20', + 'ci': 'chacha20-ietf', + 's': 'salsa20', + 'a1': 'aes-128-ctr', + 'a2': 'aes-192-ctr', + 'a3': 'aes-256-ctr'} + try: + optlist, args = getopt.getopt(sys.argv[1:], shortopts, longopts) + for key, value in optlist: + if key == '-a': + action = 1 + elif key == '-d': + action = 2 + elif key == '-e': + action = 3 + elif key == '-l': + action = 4 + elif key == '-c': + action = 0 + elif key == '-u': + user['user'] = value + elif key == '-i': + user['muid'] = int(value) + elif key == '-p': + user['port'] = int(value) + elif key == '-k': + user['passwd'] = value + elif key == '-o': + if value in fast_set_obfs: + user['obfs'] = fast_set_obfs[value] + else: + user['obfs'] = value + elif key == '-O': + if value in fast_set_protocol: + user['protocol'] = fast_set_protocol[value] + else: + user['protocol'] = value + elif key == '-g': + user['obfs_param'] = value + elif key == '-G': + user['protocol_param'] = value + elif key == '-s': + user['speed_limit_per_con'] = int(value) + elif key == '-S': + user['speed_limit_per_user'] = int(value) + elif key == '-m': + if value in fast_set_method: + user['method'] = fast_set_method[value] + else: + user['method'] = value + elif key == '-f': + user['forbidden_port'] = value + elif key == '-t': + val = float(value) + try: + val = int(value) + except: + pass + user['transfer_enable'] = int(val * 1024) * (1024 ** 2) + elif key in ('-h', '--help'): + print_server_help() + sys.exit(0) + except getopt.GetoptError as e: + print(e) + sys.exit(2) + + manage = MuMgr() + if action == 0: + manage.clear_ud(user) + elif action == 1: + if 'user' not in user and 'port' in user: + user['user'] = str(user['port']) + if 'user' in user and 'port' in user: + manage.add(user) + else: + print("You have to set the port with -p") + elif action == 2: + if 'user' in user or 'port' in user: + manage.delete(user) + else: + print("You have to set the user name or port with -u/-p") + elif action == 3: + if 'user' in user or 'port' in user: + manage.edit(user) + else: + print("You have to set the user name or port with -u/-p") + elif action == 4: + manage.list_user(user) + elif action is None: + print_server_help() + +if __name__ == '__main__': + main() diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/mysql.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/mysql.json new file mode 100644 index 000000000..1849e9e81 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/mysql.json @@ -0,0 +1,13 @@ +{ + "host": "127.0.0.1", + "port": 3306, + "user": "ss", + "password": "pass", + "db": "sspanel", + "node_id": 0, + "transfer_mul": 1.0, + "ssl_enable": 0, + "ssl_ca": "", + "ssl_cert": "", + "ssl_key": "" +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/run.sh b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/run.sh new file mode 100755 index 000000000..0de8d204c --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/run.sh @@ -0,0 +1,7 @@ +#!/bin/bash +cd `dirname $0` +python_ver=$(ls /usr/bin|grep -e "^python[23]\.[1-9]\+$"|tail -1) +eval $(ps -ef | grep "[0-9] ${python_ver} server\\.py m" | awk '{print "kill "$2}') +ulimit -n 512000 +nohup ${python_ver} server.py m>> /dev/null 2>&1 & + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/server.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/server.py new file mode 100644 index 000000000..ba863b684 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/server.py @@ -0,0 +1,66 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright 2015 breakwall +# +# 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. + +import time +import sys +import threading +import os + +if __name__ == '__main__': + import inspect + os.chdir(os.path.dirname(os.path.realpath(inspect.getfile(inspect.currentframe())))) + +import server_pool +import db_transfer +from shadowsocks import shell +from configloader import load_config, get_config + +class MainThread(threading.Thread): + def __init__(self, obj): + super(MainThread, self).__init__() + self.daemon = True + self.obj = obj + + def run(self): + self.obj.thread_db(self.obj) + + def stop(self): + self.obj.thread_db_stop() + +def main(): + shell.check_python() + if False: + db_transfer.DbTransfer.thread_db() + else: + if get_config().API_INTERFACE == 'mudbjson': + thread = MainThread(db_transfer.MuJsonTransfer) + elif get_config().API_INTERFACE == 'sspanelv2': + thread = MainThread(db_transfer.DbTransfer) + else: + thread = MainThread(db_transfer.Dbv3Transfer) + thread.start() + try: + while thread.is_alive(): + thread.join(10.0) + except (KeyboardInterrupt, IOError, OSError) as e: + import traceback + traceback.print_exc() + thread.stop() + +if __name__ == '__main__': + main() + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/server_pool.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/server_pool.py new file mode 100644 index 000000000..d159817a3 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/server_pool.py @@ -0,0 +1,293 @@ +锘#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2014 clowwindy +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import os +import logging +import struct +import time +from shadowsocks import shell, eventloop, tcprelay, udprelay, asyncdns, common +import threading +import sys +import traceback +from socket import * +from configloader import load_config, get_config + +class MainThread(threading.Thread): + def __init__(self, params): + super(MainThread, self).__init__() + self.params = params + + def run(self): + ServerPool._loop(*self.params) + +class ServerPool(object): + + instance = None + + def __init__(self): + shell.check_python() + self.config = shell.get_config(False) + self.dns_resolver = asyncdns.DNSResolver() + if not self.config.get('dns_ipv6', False): + asyncdns.IPV6_CONNECTION_SUPPORT = False + + self.mgr = None #asyncmgr.ServerMgr() + + self.tcp_servers_pool = {} + self.tcp_ipv6_servers_pool = {} + self.udp_servers_pool = {} + self.udp_ipv6_servers_pool = {} + self.stat_counter = {} + + self.loop = eventloop.EventLoop() + self.thread = MainThread( (self.loop, self.dns_resolver, self.mgr) ) + self.thread.start() + + @staticmethod + def get_instance(): + if ServerPool.instance is None: + ServerPool.instance = ServerPool() + return ServerPool.instance + + def stop(self): + self.loop.stop() + + @staticmethod + def _loop(loop, dns_resolver, mgr): + try: + if mgr is not None: + mgr.add_to_loop(loop) + dns_resolver.add_to_loop(loop) + loop.run() + except (KeyboardInterrupt, IOError, OSError) as e: + logging.error(e) + traceback.print_exc() + os.exit(0) + except Exception as e: + logging.error(e) + traceback.print_exc() + + def server_is_run(self, port): + port = int(port) + ret = 0 + if port in self.tcp_servers_pool: + ret = 1 + if port in self.tcp_ipv6_servers_pool: + ret |= 2 + return ret + + def server_run_status(self, port): + if 'server' in self.config: + if port not in self.tcp_servers_pool: + return False + if 'server_ipv6' in self.config: + if port not in self.tcp_ipv6_servers_pool: + return False + return True + + def new_server(self, port, user_config): + ret = True + port = int(port) + ipv6_ok = False + + if 'server_ipv6' in self.config: + if port in self.tcp_ipv6_servers_pool: + logging.info("server already at %s:%d" % (self.config['server_ipv6'], port)) + return 'this port server is already running' + else: + a_config = self.config.copy() + a_config.update(user_config) + if len(a_config['server_ipv6']) > 2 and a_config['server_ipv6'][0] == "[" and a_config['server_ipv6'][-1] == "]": + a_config['server_ipv6'] = a_config['server_ipv6'][1:-1] + a_config['server'] = a_config['server_ipv6'] + a_config['server_port'] = port + a_config['max_connect'] = 128 + a_config['method'] = common.to_str(a_config['method']) + try: + logging.info("starting server at [%s]:%d" % (common.to_str(a_config['server']), port)) + + tcp_server = tcprelay.TCPRelay(a_config, self.dns_resolver, False, stat_counter=self.stat_counter) + tcp_server.add_to_loop(self.loop) + self.tcp_ipv6_servers_pool.update({port: tcp_server}) + + udp_server = udprelay.UDPRelay(a_config, self.dns_resolver, False, stat_counter=self.stat_counter) + udp_server.add_to_loop(self.loop) + self.udp_ipv6_servers_pool.update({port: udp_server}) + + if common.to_str(a_config['server_ipv6']) == "::": + ipv6_ok = True + except Exception as e: + logging.warn("IPV6 %s " % (e,)) + + if 'server' in self.config: + if port in self.tcp_servers_pool: + logging.info("server already at %s:%d" % (common.to_str(self.config['server']), port)) + return 'this port server is already running' + else: + a_config = self.config.copy() + a_config.update(user_config) + a_config['server_port'] = port + a_config['max_connect'] = 128 + a_config['method'] = common.to_str(a_config['method']) + try: + logging.info("starting server at %s:%d" % (common.to_str(a_config['server']), port)) + + tcp_server = tcprelay.TCPRelay(a_config, self.dns_resolver, False) + tcp_server.add_to_loop(self.loop) + self.tcp_servers_pool.update({port: tcp_server}) + + udp_server = udprelay.UDPRelay(a_config, self.dns_resolver, False) + udp_server.add_to_loop(self.loop) + self.udp_servers_pool.update({port: udp_server}) + + except Exception as e: + if not ipv6_ok: + logging.warn("IPV4 %s " % (e,)) + + return True + + def del_server(self, port): + port = int(port) + logging.info("del server at %d" % port) + try: + udpsock = socket(AF_INET, SOCK_DGRAM) + udpsock.sendto('%s:%s:0:0' % (get_config().MANAGE_PASS, port), (get_config().MANAGE_BIND_IP, get_config().MANAGE_PORT)) + udpsock.close() + except Exception as e: + logging.warn(e) + return True + + def cb_del_server(self, port): + port = int(port) + + if port not in self.tcp_servers_pool: + logging.info("stopped server at %s:%d already stop" % (self.config['server'], port)) + else: + logging.info("stopped server at %s:%d" % (self.config['server'], port)) + try: + self.tcp_servers_pool[port].close(True) + del self.tcp_servers_pool[port] + except Exception as e: + logging.warn(e) + try: + self.udp_servers_pool[port].close(True) + del self.udp_servers_pool[port] + except Exception as e: + logging.warn(e) + + if 'server_ipv6' in self.config: + if port not in self.tcp_ipv6_servers_pool: + logging.info("stopped server at [%s]:%d already stop" % (self.config['server_ipv6'], port)) + else: + logging.info("stopped server at [%s]:%d" % (self.config['server_ipv6'], port)) + try: + self.tcp_ipv6_servers_pool[port].close(True) + del self.tcp_ipv6_servers_pool[port] + except Exception as e: + logging.warn(e) + try: + self.udp_ipv6_servers_pool[port].close(True) + del self.udp_ipv6_servers_pool[port] + except Exception as e: + logging.warn(e) + + return True + + def update_mu_users(self, port, users): + port = int(port) + if port in self.tcp_servers_pool: + try: + self.tcp_servers_pool[port].update_users(users) + except Exception as e: + logging.warn(e) + try: + self.udp_servers_pool[port].update_users(users) + except Exception as e: + logging.warn(e) + if port in self.tcp_ipv6_servers_pool: + try: + self.tcp_ipv6_servers_pool[port].update_users(users) + except Exception as e: + logging.warn(e) + try: + self.udp_ipv6_servers_pool[port].update_users(users) + except Exception as e: + logging.warn(e) + + def get_server_transfer(self, port): + port = int(port) + uid = struct.pack(' 63: + return None + results.append(common.chr(l)) + results.append(label) + results.append(b'\0') + return b''.join(results) + + +def build_request(address, qtype): + request_id = os.urandom(2) + header = struct.pack('!BBHHHH', 1, 0, 1, 0, 0, 0) + addr = build_address(address) + qtype_qclass = struct.pack('!HH', qtype, QCLASS_IN) + return request_id + header + addr + qtype_qclass + + +def parse_ip(addrtype, data, length, offset): + if addrtype == QTYPE_A: + return socket.inet_ntop(socket.AF_INET, data[offset:offset + length]) + elif addrtype == QTYPE_AAAA: + return socket.inet_ntop(socket.AF_INET6, data[offset:offset + length]) + elif addrtype in [QTYPE_CNAME, QTYPE_NS]: + return parse_name(data, offset)[1] + else: + return data[offset:offset + length] + + +def parse_name(data, offset): + p = offset + labels = [] + l = common.ord(data[p]) + while l > 0: + if (l & (128 + 64)) == (128 + 64): + # pointer + pointer = struct.unpack('!H', data[p:p + 2])[0] + pointer &= 0x3FFF + r = parse_name(data, pointer) + labels.append(r[1]) + p += 2 + # pointer is the end + return p - offset, b'.'.join(labels) + else: + labels.append(data[p + 1:p + 1 + l]) + p += 1 + l + l = common.ord(data[p]) + return p - offset + 1, b'.'.join(labels) + + +# rfc1035 +# record +# 1 1 1 1 1 1 +# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | | +# / / +# / NAME / +# | | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | TYPE | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | CLASS | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | TTL | +# | | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | RDLENGTH | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--| +# / RDATA / +# / / +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +def parse_record(data, offset, question=False): + nlen, name = parse_name(data, offset) + if not question: + record_type, record_class, record_ttl, record_rdlength = struct.unpack( + '!HHiH', data[offset + nlen:offset + nlen + 10] + ) + ip = parse_ip(record_type, data, record_rdlength, offset + nlen + 10) + return nlen + 10 + record_rdlength, \ + (name, ip, record_type, record_class, record_ttl) + else: + record_type, record_class = struct.unpack( + '!HH', data[offset + nlen:offset + nlen + 4] + ) + return nlen + 4, (name, None, record_type, record_class, None, None) + + +def parse_header(data): + if len(data) >= 12: + header = struct.unpack('!HBBHHHH', data[:12]) + res_id = header[0] + res_qr = header[1] & 128 + res_tc = header[1] & 2 + res_ra = header[2] & 128 + res_rcode = header[2] & 15 + # assert res_tc == 0 + # assert res_rcode in [0, 3] + res_qdcount = header[3] + res_ancount = header[4] + res_nscount = header[5] + res_arcount = header[6] + return (res_id, res_qr, res_tc, res_ra, res_rcode, res_qdcount, + res_ancount, res_nscount, res_arcount) + return None + + +def parse_response(data): + try: + if len(data) >= 12: + header = parse_header(data) + if not header: + return None + res_id, res_qr, res_tc, res_ra, res_rcode, res_qdcount, \ + res_ancount, res_nscount, res_arcount = header + + qds = [] + ans = [] + offset = 12 + for i in range(0, res_qdcount): + l, r = parse_record(data, offset, True) + offset += l + if r: + qds.append(r) + for i in range(0, res_ancount): + l, r = parse_record(data, offset) + offset += l + if r: + ans.append(r) + for i in range(0, res_nscount): + l, r = parse_record(data, offset) + offset += l + for i in range(0, res_arcount): + l, r = parse_record(data, offset) + offset += l + response = DNSResponse() + if qds: + response.hostname = qds[0][0] + for an in qds: + response.questions.append((an[1], an[2], an[3])) + for an in ans: + response.answers.append((an[1], an[2], an[3])) + return response + except Exception as e: + shell.print_exception(e) + return None + + +def is_valid_hostname(hostname): + if len(hostname) > 255: + return False + if hostname[-1] == b'.': + hostname = hostname[:-1] + return all(VALID_HOSTNAME.match(x) for x in hostname.split(b'.')) + + +class DNSResponse(object): + def __init__(self): + self.hostname = None + self.questions = [] # each: (addr, type, class) + self.answers = [] # each: (addr, type, class) + + def __str__(self): + return '%s: %s' % (self.hostname, str(self.answers)) + + +STATUS_IPV4 = 0 +STATUS_IPV6 = 1 + + +class DNSResolver(object): + def __init__(self, black_hostname_list=None): + self._loop = None + self._hosts = {} + self._hostname_status = {} + self._hostname_to_cb = {} + self._cb_to_hostname = {} + self._cache = lru_cache.LRUCache(timeout=300) + # read black_hostname_list from config + if type(black_hostname_list) != list: + self._black_hostname_list = [] + else: + self._black_hostname_list = list(map( + (lambda t: t if type(t) == bytes else t.encode('utf8')), + black_hostname_list + )) + logging.info('black_hostname_list init as : ' + str(self._black_hostname_list)) + self._sock = None + self._servers = None + self._parse_resolv() + self._parse_hosts() + # TODO monitor hosts change and reload hosts + # TODO parse /etc/gai.conf and follow its rules + + def _parse_resolv(self): + self._servers = [] + try: + with open('dns.conf', 'rb') as f: + content = f.readlines() + for line in content: + line = line.strip() + if line: + parts = line.split(b' ', 1) + if len(parts) >= 2: + server = parts[0] + port = int(parts[1]) + else: + server = parts[0] + port = 53 + if common.is_ip(server) == socket.AF_INET: + if type(server) != str: + server = server.decode('utf8') + self._servers.append((server, port)) + except IOError: + pass + if not self._servers: + try: + with open('/etc/resolv.conf', 'rb') as f: + content = f.readlines() + for line in content: + line = line.strip() + if line: + if line.startswith(b'nameserver'): + parts = line.split() + if len(parts) >= 2: + server = parts[1] + if common.is_ip(server) == socket.AF_INET: + if type(server) != str: + server = server.decode('utf8') + self._servers.append((server, 53)) + except IOError: + pass + if not self._servers: + self._servers = [('8.8.4.4', 53), ('8.8.8.8', 53)] + logging.info('dns server: %s' % (self._servers,)) + + def _parse_hosts(self): + etc_path = '/etc/hosts' + if 'WINDIR' in os.environ: + etc_path = os.environ['WINDIR'] + '/system32/drivers/etc/hosts' + try: + with open(etc_path, 'rb') as f: + for line in f.readlines(): + line = line.strip() + if b"#" in line: + line = line[:line.find(b'#')] + parts = line.split() + if len(parts) >= 2: + ip = parts[0] + if common.is_ip(ip): + for i in range(1, len(parts)): + hostname = parts[i] + if hostname: + self._hosts[hostname] = ip + except IOError: + self._hosts['localhost'] = '127.0.0.1' + + def add_to_loop(self, loop): + if self._loop: + raise Exception('already add to loop') + self._loop = loop + # TODO when dns server is IPv6 + self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, + socket.SOL_UDP) + self._sock.setblocking(False) + loop.add(self._sock, eventloop.POLL_IN, self) + loop.add_periodic(self.handle_periodic) + + def _call_callback(self, hostname, ip, error=None): + callbacks = self._hostname_to_cb.get(hostname, []) + for callback in callbacks: + if callback in self._cb_to_hostname: + del self._cb_to_hostname[callback] + if ip or error: + callback((hostname, ip), error) + else: + callback((hostname, None), + Exception('unable to parse hostname %s' % hostname)) + if hostname in self._hostname_to_cb: + del self._hostname_to_cb[hostname] + if hostname in self._hostname_status: + del self._hostname_status[hostname] + + def _handle_data(self, data): + response = parse_response(data) + if response and response.hostname: + hostname = response.hostname + ip = None + for answer in response.answers: + if answer[1] in (QTYPE_A, QTYPE_AAAA) and \ + answer[2] == QCLASS_IN: + ip = answer[0] + break + if IPV6_CONNECTION_SUPPORT: + if not ip and self._hostname_status.get(hostname, STATUS_IPV4) \ + == STATUS_IPV6: + self._hostname_status[hostname] = STATUS_IPV4 + self._send_req(hostname, QTYPE_A) + else: + if ip: + self._cache[hostname] = ip + self._call_callback(hostname, ip) + elif self._hostname_status.get(hostname, None) == STATUS_IPV4: + for question in response.questions: + if question[1] == QTYPE_A: + self._call_callback(hostname, None) + break + else: + if not ip and self._hostname_status.get(hostname, STATUS_IPV6) \ + == STATUS_IPV4: + self._hostname_status[hostname] = STATUS_IPV6 + self._send_req(hostname, QTYPE_AAAA) + else: + if ip: + self._cache[hostname] = ip + self._call_callback(hostname, ip) + elif self._hostname_status.get(hostname, None) == STATUS_IPV6: + for question in response.questions: + if question[1] == QTYPE_AAAA: + self._call_callback(hostname, None) + break + + def handle_event(self, sock, fd, event): + if sock != self._sock: + return + if event & eventloop.POLL_ERR: + logging.error('dns socket err') + self._loop.remove(self._sock) + self._sock.close() + # TODO when dns server is IPv6 + self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, + socket.SOL_UDP) + self._sock.setblocking(False) + self._loop.add(self._sock, eventloop.POLL_IN, self) + else: + data, addr = sock.recvfrom(1024) + if addr not in self._servers: + logging.warn('received a packet other than our dns') + return + self._handle_data(data) + + def handle_periodic(self): + self._cache.sweep() + + def remove_callback(self, callback): + hostname = self._cb_to_hostname.get(callback) + if hostname: + del self._cb_to_hostname[callback] + arr = self._hostname_to_cb.get(hostname, None) + if arr: + arr.remove(callback) + if not arr: + del self._hostname_to_cb[hostname] + if hostname in self._hostname_status: + del self._hostname_status[hostname] + + def _send_req(self, hostname, qtype): + req = build_request(hostname, qtype) + for server in self._servers: + logging.debug('resolving %s with type %d using server %s', + hostname, qtype, server) + self._sock.sendto(req, server) + + def resolve(self, hostname, callback): + if type(hostname) != bytes: + hostname = hostname.encode('utf8') + if not hostname: + callback(None, Exception('empty hostname')) + elif common.is_ip(hostname): + callback((hostname, hostname), None) + elif hostname in self._hosts: + logging.debug('hit hosts: %s', hostname) + ip = self._hosts[hostname] + callback((hostname, ip), None) + elif hostname in self._cache: + logging.debug('hit cache: %s ==>> %s', hostname, self._cache[hostname]) + ip = self._cache[hostname] + callback((hostname, ip), None) + elif any(hostname.endswith(t) for t in self._black_hostname_list): + callback(None, Exception('hostname <%s> is block by the black hostname list' % hostname)) + return + else: + if not is_valid_hostname(hostname): + callback(None, Exception('invalid hostname: %s' % hostname)) + return + if False: + addrs = socket.getaddrinfo(hostname, 0, 0, + socket.SOCK_DGRAM, socket.SOL_UDP) + if addrs: + af, socktype, proto, canonname, sa = addrs[0] + logging.debug('DNS resolve %s %s' % (hostname, sa[0])) + self._cache[hostname] = sa[0] + callback((hostname, sa[0]), None) + return + arr = self._hostname_to_cb.get(hostname, None) + if not arr: + if IPV6_CONNECTION_SUPPORT: + self._hostname_status[hostname] = STATUS_IPV6 + self._send_req(hostname, QTYPE_AAAA) + else: + self._hostname_status[hostname] = STATUS_IPV4 + self._send_req(hostname, QTYPE_A) + self._hostname_to_cb[hostname] = [callback] + self._cb_to_hostname[callback] = hostname + else: + arr.append(callback) + # TODO send again only if waited too long + if IPV6_CONNECTION_SUPPORT: + self._send_req(hostname, QTYPE_AAAA) + else: + self._send_req(hostname, QTYPE_A) + + def close(self): + if self._sock: + if self._loop: + self._loop.remove_periodic(self.handle_periodic) + self._loop.remove(self._sock) + self._sock.close() + self._sock = None + + +def test(): + black_hostname_list = [ + 'baidu.com', + 'yahoo.com', + ] + dns_resolver = DNSResolver(black_hostname_list=black_hostname_list) + loop = eventloop.EventLoop() + dns_resolver.add_to_loop(loop) + + global counter + counter = 0 + + def make_callback(): + global counter + + def callback(result, error): + global counter + # TODO: what can we assert? + print(result, error) + counter += 1 + if counter == 12: + dns_resolver.close() + loop.stop() + + a_callback = callback + return a_callback + + assert (make_callback() != make_callback()) + + dns_resolver.resolve(b'google.com', make_callback()) + dns_resolver.resolve('google.com', make_callback()) + dns_resolver.resolve('baidu.com', make_callback()) + dns_resolver.resolve('map.baidu.com', make_callback()) + dns_resolver.resolve('yahoo.com', make_callback()) + dns_resolver.resolve('example.com', make_callback()) + dns_resolver.resolve('ipv6.google.com', make_callback()) + dns_resolver.resolve('www.facebook.com', make_callback()) + dns_resolver.resolve('ns2.google.com', make_callback()) + dns_resolver.resolve('invalid.@!#$%^&$@.hostname', make_callback()) + dns_resolver.resolve('toooooooooooooooooooooooooooooooooooooooooooooooooo' + 'ooooooooooooooooooooooooooooooooooooooooooooooooooo' + 'long.hostname', make_callback()) + dns_resolver.resolve('toooooooooooooooooooooooooooooooooooooooooooooooooo' + 'ooooooooooooooooooooooooooooooooooooooooooooooooooo' + 'ooooooooooooooooooooooooooooooooooooooooooooooooooo' + 'ooooooooooooooooooooooooooooooooooooooooooooooooooo' + 'ooooooooooooooooooooooooooooooooooooooooooooooooooo' + 'ooooooooooooooooooooooooooooooooooooooooooooooooooo' + 'long.hostname', make_callback()) + loop.run() + # test black_hostname_list + dns_resolver = DNSResolver(black_hostname_list=[]) + assert type(dns_resolver._black_hostname_list) == list + assert len(dns_resolver._black_hostname_list) == 0 + dns_resolver.close() + dns_resolver = DNSResolver(black_hostname_list=123) + assert type(dns_resolver._black_hostname_list) == list + assert len(dns_resolver._black_hostname_list) == 0 + dns_resolver.close() + dns_resolver = DNSResolver(black_hostname_list=None) + assert type(dns_resolver._black_hostname_list) == list + assert len(dns_resolver._black_hostname_list) == 0 + dns_resolver.close() + dns_resolver = DNSResolver() + assert type(dns_resolver._black_hostname_list) == list + assert dns_resolver._black_hostname_list.__len__() == 0 + dns_resolver.close() + + +if __name__ == '__main__': + test() diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/common.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/common.py new file mode 100644 index 000000000..c4484c046 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/common.py @@ -0,0 +1,418 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright 2013-2015 clowwindy +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import socket +import struct +import logging +import binascii +import re + +from shadowsocks import lru_cache + +def compat_ord(s): + if type(s) == int: + return s + return _ord(s) + + +def compat_chr(d): + if bytes == str: + return _chr(d) + return bytes([d]) + + +_ord = ord +_chr = chr +ord = compat_ord +chr = compat_chr + +connect_log = logging.debug + +def to_bytes(s): + if bytes != str: + if type(s) == str: + return s.encode('utf-8') + return s + + +def to_str(s): + if bytes != str: + if type(s) == bytes: + return s.decode('utf-8') + return s + +def int32(x): + if x > 0xFFFFFFFF or x < 0: + x &= 0xFFFFFFFF + if x > 0x7FFFFFFF: + x = int(0x100000000 - x) + if x < 0x80000000: + return -x + else: + return -2147483648 + return x + +def inet_ntop(family, ipstr): + if family == socket.AF_INET: + return to_bytes(socket.inet_ntoa(ipstr)) + elif family == socket.AF_INET6: + import re + v6addr = ':'.join(('%02X%02X' % (ord(i), ord(j))).lstrip('0') + for i, j in zip(ipstr[::2], ipstr[1::2])) + v6addr = re.sub('::+', '::', v6addr, count=1) + return to_bytes(v6addr) + + +def inet_pton(family, addr): + addr = to_str(addr) + if family == socket.AF_INET: + return socket.inet_aton(addr) + elif family == socket.AF_INET6: + if '.' in addr: # a v4 addr + v4addr = addr[addr.rindex(':') + 1:] + v4addr = socket.inet_aton(v4addr) + v4addr = ['%02X' % ord(x) for x in v4addr] + v4addr.insert(2, ':') + newaddr = addr[:addr.rindex(':') + 1] + ''.join(v4addr) + return inet_pton(family, newaddr) + dbyts = [0] * 8 # 8 groups + grps = addr.split(':') + for i, v in enumerate(grps): + if v: + dbyts[i] = int(v, 16) + else: + for j, w in enumerate(grps[::-1]): + if w: + dbyts[7 - j] = int(w, 16) + else: + break + break + return b''.join((chr(i // 256) + chr(i % 256)) for i in dbyts) + else: + raise RuntimeError("What family?") + + +def is_ip(address): + for family in (socket.AF_INET, socket.AF_INET6): + try: + if type(address) != str: + address = address.decode('utf8') + inet_pton(family, address) + return family + except (TypeError, ValueError, OSError, IOError): + pass + return False + + +def match_regex(regex, text): + regex = re.compile(regex) + for item in regex.findall(text): + return True + return False + + +def patch_socket(): + if not hasattr(socket, 'inet_pton'): + socket.inet_pton = inet_pton + + if not hasattr(socket, 'inet_ntop'): + socket.inet_ntop = inet_ntop + + +patch_socket() + + +ADDRTYPE_IPV4 = 1 +ADDRTYPE_IPV6 = 4 +ADDRTYPE_HOST = 3 + + +def pack_addr(address): + address_str = to_str(address) + for family in (socket.AF_INET, socket.AF_INET6): + try: + r = socket.inet_pton(family, address_str) + if family == socket.AF_INET6: + return b'\x04' + r + else: + return b'\x01' + r + except (TypeError, ValueError, OSError, IOError): + pass + if len(address) > 255: + address = address[:255] # TODO + return b'\x03' + chr(len(address)) + address + +def pre_parse_header(data): + if not data: + return None + datatype = ord(data[0]) + if datatype == 0x80: + if len(data) <= 2: + return None + rand_data_size = ord(data[1]) + if rand_data_size + 2 >= len(data): + logging.warn('header too short, maybe wrong password or ' + 'encryption method') + return None + data = data[rand_data_size + 2:] + elif datatype == 0x81: + data = data[1:] + elif datatype == 0x82: + if len(data) <= 3: + return None + rand_data_size = struct.unpack('>H', data[1:3])[0] + if rand_data_size + 3 >= len(data): + logging.warn('header too short, maybe wrong password or ' + 'encryption method') + return None + data = data[rand_data_size + 3:] + elif datatype == 0x88 or (~datatype & 0xff) == 0x88: + if len(data) <= 7 + 7: + return None + data_size = struct.unpack('>H', data[1:3])[0] + ogn_data = data + data = data[:data_size] + crc = binascii.crc32(data) & 0xffffffff + if crc != 0xffffffff: + logging.warn('uncorrect CRC32, maybe wrong password or ' + 'encryption method') + return None + start_pos = 3 + ord(data[3]) + data = data[start_pos:-4] + if data_size < len(ogn_data): + data += ogn_data[data_size:] + return data + +def parse_header(data): + addrtype = ord(data[0]) + dest_addr = None + dest_port = None + header_length = 0 + connecttype = (addrtype & 0x8) and 1 or 0 + addrtype &= ~0x8 + if addrtype == ADDRTYPE_IPV4: + if len(data) >= 7: + dest_addr = socket.inet_ntoa(data[1:5]) + dest_port = struct.unpack('>H', data[5:7])[0] + header_length = 7 + else: + logging.warn('header is too short') + elif addrtype == ADDRTYPE_HOST: + if len(data) > 2: + addrlen = ord(data[1]) + if len(data) >= 4 + addrlen: + dest_addr = data[2:2 + addrlen] + dest_port = struct.unpack('>H', data[2 + addrlen:4 + + addrlen])[0] + header_length = 4 + addrlen + else: + logging.warn('header is too short') + else: + logging.warn('header is too short') + elif addrtype == ADDRTYPE_IPV6: + if len(data) >= 19: + dest_addr = socket.inet_ntop(socket.AF_INET6, data[1:17]) + dest_port = struct.unpack('>H', data[17:19])[0] + header_length = 19 + else: + logging.warn('header is too short') + else: + logging.warn('unsupported addrtype %d, maybe wrong password or ' + 'encryption method' % addrtype) + if dest_addr is None: + return None + return connecttype, addrtype, to_bytes(dest_addr), dest_port, header_length + + +class IPNetwork(object): + ADDRLENGTH = {socket.AF_INET: 32, socket.AF_INET6: 128, False: 0} + + def __init__(self, addrs): + self.addrs_str = addrs + self._network_list_v4 = [] + self._network_list_v6 = [] + if type(addrs) == str: + addrs = addrs.split(',') + list(map(self.add_network, addrs)) + + def add_network(self, addr): + if addr is "": + return + block = addr.split('/') + addr_family = is_ip(block[0]) + addr_len = IPNetwork.ADDRLENGTH[addr_family] + if addr_family is socket.AF_INET: + ip, = struct.unpack("!I", socket.inet_aton(block[0])) + elif addr_family is socket.AF_INET6: + hi, lo = struct.unpack("!QQ", inet_pton(addr_family, block[0])) + ip = (hi << 64) | lo + else: + raise Exception("Not a valid CIDR notation: %s" % addr) + if len(block) is 1: + prefix_size = 0 + while (ip & 1) == 0 and ip is not 0: + ip >>= 1 + prefix_size += 1 + logging.warn("You did't specify CIDR routing prefix size for %s, " + "implicit treated as %s/%d" % (addr, addr, addr_len)) + elif block[1].isdigit() and int(block[1]) <= addr_len: + prefix_size = addr_len - int(block[1]) + ip >>= prefix_size + else: + raise Exception("Not a valid CIDR notation: %s" % addr) + if addr_family is socket.AF_INET: + self._network_list_v4.append((ip, prefix_size)) + else: + self._network_list_v6.append((ip, prefix_size)) + + def __contains__(self, addr): + addr_family = is_ip(addr) + if addr_family is socket.AF_INET: + ip, = struct.unpack("!I", socket.inet_aton(addr)) + return any(map(lambda n_ps: n_ps[0] == ip >> n_ps[1], + self._network_list_v4)) + elif addr_family is socket.AF_INET6: + hi, lo = struct.unpack("!QQ", inet_pton(addr_family, addr)) + ip = (hi << 64) | lo + return any(map(lambda n_ps: n_ps[0] == ip >> n_ps[1], + self._network_list_v6)) + else: + return False + + def __cmp__(self, other): + return cmp(self.addrs_str, other.addrs_str) + + def __eq__(self, other): + return self.addrs_str == other.addrs_str + + def __ne__(self, other): + return self.addrs_str != other.addrs_str + +class PortRange(object): + def __init__(self, range_str): + self.range_str = to_str(range_str) + self.range = set() + range_str = to_str(range_str).split(',') + for item in range_str: + try: + int_range = item.split('-') + if len(int_range) == 1: + if item: + self.range.add(int(item)) + elif len(int_range) == 2: + int_range[0] = int(int_range[0]) + int_range[1] = int(int_range[1]) + if int_range[0] < 0: + int_range[0] = 0 + if int_range[1] > 65535: + int_range[1] = 65535 + i = int_range[0] + while i <= int_range[1]: + self.range.add(i) + i += 1 + except Exception as e: + logging.error(e) + + def __contains__(self, val): + return val in self.range + + def __cmp__(self, other): + return cmp(self.range_str, other.range_str) + + def __eq__(self, other): + return self.range_str == other.range_str + + def __ne__(self, other): + return self.range_str != other.range_str + +class UDPAsyncDNSHandler(object): + dns_cache = lru_cache.LRUCache(timeout=1800) + def __init__(self, params): + self.params = params + self.remote_addr = None + self.call_back = None + + def resolve(self, dns_resolver, remote_addr, call_back): + if remote_addr in UDPAsyncDNSHandler.dns_cache: + if call_back: + call_back("", remote_addr, UDPAsyncDNSHandler.dns_cache[remote_addr], self.params) + else: + self.call_back = call_back + self.remote_addr = remote_addr + dns_resolver.resolve(remote_addr[0], self._handle_dns_resolved) + UDPAsyncDNSHandler.dns_cache.sweep() + + def _handle_dns_resolved(self, result, error): + if error: + logging.error("%s when resolve DNS" % (error,)) #drop + return self.call_back(error, self.remote_addr, None, self.params) + if result: + ip = result[1] + if ip: + return self.call_back("", self.remote_addr, ip, self.params) + logging.warning("can't resolve %s" % (self.remote_addr,)) + return self.call_back("fail to resolve", self.remote_addr, None, self.params) + +def test_inet_conv(): + ipv4 = b'8.8.4.4' + b = inet_pton(socket.AF_INET, ipv4) + assert inet_ntop(socket.AF_INET, b) == ipv4 + ipv6 = b'2404:6800:4005:805::1011' + b = inet_pton(socket.AF_INET6, ipv6) + assert inet_ntop(socket.AF_INET6, b) == ipv6 + + +def test_parse_header(): + assert parse_header(b'\x03\x0ewww.google.com\x00\x50') == \ + (0, b'www.google.com', 80, 18) + assert parse_header(b'\x01\x08\x08\x08\x08\x00\x35') == \ + (0, b'8.8.8.8', 53, 7) + assert parse_header((b'\x04$\x04h\x00@\x05\x08\x05\x00\x00\x00\x00\x00' + b'\x00\x10\x11\x00\x50')) == \ + (0, b'2404:6800:4005:805::1011', 80, 19) + + +def test_pack_header(): + assert pack_addr(b'8.8.8.8') == b'\x01\x08\x08\x08\x08' + assert pack_addr(b'2404:6800:4005:805::1011') == \ + b'\x04$\x04h\x00@\x05\x08\x05\x00\x00\x00\x00\x00\x00\x10\x11' + assert pack_addr(b'www.google.com') == b'\x03\x0ewww.google.com' + + +def test_ip_network(): + ip_network = IPNetwork('127.0.0.0/24,::ff:1/112,::1,192.168.1.1,192.0.2.0') + assert '127.0.0.1' in ip_network + assert '127.0.1.1' not in ip_network + assert ':ff:ffff' in ip_network + assert '::ffff:1' not in ip_network + assert '::1' in ip_network + assert '::2' not in ip_network + assert '192.168.1.1' in ip_network + assert '192.168.1.2' not in ip_network + assert '192.0.2.1' in ip_network + assert '192.0.3.1' in ip_network # 192.0.2.0 is treated as 192.0.2.0/23 + assert 'www.google.com' not in ip_network + + +if __name__ == '__main__': + test_inet_conv() + test_parse_header() + test_pack_header() + test_ip_network() diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/__init__.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/__init__.py new file mode 100644 index 000000000..401c7b726 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/__init__.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python +# +# Copyright 2015 clowwindy +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/ctypes_libsodium.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/ctypes_libsodium.py new file mode 100644 index 000000000..efecfd415 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/ctypes_libsodium.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python + +# Copyright (c) 2014 clowwindy +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import logging +from ctypes import CDLL, c_char_p, c_int, c_ulonglong, byref, \ + create_string_buffer, c_void_p + +__all__ = ['ciphers'] + +libsodium = None +loaded = False + +buf_size = 2048 + +# for salsa20 and chacha20 +BLOCK_SIZE = 64 + + +def load_libsodium(): + global loaded, libsodium, buf + + from ctypes.util import find_library + for p in ('sodium',): + libsodium_path = find_library(p) + if libsodium_path: + break + else: + raise Exception('libsodium not found') + logging.info('loading libsodium from %s', libsodium_path) + libsodium = CDLL(libsodium_path) + libsodium.sodium_init.restype = c_int + libsodium.crypto_stream_salsa20_xor_ic.restype = c_int + libsodium.crypto_stream_salsa20_xor_ic.argtypes = (c_void_p, c_char_p, + c_ulonglong, + c_char_p, c_ulonglong, + c_char_p) + libsodium.crypto_stream_chacha20_xor_ic.restype = c_int + libsodium.crypto_stream_chacha20_xor_ic.argtypes = (c_void_p, c_char_p, + c_ulonglong, + c_char_p, c_ulonglong, + c_char_p) + + libsodium.sodium_init() + + buf = create_string_buffer(buf_size) + loaded = True + + +class Salsa20Crypto(object): + def __init__(self, cipher_name, key, iv, op): + if not loaded: + load_libsodium() + self.key = key + self.iv = iv + self.key_ptr = c_char_p(key) + self.iv_ptr = c_char_p(iv) + if cipher_name == b'salsa20': + self.cipher = libsodium.crypto_stream_salsa20_xor_ic + elif cipher_name == b'chacha20': + self.cipher = libsodium.crypto_stream_chacha20_xor_ic + else: + raise Exception('Unknown cipher') + # byte counter, not block counter + self.counter = 0 + + def update(self, data): + global buf_size, buf + l = len(data) + + # we can only prepend some padding to make the encryption align to + # blocks + padding = self.counter % BLOCK_SIZE + if buf_size < padding + l: + buf_size = (padding + l) * 2 + buf = create_string_buffer(buf_size) + + if padding: + data = (b'\0' * padding) + data + self.cipher(byref(buf), c_char_p(data), padding + l, + self.iv_ptr, int(self.counter / BLOCK_SIZE), self.key_ptr) + self.counter += l + # buf is copied to a str object when we access buf.raw + # strip off the padding + return buf.raw[padding:padding + l] + + +ciphers = { + b'salsa20': (32, 8, Salsa20Crypto), + b'chacha20': (32, 8, Salsa20Crypto), +} + + +def test_salsa20(): + from shadowsocks.crypto import util + + cipher = Salsa20Crypto(b'salsa20', b'k' * 32, b'i' * 16, 1) + decipher = Salsa20Crypto(b'salsa20', b'k' * 32, b'i' * 16, 0) + + util.run_cipher(cipher, decipher) + + +def test_chacha20(): + from shadowsocks.crypto import util + + cipher = Salsa20Crypto(b'chacha20', b'k' * 32, b'i' * 16, 1) + decipher = Salsa20Crypto(b'chacha20', b'k' * 32, b'i' * 16, 0) + + util.run_cipher(cipher, decipher) + + +if __name__ == '__main__': + test_chacha20() + test_salsa20() diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/ctypes_openssl.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/ctypes_openssl.py new file mode 100644 index 000000000..0ef8ce0f8 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/ctypes_openssl.py @@ -0,0 +1,188 @@ +#!/usr/bin/env python + +# Copyright (c) 2014 clowwindy +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import logging +from ctypes import CDLL, c_char_p, c_int, c_long, byref,\ + create_string_buffer, c_void_p + +__all__ = ['ciphers'] + +libcrypto = None +loaded = False + +buf_size = 2048 + + +def load_openssl(): + global loaded, libcrypto, buf + + from ctypes.util import find_library + for p in ('crypto', 'eay32', 'libeay32'): + libcrypto_path = find_library(p) + if libcrypto_path: + break + else: + raise Exception('libcrypto(OpenSSL) not found') + logging.info('loading libcrypto from %s', libcrypto_path) + libcrypto = CDLL(libcrypto_path) + libcrypto.EVP_get_cipherbyname.restype = c_void_p + libcrypto.EVP_CIPHER_CTX_new.restype = c_void_p + + libcrypto.EVP_CipherInit_ex.argtypes = (c_void_p, c_void_p, c_char_p, + c_char_p, c_char_p, c_int) + + libcrypto.EVP_CipherUpdate.argtypes = (c_void_p, c_void_p, c_void_p, + c_char_p, c_int) + + libcrypto.EVP_CIPHER_CTX_cleanup.argtypes = (c_void_p,) + libcrypto.EVP_CIPHER_CTX_free.argtypes = (c_void_p,) + if hasattr(libcrypto, 'OpenSSL_add_all_ciphers'): + libcrypto.OpenSSL_add_all_ciphers() + + buf = create_string_buffer(buf_size) + loaded = True + + +def load_cipher(cipher_name): + func_name = b'EVP_' + cipher_name.replace(b'-', b'_') + if bytes != str: + func_name = str(func_name, 'utf-8') + cipher = getattr(libcrypto, func_name, None) + if cipher: + cipher.restype = c_void_p + return cipher() + return None + + +class CtypesCrypto(object): + def __init__(self, cipher_name, key, iv, op): + if not loaded: + load_openssl() + self._ctx = None + cipher = libcrypto.EVP_get_cipherbyname(cipher_name) + if not cipher: + cipher = load_cipher(cipher_name) + if not cipher: + raise Exception('cipher %s not found in libcrypto' % cipher_name) + key_ptr = c_char_p(key) + iv_ptr = c_char_p(iv) + self._ctx = libcrypto.EVP_CIPHER_CTX_new() + if not self._ctx: + raise Exception('can not create cipher context') + r = libcrypto.EVP_CipherInit_ex(self._ctx, cipher, None, + key_ptr, iv_ptr, c_int(op)) + if not r: + self.clean() + raise Exception('can not initialize cipher context') + + def update(self, data): + global buf_size, buf + cipher_out_len = c_long(0) + l = len(data) + if buf_size < l: + buf_size = l * 2 + buf = create_string_buffer(buf_size) + libcrypto.EVP_CipherUpdate(self._ctx, byref(buf), + byref(cipher_out_len), c_char_p(data), l) + # buf is copied to a str object when we access buf.raw + return buf.raw[:cipher_out_len.value] + + def __del__(self): + self.clean() + + def clean(self): + if self._ctx: + libcrypto.EVP_CIPHER_CTX_cleanup(self._ctx) + libcrypto.EVP_CIPHER_CTX_free(self._ctx) + + +ciphers = { + b'aes-128-cfb': (16, 16, CtypesCrypto), + b'aes-192-cfb': (24, 16, CtypesCrypto), + b'aes-256-cfb': (32, 16, CtypesCrypto), + b'aes-128-ofb': (16, 16, CtypesCrypto), + b'aes-192-ofb': (24, 16, CtypesCrypto), + b'aes-256-ofb': (32, 16, CtypesCrypto), + b'aes-128-ctr': (16, 16, CtypesCrypto), + b'aes-192-ctr': (24, 16, CtypesCrypto), + b'aes-256-ctr': (32, 16, CtypesCrypto), + b'aes-128-cfb8': (16, 16, CtypesCrypto), + b'aes-192-cfb8': (24, 16, CtypesCrypto), + b'aes-256-cfb8': (32, 16, CtypesCrypto), + b'aes-128-cfb1': (16, 16, CtypesCrypto), + b'aes-192-cfb1': (24, 16, CtypesCrypto), + b'aes-256-cfb1': (32, 16, CtypesCrypto), + b'bf-cfb': (16, 8, CtypesCrypto), + b'camellia-128-cfb': (16, 16, CtypesCrypto), + b'camellia-192-cfb': (24, 16, CtypesCrypto), + b'camellia-256-cfb': (32, 16, CtypesCrypto), + b'cast5-cfb': (16, 8, CtypesCrypto), + b'des-cfb': (8, 8, CtypesCrypto), + b'idea-cfb': (16, 8, CtypesCrypto), + b'rc2-cfb': (16, 8, CtypesCrypto), + b'rc4': (16, 0, CtypesCrypto), + b'seed-cfb': (16, 16, CtypesCrypto), +} + + +def run_method(method): + from shadowsocks.crypto import util + + cipher = CtypesCrypto(method, b'k' * 32, b'i' * 16, 1) + decipher = CtypesCrypto(method, b'k' * 32, b'i' * 16, 0) + + util.run_cipher(cipher, decipher) + + +def test_aes_128_cfb(): + run_method(b'aes-128-cfb') + + +def test_aes_256_cfb(): + run_method(b'aes-256-cfb') + + +def test_aes_128_cfb8(): + run_method(b'aes-128-cfb8') + + +def test_aes_256_ofb(): + run_method(b'aes-256-ofb') + + +def test_aes_256_ctr(): + run_method(b'aes-256-ctr') + + +def test_bf_cfb(): + run_method(b'bf-cfb') + + +def test_rc4(): + run_method(b'rc4') + + +if __name__ == '__main__': + test_aes_128_cfb() diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/openssl.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/openssl.py new file mode 100644 index 000000000..0a8ca53fb --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/openssl.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python +# +# Copyright 2015 clowwindy +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +from ctypes import c_char_p, c_int, c_long, byref,\ + create_string_buffer, c_void_p + +from shadowsocks import common +from shadowsocks.crypto import util + +__all__ = ['ciphers'] + +libcrypto = None +loaded = False + +buf_size = 2048 + + +def load_openssl(): + global loaded, libcrypto, buf + + libcrypto = util.find_library(('crypto', 'eay32'), + 'EVP_get_cipherbyname', + 'libcrypto') + if libcrypto is None: + raise Exception('libcrypto(OpenSSL) not found') + + libcrypto.EVP_get_cipherbyname.restype = c_void_p + libcrypto.EVP_CIPHER_CTX_new.restype = c_void_p + + libcrypto.EVP_CipherInit_ex.argtypes = (c_void_p, c_void_p, c_char_p, + c_char_p, c_char_p, c_int) + + libcrypto.EVP_CipherUpdate.argtypes = (c_void_p, c_void_p, c_void_p, + c_char_p, c_int) + + if hasattr(libcrypto, "EVP_CIPHER_CTX_cleanup"): + libcrypto.EVP_CIPHER_CTX_cleanup.argtypes = (c_void_p,) + else: + libcrypto.EVP_CIPHER_CTX_reset.argtypes = (c_void_p,) + libcrypto.EVP_CIPHER_CTX_free.argtypes = (c_void_p,) + + libcrypto.RAND_bytes.restype = c_int + libcrypto.RAND_bytes.argtypes = (c_void_p, c_int) + + if hasattr(libcrypto, 'OpenSSL_add_all_ciphers'): + libcrypto.OpenSSL_add_all_ciphers() + + buf = create_string_buffer(buf_size) + loaded = True + + +def load_cipher(cipher_name): + func_name = 'EVP_' + cipher_name.replace('-', '_') + cipher = getattr(libcrypto, func_name, None) + if cipher: + cipher.restype = c_void_p + return cipher() + return None + +def rand_bytes(length): + if not loaded: + load_openssl() + buf = create_string_buffer(length) + r = libcrypto.RAND_bytes(buf, length) + if r <= 0: + raise Exception('RAND_bytes return error') + return buf.raw + +class OpenSSLCrypto(object): + def __init__(self, cipher_name, key, iv, op): + self._ctx = None + if not loaded: + load_openssl() + cipher = libcrypto.EVP_get_cipherbyname(common.to_bytes(cipher_name)) + if not cipher: + cipher = load_cipher(cipher_name) + if not cipher: + raise Exception('cipher %s not found in libcrypto' % cipher_name) + key_ptr = c_char_p(key) + iv_ptr = c_char_p(iv) + self._ctx = libcrypto.EVP_CIPHER_CTX_new() + if not self._ctx: + raise Exception('can not create cipher context') + r = libcrypto.EVP_CipherInit_ex(self._ctx, cipher, None, + key_ptr, iv_ptr, c_int(op)) + if not r: + self.clean() + raise Exception('can not initialize cipher context') + + def update(self, data): + global buf_size, buf + cipher_out_len = c_long(0) + l = len(data) + if buf_size < l: + buf_size = l * 2 + buf = create_string_buffer(buf_size) + libcrypto.EVP_CipherUpdate(self._ctx, byref(buf), + byref(cipher_out_len), c_char_p(data), l) + # buf is copied to a str object when we access buf.raw + return buf.raw[:cipher_out_len.value] + + def __del__(self): + self.clean() + + def clean(self): + if self._ctx: + if hasattr(libcrypto, "EVP_CIPHER_CTX_cleanup"): + libcrypto.EVP_CIPHER_CTX_cleanup(self._ctx) + else: + libcrypto.EVP_CIPHER_CTX_reset(self._ctx) + libcrypto.EVP_CIPHER_CTX_free(self._ctx) + + +ciphers = { + 'aes-128-cbc': (16, 16, OpenSSLCrypto), + 'aes-192-cbc': (24, 16, OpenSSLCrypto), + 'aes-256-cbc': (32, 16, OpenSSLCrypto), + 'aes-128-cfb': (16, 16, OpenSSLCrypto), + 'aes-192-cfb': (24, 16, OpenSSLCrypto), + 'aes-256-cfb': (32, 16, OpenSSLCrypto), + 'aes-128-ofb': (16, 16, OpenSSLCrypto), + 'aes-192-ofb': (24, 16, OpenSSLCrypto), + 'aes-256-ofb': (32, 16, OpenSSLCrypto), + 'aes-128-ctr': (16, 16, OpenSSLCrypto), + 'aes-192-ctr': (24, 16, OpenSSLCrypto), + 'aes-256-ctr': (32, 16, OpenSSLCrypto), + 'aes-128-cfb8': (16, 16, OpenSSLCrypto), + 'aes-192-cfb8': (24, 16, OpenSSLCrypto), + 'aes-256-cfb8': (32, 16, OpenSSLCrypto), + 'aes-128-cfb1': (16, 16, OpenSSLCrypto), + 'aes-192-cfb1': (24, 16, OpenSSLCrypto), + 'aes-256-cfb1': (32, 16, OpenSSLCrypto), + 'bf-cfb': (16, 8, OpenSSLCrypto), + 'camellia-128-cfb': (16, 16, OpenSSLCrypto), + 'camellia-192-cfb': (24, 16, OpenSSLCrypto), + 'camellia-256-cfb': (32, 16, OpenSSLCrypto), + 'cast5-cfb': (16, 8, OpenSSLCrypto), + 'des-cfb': (8, 8, OpenSSLCrypto), + 'idea-cfb': (16, 8, OpenSSLCrypto), + 'rc2-cfb': (16, 8, OpenSSLCrypto), + 'rc4': (16, 0, OpenSSLCrypto), + 'seed-cfb': (16, 16, OpenSSLCrypto), +} + + +def run_method(method): + + cipher = OpenSSLCrypto(method, b'k' * 32, b'i' * 16, 1) + decipher = OpenSSLCrypto(method, b'k' * 32, b'i' * 16, 0) + + util.run_cipher(cipher, decipher) + + +def test_aes_128_cfb(): + run_method('aes-128-cfb') + + +def test_aes_256_cfb(): + run_method('aes-256-cfb') + + +def test_aes_128_cfb8(): + run_method('aes-128-cfb8') + + +def test_aes_256_ofb(): + run_method('aes-256-ofb') + + +def test_aes_256_ctr(): + run_method('aes-256-ctr') + + +def test_bf_cfb(): + run_method('bf-cfb') + + +def test_rc4(): + run_method('rc4') + + +if __name__ == '__main__': + test_aes_128_cfb() diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/rc4_md5.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/rc4_md5.py new file mode 100644 index 000000000..b0105ec29 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/rc4_md5.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# +# Copyright 2015 clowwindy +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import hashlib + +from shadowsocks.crypto import openssl + +__all__ = ['ciphers'] + + +def create_cipher(alg, key, iv, op, key_as_bytes=0, d=None, salt=None, + i=1, padding=1): + md5 = hashlib.md5() + md5.update(key) + md5.update(iv) + rc4_key = md5.digest() + return openssl.OpenSSLCrypto(b'rc4', rc4_key, b'', op) + + +ciphers = { + 'rc4-md5': (16, 16, create_cipher), + 'rc4-md5-6': (16, 6, create_cipher), +} + + +def test(): + from shadowsocks.crypto import util + + cipher = create_cipher('rc4-md5', b'k' * 32, b'i' * 16, 1) + decipher = create_cipher('rc4-md5', b'k' * 32, b'i' * 16, 0) + + util.run_cipher(cipher, decipher) + + +if __name__ == '__main__': + test() diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/sodium.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/sodium.py new file mode 100644 index 000000000..51d476bed --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/sodium.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python +# +# Copyright 2015 clowwindy +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +from ctypes import c_char_p, c_int, c_ulong, c_ulonglong, byref, \ + create_string_buffer, c_void_p + +from shadowsocks.crypto import util + +__all__ = ['ciphers'] + +libsodium = None +loaded = False + +buf_size = 2048 + +# for salsa20 and chacha20 and chacha20-ietf +BLOCK_SIZE = 64 + + +def load_libsodium(): + global loaded, libsodium, buf + + libsodium = util.find_library('sodium', 'crypto_stream_salsa20_xor_ic', + 'libsodium') + if libsodium is None: + raise Exception('libsodium not found') + + libsodium.crypto_stream_salsa20_xor_ic.restype = c_int + libsodium.crypto_stream_salsa20_xor_ic.argtypes = (c_void_p, c_char_p, + c_ulonglong, + c_char_p, c_ulonglong, + c_char_p) + libsodium.crypto_stream_chacha20_xor_ic.restype = c_int + libsodium.crypto_stream_chacha20_xor_ic.argtypes = (c_void_p, c_char_p, + c_ulonglong, + c_char_p, c_ulonglong, + c_char_p) + + try: + libsodium.crypto_stream_chacha20_ietf_xor_ic.restype = c_int + libsodium.crypto_stream_chacha20_ietf_xor_ic.argtypes = (c_void_p, c_char_p, + c_ulonglong, + c_char_p, c_ulong, + c_char_p) + except: + pass + + buf = create_string_buffer(buf_size) + loaded = True + + +class SodiumCrypto(object): + def __init__(self, cipher_name, key, iv, op): + if not loaded: + load_libsodium() + self.key = key + self.iv = iv + self.key_ptr = c_char_p(key) + self.iv_ptr = c_char_p(iv) + if cipher_name == 'salsa20': + self.cipher = libsodium.crypto_stream_salsa20_xor_ic + elif cipher_name == 'chacha20': + self.cipher = libsodium.crypto_stream_chacha20_xor_ic + elif cipher_name == 'chacha20-ietf': + self.cipher = libsodium.crypto_stream_chacha20_ietf_xor_ic + else: + raise Exception('Unknown cipher') + # byte counter, not block counter + self.counter = 0 + + def update(self, data): + global buf_size, buf + l = len(data) + + # we can only prepend some padding to make the encryption align to + # blocks + padding = self.counter % BLOCK_SIZE + if buf_size < padding + l: + buf_size = (padding + l) * 2 + buf = create_string_buffer(buf_size) + + if padding: + data = (b'\0' * padding) + data + self.cipher(byref(buf), c_char_p(data), padding + l, + self.iv_ptr, int(self.counter / BLOCK_SIZE), self.key_ptr) + self.counter += l + # buf is copied to a str object when we access buf.raw + # strip off the padding + return buf.raw[padding:padding + l] + + +ciphers = { + 'salsa20': (32, 8, SodiumCrypto), + 'chacha20': (32, 8, SodiumCrypto), + 'chacha20-ietf': (32, 12, SodiumCrypto), +} + + +def test_salsa20(): + cipher = SodiumCrypto('salsa20', b'k' * 32, b'i' * 16, 1) + decipher = SodiumCrypto('salsa20', b'k' * 32, b'i' * 16, 0) + + util.run_cipher(cipher, decipher) + + +def test_chacha20(): + + cipher = SodiumCrypto('chacha20', b'k' * 32, b'i' * 16, 1) + decipher = SodiumCrypto('chacha20', b'k' * 32, b'i' * 16, 0) + + util.run_cipher(cipher, decipher) + + +def test_chacha20_ietf(): + + cipher = SodiumCrypto('chacha20-ietf', b'k' * 32, b'i' * 16, 1) + decipher = SodiumCrypto('chacha20-ietf', b'k' * 32, b'i' * 16, 0) + + util.run_cipher(cipher, decipher) + +if __name__ == '__main__': + test_chacha20_ietf() + test_chacha20() + test_salsa20() diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/table.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/table.py new file mode 100644 index 000000000..60c2f2451 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/crypto/table.py @@ -0,0 +1,181 @@ +# !/usr/bin/env python +# +# Copyright 2015 clowwindy +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import string +import struct +import hashlib + + +__all__ = ['ciphers'] + +cached_tables = {} + +if hasattr(string, 'maketrans'): + maketrans = string.maketrans + translate = string.translate +else: + maketrans = bytes.maketrans + translate = bytes.translate + + +def get_table(key): + m = hashlib.md5() + m.update(key) + s = m.digest() + a, b = struct.unpack(' 0: + # parent waits for its child + time.sleep(5) + sys.exit(0) + + # child signals its parent to exit + ppid = os.getppid() + pid = os.getpid() + if write_pid_file(pid_file, pid) != 0: + os.kill(ppid, signal.SIGINT) + sys.exit(1) + + os.setsid() + signal.signal(signal.SIG_IGN, signal.SIGHUP) + + print('started') + os.kill(ppid, signal.SIGTERM) + + sys.stdin.close() + try: + freopen(log_file, 'a', sys.stdout) + freopen(log_file, 'a', sys.stderr) + except IOError as e: + shell.print_exception(e) + sys.exit(1) + + +def daemon_stop(pid_file): + import errno + try: + with open(pid_file) as f: + buf = f.read() + pid = common.to_str(buf) + if not buf: + logging.error('not running') + except IOError as e: + shell.print_exception(e) + if e.errno == errno.ENOENT: + # always exit 0 if we are sure daemon is not running + logging.error('not running') + return + sys.exit(1) + pid = int(pid) + if pid > 0: + try: + os.kill(pid, signal.SIGTERM) + except OSError as e: + if e.errno == errno.ESRCH: + logging.error('not running') + # always exit 0 if we are sure daemon is not running + return + shell.print_exception(e) + sys.exit(1) + else: + logging.error('pid is not positive: %d', pid) + + # sleep for maximum 10s + for i in range(0, 200): + try: + # query for the pid + os.kill(pid, 0) + except OSError as e: + if e.errno == errno.ESRCH: + break + time.sleep(0.05) + else: + logging.error('timed out when stopping pid %d', pid) + sys.exit(1) + print('stopped') + os.unlink(pid_file) + + +def set_user(username): + if username is None: + return + + import pwd + import grp + + try: + pwrec = pwd.getpwnam(username) + except KeyError: + logging.error('user not found: %s' % username) + raise + user = pwrec[0] + uid = pwrec[2] + gid = pwrec[3] + + cur_uid = os.getuid() + if uid == cur_uid: + return + if cur_uid != 0: + logging.error('can not set user as nonroot user') + # will raise later + + # inspired by supervisor + if hasattr(os, 'setgroups'): + groups = [grprec[2] for grprec in grp.getgrall() if user in grprec[3]] + groups.insert(0, gid) + os.setgroups(groups) + os.setgid(gid) + os.setuid(uid) diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/encrypt.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/encrypt.py new file mode 100644 index 000000000..44f905250 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/encrypt.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python +# +# Copyright 2012-2015 clowwindy +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import os +import sys +import hashlib +import logging + +from shadowsocks import common +from shadowsocks.crypto import rc4_md5, openssl, sodium, table + + +method_supported = {} +method_supported.update(rc4_md5.ciphers) +method_supported.update(openssl.ciphers) +method_supported.update(sodium.ciphers) +method_supported.update(table.ciphers) + + +def random_string(length): + try: + return os.urandom(length) + except NotImplementedError as e: + return openssl.rand_bytes(length) + +cached_keys = {} + + +def try_cipher(key, method=None): + Encryptor(key, method) + + +def EVP_BytesToKey(password, key_len, iv_len): + # equivalent to OpenSSL's EVP_BytesToKey() with count 1 + # so that we make the same key and iv as nodejs version + if hasattr(password, 'encode'): + password = password.encode('utf-8') + cached_key = '%s-%d-%d' % (password, key_len, iv_len) + r = cached_keys.get(cached_key, None) + if r: + return r + m = [] + i = 0 + while len(b''.join(m)) < (key_len + iv_len): + md5 = hashlib.md5() + data = password + if i > 0: + data = m[i - 1] + password + md5.update(data) + m.append(md5.digest()) + i += 1 + ms = b''.join(m) + key = ms[:key_len] + iv = ms[key_len:key_len + iv_len] + cached_keys[cached_key] = (key, iv) + return key, iv + + +class Encryptor(object): + def __init__(self, key, method, iv = None): + self.key = key + self.method = method + self.iv = None + self.iv_sent = False + self.cipher_iv = b'' + self.iv_buf = b'' + self.cipher_key = b'' + self.decipher = None + method = method.lower() + self._method_info = self.get_method_info(method) + if self._method_info: + if iv is None or len(iv) != self._method_info[1]: + self.cipher = self.get_cipher(key, method, 1, + random_string(self._method_info[1])) + else: + self.cipher = self.get_cipher(key, method, 1, iv) + else: + logging.error('method %s not supported' % method) + sys.exit(1) + + def get_method_info(self, method): + method = method.lower() + m = method_supported.get(method) + return m + + def iv_len(self): + return len(self.cipher_iv) + + def get_cipher(self, password, method, op, iv): + password = common.to_bytes(password) + m = self._method_info + if m[0] > 0: + key, iv_ = EVP_BytesToKey(password, m[0], m[1]) + else: + # key_length == 0 indicates we should use the key directly + key, iv = password, b'' + + iv = iv[:m[1]] + if op == 1: + # this iv is for cipher not decipher + self.cipher_iv = iv[:m[1]] + self.cipher_key = key + return m[2](method, key, iv, op) + + def encrypt(self, buf): + if len(buf) == 0: + return buf + if self.iv_sent: + return self.cipher.update(buf) + else: + self.iv_sent = True + return self.cipher_iv + self.cipher.update(buf) + + def decrypt(self, buf): + if len(buf) == 0: + return buf + if self.decipher is not None: #optimize + return self.decipher.update(buf) + + decipher_iv_len = self._method_info[1] + if len(self.iv_buf) <= decipher_iv_len: + self.iv_buf += buf + if len(self.iv_buf) > decipher_iv_len: + decipher_iv = self.iv_buf[:decipher_iv_len] + self.decipher = self.get_cipher(self.key, self.method, 0, + iv=decipher_iv) + buf = self.iv_buf[decipher_iv_len:] + del self.iv_buf + return self.decipher.update(buf) + else: + return b'' + +def encrypt_all(password, method, op, data): + result = [] + method = method.lower() + (key_len, iv_len, m) = method_supported[method] + if key_len > 0: + key, _ = EVP_BytesToKey(password, key_len, iv_len) + else: + key = password + if op: + iv = random_string(iv_len) + result.append(iv) + else: + iv = data[:iv_len] + data = data[iv_len:] + cipher = m(method, key, iv, op) + result.append(cipher.update(data)) + return b''.join(result) + +def encrypt_key(password, method): + method = method.lower() + (key_len, iv_len, m) = method_supported[method] + if key_len > 0: + key, _ = EVP_BytesToKey(password, key_len, iv_len) + else: + key = password + return key + +def encrypt_iv_len(method): + method = method.lower() + (key_len, iv_len, m) = method_supported[method] + return iv_len + +def encrypt_new_iv(method): + method = method.lower() + (key_len, iv_len, m) = method_supported[method] + return random_string(iv_len) + +def encrypt_all_iv(key, method, op, data, ref_iv): + result = [] + method = method.lower() + (key_len, iv_len, m) = method_supported[method] + if op: + iv = ref_iv[0] + result.append(iv) + else: + iv = data[:iv_len] + data = data[iv_len:] + ref_iv[0] = iv + cipher = m(method, key, iv, op) + result.append(cipher.update(data)) + return b''.join(result) + + +CIPHERS_TO_TEST = [ + 'aes-128-cfb', + 'aes-256-cfb', + 'rc4-md5', + 'salsa20', + 'chacha20', + 'table', +] + + +def test_encryptor(): + from os import urandom + plain = urandom(10240) + for method in CIPHERS_TO_TEST: + logging.warn(method) + encryptor = Encryptor(b'key', method) + decryptor = Encryptor(b'key', method) + cipher = encryptor.encrypt(plain) + plain2 = decryptor.decrypt(cipher) + assert plain == plain2 + + +def test_encrypt_all(): + from os import urandom + plain = urandom(10240) + for method in CIPHERS_TO_TEST: + logging.warn(method) + cipher = encrypt_all(b'key', method, 1, plain) + plain2 = encrypt_all(b'key', method, 0, cipher) + assert plain == plain2 + + +if __name__ == '__main__': + test_encrypt_all() + test_encryptor() diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/encrypt_test.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/encrypt_test.py new file mode 100644 index 000000000..d5e507789 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/encrypt_test.py @@ -0,0 +1,51 @@ +from __future__ import absolute_import, division, print_function, \ + with_statement + +import sys +import os + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../')) + + +from shadowsocks.crypto import rc4_md5 +from shadowsocks.crypto import openssl +from shadowsocks.crypto import sodium +from shadowsocks.crypto import table + +def run(func): + try: + func() + except: + pass + +def run_n(func, name): + try: + func(name) + except: + pass + +def main(): + print("\n""rc4_md5") + rc4_md5.test() + print("\n""aes-256-cfb") + openssl.test_aes_256_cfb() + print("\n""aes-128-cfb") + openssl.test_aes_128_cfb() + print("\n""bf-cfb") + run(openssl.test_bf_cfb) + print("\n""camellia-128-cfb") + run_n(openssl.run_method, "camellia-128-cfb") + print("\n""cast5-cfb") + run_n(openssl.run_method, "cast5-cfb") + print("\n""idea-cfb") + run_n(openssl.run_method, "idea-cfb") + print("\n""seed-cfb") + run_n(openssl.run_method, "seed-cfb") + print("\n""salsa20") + run(sodium.test_salsa20) + print("\n""chacha20") + run(sodium.test_chacha20) + +if __name__ == '__main__': + main() + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/eventloop.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/eventloop.py new file mode 100644 index 000000000..341620efd --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/eventloop.py @@ -0,0 +1,258 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright 2013-2015 clowwindy +# +# 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. + +# from ssloop +# https://github.com/clowwindy/ssloop + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import os +import time +import socket +import select +import errno +import logging +from collections import defaultdict + +from shadowsocks import shell + + +__all__ = ['EventLoop', 'POLL_NULL', 'POLL_IN', 'POLL_OUT', 'POLL_ERR', + 'POLL_HUP', 'POLL_NVAL', 'EVENT_NAMES'] + +POLL_NULL = 0x00 +POLL_IN = 0x01 +POLL_OUT = 0x04 +POLL_ERR = 0x08 +POLL_HUP = 0x10 +POLL_NVAL = 0x20 + + +EVENT_NAMES = { + POLL_NULL: 'POLL_NULL', + POLL_IN: 'POLL_IN', + POLL_OUT: 'POLL_OUT', + POLL_ERR: 'POLL_ERR', + POLL_HUP: 'POLL_HUP', + POLL_NVAL: 'POLL_NVAL', +} + +# we check timeouts every TIMEOUT_PRECISION seconds +TIMEOUT_PRECISION = 2 + + +class KqueueLoop(object): + + MAX_EVENTS = 1024 + + def __init__(self): + self._kqueue = select.kqueue() + self._fds = {} + + def _control(self, fd, mode, flags): + events = [] + if mode & POLL_IN: + events.append(select.kevent(fd, select.KQ_FILTER_READ, flags)) + if mode & POLL_OUT: + events.append(select.kevent(fd, select.KQ_FILTER_WRITE, flags)) + for e in events: + self._kqueue.control([e], 0) + + def poll(self, timeout): + if timeout < 0: + timeout = None # kqueue behaviour + events = self._kqueue.control(None, KqueueLoop.MAX_EVENTS, timeout) + results = defaultdict(lambda: POLL_NULL) + for e in events: + fd = e.ident + if e.filter == select.KQ_FILTER_READ: + results[fd] |= POLL_IN + elif e.filter == select.KQ_FILTER_WRITE: + results[fd] |= POLL_OUT + return results.items() + + def register(self, fd, mode): + self._fds[fd] = mode + self._control(fd, mode, select.KQ_EV_ADD) + + def unregister(self, fd): + self._control(fd, self._fds[fd], select.KQ_EV_DELETE) + del self._fds[fd] + + def modify(self, fd, mode): + self.unregister(fd) + self.register(fd, mode) + + def close(self): + self._kqueue.close() + + +class SelectLoop(object): + + def __init__(self): + self._r_list = set() + self._w_list = set() + self._x_list = set() + + def poll(self, timeout): + r, w, x = select.select(self._r_list, self._w_list, self._x_list, + timeout) + results = defaultdict(lambda: POLL_NULL) + for p in [(r, POLL_IN), (w, POLL_OUT), (x, POLL_ERR)]: + for fd in p[0]: + results[fd] |= p[1] + return results.items() + + def register(self, fd, mode): + if mode & POLL_IN: + self._r_list.add(fd) + if mode & POLL_OUT: + self._w_list.add(fd) + if mode & POLL_ERR: + self._x_list.add(fd) + + def unregister(self, fd): + if fd in self._r_list: + self._r_list.remove(fd) + if fd in self._w_list: + self._w_list.remove(fd) + if fd in self._x_list: + self._x_list.remove(fd) + + def modify(self, fd, mode): + self.unregister(fd) + self.register(fd, mode) + + def close(self): + pass + + +class EventLoop(object): + def __init__(self): + if hasattr(select, 'epoll'): + self._impl = select.epoll() + model = 'epoll' + elif hasattr(select, 'kqueue'): + self._impl = KqueueLoop() + model = 'kqueue' + elif hasattr(select, 'select'): + self._impl = SelectLoop() + model = 'select' + else: + raise Exception('can not find any available functions in select ' + 'package') + self._fdmap = {} # (f, handler) + self._last_time = time.time() + self._periodic_callbacks = [] + self._stopping = False + logging.debug('using event model: %s', model) + + def poll(self, timeout=None): + events = self._impl.poll(timeout) + return [(self._fdmap[fd][0], fd, event) for fd, event in events] + + def add(self, f, mode, handler): + fd = f.fileno() + self._fdmap[fd] = (f, handler) + self._impl.register(fd, mode) + + def remove(self, f): + fd = f.fileno() + del self._fdmap[fd] + self._impl.unregister(fd) + + def removefd(self, fd): + del self._fdmap[fd] + self._impl.unregister(fd) + + def add_periodic(self, callback): + self._periodic_callbacks.append(callback) + + def remove_periodic(self, callback): + self._periodic_callbacks.remove(callback) + + def modify(self, f, mode): + fd = f.fileno() + self._impl.modify(fd, mode) + + def stop(self): + self._stopping = True + + def run(self): + events = [] + while not self._stopping: + asap = False + try: + events = self.poll(TIMEOUT_PRECISION) + except (OSError, IOError) as e: + if errno_from_exception(e) in (errno.EPIPE, errno.EINTR): + # EPIPE: Happens when the client closes the connection + # EINTR: Happens when received a signal + # handles them as soon as possible + asap = True + logging.debug('poll:%s', e) + else: + logging.error('poll:%s', e) + import traceback + traceback.print_exc() + continue + + handle = False + for sock, fd, event in events: + handler = self._fdmap.get(fd, None) + if handler is not None: + handler = handler[1] + try: + handle = handler.handle_event(sock, fd, event) or handle + except (OSError, IOError) as e: + shell.print_exception(e) + now = time.time() + if asap or now - self._last_time >= TIMEOUT_PRECISION: + for callback in self._periodic_callbacks: + callback() + self._last_time = now + if events and not handle: + time.sleep(0.001) + + def __del__(self): + self._impl.close() + + +# from tornado +def errno_from_exception(e): + """Provides the errno from an Exception object. + + There are cases that the errno attribute was not set so we pull + the errno out of the args but if someone instatiates an Exception + without any args you will get a tuple error. So this function + abstracts all that behavior to give you a safe way to get the + errno. + """ + + if hasattr(e, 'errno'): + return e.errno + elif e.args: + return e.args[0] + else: + return None + + +# from tornado +def get_sock_error(sock): + error_number = sock.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) + return socket.error(error_number, os.strerror(error_number)) diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/local.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/local.py new file mode 100755 index 000000000..9f54d9306 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/local.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2012-2015 clowwindy +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import sys +import os +import logging +import signal + +if __name__ == '__main__': + import inspect + file_path = os.path.dirname(os.path.realpath(inspect.getfile(inspect.currentframe()))) + sys.path.insert(0, os.path.join(file_path, '../')) + +from shadowsocks import shell, daemon, eventloop, tcprelay, udprelay, asyncdns + + +def main(): + shell.check_python() + + # fix py2exe + if hasattr(sys, "frozen") and sys.frozen in \ + ("windows_exe", "console_exe"): + p = os.path.dirname(os.path.abspath(sys.executable)) + os.chdir(p) + + config = shell.get_config(True) + + if not config.get('dns_ipv6', False): + asyncdns.IPV6_CONNECTION_SUPPORT = False + + daemon.daemon_exec(config) + logging.info("local start with protocol[%s] password [%s] method [%s] obfs [%s] obfs_param [%s]" % + (config['protocol'], config['password'], config['method'], config['obfs'], config['obfs_param'])) + + try: + logging.info("starting local at %s:%d" % + (config['local_address'], config['local_port'])) + + dns_resolver = asyncdns.DNSResolver() + tcp_server = tcprelay.TCPRelay(config, dns_resolver, True) + udp_server = udprelay.UDPRelay(config, dns_resolver, True) + loop = eventloop.EventLoop() + dns_resolver.add_to_loop(loop) + tcp_server.add_to_loop(loop) + udp_server.add_to_loop(loop) + + def handler(signum, _): + logging.warn('received SIGQUIT, doing graceful shutting down..') + tcp_server.close(next_tick=True) + udp_server.close(next_tick=True) + signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM), handler) + + def int_handler(signum, _): + sys.exit(1) + signal.signal(signal.SIGINT, int_handler) + + daemon.set_user(config.get('user', None)) + loop.run() + except Exception as e: + shell.print_exception(e) + sys.exit(1) + +if __name__ == '__main__': + main() diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/logrun.sh b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/logrun.sh new file mode 100755 index 000000000..fc081e1d2 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/logrun.sh @@ -0,0 +1,8 @@ +#!/bin/bash +cd `dirname $0` +python_ver=$(ls /usr/bin|grep -e "^python[23]\.[1-9]\+$"|tail -1) +eval $(ps -ef | grep "[0-9] ${python_ver} server\\.py a" | awk '{print "kill "$2}') +ulimit -n 512000 +nohup ${python_ver} server.py a>> ssserver.log 2>&1 & + + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/lru_cache.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/lru_cache.py new file mode 100644 index 000000000..ab0d21086 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/lru_cache.py @@ -0,0 +1,179 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright 2015 clowwindy +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import collections +import logging +import time + +if __name__ == '__main__': + import os, sys, inspect + file_path = os.path.dirname(os.path.realpath(inspect.getfile(inspect.currentframe()))) + sys.path.insert(0, os.path.join(file_path, '../')) + +try: + from collections import OrderedDict +except: + from shadowsocks.ordereddict import OrderedDict + +# this LRUCache is optimized for concurrency, not QPS +# n: concurrency, keys stored in the cache +# m: visits not timed out, proportional to QPS * timeout +# get & set is O(1), not O(n). thus we can support very large n +# sweep is O((n - m)) or O(1024) at most, +# no metter how large the cache or timeout value is + +SWEEP_MAX_ITEMS = 1024 + +class LRUCache(collections.MutableMapping): + """This class is not thread safe""" + + def __init__(self, timeout=60, close_callback=None, *args, **kwargs): + self.timeout = timeout + self.close_callback = close_callback + self._store = {} + self._keys_to_last_time = OrderedDict() + self.update(dict(*args, **kwargs)) # use the free update to set keys + + def __getitem__(self, key): + # O(1) + t = time.time() + last_t = self._keys_to_last_time[key] + del self._keys_to_last_time[key] + self._keys_to_last_time[key] = t + return self._store[key] + + def __setitem__(self, key, value): + # O(1) + t = time.time() + if key in self._keys_to_last_time: + del self._keys_to_last_time[key] + self._keys_to_last_time[key] = t + self._store[key] = value + + def __delitem__(self, key): + # O(1) + last_t = self._keys_to_last_time[key] + del self._store[key] + del self._keys_to_last_time[key] + + def __contains__(self, key): + return key in self._store + + def __iter__(self): + return iter(self._store) + + def __len__(self): + return len(self._store) + + def first(self): + if len(self._keys_to_last_time) > 0: + for key in self._keys_to_last_time: + return key + + def sweep(self, sweep_item_cnt = SWEEP_MAX_ITEMS): + # O(n - m) + now = time.time() + c = 0 + while c < sweep_item_cnt: + if len(self._keys_to_last_time) == 0: + break + for key in self._keys_to_last_time: + break + last_t = self._keys_to_last_time[key] + if now - last_t <= self.timeout: + break + value = self._store[key] + del self._store[key] + del self._keys_to_last_time[key] + if self.close_callback is not None: + self.close_callback(value) + c += 1 + if c: + logging.debug('%d keys swept' % c) + return c < SWEEP_MAX_ITEMS + + def clear(self, keep): + now = time.time() + c = 0 + while len(self._keys_to_last_time) > keep: + if len(self._keys_to_last_time) == 0: + break + for key in self._keys_to_last_time: + break + last_t = self._keys_to_last_time[key] + value = self._store[key] + if self.close_callback is not None: + self.close_callback(value) + del self._store[key] + del self._keys_to_last_time[key] + c += 1 + if c: + logging.debug('%d keys swept' % c) + return c < SWEEP_MAX_ITEMS + +def test(): + c = LRUCache(timeout=0.3) + + c['a'] = 1 + assert c['a'] == 1 + c['a'] = 1 + + time.sleep(0.5) + c.sweep() + assert 'a' not in c + + c['a'] = 2 + c['b'] = 3 + time.sleep(0.2) + c.sweep() + assert c['a'] == 2 + assert c['b'] == 3 + + time.sleep(0.2) + c.sweep() + c['b'] + time.sleep(0.2) + c.sweep() + assert 'a' not in c + assert c['b'] == 3 + + time.sleep(0.5) + c.sweep() + assert 'a' not in c + assert 'b' not in c + + global close_cb_called + close_cb_called = False + + def close_cb(t): + global close_cb_called + assert not close_cb_called + close_cb_called = True + + c = LRUCache(timeout=0.1, close_callback=close_cb) + c['s'] = 1 + c['s'] + time.sleep(0.1) + c['s'] + time.sleep(0.3) + c.sweep() + +if __name__ == '__main__': + test() diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/manager.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/manager.py new file mode 100644 index 000000000..80d0a320b --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/manager.py @@ -0,0 +1,291 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright 2015 clowwindy +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import errno +import traceback +import socket +import logging +import json +import collections + +from shadowsocks import common, eventloop, tcprelay, udprelay, asyncdns, shell + + +BUF_SIZE = 1506 +STAT_SEND_LIMIT = 50 + + +class Manager(object): + + def __init__(self, config): + self._config = config + self._relays = {} # (tcprelay, udprelay) + self._loop = eventloop.EventLoop() + self._dns_resolver = asyncdns.DNSResolver() + self._dns_resolver.add_to_loop(self._loop) + + self._statistics = collections.defaultdict(int) + self._control_client_addr = None + try: + manager_address = common.to_str(config['manager_address']) + if ':' in manager_address: + addr = manager_address.rsplit(':', 1) + addr = addr[0], int(addr[1]) + addrs = socket.getaddrinfo(addr[0], addr[1]) + if addrs: + family = addrs[0][0] + else: + logging.error('invalid address: %s', manager_address) + exit(1) + else: + addr = manager_address + family = socket.AF_UNIX + self._control_socket = socket.socket(family, + socket.SOCK_DGRAM) + self._control_socket.bind(addr) + self._control_socket.setblocking(False) + except (OSError, IOError) as e: + logging.error(e) + logging.error('can not bind to manager address') + exit(1) + self._loop.add(self._control_socket, + eventloop.POLL_IN, self) + self._loop.add_periodic(self.handle_periodic) + + port_password = config['port_password'] + del config['port_password'] + for port, password in port_password.items(): + a_config = config.copy() + a_config['server_port'] = int(port) + a_config['password'] = password + self.add_port(a_config) + + def add_port(self, config): + port = int(config['server_port']) + servers = self._relays.get(port, None) + if servers: + logging.error("server already exists at %s:%d" % (config['server'], + port)) + return + logging.info("adding server at %s:%d" % (config['server'], port)) + t = tcprelay.TCPRelay(config, self._dns_resolver, False, + stat_callback=self.stat_callback) + u = udprelay.UDPRelay(config, self._dns_resolver, False, + stat_callback=self.stat_callback) + t.add_to_loop(self._loop) + u.add_to_loop(self._loop) + self._relays[port] = (t, u) + + def remove_port(self, config): + port = int(config['server_port']) + servers = self._relays.get(port, None) + if servers: + logging.info("removing server at %s:%d" % (config['server'], port)) + t, u = servers + t.close(next_tick=False) + u.close(next_tick=False) + del self._relays[port] + else: + logging.error("server not exist at %s:%d" % (config['server'], + port)) + + def handle_event(self, sock, fd, event): + if sock == self._control_socket and event == eventloop.POLL_IN: + data, self._control_client_addr = sock.recvfrom(BUF_SIZE) + parsed = self._parse_command(data) + if parsed: + command, config = parsed + a_config = self._config.copy() + if config: + # let the command override the configuration file + a_config.update(config) + if 'server_port' not in a_config: + logging.error('can not find server_port in config') + else: + if command == 'add': + self.add_port(a_config) + self._send_control_data(b'ok') + elif command == 'remove': + self.remove_port(a_config) + self._send_control_data(b'ok') + elif command == 'ping': + self._send_control_data(b'pong') + else: + logging.error('unknown command %s', command) + + def _parse_command(self, data): + # commands: + # add: {"server_port": 8000, "password": "foobar"} + # remove: {"server_port": 8000"} + data = common.to_str(data) + parts = data.split(':', 1) + if len(parts) < 2: + return data, None + command, config_json = parts + try: + config = shell.parse_json_in_str(config_json) + return command, config + except Exception as e: + logging.error(e) + return None + + def stat_callback(self, port, data_len): + self._statistics[port] += data_len + + def handle_periodic(self): + r = {} + i = 0 + + def send_data(data_dict): + if data_dict: + # use compact JSON format (without space) + data = common.to_bytes(json.dumps(data_dict, + separators=(',', ':'))) + self._send_control_data(b'stat: ' + data) + + for k, v in self._statistics.items(): + r[k] = v + i += 1 + # split the data into segments that fit in UDP packets + if i >= STAT_SEND_LIMIT: + send_data(r) + r.clear() + i = 0 + if len(r) > 0 : + send_data(r) + self._statistics.clear() + + def _send_control_data(self, data): + if self._control_client_addr: + try: + self._control_socket.sendto(data, self._control_client_addr) + except (socket.error, OSError, IOError) as e: + error_no = eventloop.errno_from_exception(e) + if error_no in (errno.EAGAIN, errno.EINPROGRESS, + errno.EWOULDBLOCK): + return + else: + shell.print_exception(e) + if self._config['verbose']: + traceback.print_exc() + + def run(self): + self._loop.run() + + +def run(config): + Manager(config).run() + + +def test(): + import time + import threading + import struct + from shadowsocks import encrypt + + logging.basicConfig(level=5, + format='%(asctime)s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S') + enc = [] + eventloop.TIMEOUT_PRECISION = 1 + + def run_server(): + config = shell.get_config(True) + config = config.copy() + a_config = { + 'server': '127.0.0.1', + 'local_port': 1081, + 'port_password': { + '8381': 'foobar1', + '8382': 'foobar2' + }, + 'method': 'aes-256-cfb', + 'manager_address': '127.0.0.1:6001', + 'timeout': 60, + 'fast_open': False, + 'verbose': 2 + } + config.update(a_config) + manager = Manager(config) + enc.append(manager) + manager.run() + + t = threading.Thread(target=run_server) + t.start() + time.sleep(1) + manager = enc[0] + cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + cli.connect(('127.0.0.1', 6001)) + + # test add and remove + time.sleep(1) + cli.send(b'add: {"server_port":7001, "password":"asdfadsfasdf"}') + time.sleep(1) + assert 7001 in manager._relays + data, addr = cli.recvfrom(1506) + assert b'ok' in data + + cli.send(b'remove: {"server_port":8381}') + time.sleep(1) + assert 8381 not in manager._relays + data, addr = cli.recvfrom(1506) + assert b'ok' in data + logging.info('add and remove test passed') + + # test statistics for TCP + header = common.pack_addr(b'google.com') + struct.pack('>H', 80) + data = encrypt.encrypt_all(b'asdfadsfasdf', 'aes-256-cfb', 1, + header + b'GET /\r\n\r\n') + tcp_cli = socket.socket() + tcp_cli.connect(('127.0.0.1', 7001)) + tcp_cli.send(data) + tcp_cli.recv(4096) + tcp_cli.close() + + data, addr = cli.recvfrom(1506) + data = common.to_str(data) + assert data.startswith('stat: ') + data = data.split('stat:')[1] + stats = shell.parse_json_in_str(data) + assert '7001' in stats + logging.info('TCP statistics test passed') + + # test statistics for UDP + header = common.pack_addr(b'127.0.0.1') + struct.pack('>H', 80) + data = encrypt.encrypt_all(b'foobar2', 'aes-256-cfb', 1, + header + b'test') + udp_cli = socket.socket(type=socket.SOCK_DGRAM) + udp_cli.sendto(data, ('127.0.0.1', 8382)) + tcp_cli.close() + + data, addr = cli.recvfrom(1506) + data = common.to_str(data) + assert data.startswith('stat: ') + data = data.split('stat:')[1] + stats = json.loads(data) + assert '8382' in stats + logging.info('UDP statistics test passed') + + manager._loop.stop() + t.join() + + +if __name__ == '__main__': + test() diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/obfs.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/obfs.py new file mode 100644 index 000000000..3dfdb141f --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/obfs.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python +# +# Copyright 2015-2015 breakwa11 +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import os +import sys +import hashlib +import logging + +from shadowsocks import common +from shadowsocks.obfsplugin import plain, http_simple, obfs_tls, verify, auth, auth_chain + + +method_supported = {} +method_supported.update(plain.obfs_map) +method_supported.update(http_simple.obfs_map) +method_supported.update(obfs_tls.obfs_map) +method_supported.update(verify.obfs_map) +method_supported.update(auth.obfs_map) +method_supported.update(auth_chain.obfs_map) + +def mu_protocol(): + return ["auth_aes128_md5", "auth_aes128_sha1", "auth_chain_a"] + +class server_info(object): + def __init__(self, data): + self.data = data + +class obfs(object): + def __init__(self, method): + method = common.to_str(method) + self.method = method + self._method_info = self.get_method_info(method) + if self._method_info: + self.obfs = self.get_obfs(method) + else: + raise Exception('obfs plugin [%s] not supported' % method) + + def init_data(self): + return self.obfs.init_data() + + def set_server_info(self, server_info): + return self.obfs.set_server_info(server_info) + + def get_server_info(self): + return self.obfs.get_server_info() + + def get_method_info(self, method): + method = method.lower() + m = method_supported.get(method) + return m + + def get_obfs(self, method): + m = self._method_info + return m[0](method) + + def get_overhead(self, direction): + return self.obfs.get_overhead(direction) + + def client_pre_encrypt(self, buf): + return self.obfs.client_pre_encrypt(buf) + + def client_encode(self, buf): + return self.obfs.client_encode(buf) + + def client_decode(self, buf): + return self.obfs.client_decode(buf) + + def client_post_decrypt(self, buf): + return self.obfs.client_post_decrypt(buf) + + def server_pre_encrypt(self, buf): + return self.obfs.server_pre_encrypt(buf) + + def server_encode(self, buf): + return self.obfs.server_encode(buf) + + def server_decode(self, buf): + return self.obfs.server_decode(buf) + + def server_post_decrypt(self, buf): + return self.obfs.server_post_decrypt(buf) + + def client_udp_pre_encrypt(self, buf): + return self.obfs.client_udp_pre_encrypt(buf) + + def client_udp_post_decrypt(self, buf): + return self.obfs.client_udp_post_decrypt(buf) + + def server_udp_pre_encrypt(self, buf, uid): + return self.obfs.server_udp_pre_encrypt(buf, uid) + + def server_udp_post_decrypt(self, buf): + return self.obfs.server_udp_post_decrypt(buf) + + def dispose(self): + self.obfs.dispose() + del self.obfs + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/obfsplugin/__init__.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/obfsplugin/__init__.py new file mode 100644 index 000000000..401c7b726 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/obfsplugin/__init__.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python +# +# Copyright 2015 clowwindy +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/obfsplugin/auth.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/obfsplugin/auth.py new file mode 100755 index 000000000..a745e098f --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/obfsplugin/auth.py @@ -0,0 +1,787 @@ +#!/usr/bin/env python +# +# Copyright 2015-2015 breakwa11 +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import os +import sys +import hashlib +import logging +import binascii +import base64 +import time +import datetime +import random +import math +import struct +import zlib +import hmac +import hashlib + +import shadowsocks +from shadowsocks import common, lru_cache, encrypt +from shadowsocks.obfsplugin import plain +from shadowsocks.common import to_bytes, to_str, ord, chr + +def create_auth_sha1_v4(method): + return auth_sha1_v4(method) + +def create_auth_aes128_md5(method): + return auth_aes128_sha1(method, hashlib.md5) + +def create_auth_aes128_sha1(method): + return auth_aes128_sha1(method, hashlib.sha1) + +obfs_map = { + 'auth_sha1_v4': (create_auth_sha1_v4,), + 'auth_sha1_v4_compatible': (create_auth_sha1_v4,), + 'auth_aes128_md5': (create_auth_aes128_md5,), + 'auth_aes128_sha1': (create_auth_aes128_sha1,), +} + +def match_begin(str1, str2): + if len(str1) >= len(str2): + if str1[:len(str2)] == str2: + return True + return False + +class auth_base(plain.plain): + def __init__(self, method): + super(auth_base, self).__init__(method) + self.method = method + self.no_compatible_method = '' + self.overhead = 7 + + def init_data(self): + return '' + + def get_overhead(self, direction): # direction: true for c->s false for s->c + return self.overhead + + def set_server_info(self, server_info): + self.server_info = server_info + + def client_encode(self, buf): + return buf + + def client_decode(self, buf): + return (buf, False) + + def server_encode(self, buf): + return buf + + def server_decode(self, buf): + return (buf, True, False) + + def not_match_return(self, buf): + self.raw_trans = True + self.overhead = 0 + if self.method == self.no_compatible_method: + return (b'E'*2048, False) + return (buf, False) + +class client_queue(object): + def __init__(self, begin_id): + self.front = begin_id - 64 + self.back = begin_id + 1 + self.alloc = {} + self.enable = True + self.last_update = time.time() + + def update(self): + self.last_update = time.time() + + def is_active(self): + return time.time() - self.last_update < 60 * 3 + + def re_enable(self, connection_id): + self.enable = True + self.front = connection_id - 64 + self.back = connection_id + 1 + self.alloc = {} + + def insert(self, connection_id): + if not self.enable: + logging.warn('obfs auth: not enable') + return False + if not self.is_active(): + self.re_enable(connection_id) + self.update() + if connection_id < self.front: + logging.warn('obfs auth: deprecated id, someone replay attack') + return False + if connection_id > self.front + 0x4000: + logging.warn('obfs auth: wrong id') + return False + if connection_id in self.alloc: + logging.warn('obfs auth: duplicate id, someone replay attack') + return False + if self.back <= connection_id: + self.back = connection_id + 1 + self.alloc[connection_id] = 1 + while (self.front in self.alloc) or self.front + 0x1000 < self.back: + if self.front in self.alloc: + del self.alloc[self.front] + self.front += 1 + return True + +class obfs_auth_v2_data(object): + def __init__(self): + self.client_id = lru_cache.LRUCache() + self.local_client_id = b'' + self.connection_id = 0 + self.set_max_client(64) # max active client count + + def update(self, client_id, connection_id): + if client_id in self.client_id: + self.client_id[client_id].update() + + def set_max_client(self, max_client): + self.max_client = max_client + self.max_buffer = max(self.max_client * 2, 1024) + + def insert(self, client_id, connection_id): + if self.client_id.get(client_id, None) is None or not self.client_id[client_id].enable: + if self.client_id.first() is None or len(self.client_id) < self.max_client: + if client_id not in self.client_id: + #TODO: check + self.client_id[client_id] = client_queue(connection_id) + else: + self.client_id[client_id].re_enable(connection_id) + return self.client_id[client_id].insert(connection_id) + + if not self.client_id[self.client_id.first()].is_active(): + del self.client_id[self.client_id.first()] + if client_id not in self.client_id: + #TODO: check + self.client_id[client_id] = client_queue(connection_id) + else: + self.client_id[client_id].re_enable(connection_id) + return self.client_id[client_id].insert(connection_id) + + logging.warn('auth_sha1_v2: no inactive client') + return False + else: + return self.client_id[client_id].insert(connection_id) + +class auth_sha1_v4(auth_base): + def __init__(self, method): + super(auth_sha1_v4, self).__init__(method) + self.recv_buf = b'' + self.unit_len = 8100 + self.decrypt_packet_num = 0 + self.raw_trans = False + self.has_sent_header = False + self.has_recv_header = False + self.client_id = 0 + self.connection_id = 0 + self.max_time_dif = 60 * 60 * 24 # time dif (second) setting + self.salt = b"auth_sha1_v4" + self.no_compatible_method = 'auth_sha1_v4' + + def init_data(self): + return obfs_auth_v2_data() + + def set_server_info(self, server_info): + self.server_info = server_info + try: + max_client = int(server_info.protocol_param) + except: + max_client = 64 + self.server_info.data.set_max_client(max_client) + + def rnd_data(self, buf_size): + if buf_size > 1200: + return b'\x01' + + if buf_size > 400: + rnd_data = os.urandom(common.ord(os.urandom(1)[0]) % 256) + else: + rnd_data = os.urandom(struct.unpack('>H', os.urandom(2))[0] % 512) + + if len(rnd_data) < 128: + return common.chr(len(rnd_data) + 1) + rnd_data + else: + return common.chr(255) + struct.pack('>H', len(rnd_data) + 3) + rnd_data + + def pack_data(self, buf): + data = self.rnd_data(len(buf)) + buf + data_len = len(data) + 8 + crc = binascii.crc32(struct.pack('>H', data_len)) & 0xFFFF + data = struct.pack('H', data_len) + data + adler32 = zlib.adler32(data) & 0xFFFFFFFF + data += struct.pack('H', data_len) + self.salt + self.server_info.key) & 0xFFFFFFFF + data = struct.pack('H', data_len) + data + data += hmac.new(self.server_info.iv + self.server_info.key, data, hashlib.sha1).digest()[:10] + return data + + def auth_data(self): + utc_time = int(time.time()) & 0xFFFFFFFF + if self.server_info.data.connection_id > 0xFF000000: + self.server_info.data.local_client_id = b'' + if not self.server_info.data.local_client_id: + self.server_info.data.local_client_id = os.urandom(4) + logging.debug("local_client_id %s" % (binascii.hexlify(self.server_info.data.local_client_id),)) + self.server_info.data.connection_id = struct.unpack(' self.unit_len: + ret += self.pack_data(buf[:self.unit_len]) + buf = buf[self.unit_len:] + ret += self.pack_data(buf) + return ret + + def client_post_decrypt(self, buf): + if self.raw_trans: + return buf + self.recv_buf += buf + out_buf = b'' + while len(self.recv_buf) > 4: + crc = struct.pack('H', self.recv_buf[:2])[0] + if length >= 8192 or length < 7: + self.raw_trans = True + self.recv_buf = b'' + raise Exception('client_post_decrypt data error') + if length > len(self.recv_buf): + break + + if struct.pack('H', self.recv_buf[5:7])[0] + 4 + out_buf += self.recv_buf[pos:length - 4] + self.recv_buf = self.recv_buf[length:] + + if out_buf: + self.decrypt_packet_num += 1 + return out_buf + + def server_pre_encrypt(self, buf): + if self.raw_trans: + return buf + ret = b'' + while len(buf) > self.unit_len: + ret += self.pack_data(buf[:self.unit_len]) + buf = buf[self.unit_len:] + ret += self.pack_data(buf) + return ret + + def server_post_decrypt(self, buf): + if self.raw_trans: + return (buf, False) + self.recv_buf += buf + out_buf = b'' + sendback = False + + if not self.has_recv_header: + if len(self.recv_buf) <= 6: + return (b'', False) + crc = struct.pack('H', self.recv_buf[:2])[0] + if length > len(self.recv_buf): + return (b'', False) + sha1data = hmac.new(self.server_info.recv_iv + self.server_info.key, self.recv_buf[:length - 10], hashlib.sha1).digest()[:10] + if sha1data != self.recv_buf[length - 10:length]: + logging.error('auth_sha1_v4 data uncorrect auth HMAC-SHA1') + return self.not_match_return(self.recv_buf) + pos = common.ord(self.recv_buf[6]) + if pos < 255: + pos += 6 + else: + pos = struct.unpack('>H', self.recv_buf[7:9])[0] + 6 + out_buf = self.recv_buf[pos:length - 10] + if len(out_buf) < 12: + logging.info('auth_sha1_v4: too short, data %s' % (binascii.hexlify(self.recv_buf),)) + return self.not_match_return(self.recv_buf) + utc_time = struct.unpack(' self.max_time_dif: + logging.info('auth_sha1_v4: wrong timestamp, time_dif %d, data %s' % (time_dif, binascii.hexlify(out_buf),)) + return self.not_match_return(self.recv_buf) + elif self.server_info.data.insert(client_id, connection_id): + self.has_recv_header = True + out_buf = out_buf[12:] + self.client_id = client_id + self.connection_id = connection_id + else: + logging.info('auth_sha1_v4: auth fail, data %s' % (binascii.hexlify(out_buf),)) + return self.not_match_return(self.recv_buf) + self.recv_buf = self.recv_buf[length:] + self.has_recv_header = True + sendback = True + + while len(self.recv_buf) > 4: + crc = struct.pack('H', self.recv_buf[:2])[0] + if length >= 8192 or length < 7: + self.raw_trans = True + self.recv_buf = b'' + if self.decrypt_packet_num == 0: + logging.info('auth_sha1_v4: over size') + return (b'E'*2048, False) + else: + raise Exception('server_post_decrype data error') + if length > len(self.recv_buf): + break + + if struct.pack('H', self.recv_buf[5:7])[0] + 4 + out_buf += self.recv_buf[pos:length - 4] + self.recv_buf = self.recv_buf[length:] + if pos == length - 4: + sendback = True + + if out_buf: + self.server_info.data.update(self.client_id, self.connection_id) + self.decrypt_packet_num += 1 + return (out_buf, sendback) + +class obfs_auth_mu_data(object): + def __init__(self): + self.user_id = {} + self.local_client_id = b'' + self.connection_id = 0 + self.set_max_client(64) # max active client count + + def update(self, user_id, client_id, connection_id): + if user_id not in self.user_id: + self.user_id[user_id] = lru_cache.LRUCache() + local_client_id = self.user_id[user_id] + + if client_id in local_client_id: + local_client_id[client_id].update() + + def set_max_client(self, max_client): + self.max_client = max_client + self.max_buffer = max(self.max_client * 2, 1024) + + def insert(self, user_id, client_id, connection_id): + if user_id not in self.user_id: + self.user_id[user_id] = lru_cache.LRUCache() + local_client_id = self.user_id[user_id] + + if local_client_id.get(client_id, None) is None or not local_client_id[client_id].enable: + if local_client_id.first() is None or len(local_client_id) < self.max_client: + if client_id not in local_client_id: + #TODO: check + local_client_id[client_id] = client_queue(connection_id) + else: + local_client_id[client_id].re_enable(connection_id) + return local_client_id[client_id].insert(connection_id) + + if not local_client_id[local_client_id.first()].is_active(): + del local_client_id[local_client_id.first()] + if client_id not in local_client_id: + #TODO: check + local_client_id[client_id] = client_queue(connection_id) + else: + local_client_id[client_id].re_enable(connection_id) + return local_client_id[client_id].insert(connection_id) + + logging.warn('auth_aes128: no inactive client') + return False + else: + return local_client_id[client_id].insert(connection_id) + +class auth_aes128_sha1(auth_base): + def __init__(self, method, hashfunc): + super(auth_aes128_sha1, self).__init__(method) + self.hashfunc = hashfunc + self.recv_buf = b'' + self.unit_len = 8100 + self.raw_trans = False + self.has_sent_header = False + self.has_recv_header = False + self.client_id = 0 + self.connection_id = 0 + self.max_time_dif = 60 * 60 * 24 # time dif (second) setting + self.salt = hashfunc == hashlib.md5 and b"auth_aes128_md5" or b"auth_aes128_sha1" + self.no_compatible_method = hashfunc == hashlib.md5 and "auth_aes128_md5" or 'auth_aes128_sha1' + self.extra_wait_size = struct.unpack('>H', os.urandom(2))[0] % 1024 + self.pack_id = 1 + self.recv_id = 1 + self.user_id = None + self.user_key = None + self.last_rnd_len = 0 + self.overhead = 9 + + def init_data(self): + return obfs_auth_mu_data() + + def get_overhead(self, direction): # direction: true for c->s false for s->c + return self.overhead + + def set_server_info(self, server_info): + self.server_info = server_info + try: + max_client = int(server_info.protocol_param.split('#')[0]) + except: + max_client = 64 + self.server_info.data.set_max_client(max_client) + + def trapezoid_random_float(self, d): + if d == 0: + return random.random() + s = random.random() + a = 1 - d + return (math.sqrt(a * a + 4 * d * s) - a) / (2 * d) + + def trapezoid_random_int(self, max_val, d): + v = self.trapezoid_random_float(d) + return int(v * max_val) + + def rnd_data_len(self, buf_size, full_buf_size): + if full_buf_size >= self.server_info.buffer_size: + return 0 + tcp_mss = self.server_info.tcp_mss + rev_len = tcp_mss - buf_size - 9 + if rev_len == 0: + return 0 + if rev_len < 0: + if rev_len > -tcp_mss: + return self.trapezoid_random_int(rev_len + tcp_mss, -0.3) + return common.ord(os.urandom(1)[0]) % 32 + if buf_size > 900: + return struct.unpack('>H', os.urandom(2))[0] % rev_len + return self.trapezoid_random_int(rev_len, -0.3) + + def rnd_data(self, buf_size, full_buf_size): + data_len = self.rnd_data_len(buf_size, full_buf_size) + + if data_len < 128: + return common.chr(data_len + 1) + os.urandom(data_len) + + return common.chr(255) + struct.pack(' 400: + rnd_len = struct.unpack(' 0xFF000000: + self.server_info.data.local_client_id = b'' + if not self.server_info.data.local_client_id: + self.server_info.data.local_client_id = os.urandom(4) + logging.debug("local_client_id %s" % (binascii.hexlify(self.server_info.data.local_client_id),)) + self.server_info.data.connection_id = struct.unpack(' self.unit_len: + ret += self.pack_data(buf[:self.unit_len], ogn_data_len) + buf = buf[self.unit_len:] + ret += self.pack_data(buf, ogn_data_len) + self.last_rnd_len = ogn_data_len + return ret + + def client_post_decrypt(self, buf): + if self.raw_trans: + return buf + self.recv_buf += buf + out_buf = b'' + while len(self.recv_buf) > 4: + mac_key = self.user_key + struct.pack('= 8192 or length < 7: + self.raw_trans = True + self.recv_buf = b'' + raise Exception('client_post_decrypt data error') + if length > len(self.recv_buf): + break + + if hmac.new(mac_key, self.recv_buf[:length - 4], self.hashfunc).digest()[:4] != self.recv_buf[length - 4:length]: + self.raw_trans = True + self.recv_buf = b'' + raise Exception('client_post_decrypt data uncorrect checksum') + + self.recv_id = (self.recv_id + 1) & 0xFFFFFFFF + pos = common.ord(self.recv_buf[4]) + if pos < 255: + pos += 4 + else: + pos = struct.unpack(' self.unit_len: + ret += self.pack_data(buf[:self.unit_len], ogn_data_len) + buf = buf[self.unit_len:] + ret += self.pack_data(buf, ogn_data_len) + self.last_rnd_len = ogn_data_len + return ret + + def server_post_decrypt(self, buf): + if self.raw_trans: + return (buf, False) + self.recv_buf += buf + out_buf = b'' + sendback = False + + if not self.has_recv_header: + if len(self.recv_buf) >= 7 or len(self.recv_buf) in [2, 3]: + recv_len = min(len(self.recv_buf), 7) + mac_key = self.server_info.recv_iv + self.server_info.key + sha1data = hmac.new(mac_key, self.recv_buf[:1], self.hashfunc).digest()[:recv_len - 1] + if sha1data != self.recv_buf[1:recv_len]: + return self.not_match_return(self.recv_buf) + + if len(self.recv_buf) < 31: + return (b'', False) + sha1data = hmac.new(mac_key, self.recv_buf[7:27], self.hashfunc).digest()[:4] + if sha1data != self.recv_buf[27:31]: + logging.error('%s data uncorrect auth HMAC-SHA1 from %s:%d, data %s' % (self.no_compatible_method, self.server_info.client, self.server_info.client_port, binascii.hexlify(self.recv_buf))) + if len(self.recv_buf) < 31 + self.extra_wait_size: + return (b'', False) + return self.not_match_return(self.recv_buf) + + uid = self.recv_buf[7:11] + if uid in self.server_info.users: + self.user_id = uid + self.user_key = self.hashfunc(self.server_info.users[uid]).digest() + self.server_info.update_user_func(uid) + else: + if not self.server_info.users: + self.user_key = self.server_info.key + else: + self.user_key = self.server_info.recv_iv + encryptor = encrypt.Encryptor(to_bytes(base64.b64encode(self.user_key)) + self.salt, 'aes-128-cbc') + head = encryptor.decrypt(b'\x00' * 16 + self.recv_buf[11:27] + b'\x00') # need an extra byte or recv empty + length = struct.unpack(' self.max_time_dif: + logging.info('%s: wrong timestamp, time_dif %d, data %s' % (self.no_compatible_method, time_dif, binascii.hexlify(head))) + return self.not_match_return(self.recv_buf) + elif self.server_info.data.insert(self.user_id, client_id, connection_id): + self.has_recv_header = True + out_buf = self.recv_buf[31 + rnd_len:length - 4] + self.client_id = client_id + self.connection_id = connection_id + else: + logging.info('%s: auth fail, data %s' % (self.no_compatible_method, binascii.hexlify(out_buf))) + return self.not_match_return(self.recv_buf) + self.recv_buf = self.recv_buf[length:] + self.has_recv_header = True + sendback = True + + while len(self.recv_buf) > 4: + mac_key = self.user_key + struct.pack('= 8192 or length < 7: + self.raw_trans = True + self.recv_buf = b'' + if self.recv_id == 0: + logging.info(self.no_compatible_method + ': over size') + return (b'E'*2048, False) + else: + raise Exception('server_post_decrype data error') + if length > len(self.recv_buf): + break + + if hmac.new(mac_key, self.recv_buf[:length - 4], self.hashfunc).digest()[:4] != self.recv_buf[length - 4:length]: + logging.info('%s: checksum error, data %s' % (self.no_compatible_method, binascii.hexlify(self.recv_buf[:length]))) + self.raw_trans = True + self.recv_buf = b'' + if self.recv_id == 0: + return (b'E'*2048, False) + else: + raise Exception('server_post_decrype data uncorrect checksum') + + self.recv_id = (self.recv_id + 1) & 0xFFFFFFFF + pos = common.ord(self.recv_buf[4]) + if pos < 255: + pos += 4 + else: + pos = struct.unpack('> 17) ^ (y >> 26)) & xorshift128plus.max_int + self.v1 = x + return (x + y) & xorshift128plus.max_int + + def init_from_bin(self, bin): + bin += b'\0' * 16 + self.v0 = struct.unpack('= len(str2): + if str1[:len(str2)] == str2: + return True + return False + + +class auth_base(plain.plain): + def __init__(self, method): + super(auth_base, self).__init__(method) + self.method = method + self.no_compatible_method = '' + self.overhead = 4 + + def init_data(self): + return '' + + def get_overhead(self, direction): # direction: true for c->s false for s->c + return self.overhead + + def set_server_info(self, server_info): + self.server_info = server_info + + def client_encode(self, buf): + return buf + + def client_decode(self, buf): + return (buf, False) + + def server_encode(self, buf): + return buf + + def server_decode(self, buf): + return (buf, True, False) + + def not_match_return(self, buf): + self.raw_trans = True + self.overhead = 0 + if self.method == self.no_compatible_method: + return (b'E' * 2048, False) + return (buf, False) + + +class client_queue(object): + def __init__(self, begin_id): + self.front = begin_id - 64 + self.back = begin_id + 1 + self.alloc = {} + self.enable = True + self.last_update = time.time() + self.ref = 0 + + def update(self): + self.last_update = time.time() + + def addref(self): + self.ref += 1 + + def delref(self): + if self.ref > 0: + self.ref -= 1 + + def is_active(self): + return (self.ref > 0) and (time.time() - self.last_update < 60 * 10) + + def re_enable(self, connection_id): + self.enable = True + self.front = connection_id - 64 + self.back = connection_id + 1 + self.alloc = {} + + def insert(self, connection_id): + if not self.enable: + logging.warn('obfs auth: not enable') + return False + if not self.is_active(): + self.re_enable(connection_id) + self.update() + if connection_id < self.front: + logging.warn('obfs auth: deprecated id, someone replay attack') + return False + if connection_id > self.front + 0x4000: + logging.warn('obfs auth: wrong id') + return False + if connection_id in self.alloc: + logging.warn('obfs auth: duplicate id, someone replay attack') + return False + if self.back <= connection_id: + self.back = connection_id + 1 + self.alloc[connection_id] = 1 + while (self.front in self.alloc) or self.front + 0x1000 < self.back: + if self.front in self.alloc: + del self.alloc[self.front] + self.front += 1 + self.addref() + return True + + +class obfs_auth_chain_data(object): + def __init__(self, name): + self.name = name + self.user_id = {} + self.local_client_id = b'' + self.connection_id = 0 + self.set_max_client(64) # max active client count + + def update(self, user_id, client_id, connection_id): + if user_id not in self.user_id: + self.user_id[user_id] = lru_cache.LRUCache() + local_client_id = self.user_id[user_id] + + if client_id in local_client_id: + local_client_id[client_id].update() + + def set_max_client(self, max_client): + self.max_client = max_client + self.max_buffer = max(self.max_client * 2, 1024) + + def insert(self, user_id, client_id, connection_id): + if user_id not in self.user_id: + self.user_id[user_id] = lru_cache.LRUCache() + local_client_id = self.user_id[user_id] + + if local_client_id.get(client_id, None) is None or not local_client_id[client_id].enable: + if local_client_id.first() is None or len(local_client_id) < self.max_client: + if client_id not in local_client_id: + # TODO: check + local_client_id[client_id] = client_queue(connection_id) + else: + local_client_id[client_id].re_enable(connection_id) + return local_client_id[client_id].insert(connection_id) + + if not local_client_id[local_client_id.first()].is_active(): + del local_client_id[local_client_id.first()] + if client_id not in local_client_id: + # TODO: check + local_client_id[client_id] = client_queue(connection_id) + else: + local_client_id[client_id].re_enable(connection_id) + return local_client_id[client_id].insert(connection_id) + + logging.warn(self.name + ': no inactive client') + return False + else: + return local_client_id[client_id].insert(connection_id) + + def remove(self, user_id, client_id): + if user_id in self.user_id: + local_client_id = self.user_id[user_id] + if client_id in local_client_id: + local_client_id[client_id].delref() + + +class auth_chain_a(auth_base): + def __init__(self, method): + super(auth_chain_a, self).__init__(method) + self.hashfunc = hashlib.md5 + self.recv_buf = b'' + self.unit_len = 2800 + self.raw_trans = False + self.has_sent_header = False + self.has_recv_header = False + self.client_id = 0 + self.connection_id = 0 + self.max_time_dif = 60 * 60 * 24 # time dif (second) setting + self.salt = b"auth_chain_a" + self.no_compatible_method = 'auth_chain_a' + self.pack_id = 1 + self.recv_id = 1 + self.user_id = None + self.user_id_num = 0 + self.user_key = None + self.overhead = 4 + self.client_over_head = 4 + self.last_client_hash = b'' + self.last_server_hash = b'' + self.random_client = xorshift128plus() + self.random_server = xorshift128plus() + self.encryptor = None + + def init_data(self): + return obfs_auth_chain_data(self.method) + + def get_overhead(self, direction): # direction: true for c->s false for s->c + return self.overhead + + def set_server_info(self, server_info): + self.server_info = server_info + try: + max_client = int(server_info.protocol_param.split('#')[0]) + except: + max_client = 64 + self.server_info.data.set_max_client(max_client) + + def trapezoid_random_float(self, d): + if d == 0: + return random.random() + s = random.random() + a = 1 - d + return (math.sqrt(a * a + 4 * d * s) - a) / (2 * d) + + def trapezoid_random_int(self, max_val, d): + v = self.trapezoid_random_float(d) + return int(v * max_val) + + def rnd_data_len(self, buf_size, last_hash, random): + if buf_size > 1440: + return 0 + random.init_from_bin_len(last_hash, buf_size) + if buf_size > 1300: + return random.next() % 31 + if buf_size > 900: + return random.next() % 127 + if buf_size > 400: + return random.next() % 521 + return random.next() % 1021 + + def udp_rnd_data_len(self, last_hash, random): + random.init_from_bin(last_hash) + return random.next() % 127 + + def rnd_start_pos(self, rand_len, random): + if rand_len > 0: + return random.next() % 8589934609 % rand_len + return 0 + + def rnd_data(self, buf_size, buf, last_hash, random): + rand_len = self.rnd_data_len(buf_size, last_hash, random) + + rnd_data_buf = os.urandom(rand_len) + + if buf_size == 0: + return rnd_data_buf + else: + if rand_len > 0: + start_pos = self.rnd_start_pos(rand_len, random) + return rnd_data_buf[:start_pos] + buf + rnd_data_buf[start_pos:] + else: + return buf + + def pack_client_data(self, buf): + buf = self.encryptor.encrypt(buf) + data = self.rnd_data(len(buf), buf, self.last_client_hash, self.random_client) + data_len = len(data) + 8 + mac_key = self.user_key + struct.pack(' 0xFF000000: + self.server_info.data.local_client_id = b'' + if not self.server_info.data.local_client_id: + self.server_info.data.local_client_id = os.urandom(4) + logging.debug("local_client_id %s" % (binascii.hexlify(self.server_info.data.local_client_id),)) + self.server_info.data.connection_id = struct.unpack(' self.unit_len: + ret += self.pack_client_data(buf[:self.unit_len]) + buf = buf[self.unit_len:] + ret += self.pack_client_data(buf) + return ret + + def client_post_decrypt(self, buf): + if self.raw_trans: + return buf + self.recv_buf += buf + out_buf = b'' + while len(self.recv_buf) > 4: + mac_key = self.user_key + struct.pack('= 4096: + self.raw_trans = True + self.recv_buf = b'' + raise Exception('client_post_decrypt data error') + + if length + 4 > len(self.recv_buf): + break + + server_hash = hmac.new(mac_key, self.recv_buf[:length + 2], self.hashfunc).digest() + if server_hash[:2] != self.recv_buf[length + 2: length + 4]: + logging.info('%s: checksum error, data %s' + % (self.no_compatible_method, binascii.hexlify(self.recv_buf[:length]))) + self.raw_trans = True + self.recv_buf = b'' + raise Exception('client_post_decrypt data uncorrect checksum') + + pos = 2 + if data_len > 0 and rand_len > 0: + pos = 2 + self.rnd_start_pos(rand_len, self.random_server) + out_buf += self.encryptor.decrypt(self.recv_buf[pos: data_len + pos]) + self.last_server_hash = server_hash + if self.recv_id == 1: + self.server_info.tcp_mss = struct.unpack(' self.unit_len: + ret += self.pack_server_data(buf[:self.unit_len]) + buf = buf[self.unit_len:] + ret += self.pack_server_data(buf) + return ret + + def server_post_decrypt(self, buf): + if self.raw_trans: + return (buf, False) + self.recv_buf += buf + out_buf = b'' + sendback = False + + if not self.has_recv_header: + if len(self.recv_buf) >= 12 or len(self.recv_buf) in [7, 8]: + recv_len = min(len(self.recv_buf), 12) + mac_key = self.server_info.recv_iv + self.server_info.key + md5data = hmac.new(mac_key, self.recv_buf[:4], self.hashfunc).digest() + if md5data[:recv_len - 4] != self.recv_buf[4:recv_len]: + return self.not_match_return(self.recv_buf) + + if len(self.recv_buf) < 12 + 24: + return (b'', False) + + self.last_client_hash = md5data + uid = struct.unpack(' self.max_time_dif: + logging.info('%s: wrong timestamp, time_dif %d, data %s' % ( + self.no_compatible_method, time_dif, binascii.hexlify(head) + )) + return self.not_match_return(self.recv_buf) + elif self.server_info.data.insert(self.user_id, client_id, connection_id): + self.has_recv_header = True + self.client_id = client_id + self.connection_id = connection_id + else: + logging.info('%s: auth fail, data %s' % (self.no_compatible_method, binascii.hexlify(out_buf))) + return self.not_match_return(self.recv_buf) + + self.encryptor = encrypt.Encryptor( + to_bytes(base64.b64encode(self.user_key)) + to_bytes(base64.b64encode(self.last_client_hash)), 'rc4') + self.recv_buf = self.recv_buf[36:] + self.has_recv_header = True + sendback = True + + while len(self.recv_buf) > 4: + mac_key = self.user_key + struct.pack('= 4096: + self.raw_trans = True + self.recv_buf = b'' + if self.recv_id == 0: + logging.info(self.no_compatible_method + ': over size') + return (b'E' * 2048, False) + else: + raise Exception('server_post_decrype data error') + + if length + 4 > len(self.recv_buf): + break + + client_hash = hmac.new(mac_key, self.recv_buf[:length + 2], self.hashfunc).digest() + if client_hash[:2] != self.recv_buf[length + 2: length + 4]: + logging.info('%s: checksum error, data %s' % ( + self.no_compatible_method, binascii.hexlify(self.recv_buf[:length]) + )) + self.raw_trans = True + self.recv_buf = b'' + if self.recv_id == 0: + return (b'E' * 2048, False) + else: + raise Exception('server_post_decrype data uncorrect checksum') + + self.recv_id = (self.recv_id + 1) & 0xFFFFFFFF + pos = 2 + if data_len > 0 and rand_len > 0: + pos = 2 + self.rnd_start_pos(rand_len, self.random_client) + out_buf += self.encryptor.decrypt(self.recv_buf[pos: data_len + pos]) + self.last_client_hash = client_hash + self.recv_buf = self.recv_buf[length + 4:] + if data_len == 0: + sendback = True + + if out_buf: + self.server_info.data.update(self.user_id, self.client_id, self.connection_id) + return (out_buf, sendback) + + def client_udp_pre_encrypt(self, buf): + if self.user_key is None: + if b':' in to_bytes(self.server_info.protocol_param): + try: + items = to_bytes(self.server_info.protocol_param).split(':') + self.user_key = self.hashfunc(items[1]).digest() + self.user_id = struct.pack('= 1440: + return 0 + random.init_from_bin_len(last_hash, buf_size) + pos = bisect.bisect_left(self.data_size_list, buf_size + self.server_info.overhead) + final_pos = pos + random.next() % (len(self.data_size_list)) + # 鍋囪random鍧囧寑鍒嗗竷锛屽垯瓒婇暱鐨勫師濮嬫暟鎹暱搴﹁秺瀹规槗if false + if final_pos < len(self.data_size_list): + return self.data_size_list[final_pos] - buf_size - self.server_info.overhead + + # 涓婇潰if false鍚庨夋嫨2鍙疯ˉ鍏ㄦ暟缁勶紝姝ゅ鏈夋洿绮剧粏鐨勯暱搴﹀垎娈 + pos = bisect.bisect_left(self.data_size_list2, buf_size + self.server_info.overhead) + final_pos = pos + random.next() % (len(self.data_size_list2)) + if final_pos < len(self.data_size_list2): + return self.data_size_list2[final_pos] - buf_size - self.server_info.overhead + # final_pos 鎬绘槸鍒嗗竷鍦╬os~(data_size_list2.len-1)涔嬮棿 + if final_pos < pos + len(self.data_size_list2) - 1: + return 0 + # 鏈1/len(self.data_size_list2)鐨勬鐜囦笉婊¤冻涓婁竴涓猧f ? + # 鐞嗚涓婁笉浼氳繍琛屽埌姝ゅ锛屽洜姝ゅ彲浠ユ彃鍏ヨ繍琛屾柇瑷 ? + # assert False + + if buf_size > 1300: + return random.next() % 31 + if buf_size > 900: + return random.next() % 127 + if buf_size > 400: + return random.next() % 521 + return random.next() % 1021 + + +class auth_chain_c(auth_chain_b): + def __init__(self, method): + super(auth_chain_c, self).__init__(method) + self.salt = b"auth_chain_c" + self.no_compatible_method = 'auth_chain_c' + self.data_size_list0 = [] + + def init_data_size(self, key): + if self.data_size_list0: + self.data_size_list0 = [] + random = xorshift128plus() + random.init_from_bin(key) + # 琛ュ叏鏁扮粍闀夸负12~24-1 + list_len = random.next() % (8 + 16) + (4 + 8) + for i in range(0, list_len): + self.data_size_list0.append((int)(random.next() % 2340 % 2040 % 1440)) + self.data_size_list0.sort() + + def set_server_info(self, server_info): + self.server_info = server_info + try: + max_client = int(server_info.protocol_param.split('#')[0]) + except: + max_client = 64 + self.server_info.data.set_max_client(max_client) + self.init_data_size(self.server_info.key) + + def rnd_data_len(self, buf_size, last_hash, random): + other_data_size = buf_size + self.server_info.overhead + # 涓瀹氳鍦╮andom浣跨敤鍓嶅垵濮嬪寲锛屼互淇濊瘉鏈嶅姟鍣ㄤ笌瀹㈡埛绔悓姝ワ紝淇濊瘉鍖呭ぇ灏忛獙璇佺粨鏋滄纭 + random.init_from_bin_len(last_hash, buf_size) + # final_pos 鎬绘槸鍒嗗竷鍦╬os~(data_size_list0.len-1)涔嬮棿 + # 闄ら潪data_size_list0涓殑浠讳綍鍊煎潎杩囧皬浣垮叾鍏ㄩ儴閮芥棤娉曞绾砨uf + if other_data_size >= self.data_size_list0[-1]: + if other_data_size >= 1440: + return 0 + if other_data_size > 1300: + return random.next() % 31 + if other_data_size > 900: + return random.next() % 127 + if other_data_size > 400: + return random.next() % 521 + return random.next() % 1021 + + pos = bisect.bisect_left(self.data_size_list0, other_data_size) + # random select a size in the leftover data_size_list0 + final_pos = pos + random.next() % (len(self.data_size_list0) - pos) + return self.data_size_list0[final_pos] - other_data_size + + +class auth_chain_d(auth_chain_b): + def __init__(self, method): + super(auth_chain_d, self).__init__(method) + self.salt = b"auth_chain_d" + self.no_compatible_method = 'auth_chain_d' + self.data_size_list0 = [] + + def check_and_patch_data_size(self, random): + # append new item + # when the biggest item(first time) or the last append item(other time) are not big enough. + # but set a limit size (64) to avoid stack overflow. + if self.data_size_list0[-1] < 1300 and len(self.data_size_list0) < 64: + self.data_size_list0.append((int)(random.next() % 2340 % 2040 % 1440)) + self.check_and_patch_data_size(random) + + def init_data_size(self, key): + if self.data_size_list0: + self.data_size_list0 = [] + random = xorshift128plus() + random.init_from_bin(key) + # 琛ュ叏鏁扮粍闀夸负12~24-1 + list_len = random.next() % (8 + 16) + (4 + 8) + for i in range(0, list_len): + self.data_size_list0.append((int)(random.next() % 2340 % 2040 % 1440)) + self.data_size_list0.sort() + old_len = len(self.data_size_list0) + self.check_and_patch_data_size(random) + # if check_and_patch_data_size are work, re-sort again. + if old_len != len(self.data_size_list0): + self.data_size_list0.sort() + + def set_server_info(self, server_info): + self.server_info = server_info + try: + max_client = int(server_info.protocol_param.split('#')[0]) + except: + max_client = 64 + self.server_info.data.set_max_client(max_client) + self.init_data_size(self.server_info.key) + + def rnd_data_len(self, buf_size, last_hash, random): + other_data_size = buf_size + self.server_info.overhead + # if other_data_size > the bigest item in data_size_list0, not padding any data + if other_data_size >= self.data_size_list0[-1]: + return 0 + + random.init_from_bin_len(last_hash, buf_size) + pos = bisect.bisect_left(self.data_size_list0, other_data_size) + # random select a size in the leftover data_size_list0 + final_pos = pos + random.next() % (len(self.data_size_list0) - pos) + return self.data_size_list0[final_pos] - other_data_size diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/obfsplugin/http_simple.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/obfsplugin/http_simple.py new file mode 100644 index 000000000..ff3c5fdfb --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/obfsplugin/http_simple.py @@ -0,0 +1,315 @@ +#!/usr/bin/env python +# +# Copyright 2015-2015 breakwa11 +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import os +import sys +import hashlib +import logging +import binascii +import struct +import base64 +import datetime +import random + +from shadowsocks import common +from shadowsocks.obfsplugin import plain +from shadowsocks.common import to_bytes, to_str, ord, chr + +def create_http_simple_obfs(method): + return http_simple(method) + +def create_http_post_obfs(method): + return http_post(method) + +def create_random_head_obfs(method): + return random_head(method) + +obfs_map = { + 'http_simple': (create_http_simple_obfs,), + 'http_simple_compatible': (create_http_simple_obfs,), + 'http_post': (create_http_post_obfs,), + 'http_post_compatible': (create_http_post_obfs,), + 'random_head': (create_random_head_obfs,), + 'random_head_compatible': (create_random_head_obfs,), +} + +def match_begin(str1, str2): + if len(str1) >= len(str2): + if str1[:len(str2)] == str2: + return True + return False + +class http_simple(plain.plain): + def __init__(self, method): + self.method = method + self.has_sent_header = False + self.has_recv_header = False + self.host = None + self.port = 0 + self.recv_buffer = b'' + # TODO user config user_agent + self.user_agent = [b"Mozilla/5.0 (Windows NT 6.3; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0", + b"Mozilla/5.0 (Windows NT 6.3; WOW64; rv:40.0) Gecko/20100101 Firefox/44.0", + b"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36", + b"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Ubuntu/11.10 Chromium/27.0.1453.93 Chrome/27.0.1453.93 Safari/537.36", + b"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:35.0) Gecko/20100101 Firefox/35.0", + b"Mozilla/5.0 (compatible; WOW64; MSIE 10.0; Windows NT 6.2)", + b"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27", + b"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.3; Trident/7.0; .NET4.0E; .NET4.0C)", + b"Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko", + b"Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/BuildID) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36", + b"Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3", + b"Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3"] + + def encode_head(self, buf): + hexstr = binascii.hexlify(buf) + chs = [] + for i in range(0, len(hexstr), 2): + chs.append(b"%" + hexstr[i:i+2]) + return b''.join(chs) + + def client_encode(self, buf): + if self.has_sent_header: + return buf + head_size = len(self.server_info.iv) + self.server_info.head_len + if len(buf) - head_size > 64: + headlen = head_size + random.randint(0, 64) + else: + headlen = len(buf) + headdata = buf[:headlen] + buf = buf[headlen:] + port = b'' + if self.server_info.port != 80: + port = b':' + to_bytes(str(self.server_info.port)) + body = None + hosts = (self.server_info.obfs_param or self.server_info.host) + pos = hosts.find("#") + if pos >= 0: + body = hosts[pos + 1:].replace("\n", "\r\n") + body = body.replace("\\n", "\r\n") + hosts = hosts[:pos] + hosts = hosts.split(',') + host = random.choice(hosts) + http_head = b"GET /" + self.encode_head(headdata) + b" HTTP/1.1\r\n" + http_head += b"Host: " + to_bytes(host) + port + b"\r\n" + if body: + http_head += body + "\r\n\r\n" + else: + http_head += b"User-Agent: " + random.choice(self.user_agent) + b"\r\n" + http_head += b"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-US,en;q=0.8\r\nAccept-Encoding: gzip, deflate\r\nDNT: 1\r\nConnection: keep-alive\r\n\r\n" + self.has_sent_header = True + return http_head + buf + + def client_decode(self, buf): + if self.has_recv_header: + return (buf, False) + pos = buf.find(b'\r\n\r\n') + if pos >= 0: + self.has_recv_header = True + return (buf[pos + 4:], False) + else: + return (b'', False) + + def server_encode(self, buf): + if self.has_sent_header: + return buf + + header = b'HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nContent-Encoding: gzip\r\nContent-Type: text/html\r\nDate: ' + header += to_bytes(datetime.datetime.now().strftime('%a, %d %b %Y %H:%M:%S GMT')) + header += b'\r\nServer: nginx\r\nVary: Accept-Encoding\r\n\r\n' + self.has_sent_header = True + return header + buf + + def get_data_from_http_header(self, buf): + ret_buf = b'' + lines = buf.split(b'\r\n') + if lines and len(lines) > 1: + hex_items = lines[0].split(b'%') + if hex_items and len(hex_items) > 1: + for index in range(1, len(hex_items)): + if len(hex_items[index]) < 2: + ret_buf += binascii.unhexlify('0' + hex_items[index]) + break + elif len(hex_items[index]) > 2: + ret_buf += binascii.unhexlify(hex_items[index][:2]) + break + else: + ret_buf += binascii.unhexlify(hex_items[index]) + return ret_buf + return b'' + + def get_host_from_http_header(self, buf): + ret_buf = b'' + lines = buf.split(b'\r\n') + if lines and len(lines) > 1: + for line in lines: + if match_begin(line, b"Host: "): + return common.to_str(line[6:]) + + def not_match_return(self, buf): + self.has_sent_header = True + self.has_recv_header = True + if self.method == 'http_simple': + return (b'E'*2048, False, False) + return (buf, True, False) + + def error_return(self, buf): + self.has_sent_header = True + self.has_recv_header = True + return (b'E'*2048, False, False) + + def server_decode(self, buf): + if self.has_recv_header: + return (buf, True, False) + + self.recv_buffer += buf + buf = self.recv_buffer + if len(buf) > 10: + if match_begin(buf, b'GET ') or match_begin(buf, b'POST '): + if len(buf) > 65536: + self.recv_buffer = None + logging.warn('http_simple: over size') + return self.not_match_return(buf) + else: #not http header, run on original protocol + self.recv_buffer = None + logging.debug('http_simple: not match begin') + return self.not_match_return(buf) + else: + return (b'', True, False) + + if b'\r\n\r\n' in buf: + datas = buf.split(b'\r\n\r\n', 1) + ret_buf = self.get_data_from_http_header(buf) + host = self.get_host_from_http_header(buf) + if host and self.server_info.obfs_param: + pos = host.find(":") + if pos >= 0: + host = host[:pos] + hosts = self.server_info.obfs_param.split(',') + if host not in hosts: + return self.not_match_return(buf) + if len(ret_buf) < 4: + return self.error_return(buf) + if len(datas) > 1: + ret_buf += datas[1] + if len(ret_buf) >= 13: + self.has_recv_header = True + return (ret_buf, True, False) + return self.not_match_return(buf) + else: + return (b'', True, False) + +class http_post(http_simple): + def __init__(self, method): + super(http_post, self).__init__(method) + + def boundary(self): + return to_bytes(''.join([random.choice("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") for i in range(32)])) + + def client_encode(self, buf): + if self.has_sent_header: + return buf + head_size = len(self.server_info.iv) + self.server_info.head_len + if len(buf) - head_size > 64: + headlen = head_size + random.randint(0, 64) + else: + headlen = len(buf) + headdata = buf[:headlen] + buf = buf[headlen:] + port = b'' + if self.server_info.port != 80: + port = b':' + to_bytes(str(self.server_info.port)) + body = None + hosts = (self.server_info.obfs_param or self.server_info.host) + pos = hosts.find("#") + if pos >= 0: + body = hosts[pos + 1:].replace("\\n", "\r\n") + hosts = hosts[:pos] + hosts = hosts.split(',') + host = random.choice(hosts) + http_head = b"POST /" + self.encode_head(headdata) + b" HTTP/1.1\r\n" + http_head += b"Host: " + to_bytes(host) + port + b"\r\n" + if body: + http_head += body + "\r\n\r\n" + else: + http_head += b"User-Agent: " + random.choice(self.user_agent) + b"\r\n" + http_head += b"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-US,en;q=0.8\r\nAccept-Encoding: gzip, deflate\r\n" + http_head += b"Content-Type: multipart/form-data; boundary=" + self.boundary() + b"\r\nDNT: 1\r\n" + http_head += b"Connection: keep-alive\r\n\r\n" + self.has_sent_header = True + return http_head + buf + + def not_match_return(self, buf): + self.has_sent_header = True + self.has_recv_header = True + if self.method == 'http_post': + return (b'E'*2048, False, False) + return (buf, True, False) + +class random_head(plain.plain): + def __init__(self, method): + self.method = method + self.has_sent_header = False + self.has_recv_header = False + self.raw_trans_sent = False + self.raw_trans_recv = False + self.send_buffer = b'' + + def client_encode(self, buf): + if self.raw_trans_sent: + return buf + self.send_buffer += buf + if not self.has_sent_header: + self.has_sent_header = True + data = os.urandom(common.ord(os.urandom(1)[0]) % 96 + 4) + crc = (0xffffffff - binascii.crc32(data)) & 0xffffffff + return data + struct.pack('= len(str2): + if str1[:len(str2)] == str2: + return True + return False + +class obfs_auth_data(object): + def __init__(self): + self.client_data = lru_cache.LRUCache(60 * 5) + self.client_id = os.urandom(32) + self.startup_time = int(time.time() - 60 * 30) & 0xFFFFFFFF + self.ticket_buf = {} + +class tls_ticket_auth(plain.plain): + def __init__(self, method): + self.method = method + self.handshake_status = 0 + self.send_buffer = b'' + self.recv_buffer = b'' + self.client_id = b'' + self.max_time_dif = 60 * 60 * 24 # time dif (second) setting + self.tls_version = b'\x03\x03' + self.overhead = 5 + + def init_data(self): + return obfs_auth_data() + + def get_overhead(self, direction): # direction: true for c->s false for s->c + return self.overhead + + def sni(self, url): + url = common.to_bytes(url) + data = b"\x00" + struct.pack('>H', len(url)) + url + data = b"\x00\x00" + struct.pack('>H', len(data) + 2) + struct.pack('>H', len(data)) + data + return data + + def pack_auth_data(self, client_id): + utc_time = int(time.time()) & 0xFFFFFFFF + data = struct.pack('>I', utc_time) + os.urandom(18) + data += hmac.new(self.server_info.key + client_id, data, hashlib.sha1).digest()[:10] + return data + + def client_encode(self, buf): + if self.handshake_status == -1: + return buf + if self.handshake_status == 8: + ret = b'' + while len(buf) > 2048: + size = min(struct.unpack('>H', os.urandom(2))[0] % 4096 + 100, len(buf)) + ret += b"\x17" + self.tls_version + struct.pack('>H', size) + buf[:size] + buf = buf[size:] + if len(buf) > 0: + ret += b"\x17" + self.tls_version + struct.pack('>H', len(buf)) + buf + return ret + if len(buf) > 0: + self.send_buffer += b"\x17" + self.tls_version + struct.pack('>H', len(buf)) + buf + if self.handshake_status == 0: + self.handshake_status = 1 + data = self.tls_version + self.pack_auth_data(self.server_info.data.client_id) + b"\x20" + self.server_info.data.client_id + binascii.unhexlify(b"001cc02bc02fcca9cca8cc14cc13c00ac014c009c013009c0035002f000a" + b"0100") + ext = binascii.unhexlify(b"ff01000100") + host = self.server_info.obfs_param or self.server_info.host + if host and host[-1] in string.digits: + host = '' + hosts = host.split(',') + host = random.choice(hosts) + ext += self.sni(host) + ext += b"\x00\x17\x00\x00" + if host not in self.server_info.data.ticket_buf: + self.server_info.data.ticket_buf[host] = os.urandom((struct.unpack('>H', os.urandom(2))[0] % 17 + 8) * 16) + ext += b"\x00\x23" + struct.pack('>H', len(self.server_info.data.ticket_buf[host])) + self.server_info.data.ticket_buf[host] + ext += binascii.unhexlify(b"000d001600140601060305010503040104030301030302010203") + ext += binascii.unhexlify(b"000500050100000000") + ext += binascii.unhexlify(b"00120000") + ext += binascii.unhexlify(b"75500000") + ext += binascii.unhexlify(b"000b00020100") + ext += binascii.unhexlify(b"000a0006000400170018") + data += struct.pack('>H', len(ext)) + ext + data = b"\x01\x00" + struct.pack('>H', len(data)) + data + data = b"\x16\x03\x01" + struct.pack('>H', len(data)) + data + return data + elif self.handshake_status == 1 and len(buf) == 0: + data = b"\x14" + self.tls_version + b"\x00\x01\x01" #ChangeCipherSpec + data += b"\x16" + self.tls_version + b"\x00\x20" + os.urandom(22) #Finished + data += hmac.new(self.server_info.key + self.server_info.data.client_id, data, hashlib.sha1).digest()[:10] + ret = data + self.send_buffer + self.send_buffer = b'' + self.handshake_status = 8 + return ret + return b'' + + def client_decode(self, buf): + if self.handshake_status == -1: + return (buf, False) + + if self.handshake_status == 8: + ret = b'' + self.recv_buffer += buf + while len(self.recv_buffer) > 5: + if ord(self.recv_buffer[0]) != 0x17: + logging.info("data = %s" % (binascii.hexlify(self.recv_buffer))) + raise Exception('server_decode appdata error') + size = struct.unpack('>H', self.recv_buffer[3:5])[0] + if len(self.recv_buffer) < size + 5: + break + buf = self.recv_buffer[5:size+5] + ret += buf + self.recv_buffer = self.recv_buffer[size+5:] + return (ret, False) + + if len(buf) < 11 + 32 + 1 + 32: + raise Exception('client_decode data error') + verify = buf[11:33] + if hmac.new(self.server_info.key + self.server_info.data.client_id, verify, hashlib.sha1).digest()[:10] != buf[33:43]: + raise Exception('client_decode data error') + if hmac.new(self.server_info.key + self.server_info.data.client_id, buf[:-10], hashlib.sha1).digest()[:10] != buf[-10:]: + raise Exception('client_decode data error') + return (b'', True) + + def server_encode(self, buf): + if self.handshake_status == -1: + return buf + if (self.handshake_status & 8) == 8: + ret = b'' + while len(buf) > 2048: + size = min(struct.unpack('>H', os.urandom(2))[0] % 4096 + 100, len(buf)) + ret += b"\x17" + self.tls_version + struct.pack('>H', size) + buf[:size] + buf = buf[size:] + if len(buf) > 0: + ret += b"\x17" + self.tls_version + struct.pack('>H', len(buf)) + buf + return ret + self.handshake_status |= 8 + data = self.tls_version + self.pack_auth_data(self.client_id) + b"\x20" + self.client_id + binascii.unhexlify(b"c02f000005ff01000100") + data = b"\x02\x00" + struct.pack('>H', len(data)) + data #server hello + data = b"\x16" + self.tls_version + struct.pack('>H', len(data)) + data + if random.randint(0, 8) < 1: + ticket = os.urandom((struct.unpack('>H', os.urandom(2))[0] % 164) * 2 + 64) + ticket = struct.pack('>H', len(ticket) + 4) + b"\x04\x00" + struct.pack('>H', len(ticket)) + ticket + data += b"\x16" + self.tls_version + ticket #New session ticket + data += b"\x14" + self.tls_version + b"\x00\x01\x01" #ChangeCipherSpec + finish_len = random.choice([32, 40]) + data += b"\x16" + self.tls_version + struct.pack('>H', finish_len) + os.urandom(finish_len - 10) #Finished + data += hmac.new(self.server_info.key + self.client_id, data, hashlib.sha1).digest()[:10] + if buf: + data += self.server_encode(buf) + return data + + def decode_error_return(self, buf): + self.handshake_status = -1 + if self.overhead > 0: + self.server_info.overhead -= self.overhead + self.overhead = 0 + if self.method in ['tls1.2_ticket_auth', 'tls1.2_ticket_fastauth']: + return (b'E'*2048, False, False) + return (buf, True, False) + + def server_decode(self, buf): + if self.handshake_status == -1: + return (buf, True, False) + + if (self.handshake_status & 4) == 4: + ret = b'' + self.recv_buffer += buf + while len(self.recv_buffer) > 5: + if ord(self.recv_buffer[0]) != 0x17 or ord(self.recv_buffer[1]) != 0x3 or ord(self.recv_buffer[2]) != 0x3: + logging.info("data = %s" % (binascii.hexlify(self.recv_buffer))) + raise Exception('server_decode appdata error') + size = struct.unpack('>H', self.recv_buffer[3:5])[0] + if len(self.recv_buffer) < size + 5: + break + ret += self.recv_buffer[5:size+5] + self.recv_buffer = self.recv_buffer[size+5:] + return (ret, True, False) + + if (self.handshake_status & 1) == 1: + self.recv_buffer += buf + buf = self.recv_buffer + verify = buf + if len(buf) < 11: + raise Exception('server_decode data error') + if not match_begin(buf, b"\x14" + self.tls_version + b"\x00\x01\x01"): #ChangeCipherSpec + raise Exception('server_decode data error') + buf = buf[6:] + if not match_begin(buf, b"\x16" + self.tls_version + b"\x00"): #Finished + raise Exception('server_decode data error') + verify_len = struct.unpack('>H', buf[3:5])[0] + 1 # 11 - 10 + if len(verify) < verify_len + 10: + return (b'', False, False) + if hmac.new(self.server_info.key + self.client_id, verify[:verify_len], hashlib.sha1).digest()[:10] != verify[verify_len:verify_len+10]: + raise Exception('server_decode data error') + self.recv_buffer = verify[verify_len + 10:] + status = self.handshake_status + self.handshake_status |= 4 + ret = self.server_decode(b'') + return ret; + + #raise Exception("handshake data = %s" % (binascii.hexlify(buf))) + self.recv_buffer += buf + buf = self.recv_buffer + ogn_buf = buf + if len(buf) < 3: + return (b'', False, False) + if not match_begin(buf, b'\x16\x03\x01'): + return self.decode_error_return(ogn_buf) + buf = buf[3:] + header_len = struct.unpack('>H', buf[:2])[0] + if header_len > len(buf) - 2: + return (b'', False, False) + + self.recv_buffer = self.recv_buffer[header_len + 5:] + self.handshake_status = 1 + buf = buf[2:header_len + 2] + if not match_begin(buf, b'\x01\x00'): #client hello + logging.info("tls_auth not client hello message") + return self.decode_error_return(ogn_buf) + buf = buf[2:] + if struct.unpack('>H', buf[:2])[0] != len(buf) - 2: + logging.info("tls_auth wrong message size") + return self.decode_error_return(ogn_buf) + buf = buf[2:] + if not match_begin(buf, self.tls_version): + logging.info("tls_auth wrong tls version") + return self.decode_error_return(ogn_buf) + buf = buf[2:] + verifyid = buf[:32] + buf = buf[32:] + sessionid_len = ord(buf[0]) + if sessionid_len < 32: + logging.info("tls_auth wrong sessionid_len") + return self.decode_error_return(ogn_buf) + sessionid = buf[1:sessionid_len + 1] + buf = buf[sessionid_len+1:] + self.client_id = sessionid + sha1 = hmac.new(self.server_info.key + sessionid, verifyid[:22], hashlib.sha1).digest()[:10] + utc_time = struct.unpack('>I', verifyid[:4])[0] + time_dif = common.int32((int(time.time()) & 0xffffffff) - utc_time) + if self.server_info.obfs_param: + try: + self.max_time_dif = int(self.server_info.obfs_param) + except: + pass + if self.max_time_dif > 0 and (time_dif < -self.max_time_dif or time_dif > self.max_time_dif \ + or common.int32(utc_time - self.server_info.data.startup_time) < -self.max_time_dif / 2): + logging.info("tls_auth wrong time") + return self.decode_error_return(ogn_buf) + if sha1 != verifyid[22:]: + logging.info("tls_auth wrong sha1") + return self.decode_error_return(ogn_buf) + if self.server_info.data.client_data.get(verifyid[:22]): + logging.info("replay attack detect, id = %s" % (binascii.hexlify(verifyid))) + return self.decode_error_return(ogn_buf) + self.server_info.data.client_data.sweep() + self.server_info.data.client_data[verifyid[:22]] = sessionid + if len(self.recv_buffer) >= 11: + ret = self.server_decode(b'') + return (ret[0], True, True) + # (buffer_to_recv, is_need_decrypt, is_need_to_encode_and_send_back) + return (b'', False, True) + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/obfsplugin/plain.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/obfsplugin/plain.py new file mode 100644 index 000000000..8c6355c38 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/obfsplugin/plain.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +# +# Copyright 2015-2015 breakwa11 +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import os +import sys +import hashlib +import logging + +from shadowsocks.common import ord + +def create_obfs(method): + return plain(method) + +obfs_map = { + 'plain': (create_obfs,), + 'origin': (create_obfs,), +} + +class plain(object): + def __init__(self, method): + self.method = method + self.server_info = None + + def init_data(self): + return b'' + + def get_overhead(self, direction): # direction: true for c->s false for s->c + return 0 + + def get_server_info(self): + return self.server_info + + def set_server_info(self, server_info): + self.server_info = server_info + + def client_pre_encrypt(self, buf): + return buf + + def client_encode(self, buf): + return buf + + def client_decode(self, buf): + # (buffer_to_recv, is_need_to_encode_and_send_back) + return (buf, False) + + def client_post_decrypt(self, buf): + return buf + + def server_pre_encrypt(self, buf): + return buf + + def server_encode(self, buf): + return buf + + def server_decode(self, buf): + # (buffer_to_recv, is_need_decrypt, is_need_to_encode_and_send_back) + return (buf, True, False) + + def server_post_decrypt(self, buf): + return (buf, False) + + def client_udp_pre_encrypt(self, buf): + return buf + + def client_udp_post_decrypt(self, buf): + return buf + + def server_udp_pre_encrypt(self, buf, uid): + return buf + + def server_udp_post_decrypt(self, buf): + return (buf, None) + + def dispose(self): + pass + + def get_head_size(self, buf, def_value): + if len(buf) < 2: + return def_value + head_type = ord(buf[0]) & 0x7 + if head_type == 1: + return 7 + if head_type == 4: + return 19 + if head_type == 3: + return 4 + ord(buf[1]) + return def_value + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/obfsplugin/verify.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/obfsplugin/verify.py new file mode 100644 index 000000000..0dc0ca6d1 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/obfsplugin/verify.py @@ -0,0 +1,154 @@ +#!/usr/bin/env python +# +# Copyright 2015-2015 breakwa11 +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import os +import sys +import hashlib +import logging +import binascii +import base64 +import time +import datetime +import random +import struct +import zlib +import hmac +import hashlib + +import shadowsocks +from shadowsocks import common +from shadowsocks.obfsplugin import plain +from shadowsocks.common import to_bytes, to_str, ord, chr + +def create_verify_deflate(method): + return verify_deflate(method) + +obfs_map = { + 'verify_deflate': (create_verify_deflate,), +} + +def match_begin(str1, str2): + if len(str1) >= len(str2): + if str1[:len(str2)] == str2: + return True + return False + +class obfs_verify_data(object): + def __init__(self): + pass + +class verify_base(plain.plain): + def __init__(self, method): + super(verify_base, self).__init__(method) + self.method = method + + def init_data(self): + return obfs_verify_data() + + def set_server_info(self, server_info): + self.server_info = server_info + + def client_encode(self, buf): + return buf + + def client_decode(self, buf): + return (buf, False) + + def server_encode(self, buf): + return buf + + def server_decode(self, buf): + return (buf, True, False) + +class verify_deflate(verify_base): + def __init__(self, method): + super(verify_deflate, self).__init__(method) + self.recv_buf = b'' + self.unit_len = 32700 + self.decrypt_packet_num = 0 + self.raw_trans = False + + def pack_data(self, buf): + if len(buf) == 0: + return b'' + data = zlib.compress(buf) + data = struct.pack('>H', len(data)) + data[2:] + return data + + def client_pre_encrypt(self, buf): + ret = b'' + while len(buf) > self.unit_len: + ret += self.pack_data(buf[:self.unit_len]) + buf = buf[self.unit_len:] + ret += self.pack_data(buf) + return ret + + def client_post_decrypt(self, buf): + if self.raw_trans: + return buf + self.recv_buf += buf + out_buf = b'' + while len(self.recv_buf) > 2: + length = struct.unpack('>H', self.recv_buf[:2])[0] + if length >= 32768 or length < 6: + self.raw_trans = True + self.recv_buf = b'' + raise Exception('client_post_decrypt data error') + if length > len(self.recv_buf): + break + + out_buf += zlib.decompress(b'x\x9c' + self.recv_buf[2:length]) + self.recv_buf = self.recv_buf[length:] + + if out_buf: + self.decrypt_packet_num += 1 + return out_buf + + def server_pre_encrypt(self, buf): + ret = b'' + while len(buf) > self.unit_len: + ret += self.pack_data(buf[:self.unit_len]) + buf = buf[self.unit_len:] + ret += self.pack_data(buf) + return ret + + def server_post_decrypt(self, buf): + if self.raw_trans: + return (buf, False) + self.recv_buf += buf + out_buf = b'' + while len(self.recv_buf) > 2: + length = struct.unpack('>H', self.recv_buf[:2])[0] + if length >= 32768 or length < 6: + self.raw_trans = True + self.recv_buf = b'' + if self.decrypt_packet_num == 0: + return (b'E'*2048, False) + else: + raise Exception('server_post_decrype data error') + if length > len(self.recv_buf): + break + + out_buf += zlib.decompress(b'\x78\x9c' + self.recv_buf[2:length]) + self.recv_buf = self.recv_buf[length:] + + if out_buf: + self.decrypt_packet_num += 1 + return (out_buf, False) + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/ordereddict.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/ordereddict.py new file mode 100644 index 000000000..e1918f5e0 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/ordereddict.py @@ -0,0 +1,214 @@ +import collections + +################################################################################ +### OrderedDict +################################################################################ + +class OrderedDict(dict): + 'Dictionary that remembers insertion order' + # An inherited dict maps keys to values. + # The inherited dict provides __getitem__, __len__, __contains__, and get. + # The remaining methods are order-aware. + # Big-O running times for all methods are the same as regular dictionaries. + + # The internal self.__map dict maps keys to links in a doubly linked list. + # The circular doubly linked list starts and ends with a sentinel element. + # The sentinel element never gets deleted (this simplifies the algorithm). + # Each link is stored as a list of length three: [PREV, NEXT, KEY]. + + def __init__(*args, **kwds): + '''Initialize an ordered dictionary. The signature is the same as + regular dictionaries, but keyword arguments are not recommended because + their insertion order is arbitrary. + + ''' + if not args: + raise TypeError("descriptor '__init__' of 'OrderedDict' object " + "needs an argument") + self = args[0] + args = args[1:] + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__root + except AttributeError: + self.__root = root = [] # sentinel node + root[:] = [root, root, None] + self.__map = {} + self.__update(*args, **kwds) + + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): + 'od.__setitem__(i, y) <==> od[i]=y' + # Setting a new item creates a new link at the end of the linked list, + # and the inherited dictionary is updated with the new key/value pair. + if key not in self: + root = self.__root + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + return dict_setitem(self, key, value) + + def __delitem__(self, key, dict_delitem=dict.__delitem__): + 'od.__delitem__(y) <==> del od[y]' + # Deleting an existing item uses self.__map to find the link which gets + # removed by updating the links in the predecessor and successor nodes. + dict_delitem(self, key) + link_prev, link_next, _ = self.__map.pop(key) + link_prev[1] = link_next # update link_prev[NEXT] + link_next[0] = link_prev # update link_next[PREV] + + def __iter__(self): + 'od.__iter__() <==> iter(od)' + # Traverse the linked list in order. + root = self.__root + curr = root[1] # start at the first node + while curr is not root: + yield curr[2] # yield the curr[KEY] + curr = curr[1] # move to next node + + def __reversed__(self): + 'od.__reversed__() <==> reversed(od)' + # Traverse the linked list in reverse order. + root = self.__root + curr = root[0] # start at the last node + while curr is not root: + yield curr[2] # yield the curr[KEY] + curr = curr[0] # move to previous node + + def clear(self): + 'od.clear() -> None. Remove all items from od.' + root = self.__root + root[:] = [root, root, None] + self.__map.clear() + dict.clear(self) + + # -- the following methods do not depend on the internal structure -- + + def keys(self): + 'od.keys() -> list of keys in od' + return list(self) + + def values(self): + 'od.values() -> list of values in od' + return [self[key] for key in self] + + def items(self): + 'od.items() -> list of (key, value) pairs in od' + return [(key, self[key]) for key in self] + + def iterkeys(self): + 'od.iterkeys() -> an iterator over the keys in od' + return iter(self) + + def itervalues(self): + 'od.itervalues -> an iterator over the values in od' + for k in self: + yield self[k] + + def iteritems(self): + 'od.iteritems -> an iterator over the (key, value) pairs in od' + for k in self: + yield (k, self[k]) + + update = collections.MutableMapping.update + + __update = update # let subclasses override update without breaking __init__ + + __marker = object() + + def pop(self, key, default=__marker): + '''od.pop(k[,d]) -> v, remove specified key and return the corresponding + value. If key is not found, d is returned if given, otherwise KeyError + is raised. + + ''' + if key in self: + result = self[key] + del self[key] + return result + if default is self.__marker: + raise KeyError(key) + return default + + def setdefault(self, key, default=None): + 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' + if key in self: + return self[key] + self[key] = default + return default + + def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' + if not self: + raise KeyError('dictionary is empty') + key = next(reversed(self) if last else iter(self)) + value = self.pop(key) + return key, value + + def __repr__(self, _repr_running={}): + 'od.__repr__() <==> repr(od)' + call_key = id(self), _get_ident() + if call_key in _repr_running: + return '...' + _repr_running[call_key] = 1 + try: + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + finally: + del _repr_running[call_key] + + def __reduce__(self): + 'Return state information for pickling' + items = [[k, self[k]] for k in self] + inst_dict = vars(self).copy() + for k in vars(OrderedDict()): + inst_dict.pop(k, None) + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def copy(self): + 'od.copy() -> a shallow copy of od' + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S. + If not specified, the value defaults to None. + + ''' + self = cls() + for key in iterable: + self[key] = value + return self + + def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' + if isinstance(other, OrderedDict): + return dict.__eq__(self, other) and all(_imap(_eq, self, other)) + return dict.__eq__(self, other) + + def __ne__(self, other): + 'od.__ne__(y) <==> od!=y' + return not self == other + + # -- the following methods support python 3.x style dictionary views -- + + def viewkeys(self): + "od.viewkeys() -> a set-like object providing a view on od's keys" + return KeysView(self) + + def viewvalues(self): + "od.viewvalues() -> an object providing a view on od's values" + return ValuesView(self) + + def viewitems(self): + "od.viewitems() -> a set-like object providing a view on od's items" + return ItemsView(self) + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/run.sh b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/run.sh new file mode 100755 index 000000000..43720308d --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/run.sh @@ -0,0 +1,7 @@ +#!/bin/bash +cd `dirname $0` +python_ver=$(ls /usr/bin|grep -e "^python[23]\.[1-9]\+$"|tail -1) +eval $(ps -ef | grep "[0-9] ${python_ver} server\\.py a" | awk '{print "kill "$2}') +ulimit -n 512000 +nohup ${python_ver} server.py a>> /dev/null 2>&1 & + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/server.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/server.py new file mode 100755 index 000000000..081538933 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/server.py @@ -0,0 +1,221 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2015 clowwindy +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import sys +import os +import logging +import signal + +if __name__ == '__main__': + import inspect + + file_path = os.path.dirname(os.path.realpath(inspect.getfile(inspect.currentframe()))) + sys.path.insert(0, os.path.join(file_path, '../')) + +from shadowsocks import shell, daemon, eventloop, tcprelay, udprelay, \ + asyncdns, manager, common + + +def main(): + shell.check_python() + + config = shell.get_config(False) + + shell.log_shadowsocks_version() + + daemon.daemon_exec(config) + + try: + import resource + logging.info( + 'current process RLIMIT_NOFILE resource: soft %d hard %d' % resource.getrlimit(resource.RLIMIT_NOFILE)) + except ImportError: + pass + + if config['port_password']: + pass + else: + config['port_password'] = {} + server_port = config['server_port'] + if type(server_port) == list: + for a_server_port in server_port: + config['port_password'][a_server_port] = config['password'] + else: + config['port_password'][str(server_port)] = config['password'] + + if not config.get('dns_ipv6', False): + asyncdns.IPV6_CONNECTION_SUPPORT = False + + if config.get('manager_address', 0): + logging.info('entering manager mode') + manager.run(config) + return + + tcp_servers = [] + udp_servers = [] + dns_resolver = asyncdns.DNSResolver(config['black_hostname_list']) + if int(config['workers']) > 1: + stat_counter_dict = None + else: + stat_counter_dict = {} + port_password = config['port_password'] + config_password = config.get('password', 'm') + del config['port_password'] + for port, password_obfs in port_password.items(): + method = config["method"] + protocol = config.get("protocol", 'origin') + protocol_param = config.get("protocol_param", '') + obfs = config.get("obfs", 'plain') + obfs_param = config.get("obfs_param", '') + bind = config.get("out_bind", '') + bindv6 = config.get("out_bindv6", '') + if type(password_obfs) == list: + password = password_obfs[0] + obfs = common.to_str(password_obfs[1]) + if len(password_obfs) > 2: + protocol = common.to_str(password_obfs[2]) + elif type(password_obfs) == dict: + password = password_obfs.get('password', config_password) + method = common.to_str(password_obfs.get('method', method)) + protocol = common.to_str(password_obfs.get('protocol', protocol)) + protocol_param = common.to_str(password_obfs.get('protocol_param', protocol_param)) + obfs = common.to_str(password_obfs.get('obfs', obfs)) + obfs_param = common.to_str(password_obfs.get('obfs_param', obfs_param)) + bind = password_obfs.get('out_bind', bind) + bindv6 = password_obfs.get('out_bindv6', bindv6) + else: + password = password_obfs + a_config = config.copy() + ipv6_ok = False + logging.info("server start with protocol[%s] password [%s] method [%s] obfs [%s] obfs_param [%s]" % + (protocol, password, method, obfs, obfs_param)) + if 'server_ipv6' in a_config: + try: + if len(a_config['server_ipv6']) > 2 and a_config['server_ipv6'][0] == "[" and a_config['server_ipv6'][ + -1] == "]": + a_config['server_ipv6'] = a_config['server_ipv6'][1:-1] + a_config['server_port'] = int(port) + a_config['password'] = password + a_config['method'] = method + a_config['protocol'] = protocol + a_config['protocol_param'] = protocol_param + a_config['obfs'] = obfs + a_config['obfs_param'] = obfs_param + a_config['out_bind'] = bind + a_config['out_bindv6'] = bindv6 + a_config['server'] = a_config['server_ipv6'] + logging.info("starting server at [%s]:%d" % + (a_config['server'], int(port))) + tcp_servers.append(tcprelay.TCPRelay(a_config, dns_resolver, False, stat_counter=stat_counter_dict)) + udp_servers.append(udprelay.UDPRelay(a_config, dns_resolver, False, stat_counter=stat_counter_dict)) + if a_config['server_ipv6'] == b"::": + ipv6_ok = True + except Exception as e: + shell.print_exception(e) + + try: + a_config = config.copy() + a_config['server_port'] = int(port) + a_config['password'] = password + a_config['method'] = method + a_config['protocol'] = protocol + a_config['protocol_param'] = protocol_param + a_config['obfs'] = obfs + a_config['obfs_param'] = obfs_param + a_config['out_bind'] = bind + a_config['out_bindv6'] = bindv6 + logging.info("starting server at %s:%d" % + (a_config['server'], int(port))) + tcp_servers.append(tcprelay.TCPRelay(a_config, dns_resolver, False, stat_counter=stat_counter_dict)) + udp_servers.append(udprelay.UDPRelay(a_config, dns_resolver, False, stat_counter=stat_counter_dict)) + except Exception as e: + if not ipv6_ok: + shell.print_exception(e) + + def run_server(): + def child_handler(signum, _): + logging.warn('received SIGQUIT, doing graceful shutting down..') + list(map(lambda s: s.close(next_tick=True), + tcp_servers + udp_servers)) + + signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM), + child_handler) + + def int_handler(signum, _): + sys.exit(1) + + signal.signal(signal.SIGINT, int_handler) + + try: + loop = eventloop.EventLoop() + dns_resolver.add_to_loop(loop) + list(map(lambda s: s.add_to_loop(loop), tcp_servers + udp_servers)) + + daemon.set_user(config.get('user', None)) + loop.run() + except Exception as e: + shell.print_exception(e) + sys.exit(1) + + if int(config['workers']) > 1: + if os.name == 'posix': + children = [] + is_child = False + for i in range(0, int(config['workers'])): + r = os.fork() + if r == 0: + logging.info('worker started') + is_child = True + run_server() + break + else: + children.append(r) + if not is_child: + def handler(signum, _): + for pid in children: + try: + os.kill(pid, signum) + os.waitpid(pid, 0) + except OSError: # child may already exited + pass + sys.exit() + + signal.signal(signal.SIGTERM, handler) + signal.signal(signal.SIGQUIT, handler) + signal.signal(signal.SIGINT, handler) + + # master + for a_tcp_server in tcp_servers: + a_tcp_server.close() + for a_udp_server in udp_servers: + a_udp_server.close() + dns_resolver.close() + + for child in children: + os.waitpid(child, 0) + else: + logging.warn('worker is only available on Unix/Linux') + run_server() + else: + run_server() + + +if __name__ == '__main__': + main() diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/shell.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/shell.py new file mode 100755 index 000000000..a1547d082 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/shell.py @@ -0,0 +1,451 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright 2015 clowwindy +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import os +import json +import sys +import getopt +import logging +from shadowsocks.common import to_bytes, to_str, IPNetwork, PortRange +from shadowsocks import encrypt + +VERBOSE_LEVEL = 5 + +verbose = 0 + + +def check_python(): + info = sys.version_info + if info[0] == 2 and not info[1] >= 6: + print('Python 2.6+ required') + sys.exit(1) + elif info[0] == 3 and not info[1] >= 3: + print('Python 3.3+ required') + sys.exit(1) + elif info[0] not in [2, 3]: + print('Python version not supported') + sys.exit(1) + + +def print_exception(e): + global verbose + logging.error(e) + if verbose > 0: + import traceback + traceback.print_exc() + + +def __version(): + version_str = '' + try: + import pkg_resources + version_str = pkg_resources.get_distribution('shadowsocks').version + except Exception: + try: + from shadowsocks import version + version_str = version.version() + except Exception: + pass + return version_str + + +def print_shadowsocks(): + print('ShadowsocksR %s' % __version()) + + +def log_shadowsocks_version(): + logging.info('ShadowsocksR %s' % __version()) + + +def find_config(): + user_config_path = 'user-config.json' + config_path = 'config.json' + + def sub_find(file_name): + if os.path.exists(file_name): + return file_name + file_name = os.path.join(os.path.abspath('..'), file_name) + return file_name if os.path.exists(file_name) else None + + return sub_find(user_config_path) or sub_find(config_path) + + +def check_config(config, is_local): + if config.get('daemon', None) == 'stop': + # no need to specify configuration for daemon stop + return + + if is_local and not config.get('password', None): + logging.error('password not specified') + print_help(is_local) + sys.exit(2) + + if not is_local and not config.get('password', None) \ + and not config.get('port_password', None): + logging.error('password or port_password not specified') + print_help(is_local) + sys.exit(2) + + if 'local_port' in config: + config['local_port'] = int(config['local_port']) + + if 'server_port' in config and type(config['server_port']) != list: + config['server_port'] = int(config['server_port']) + + if config.get('local_address', '') in [b'0.0.0.0']: + logging.warning('warning: local set to listen on 0.0.0.0, it\'s not safe') + if config.get('server', '') in ['127.0.0.1', 'localhost']: + logging.warning('warning: server set to listen on %s:%s, are you sure?' % + (to_str(config['server']), config['server_port'])) + if config.get('timeout', 300) < 100: + logging.warning('warning: your timeout %d seems too short' % + int(config.get('timeout'))) + if config.get('timeout', 300) > 600: + logging.warning('warning: your timeout %d seems too long' % + int(config.get('timeout'))) + if config.get('password') in [b'mypassword']: + logging.error('DON\'T USE DEFAULT PASSWORD! Please change it in your ' + 'config.json!') + sys.exit(1) + if config.get('user', None) is not None: + if os.name != 'posix': + logging.error('user can be used only on Unix') + sys.exit(1) + + encrypt.try_cipher(config['password'], config['method']) + + +def get_config(is_local): + global verbose + config = {} + config_path = None + logging.basicConfig(level=logging.INFO, + format='%(levelname)-s: %(message)s') + if is_local: + shortopts = 'hd:s:b:p:k:l:m:O:o:G:g:c:t:vq' + longopts = ['help', 'fast-open', 'pid-file=', 'log-file=', 'user=', + 'version'] + else: + shortopts = 'hd:s:p:k:m:O:o:G:g:c:t:vq' + longopts = ['help', 'fast-open', 'pid-file=', 'log-file=', 'workers=', + 'forbidden-ip=', 'user=', 'manager-address=', 'version'] + try: + optlist, args = getopt.getopt(sys.argv[1:], shortopts, longopts) + for key, value in optlist: + if key == '-c': + config_path = value + elif key in ('-h', '--help'): + print_help(is_local) + sys.exit(0) + elif key == '--version': + print_shadowsocks() + sys.exit(0) + else: + continue + + if config_path is None: + config_path = find_config() + + if config_path: + logging.debug('loading config from %s' % config_path) + with open(config_path, 'rb') as f: + try: + config = parse_json_in_str(remove_comment(f.read().decode('utf8'))) + except ValueError as e: + logging.error('found an error in config.json: %s', str(e)) + sys.exit(1) + + v_count = 0 + for key, value in optlist: + if key == '-p': + config['server_port'] = int(value) + elif key == '-k': + config['password'] = to_bytes(value) + elif key == '-l': + config['local_port'] = int(value) + elif key == '-s': + config['server'] = to_str(value) + elif key == '-m': + config['method'] = to_str(value) + elif key == '-O': + config['protocol'] = to_str(value) + elif key == '-o': + config['obfs'] = to_str(value) + elif key == '-G': + config['protocol_param'] = to_str(value) + elif key == '-g': + config['obfs_param'] = to_str(value) + elif key == '-b': + config['local_address'] = to_str(value) + elif key == '-v': + v_count += 1 + # '-vv' turns on more verbose mode + config['verbose'] = v_count + elif key == '-t': + config['timeout'] = int(value) + elif key == '--fast-open': + config['fast_open'] = True + elif key == '--workers': + config['workers'] = int(value) + elif key == '--manager-address': + config['manager_address'] = value + elif key == '--user': + config['user'] = to_str(value) + elif key == '--forbidden-ip': + config['forbidden_ip'] = to_str(value) + + elif key == '-d': + config['daemon'] = to_str(value) + elif key == '--pid-file': + config['pid-file'] = to_str(value) + elif key == '--log-file': + config['log-file'] = to_str(value) + elif key == '-q': + v_count -= 1 + config['verbose'] = v_count + else: + continue + except getopt.GetoptError as e: + print(e, file=sys.stderr) + print_help(is_local) + sys.exit(2) + + if not config: + logging.error('config not specified') + print_help(is_local) + sys.exit(2) + + config['password'] = to_bytes(config.get('password', b'')) + config['method'] = to_str(config.get('method', 'aes-256-cfb')) + config['protocol'] = to_str(config.get('protocol', 'origin')) + config['protocol_param'] = to_str(config.get('protocol_param', '')) + config['obfs'] = to_str(config.get('obfs', 'plain')) + config['obfs_param'] = to_str(config.get('obfs_param', '')) + config['port_password'] = config.get('port_password', None) + config['additional_ports'] = config.get('additional_ports', {}) + config['additional_ports_only'] = config.get('additional_ports_only', False) + config['timeout'] = int(config.get('timeout', 300)) + config['udp_timeout'] = int(config.get('udp_timeout', 120)) + config['udp_cache'] = int(config.get('udp_cache', 64)) + config['fast_open'] = config.get('fast_open', False) + config['workers'] = config.get('workers', 1) + config['pid-file'] = config.get('pid-file', '/var/run/shadowsocksr.pid') + config['log-file'] = config.get('log-file', '/var/log/shadowsocksr.log') + config['verbose'] = config.get('verbose', False) + config['connect_verbose_info'] = config.get('connect_verbose_info', 0) + config['local_address'] = to_str(config.get('local_address', '127.0.0.1')) + config['local_port'] = config.get('local_port', 1080) + if is_local: + if config.get('server', None) is None: + logging.error('server addr not specified') + print_local_help() + sys.exit(2) + else: + config['server'] = to_str(config['server']) + else: + config['server'] = to_str(config.get('server', '0.0.0.0')) + config['black_hostname_list'] = to_str(config.get('black_hostname_list', '')).split(',') + if len(config['black_hostname_list']) == 1 and config['black_hostname_list'][0] == '': + config['black_hostname_list'] = [] + try: + config['forbidden_ip'] = \ + IPNetwork(config.get('forbidden_ip', '127.0.0.0/8,::1/128')) + except Exception as e: + logging.error(e) + sys.exit(2) + try: + config['forbidden_port'] = PortRange(config.get('forbidden_port', '')) + except Exception as e: + logging.error(e) + sys.exit(2) + try: + config['ignore_bind'] = \ + IPNetwork(config.get('ignore_bind', '127.0.0.0/8,::1/128,10.0.0.0/8,192.168.0.0/16')) + except Exception as e: + logging.error(e) + sys.exit(2) + config['server_port'] = config.get('server_port', 8388) + + logging.getLogger('').handlers = [] + logging.addLevelName(VERBOSE_LEVEL, 'VERBOSE') + if config['verbose'] >= 2: + level = VERBOSE_LEVEL + elif config['verbose'] == 1: + level = logging.DEBUG + elif config['verbose'] == -1: + level = logging.WARN + elif config['verbose'] <= -2: + level = logging.ERROR + else: + level = logging.INFO + verbose = config['verbose'] + logging.basicConfig(level=level, + format='%(asctime)s %(levelname)-8s %(filename)s:%(lineno)s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S') + + check_config(config, is_local) + + return config + + +def print_help(is_local): + if is_local: + print_local_help() + else: + print_server_help() + + +def print_local_help(): + print('''usage: sslocal [OPTION]... +A fast tunnel proxy that helps you bypass firewalls. + +You can supply configurations via either config file or command line arguments. + +Proxy options: + -c CONFIG path to config file + -s SERVER_ADDR server address + -p SERVER_PORT server port, default: 8388 + -b LOCAL_ADDR local binding address, default: 127.0.0.1 + -l LOCAL_PORT local port, default: 1080 + -k PASSWORD password + -m METHOD encryption method, default: aes-256-cfb + -o OBFS obfsplugin, default: http_simple + -t TIMEOUT timeout in seconds, default: 300 + --fast-open use TCP_FASTOPEN, requires Linux 3.7+ + +General options: + -h, --help show this help message and exit + -d start/stop/restart daemon mode + --pid-file PID_FILE pid file for daemon mode + --log-file LOG_FILE log file for daemon mode + --user USER username to run as + -v, -vv verbose mode + -q, -qq quiet mode, only show warnings/errors + --version show version information + +Online help: +''') + + +def print_server_help(): + print('''usage: ssserver [OPTION]... +A fast tunnel proxy that helps you bypass firewalls. + +You can supply configurations via either config file or command line arguments. + +Proxy options: + -c CONFIG path to config file + -s SERVER_ADDR server address, default: 0.0.0.0 + -p SERVER_PORT server port, default: 8388 + -k PASSWORD password + -m METHOD encryption method, default: aes-256-cfb + -o OBFS obfsplugin, default: http_simple + -t TIMEOUT timeout in seconds, default: 300 + --fast-open use TCP_FASTOPEN, requires Linux 3.7+ + --workers WORKERS number of workers, available on Unix/Linux + --forbidden-ip IPLIST comma seperated IP list forbidden to connect + --manager-address ADDR optional server manager UDP address, see wiki + +General options: + -h, --help show this help message and exit + -d start/stop/restart daemon mode + --pid-file PID_FILE pid file for daemon mode + --log-file LOG_FILE log file for daemon mode + --user USER username to run as + -v, -vv verbose mode + -q, -qq quiet mode, only show warnings/errors + --version show version information + +Online help: +''') + + +def _decode_list(data): + rv = [] + for item in data: + if hasattr(item, 'encode'): + item = item.encode('utf-8') + elif isinstance(item, list): + item = _decode_list(item) + elif isinstance(item, dict): + item = _decode_dict(item) + rv.append(item) + return rv + + +def _decode_dict(data): + rv = {} + for key, value in data.items(): + if hasattr(value, 'encode'): + value = value.encode('utf-8') + elif isinstance(value, list): + value = _decode_list(value) + elif isinstance(value, dict): + value = _decode_dict(value) + rv[key] = value + return rv + + +class JSFormat: + def __init__(self): + self.state = 0 + + def push(self, ch): + ch = ord(ch) + if self.state == 0: + if ch == ord('"'): + self.state = 1 + return to_str(chr(ch)) + elif ch == ord('/'): + self.state = 3 + else: + return to_str(chr(ch)) + elif self.state == 1: + if ch == ord('"'): + self.state = 0 + return to_str(chr(ch)) + elif ch == ord('\\'): + self.state = 2 + return to_str(chr(ch)) + elif self.state == 2: + self.state = 1 + if ch == ord('"'): + return to_str(chr(ch)) + return "\\" + to_str(chr(ch)) + elif self.state == 3: + if ch == ord('/'): + self.state = 4 + else: + return "/" + to_str(chr(ch)) + elif self.state == 4: + if ch == ord('\n'): + self.state = 0 + return "\n" + return "" + + +def remove_comment(json): + fmt = JSFormat() + return "".join([fmt.push(c) for c in json]) + + +def parse_json_in_str(data): + # parse json and convert everything from unicode to str + return json.loads(data, object_hook=_decode_dict) diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/stop.sh b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/stop.sh new file mode 100755 index 000000000..d7d29589e --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/stop.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +python_ver=$(ls /usr/bin|grep -e "^python[23]\.[1-9]\+$"|tail -1) +eval $(ps -ef | grep "[0-9] ${python_ver} server\\.py a" | awk '{print "kill "$2}') + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/tail.sh b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/tail.sh new file mode 100755 index 000000000..aa3713939 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/tail.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +tail -f ssserver.log diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/tcprelay.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/tcprelay.py new file mode 100644 index 000000000..595e2be73 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/tcprelay.py @@ -0,0 +1,1476 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright 2015 clowwindy +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import time +import socket +import errno +import struct +import logging +import binascii +import traceback +import random +import platform +import threading + +from shadowsocks import encrypt, obfs, eventloop, shell, common, lru_cache, version +from shadowsocks.common import pre_parse_header, parse_header + +# we clear at most TIMEOUTS_CLEAN_SIZE timeouts each time +TIMEOUTS_CLEAN_SIZE = 512 + +MSG_FASTOPEN = 0x20000000 + +# SOCKS command definition +CMD_CONNECT = 1 +CMD_BIND = 2 +CMD_UDP_ASSOCIATE = 3 + +# for each opening port, we have a TCP Relay + +# for each connection, we have a TCP Relay Handler to handle the connection + +# for each handler, we have 2 sockets: +# local: connected to the client +# remote: connected to remote server + +# for each handler, it could be at one of several stages: + +# as sslocal: +# stage 0 SOCKS hello received from local, send hello to local +# stage 1 addr received from local, query DNS for remote +# stage 2 UDP assoc +# stage 3 DNS resolved, connect to remote +# stage 4 still connecting, more data from local received +# stage 5 remote connected, piping local and remote + +# as ssserver: +# stage 0 just jump to stage 1 +# stage 1 addr received from local, query DNS for remote +# stage 3 DNS resolved, connect to remote +# stage 4 still connecting, more data from local received +# stage 5 remote connected, piping local and remote + +STAGE_INIT = 0 +STAGE_ADDR = 1 +STAGE_UDP_ASSOC = 2 +STAGE_DNS = 3 +STAGE_CONNECTING = 4 +STAGE_STREAM = 5 +STAGE_DESTROYED = -1 + +# for each handler, we have 2 stream directions: +# upstream: from client to server direction +# read local and write to remote +# downstream: from server to client direction +# read remote and write to local + +STREAM_UP = 0 +STREAM_DOWN = 1 + +# for each stream, it's waiting for reading, or writing, or both +WAIT_STATUS_INIT = 0 +WAIT_STATUS_READING = 1 +WAIT_STATUS_WRITING = 2 +WAIT_STATUS_READWRITING = WAIT_STATUS_READING | WAIT_STATUS_WRITING + +NETWORK_MTU = 1500 +TCP_MSS = NETWORK_MTU - 40 +BUF_SIZE = 32 * 1024 +UDP_MAX_BUF_SIZE = 65536 + +class SpeedTester(object): + def __init__(self, max_speed = 0): + self.max_speed = max_speed * 1024 + self.last_time = time.time() + self.sum_len = 0 + + def update_limit(self, max_speed): + self.max_speed = max_speed * 1024 + + def add(self, data_len): + if self.max_speed > 0: + cut_t = time.time() + self.sum_len -= (cut_t - self.last_time) * self.max_speed + if self.sum_len < 0: + self.sum_len = 0 + self.last_time = cut_t + self.sum_len += data_len + + def isExceed(self): + if self.max_speed > 0: + cut_t = time.time() + self.sum_len -= (cut_t - self.last_time) * self.max_speed + if self.sum_len < 0: + self.sum_len = 0 + self.last_time = cut_t + return self.sum_len >= self.max_speed + return False + +class TCPRelayHandler(object): + def __init__(self, server, fd_to_handlers, loop, local_sock, config, + dns_resolver, is_local): + self._server = server + self._fd_to_handlers = fd_to_handlers + self._loop = loop + self._local_sock = local_sock + self._remote_sock = None + self._remote_sock_v6 = None + self._local_sock_fd = None + self._remote_sock_fd = None + self._remotev6_sock_fd = None + self._remote_udp = False + self._config = config + self._dns_resolver = dns_resolver + self._add_ref = 0 + if not self._create_encryptor(config): + return + + self._client_address = local_sock.getpeername()[:2] + self._accept_address = local_sock.getsockname()[:2] + self._user = None + self._user_id = server._listen_port + self._update_tcp_mss(local_sock) + + # TCP Relay works as either sslocal or ssserver + # if is_local, this is sslocal + self._is_local = is_local + self._encrypt_correct = True + self._obfs = obfs.obfs(config['obfs']) + self._protocol = obfs.obfs(config['protocol']) + self._overhead = self._obfs.get_overhead(self._is_local) + self._protocol.get_overhead(self._is_local) + self._recv_buffer_size = BUF_SIZE - self._overhead + + server_info = obfs.server_info(server.obfs_data) + server_info.host = config['server'] + server_info.port = server._listen_port + #server_info.users = server.server_users + #server_info.update_user_func = self._update_user + server_info.client = self._client_address[0] + server_info.client_port = self._client_address[1] + server_info.protocol_param = '' + server_info.obfs_param = config['obfs_param'] + server_info.iv = self._encryptor.cipher_iv + server_info.recv_iv = b'' + server_info.key_str = common.to_bytes(config['password']) + server_info.key = self._encryptor.cipher_key + server_info.head_len = 30 + server_info.tcp_mss = self._tcp_mss + server_info.buffer_size = self._recv_buffer_size + server_info.overhead = self._overhead + self._obfs.set_server_info(server_info) + + server_info = obfs.server_info(server.protocol_data) + server_info.host = config['server'] + server_info.port = server._listen_port + server_info.users = server.server_users + server_info.update_user_func = self._update_user + server_info.client = self._client_address[0] + server_info.client_port = self._client_address[1] + server_info.protocol_param = config['protocol_param'] + server_info.obfs_param = '' + server_info.iv = self._encryptor.cipher_iv + server_info.recv_iv = b'' + server_info.key_str = common.to_bytes(config['password']) + server_info.key = self._encryptor.cipher_key + server_info.head_len = 30 + server_info.tcp_mss = self._tcp_mss + server_info.buffer_size = self._recv_buffer_size + server_info.overhead = self._overhead + self._protocol.set_server_info(server_info) + + self._redir_list = config.get('redirect', ["*#0.0.0.0:0"]) + self._is_redirect = False + self._bind = config.get('out_bind', '') + self._bindv6 = config.get('out_bindv6', '') + self._ignore_bind_list = config.get('ignore_bind', []) + + self._fastopen_connected = False + self._data_to_write_to_local = [] + self._data_to_write_to_remote = [] + self._udp_data_send_buffer = b'' + self._upstream_status = WAIT_STATUS_READING + self._downstream_status = WAIT_STATUS_INIT + self._remote_address = None + + self._forbidden_iplist = config.get('forbidden_ip', None) + self._forbidden_portset = config.get('forbidden_port', None) + if is_local: + self._chosen_server = self._get_a_server() + + self.last_activity = 0 + self._update_activity() + self._server.add_connection(1) + self._server.stat_add(self._client_address[0], 1) + self._add_ref = 1 + self.speed_tester_u = SpeedTester(config.get("speed_limit_per_con", 0)) + self.speed_tester_d = SpeedTester(config.get("speed_limit_per_con", 0)) + self._recv_u_max_size = BUF_SIZE + self._recv_d_max_size = BUF_SIZE + self._recv_pack_id = 0 + self._udp_send_pack_id = 0 + self._udpv6_send_pack_id = 0 + + local_sock.setblocking(False) + local_sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1) + self._local_sock_fd = local_sock.fileno() + fd_to_handlers[self._local_sock_fd] = self + loop.add(local_sock, eventloop.POLL_IN | eventloop.POLL_ERR, self._server) + self._stage = STAGE_INIT + + def __hash__(self): + # default __hash__ is id / 16 + # we want to eliminate collisions + return id(self) + + @property + def remote_address(self): + return self._remote_address + + def _get_a_server(self): + server = self._config['server'] + server_port = self._config['server_port'] + if type(server_port) == list: + server_port = random.choice(server_port) + if type(server) == list: + server = random.choice(server) + logging.debug('chosen server: %s:%d', server, server_port) + return server, server_port + + def _update_tcp_mss(self, local_sock): + self._tcp_mss = TCP_MSS + try: + tcp_mss = local_sock.getsockopt(socket.SOL_TCP, socket.TCP_MAXSEG) + if tcp_mss > 500 and tcp_mss <= 1500: + self._tcp_mss = tcp_mss + logging.debug("TCP MSS = %d" % (self._tcp_mss,)) + except: + pass + + def _create_encryptor(self, config): + try: + self._encryptor = encrypt.Encryptor(config['password'], + config['method']) + return True + except Exception: + self._stage = STAGE_DESTROYED + logging.error('create encryptor fail at port %d', self._server._listen_port) + + def _update_user(self, user): + self._user = user + self._user_id = struct.unpack(' 6: + length = struct.unpack('>H', self._udp_data_send_buffer[:2])[0] + + if length > len(self._udp_data_send_buffer): + break + + data = self._udp_data_send_buffer[:length] + self._udp_data_send_buffer = self._udp_data_send_buffer[length:] + + frag = common.ord(data[2]) + if frag != 0: + logging.warn('drop a message since frag is %d' % (frag,)) + continue + else: + data = data[3:] + header_result = parse_header(data) + if header_result is None: + continue + connecttype, addrtype, dest_addr, dest_port, header_length = header_result + if (addrtype & 7) == 3: + af = common.is_ip(dest_addr) + if af == False: + handler = common.UDPAsyncDNSHandler(data[header_length:]) + handler.resolve(self._dns_resolver, (dest_addr, dest_port), self._handle_server_dns_resolved) + else: + return self._handle_server_dns_resolved("", (dest_addr, dest_port), dest_addr, data[header_length:]) + else: + return self._handle_server_dns_resolved("", (dest_addr, dest_port), dest_addr, data[header_length:]) + + except Exception as e: + #trace = traceback.format_exc() + #logging.error(trace) + error_no = eventloop.errno_from_exception(e) + if error_no in (errno.EAGAIN, errno.EINPROGRESS, + errno.EWOULDBLOCK): + uncomplete = True + else: + shell.print_exception(e) + logging.error("exception from %s:%d" % (self._client_address[0], self._client_address[1])) + self.destroy() + return False + return True + else: + try: + if self._encrypt_correct: + if sock == self._remote_sock: + self._server.add_transfer_u(self._user, len(data)) + self._update_activity(len(data)) + if data: + l = len(data) + s = sock.send(data) + if s < l: + data = data[s:] + uncomplete = True + else: + return + except (OSError, IOError) as e: + error_no = eventloop.errno_from_exception(e) + if error_no in (errno.EAGAIN, errno.EINPROGRESS, + errno.EWOULDBLOCK): + uncomplete = True + else: + #traceback.print_exc() + shell.print_exception(e) + logging.error("exception from %s:%d" % (self._client_address[0], self._client_address[1])) + self.destroy() + return False + except Exception as e: + shell.print_exception(e) + logging.error("exception from %s:%d" % (self._client_address[0], self._client_address[1])) + self.destroy() + return False + if uncomplete: + if sock == self._local_sock: + self._data_to_write_to_local.append(data) + self._update_stream(STREAM_DOWN, WAIT_STATUS_WRITING) + elif sock == self._remote_sock: + self._data_to_write_to_remote.append(data) + self._update_stream(STREAM_UP, WAIT_STATUS_WRITING) + else: + logging.error('write_all_to_sock:unknown socket from %s:%d' % (self._client_address[0], self._client_address[1])) + else: + if sock == self._local_sock: + self._update_stream(STREAM_DOWN, WAIT_STATUS_READING) + elif sock == self._remote_sock: + self._update_stream(STREAM_UP, WAIT_STATUS_READING) + else: + logging.error('write_all_to_sock:unknown socket from %s:%d' % (self._client_address[0], self._client_address[1])) + return True + + def _handle_server_dns_resolved(self, error, remote_addr, server_addr, data): + if error: + return + try: + addrs = socket.getaddrinfo(server_addr, remote_addr[1], 0, socket.SOCK_DGRAM, socket.SOL_UDP) + if not addrs: # drop + return + af, socktype, proto, canonname, sa = addrs[0] + if af == socket.AF_INET6: + self._remote_sock_v6.sendto(data, (server_addr, remote_addr[1])) + if self._udpv6_send_pack_id == 0: + addr, port = self._remote_sock_v6.getsockname()[:2] + common.connect_log('UDPv6 sendto %s(%s):%d from %s:%d by user %d' % + (common.to_str(remote_addr[0]), common.to_str(server_addr), remote_addr[1], addr, port, self._user_id)) + self._udpv6_send_pack_id += 1 + else: + self._remote_sock.sendto(data, (server_addr, remote_addr[1])) + if self._udp_send_pack_id == 0: + addr, port = self._remote_sock.getsockname()[:2] + common.connect_log('UDP sendto %s(%s):%d from %s:%d by user %d' % + (common.to_str(remote_addr[0]), common.to_str(server_addr), remote_addr[1], addr, port, self._user_id)) + self._udp_send_pack_id += 1 + return True + except Exception as e: + shell.print_exception(e) + logging.error("exception from %s:%d" % (self._client_address[0], self._client_address[1])) + + def _get_redirect_host(self, client_address, ogn_data): + host_list = self._redir_list or ["*#0.0.0.0:0"] + + if type(host_list) != list: + host_list = [host_list] + + items_sum = common.to_str(host_list[0]).rsplit('#', 1) + if len(items_sum) < 2: + hash_code = binascii.crc32(ogn_data) + addrs = socket.getaddrinfo(client_address[0], client_address[1], 0, socket.SOCK_STREAM, socket.SOL_TCP) + af, socktype, proto, canonname, sa = addrs[0] + address_bytes = common.inet_pton(af, sa[0]) + if af == socket.AF_INET6: + addr = struct.unpack('>Q', address_bytes[8:])[0] + elif af == socket.AF_INET: + addr = struct.unpack('>I', address_bytes)[0] + else: + addr = 0 + + host_port = [] + match_port = False + for host in host_list: + items = common.to_str(host).rsplit(':', 1) + if len(items) > 1: + try: + port = int(items[1]) + if port == self._server._listen_port: + match_port = True + host_port.append((items[0], port)) + except: + pass + else: + host_port.append((host, 80)) + + if match_port: + last_host_port = host_port + host_port = [] + for host in last_host_port: + if host[1] == self._server._listen_port: + host_port.append(host) + + return host_port[((hash_code & 0xffffffff) + addr) % len(host_port)] + + else: + host_port = [] + for host in host_list: + items_sum = common.to_str(host).rsplit('#', 1) + items_match = common.to_str(items_sum[0]).rsplit(':', 1) + items = common.to_str(items_sum[1]).rsplit(':', 1) + if len(items_match) > 1: + if items_match[1] != "*": + try: + if self._server._listen_port != int(items_match[1]) and int(items_match[1]) != 0: + continue + except: + pass + + if items_match[0] != "*" and common.match_regex( + items_match[0], ogn_data) == False: + continue + if len(items) > 1: + try: + port = int(items[1]) + return (items[0], port) + except: + pass + else: + return (items[0], 80) + + return ("0.0.0.0", 0) + + def _handel_protocol_error(self, client_address, ogn_data): + logging.warn("Protocol ERROR, TCP ogn data %s from %s:%d via port %d by UID %d" % (binascii.hexlify(ogn_data), client_address[0], client_address[1], self._server._listen_port, self._user_id)) + self._encrypt_correct = False + #create redirect or disconnect by hash code + host, port = self._get_redirect_host(client_address, ogn_data) + if port == 0: + raise Exception('can not parse header') + data = b"\x03" + common.to_bytes(common.chr(len(host))) + common.to_bytes(host) + struct.pack('>H', port) + self._is_redirect = True + logging.warn("TCP data redir %s:%d %s" % (host, port, binascii.hexlify(data))) + return data + ogn_data + + def _handle_stage_connecting(self, data): + if self._is_local: + if self._encryptor is not None: + data = self._protocol.client_pre_encrypt(data) + data = self._encryptor.encrypt(data) + data = self._obfs.client_encode(data) + if data: + self._data_to_write_to_remote.append(data) + if self._is_local and not self._fastopen_connected and \ + self._config['fast_open']: + # for sslocal and fastopen, we basically wait for data and use + # sendto to connect + try: + # only connect once + self._fastopen_connected = True + remote_sock = \ + self._create_remote_socket(self._chosen_server[0], + self._chosen_server[1]) + self._loop.add(remote_sock, eventloop.POLL_ERR, self._server) + data = b''.join(self._data_to_write_to_remote) + l = len(data) + s = remote_sock.sendto(data, MSG_FASTOPEN, self._chosen_server) + if s < l: + data = data[s:] + self._data_to_write_to_remote = [data] + else: + self._data_to_write_to_remote = [] + self._update_stream(STREAM_UP, WAIT_STATUS_READWRITING) + except (OSError, IOError) as e: + if eventloop.errno_from_exception(e) == errno.EINPROGRESS: + # in this case data is not sent at all + self._update_stream(STREAM_UP, WAIT_STATUS_READWRITING) + elif eventloop.errno_from_exception(e) == errno.ENOTCONN: + logging.error('fast open not supported on this OS') + self._config['fast_open'] = False + self.destroy() + else: + shell.print_exception(e) + if self._config['verbose']: + traceback.print_exc() + logging.error("exception from %s:%d" % (self._client_address[0], self._client_address[1])) + self.destroy() + + def _get_head_size(self, buf, def_value): + if len(buf) < 2: + return def_value + head_type = common.ord(buf[0]) & 0xF + if head_type == 1: + return 7 + if head_type == 4: + return 19 + if head_type == 3: + return 4 + common.ord(buf[1]) + return def_value + + def _handle_stage_addr(self, ogn_data, data): + try: + if self._is_local: + cmd = common.ord(data[1]) + if cmd == CMD_UDP_ASSOCIATE: + logging.debug('UDP associate') + if self._local_sock.family == socket.AF_INET6: + header = b'\x05\x00\x00\x04' + else: + header = b'\x05\x00\x00\x01' + addr, port = self._local_sock.getsockname()[:2] + addr_to_send = socket.inet_pton(self._local_sock.family, + addr) + port_to_send = struct.pack('>H', port) + self._write_to_sock(header + addr_to_send + port_to_send, + self._local_sock) + self._stage = STAGE_UDP_ASSOC + # just wait for the client to disconnect + return + elif cmd == CMD_CONNECT: + # just trim VER CMD RSV + data = data[3:] + else: + logging.error('invalid command %d', cmd) + self.destroy() + return + + before_parse_data = data + if self._is_local: + header_result = parse_header(data) + else: + data = pre_parse_header(data) + if data is None: + data = self._handel_protocol_error(self._client_address, ogn_data) + header_result = parse_header(data) + if header_result is not None: + try: + common.to_str(header_result[2]) + except Exception as e: + header_result = None + if header_result is None: + data = self._handel_protocol_error(self._client_address, ogn_data) + header_result = parse_header(data) + self._overhead = self._obfs.get_overhead(self._is_local) + self._protocol.get_overhead(self._is_local) + self._recv_buffer_size = BUF_SIZE - self._overhead + server_info = self._obfs.get_server_info() + server_info.buffer_size = self._recv_buffer_size + server_info = self._protocol.get_server_info() + server_info.buffer_size = self._recv_buffer_size + connecttype, addrtype, remote_addr, remote_port, header_length = header_result + if connecttype != 0: + pass + #common.connect_log('UDP over TCP by user %d' % + # (self._user_id, )) + else: + common.connect_log('TCP request %s:%d by user %d' % + (common.to_str(remote_addr), remote_port, self._user_id)) + self._remote_address = (common.to_str(remote_addr), remote_port) + self._remote_udp = (connecttype != 0) + # pause reading + self._update_stream(STREAM_UP, WAIT_STATUS_WRITING) + self._stage = STAGE_DNS + if self._is_local: + # forward address to remote + self._write_to_sock((b'\x05\x00\x00\x01' + b'\x00\x00\x00\x00\x10\x10'), + self._local_sock) + head_len = self._get_head_size(data, 30) + self._obfs.obfs.server_info.head_len = head_len + self._protocol.obfs.server_info.head_len = head_len + if self._encryptor is not None: + data = self._protocol.client_pre_encrypt(data) + data_to_send = self._encryptor.encrypt(data) + data_to_send = self._obfs.client_encode(data_to_send) + if data_to_send: + self._data_to_write_to_remote.append(data_to_send) + # notice here may go into _handle_dns_resolved directly + self._dns_resolver.resolve(self._chosen_server[0], + self._handle_dns_resolved) + else: + if len(data) > header_length: + self._data_to_write_to_remote.append(data[header_length:]) + # notice here may go into _handle_dns_resolved directly + self._dns_resolver.resolve(remote_addr, + self._handle_dns_resolved) + except Exception as e: + self._log_error(e) + if self._config['verbose']: + traceback.print_exc() + self.destroy() + + def _socket_bind_addr(self, sock, af): + bind_addr = '' + if self._bind and af == socket.AF_INET: + bind_addr = self._bind + elif self._bindv6 and af == socket.AF_INET6: + bind_addr = self._bindv6 + else: + bind_addr = self._accept_address[0] + + bind_addr = bind_addr.replace("::ffff:", "") + if bind_addr in self._ignore_bind_list: + bind_addr = None + if bind_addr: + local_addrs = socket.getaddrinfo(bind_addr, 0, 0, socket.SOCK_STREAM, socket.SOL_TCP) + if local_addrs[0][0] == af: + logging.debug("bind %s" % (bind_addr,)) + try: + sock.bind((bind_addr, 0)) + except Exception as e: + logging.warn("bind %s fail" % (bind_addr,)) + + def _create_remote_socket(self, ip, port): + if self._remote_udp: + addrs_v6 = socket.getaddrinfo("::", 0, 0, socket.SOCK_DGRAM, socket.SOL_UDP) + addrs = socket.getaddrinfo("0.0.0.0", 0, 0, socket.SOCK_DGRAM, socket.SOL_UDP) + else: + addrs = socket.getaddrinfo(ip, port, 0, socket.SOCK_STREAM, socket.SOL_TCP) + if len(addrs) == 0: + raise Exception("getaddrinfo failed for %s:%d" % (ip, port)) + af, socktype, proto, canonname, sa = addrs[0] + if not self._remote_udp and not self._is_redirect: + if self._forbidden_iplist: + if common.to_str(sa[0]) in self._forbidden_iplist: + if self._remote_address: + raise Exception('IP %s is in forbidden list, when connect to %s:%d via port %d by UID %d' % + (common.to_str(sa[0]), self._remote_address[0], self._remote_address[1], self._server._listen_port, self._user_id)) + raise Exception('IP %s is in forbidden list, reject' % + common.to_str(sa[0])) + if self._forbidden_portset: + if sa[1] in self._forbidden_portset: + if self._remote_address: + raise Exception('Port %d is in forbidden list, when connect to %s:%d via port %d by UID %d' % + (sa[1], self._remote_address[0], self._remote_address[1], self._server._listen_port, self._user_id)) + raise Exception('Port %d is in forbidden list, reject' % sa[1]) + remote_sock = socket.socket(af, socktype, proto) + self._remote_sock = remote_sock + self._remote_sock_fd = remote_sock.fileno() + self._fd_to_handlers[self._remote_sock_fd] = self + + if self._remote_udp: + af, socktype, proto, canonname, sa = addrs_v6[0] + remote_sock_v6 = socket.socket(af, socktype, proto) + self._remote_sock_v6 = remote_sock_v6 + self._remotev6_sock_fd = remote_sock_v6.fileno() + self._fd_to_handlers[self._remotev6_sock_fd] = self + + remote_sock.setblocking(False) + if self._remote_udp: + remote_sock_v6.setblocking(False) + + if not self._is_local: + self._socket_bind_addr(remote_sock, af) + self._socket_bind_addr(remote_sock_v6, af) + else: + remote_sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1) + if not self._is_local: + self._socket_bind_addr(remote_sock, af) + return remote_sock + + def _handle_dns_resolved(self, result, error): + if error: + self._log_error(error) + self.destroy() + return + if result: + ip = result[1] + if ip: + try: + self._stage = STAGE_CONNECTING + remote_addr = ip + if self._is_local: + remote_port = self._chosen_server[1] + else: + remote_port = self._remote_address[1] + + if self._is_local and self._config['fast_open']: + # for fastopen: + # wait for more data to arrive and send them in one SYN + self._stage = STAGE_CONNECTING + # we don't have to wait for remote since it's not + # created + self._update_stream(STREAM_UP, WAIT_STATUS_READING) + # TODO when there is already data in this packet + else: + # else do connect + remote_sock = self._create_remote_socket(remote_addr, + remote_port) + if self._remote_udp: + self._loop.add(remote_sock, + eventloop.POLL_IN, + self._server) + if self._remote_sock_v6: + self._loop.add(self._remote_sock_v6, + eventloop.POLL_IN, + self._server) + else: + try: + remote_sock.connect((remote_addr, remote_port)) + except (OSError, IOError) as e: + if eventloop.errno_from_exception(e) in (errno.EINPROGRESS, + errno.EWOULDBLOCK): + pass # always goto here + else: + raise e + addr, port = self._remote_sock.getsockname()[:2] + common.connect_log('TCP connecting %s(%s):%d from %s:%d by user %d' % + (common.to_str(self._remote_address[0]), common.to_str(remote_addr), remote_port, addr, port, self._user_id)) + + self._loop.add(remote_sock, + eventloop.POLL_ERR | eventloop.POLL_OUT, + self._server) + self._stage = STAGE_CONNECTING + self._update_stream(STREAM_UP, WAIT_STATUS_READWRITING) + self._update_stream(STREAM_DOWN, WAIT_STATUS_READING) + if self._remote_udp: + while self._data_to_write_to_remote: + data = self._data_to_write_to_remote[0] + del self._data_to_write_to_remote[0] + self._write_to_sock(data, self._remote_sock) + return + except Exception as e: + shell.print_exception(e) + if self._config['verbose']: + traceback.print_exc() + logging.error("exception from %s:%d" % (self._client_address[0], self._client_address[1])) + self.destroy() + + def _get_read_size(self, sock, recv_buffer_size, up): + if self._overhead == 0: + return recv_buffer_size + buffer_size = len(sock.recv(recv_buffer_size, socket.MSG_PEEK)) + frame_size = self._tcp_mss - self._overhead + if up: + buffer_size = min(buffer_size, self._recv_u_max_size) + self._recv_u_max_size = min(self._recv_u_max_size + frame_size, BUF_SIZE) + else: + buffer_size = min(buffer_size, self._recv_d_max_size) + self._recv_d_max_size = min(self._recv_d_max_size + frame_size, BUF_SIZE) + if buffer_size == recv_buffer_size: + return buffer_size + if buffer_size > frame_size: + buffer_size = int(buffer_size / frame_size) * frame_size + return buffer_size + + def _on_local_read(self): + # handle all local read events and dispatch them to methods for + # each stage + if not self._local_sock: + return + is_local = self._is_local + if is_local: + recv_buffer_size = self._get_read_size(self._local_sock, self._recv_buffer_size, True) + else: + recv_buffer_size = BUF_SIZE + data = None + try: + data = self._local_sock.recv(recv_buffer_size) + except (OSError, IOError) as e: + if eventloop.errno_from_exception(e) in \ + (errno.ETIMEDOUT, errno.EAGAIN, errno.EWOULDBLOCK): + return + if not data: + self.destroy() + return + + self.speed_tester_u.add(len(data)) + self._server.speed_tester_u(self._user_id).add(len(data)) + ogn_data = data + if not is_local: + if self._encryptor is not None: + if self._encrypt_correct: + try: + obfs_decode = self._obfs.server_decode(data) + if self._stage == STAGE_INIT: + self._overhead = self._obfs.get_overhead(self._is_local) + self._protocol.get_overhead(self._is_local) + server_info = self._protocol.get_server_info() + server_info.overhead = self._overhead + except Exception as e: + shell.print_exception(e) + logging.error("exception from %s:%d" % (self._client_address[0], self._client_address[1])) + self.destroy() + return + if obfs_decode[2]: + data = self._obfs.server_encode(b'') + try: + self._write_to_sock(data, self._local_sock) + except Exception as e: + shell.print_exception(e) + if self._config['verbose']: + traceback.print_exc() + logging.error("exception from %s:%d" % (self._client_address[0], self._client_address[1])) + self.destroy() + return + if obfs_decode[1]: + if not self._protocol.obfs.server_info.recv_iv: + iv_len = len(self._protocol.obfs.server_info.iv) + self._protocol.obfs.server_info.recv_iv = obfs_decode[0][:iv_len] + data = self._encryptor.decrypt(obfs_decode[0]) + else: + data = obfs_decode[0] + try: + data, sendback = self._protocol.server_post_decrypt(data) + if sendback: + backdata = self._protocol.server_pre_encrypt(b'') + backdata = self._encryptor.encrypt(backdata) + backdata = self._obfs.server_encode(backdata) + try: + self._write_to_sock(backdata, self._local_sock) + except Exception as e: + shell.print_exception(e) + if self._config['verbose']: + traceback.print_exc() + logging.error("exception from %s:%d" % (self._client_address[0], self._client_address[1])) + self.destroy() + return + except Exception as e: + shell.print_exception(e) + logging.error("exception from %s:%d" % (self._client_address[0], self._client_address[1])) + self.destroy() + return + else: + return + if not data: + return + if self._stage == STAGE_STREAM: + if self._is_local: + if self._encryptor is not None: + data = self._protocol.client_pre_encrypt(data) + data = self._encryptor.encrypt(data) + data = self._obfs.client_encode(data) + self._write_to_sock(data, self._remote_sock) + elif is_local and self._stage == STAGE_INIT: + # TODO check auth method + self._write_to_sock(b'\x05\00', self._local_sock) + self._stage = STAGE_ADDR + elif self._stage == STAGE_CONNECTING: + self._handle_stage_connecting(data) + elif (is_local and self._stage == STAGE_ADDR) or \ + (not is_local and self._stage == STAGE_INIT): + self._handle_stage_addr(ogn_data, data) + + def _on_remote_read(self, is_remote_sock): + # handle all remote read events + data = None + try: + if self._remote_udp: + if is_remote_sock: + data, addr = self._remote_sock.recvfrom(UDP_MAX_BUF_SIZE) + else: + data, addr = self._remote_sock_v6.recvfrom(UDP_MAX_BUF_SIZE) + port = struct.pack('>H', addr[1]) + try: + ip = socket.inet_aton(addr[0]) + data = b'\x00\x01' + ip + port + data + except Exception as e: + ip = socket.inet_pton(socket.AF_INET6, addr[0]) + data = b'\x00\x04' + ip + port + data + size = len(data) + 2 + data = struct.pack('>H', size) + data + #logging.info('UDP over TCP recvfrom %s:%d %d bytes to %s:%d' % (addr[0], addr[1], len(data), self._client_address[0], self._client_address[1])) + else: + if self._is_local: + recv_buffer_size = BUF_SIZE + else: + recv_buffer_size = self._get_read_size(self._remote_sock, self._recv_buffer_size, False) + data = self._remote_sock.recv(recv_buffer_size) + self._recv_pack_id += 1 + except (OSError, IOError) as e: + if eventloop.errno_from_exception(e) in \ + (errno.ETIMEDOUT, errno.EAGAIN, errno.EWOULDBLOCK, 10035): #errno.WSAEWOULDBLOCK + return + if not data: + self.destroy() + return + + self.speed_tester_d.add(len(data)) + self._server.speed_tester_d(self._user_id).add(len(data)) + if self._encryptor is not None: + if self._is_local: + try: + obfs_decode = self._obfs.client_decode(data) + except Exception as e: + shell.print_exception(e) + logging.error("exception from %s:%d" % (self._client_address[0], self._client_address[1])) + self.destroy() + return + if obfs_decode[1]: + send_back = self._obfs.client_encode(b'') + self._write_to_sock(send_back, self._remote_sock) + if not self._protocol.obfs.server_info.recv_iv: + iv_len = len(self._protocol.obfs.server_info.iv) + self._protocol.obfs.server_info.recv_iv = obfs_decode[0][:iv_len] + data = self._encryptor.decrypt(obfs_decode[0]) + try: + data = self._protocol.client_post_decrypt(data) + if self._recv_pack_id == 1: + self._tcp_mss = self._protocol.get_server_info().tcp_mss + except Exception as e: + shell.print_exception(e) + logging.error("exception from %s:%d" % (self._client_address[0], self._client_address[1])) + self.destroy() + return + else: + if self._encrypt_correct: + data = self._protocol.server_pre_encrypt(data) + data = self._encryptor.encrypt(data) + data = self._obfs.server_encode(data) + self._server.add_transfer_d(self._user, len(data)) + self._update_activity(len(data)) + else: + return + try: + self._write_to_sock(data, self._local_sock) + except Exception as e: + shell.print_exception(e) + if self._config['verbose']: + traceback.print_exc() + logging.error("exception from %s:%d" % (self._client_address[0], self._client_address[1])) + self.destroy() + + def _on_local_write(self): + # handle local writable event + if self._data_to_write_to_local: + data = b''.join(self._data_to_write_to_local) + self._data_to_write_to_local = [] + self._write_to_sock(data, self._local_sock) + else: + self._update_stream(STREAM_DOWN, WAIT_STATUS_READING) + + def _on_remote_write(self): + # handle remote writable event + self._stage = STAGE_STREAM + if self._data_to_write_to_remote: + data = b''.join(self._data_to_write_to_remote) + self._data_to_write_to_remote = [] + self._write_to_sock(data, self._remote_sock) + else: + self._update_stream(STREAM_UP, WAIT_STATUS_READING) + + def _on_local_error(self): + if self._local_sock: + err = eventloop.get_sock_error(self._local_sock) + if err.errno not in [errno.ECONNRESET, errno.EPIPE]: + logging.error(err) + logging.error("local error, exception from %s:%d" % (self._client_address[0], self._client_address[1])) + self.destroy() + + def _on_remote_error(self): + if self._remote_sock: + err = eventloop.get_sock_error(self._remote_sock) + if err.errno not in [errno.ECONNRESET]: + logging.error(err) + if self._remote_address: + logging.error("remote error, when connect to %s:%d" % (self._remote_address[0], self._remote_address[1])) + else: + logging.error("remote error, exception from %s:%d" % (self._client_address[0], self._client_address[1])) + self.destroy() + + def handle_event(self, sock, fd, event): + # handle all events in this handler and dispatch them to methods + handle = False + if self._stage == STAGE_DESTROYED: + logging.debug('ignore handle_event: destroyed') + return True + if self._user is not None and self._user not in self._server.server_users: + self.destroy() + return True + if fd == self._remote_sock_fd or fd == self._remotev6_sock_fd: + if event & eventloop.POLL_ERR: + handle = True + self._on_remote_error() + elif event & (eventloop.POLL_IN | eventloop.POLL_HUP): + if not self.speed_tester_d.isExceed() and not self._server.speed_tester_d(self._user_id).isExceed(): + handle = True + self._on_remote_read(sock == self._remote_sock) + else: + self._recv_d_max_size = self._tcp_mss - self._overhead + elif event & eventloop.POLL_OUT: + handle = True + self._on_remote_write() + elif fd == self._local_sock_fd: + if event & eventloop.POLL_ERR: + handle = True + self._on_local_error() + elif event & (eventloop.POLL_IN | eventloop.POLL_HUP): + if not self.speed_tester_u.isExceed() and not self._server.speed_tester_u(self._user_id).isExceed(): + handle = True + self._on_local_read() + else: + self._recv_u_max_size = self._tcp_mss - self._overhead + elif event & eventloop.POLL_OUT: + handle = True + self._on_local_write() + else: + logging.warn('unknown socket from %s:%d' % (self._client_address[0], self._client_address[1])) + try: + self._loop.removefd(fd) + except Exception as e: + shell.print_exception(e) + try: + del self._fd_to_handlers[fd] + except Exception as e: + shell.print_exception(e) + sock.close() + + return handle + + def _log_error(self, e): + logging.error('%s when handling connection from %s:%d' % + (e, self._client_address[0], self._client_address[1])) + + def stage(self): + return self._stage + + def destroy(self): + # destroy the handler and release any resources + # promises: + # 1. destroy won't make another destroy() call inside + # 2. destroy releases resources so it prevents future call to destroy + # 3. destroy won't raise any exceptions + # if any of the promises are broken, it indicates a bug has been + # introduced! mostly likely memory leaks, etc + if self._stage == STAGE_DESTROYED: + # this couldn't happen + logging.debug('already destroyed') + return + self._stage = STAGE_DESTROYED + if self._remote_address: + logging.debug('destroy: %s:%d' % + self._remote_address) + else: + logging.debug('destroy') + if self._remote_sock: + logging.debug('destroying remote') + try: + self._loop.removefd(self._remote_sock_fd) + except Exception as e: + shell.print_exception(e) + try: + if self._remote_sock_fd is not None: + del self._fd_to_handlers[self._remote_sock_fd] + except Exception as e: + shell.print_exception(e) + self._remote_sock.close() + self._remote_sock = None + if self._remote_sock_v6: + logging.debug('destroying remote_v6') + try: + self._loop.removefd(self._remotev6_sock_fd) + except Exception as e: + shell.print_exception(e) + try: + if self._remotev6_sock_fd is not None: + del self._fd_to_handlers[self._remotev6_sock_fd] + except Exception as e: + shell.print_exception(e) + self._remote_sock_v6.close() + self._remote_sock_v6 = None + if self._local_sock: + logging.debug('destroying local') + try: + self._loop.removefd(self._local_sock_fd) + except Exception as e: + shell.print_exception(e) + try: + if self._local_sock_fd is not None: + del self._fd_to_handlers[self._local_sock_fd] + except Exception as e: + shell.print_exception(e) + self._local_sock.close() + self._local_sock = None + if self._obfs: + self._obfs.dispose() + self._obfs = None + if self._protocol: + self._protocol.dispose() + self._protocol = None + self._encryptor = None + self._dns_resolver.remove_callback(self._handle_dns_resolved) + self._server.remove_handler(self) + if self._add_ref > 0: + self._server.add_connection(-1) + self._server.stat_add(self._client_address[0], -1) + +class TCPRelay(object): + def __init__(self, config, dns_resolver, is_local, stat_callback=None, stat_counter=None): + self._config = config + self._is_local = is_local + self._dns_resolver = dns_resolver + self._closed = False + self._eventloop = None + self._fd_to_handlers = {} + self.server_transfer_ul = 0 + self.server_transfer_dl = 0 + self.server_users = {} + self.server_users_cfg = {} + self.server_user_transfer_ul = {} + self.server_user_transfer_dl = {} + self.mu = False + self._speed_tester_u = {} + self._speed_tester_d = {} + self.server_connections = 0 + self.protocol_data = obfs.obfs(config['protocol']).init_data() + self.obfs_data = obfs.obfs(config['obfs']).init_data() + + if config.get('connect_verbose_info', 0) > 0: + common.connect_log = logging.info + + self._timeout = config['timeout'] + self._timeout_cache = lru_cache.LRUCache(timeout=self._timeout, + close_callback=self._close_tcp_client) + + if is_local: + listen_addr = config['local_address'] + listen_port = config['local_port'] + else: + listen_addr = config['server'] + listen_port = config['server_port'] + self._listen_port = listen_port + + if common.to_str(config['protocol']) in obfs.mu_protocol(): + self._update_users(None, None) + + addrs = socket.getaddrinfo(listen_addr, listen_port, 0, + socket.SOCK_STREAM, socket.SOL_TCP) + if len(addrs) == 0: + raise Exception("can't get addrinfo for %s:%d" % + (listen_addr, listen_port)) + af, socktype, proto, canonname, sa = addrs[0] + server_socket = socket.socket(af, socktype, proto) + server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + server_socket.bind(sa) + server_socket.setblocking(False) + if config['fast_open']: + try: + server_socket.setsockopt(socket.SOL_TCP, 23, 5) + except socket.error: + logging.error('warning: fast open is not available') + self._config['fast_open'] = False + server_socket.listen(config.get('max_connect', 1024)) + self._server_socket = server_socket + self._server_socket_fd = server_socket.fileno() + self._stat_counter = stat_counter + self._stat_callback = stat_callback + + def add_to_loop(self, loop): + if self._eventloop: + raise Exception('already add to loop') + if self._closed: + raise Exception('already closed') + self._eventloop = loop + self._eventloop.add(self._server_socket, + eventloop.POLL_IN | eventloop.POLL_ERR, self) + self._eventloop.add_periodic(self.handle_periodic) + + def remove_handler(self, client): + if hash(client) in self._timeout_cache: + del self._timeout_cache[hash(client)] + + def add_connection(self, val): + self.server_connections += val + logging.debug('server port %5d connections = %d' % (self._listen_port, self.server_connections,)) + + def get_ud(self): + return (self.server_transfer_ul, self.server_transfer_dl) + + def get_users_ud(self): + return (self.server_user_transfer_ul.copy(), self.server_user_transfer_dl.copy()) + + def _update_users(self, protocol_param, acl): + if protocol_param is None: + protocol_param = self._config['protocol_param'] + param = common.to_bytes(protocol_param).split(b'#') + if len(param) == 2: + self.mu = True + user_list = param[1].split(b',') + if user_list: + for user in user_list: + items = user.split(b':') + if len(items) == 2: + user_int_id = int(items[0]) + uid = struct.pack('= stat_dict.get(-1, 0) + connections_step: + logging.info('port %d connections up to %d' % (port, newval)) + stat_dict[-1] = stat_dict.get(-1, 0) + connections_step + elif newval <= stat_dict.get(-1, 0) - connections_step: + logging.info('port %d connections down to %d' % (port, newval)) + stat_dict[-1] = stat_dict.get(-1, 0) - connections_step + + def stat_add(self, local_addr, val): + if self._stat_counter is not None: + if self._listen_port not in self._stat_counter: + self._stat_counter[self._listen_port] = {} + newval = self._stat_counter[self._listen_port].get(local_addr, 0) + val + logging.debug('port %d addr %s connections %d' % (self._listen_port, local_addr, newval)) + self._stat_counter[self._listen_port][local_addr] = newval + self.update_stat(self._listen_port, self._stat_counter[self._listen_port], val) + if newval <= 0: + if local_addr in self._stat_counter[self._listen_port]: + del self._stat_counter[self._listen_port][local_addr] + + newval = self._stat_counter.get(0, 0) + val + self._stat_counter[0] = newval + logging.debug('Total connections %d' % newval) + + connections_step = 50 + if newval >= self._stat_counter.get(-1, 0) + connections_step: + logging.info('Total connections up to %d' % newval) + self._stat_counter[-1] = self._stat_counter.get(-1, 0) + connections_step + elif newval <= self._stat_counter.get(-1, 0) - connections_step: + logging.info('Total connections down to %d' % newval) + self._stat_counter[-1] = self._stat_counter.get(-1, 0) - connections_step + + def update_activity(self, client, data_len): + if data_len and self._stat_callback: + self._stat_callback(self._listen_port, data_len) + + self._timeout_cache[hash(client)] = client + + def _sweep_timeout(self): + self._timeout_cache.sweep() + + def _close_tcp_client(self, client): + if client.remote_address: + logging.debug('timed out: %s:%d' % + client.remote_address) + else: + logging.debug('timed out') + client.destroy() + + def handle_event(self, sock, fd, event): + # handle events and dispatch to handlers + handle = False + if sock: + logging.log(shell.VERBOSE_LEVEL, 'fd %d %s', fd, + eventloop.EVENT_NAMES.get(event, event)) + if sock == self._server_socket: + if event & eventloop.POLL_ERR: + # TODO + raise Exception('server_socket error') + handler = None + handle = True + try: + logging.debug('accept') + conn = self._server_socket.accept() + handler = TCPRelayHandler(self, self._fd_to_handlers, + self._eventloop, conn[0], self._config, + self._dns_resolver, self._is_local) + if handler.stage() == STAGE_DESTROYED: + conn[0].close() + except (OSError, IOError) as e: + error_no = eventloop.errno_from_exception(e) + if error_no in (errno.EAGAIN, errno.EINPROGRESS, + errno.EWOULDBLOCK): + return + else: + shell.print_exception(e) + if self._config['verbose']: + traceback.print_exc() + if handler: + handler.destroy() + else: + if sock: + handler = self._fd_to_handlers.get(fd, None) + if handler: + handle = handler.handle_event(sock, fd, event) + else: + logging.warn('unknown fd') + handle = True + try: + self._eventloop.removefd(fd) + except Exception as e: + shell.print_exception(e) + sock.close() + else: + logging.warn('poll removed fd') + handle = True + if fd in self._fd_to_handlers: + try: + del self._fd_to_handlers[fd] + except Exception as e: + shell.print_exception(e) + return handle + + def handle_periodic(self): + if self._closed: + if self._server_socket: + self._eventloop.removefd(self._server_socket_fd) + self._server_socket.close() + self._server_socket = None + logging.info('closed TCP port %d', self._listen_port) + for handler in list(self._fd_to_handlers.values()): + handler.destroy() + self._sweep_timeout() + + def close(self, next_tick=False): + logging.debug('TCP close') + self._closed = True + if not next_tick: + if self._eventloop: + self._eventloop.remove_periodic(self.handle_periodic) + self._eventloop.removefd(self._server_socket_fd) + self._server_socket.close() + for handler in list(self._fd_to_handlers.values()): + handler.destroy() diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/udprelay.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/udprelay.py new file mode 100644 index 000000000..b9606cd81 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/udprelay.py @@ -0,0 +1,656 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright 2015 clowwindy +# +# 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. + +# SOCKS5 UDP Request +# +----+------+------+----------+----------+----------+ +# |RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA | +# +----+------+------+----------+----------+----------+ +# | 2 | 1 | 1 | Variable | 2 | Variable | +# +----+------+------+----------+----------+----------+ + +# SOCKS5 UDP Response +# +----+------+------+----------+----------+----------+ +# |RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA | +# +----+------+------+----------+----------+----------+ +# | 2 | 1 | 1 | Variable | 2 | Variable | +# +----+------+------+----------+----------+----------+ + +# shadowsocks UDP Request (before encrypted) +# +------+----------+----------+----------+ +# | ATYP | DST.ADDR | DST.PORT | DATA | +# +------+----------+----------+----------+ +# | 1 | Variable | 2 | Variable | +# +------+----------+----------+----------+ + +# shadowsocks UDP Response (before encrypted) +# +------+----------+----------+----------+ +# | ATYP | DST.ADDR | DST.PORT | DATA | +# +------+----------+----------+----------+ +# | 1 | Variable | 2 | Variable | +# +------+----------+----------+----------+ + +# shadowsocks UDP Request and Response (after encrypted) +# +-------+--------------+ +# | IV | PAYLOAD | +# +-------+--------------+ +# | Fixed | Variable | +# +-------+--------------+ + +# HOW TO NAME THINGS +# ------------------ +# `dest` means destination server, which is from DST fields in the SOCKS5 +# request +# `local` means local server of shadowsocks +# `remote` means remote server of shadowsocks +# `client` means UDP clients that connects to other servers +# `server` means the UDP server that handles user requests + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import time +import socket +import logging +import struct +import errno +import random +import binascii +import traceback +import threading + +from shadowsocks import encrypt, obfs, eventloop, lru_cache, common, shell +from shadowsocks.common import pre_parse_header, parse_header, pack_addr + +# for each handler, we have 2 stream directions: +# upstream: from client to server direction +# read local and write to remote +# downstream: from server to client direction +# read remote and write to local + +STREAM_UP = 0 +STREAM_DOWN = 1 + +# for each stream, it's waiting for reading, or writing, or both +WAIT_STATUS_INIT = 0 +WAIT_STATUS_READING = 1 +WAIT_STATUS_WRITING = 2 +WAIT_STATUS_READWRITING = WAIT_STATUS_READING | WAIT_STATUS_WRITING + +BUF_SIZE = 65536 +DOUBLE_SEND_BEG_IDS = 16 +POST_MTU_MIN = 500 +POST_MTU_MAX = 1400 +SENDING_WINDOW_SIZE = 8192 + +STAGE_INIT = 0 +STAGE_RSP_ID = 1 +STAGE_DNS = 2 +STAGE_CONNECTING = 3 +STAGE_STREAM = 4 +STAGE_DESTROYED = -1 + +CMD_CONNECT = 0 +CMD_RSP_CONNECT = 1 +CMD_CONNECT_REMOTE = 2 +CMD_RSP_CONNECT_REMOTE = 3 +CMD_POST = 4 +CMD_SYN_STATUS = 5 +CMD_POST_64 = 6 +CMD_SYN_STATUS_64 = 7 +CMD_DISCONNECT = 8 + +CMD_VER_STR = b"\x08" + +RSP_STATE_EMPTY = b"" +RSP_STATE_REJECT = b"\x00" +RSP_STATE_CONNECTED = b"\x01" +RSP_STATE_CONNECTEDREMOTE = b"\x02" +RSP_STATE_ERROR = b"\x03" +RSP_STATE_DISCONNECT = b"\x04" +RSP_STATE_REDIRECT = b"\x05" + +def client_key(source_addr, server_af): + # notice this is server af, not dest af + return '%s:%s:%d' % (source_addr[0], source_addr[1], server_af) + +class UDPRelay(object): + def __init__(self, config, dns_resolver, is_local, stat_callback=None, stat_counter=None): + self._config = config + if config.get('connect_verbose_info', 0) > 0: + common.connect_log = logging.info + if is_local: + self._listen_addr = config['local_address'] + self._listen_port = config['local_port'] + self._remote_addr = config['server'] + self._remote_port = config['server_port'] + else: + self._listen_addr = config['server'] + self._listen_port = config['server_port'] + self._remote_addr = None + self._remote_port = None + self._dns_resolver = dns_resolver + self._password = common.to_bytes(config['password']) + self._method = config['method'] + self._timeout = config['timeout'] + self._is_local = is_local + self._udp_cache_size = config['udp_cache'] + self._cache = lru_cache.LRUCache(timeout=config['udp_timeout'], + close_callback=self._close_client_pair) + self._cache_dns_client = lru_cache.LRUCache(timeout=10, + close_callback=self._close_client_pair) + self._client_fd_to_server_addr = {} + #self._dns_cache = lru_cache.LRUCache(timeout=1800) + self._eventloop = None + self._closed = False + self.server_transfer_ul = 0 + self.server_transfer_dl = 0 + self.server_users = {} + self.server_user_transfer_ul = {} + self.server_user_transfer_dl = {} + + if common.to_bytes(config['protocol']) in obfs.mu_protocol(): + self._update_users(None, None) + + self.protocol_data = obfs.obfs(config['protocol']).init_data() + self._protocol = obfs.obfs(config['protocol']) + server_info = obfs.server_info(self.protocol_data) + server_info.host = self._listen_addr + server_info.port = self._listen_port + server_info.users = self.server_users + server_info.protocol_param = config['protocol_param'] + server_info.obfs_param = '' + server_info.iv = b'' + server_info.recv_iv = b'' + server_info.key_str = common.to_bytes(config['password']) + server_info.key = encrypt.encrypt_key(self._password, self._method) + server_info.head_len = 30 + server_info.tcp_mss = 1452 + server_info.buffer_size = BUF_SIZE + server_info.overhead = 0 + self._protocol.set_server_info(server_info) + + self._sockets = set() + self._fd_to_handlers = {} + self._reqid_to_hd = {} + self._data_to_write_to_server_socket = [] + + self._timeout_cache = lru_cache.LRUCache(timeout=self._timeout, + close_callback=self._close_tcp_client) + + self._bind = config.get('out_bind', '') + self._bindv6 = config.get('out_bindv6', '') + self._ignore_bind_list = config.get('ignore_bind', []) + + if 'forbidden_ip' in config: + self._forbidden_iplist = config['forbidden_ip'] + else: + self._forbidden_iplist = None + if 'forbidden_port' in config: + self._forbidden_portset = config['forbidden_port'] + else: + self._forbidden_portset = None + + addrs = socket.getaddrinfo(self._listen_addr, self._listen_port, 0, + socket.SOCK_DGRAM, socket.SOL_UDP) + if len(addrs) == 0: + raise Exception("can't get addrinfo for %s:%d" % + (self._listen_addr, self._listen_port)) + af, socktype, proto, canonname, sa = addrs[0] + server_socket = socket.socket(af, socktype, proto) + server_socket.bind((self._listen_addr, self._listen_port)) + server_socket.setblocking(False) + self._server_socket = server_socket + self._stat_callback = stat_callback + + def _get_a_server(self): + server = self._config['server'] + server_port = self._config['server_port'] + if type(server_port) == list: + server_port = random.choice(server_port) + if type(server) == list: + server = random.choice(server) + logging.debug('chosen server: %s:%d', server, server_port) + return server, server_port + + def get_ud(self): + return (self.server_transfer_ul, self.server_transfer_dl) + + def get_users_ud(self): + ret = (self.server_user_transfer_ul.copy(), self.server_user_transfer_dl.copy()) + return ret + + def _update_users(self, protocol_param, acl): + if protocol_param is None: + protocol_param = self._config['protocol_param'] + param = common.to_bytes(protocol_param).split(b'#') + if len(param) == 2: + user_list = param[1].split(b',') + if user_list: + for user in user_list: + items = user.split(b':') + if len(items) == 2: + user_int_id = int(items[0]) + uid = struct.pack(' header_length + 13 and data[header_length + 4 : header_length + 12] == b"\x00\x01\x00\x00\x00\x00\x00\x00": + is_dns = True + else: + pass + if sa[1] == 53 and is_dns: #DNS + logging.debug("DNS query %s from %s:%d" % (common.to_str(sa[0]), r_addr[0], r_addr[1])) + self._cache_dns_client[key] = (client, uid) + else: + self._cache[key] = (client, uid) + self._client_fd_to_server_addr[client.fileno()] = (r_addr, af) + + self._sockets.add(client.fileno()) + self._eventloop.add(client, eventloop.POLL_IN, self) + + logging.debug('UDP port %5d sockets %d' % (self._listen_port, len(self._sockets))) + + if uid is not None: + user_id = struct.unpack(' 255: + # drop + return + data = pack_addr(r_addr[0]) + struct.pack('>H', r_addr[1]) + data + ref_iv = [encrypt.encrypt_new_iv(self._method)] + self._protocol.obfs.server_info.iv = ref_iv[0] + data = self._protocol.server_udp_pre_encrypt(data, client_uid) + response = encrypt.encrypt_all_iv(self._protocol.obfs.server_info.key, self._method, 1, + data, ref_iv) + if not response: + return + else: + ref_iv = [0] + data = encrypt.encrypt_all_iv(self._protocol.obfs.server_info.key, self._method, 0, + data, ref_iv) + if not data: + return + self._protocol.obfs.server_info.recv_iv = ref_iv[0] + data = self._protocol.client_udp_post_decrypt(data) + header_result = parse_header(data) + if header_result is None: + return + #connecttype, dest_addr, dest_port, header_length = header_result + #logging.debug('UDP handle_client %s:%d to %s:%d' % (common.to_str(r_addr[0]), r_addr[1], dest_addr, dest_port)) + + response = b'\x00\x00\x00' + data + + if client_addr: + if client_uid: + self.add_transfer_d(client_uid, len(response)) + else: + self.server_transfer_dl += len(response) + self.write_to_server_socket(response, client_addr[0]) + if client_dns_pair: + logging.debug("remove dns client %s:%d" % (client_addr[0][0], client_addr[0][1])) + del self._cache_dns_client[key] + self._close_client(client_dns_pair[0]) + else: + # this packet is from somewhere else we know + # simply drop that packet + pass + + def write_to_server_socket(self, data, addr): + uncomplete = False + retry = 0 + try: + self._server_socket.sendto(data, addr) + data = None + while self._data_to_write_to_server_socket: + data_buf = self._data_to_write_to_server_socket[0] + retry = data_buf[1] + 1 + del self._data_to_write_to_server_socket[0] + data, addr = data_buf[0] + self._server_socket.sendto(data, addr) + except (OSError, IOError) as e: + error_no = eventloop.errno_from_exception(e) + uncomplete = True + if error_no in (errno.EWOULDBLOCK,): + pass + else: + shell.print_exception(e) + return False + #if uncomplete and data is not None and retry < 3: + # self._data_to_write_to_server_socket.append([(data, addr), retry]) + #''' + + def add_to_loop(self, loop): + if self._eventloop: + raise Exception('already add to loop') + if self._closed: + raise Exception('already closed') + self._eventloop = loop + + server_socket = self._server_socket + self._eventloop.add(server_socket, + eventloop.POLL_IN | eventloop.POLL_ERR, self) + loop.add_periodic(self.handle_periodic) + + def remove_handler(self, client): + if hash(client) in self._timeout_cache: + del self._timeout_cache[hash(client)] + + def update_activity(self, client): + self._timeout_cache[hash(client)] = client + + def _sweep_timeout(self): + self._timeout_cache.sweep() + + def _close_tcp_client(self, client): + if client.remote_address: + logging.debug('timed out: %s:%d' % + client.remote_address) + else: + logging.debug('timed out') + client.destroy() + client.destroy_local() + + def handle_event(self, sock, fd, event): + if sock == self._server_socket: + if event & eventloop.POLL_ERR: + logging.error('UDP server_socket err') + try: + self._handle_server() + except Exception as e: + shell.print_exception(e) + if self._config['verbose']: + traceback.print_exc() + elif sock and (fd in self._sockets): + if event & eventloop.POLL_ERR: + logging.error('UDP client_socket err') + try: + self._handle_client(sock) + except Exception as e: + shell.print_exception(e) + if self._config['verbose']: + traceback.print_exc() + else: + if sock: + handler = self._fd_to_handlers.get(fd, None) + if handler: + handler.handle_event(sock, event) + else: + logging.warn('poll removed fd') + + def handle_periodic(self): + if self._closed: + self._cache.clear(0) + self._cache_dns_client.clear(0) + if self._eventloop: + self._eventloop.remove_periodic(self.handle_periodic) + self._eventloop.remove(self._server_socket) + if self._server_socket: + self._server_socket.close() + self._server_socket = None + logging.info('closed UDP port %d', self._listen_port) + else: + before_sweep_size = len(self._sockets) + self._cache.sweep() + self._cache_dns_client.sweep() + if before_sweep_size != len(self._sockets): + logging.debug('UDP port %5d sockets %d' % (self._listen_port, len(self._sockets))) + self._sweep_timeout() + + def close(self, next_tick=False): + logging.debug('UDP close') + self._closed = True + if not next_tick: + if self._eventloop: + self._eventloop.remove_periodic(self.handle_periodic) + self._eventloop.remove(self._server_socket) + self._server_socket.close() + self._cache.clear(0) + self._cache_dns_client.clear(0) diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/version.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/version.py new file mode 100644 index 000000000..f3e1ef796 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/shadowsocks/version.py @@ -0,0 +1,20 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright 2017 breakwa11 +# +# 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. + +def version(): + return '3.4.0 2017-07-27' + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/stop.sh b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/stop.sh new file mode 100755 index 000000000..56567daa0 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/stop.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +python_ver=$(ls /usr/bin|grep -e "^python[23]\.[1-9]\+$"|tail -1) +eval $(ps -ef | grep "[0-9] ${python_ver} server\\.py m" | awk '{print "kill "$2}') + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/switchrule.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/switchrule.py new file mode 100644 index 000000000..6687e12cf --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/switchrule.py @@ -0,0 +1,8 @@ +def getKeys(key_list): + return key_list + #return key_list + ['plan'] # append the column name 'plan' + +def isTurnOn(row): + return True + #return row['plan'] == 'B' # then judge here + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tail.sh b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tail.sh new file mode 100755 index 000000000..f36f605ee --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tail.sh @@ -0,0 +1,3 @@ +#!/bin/bash +cd `dirname $0` +tail -f ssserver.log diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/aes-cfb1.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/aes-cfb1.json new file mode 100644 index 000000000..40d0b2107 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/aes-cfb1.json @@ -0,0 +1,10 @@ +{ + "server":"127.0.0.1", + "server_port":8388, + "local_port":1081, + "password":"aes_password", + "timeout":60, + "method":"aes-256-cfb1", + "local_address":"127.0.0.1", + "fast_open":false +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/aes-cfb8.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/aes-cfb8.json new file mode 100644 index 000000000..fb7014b1e --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/aes-cfb8.json @@ -0,0 +1,10 @@ +{ + "server":"127.0.0.1", + "server_port":8388, + "local_port":1081, + "password":"aes_password", + "timeout":60, + "method":"aes-256-cfb8", + "local_address":"127.0.0.1", + "fast_open":false +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/aes-ctr.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/aes-ctr.json new file mode 100644 index 000000000..1fed8a8c7 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/aes-ctr.json @@ -0,0 +1,10 @@ +{ + "server":"127.0.0.1", + "server_port":8388, + "local_port":1081, + "password":"aes_password", + "timeout":60, + "method":"aes-256-ctr", + "local_address":"127.0.0.1", + "fast_open":false +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/aes.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/aes.json new file mode 100644 index 000000000..a3d95b9b5 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/aes.json @@ -0,0 +1,10 @@ +{ + "server":"127.0.0.1", + "server_port":8388, + "local_port":1081, + "password":"aes_password", + "timeout":60, + "method":"aes-256-cfb", + "local_address":"127.0.0.1", + "fast_open":false +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/assert.sh b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/assert.sh new file mode 100755 index 000000000..b0c679cbc --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/assert.sh @@ -0,0 +1,148 @@ +#!/bin/bash +# assert.sh 1.0 - bash unit testing framework +# Copyright (C) 2009, 2010, 2011, 2012 Robert Lehmann +# +# http://github.com/lehmannro/assert.sh +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . + +export DISCOVERONLY=${DISCOVERONLY:-} +export DEBUG=${DEBUG:-} +export STOP=${STOP:-} +export INVARIANT=${INVARIANT:-} +export CONTINUE=${CONTINUE:-} + +args="$(getopt -n "$0" -l \ + verbose,help,stop,discover,invariant,continue vhxdic $*)" \ +|| exit -1 +for arg in $args; do + case "$arg" in + -h) + echo "$0 [-vxidc]" \ + "[--verbose] [--stop] [--invariant] [--discover] [--continue]" + echo "`sed 's/./ /g' <<< "$0"` [-h] [--help]" + exit 0;; + --help) + cat < [stdin] + (( tests_ran++ )) || : + [[ -n "$DISCOVERONLY" ]] && return || true + # printf required for formatting + printf -v expected "x${2:-}" # x required to overwrite older results + result="$(eval 2>/dev/null $1 <<< ${3:-})" || true + # Note: $expected is already decorated + if [[ "x$result" == "$expected" ]]; then + [[ -n "$DEBUG" ]] && echo -n . || true + return + fi + result="$(sed -e :a -e '$!N;s/\n/\\n/;ta' <<< "$result")" + [[ -z "$result" ]] && result="nothing" || result="\"$result\"" + [[ -z "$2" ]] && expected="nothing" || expected="\"$2\"" + _assert_fail "expected $expected${_indent}got $result" "$1" "$3" +} + +assert_raises() { + # assert_raises [stdin] + (( tests_ran++ )) || : + [[ -n "$DISCOVERONLY" ]] && return || true + status=0 + (eval $1 <<< ${3:-}) > /dev/null 2>&1 || status=$? + expected=${2:-0} + if [[ "$status" -eq "$expected" ]]; then + [[ -n "$DEBUG" ]] && echo -n . || true + return + fi + _assert_fail "program terminated with code $status instead of $expected" "$1" "$3" +} + +_assert_fail() { + # _assert_fail + [[ -n "$DEBUG" ]] && echo -n X + report="test #$tests_ran \"$2${3:+ <<< $3}\" failed:${_indent}$1" + if [[ -n "$STOP" ]]; then + [[ -n "$DEBUG" ]] && echo + echo "$report" + exit 1 + fi + tests_errors[$tests_failed]="$report" + (( tests_failed++ )) || : +} + +_assert_reset +: ${tests_suite_status:=0} # remember if any of the tests failed so far +_assert_cleanup() { + local status=$? + # modify exit code if it's not already non-zero + [[ $status -eq 0 && -z $CONTINUE ]] && exit $tests_suite_status +} +trap _assert_cleanup EXIT diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/chacha20.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/chacha20.json new file mode 100644 index 000000000..541a9beb5 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/chacha20.json @@ -0,0 +1,10 @@ +{ + "server":"127.0.0.1", + "server_port":8388, + "local_port":1081, + "password":"salsa20_password", + "timeout":60, + "method":"chacha20", + "local_address":"127.0.0.1", + "fast_open":false +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/client-multi-server-ip.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/client-multi-server-ip.json new file mode 100644 index 000000000..1823c2a75 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/client-multi-server-ip.json @@ -0,0 +1,10 @@ +{ + "server":["127.0.0.1", "127.0.0.1"], + "server_port":8388, + "local_port":1081, + "password":"aes_password", + "timeout":60, + "method":"aes-256-cfb", + "local_address":"127.0.0.1", + "fast_open":false +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/coverage_server.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/coverage_server.py new file mode 100644 index 000000000..23cc8cd71 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/coverage_server.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# +# Copyright 2015 clowwindy +# +# 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. + +if __name__ == '__main__': + import tornado.ioloop + import tornado.web + import urllib + + class MainHandler(tornado.web.RequestHandler): + def get(self, project): + try: + with open('/tmp/%s-coverage' % project, 'rb') as f: + coverage = f.read().strip() + n = int(coverage.strip('%')) + if n >= 80: + color = 'brightgreen' + else: + color = 'yellow' + self.redirect(('https://img.shields.io/badge/' + 'coverage-%s-%s.svg' + '?style=flat') % + (urllib.quote(coverage), color)) + except IOError: + raise tornado.web.HTTPError(404) + + application = tornado.web.Application([ + (r"/([a-zA-Z0-9\-_]+)", MainHandler), + ]) + + if __name__ == "__main__": + application.listen(8888, address='127.0.0.1') + tornado.ioloop.IOLoop.instance().start() diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/fastopen.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/fastopen.json new file mode 100644 index 000000000..f3980b65e --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/fastopen.json @@ -0,0 +1,10 @@ +{ + "server":"127.0.0.1", + "server_port":8388, + "local_port":1081, + "password":"fastopen_password", + "timeout":60, + "method":"aes-256-cfb", + "local_address":"127.0.0.1", + "fast_open":true +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/ipv6-client-side.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/ipv6-client-side.json new file mode 100644 index 000000000..6c3cfaf8d --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/ipv6-client-side.json @@ -0,0 +1,10 @@ +{ + "server":"::1", + "server_port":8388, + "local_port":1081, + "password":"aes_password", + "timeout":60, + "method":"aes-256-cfb", + "local_address":"127.0.0.1", + "fast_open":false +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/ipv6.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/ipv6.json new file mode 100644 index 000000000..d855f9c47 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/ipv6.json @@ -0,0 +1,10 @@ +{ + "server":"::", + "server_port":8388, + "local_port":1081, + "password":"aes_password", + "timeout":60, + "method":"aes-256-cfb", + "local_address":"127.0.0.1", + "fast_open":false +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/jenkins.sh b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/jenkins.sh new file mode 100755 index 000000000..ea5c1630b --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/jenkins.sh @@ -0,0 +1,82 @@ +#!/bin/bash + +result=0 + +function run_test { + printf '\e[0;36m' + echo "running test: $command $@" + printf '\e[0m' + + $command "$@" + status=$? + if [ $status -ne 0 ]; then + printf '\e[0;31m' + echo "test failed: $command $@" + printf '\e[0m' + echo + result=1 + else + printf '\e[0;32m' + echo OK + printf '\e[0m' + echo + fi + return 0 +} + +python --version +coverage erase +mkdir tmp +run_test pep8 --ignore=E402 . +run_test pyflakes . +run_test coverage run tests/nose_plugin.py -v +run_test python setup.py sdist +run_test tests/test_daemon.sh +run_test python tests/test.py --with-coverage -c tests/aes.json +run_test python tests/test.py --with-coverage -c tests/aes-ctr.json +run_test python tests/test.py --with-coverage -c tests/aes-cfb1.json +run_test python tests/test.py --with-coverage -c tests/aes-cfb8.json +run_test python tests/test.py --with-coverage -c tests/rc4-md5.json +run_test python tests/test.py --with-coverage -c tests/salsa20.json +run_test python tests/test.py --with-coverage -c tests/chacha20.json +run_test python tests/test.py --with-coverage -c tests/table.json +run_test python tests/test.py --with-coverage -c tests/server-multi-ports.json +run_test python tests/test.py --with-coverage -s tests/aes.json -c tests/client-multi-server-ip.json +run_test python tests/test.py --with-coverage -s tests/server-multi-passwd.json -c tests/server-multi-passwd-client-side.json +run_test python tests/test.py --with-coverage -c tests/workers.json +run_test python tests/test.py --with-coverage -s tests/ipv6.json -c tests/ipv6-client-side.json +run_test python tests/test.py --with-coverage -b "-m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -q" -a "-m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -l 1081 -vv" +run_test python tests/test.py --with-coverage -b "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 --workers 1" -a "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 -l 1081 -t 30 -qq -b 127.0.0.1" +run_test python tests/test.py --with-coverage --should-fail --url="http://127.0.0.1/" -b "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 --forbidden-ip=127.0.0.1,::1,8.8.8.8" -a "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 -l 1081 -t 30 -b 127.0.0.1" + +# test if DNS works +run_test python tests/test.py --with-coverage -c tests/aes.json --url="https://clients1.google.com/generate_204" + +# test localhost is in the forbidden list by default +run_test python tests/test.py --with-coverage --should-fail --tcp-only --url="http://127.0.0.1/" -b "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388" -a "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 -l 1081 -t 30 -b 127.0.0.1" + +# test localhost is available when forbidden list is empty +run_test python tests/test.py --with-coverage --tcp-only --url="http://127.0.0.1/" -b "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 --forbidden-ip=" -a "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 -l 1081 -t 30 -b 127.0.0.1" + +if [ -f /proc/sys/net/ipv4/tcp_fastopen ] ; then + if [ 3 -eq `cat /proc/sys/net/ipv4/tcp_fastopen` ] ; then + # we have to run it twice: + # the first time there's no syn cookie + # the second time there is syn cookie + run_test python tests/test.py --with-coverage -c tests/fastopen.json + run_test python tests/test.py --with-coverage -c tests/fastopen.json + fi +fi + +run_test tests/test_large_file.sh +run_test tests/test_udp_src.sh +run_test tests/test_command.sh + +coverage combine && coverage report --include=shadowsocks/* +rm -rf htmlcov +rm -rf tmp +coverage html --include=shadowsocks/* + +coverage report --include=shadowsocks/* | tail -n1 | rev | cut -d' ' -f 1 | rev > /tmp/shadowsocks-coverage + +exit $result diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/libsodium/install.sh b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/libsodium/install.sh new file mode 100755 index 000000000..b0e35fa13 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/libsodium/install.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [ ! -d libsodium-1.0.1 ]; then + wget https://github.com/jedisct1/libsodium/releases/download/1.0.1/libsodium-1.0.1.tar.gz || exit 1 + tar xf libsodium-1.0.1.tar.gz || exit 1 +fi +pushd libsodium-1.0.1 +./configure && make -j2 && make install || exit 1 +sudo ldconfig +popd diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/nose_plugin.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/nose_plugin.py new file mode 100644 index 000000000..86b1a8653 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/nose_plugin.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python +# +# Copyright 2015 clowwindy +# +# 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. + +import nose +from nose.plugins.base import Plugin + + +class ExtensionPlugin(Plugin): + + name = "ExtensionPlugin" + + def options(self, parser, env): + Plugin.options(self, parser, env) + + def configure(self, options, config): + Plugin.configure(self, options, config) + self.enabled = True + + def wantFile(self, file): + return file.endswith('.py') + + def wantDirectory(self, directory): + return True + + def wantModule(self, file): + return True + + +if __name__ == '__main__': + nose.main(addplugins=[ExtensionPlugin()]) diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/rc4-md5.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/rc4-md5.json new file mode 100644 index 000000000..26ba0dfa7 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/rc4-md5.json @@ -0,0 +1,10 @@ +{ + "server":"127.0.0.1", + "server_port":8388, + "local_port":1081, + "password":"aes_password", + "timeout":60, + "method":"rc4-md5", + "local_address":"127.0.0.1", + "fast_open":false +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/salsa20-ctr.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/salsa20-ctr.json new file mode 100644 index 000000000..5ca6c45f5 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/salsa20-ctr.json @@ -0,0 +1,10 @@ +{ + "server":"127.0.0.1", + "server_port":8388, + "local_port":1081, + "password":"salsa20_password", + "timeout":60, + "method":"salsa20-ctr", + "local_address":"127.0.0.1", + "fast_open":false +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/salsa20.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/salsa20.json new file mode 100644 index 000000000..7e303800d --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/salsa20.json @@ -0,0 +1,10 @@ +{ + "server":"127.0.0.1", + "server_port":8388, + "local_port":1081, + "password":"salsa20_password", + "timeout":60, + "method":"salsa20", + "local_address":"127.0.0.1", + "fast_open":false +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/server-multi-passwd-client-side.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/server-multi-passwd-client-side.json new file mode 100644 index 000000000..c822c98b9 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/server-multi-passwd-client-side.json @@ -0,0 +1,8 @@ +{ + "server": "127.0.0.1", + "server_port": "8385", + "local_port": 1081, + "password": "foobar5", + "timeout": 60, + "method": "aes-256-cfb" +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/server-multi-passwd-table.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/server-multi-passwd-table.json new file mode 100644 index 000000000..a2c0a8089 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/server-multi-passwd-table.json @@ -0,0 +1,19 @@ +{ + "server": "127.0.0.1", + "server_port": 8384, + "local_port": 1081, + "password": "foobar4", + "port_password": { + "8381": "foobar1", + "8382": "foobar2", + "8383": "foobar3", + "8384": "foobar4", + "8385": "foobar5", + "8386": "foobar6", + "8387": "foobar7", + "8388": "foobar8", + "8389": "foobar9" + }, + "timeout": 60, + "method": "table" +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/server-multi-passwd.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/server-multi-passwd.json new file mode 100644 index 000000000..b1407f0a1 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/server-multi-passwd.json @@ -0,0 +1,17 @@ +{ + "server": "127.0.0.1", + "local_port": 1081, + "port_password": { + "8381": "foobar1", + "8382": "foobar2", + "8383": "foobar3", + "8384": "foobar4", + "8385": "foobar5", + "8386": "foobar6", + "8387": "foobar7", + "8388": "foobar8", + "8389": "foobar9" + }, + "timeout": 60, + "method": "aes-256-cfb" +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/server-multi-ports.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/server-multi-ports.json new file mode 100644 index 000000000..5bdbcab64 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/server-multi-ports.json @@ -0,0 +1,8 @@ +{ + "server": "127.0.0.1", + "server_port": [8384, 8345, 8346, 8347], + "local_port": 1081, + "password": "foobar4", + "timeout": 60, + "method": "aes-256-cfb" +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/setup_tc.sh b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/setup_tc.sh new file mode 100755 index 000000000..1a5fa208b --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/setup_tc.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +DEV=lo +PORT=8388 +DELAY=100ms + +type tc 2> /dev/null && ( + tc qdisc add dev $DEV root handle 1: htb + tc class add dev $DEV parent 1: classid 1:1 htb rate 2mbps + tc class add dev $DEV parent 1:1 classid 1:6 htb rate 2mbps ceil 1mbps prio 0 + tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 6 fw flowid 1:6 + + tc filter add dev $DEV parent 1:0 protocol ip u32 match ip dport $PORT 0xffff flowid 1:6 + tc filter add dev $DEV parent 1:0 protocol ip u32 match ip sport $PORT 0xffff flowid 1:6 + + tc qdisc show dev lo +) + diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/socksify/install.sh b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/socksify/install.sh new file mode 100755 index 000000000..8eff72df0 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/socksify/install.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [ ! -d dante-1.4.0 ]; then + wget http://www.inet.no/dante/files/dante-1.4.0.tar.gz || exit 1 + tar xf dante-1.4.0.tar.gz || exit 1 +fi +pushd dante-1.4.0 +./configure && make -j4 && make install || exit 1 +popd +cp tests/socksify/socks.conf /etc/ || exit 1 diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/socksify/socks.conf b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/socksify/socks.conf new file mode 100644 index 000000000..13db772fd --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/socksify/socks.conf @@ -0,0 +1,5 @@ +route { + from: 0.0.0.0/0 to: 0.0.0.0/0 via: 127.0.0.1 port = 1081 + proxyprotocol: socks_v5 + method: none +} \ No newline at end of file diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/table.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/table.json new file mode 100644 index 000000000..cca6ac27e --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/table.json @@ -0,0 +1,10 @@ +{ + "server":"127.0.0.1", + "server_port":8388, + "local_port":1081, + "password":"table_password", + "timeout":60, + "method":"table", + "local_address":"127.0.0.1", + "fast_open":false +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/test.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/test.py new file mode 100755 index 000000000..408340134 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/test.py @@ -0,0 +1,158 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright 2015 clowwindy +# +# 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. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import sys +import os +import signal +import select +import time +import argparse +from subprocess import Popen, PIPE + +python = ['python'] + +default_url = 'http://localhost/' + +parser = argparse.ArgumentParser(description='test Shadowsocks') +parser.add_argument('-c', '--client-conf', type=str, default=None) +parser.add_argument('-s', '--server-conf', type=str, default=None) +parser.add_argument('-a', '--client-args', type=str, default=None) +parser.add_argument('-b', '--server-args', type=str, default=None) +parser.add_argument('--with-coverage', action='store_true', default=None) +parser.add_argument('--should-fail', action='store_true', default=None) +parser.add_argument('--tcp-only', action='store_true', default=None) +parser.add_argument('--url', type=str, default=default_url) +parser.add_argument('--dns', type=str, default='8.8.8.8') + +config = parser.parse_args() + +if config.with_coverage: + python = ['coverage', 'run', '-p'] + +client_args = python + ['shadowsocks/local.py', '-v'] +server_args = python + ['shadowsocks/server.py', '-v'] + +if config.client_conf: + client_args.extend(['-c', config.client_conf]) + if config.server_conf: + server_args.extend(['-c', config.server_conf]) + else: + server_args.extend(['-c', config.client_conf]) +if config.client_args: + client_args.extend(config.client_args.split()) + if config.server_args: + server_args.extend(config.server_args.split()) + else: + server_args.extend(config.client_args.split()) +if config.url == default_url: + server_args.extend(['--forbidden-ip', '']) + +p1 = Popen(server_args, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True) +p2 = Popen(client_args, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True) +p3 = None +p4 = None +p3_fin = False +p4_fin = False + +# 1 shadowsocks started +# 2 curl started +# 3 curl finished +# 4 dig started +# 5 dig finished +stage = 1 + +try: + local_ready = False + server_ready = False + fdset = [p1.stdout, p2.stdout, p1.stderr, p2.stderr] + while True: + r, w, e = select.select(fdset, [], fdset) + if e: + break + + for fd in r: + line = fd.readline() + if not line: + if stage == 2 and fd == p3.stdout: + stage = 3 + if stage == 4 and fd == p4.stdout: + stage = 5 + if bytes != str: + line = str(line, 'utf8') + sys.stderr.write(line) + if line.find('starting local') >= 0: + local_ready = True + if line.find('starting server') >= 0: + server_ready = True + + if stage == 1: + time.sleep(2) + + p3 = Popen(['curl', config.url, '-v', '-L', + '--socks5-hostname', '127.0.0.1:1081', + '-m', '15', '--connect-timeout', '10'], + stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True) + if p3 is not None: + fdset.append(p3.stdout) + fdset.append(p3.stderr) + stage = 2 + else: + sys.exit(1) + + if stage == 3 and p3 is not None: + fdset.remove(p3.stdout) + fdset.remove(p3.stderr) + r = p3.wait() + if config.should_fail: + if r == 0: + sys.exit(1) + else: + if r != 0: + sys.exit(1) + if config.tcp_only: + break + p4 = Popen(['socksify', 'dig', '@%s' % config.dns, + 'www.google.com'], + stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True) + if p4 is not None: + fdset.append(p4.stdout) + fdset.append(p4.stderr) + stage = 4 + else: + sys.exit(1) + + if stage == 5: + r = p4.wait() + if config.should_fail: + if r == 0: + sys.exit(1) + print('test passed (expecting failure)') + else: + if r != 0: + sys.exit(1) + print('test passed') + break +finally: + for p in [p1, p2]: + try: + os.kill(p.pid, signal.SIGINT) + os.waitpid(p.pid, 0) + except OSError: + pass diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/test_command.sh b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/test_command.sh new file mode 100755 index 000000000..a1a777b0d --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/test_command.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +. tests/assert.sh + +PYTHON="coverage run -p" +LOCAL="$PYTHON shadowsocks/local.py" +SERVER="$PYTHON shadowsocks/server.py" + +assert "$LOCAL --version 2>&1 | grep Shadowsocks | awk -F\" \" '{print \$1}'" "Shadowsocks" +assert "$SERVER --version 2>&1 | grep Shadowsocks | awk -F\" \" '{print \$1}'" "Shadowsocks" + + +assert "$LOCAL 2>&1 -m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -d start | grep WARNING | awk -F\"WARNING\" '{print \$2}'" " warning: server set to listen on 127.0.0.1:8388, are you sure?" +$LOCAL 2>/dev/null 1>/dev/null -m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -d stop + +assert "$LOCAL 2>&1 -m rc4-md5 -k testrc4 -s 0.0.0.0 -p 8388 -t10 -d start | grep WARNING | awk -F\"WARNING\" '{print \$2}'" " warning: your timeout 10 seems too short" +$LOCAL 2>/dev/null 1>/dev/null -m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -d stop + +assert "$LOCAL 2>&1 -m rc4-md5 -k testrc4 -s 0.0.0.0 -p 8388 -t1000 -d start | grep WARNING | awk -F\"WARNING\" '{print \$2}'" " warning: your timeout 1000 seems too long" +$LOCAL 2>/dev/null 1>/dev/null -m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -d stop + +assert "$LOCAL 2>&1 -m rc4 -k testrc4 -s 0.0.0.0 -p 8388 -d start | grep WARNING | awk -F\"WARNING\" '{print \$2}'" " warning: RC4 is not safe; please use a safer cipher, like AES-256-CFB" +$LOCAL 2>/dev/null 1>/dev/null -m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -d stop + +assert "$LOCAL 2>&1 -m rc4-md5 -k mypassword -s 0.0.0.0 -p 8388 -d start | grep ERROR | awk -F\"ERROR\" '{print \$2}'" " DON'T USE DEFAULT PASSWORD! Please change it in your config.json!" +$LOCAL 2>/dev/null 1>/dev/null -m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -d stop + + +assert "$SERVER 2>&1 --forbidden-ip 127.0.0.1/4a -m rc4-md5 -k 12345 -p 8388 -s 0.0.0.0 -d start | grep ERROR | awk -F\"ERROR\" '{print \$2}'" ": Not a valid CIDR notation: 127.0.0.1/4a" +$LOCAL 2>/dev/null 1>/dev/null -m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -d stop + +assert_end command diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/test_daemon.sh b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/test_daemon.sh new file mode 100755 index 000000000..7a192bdb1 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/test_daemon.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +function run_test { + expected=$1 + shift + echo "running test: $command $@" + $command $@ + status=$? + if [ $status -ne $expected ]; then + echo "exit $status != $expected" + exit 1 + fi + echo "exit status $status == $expected" + echo OK + return +} + +for module in local server +do + +command="coverage run -p shadowsocks/$module.py" + +mkdir -p tmp + +run_test 0 -c tests/aes.json -d stop --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log + +run_test 0 -c tests/aes.json -d start --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log +run_test 0 -c tests/aes.json -d stop --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log + +run_test 0 -c tests/aes.json -d start --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log +run_test 1 -c tests/aes.json -d start --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log +run_test 0 -c tests/aes.json -d stop --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log + +run_test 0 -c tests/aes.json -d start --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log +run_test 0 -c tests/aes.json -d restart --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log +run_test 0 -c tests/aes.json -d stop --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log + +run_test 0 -c tests/aes.json -d restart --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log +run_test 0 -c tests/aes.json -d stop --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log + +run_test 1 -c tests/aes.json -d start --pid-file tmp/not_exist/shadowsocks.pid --log-file tmp/shadowsocks.log + +done diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/test_large_file.sh b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/test_large_file.sh new file mode 100755 index 000000000..7a61caff1 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/test_large_file.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +PYTHON="coverage run -p" +URL=http://127.0.0.1/file + +mkdir -p tmp + +$PYTHON shadowsocks/local.py -c tests/aes.json & +LOCAL=$! + +$PYTHON shadowsocks/server.py -c tests/aes.json --forbidden-ip "" & +SERVER=$! + +sleep 3 + +time curl -o tmp/expected $URL +time curl -o tmp/result --socks5-hostname 127.0.0.1:1081 $URL + +kill -s SIGINT $LOCAL +kill -s SIGINT $SERVER + +sleep 2 + +diff tmp/expected tmp/result || exit 1 diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/test_udp_src.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/test_udp_src.py new file mode 100644 index 000000000..e8fa5057e --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/test_udp_src.py @@ -0,0 +1,83 @@ +#!/usr/bin/python + +import socket +import socks + + +SERVER_IP = '127.0.0.1' +SERVER_PORT = 1081 + + +if __name__ == '__main__': + # Test 1: same source port IPv4 + sock_out = socks.socksocket(socket.AF_INET, socket.SOCK_DGRAM, + socket.SOL_UDP) + sock_out.set_proxy(socks.SOCKS5, SERVER_IP, SERVER_PORT) + sock_out.bind(('127.0.0.1', 9000)) + + sock_in1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, + socket.SOL_UDP) + sock_in2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, + socket.SOL_UDP) + + sock_in1.bind(('127.0.0.1', 9001)) + sock_in2.bind(('127.0.0.1', 9002)) + + sock_out.sendto(b'data', ('127.0.0.1', 9001)) + result1 = sock_in1.recvfrom(8) + + sock_out.sendto(b'data', ('127.0.0.1', 9002)) + result2 = sock_in2.recvfrom(8) + + sock_out.close() + sock_in1.close() + sock_in2.close() + + # make sure they're from the same source port + assert result1 == result2 + + # Test 2: same source port IPv6 + # try again from the same port but IPv6 + sock_out = socks.socksocket(socket.AF_INET, socket.SOCK_DGRAM, + socket.SOL_UDP) + sock_out.set_proxy(socks.SOCKS5, SERVER_IP, SERVER_PORT) + sock_out.bind(('127.0.0.1', 9000)) + + sock_in1 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, + socket.SOL_UDP) + sock_in2 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, + socket.SOL_UDP) + + sock_in1.bind(('::1', 9001)) + sock_in2.bind(('::1', 9002)) + + sock_out.sendto(b'data', ('::1', 9001)) + result1 = sock_in1.recvfrom(8) + + sock_out.sendto(b'data', ('::1', 9002)) + result2 = sock_in2.recvfrom(8) + + sock_out.close() + sock_in1.close() + sock_in2.close() + + # make sure they're from the same source port + assert result1 == result2 + + # Test 3: different source ports IPv6 + sock_out = socks.socksocket(socket.AF_INET, socket.SOCK_DGRAM, + socket.SOL_UDP) + sock_out.set_proxy(socks.SOCKS5, SERVER_IP, SERVER_PORT) + sock_out.bind(('127.0.0.1', 9003)) + + sock_in1 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, + socket.SOL_UDP) + sock_in1.bind(('::1', 9001)) + sock_out.sendto(b'data', ('::1', 9001)) + result3 = sock_in1.recvfrom(8) + + # make sure they're from different source ports + assert result1 != result3 + + sock_out.close() + sock_in1.close() diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/test_udp_src.sh b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/test_udp_src.sh new file mode 100755 index 000000000..6a778abc1 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/test_udp_src.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +PYTHON="coverage run -p" + +mkdir -p tmp + +$PYTHON shadowsocks/local.py -c tests/aes.json -v & +LOCAL=$! + +$PYTHON shadowsocks/server.py -c tests/aes.json --forbidden-ip "" -v & +SERVER=$! + +sleep 3 + +python tests/test_udp_src.py +r=$? + +kill -s SIGINT $LOCAL +kill -s SIGINT $SERVER + +sleep 2 + +exit $r diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/workers.json b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/workers.json new file mode 100644 index 000000000..2015ff6c6 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/tests/workers.json @@ -0,0 +1,10 @@ +{ + "server":"127.0.0.1", + "server_port":8388, + "local_port":1081, + "password":"workers_password", + "timeout":60, + "method":"aes-256-cfb", + "local_address":"127.0.0.1", + "workers": 4 +} diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/utils/README.md b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/utils/README.md new file mode 100644 index 000000000..f624309c7 --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/utils/README.md @@ -0,0 +1,9 @@ +Useful Tools +=========== + +autoban.py +---------- + +Automatically ban IPs that try to brute force crack the server. + +See https://github.com/shadowsocks/shadowsocks/wiki/Ban-Brute-Force-Crackers diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/utils/autoban.py b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/utils/autoban.py new file mode 100755 index 000000000..1bbb65c9b --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/utils/autoban.py @@ -0,0 +1,53 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2015 clowwindy +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import absolute_import, division, print_function, \ + with_statement + +import os +import sys +import argparse + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='See README') + parser.add_argument('-c', '--count', default=3, type=int, + help='with how many failure times it should be ' + 'considered as an attack') + config = parser.parse_args() + ips = {} + banned = set() + for line in sys.stdin: + if 'can not parse header when' in line: + ip = line.split()[-1].split(':')[0] + if ip not in ips: + ips[ip] = 1 + print(ip) + sys.stdout.flush() + else: + ips[ip] += 1 + if ip not in banned and ips[ip] >= config.count: + banned.add(ip) + cmd = 'iptables -A INPUT -s %s -j DROP' % ip + print(cmd, file=sys.stderr) + sys.stderr.flush() + os.system(cmd) diff --git a/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/utils/fail2ban/shadowsocks.conf b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/utils/fail2ban/shadowsocks.conf new file mode 100644 index 000000000..9b1c7ec7a --- /dev/null +++ b/package/lean/luci-app-ssrserver-python/root/usr/share/ssr/utils/fail2ban/shadowsocks.conf @@ -0,0 +1,5 @@ +[Definition] + +_daemon = shadowsocks + +failregex = ^\s+ERROR\s+can not parse header when handling connection from :\d+$ diff --git a/package/lean/luci-app-usb-printer/Makefile b/package/lean/luci-app-usb-printer/Makefile new file mode 100644 index 000000000..fe3e8849b --- /dev/null +++ b/package/lean/luci-app-usb-printer/Makefile @@ -0,0 +1,18 @@ +# +# Copyright (C) 2008-2014 The LuCI Team +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=USB Printer Share via TCP/IP +LUCI_DEPENDS:=+p910nd +kmod-usb-printer +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature +#applications/luci-app-usb-printer/ +#applications/luci-app-usb-printer/ diff --git a/package/lean/luci-app-usb-printer/ipkg/postinst b/package/lean/luci-app-usb-printer/ipkg/postinst new file mode 100755 index 000000000..97a343c7b --- /dev/null +++ b/package/lean/luci-app-usb-printer/ipkg/postinst @@ -0,0 +1,6 @@ +#!/bin/sh +[ -n "${IPKG_INSTROOT}" ] || { + ( . /etc/uci-defaults/luci-usb-printer ) && rm -f /etc/uci-defaults/luci-usb-printer + exit 0 +} + diff --git a/package/lean/luci-app-usb-printer/luasrc/controller/usb_printer.lua b/package/lean/luci-app-usb-printer/luasrc/controller/usb_printer.lua new file mode 100644 index 000000000..ebcee4f79 --- /dev/null +++ b/package/lean/luci-app-usb-printer/luasrc/controller/usb_printer.lua @@ -0,0 +1,29 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright 2008 Steven Barth + +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 + +$Id$ +]]-- + +require("luci.sys") + +module("luci.controller.usb_printer", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/usb_printer") then + return + end + + entry({"admin", "nas"}, firstchild(), "NAS", 44).dependent = false + + local page + + page = entry({"admin", "nas", "usb_printer"}, cbi("usb_printer"), _("USB Printer Server"), 50) +end diff --git a/package/lean/luci-app-usb-printer/luasrc/model/cbi/usb_printer.lua b/package/lean/luci-app-usb-printer/luasrc/model/cbi/usb_printer.lua new file mode 100644 index 000000000..3cc7526ef --- /dev/null +++ b/package/lean/luci-app-usb-printer/luasrc/model/cbi/usb_printer.lua @@ -0,0 +1,130 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright 2008 Steven Barth +Copyright 2005-2013 hackpascal + +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 + +$Id$ +]]-- + +require "luci.util" +local uci = luci.model.uci.cursor_state() +local net = require "luci.model.network" + +m = Map("usb_printer", translate("USB Printer Server"), + translate("Shares multiple USB printers via TCP/IP.
When modified bingings, re-plug usb connectors to take effect.
This module requires kmod-usb-printer.")) + +function hex_align(hex, num) + local len = num - string.len(hex) + + return string.rep("0", len) .. hex +end + +function detect_usb_printers() + local data = {} + + local lps = luci.util.execi("/usr/bin/detectlp") + + for value in lps do + local row = {} + + --[[ + detectlp 鐨勮緭鍑烘牸寮忥細 + 璁惧鍚嶏紝VID/PID/?,鎻忚堪锛屽瀷鍙 + ]]-- + + local pos = string.find(value, ",") + + local devname = string.sub(value, 1, pos - 1) + + local value = string.sub(value, pos + 1, string.len(value)) + + pos = string.find(value, ",") + local product = string.sub(value, 1, pos - 1) + + value = string.sub(value, pos + 1, string.len(value)) + + pos = string.find(value, ",") + local model = string.sub(value, 1, pos - 1) + + local name = string.sub(value, pos + 1, string.len(value)) + + pos = string.find(product, "/"); + + local vid = string.sub(product, 1, pos - 1) + + local pid = string.sub(product, pos + 1, string.len(product)) + + pos = string.find(pid, "/") + pid = string.sub(pid, 1, pos - 1) + + row["description"] = name + row["model"] = model + row["id"] = hex_align(vid, 4) .. ":" .. hex_align(pid, 4) + row["name"] = devname + row["product"] = product + + table.insert(data, row) + end + + return data +end + +local printers = detect_usb_printers() + +v = m:section(Table, printers, translate("Detected printers")) + +v:option(DummyValue, "description", translate("Description")) +v:option(DummyValue, "model", translate("Printer Model")) +v:option(DummyValue, "id", translate("VID/PID")) +v:option(DummyValue, "name", translate("Device Name")) + +net = net.init(m.uci) + +s = m:section(TypedSection, "printer", translate("Bindings")) +s.addremove = true +s.anonymous = true + +s:option(Flag, "enabled", translate("enable")) + +d = s:option(Value, "device", translate("Device")) +d.rmempty = true + +for key, item in ipairs(printers) do + d:value(item["product"], item["description"] .. " [" .. item["id"] .. "]") +end + +b = s:option(Value, "bind", translate("Interface"), translate("Specifies the interface to listen on.")) +b.template = "cbi/network_netlist" +b.nocreate = true +b.unspecified = true + +function b.cfgvalue(...) + local v = Value.cfgvalue(...) + if v then + return (net:get_status_by_address(v)) + end +end + +function b.write(self, section, value) + local n = net:get_network(value) + if n and n:ipaddr() then + Value.write(self, section, n:ipaddr()) + end +end + +p = s:option(ListValue, "port", translate("Port"), translate("TCP listener port.")) +p.rmempty = true +for i = 0, 9 do + p:value(i, 9100 + i) +end + +s:option(Flag, "bidirectional", translate("Bidirectional mode")) + +return m diff --git a/package/lean/luci-app-usb-printer/po/zh-cn/usb-printer.po b/package/lean/luci-app-usb-printer/po/zh-cn/usb-printer.po new file mode 100644 index 000000000..62fc5b450 --- /dev/null +++ b/package/lean/luci-app-usb-printer/po/zh-cn/usb-printer.po @@ -0,0 +1,58 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-05-18 01:34+0800\n" +"PO-Revision-Date: 2014-05-18 01:34+0800\n" +"Last-Translator: hackpascal \n" +"Language-Team: \n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Pootle 2.0.6\n" + +msgid "Bidirectional mode" +msgstr "鍙屽悜妯″紡" + +msgid "Bindings" +msgstr "缁戝畾" + +msgid "Device" +msgstr "璁惧" + +msgid "Device Name" +msgstr "璁惧鍚" + +msgid "Detected printers" +msgstr "妫娴嬪埌鐨勬墦鍗版満" + +msgid "" +"Shares multiple USB printers via TCP/IP.
" +"When modified bingings, re-plug usb connectors to take effect.
" +"This module requires kmod-usb-printer." +msgstr "" +"閫氳繃 TCP/IP 鍏变韩 USB 鎵撳嵃鏈恒
淇敼璁剧疆鍚庯紝璇烽噸鏂拌繛鎺ユ墦鍗版満浠ヤ娇璁剧疆鐢熸晥銆
" +"姝ゆā鍧楅渶瑕 kmod-usb-printer 鏀寔銆" + +msgid "Port" +msgstr "绔彛" + +msgid "Printer Model" +msgstr "鎵撳嵃鏈哄瀷鍙" + +msgid "Settings" +msgstr "璁剧疆" + +msgid "TCP listener port." +msgstr "TCP 鐩戝惉绔彛銆" + +msgid "enable" +msgstr "鍚敤" + +msgid "USB Printer Server" +msgstr "USB 鎵撳嵃鏈嶅姟鍣" + +msgid "Specifies the interface to listen on." +msgstr "鎸囧畾瑕佺洃鍚殑鎺ュ彛銆" diff --git a/package/lean/luci-app-usb-printer/root/etc/config/usb_printer b/package/lean/luci-app-usb-printer/root/etc/config/usb_printer new file mode 100644 index 000000000..e69de29bb diff --git a/package/lean/luci-app-usb-printer/root/etc/hotplug.d/usb/10-usb_printer b/package/lean/luci-app-usb-printer/root/etc/hotplug.d/usb/10-usb_printer new file mode 100755 index 000000000..c250fe78f --- /dev/null +++ b/package/lean/luci-app-usb-printer/root/etc/hotplug.d/usb/10-usb_printer @@ -0,0 +1,7 @@ +#!/bin/sh +# Copyright (C) 2005-2014 NowRush Studio +# Author: hackpascal + +if [ x"$INTERFACE" = x"7/1/1" ] || [ x"$INTERFACE" = x"7/1/2" ]; then + /usr/bin/usb_printer_hotplug "$PRODUCT" "$ACTION" +fi diff --git a/package/lean/luci-app-usb-printer/root/etc/init.d/usb_printer b/package/lean/luci-app-usb-printer/root/etc/init.d/usb_printer new file mode 100755 index 000000000..4da5e3445 --- /dev/null +++ b/package/lean/luci-app-usb-printer/root/etc/init.d/usb_printer @@ -0,0 +1,22 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2005-2013 NowRush Studio +# Author: hackpascal + +START=70 + +stop() { + killall p910nd 2>/dev/null +} + +start() { + for lps in `/usr/bin/detectlp`; do + product=`echo $lps | cut -d , -f 2` + + /usr/bin/usb_printer_hotplug "$product" add + done +} + +restart() { + stop + start +} diff --git a/package/lean/luci-app-usb-printer/root/etc/uci-defaults/luci-usb-printer b/package/lean/luci-app-usb-printer/root/etc/uci-defaults/luci-usb-printer new file mode 100755 index 000000000..38c214f9c --- /dev/null +++ b/package/lean/luci-app-usb-printer/root/etc/uci-defaults/luci-usb-printer @@ -0,0 +1,12 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@usb_printer[-1] + add ucitrack usb_printer + set ucitrack.@usb_printer[-1].init=usb_printer + commit ucitrack +EOF + +[ -f /etc/init.d/p910nd ] && /etc/init.d/p910nd disable + +exit 0 diff --git a/package/lean/luci-app-usb-printer/root/usr/bin/detectlp b/package/lean/luci-app-usb-printer/root/usr/bin/detectlp new file mode 100755 index 000000000..b69385bb9 --- /dev/null +++ b/package/lean/luci-app-usb-printer/root/usr/bin/detectlp @@ -0,0 +1,20 @@ +#!/bin/sh + +lp_path=/sys/class/usbmisc + +if ! [ -d "$lp_path" ]; then + exit +fi + +cd $lp_path + +for lps in `ls`; do + desc_file=$lp_path/$lps/device/ieee1284_id + uevent_file=$lp_path/$lps/device/uevent + + name=`cat $desc_file | sed 's/.*DES:\(.*\);.*/\1/' | cut -d ';' -f 1` + model=`cat $desc_file | sed 's/.*MDL:\(.*\);.*/\1/' | cut -d ';' -f 1` + product=`cat $uevent_file | grep PRODUCT= | sed 's/PRODUCT=\(.*\)/\1/'` + + echo $lps,$product,$model,$name; +done diff --git a/package/lean/luci-app-usb-printer/root/usr/bin/usb_printer_hotplug b/package/lean/luci-app-usb-printer/root/usr/bin/usb_printer_hotplug new file mode 100755 index 000000000..e0a60b003 --- /dev/null +++ b/package/lean/luci-app-usb-printer/root/usr/bin/usb_printer_hotplug @@ -0,0 +1,72 @@ +#!/bin/sh +# Copyright (C) 2005-2014 NowRush Studio +# Author: hackpascal + +. $IPKG_INSTROOT/lib/functions.sh + +PRODUCT=$1 +ACTION=$2 + +DEVICES= + +check_printer() { + local cfg=$1 + local enabled + local device_id + local bind_ip + local port + local bidirect + local device_file + local args="" + local pid_file + + config_get_bool enabled "$cfg" enabled 0 + [ "$enabled" -eq 0 ] && return 0 + + config_get device_id "$cfg" device "" + config_get bind_ip "$cfg" bind "0.0.0.0" + config_get port "$cfg" port "" + config_get_bool bidirect "$cfg" bidirectional "0" + + if [ -z "$device_id" ] || [ -z "$port" ]; then + return + fi + + if [ x"$PRODUCT" != x"$device_id" ]; then + return + fi + + device_file=`echo $DEVICES | grep $device_id | cut -d , -f 1` + + if [ "$ACTION" = "add" ] && [ -z "$device_file" ]; then + return + fi + + pid_file=/var/run/p910${port}d.pid + [ -f $pid_file ] && kill `cat $pid_file` 2>/dev/null + + if [ "$ACTION" = "add" ]; then + if [ "$bidirect" != 0 ]; then + args='-b' + fi + + logger "usb_printer: start p910nd on $bind_ip:$port for /dev/usb/$device_file" + /usr/sbin/p910nd $args -f /dev/usb/$device_file -i $bind_ip $port + fi +} + +if [ -z "$PRODUCT" ] || [ -z "$ACTION" ]; then + echo "Arguements required" + exit 1 +fi + +if [ "$ACTION" != "add" ] && [ "$ACTION" != "remove" ]; then + echo "Invalid action arguement" + exit 1 +fi + +DEVICES=`/usr/bin/detectlp` + +config_load usb_printer + +config_foreach check_printer printer diff --git a/package/lean/luci-app-vlmcsd b/package/lean/luci-app-vlmcsd new file mode 160000 index 000000000..192bd9a48 --- /dev/null +++ b/package/lean/luci-app-vlmcsd @@ -0,0 +1 @@ +Subproject commit 192bd9a482dd15656613a56f64f5e8b49bf1bfb8 diff --git a/package/lean/luci-app-vsftpd/Makefile b/package/lean/luci-app-vsftpd/Makefile new file mode 100644 index 000000000..97d181f01 --- /dev/null +++ b/package/lean/luci-app-vsftpd/Makefile @@ -0,0 +1,17 @@ +# Copyright (C) 2016 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for VSFTPD +LUCI_DEPENDS:=+vsftpd-alt +LUCI_PKGARCH:=all +PKG_VERSION:=1.0 +PKG_RELEASE:=2 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature + diff --git a/package/lean/luci-app-vsftpd/luasrc/controller/vsftpd.lua b/package/lean/luci-app-vsftpd/luasrc/controller/vsftpd.lua new file mode 100644 index 000000000..de44711dc --- /dev/null +++ b/package/lean/luci-app-vsftpd/luasrc/controller/vsftpd.lua @@ -0,0 +1,47 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright 2016 Weijie Gao + +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 + +$Id$ +]]-- + +require("luci.sys") + +module("luci.controller.vsftpd", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/vsftpd") then + return + end + + entry({"admin", "nas"}, firstchild(), "NAS", 44).dependent = false + entry({"admin", "nas", "vsftpd"}, + alias("admin", "nas", "vsftpd", "general"), + _("FTP Server")) + + entry({"admin", "nas", "vsftpd", "general"}, + cbi("vsftpd/general"), + _("General Settings"), 10).leaf = true + + entry({"admin", "nas", "vsftpd", "users"}, + cbi("vsftpd/users"), + _("Virtual Users"), 20).leaf = true + + entry({"admin", "nas", "vsftpd", "anonymous"}, + cbi("vsftpd/anonymous"), + _("Anonymous User"), 30).leaf = true + + entry({"admin", "nas", "vsftpd", "log"}, + cbi("vsftpd/log"), + _("Log Settings"), 40).leaf = true + + entry({"admin", "nas", "vsftpd", "item"}, + cbi("vsftpd/item"), nil).leaf = true +end diff --git a/package/lean/luci-app-vsftpd/luasrc/model/cbi/vsftpd/anonymous.lua b/package/lean/luci-app-vsftpd/luasrc/model/cbi/vsftpd/anonymous.lua new file mode 100644 index 000000000..3ebbb4ba9 --- /dev/null +++ b/package/lean/luci-app-vsftpd/luasrc/model/cbi/vsftpd/anonymous.lua @@ -0,0 +1,44 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright 2016 Weijie Gao + +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 + +$Id$ +]]-- + +m = Map("vsftpd", translate("FTP Server - Anonymous Settings")) + +sa = m:section(NamedSection, "anonymous", "anonymous", translate("Anonymous Settings")) + +o = sa:option(Flag, "enabled", translate("Enabled")) +o.default = false + +o = sa:option(Value, "username", translate("Username"), translate("An actual local user to handle anonymous user")) +o.default = "ftp" + +o = sa:option(Value, "root", translate("Root directory")) +o.default = "/home/ftp" + +o = sa:option(Value, "umask", translate("File mode umask")) +o.default = "022" + +o = sa:option(Value, "maxrate", translate("Max transmit rate"), translate("0 means no limitation")) +o.default = "0" + +o = sa:option(Flag, "writemkdir", translate("Enable write/mkdir")) +o.default = false + +o = sa:option(Flag, "upload", translate("Enable upload")) +o.default = false + +o = sa:option(Flag, "others", translate("Enable other rights"), translate("Include rename, deletion ...")) +o.default = false + + +return m diff --git a/package/lean/luci-app-vsftpd/luasrc/model/cbi/vsftpd/general.lua b/package/lean/luci-app-vsftpd/luasrc/model/cbi/vsftpd/general.lua new file mode 100644 index 000000000..74dbcad6e --- /dev/null +++ b/package/lean/luci-app-vsftpd/luasrc/model/cbi/vsftpd/general.lua @@ -0,0 +1,114 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright 2016 Weijie Gao + +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 + +$Id$ +]]-- + +m = Map("vsftpd", translate("FTP Server - General Settings")) + +sl = m:section(NamedSection, "listen", "listen", translate("Listening Settings")) + +o = sl:option(Flag, "enable4", translate("Enable IPv4")) +o.rmempty = false +o.default = true + +o = sl:option(Value, "ipv4", translate("IPv4 Address")) +o.datatype = "ip4addr" +o.default = "0.0.0.0" + +o = sl:option(Flag, "enable6", translate("Enable IPv6")) +o.rmempty = false + +o = sl:option(Value, "ipv6", translate("IPv6 Address")) +o.datatype = "ip6addr" +o.default = "::" + +o = sl:option(Value, "port", translate("Listen Port")) +o.datatype = "uinteger" +o.default = "21" + +o = sl:option(Value, "dataport", translate("Data Port")) +o.datatype = "uinteger" +o.default = "20" + + +sg = m:section(NamedSection, "global", "global", translate("Global Settings")) + +o = sg:option(Flag, "write", translate("Enable write"), translate("When disabled, all write request will give permission denied.")); +o.default = true + +o = sg:option(Flag, "download", translate("Enable download"), translate("When disabled, all download request will give permission denied.")); +o.default = true + +o = sg:option(Flag, "dirlist", translate("Enable directory list"), translate("When disabled, list commands will give permission denied.")) +o.default = true + +o = sg:option(Flag, "lsrecurse", translate("Allow directory recursely list")) + +o = sg:option(Flag, "dotfile", translate("Show dot files"), translate(". and .. are excluded.")); +o.default = true + +o = sg:option(Value, "umask", translate("File mode umask"), translate("Uploaded file mode will be 666 - <umask>; directory mode will be 777 - <umask>.")) +o.default = "022" + +o = sg:option(Value, "banner", translate("FTP Banner")) + +o = sg:option(Flag, "dirmessage", translate("Enable directory message"), translate("A message will be displayed when entering a directory.")) + +o = sg:option(Value, "dirmsgfile", translate("Directory message filename")) +o.default = ".message" + + +sl = m:section(NamedSection, "local", "local", translate("Local Users")) + +o = sl:option(Flag, "enabled", translate("Enable local user")) +o.rmempty = false + +o = sl:option(Value, "root", translate("Root directory"), translate("Leave empty will use user's home directory")) +o.default = "" + + +sc = m:section(NamedSection, "connection", "connection", translate("Connection Settings")) + +o = sc:option(Flag, "portmode", translate("Enable PORT mode")) +o = sc:option(Flag, "pasvmode", translate("Enable PASV mode")) + +o = sc:option(ListValue, "ascii", translate("ASCII mode")) +o:value("disabled", translate("Disabled")) +o:value("download", translate("Download only")) +o:value("upload", translate("Upload only")) +o:value("both", translate("Both download and upload")) +o.default = "both" + +o = sc:option(Value, "idletimeout", translate("Idle session timeout"), translate("in seconds")) +o.datatype = "uinteger" +o.default = "1800" +o = sc:option(Value, "conntimeout", translate("Connection timeout"), translate("in seconds")) +o.datatype = "uinteger" +o.default = "120" +o = sc:option(Value, "dataconntimeout", translate("Data connection timeout"), translate("in seconds")) +o.datatype = "uinteger" +o.default = "120" +o = sc:option(Value, "maxclient", translate("Max clients"), translate("0 means no limitation")) +o.datatype = "uinteger" +o.default = "0" +o = sc:option(Value, "maxperip", translate("Max clients per IP"), translate("0 means no limitation")) +o.datatype = "uinteger" +o.default = "0" +o = sc:option(Value, "maxrate", translate("Max transmit rate"), translate("in KB/s, 0 means no limitation")) +o.datatype = "uinteger" +o.default = "0" +o = sc:option(Value, "maxretry", translate("Max login fail count"), translate("Can not be zero, default is 3")) +o.datatype = "uinteger" +o.default = "3" + + +return m diff --git a/package/lean/luci-app-vsftpd/luasrc/model/cbi/vsftpd/item.lua b/package/lean/luci-app-vsftpd/luasrc/model/cbi/vsftpd/item.lua new file mode 100644 index 000000000..2a0003c8b --- /dev/null +++ b/package/lean/luci-app-vsftpd/luasrc/model/cbi/vsftpd/item.lua @@ -0,0 +1,70 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright 2016 Weijie Gao + +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 + +$Id$ +]]-- + +local sid = arg[1] +local utl = require "luci.util" + +m = Map("vsftpd", translate("FTP Server - Virtual User <new>")) + +m.redirect = luci.dispatcher.build_url("admin/nas/vsftpd/users") + +if m.uci:get("vsftpd", sid) ~= "user" then + luci.http.redirect(m.redirect) + return +end + +m.uci:foreach("vsftpd", "user", + function(s) + if s['.name'] == sid and s.username then + m.title = translatef("FTP Server - Virtual User %q", s.username) + return false + end + end) + +s = m:section(NamedSection, sid, "settings", translate("User Settings")) +s.addremove = false + +o = s:option(Value, "username", translate("Username")) +o.rmempty = false + +function o.validate(self, value) + if value == "" then + return nil, translate("Username cannot be empty") + end + return value +end + +o = s:option(Value, "password", translate("Password")) +o.password = true + +o = s:option(Value, "home", translate("Home directory")) +o.default = "/home/ftp" + +o = s:option(Value, "umask", translate("File mode umask")) +o.default = "022" + +o = s:option(Value, "maxrate", translate("Max transmit rate"), translate("0 means no limitation")) +o.default = "0" + +o = s:option(Flag, "writemkdir", translate("Enable write/mkdir")) +o.default = false + +o = s:option(Flag, "upload", translate("Enable upload")) +o.default = false + +o = s:option(Flag, "others", translate("Enable other rights"), translate("Include rename, deletion ...")) +o.default = false + + +return m diff --git a/package/lean/luci-app-vsftpd/luasrc/model/cbi/vsftpd/log.lua b/package/lean/luci-app-vsftpd/luasrc/model/cbi/vsftpd/log.lua new file mode 100644 index 000000000..969ce817c --- /dev/null +++ b/package/lean/luci-app-vsftpd/luasrc/model/cbi/vsftpd/log.lua @@ -0,0 +1,29 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright 2016 Weijie Gao + +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 + +$Id$ +]]-- + +m = Map("vsftpd", translate("FTP Server - Log Settings")) + +sl = m:section(NamedSection, "log", "log", translate("Log Settings")) + +o = sl:option(Flag, "syslog", translate("Enable syslog")) +o.default = false + +o = sl:option(Flag, "xreflog", translate("Enable file log")) +o.default = true + +o = sl:option(Value, "file", translate("Log file")) +o.default = "/var/log/vsftpd.log" + + +return m diff --git a/package/lean/luci-app-vsftpd/luasrc/model/cbi/vsftpd/users.lua b/package/lean/luci-app-vsftpd/luasrc/model/cbi/vsftpd/users.lua new file mode 100644 index 000000000..2ffaf759d --- /dev/null +++ b/package/lean/luci-app-vsftpd/luasrc/model/cbi/vsftpd/users.lua @@ -0,0 +1,54 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright 2016 Weijie Gao + +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 + +$Id$ +]]-- + +m = Map("vsftpd", translate("FTP Server - Virtual User Settings")) + +sv = m:section(NamedSection, "vuser", "vuser", translate("Settings")) + +o = sv:option(Flag, "enabled", translate("Enabled")) +o.default = false + +o = sv:option(Value, "username", translate("Username"), translate("An actual local user to handle virtual users")) +o.default = "ftp" + +s = m:section(TypedSection, "user", translate("User lists")) +s.template = "cbi/tblsection" +s.extedit = luci.dispatcher.build_url("admin/nas/vsftpd/item/%s") +s.addremove = true +s.anonymous = true + +function s.create(...) + local id = TypedSection.create(...) + luci.http.redirect(s.extedit % id) +end + +function s.remove(self, section) + return TypedSection.remove(self, section) +end + +o = s:option(DummyValue, "username", translate("Username")) +function o.cfgvalue(...) + local v = Value.cfgvalue(...) or ("<%s>" % translate("Unknown")) + return v +end +o.rmempty = false + +o = s:option(DummyValue, "home", translate("Home directory")) +function o.cfgvalue(...) + local v = Value.cfgvalue(...) or ("/home/ftp") + return v +end +o.rmempty = false + +return m diff --git a/package/lean/luci-app-vsftpd/po/zh-cn/vsftpd.po b/package/lean/luci-app-vsftpd/po/zh-cn/vsftpd.po new file mode 100644 index 000000000..f8e3ba64a --- /dev/null +++ b/package/lean/luci-app-vsftpd/po/zh-cn/vsftpd.po @@ -0,0 +1,229 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-02-17 18:00+0800\n"\ +"Last-Translator: Weijie Gao \n" +"Language-Team: \n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Pootle 2.0.6\n" + +msgid "NAS" +msgstr "缃戠粶瀛樺偍" + +msgid ". and .. are excluded." +msgstr ". 鍜 .. 灏嗚蹇界暐銆" + +msgid "0 means no limitation" +msgstr "0 琛ㄦ槑涓嶉檺鍒" + +msgid "A message will be displayed when entering a directory." +msgstr "鍦ㄨ繘鍏ヤ竴涓柊鐩綍鏃跺皢鏄剧ず鐨勬秷鎭" + +msgid "ASCII mode" +msgstr "ASCII 妯″紡" + +msgid "Allow directory recursely list" +msgstr "鍏佽閫掑綊鍒楃洰褰" + +msgid "An actual local user to handle anonymous user" +msgstr "鎵胯浇鍖垮悕鐢ㄦ埛鐨勬湰鍦扮敤鎴" + +msgid "An actual local user to handle virtual users" +msgstr "鎵胯浇铏氭嫙鐢ㄦ埛鐨勬湰鍦扮敤鎴" + +msgid "Anonymous Settings" +msgstr "鍖垮悕鐢ㄦ埛璁剧疆" + +msgid "Anonymous User" +msgstr "鍖垮悕鐢ㄦ埛" + +msgid "Both download and upload" +msgstr "涓嬭浇鍜屼笂浼" + +msgid "Can not be zero, default is 3" +msgstr "涓嶈兘涓 0锛岄粯璁や负 3" + +msgid "Connection Settings" +msgstr "杩炴帴璁剧疆" + +msgid "Connection timeout" +msgstr "杩炴帴瓒呮椂" + +msgid "Data Port" +msgstr "鏁版嵁绔彛" + +msgid "Data connection timeout" +msgstr "鏁版嵁杩炴帴瓒呮椂" + +msgid "Directory message filename" +msgstr "鐩綍娑堟伅鏂囦欢鍚" + +msgid "Download only" +msgstr "浠呬笅杞" + +msgid "Enable IPv4" +msgstr "鍚敤 IPv4" + +msgid "Enable IPv6" +msgstr "鍚敤 IPv6" + +msgid "Enable PASV mode" +msgstr "鍚敤 PASV 妯″紡" + +msgid "Enable PORT mode" +msgstr "鍚敤 PORT 妯″紡" + +msgid "Enable directory list" +msgstr "鍏佽鍒楃洰褰" + +msgid "Enable directory message" +msgstr "鍚敤鐩綍娑堟伅" + +msgid "Enable download" +msgstr "鍏佽涓嬭浇" + +msgid "Enable file log" +msgstr "鍚敤鏂囦欢鏃ュ織" + +msgid "Enable local user" +msgstr "鍚敤鏈湴鐢ㄦ埛" + +msgid "Enable other rights" +msgstr "鍏佽鍏跺畠鏉冮檺" + +msgid "Enable syslog" +msgstr "鍚敤绯荤粺鏃ュ織" + +msgid "Enable upload" +msgstr "鍏佽涓婁紶" + +msgid "Enable write" +msgstr "鍏佽鍐" + +msgid "Enable write/mkdir" +msgstr "鍏佽鍐/鍒涘缓鐩綍" + +msgid "FTP Banner" +msgstr "FTP 娆㈣繋鎻愮ず" + +msgid "FTP Server" +msgstr "FTP 鏈嶅姟鍣" + +msgid "FTP Server - Anonymous Settings" +msgstr "FTP 鏈嶅姟鍣 - 鍖垮悕鐢ㄦ埛璁剧疆" + +msgid "FTP Server - General Settings" +msgstr "FTP 鏈嶅姟鍣 - 甯歌璁剧疆" + +msgid "FTP Server - Log Settings" +msgstr "FTP 鏈嶅姟鍣 - 鏃ュ織璁剧疆" + +msgid "FTP Server - Virtual User %q" +msgstr "FTP 鏈嶅姟鍣 - 铏氭嫙鐢ㄦ埛 %q" + +msgid "FTP Server - Virtual User <new>" +msgstr "FTP 鏈嶅姟鍣 - 铏氭嫙鐢ㄦ埛 <鏂扮敤鎴>" + +msgid "FTP Server - Virtual User Settings" +msgstr "FTP 鏈嶅姟鍣 - 铏氭嫙鐢ㄦ埛璁剧疆" + +msgid "File mode umask" +msgstr "鏂囦欢鏉冮檺鎺╃爜" + +msgid "General Settings" +msgstr "甯歌璁剧疆" + +msgid "Global Settings" +msgstr "鍏ㄥ眬璁剧疆" + +msgid "Home directory" +msgstr "涓荤洰褰" + +msgid "IPv4 Address" +msgstr "IPv4 鍦板潃" + +msgid "IPv6 Address" +msgstr "IPv6 鍦板潃" + +msgid "Idle session timeout" +msgstr "绌洪棽鍥炶瘽瓒呮椂" + +msgid "Include rename, deletion ..." +msgstr "鍖呮嫭閲嶅懡鍚嶃佸垹闄 ..." + +msgid "Leave empty will use user's home directory" +msgstr "鐣欑┖灏嗕娇鐢ㄧ敤鎴蜂富鐩綍" + +msgid "Listen Port" +msgstr "鐩戝惉绔彛" + +msgid "Listening Settings" +msgstr "鐩戝惉璁剧疆" + +msgid "Local Users" +msgstr "鏈湴鐢ㄦ埛" + +msgid "Log Settings" +msgstr "鏃ュ織璁剧疆" + +msgid "Log file" +msgstr "鏃ュ織鏂囦欢" + +msgid "Max clients" +msgstr "鏈澶ц繛鎺ユ暟" + +msgid "Max clients per IP" +msgstr "鍚屼竴 IP 鐨勬渶澶ц繛鎺ユ暟" + +msgid "Max login fail count" +msgstr "鏈澶х櫥褰曞皾璇曟暟" + +msgid "Max transmit rate" +msgstr "鏈澶т紶杈撻熺巼" + +msgid "Root directory" +msgstr "鏍圭洰褰" + +msgid "Settings" +msgstr "璁剧疆" + +msgid "Show dot files" +msgstr "鏄剧ず浠ョ偣寮澶寸殑鏂囦欢 (闅愯棌鏂囦欢)" + +msgid "Upload only" +msgstr "浠呬笂浼" + +msgid "Uploaded file mode will be 666 - <umask>; directory mode will be 777 - <umask>." +msgstr "涓婁紶鐨勬枃浠舵潈闄愬皢琚缃负 666 - <鎺╃爜>锛涚洰褰曟潈闄愬皢琚缃负 777 - <鎺╃爜>銆" + +msgid "User Settings" +msgstr "鐢ㄦ埛璁剧疆" + +msgid "User lists" +msgstr "鐢ㄦ埛鍒楄〃" + +msgid "Username cannot be empty" +msgstr "鐢ㄦ埛鍚嶄笉鑳戒负绌" + +msgid "When disabled, all download request will give permission denied." +msgstr "濡傛灉绂佹锛屾墍鏈夌殑涓嬭浇璇锋眰閮藉皢琚嫆缁濄" + +msgid "When disabled, all write request will give permission denied." +msgstr "濡傛灉绂佹锛屾墍鏈夌殑鍐欑被鍨嬭姹傞兘灏嗚鎷掔粷銆" + +msgid "When disabled, list commands will give permission denied." +msgstr "濡傛灉绂佹锛屽垪鐩綍鍛戒护灏嗚鎷掔粷銆" + +msgid "Virtual Users" +msgstr "铏氭嫙鐢ㄦ埛" + +msgid "in seconds" +msgstr "鍗曚綅涓虹" + +msgid "in KB/s, 0 means no limitation" +msgstr "鍗曚綅涓 KB/s锛0 琛ㄦ槑涓嶉檺鍒" diff --git a/package/lean/luci-app-vsftpd/root/etc/uci-defaults/luci-vsftpd b/package/lean/luci-app-vsftpd/root/etc/uci-defaults/luci-vsftpd new file mode 100755 index 000000000..aa2f71a36 --- /dev/null +++ b/package/lean/luci-app-vsftpd/root/etc/uci-defaults/luci-vsftpd @@ -0,0 +1,11 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@vsftpd[-1] + add ucitrack vsftpd + set ucitrack.@vsftpd[-1].init=vsftpd + commit ucitrack +EOF + +rm -f /tmp/luci-vsftpd +exit 0 diff --git a/package/lean/luci-app-xunlei/Makefile b/package/lean/luci-app-xunlei/Makefile new file mode 100644 index 000000000..63691b4f9 --- /dev/null +++ b/package/lean/luci-app-xunlei/Makefile @@ -0,0 +1,16 @@ +# +# Copyright (C) 2008-2014 The LuCI Team +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI Support for Xware downloading app. +LUCI_DEPENDS:=+wget +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/package/lean/luci-app-xunlei/luasrc/controller/xunlei.lua b/package/lean/luci-app-xunlei/luasrc/controller/xunlei.lua new file mode 100755 index 000000000..b0d15cd13 --- /dev/null +++ b/package/lean/luci-app-xunlei/luasrc/controller/xunlei.lua @@ -0,0 +1,13 @@ + +module("luci.controller.xunlei", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/xunlei") then + return + end + + local page + page = entry({"admin", "services", "xunlei"}, cbi("xunlei"), _("杩呴浄杩滅▼涓嬭浇"), 199) + page.i18n = "xunlei" + page.dependent = true +end diff --git a/package/lean/luci-app-xunlei/luasrc/model/cbi/xunlei.lua b/package/lean/luci-app-xunlei/luasrc/model/cbi/xunlei.lua new file mode 100755 index 000000000..fd3bec29a --- /dev/null +++ b/package/lean/luci-app-xunlei/luasrc/model/cbi/xunlei.lua @@ -0,0 +1,106 @@ +local fs = require "nixio.fs" +local util = require "nixio.util" + +local running=(luci.sys.call("pidof EmbedThunderManager > /dev/null") == 0) +local button="" +local xunleiinfo="" +local tblXLInfo={} +local detailInfo = "
鍚姩鍚庝細鐪嬪埌绫讳技濡備笅淇℃伅锛

[ 0, 1, 1, 0, 鈥7DHS94鈥,1, 鈥201_2.1.3.121鈥, 鈥渟hdixang鈥, 1 ]

鍏朵腑鏈夌敤鐨勫嚑椤逛负锛

绗竴椤癸細 0琛ㄧず杩斿洖缁撴灉鎴愬姛锛

绗簩椤癸細 1琛ㄧず妫娴嬬綉缁滄甯革紝0琛ㄧず妫娴嬬綉缁滃紓甯革紱

绗洓椤癸細 1琛ㄧず宸茬粦瀹氭垚鍔燂紝0琛ㄧず鏈粦瀹氾紱

绗簲椤癸細 鏈粦瀹氱殑鎯呭喌涓嬶紝涓虹粦瀹氱殑闇瑕佺殑婵娲荤爜锛

绗叚椤癸細 1琛ㄧず纾佺洏鎸傝浇妫娴嬫垚鍔燂紝0琛ㄧず纾佺洏鎸傝浇妫娴嬪け璐ャ" + +if running then + xunleiinfo = luci.sys.exec("wget-ssl http://127.0.0.1:9000/getsysinfo -O - 2>/dev/null") + m = Map("xunlei", translate("Xware"), translate("杩呴浄杩滅▼涓嬭浇 杩愯涓")) + string.gsub(string.sub(xunleiinfo, 2, -2),'[^,]+',function(w) table.insert(tblXLInfo, w) end) + + detailInfo = [[

鍚姩淇℃伅锛歖] .. xunleiinfo .. [[

]] + if tonumber(tblXLInfo[1]) == 0 then + detailInfo = detailInfo .. [[

鐘舵佹甯

]] + else + detailInfo = detailInfo .. [[

鎵ц寮傚父

]] + end + + if tonumber(tblXLInfo[2]) == 0 then + detailInfo = detailInfo .. [[

缃戠粶寮傚父

]] + else + detailInfo = detailInfo .. [[

缃戠粶姝e父

]] + end + + if tonumber(tblXLInfo[4]) == 0 then + detailInfo = detailInfo .. [[

鏈粦瀹歖].. [[  婵娲荤爜锛歖].. tblXLInfo[5] ..[[

]] + else + detailInfo = detailInfo .. [[

宸茬粦瀹

]] + end + + if tonumber(tblXLInfo[6]) == 0 then + detailInfo = detailInfo .. [[

纾佺洏鎸傝浇妫娴嬪け璐

]] + else + detailInfo = detailInfo .. [[

纾佺洏鎸傝浇妫娴嬫垚鍔

]] + end +else + m = Map("xunlei", translate("Xware"), translate("杩呴浄杩滅▼涓嬭浇 鏈繍琛")) +end + +----------- +--Xware-- +----------- + +s = m:section(TypedSection, "xunlei","Xware 璁剧疆") +s.anonymous = true + +s:tab("basic", translate("Settings")) + +enable = s:taboption("basic", Flag, "enable", "鍚敤 杩呴浄杩滅▼涓嬭浇") +enable.rmempty = false + +vod = s:taboption("basic", Flag, "vod", "鍒犻櫎杩呴浄VOD鏈嶅姟鍣", "鍒犻櫎杩呴浄VOD鏈嶅姟鍣紝鍑忓皯涓婁紶娴侀噺銆") +vod.rmempty = false + +s:taboption("basic", DummyValue,"opennewwindow" ,"

", detailInfo) + +s:taboption("basic", DummyValue,"opennewwindow" ,"

", "
鎵撳紑杩呴浄杩滅▼涓嬭浇椤甸潰銆傞娆¤繍琛屽皢婵娲荤爜濉繘缃戦〉鍗冲彲缁戝畾銆") + + +s:tab("editconf_etm", translate("Xware 閰嶇疆")) +editconf_etm = s:taboption("editconf_etm", Value, "_editconf_etm", + translate("Xware 閰嶇疆锛"), + translate("娉ㄩ噴鐢ㄢ ; 鈥")) +editconf_etm.template = "cbi/tvalue" +editconf_etm.rows = 20 +editconf_etm.wrap = "off" + +function editconf_etm.cfgvalue(self, section) + return fs.readfile("/tmp/etc/etm.cfg") or "" +end +function editconf_etm.write(self, section, value2) + if value2 then + value2 = value2:gsub("\r\n?", "\n") + fs.writefile("/tmp/etm.cfg", value2) + if (luci.sys.call("cmp -s /tmp/etm.cfg /tmp/etc/etm.cfg") == 1) then + fs.writefile("/tmp/etc/etm.cfg", value2) + end + fs.remove("/tmp/etm.cfg") + end +end + +s:tab("editconf_download", translate("涓嬭浇閰嶇疆")) +editconf_download = s:taboption("editconf_download", Value, "_editconf_download", + translate("涓嬭浇閰嶇疆"), + translate("娉ㄩ噴鐢ㄢ ; 鈥")) +editconf_download.template = "cbi/tvalue" +editconf_download.rows = 20 +editconf_download.wrap = "off" + +function editconf_download.cfgvalue(self, section) + return fs.readfile("/tmp/etc/download.cfg") or "" +end +function editconf_download.write(self, section, value3) + if value3 then + value3 = value3:gsub("\r\n?", "\n") + fs.writefile("/tmp/download.cfg", value3) + if (luci.sys.call("cmp -s /tmp/download.cfg /tmp/etc/download.cfg") == 1) then + fs.writefile("/tmp/etc/download.cfg", value3) + end + fs.remove("/tmp/download.cfg") + end +end +return m diff --git a/package/lean/luci-app-xunlei/root/etc/config/xunlei b/package/lean/luci-app-xunlei/root/etc/config/xunlei new file mode 100755 index 000000000..181ed73b6 --- /dev/null +++ b/package/lean/luci-app-xunlei/root/etc/config/xunlei @@ -0,0 +1,10 @@ + +config xunlei 'config' + option device '/mnt/sda1' + option up '0' + option xware 'Xware_mipseb_32_uclibc.tar.gz' + option url 'http://dl.lazyzhu.com/file/Thunder/Xware' + option file '/app' + option vod '1' + option enable '0' + diff --git a/package/lean/luci-app-xunlei/root/etc/init.d/xunlei b/package/lean/luci-app-xunlei/root/etc/init.d/xunlei new file mode 100755 index 000000000..b0aa473a5 --- /dev/null +++ b/package/lean/luci-app-xunlei/root/etc/init.d/xunlei @@ -0,0 +1,49 @@ +#!/bin/sh /etc/rc.common +START=99 + +start() { + config_load "xunlei" + + config_get enable config enable 0 + config_get device config device + config_get up config up 0 + config_get file config file + + device=$(uci get xunlei.config.device) + file=$(uci get xunlei.config.file) + vod=$(uci get xunlei.config.vod) + mountpoint="`mount | grep "$device" | awk '{print $3;exit}'`" + + rm -f /tmp/etc/thunder_mounts.cfg + rm -f /tmp/etc/etm.cfg + rm -f /tmp/etc/download.cfg + + path1="$file/xunlei/cfg/thunder_mounts.cfg" + path2="$file/xunlei/cfg/etm.cfg" + path3="$file/xunlei/cfg/download.cfg" + + [ "$up" -eq 1 ] && /etc/xware/xlup && /etc/xware/cfg + [ "$vod" -eq 1 ] && rm -f $file/xunlei/lib/vod_httpserver + [ "$vod" -eq 1 ] && rm -f $file/xunlei/vod_httpserver + + [ "$enable" -eq 0 ] && exit 0 + + ln -s "$path1" /tmp/etc/thunder_mounts.cfg + ln -s "$path2" /tmp/etc/etm.cfg + ln -s "$path3" /tmp/etc/download.cfg + + $file/xunlei/portal + sleep 3 + renice -n 19 $(pidof EmbedThunderManager) +} + +stop() { + file=$(uci get xunlei.config.file) + $file/xunlei/portal -s +} + +restart() { + stop + sleep 1 + start +} diff --git a/package/lean/luci-app-xunlei/root/etc/uci-defaults/luci-xunlei b/package/lean/luci-app-xunlei/root/etc/uci-defaults/luci-xunlei new file mode 100755 index 000000000..3d2c0c992 --- /dev/null +++ b/package/lean/luci-app-xunlei/root/etc/uci-defaults/luci-xunlei @@ -0,0 +1,11 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@xunlei[-1] + add ucitrack xunlei + set ucitrack.@xunlei[-1].init=xunlei + commit ucitrack +EOF + +rm -f /tmp/luci-indexcahe +exit 0 diff --git a/package/lean/luci-app-xunlei/root/etc/xware/cfg b/package/lean/luci-app-xunlei/root/etc/xware/cfg new file mode 100755 index 000000000..9b7684906 --- /dev/null +++ b/package/lean/luci-app-xunlei/root/etc/xware/cfg @@ -0,0 +1,18 @@ +#!/bin/sh /etc/rc.common + +device=$(uci get xunlei.config.device) +file=$(uci get xunlei.config.file) +mountpoint="`mount | grep "$device" | awk '{print $3;exit}'`" + +[ -f "$file/xunlei/cfg/thunder_mounts.cfg" ] && cfg="$file/xunlei/cfg/thunder_mounts.cfg" +[ ! -f "$cfg" ] && { + cfg="/$file/xunlei/cfg/thunder_mounts.cfg" + +cat > "$cfg" << EOF +avaliable_mount_path_pattern +{ +$mountpoint +} + +EOF + } diff --git a/package/lean/luci-app-xunlei/root/etc/xware/xlatest b/package/lean/luci-app-xunlei/root/etc/xware/xlatest new file mode 100755 index 000000000..9c76c5876 --- /dev/null +++ b/package/lean/luci-app-xunlei/root/etc/xware/xlatest @@ -0,0 +1,10 @@ +#!/bin/sh /etc/rc.common + +VERSION=`wget -qO- http://dl.lazyzhu.com/file/Thunder/Xware/latest` +sleep 3 && killall wget +xl_configfile="/tmp/etc/xlver" +[ ! -f "$xl_configfile" ] && touch "$xl_configfile" +cat > "$xl_configfile" << EOF +$VERSION +EOF + diff --git a/package/lean/luci-app-xunlei/root/etc/xware/xlup b/package/lean/luci-app-xunlei/root/etc/xware/xlup new file mode 100755 index 000000000..ca2745539 --- /dev/null +++ b/package/lean/luci-app-xunlei/root/etc/xware/xlup @@ -0,0 +1,43 @@ +#!/bin/sh /etc/rc.common + +device=$(uci get xunlei.config.device) +file=$(uci get xunlei.config.file) +mountpoint="`mount | grep "$device" | awk '{print $3;exit}'`" +DIR=$file/xunlei +$DIR/portal -s +sleep 1 +mkdir -p ${DIR}/cfg +cd ${DIR} +FILES=$(uci get xunlei.config.xware) +ver=$(uci get xunlei.config.ver) +url=$(uci get xunlei.config.url) +zversion=$(uci get xunlei.config.zversion) +VERSION=$(wget --no-check-certificate -O- ${url}/latest) + +{ + if [ "$zversion" -eq 1 ];then + wget --no-check-certificate ${url}/${ver}/${FILES} + else + wget --no-check-certificate ${url}/${VERSION}/${FILES} + fi +} + +{ +xl_configfile="/tmp/etc/xlver" +[ ! -f "$xl_configfile" ] && touch "$xl_configfile" + +cat > "$xl_configfile" << EOF +$VERSION +EOF +} + +rm -rf $DIR/portal && rm -rf $DIR/lib && tar zxvf ${FILES} +chmod +x $DIR/* && chmod +x $DIR/lib/* +rm -rf ${FILES} +rm -rf $file/xunlei/cfg/thunder_mounts.cfg>> /dev/null 2>&1 +uci set xunlei.config.up=0>> /dev/null 2>&1 +uci commit 2>&1 > /dev/null +vod=$(uci get xunlei.config.vod) +[ "$vod" -eq 1 ] && rm -f "$file"/xunlei/vod_httpserver +[ "$vod" -eq 1 ] && rm -f "$file"/xunlei/lib/vod_httpserver +sleep 3 && killall wget diff --git a/package/lean/luci-lib-fs/Makefile b/package/lean/luci-lib-fs/Makefile new file mode 100644 index 000000000..9d78a2971 --- /dev/null +++ b/package/lean/luci-lib-fs/Makefile @@ -0,0 +1,49 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-lib-fs +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/luci-lib-fs + SUBMENU:=Lua + SECTION:=lang + CATEGORY:=Languages + TITLE:=luci-lib-fs + PKGARCH:=all + URL:=https://github.com/lbthomsen/openwrt-luci + DEPENDS:=+luci +luci-lib-nixio +endef + +define Package/luci-lib-fs/description + luci-lib-fs +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Build/Install +endef + + +define Package/luci-lib-fs/install + $(INSTALL_DIR) $(1)/usr/lib/lua/luci + $(CP) ./files/*.lua $(1)/usr/lib/lua/luci + +endef + +$(eval $(call BuildPackage,luci-lib-fs)) diff --git a/package/lean/luci-lib-fs/files/fs.lua b/package/lean/luci-lib-fs/files/fs.lua new file mode 100644 index 000000000..a81ff675d --- /dev/null +++ b/package/lean/luci-lib-fs/files/fs.lua @@ -0,0 +1,244 @@ +--[[ +LuCI - Filesystem tools + +Description: +A module offering often needed filesystem manipulation functions + +FileId: +$Id$ + +License: +Copyright 2008 Steven Barth + +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. + +]]-- + +local io = require "io" +local os = require "os" +local ltn12 = require "luci.ltn12" +local fs = require "nixio.fs" +local nutil = require "nixio.util" + +local type = type + +--- LuCI filesystem library. +module "luci.fs" + +--- Test for file access permission on given path. +-- @class function +-- @name access +-- @param str String value containing the path +-- @return Number containing the return code, 0 on sucess or nil on error +-- @return String containing the error description (if any) +-- @return Number containing the os specific errno (if any) +access = fs.access + +--- Evaluate given shell glob pattern and return a table containing all matching +-- file and directory entries. +-- @class function +-- @name glob +-- @param filename String containing the path of the file to read +-- @return Table containing file and directory entries or nil if no matches +-- @return String containing the error description (if no matches) +-- @return Number containing the os specific errno (if no matches) +function glob(...) + local iter, code, msg = fs.glob(...) + if iter then + return nutil.consume(iter) + else + return nil, code, msg + end +end + +--- Checks wheather the given path exists and points to a regular file. +-- @param filename String containing the path of the file to test +-- @return Boolean indicating wheather given path points to regular file +function isfile(filename) + return fs.stat(filename, "type") == "reg" +end + +--- Checks wheather the given path exists and points to a directory. +-- @param dirname String containing the path of the directory to test +-- @return Boolean indicating wheather given path points to directory +function isdirectory(dirname) + return fs.stat(dirname, "type") == "dir" +end + +--- Read the whole content of the given file into memory. +-- @param filename String containing the path of the file to read +-- @return String containing the file contents or nil on error +-- @return String containing the error message on error +readfile = fs.readfile + +--- Write the contents of given string to given file. +-- @param filename String containing the path of the file to read +-- @param data String containing the data to write +-- @return Boolean containing true on success or nil on error +-- @return String containing the error message on error +writefile = fs.writefile + +--- Copies a file. +-- @param source Source file +-- @param dest Destination +-- @return Boolean containing true on success or nil on error +copy = fs.datacopy + +--- Renames a file. +-- @param source Source file +-- @param dest Destination +-- @return Boolean containing true on success or nil on error +rename = fs.move + +--- Get the last modification time of given file path in Unix epoch format. +-- @param path String containing the path of the file or directory to read +-- @return Number containing the epoch time or nil on error +-- @return String containing the error description (if any) +-- @return Number containing the os specific errno (if any) +function mtime(path) + return fs.stat(path, "mtime") +end + +--- Set the last modification time of given file path in Unix epoch format. +-- @param path String containing the path of the file or directory to read +-- @param mtime Last modification timestamp +-- @param atime Last accessed timestamp +-- @return 0 in case of success nil on error +-- @return String containing the error description (if any) +-- @return Number containing the os specific errno (if any) +function utime(path, mtime, atime) + return fs.utimes(path, atime, mtime) +end + +--- Return the last element - usually the filename - from the given path with +-- the directory component stripped. +-- @class function +-- @name basename +-- @param path String containing the path to strip +-- @return String containing the base name of given path +-- @see dirname +basename = fs.basename + +--- Return the directory component of the given path with the last element +-- stripped of. +-- @class function +-- @name dirname +-- @param path String containing the path to strip +-- @return String containing the directory component of given path +-- @see basename +dirname = fs.dirname + +--- Return a table containing all entries of the specified directory. +-- @class function +-- @name dir +-- @param path String containing the path of the directory to scan +-- @return Table containing file and directory entries or nil on error +-- @return String containing the error description on error +-- @return Number containing the os specific errno on error +function dir(...) + local iter, code, msg = fs.dir(...) + if iter then + local t = nutil.consume(iter) + t[#t+1] = "." + t[#t+1] = ".." + return t + else + return nil, code, msg + end +end + +--- Create a new directory, recursively on demand. +-- @param path String with the name or path of the directory to create +-- @param recursive Create multiple directory levels (optional, default is true) +-- @return Number with the return code, 0 on sucess or nil on error +-- @return String containing the error description on error +-- @return Number containing the os specific errno on error +function mkdir(path, recursive) + return recursive and fs.mkdirr(path) or fs.mkdir(path) +end + +--- Remove the given empty directory. +-- @class function +-- @name rmdir +-- @param path String containing the path of the directory to remove +-- @return Number with the return code, 0 on sucess or nil on error +-- @return String containing the error description on error +-- @return Number containing the os specific errno on error +rmdir = fs.rmdir + +local stat_tr = { + reg = "regular", + dir = "directory", + lnk = "link", + chr = "character device", + blk = "block device", + fifo = "fifo", + sock = "socket" +} +--- Get information about given file or directory. +-- @class function +-- @name stat +-- @param path String containing the path of the directory to query +-- @return Table containing file or directory properties or nil on error +-- @return String containing the error description on error +-- @return Number containing the os specific errno on error +function stat(path, key) + local data, code, msg = fs.stat(path) + if data then + data.mode = data.modestr + data.type = stat_tr[data.type] or "?" + end + return key and data and data[key] or data, code, msg +end + +--- Set permissions on given file or directory. +-- @class function +-- @name chmod +-- @param path String containing the path of the directory +-- @param perm String containing the permissions to set ([ugoa][+-][rwx]) +-- @return Number with the return code, 0 on sucess or nil on error +-- @return String containing the error description on error +-- @return Number containing the os specific errno on error +chmod = fs.chmod + +--- Create a hard- or symlink from given file (or directory) to specified target +-- file (or directory) path. +-- @class function +-- @name link +-- @param path1 String containing the source path to link +-- @param path2 String containing the destination path for the link +-- @param symlink Boolean indicating wheather to create a symlink (optional) +-- @return Number with the return code, 0 on sucess or nil on error +-- @return String containing the error description on error +-- @return Number containing the os specific errno on error +function link(src, dest, sym) + return sym and fs.symlink(src, dest) or fs.link(src, dest) +end + +--- Remove the given file. +-- @class function +-- @name unlink +-- @param path String containing the path of the file to remove +-- @return Number with the return code, 0 on sucess or nil on error +-- @return String containing the error description on error +-- @return Number containing the os specific errno on error +unlink = fs.unlink + +--- Retrieve target of given symlink. +-- @class function +-- @name readlink +-- @param path String containing the path of the symlink to read +-- @return String containing the link target or nil on error +-- @return String containing the error description on error +-- @return Number containing the os specific errno on error +readlink = fs.readlink diff --git a/package/lean/n2n_v2/Makefile b/package/lean/n2n_v2/Makefile new file mode 100644 index 000000000..1103d2b20 --- /dev/null +++ b/package/lean/n2n_v2/Makefile @@ -0,0 +1,55 @@ +# +# Copyright (C) 2007-2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_BRANCH:=trunk +PKG_SOURCE_URL:=https://shop.ntop.org/svn/ntop/trunk/n2n/n2n_v2 +PKG_REV:=9349 + +PKG_NAME:=n2n_v2 +PKG_VERSION:=$(PKG_REV) +PKG_RELEASE:=1 + +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE:=$(PKG_SOURCE_SUBDIR).tar.gz +PKG_SOURCE_PROTO:=svn +PKG_SOURCE_VERSION:=$(PKG_REV) + +include $(INCLUDE_DIR)/package.mk + +define Package/n2n_v2 + SECTION:=net + CATEGORY:=Network + TITLE:=N2N VPN tunneling daemon(V2) + URL:=http://www.ntop.org/n2n/ + SUBMENU:=VPN + DEPENDS:=+libpthread +kmod-tun +libopenssl +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(TARGET_CONFIGURE_OPTS) \ + CFLAGS="$(TARGET_CFLAGS)" \ + INSTALL_PROG=":" +endef + +define Package/n2n_v2/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/edge $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/supernode $(1)/usr/sbin/ + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_DATA) ./files/n2n_v2.config $(1)/etc/config/n2n_v2 + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/n2n_v2.init $(1)/etc/init.d/n2n_v2 +endef + +define Package/n2n_v2/conffiles +/etc/config/n2n_v2 +endef + +$(eval $(call BuildPackage,n2n_v2)) diff --git a/package/lean/n2n_v2/files/n2n_v2.config b/package/lean/n2n_v2/files/n2n_v2.config new file mode 100644 index 000000000..c765d02dd --- /dev/null +++ b/package/lean/n2n_v2/files/n2n_v2.config @@ -0,0 +1,15 @@ +config edge + option enabled '0' + option tunname 'n2n_edge' + option mode 'static' + option ipaddr '10.0.0.100' + option netmask '255.255.255.0' + option supernode '1.2.3.4' + option port '1234' + option community 'example' + option key 'password' + option route '0' + +config supernode + option enabled '0' + option port '1235' diff --git a/package/lean/n2n_v2/files/n2n_v2.init b/package/lean/n2n_v2/files/n2n_v2.init new file mode 100644 index 000000000..08dda79f3 --- /dev/null +++ b/package/lean/n2n_v2/files/n2n_v2.init @@ -0,0 +1,62 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2008-2012 OpenWrt.org + +START=90 + +start_instance() { + local cfg="$1" + + config_get type "$cfg" TYPE + + case "$type" in + edge) + config_get_bool enabled "$cfg" 'enabled' '0' + [ "$enabled" = "0" ] && return 1 + config_get tunname "$cfg" 'tunname' + config_get mode "$cfg" 'mode' + config_get ipaddr "$cfg" 'ipaddr' + config_get netmask "$cfg" 'netmask' + config_get supernode "$cfg" 'supernode' + config_get port "$cfg" 'port' + config_get community "$cfg" 'community' + config_get key "$cfg" 'key' + config_get_bool route "$cfg" 'route' '0' + [ "$route" = "1" ] && args='-r' + [ "$mode" = 'dhcp' ] && ipaddr='0.0.0.0' + /usr/sbin/edge -d $tunname -a ${mode}:${ipaddr} -c $community $([ -n "$key" ] && echo -k $key) -s ${netmask} -l ${supernode}:${port} $args + ;; + supernode) + config_get_bool enabled "$cfg" 'enabled' '0' + [ "$enabled" = "0" ] && return 1 + config_get port "$cfg" port + /usr/sbin/supernode -l $port + ;; + esac +} + +stop_instance() { + local cfg="$1" + + config_get type "$cfg" TYPE + + case "$type" in + edge) + killall -9 edge + ;; + supernode) + killall -9 supernode + ;; + esac +} + +start() { + config_load 'n2n_v2' + config_foreach start_instance 'edge' + config_foreach start_instance 'supernode' +} + +stop() { + config_load 'n2n_v2' + killall -9 edge + killall -9 supernode +} diff --git a/package/lean/ngrokc/Makefile b/package/lean/ngrokc/Makefile new file mode 100644 index 000000000..a355b0ac3 --- /dev/null +++ b/package/lean/ngrokc/Makefile @@ -0,0 +1,36 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=ngrokc +PKG_VERSION:=20160829 +PKG_RELEASE:=1 +PKG_REV:=355aa8ba062e92cfe54966084ca79e9bd5ff8555 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_URL:=https://github.com/dosgo/ngrok-c.git +PKG_SOURCE_VERSION:=$(PKG_REV) + +include $(INCLUDE_DIR)/package.mk + +define Package/ngrokc + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + TITLE:=Secure tunnels to localhost(C++ port) + URL:=https://github.com/dosgo/ngrok-c + DEPENDS:=+libc +libpthread +libopenssl +libstdcpp +endef + +define Build/Prepare + $(call Build/Prepare/Default,) + $(CP) $(PKG_BUILD_DIR)/Makefile.openssl $(PKG_BUILD_DIR)/Makefile +endef + +define Package/ngrokc/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/ngrokc $(1)/usr/bin +endef + + +$(eval $(call BuildPackage,ngrokc)) \ No newline at end of file diff --git a/package/lean/openwrt-mproxy/Makefile b/package/lean/openwrt-mproxy/Makefile new file mode 100644 index 000000000..74b473769 --- /dev/null +++ b/package/lean/openwrt-mproxy/Makefile @@ -0,0 +1,49 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=mproxy +PKG_VERSION=1 +PKG_RELEASE:=6 + +PKG_MAINTAINER:=lean +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=LICENSE + +PKG_SOURCE_PROTO:=git +#PKG_SOURCE_URL:=https://github.com/openwrt-develop/mproxy.git +#PKG_SOURCE_VERSION:=0e0e27192e91ff08f4e235065b6b24c642541334 +PKG_SOURCE_URL:=https://github.com/lonsx/mproxy-mod.git +PKG_SOURCE_VERSION:=ea3abaa40c901da6bb8e655cde63d3cac28b83ec + +PKG_SOURCE_SUBDIR:=$(PKG_NAME) +#PKG_SOURCE:=$(PKG_SOURCE_SUBDIR).tar.gz +PKG_SOURCE:=$(PKG_NAME).$(PKG_VERSION).$(PKG_RELEASE).tar.gz +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_SOURCE_SUBDIR) +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/mproxy + SECTION:=net + CATEGORY:=Network + TITLE:=mproxy for OpenWRT + DEPENDS:= +endef + +define Package/mproxy/description + mproxy is a Tiny Proxy in C. +endef + + +define Package/mproxy/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + + +define Package/mproxy/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/mproxy $(1)/usr/bin/mproxy +endef + +$(eval $(call BuildPackage,mproxy)) + diff --git a/package/lean/openwrt-mproxy/src/Makefile b/package/lean/openwrt-mproxy/src/Makefile new file mode 100644 index 000000000..d08aaa6f5 --- /dev/null +++ b/package/lean/openwrt-mproxy/src/Makefile @@ -0,0 +1,14 @@ +CC ?= gcc +CFLAGS = -g -Wall -Werror -DDBUG + +all: mproxy + +mproxy: mproxy.o + $(CC) $(CFLAGS) mproxy.o -o mproxy + +mproxy.o: mproxy.c + $(CC) $(CFLAGS) -c mproxy.c + +clean: + rm -rf *.o + rm -rf mproxy diff --git a/package/lean/openwrt-mproxy/src/mproxy.c b/package/lean/openwrt-mproxy/src/mproxy.c new file mode 100644 index 000000000..822add6c1 --- /dev/null +++ b/package/lean/openwrt-mproxy/src/mproxy.c @@ -0,0 +1,862 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + +#define BUF_SIZE 8192 + +#define READ 0 +#define WRITE 1 + +#define DEFAULT_LOCAL_PORT 8080 +#define DEFAULT_REMOTE_PORT 8081 +#define DEFAULT_R_P 1024 /* 瀹氫箟-r 鏃堕粯璁ょ殑杞彂CONNECT娴佺殑绔彛 */ +#define DEFAULT_M_S Lbxx: /* 瀹氫箟-m 鏃堕粯璁ょ殑ML鍏抽敭瀛楃涓(缁忓垽鏂棤鐢紝鍙垗寮) */ +#define SERVER_SOCKET_ERROR -1 +#define SERVER_SETSOCKOPT_ERROR -2 +#define SERVER_BIND_ERROR -3 +#define SERVER_LISTEN_ERROR -4 +#define CLIENT_SOCKET_ERROR -5 +#define CLIENT_RESOLVE_ERROR -6 +#define CLIENT_CONNECT_ERROR -7 +#define CREATE_PIPE_ERROR -8 +#define BROKEN_PIPE_ERROR -9 +#define HEADER_BUFFER_FULL -10 +#define BAD_HTTP_PROTOCOL -11 + +#define MAX_HEADER_SIZE 8192 + + +#if defined(OS_ANDROID) +#include + +#define LOG(fmt...) __android_log_print(ANDROID_LOG_DEBUG,__FILE__,##fmt) + +#else +#define LOG(fmt...) do { fprintf(stderr,"%s %s ",__DATE__,__TIME__); fprintf(stderr, ##fmt); } while(0) +#endif + + +char remote_host[128]; +int remote_port; +int local_port; +char r_h[128]; +int r_p; +char m_s[128]; + +int server_sock; +int client_sock; +int remote_sock; + + + + +char * header_buffer ; + + +enum +{ + FLG_NONE = 0, /* 姝e父鏁版嵁娴佷笉杩涜缂栬В鐮 */ + R_C_DEC = 1, /* 璇诲彇瀹㈡埛绔暟鎹粎杩涜瑙g爜 */ + W_S_ENC = 2 /* 鍙戦佸埌鏈嶅姟绔繘琛岀紪鐮 */ +}; + +static int io_flag; /* 缃戠粶io鐨勪竴浜涙爣蹇椾綅 */ +static int r_flag; /* 鏄惁鍚敤-r 鍖归厤鍏嶆祦host鐩存帴杞彂CONNECT娴侀噺妯″紡 */ +static int m_flag; /* 鏄惁鍚敤-m 鍏抽敭瀛楀ご鍖归厤鍏嶆祦妯″紡 */ +static int m_pid; /* 淇濆瓨涓昏繘绋媔d */ + + + +void server_loop(); +void stop_server(); +void handle_client(int client_sock, struct sockaddr_in client_addr); +void forward_header(int destination_sock); +void forward_data(int source_sock, int destination_sock); +void rewrite_header(); +int send_data(int socket,char * buffer,int len ); +int receive_data(int socket, char * buffer, int len); +void hand_mproxy_info_req(int sock,char * header_buffer) ; +void get_info(char * output); +const char * get_work_mode() ; +int create_connection() ; +int _main(int argc, char *argv[]) ; + + + + +ssize_t readLine(int fd, void *buffer, size_t n) +{ + ssize_t numRead; + size_t totRead; + char *buf; + char ch; + + if (n <= 0 || buffer == NULL) { + errno = EINVAL; + return -1; + } + + buf = buffer; + + totRead = 0; + for (;;) { + numRead = receive_data(fd, &ch, 1); + + if (numRead == -1) { + if (errno == EINTR) + continue; + else + return -1; /* 鏈煡閿欒 */ + + } else if (numRead == 0) { /* EOF */ + if (totRead == 0) /* No bytes read; return 0 */ + return 0; + else /* Some bytes read; add '\0' */ + break; + + } else { + + if (totRead < n - 1) { /* Discard > (n - 1) bytes */ + totRead++; + *buf++ = ch; + } + + if (ch == '\n') + break; + } + } + + *buf = '\0'; + return totRead; +} + +int read_header(int fd, void * buffer) +{ + // bzero(header_buffer,sizeof(MAX_HEADER_SIZE)); + memset(header_buffer,0,MAX_HEADER_SIZE); + char line_buffer[2048]; + char * base_ptr = header_buffer; + + for(;;) + { + memset(line_buffer,0,2048); + + int total_read = readLine(fd,line_buffer,2048); + if(total_read <= 0) + { + return CLIENT_SOCKET_ERROR; + } + //闃叉header缂撳啿鍖鸿洰瓒婄晫 + if(base_ptr + total_read - header_buffer <= MAX_HEADER_SIZE) + { + strncpy(base_ptr,line_buffer,total_read); + base_ptr += total_read; + } else + { + return HEADER_BUFFER_FULL; + } + + //璇诲埌浜嗙┖琛岋紝http澶寸粨鏉 + if(strcmp(line_buffer,"\r\n") == 0 || strcmp(line_buffer,"\n") == 0) + { + break; + } + + } + return 0; + +} + +void extract_server_path(const char * header,char * output) +{ + char * p = strstr(header,"GET /"); + if(p) { + char * p1 = strchr(p+4,' '); + strncpy(output,p+4,(int)(p1 - p - 4) ); + } + +} + +int extract_host(const char * header) +{ + if(!m_flag) + { + if(!r_flag) + { + char * _p = strstr(header,"CONNECT"); /* 鍦 CONNECT 鏂规硶涓В鏋 闅ч亾涓绘満鍚嶇О鍙婄鍙e彿 */ + if(_p) + { + char * _p1 = strchr(_p,' '); + + char * _p2 = strchr(_p1 + 1,':'); + char * _p3 = strchr(_p1 + 1,' '); + + if(_p2) + { + char s_port[10]; + bzero(s_port,10); + + strncpy(remote_host,_p1+1,(int)(_p2 - _p1) - 1); + strncpy(s_port,_p2+1,(int) (_p3 - _p2) -1); + remote_port = atoi(s_port); + + } else + { + strncpy(remote_host,_p1+1,(int)(_p3 - _p1) -1); + remote_port = 80; + } + + + return 0; + } + + + char * p = strstr(header,"Host:"); + if(!p) + { + return BAD_HTTP_PROTOCOL; + } + char * p1 = strchr(p,'\n'); + if(!p1) + { + return BAD_HTTP_PROTOCOL; + } + + char * p2 = strchr(p + 5,':'); /* 5鏄寚'Host:'鐨勯暱搴 */ + + if(p2 && p2 < p1) + { + + int p_len = (int)(p1 - p2 -1); + char s_port[p_len]; + strncpy(s_port,p2+1,p_len); + s_port[p_len] = '\0'; + remote_port = atoi(s_port); + + int h_len = (int)(p2 - p -5 -1 ); + strncpy(remote_host,p + 5 + 1 ,h_len); //Host: + //assert h_len < 128; + remote_host[h_len] = '\0'; + } else + { + int h_len = (int)(p1 - p - 5 -1 -1); + strncpy(remote_host,p + 5 + 1,h_len); + //assert h_len < 128; + remote_host[h_len] = '\0'; + remote_port = 80; + } + } else + { + strncpy(remote_host, r_h, strlen(r_h)); + remote_port = r_p; + } + } else + { + char * __p = strstr(header,"CONNECT"); /* 鍦 CONNECT 鏂规硶涓В鏋 闅ч亾涓绘満鍚嶇О鍙婄鍙e彿 */ + char * _p = strstr(header,m_s); + //printf("Show: %s\n",_p); + if(_p && __p) + { + char * _p1 = strchr(_p,' '); + + char * _p2 = strchr(_p1 + 1,':'); + char * _p3 = strchr(_p1 + 1,'\r'); + + if(_p2) + { + char s_port[10]; + bzero(s_port,10); + + strncpy(remote_host,_p1+1,(int)(_p2 - _p1) - 1); + strncpy(s_port,_p2+1,(int) (_p3 - _p2) -1); + remote_port = atoi(s_port); + + } else + { + strncpy(remote_host,_p1+1,(int)(_p3 - _p1) -1); + remote_port = 80; + } + + + return 0; + } + + + char * p = strstr(header,m_s); + if(!p) + { + if(r_flag) + { + strncpy(remote_host, r_h, strlen(r_h)); + remote_port = r_p; + return 0; + }else + { + return BAD_HTTP_PROTOCOL; + } + } + char * p1 = strchr(p,'\n'); + if(!p1) + { + return BAD_HTTP_PROTOCOL; + } + + int m_l = strlen(m_s); + char * p2 = strchr(p + m_l,':'); /* m_l鏄寚绫讳技鑷畾涔'Lbxx:'鐨勯暱搴 */ + + if(p2 && p2 < p1) + { + + int p_len = (int)(p1 - p2 -1); + char s_port[p_len]; + strncpy(s_port,p2+1,p_len); + s_port[p_len] = '\0'; + remote_port = atoi(s_port); + + int h_len = (int)(p2 - p - m_l -1 ); + strncpy(remote_host,p + m_l + 1 ,h_len); //Host: + //assert h_len < 128; + remote_host[h_len] = '\0'; + } else + { + int h_len = (int)(p1 - p - m_l -1 -1); + strncpy(remote_host,p + m_l + 1,h_len); + //assert h_len < 128; + remote_host[h_len] = '\0'; + remote_port = 80; + } + } + return 0; +} + +/* 鍝嶅簲闅ч亾杩炴帴璇锋眰 */ +int send_tunnel_ok(int client_sock) +{ + char * resp = "HTTP/1.1 200 Connection Established\r\n\r\n"; + int len = strlen(resp); + char buffer[len+1]; + strcpy(buffer,resp); + if(send_data(client_sock,buffer,len) < 0) + { + perror("Send http tunnel response failed\n"); + return -1; + } + return 0; +} + + +//杩斿洖mproxy鐨勮繍琛屽熀鏈俊鎭 +void hand_mproxy_info_req(int sock, char * header) { + char server_path[255] ; + char response[8192]; + extract_server_path(header,server_path); + + LOG("server path:%s\n",server_path); + char info_buf[1024]; + get_info(info_buf); + sprintf(response,"HTTP/1.0 200 OK\nServer: MProxy/0.1\n\ + Content-type: text/html; charset=utf-8\n\n\ + \ +
%s
\ + \n",info_buf); + + + write(sock,response,strlen(response)); + +} + +/* 鑾峰彇杩愯鐨勫熀鏈俊鎭緭鍑哄埌鎸囧畾鐨勭紦鍐插尯 */ +void get_info(char * output) +{ + int pos = 0; + char line_buffer[512]; + sprintf(line_buffer,"======= mproxy (v0.1) ========\n"); + int len = strlen(line_buffer); + memcpy(output,line_buffer,len); + pos += len ; + + sprintf(line_buffer,"%s\n",get_work_mode()); + len = strlen(line_buffer); + memcpy(output + pos,line_buffer,len); + pos += len; + + if(strlen(remote_host) > 0) + { + sprintf(line_buffer,"start server on %d and next hop is %s:%d\n",local_port,remote_host,remote_port); + + } else + { + sprintf(line_buffer,"start server on %d\n",local_port); + } + + len = strlen(line_buffer); + memcpy(output+ pos,line_buffer,len); + pos += len ; + + output[pos] = '\0'; + +} + + +const char * get_work_mode() +{ + + if(strlen(remote_host) == 0) + { + if(!r_flag && !m_flag) + { + if(io_flag == FLG_NONE) + { + return "start as normal http proxy"; + } else if(io_flag == R_C_DEC) + { + return "start as remote forward proxy and do decode data when recevie data" ; + } + } else + { + return "start as -r or -m mode"; + } + + } else + { + if(io_flag == FLG_NONE) + { + return "start as remote forward proxy"; + } else if(io_flag == W_S_ENC) + { + return "start as forward proxy and do encode data when send data"; + } + } + return "unknow"; + + +} + +/* 澶勭悊瀹㈡埛绔殑杩炴帴 */ +void handle_client(int client_sock, struct sockaddr_in client_addr) +{ + int is_http_tunnel = 0; + if(strlen(remote_host) == 0) /* 鏈寚瀹氳繙绔富鏈哄悕绉颁粠http 璇锋眰 HOST 瀛楁涓幏鍙 */ + { + + #ifdef DEBUG + LOG(" ============ handle new client ============\n"); + LOG(">>>Header:%s\n",header_buffer); + #endif + + if(read_header(client_sock,header_buffer) < 0) + { + LOG("Read Http header failed\n"); + return; + } else + { + char * p = strstr(header_buffer,"CONNECT"); /* 鍒ゆ柇鏄惁鏄痟ttp 闅ч亾璇锋眰 */ + if(p) + { + LOG("receive CONNECT request\n"); + is_http_tunnel = 1; + } + + if(strstr(header_buffer,"GET /mproxy") >0 ) + { + LOG("====== hand mproxy info request ===="); + //杩斿洖mproxy鐨勮繍琛屽熀鏈俊鎭 + hand_mproxy_info_req(client_sock,header_buffer); + + return; + } + + if(extract_host(header_buffer) < 0) + { + LOG("Cannot extract host field,bad http protrotol"); + return; + } + LOG("Host:%s port: %d io_flag:%d\n",remote_host,remote_port,io_flag); + + } + } + + if ((remote_sock = create_connection()) < 0) { + LOG("Cannot connect to host [%s:%d]\n",remote_host,remote_port); + return; + } + + if (fork() == 0) { // 鍒涘缓瀛愯繘绋嬬敤浜庝粠瀹㈡埛绔浆鍙戞暟鎹埌杩滅socket鎺ュ彛 + + if(strlen(header_buffer) > 0 && !is_http_tunnel) + { + forward_header(remote_sock); //鏅氱殑http璇锋眰鍏堣浆鍙慼eader + } + + forward_data(client_sock, remote_sock); + exit(0); + } + + if (fork() == 0) { // 鍒涘缓瀛愯繘绋嬬敤浜庤浆鍙戜粠杩滅socket鎺ュ彛杩囨潵鐨勬暟鎹埌瀹㈡埛绔 + + if(io_flag == W_S_ENC) + { + io_flag = R_C_DEC; //鍙戦佽姹傜粰鏈嶅姟绔繘琛岀紪鐮侊紝璇诲彇鏈嶅姟绔殑鍝嶅簲鍒欒繘琛岃В鐮 + } else if (io_flag == R_C_DEC) + { + io_flag = W_S_ENC; //鎺ユ敹瀹㈡埛绔姹傝繘琛岃В鐮侊紝閭d箞鍝嶅簲瀹㈡埛绔姹傞渶瑕佺紪鐮 + } + + if(is_http_tunnel) + { + send_tunnel_ok(client_sock); + } + + forward_data(remote_sock, client_sock); + exit(0); + } + + close(remote_sock); + close(client_sock); +} + +void forward_header(int destination_sock) +{ + rewrite_header(); + #ifdef DEBUG + LOG("================ The Forward HEAD ================="); + LOG("%s\n",header_buffer); + #endif + + int len = strlen(header_buffer); + send_data(destination_sock,header_buffer,len) ; +} + +int send_data(int socket,char * buffer,int len) +{ + + if(io_flag == W_S_ENC) + { + int i; + for(i = 0; i < len ; i++) + { + buffer[i] ^= 1; + + } + } + + return send(socket,buffer,len,0); +} + +int receive_data(int socket, char * buffer, int len) +{ + int n = recv(socket, buffer, len, 0); + if(io_flag == R_C_DEC && n > 0) + { + int i; + for(i = 0; i< n; i++ ) + { + buffer[i] ^= 1; + // printf("%d => %d\n",c,buffer[i]); + } + } + + return n; +} + + + +/* 浠g悊涓殑瀹屾暣URL杞彂鍓嶉渶鏀规垚 path 鐨勫舰寮 */ +void rewrite_header() +{ + char * p = strstr(header_buffer,"http://"); + char * p0 = strchr(p,'\0'); + char * p5 = strstr(header_buffer,"HTTP/"); /* "HTTP/" 鏄崗璁爣璇 濡 "HTTP/1.1" */ + int len = strlen(header_buffer); + if(p) + { + char * p1 = strchr(p + 7,'/'); + if(p1 && (p5 > p1)) + { + //杞崲url鍒 path + memcpy(p,p1,(int)(p0 -p1)); + int l = len - (p1 - p) ; + header_buffer[l] = '\0'; + + + } else + { + char * p2 = strchr(p,' '); //GET http://3g.sina.com.cn HTTP/1.1 + + // printf("%s\n",p2); + memcpy(p + 1,p2,(int)(p0-p2)); + *p = '/'; //url 娌℃湁璺緞浣跨敤鏍 + int l = len - (p2 - p ) + 1; + header_buffer[l] = '\0'; + + } + } + + + if(m_flag) + { + char * p6 = strstr(header_buffer,"Host:"); //...\r\nHost: miguvod.lovev.com:8080\r\nLbxx: tiny.cc\r\n.... + char * p00 = strchr(p6,'\0'); // p6 p7 p8 p9 p00 + char * p7 = strchr(p6,' '); + char * p8 = strstr(header_buffer,m_s); + char * p9 = strchr(p8,' '); + if(p6) + { + if(p8 && (p8 > p6)) + { + memcpy(p7,p9,(int)(p00 -p9)); //浠bxx鐨勫艰鐩朒ost鐨勫硷紝杩欒姹侺bxx鍦ㄦā寮忎腑瑕佺揣璺熷湪Host鍚庨潰(浠呭http) + int l = len - (p9 - p7) ; + header_buffer[l] = '\0'; + } + } + } +} + + +void forward_data(int source_sock, int destination_sock) { + char buffer[BUF_SIZE]; + int n; + + while ((n = receive_data(source_sock, buffer, BUF_SIZE)) > 0) + { + + send_data(destination_sock, buffer, n); + } + + shutdown(destination_sock, SHUT_RDWR); + + shutdown(source_sock, SHUT_RDWR); +} + + + +int create_connection() { + struct sockaddr_in server_addr; + struct hostent *server; + int sock; + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + return CLIENT_SOCKET_ERROR; + } + + if ((server = gethostbyname(remote_host)) == NULL) { + errno = EFAULT; + return CLIENT_RESOLVE_ERROR; + } + LOG("======= forward request to remote host:%s port:%d ======= \n",remote_host,remote_port); + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + memcpy(&server_addr.sin_addr.s_addr, server->h_addr, server->h_length); + server_addr.sin_port = htons(remote_port); + + if (connect(sock, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) { + return CLIENT_CONNECT_ERROR; + } + + return sock; +} + + +int create_server_socket(int port) { + int server_sock, optval; + struct sockaddr_in server_addr; + + if ((server_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + return SERVER_SOCKET_ERROR; + } + + if (setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) { + return SERVER_SETSOCKOPT_ERROR; + } + + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(port); + server_addr.sin_addr.s_addr = INADDR_ANY; + + if (bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) != 0) { + return SERVER_BIND_ERROR; + } + + if (listen(server_sock, 20) < 0) { + return SERVER_LISTEN_ERROR; + } + + return server_sock; +} + +/* 澶勭悊鍍靛案杩涚▼ */ +void sigchld_handler(int signal) { + while (waitpid(-1, NULL, WNOHANG) > 0); +} + +void server_loop() { + struct sockaddr_in client_addr; + socklen_t addrlen = sizeof(client_addr); + + while (1) { + client_sock = accept(server_sock, (struct sockaddr*)&client_addr, &addrlen); + + if (fork() == 0) { // 鍒涘缓瀛愯繘绋嬪鐞嗗鎴风杩炴帴璇锋眰 + close(server_sock); + handle_client(client_sock, client_addr); + exit(0); + } + close(client_sock); + } + +} + +void stop_server() +{ + kill(m_pid, SIGKILL); +} + +void usage(void) +{ + printf("Usage:\n"); + printf(" -l specifyed local listen port \n"); + printf(" -h specifyed next hop server name to forward all trafic unhandled, prior to -m & -r\n"); + printf(" -r specifyed server name to forward 'HTTP'&'CONNECT' to, no matter what host is\n"); + printf(" -m specifyed key words replaced & recognized as 'Host:' function, prior to -r\n"); + printf(" -d run as daemon\n"); + printf(" -E encode data when forwarding data\n"); + printf(" -D decode data when receiving data\n"); + printf(" Notice:-h -r -m can not be used together.\n"); + exit (8); +} + +void start_server(int daemon) +{ + //鍒濆鍖栧叏灞鍙橀噺 + header_buffer = (char *) malloc(MAX_HEADER_SIZE); + + signal(SIGCHLD, sigchld_handler); // 闃叉瀛愯繘绋嬪彉鎴愬兊灏歌繘绋 + + if ((server_sock = create_server_socket(local_port)) < 0) + { // start server + LOG("Cannot run server on %d\n",local_port); + exit(server_sock); + } + + if(daemon) + { + pid_t pid; + if((pid = fork()) == 0) + { + server_loop(); + } else if (pid > 0 ) + { + m_pid = pid; + LOG("mporxy pid is: [%d]\n",pid); + close(server_sock); + } else + { + LOG("Cannot daemonize\n"); + exit(pid); + } + + } else + { + server_loop(); + } + +} + +int main(int argc, char *argv[]) +{ + return _main(argc,argv); +} + +int _main(int argc, char *argv[]) +{ + local_port = DEFAULT_LOCAL_PORT; + io_flag = FLG_NONE; + r_flag = 0; + m_flag = 0; + //m_s = "DEFAULT_M_S"; + int daemon = 0; + + char info_buf[2048]; + + int opt; + char optstrs[] = ":l:h:r:m:dED"; + char *p = NULL; + while(-1 != (opt = getopt(argc, argv, optstrs))) + { + switch(opt) + { + case 'l': + local_port = atoi(optarg); + break; + case 'h': + p = strchr(optarg, ':'); + if(p) + { + strncpy(remote_host, optarg, p - optarg); + remote_port = atoi(p+1); + } + else + { + strncpy(remote_host, optarg, strlen(optarg)); + remote_port = DEFAULT_REMOTE_PORT; + } + break; + case 'r': + p = strchr(optarg, ':'); + if(p) + { + strncpy(r_h, optarg, p - optarg); + r_p = atoi(p+1); + } + else + { + strncpy(r_h, optarg, strlen(optarg)); + r_p = DEFAULT_R_P; + } + printf("Your forward server is: %s:%d\n",r_h,r_p); + r_flag = 1; + break; + case 'm': + strncpy(m_s, optarg, strlen(optarg)); + printf("Your sting is: %s\n",m_s); + m_flag = 1; + break; + case 'd': + daemon = 1; + break; + case 'E': + io_flag = W_S_ENC; + break; + case 'D': + io_flag = R_C_DEC; + break; + case ':': + printf("\nMissing argument after: -%c\n", optopt); + usage(); + case '?': + printf("\nInvalid argument: %c\n", optopt); + default: + usage(); + } + } + + get_info(info_buf); + LOG("%s\n",info_buf); + start_server(daemon); + return 0; + +} diff --git a/package/lean/openwrt-shadowsocksR-libev-full b/package/lean/openwrt-shadowsocksR-libev-full new file mode 160000 index 000000000..6993a4a1c --- /dev/null +++ b/package/lean/openwrt-shadowsocksR-libev-full @@ -0,0 +1 @@ +Subproject commit 6993a4a1ca6e6fd07700cf70a0580b4fcf1eb2c0 diff --git a/package/lean/openwrt-vlmcsd b/package/lean/openwrt-vlmcsd new file mode 160000 index 000000000..68ad9fba5 --- /dev/null +++ b/package/lean/openwrt-vlmcsd @@ -0,0 +1 @@ +Subproject commit 68ad9fba57c70aba1d329c5b84e908557323ed5d diff --git a/package/lean/pdnsd-alt/Makefile b/package/lean/pdnsd-alt/Makefile new file mode 100644 index 000000000..c1b86bd80 --- /dev/null +++ b/package/lean/pdnsd-alt/Makefile @@ -0,0 +1,55 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=pdnsd +PKG_VERSION:=1.2.9a-par +PKG_RELEASE=$(PKG_SOURCE_VERSION) + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=git://gitorious.org/pdnsd/pdnsd.git +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_VERSION:=a8e46ccba7b0fa2230d6c42ab6dcd92926f6c21d +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz +# PKG_MIRROR_MD5SUM:= +# CMAKE_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/pdnsd-alt + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + DEPENDS:=+libpthread + TITLE:=Proxy DNS Server +endef + +define Package/pdnsd-alt/description + pdnsd, is an IPv6 capable proxy DNS server with permanent caching (the cache + contents are written to hard disk on exit) that is designed to cope with + unreachable or down DNS servers (for example in dial-in networking). + + pdnsd can be used with applications that do dns lookups, eg on startup, and + can't be configured to change that behaviour, to prevent the often + minute-long hangs (or even crashes) that result from stalled dns queries. +endef + +TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include +#TARGET_CFLAGS += -ggdb3 + +CMAKE_OPTIONS += -DDEBUG=1 + +CONFIGURE_ARGS += \ + --with-cachedir=/var/pdnsd + +define Package/pdnsd-alt/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/pdnsd $(1)/usr/sbin/ + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/pdnsd-ctl/pdnsd-ctl $(1)/usr/bin/ + + #$(INSTALL_DIR) $(1)/etc/init.d + #$(INSTALL_BIN) ./files/pdnsd.init $(1)/etc/init.d/pdnsd + $(INSTALL_DIR) $(1)/etc + $(INSTALL_CONF) $(PKG_BUILD_DIR)/doc/pdnsd.conf $(1)/etc/ +endef + +$(eval $(call BuildPackage,pdnsd-alt)) diff --git a/package/lean/pdnsd-alt/files/pdnsd.init b/package/lean/pdnsd-alt/files/pdnsd.init new file mode 100644 index 000000000..e678d8d6a --- /dev/null +++ b/package/lean/pdnsd-alt/files/pdnsd.init @@ -0,0 +1,46 @@ +#!/bin/sh /etc/rc.common + +START=65 +NAME=pdnsd +DESC="proxy DNS server" + +DAEMON=/usr/sbin/pdnsd +PID_FILE=/var/run/$NAME.pid +CACHEDIR=/var/pdnsd +CACHE=$CACHEDIR/pdnsd.cache + +USER=nobody +GROUP=nogroup + +start() { + echo -n "Starting $DESC: $NAME" + + gen_cache + + $DAEMON --daemon -p $PID_FILE + echo " ." +} + +stop() { + echo -n "Stopping $DESC: $NAME" + kill `cat $PID_FILE` > /dev/null 2>&1 + rm -rf $PID_FILE + echo " ." +} + +restart() { + echo "Restarting $DESC: $NAME... " + stop + sleep 2 + start +} + +gen_cache() +{ + if ! test -f "$CACHE"; then + mkdir -p `dirname $CACHE` + dd if=/dev/zero of="$CACHE" bs=1 count=4 2> /dev/null + chown -R $USER.$GROUP $CACHEDIR + fi +} +