diff --git a/package/lean/kcptun-client/Makefile b/package/lean/kcptun-client/Makefile new file mode 100644 index 0000000000..0643213c4b --- /dev/null +++ b/package/lean/kcptun-client/Makefile @@ -0,0 +1,71 @@ +# +# Copyright (C) 2015-2016 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v3. +# + +include $(TOPDIR)/rules.mk + +ifeq ($(ARCH),x86_64) + PKG_ARCH_KCPTUN:=amd64 +endif +ifeq ($(ARCH),mipsel) + PKG_ARCH_KCPTUN:=mipsle +endif +ifeq ($(ARCH),mips) + PKG_ARCH_KCPTUN:=mips +endif +ifeq ($(ARCH),i386) + PKG_ARCH_KCPTUN:=386 +endif +ifeq ($(ARCH),arm) + PKG_ARCH_KCPTUN:=arm7 +endif +ifeq ($(BOARD),bcm53xx) + PKG_ARCH_KCPTUN:=arm6 +endif +ifeq ($(BOARD),kirkwood) + PKG_ARCH_KCPTUN:=arm5 +endif +ifeq ($(ARCH),aarch64) + PKG_ARCH_KCPTUN:=arm64 +endif + +PKG_NAME:=kcptun-client +PKG_VERSION:=20190924 +PKG_RELEASE:=1 +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE:=kcptun-linux-$(PKG_ARCH_KCPTUN)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://github.com/xtaci/kcptun/releases/download/v$(PKG_VERSION) +PKG_HASH:=skip + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME) + SECTION:=net + CATEGORY:=Network + TITLE:=Kcptun is a cross-platform proxy software + DEPENDS:= + URL:=https://github.com/xtaci/kcptun +endef + +define Package/$(PKG_NAME)/description + Kcptun is a Fast and Reliable ARQ Protocol tunnel +endef + +define Build/Prepare + tar -xzvf $(DL_DIR)/$(PKG_SOURCE) -C $(PKG_BUILD_DIR) +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/client_linux_$(PKG_ARCH_KCPTUN) $(1)/usr/bin/kcptun-client +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/package/lean/luci-app-ssr-plus/Makefile b/package/lean/luci-app-ssr-plus/Makefile new file mode 100644 index 0000000000..ea45e4c967 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/Makefile @@ -0,0 +1,91 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-ssr-plus +PKG_VERSION:=1 +PKG_RELEASE:=125 + +PKG_CONFIG_DEPENDS:= CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME)/config +config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks + bool "Include Shadowsocks New Version" + default y if x86_64 + +config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray + bool "Include V2ray" + default y if x86_64 + +config PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun + bool "Include Kcptun" + default n + +config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server + bool "Include ShadowsocksR Server" + default y if x86_64 + +config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks + bool "Include ShadowsocksR Socks and Tunnel" + default y if x86_64 +endef + +define Package/luci-app-ssr-plus + SECTION:=luci + CATEGORY:=LuCI + SUBMENU:=3. Applications + TITLE:=SS/SSR/V2Ray LuCI interface + PKGARCH:=all + DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +bash +pdnsd-alt +wget \ + +PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks:shadowsocks-libev-ss-redir \ + +PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray \ + +PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun-client \ + +PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server:shadowsocksr-libev-server \ + +PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks:shadowsocksr-libev-ssr-local +endef + +define Build/Prepare +endef + +define Build/Compile +endef + +define Package/luci-app-ssr-plus/conffiles +/etc/ssr_ip +/etc/dnsmasq.ssr/gfw_list.conf +endef + +define Package/luci-app-ssr-plus/install + $(INSTALL_DIR) $(1)/usr/lib/lua/luci + cp -pR ./luasrc/* $(1)/usr/lib/lua/luci + $(INSTALL_DIR) $(1)/ + cp -pR ./root/* $(1)/ + $(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n + po2lmo ./po/zh-cn/ssr-plus.po $(1)/usr/lib/lua/luci/i18n/ssr-plus.zh-cn.lmo +endef + +define Package/luci-app-ssr-plus/postinst +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + ( . /etc/uci-defaults/luci-ssr-plus ) && rm -f /etc/uci-defaults/luci-ssr-plus + rm -f /tmp/luci-indexcache + chmod 755 /etc/init.d/shadowsocksr >/dev/null 2>&1 + /etc/init.d/shadowsocksr enable >/dev/null 2>&1 +fi +exit 0 +endef + +define Package/luci-app-ssr-plus/prerm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/shadowsocksr disable + /etc/init.d/shadowsocksr stop +fi +exit 0 +endef + +$(eval $(call BuildPackage,luci-app-ssr-plus)) diff --git a/package/lean/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua b/package/lean/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua new file mode 100644 index 0000000000..7ec5d37cf4 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua @@ -0,0 +1,192 @@ +-- Copyright (C) 2017 yushi studio +-- Licensed to the public under the GNU General Public License v3. + +module("luci.controller.shadowsocksr", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/shadowsocksr") then + return + end + + + entry({"admin", "services", "shadowsocksr"},alias("admin", "services", "shadowsocksr", "client"),_("ShadowSocksR Plus+"), 10).dependent = true + + entry({"admin", "services", "shadowsocksr", "client"},cbi("shadowsocksr/client"),_("SSR Client"), 10).leaf = true + + entry({"admin", "services", "shadowsocksr", "servers"}, arcombine(cbi("shadowsocksr/servers", {autoapply=true}), cbi("shadowsocksr/client-config")),_("Severs Nodes"), 20).leaf = true + + entry({"admin", "services", "shadowsocksr", "control"},cbi("shadowsocksr/control"),_("Access Control"), 30).leaf = true + + -- entry({"admin", "services", "shadowsocksr", "list"},form("shadowsocksr/list"),_("GFW List"), 40).leaf = true + + entry({"admin", "services", "shadowsocksr", "advanced"},cbi("shadowsocksr/advanced"),_("Advanced Settings"), 50).leaf = true + + if nixio.fs.access("/usr/bin/ssr-server") then + entry({"admin", "services", "shadowsocksr", "server"},arcombine(cbi("shadowsocksr/server"), cbi("shadowsocksr/server-config")),_("SSR Server"), 60).leaf = true + end + + entry({"admin", "services", "shadowsocksr", "status"},form("shadowsocksr/status"),_("Status"), 70).leaf = true + + entry({"admin", "services", "shadowsocksr", "check"}, call("check_status")) + entry({"admin", "services", "shadowsocksr", "refresh"}, call("refresh_data")) + entry({"admin", "services", "shadowsocksr", "checkport"}, call("check_port")) + + entry({"admin", "services", "shadowsocksr", "log"},form("shadowsocksr/log"),_("Log"), 80).leaf = true + + entry({"admin", "services", "shadowsocksr","run"},call("act_status")).leaf=true + + entry({"admin", "services", "shadowsocksr", "ping"}, call("act_ping")).leaf=true + +end + +function act_status() + local e={} + e.running=luci.sys.call("busybox ps -w | grep ssr-retcp | grep -v grep >/dev/null")==0 + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end + +function act_ping() + local e={} + e.index=luci.http.formvalue("index") + e.ping=luci.sys.exec("ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*.[0-9]' | awk -F '=' '{print$2}'"%luci.http.formvalue("domain")) + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end + +function check_status() +local set ="/usr/bin/ssr-check www." .. luci.http.formvalue("set") .. ".com 80 3 1" +sret=luci.sys.call(set) +if sret== 0 then + retstring ="0" +else + retstring ="1" +end +luci.http.prepare_content("application/json") +luci.http.write_json({ ret=retstring }) +end + +function refresh_data() +local set =luci.http.formvalue("set") +local icount =0 + +if set == "gfw_data" then + if nixio.fs.access("/usr/bin/wget-ssl") then + refresh_cmd="wget-ssl --no-check-certificate https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt -O /tmp/gfw.b64" + else + refresh_cmd="wget -O /tmp/gfw.b64 http://iytc.net/tools/list.b64" + end + sret=luci.sys.call(refresh_cmd .. " 2>/dev/null") + if sret== 0 then + luci.sys.call("/usr/bin/ssr-gfw") + icount = luci.sys.exec("cat /tmp/gfwnew.txt | wc -l") + if tonumber(icount)>1000 then + oldcount=luci.sys.exec("cat /etc/dnsmasq.ssr/gfw_list.conf | wc -l") + if tonumber(icount) ~= tonumber(oldcount) then + luci.sys.exec("cp -f /tmp/gfwnew.txt /etc/dnsmasq.ssr/gfw_list.conf") + retstring=tostring(math.ceil(tonumber(icount)/2)) + else + retstring ="0" + end + else + retstring ="-1" + end + luci.sys.exec("rm -f /tmp/gfwnew.txt ") + else + retstring ="-1" + end +elseif set == "ip_data" then + refresh_cmd="wget -O- 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' 2>/dev/null| awk -F\\| '/CN\\|ipv4/ { printf(\"%s/%d\\n\", $4, 32-log($5)/log(2)) }' > /tmp/china_ssr.txt" + sret=luci.sys.call(refresh_cmd) + icount = luci.sys.exec("cat /tmp/china_ssr.txt | wc -l") + if sret== 0 and tonumber(icount)>1000 then + oldcount=luci.sys.exec("cat /etc/china_ssr.txt | wc -l") + if tonumber(icount) ~= tonumber(oldcount) then + luci.sys.exec("cp -f /tmp/china_ssr.txt /etc/china_ssr.txt") + retstring=tostring(tonumber(icount)) + else + retstring ="0" + end + + else + retstring ="-1" + end + luci.sys.exec("rm -f /tmp/china_ssr.txt ") +else + local need_process = 0 + if nixio.fs.access("/usr/bin/wget-ssl") then + refresh_cmd="wget-ssl --no-check-certificate -O - https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt > /tmp/adnew.conf" + need_process = 1 + else + refresh_cmd="wget -O /tmp/ad.conf http://iytc.net/tools/ad.conf" + end + sret=luci.sys.call(refresh_cmd .. " 2>/dev/null") + if sret== 0 then + if need_process == 1 then + luci.sys.call("/usr/bin/ssr-ad") + end + icount = luci.sys.exec("cat /tmp/ad.conf | wc -l") + if tonumber(icount)>1000 then + if nixio.fs.access("/etc/dnsmasq.ssr/ad.conf") then + oldcount=luci.sys.exec("cat /etc/dnsmasq.ssr/ad.conf | wc -l") + else + oldcount=0 + end + + if tonumber(icount) ~= tonumber(oldcount) then + luci.sys.exec("cp -f /tmp/ad.conf /etc/dnsmasq.ssr/ad.conf") + retstring=tostring(math.ceil(tonumber(icount))) + if oldcount==0 then + luci.sys.call("/etc/init.d/dnsmasq restart") + end + else + retstring ="0" + end + else + retstring ="-1" + end + luci.sys.exec("rm -f /tmp/ad.conf ") + else + retstring ="-1" + end +end +luci.http.prepare_content("application/json") +luci.http.write_json({ ret=retstring ,retcount=icount}) +end + + +function check_port() +local set="" +local retstring="

" +local s +local server_name = "" +local shadowsocksr = "shadowsocksr" +local uci = luci.model.uci.cursor() +local iret=1 + +uci:foreach(shadowsocksr, "servers", function(s) + + if s.alias then + server_name=s.alias + elseif s.server and s.server_port then + server_name= "%s:%s" %{s.server, s.server_port} + end + iret=luci.sys.call(" ipset add ss_spec_wan_ac " .. s.server .. " 2>/dev/null") + socket = nixio.socket("inet", "stream") + socket:setopt("socket", "rcvtimeo", 3) + socket:setopt("socket", "sndtimeo", 3) + ret=socket:connect(s.server,s.server_port) + if tostring(ret) == "true" then + socket:close() + retstring =retstring .. "[" .. server_name .. "] OK.
" + else + retstring =retstring .. "[" .. server_name .. "] Error.
" + end + if iret== 0 then + luci.sys.call(" ipset del ss_spec_wan_ac " .. s.server) + end +end) + +luci.http.prepare_content("application/json") +luci.http.write_json({ ret=retstring }) +end diff --git a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua new file mode 100644 index 0000000000..5c76574240 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua @@ -0,0 +1,59 @@ +local shadowsocksr = "shadowsocksr" +local uci = luci.model.uci.cursor() +local server_table = {} + +uci:foreach(shadowsocksr, "servers", function(s) + if s.alias then + server_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias} + elseif s.server and s.server_port then + server_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port} + end +end) + +local key_table = {} +for key,_ in pairs(server_table) do + table.insert(key_table,key) +end + +table.sort(key_table) + +m = Map(shadowsocksr) + +s = m:section(TypedSection, "global", translate("Server failsafe auto swith settings")) +s.anonymous = true + +o = s:option(Flag, "monitor_enable", translate("Enable Process Deamon")) +o.rmempty = false + +o = s:option(Flag, "enable_switch", translate("Enable Auto Switch")) +o.rmempty = false + +o = s:option(Value, "switch_time", translate("Switch check cycly(second)")) +o.datatype = "uinteger" +o:depends("enable_switch", "1") +o.default = 3600 + +o = s:option(Value, "switch_timeout", translate("Check timout(second)")) +o.datatype = "uinteger" +o:depends("enable_switch", "1") +o.default = 5 + +-- [[ SOCKS5 Proxy ]]-- +if nixio.fs.access("/usr/bin/ssr-local") then +s = m:section(TypedSection, "socks5_proxy", translate("SOCKS5 Proxy")) +s.anonymous = true + +o = s:option(ListValue, "server", translate("Server")) +o:value("nil", translate("Disable")) +for _,key in pairs(key_table) do o:value(key,server_table[key]) end +o.default = "nil" +o.rmempty = false + +o = s:option(Value, "local_port", translate("Local Port")) +o.datatype = "port" +o.default = 1080 +o.rmempty = false + +end + +return m diff --git a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua new file mode 100644 index 0000000000..5b7dc7fe32 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua @@ -0,0 +1,403 @@ +-- Copyright (C) 2017 yushi studio github.com/ywb94 +-- Licensed to the public under the GNU General Public License v3. + +local m, s, o,kcp_enable +local shadowsocksr = "shadowsocksr" +local uci = luci.model.uci.cursor() +local fs = require "nixio.fs" +local sys = require "luci.sys" +local sid = arg[1] +local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid") + +local function isKcptun(file) + if not fs.access(file, "rwx", "rx", "rx") then + fs.chmod(file, 755) + end + + local str = sys.exec(file .. " -v | awk '{printf $1}'") + return (str:lower() == "kcptun") +end + + +local server_table = {} +local encrypt_methods = { + "none", + "table", + "rc4", + "rc4-md5-6", + "rc4-md5", + "aes-128-cfb", + "aes-192-cfb", + "aes-256-cfb", + "aes-128-ctr", + "aes-192-ctr", + "aes-256-ctr", + "bf-cfb", + "camellia-128-cfb", + "camellia-192-cfb", + "camellia-256-cfb", + "cast5-cfb", + "des-cfb", + "idea-cfb", + "rc2-cfb", + "seed-cfb", + "salsa20", + "chacha20", + "chacha20-ietf", +} + +local encrypt_methods_ss = { + -- aead + "aes-128-gcm", + "aes-192-gcm", + "aes-256-gcm", + "chacha20-ietf-poly1305", + "xchacha20-ietf-poly1305", + -- stream + "table", + "rc4", + "rc4-md5", + "aes-128-cfb", + "aes-192-cfb", + "aes-256-cfb", + "aes-128-ctr", + "aes-192-ctr", + "aes-256-ctr", + "bf-cfb", + "camellia-128-cfb", + "camellia-192-cfb", + "camellia-256-cfb", + "salsa20", + "chacha20", + "chacha20-ietf", +} + +local protocol = { + "origin", + "verify_deflate", + "auth_sha1_v4", + "auth_aes128_sha1", + "auth_aes128_md5", + "auth_chain_a", + "auth_chain_b", + "auth_chain_c", + "auth_chain_d", + "auth_chain_e", + "auth_chain_f", +} + +obfs = { + "plain", + "http_simple", + "http_post", + "random_head", + "tls1.2_ticket_auth", +} + +local securitys = { + "auto", + "none", + "aes-128-gcm", + "chacha20-poly1305" +} + + +m = Map(shadowsocksr, translate("Edit ShadowSocksR Server")) +m.redirect = luci.dispatcher.build_url("admin/services/shadowsocksr/servers") +if m.uci:get(shadowsocksr, sid) ~= "servers" then + luci.http.redirect(m.redirect) + return +end + +-- [[ Servers Setting ]]-- +s = m:section(NamedSection, sid, "servers") +s.anonymous = true +s.addremove = false + +o = s:option(DummyValue,"ssr_url","SS/SSR/V2RAY URL") +o.rawhtml = true +o.template = "shadowsocksr/ssrurl" +o.value =sid + +o = s:option(ListValue, "type", translate("Server Node Type")) +o:value("ssr", translate("ShadowsocksR")) +if nixio.fs.access("/usr/bin/ss-redir") then +o:value("ss", translate("Shadowsocks New Version")) +end +if nixio.fs.access("/usr/bin/v2ray/v2ray") then +o:value("v2ray", translate("V2Ray")) +end +o.description = translate("Using incorrect encryption mothod may causes service fail to start") + +o = s:option(Value, "alias", translate("Alias(optional)")) + +o = s:option(Value, "server", translate("Server Address")) +o.datatype = "host" +o.rmempty = false + +o = s:option(Value, "server_port", translate("Server Port")) +o.datatype = "port" +o.rmempty = false + +-- o = s:option(Value, "timeout", translate("Connection Timeout")) +-- o.datatype = "uinteger" +-- o.default = 60 +-- o.rmempty = false + +o = s:option(Value, "password", translate("Password")) +o.password = true +o.rmempty = true +o:depends("type", "ssr") +o:depends("type", "ss") + +o = s:option(ListValue, "encrypt_method", translate("Encrypt Method")) +for _, v in ipairs(encrypt_methods) do o:value(v) end +o.rmempty = true +o:depends("type", "ssr") + +o = s:option(ListValue, "encrypt_method_ss", translate("Encrypt Method")) +for _, v in ipairs(encrypt_methods_ss) do o:value(v) end +o.rmempty = true +o:depends("type", "ss") + +o = s:option(ListValue, "protocol", translate("Protocol")) +for _, v in ipairs(protocol) do o:value(v) end +o.rmempty = true +o:depends("type", "ssr") + +o = s:option(Value, "protocol_param", translate("Protocol param(optional)")) +o:depends("type", "ssr") + +o = s:option(ListValue, "obfs", translate("Obfs")) +for _, v in ipairs(obfs) do o:value(v) end +o.rmempty = true +o:depends("type", "ssr") + +o = s:option(Value, "obfs_param", translate("Obfs param(optional)")) +o:depends("type", "ssr") + +-- AlterId +o = s:option(Value, "alter_id", translate("AlterId")) +o.datatype = "port" +o.default = 16 +o.rmempty = true +o:depends("type", "v2ray") + +-- VmessId +o = s:option(Value, "vmess_id", translate("VmessId (UUID)")) +o.rmempty = true +o.default = uuid +o:depends("type", "v2ray") + +-- 加密方式 +o = s:option(ListValue, "security", translate("Encrypt Method")) +for _, v in ipairs(securitys) do o:value(v, v:upper()) end +o.rmempty = true +o:depends("type", "v2ray") + +-- 传输协议 +o = s:option(ListValue, "transport", translate("Transport")) +o:value("tcp", "TCP") +o:value("kcp", "mKCP") +o:value("ws", "WebSocket") +o:value("h2", "HTTP/2") +o:value("quic", "QUIC") +o.rmempty = true +o:depends("type", "v2ray") + +-- [[ TCP部分 ]]-- + +-- TCP伪装 +o = s:option(ListValue, "tcp_guise", translate("Camouflage Type")) +o:depends("transport", "tcp") +o:value("http", "HTTP") +o:value("none", translate("None")) +o.rmempty = true + +-- HTTP域名 +o = s:option(Value, "http_host", translate("HTTP Host")) +o:depends("tcp_guise", "http") +o.rmempty = true + +-- HTTP路径 +o = s:option(Value, "http_path", translate("HTTP Path")) +o:depends("tcp_guise", "http") +o.rmempty = true + +-- [[ WS部分 ]]-- + +-- WS域名 +o = s:option(Value, "ws_host", translate("WebSocket Host")) +o:depends("transport", "ws") +o.rmempty = true + +-- WS路径 +o = s:option(Value, "ws_path", translate("WebSocket Path")) +o:depends("transport", "ws") +o.rmempty = true + +-- [[ H2部分 ]]-- + +-- H2域名 +o = s:option(Value, "h2_host", translate("HTTP/2 Host")) +o:depends("transport", "h2") +o.rmempty = true + +-- H2路径 +o = s:option(Value, "h2_path", translate("HTTP/2 Path")) +o:depends("transport", "h2") +o.rmempty = true + +-- [[ QUIC部分 ]]-- + +o = s:option(ListValue, "quic_security", translate("QUIC Security")) +o:depends("transport", "quic") +o.rmempty = true +o:value("none", translate("None")) +o:value("aes-128-gcm", translate("aes-128-gcm")) +o:value("chacha20-poly1305", translate("chacha20-poly1305")) + +o = s:option(Value, "quic_key", translate("QUIC Key")) +o:depends("transport", "quic") +o.rmempty = true + +o = s:option(ListValue, "quic_guise", translate("Header")) +o:depends("transport", "quic") +o.rmempty = true +o:value("none", translate("None")) +o:value("srtp", translate("VideoCall (SRTP)")) +o:value("utp", translate("BitTorrent (uTP)")) +o:value("wechat-video", translate("WechatVideo")) +o:value("dtls", "DTLS 1.2") +o:value("wireguard", "WireGuard") + +-- [[ mKCP部分 ]]-- + +o = s:option(ListValue, "kcp_guise", translate("Camouflage Type")) +o:depends("transport", "kcp") +o:value("none", translate("None")) +o:value("srtp", translate("VideoCall (SRTP)")) +o:value("utp", translate("BitTorrent (uTP)")) +o:value("wechat-video", translate("WechatVideo")) +o:value("dtls", "DTLS 1.2") +o:value("wireguard", "WireGuard") +o.rmempty = true + +o = s:option(Value, "mtu", translate("MTU")) +o.datatype = "uinteger" +o:depends("transport", "kcp") +o.default = 1350 +o.rmempty = true + +o = s:option(Value, "tti", translate("TTI")) +o.datatype = "uinteger" +o:depends("transport", "kcp") +o.default = 50 +o.rmempty = true + +o = s:option(Value, "uplink_capacity", translate("Uplink Capacity")) +o.datatype = "uinteger" +o:depends("transport", "kcp") +o.default = 5 +o.rmempty = true + +o = s:option(Value, "downlink_capacity", translate("Downlink Capacity")) +o.datatype = "uinteger" +o:depends("transport", "kcp") +o.default = 20 +o.rmempty = true + +o = s:option(Value, "read_buffer_size", translate("Read Buffer Size")) +o.datatype = "uinteger" +o:depends("transport", "kcp") +o.default = 2 +o.rmempty = true + +o = s:option(Value, "write_buffer_size", translate("Write Buffer Size")) +o.datatype = "uinteger" +o:depends("transport", "kcp") +o.default = 2 +o.rmempty = true + +o = s:option(Flag, "congestion", translate("Congestion")) +o:depends("transport", "kcp") +o.rmempty = true + +-- [[ allowInsecure ]]-- +o = s:option(Flag, "insecure", translate("allowInsecure")) +o.rmempty = true +o:depends("type", "v2ray") + +-- [[ TLS ]]-- +o = s:option(Flag, "tls", translate("TLS")) +o.rmempty = true +o.default = "0" +o:depends("type", "v2ray") + +-- [[ Mux ]]-- +o = s:option(Flag, "mux", translate("Mux")) +o.rmempty = true +o.default = "0" +o:depends("type", "v2ray") + +o = s:option(Value, "concurrency", translate("Concurrency")) +o.datatype = "uinteger" +o.rmempty = true +o.default = "8" +o:depends("mux", "1") + +o = s:option(Flag, "fast_open", translate("TCP Fast Open")) +o.rmempty = true +o.default = "0" +o:depends("type", "ssr") +o:depends("type", "ss") + +o = s:option(Flag, "switch_enable", translate("Enable Auto Switch")) +o.rmempty = false +o.default = "1" + +o = s:option(Value, "local_port", translate("Local Port")) +o.datatype = "port" +o.default = 1234 +o.rmempty = false + +if nixio.fs.access("/usr/bin/kcptun-client") then + +kcp_enable = s:option(Flag, "kcp_enable", translate("KcpTun Enable"), translate("bin:/usr/bin/kcptun-client")) +kcp_enable.rmempty = true +kcp_enable.default = "0" +kcp_enable:depends("type", "ssr") +kcp_enable:depends("type", "ss") + +o = s:option(Value, "kcp_port", translate("KcpTun Port")) +o.datatype = "port" +o.default = 4000 +function o.validate(self, value, section) + local kcp_file="/usr/bin/kcptun-client" + local enable = kcp_enable:formvalue(section) or kcp_enable.disabled + if enable == kcp_enable.enabled then + if not fs.access(kcp_file) then + return nil, translate("Haven't a Kcptun executable file") + elseif not isKcptun(kcp_file) then + return nil, translate("Not a Kcptun executable file") + end + end + + return value +end +o:depends("type", "ssr") +o:depends("type", "ss") + +o = s:option(Value, "kcp_password", translate("KcpTun Password")) +o.password = true +o:depends("type", "ssr") +o:depends("type", "ss") + +o = s:option(Value, "kcp_param", translate("KcpTun Param")) +o.default = "--nocomp" +o:depends("type", "ssr") +o:depends("type", "ss") + +end + +return m diff --git a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua new file mode 100644 index 0000000000..28d803cad6 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua @@ -0,0 +1,89 @@ +-- Copyright (C) 2017 yushi studio github.com/ywb94 +-- Copyright (C) 2018 lean github.com/coolsnowwolf +-- Licensed to the public under the GNU General Public License v3. + +local m, s, sec, o, kcp_enable +local shadowsocksr = "shadowsocksr" +local uci = luci.model.uci.cursor() + +local sys = require "luci.sys" + +m = Map(shadowsocksr, translate("ShadowSocksR Plus+ Settings")) + +m:section(SimpleSection).template = "shadowsocksr/status" + +local server_table = {} +uci:foreach(shadowsocksr, "servers", function(s) + if s.alias then + server_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias} + elseif s.server and s.server_port then + server_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port} + end +end) + +local key_table = {} +for key,_ in pairs(server_table) do + table.insert(key_table,key) +end + +table.sort(key_table) + +-- [[ Global Setting ]]-- +s = m:section(TypedSection, "global") +s.anonymous = true + +o = s:option(ListValue, "global_server", translate("Main Server")) +o:value("nil", translate("Disable")) +for _,key in pairs(key_table) do o:value(key,server_table[key]) end +o.default = "nil" +o.rmempty = false + +o = s:option(ListValue, "udp_relay_server", translate("Game Mode UDP Server")) +o:value("", translate("Disable")) +o:value("same", translate("Same as Global Server")) +for _,key in pairs(key_table) do o:value(key,server_table[key]) end + +o = s:option(ListValue, "threads", translate("Multi Threads Option")) +o:value("0", translate("Auto Threads")) +o:value("1", translate("1 Thread")) +o:value("2", translate("2 Threads")) +o:value("4", translate("4 Threads")) +o:value("8", translate("8 Threads")) +o.default = "0" +o.rmempty = false + +o = s:option(ListValue, "run_mode", translate("Running Mode")) +o:value("gfw", translate("GFW List Mode")) +o:value("router", translate("IP Route Mode")) +o:value("all", translate("Global Mode")) +o:value("oversea", translate("Oversea Mode")) +o.default = gfw + +o = s:option(ListValue, "dports", translate("Proxy Ports")) +o:value("1", translate("All Ports")) +o:value("2", translate("Only Common Ports")) +o.default = 1 + +o = s:option(ListValue, "pdnsd_enable", translate("Resolve Dns Mode")) +o:value("1", translate("Use Pdnsd tcp query and cache")) +o:value("0", translate("Use Local DNS Service listen port 5335")) +o:value("2", translate("Use system DNS")) +o.default = 1 + +o = s:option(ListValue, "tunnel_forward", translate("Anti-pollution DNS Server")) +o:value("8.8.4.4:53", translate("Google Public DNS (8.8.4.4)")) +o:value("8.8.8.8:53", translate("Google Public DNS (8.8.8.8)")) +o:value("208.67.222.222:53", translate("OpenDNS (208.67.222.222)")) +o:value("208.67.220.220:53", translate("OpenDNS (208.67.220.220)")) +o:value("209.244.0.3:53", translate("Level 3 Public DNS (209.244.0.3)")) +o:value("209.244.0.4:53", translate("Level 3 Public DNS (209.244.0.4)")) +o:value("4.2.2.1:53", translate("Level 3 Public DNS (4.2.2.1)")) +o:value("4.2.2.2:53", translate("Level 3 Public DNS (4.2.2.2)")) +o:value("4.2.2.3:53", translate("Level 3 Public DNS (4.2.2.3)")) +o:value("4.2.2.4:53", translate("Level 3 Public DNS (4.2.2.4)")) +o:value("1.1.1.1:53", translate("Cloudflare DNS (1.1.1.1)")) +o:value("114.114.114.114:53", translate("Oversea Mode DNS-1 (114.114.114.114)")) +o:value("114.114.115.115:53", translate("Oversea Mode DNS-2 (114.114.115.115)")) +o:depends("pdnsd_enable", "1") + +return m diff --git a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua new file mode 100644 index 0000000000..3cd320ef33 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua @@ -0,0 +1,88 @@ +local m, s, o +local NXFS = require "nixio.fs" + +m = Map("shadowsocksr", translate("IP black-and-white list")) + +s = m:section(TypedSection, "access_control") +s.anonymous = true + +-- Part of WAN +s:tab("wan_ac", translate("WAN IP AC")) + +o = s:taboption("wan_ac", DynamicList, "wan_bp_ips", translate("WAN White List IP")) +o.datatype = "ip4addr" + +o = s:taboption("wan_ac", DynamicList, "wan_fw_ips", translate("WAN Force Proxy IP")) +o.datatype = "ip4addr" + +-- Part of LAN +s:tab("lan_ac", translate("LAN IP AC")) + +o = s:taboption("lan_ac", DynamicList, "lan_ac_ips", translate("LAN Bypassed Host List")) +o.datatype = "ipaddr" +luci.ip.neighbors({ family = 4 }, function(entry) + if entry.reachable then + o:value(entry.dest:string()) + end +end) + +o = s:taboption("lan_ac", DynamicList, "lan_fp_ips", translate("LAN Force Proxy Host List")) +o.datatype = "ipaddr" +luci.ip.neighbors({ family = 4 }, function(entry) + if entry.reachable then + o:value(entry.dest:string()) + end +end) + +o = s:taboption("lan_ac", DynamicList, "lan_gm_ips", translate("Game Mode Host List")) +o.datatype = "ipaddr" +luci.ip.neighbors({ family = 4 }, function(entry) + if entry.reachable then + o:value(entry.dest:string()) + end +end) + +-- Part of Self +-- s:tab("self_ac", translate("Router Self AC")) +-- o = s:taboption("self_ac",ListValue, "router_proxy", translate("Router Self Proxy")) +-- o:value("1", translatef("Normal Proxy")) +-- o:value("0", translatef("Bypassed Proxy")) +-- o:value("2", translatef("Forwarded Proxy")) +-- o.rmempty = false + +s:tab("esc", translate("Bypass Domain List")) + +local escconf = "/etc/config/white.list" +o = s:taboption("esc", TextValue, "escconf") +o.rows = 13 +o.wrap = "off" +o.rmempty = true +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")) +end +o.remove = function(self, section, value) + NXFS.writefile(escconf, "") +end + + +s:tab("block", translate("Black Domain List")) + +local blockconf = "/etc/config/black.list" +o = s:taboption("block", TextValue, "blockconf") +o.rows = 13 +o.wrap = "off" +o.rmempty = true +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")) +end +o.remove = function(self, section, value) + NXFS.writefile(blockconf, "") +end + +return m \ No newline at end of file diff --git a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/list.lua b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/list.lua new file mode 100644 index 0000000000..f0625b6048 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/list.lua @@ -0,0 +1,23 @@ +local fs = require "nixio.fs" +local conffile = "/etc/config/gfw.list" + +f = SimpleForm("custom", translate("GFW Custom List"), translate("Please refer to the following writing")) + +t = f:field(TextValue, "conf") +t.rmempty = true +t.rows = 13 +function t.cfgvalue() + return fs.readfile(conffile) or "" +end + +function f.handle(self, state, data) + if state == FORM_VALID then + if data.conf then + fs.writefile(conffile, data.conf:gsub("\r\n", "\n")) + luci.sys.call("/usr/share/shadowsocksr/gfw2ipset.sh && /etc/init.d/dnsmasq restart") + end + end + return true +end + +return f \ No newline at end of file diff --git a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua new file mode 100644 index 0000000000..05b4162fc4 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua @@ -0,0 +1,15 @@ +local fs = require "nixio.fs" +local conffile = "/tmp/ssrpro.log" + +f = SimpleForm("logview") + +t = f:field(TextValue, "conf") +t.rmempty = true +t.rows = 20 +function t.cfgvalue() + luci.sys.exec("[ -f /tmp/ssrplus.log ] && sed '1!G;h;$!d' /tmp/ssrplus.log > /tmp/ssrpro.log") + return fs.readfile(conffile) or "" +end +t.readonly="readonly" + +return f \ No newline at end of file diff --git a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua new file mode 100644 index 0000000000..76ec0f0ac0 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua @@ -0,0 +1,95 @@ +-- Copyright (C) 2017 yushi studio +-- Licensed to the public under the GNU General Public License v3. + +local m, s, o +local shadowsocksr = "shadowsocksr" +local sid = arg[1] + +local encrypt_methods = { + "rc4-md5", + "rc4-md5-6", + "rc4", + "table", + "aes-128-cfb", + "aes-192-cfb", + "aes-256-cfb", + "aes-128-ctr", + "aes-192-ctr", + "aes-256-ctr", + "bf-cfb", + "camellia-128-cfb", + "camellia-192-cfb", + "camellia-256-cfb", + "cast5-cfb", + "des-cfb", + "idea-cfb", + "rc2-cfb", + "seed-cfb", + "salsa20", + "chacha20", + "chacha20-ietf", +} + +local protocol = { + "origin", +} + +obfs = { + "plain", + "http_simple", + "http_post", +} + +m = Map(shadowsocksr, translate("Edit ShadowSocksR Server")) + +m.redirect = luci.dispatcher.build_url("admin/services/shadowsocksr/server") +if m.uci:get(shadowsocksr, sid) ~= "server_config" then + luci.http.redirect(m.redirect) + return +end + + + + +-- [[ Server Setting ]]-- +s = m:section(NamedSection, sid, "server_config") +s.anonymous = true +s.addremove = false + +o = s:option(Flag, "enable", translate("Enable")) +o.default = 1 +o.rmempty = false + +o = s:option(Value, "server_port", translate("Server Port")) +o.datatype = "port" +o.default = 8388 +o.rmempty = false + +o = s:option(Value, "timeout", translate("Connection Timeout")) +o.datatype = "uinteger" +o.default = 60 +o.rmempty = false + +o = s:option(Value, "password", translate("Password")) +o.password = true +o.rmempty = false + +o = s:option(ListValue, "encrypt_method", translate("Encrypt Method")) +for _, v in ipairs(encrypt_methods) do o:value(v) end +o.rmempty = false + +o = s:option(ListValue, "protocol", translate("Protocol")) +for _, v in ipairs(protocol) do o:value(v) end +o.rmempty = false + + +o = s:option(ListValue, "obfs", translate("Obfs")) +for _, v in ipairs(obfs) do o:value(v) end +o.rmempty = false + +o = s:option(Value, "obfs_param", translate("Obfs param(optional)")) + +o = s:option(Flag, "fast_open", translate("TCP Fast Open")) +o.rmempty = false + +return m diff --git a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua new file mode 100644 index 0000000000..fcec57bc33 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua @@ -0,0 +1,114 @@ +-- Copyright (C) 2017 yushi studio +-- Licensed to the public under the GNU General Public License v3. + +local m, sec, o +local shadowsocksr = "shadowsocksr" +local uci = luci.model.uci.cursor() +local ipkg = require("luci.model.ipkg") + + +m = Map(shadowsocksr, translate("ShadowSocksR Server")) + +local encrypt_methods = { + "table", + "rc4", + "rc4-md5", + "rc4-md5-6", + "aes-128-cfb", + "aes-192-cfb", + "aes-256-cfb", + "aes-128-ctr", + "aes-192-ctr", + "aes-256-ctr", + "bf-cfb", + "camellia-128-cfb", + "camellia-192-cfb", + "camellia-256-cfb", + "cast5-cfb", + "des-cfb", + "idea-cfb", + "rc2-cfb", + "seed-cfb", + "salsa20", + "chacha20", + "chacha20-ietf", +} + +local protocol = { + "origin", + "verify_deflate", + "auth_sha1_v4", + "auth_aes128_sha1", + "auth_aes128_md5", + "auth_chain_a", +} + +obfs = { + "plain", + "http_simple", + "http_post", + "random_head", + "tls1.2_ticket_auth", + "tls1.2_ticket_fastauth", +} + + + + + +-- [[ Global Setting ]]-- +sec = m:section(TypedSection, "server_global", translate("Global Setting")) +sec.anonymous = true + + + +o = sec:option(Flag, "enable_server", translate("Enable Server")) +o.rmempty = false + +-- [[ Server Setting ]]-- +sec = m:section(TypedSection, "server_config", translate("Server Setting")) +sec.anonymous = true +sec.addremove = true +sec.template = "cbi/tblsection" +sec.extedit = luci.dispatcher.build_url("admin/services/shadowsocksr/server/%s") +function sec.create(...) + local sid = TypedSection.create(...) + if sid then + luci.http.redirect(sec.extedit % sid) + return + end +end + +o = sec:option(Flag, "enable", translate("Enable")) +function o.cfgvalue(...) + return Value.cfgvalue(...) or translate("0") +end +o.rmempty = false + +o = sec:option(DummyValue, "server_port", translate("Server Port")) +function o.cfgvalue(...) + return Value.cfgvalue(...) or "?" +end + + +o = sec:option(DummyValue, "encrypt_method", translate("Encrypt Method")) +function o.cfgvalue(...) + local v = Value.cfgvalue(...) + return v and v:upper() or "?" +end + +o = sec:option(DummyValue, "protocol", translate("Protocol")) +function o.cfgvalue(...) + return Value.cfgvalue(...) or "?" +end + + + +o = sec:option(DummyValue, "obfs", translate("Obfs")) +function o.cfgvalue(...) + return Value.cfgvalue(...) or "?" +end + + + +return m diff --git a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua new file mode 100644 index 0000000000..fa0c336fa2 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua @@ -0,0 +1,122 @@ +-- Licensed to the public under the GNU General Public License v3. + +local m, s, o +local shadowsocksr = "shadowsocksr" + +local uci = luci.model.uci.cursor() +local server_count = 0 +uci:foreach("shadowsocksr", "servers", function(s) + server_count = server_count + 1 +end) + +local fs = require "nixio.fs" +local sys = require "luci.sys" + +m = Map(shadowsocksr, translate("Servers subscription and manage")) + +-- Server Subscribe + +s = m:section(TypedSection, "server_subscribe") +s.anonymous = true + +o = s:option(Flag, "auto_update", translate("Auto Update")) +o.rmempty = false +o.description = translate("Auto Update Server subscription, GFW list and CHN route") + + +o = s:option(ListValue, "auto_update_time", translate("Update time (every day)")) +for t = 0,23 do +o:value(t, t..":00") +end +o.default=2 +o.rmempty = false + +o = s:option(DynamicList, "subscribe_url", translate("Subscribe URL")) +o.rmempty = true + +o = s:option(Button,"update_Sub",translate("Update Subscribe List")) +o.inputstyle = "reload" +o.description = translate("Update subscribe url list first") +o.write = function() + luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers")) +end + +o = s:option(Flag, "proxy", translate("Through proxy update")) +o.rmempty = false +o.description = translate("Through proxy update list, Not Recommended ") + +o = s:option(Button,"update",translate("Update All Subscribe Severs")) +o.inputstyle = "apply" +o.write = function() + luci.sys.exec("bash /usr/share/shadowsocksr/subscribe.sh >>/tmp/ssrplus.log 2>&1") + luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers")) +end + + +o = s:option(Button,"delete",translate("Delete all severs")) +o.inputstyle = "reset" +o.description = string.format(translate("Server Count") .. ": %d", server_count) +o.write = function() + uci:delete_all("shadowsocksr", "servers", function(s) return true end) + uci:save("shadowsocksr") + luci.sys.call("uci commit shadowsocksr && /etc/init.d/shadowsocksr stop") + luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers")) + return +end + +-- [[ Servers Manage ]]-- +s = m:section(TypedSection, "servers") +s.anonymous = true +s.addremove = true +s.sortable = false +s.template = "cbi/tblsection" +s.extedit = luci.dispatcher.build_url("admin/services/shadowsocksr/servers/%s") +function s.create(...) + local sid = TypedSection.create(...) + if sid then + luci.http.redirect(s.extedit % sid) + return + end +end + +o = s:option(DummyValue, "type", translate("Type")) +function o.cfgvalue(...) + return Value.cfgvalue(...) or translate("") +end + +o = s:option(DummyValue, "alias", translate("Alias")) +function o.cfgvalue(...) + return Value.cfgvalue(...) or translate("None") +end + +o = s:option(DummyValue, "server", translate("Server Address")) +function o.cfgvalue(...) + return Value.cfgvalue(...) or "?" +end + +o = s:option(DummyValue, "server_port", translate("Server Port")) +function o.cfgvalue(...) + return Value.cfgvalue(...) or "?" +end + +if nixio.fs.access("/usr/bin/kcptun-client") then + +o = s:option(DummyValue, "kcp_enable", translate("KcpTun")) +function o.cfgvalue(...) + return Value.cfgvalue(...) or "?" +end + +end + +o = s:option(DummyValue, "switch_enable", translate("Auto Switch")) +function o.cfgvalue(...) + return Value.cfgvalue(...) or "0" +end + +o = s:option(DummyValue,"server",translate("Ping Latency")) +o.template="shadowsocksr/ping" +o.width="10%" + +m:append(Template("shadowsocksr/server_list")) + +return m diff --git a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua new file mode 100644 index 0000000000..9163c742f0 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua @@ -0,0 +1,180 @@ +-- Copyright (C) 2017 yushi studio +-- Licensed to the public under the GNU General Public License v3. + +local IPK_Version="3.0.9" +local m, s, o +local redir_run=0 +local reudp_run=0 +local sock5_run=0 +local server_run=0 +local kcptun_run=0 +local tunnel_run=0 +local udp2raw_run=0 +local udpspeeder_run=0 +local gfw_count=0 +local ad_count=0 +local ip_count=0 +local gfwmode=0 + +if nixio.fs.access("/etc/dnsmasq.ssr/gfw_list.conf") then +gfwmode=1 +end + +local shadowsocksr = "shadowsocksr" +-- html constants +font_blue = [[]] +font_off = [[]] +bold_on = [[]] +bold_off = [[]] + +local fs = require "nixio.fs" +local sys = require "luci.sys" +local kcptun_version=translate("Unknown") +local kcp_file="/usr/bin/kcptun-client" +if not fs.access(kcp_file) then + kcptun_version=translate("Not exist") +else + if not fs.access(kcp_file, "rwx", "rx", "rx") then + fs.chmod(kcp_file, 755) + end + kcptun_version=sys.exec(kcp_file .. " -v | awk '{printf $3}'") + if not kcptun_version or kcptun_version == "" then + kcptun_version = translate("Unknown") + end + +end + +if gfwmode==1 then + gfw_count = tonumber(sys.exec("cat /etc/dnsmasq.ssr/gfw_list.conf | wc -l"))/2 + if nixio.fs.access("/etc/dnsmasq.ssr/ad.conf") then + ad_count=tonumber(sys.exec("cat /etc/dnsmasq.ssr/ad.conf | wc -l")) + end +end + +if nixio.fs.access("/etc/china_ssr.txt") then + ip_count = sys.exec("cat /etc/china_ssr.txt | wc -l") +end + +local icount=sys.exec("busybox ps -w | grep ssr-reudp |grep -v grep| wc -l") +if tonumber(icount)>0 then +reudp_run=1 +else +icount=sys.exec("busybox ps -w | grep ssr-retcp |grep \"\\-u\"|grep -v grep| wc -l") +if tonumber(icount)>0 then +reudp_run=1 +end +end + + +if luci.sys.call("busybox ps -w | grep ssr-retcp | grep -v grep >/dev/null") == 0 then +redir_run=1 +end + +if luci.sys.call("pidof ssr-local >/dev/null") == 0 then +sock5_run=1 +end + +if luci.sys.call("pidof kcptun-client >/dev/null") == 0 then +kcptun_run=1 +end + +if luci.sys.call("pidof ssr-server >/dev/null") == 0 then +server_run=1 +end + +if luci.sys.call("busybox ps -w | grep ssr-tunnel |grep -v grep >/dev/null") == 0 then +tunnel_run=1 +end + +if luci.sys.call("pidof pdnsd >/dev/null") == 0 then +pdnsd_run=1 +end + +m = SimpleForm("Version") +m.reset = false +m.submit = false + +s=m:field(DummyValue,"redir_run",translate("Global Client")) +s.rawhtml = true +if redir_run == 1 then +s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off +else +s.value = translate("Not Running") +end + +s=m:field(DummyValue,"reudp_run",translate("Game Mode UDP Relay")) +s.rawhtml = true +if reudp_run == 1 then +s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off +else +s.value = translate("Not Running") +end + +s=m:field(DummyValue,"pdnsd_run",translate("PDNSD")) +s.rawhtml = true +if pdnsd_run == 1 then +s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off +else +s.value = translate("Not Running") +end + +if nixio.fs.access("/usr/bin/ssr-local") then +s=m:field(DummyValue,"sock5_run",translate("SOCKS5 Proxy")) +s.rawhtml = true +if sock5_run == 1 then +s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off +else +s.value = translate("Not Running") +end +end + +if nixio.fs.access("/usr/bin/ssr-server") then +s=m:field(DummyValue,"server_run",translate("Global SSR Server")) +s.rawhtml = true +if server_run == 1 then +s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off +else +s.value = translate("Not Running") +end +end + +if nixio.fs.access("/usr/bin/kcptun-client") then +s=m:field(DummyValue,"kcp_version",translate("KcpTun Version")) +s.rawhtml = true +s.value =kcptun_version + +s=m:field(DummyValue,"kcptun_run",translate("KcpTun")) +s.rawhtml = true +if kcptun_run == 1 then +s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off +else +s.value = translate("Not Running") +end +end + +s=m:field(DummyValue,"google",translate("Google Connectivity")) +s.value = translate("No Check") +s.template = "shadowsocksr/check" + +s=m:field(DummyValue,"baidu",translate("Baidu Connectivity")) +s.value = translate("No Check") +s.template = "shadowsocksr/check" + +if gfwmode==1 then +s=m:field(DummyValue,"gfw_data",translate("GFW List Data")) +s.rawhtml = true +s.template = "shadowsocksr/refresh" +s.value =tostring(math.ceil(gfw_count)) .. " " .. translate("Records") + +end + +s=m:field(DummyValue,"ip_data",translate("China IP Data")) +s.rawhtml = true +s.template = "shadowsocksr/refresh" +s.value =ip_count .. " " .. translate("Records") + +s=m:field(DummyValue,"check_port",translate("Check Server Port")) +s.template = "shadowsocksr/checkport" +s.value =translate("No Check") + +return m diff --git a/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm new file mode 100644 index 0000000000..bd78926118 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm @@ -0,0 +1,38 @@ +<%+cbi/valueheader%> + + + + + +<%=self.value%> + +<%+cbi/valuefooter%> \ No newline at end of file diff --git a/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/checkport.htm b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/checkport.htm new file mode 100644 index 0000000000..ed91a2f22c --- /dev/null +++ b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/checkport.htm @@ -0,0 +1,36 @@ +<%+cbi/valueheader%> + + + +<%=self.value%> + + + +<%+cbi/valuefooter%> \ No newline at end of file diff --git a/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/ping.htm b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/ping.htm new file mode 100644 index 0000000000..8c86aee74a --- /dev/null +++ b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/ping.htm @@ -0,0 +1,3 @@ +<%+cbi/valueheader%> +-- ms +<%+cbi/valuefooter%> \ No newline at end of file diff --git a/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm new file mode 100644 index 0000000000..00da6cd6d9 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm @@ -0,0 +1,44 @@ +<%+cbi/valueheader%> + + + + + +<%=self.value%> + +<%+cbi/valuefooter%> \ No newline at end of file diff --git a/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm new file mode 100644 index 0000000000..9652837efa --- /dev/null +++ b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm @@ -0,0 +1,24 @@ +<%# + Copyright 2018-2019 Lienol + Licensed to the public under the Apache License 2.0. +-%> + +<% +local dsp = require "luci.dispatcher" +-%> + + \ No newline at end of file diff --git a/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm new file mode 100644 index 0000000000..639ef70271 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm @@ -0,0 +1,204 @@ +<%+cbi/valueheader%> + + + + + + +<%+cbi/valuefooter%> diff --git a/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/status.htm b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/status.htm new file mode 100644 index 0000000000..0dab4d5502 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/status.htm @@ -0,0 +1,22 @@ + + +
+

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

+
diff --git a/package/lean/luci-app-ssr-plus/po/zh-cn/ssr-plus.po b/package/lean/luci-app-ssr-plus/po/zh-cn/ssr-plus.po new file mode 100644 index 0000000000..7f92a7f6dc --- /dev/null +++ b/package/lean/luci-app-ssr-plus/po/zh-cn/ssr-plus.po @@ -0,0 +1,531 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8\n" + +msgid "ShadowSocksR Client" +msgstr "ShadowSocksR 客户端" + +msgid "Enable" +msgstr "启用" + +msgid "Disable" +msgstr "停用" + +msgid "Log" +msgstr "日志" + +msgid "ShadowSocksR is running" +msgstr "ShadowSocksR 客户端运行中" + +msgid "ShadowSocksR is not running" +msgstr "ShadowSocksR 客户端未运行" + +msgid "Global Setting" +msgstr "全局设置" + +msgid "Global Server" +msgstr "全局服务器" + +msgid "ShadowSocksR SOCK5 Proxy is running" +msgstr "ShadowSocksR SOCK5代理运行中" + +msgid "UDP Relay Server" +msgstr "UDP中继服务器" + +msgid "Same as Global Server" +msgstr "与全局服务器相同" + +msgid "Servers Setting" +msgstr "服务器配置" + +msgid "Alias(optional)" +msgstr "别名(可选)" + +msgid "Onetime Authentication" +msgstr "一次验证" + +msgid "Server Address" +msgstr "服务器地址" + +msgid "Server Port" +msgstr "服务器端口" + +msgid "Local Port" +msgstr "本地端口" + +msgid "Connection Timeout" +msgstr "连接超时" + +msgid "Password" +msgstr "密码" + +msgid "Encrypt Method" +msgstr "加密方式" + +msgid "Protocol" +msgstr "传输协议" + +msgid "Protocol param(optional)" +msgstr "传输协议参数(可选)" + +msgid "Obfs" +msgstr "混淆插件" + +msgid "Obfs param(optional)" +msgstr "混淆参数(可选)" + +msgid "Enable Tunnel(DNS)" +msgstr "启用隧道(DNS)转发" + +msgid "Tunnel Port" +msgstr "隧道(DNS)本地端口" + +msgid "Forwarding Tunnel" +msgstr "隧道(DNS)转发地址" + +msgid "Access Control" +msgstr "访问控制" + +msgid "Interfaces - WAN" +msgstr "接口 - WAN" + +msgid "Bypassed IP List" +msgstr "被忽略IP列表" + +msgid "NULL - As Global Proxy" +msgstr "留空 - 作为全局代理" + +msgid "Bypassed IP" +msgstr "额外被忽略IP" + +msgid "Forwarded IP" +msgstr "强制走代理IP" + +msgid "Interfaces - LAN" +msgstr "接口 - LAN" + +msgid "LAN Access Control" +msgstr "内网访问控制" + +msgid "Allow listed only" +msgstr "仅允许列表内" + +msgid "Allow all except listed" +msgstr "仅允许列表外" + +msgid "LAN Host List" +msgstr "内网主机列表" + +msgid "SSR Client" +msgstr "客户端" + +msgid "SSR Server" +msgstr "服务端" + +msgid "ShadowSocksR Server" +msgstr "ShadowSocksR 服务端" + +msgid "ShadowSocksR Server is running" +msgstr "ShadowSocksR 服务端运行中" + +msgid "ShadowSocksR Server is not running" +msgstr "ShadowSocksR 服务端未运行" + +msgid "Enable Server" +msgstr "启动服务端" + +msgid "Server Setting" +msgstr "服务端配置" + +msgid "KcpTun Enable" +msgstr "KcpTun 启用" + +msgid "bin:/usr/bin/kcptun-client" +msgstr "二进制文件:/usr/bin/kcptun-client" + +msgid "KcpTun Port" +msgstr "KcpTun 端口" + +msgid "KcpTun Param" +msgstr "KcpTun 参数" + +msgid "KcpTun Password" +msgstr "KcpTun 密码" + +msgid "Haven't a Kcptun executable file" +msgstr "不存在Kcptun可执行文件,请下载Kcptun可执行文件并改名放入/usr/bin/kcptun-client" + +msgid "Not a Kcptun executable file" +msgstr "Kcptun可执行文件格式不正确,请确认是否正确下载了路由器对应的可执行文件" + +msgid "Enable Process Monitor" +msgstr "启用进程监控" + +msgid "Edit ShadowSocksR Server" +msgstr "编辑服务器配置" + +msgid "Alias" +msgstr "别名" + +msgid "SOCKS5 Proxy" +msgstr "SOCKS5代理" + +msgid "Server" +msgstr "服务器" + +msgid "TCP Fast Open" +msgstr "TCP快速打开" + +msgid "Status" +msgstr "状态" + +msgid "Unknown" +msgstr "未知" + +msgid "Running Status" +msgstr "运行状态" + +msgid "Global Client" +msgstr "TCP透明代理" + +msgid "Global SSR Server" +msgstr "SSR服务端" + +msgid "DNS Tunnel" +msgstr "DNS 隧道" + +msgid "IPK Version" +msgstr "IPK 版本号" + +msgid "KcpTun Version" +msgstr "KcpTun 版本号" + +msgid "Not exist" +msgstr "未安装可执行文件" + +msgid "IPK Installation Time" +msgstr "IPK 安装时间" + +msgid "Project" +msgstr "项目地址" + +msgid "Not Running" +msgstr "未运行" + +msgid "Running" +msgstr "运行中" + +msgid "Enable GFW mode" +msgstr "启用 GFW 模式" + +msgid "Running Mode" +msgstr "运行模式" + +msgid "IP Route Mode" +msgstr "绕过中国大陆IP模式" + +msgid "GFW List Mode" +msgstr "GFW列表模式" + +msgid "Global Mode" +msgstr "全局模式" + +msgid "Oversea Mode" +msgstr "海外用户回国模式" + +msgid "Router Proxy" +msgstr "路由器访问控制" + +msgid "Normal Proxy" +msgstr "正常代理" + +msgid "Bypassed Proxy" +msgstr "不走代理" + +msgid "Forwarded Proxy" +msgstr "强制走代理" + +msgid "UDP Relay" +msgstr "UDP中继" + +msgid "Google Connectivity" +msgstr "【谷歌】连通性检查" + +msgid "Baidu Connectivity" +msgstr "【百度】连通性检查" + +msgid "No Check" +msgstr "未检查" + +msgid "Check" +msgstr "检查" + +msgid "Connect OK" +msgstr "连接正常" + +msgid "Connect Error" +msgstr "连接错误" + +msgid "Check..." +msgstr "正在检查.." + +msgid "Proxy Check" +msgstr "代理检查" + + +msgid "GFW List Data" +msgstr "【GFW列表】数据库" + +msgid "China IP Data" +msgstr "【国内IP段】数据库" + +msgid "Records" +msgstr "条记录" + +msgid "Refresh Data" +msgstr "更新数据库" + +msgid "Refresh..." +msgstr "正在更新,请稍候.." + +msgid "Refresh OK!" +msgstr "更新成功!" + +msgid "Refresh Error!" +msgstr "更新失败!" + +msgid "No new data!" +msgstr "你已经是最新数据,无需更新!" + +msgid "Total Records:" +msgstr "新的总纪录数:" + +msgid "Check Server Port" +msgstr "【服务器端口】检查" + +msgid "Check Connect" +msgstr "检查连通性" + +msgid "Check Server" +msgstr "检查服务器" + +msgid "Auto Switch" +msgstr "自动切换" + +msgid "Enable Auto Switch" +msgstr "启用自动切换" + +msgid "Switch check cycly(second)" +msgstr "自动切换检查周期(秒)" + +msgid "Check timout(second)" +msgstr "切换检查超时时间(秒)" + +msgid "Enable Process Deamon" +msgstr "启用进程自动守护" + +msgid "Advertising Data" +msgstr "【广告屏蔽】数据库" + +msgid "DNS Server IP and Port" +msgstr "DNS服务器地址和端口" + +msgid "Resolve Dns Mode" +msgstr "DNS解析方式" + +msgid "Use SSR DNS Tunnel" +msgstr "使用SSR-DNS隧道" + +msgid "Use Pdnsd" +msgstr "使用Pdnsd" + +msgid "Use Other DNS Tunnel(Need to install)" +msgstr "使用其他DNS转发(需要自己安装)" + +msgid "Import SSR" +msgstr "导入ssr配置信息" + +msgid "Export SSR" +msgstr "导出ssr配置信息" + +msgid "Import SSR successfully." +msgstr "成功导入SSR。" + +msgid "Invalid SSR format." +msgstr "无效的SSR格式。" + +msgid "User cancelled." +msgstr "用户已取消。" + +msgid "Paste ssr url here" +msgstr "在此处粘贴ssr://网址" + +msgid "Unable to copy SSR to clipboard." +msgstr "无法复制SSR网址到剪贴板。" + +msgid "Copy SSR to clipboard successfully." +msgstr "成功复制SSR网址到剪贴板。" + +msgid "Servers Manage" +msgstr "服务器管理" + +msgid "Auto Update" +msgstr "自动更新" + +msgid "Through proxy update" +msgstr "通过代理更新" + +msgid "GFW List" +msgstr "GFW列表" + +msgid "ShadowSocksR Plus+ Settings" +msgstr "ShadowSocksR Plus+ 设置(支持SS/SSR/V2RAY)" + +msgid "Main Server" +msgstr "主服务器" + +msgid "Anti-pollution DNS Server" +msgstr "访问国外域名DNS服务器" + +msgid "Use Pdnsd tcp query and cache" +msgstr "使用PDNSD TCP查询并缓存" + +msgid "DNS Server IP:Port" +msgstr "DNS服务器 IP:Port" + +msgid "Update time (every day)" +msgstr "更新时间 (每天)" + +msgid "Auto Update Server subscription, GFW list and CHN route" +msgstr "自动更新服务器订阅、GFW列表和 CHN路由表" + +msgid "Subscribe URL" +msgstr "SS/SSR/V2RAY订阅URL地址" + +msgid "Update" +msgstr "更新" + +msgid "Server Count" +msgstr "服务器节点数量" + +msgid "IP black-and-white list" +msgstr "黑白名单" + +msgid "WAN IP AC" +msgstr "WAN IP访问控制" + +msgid "WAN White List IP" +msgstr "不走代理的WAN IP" + +msgid "WAN Force Proxy IP" +msgstr "强制走代理的WAN IP" + +msgid "LAN Bypassed Host List" +msgstr "不走代理的局域网LAN IP" + +msgid "LAN Force Proxy Host List" +msgstr "全局代理的LAN IP" + +msgid "Router Self AC" +msgstr "路由器自身代理设置" + +msgid "Router Self Proxy" +msgstr "路由器自身代理方式" + +msgid "Normal Proxy" +msgstr "跟随全局设置" + +msgid "Bypassed Proxy" +msgstr "不走代理" + +msgid "Forwarded Proxy" +msgstr "全局代理" + +msgid "GFW Custom List" +msgstr "GFW 用户自定义列表" + +msgid "Please refer to the following writing" +msgstr "每行一个域名,无需写前面的 HTTP(S):// ,提交后即时生效" + +msgid "Servers subscription and manage" +msgstr "服务器节点订阅与管理(支持订阅和手动导入SSR链接)" + +msgid "Through proxy update list, Not Recommended" +msgstr "通过路由器自身代理更新订阅" + +msgid "LAN IP AC" +msgstr "LAN IP访问控制" + +msgid "Game Mode UDP Server" +msgstr "游戏模式UDP中继服务器" + +msgid "Game Mode UDP Relay" +msgstr "游戏模式UDP中继" + +msgid "Server failsafe auto swith settings" +msgstr "服务器节点故障自动切换设置" + +msgid "Delete all severs" +msgstr "删除所有服务器节点" + +msgid "Severs Nodes" +msgstr "服务器节点" + +msgid "Use Local DNS Service listen port 5335" +msgstr "使用本机端口为5335的DNS服务" + +msgid "Use system DNS" +msgstr "使用系统DNS" + +msgid "Server Node Type" +msgstr "服务器节点类型" + +msgid "Using incorrect encryption mothod may causes service fail to start" +msgstr "输入不正确的参数组合可能会导致服务无法启动" + +msgid "Game Mode Host List" +msgstr "增强游戏模式客户端LAN IP" + +msgid "Multi Threads Option" +msgstr "多线程并发转发" + +msgid "Auto Threads" +msgstr "自动(CPU线程数)" + +msgid "1 Thread" +msgstr "单线程" + +msgid "2 Threads" +msgstr "2 线程" + +msgid "4 Threads" +msgstr "4 线程" + +msgid "8 Threads" +msgstr "8 线程" + +msgid "Proxy Ports" +msgstr "需要代理的端口" + +msgid "All Ports" +msgstr "所有端口(默认)" + +msgid "Only Common Ports" +msgstr "仅常用端口(不走P2P流量到代理)" + +msgid "Ping Latency" +msgstr "Ping延迟" + +msgid "Bypass Domain List" +msgstr "域名白名单" + +msgid "Black Domain List" +msgstr "域名黑名单" + +msgid "Update Subscribe List" +msgstr "更新订阅URL列表" + +msgid "Update subscribe url list first" +msgstr "订阅服务器节点前,请先更新订阅URL列表" + +msgid "Update All Subscribe Severs" +msgstr "更新所有订阅服务器节点" diff --git a/package/lean/luci-app-ssr-plus/root/etc/china_ssr.txt b/package/lean/luci-app-ssr-plus/root/etc/china_ssr.txt new file mode 100644 index 0000000000..b182fc7615 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/etc/china_ssr.txt @@ -0,0 +1,8296 @@ +1.0.1.0/24 +1.0.2.0/23 +1.0.8.0/21 +1.0.32.0/19 +1.1.0.0/24 +1.1.2.0/23 +1.1.4.0/22 +1.1.8.0/24 +1.1.9.0/24 +1.1.10.0/23 +1.1.12.0/22 +1.1.16.0/20 +1.1.32.0/19 +1.2.0.0/23 +1.2.2.0/24 +1.2.4.0/24 +1.2.5.0/24 +1.2.6.0/23 +1.2.8.0/24 +1.2.9.0/24 +1.2.10.0/23 +1.2.12.0/22 +1.2.16.0/20 +1.2.32.0/19 +1.2.64.0/18 +1.3.0.0/16 +1.4.1.0/24 +1.4.2.0/23 +1.4.4.0/24 +1.4.5.0/24 +1.4.6.0/23 +1.4.8.0/21 +1.4.16.0/20 +1.4.32.0/19 +1.4.64.0/18 +1.8.0.0/16 +1.10.0.0/21 +1.10.8.0/23 +1.10.11.0/24 +1.10.12.0/22 +1.10.16.0/20 +1.10.32.0/19 +1.10.64.0/18 +1.12.0.0/14 +1.24.0.0/13 +1.45.0.0/16 +1.48.0.0/15 +1.50.0.0/16 +1.51.0.0/16 +1.56.0.0/13 +1.68.0.0/14 +1.80.0.0/13 +1.88.0.0/14 +1.92.0.0/15 +1.94.0.0/15 +1.116.0.0/15 +1.118.0.0/16 +1.119.0.0/17 +1.119.128.0/17 +1.180.0.0/14 +1.184.0.0/15 +1.188.0.0/14 +1.192.0.0/13 +1.202.0.0/15 +1.204.0.0/14 +14.0.0.0/21 +14.0.12.0/22 +14.1.0.0/22 +14.1.24.0/22 +14.1.96.0/22 +14.1.108.0/22 +14.16.0.0/12 +14.102.128.0/22 +14.102.156.0/22 +14.102.180.0/22 +14.103.0.0/16 +14.104.0.0/13 +14.112.0.0/12 +14.130.0.0/15 +14.134.0.0/15 +14.144.0.0/12 +14.192.60.0/22 +14.192.76.0/22 +14.196.0.0/15 +14.204.0.0/15 +14.208.0.0/12 +27.0.128.0/22 +27.0.132.0/22 +27.0.160.0/22 +27.0.164.0/22 +27.0.188.0/22 +27.0.204.0/22 +27.0.208.0/22 +27.0.212.0/22 +27.8.0.0/13 +27.16.0.0/12 +27.34.232.0/21 +27.36.0.0/14 +27.40.0.0/13 +27.50.40.0/21 +27.50.128.0/17 +27.54.72.0/21 +27.54.152.0/21 +27.54.192.0/18 +27.98.208.0/20 +27.98.224.0/19 +27.99.128.0/17 +27.103.0.0/16 +27.106.128.0/18 +27.106.204.0/22 +27.109.32.0/19 +27.109.124.0/22 +27.112.0.0/18 +27.112.80.0/20 +27.112.112.0/22 +27.112.116.0/22 +27.113.128.0/18 +27.115.0.0/17 +27.116.44.0/22 +27.121.72.0/21 +27.121.120.0/21 +27.123.232.0/22 +27.128.0.0/15 +27.131.220.0/22 +27.144.0.0/16 +27.148.0.0/14 +27.152.0.0/13 +27.184.0.0/13 +27.192.0.0/11 +27.224.0.0/14 +36.0.0.0/22 +36.0.8.0/21 +36.0.16.0/20 +36.0.32.0/19 +36.0.64.0/18 +36.0.128.0/17 +36.1.0.0/16 +36.4.0.0/14 +36.16.0.0/12 +36.32.0.0/14 +36.36.0.0/16 +36.37.0.0/19 +36.37.36.0/23 +36.37.39.0/24 +36.37.40.0/21 +36.37.48.0/20 +36.40.0.0/13 +36.48.0.0/15 +36.51.0.0/16 +36.56.0.0/13 +36.96.0.0/11 +36.128.0.0/10 +36.192.0.0/11 +36.248.0.0/14 +36.254.0.0/16 +36.255.116.0/22 +36.255.128.0/22 +36.255.164.0/22 +36.255.172.0/22 +36.255.176.0/22 +36.255.220.0/22 +39.0.0.0/24 +39.0.2.0/23 +39.0.4.0/22 +39.0.8.0/21 +39.0.16.0/20 +39.0.32.0/19 +39.0.64.0/18 +39.0.128.0/17 +39.64.0.0/11 +39.96.0.0/13 +39.104.0.0/14 +39.108.0.0/16 +39.128.0.0/10 +40.72.0.0/15 +40.125.128.0/17 +40.126.64.0/18 +42.0.0.0/22 +42.0.8.0/21 +42.0.16.0/21 +42.0.24.0/22 +42.0.32.0/19 +42.0.128.0/17 +42.1.0.0/19 +42.1.32.0/20 +42.1.48.0/21 +42.1.56.0/22 +42.1.128.0/17 +42.4.0.0/14 +42.48.0.0/15 +42.50.0.0/16 +42.51.0.0/16 +42.52.0.0/14 +42.56.0.0/14 +42.62.0.0/17 +42.62.128.0/19 +42.62.160.0/20 +42.62.180.0/22 +42.62.184.0/21 +42.63.0.0/16 +42.80.0.0/15 +42.83.64.0/20 +42.83.80.0/22 +42.83.88.0/21 +42.83.96.0/19 +42.83.128.0/17 +42.84.0.0/14 +42.88.0.0/13 +42.96.64.0/19 +42.96.96.0/21 +42.96.108.0/22 +42.96.112.0/20 +42.96.128.0/17 +42.97.0.0/16 +42.99.0.0/18 +42.99.64.0/19 +42.99.96.0/20 +42.99.112.0/22 +42.99.120.0/21 +42.100.0.0/14 +42.120.0.0/15 +42.122.0.0/16 +42.123.0.0/19 +42.123.36.0/22 +42.123.40.0/21 +42.123.48.0/20 +42.123.64.0/18 +42.123.128.0/17 +42.128.0.0/12 +42.156.0.0/19 +42.156.36.0/22 +42.156.40.0/21 +42.156.48.0/20 +42.156.64.0/18 +42.156.128.0/17 +42.157.0.0/16 +42.158.0.0/16 +42.159.0.0/16 +42.160.0.0/12 +42.176.0.0/13 +42.184.0.0/15 +42.186.0.0/16 +42.187.0.0/18 +42.187.64.0/19 +42.187.96.0/20 +42.187.112.0/21 +42.187.120.0/22 +42.187.128.0/17 +42.192.0.0/15 +42.194.0.0/21 +42.194.8.0/22 +42.194.12.0/22 +42.194.16.0/20 +42.194.32.0/19 +42.194.64.0/18 +42.194.128.0/17 +42.195.0.0/16 +42.196.0.0/14 +42.201.0.0/17 +42.202.0.0/15 +42.204.0.0/14 +42.208.0.0/12 +42.224.0.0/12 +42.240.0.0/17 +42.240.128.0/17 +42.242.0.0/15 +42.244.0.0/14 +42.248.0.0/13 +43.224.12.0/22 +43.224.24.0/22 +43.224.44.0/22 +43.224.52.0/22 +43.224.56.0/22 +43.224.64.0/22 +43.224.68.0/22 +43.224.72.0/22 +43.224.80.0/22 +43.224.100.0/22 +43.224.144.0/22 +43.224.160.0/22 +43.224.176.0/22 +43.224.184.0/22 +43.224.200.0/22 +43.224.204.0/22 +43.224.208.0/22 +43.224.212.0/22 +43.224.216.0/22 +43.224.240.0/22 +43.225.76.0/22 +43.225.84.0/22 +43.225.120.0/22 +43.225.124.0/22 +43.225.140.0/22 +43.225.172.0/22 +43.225.180.0/22 +43.225.208.0/22 +43.225.216.0/22 +43.225.220.0/22 +43.225.224.0/22 +43.225.228.0/22 +43.225.232.0/22 +43.225.236.0/22 +43.225.240.0/22 +43.225.244.0/22 +43.225.252.0/22 +43.226.32.0/22 +43.226.36.0/22 +43.226.40.0/22 +43.226.44.0/22 +43.226.48.0/22 +43.226.52.0/22 +43.226.56.0/22 +43.226.60.0/22 +43.226.64.0/22 +43.226.68.0/22 +43.226.72.0/22 +43.226.76.0/22 +43.226.80.0/22 +43.226.84.0/22 +43.226.88.0/22 +43.226.92.0/22 +43.226.96.0/22 +43.226.100.0/22 +43.226.104.0/22 +43.226.108.0/22 +43.226.112.0/22 +43.226.116.0/22 +43.226.120.0/22 +43.226.128.0/22 +43.226.132.0/22 +43.226.136.0/22 +43.226.140.0/22 +43.226.144.0/22 +43.226.148.0/22 +43.226.152.0/22 +43.226.156.0/22 +43.226.160.0/22 +43.226.164.0/22 +43.226.168.0/22 +43.226.172.0/22 +43.226.176.0/22 +43.226.180.0/22 +43.226.184.0/22 +43.226.188.0/22 +43.226.192.0/22 +43.226.196.0/22 +43.226.200.0/22 +43.226.204.0/22 +43.226.208.0/22 +43.226.212.0/22 +43.226.236.0/22 +43.226.240.0/22 +43.226.244.0/22 +43.226.248.0/22 +43.226.252.0/22 +43.227.0.0/22 +43.227.4.0/22 +43.227.8.0/22 +43.227.32.0/22 +43.227.36.0/22 +43.227.40.0/22 +43.227.44.0/22 +43.227.48.0/22 +43.227.52.0/22 +43.227.56.0/22 +43.227.60.0/22 +43.227.64.0/22 +43.227.68.0/22 +43.227.72.0/22 +43.227.76.0/22 +43.227.80.0/22 +43.227.84.0/22 +43.227.88.0/22 +43.227.92.0/22 +43.227.96.0/22 +43.227.100.0/22 +43.227.104.0/22 +43.227.136.0/22 +43.227.140.0/22 +43.227.144.0/22 +43.227.152.0/22 +43.227.156.0/22 +43.227.160.0/22 +43.227.164.0/22 +43.227.168.0/22 +43.227.172.0/22 +43.227.176.0/22 +43.227.180.0/22 +43.227.188.0/22 +43.227.192.0/22 +43.227.196.0/22 +43.227.200.0/22 +43.227.204.0/22 +43.227.208.0/22 +43.227.212.0/22 +43.227.216.0/22 +43.227.220.0/22 +43.227.232.0/22 +43.227.248.0/22 +43.227.252.0/22 +43.228.0.0/22 +43.228.4.0/22 +43.228.8.0/22 +43.228.12.0/22 +43.228.16.0/22 +43.228.20.0/22 +43.228.24.0/22 +43.228.28.0/22 +43.228.32.0/22 +43.228.36.0/22 +43.228.40.0/22 +43.228.44.0/22 +43.228.48.0/22 +43.228.52.0/22 +43.228.56.0/22 +43.228.60.0/22 +43.228.64.0/22 +43.228.68.0/22 +43.228.76.0/22 +43.228.100.0/22 +43.228.116.0/22 +43.228.120.0/22 +43.228.132.0/22 +43.228.136.0/22 +43.228.148.0/22 +43.228.152.0/22 +43.228.188.0/22 +43.229.16.0/22 +43.229.40.0/22 +43.229.48.0/22 +43.229.56.0/22 +43.229.96.0/22 +43.229.120.0/22 +43.229.136.0/22 +43.229.140.0/22 +43.229.144.0/22 +43.229.168.0/22 +43.229.172.0/22 +43.229.176.0/22 +43.229.180.0/22 +43.229.184.0/22 +43.229.188.0/22 +43.229.192.0/22 +43.229.196.0/22 +43.229.216.0/22 +43.229.220.0/22 +43.229.232.0/22 +43.229.236.0/22 +43.230.20.0/22 +43.230.32.0/22 +43.230.68.0/22 +43.230.72.0/22 +43.230.84.0/22 +43.230.124.0/22 +43.230.136.0/22 +43.230.168.0/22 +43.230.220.0/22 +43.230.224.0/22 +43.230.228.0/22 +43.230.232.0/22 +43.230.236.0/22 +43.230.240.0/22 +43.230.244.0/22 +43.230.248.0/22 +43.230.252.0/22 +43.231.32.0/22 +43.231.36.0/22 +43.231.40.0/22 +43.231.44.0/22 +43.231.80.0/22 +43.231.84.0/22 +43.231.88.0/22 +43.231.92.0/22 +43.231.96.0/22 +43.231.100.0/22 +43.231.104.0/22 +43.231.108.0/22 +43.231.136.0/22 +43.231.140.0/22 +43.231.144.0/22 +43.231.148.0/22 +43.231.152.0/22 +43.231.156.0/22 +43.231.160.0/22 +43.231.164.0/22 +43.231.168.0/22 +43.231.172.0/22 +43.231.176.0/22 +43.231.180.0/22 +43.236.0.0/22 +43.236.4.0/22 +43.236.8.0/22 +43.236.12.0/22 +43.236.16.0/22 +43.236.20.0/22 +43.236.24.0/22 +43.236.28.0/22 +43.236.32.0/22 +43.236.36.0/22 +43.236.40.0/22 +43.236.44.0/22 +43.236.48.0/22 +43.236.52.0/22 +43.236.56.0/22 +43.236.60.0/22 +43.236.64.0/22 +43.236.68.0/22 +43.236.72.0/22 +43.236.76.0/22 +43.236.80.0/22 +43.236.84.0/22 +43.236.88.0/22 +43.236.92.0/22 +43.236.96.0/22 +43.236.100.0/22 +43.236.104.0/22 +43.236.108.0/22 +43.236.112.0/22 +43.236.116.0/22 +43.236.120.0/22 +43.236.124.0/22 +43.236.128.0/22 +43.236.132.0/22 +43.236.136.0/22 +43.236.140.0/22 +43.236.144.0/22 +43.236.148.0/22 +43.236.152.0/22 +43.236.156.0/22 +43.236.160.0/22 +43.236.164.0/22 +43.236.168.0/22 +43.236.172.0/22 +43.236.176.0/22 +43.236.180.0/22 +43.236.184.0/22 +43.236.188.0/22 +43.236.192.0/22 +43.236.196.0/22 +43.236.200.0/22 +43.236.204.0/22 +43.236.208.0/22 +43.236.212.0/22 +43.236.216.0/22 +43.236.220.0/22 +43.236.224.0/22 +43.236.228.0/22 +43.236.232.0/22 +43.236.236.0/22 +43.236.240.0/22 +43.236.244.0/22 +43.236.248.0/22 +43.236.252.0/22 +43.237.0.0/22 +43.237.4.0/22 +43.237.8.0/22 +43.237.12.0/22 +43.237.16.0/22 +43.237.20.0/22 +43.237.24.0/22 +43.237.28.0/22 +43.237.32.0/22 +43.237.36.0/22 +43.237.40.0/22 +43.237.44.0/22 +43.237.48.0/22 +43.237.52.0/22 +43.237.56.0/22 +43.237.60.0/22 +43.237.64.0/22 +43.237.68.0/22 +43.237.72.0/22 +43.237.76.0/22 +43.237.80.0/22 +43.237.84.0/22 +43.237.88.0/22 +43.237.92.0/22 +43.237.96.0/22 +43.237.100.0/22 +43.237.104.0/22 +43.237.108.0/22 +43.237.112.0/22 +43.237.116.0/22 +43.237.120.0/22 +43.237.124.0/22 +43.237.128.0/22 +43.237.132.0/22 +43.237.136.0/22 +43.237.140.0/22 +43.237.144.0/22 +43.237.148.0/22 +43.237.152.0/22 +43.237.156.0/22 +43.237.160.0/22 +43.237.164.0/22 +43.237.168.0/22 +43.237.172.0/22 +43.237.176.0/22 +43.237.180.0/22 +43.237.184.0/22 +43.237.188.0/22 +43.237.192.0/22 +43.237.196.0/22 +43.237.200.0/22 +43.237.204.0/22 +43.237.208.0/22 +43.237.212.0/22 +43.237.216.0/22 +43.237.220.0/22 +43.237.224.0/22 +43.237.228.0/22 +43.237.232.0/22 +43.237.236.0/22 +43.237.240.0/22 +43.237.244.0/22 +43.237.248.0/22 +43.237.252.0/22 +43.238.0.0/22 +43.238.4.0/22 +43.238.8.0/22 +43.238.12.0/22 +43.238.16.0/22 +43.238.20.0/22 +43.238.24.0/22 +43.238.28.0/22 +43.238.32.0/22 +43.238.36.0/22 +43.238.40.0/22 +43.238.44.0/22 +43.238.48.0/22 +43.238.52.0/22 +43.238.56.0/22 +43.238.60.0/22 +43.238.64.0/22 +43.238.68.0/22 +43.238.72.0/22 +43.238.76.0/22 +43.238.80.0/22 +43.238.84.0/22 +43.238.88.0/22 +43.238.92.0/22 +43.238.96.0/22 +43.238.100.0/22 +43.238.104.0/22 +43.238.108.0/22 +43.238.112.0/22 +43.238.116.0/22 +43.238.120.0/22 +43.238.124.0/22 +43.238.128.0/22 +43.238.132.0/22 +43.238.136.0/22 +43.238.140.0/22 +43.238.144.0/22 +43.238.148.0/22 +43.238.152.0/22 +43.238.156.0/22 +43.238.160.0/22 +43.238.164.0/22 +43.238.168.0/22 +43.238.172.0/22 +43.238.176.0/22 +43.238.180.0/22 +43.238.184.0/22 +43.238.188.0/22 +43.238.192.0/22 +43.238.196.0/22 +43.238.200.0/22 +43.238.204.0/22 +43.238.208.0/22 +43.238.212.0/22 +43.238.216.0/22 +43.238.220.0/22 +43.238.224.0/22 +43.238.228.0/22 +43.238.232.0/22 +43.238.236.0/22 +43.238.240.0/22 +43.238.244.0/22 +43.238.248.0/22 +43.238.252.0/22 +43.239.0.0/22 +43.239.4.0/22 +43.239.8.0/21 +43.239.16.0/22 +43.239.20.0/22 +43.239.24.0/22 +43.239.28.0/22 +43.239.32.0/22 +43.239.36.0/22 +43.239.40.0/22 +43.239.44.0/22 +43.239.48.0/22 +43.239.116.0/22 +43.239.120.0/22 +43.239.172.0/22 +43.239.176.0/22 +43.240.0.0/22 +43.240.48.0/22 +43.240.56.0/22 +43.240.60.0/22 +43.240.68.0/22 +43.240.72.0/22 +43.240.76.0/22 +43.240.84.0/22 +43.240.124.0/22 +43.240.128.0/22 +43.240.132.0/22 +43.240.136.0/22 +43.240.156.0/22 +43.240.160.0/22 +43.240.164.0/22 +43.240.168.0/22 +43.240.172.0/22 +43.240.176.0/22 +43.240.180.0/22 +43.240.184.0/22 +43.240.188.0/22 +43.240.192.0/22 +43.240.196.0/22 +43.240.200.0/22 +43.240.204.0/22 +43.240.208.0/22 +43.240.212.0/22 +43.240.216.0/22 +43.240.220.0/22 +43.240.236.0/22 +43.240.240.0/22 +43.240.244.0/22 +43.240.248.0/22 +43.240.252.0/22 +43.241.0.0/22 +43.241.4.0/22 +43.241.8.0/22 +43.241.12.0/22 +43.241.16.0/22 +43.241.20.0/22 +43.241.48.0/22 +43.241.76.0/22 +43.241.80.0/22 +43.241.84.0/22 +43.241.88.0/22 +43.241.92.0/22 +43.241.112.0/22 +43.241.168.0/22 +43.241.172.0/22 +43.241.176.0/22 +43.241.180.0/22 +43.241.184.0/22 +43.241.196.0/22 +43.241.208.0/22 +43.241.212.0/22 +43.241.216.0/22 +43.241.220.0/22 +43.241.224.0/22 +43.241.228.0/22 +43.241.232.0/22 +43.241.236.0/22 +43.241.240.0/22 +43.241.248.0/22 +43.241.252.0/22 +43.242.8.0/22 +43.242.12.0/22 +43.242.16.0/22 +43.242.20.0/22 +43.242.24.0/22 +43.242.28.0/22 +43.242.44.0/22 +43.242.48.0/22 +43.242.52.0/22 +43.242.56.0/22 +43.242.60.0/22 +43.242.64.0/22 +43.242.72.0/22 +43.242.76.0/22 +43.242.80.0/22 +43.242.84.0/22 +43.242.88.0/22 +43.242.92.0/22 +43.242.96.0/22 +43.242.144.0/22 +43.242.148.0/22 +43.242.152.0/22 +43.242.156.0/22 +43.242.160.0/22 +43.242.164.0/22 +43.242.168.0/22 +43.242.180.0/22 +43.242.188.0/22 +43.242.192.0/22 +43.242.196.0/22 +43.242.204.0/22 +43.242.216.0/22 +43.242.220.0/22 +43.242.252.0/22 +43.243.4.0/22 +43.243.8.0/22 +43.243.12.0/22 +43.243.16.0/22 +43.243.24.0/22 +43.243.88.0/22 +43.243.128.0/22 +43.243.136.0/22 +43.243.144.0/22 +43.243.148.0/22 +43.243.156.0/22 +43.243.168.0/22 +43.243.180.0/22 +43.243.188.0/22 +43.243.228.0/22 +43.243.232.0/22 +43.243.244.0/22 +43.246.0.0/22 +43.246.4.0/22 +43.246.8.0/22 +43.246.12.0/22 +43.246.16.0/22 +43.246.20.0/22 +43.246.24.0/22 +43.246.28.0/22 +43.246.32.0/22 +43.246.36.0/22 +43.246.40.0/22 +43.246.44.0/22 +43.246.48.0/22 +43.246.52.0/22 +43.246.56.0/22 +43.246.60.0/22 +43.246.64.0/22 +43.246.68.0/22 +43.246.72.0/22 +43.246.76.0/22 +43.246.80.0/22 +43.246.84.0/22 +43.246.88.0/22 +43.246.92.0/22 +43.246.96.0/22 +43.246.112.0/22 +43.246.212.0/22 +43.246.228.0/22 +43.247.4.0/22 +43.247.8.0/22 +43.247.44.0/22 +43.247.48.0/22 +43.247.68.0/22 +43.247.76.0/22 +43.247.84.0/22 +43.247.88.0/22 +43.247.92.0/22 +43.247.96.0/22 +43.247.100.0/22 +43.247.108.0/22 +43.247.112.0/22 +43.247.148.0/22 +43.247.152.0/22 +43.247.176.0/22 +43.247.180.0/22 +43.247.184.0/22 +43.247.188.0/22 +43.247.196.0/22 +43.247.200.0/22 +43.247.204.0/22 +43.247.208.0/22 +43.247.212.0/22 +43.247.216.0/22 +43.247.220.0/22 +43.247.224.0/22 +43.247.228.0/22 +43.247.232.0/22 +43.247.236.0/22 +43.247.240.0/22 +43.247.244.0/22 +43.247.248.0/22 +43.247.252.0/22 +43.248.0.0/22 +43.248.4.0/22 +43.248.20.0/22 +43.248.28.0/22 +43.248.48.0/22 +43.248.76.0/22 +43.248.80.0/22 +43.248.84.0/22 +43.248.88.0/22 +43.248.92.0/22 +43.248.96.0/22 +43.248.100.0/22 +43.248.104.0/22 +43.248.108.0/22 +43.248.112.0/22 +43.248.116.0/22 +43.248.120.0/22 +43.248.124.0/22 +43.248.128.0/22 +43.248.132.0/22 +43.248.136.0/22 +43.248.140.0/22 +43.248.144.0/22 +43.248.148.0/22 +43.248.176.0/22 +43.248.180.0/22 +43.248.184.0/22 +43.248.188.0/22 +43.248.192.0/22 +43.248.196.0/22 +43.248.200.0/22 +43.248.204.0/22 +43.248.208.0/22 +43.248.228.0/22 +43.248.232.0/22 +43.248.244.0/22 +43.249.4.0/22 +43.249.8.0/22 +43.249.24.0/22 +43.249.120.0/22 +43.249.132.0/22 +43.249.136.0/22 +43.249.144.0/22 +43.249.148.0/22 +43.249.152.0/22 +43.249.156.0/22 +43.249.160.0/22 +43.249.164.0/22 +43.249.168.0/22 +43.249.192.0/22 +43.249.236.0/22 +43.250.4.0/22 +43.250.12.0/22 +43.250.16.0/22 +43.250.20.0/22 +43.250.28.0/22 +43.250.32.0/22 +43.250.36.0/22 +43.250.72.0/22 +43.250.96.0/22 +43.250.100.0/22 +43.250.104.0/22 +43.250.108.0/22 +43.250.112.0/22 +43.250.116.0/22 +43.250.128.0/22 +43.250.144.0/22 +43.250.148.0/22 +43.250.160.0/22 +43.250.168.0/22 +43.250.172.0/22 +43.250.176.0/22 +43.250.200.0/22 +43.250.212.0/22 +43.250.216.0/22 +43.250.220.0/22 +43.250.236.0/22 +43.250.244.0/22 +43.251.4.0/22 +43.251.8.0/22 +43.251.12.0/22 +43.251.36.0/22 +43.251.100.0/22 +43.251.116.0/22 +43.251.192.0/22 +43.251.232.0/22 +43.251.236.0/22 +43.251.244.0/22 +43.252.40.0/22 +43.252.48.0/22 +43.252.56.0/22 +43.252.224.0/22 +43.254.0.0/22 +43.254.4.0/22 +43.254.8.0/22 +43.254.24.0/22 +43.254.36.0/22 +43.254.44.0/22 +43.254.52.0/22 +43.254.64.0/22 +43.254.72.0/22 +43.254.84.0/22 +43.254.88.0/22 +43.254.92.0/22 +43.254.100.0/22 +43.254.104.0/22 +43.254.112.0/22 +43.254.116.0/22 +43.254.128.0/22 +43.254.136.0/22 +43.254.140.0/22 +43.254.144.0/22 +43.254.148.0/22 +43.254.152.0/22 +43.254.156.0/22 +43.254.168.0/22 +43.254.172.0/22 +43.254.180.0/22 +43.254.184.0/22 +43.254.188.0/22 +43.254.192.0/22 +43.254.196.0/22 +43.254.200.0/22 +43.254.208.0/22 +43.254.220.0/22 +43.254.224.0/22 +43.254.228.0/22 +43.254.232.0/22 +43.254.236.0/22 +43.254.240.0/22 +43.254.248.0/22 +43.254.252.0/22 +43.255.0.0/22 +43.255.4.0/22 +43.255.8.0/22 +43.255.16.0/22 +43.255.48.0/22 +43.255.64.0/22 +43.255.68.0/22 +43.255.72.0/22 +43.255.76.0/22 +43.255.84.0/22 +43.255.96.0/22 +43.255.108.0/22 +43.255.144.0/22 +43.255.168.0/22 +43.255.176.0/22 +43.255.184.0/22 +43.255.192.0/22 +43.255.200.0/22 +43.255.204.0/22 +43.255.208.0/22 +43.255.212.0/22 +43.255.224.0/22 +43.255.228.0/22 +43.255.232.0/22 +43.255.244.0/22 +45.40.192.0/18 +45.65.16.0/22 +45.65.20.0/22 +45.65.24.0/22 +45.65.28.0/22 +45.112.132.0/22 +45.112.188.0/22 +45.112.208.0/22 +45.112.212.0/22 +45.112.216.0/22 +45.112.220.0/22 +45.112.228.0/22 +45.112.232.0/22 +45.112.236.0/22 +45.113.12.0/22 +45.113.16.0/22 +45.113.20.0/22 +45.113.24.0/22 +45.113.28.0/22 +45.113.40.0/22 +45.113.52.0/22 +45.113.56.0/22 +45.113.72.0/22 +45.113.144.0/22 +45.113.148.0/22 +45.113.168.0/22 +45.113.176.0/22 +45.113.184.0/22 +45.113.200.0/22 +45.113.204.0/22 +45.113.208.0/22 +45.113.212.0/22 +45.113.216.0/22 +45.113.220.0/22 +45.113.240.0/22 +45.113.252.0/22 +45.114.0.0/22 +45.114.12.0/22 +45.114.32.0/22 +45.114.40.0/22 +45.114.52.0/22 +45.114.96.0/22 +45.114.104.0/22 +45.114.108.0/22 +45.114.124.0/22 +45.114.136.0/22 +45.114.196.0/22 +45.114.200.0/22 +45.114.228.0/22 +45.114.252.0/22 +45.115.44.0/22 +45.115.100.0/22 +45.115.120.0/22 +45.115.132.0/22 +45.115.144.0/22 +45.115.156.0/22 +45.115.164.0/22 +45.115.200.0/22 +45.115.212.0/22 +45.115.228.0/22 +45.115.236.0/22 +45.115.244.0/22 +45.115.248.0/22 +45.116.12.0/22 +45.116.16.0/22 +45.116.24.0/22 +45.116.32.0/22 +45.116.36.0/22 +45.116.52.0/22 +45.116.96.0/22 +45.116.100.0/22 +45.116.140.0/22 +45.116.152.0/22 +45.116.208.0/22 +45.117.8.0/22 +45.117.20.0/22 +45.117.68.0/22 +45.117.124.0/22 +45.117.252.0/22 +45.119.52.0/22 +45.119.60.0/22 +45.119.64.0/22 +45.119.68.0/22 +45.119.72.0/22 +45.119.104.0/22 +45.119.116.0/22 +45.119.232.0/22 +45.120.100.0/22 +45.120.140.0/22 +45.120.164.0/22 +45.120.220.0/22 +45.120.240.0/22 +45.121.20.0/22 +45.121.52.0/22 +45.121.64.0/22 +45.121.68.0/22 +45.121.72.0/22 +45.121.92.0/22 +45.121.96.0/22 +45.121.104.0/22 +45.121.172.0/22 +45.121.176.0/22 +45.121.212.0/22 +45.121.240.0/22 +45.121.244.0/22 +45.121.248.0/22 +45.121.252.0/22 +45.122.0.0/22 +45.122.4.0/22 +45.122.8.0/22 +45.122.12.0/22 +45.122.16.0/22 +45.122.20.0/22 +45.122.24.0/22 +45.122.28.0/22 +45.122.32.0/22 +45.122.36.0/22 +45.122.40.0/22 +45.122.60.0/22 +45.122.64.0/22 +45.122.68.0/22 +45.122.72.0/22 +45.122.76.0/22 +45.122.80.0/22 +45.122.84.0/22 +45.122.88.0/22 +45.122.92.0/22 +45.122.96.0/21 +45.122.104.0/22 +45.122.108.0/22 +45.122.112.0/22 +45.122.116.0/22 +45.122.160.0/22 +45.122.164.0/22 +45.122.168.0/22 +45.122.172.0/22 +45.122.176.0/22 +45.122.180.0/22 +45.122.184.0/22 +45.122.188.0/22 +45.122.192.0/22 +45.122.196.0/22 +45.122.200.0/22 +45.122.204.0/22 +45.122.208.0/22 +45.122.212.0/22 +45.122.216.0/22 +45.123.28.0/22 +45.123.32.0/22 +45.123.36.0/22 +45.123.44.0/22 +45.123.48.0/22 +45.123.52.0/22 +45.123.56.0/22 +45.123.60.0/22 +45.123.64.0/22 +45.123.68.0/22 +45.123.72.0/22 +45.123.76.0/22 +45.123.80.0/22 +45.123.84.0/22 +45.123.88.0/22 +45.123.120.0/22 +45.123.128.0/22 +45.123.132.0/22 +45.123.136.0/22 +45.123.148.0/22 +45.123.152.0/22 +45.123.156.0/22 +45.123.164.0/22 +45.123.168.0/22 +45.123.172.0/22 +45.123.176.0/22 +45.123.180.0/22 +45.123.184.0/22 +45.123.204.0/22 +45.123.212.0/22 +45.123.224.0/22 +45.123.228.0/22 +45.123.232.0/22 +45.123.236.0/22 +45.123.240.0/22 +45.123.244.0/22 +45.123.248.0/22 +45.123.252.0/22 +45.124.0.0/22 +45.124.20.0/22 +45.124.28.0/22 +45.124.32.0/22 +45.124.36.0/22 +45.124.44.0/22 +45.124.68.0/22 +45.124.76.0/22 +45.124.80.0/22 +45.124.100.0/22 +45.124.124.0/22 +45.124.172.0/22 +45.124.176.0/22 +45.124.208.0/22 +45.124.248.0/22 +45.124.252.0/22 +45.125.12.0/22 +45.125.16.0/22 +45.125.24.0/22 +45.125.28.0/22 +45.125.32.0/22 +45.125.44.0/22 +45.125.52.0/22 +45.125.56.0/22 +45.125.76.0/22 +45.125.80.0/22 +45.125.84.0/22 +45.125.88.0/22 +45.125.92.0/22 +45.125.96.0/22 +45.125.100.0/22 +45.125.104.0/22 +45.125.136.0/22 +45.126.48.0/22 +45.126.52.0/22 +45.126.100.0/22 +45.126.108.0/22 +45.126.112.0/22 +45.126.116.0/22 +45.126.120.0/22 +45.126.212.0/22 +45.126.220.0/22 +45.127.8.0/22 +45.127.12.0/22 +45.127.96.0/22 +45.127.116.0/22 +45.127.124.0/22 +45.127.128.0/22 +45.127.144.0/22 +45.127.148.0/22 +45.127.156.0/22 +45.127.216.0/22 +45.248.8.0/22 +45.248.80.0/22 +45.248.84.0/22 +45.248.88.0/22 +45.248.96.0/22 +45.248.100.0/22 +45.248.104.0/22 +45.248.108.0/22 +45.248.128.0/22 +45.248.132.0/22 +45.248.204.0/22 +45.248.208.0/22 +45.248.212.0/22 +45.248.216.0/22 +45.248.220.0/22 +45.248.224.0/22 +45.248.228.0/22 +45.248.232.0/22 +45.248.236.0/22 +45.248.240.0/22 +45.248.244.0/22 +45.248.248.0/22 +45.248.252.0/22 +45.249.0.0/22 +45.249.4.0/22 +45.249.12.0/22 +45.249.16.0/22 +45.249.20.0/22 +45.249.24.0/22 +45.249.28.0/22 +45.249.32.0/22 +45.249.36.0/22 +45.249.92.0/22 +45.249.112.0/22 +45.249.180.0/22 +45.249.188.0/22 +45.249.192.0/22 +45.249.196.0/22 +45.249.200.0/22 +45.249.204.0/22 +45.249.208.0/22 +45.249.212.0/22 +45.250.12.0/22 +45.250.16.0/22 +45.250.28.0/22 +45.250.32.0/22 +45.250.36.0/22 +45.250.40.0/22 +45.250.76.0/22 +45.250.80.0/22 +45.250.84.0/22 +45.250.88.0/22 +45.250.92.0/22 +45.250.96.0/22 +45.250.104.0/22 +45.250.108.0/22 +45.250.112.0/22 +45.250.116.0/22 +45.250.120.0/22 +45.250.124.0/22 +45.250.128.0/22 +45.250.132.0/22 +45.250.136.0/22 +45.250.140.0/22 +45.250.144.0/22 +45.250.148.0/22 +45.250.152.0/22 +45.250.164.0/22 +45.250.180.0/22 +45.250.184.0/22 +45.250.188.0/22 +45.250.192.0/22 +45.251.0.0/22 +45.251.8.0/22 +45.251.16.0/22 +45.251.20.0/22 +45.251.52.0/22 +45.251.84.0/22 +45.251.88.0/22 +45.251.92.0/22 +45.251.96.0/22 +45.251.100.0/22 +45.251.120.0/22 +45.251.124.0/22 +45.251.136.0/22 +45.251.140.0/22 +45.251.144.0/22 +45.251.148.0/22 +45.251.152.0/22 +45.251.156.0/22 +45.251.160.0/22 +45.251.164.0/22 +45.251.168.0/22 +45.251.172.0/22 +45.251.176.0/22 +45.251.180.0/22 +45.251.184.0/22 +45.251.188.0/22 +45.251.192.0/22 +45.251.196.0/22 +45.251.200.0/22 +45.251.204.0/22 +45.251.208.0/22 +45.251.212.0/22 +45.251.216.0/22 +45.251.220.0/22 +45.251.224.0/22 +45.251.240.0/22 +45.252.0.0/22 +45.252.4.0/22 +45.252.8.0/22 +45.252.12.0/22 +45.252.16.0/22 +45.252.20.0/22 +45.252.24.0/22 +45.252.28.0/22 +45.252.32.0/22 +45.252.36.0/22 +45.252.40.0/22 +45.252.44.0/22 +45.252.48.0/22 +45.252.60.0/22 +45.252.84.0/22 +45.252.88.0/22 +45.252.92.0/22 +45.252.96.0/22 +45.252.100.0/22 +45.252.104.0/22 +45.252.108.0/22 +45.252.112.0/22 +45.252.116.0/22 +45.252.120.0/22 +45.252.124.0/22 +45.252.128.0/22 +45.252.132.0/22 +45.252.136.0/22 +45.252.140.0/22 +45.252.144.0/22 +45.252.148.0/22 +45.252.152.0/22 +45.252.156.0/22 +45.252.160.0/22 +45.252.164.0/22 +45.252.168.0/22 +45.252.172.0/22 +45.252.176.0/22 +45.252.192.0/22 +45.252.196.0/22 +45.252.200.0/22 +45.252.204.0/22 +45.252.208.0/22 +45.252.212.0/22 +45.252.216.0/22 +45.252.220.0/22 +45.252.224.0/22 +45.252.228.0/22 +45.252.232.0/22 +45.253.0.0/22 +45.253.4.0/22 +45.253.8.0/22 +45.253.12.0/22 +45.253.16.0/22 +45.253.20.0/22 +45.253.24.0/22 +45.253.28.0/22 +45.253.32.0/22 +45.253.36.0/22 +45.253.40.0/22 +45.253.44.0/22 +45.253.48.0/22 +45.253.52.0/22 +45.253.56.0/22 +45.253.60.0/22 +45.253.64.0/22 +45.253.68.0/22 +45.253.72.0/22 +45.253.76.0/22 +45.253.80.0/22 +45.253.84.0/22 +45.253.92.0/22 +45.253.96.0/22 +45.253.100.0/22 +45.253.104.0/22 +45.253.108.0/22 +45.253.112.0/22 +45.253.116.0/22 +45.253.120.0/22 +45.253.132.0/22 +45.253.136.0/22 +45.253.140.0/22 +45.253.144.0/22 +45.253.148.0/22 +45.253.152.0/22 +45.253.156.0/22 +45.253.160.0/22 +45.253.164.0/22 +45.253.168.0/22 +45.253.172.0/22 +45.253.176.0/22 +45.253.180.0/22 +45.253.184.0/22 +45.253.188.0/22 +45.253.192.0/22 +45.253.196.0/22 +45.253.200.0/22 +45.253.204.0/22 +45.253.208.0/22 +45.253.212.0/22 +45.253.216.0/22 +45.253.220.0/22 +45.253.224.0/22 +45.253.228.0/22 +45.253.232.0/22 +45.253.236.0/22 +45.253.240.0/22 +45.253.244.0/22 +45.253.248.0/22 +45.253.252.0/22 +45.254.0.0/22 +45.254.4.0/22 +45.254.8.0/22 +45.254.12.0/22 +45.254.16.0/22 +45.254.20.0/22 +45.254.24.0/22 +45.254.28.0/22 +45.254.40.0/22 +45.254.48.0/22 +45.254.52.0/22 +45.254.56.0/22 +45.254.60.0/22 +45.254.64.0/22 +45.254.68.0/22 +45.254.72.0/22 +45.254.76.0/22 +45.254.80.0/22 +45.254.84.0/22 +45.254.88.0/22 +45.254.92.0/22 +45.254.96.0/22 +45.254.100.0/22 +45.254.104.0/22 +45.254.108.0/22 +45.254.112.0/22 +45.254.116.0/22 +45.254.120.0/22 +45.254.124.0/22 +45.254.128.0/22 +45.254.132.0/22 +45.254.136.0/22 +45.254.140.0/22 +45.254.144.0/22 +45.254.148.0/22 +45.254.152.0/22 +45.254.156.0/22 +45.254.160.0/22 +45.254.164.0/22 +45.254.168.0/22 +45.254.172.0/22 +45.254.176.0/22 +45.254.180.0/22 +45.254.184.0/22 +45.254.188.0/22 +45.254.192.0/22 +45.254.196.0/22 +45.254.200.0/22 +45.254.204.0/22 +45.254.208.0/22 +45.254.212.0/22 +45.254.216.0/22 +45.254.220.0/22 +45.254.224.0/22 +45.254.228.0/22 +45.254.236.0/22 +45.254.240.0/22 +45.254.248.0/22 +45.255.0.0/22 +45.255.4.0/22 +45.255.8.0/22 +45.255.12.0/22 +45.255.16.0/22 +45.255.20.0/22 +45.255.24.0/22 +45.255.28.0/22 +45.255.32.0/22 +45.255.36.0/22 +45.255.40.0/22 +45.255.44.0/22 +45.255.48.0/22 +45.255.52.0/22 +45.255.56.0/22 +45.255.60.0/22 +45.255.64.0/22 +45.255.68.0/22 +45.255.72.0/22 +45.255.76.0/22 +45.255.80.0/22 +45.255.84.0/22 +45.255.88.0/22 +45.255.92.0/22 +45.255.96.0/22 +45.255.100.0/22 +45.255.104.0/22 +45.255.108.0/22 +45.255.112.0/22 +45.255.116.0/22 +45.255.120.0/22 +45.255.124.0/22 +45.255.132.0/22 +45.255.136.0/22 +45.255.140.0/22 +45.255.144.0/22 +45.255.148.0/22 +45.255.152.0/22 +45.255.156.0/22 +45.255.160.0/22 +45.255.164.0/22 +45.255.168.0/22 +45.255.172.0/22 +45.255.176.0/22 +45.255.180.0/22 +45.255.184.0/22 +45.255.188.0/22 +45.255.192.0/22 +45.255.196.0/22 +45.255.200.0/22 +45.255.204.0/22 +45.255.208.0/22 +45.255.212.0/22 +45.255.216.0/22 +45.255.220.0/22 +45.255.224.0/22 +45.255.228.0/22 +45.255.232.0/22 +45.255.236.0/22 +45.255.240.0/22 +45.255.244.0/22 +45.255.248.0/22 +47.92.0.0/14 +47.96.0.0/11 +49.4.0.0/14 +49.51.0.0/16 +49.52.0.0/14 +49.64.0.0/11 +49.112.0.0/13 +49.120.0.0/14 +49.128.0.0/24 +49.128.2.0/23 +49.128.4.0/22 +49.140.0.0/15 +49.152.0.0/14 +49.208.0.0/15 +49.210.0.0/15 +49.220.0.0/14 +49.232.0.0/14 +49.239.0.0/18 +49.239.192.0/18 +49.246.224.0/19 +52.80.0.0/15 +52.82.0.0/15 +52.130.0.0/15 +54.222.0.0/15 +58.14.0.0/15 +58.16.0.0/16 +58.17.0.0/17 +58.17.128.0/17 +58.18.0.0/16 +58.19.0.0/16 +58.20.0.0/16 +58.21.0.0/16 +58.22.0.0/15 +58.24.0.0/15 +58.30.0.0/15 +58.32.0.0/13 +58.40.0.0/15 +58.42.0.0/16 +58.43.0.0/16 +58.44.0.0/14 +58.48.0.0/13 +58.56.0.0/15 +58.58.0.0/16 +58.59.0.0/17 +58.59.128.0/17 +58.60.0.0/14 +58.65.232.0/21 +58.66.0.0/15 +58.68.128.0/17 +58.82.0.0/17 +58.83.0.0/17 +58.83.128.0/17 +58.87.64.0/18 +58.99.128.0/17 +58.100.0.0/15 +58.116.0.0/14 +58.128.0.0/13 +58.144.0.0/16 +58.154.0.0/15 +58.192.0.0/15 +58.194.0.0/15 +58.196.0.0/15 +58.198.0.0/15 +58.200.0.0/13 +58.208.0.0/12 +58.240.0.0/15 +58.242.0.0/15 +58.244.0.0/15 +58.246.0.0/15 +58.248.0.0/13 +59.32.0.0/13 +59.40.0.0/15 +59.42.0.0/16 +59.43.0.0/16 +59.44.0.0/14 +59.48.0.0/16 +59.49.0.0/17 +59.49.128.0/17 +59.50.0.0/16 +59.51.0.0/17 +59.51.128.0/17 +59.52.0.0/14 +59.56.0.0/14 +59.60.0.0/15 +59.62.0.0/15 +59.64.0.0/14 +59.68.0.0/14 +59.72.0.0/15 +59.74.0.0/15 +59.76.0.0/16 +59.77.0.0/16 +59.78.0.0/15 +59.80.0.0/15 +59.82.0.0/15 +59.107.0.0/17 +59.107.128.0/17 +59.108.0.0/15 +59.110.0.0/15 +59.151.0.0/17 +59.152.16.0/22 +59.152.20.0/22 +59.152.24.0/22 +59.152.28.0/22 +59.152.32.0/22 +59.152.36.0/22 +59.152.64.0/22 +59.152.68.0/22 +59.152.72.0/22 +59.152.76.0/22 +59.152.112.0/22 +59.152.116.0/22 +59.153.4.0/22 +59.153.32.0/22 +59.153.60.0/22 +59.153.64.0/22 +59.153.68.0/22 +59.153.72.0/22 +59.153.92.0/22 +59.153.116.0/22 +59.153.136.0/22 +59.153.152.0/22 +59.153.156.0/22 +59.153.164.0/22 +59.153.168.0/22 +59.153.172.0/22 +59.153.176.0/22 +59.153.180.0/22 +59.153.184.0/22 +59.153.188.0/22 +59.153.192.0/22 +59.155.0.0/16 +59.172.0.0/15 +59.174.0.0/15 +59.191.0.0/17 +59.191.240.0/20 +59.192.0.0/10 +60.0.0.0/13 +60.8.0.0/15 +60.10.0.0/16 +60.11.0.0/16 +60.12.0.0/16 +60.13.0.0/18 +60.13.64.0/18 +60.13.128.0/17 +60.14.0.0/15 +60.16.0.0/13 +60.24.0.0/14 +60.28.0.0/15 +60.30.0.0/16 +60.31.0.0/16 +60.55.0.0/16 +60.63.0.0/16 +60.160.0.0/15 +60.162.0.0/15 +60.164.0.0/15 +60.166.0.0/15 +60.168.0.0/13 +60.176.0.0/12 +60.194.0.0/15 +60.200.0.0/14 +60.204.0.0/16 +60.205.0.0/16 +60.206.0.0/15 +60.208.0.0/13 +60.216.0.0/15 +60.218.0.0/15 +60.220.0.0/14 +60.232.0.0/15 +60.235.0.0/16 +60.245.128.0/17 +60.247.0.0/16 +60.252.0.0/16 +60.253.128.0/17 +60.255.0.0/16 +61.4.80.0/22 +61.4.84.0/22 +61.4.88.0/21 +61.4.176.0/20 +61.8.160.0/20 +61.14.212.0/22 +61.14.216.0/22 +61.14.220.0/22 +61.14.240.0/22 +61.14.244.0/22 +61.28.0.0/20 +61.28.16.0/20 +61.28.32.0/19 +61.28.64.0/18 +61.29.128.0/18 +61.29.192.0/19 +61.29.224.0/20 +61.29.240.0/20 +61.45.128.0/18 +61.45.224.0/20 +61.47.128.0/18 +61.48.0.0/14 +61.52.0.0/15 +61.54.0.0/16 +61.55.0.0/16 +61.87.192.0/18 +61.128.0.0/15 +61.130.0.0/15 +61.132.0.0/16 +61.133.0.0/17 +61.133.128.0/17 +61.134.0.0/18 +61.134.64.0/19 +61.134.96.0/19 +61.134.128.0/18 +61.134.192.0/18 +61.135.0.0/16 +61.136.0.0/18 +61.136.64.0/18 +61.136.128.0/17 +61.137.0.0/17 +61.137.128.0/17 +61.138.0.0/18 +61.138.64.0/18 +61.138.128.0/18 +61.138.192.0/18 +61.139.0.0/17 +61.139.128.0/18 +61.139.192.0/18 +61.140.0.0/14 +61.144.0.0/14 +61.148.0.0/15 +61.150.0.0/15 +61.152.0.0/16 +61.153.0.0/16 +61.154.0.0/15 +61.156.0.0/16 +61.157.0.0/16 +61.158.0.0/17 +61.158.128.0/17 +61.159.0.0/18 +61.159.64.0/18 +61.159.128.0/17 +61.160.0.0/16 +61.161.0.0/18 +61.161.64.0/18 +61.161.128.0/17 +61.162.0.0/16 +61.163.0.0/16 +61.164.0.0/16 +61.165.0.0/16 +61.166.0.0/16 +61.167.0.0/16 +61.168.0.0/16 +61.169.0.0/16 +61.170.0.0/15 +61.172.0.0/14 +61.176.0.0/16 +61.177.0.0/16 +61.178.0.0/16 +61.179.0.0/16 +61.180.0.0/17 +61.180.128.0/17 +61.181.0.0/16 +61.182.0.0/16 +61.183.0.0/16 +61.184.0.0/14 +61.188.0.0/16 +61.189.0.0/17 +61.189.128.0/17 +61.190.0.0/15 +61.232.0.0/14 +61.236.0.0/15 +61.240.0.0/14 +62.234.0.0/16 +68.79.0.0/18 +69.230.192.0/18 +69.231.128.0/18 +69.234.192.0/18 +69.235.128.0/18 +71.131.192.0/18 +71.132.0.0/18 +71.136.64.0/18 +71.137.0.0/18 +81.68.0.0/14 +82.156.0.0/15 +94.191.0.0/17 +101.0.0.0/22 +101.1.0.0/22 +101.2.172.0/22 +101.4.0.0/14 +101.16.0.0/12 +101.32.0.0/14 +101.36.0.0/17 +101.36.128.0/17 +101.37.0.0/16 +101.38.0.0/15 +101.40.0.0/13 +101.48.0.0/15 +101.50.8.0/22 +101.50.12.0/22 +101.50.56.0/22 +101.52.0.0/16 +101.53.100.0/22 +101.54.0.0/16 +101.55.224.0/21 +101.64.0.0/13 +101.72.0.0/14 +101.76.0.0/15 +101.78.0.0/22 +101.78.32.0/19 +101.80.0.0/12 +101.96.0.0/21 +101.96.8.0/22 +101.96.16.0/20 +101.96.128.0/17 +101.99.96.0/19 +101.101.64.0/19 +101.101.100.0/24 +101.101.102.0/23 +101.101.104.0/21 +101.101.112.0/20 +101.102.64.0/19 +101.102.100.0/23 +101.102.102.0/24 +101.102.104.0/21 +101.102.112.0/20 +101.104.0.0/14 +101.110.64.0/19 +101.110.96.0/20 +101.110.116.0/22 +101.110.120.0/21 +101.120.0.0/14 +101.124.0.0/15 +101.126.0.0/16 +101.128.0.0/22 +101.128.8.0/21 +101.128.16.0/20 +101.128.32.0/19 +101.129.0.0/16 +101.130.0.0/15 +101.132.0.0/14 +101.144.0.0/12 +101.192.0.0/14 +101.196.0.0/16 +101.197.0.0/16 +101.198.0.0/15 +101.200.0.0/15 +101.203.128.0/19 +101.203.160.0/21 +101.203.172.0/22 +101.203.176.0/20 +101.204.0.0/14 +101.224.0.0/13 +101.232.0.0/15 +101.234.64.0/21 +101.234.76.0/22 +101.234.80.0/20 +101.234.96.0/19 +101.236.0.0/14 +101.240.0.0/14 +101.244.0.0/14 +101.248.0.0/15 +101.251.0.0/22 +101.251.8.0/21 +101.251.16.0/20 +101.251.32.0/19 +101.251.64.0/18 +101.251.128.0/17 +101.252.0.0/15 +101.254.0.0/16 +103.1.8.0/22 +103.1.20.0/22 +103.1.24.0/22 +103.1.72.0/22 +103.1.88.0/22 +103.1.168.0/22 +103.2.108.0/22 +103.2.156.0/22 +103.2.164.0/22 +103.2.200.0/22 +103.2.204.0/22 +103.2.208.0/22 +103.2.212.0/22 +103.3.84.0/22 +103.3.88.0/22 +103.3.92.0/22 +103.3.96.0/22 +103.3.100.0/22 +103.3.104.0/22 +103.3.108.0/22 +103.3.112.0/22 +103.3.116.0/22 +103.3.120.0/22 +103.3.124.0/22 +103.3.128.0/22 +103.3.132.0/22 +103.3.136.0/22 +103.3.140.0/22 +103.3.148.0/22 +103.3.152.0/22 +103.3.156.0/22 +103.4.56.0/22 +103.4.168.0/22 +103.4.184.0/22 +103.4.224.0/22 +103.5.36.0/22 +103.5.52.0/22 +103.5.56.0/22 +103.5.152.0/22 +103.5.168.0/22 +103.5.192.0/22 +103.5.252.0/22 +103.6.76.0/22 +103.6.108.0/22 +103.6.220.0/22 +103.6.228.0/22 +103.7.4.0/22 +103.7.28.0/22 +103.7.140.0/22 +103.7.212.0/22 +103.7.216.0/22 +103.7.220.0/22 +103.8.0.0/22 +103.8.4.0/22 +103.8.8.0/22 +103.8.32.0/22 +103.8.52.0/22 +103.8.68.0/22 +103.8.108.0/22 +103.8.156.0/22 +103.8.200.0/22 +103.8.204.0/22 +103.8.220.0/22 +103.9.8.0/22 +103.9.24.0/22 +103.9.108.0/22 +103.9.152.0/22 +103.9.192.0/22 +103.9.248.0/22 +103.9.252.0/22 +103.10.0.0/22 +103.10.16.0/22 +103.10.84.0/22 +103.10.140.0/22 +103.11.16.0/22 +103.11.168.0/22 +103.11.180.0/22 +103.12.32.0/22 +103.12.68.0/22 +103.12.92.0/22 +103.12.136.0/22 +103.12.184.0/22 +103.12.232.0/22 +103.13.12.0/22 +103.13.72.0/23 +103.13.124.0/22 +103.13.144.0/22 +103.13.196.0/22 +103.13.220.0/22 +103.13.244.0/22 +103.14.32.0/22 +103.14.84.0/22 +103.14.100.0/22 +103.14.132.0/22 +103.14.136.0/22 +103.14.156.0/22 +103.14.240.0/22 +103.15.4.0/22 +103.15.8.0/22 +103.15.16.0/22 +103.15.96.0/22 +103.15.200.0/22 +103.16.52.0/22 +103.16.80.0/22 +103.16.84.0/22 +103.16.88.0/22 +103.16.108.0/22 +103.16.124.0/22 +103.17.40.0/22 +103.17.64.0/22 +103.17.120.0/22 +103.17.136.0/22 +103.17.160.0/22 +103.17.204.0/22 +103.17.228.0/22 +103.18.192.0/22 +103.18.208.0/22 +103.18.212.0/22 +103.18.224.0/22 +103.19.0.0/22 +103.19.12.0/22 +103.19.40.0/22 +103.19.44.0/22 +103.19.64.0/22 +103.19.68.0/22 +103.19.72.0/22 +103.19.232.0/22 +103.20.12.0/22 +103.20.32.0/22 +103.20.44.0/22 +103.20.68.0/22 +103.20.112.0/22 +103.20.128.0/22 +103.20.160.0/22 +103.20.248.0/22 +103.21.112.0/22 +103.21.116.0/22 +103.21.136.0/22 +103.21.140.0/22 +103.21.176.0/22 +103.21.208.0/22 +103.21.240.0/22 +103.22.0.0/22 +103.22.4.0/22 +103.22.8.0/22 +103.22.12.0/22 +103.22.16.0/22 +103.22.20.0/22 +103.22.24.0/22 +103.22.28.0/22 +103.22.32.0/22 +103.22.36.0/22 +103.22.40.0/22 +103.22.44.0/22 +103.22.48.0/22 +103.22.52.0/22 +103.22.56.0/22 +103.22.60.0/22 +103.22.64.0/22 +103.22.68.0/22 +103.22.72.0/22 +103.22.76.0/22 +103.22.80.0/22 +103.22.84.0/22 +103.22.88.0/22 +103.22.92.0/22 +103.22.100.0/22 +103.22.104.0/22 +103.22.108.0/22 +103.22.112.0/22 +103.22.116.0/22 +103.22.120.0/22 +103.22.124.0/22 +103.22.188.0/22 +103.22.228.0/22 +103.22.252.0/22 +103.23.8.0/22 +103.23.56.0/22 +103.23.160.0/22 +103.23.164.0/22 +103.23.176.0/22 +103.23.228.0/22 +103.24.24.0/22 +103.24.116.0/22 +103.24.128.0/22 +103.24.144.0/22 +103.24.176.0/22 +103.24.184.0/22 +103.24.220.0/22 +103.24.228.0/22 +103.24.248.0/22 +103.24.252.0/22 +103.25.8.0/23 +103.25.20.0/22 +103.25.24.0/22 +103.25.28.0/22 +103.25.32.0/22 +103.25.36.0/22 +103.25.40.0/22 +103.25.48.0/22 +103.25.64.0/22 +103.25.68.0/22 +103.25.148.0/22 +103.25.156.0/22 +103.25.216.0/22 +103.26.0.0/22 +103.26.64.0/22 +103.26.76.0/22 +103.26.132.0/22 +103.26.156.0/22 +103.26.160.0/22 +103.26.228.0/22 +103.26.240.0/22 +103.27.4.0/22 +103.27.12.0/22 +103.27.24.0/22 +103.27.56.0/22 +103.27.96.0/22 +103.27.184.0/22 +103.27.208.0/22 +103.27.212.0/22 +103.27.240.0/22 +103.28.4.0/22 +103.28.8.0/22 +103.28.184.0/22 +103.28.204.0/22 +103.28.212.0/22 +103.29.16.0/22 +103.29.128.0/22 +103.29.132.0/22 +103.29.136.0/22 +103.30.20.0/22 +103.30.96.0/22 +103.30.148.0/22 +103.30.200.0/22 +103.30.228.0/22 +103.30.236.0/22 +103.31.0.0/22 +103.31.48.0/22 +103.31.52.0/22 +103.31.56.0/22 +103.31.60.0/22 +103.31.64.0/22 +103.31.68.0/22 +103.31.148.0/22 +103.31.160.0/22 +103.31.168.0/22 +103.31.200.0/22 +103.31.236.0/22 +103.32.0.0/22 +103.32.4.0/22 +103.32.8.0/22 +103.32.12.0/22 +103.32.16.0/22 +103.32.20.0/22 +103.32.24.0/22 +103.32.28.0/22 +103.32.32.0/22 +103.32.36.0/22 +103.32.40.0/22 +103.32.44.0/22 +103.32.48.0/22 +103.32.52.0/22 +103.32.56.0/22 +103.32.60.0/22 +103.32.64.0/22 +103.32.68.0/22 +103.32.72.0/22 +103.32.76.0/22 +103.32.80.0/22 +103.32.84.0/22 +103.32.88.0/22 +103.32.92.0/22 +103.32.96.0/22 +103.32.100.0/22 +103.32.104.0/22 +103.32.108.0/22 +103.32.112.0/22 +103.32.116.0/22 +103.32.120.0/22 +103.32.124.0/22 +103.32.128.0/22 +103.32.132.0/22 +103.32.136.0/22 +103.32.140.0/22 +103.32.144.0/22 +103.32.148.0/22 +103.32.152.0/22 +103.32.156.0/22 +103.32.160.0/22 +103.32.164.0/22 +103.32.168.0/22 +103.32.172.0/22 +103.32.176.0/22 +103.32.180.0/22 +103.32.184.0/22 +103.32.188.0/22 +103.32.192.0/22 +103.32.196.0/22 +103.32.200.0/22 +103.32.204.0/22 +103.32.208.0/22 +103.32.212.0/22 +103.32.216.0/22 +103.32.220.0/22 +103.32.224.0/22 +103.32.228.0/22 +103.32.232.0/22 +103.32.236.0/22 +103.32.240.0/22 +103.32.244.0/22 +103.32.248.0/22 +103.32.252.0/22 +103.33.0.0/22 +103.33.4.0/22 +103.33.8.0/22 +103.33.12.0/22 +103.33.16.0/22 +103.33.20.0/22 +103.33.24.0/22 +103.33.28.0/22 +103.33.32.0/22 +103.33.36.0/22 +103.33.40.0/22 +103.33.44.0/22 +103.33.48.0/22 +103.33.52.0/22 +103.33.56.0/22 +103.33.60.0/22 +103.33.64.0/22 +103.33.68.0/22 +103.33.72.0/22 +103.33.76.0/22 +103.33.80.0/22 +103.33.84.0/22 +103.33.88.0/22 +103.33.92.0/22 +103.33.96.0/22 +103.33.100.0/22 +103.33.104.0/22 +103.33.108.0/22 +103.33.112.0/22 +103.33.116.0/22 +103.33.120.0/22 +103.33.124.0/22 +103.33.128.0/22 +103.33.132.0/22 +103.33.136.0/22 +103.33.140.0/22 +103.33.144.0/22 +103.33.148.0/22 +103.33.152.0/22 +103.33.156.0/22 +103.33.160.0/22 +103.33.164.0/22 +103.33.168.0/22 +103.33.172.0/22 +103.33.176.0/22 +103.33.180.0/22 +103.33.184.0/22 +103.33.188.0/22 +103.33.192.0/22 +103.33.196.0/22 +103.33.200.0/22 +103.33.204.0/22 +103.33.208.0/22 +103.33.212.0/22 +103.33.216.0/22 +103.33.220.0/22 +103.33.224.0/22 +103.33.228.0/22 +103.33.232.0/22 +103.33.236.0/22 +103.33.240.0/22 +103.33.244.0/22 +103.33.248.0/22 +103.33.252.0/22 +103.34.0.0/22 +103.34.4.0/22 +103.34.8.0/22 +103.34.12.0/22 +103.34.16.0/22 +103.34.20.0/22 +103.34.24.0/22 +103.34.28.0/22 +103.34.32.0/22 +103.34.36.0/22 +103.34.40.0/22 +103.34.44.0/22 +103.34.48.0/22 +103.34.52.0/22 +103.34.56.0/22 +103.34.60.0/22 +103.34.64.0/22 +103.34.68.0/22 +103.34.72.0/22 +103.34.76.0/22 +103.34.80.0/22 +103.34.84.0/22 +103.34.88.0/22 +103.34.92.0/22 +103.34.96.0/22 +103.34.100.0/22 +103.34.104.0/22 +103.34.108.0/22 +103.34.112.0/22 +103.34.116.0/22 +103.34.120.0/22 +103.34.124.0/22 +103.34.128.0/22 +103.34.132.0/22 +103.34.136.0/22 +103.34.140.0/22 +103.34.144.0/22 +103.34.148.0/22 +103.34.152.0/22 +103.34.156.0/22 +103.34.160.0/22 +103.34.164.0/22 +103.34.168.0/22 +103.34.172.0/22 +103.34.176.0/22 +103.34.180.0/22 +103.34.184.0/22 +103.34.188.0/22 +103.34.192.0/22 +103.34.196.0/22 +103.34.200.0/22 +103.34.204.0/22 +103.34.208.0/22 +103.34.212.0/22 +103.34.216.0/22 +103.34.220.0/22 +103.34.224.0/22 +103.34.228.0/22 +103.34.232.0/22 +103.34.236.0/22 +103.34.240.0/22 +103.34.244.0/22 +103.34.248.0/22 +103.34.252.0/22 +103.35.0.0/22 +103.35.4.0/22 +103.35.8.0/22 +103.35.12.0/22 +103.35.16.0/22 +103.35.20.0/22 +103.35.24.0/22 +103.35.28.0/22 +103.35.32.0/22 +103.35.36.0/22 +103.35.40.0/22 +103.35.44.0/22 +103.35.48.0/22 +103.35.104.0/22 +103.35.116.0/22 +103.35.180.0/22 +103.35.200.0/22 +103.35.220.0/22 +103.36.20.0/22 +103.36.28.0/22 +103.36.36.0/22 +103.36.56.0/22 +103.36.60.0/22 +103.36.64.0/22 +103.36.72.0/22 +103.36.96.0/22 +103.36.132.0/22 +103.36.136.0/22 +103.36.160.0/22 +103.36.164.0/22 +103.36.168.0/22 +103.36.172.0/22 +103.36.176.0/22 +103.36.180.0/22 +103.36.184.0/22 +103.36.188.0/22 +103.36.192.0/22 +103.36.196.0/22 +103.36.200.0/22 +103.36.204.0/22 +103.36.208.0/22 +103.36.212.0/22 +103.36.216.0/22 +103.36.220.0/22 +103.36.224.0/22 +103.36.228.0/22 +103.36.232.0/22 +103.36.236.0/22 +103.36.240.0/22 +103.36.244.0/22 +103.37.0.0/22 +103.37.12.0/22 +103.37.16.0/22 +103.37.24.0/22 +103.37.44.0/22 +103.37.52.0/22 +103.37.56.0/22 +103.37.72.0/22 +103.37.100.0/22 +103.37.104.0/22 +103.37.124.0/22 +103.37.136.0/22 +103.37.140.0/22 +103.37.144.0/22 +103.37.148.0/22 +103.37.152.0/22 +103.37.156.0/22 +103.37.160.0/22 +103.37.164.0/22 +103.37.172.0/22 +103.37.176.0/22 +103.37.188.0/22 +103.37.208.0/22 +103.37.212.0/22 +103.37.216.0/22 +103.37.220.0/22 +103.37.248.0/22 +103.37.252.0/22 +103.38.0.0/22 +103.38.32.0/22 +103.38.40.0/22 +103.38.44.0/22 +103.38.56.0/22 +103.38.76.0/22 +103.38.84.0/22 +103.38.92.0/22 +103.38.96.0/22 +103.38.116.0/22 +103.38.132.0/22 +103.38.140.0/22 +103.38.224.0/22 +103.38.228.0/22 +103.38.232.0/22 +103.38.252.0/22 +103.39.16.0/22 +103.39.64.0/22 +103.39.88.0/22 +103.39.100.0/22 +103.39.104.0/22 +103.39.108.0/22 +103.39.160.0/22 +103.39.164.0/22 +103.39.168.0/22 +103.39.172.0/22 +103.39.176.0/22 +103.39.180.0/22 +103.39.184.0/22 +103.39.188.0/22 +103.39.200.0/22 +103.39.204.0/22 +103.39.208.0/22 +103.39.212.0/22 +103.39.216.0/22 +103.39.220.0/22 +103.39.224.0/22 +103.39.228.0/22 +103.39.232.0/22 +103.40.12.0/22 +103.40.16.0/22 +103.40.20.0/22 +103.40.24.0/22 +103.40.28.0/22 +103.40.32.0/22 +103.40.36.0/22 +103.40.40.0/22 +103.40.44.0/22 +103.40.88.0/22 +103.40.100.0/22 +103.40.112.0/22 +103.40.192.0/22 +103.40.212.0/22 +103.40.220.0/22 +103.40.228.0/22 +103.40.232.0/22 +103.40.236.0/22 +103.40.240.0/22 +103.40.244.0/22 +103.40.248.0/22 +103.40.252.0/22 +103.41.0.0/22 +103.41.16.0/22 +103.41.52.0/22 +103.41.140.0/22 +103.41.148.0/22 +103.41.152.0/22 +103.41.160.0/22 +103.41.164.0/22 +103.41.220.0/22 +103.41.224.0/22 +103.41.228.0/22 +103.41.232.0/22 +103.42.8.0/22 +103.42.24.0/22 +103.42.28.0/22 +103.42.32.0/22 +103.42.64.0/22 +103.42.68.0/22 +103.42.76.0/22 +103.42.104.0/22 +103.42.180.0/22 +103.42.232.0/22 +103.43.16.0/22 +103.43.84.0/22 +103.43.96.0/22 +103.43.100.0/22 +103.43.104.0/22 +103.43.124.0/22 +103.43.184.0/22 +103.43.192.0/22 +103.43.196.0/22 +103.43.208.0/22 +103.43.220.0/22 +103.43.224.0/22 +103.43.232.0/22 +103.43.240.0/22 +103.44.56.0/22 +103.44.80.0/22 +103.44.88.0/22 +103.44.120.0/22 +103.44.124.0/22 +103.44.132.0/22 +103.44.144.0/22 +103.44.168.0/22 +103.44.176.0/22 +103.44.180.0/22 +103.44.184.0/22 +103.44.188.0/22 +103.44.192.0/22 +103.44.196.0/22 +103.44.200.0/22 +103.44.204.0/22 +103.44.224.0/22 +103.44.236.0/22 +103.44.240.0/22 +103.44.244.0/22 +103.44.248.0/22 +103.44.252.0/22 +103.45.0.0/22 +103.45.4.0/22 +103.45.8.0/22 +103.45.12.0/22 +103.45.16.0/22 +103.45.20.0/22 +103.45.24.0/22 +103.45.28.0/22 +103.45.32.0/22 +103.45.36.0/22 +103.45.40.0/22 +103.45.44.0/22 +103.45.48.0/22 +103.45.52.0/22 +103.45.56.0/22 +103.45.60.0/22 +103.45.72.0/22 +103.45.76.0/22 +103.45.80.0/22 +103.45.84.0/22 +103.45.88.0/22 +103.45.92.0/22 +103.45.96.0/22 +103.45.100.0/22 +103.45.104.0/22 +103.45.108.0/22 +103.45.112.0/22 +103.45.116.0/22 +103.45.120.0/22 +103.45.124.0/22 +103.45.128.0/22 +103.45.132.0/22 +103.45.136.0/22 +103.45.140.0/22 +103.45.144.0/22 +103.45.148.0/22 +103.45.152.0/22 +103.45.156.0/22 +103.45.160.0/22 +103.45.164.0/22 +103.45.168.0/22 +103.45.172.0/22 +103.45.176.0/22 +103.45.180.0/22 +103.45.184.0/22 +103.45.188.0/22 +103.45.192.0/22 +103.45.196.0/22 +103.45.200.0/22 +103.45.204.0/22 +103.45.208.0/22 +103.45.212.0/22 +103.45.216.0/22 +103.45.220.0/22 +103.45.224.0/22 +103.45.248.0/22 +103.46.0.0/22 +103.46.12.0/22 +103.46.16.0/22 +103.46.20.0/22 +103.46.24.0/22 +103.46.28.0/22 +103.46.32.0/22 +103.46.36.0/22 +103.46.40.0/22 +103.46.44.0/22 +103.46.48.0/22 +103.46.52.0/22 +103.46.56.0/22 +103.46.60.0/22 +103.46.64.0/22 +103.46.68.0/22 +103.46.72.0/22 +103.46.76.0/22 +103.46.80.0/22 +103.46.84.0/22 +103.46.88.0/22 +103.46.92.0/22 +103.46.96.0/22 +103.46.100.0/22 +103.46.104.0/22 +103.46.108.0/22 +103.46.112.0/22 +103.46.116.0/22 +103.46.120.0/22 +103.46.124.0/22 +103.46.128.0/22 +103.46.132.0/22 +103.46.136.0/22 +103.46.152.0/22 +103.46.156.0/22 +103.46.160.0/22 +103.46.164.0/22 +103.46.168.0/22 +103.46.172.0/22 +103.46.176.0/22 +103.46.180.0/22 +103.46.244.0/22 +103.46.248.0/22 +103.47.4.0/22 +103.47.20.0/22 +103.47.36.0/22 +103.47.40.0/22 +103.47.48.0/22 +103.47.80.0/22 +103.47.96.0/22 +103.47.108.0/22 +103.47.116.0/22 +103.47.120.0/22 +103.47.136.0/22 +103.47.140.0/22 +103.47.212.0/22 +103.48.20.0/22 +103.48.52.0/22 +103.48.92.0/22 +103.48.144.0/22 +103.48.148.0/22 +103.48.152.0/22 +103.48.156.0/22 +103.48.202.0/23 +103.48.216.0/22 +103.48.220.0/22 +103.48.224.0/22 +103.48.228.0/22 +103.48.232.0/22 +103.48.236.0/22 +103.48.240.0/22 +103.48.244.0/22 +103.49.12.0/22 +103.49.20.0/22 +103.49.72.0/22 +103.49.76.0/22 +103.49.92.0/22 +103.49.96.0/22 +103.49.108.0/22 +103.49.128.0/22 +103.49.176.0/22 +103.49.180.0/22 +103.49.196.0/22 +103.49.248.0/22 +103.50.36.0/22 +103.50.44.0/22 +103.50.48.0/22 +103.50.52.0/22 +103.50.56.0/22 +103.50.60.0/22 +103.50.64.0/22 +103.50.68.0/22 +103.50.72.0/22 +103.50.108.0/22 +103.50.112.0/22 +103.50.116.0/22 +103.50.120.0/22 +103.50.124.0/22 +103.50.132.0/22 +103.50.136.0/22 +103.50.140.0/22 +103.50.172.0/22 +103.50.176.0/22 +103.50.180.0/22 +103.50.184.0/22 +103.50.188.0/22 +103.50.192.0/22 +103.50.196.0/22 +103.50.200.0/22 +103.50.220.0/22 +103.50.224.0/22 +103.50.228.0/22 +103.50.232.0/22 +103.50.236.0/22 +103.50.240.0/22 +103.50.244.0/22 +103.50.248.0/22 +103.52.40.0/22 +103.52.72.0/22 +103.52.76.0/22 +103.52.80.0/22 +103.52.84.0/22 +103.52.96.0/22 +103.52.100.0/22 +103.52.104.0/22 +103.52.160.0/22 +103.52.164.0/22 +103.52.172.0/22 +103.52.176.0/22 +103.52.184.0/22 +103.52.196.0/22 +103.53.4.0/22 +103.53.64.0/22 +103.53.68.0/22 +103.53.92.0/22 +103.53.100.0/22 +103.53.124.0/22 +103.53.128.0/22 +103.53.132.0/22 +103.53.136.0/22 +103.53.140.0/22 +103.53.144.0/22 +103.53.180.0/22 +103.53.204.0/22 +103.53.208.0/22 +103.53.212.0/22 +103.53.216.0/22 +103.53.236.0/22 +103.53.248.0/22 +103.54.8.0/22 +103.54.48.0/22 +103.54.60.0/22 +103.54.160.0/22 +103.54.164.0/22 +103.54.212.0/22 +103.54.240.0/22 +103.55.24.0/22 +103.55.80.0/22 +103.55.120.0/22 +103.55.152.0/22 +103.55.172.0/22 +103.55.204.0/22 +103.55.208.0/22 +103.55.228.0/22 +103.55.236.0/22 +103.56.8.0/22 +103.56.16.0/22 +103.56.20.0/22 +103.56.32.0/22 +103.56.52.0/22 +103.56.56.0/22 +103.56.60.0/22 +103.56.72.0/22 +103.56.76.0/22 +103.56.140.0/22 +103.56.152.0/22 +103.56.184.0/22 +103.56.200.0/22 +103.57.12.0/22 +103.57.52.0/22 +103.57.56.0/22 +103.57.76.0/22 +103.57.136.0/22 +103.57.196.0/22 +103.58.24.0/22 +103.59.76.0/22 +103.59.100.0/22 +103.59.112.0/22 +103.59.116.0/22 +103.59.120.0/22 +103.59.124.0/22 +103.59.128.0/22 +103.59.148.0/22 +103.59.164.0/22 +103.60.32.0/22 +103.60.44.0/22 +103.60.164.0/22 +103.60.228.0/22 +103.60.236.0/22 +103.61.60.0/22 +103.61.104.0/22 +103.61.140.0/22 +103.61.152.0/22 +103.61.156.0/22 +103.61.160.0/22 +103.61.172.0/22 +103.61.176.0/22 +103.61.184.0/22 +103.61.188.0/22 +103.62.24.0/22 +103.62.52.0/22 +103.62.72.0/22 +103.62.76.0/22 +103.62.80.0/22 +103.62.84.0/22 +103.62.88.0/22 +103.62.96.0/22 +103.62.100.0/22 +103.62.104.0/22 +103.62.108.0/22 +103.62.112.0/22 +103.62.116.0/22 +103.62.120.0/22 +103.62.124.0/22 +103.62.128.0/22 +103.62.132.0/22 +103.62.156.0/22 +103.62.160.0/22 +103.62.164.0/22 +103.62.168.0/22 +103.62.172.0/22 +103.62.176.0/22 +103.62.180.0/22 +103.62.184.0/22 +103.62.188.0/22 +103.62.192.0/22 +103.62.204.0/22 +103.62.208.0/22 +103.62.212.0/22 +103.62.216.0/22 +103.62.220.0/22 +103.62.224.0/22 +103.63.32.0/22 +103.63.36.0/22 +103.63.40.0/22 +103.63.44.0/22 +103.63.48.0/22 +103.63.52.0/22 +103.63.56.0/22 +103.63.60.0/22 +103.63.64.0/22 +103.63.68.0/22 +103.63.72.0/22 +103.63.76.0/22 +103.63.80.0/22 +103.63.84.0/22 +103.63.88.0/22 +103.63.140.0/22 +103.63.144.0/22 +103.63.152.0/22 +103.63.160.0/22 +103.63.164.0/22 +103.63.168.0/22 +103.63.172.0/22 +103.63.176.0/22 +103.63.180.0/22 +103.63.184.0/22 +103.63.192.0/22 +103.63.196.0/22 +103.63.200.0/22 +103.63.204.0/22 +103.63.208.0/22 +103.63.240.0/22 +103.63.244.0/22 +103.63.248.0/22 +103.63.252.0/22 +103.64.0.0/22 +103.64.4.0/22 +103.64.24.0/22 +103.64.28.0/22 +103.64.32.0/22 +103.64.36.0/22 +103.64.40.0/22 +103.64.44.0/22 +103.64.48.0/22 +103.64.52.0/22 +103.64.56.0/22 +103.64.60.0/22 +103.64.64.0/22 +103.64.68.0/22 +103.64.72.0/22 +103.64.76.0/22 +103.64.80.0/22 +103.64.84.0/22 +103.64.88.0/22 +103.64.92.0/22 +103.64.96.0/22 +103.64.100.0/22 +103.64.104.0/22 +103.64.108.0/22 +103.64.112.0/22 +103.64.116.0/22 +103.64.120.0/22 +103.64.124.0/22 +103.64.140.0/22 +103.64.144.0/22 +103.64.152.0/22 +103.64.156.0/22 +103.64.160.0/22 +103.64.164.0/22 +103.64.168.0/22 +103.64.172.0/22 +103.64.176.0/22 +103.64.180.0/22 +103.64.184.0/22 +103.64.188.0/22 +103.64.192.0/22 +103.64.196.0/22 +103.64.200.0/22 +103.64.204.0/22 +103.64.208.0/22 +103.64.212.0/22 +103.64.216.0/22 +103.64.220.0/22 +103.64.224.0/22 +103.64.228.0/22 +103.64.232.0/22 +103.64.236.0/22 +103.64.240.0/22 +103.64.244.0/22 +103.64.248.0/22 +103.64.252.0/22 +103.65.0.0/22 +103.65.4.0/22 +103.65.8.0/22 +103.65.12.0/22 +103.65.16.0/22 +103.65.36.0/22 +103.65.40.0/22 +103.65.48.0/22 +103.65.52.0/22 +103.65.56.0/22 +103.65.60.0/22 +103.65.64.0/22 +103.65.68.0/22 +103.65.72.0/22 +103.65.76.0/22 +103.65.80.0/22 +103.65.84.0/22 +103.65.88.0/22 +103.65.92.0/22 +103.65.100.0/22 +103.65.104.0/22 +103.65.108.0/22 +103.65.112.0/22 +103.65.144.0/22 +103.65.148.0/22 +103.65.152.0/22 +103.65.156.0/22 +103.65.160.0/22 +103.65.164.0/22 +103.65.168.0/22 +103.65.172.0/22 +103.66.32.0/22 +103.66.40.0/22 +103.66.92.0/22 +103.66.108.0/22 +103.66.200.0/22 +103.66.216.0/22 +103.66.240.0/22 +103.66.244.0/22 +103.66.248.0/22 +103.66.252.0/22 +103.67.0.0/22 +103.67.4.0/22 +103.67.8.0/22 +103.67.100.0/22 +103.67.104.0/22 +103.67.108.0/22 +103.67.112.0/22 +103.67.116.0/22 +103.67.120.0/22 +103.67.124.0/22 +103.67.128.0/22 +103.67.132.0/22 +103.67.136.0/22 +103.67.140.0/22 +103.67.144.0/22 +103.67.148.0/22 +103.67.172.0/22 +103.67.192.0/22 +103.67.212.0/22 +103.67.252.0/22 +103.68.64.0/22 +103.68.88.0/22 +103.68.100.0/22 +103.68.128.0/22 +103.68.192.0/22 +103.69.16.0/22 +103.69.116.0/22 +103.69.132.0/22 +103.69.152.0/22 +103.69.212.0/22 +103.70.8.0/22 +103.70.148.0/22 +103.70.184.0/22 +103.70.220.0/22 +103.70.224.0/22 +103.70.236.0/22 +103.70.252.0/22 +103.71.0.0/22 +103.71.32.0/22 +103.71.48.0/22 +103.71.68.0/22 +103.71.72.0/22 +103.71.80.0/22 +103.71.84.0/22 +103.71.88.0/22 +103.71.120.0/22 +103.71.124.0/22 +103.71.128.0/22 +103.71.144.0/22 +103.71.196.0/22 +103.71.200.0/22 +103.71.232.0/22 +103.72.12.0/22 +103.72.16.0/22 +103.72.20.0/22 +103.72.24.0/22 +103.72.28.0/22 +103.72.32.0/22 +103.72.36.0/22 +103.72.40.0/22 +103.72.44.0/22 +103.72.48.0/22 +103.72.52.0/22 +103.72.112.0/22 +103.72.116.0/22 +103.72.120.0/22 +103.72.124.0/22 +103.72.128.0/22 +103.72.132.0/22 +103.72.144.0/22 +103.72.148.0/22 +103.72.172.0/22 +103.72.180.0/22 +103.72.224.0/22 +103.72.228.0/22 +103.72.232.0/22 +103.72.236.0/22 +103.72.240.0/22 +103.72.244.0/22 +103.72.248.0/22 +103.72.252.0/22 +103.73.0.0/22 +103.73.4.0/22 +103.73.8.0/22 +103.73.12.0/22 +103.73.16.0/22 +103.73.20.0/22 +103.73.24.0/22 +103.73.28.0/22 +103.73.48.0/22 +103.73.88.0/22 +103.73.96.0/22 +103.73.116.0/22 +103.73.120.0/22 +103.73.128.0/22 +103.73.132.0/22 +103.73.136.0/22 +103.73.140.0/22 +103.73.144.0/22 +103.73.168.0/22 +103.73.176.0/22 +103.73.204.0/22 +103.73.208.0/22 +103.73.240.0/22 +103.73.244.0/22 +103.73.248.0/22 +103.74.24.0/22 +103.74.28.0/22 +103.74.32.0/22 +103.74.36.0/22 +103.74.40.0/22 +103.74.44.0/22 +103.74.48.0/22 +103.74.56.0/22 +103.74.60.0/22 +103.74.80.0/22 +103.74.124.0/22 +103.74.148.0/22 +103.74.152.0/22 +103.74.156.0/22 +103.74.204.0/22 +103.74.232.0/22 +103.75.16.0/22 +103.75.88.0/22 +103.75.92.0/22 +103.75.104.0/22 +103.75.108.0/22 +103.75.112.0/22 +103.75.120.0/22 +103.75.128.0/22 +103.75.144.0/22 +103.75.152.0/22 +103.75.236.0/24 +103.76.60.0/22 +103.76.64.0/22 +103.76.68.0/22 +103.76.72.0/22 +103.76.84.0/22 +103.76.92.0/22 +103.76.104.0/22 +103.76.216.0/22 +103.76.220.0/22 +103.76.224.0/22 +103.77.28.0/22 +103.77.52.0/22 +103.77.56.0/22 +103.77.72.0/22 +103.77.88.0/22 +103.77.92.0/22 +103.77.132.0/22 +103.77.148.0/22 +103.77.220.0/22 +103.78.56.0/22 +103.78.60.0/22 +103.78.64.0/22 +103.78.68.0/22 +103.78.124.0/22 +103.78.172.0/22 +103.78.176.0/22 +103.78.196.0/22 +103.78.228.0/22 +103.79.24.0/22 +103.79.28.0/22 +103.79.36.0/22 +103.79.40.0/22 +103.79.44.0/22 +103.79.52.0/22 +103.79.56.0/22 +103.79.60.0/22 +103.79.64.0/22 +103.79.68.0/22 +103.79.80.0/22 +103.79.84.0/22 +103.79.120.0/22 +103.79.136.0/22 +103.79.188.0/22 +103.79.192.0/22 +103.79.196.0/22 +103.79.200.0/22 +103.79.204.0/22 +103.79.208.0/22 +103.79.212.0/22 +103.79.240.0/22 +103.80.24.0/22 +103.80.28.0/22 +103.80.44.0/22 +103.80.72.0/22 +103.80.176.0/22 +103.80.180.0/22 +103.80.184.0/22 +103.80.192.0/22 +103.80.200.0/22 +103.80.232.0/22 +103.81.4.0/22 +103.81.8.0/22 +103.81.16.0/22 +103.81.20.0/22 +103.81.44.0/22 +103.81.48.0/22 +103.81.96.0/22 +103.81.120.0/22 +103.81.148.0/22 +103.81.164.0/22 +103.81.168.0/22 +103.81.183.0/24 +103.81.184.0/22 +103.81.200.0/22 +103.81.232.0/22 +103.82.52.0/22 +103.82.60.0/22 +103.82.68.0/22 +103.82.84.0/22 +103.82.104.0/22 +103.82.224.0/22 +103.82.236.0/22 +103.83.44.0/22 +103.83.52.0/22 +103.83.60.0/22 +103.83.64.0/22 +103.83.72.0/22 +103.83.112.0/22 +103.83.120.0/22 +103.83.180.0/22 +103.84.0.0/22 +103.84.12.0/22 +103.84.16.0/22 +103.84.20.0/22 +103.84.24.0/22 +103.84.28.0/22 +103.84.48.0/22 +103.84.64.0/22 +103.84.72.0/22 +103.84.92.0/22 +103.84.108.0/22 +103.84.136.0/22 +103.85.20.0/22 +103.85.24.0/22 +103.85.44.0/22 +103.85.48.0/22 +103.85.84.0/22 +103.85.136.0/22 +103.85.144.0/22 +103.85.164.0/22 +103.85.168.0/22 +103.85.172.0/22 +103.85.176.0/22 +103.85.224.0/22 +103.86.28.0/22 +103.86.32.0/22 +103.86.44.0/22 +103.86.60.0/22 +103.86.68.0/22 +103.86.80.0/22 +103.86.84.0/22 +103.86.88.0/22 +103.86.204.0/22 +103.86.208.0/22 +103.86.212.0/22 +103.86.216.0/22 +103.86.220.0/22 +103.86.224.0/22 +103.86.228.0/22 +103.86.232.0/22 +103.86.236.0/22 +103.86.240.0/22 +103.86.244.0/22 +103.86.248.0/22 +103.86.252.0/22 +103.87.0.0/22 +103.87.4.0/22 +103.87.20.0/22 +103.87.32.0/22 +103.87.72.0/22 +103.87.96.0/22 +103.87.132.0/22 +103.87.180.0/22 +103.87.224.0/22 +103.88.4.0/22 +103.88.8.0/22 +103.88.12.0/22 +103.88.16.0/22 +103.88.20.0/22 +103.88.32.0/22 +103.88.36.0/22 +103.88.60.0/22 +103.88.64.0/22 +103.88.72.0/22 +103.88.96.0/22 +103.88.100.0/22 +103.88.164.0/22 +103.88.176.0/22 +103.88.184.0/22 +103.88.188.0/22 +103.88.212.0/22 +103.89.28.0/22 +103.89.96.0/22 +103.89.100.0/22 +103.89.104.0/22 +103.89.108.0/22 +103.89.112.0/22 +103.89.116.0/22 +103.89.148.0/22 +103.89.172.0/22 +103.89.184.0/22 +103.89.188.0/22 +103.89.192.0/22 +103.89.196.0/22 +103.89.200.0/22 +103.89.204.0/22 +103.89.208.0/22 +103.89.212.0/22 +103.89.216.0/22 +103.89.220.0/22 +103.89.224.0/22 +103.89.228.0/22 +103.90.52.0/22 +103.90.92.0/22 +103.90.100.0/22 +103.90.104.0/22 +103.90.108.0/22 +103.90.112.0/22 +103.90.116.0/22 +103.90.120.0/22 +103.90.124.0/22 +103.90.128.0/22 +103.90.132.0/22 +103.90.152.0/22 +103.90.168.0/22 +103.90.173.0/24 +103.90.176.0/22 +103.90.188.0/22 +103.90.192.0/22 +103.91.36.0/22 +103.91.40.0/22 +103.91.108.0/22 +103.91.152.0/22 +103.91.176.0/22 +103.91.200.0/22 +103.91.208.0/22 +103.91.212.0/22 +103.91.219.0/24 +103.91.236.0/22 +103.91.252.0/22 +103.92.0.0/22 +103.92.4.0/22 +103.92.8.0/22 +103.92.12.0/22 +103.92.48.0/22 +103.92.52.0/22 +103.92.56.0/22 +103.92.60.0/22 +103.92.64.0/22 +103.92.68.0/22 +103.92.72.0/22 +103.92.76.0/22 +103.92.80.0/22 +103.92.86.0/24 +103.92.88.0/22 +103.92.108.0/22 +103.92.124.0/22 +103.92.128.0/24 +103.92.132.0/22 +103.92.156.0/22 +103.92.164.0/22 +103.92.168.0/22 +103.92.172.0/22 +103.92.176.0/22 +103.92.180.0/22 +103.92.184.0/22 +103.92.188.0/22 +103.92.192.0/22 +103.92.236.0/22 +103.92.240.0/22 +103.92.244.0/22 +103.92.248.0/22 +103.92.252.0/22 +103.93.0.0/22 +103.93.4.0/22 +103.93.28.0/22 +103.93.76.0/22 +103.93.84.0/22 +103.93.121.0/24 +103.93.152.0/22 +103.93.180.0/22 +103.93.204.0/22 +103.94.12.0/22 +103.94.20.0/22 +103.94.28.0/22 +103.94.32.0/22 +103.94.36.0/22 +103.94.40.0/22 +103.94.44.0/22 +103.94.72.0/22 +103.94.88.0/22 +103.94.116.0/22 +103.94.160.0/22 +103.94.180.0/22 +103.94.200.0/22 +103.95.28.0/22 +103.95.52.0/22 +103.95.64.0/22 +103.95.68.0/22 +103.95.88.0/22 +103.95.92.0/22 +103.95.116.0/22 +103.95.128.0/22 +103.95.136.0/22 +103.95.140.0/22 +103.95.144.0/22 +103.95.152.0/22 +103.95.207.0/24 +103.95.216.0/22 +103.95.220.0/22 +103.95.224.0/22 +103.95.236.0/22 +103.95.240.0/22 +103.95.244.0/22 +103.95.248.0/22 +103.95.252.0/22 +103.96.0.0/22 +103.96.8.0/22 +103.96.80.0/22 +103.96.124.0/22 +103.96.136.0/22 +103.96.140.0/24 +103.96.148.0/22 +103.96.152.0/22 +103.96.156.0/22 +103.96.160.0/22 +103.96.164.0/22 +103.96.168.0/22 +103.96.172.0/22 +103.96.176.0/22 +103.96.180.0/22 +103.96.184.0/22 +103.96.188.0/22 +103.96.192.0/22 +103.96.196.0/22 +103.96.200.0/22 +103.96.204.0/22 +103.96.208.0/22 +103.96.212.0/22 +103.96.216.0/22 +103.97.8.0/22 +103.97.12.0/22 +103.97.16.0/22 +103.97.20.0/22 +103.97.24.0/22 +103.97.28.0/22 +103.97.32.0/22 +103.97.36.0/22 +103.97.40.0/22 +103.97.56.0/22 +103.97.60.0/22 +103.97.64.0/22 +103.97.68.0/22 +103.97.72.0/22 +103.97.80.0/22 +103.97.112.0/22 +103.97.116.0/22 +103.97.128.0/22 +103.97.144.0/22 +103.97.148.0/22 +103.97.188.0/22 +103.97.192.0/22 +103.97.224.0/22 +103.97.228.0/23 +103.98.28.0/23 +103.98.40.0/22 +103.98.44.0/22 +103.98.48.0/22 +103.98.56.0/22 +103.98.80.0/22 +103.98.88.0/22 +103.98.92.0/22 +103.98.96.0/22 +103.98.100.0/22 +103.98.124.0/22 +103.98.136.0/22 +103.98.140.0/22 +103.98.144.0/22 +103.98.164.0/22 +103.98.168.0/22 +103.98.180.0/22 +103.98.196.0/22 +103.98.216.0/22 +103.98.220.0/22 +103.98.224.0/22 +103.98.228.0/22 +103.98.232.0/22 +103.98.240.0/22 +103.98.244.0/22 +103.98.248.0/22 +103.98.252.0/22 +103.99.40.0/23 +103.99.52.0/22 +103.99.56.0/22 +103.99.60.0/22 +103.99.76.0/22 +103.99.104.0/22 +103.99.116.0/22 +103.99.120.0/22 +103.99.152.0/22 +103.99.220.0/22 +103.99.232.0/22 +103.99.236.0/22 +103.100.0.0/22 +103.100.32.0/22 +103.100.40.0/22 +103.100.48.0/22 +103.100.52.0/22 +103.100.56.0/22 +103.100.60.0/22 +103.100.64.0/22 +103.100.68.0/22 +103.100.88.0/22 +103.100.116.0/22 +103.100.140.0/22 +103.100.144.0/22 +103.100.236.0/22 +103.100.240.0/22 +103.100.248.0/22 +103.100.252.0/22 +103.101.4.0/22 +103.101.8.0/22 +103.101.12.0/22 +103.101.28.0/22 +103.101.60.0/22 +103.101.120.0/22 +103.101.124.0/22 +103.101.144.0/22 +103.101.148.0/22 +103.101.153.0/24 +103.101.180.0/22 +103.101.184.0/22 +103.102.76.0/22 +103.102.80.0/22 +103.102.168.0/22 +103.102.172.0/22 +103.102.180.0/22 +103.102.184.0/22 +103.102.188.0/22 +103.102.192.0/22 +103.102.196.0/22 +103.102.200.0/22 +103.102.208.0/22 +103.102.212.0/22 +103.103.12.0/22 +103.103.16.0/22 +103.103.36.0/22 +103.103.68.0/22 +103.103.72.0/22 +103.103.176.0/22 +103.103.188.0/22 +103.103.200.0/22 +103.103.204.0/22 +103.103.220.0/22 +103.103.224.0/22 +103.103.228.0/22 +103.103.232.0/22 +103.103.248.0/22 +103.103.252.0/22 +103.104.0.0/22 +103.104.4.0/22 +103.104.36.0/22 +103.104.40.0/22 +103.104.64.0/22 +103.104.104.0/22 +103.104.152.0/22 +103.104.168.0/22 +103.104.172.0/22 +103.104.188.0/22 +103.104.198.0/23 +103.104.252.0/22 +103.105.0.0/22 +103.105.4.0/22 +103.105.12.0/22 +103.105.16.0/22 +103.105.23.0/24 +103.105.56.0/22 +103.105.60.0/22 +103.105.116.0/22 +103.105.132.0/22 +103.105.180.0/22 +103.105.184.0/22 +103.105.200.0/22 +103.105.204.0/22 +103.105.220.0/22 +103.106.36.0/22 +103.106.40.0/22 +103.106.44.0/22 +103.106.60.0/22 +103.106.68.0/22 +103.106.96.0/22 +103.106.120.0/22 +103.106.128.0/22 +103.106.132.0/22 +103.106.160.0/22 +103.106.188.0/22 +103.106.196.0/22 +103.106.202.0/23 +103.106.212.0/22 +103.106.244.0/22 +103.106.252.0/22 +103.107.0.0/22 +103.107.8.0/24 +103.107.28.0/22 +103.107.32.0/22 +103.107.44.0/22 +103.107.72.0/22 +103.107.108.0/22 +103.107.164.0/22 +103.107.168.0/22 +103.107.188.0/22 +103.107.192.0/22 +103.107.208.0/22 +103.107.212.0/22 +103.107.216.0/22 +103.107.220.0/22 +103.108.52.0/22 +103.108.64.0/22 +103.108.160.0/22 +103.108.164.0/22 +103.108.184.0/23 +103.108.188.0/23 +103.108.192.0/22 +103.108.196.0/22 +103.108.208.0/22 +103.108.212.0/22 +103.108.224.0/22 +103.108.244.0/22 +103.108.251.0/24 +103.109.20.0/22 +103.109.48.0/22 +103.109.88.0/22 +103.109.106.0/23 +103.109.248.0/22 +103.110.32.0/22 +103.110.80.0/23 +103.110.92.0/22 +103.110.100.0/22 +103.110.116.0/22 +103.110.127.0/24 +103.110.128.0/23 +103.110.131.0/24 +103.110.132.0/22 +103.110.136.0/22 +103.110.152.0/22 +103.110.156.0/22 +103.110.188.0/22 +103.110.204.0/22 +103.111.38.0/23 +103.111.64.0/22 +103.111.172.0/22 +103.111.252.0/22 +103.112.28.0/22 +103.112.68.0/22 +103.112.72.0/22 +103.112.88.0/22 +103.112.92.0/22 +103.112.96.0/22 +103.112.108.0/22 +103.112.112.0/22 +103.112.116.0/22 +103.112.140.0/22 +103.112.172.0/22 +103.112.184.0/22 +103.112.208.0/22 +103.113.4.0/22 +103.113.92.0/22 +103.113.144.0/22 +103.113.220.0/22 +103.113.232.0/22 +103.113.236.0/22 +103.114.4.0/22 +103.114.28.0/22 +103.114.68.0/22 +103.114.72.0/22 +103.114.100.0/22 +103.114.132.0/22 +103.114.148.0/22 +103.114.156.0/22 +103.114.176.0/22 +103.114.212.0/22 +103.114.236.0/22 +103.114.240.0/22 +103.115.16.0/22 +103.115.40.0/22 +103.115.44.0/22 +103.115.48.0/22 +103.115.52.0/22 +103.115.56.0/22 +103.115.60.0/22 +103.115.64.0/22 +103.115.68.0/22 +103.115.92.0/22 +103.115.120.0/22 +103.115.148.0/22 +103.115.204.0/23 +103.115.248.0/22 +103.116.20.0/22 +103.116.40.0/22 +103.116.64.0/22 +103.116.72.0/22 +103.116.76.0/22 +103.116.92.0/22 +103.116.120.0/22 +103.116.128.0/22 +103.116.132.0/23 +103.116.148.0/22 +103.116.184.0/22 +103.116.206.0/23 +103.116.220.0/22 +103.116.224.0/22 +103.116.228.0/22 +103.117.16.0/22 +103.117.72.0/22 +103.117.88.0/22 +103.117.132.0/22 +103.117.136.0/22 +103.117.188.0/22 +103.117.220.0/22 +103.118.19.0/24 +103.118.36.0/22 +103.118.52.0/22 +103.118.56.0/22 +103.118.60.0/22 +103.118.64.0/22 +103.118.68.0/22 +103.118.72.0/22 +103.118.88.0/22 +103.118.173.0/24 +103.118.192.0/22 +103.118.196.0/22 +103.118.200.0/22 +103.118.204.0/22 +103.118.208.0/22 +103.118.212.0/22 +103.118.216.0/22 +103.118.220.0/22 +103.118.240.0/22 +103.118.244.0/22 +103.118.248.0/22 +103.118.252.0/22 +103.119.0.0/22 +103.119.12.0/22 +103.119.16.0/22 +103.119.28.0/22 +103.119.44.0/22 +103.119.104.0/22 +103.119.115.0/24 +103.119.156.0/22 +103.119.180.0/22 +103.119.200.0/22 +103.119.224.0/22 +103.120.52.0/22 +103.120.72.0/22 +103.120.76.0/24 +103.120.88.0/22 +103.120.96.0/22 +103.120.100.0/22 +103.120.140.0/22 +103.120.196.0/22 +103.120.224.0/22 +103.121.52.0/22 +103.121.92.0/22 +103.121.160.0/22 +103.121.164.0/22 +103.121.250.0/24 +103.121.252.0/22 +103.122.48.0/22 +103.122.176.0/22 +103.122.192.0/22 +103.122.240.0/22 +103.123.4.0/22 +103.123.56.0/22 +103.123.88.0/22 +103.123.92.0/22 +103.123.116.0/22 +103.123.160.0/22 +103.123.176.0/22 +103.123.200.0/22 +103.123.204.0/22 +103.123.208.0/22 +103.123.212.0/22 +103.124.24.0/22 +103.124.48.0/22 +103.124.64.0/22 +103.124.212.0/22 +103.124.216.0/22 +103.125.20.0/22 +103.125.44.0/22 +103.129.52.0/22 +103.129.148.0/22 +103.130.132.0/22 +103.130.152.0/24 +103.130.160.0/22 +103.130.228.0/22 +103.131.20.0/22 +103.131.36.0/22 +103.131.152.0/22 +103.131.168.0/22 +103.131.176.0/22 +103.131.224.0/22 +103.131.228.0/22 +103.131.240.0/22 +103.192.0.0/22 +103.192.4.0/22 +103.192.8.0/22 +103.192.12.0/22 +103.192.16.0/22 +103.192.20.0/22 +103.192.24.0/22 +103.192.28.0/22 +103.192.48.0/22 +103.192.52.0/22 +103.192.56.0/22 +103.192.84.0/22 +103.192.88.0/22 +103.192.92.0/22 +103.192.96.0/22 +103.192.100.0/22 +103.192.104.0/22 +103.192.108.0/22 +103.192.112.0/22 +103.192.128.0/22 +103.192.132.0/22 +103.192.136.0/22 +103.192.140.0/22 +103.192.144.0/22 +103.192.164.0/22 +103.192.188.0/22 +103.192.208.0/22 +103.192.212.0/22 +103.192.216.0/22 +103.192.252.0/22 +103.193.40.0/22 +103.193.44.0/22 +103.193.120.0/22 +103.193.124.0/22 +103.193.140.0/22 +103.193.144.0/22 +103.193.148.0/22 +103.193.160.0/22 +103.193.188.0/22 +103.193.192.0/22 +103.193.212.0/22 +103.193.216.0/22 +103.193.220.0/22 +103.193.224.0/22 +103.193.228.0/22 +103.193.232.0/22 +103.193.236.0/22 +103.193.240.0/22 +103.194.16.0/22 +103.195.104.0/22 +103.195.112.0/22 +103.195.136.0/22 +103.195.148.0/22 +103.195.152.0/22 +103.195.160.0/22 +103.195.192.0/22 +103.196.60.0/22 +103.196.64.0/22 +103.196.72.0/22 +103.196.88.0/22 +103.196.92.0/22 +103.196.96.0/22 +103.196.168.0/22 +103.196.204.0/22 +103.197.180.0/22 +103.197.228.0/22 +103.198.20.0/22 +103.198.60.0/22 +103.198.64.0/22 +103.198.72.0/22 +103.198.124.0/22 +103.198.156.0/22 +103.198.180.0/22 +103.198.196.0/22 +103.198.200.0/22 +103.198.216.0/22 +103.198.220.0/22 +103.198.224.0/22 +103.198.228.0/22 +103.198.232.0/22 +103.198.236.0/22 +103.198.240.0/22 +103.198.244.0/22 +103.199.164.0/22 +103.199.196.0/22 +103.199.228.0/22 +103.199.248.0/22 +103.199.252.0/22 +103.200.28.0/22 +103.200.32.0/22 +103.200.52.0/22 +103.200.64.0/22 +103.200.68.0/22 +103.200.136.0/22 +103.200.140.0/22 +103.200.144.0/22 +103.200.148.0/22 +103.200.152.0/22 +103.200.156.0/22 +103.200.160.0/22 +103.200.164.0/22 +103.200.168.0/22 +103.200.172.0/22 +103.200.176.0/22 +103.200.180.0/22 +103.200.184.0/22 +103.200.188.0/22 +103.200.192.0/22 +103.200.220.0/22 +103.200.224.0/22 +103.200.228.0/22 +103.200.232.0/22 +103.200.236.0/22 +103.200.240.0/22 +103.200.244.0/22 +103.200.248.0/22 +103.200.252.0/22 +103.201.0.0/22 +103.201.4.0/22 +103.201.8.0/22 +103.201.12.0/22 +103.201.16.0/22 +103.201.20.0/22 +103.201.28.0/22 +103.201.32.0/22 +103.201.36.0/22 +103.201.40.0/22 +103.201.44.0/22 +103.201.48.0/22 +103.201.52.0/22 +103.201.56.0/22 +103.201.60.0/22 +103.201.64.0/22 +103.201.76.0/22 +103.201.80.0/22 +103.201.84.0/22 +103.201.88.0/22 +103.201.92.0/22 +103.201.96.0/22 +103.201.100.0/22 +103.201.104.0/22 +103.201.108.0/22 +103.201.112.0/22 +103.201.116.0/22 +103.201.120.0/22 +103.201.152.0/22 +103.201.156.0/22 +103.201.160.0/22 +103.201.164.0/22 +103.201.168.0/22 +103.201.172.0/22 +103.201.176.0/22 +103.201.180.0/22 +103.201.184.0/22 +103.201.188.0/22 +103.201.192.0/22 +103.201.196.0/22 +103.201.200.0/22 +103.201.204.0/22 +103.201.208.0/22 +103.201.212.0/22 +103.201.216.0/22 +103.201.220.0/22 +103.201.224.0/22 +103.201.228.0/22 +103.201.232.0/22 +103.201.236.0/22 +103.201.240.0/22 +103.201.244.0/22 +103.201.248.0/22 +103.201.252.0/22 +103.202.0.0/22 +103.202.4.0/22 +103.202.8.0/22 +103.202.12.0/22 +103.202.16.0/22 +103.202.20.0/22 +103.202.24.0/22 +103.202.28.0/22 +103.202.32.0/22 +103.202.36.0/22 +103.202.40.0/22 +103.202.44.0/22 +103.202.56.0/22 +103.202.60.0/22 +103.202.64.0/22 +103.202.68.0/22 +103.202.72.0/22 +103.202.76.0/22 +103.202.80.0/22 +103.202.84.0/22 +103.202.88.0/22 +103.202.92.0/22 +103.202.96.0/22 +103.202.100.0/22 +103.202.104.0/22 +103.202.108.0/22 +103.202.112.0/22 +103.202.116.0/22 +103.202.120.0/22 +103.202.124.0/22 +103.202.128.0/22 +103.202.132.0/22 +103.202.136.0/22 +103.202.140.0/22 +103.202.144.0/22 +103.202.152.0/22 +103.202.156.0/22 +103.202.160.0/22 +103.202.164.0/22 +103.202.168.0/22 +103.202.172.0/22 +103.202.176.0/22 +103.202.180.0/22 +103.202.184.0/22 +103.202.188.0/22 +103.202.192.0/22 +103.202.196.0/22 +103.202.200.0/21 +103.202.212.0/22 +103.202.228.0/22 +103.202.236.0/22 +103.202.240.0/22 +103.202.244.0/22 +103.202.248.0/22 +103.202.252.0/22 +103.203.0.0/22 +103.203.4.0/22 +103.203.8.0/22 +103.203.12.0/22 +103.203.16.0/22 +103.203.20.0/22 +103.203.24.0/22 +103.203.28.0/22 +103.203.32.0/22 +103.203.52.0/22 +103.203.56.0/22 +103.203.96.0/22 +103.203.100.0/22 +103.203.104.0/22 +103.203.108.0/22 +103.203.112.0/22 +103.203.116.0/22 +103.203.120.0/22 +103.203.124.0/22 +103.203.128.0/22 +103.203.140.0/22 +103.203.164.0/22 +103.203.168.0/22 +103.203.192.0/22 +103.203.200.0/22 +103.203.212.0/22 +103.203.216.0/22 +103.204.24.0/22 +103.204.72.0/22 +103.204.88.0/22 +103.204.112.0/22 +103.204.136.0/22 +103.204.140.0/22 +103.204.144.0/22 +103.204.148.0/22 +103.204.152.0/22 +103.204.196.0/22 +103.204.232.0/22 +103.204.236.0/22 +103.205.4.0/22 +103.205.8.0/22 +103.205.40.0/22 +103.205.44.0/22 +103.205.52.0/22 +103.205.108.0/22 +103.205.116.0/22 +103.205.120.0/22 +103.205.136.0/22 +103.205.162.0/24 +103.205.188.0/22 +103.205.192.0/22 +103.205.196.0/22 +103.205.200.0/22 +103.205.236.0/22 +103.205.248.0/22 +103.205.252.0/22 +103.206.0.0/22 +103.206.44.0/22 +103.206.108.0/22 +103.206.148.0/22 +103.207.48.0/22 +103.207.104.0/22 +103.207.164.0/22 +103.207.184.0/22 +103.207.188.0/22 +103.207.192.0/22 +103.207.196.0/22 +103.207.200.0/22 +103.207.204.0/22 +103.207.208.0/22 +103.207.212.0/22 +103.207.220.0/22 +103.207.228.0/22 +103.207.232.0/22 +103.208.12.0/22 +103.208.16.0/22 +103.208.28.0/22 +103.208.40.0/22 +103.208.44.0/22 +103.208.48.0/22 +103.208.148.0/22 +103.209.112.0/22 +103.209.136.0/22 +103.209.200.0/22 +103.209.208.0/22 +103.209.216.0/22 +103.210.0.0/22 +103.210.20.0/22 +103.210.96.0/22 +103.210.156.0/22 +103.210.160.0/22 +103.210.164.0/22 +103.210.168.0/22 +103.210.172.0/22 +103.210.176.0/22 +103.210.180.0/22 +103.210.184.0/22 +103.210.188.0/22 +103.210.216.0/22 +103.211.44.0/22 +103.211.96.0/22 +103.211.100.0/22 +103.211.156.0/22 +103.211.164.0/22 +103.211.192.0/22 +103.211.220.0/22 +103.211.224.0/22 +103.211.248.0/22 +103.212.0.0/22 +103.212.4.0/22 +103.212.8.0/22 +103.212.12.0/22 +103.212.32.0/22 +103.212.44.0/22 +103.212.48.0/22 +103.212.84.0/22 +103.212.100.0/22 +103.212.104.0/22 +103.212.108.0/22 +103.212.148.0/22 +103.212.164.0/22 +103.212.196.0/22 +103.212.200.0/22 +103.212.228.0/22 +103.212.252.0/22 +103.213.40.0/22 +103.213.44.0/22 +103.213.48.0/22 +103.213.52.0/22 +103.213.56.0/22 +103.213.60.0/22 +103.213.64.0/22 +103.213.68.0/22 +103.213.72.0/22 +103.213.76.0/22 +103.213.80.0/22 +103.213.84.0/22 +103.213.88.0/22 +103.213.92.0/22 +103.213.96.0/22 +103.213.132.0/22 +103.213.136.0/22 +103.213.140.0/22 +103.213.144.0/22 +103.213.148.0/22 +103.213.152.0/22 +103.213.156.0/22 +103.213.160.0/22 +103.213.164.0/22 +103.213.168.0/22 +103.213.172.0/22 +103.213.176.0/22 +103.213.180.0/22 +103.213.184.0/22 +103.213.188.0/22 +103.213.248.0/22 +103.214.32.0/22 +103.214.48.0/22 +103.214.84.0/22 +103.214.168.0/22 +103.214.212.0/22 +103.214.240.0/22 +103.214.244.0/22 +103.215.28.0/22 +103.215.32.0/22 +103.215.36.0/22 +103.215.44.0/22 +103.215.48.0/22 +103.215.100.0/22 +103.215.104.0/22 +103.215.108.0/22 +103.215.116.0/22 +103.215.120.0/22 +103.215.140.0/22 +103.215.184.0/22 +103.215.228.0/22 +103.216.4.0/22 +103.216.8.0/22 +103.216.12.0/22 +103.216.16.0/22 +103.216.20.0/22 +103.216.24.0/22 +103.216.28.0/22 +103.216.32.0/22 +103.216.36.0/22 +103.216.40.0/22 +103.216.44.0/22 +103.216.64.0/22 +103.216.108.0/22 +103.216.136.0/22 +103.216.152.0/22 +103.216.224.0/22 +103.216.228.0/22 +103.216.240.0/22 +103.216.244.0/22 +103.216.248.0/22 +103.216.252.0/22 +103.217.0.0/22 +103.217.4.0/22 +103.217.8.0/22 +103.217.12.0/22 +103.217.16.0/22 +103.217.20.0/22 +103.217.24.0/22 +103.217.28.0/22 +103.217.32.0/22 +103.217.36.0/22 +103.217.40.0/22 +103.217.44.0/22 +103.217.48.0/22 +103.217.52.0/22 +103.217.56.0/22 +103.217.60.0/22 +103.217.168.0/22 +103.217.180.0/22 +103.217.184.0/22 +103.217.188.0/22 +103.217.192.0/22 +103.217.196.0/22 +103.217.200.0/22 +103.217.204.0/22 +103.218.0.0/22 +103.218.8.0/22 +103.218.12.0/22 +103.218.16.0/22 +103.218.20.0/22 +103.218.28.0/22 +103.218.32.0/22 +103.218.36.0/22 +103.218.40.0/22 +103.218.44.0/22 +103.218.48.0/22 +103.218.52.0/22 +103.218.56.0/22 +103.218.60.0/22 +103.218.64.0/22 +103.218.68.0/22 +103.218.72.0/22 +103.218.76.0/22 +103.218.80.0/22 +103.218.84.0/22 +103.218.88.0/22 +103.218.92.0/22 +103.218.184.0/22 +103.218.192.0/22 +103.218.196.0/22 +103.218.200.0/22 +103.218.204.0/22 +103.218.208.0/22 +103.218.212.0/22 +103.218.216.0/22 +103.219.24.0/22 +103.219.28.0/22 +103.219.32.0/22 +103.219.36.0/22 +103.219.64.0/22 +103.219.84.0/22 +103.219.88.0/22 +103.219.92.0/22 +103.219.96.0/22 +103.219.100.0/22 +103.219.176.0/22 +103.219.184.0/22 +103.220.48.0/22 +103.220.52.0/22 +103.220.56.0/22 +103.220.60.0/22 +103.220.64.0/22 +103.220.92.0/22 +103.220.96.0/22 +103.220.100.0/22 +103.220.104.0/22 +103.220.108.0/22 +103.220.116.0/22 +103.220.120.0/22 +103.220.124.0/22 +103.220.128.0/22 +103.220.132.0/22 +103.220.136.0/22 +103.220.140.0/22 +103.220.144.0/22 +103.220.148.0/22 +103.220.152.0/22 +103.220.160.0/22 +103.220.164.0/22 +103.220.168.0/22 +103.220.172.0/22 +103.220.176.0/22 +103.220.180.0/22 +103.220.184.0/22 +103.220.188.0/22 +103.220.192.0/22 +103.220.196.0/22 +103.220.200.0/22 +103.220.240.0/22 +103.220.244.0/22 +103.220.248.0/22 +103.220.252.0/22 +103.221.0.0/22 +103.221.4.0/22 +103.221.8.0/22 +103.221.12.0/22 +103.221.16.0/22 +103.221.20.0/22 +103.221.24.0/22 +103.221.28.0/22 +103.221.32.0/22 +103.221.36.0/22 +103.221.40.0/22 +103.221.44.0/22 +103.221.48.0/22 +103.221.88.0/22 +103.221.92.0/22 +103.221.96.0/22 +103.221.100.0/22 +103.221.104.0/22 +103.221.108.0/22 +103.221.112.0/22 +103.221.116.0/22 +103.221.120.0/22 +103.221.124.0/22 +103.221.128.0/22 +103.221.132.0/22 +103.221.136.0/22 +103.221.140.0/22 +103.221.144.0/22 +103.221.148.0/22 +103.221.152.0/22 +103.221.156.0/22 +103.221.160.0/22 +103.221.164.0/22 +103.221.168.0/22 +103.221.172.0/22 +103.221.176.0/22 +103.221.180.0/22 +103.221.184.0/22 +103.221.188.0/22 +103.221.192.0/22 +103.221.196.0/22 +103.221.200.0/22 +103.221.204.0/22 +103.222.0.0/22 +103.222.4.0/22 +103.222.8.0/22 +103.222.12.0/22 +103.222.16.0/22 +103.222.24.0/22 +103.222.28.0/22 +103.222.32.0/22 +103.222.36.0/22 +103.222.40.0/22 +103.222.44.0/22 +103.222.48.0/22 +103.222.52.0/22 +103.222.56.0/22 +103.222.60.0/22 +103.222.64.0/22 +103.222.68.0/22 +103.222.72.0/22 +103.222.76.0/22 +103.222.80.0/22 +103.222.84.0/22 +103.222.88.0/22 +103.222.92.0/22 +103.222.96.0/22 +103.222.100.0/22 +103.222.104.0/22 +103.222.108.0/22 +103.222.112.0/22 +103.222.116.0/22 +103.222.120.0/22 +103.222.124.0/22 +103.222.128.0/22 +103.222.132.0/22 +103.222.136.0/22 +103.222.140.0/22 +103.222.144.0/22 +103.222.148.0/22 +103.222.152.0/22 +103.222.156.0/22 +103.222.160.0/22 +103.222.164.0/22 +103.222.168.0/22 +103.222.172.0/22 +103.222.176.0/22 +103.222.180.0/22 +103.222.184.0/22 +103.222.188.0/22 +103.222.192.0/22 +103.222.196.0/22 +103.222.200.0/22 +103.222.204.0/22 +103.222.208.0/22 +103.222.212.0/22 +103.222.216.0/22 +103.222.220.0/22 +103.222.224.0/22 +103.222.228.0/22 +103.222.232.0/22 +103.222.240.0/22 +103.222.244.0/22 +103.223.16.0/22 +103.223.20.0/22 +103.223.24.0/22 +103.223.28.0/22 +103.223.32.0/22 +103.223.36.0/22 +103.223.40.0/22 +103.223.44.0/22 +103.223.48.0/22 +103.223.52.0/22 +103.223.56.0/22 +103.223.60.0/22 +103.223.64.0/22 +103.223.68.0/22 +103.223.72.0/22 +103.223.76.0/22 +103.223.80.0/22 +103.223.84.0/22 +103.223.88.0/22 +103.223.92.0/22 +103.223.96.0/22 +103.223.100.0/22 +103.223.104.0/22 +103.223.108.0/22 +103.223.112.0/22 +103.223.116.0/22 +103.223.120.0/22 +103.223.124.0/22 +103.223.128.0/22 +103.223.132.0/22 +103.223.140.0/22 +103.223.144.0/22 +103.223.148.0/22 +103.223.152.0/22 +103.223.156.0/22 +103.223.160.0/22 +103.223.164.0/22 +103.223.168.0/22 +103.223.172.0/22 +103.223.176.0/22 +103.223.180.0/22 +103.223.188.0/22 +103.223.192.0/22 +103.223.196.0/22 +103.223.200.0/22 +103.223.204.0/22 +103.223.208.0/22 +103.223.212.0/22 +103.223.216.0/22 +103.223.220.0/22 +103.223.224.0/22 +103.223.228.0/22 +103.223.232.0/22 +103.223.236.0/22 +103.223.240.0/22 +103.223.244.0/22 +103.223.248.0/22 +103.223.252.0/22 +103.224.0.0/22 +103.224.40.0/22 +103.224.44.0/22 +103.224.60.0/22 +103.224.80.0/22 +103.224.220.0/22 +103.224.224.0/22 +103.224.228.0/22 +103.224.232.0/22 +103.225.84.0/22 +103.226.16.0/22 +103.226.40.0/22 +103.226.56.0/22 +103.226.60.0/22 +103.226.80.0/22 +103.226.132.0/22 +103.226.156.0/22 +103.226.180.0/22 +103.226.196.0/22 +103.227.48.0/22 +103.227.72.0/22 +103.227.76.0/22 +103.227.80.0/22 +103.227.100.0/22 +103.227.120.0/22 +103.227.132.0/22 +103.227.136.0/22 +103.227.196.0/22 +103.227.204.0/22 +103.227.212.0/22 +103.227.228.0/22 +103.228.12.0/22 +103.228.28.0/22 +103.228.68.0/22 +103.228.88.0/22 +103.228.128.0/22 +103.228.136.0/22 +103.228.160.0/22 +103.228.176.0/22 +103.228.204.0/22 +103.228.208.0/22 +103.228.228.0/22 +103.228.232.0/22 +103.229.20.0/22 +103.229.60.0/22 +103.229.136.0/22 +103.229.148.0/22 +103.229.172.0/22 +103.229.212.0/22 +103.229.216.0/22 +103.229.220.0/22 +103.229.228.0/22 +103.229.236.0/22 +103.229.240.0/22 +103.230.0.0/22 +103.230.28.0/22 +103.230.44.0/22 +103.230.96.0/22 +103.230.196.0/22 +103.230.200.0/22 +103.230.204.0/22 +103.230.212.0/22 +103.230.236.0/22 +103.231.16.0/22 +103.231.20.0/22 +103.231.64.0/22 +103.231.68.0/22 +103.231.144.0/22 +103.231.180.0/22 +103.231.184.0/22 +103.231.244.0/22 +103.232.4.0/22 +103.232.144.0/22 +103.232.188.0/22 +103.232.212.0/22 +103.233.4.0/22 +103.233.44.0/22 +103.233.52.0/22 +103.233.104.0/22 +103.233.128.0/22 +103.233.136.0/22 +103.233.228.0/22 +103.234.0.0/22 +103.234.20.0/22 +103.234.56.0/22 +103.234.128.0/22 +103.234.172.0/22 +103.234.180.0/22 +103.234.244.0/22 +103.235.16.0/22 +103.235.48.0/22 +103.235.56.0/22 +103.235.60.0/22 +103.235.80.0/22 +103.235.84.0/22 +103.235.128.0/22 +103.235.132.0/22 +103.235.136.0/22 +103.235.140.0/22 +103.235.144.0/22 +103.235.148.0/22 +103.235.184.0/22 +103.235.192.0/22 +103.235.200.0/22 +103.235.220.0/22 +103.235.224.0/22 +103.235.228.0/22 +103.235.232.0/22 +103.235.236.0/22 +103.235.240.0/22 +103.235.244.0/22 +103.235.248.0/22 +103.235.252.0/22 +103.236.0.0/22 +103.236.4.0/22 +103.236.8.0/22 +103.236.12.0/22 +103.236.16.0/22 +103.236.20.0/22 +103.236.24.0/22 +103.236.28.0/22 +103.236.32.0/22 +103.236.36.0/22 +103.236.40.0/22 +103.236.44.0/22 +103.236.48.0/22 +103.236.52.0/22 +103.236.56.0/22 +103.236.60.0/22 +103.236.64.0/22 +103.236.68.0/22 +103.236.72.0/22 +103.236.76.0/22 +103.236.80.0/22 +103.236.84.0/22 +103.236.88.0/22 +103.236.92.0/22 +103.236.96.0/22 +103.236.120.0/22 +103.236.184.0/22 +103.236.220.0/22 +103.236.232.0/22 +103.236.240.0/22 +103.236.244.0/22 +103.236.248.0/22 +103.236.252.0/22 +103.237.0.0/22 +103.237.4.0/22 +103.237.8.0/22 +103.237.12.0/22 +103.237.24.0/22 +103.237.28.0/22 +103.237.68.0/22 +103.237.88.0/22 +103.237.152.0/22 +103.237.176.0/22 +103.237.180.0/22 +103.237.184.0/22 +103.237.188.0/22 +103.237.192.0/22 +103.237.196.0/22 +103.237.200.0/22 +103.237.204.0/22 +103.237.208.0/22 +103.237.212.0/22 +103.237.216.0/22 +103.237.220.0/22 +103.237.224.0/22 +103.237.228.0/22 +103.237.232.0/22 +103.237.236.0/22 +103.237.240.0/22 +103.237.244.0/22 +103.237.248.0/22 +103.237.252.0/22 +103.238.0.0/22 +103.238.4.0/22 +103.238.16.0/22 +103.238.20.0/22 +103.238.24.0/22 +103.238.28.0/22 +103.238.32.0/22 +103.238.36.0/22 +103.238.40.0/22 +103.238.44.0/22 +103.238.48.0/22 +103.238.52.0/22 +103.238.56.0/22 +103.238.88.0/22 +103.238.92.0/22 +103.238.96.0/22 +103.238.132.0/22 +103.238.140.0/22 +103.238.144.0/22 +103.238.160.0/22 +103.238.164.0/22 +103.238.168.0/22 +103.238.172.0/22 +103.238.176.0/22 +103.238.180.0/22 +103.238.184.0/22 +103.238.188.0/22 +103.238.196.0/22 +103.238.204.0/22 +103.238.252.0/22 +103.239.0.0/22 +103.239.44.0/22 +103.239.68.0/22 +103.239.96.0/22 +103.239.152.0/22 +103.239.156.0/22 +103.239.176.0/22 +103.239.180.0/22 +103.239.184.0/22 +103.239.192.0/22 +103.239.196.0/22 +103.239.204.0/22 +103.239.208.0/22 +103.239.224.0/22 +103.239.244.0/22 +103.240.16.0/22 +103.240.36.0/22 +103.240.72.0/22 +103.240.84.0/22 +103.240.124.0/22 +103.240.156.0/22 +103.240.172.0/22 +103.240.188.0/22 +103.240.244.0/22 +103.241.12.0/22 +103.241.72.0/22 +103.241.92.0/22 +103.241.96.0/22 +103.241.160.0/22 +103.241.184.0/22 +103.241.188.0/22 +103.241.220.0/22 +103.242.64.0/22 +103.242.128.0/22 +103.242.132.0/22 +103.242.160.0/22 +103.242.168.0/22 +103.242.172.0/22 +103.242.176.0/22 +103.242.200.0/22 +103.242.212.0/22 +103.242.220.0/22 +103.242.240.0/22 +103.243.136.0/22 +103.243.252.0/22 +103.244.16.0/22 +103.244.58.0/23 +103.244.60.0/22 +103.244.64.0/22 +103.244.68.0/22 +103.244.72.0/22 +103.244.76.0/22 +103.244.80.0/22 +103.244.84.0/22 +103.244.116.0/22 +103.244.164.0/22 +103.244.232.0/22 +103.244.252.0/22 +103.245.23.0/24 +103.245.52.0/22 +103.245.60.0/22 +103.245.80.0/22 +103.245.124.0/22 +103.245.128.0/22 +103.246.8.0/22 +103.246.12.0/22 +103.246.120.0/22 +103.246.124.0/22 +103.246.132.0/22 +103.246.152.0/22 +103.246.156.0/22 +103.247.168.0/22 +103.247.172.0/22 +103.247.176.0/22 +103.247.200.0/22 +103.247.212.0/22 +103.248.0.0/23 +103.248.64.0/22 +103.248.100.0/22 +103.248.124.0/22 +103.248.152.0/22 +103.248.168.0/22 +103.248.192.0/22 +103.248.212.0/22 +103.248.220.0/22 +103.248.224.0/22 +103.249.8.0/22 +103.249.12.0/22 +103.249.52.0/22 +103.249.104.0/22 +103.249.128.0/22 +103.249.136.0/22 +103.249.144.0/22 +103.249.164.0/22 +103.249.168.0/22 +103.249.172.0/22 +103.249.176.0/22 +103.249.188.0/22 +103.249.192.0/22 +103.249.244.0/22 +103.249.252.0/22 +103.250.32.0/22 +103.250.104.0/22 +103.250.124.0/22 +103.250.180.0/22 +103.250.192.0/22 +103.250.216.0/22 +103.250.224.0/22 +103.250.236.0/22 +103.250.248.0/22 +103.250.252.0/22 +103.251.32.0/22 +103.251.36.0/22 +103.251.84.0/22 +103.251.96.0/22 +103.251.124.0/22 +103.251.128.0/22 +103.251.160.0/22 +103.251.192.0/22 +103.251.204.0/22 +103.251.236.0/22 +103.251.240.0/22 +103.252.28.0/22 +103.252.36.0/22 +103.252.64.0/22 +103.252.96.0/22 +103.252.104.0/22 +103.252.172.0/22 +103.252.204.0/22 +103.252.208.0/22 +103.252.232.0/22 +103.252.248.0/22 +103.253.4.0/22 +103.253.60.0/22 +103.253.204.0/22 +103.253.220.0/22 +103.253.224.0/22 +103.253.232.0/22 +103.254.8.0/22 +103.254.20.0/22 +103.254.64.0/22 +103.254.68.0/22 +103.254.72.0/22 +103.254.76.0/22 +103.254.112.0/22 +103.254.176.0/22 +103.254.188.0/22 +103.254.196.0/24 +103.254.220.0/22 +103.255.56.0/22 +103.255.68.0/22 +103.255.88.0/22 +103.255.92.0/22 +103.255.136.0/22 +103.255.140.0/22 +103.255.184.0/22 +103.255.200.0/22 +103.255.212.0/22 +103.255.228.0/22 +106.0.0.0/24 +106.0.2.0/23 +106.0.4.0/22 +106.0.8.0/21 +106.0.16.0/20 +106.0.44.0/22 +106.0.64.0/18 +106.2.0.0/15 +106.4.0.0/14 +106.8.0.0/15 +106.11.0.0/16 +106.12.0.0/14 +106.16.0.0/12 +106.32.0.0/12 +106.48.0.0/15 +106.50.0.0/16 +106.52.0.0/14 +106.56.0.0/13 +106.74.0.0/16 +106.75.0.0/16 +106.80.0.0/12 +106.108.0.0/14 +106.112.0.0/13 +106.120.0.0/13 +106.224.0.0/12 +109.244.0.0/16 +110.6.0.0/15 +110.16.0.0/14 +110.34.40.0/22 +110.34.44.0/22 +110.40.0.0/14 +110.44.12.0/22 +110.44.144.0/20 +110.48.0.0/16 +110.51.0.0/16 +110.52.0.0/15 +110.56.0.0/13 +110.64.0.0/15 +110.72.0.0/15 +110.75.0.0/17 +110.75.128.0/19 +110.75.160.0/19 +110.75.192.0/18 +110.76.0.0/19 +110.76.32.0/19 +110.76.132.0/22 +110.76.156.0/22 +110.76.184.0/22 +110.76.192.0/18 +110.77.0.0/17 +110.80.0.0/13 +110.88.0.0/14 +110.92.68.0/22 +110.93.32.0/19 +110.94.0.0/15 +110.96.0.0/11 +110.152.0.0/14 +110.156.0.0/15 +110.165.32.0/19 +110.166.0.0/15 +110.172.192.0/18 +110.173.0.0/19 +110.173.32.0/20 +110.173.64.0/19 +110.173.96.0/19 +110.173.192.0/19 +110.176.0.0/13 +110.184.0.0/13 +110.192.0.0/11 +110.228.0.0/14 +110.232.32.0/19 +110.236.0.0/15 +110.240.0.0/12 +111.0.0.0/10 +111.66.0.0/16 +111.67.192.0/20 +111.68.64.0/19 +111.72.0.0/13 +111.85.0.0/16 +111.91.192.0/19 +111.92.248.0/22 +111.92.252.0/22 +111.112.0.0/15 +111.114.0.0/15 +111.116.0.0/15 +111.118.200.0/21 +111.119.64.0/18 +111.119.128.0/19 +111.120.0.0/14 +111.124.0.0/16 +111.126.0.0/15 +111.128.0.0/11 +111.160.0.0/13 +111.170.0.0/16 +111.172.0.0/14 +111.176.0.0/13 +111.186.0.0/15 +111.192.0.0/12 +111.208.0.0/14 +111.212.0.0/14 +111.221.28.0/24 +111.221.128.0/17 +111.222.0.0/16 +111.223.4.0/22 +111.223.8.0/22 +111.223.12.0/22 +111.223.16.0/22 +111.223.240.0/22 +111.223.248.0/22 +111.224.0.0/14 +111.228.0.0/14 +111.235.96.0/19 +111.235.156.0/22 +111.235.160.0/19 +112.0.0.0/10 +112.64.0.0/15 +112.66.0.0/15 +112.73.0.0/16 +112.74.0.0/15 +112.80.0.0/13 +112.88.0.0/13 +112.96.0.0/15 +112.98.0.0/15 +112.100.0.0/14 +112.109.128.0/17 +112.111.0.0/16 +112.112.0.0/14 +112.116.0.0/15 +112.122.0.0/15 +112.124.0.0/14 +112.128.0.0/14 +112.132.0.0/16 +112.137.48.0/21 +112.192.0.0/14 +112.224.0.0/11 +113.0.0.0/13 +113.8.0.0/15 +113.11.192.0/19 +113.12.0.0/14 +113.16.0.0/15 +113.18.0.0/16 +113.21.232.0/22 +113.21.236.0/22 +113.24.0.0/14 +113.31.0.0/16 +113.44.0.0/14 +113.48.0.0/14 +113.52.160.0/19 +113.52.228.0/22 +113.54.0.0/15 +113.56.0.0/15 +113.58.0.0/16 +113.59.0.0/17 +113.59.224.0/22 +113.62.0.0/15 +113.64.0.0/11 +113.96.0.0/12 +113.112.0.0/13 +113.120.0.0/13 +113.128.0.0/15 +113.130.96.0/20 +113.130.112.0/21 +113.132.0.0/14 +113.136.0.0/13 +113.194.0.0/15 +113.197.100.0/22 +113.200.0.0/15 +113.202.0.0/16 +113.204.0.0/14 +113.208.96.0/19 +113.208.128.0/17 +113.209.0.0/16 +113.212.0.0/18 +113.212.100.0/22 +113.212.184.0/21 +113.213.0.0/17 +113.214.0.0/15 +113.218.0.0/15 +113.220.0.0/14 +113.224.0.0/12 +113.240.0.0/13 +113.248.0.0/14 +114.28.0.0/16 +114.31.64.0/22 +114.31.68.0/22 +114.54.0.0/15 +114.60.0.0/14 +114.64.0.0/14 +114.68.0.0/16 +114.79.64.0/18 +114.80.0.0/12 +114.96.0.0/13 +114.104.0.0/14 +114.110.0.0/20 +114.110.64.0/18 +114.111.0.0/19 +114.111.160.0/19 +114.112.0.0/14 +114.116.0.0/16 +114.117.0.0/16 +114.118.0.0/16 +114.119.0.0/17 +114.119.128.0/18 +114.119.192.0/21 +114.119.200.0/22 +114.119.204.0/22 +114.119.208.0/20 +114.119.224.0/19 +114.132.0.0/16 +114.135.0.0/16 +114.138.0.0/15 +114.141.64.0/21 +114.141.80.0/22 +114.141.84.0/22 +114.141.128.0/18 +114.196.0.0/15 +114.198.248.0/21 +114.208.0.0/14 +114.212.0.0/15 +114.214.0.0/16 +114.215.0.0/16 +114.216.0.0/13 +114.224.0.0/12 +114.240.0.0/12 +115.24.0.0/14 +115.28.0.0/15 +115.31.64.0/22 +115.31.68.0/22 +115.31.72.0/22 +115.31.76.0/22 +115.32.0.0/14 +115.42.56.0/22 +115.44.0.0/15 +115.46.0.0/16 +115.47.0.0/16 +115.48.0.0/12 +115.69.64.0/20 +115.84.0.0/18 +115.84.192.0/19 +115.85.192.0/18 +115.100.0.0/14 +115.104.0.0/14 +115.120.0.0/14 +115.124.16.0/20 +115.148.0.0/14 +115.152.0.0/15 +115.154.0.0/15 +115.156.0.0/15 +115.158.0.0/16 +115.159.0.0/16 +115.166.64.0/19 +115.168.0.0/14 +115.172.0.0/14 +115.180.0.0/15 +115.182.0.0/16 +115.183.0.0/16 +115.187.0.0/22 +115.187.4.0/22 +115.187.8.0/22 +115.187.12.0/22 +115.190.0.0/15 +115.192.0.0/11 +115.224.0.0/12 +116.0.8.0/21 +116.0.24.0/21 +116.1.0.0/16 +116.2.0.0/15 +116.4.0.0/14 +116.8.0.0/14 +116.13.0.0/16 +116.16.0.0/12 +116.50.0.0/20 +116.52.0.0/14 +116.56.0.0/15 +116.58.128.0/20 +116.58.208.0/20 +116.60.0.0/14 +116.66.0.0/17 +116.66.176.0/22 +116.68.136.0/22 +116.68.140.0/22 +116.68.176.0/22 +116.68.180.0/22 +116.69.0.0/16 +116.70.0.0/17 +116.76.0.0/15 +116.78.0.0/15 +116.85.0.0/16 +116.89.144.0/20 +116.89.240.0/22 +116.90.80.0/20 +116.90.184.0/21 +116.95.0.0/16 +116.112.0.0/14 +116.116.0.0/15 +116.128.0.0/10 +116.192.0.0/16 +116.193.16.0/20 +116.193.32.0/19 +116.193.152.0/22 +116.193.164.0/22 +116.193.176.0/21 +116.194.0.0/15 +116.196.0.0/16 +116.197.160.0/22 +116.197.164.0/22 +116.198.0.0/16 +116.199.0.0/17 +116.199.128.0/19 +116.204.0.0/17 +116.204.132.0/22 +116.204.168.0/22 +116.204.216.0/22 +116.205.0.0/16 +116.206.92.0/22 +116.206.100.0/22 +116.206.176.0/22 +116.207.0.0/16 +116.208.0.0/14 +116.212.160.0/20 +116.213.44.0/22 +116.213.64.0/18 +116.213.128.0/17 +116.214.32.0/19 +116.214.64.0/20 +116.214.128.0/17 +116.215.0.0/16 +116.216.0.0/14 +116.224.0.0/12 +116.242.0.0/15 +116.244.0.0/15 +116.246.0.0/15 +116.248.0.0/15 +116.251.64.0/18 +116.252.0.0/15 +116.254.104.0/22 +116.254.108.0/22 +116.254.128.0/17 +116.255.128.0/17 +117.8.0.0/13 +117.21.0.0/16 +117.22.0.0/15 +117.24.0.0/13 +117.32.0.0/13 +117.40.0.0/14 +117.44.0.0/15 +117.48.0.0/14 +117.53.48.0/20 +117.53.176.0/20 +117.57.0.0/16 +117.58.0.0/17 +117.59.0.0/16 +117.60.0.0/14 +117.64.0.0/13 +117.72.0.0/15 +117.74.64.0/20 +117.74.80.0/20 +117.74.128.0/17 +117.75.0.0/16 +117.76.0.0/14 +117.80.0.0/12 +117.100.0.0/15 +117.103.16.0/20 +117.103.40.0/21 +117.103.72.0/21 +117.103.128.0/20 +117.104.168.0/21 +117.106.0.0/15 +117.112.0.0/13 +117.120.64.0/18 +117.120.128.0/17 +117.121.0.0/17 +117.121.128.0/18 +117.121.192.0/21 +117.122.128.0/17 +117.124.0.0/14 +117.128.0.0/10 +118.24.0.0/15 +118.26.0.0/19 +118.26.32.0/22 +118.26.36.0/22 +118.26.40.0/21 +118.26.48.0/21 +118.26.56.0/21 +118.26.64.0/19 +118.26.96.0/21 +118.26.104.0/21 +118.26.112.0/21 +118.26.120.0/21 +118.26.128.0/17 +118.28.0.0/15 +118.30.0.0/16 +118.31.0.0/16 +118.64.0.0/15 +118.66.0.0/16 +118.67.112.0/20 +118.72.0.0/13 +118.80.0.0/15 +118.84.0.0/15 +118.88.32.0/19 +118.88.64.0/18 +118.88.128.0/17 +118.89.0.0/16 +118.91.240.0/20 +118.102.16.0/20 +118.102.32.0/21 +118.103.164.0/22 +118.103.168.0/22 +118.103.172.0/22 +118.103.176.0/22 +118.107.180.0/22 +118.112.0.0/13 +118.120.0.0/14 +118.124.0.0/15 +118.126.0.0/16 +118.127.128.0/19 +118.132.0.0/14 +118.144.0.0/14 +118.178.0.0/16 +118.180.0.0/14 +118.184.0.0/17 +118.184.128.0/17 +118.186.0.0/15 +118.188.0.0/16 +118.190.0.0/16 +118.191.0.0/16 +118.192.0.0/16 +118.193.0.0/21 +118.193.8.0/21 +118.193.32.0/19 +118.193.64.0/20 +118.193.96.0/19 +118.193.128.0/17 +118.194.0.0/17 +118.194.128.0/17 +118.195.0.0/17 +118.195.128.0/17 +118.196.0.0/14 +118.202.0.0/15 +118.204.0.0/14 +118.212.0.0/16 +118.213.0.0/16 +118.215.192.0/18 +118.224.0.0/14 +118.228.0.0/15 +118.230.0.0/16 +118.239.0.0/16 +118.242.0.0/16 +118.244.0.0/14 +118.248.0.0/13 +119.0.0.0/15 +119.2.0.0/19 +119.2.128.0/17 +119.3.0.0/16 +119.4.0.0/14 +119.8.0.0/16 +119.10.0.0/17 +119.15.136.0/21 +119.16.0.0/16 +119.18.192.0/20 +119.18.208.0/21 +119.18.224.0/20 +119.18.240.0/20 +119.19.0.0/16 +119.20.0.0/14 +119.27.64.0/18 +119.27.128.0/19 +119.27.160.0/19 +119.27.192.0/18 +119.28.0.0/15 +119.30.48.0/20 +119.31.192.0/19 +119.32.0.0/14 +119.36.0.0/16 +119.37.0.0/17 +119.37.128.0/18 +119.37.192.0/18 +119.38.0.0/17 +119.38.128.0/18 +119.38.192.0/20 +119.38.208.0/20 +119.38.224.0/19 +119.39.0.0/16 +119.40.0.0/18 +119.40.64.0/20 +119.40.128.0/17 +119.41.0.0/16 +119.42.0.0/19 +119.42.52.0/22 +119.42.128.0/21 +119.42.136.0/21 +119.42.224.0/19 +119.44.0.0/15 +119.48.0.0/13 +119.57.0.0/16 +119.58.0.0/16 +119.59.128.0/17 +119.60.0.0/16 +119.61.0.0/16 +119.62.0.0/16 +119.63.32.0/19 +119.75.208.0/20 +119.78.0.0/15 +119.80.0.0/16 +119.82.208.0/20 +119.84.0.0/14 +119.88.0.0/14 +119.96.0.0/13 +119.108.0.0/15 +119.112.0.0/13 +119.120.0.0/13 +119.128.0.0/12 +119.144.0.0/14 +119.148.160.0/20 +119.148.176.0/20 +119.151.192.0/18 +119.160.200.0/21 +119.161.120.0/22 +119.161.124.0/22 +119.161.128.0/17 +119.162.0.0/15 +119.164.0.0/14 +119.176.0.0/12 +119.232.0.0/15 +119.235.128.0/18 +119.248.0.0/14 +119.252.96.0/21 +119.252.240.0/20 +119.253.0.0/16 +119.254.0.0/15 +120.0.0.0/12 +120.24.0.0/14 +120.30.0.0/16 +120.31.0.0/16 +120.32.0.0/13 +120.40.0.0/14 +120.44.0.0/14 +120.48.0.0/15 +120.52.0.0/16 +120.53.0.0/16 +120.54.0.0/15 +120.64.0.0/14 +120.68.0.0/14 +120.72.32.0/19 +120.72.128.0/17 +120.76.0.0/14 +120.80.0.0/13 +120.88.8.0/21 +120.90.0.0/15 +120.92.0.0/16 +120.94.0.0/16 +120.95.0.0/16 +120.128.0.0/14 +120.132.0.0/17 +120.132.128.0/17 +120.133.0.0/16 +120.134.0.0/15 +120.136.16.0/22 +120.136.20.0/22 +120.136.128.0/18 +120.137.0.0/17 +120.143.128.0/19 +120.192.0.0/10 +121.0.8.0/21 +121.0.16.0/20 +121.4.0.0/15 +121.8.0.0/13 +121.16.0.0/13 +121.24.0.0/14 +121.28.0.0/15 +121.30.0.0/16 +121.31.0.0/16 +121.32.0.0/14 +121.36.0.0/16 +121.37.0.0/16 +121.38.0.0/15 +121.40.0.0/14 +121.46.0.0/18 +121.46.76.0/22 +121.46.128.0/17 +121.47.0.0/16 +121.48.0.0/15 +121.50.8.0/21 +121.51.0.0/16 +121.52.160.0/19 +121.52.208.0/20 +121.52.224.0/19 +121.54.176.0/21 +121.54.188.0/22 +121.55.0.0/18 +121.56.0.0/15 +121.58.0.0/17 +121.58.136.0/21 +121.58.144.0/20 +121.58.160.0/21 +121.59.0.0/16 +121.60.0.0/14 +121.68.0.0/14 +121.76.0.0/15 +121.79.128.0/18 +121.89.0.0/16 +121.100.128.0/17 +121.101.0.0/18 +121.101.208.0/20 +121.192.0.0/16 +121.193.0.0/16 +121.194.0.0/15 +121.196.0.0/14 +121.200.192.0/21 +121.201.0.0/16 +121.204.0.0/14 +121.224.0.0/12 +121.248.0.0/14 +121.255.0.0/16 +122.0.64.0/18 +122.0.128.0/17 +122.4.0.0/14 +122.8.0.0/16 +122.9.0.0/16 +122.10.128.0/22 +122.10.132.0/23 +122.10.134.0/23 +122.10.136.0/23 +122.10.138.0/23 +122.10.140.0/22 +122.10.144.0/20 +122.10.160.0/19 +122.10.192.0/20 +122.10.208.0/21 +122.10.216.0/22 +122.10.220.0/22 +122.10.224.0/19 +122.11.0.0/17 +122.12.0.0/16 +122.13.0.0/16 +122.14.0.0/17 +122.14.128.0/18 +122.14.192.0/18 +122.48.0.0/16 +122.49.0.0/18 +122.51.0.0/16 +122.64.0.0/11 +122.96.0.0/15 +122.102.0.0/20 +122.102.64.0/20 +122.102.80.0/20 +122.112.0.0/18 +122.112.64.0/18 +122.112.128.0/17 +122.113.0.0/16 +122.114.0.0/16 +122.115.0.0/17 +122.115.128.0/19 +122.115.160.0/19 +122.115.192.0/19 +122.115.224.0/19 +122.119.0.0/16 +122.128.100.0/22 +122.128.120.0/21 +122.136.0.0/13 +122.144.128.0/17 +122.152.192.0/18 +122.156.0.0/14 +122.188.0.0/14 +122.192.0.0/14 +122.198.0.0/16 +122.200.40.0/22 +122.200.44.0/22 +122.200.64.0/18 +122.201.48.0/20 +122.204.0.0/14 +122.224.0.0/12 +122.240.0.0/13 +122.248.24.0/21 +122.248.48.0/20 +122.255.64.0/21 +123.0.128.0/18 +123.4.0.0/14 +123.8.0.0/13 +123.49.128.0/17 +123.50.160.0/19 +123.52.0.0/14 +123.56.0.0/15 +123.58.0.0/20 +123.58.16.0/20 +123.58.32.0/19 +123.58.64.0/19 +123.58.96.0/19 +123.58.128.0/18 +123.58.192.0/19 +123.58.224.0/20 +123.58.240.0/20 +123.59.0.0/16 +123.60.0.0/16 +123.61.0.0/16 +123.62.0.0/16 +123.64.0.0/11 +123.96.0.0/15 +123.98.0.0/17 +123.99.128.0/17 +123.100.0.0/19 +123.101.0.0/16 +123.103.0.0/17 +123.108.128.0/20 +123.108.208.0/20 +123.112.0.0/12 +123.128.0.0/13 +123.136.80.0/20 +123.137.0.0/16 +123.138.0.0/15 +123.144.0.0/14 +123.148.0.0/16 +123.149.0.0/16 +123.150.0.0/15 +123.152.0.0/13 +123.160.0.0/14 +123.164.0.0/14 +123.168.0.0/14 +123.172.0.0/15 +123.174.0.0/15 +123.176.60.0/22 +123.176.80.0/20 +123.177.0.0/16 +123.178.0.0/15 +123.180.0.0/14 +123.184.0.0/14 +123.188.0.0/14 +123.196.0.0/15 +123.199.128.0/17 +123.206.0.0/15 +123.232.0.0/14 +123.242.0.0/17 +123.242.192.0/22 +123.242.196.0/22 +123.244.0.0/14 +123.249.0.0/16 +123.254.96.0/22 +123.254.100.0/22 +124.6.64.0/18 +124.14.0.0/15 +124.16.0.0/15 +124.20.0.0/16 +124.21.0.0/20 +124.21.16.0/20 +124.21.32.0/19 +124.21.64.0/18 +124.21.128.0/17 +124.22.0.0/15 +124.28.192.0/18 +124.29.0.0/17 +124.31.0.0/16 +124.40.112.0/20 +124.40.128.0/18 +124.40.192.0/19 +124.40.240.0/22 +124.42.0.0/17 +124.42.128.0/17 +124.47.0.0/18 +124.64.0.0/15 +124.66.0.0/17 +124.67.0.0/16 +124.68.0.0/14 +124.72.0.0/16 +124.73.0.0/16 +124.74.0.0/15 +124.76.0.0/14 +124.88.0.0/16 +124.89.0.0/17 +124.89.128.0/17 +124.90.0.0/15 +124.92.0.0/14 +124.108.8.0/21 +124.108.40.0/21 +124.109.96.0/21 +124.112.0.0/15 +124.114.0.0/15 +124.116.0.0/16 +124.117.0.0/16 +124.118.0.0/15 +124.126.0.0/15 +124.128.0.0/13 +124.147.128.0/17 +124.150.137.0/24 +124.151.0.0/16 +124.152.0.0/16 +124.160.0.0/16 +124.161.0.0/16 +124.162.0.0/16 +124.163.0.0/16 +124.164.0.0/14 +124.172.0.0/15 +124.174.0.0/15 +124.192.0.0/15 +124.196.0.0/16 +124.200.0.0/13 +124.220.0.0/14 +124.224.0.0/16 +124.225.0.0/16 +124.226.0.0/15 +124.228.0.0/14 +124.232.0.0/15 +124.234.0.0/15 +124.236.0.0/14 +124.240.0.0/17 +124.240.128.0/18 +124.242.0.0/16 +124.243.192.0/18 +124.248.0.0/17 +124.249.0.0/16 +124.250.0.0/15 +124.254.0.0/18 +125.31.192.0/18 +125.32.0.0/16 +125.33.0.0/16 +125.34.0.0/16 +125.35.0.0/17 +125.35.128.0/17 +125.36.0.0/14 +125.40.0.0/13 +125.58.128.0/17 +125.61.128.0/17 +125.62.0.0/18 +125.64.0.0/13 +125.72.0.0/16 +125.73.0.0/16 +125.74.0.0/15 +125.76.0.0/17 +125.76.128.0/17 +125.77.0.0/16 +125.78.0.0/15 +125.80.0.0/13 +125.88.0.0/13 +125.96.0.0/15 +125.98.0.0/16 +125.104.0.0/13 +125.112.0.0/12 +125.169.0.0/16 +125.171.0.0/16 +125.208.0.0/18 +125.210.0.0/16 +125.211.0.0/16 +125.213.0.0/17 +125.214.96.0/19 +125.215.0.0/18 +125.216.0.0/15 +125.218.0.0/16 +125.219.0.0/16 +125.220.0.0/15 +125.222.0.0/15 +125.254.128.0/18 +125.254.192.0/18 +128.108.0.0/16 +129.28.0.0/16 +129.204.0.0/16 +129.211.0.0/16 +132.232.0.0/16 +134.175.0.0/16 +137.59.59.0/24 +137.59.88.0/22 +139.5.56.0/22 +139.5.60.0/22 +139.5.80.0/22 +139.5.92.0/22 +139.5.108.0/22 +139.5.128.0/22 +139.5.160.0/22 +139.5.192.0/22 +139.5.204.0/22 +139.5.208.0/22 +139.5.212.0/22 +139.5.244.0/22 +139.9.0.0/16 +139.129.0.0/16 +139.148.0.0/16 +139.155.0.0/16 +139.159.0.0/16 +139.170.0.0/16 +139.176.0.0/16 +139.183.0.0/16 +139.186.0.0/16 +139.189.0.0/16 +139.196.0.0/14 +139.200.0.0/13 +139.208.0.0/13 +139.217.0.0/16 +139.219.0.0/16 +139.220.0.0/15 +139.224.0.0/16 +139.226.0.0/15 +140.75.0.0/16 +140.143.0.0/16 +140.179.0.0/16 +140.205.0.0/16 +140.206.0.0/15 +140.210.0.0/16 +140.224.0.0/16 +140.237.0.0/16 +140.240.0.0/16 +140.243.0.0/16 +140.246.0.0/16 +140.249.0.0/16 +140.250.0.0/16 +140.255.0.0/16 +144.0.0.0/16 +144.7.0.0/16 +144.12.0.0/16 +144.48.8.0/22 +144.48.64.0/22 +144.48.88.0/22 +144.48.156.0/22 +144.48.180.0/22 +144.48.184.0/22 +144.48.204.0/22 +144.48.208.0/22 +144.48.212.0/22 +144.48.220.0/22 +144.48.252.0/22 +144.52.0.0/16 +144.123.0.0/16 +144.255.0.0/16 +146.56.192.0/18 +146.196.56.0/22 +146.196.68.0/22 +146.196.72.0/22 +146.196.92.0/22 +146.196.112.0/22 +146.196.116.0/22 +146.196.124.0/22 +148.70.0.0/16 +150.0.0.0/16 +150.115.0.0/16 +150.121.0.0/16 +150.122.0.0/16 +150.129.136.0/22 +150.129.192.0/22 +150.129.216.0/22 +150.129.252.0/22 +150.138.0.0/15 +150.158.0.0/16 +150.223.0.0/16 +150.242.0.0/22 +150.242.4.0/22 +150.242.8.0/22 +150.242.28.0/22 +150.242.44.0/22 +150.242.48.0/22 +150.242.52.0/22 +150.242.56.0/22 +150.242.76.0/22 +150.242.80.0/22 +150.242.92.0/22 +150.242.96.0/22 +150.242.112.0/22 +150.242.116.0/22 +150.242.120.0/22 +150.242.152.0/22 +150.242.156.0/22 +150.242.160.0/22 +150.242.164.0/22 +150.242.168.0/22 +150.242.184.0/22 +150.242.188.0/22 +150.242.192.0/22 +150.242.212.0/22 +150.242.224.0/22 +150.242.228.0/22 +150.242.232.0/22 +150.242.236.0/22 +150.242.240.0/22 +150.242.244.0/22 +150.242.248.0/22 +150.255.0.0/16 +152.104.128.0/17 +152.136.0.0/16 +153.0.0.0/16 +153.3.0.0/16 +153.34.0.0/15 +153.36.0.0/15 +153.99.0.0/16 +153.101.0.0/16 +153.118.0.0/15 +154.8.128.0/17 +157.0.0.0/16 +157.18.0.0/16 +157.61.0.0/16 +157.119.0.0/22 +157.119.8.0/22 +157.119.12.0/22 +157.119.16.0/22 +157.119.28.0/22 +157.119.68.0/22 +157.119.112.0/22 +157.119.132.0/22 +157.119.136.0/22 +157.119.140.0/22 +157.119.144.0/22 +157.119.148.0/22 +157.119.152.0/22 +157.119.156.0/22 +157.119.160.0/22 +157.119.164.0/22 +157.119.172.0/22 +157.119.192.0/22 +157.119.196.0/22 +157.119.240.0/22 +157.119.252.0/22 +157.122.0.0/16 +157.148.0.0/16 +157.156.0.0/16 +157.255.0.0/16 +159.75.0.0/16 +159.226.0.0/16 +160.19.208.0/22 +160.19.212.0/22 +160.19.216.0/22 +160.20.48.0/22 +160.202.60.0/22 +160.202.148.0/22 +160.202.152.0/22 +160.202.168.0/22 +160.202.212.0/22 +160.202.216.0/22 +160.202.220.0/22 +160.202.224.0/22 +160.202.228.0/22 +160.202.232.0/22 +160.202.236.0/22 +160.202.240.0/22 +160.202.244.0/22 +160.202.248.0/22 +160.202.252.0/22 +160.238.64.0/22 +161.189.0.0/16 +161.207.0.0/16 +162.14.0.0/16 +162.105.0.0/16 +163.0.0.0/16 +163.47.4.0/22 +163.53.0.0/22 +163.53.4.0/22 +163.53.8.0/22 +163.53.12.0/22 +163.53.36.0/22 +163.53.40.0/22 +163.53.44.0/22 +163.53.48.0/22 +163.53.52.0/22 +163.53.56.0/22 +163.53.60.0/22 +163.53.64.0/22 +163.53.88.0/22 +163.53.92.0/22 +163.53.96.0/22 +163.53.100.0/22 +163.53.104.0/22 +163.53.108.0/22 +163.53.112.0/22 +163.53.116.0/22 +163.53.120.0/22 +163.53.124.0/22 +163.53.128.0/22 +163.53.132.0/22 +163.53.136.0/22 +163.53.160.0/22 +163.53.164.0/22 +163.53.168.0/22 +163.53.172.0/22 +163.53.188.0/22 +163.53.220.0/22 +163.53.240.0/22 +163.125.0.0/16 +163.142.0.0/16 +163.177.0.0/16 +163.179.0.0/16 +163.204.0.0/16 +164.52.0.0/17 +166.111.0.0/16 +167.139.0.0/16 +167.189.0.0/16 +167.220.244.0/22 +168.160.0.0/16 +170.179.0.0/16 +171.8.0.0/13 +171.34.0.0/15 +171.36.0.0/14 +171.40.0.0/13 +171.80.0.0/14 +171.84.0.0/14 +171.88.0.0/13 +171.104.0.0/13 +171.112.0.0/14 +171.116.0.0/14 +171.120.0.0/13 +171.208.0.0/12 +172.81.192.0/18 +175.0.0.0/12 +175.16.0.0/13 +175.24.0.0/14 +175.30.0.0/15 +175.42.0.0/15 +175.44.0.0/16 +175.46.0.0/15 +175.48.0.0/12 +175.64.0.0/11 +175.102.0.0/16 +175.106.128.0/17 +175.111.144.0/22 +175.111.148.0/22 +175.111.152.0/22 +175.111.156.0/22 +175.111.160.0/22 +175.111.164.0/22 +175.111.168.0/22 +175.111.172.0/22 +175.111.184.0/22 +175.146.0.0/15 +175.148.0.0/14 +175.152.0.0/14 +175.158.96.0/22 +175.160.0.0/12 +175.176.156.0/22 +175.176.176.0/22 +175.176.188.0/22 +175.176.192.0/22 +175.178.0.0/16 +175.184.128.0/18 +175.185.0.0/16 +175.186.0.0/15 +175.188.0.0/14 +180.76.0.0/16 +180.77.0.0/16 +180.78.0.0/15 +180.84.0.0/15 +180.86.0.0/16 +180.88.0.0/14 +180.94.56.0/21 +180.94.96.0/20 +180.94.120.0/22 +180.94.124.0/22 +180.95.128.0/17 +180.96.0.0/11 +180.129.128.0/17 +180.130.0.0/16 +180.136.0.0/13 +180.148.16.0/21 +180.148.152.0/21 +180.148.216.0/21 +180.148.224.0/19 +180.149.128.0/19 +180.149.236.0/22 +180.150.160.0/19 +180.152.0.0/13 +180.160.0.0/12 +180.178.112.0/22 +180.178.116.0/22 +180.178.192.0/18 +180.184.0.0/14 +180.188.0.0/17 +180.189.148.0/22 +180.200.252.0/22 +180.201.0.0/16 +180.202.0.0/15 +180.208.0.0/15 +180.210.212.0/22 +180.210.224.0/19 +180.212.0.0/15 +180.222.224.0/19 +180.223.0.0/16 +180.233.0.0/18 +180.233.64.0/19 +180.233.144.0/22 +180.235.64.0/19 +180.235.112.0/22 +180.235.136.0/22 +182.16.144.0/22 +182.16.148.0/22 +182.16.192.0/19 +182.18.0.0/17 +182.23.184.0/21 +182.23.200.0/21 +182.32.0.0/12 +182.48.96.0/19 +182.49.0.0/16 +182.50.0.0/20 +182.50.112.0/20 +182.51.0.0/16 +182.54.0.0/17 +182.54.244.0/22 +182.61.0.0/16 +182.80.0.0/14 +182.84.0.0/14 +182.88.0.0/14 +182.92.0.0/16 +182.96.0.0/12 +182.112.0.0/12 +182.128.0.0/12 +182.144.0.0/13 +182.157.0.0/16 +182.160.64.0/19 +182.174.0.0/15 +182.200.0.0/13 +182.236.128.0/17 +182.237.24.0/22 +182.237.28.0/22 +182.238.0.0/16 +182.239.0.0/19 +182.240.0.0/13 +182.254.0.0/16 +182.255.32.0/22 +182.255.36.0/22 +182.255.60.0/22 +183.0.0.0/10 +183.64.0.0/13 +183.78.160.0/22 +183.78.164.0/22 +183.78.180.0/22 +183.81.172.0/22 +183.81.180.0/22 +183.84.0.0/15 +183.91.128.0/22 +183.91.136.0/21 +183.91.144.0/20 +183.92.0.0/14 +183.128.0.0/11 +183.160.0.0/13 +183.168.0.0/15 +183.170.0.0/16 +183.172.0.0/14 +183.182.0.0/19 +183.184.0.0/13 +183.192.0.0/10 +188.131.128.0/17 +192.55.46.0/24 +192.55.68.0/22 +192.102.204.0/23 +192.124.154.0/24 +192.140.128.0/22 +192.140.132.0/22 +192.140.136.0/22 +192.140.156.0/22 +192.140.160.0/22 +192.140.164.0/22 +192.140.168.0/22 +192.140.172.0/22 +192.140.176.0/22 +192.140.180.0/22 +192.140.184.0/22 +192.140.188.0/22 +192.140.192.0/22 +192.140.196.0/22 +192.140.200.0/22 +192.140.204.0/22 +192.140.208.0/22 +192.140.212.0/22 +192.144.128.0/17 +193.112.0.0/16 +198.175.100.0/22 +202.0.100.0/23 +202.0.122.0/23 +202.0.176.0/22 +202.3.128.0/23 +202.4.128.0/19 +202.4.252.0/22 +202.5.208.0/22 +202.5.212.0/22 +202.5.216.0/22 +202.6.6.0/23 +202.6.66.0/23 +202.6.72.0/23 +202.6.87.0/24 +202.6.88.0/23 +202.6.92.0/23 +202.6.103.0/24 +202.6.108.0/24 +202.6.110.0/23 +202.6.114.0/24 +202.6.176.0/20 +202.8.0.0/24 +202.8.2.0/23 +202.8.4.0/23 +202.8.12.0/24 +202.8.24.0/24 +202.8.77.0/24 +202.8.128.0/19 +202.8.192.0/20 +202.9.32.0/24 +202.9.34.0/23 +202.9.48.0/23 +202.9.51.0/24 +202.9.52.0/23 +202.9.54.0/24 +202.9.57.0/24 +202.9.58.0/23 +202.10.64.0/20 +202.10.112.0/22 +202.10.116.0/22 +202.10.120.0/22 +202.10.124.0/22 +202.12.1.0/24 +202.12.2.0/24 +202.12.17.0/24 +202.12.18.0/24 +202.12.19.0/24 +202.12.72.0/24 +202.12.84.0/23 +202.12.96.0/24 +202.12.98.0/23 +202.12.106.0/24 +202.12.111.0/24 +202.12.116.0/24 +202.14.64.0/23 +202.14.69.0/24 +202.14.73.0/24 +202.14.74.0/23 +202.14.76.0/24 +202.14.78.0/23 +202.14.88.0/24 +202.14.97.0/24 +202.14.104.0/23 +202.14.108.0/23 +202.14.111.0/24 +202.14.114.0/23 +202.14.118.0/23 +202.14.124.0/23 +202.14.127.0/24 +202.14.129.0/24 +202.14.135.0/24 +202.14.136.0/24 +202.14.149.0/24 +202.14.151.0/24 +202.14.157.0/24 +202.14.158.0/23 +202.14.169.0/24 +202.14.170.0/23 +202.14.172.0/22 +202.14.176.0/24 +202.14.184.0/23 +202.14.208.0/23 +202.14.213.0/24 +202.14.219.0/24 +202.14.220.0/24 +202.14.222.0/23 +202.14.225.0/24 +202.14.226.0/23 +202.14.231.0/24 +202.14.235.0/24 +202.14.236.0/23 +202.14.238.0/24 +202.14.239.0/24 +202.14.246.0/24 +202.14.251.0/24 +202.20.66.0/24 +202.20.79.0/24 +202.20.87.0/24 +202.20.88.0/23 +202.20.90.0/24 +202.20.94.0/23 +202.20.114.0/24 +202.20.117.0/24 +202.20.120.0/24 +202.20.125.0/24 +202.20.126.0/24 +202.20.127.0/24 +202.21.48.0/22 +202.21.52.0/22 +202.21.56.0/22 +202.21.60.0/22 +202.21.131.0/24 +202.21.132.0/24 +202.21.141.0/24 +202.21.142.0/24 +202.21.147.0/24 +202.21.148.0/24 +202.21.150.0/23 +202.21.152.0/23 +202.21.154.0/24 +202.21.156.0/24 +202.22.248.0/22 +202.22.252.0/22 +202.27.12.0/24 +202.27.14.0/24 +202.27.136.0/23 +202.36.226.0/24 +202.38.0.0/23 +202.38.2.0/23 +202.38.8.0/21 +202.38.48.0/20 +202.38.64.0/19 +202.38.96.0/19 +202.38.128.0/23 +202.38.130.0/23 +202.38.132.0/23 +202.38.134.0/24 +202.38.135.0/24 +202.38.136.0/23 +202.38.138.0/24 +202.38.140.0/23 +202.38.142.0/23 +202.38.146.0/23 +202.38.149.0/24 +202.38.150.0/23 +202.38.152.0/23 +202.38.154.0/23 +202.38.156.0/24 +202.38.158.0/23 +202.38.160.0/23 +202.38.164.0/22 +202.38.168.0/23 +202.38.170.0/24 +202.38.171.0/24 +202.38.176.0/23 +202.38.184.0/21 +202.38.192.0/18 +202.40.4.0/23 +202.40.7.0/24 +202.40.15.0/24 +202.40.135.0/24 +202.40.136.0/24 +202.40.140.0/24 +202.40.143.0/24 +202.40.144.0/23 +202.40.150.0/24 +202.40.155.0/24 +202.40.156.0/24 +202.40.158.0/23 +202.40.162.0/24 +202.41.8.0/23 +202.41.11.0/24 +202.41.12.0/23 +202.41.128.0/24 +202.41.130.0/23 +202.41.152.0/21 +202.41.192.0/24 +202.41.196.0/22 +202.41.200.0/22 +202.41.240.0/20 +202.43.76.0/22 +202.43.144.0/20 +202.44.16.0/20 +202.44.48.0/22 +202.44.67.0/24 +202.44.74.0/24 +202.44.97.0/24 +202.44.129.0/24 +202.44.132.0/23 +202.44.146.0/23 +202.45.0.0/23 +202.45.2.0/24 +202.45.15.0/24 +202.45.16.0/20 +202.46.16.0/23 +202.46.18.0/24 +202.46.20.0/23 +202.46.32.0/19 +202.46.128.0/24 +202.46.224.0/20 +202.47.82.0/23 +202.47.96.0/22 +202.47.100.0/22 +202.47.104.0/22 +202.47.108.0/22 +202.47.126.0/24 +202.47.128.0/24 +202.47.130.0/23 +202.52.33.0/24 +202.52.34.0/24 +202.52.47.0/24 +202.52.143.0/24 +202.53.140.0/24 +202.53.143.0/24 +202.57.192.0/22 +202.57.196.0/22 +202.57.200.0/22 +202.57.204.0/22 +202.57.212.0/22 +202.57.216.0/22 +202.57.240.0/20 +202.58.0.0/24 +202.58.104.0/22 +202.58.112.0/22 +202.59.0.0/24 +202.59.1.0/24 +202.59.212.0/22 +202.59.236.0/24 +202.59.240.0/24 +202.60.48.0/21 +202.60.96.0/21 +202.60.112.0/20 +202.60.132.0/22 +202.60.136.0/21 +202.60.144.0/20 +202.61.68.0/22 +202.61.76.0/22 +202.61.88.0/22 +202.61.123.0/24 +202.61.127.0/24 +202.62.112.0/22 +202.62.248.0/22 +202.62.252.0/24 +202.62.255.0/24 +202.63.80.0/24 +202.63.81.0/24 +202.63.82.0/23 +202.63.84.0/22 +202.63.88.0/21 +202.63.160.0/19 +202.63.248.0/22 +202.63.253.0/24 +202.65.0.0/21 +202.65.8.0/23 +202.65.96.0/22 +202.65.100.0/22 +202.65.104.0/22 +202.65.108.0/22 +202.66.168.0/22 +202.67.0.0/22 +202.69.4.0/22 +202.69.16.0/20 +202.70.0.0/19 +202.70.96.0/20 +202.70.192.0/20 +202.71.32.0/22 +202.71.36.0/22 +202.71.40.0/22 +202.71.44.0/22 +202.72.40.0/21 +202.72.80.0/20 +202.72.112.0/22 +202.72.116.0/22 +202.72.120.0/22 +202.72.124.0/22 +202.73.128.0/22 +202.73.240.0/22 +202.73.244.0/22 +202.73.248.0/22 +202.73.252.0/22 +202.74.8.0/21 +202.74.36.0/24 +202.74.42.0/24 +202.74.52.0/24 +202.74.80.0/20 +202.74.232.0/22 +202.74.254.0/23 +202.75.208.0/20 +202.75.252.0/22 +202.76.252.0/22 +202.77.80.0/21 +202.77.92.0/22 +202.78.8.0/21 +202.79.224.0/21 +202.79.248.0/22 +202.80.192.0/21 +202.80.200.0/21 +202.81.0.0/22 +202.81.176.0/22 +202.81.180.0/22 +202.81.184.0/22 +202.81.188.0/22 +202.83.252.0/22 +202.84.0.0/22 +202.84.4.0/22 +202.84.8.0/21 +202.84.16.0/23 +202.84.22.0/24 +202.84.24.0/21 +202.85.208.0/20 +202.86.249.0/24 +202.86.252.0/22 +202.87.80.0/20 +202.88.32.0/22 +202.89.8.0/21 +202.89.96.0/22 +202.89.108.0/22 +202.89.119.0/24 +202.89.232.0/21 +202.90.0.0/22 +202.90.16.0/22 +202.90.20.0/22 +202.90.24.0/22 +202.90.28.0/22 +202.90.37.0/24 +202.90.96.0/22 +202.90.100.0/22 +202.90.104.0/22 +202.90.108.0/22 +202.90.112.0/20 +202.90.193.0/24 +202.90.196.0/24 +202.90.205.0/24 +202.90.224.0/20 +202.91.0.0/22 +202.91.36.0/22 +202.91.96.0/20 +202.91.128.0/22 +202.91.176.0/20 +202.91.224.0/19 +202.92.0.0/22 +202.92.8.0/21 +202.92.48.0/20 +202.92.252.0/22 +202.93.0.0/22 +202.93.252.0/22 +202.94.74.0/24 +202.94.81.0/24 +202.94.92.0/22 +202.95.240.0/21 +202.95.252.0/22 +202.96.0.0/18 +202.96.64.0/21 +202.96.72.0/21 +202.96.80.0/20 +202.96.96.0/21 +202.96.104.0/21 +202.96.112.0/20 +202.96.128.0/21 +202.96.136.0/21 +202.96.144.0/20 +202.96.160.0/21 +202.96.168.0/21 +202.96.176.0/20 +202.96.192.0/21 +202.96.200.0/21 +202.96.208.0/20 +202.96.224.0/21 +202.96.232.0/21 +202.96.240.0/20 +202.97.0.0/21 +202.97.8.0/21 +202.97.16.0/20 +202.97.32.0/19 +202.97.64.0/19 +202.97.96.0/20 +202.97.112.0/20 +202.97.128.0/18 +202.97.192.0/19 +202.97.224.0/21 +202.97.232.0/21 +202.97.240.0/20 +202.98.0.0/21 +202.98.8.0/21 +202.98.16.0/20 +202.98.32.0/21 +202.98.40.0/21 +202.98.48.0/20 +202.98.64.0/19 +202.98.96.0/21 +202.98.104.0/21 +202.98.112.0/20 +202.98.128.0/19 +202.98.160.0/21 +202.98.168.0/21 +202.98.176.0/20 +202.98.192.0/21 +202.98.200.0/21 +202.98.208.0/20 +202.98.224.0/21 +202.98.232.0/21 +202.98.240.0/20 +202.99.0.0/18 +202.99.64.0/19 +202.99.96.0/21 +202.99.104.0/21 +202.99.112.0/20 +202.99.128.0/19 +202.99.160.0/21 +202.99.168.0/21 +202.99.176.0/20 +202.99.192.0/21 +202.99.200.0/21 +202.99.208.0/20 +202.99.224.0/21 +202.99.232.0/21 +202.99.240.0/20 +202.100.0.0/21 +202.100.8.0/21 +202.100.16.0/20 +202.100.32.0/19 +202.100.64.0/21 +202.100.72.0/21 +202.100.80.0/20 +202.100.96.0/21 +202.100.104.0/21 +202.100.112.0/20 +202.100.128.0/21 +202.100.136.0/21 +202.100.144.0/20 +202.100.160.0/21 +202.100.168.0/21 +202.100.176.0/20 +202.100.192.0/21 +202.100.200.0/21 +202.100.208.0/20 +202.100.224.0/19 +202.101.0.0/18 +202.101.64.0/19 +202.101.96.0/19 +202.101.128.0/18 +202.101.192.0/19 +202.101.224.0/21 +202.101.232.0/21 +202.101.240.0/20 +202.102.0.0/19 +202.102.32.0/19 +202.102.64.0/18 +202.102.128.0/21 +202.102.136.0/21 +202.102.144.0/20 +202.102.160.0/19 +202.102.192.0/21 +202.102.200.0/21 +202.102.208.0/20 +202.102.224.0/21 +202.102.232.0/21 +202.102.240.0/20 +202.103.0.0/21 +202.103.8.0/21 +202.103.16.0/20 +202.103.32.0/19 +202.103.64.0/19 +202.103.96.0/21 +202.103.104.0/21 +202.103.112.0/20 +202.103.128.0/18 +202.103.192.0/19 +202.103.224.0/21 +202.103.232.0/21 +202.103.240.0/20 +202.104.0.0/15 +202.106.0.0/16 +202.107.0.0/17 +202.107.128.0/17 +202.108.0.0/16 +202.109.0.0/16 +202.110.0.0/18 +202.110.64.0/18 +202.110.128.0/18 +202.110.192.0/18 +202.111.0.0/17 +202.111.128.0/19 +202.111.160.0/19 +202.111.192.0/18 +202.112.0.0/16 +202.113.0.0/20 +202.113.16.0/20 +202.113.32.0/19 +202.113.64.0/18 +202.113.128.0/18 +202.113.192.0/19 +202.113.224.0/20 +202.113.240.0/20 +202.114.0.0/19 +202.114.32.0/19 +202.114.64.0/18 +202.114.128.0/17 +202.115.0.0/19 +202.115.32.0/19 +202.115.64.0/18 +202.115.128.0/17 +202.116.0.0/19 +202.116.32.0/20 +202.116.48.0/20 +202.116.64.0/19 +202.116.96.0/19 +202.116.128.0/17 +202.117.0.0/18 +202.117.64.0/18 +202.117.128.0/17 +202.118.0.0/19 +202.118.32.0/19 +202.118.64.0/18 +202.118.128.0/17 +202.119.0.0/19 +202.119.32.0/19 +202.119.64.0/20 +202.119.80.0/20 +202.119.96.0/19 +202.119.128.0/17 +202.120.0.0/18 +202.120.64.0/18 +202.120.128.0/17 +202.121.0.0/16 +202.122.0.0/21 +202.122.32.0/21 +202.122.64.0/19 +202.122.112.0/21 +202.122.120.0/21 +202.122.128.0/24 +202.122.132.0/24 +202.123.96.0/20 +202.123.116.0/22 +202.123.120.0/22 +202.124.16.0/21 +202.124.24.0/22 +202.125.107.0/24 +202.125.109.0/24 +202.125.112.0/20 +202.125.176.0/20 +202.127.0.0/23 +202.127.2.0/24 +202.127.3.0/24 +202.127.4.0/24 +202.127.5.0/24 +202.127.6.0/23 +202.127.12.0/22 +202.127.16.0/20 +202.127.40.0/21 +202.127.48.0/20 +202.127.112.0/20 +202.127.128.0/20 +202.127.144.0/20 +202.127.160.0/21 +202.127.192.0/23 +202.127.194.0/23 +202.127.196.0/22 +202.127.200.0/21 +202.127.208.0/24 +202.127.209.0/24 +202.127.212.0/22 +202.127.216.0/21 +202.127.224.0/19 +202.129.208.0/24 +202.130.0.0/19 +202.130.39.0/24 +202.130.224.0/19 +202.131.16.0/21 +202.131.48.0/20 +202.131.208.0/20 +202.133.32.0/20 +202.134.58.0/24 +202.134.128.0/20 +202.134.208.0/22 +202.134.212.0/22 +202.134.216.0/22 +202.134.220.0/22 +202.136.48.0/20 +202.136.208.0/20 +202.136.224.0/20 +202.136.248.0/22 +202.137.231.0/24 +202.140.140.0/22 +202.140.144.0/22 +202.140.148.0/22 +202.140.152.0/22 +202.140.156.0/22 +202.141.160.0/19 +202.142.16.0/20 +202.143.4.0/22 +202.143.16.0/20 +202.143.32.0/20 +202.143.56.0/21 +202.143.100.0/22 +202.143.104.0/22 +202.144.196.0/22 +202.146.160.0/20 +202.146.186.0/24 +202.146.188.0/22 +202.146.196.0/22 +202.146.200.0/21 +202.147.144.0/20 +202.148.32.0/20 +202.148.64.0/19 +202.148.96.0/19 +202.149.32.0/19 +202.149.160.0/19 +202.149.224.0/19 +202.150.16.0/20 +202.150.32.0/20 +202.150.56.0/22 +202.150.192.0/20 +202.150.224.0/19 +202.151.0.0/22 +202.151.33.0/24 +202.151.128.0/19 +202.152.176.0/20 +202.153.0.0/22 +202.153.7.0/24 +202.153.48.0/20 +202.157.192.0/19 +202.158.160.0/19 +202.158.242.0/24 +202.160.140.0/22 +202.160.156.0/22 +202.160.176.0/20 +202.162.67.0/24 +202.162.75.0/24 +202.164.0.0/20 +202.164.96.0/19 +202.165.176.0/20 +202.165.208.0/20 +202.165.239.0/24 +202.165.240.0/23 +202.165.243.0/24 +202.165.245.0/24 +202.165.251.0/24 +202.165.252.0/22 +202.166.224.0/19 +202.168.80.0/22 +202.168.128.0/22 +202.168.132.0/22 +202.168.136.0/22 +202.168.140.0/22 +202.168.160.0/20 +202.168.176.0/20 +202.170.128.0/19 +202.170.216.0/21 +202.170.224.0/19 +202.171.216.0/21 +202.171.232.0/24 +202.171.235.0/24 +202.172.0.0/22 +202.172.7.0/24 +202.173.0.0/22 +202.173.6.0/24 +202.173.8.0/21 +202.173.112.0/22 +202.173.224.0/19 +202.174.64.0/20 +202.174.124.0/22 +202.176.224.0/19 +202.179.160.0/22 +202.179.164.0/22 +202.179.168.0/22 +202.179.172.0/22 +202.179.240.0/20 +202.180.128.0/19 +202.180.208.0/21 +202.181.8.0/22 +202.181.28.0/22 +202.181.112.0/20 +202.182.32.0/20 +202.182.192.0/19 +202.189.0.0/18 +202.189.80.0/20 +202.189.184.0/21 +202.191.0.0/24 +202.191.68.0/22 +202.191.72.0/21 +202.191.80.0/20 +202.192.0.0/13 +202.200.0.0/14 +202.204.0.0/14 +203.0.4.0/22 +203.0.10.0/23 +203.0.18.0/24 +203.0.24.0/24 +203.0.42.0/23 +203.0.45.0/24 +203.0.46.0/23 +203.0.81.0/24 +203.0.82.0/23 +203.0.90.0/23 +203.0.96.0/23 +203.0.104.0/21 +203.0.114.0/23 +203.0.122.0/24 +203.0.128.0/24 +203.0.130.0/23 +203.0.132.0/22 +203.0.137.0/24 +203.0.142.0/24 +203.0.144.0/24 +203.0.146.0/24 +203.0.148.0/24 +203.0.150.0/23 +203.0.152.0/24 +203.0.177.0/24 +203.0.224.0/24 +203.1.4.0/22 +203.1.18.0/24 +203.1.26.0/23 +203.1.65.0/24 +203.1.66.0/23 +203.1.70.0/23 +203.1.76.0/23 +203.1.90.0/24 +203.1.97.0/24 +203.1.98.0/23 +203.1.100.0/22 +203.1.108.0/24 +203.1.253.0/24 +203.1.254.0/24 +203.2.64.0/21 +203.2.73.0/24 +203.2.112.0/21 +203.2.126.0/23 +203.2.140.0/24 +203.2.150.0/24 +203.2.152.0/22 +203.2.156.0/23 +203.2.160.0/21 +203.2.180.0/23 +203.2.196.0/23 +203.2.209.0/24 +203.2.214.0/23 +203.2.226.0/23 +203.2.229.0/24 +203.2.236.0/23 +203.3.68.0/24 +203.3.72.0/23 +203.3.75.0/24 +203.3.80.0/21 +203.3.96.0/22 +203.3.105.0/24 +203.3.112.0/21 +203.3.120.0/24 +203.3.123.0/24 +203.3.135.0/24 +203.3.139.0/24 +203.3.143.0/24 +203.4.132.0/23 +203.4.134.0/24 +203.4.151.0/24 +203.4.152.0/22 +203.4.174.0/23 +203.4.180.0/24 +203.4.186.0/24 +203.4.205.0/24 +203.4.208.0/22 +203.4.227.0/24 +203.4.230.0/23 +203.5.4.0/23 +203.5.7.0/24 +203.5.8.0/23 +203.5.11.0/24 +203.5.21.0/24 +203.5.22.0/24 +203.5.44.0/24 +203.5.46.0/23 +203.5.52.0/22 +203.5.56.0/23 +203.5.60.0/23 +203.5.114.0/23 +203.5.118.0/24 +203.5.120.0/24 +203.5.172.0/24 +203.5.180.0/23 +203.5.182.0/24 +203.5.185.0/24 +203.5.186.0/24 +203.5.188.0/23 +203.5.190.0/24 +203.5.195.0/24 +203.5.214.0/23 +203.5.218.0/23 +203.6.131.0/24 +203.6.136.0/24 +203.6.138.0/23 +203.6.142.0/24 +203.6.150.0/23 +203.6.157.0/24 +203.6.159.0/24 +203.6.224.0/20 +203.6.248.0/23 +203.7.129.0/24 +203.7.138.0/23 +203.7.147.0/24 +203.7.150.0/23 +203.7.158.0/24 +203.7.192.0/23 +203.7.200.0/24 +203.8.0.0/24 +203.8.8.0/24 +203.8.23.0/24 +203.8.24.0/21 +203.8.70.0/24 +203.8.82.0/24 +203.8.86.0/23 +203.8.91.0/24 +203.8.110.0/23 +203.8.115.0/24 +203.8.166.0/23 +203.8.169.0/24 +203.8.173.0/24 +203.8.184.0/24 +203.8.186.0/23 +203.8.190.0/23 +203.8.192.0/24 +203.8.197.0/24 +203.8.198.0/23 +203.8.203.0/24 +203.8.209.0/24 +203.8.210.0/23 +203.8.212.0/22 +203.8.217.0/24 +203.8.220.0/24 +203.9.32.0/24 +203.9.36.0/23 +203.9.57.0/24 +203.9.63.0/24 +203.9.65.0/24 +203.9.70.0/23 +203.9.72.0/24 +203.9.75.0/24 +203.9.76.0/23 +203.9.96.0/22 +203.9.100.0/23 +203.9.108.0/24 +203.9.158.0/24 +203.10.34.0/24 +203.10.56.0/24 +203.10.74.0/23 +203.10.84.0/22 +203.10.88.0/24 +203.10.95.0/24 +203.10.125.0/24 +203.11.70.0/24 +203.11.76.0/22 +203.11.82.0/24 +203.11.84.0/22 +203.11.100.0/22 +203.11.109.0/24 +203.11.117.0/24 +203.11.122.0/24 +203.11.126.0/24 +203.11.136.0/22 +203.11.141.0/24 +203.11.142.0/23 +203.11.180.0/22 +203.11.208.0/22 +203.12.16.0/24 +203.12.19.0/24 +203.12.24.0/24 +203.12.57.0/24 +203.12.65.0/24 +203.12.66.0/24 +203.12.70.0/23 +203.12.87.0/24 +203.12.88.0/21 +203.12.100.0/23 +203.12.103.0/24 +203.12.114.0/24 +203.12.118.0/24 +203.12.130.0/24 +203.12.137.0/24 +203.12.196.0/22 +203.12.200.0/21 +203.12.211.0/24 +203.12.219.0/24 +203.12.226.0/24 +203.12.240.0/22 +203.13.18.0/24 +203.13.24.0/24 +203.13.44.0/23 +203.13.80.0/21 +203.13.88.0/23 +203.13.92.0/22 +203.13.173.0/24 +203.13.224.0/23 +203.13.227.0/24 +203.13.233.0/24 +203.14.24.0/22 +203.14.33.0/24 +203.14.56.0/24 +203.14.61.0/24 +203.14.62.0/24 +203.14.104.0/24 +203.14.114.0/23 +203.14.118.0/24 +203.14.162.0/24 +203.14.184.0/21 +203.14.192.0/24 +203.14.194.0/23 +203.14.214.0/24 +203.14.231.0/24 +203.14.246.0/24 +203.15.0.0/20 +203.15.20.0/23 +203.15.22.0/24 +203.15.87.0/24 +203.15.88.0/23 +203.15.105.0/24 +203.15.112.0/21 +203.15.130.0/23 +203.15.149.0/24 +203.15.151.0/24 +203.15.156.0/22 +203.15.174.0/24 +203.15.227.0/24 +203.15.232.0/21 +203.15.240.0/23 +203.15.246.0/24 +203.16.10.0/24 +203.16.12.0/23 +203.16.16.0/21 +203.16.27.0/24 +203.16.38.0/24 +203.16.49.0/24 +203.16.50.0/23 +203.16.58.0/24 +203.16.63.0/24 +203.16.133.0/24 +203.16.161.0/24 +203.16.162.0/24 +203.16.186.0/23 +203.16.228.0/24 +203.16.238.0/24 +203.16.240.0/24 +203.16.245.0/24 +203.17.2.0/24 +203.17.18.0/24 +203.17.28.0/24 +203.17.39.0/24 +203.17.56.0/24 +203.17.74.0/23 +203.17.88.0/23 +203.17.136.0/24 +203.17.164.0/24 +203.17.187.0/24 +203.17.190.0/23 +203.17.231.0/24 +203.17.233.0/24 +203.17.248.0/24 +203.17.249.0/24 +203.17.255.0/24 +203.18.2.0/23 +203.18.4.0/24 +203.18.7.0/24 +203.18.31.0/24 +203.18.37.0/24 +203.18.48.0/23 +203.18.52.0/24 +203.18.72.0/22 +203.18.80.0/23 +203.18.87.0/24 +203.18.100.0/23 +203.18.105.0/24 +203.18.107.0/24 +203.18.110.0/24 +203.18.129.0/24 +203.18.131.0/24 +203.18.132.0/23 +203.18.144.0/24 +203.18.153.0/24 +203.18.199.0/24 +203.18.208.0/24 +203.18.211.0/24 +203.18.215.0/24 +203.19.1.0/24 +203.19.18.0/24 +203.19.24.0/24 +203.19.30.0/24 +203.19.32.0/21 +203.19.41.0/24 +203.19.44.0/23 +203.19.46.0/24 +203.19.58.0/24 +203.19.60.0/23 +203.19.64.0/24 +203.19.68.0/24 +203.19.72.0/24 +203.19.101.0/24 +203.19.111.0/24 +203.19.131.0/24 +203.19.133.0/24 +203.19.144.0/24 +203.19.147.0/24 +203.19.149.0/24 +203.19.156.0/24 +203.19.176.0/24 +203.19.178.0/23 +203.19.208.0/24 +203.19.228.0/22 +203.19.233.0/24 +203.19.242.0/24 +203.19.248.0/23 +203.19.255.0/24 +203.20.17.0/24 +203.20.40.0/23 +203.20.44.0/24 +203.20.48.0/24 +203.20.61.0/24 +203.20.65.0/24 +203.20.84.0/23 +203.20.89.0/24 +203.20.106.0/23 +203.20.115.0/24 +203.20.117.0/24 +203.20.118.0/23 +203.20.122.0/24 +203.20.126.0/23 +203.20.135.0/24 +203.20.136.0/21 +203.20.150.0/24 +203.20.230.0/24 +203.20.232.0/24 +203.20.236.0/24 +203.21.0.0/23 +203.21.2.0/24 +203.21.8.0/24 +203.21.10.0/24 +203.21.18.0/24 +203.21.33.0/24 +203.21.34.0/24 +203.21.41.0/24 +203.21.44.0/24 +203.21.68.0/24 +203.21.82.0/24 +203.21.96.0/22 +203.21.124.0/24 +203.21.136.0/23 +203.21.145.0/24 +203.21.206.0/24 +203.22.24.0/24 +203.22.28.0/23 +203.22.31.0/24 +203.22.68.0/24 +203.22.76.0/24 +203.22.78.0/24 +203.22.84.0/24 +203.22.87.0/24 +203.22.92.0/22 +203.22.99.0/24 +203.22.106.0/24 +203.22.122.0/23 +203.22.131.0/24 +203.22.163.0/24 +203.22.166.0/24 +203.22.170.0/24 +203.22.176.0/21 +203.22.194.0/24 +203.22.242.0/23 +203.22.245.0/24 +203.22.246.0/24 +203.22.252.0/23 +203.23.0.0/24 +203.23.47.0/24 +203.23.61.0/24 +203.23.62.0/23 +203.23.73.0/24 +203.23.85.0/24 +203.23.92.0/22 +203.23.98.0/24 +203.23.107.0/24 +203.23.112.0/24 +203.23.130.0/24 +203.23.140.0/23 +203.23.172.0/24 +203.23.182.0/24 +203.23.186.0/23 +203.23.192.0/24 +203.23.197.0/24 +203.23.198.0/24 +203.23.204.0/22 +203.23.224.0/24 +203.23.226.0/23 +203.23.228.0/22 +203.23.249.0/24 +203.23.251.0/24 +203.24.13.0/24 +203.24.18.0/24 +203.24.27.0/24 +203.24.43.0/24 +203.24.56.0/24 +203.24.58.0/24 +203.24.67.0/24 +203.24.74.0/24 +203.24.79.0/24 +203.24.80.0/23 +203.24.84.0/23 +203.24.86.0/24 +203.24.90.0/24 +203.24.111.0/24 +203.24.112.0/24 +203.24.116.0/24 +203.24.122.0/23 +203.24.145.0/24 +203.24.152.0/23 +203.24.157.0/24 +203.24.161.0/24 +203.24.167.0/24 +203.24.186.0/23 +203.24.199.0/24 +203.24.202.0/24 +203.24.212.0/23 +203.24.217.0/24 +203.24.219.0/24 +203.24.244.0/24 +203.25.19.0/24 +203.25.20.0/23 +203.25.46.0/24 +203.25.48.0/21 +203.25.64.0/23 +203.25.91.0/24 +203.25.99.0/24 +203.25.100.0/24 +203.25.106.0/24 +203.25.131.0/24 +203.25.135.0/24 +203.25.138.0/24 +203.25.147.0/24 +203.25.153.0/24 +203.25.154.0/23 +203.25.164.0/24 +203.25.166.0/24 +203.25.174.0/23 +203.25.180.0/24 +203.25.182.0/24 +203.25.191.0/24 +203.25.199.0/24 +203.25.200.0/24 +203.25.202.0/23 +203.25.208.0/20 +203.25.229.0/24 +203.25.235.0/24 +203.25.236.0/24 +203.25.242.0/24 +203.26.12.0/24 +203.26.34.0/24 +203.26.49.0/24 +203.26.50.0/24 +203.26.55.0/24 +203.26.56.0/23 +203.26.60.0/24 +203.26.65.0/24 +203.26.68.0/24 +203.26.76.0/24 +203.26.80.0/24 +203.26.84.0/24 +203.26.97.0/24 +203.26.102.0/23 +203.26.115.0/24 +203.26.116.0/24 +203.26.129.0/24 +203.26.143.0/24 +203.26.144.0/24 +203.26.148.0/23 +203.26.154.0/24 +203.26.158.0/23 +203.26.170.0/24 +203.26.173.0/24 +203.26.176.0/24 +203.26.185.0/24 +203.26.202.0/23 +203.26.210.0/24 +203.26.214.0/24 +203.26.222.0/24 +203.26.224.0/24 +203.26.228.0/24 +203.26.232.0/24 +203.27.0.0/24 +203.27.10.0/24 +203.27.15.0/24 +203.27.16.0/24 +203.27.20.0/24 +203.27.22.0/23 +203.27.40.0/24 +203.27.45.0/24 +203.27.53.0/24 +203.27.65.0/24 +203.27.66.0/24 +203.27.81.0/24 +203.27.88.0/24 +203.27.102.0/24 +203.27.109.0/24 +203.27.117.0/24 +203.27.121.0/24 +203.27.122.0/23 +203.27.125.0/24 +203.27.200.0/24 +203.27.202.0/24 +203.27.233.0/24 +203.27.241.0/24 +203.27.250.0/24 +203.28.10.0/24 +203.28.12.0/24 +203.28.33.0/24 +203.28.34.0/23 +203.28.43.0/24 +203.28.44.0/24 +203.28.54.0/24 +203.28.56.0/24 +203.28.73.0/24 +203.28.74.0/24 +203.28.76.0/24 +203.28.86.0/24 +203.28.88.0/24 +203.28.112.0/24 +203.28.131.0/24 +203.28.136.0/24 +203.28.140.0/24 +203.28.145.0/24 +203.28.165.0/24 +203.28.169.0/24 +203.28.170.0/24 +203.28.178.0/23 +203.28.185.0/24 +203.28.187.0/24 +203.28.196.0/24 +203.28.226.0/23 +203.28.239.0/24 +203.29.2.0/24 +203.29.8.0/23 +203.29.13.0/24 +203.29.14.0/24 +203.29.28.0/24 +203.29.46.0/24 +203.29.57.0/24 +203.29.61.0/24 +203.29.63.0/24 +203.29.69.0/24 +203.29.73.0/24 +203.29.81.0/24 +203.29.90.0/24 +203.29.95.0/24 +203.29.100.0/24 +203.29.103.0/24 +203.29.112.0/24 +203.29.120.0/22 +203.29.182.0/23 +203.29.187.0/24 +203.29.189.0/24 +203.29.190.0/24 +203.29.205.0/24 +203.29.210.0/24 +203.29.217.0/24 +203.29.227.0/24 +203.29.231.0/24 +203.29.233.0/24 +203.29.234.0/24 +203.29.248.0/24 +203.29.254.0/23 +203.30.16.0/23 +203.30.25.0/24 +203.30.27.0/24 +203.30.29.0/24 +203.30.66.0/24 +203.30.81.0/24 +203.30.87.0/24 +203.30.111.0/24 +203.30.121.0/24 +203.30.123.0/24 +203.30.152.0/24 +203.30.156.0/24 +203.30.162.0/24 +203.30.173.0/24 +203.30.175.0/24 +203.30.187.0/24 +203.30.194.0/24 +203.30.217.0/24 +203.30.220.0/24 +203.30.222.0/24 +203.30.232.0/23 +203.30.235.0/24 +203.30.240.0/23 +203.30.246.0/24 +203.30.250.0/23 +203.31.45.0/24 +203.31.46.0/24 +203.31.49.0/24 +203.31.51.0/24 +203.31.54.0/23 +203.31.69.0/24 +203.31.72.0/24 +203.31.80.0/24 +203.31.85.0/24 +203.31.97.0/24 +203.31.105.0/24 +203.31.106.0/24 +203.31.108.0/23 +203.31.124.0/24 +203.31.162.0/24 +203.31.174.0/24 +203.31.177.0/24 +203.31.181.0/24 +203.31.187.0/24 +203.31.189.0/24 +203.31.204.0/24 +203.31.220.0/24 +203.31.222.0/23 +203.31.225.0/24 +203.31.229.0/24 +203.31.248.0/23 +203.31.253.0/24 +203.32.20.0/24 +203.32.48.0/23 +203.32.56.0/24 +203.32.60.0/24 +203.32.62.0/24 +203.32.68.0/23 +203.32.76.0/24 +203.32.81.0/24 +203.32.84.0/23 +203.32.95.0/24 +203.32.102.0/24 +203.32.105.0/24 +203.32.130.0/24 +203.32.133.0/24 +203.32.140.0/24 +203.32.152.0/24 +203.32.186.0/23 +203.32.192.0/24 +203.32.196.0/24 +203.32.203.0/24 +203.32.204.0/23 +203.32.212.0/24 +203.33.4.0/24 +203.33.7.0/24 +203.33.8.0/21 +203.33.21.0/24 +203.33.26.0/24 +203.33.32.0/24 +203.33.63.0/24 +203.33.64.0/24 +203.33.67.0/24 +203.33.68.0/24 +203.33.73.0/24 +203.33.79.0/24 +203.33.100.0/24 +203.33.122.0/24 +203.33.129.0/24 +203.33.131.0/24 +203.33.145.0/24 +203.33.156.0/24 +203.33.158.0/23 +203.33.174.0/24 +203.33.185.0/24 +203.33.200.0/24 +203.33.202.0/23 +203.33.204.0/24 +203.33.206.0/23 +203.33.214.0/23 +203.33.224.0/23 +203.33.226.0/24 +203.33.233.0/24 +203.33.243.0/24 +203.33.250.0/24 +203.34.4.0/24 +203.34.21.0/24 +203.34.27.0/24 +203.34.39.0/24 +203.34.48.0/23 +203.34.54.0/24 +203.34.56.0/23 +203.34.67.0/24 +203.34.69.0/24 +203.34.76.0/24 +203.34.92.0/24 +203.34.106.0/24 +203.34.113.0/24 +203.34.147.0/24 +203.34.150.0/24 +203.34.152.0/23 +203.34.161.0/24 +203.34.162.0/24 +203.34.187.0/24 +203.34.192.0/21 +203.34.204.0/22 +203.34.232.0/24 +203.34.240.0/24 +203.34.242.0/24 +203.34.245.0/24 +203.34.251.0/24 +203.55.2.0/23 +203.55.4.0/24 +203.55.10.0/24 +203.55.13.0/24 +203.55.22.0/24 +203.55.30.0/24 +203.55.93.0/24 +203.55.101.0/24 +203.55.109.0/24 +203.55.110.0/24 +203.55.116.0/23 +203.55.119.0/24 +203.55.128.0/23 +203.55.146.0/23 +203.55.192.0/24 +203.55.196.0/24 +203.55.218.0/23 +203.55.221.0/24 +203.55.224.0/24 +203.56.1.0/24 +203.56.4.0/24 +203.56.12.0/24 +203.56.24.0/24 +203.56.38.0/24 +203.56.40.0/24 +203.56.46.0/24 +203.56.48.0/21 +203.56.68.0/23 +203.56.82.0/23 +203.56.84.0/23 +203.56.95.0/24 +203.56.110.0/24 +203.56.121.0/24 +203.56.161.0/24 +203.56.169.0/24 +203.56.172.0/23 +203.56.175.0/24 +203.56.183.0/24 +203.56.185.0/24 +203.56.187.0/24 +203.56.192.0/24 +203.56.198.0/24 +203.56.201.0/24 +203.56.208.0/23 +203.56.210.0/24 +203.56.214.0/24 +203.56.216.0/24 +203.56.227.0/24 +203.56.228.0/24 +203.56.231.0/24 +203.56.232.0/24 +203.56.240.0/24 +203.56.252.0/24 +203.56.254.0/24 +203.57.5.0/24 +203.57.6.0/24 +203.57.12.0/23 +203.57.28.0/24 +203.57.39.0/24 +203.57.46.0/24 +203.57.58.0/24 +203.57.61.0/24 +203.57.66.0/24 +203.57.69.0/24 +203.57.70.0/23 +203.57.73.0/24 +203.57.90.0/24 +203.57.101.0/24 +203.57.109.0/24 +203.57.123.0/24 +203.57.157.0/24 +203.57.200.0/24 +203.57.202.0/24 +203.57.206.0/24 +203.57.222.0/24 +203.57.224.0/20 +203.57.246.0/23 +203.57.249.0/24 +203.57.253.0/24 +203.57.254.0/23 +203.62.2.0/24 +203.62.131.0/24 +203.62.139.0/24 +203.62.161.0/24 +203.62.197.0/24 +203.62.228.0/22 +203.62.234.0/24 +203.62.246.0/24 +203.76.160.0/22 +203.76.168.0/22 +203.76.208.0/22 +203.76.212.0/22 +203.76.216.0/22 +203.76.240.0/22 +203.76.244.0/22 +203.77.180.0/22 +203.78.48.0/20 +203.78.156.0/22 +203.79.0.0/20 +203.79.32.0/20 +203.80.4.0/23 +203.80.32.0/20 +203.80.57.0/24 +203.80.129.0/24 +203.80.132.0/22 +203.80.136.0/21 +203.80.144.0/20 +203.81.0.0/21 +203.81.16.0/20 +203.81.244.0/22 +203.82.0.0/23 +203.82.16.0/21 +203.82.112.0/22 +203.82.116.0/22 +203.82.120.0/22 +203.82.124.0/22 +203.82.224.0/22 +203.82.228.0/22 +203.82.232.0/22 +203.82.236.0/22 +203.83.0.0/22 +203.83.8.0/22 +203.83.12.0/22 +203.83.56.0/21 +203.83.224.0/20 +203.86.0.0/19 +203.86.32.0/19 +203.86.64.0/20 +203.86.80.0/20 +203.86.96.0/19 +203.86.250.0/24 +203.86.254.0/23 +203.88.32.0/19 +203.88.192.0/19 +203.89.0.0/22 +203.89.8.0/21 +203.89.100.0/22 +203.89.133.0/24 +203.89.136.0/22 +203.89.144.0/24 +203.90.0.0/22 +203.90.8.0/22 +203.90.12.0/22 +203.90.128.0/19 +203.90.160.0/19 +203.90.192.0/19 +203.91.32.0/19 +203.91.96.0/20 +203.91.120.0/21 +203.92.0.0/22 +203.92.6.0/24 +203.92.160.0/19 +203.93.0.0/22 +203.93.4.0/22 +203.93.8.0/24 +203.93.9.0/24 +203.93.10.0/23 +203.93.12.0/22 +203.93.16.0/20 +203.93.32.0/19 +203.93.64.0/18 +203.93.128.0/21 +203.93.136.0/22 +203.93.140.0/24 +203.93.141.0/24 +203.93.142.0/23 +203.93.144.0/20 +203.93.160.0/19 +203.93.192.0/18 +203.94.0.0/22 +203.94.4.0/22 +203.94.8.0/21 +203.94.16.0/20 +203.95.0.0/21 +203.95.96.0/20 +203.95.112.0/20 +203.95.128.0/18 +203.95.200.0/22 +203.95.204.0/22 +203.95.208.0/22 +203.95.224.0/19 +203.99.8.0/21 +203.99.16.0/20 +203.99.80.0/20 +203.100.32.0/20 +203.100.48.0/21 +203.100.58.0/24 +203.100.60.0/24 +203.100.63.0/24 +203.100.80.0/20 +203.100.96.0/19 +203.100.192.0/20 +203.104.32.0/20 +203.105.96.0/19 +203.105.128.0/19 +203.107.0.0/17 +203.110.160.0/19 +203.110.208.0/20 +203.110.232.0/23 +203.110.234.0/24 +203.114.80.0/22 +203.114.84.0/22 +203.114.88.0/22 +203.114.92.0/22 +203.114.244.0/22 +203.118.192.0/19 +203.118.241.0/24 +203.118.248.0/22 +203.119.24.0/21 +203.119.32.0/22 +203.119.80.0/22 +203.119.85.0/24 +203.119.113.0/24 +203.119.114.0/23 +203.119.116.0/22 +203.119.120.0/21 +203.119.128.0/17 +203.123.58.0/24 +203.128.32.0/19 +203.128.96.0/19 +203.128.224.0/21 +203.129.8.0/21 +203.130.32.0/19 +203.132.32.0/19 +203.134.240.0/21 +203.135.96.0/20 +203.135.112.0/20 +203.135.160.0/20 +203.142.219.0/24 +203.142.224.0/19 +203.144.96.0/19 +203.145.0.0/19 +203.148.0.0/18 +203.148.64.0/20 +203.148.80.0/22 +203.148.86.0/23 +203.149.92.0/22 +203.152.64.0/19 +203.152.128.0/19 +203.153.0.0/22 +203.156.192.0/18 +203.158.16.0/21 +203.160.52.0/22 +203.160.104.0/21 +203.160.129.0/24 +203.160.192.0/19 +203.161.0.0/22 +203.161.180.0/24 +203.161.183.0/24 +203.161.192.0/19 +203.166.160.0/19 +203.167.28.0/22 +203.168.0.0/19 +203.170.58.0/23 +203.171.0.0/22 +203.171.208.0/24 +203.171.224.0/20 +203.174.4.0/24 +203.174.6.0/24 +203.174.7.0/24 +203.174.96.0/19 +203.175.128.0/19 +203.175.192.0/18 +203.176.0.0/18 +203.176.64.0/19 +203.176.168.0/21 +203.184.80.0/20 +203.185.189.0/24 +203.187.160.0/19 +203.189.0.0/23 +203.189.6.0/23 +203.189.112.0/22 +203.189.192.0/19 +203.189.232.0/22 +203.189.240.0/22 +203.190.96.0/20 +203.190.249.0/24 +203.191.0.0/23 +203.191.2.0/24 +203.191.5.0/24 +203.191.7.0/24 +203.191.16.0/20 +203.191.64.0/18 +203.191.133.0/24 +203.191.144.0/21 +203.191.152.0/21 +203.192.0.0/19 +203.193.224.0/19 +203.194.120.0/21 +203.195.64.0/19 +203.195.112.0/21 +203.195.128.0/17 +203.196.0.0/21 +203.196.8.0/21 +203.196.28.0/22 +203.201.181.0/24 +203.201.182.0/24 +203.202.236.0/22 +203.205.64.0/19 +203.205.128.0/17 +203.207.64.0/20 +203.207.80.0/21 +203.207.88.0/22 +203.207.92.0/22 +203.207.96.0/20 +203.207.112.0/20 +203.207.128.0/18 +203.207.192.0/21 +203.207.200.0/21 +203.207.208.0/20 +203.207.224.0/19 +203.208.0.0/20 +203.208.16.0/22 +203.208.32.0/19 +203.209.224.0/19 +203.212.0.0/20 +203.212.80.0/20 +203.215.232.0/21 +203.217.164.0/22 +203.222.192.0/20 +203.223.0.0/20 +203.223.16.0/21 +210.2.0.0/20 +210.2.16.0/20 +210.5.0.0/19 +210.5.56.0/21 +210.5.128.0/20 +210.5.144.0/20 +210.7.56.0/22 +210.7.60.0/22 +210.12.0.0/18 +210.12.64.0/18 +210.12.128.0/18 +210.12.192.0/18 +210.13.0.0/18 +210.13.64.0/18 +210.13.128.0/17 +210.14.64.0/19 +210.14.112.0/20 +210.14.128.0/19 +210.14.160.0/19 +210.14.192.0/19 +210.14.224.0/19 +210.15.0.0/19 +210.15.32.0/19 +210.15.64.0/19 +210.15.96.0/19 +210.15.128.0/18 +210.16.104.0/22 +210.16.128.0/18 +210.21.0.0/17 +210.21.128.0/17 +210.22.0.0/16 +210.23.32.0/19 +210.25.0.0/16 +210.26.0.0/15 +210.28.0.0/14 +210.32.0.0/14 +210.36.0.0/14 +210.40.0.0/13 +210.51.0.0/16 +210.52.0.0/18 +210.52.64.0/18 +210.52.128.0/17 +210.53.0.0/17 +210.53.128.0/17 +210.56.192.0/19 +210.72.0.0/17 +210.72.128.0/19 +210.72.160.0/19 +210.72.192.0/18 +210.73.0.0/19 +210.73.32.0/19 +210.73.64.0/18 +210.73.128.0/17 +210.74.0.0/19 +210.74.32.0/19 +210.74.64.0/19 +210.74.96.0/19 +210.74.128.0/19 +210.74.160.0/19 +210.74.192.0/18 +210.75.0.0/16 +210.76.0.0/19 +210.76.32.0/19 +210.76.64.0/18 +210.76.128.0/17 +210.77.0.0/16 +210.78.0.0/19 +210.78.32.0/19 +210.78.64.0/18 +210.78.128.0/19 +210.78.160.0/19 +210.78.192.0/18 +210.79.64.0/18 +210.79.224.0/19 +210.82.0.0/15 +210.87.128.0/20 +210.87.144.0/20 +210.87.160.0/19 +210.185.192.0/18 +210.192.96.0/19 +211.64.0.0/14 +211.68.0.0/15 +211.70.0.0/15 +211.80.0.0/16 +211.81.0.0/16 +211.82.0.0/16 +211.83.0.0/16 +211.84.0.0/15 +211.86.0.0/15 +211.88.0.0/16 +211.89.0.0/16 +211.90.0.0/15 +211.92.0.0/15 +211.94.0.0/15 +211.96.0.0/15 +211.98.0.0/16 +211.99.0.0/18 +211.99.64.0/19 +211.99.96.0/19 +211.99.128.0/17 +211.100.0.0/16 +211.101.0.0/18 +211.101.64.0/18 +211.101.128.0/17 +211.102.0.0/16 +211.103.0.0/17 +211.103.128.0/17 +211.136.0.0/14 +211.140.0.0/15 +211.142.0.0/17 +211.142.128.0/17 +211.143.0.0/16 +211.144.0.0/15 +211.146.0.0/16 +211.147.0.0/16 +211.148.0.0/14 +211.152.0.0/15 +211.154.0.0/16 +211.155.0.0/18 +211.155.64.0/19 +211.155.96.0/19 +211.155.128.0/17 +211.156.0.0/14 +211.160.0.0/14 +211.164.0.0/14 +212.64.0.0/17 +212.129.128.0/17 +216.250.108.0/22 +218.0.0.0/16 +218.1.0.0/16 +218.2.0.0/15 +218.4.0.0/15 +218.6.0.0/16 +218.7.0.0/16 +218.8.0.0/15 +218.10.0.0/16 +218.11.0.0/16 +218.12.0.0/16 +218.13.0.0/16 +218.14.0.0/15 +218.16.0.0/14 +218.20.0.0/16 +218.21.0.0/17 +218.21.128.0/17 +218.22.0.0/15 +218.24.0.0/15 +218.26.0.0/16 +218.27.0.0/16 +218.28.0.0/15 +218.30.0.0/15 +218.56.0.0/14 +218.60.0.0/15 +218.62.0.0/17 +218.62.128.0/17 +218.63.0.0/16 +218.64.0.0/15 +218.66.0.0/16 +218.67.0.0/17 +218.67.128.0/17 +218.68.0.0/15 +218.70.0.0/15 +218.72.0.0/14 +218.76.0.0/15 +218.78.0.0/15 +218.80.0.0/14 +218.84.0.0/14 +218.88.0.0/13 +218.96.0.0/15 +218.98.0.0/17 +218.98.128.0/18 +218.98.192.0/19 +218.98.224.0/19 +218.99.0.0/16 +218.100.88.0/21 +218.100.96.0/19 +218.100.128.0/17 +218.104.0.0/17 +218.104.128.0/19 +218.104.160.0/19 +218.104.192.0/21 +218.104.200.0/21 +218.104.208.0/20 +218.104.224.0/19 +218.105.0.0/16 +218.106.0.0/15 +218.108.0.0/16 +218.109.0.0/16 +218.185.192.0/19 +218.185.240.0/21 +218.192.0.0/16 +218.193.0.0/16 +218.194.0.0/16 +218.195.0.0/16 +218.196.0.0/14 +218.200.0.0/14 +218.204.0.0/15 +218.206.0.0/15 +218.240.0.0/14 +218.244.0.0/15 +218.246.0.0/15 +218.249.0.0/16 +219.72.0.0/16 +219.82.0.0/16 +219.83.128.0/17 +219.90.68.0/22 +219.90.72.0/22 +219.90.76.0/22 +219.128.0.0/12 +219.144.0.0/14 +219.148.0.0/16 +219.149.0.0/17 +219.149.128.0/18 +219.149.192.0/18 +219.150.0.0/19 +219.150.32.0/19 +219.150.64.0/19 +219.150.96.0/20 +219.150.112.0/20 +219.150.128.0/17 +219.151.0.0/19 +219.151.32.0/19 +219.151.64.0/18 +219.151.128.0/17 +219.152.0.0/15 +219.154.0.0/15 +219.156.0.0/15 +219.158.0.0/17 +219.158.128.0/17 +219.159.0.0/18 +219.159.64.0/18 +219.159.128.0/17 +219.216.0.0/15 +219.218.0.0/15 +219.220.0.0/16 +219.221.0.0/16 +219.222.0.0/15 +219.224.0.0/15 +219.226.0.0/16 +219.227.0.0/16 +219.228.0.0/15 +219.230.0.0/15 +219.232.0.0/14 +219.236.0.0/15 +219.238.0.0/15 +219.242.0.0/15 +219.244.0.0/14 +220.101.192.0/18 +220.112.0.0/14 +220.152.128.0/17 +220.154.0.0/15 +220.158.240.0/22 +220.160.0.0/11 +220.192.0.0/15 +220.194.0.0/15 +220.196.0.0/14 +220.200.0.0/13 +220.231.0.0/18 +220.231.128.0/17 +220.232.64.0/18 +220.234.0.0/16 +220.242.0.0/15 +220.247.136.0/21 +220.248.0.0/14 +220.252.0.0/16 +221.0.0.0/15 +221.2.0.0/16 +221.3.0.0/17 +221.3.128.0/17 +221.4.0.0/16 +221.5.0.0/17 +221.5.128.0/17 +221.6.0.0/16 +221.7.0.0/19 +221.7.32.0/19 +221.7.64.0/19 +221.7.96.0/19 +221.7.128.0/17 +221.8.0.0/15 +221.10.0.0/16 +221.11.0.0/17 +221.11.128.0/18 +221.11.192.0/19 +221.11.224.0/19 +221.12.0.0/17 +221.12.128.0/18 +221.13.0.0/18 +221.13.64.0/19 +221.13.96.0/19 +221.13.128.0/17 +221.14.0.0/15 +221.122.0.0/15 +221.128.128.0/17 +221.129.0.0/16 +221.130.0.0/15 +221.133.224.0/19 +221.136.0.0/16 +221.137.0.0/16 +221.172.0.0/14 +221.176.0.0/13 +221.192.0.0/15 +221.194.0.0/16 +221.195.0.0/16 +221.196.0.0/15 +221.198.0.0/16 +221.199.0.0/19 +221.199.32.0/20 +221.199.48.0/20 +221.199.64.0/18 +221.199.128.0/18 +221.199.192.0/20 +221.199.224.0/19 +221.200.0.0/14 +221.204.0.0/15 +221.206.0.0/16 +221.207.0.0/18 +221.207.64.0/18 +221.207.128.0/17 +221.208.0.0/14 +221.212.0.0/16 +221.213.0.0/16 +221.214.0.0/15 +221.216.0.0/13 +221.224.0.0/13 +221.232.0.0/14 +221.236.0.0/15 +221.238.0.0/16 +221.239.0.0/17 +221.239.128.0/17 +222.16.0.0/15 +222.18.0.0/15 +222.20.0.0/15 +222.22.0.0/16 +222.23.0.0/16 +222.24.0.0/15 +222.26.0.0/15 +222.28.0.0/14 +222.32.0.0/11 +222.64.0.0/13 +222.72.0.0/15 +222.74.0.0/16 +222.75.0.0/16 +222.76.0.0/14 +222.80.0.0/15 +222.82.0.0/16 +222.83.0.0/17 +222.83.128.0/17 +222.84.0.0/16 +222.85.0.0/17 +222.85.128.0/17 +222.86.0.0/15 +222.88.0.0/15 +222.90.0.0/15 +222.92.0.0/14 +222.125.0.0/16 +222.126.128.0/17 +222.128.0.0/14 +222.132.0.0/14 +222.136.0.0/13 +222.160.0.0/15 +222.162.0.0/16 +222.163.0.0/19 +222.163.32.0/19 +222.163.64.0/18 +222.163.128.0/17 +222.168.0.0/15 +222.170.0.0/15 +222.172.0.0/17 +222.172.128.0/17 +222.173.0.0/16 +222.174.0.0/15 +222.176.0.0/13 +222.184.0.0/13 +222.192.0.0/14 +222.196.0.0/15 +222.198.0.0/16 +222.199.0.0/16 +222.200.0.0/14 +222.204.0.0/15 +222.206.0.0/15 +222.208.0.0/13 +222.216.0.0/15 +222.218.0.0/16 +222.219.0.0/16 +222.220.0.0/15 +222.222.0.0/15 +222.240.0.0/13 +222.248.0.0/16 +222.249.0.0/17 +222.249.128.0/19 +222.249.160.0/20 +222.249.176.0/20 +222.249.192.0/18 +223.0.0.0/15 +223.2.0.0/15 +223.4.0.0/14 +223.8.0.0/13 +223.20.0.0/15 +223.27.184.0/22 +223.29.208.0/22 +223.29.252.0/22 +223.64.0.0/11 +223.96.0.0/12 +223.112.0.0/14 +223.116.0.0/15 +223.120.128.0/17 +223.121.128.0/17 +223.122.0.0/15 +223.124.0.0/14 +223.128.0.0/15 +223.144.0.0/12 +223.160.0.0/14 +223.166.0.0/15 +223.192.0.0/15 +223.198.0.0/15 +223.201.0.0/16 +223.202.0.0/15 +223.208.0.0/14 +223.212.0.0/15 +223.214.0.0/15 +223.220.0.0/15 +223.223.176.0/20 +223.223.192.0/20 +223.240.0.0/13 +223.248.0.0/14 +223.252.128.0/17 +223.254.0.0/16 +223.255.0.0/17 +223.255.236.0/22 +223.255.252.0/23 diff --git a/package/lean/luci-app-ssr-plus/root/etc/config/black.list b/package/lean/luci-app-ssr-plus/root/etc/config/black.list new file mode 100644 index 0000000000..e69de29bb2 diff --git a/package/lean/luci-app-ssr-plus/root/etc/config/gfw.list b/package/lean/luci-app-ssr-plus/root/etc/config/gfw.list new file mode 100644 index 0000000000..b8772ba26e --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/etc/config/gfw.list @@ -0,0 +1,53 @@ +91smartyun.pt +adobe.com +amazonaws.com +ampproject.org +apple.news +aws.amazon.com +azureedge.net +backpackers.com.tw +bitfinex.com +buzzfeed.com +clockwise.ee +cloudfront.net +coindesk.com +coinsquare.io +cryptocompare.com +dropboxstatic.com +eurecom.fr +gdax.com +github.com +kknews.cc +nutaq.com +openairinterface.org +skype.com +sublimetext.com +textnow.com +textnow.me +trouter.io +uploaded.net +whatsapp.com +whatsapp.net +wsj.net +google.com +google.com.hk +gstatic.com +googleusercontent.com +googlepages.com +googlevideo.com +googlecode.com +googleapis.com +googlesource.com +googledrive.com +ggpht.com +youtube.com +youtu.be +ytimg.com +twitter.com +facebook.com +fastly.net +akamai.net +akamaiedge.net +akamaihd.net +edgesuite.net +edgekey.net \ No newline at end of file diff --git a/package/lean/luci-app-ssr-plus/root/etc/config/shadowsocksr b/package/lean/luci-app-ssr-plus/root/etc/config/shadowsocksr new file mode 100644 index 0000000000..7741d69088 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/etc/config/shadowsocksr @@ -0,0 +1,37 @@ + +config global + option tunnel_forward '8.8.4.4:53' + option tunnel_address '0.0.0.0' + option run_mode 'gfw' + option pdnsd_enable '1' + option monitor_enable '1' + option global_server 'nil' + option enable_switch '1' + option switch_timeout '5' + option switch_time '667' + +config socks5_proxy + option server 'nil' + option local_port '1080' + option local_address '0.0.0.0' + +config access_control + option wan_bp_list '/etc/china_ssr.txt' + option lan_ac_mode 'b' + option router_proxy '1' + list wan_fw_ips '149.154.160.0/20' + list wan_fw_ips '67.198.55.0/24' + list wan_fw_ips '91.108.4.0/22' + list wan_fw_ips '91.108.56.0/22' + list wan_fw_ips '109.239.140.0/24' + +config server_global + option enable_server '0' + +config server_subscribe + option proxy '0' + option auto_update_time '2' + option auto_update '1' + + + diff --git a/package/lean/luci-app-ssr-plus/root/etc/config/white.list b/package/lean/luci-app-ssr-plus/root/etc/config/white.list new file mode 100644 index 0000000000..e69de29bb2 diff --git a/package/lean/luci-app-ssr-plus/root/etc/dnsmasq.oversea/oversea_list.conf b/package/lean/luci-app-ssr-plus/root/etc/dnsmasq.oversea/oversea_list.conf new file mode 100644 index 0000000000..ae50fb90d0 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/etc/dnsmasq.oversea/oversea_list.conf @@ -0,0 +1,192 @@ +server=/v.youku.com/127.0.0.1#5335 +server=/api.youku.com/127.0.0.1#5335 +server=/v2.tudou.com/127.0.0.1#5335 +server=/www.tudou.com/127.0.0.1#5335 +server=/s.plcloud.music.qq.com/127.0.0.1#5335 +server=/i.y.qq.com/127.0.0.1#5335 +server=/hot.vrs.sohu.com/127.0.0.1#5335 +server=/live.tv.sohu.com/127.0.0.1#5335 +server=/pad.tv.sohu.com/127.0.0.1#5335 +server=/my.tv.sohu.com/127.0.0.1#5335 +server=/hot.vrs.letv.com/127.0.0.1#5335 +server=/data.video.qiyi.com/127.0.0.1#5335 +server=/cache.video.qiyi.com/127.0.0.1#5335 +server=/cache.vip.qiyi.com/127.0.0.1#5335 +server=/vv.video.qq.com/127.0.0.1#5335 +server=/tt.video.qq.com/127.0.0.1#5335 +server=/ice.video.qq.com/127.0.0.1#5335 +server=/tjsa.video.qq.com/127.0.0.1#5335 +server=/a10.video.qq.com/127.0.0.1#5335 +server=/xyy.video.qq.com/127.0.0.1#5335 +server=/vcq.video.qq.com/127.0.0.1#5335 +server=/vsh.video.qq.com/127.0.0.1#5335 +server=/vbj.video.qq.com/127.0.0.1#5335 +server=/bobo.video.qq.com/127.0.0.1#5335 +server=/flvs.video.qq.com/127.0.0.1#5335 +server=/bkvv.video.qq.com/127.0.0.1#5335 +server=/info.zb.qq.com/127.0.0.1#5335 +server=/geo.js.kankan.xunlei.com/127.0.0.1#5335 +server=/web-play.pptv.com/127.0.0.1#5335 +server=/web-play.pplive.cn/127.0.0.1#5335 +server=/dyn.ugc.pps.tv/127.0.0.1#5335 +server=/v.pps.tv/127.0.0.1#5335 +server=/inner.kandian.com/127.0.0.1#5335 +server=/ipservice.163.com/127.0.0.1#5335 +server=/so.open.163.com/127.0.0.1#5335 +server=/zb.s.qq.com/127.0.0.1#5335 +server=/ip.kankan.xunlei.com/127.0.0.1#5335 +server=/vxml.56.com/127.0.0.1#5335 +server=/music.sina.com.cn/127.0.0.1#5335 +server=/play.baidu.com/127.0.0.1#5335 +server=/v.iask.com/127.0.0.1#5335 +server=/tv.weibo.com/127.0.0.1#5335 +server=/wtv.v.iask.com/127.0.0.1#5335 +server=/video.sina.com.cn/127.0.0.1#5335 +server=/www.yinyuetai.com/127.0.0.1#5335 +server=/api.letv.com/127.0.0.1#5335 +server=/live.gslb.letv.com/127.0.0.1#5335 +server=/static.itv.letv.com/127.0.0.1#5335 +server=/ip.apps.cntv.cn/127.0.0.1#5335 +server=/vdn.apps.cntv.cn/127.0.0.1#5335 +server=/vdn.live.cntv.cn/127.0.0.1#5335 +server=/vip.sports.cntv.cn/127.0.0.1#5335 +server=/a.play.api.3g.youku.com/127.0.0.1#5335 +server=/i.play.api.3g.youku.com/127.0.0.1#5335 +server=/api.3g.youku.com/127.0.0.1#5335 +server=/tv.api.3g.youku.com/127.0.0.1#5335 +server=/play.api.3g.youku.com/127.0.0.1#5335 +server=/play.api.3g.tudou.com/127.0.0.1#5335 +server=/tv.api.3g.tudou.com/127.0.0.1#5335 +server=/api.3g.tudou.com/127.0.0.1#5335 +server=/api.tv.sohu.com/127.0.0.1#5335 +server=/access.tv.sohu.com/127.0.0.1#5335 +server=/iface.iqiyi.com/127.0.0.1#5335 +server=/iface2.iqiyi.com/127.0.0.1#5335 +server=/cache.m.iqiyi.com/127.0.0.1#5335 +server=/dynamic.app.m.letv.com/127.0.0.1#5335 +server=/dynamic.meizi.app.m.letv.com/127.0.0.1#5335 +server=/dynamic.search.app.m.letv.com/127.0.0.1#5335 +server=/dynamic.live.app.m.letv.com/127.0.0.1#5335 +server=/listso.m.areainfo.ppstream.com/127.0.0.1#5335 +server=/epg.api.pptv.com/127.0.0.1#5335 +server=/play.api.pptv.com/127.0.0.1#5335 +server=/m.letv.com/127.0.0.1#5335 +server=/interface.bilibili.com/127.0.0.1#5335 +server=/3g.music.qq.com/127.0.0.1#5335 +server=/mqqplayer.3g.qq.com/127.0.0.1#5335 +server=/proxy.music.qq.com/127.0.0.1#5335 +server=/proxymc.qq.com/127.0.0.1#5335 +server=/ip2.kugou.com/127.0.0.1#5335 +server=/ip.kugou.com/127.0.0.1#5335 +server=/client.api.ttpod.com/127.0.0.1#5335 +server=/mobi.kuwo.cn/127.0.0.1#5335 +server=/mobilefeedback.kugou.com/127.0.0.1#5335 +server=/tingapi.ting.baidu.com/127.0.0.1#5335 +server=/music.baidu.com/127.0.0.1#5335 +server=/serviceinfo.sdk.duomi.com/127.0.0.1#5335 +server=/music.163.com/127.0.0.1#5335 +server=/www.xiami.com/127.0.0.1#5335 +server=/spark.api.xiami.com/127.0.0.1#5335 +server=/iplocation.geo.qiyi.com/127.0.0.1#5335 +server=/sns.video.qq.com/127.0.0.1#5335 +server=/v5.pc.duomi.com/127.0.0.1#5335 +server=/tms.is.ysten.com/127.0.0.1#5335 +server=/internal.check.duokanbox.com/127.0.0.1#5335 +server=/openapi.youku.com/127.0.0.1#5335 +server=/y.qq.com/127.0.0.1#5335 +ipset=/v.youku.com/oversea +ipset=/api.youku.com/oversea +ipset=/v2.tudou.com/oversea +ipset=/www.tudou.com/oversea +ipset=/s.plcloud.music.qq.com/oversea +ipset=/i.y.qq.com/oversea +ipset=/hot.vrs.sohu.com/oversea +ipset=/live.tv.sohu.com/oversea +ipset=/pad.tv.sohu.com/oversea +ipset=/my.tv.sohu.com/oversea +ipset=/hot.vrs.letv.com/oversea +ipset=/data.video.qiyi.com/oversea +ipset=/cache.video.qiyi.com/oversea +ipset=/cache.vip.qiyi.com/oversea +ipset=/vv.video.qq.com/oversea +ipset=/tt.video.qq.com/oversea +ipset=/ice.video.qq.com/oversea +ipset=/tjsa.video.qq.com/oversea +ipset=/a10.video.qq.com/oversea +ipset=/xyy.video.qq.com/oversea +ipset=/vcq.video.qq.com/oversea +ipset=/vsh.video.qq.com/oversea +ipset=/vbj.video.qq.com/oversea +ipset=/bobo.video.qq.com/oversea +ipset=/flvs.video.qq.com/oversea +ipset=/bkvv.video.qq.com/oversea +ipset=/info.zb.qq.com/oversea +ipset=/geo.js.kankan.xunlei.com/oversea +ipset=/web-play.pptv.com/oversea +ipset=/web-play.pplive.cn/oversea +ipset=/dyn.ugc.pps.tv/oversea +ipset=/v.pps.tv/oversea +ipset=/inner.kandian.com/oversea +ipset=/ipservice.163.com/oversea +ipset=/so.open.163.com/oversea +ipset=/zb.s.qq.com/oversea +ipset=/ip.kankan.xunlei.com/oversea +ipset=/vxml.56.com/oversea +ipset=/music.sina.com.cn/oversea +ipset=/play.baidu.com/oversea +ipset=/v.iask.com/oversea +ipset=/tv.weibo.com/oversea +ipset=/wtv.v.iask.com/oversea +ipset=/video.sina.com.cn/oversea +ipset=/www.yinyuetai.com/oversea +ipset=/api.letv.com/oversea +ipset=/live.gslb.letv.com/oversea +ipset=/static.itv.letv.com/oversea +ipset=/ip.apps.cntv.cn/oversea +ipset=/vdn.apps.cntv.cn/oversea +ipset=/vdn.live.cntv.cn/oversea +ipset=/vip.sports.cntv.cn/oversea +ipset=/a.play.api.3g.youku.com/oversea +ipset=/i.play.api.3g.youku.com/oversea +ipset=/api.3g.youku.com/oversea +ipset=/tv.api.3g.youku.com/oversea +ipset=/play.api.3g.youku.com/oversea +ipset=/play.api.3g.tudou.com/oversea +ipset=/tv.api.3g.tudou.com/oversea +ipset=/api.3g.tudou.com/oversea +ipset=/api.tv.sohu.com/oversea +ipset=/access.tv.sohu.com/oversea +ipset=/iface.iqiyi.com/oversea +ipset=/iface2.iqiyi.com/oversea +ipset=/cache.m.iqiyi.com/oversea +ipset=/dynamic.app.m.letv.com/oversea +ipset=/dynamic.meizi.app.m.letv.com/oversea +ipset=/dynamic.search.app.m.letv.com/oversea +ipset=/dynamic.live.app.m.letv.com/oversea +ipset=/listso.m.areainfo.ppstream.com/oversea +ipset=/epg.api.pptv.com/oversea +ipset=/play.api.pptv.com/oversea +ipset=/m.letv.com/oversea +ipset=/interface.bilibili.com/oversea +ipset=/3g.music.qq.com/oversea +ipset=/mqqplayer.3g.qq.com/oversea +ipset=/proxy.music.qq.com/oversea +ipset=/proxymc.qq.com/oversea +ipset=/ip2.kugou.com/oversea +ipset=/ip.kugou.com/oversea +ipset=/client.api.ttpod.com/oversea +ipset=/mobi.kuwo.cn/oversea +ipset=/mobilefeedback.kugou.com/oversea +ipset=/tingapi.ting.baidu.com/oversea +ipset=/music.baidu.com/oversea +ipset=/serviceinfo.sdk.duomi.com/oversea +ipset=/music.163.com/oversea +ipset=/www.xiami.com/oversea +ipset=/spark.api.xiami.com/oversea +ipset=/iplocation.geo.qiyi.com/oversea +ipset=/sns.video.qq.com/oversea +ipset=/v5.pc.duomi.com/oversea +ipset=/tms.is.ysten.com/oversea +ipset=/internal.check.duokanbox.com/oversea +ipset=/openapi.youku.com/oversea +ipset=/y.qq.com/oversea diff --git a/package/lean/luci-app-ssr-plus/root/etc/dnsmasq.ssr/ad.conf b/package/lean/luci-app-ssr-plus/root/etc/dnsmasq.ssr/ad.conf new file mode 100644 index 0000000000..e69de29bb2 diff --git a/package/lean/luci-app-ssr-plus/root/etc/dnsmasq.ssr/gfw_base.conf b/package/lean/luci-app-ssr-plus/root/etc/dnsmasq.ssr/gfw_base.conf new file mode 100644 index 0000000000..980db214c2 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/etc/dnsmasq.ssr/gfw_base.conf @@ -0,0 +1,5878 @@ +ipset=/.h12.io/gfwlist +ipset=/.starlark.net/gfwlist +ipset=/.golang.org/gfwlist +ipset=/.honnef.co/gfwlist +ipset=/.0rz.tw/gfwlist +ipset=/.0to255.com/gfwlist +ipset=/.10musume.com/gfwlist +ipset=/.123rf.com/gfwlist +ipset=/.12bet.com/gfwlist +ipset=/.12vpn.com/gfwlist +ipset=/.141hongkong.com/gfwlist +ipset=/.173ng.com/gfwlist +ipset=/.1984bbs.com/gfwlist +ipset=/.1984bbs.org/gfwlist +ipset=/.1-apple.com.tw/gfwlist +ipset=/.1bao.org/gfwlist +ipset=/.1eew.com/gfwlist +ipset=/.1pondo.tv/gfwlist +ipset=/.2000fun.com/gfwlist +ipset=/.2008xianzhang.info/gfwlist +ipset=/.21andy.com/gfwlist +ipset=/.247realmedia.com/gfwlist +ipset=/.24smile.org/gfwlist +ipset=/.2-hand.info/gfwlist +ipset=/.2mdn.net/gfwlist +ipset=/.2shared.com/gfwlist +ipset=/.301works.org/gfwlist +ipset=/.315lz.com/gfwlist +ipset=/.32red.com/gfwlist +ipset=/.365singles.com.ar/gfwlist +ipset=/.36rain.com/gfwlist +ipset=/.4bluestones.biz/gfwlist +ipset=/.4chan.org/gfwlist +ipset=/.4pppc.gov.tw/gfwlist +ipset=/.4shared.com/gfwlist +ipset=/.4sq.com/gfwlist +ipset=/.51.ca/gfwlist +ipset=/.5i01.com/gfwlist +ipset=/.5maodang.com/gfwlist +ipset=/.64tianwang.com/gfwlist +ipset=/.64wiki.com/gfwlist +ipset=/.666kb.com/gfwlist +ipset=/.6park.com/gfwlist +ipset=/.7capture.com/gfwlist +ipset=/.881903.com/gfwlist +ipset=/.888.com/gfwlist +ipset=/.89-64.org/gfwlist +ipset=/.9001700.com/gfwlist +ipset=/.91porn.com/gfwlist +ipset=/.921.gov.tw/gfwlist +ipset=/.92ccav.com/gfwlist +ipset=/.9bis.com/gfwlist +ipset=/.9bis.net/gfwlist +ipset=/.9city.me/gfwlist +ipset=/.a5.com.ru/gfwlist +ipset=/.abc.pp.ru/gfwlist +ipset=/.abitno.linpie.com/gfwlist +ipset=/.ablwang.com/gfwlist +ipset=/.aboluowang.com/gfwlist +ipset=/.aboutgfw.com/gfwlist +ipset=/.acgkj.com/gfwlist +ipset=/.ac.jiruan.net/gfwlist +ipset=/.ac.playstation.net/gfwlist +ipset=/.actimes.com.au/gfwlist +ipset=/.aculo.us/gfwlist +ipset=/.ad1.nownews.com/gfwlist +ipset=/.addictedtocoffee.de/gfwlist +ipset=/.ads.backchina.com/gfwlist +ipset=/.adultfriendfinder.com/gfwlist +ipset=/.adultkeep.net/gfwlist +ipset=/.advanscene.com/gfwlist +ipset=/.advertfan.com/gfwlist +ipset=/.aec.gov.tw/gfwlist +ipset=/.aenhancers.com/gfwlist +ipset=/.af.mil/gfwlist +ipset=/.aftygh.gov.tw/gfwlist +ipset=/.aide.gov.tw/gfwlist +ipset=/.aiph.net/gfwlist +ipset=/.aisex.com/gfwlist +ipset=/.ait.org.tw/gfwlist +ipset=/.aiweiweiblog.com/gfwlist +ipset=/.aiweiwei.com/gfwlist +ipset=/.ajaxplorer.info/gfwlist +ipset=/.akamaihd.net/gfwlist +ipset=/.akiba-online.com/gfwlist +ipset=/.alabout.com/gfwlist +ipset=/.alasbarricadas.org/gfwlist +ipset=/.alexlur.org/gfwlist +ipset=/.aliengu.com/gfwlist +ipset=/.alkasir.com/gfwlist +ipset=/.allaboutalpha.com/gfwlist +ipset=/.allgirlsallowed.org/gfwlist +ipset=/.alliance.org.hk/gfwlist +ipset=/.allinfa.com/gfwlist +ipset=/.allinfo.com/gfwlist +ipset=/.allmovie.com/gfwlist +ipset=/.allonlinux.free.fr/gfwlist +ipset=/.all-that-is-interesting.com/gfwlist +ipset=/.al-qimmah.net/gfwlist +ipset=/.alternate-tools.com/gfwlist +ipset=/.altrec.com/gfwlist +ipset=/.alvinalexander.com/gfwlist +ipset=/.alwaysdata.com/gfwlist +ipset=/.alwaysdata.net/gfwlist +ipset=/.am730.com.hk/gfwlist +ipset=/.amazonaws.com/gfwlist +ipset=/.ameblo.jp/gfwlist +ipset=/.americangreencard.com/gfwlist +ipset=/.amiblockedornot.com/gfwlist +ipset=/.amnesty.org/gfwlist +ipset=/.amnestyusa.org/gfwlist +ipset=/.amoiist.com/gfwlist +ipset=/.amzs.me/gfwlist +ipset=/.analyze-v.com/gfwlist +ipset=/.anchorfree.com/gfwlist +ipset=/.andfaraway.net/gfwlist +ipset=/.android.com/gfwlist +ipset=/.angularjs.org/gfwlist +ipset=/.animecrazy.net/gfwlist +ipset=/.anobii.com/gfwlist +ipset=/.anontext.com/gfwlist +ipset=/.anonymizer.com/gfwlist +ipset=/.a-normal-day.com/gfwlist +ipset=/.answering-islam.org/gfwlist +ipset=/.anthonycalzadilla.com/gfwlist +ipset=/.anti.anti.cnn.googlepages.com/gfwlist +ipset=/.antidrm.hpg.ig.com.br/gfwlist +ipset=/.antiwave.net/gfwlist +ipset=/.aobo.com.au/gfwlist +ipset=/.aolchannels.aol.com/gfwlist +ipset=/.aomiwang.com/gfwlist +ipset=/.apetube.com/gfwlist +ipset=/.apiary.io/gfwlist +ipset=/.apidocs.linksalpha.com/gfwlist +ipset=/.apigee.com/gfwlist +ipset=/.api.linksalpha.com/gfwlist +ipset=/.api.proxlet.com/gfwlist +ipset=/.api.supertweet.net/gfwlist +ipset=/.app.heywire.com/gfwlist +ipset=/.app.hkatvnews.com/gfwlist +ipset=/.appledaily.com/gfwlist +ipset=/.appledaily.com.tw/gfwlist +ipset=/.apps.hloli.net/gfwlist +ipset=/.appspot.com/gfwlist +ipset=/.archive.is/gfwlist +ipset=/.archive.org/gfwlist +ipset=/.arctosia.com/gfwlist +ipset=/.areca-backup.org/gfwlist +ipset=/.army.mil/gfwlist +ipset=/.arte.gov.tw/gfwlist +ipset=/.art-or-porn.com/gfwlist +ipset=/.artsy.net/gfwlist +ipset=/.asahichinese.com/gfwlist +ipset=/.asdfg.jp/gfwlist +ipset=/.asiafriendfinder.com/gfwlist +ipset=/.asiaharvest.org/gfwlist +ipset=/.asianews.it/gfwlist +ipset=/.asianwomensfilm.de/gfwlist +ipset=/.askstudent.com/gfwlist +ipset=/.askynz.net/gfwlist +ipset=/.assembla.com/gfwlist +ipset=/.astonmartinnews.com/gfwlist +ipset=/.atchinese.com/gfwlist +ipset=/.atc.org.au/gfwlist +ipset=/.atgfw.org/gfwlist +ipset=/.atj.org.tw/gfwlist +ipset=/.atlaspost.com/gfwlist +ipset=/.atnext.com/gfwlist +ipset=/.autoproxy.org/gfwlist +ipset=/.avaaz.org/gfwlist +ipset=/.avdb.in/gfwlist +ipset=/.avidemux.org/gfwlist +ipset=/.avoision.com/gfwlist +ipset=/.awardwinningfjords.com/gfwlist +ipset=/.axureformac.com/gfwlist +ipset=/.babynet.com.hk/gfwlist +ipset=/.backchina.com/gfwlist +ipset=/.backpackers.com.tw/gfwlist +ipset=/.badassjs.com/gfwlist +ipset=/.badoo.com/gfwlist +ipset=/.baidu.jp/gfwlist +ipset=/.baixing.me/gfwlist +ipset=/.bannedbook.org/gfwlist +ipset=/.barnabu.co.uk/gfwlist +ipset=/.basetimesheightdividedby2.com/gfwlist +ipset=/.bayvoice.net/gfwlist +ipset=/.bbcchinese.com/gfwlist +ipset=/.bbc.com/gfwlist +ipset=/.bbc.co.uk/gfwlist +ipset=/.bbci.co.uk/gfwlist +ipset=/.bbcimg.co.uk/gfwlist +ipset=/.bbc.in/gfwlist +ipset=/.bbg.gov/gfwlist +ipset=/.bbs2.newsgroup.la/gfwlist +ipset=/.bbs.ecstart.com/gfwlist +ipset=/.bbsfeed.com/gfwlist +ipset=/.bbs.kimy.com.tw/gfwlist +ipset=/.bbsland.com/gfwlist +ipset=/.bbs.morbell.com/gfwlist +ipset=/.bbs.mychat.to/gfwlist +ipset=/.bbs.newsgroup.la/gfwlist +ipset=/.bbs.ozchinese.com/gfwlist +ipset=/.bbs.qmzdd.com/gfwlist +ipset=/.bbs.sina.com/gfwlist +ipset=/.bbs.skykiwi.com/gfwlist +ipset=/.bbs.tuitui.info/gfwlist +ipset=/.bb.ttv.com.tw/gfwlist +ipset=/.bcc.com.tw/gfwlist +ipset=/.bcchinese.net/gfwlist +ipset=/.bdhr.gov.tw/gfwlist +ipset=/.bd.zhe.la/gfwlist +ipset=/.bebo.com/gfwlist +ipset=/.beeg.com/gfwlist +ipset=/.beijing1989.com/gfwlist +ipset=/.beijingspring.com/gfwlist +ipset=/.benjaminste.in/gfwlist +ipset=/.berlintwitterwall.com/gfwlist +ipset=/.bestforchina.org/gfwlist +ipset=/.bestvpnservice.com/gfwlist +ipset=/.bet365.com/gfwlist +ipset=/.beta.iset.com.tw/gfwlist +ipset=/.beta.usejump.com/gfwlist +ipset=/.betfair.com/gfwlist +ipset=/.bettween.com/gfwlist +ipset=/.betvictor.com/gfwlist +ipset=/.bewww.net/gfwlist +ipset=/.beyondfirewall.com/gfwlist +ipset=/.bfnn.org/gfwlist +ipset=/.biantailajiao.com/gfwlist +ipset=/.biantailajiao.in/gfwlist +ipset=/.bigfools.com/gfwlist +ipset=/.bignews.org/gfwlist +ipset=/.bigsound.org/gfwlist +ipset=/.bill2-software.com/gfwlist +ipset=/.billywr.com/gfwlist +ipset=/.bill.zhong.pp.ru/gfwlist +ipset=/.bipic.net/gfwlist +ipset=/.bitcointalk.org/gfwlist +ipset=/.bit.ly/gfwlist +ipset=/.bitly.com/gfwlist +ipset=/.bitshare.com/gfwlist +ipset=/.bjzc.org/gfwlist +ipset=/.blinkx.com/gfwlist +ipset=/.blinw.com/gfwlist +ipset=/.blip.tv/gfwlist +ipset=/.blockcn.com/gfwlist +ipset=/.blog.birdhouseapp.com/gfwlist +ipset=/.blog.bitly.com/gfwlist +ipset=/.blogblog.com/gfwlist +ipset=/.blog.boxcar.io/gfwlist +ipset=/.blogcatalog.com/gfwlist +ipset=/.blog.davidziegler.net/gfwlist +ipset=/.blog.dayoneapp.com/gfwlist +ipset=/.blog.de/gfwlist +ipset=/.blog.dribbble.com/gfwlist +ipset=/.blog.exblog.co.jp/gfwlist +ipset=/.blog.expofutures.com/gfwlist +ipset=/.blog.fizzik.com/gfwlist +ipset=/.blog.foolsmountain.com/gfwlist +ipset=/.blogger.com/gfwlist +ipset=/.blog.gowalla.com/gfwlist +ipset=/.blog.hotpotato.com/gfwlist +ipset=/.blog.ifttt.com/gfwlist +ipset=/.blogimg.jp/gfwlist +ipset=/.blog.instagram.com/gfwlist +ipset=/.blog.instapaper.com/gfwlist +ipset=/.blog.iphone-dev.org/gfwlist +ipset=/.blog.istef.info/gfwlist +ipset=/.blog.jackjia.com/gfwlist +ipset=/.blog.joeyrobert.org/gfwlist +ipset=/.blog.kangye.org/gfwlist +ipset=/.blog.kickstarter.com/gfwlist +ipset=/.blog.kl.am/gfwlist +ipset=/.blog.klip.me/gfwlist +ipset=/.blog.lester850.info/gfwlist +ipset=/.blog.lightbox.com/gfwlist +ipset=/.bloglines.com/gfwlist +ipset=/.bloglovin.com/gfwlist +ipset=/.blog.mongodb.org/gfwlist +ipset=/.blog.openinkpot.org/gfwlist +ipset=/.blog.palm.com/gfwlist +ipset=/.blog.path.com/gfwlist +ipset=/.blog.pathtosharepoint.com/gfwlist +ipset=/.blog.pchome.com.tw/gfwlist +ipset=/.blog.pentalogic.net/gfwlist +ipset=/.blog.pikchur.com/gfwlist +ipset=/.blog.pilotmoon.com/gfwlist +ipset=/.blog.redren.com/gfwlist +ipset=/.blog.rockmelt.com/gfwlist +ipset=/.blog.romanandreg.com/gfwlist +ipset=/.blog.s135.com/gfwlist +ipset=/.blogs.icerocket.com/gfwlist +ipset=/.blog.sina.com.tw/gfwlist +ipset=/.blog.sogoo.org/gfwlist +ipset=/.blog.sparrowmailapp.com/gfwlist +ipset=/.blogspot.com/gfwlist +ipset=/.blogspot.co.uk/gfwlist +ipset=/.blogspot.de/gfwlist +ipset=/.blogspot.fr/gfwlist +ipset=/.blogspot.in/gfwlist +ipset=/.blogspot.jp/gfwlist +ipset=/.blogs.tampabay.com/gfwlist +ipset=/.blog.summify.com/gfwlist +ipset=/.blogs.yahoo.co.jp/gfwlist +ipset=/.blog.syx86.cn/gfwlist +ipset=/.blog.syx86.com/gfwlist +ipset=/.blog.taragana.com/gfwlist +ipset=/.blogtd.net/gfwlist +ipset=/.blogtd.org/gfwlist +ipset=/.blog.tiney.com/gfwlist +ipset=/.blog.topify.com/gfwlist +ipset=/.blog.usa.gov/gfwlist +ipset=/.blog.xuite.net/gfwlist +ipset=/.blog.youthwant.com.tw/gfwlist +ipset=/.blog.youxu.info/gfwlist +ipset=/.bloodshed.net/gfwlist +ipset=/.bloomberg.cn/gfwlist +ipset=/.bloomberg.com/gfwlist +ipset=/.bloomberg.de/gfwlist +ipset=/.bloomfortune.com/gfwlist +ipset=/.bmediaasia.com/gfwlist +ipset=/.bnrmetal.com/gfwlist +ipset=/.boardreader.com/gfwlist +ipset=/.bobulate.com/gfwlist +ipset=/.bolin.netfirms.com/gfwlist +ipset=/.bonbonme.com/gfwlist +ipset=/.bonjourlesgeeks.com/gfwlist +ipset=/.boobstagram.com/gfwlist +ipset=/.books.com.tw/gfwlist +ipset=/.bookshelfporn.com/gfwlist +ipset=/.botanwang.com/gfwlist +ipset=/.bot.nu/gfwlist +ipset=/.bowenpress.com/gfwlist +ipset=/.boxunblog.com/gfwlist +ipset=/.boxunclub.com/gfwlist +ipset=/.boxun.com/gfwlist +ipset=/.boxun.tv/gfwlist +ipset=/.bralio.com/gfwlist +ipset=/.branch.com/gfwlist +ipset=/.brandonhutchinson.com/gfwlist +ipset=/.braumeister.org/gfwlist +ipset=/.break.com/gfwlist +ipset=/.breakingtweets.com/gfwlist +ipset=/.briefdream.com/gfwlist +ipset=/.brightcove.com/gfwlist +ipset=/.brightkite.com/gfwlist +ipset=/.brizzly.com/gfwlist +ipset=/.broadbook.com/gfwlist +ipset=/.br.st/gfwlist +ipset=/.brucewang.net/gfwlist +ipset=/.bt95.com/gfwlist +ipset=/.btdigg.org/gfwlist +ipset=/.btrd.net/gfwlist +ipset=/.budaedu.org/gfwlist +ipset=/.bugclub.org/gfwlist +ipset=/.builtwithbootstrap.com/gfwlist +ipset=/.bullogger.com/gfwlist +ipset=/.bullog.org/gfwlist +ipset=/.businesstimes.com.cn/gfwlist +ipset=/.businessweek.com/gfwlist +ipset=/.buugaa.com/gfwlist +ipset=/.buy.yahoo.com.tw/gfwlist +ipset=/.buzzurl.jp/gfwlist +ipset=/.bwbx.io/gfwlist +ipset=/.bwsj.hk/gfwlist +ipset=/.bx.tl/gfwlist +ipset=/.c1522.mooo.com/gfwlist +ipset=/.cacnw.com/gfwlist +ipset=/.cactusvpn.com/gfwlist +ipset=/.cafepress.com/gfwlist +ipset=/.cahr.org.tw/gfwlist +ipset=/.calameo.com/gfwlist +ipset=/.calebelston.com/gfwlist +ipset=/.cams.com/gfwlist +ipset=/.cams.org.sg/gfwlist +ipset=/.canadameet.com/gfwlist +ipset=/.canyu.org/gfwlist +ipset=/.caobian.info/gfwlist +ipset=/.caochangqing.com/gfwlist +ipset=/.cao.im/gfwlist +ipset=/.cari.com.my/gfwlist +ipset=/.catch22.net/gfwlist +ipset=/.catfightpayperview.xxx/gfwlist +ipset=/.catholic.org.hk/gfwlist +ipset=/.catholic.org.tw/gfwlist +ipset=/.cbs.ntu.edu.tw/gfwlist +ipset=/.cc9007.spaces.live.com/gfwlist +ipset=/.ccavtop10.com/gfwlist +ipset=/.ccdtr.org/gfwlist +ipset=/.ccim.org/gfwlist +ipset=/.cclife.org/gfwlist +ipset=/.ccthere.com/gfwlist +ipset=/.cctongbao.com/gfwlist +ipset=/.ccue.ca/gfwlist +ipset=/.ccue.com/gfwlist +ipset=/.cdig.info/gfwlist +ipset=/.cdjp.org/gfwlist +ipset=/.cdnews.com.tw/gfwlist +ipset=/.cdn.printfriendly.com/gfwlist +ipset=/.cdp1998.org/gfwlist +ipset=/.cdp2006.org/gfwlist +ipset=/.cdp.sinica.edu.tw/gfwlist +ipset=/.cdpusa.org/gfwlist +ipset=/.cdpweb.org/gfwlist +ipset=/.cdpwu.org/gfwlist +ipset=/.cdw.com/gfwlist +ipset=/.cecc.gov/gfwlist +ipset=/.cellulo.info/gfwlist +ipset=/.cenci.tk/gfwlist +ipset=/.cenews.eu/gfwlist +ipset=/.centralnation.com/gfwlist +ipset=/.centurys.net/gfwlist +ipset=/.c-est-simple.com/gfwlist +ipset=/.cfhks.org.hk/gfwlist +ipset=/.cftfc.com/gfwlist +ipset=/.cgdepot.org/gfwlist +ipset=/.chandoo.org/gfwlist +ipset=/.change.org/gfwlist +ipset=/.changp.com/gfwlist +ipset=/.chaos.e-spacy.com/gfwlist +ipset=/.chapm25.com/gfwlist +ipset=/.chartbeat.net/gfwlist +ipset=/.chaturbate.com/gfwlist +ipset=/.chccc.gov.tw/gfwlist +ipset=/.chengmingmag.com/gfwlist +ipset=/.chenguangcheng.com/gfwlist +ipset=/.chenpokong.com/gfwlist +ipset=/.chenyehao.spaces.live.com/gfwlist +ipset=/.cherrysave.com/gfwlist +ipset=/.chevronwp7.com/gfwlist +ipset=/.chicagoncmtv.com/gfwlist +ipset=/.china101.com/gfwlist +ipset=/.china21.com/gfwlist +ipset=/.china21.org/gfwlist +ipset=/.china5000.us/gfwlist +ipset=/.chinaaffairs.org/gfwlist +ipset=/.chinaaid.me/gfwlist +ipset=/.chinaaid.net/gfwlist +ipset=/.chinaaid.org/gfwlist +ipset=/.chinaaid.us/gfwlist +ipset=/.chinachange.org/gfwlist +ipset=/.chinachannel.hk/gfwlist +ipset=/.chinacomments.org/gfwlist +ipset=/.chinadigitaltimes.net/gfwlist +ipset=/.chinaeweekly.com/gfwlist +ipset=/.chinafreepress.org/gfwlist +ipset=/.chinagate.com/gfwlist +ipset=/.chinageeks.org/gfwlist +ipset=/.chinagfw.org/gfwlist +ipset=/.chinagreenparty.org/gfwlist +ipset=/.china-green-party.spaces.live.com/gfwlist +ipset=/.chinahush.com/gfwlist +ipset=/.chinainperspective.com/gfwlist +ipset=/.chinainperspective.net/gfwlist +ipset=/.chinainperspective.org/gfwlist +ipset=/.chinainterimgov.org/gfwlist +ipset=/.chinalawandpolicy.com/gfwlist +ipset=/.chinalawtranslate.com/gfwlist +ipset=/.chinamule.com/gfwlist +ipset=/.chinamz.org/gfwlist +ipset=/.chinarightsia.org/gfwlist +ipset=/.chinasocialdemocraticparty.com/gfwlist +ipset=/.chinasoul.org/gfwlist +ipset=/.chinatimes.com/gfwlist +ipset=/.chinatweeps.com/gfwlist +ipset=/.chinaway.org/gfwlist +ipset=/.china-week.com/gfwlist +ipset=/.chinaworker.info/gfwlist +ipset=/.chinaxchina.com/gfwlist +ipset=/.chinayouth.org.hk/gfwlist +ipset=/.chinayuanmin.org/gfwlist +ipset=/.chinesedailynews.com/gfwlist +ipset=/.chinese.engadget.com/gfwlist +ipset=/.chinese-hermit.net/gfwlist +ipset=/.chinese-memorial.org/gfwlist +ipset=/.chinesen.de/gfwlist +ipset=/.chinesenewsnet.com/gfwlist +ipset=/.chinesepen.org/gfwlist +ipset=/.chinese.rnw.nl/gfwlist +ipset=/.chinese.soifind.com/gfwlist +ipset=/.chinesetalks.net/gfwlist +ipset=/.chinese.wsj.com/gfwlist +ipset=/.chingcheong.com/gfwlist +ipset=/.chn.chosun.com/gfwlist +ipset=/.chrispederick.com/gfwlist +ipset=/.chrispederick.net/gfwlist +ipset=/.christianstudy.com/gfwlist +ipset=/.christiantimes.org.hk/gfwlist +ipset=/.christusrex.org/gfwlist +ipset=/.chrlawyers.hk/gfwlist +ipset=/.chrlcg-hk.org/gfwlist +ipset=/.chromeadblock.com/gfwlist +ipset=/.chrome.com/gfwlist +ipset=/.ch.shvoong.com/gfwlist +ipset=/.chubun.com/gfwlist +ipset=/.chuizi.net/gfwlist +ipset=/.chukuang.gov.tw/gfwlist +ipset=/.circlethebayfortibet.org/gfwlist +ipset=/.citizenlab.org/gfwlist +ipset=/.citizensradio.org/gfwlist +ipset=/.city9x.com/gfwlist +ipset=/.civicparty.hk/gfwlist +ipset=/.civilhrfront.org/gfwlist +ipset=/.civilmedia.tw/gfwlist +ipset=/.cjb.net/gfwlist +ipset=/.ck101.com/gfwlist +ipset=/.classicalguitarblog.net/gfwlist +ipset=/.clb.org.hk/gfwlist +ipset=/.cl.d0z.net/gfwlist +ipset=/.clientsfromhell.net/gfwlist +ipset=/.clipfish.de/gfwlist +ipset=/.cl.ly/gfwlist +ipset=/.cloudfront.net/gfwlist +ipset=/.club.backchina.com/gfwlist +ipset=/.cms.gov/gfwlist +ipset=/.cmule.com/gfwlist +ipset=/.cn2.streetvoice.com/gfwlist +ipset=/.cna.com.tw/gfwlist +ipset=/.cnavista.com.tw/gfwlist +ipset=/.cn.calameo.com/gfwlist +ipset=/.cn.dayabook.com/gfwlist +ipset=/.cnd.org/gfwlist +ipset=/.cn.fmnnow.com/gfwlist +ipset=/.cn.ibtimes.com/gfwlist +ipset=/.cnn.com/gfwlist +ipset=/.cn.news.cnyes.com/gfwlist +ipset=/.cn.streetvoice.com/gfwlist +ipset=/.cn.uncyclopedia.wikia.com/gfwlist +ipset=/.cn.voa.mobi/gfwlist +ipset=/.cochina.org/gfwlist +ipset=/.cocoapods.org/gfwlist +ipset=/.cocoa.zonble.net/gfwlist +ipset=/.code1984.com/gfwlist +ipset=/.codeboxapp.com/gfwlist +ipset=/.codeshare.io/gfwlist +ipset=/.collateralmurder.com/gfwlist +ipset=/.collateralmurder.org/gfwlist +ipset=/.comefromchina.com/gfwlist +ipset=/.comnews.gio.gov.tw/gfwlist +ipset=/.compileheart.com/gfwlist +ipset=/.connectedchina.reuters.com/gfwlist +ipset=/.connect.facebook.net/gfwlist +ipset=/.conoyo.com/gfwlist +ipset=/.contactmagazine.net/gfwlist +ipset=/.contests.twilio.com/gfwlist +ipset=/.conviva.com/gfwlist +ipset=/.cookingtothegoodlife.com/gfwlist +ipset=/.coolaler.com/gfwlist +ipset=/.coolder.com/gfwlist +ipset=/.coolloud.org.tw/gfwlist +ipset=/.corpus4u.org/gfwlist +ipset=/.corumcollege.com/gfwlist +ipset=/.cotweet.com/gfwlist +ipset=/.couchdbwiki.com/gfwlist +ipset=/.coveringweb.com/gfwlist +ipset=/.cp-house.gov.tw/gfwlist +ipset=/.cpj.org/gfwlist +ipset=/.crackle.com/gfwlist +ipset=/.crd-net.org/gfwlist +ipset=/.creaders.net/gfwlist +ipset=/.cromotc.nat.gov.tw/gfwlist +ipset=/.crossthewall.net/gfwlist +ipset=/.csdparty.com/gfwlist +ipset=/.c-spanvideo.org/gfwlist +ipset=/.css.pixnet.in/gfwlist +ipset=/.csuchen.de/gfwlist +ipset=/.cts.com.tw/gfwlist +ipset=/.cubicle17.com/gfwlist +ipset=/.cuhkacs.org/gfwlist +ipset=/.cuihua.org/gfwlist +ipset=/.cuiweiping.net/gfwlist +ipset=/.culture.tw/gfwlist +ipset=/.curvefish.com/gfwlist +ipset=/.cwb.gov.tw/gfwlist +ipset=/.cyanogenmod.org/gfwlist +ipset=/.cyberghost.natado.com/gfwlist +ipset=/.cyberghostvpn.com/gfwlist +ipset=/.cycab.gov.tw/gfwlist +ipset=/.cydia.ifuckgfw.com/gfwlist +ipset=/.cynscribe.com/gfwlist +ipset=/.cytode.us/gfwlist +ipset=/.dabr.co.uk/gfwlist +ipset=/.dabr.me/gfwlist +ipset=/.dabr.mobi/gfwlist +ipset=/.dadazim.com/gfwlist +ipset=/.dadi360.com/gfwlist +ipset=/.dafagood.com/gfwlist +ipset=/.dafahao.com/gfwlist +ipset=/.dailidaili.com/gfwlist +ipset=/.dailymotion.com/gfwlist +ipset=/.dailynews.sina.com/gfwlist +ipset=/.dajiyuan.com/gfwlist +ipset=/.dajiyuan.eu/gfwlist +ipset=/.dajusha.baywords.com/gfwlist +ipset=/.dalailama.com/gfwlist +ipset=/.dalailama.ru/gfwlist +ipset=/.dalailamaworld.com/gfwlist +ipset=/.dalianmeng.org/gfwlist +ipset=/.danke4china.net/gfwlist +ipset=/.danwei.org/gfwlist +ipset=/.daolan.net/gfwlist +ipset=/.dapu-house.gov.tw/gfwlist +ipset=/.darpa.mil/gfwlist +ipset=/.date.fm/gfwlist +ipset=/.davidslog.com/gfwlist +ipset=/.daxa.cn/gfwlist +ipset=/.dayaarmongol.ning.com/gfwlist +ipset=/.daylife.com/gfwlist +ipset=/.ddc.com.tw/gfwlist +ipset=/.deck.ly/gfwlist +ipset=/.default.secureserver.net/gfwlist +ipset=/.delcamp.net/gfwlist +ipset=/.delicious.com/gfwlist +ipset=/.democrats.org/gfwlist +ipset=/.demo.opera-mini.net/gfwlist +ipset=/.derekhsu.homeip.net/gfwlist +ipset=/.de-sci.org/gfwlist +ipset=/.designerol.com/gfwlist +ipset=/.destiny.xfiles.to/gfwlist +ipset=/.deutsche-welle.de/gfwlist +ipset=/.dev102.com/gfwlist +ipset=/.developers.box.net/gfwlist +ipset=/.deviantart.com/gfwlist +ipset=/.deviantart.net/gfwlist +ipset=/.devio.us/gfwlist +ipset=/.devpn.com/gfwlist +ipset=/.dfas.mil/gfwlist +ipset=/.df.gov.tw/gfwlist +ipset=/.diaoyuislands.org/gfwlist +ipset=/.digitalnomadsproject.org/gfwlist +ipset=/.diigo.com/gfwlist +ipset=/.dimitrik.free.fr/gfwlist +ipset=/.dipity.com/gfwlist +ipset=/.directcreative.com/gfwlist +ipset=/.discuss.com.hk/gfwlist +ipset=/.disp.cc/gfwlist +ipset=/.dit-inc.us/gfwlist +ipset=/.dizhidizhi.com/gfwlist +ipset=/.djangosnippets.org/gfwlist +ipset=/.dl.box.net/gfwlist +ipset=/.dl-laby.jp/gfwlist +ipset=/.dl.playstation.net/gfwlist +ipset=/.dlsite.com/gfwlist +ipset=/.dmcdn.net/gfwlist +ipset=/.dmtip.gov.tw/gfwlist +ipset=/.dns2go.com/gfwlist +ipset=/.dnscrypt.org/gfwlist +ipset=/.docstoc.com/gfwlist +ipset=/.dojin.com/gfwlist +ipset=/.dok-forum.net/gfwlist +ipset=/.dolc.de/gfwlist +ipset=/.dollf.com/gfwlist +ipset=/.domain.club.tw/gfwlist +ipset=/.domainhelp.search.com/gfwlist +ipset=/.dongde.com/gfwlist +ipset=/.dongtaiwang.com/gfwlist +ipset=/.dongtaiwang.net/gfwlist +ipset=/.dongyangjing.com/gfwlist +ipset=/.dontfilter.us/gfwlist +ipset=/.dontmovetochina.com/gfwlist +ipset=/.dotheyfolloweachother.com/gfwlist +ipset=/.dotplane.com/gfwlist +ipset=/.dotsub.com/gfwlist +ipset=/.doubleaf.com/gfwlist +ipset=/.doubleclick.net/gfwlist +ipset=/.dougscripts.com/gfwlist +ipset=/.dowei.org/gfwlist +ipset=/.download.syniumsoftware.com/gfwlist +ipset=/.doxygen.org/gfwlist +ipset=/.dphk.org/gfwlist +ipset=/.dpp.org.tw/gfwlist +ipset=/.drewolanoff.com/gfwlist +ipset=/.drgan.net/gfwlist +ipset=/.dropbox.com/gfwlist +ipset=/.dropboxusercontent.com/gfwlist +ipset=/.drsunacademy.com/gfwlist +ipset=/.drtuber.com/gfwlist +ipset=/.dscn.info/gfwlist +ipset=/.dtiblog.com/gfwlist +ipset=/.dtic.mil/gfwlist +ipset=/.dtiserv2.com/gfwlist +ipset=/.duckduckgo.com/gfwlist +ipset=/.duckload.com/gfwlist +ipset=/.duckmylife.com/gfwlist +ipset=/.duihuahrjournal.org/gfwlist +ipset=/.duihua.org/gfwlist +ipset=/.duoweitimes.com/gfwlist +ipset=/.duping.net/gfwlist +ipset=/.duplicati.com/gfwlist +ipset=/.dupola.com/gfwlist +ipset=/.dupola.net/gfwlist +ipset=/.dvorak.org/gfwlist +ipset=/.dw.de/gfwlist +ipset=/.dwnews.com/gfwlist +ipset=/.dwnews.net/gfwlist +ipset=/.dw-world.com/gfwlist +ipset=/.dw-world.de/gfwlist +ipset=/.dy24k.info/gfwlist +ipset=/.dynawebinc.com/gfwlist +ipset=/.dyndns.org/gfwlist +ipset=/.dzze.com/gfwlist +ipset=/.e123.hk/gfwlist +ipset=/.eamonnbrennan.com/gfwlist +ipset=/.earthquake.usgs.gov/gfwlist +ipset=/.easy-share.com/gfwlist +ipset=/.ebookbrowse.com/gfwlist +ipset=/.ebookee.com/gfwlist +ipset=/.echofon.com/gfwlist +ipset=/.ecministry.net/gfwlist +ipset=/.edicypages.com/gfwlist +ipset=/.edoors.com/gfwlist +ipset=/.edubridge.com/gfwlist +ipset=/.eevpn.com/gfwlist +ipset=/.efcc.org.hk/gfwlist +ipset=/.efksoft.com/gfwlist +ipset=/.efmoe.com/gfwlist +ipset=/.e-gold.com/gfwlist +ipset=/.eic-av.com/gfwlist +ipset=/.e-info.org.tw/gfwlist +ipset=/.electionsmeter.com/gfwlist +ipset=/.elpais.com/gfwlist +ipset=/.eltondisney.com/gfwlist +ipset=/.emacsblog.org/gfwlist +ipset=/.embr.in/gfwlist +ipset=/.emory.edu/gfwlist +ipset=/.emule-ed2k.com/gfwlist +ipset=/.emuparadise.me/gfwlist +ipset=/.enewstree.com/gfwlist +ipset=/.en.favotter.net/gfwlist +ipset=/.englishfromengland.co.uk/gfwlist +ipset=/.entermap.com/gfwlist +ipset=/.en.wikipedia.org/gfwlist +ipset=/.epochtimes-bg.com/gfwlist +ipset=/.epochtimes.co.il/gfwlist +ipset=/.epochtimes.co.kr/gfwlist +ipset=/.epochtimes.com/gfwlist +ipset=/.epochtimes.de/gfwlist +ipset=/.epochtimes.fr/gfwlist +ipset=/.epochtimes.ie/gfwlist +ipset=/.epochtimes.jp/gfwlist +ipset=/.epochtimes-romania.com/gfwlist +ipset=/.epochtimes.ru/gfwlist +ipset=/.epochtimes.se/gfwlist +ipset=/.epochtimestr.com/gfwlist +ipset=/.epochweekly.com/gfwlist +ipset=/.erabaru.net/gfwlist +ipset=/.erepublik.com/gfwlist +ipset=/.erepublik.net/gfwlist +ipset=/.erights.net/gfwlist +ipset=/.eriversoft.com/gfwlist +ipset=/.ernestmandel.org/gfwlist +ipset=/.etaiwannews.com/gfwlist +ipset=/.etizer.org/gfwlist +ipset=/.etools.ncol.com/gfwlist +ipset=/.e-traderland.net/gfwlist +ipset=/.etraining.gov.tw/gfwlist +ipset=/.ettoday.net/gfwlist +ipset=/.evchk.wikia.com/gfwlist +ipset=/.eventful.com/gfwlist +ipset=/.everyday-carry.com/gfwlist +ipset=/.exblog.jp/gfwlist +ipset=/.expatshield.com/gfwlist +ipset=/.exploader.net/gfwlist +ipset=/.extremetube.com/gfwlist +ipset=/.eyespirit.info/gfwlist +ipset=/.eyevio.jp/gfwlist +ipset=/.eyny.com/gfwlist +ipset=/.ezpc.tk/gfwlist +ipset=/.ezpeer.com/gfwlist +ipset=/.facebook.com/gfwlist +ipset=/.facebook.net/gfwlist +ipset=/.facesofnyfw.com/gfwlist +ipset=/.fail.hk/gfwlist +ipset=/.faiththedog.info/gfwlist +ipset=/.fakku.net/gfwlist +ipset=/.falsefire.com/gfwlist +ipset=/.falunart.org/gfwlist +ipset=/.falundafamuseum.org/gfwlist +ipset=/.falundafa.org/gfwlist +ipset=/.falunhr.org/gfwlist +ipset=/.famunion.com/gfwlist +ipset=/.fangbinxing.com/gfwlist +ipset=/.fangeming.com/gfwlist +ipset=/.fanglizhi.info/gfwlist +ipset=/.fangongheike.com/gfwlist +ipset=/.fangong.org/gfwlist +ipset=/.fan-qiang.com/gfwlist +ipset=/.fanqianghou.com/gfwlist +ipset=/.fanqiangyakexi.net/gfwlist +ipset=/.fanswong.com/gfwlist +ipset=/.fanyue.info/gfwlist +ipset=/.fapdu.com/gfwlist +ipset=/.farwestchina.com/gfwlist +ipset=/.farxian.com/gfwlist +ipset=/.fastpic.ru/gfwlist +ipset=/.faststone.org/gfwlist +ipset=/.favorious.com/gfwlist +ipset=/.favstar.fm/gfwlist +ipset=/.fawanghuihui.org/gfwlist +ipset=/.faydao.com/gfwlist +ipset=/.fbcdn.net/gfwlist +ipset=/.fb.com/gfwlist +ipset=/.fb.me/gfwlist +ipset=/.fbsbx.com/gfwlist +ipset=/.fc2china.com/gfwlist +ipset=/.fc2.com/gfwlist +ipset=/.f.cl.ly/gfwlist +ipset=/.fdc89.jp/gfwlist +ipset=/.feedbooks.mobi/gfwlist +ipset=/.feedburner.com/gfwlist +ipset=/.feeds2.feedburner.com/gfwlist +ipset=/.feeds.feedburner.com/gfwlist +ipset=/.feedzshare.com/gfwlist +ipset=/.feelssh.com/gfwlist +ipset=/.feer.com/gfwlist +ipset=/.felixcat.net/gfwlist +ipset=/.feministteacher.com/gfwlist +ipset=/.fengzhenghu.com/gfwlist +ipset=/.fetchvideo.com/gfwlist +ipset=/.ff.im/gfwlist +ipset=/.fflick.com/gfwlist +ipset=/.fgmtv.net/gfwlist +ipset=/.fgmtv.org/gfwlist +ipset=/.filefactory.com/gfwlist +ipset=/.files2me.com/gfwlist +ipset=/.fileserve.com/gfwlist +ipset=/.fillthesquare.org/gfwlist +ipset=/.finalion.jp/gfwlist +ipset=/.findbook.tw/gfwlist +ipset=/.finler.net/gfwlist +ipset=/.fireofliberty.org/gfwlist +ipset=/.firstfivefollowers.com/gfwlist +ipset=/.flecheinthepeche.fr/gfwlist +ipset=/.fleshbot.com/gfwlist +ipset=/.flickr.com/gfwlist +ipset=/.flickrhivemind.net/gfwlist +ipset=/.flightcaster.com/gfwlist +ipset=/.flowerofhappiness.spaces.live.com/gfwlist +ipset=/.focustaiwan.tw/gfwlist +ipset=/.focusvpn.com/gfwlist +ipset=/.fofg.org/gfwlist +ipset=/.fooooo.com/gfwlist +ipset=/.footwiball.com/gfwlist +ipset=/.forum.baby-kingdom.com/gfwlist +ipset=/.forum.cyberctm.com/gfwlist +ipset=/.forum.idsam.com/gfwlist +ipset=/.forum.iset.com.tw/gfwlist +ipset=/.forum.my903.com/gfwlist +ipset=/.forum.mymaji.com/gfwlist +ipset=/.forum.newsgroup.la/gfwlist +ipset=/.forum.nownews.com/gfwlist +ipset=/.forum.omy.sg/gfwlist +ipset=/.forum.palmislife.com/gfwlist +ipset=/.forum.pchome.com.tw/gfwlist +ipset=/.forum.setty.com.tw/gfwlist +ipset=/.forum.sina.com.hk/gfwlist +ipset=/.forum.slime.com.tw/gfwlist +ipset=/.forum.tvb.com/gfwlist +ipset=/.forum.yorkbbs.ca/gfwlist +ipset=/.fotop.net/gfwlist +ipset=/.fourface.nodesnoop.com/gfwlist +ipset=/.fourthinternational.org/gfwlist +ipset=/.foxdie.us/gfwlist +ipset=/.foxsub.com/gfwlist +ipset=/.foxtang.com/gfwlist +ipset=/.fqrouter.com/gfwlist +ipset=/.franklc.com/gfwlist +ipset=/.freakshare.com/gfwlist +ipset=/.fredwilson.vc/gfwlist +ipset=/.free4u.com.ar/gfwlist +ipset=/.freealim.com/gfwlist +ipset=/.freechal.com/gfwlist +ipset=/.freedomhouse.org/gfwlist +ipset=/.free.fr/gfwlist +ipset=/.freegao.com/gfwlist +ipset=/.freegateget.googlepages.com/gfwlist +ipset=/.free-gate.org/gfwlist +ipset=/.free-hada-now.org/gfwlist +ipset=/.freelotto.com/gfwlist +ipset=/.freeman2.com/gfwlist +ipset=/.freemoren.com/gfwlist +ipset=/.freemorenews.com/gfwlist +ipset=/.freenet-china.org/gfwlist +ipset=/.freenetproject.org/gfwlist +ipset=/.freenewscn.com/gfwlist +ipset=/.freeopenvpn.com/gfwlist +ipset=/.freeoz.org/gfwlist +ipset=/.free-ssh.com/gfwlist +ipset=/.freessh.us/gfwlist +ipset=/.freetibet.org/gfwlist +ipset=/.freevpn.nl/gfwlist +ipset=/.freewallpaper4.me/gfwlist +ipset=/.freewebs.com/gfwlist +ipset=/.freeweibo.com/gfwlist +ipset=/.freexinwen.com/gfwlist +ipset=/.freeyoutubeproxy.net/gfwlist +ipset=/.friendfeed.com/gfwlist +ipset=/.friendfeed-media.com/gfwlist +ipset=/.fring.com/gfwlist +ipset=/.fringenetwork.com/gfwlist +ipset=/.frommel.net/gfwlist +ipset=/.frontlinedefenders.org/gfwlist +ipset=/.fscked.org/gfwlist +ipset=/.fsurf.com/gfwlist +ipset=/.ftchinese.com/gfwlist +ipset=/.fuckcnnic.net/gfwlist +ipset=/.fuckgfw.com/gfwlist +ipset=/.fuckgfw.org/gfwlist +ipset=/.fulue.com/gfwlist +ipset=/.funf.tw/gfwlist +ipset=/.funp.com/gfwlist +ipset=/.furinkan.com/gfwlist +ipset=/.furl.net/gfwlist +ipset=/.futurechinaforum.org/gfwlist +ipset=/.futureme.org/gfwlist +ipset=/.futuremessage.org/gfwlist +ipset=/.fuyin.net/gfwlist +ipset=/.fw.cm/gfwlist +ipset=/.fxnetworks.com/gfwlist +ipset=/.fzh999.com/gfwlist +ipset=/.fzh999.net/gfwlist +ipset=/.gabocorp.com/gfwlist +ipset=/.gaeproxy.com/gfwlist +ipset=/.gaeproxy.googlecode.com/gfwlist +ipset=/.galenwu.com/gfwlist +ipset=/.game735.com/gfwlist +ipset=/.gamebase.com.tw/gfwlist +ipset=/.gamer.com.tw/gfwlist +ipset=/.gamez.com.tw/gfwlist +ipset=/.ganges.com/gfwlist +ipset=/.gaoming.net/gfwlist +ipset=/.gaopi.net/gfwlist +ipset=/.gaozhisheng.net/gfwlist +ipset=/.gaozhisheng.org/gfwlist +ipset=/.gardennetworks.com/gfwlist +ipset=/.gardennetworks.org/gfwlist +ipset=/.gartlive.com/gfwlist +ipset=/.gather.com/gfwlist +ipset=/.gaymap.cc/gfwlist +ipset=/.gazotube.com/gfwlist +ipset=/.gcc.org.hk/gfwlist +ipset=/.gclooney.com/gfwlist +ipset=/.g.co/gfwlist +ipset=/.gcpnews.com/gfwlist +ipset=/.gdbt.net/gfwlist +ipset=/.gdzf.org/gfwlist +ipset=/.geek-art.net/gfwlist +ipset=/.geekerhome.com/gfwlist +ipset=/.geekmade.co.uk/gfwlist +ipset=/.geekmanuals.com/gfwlist +ipset=/.generesis.com/gfwlist +ipset=/.genuitec.com/gfwlist +ipset=/.geocities.co.jp/gfwlist +ipset=/.geocities.com/gfwlist +ipset=/.geocities.jp/gfwlist +ipset=/.geohot.com/gfwlist +ipset=/.geometrictools.com/gfwlist +ipset=/.getchu.com/gfwlist +ipset=/.getcloudapp.com/gfwlist +ipset=/.get-digital-help.com/gfwlist +ipset=/.getfoxyproxy.org/gfwlist +ipset=/.getfreedur.com/gfwlist +ipset=/.getiton.com/gfwlist +ipset=/.getjetso.com/gfwlist +ipset=/.getlantern.org/gfwlist +ipset=/.getsmartlinks.com/gfwlist +ipset=/.getsocialscope.com/gfwlist +ipset=/.gfwinterceptor.googlecode.com/gfwlist +ipset=/.gfw.org.ua/gfwlist +ipset=/.ggpht.com/gfwlist +ipset=/.ggssl.com/gfwlist +ipset=/.ghost.org/gfwlist +ipset=/.ghut.org/gfwlist +ipset=/.giga-web.jp/gfwlist +ipset=/.gigporno.ru/gfwlist +ipset=/.gimpshop.com/gfwlist +ipset=/.girlbanker.com/gfwlist +ipset=/.github.com/gfwlist +ipset=/.git-scm.com/gfwlist +ipset=/.givemesomethingtoread.com/gfwlist +ipset=/.glennhilton.com/gfwlist +ipset=/.globaljihad.net/gfwlist +ipset=/.globalmuseumoncommunism.org/gfwlist +ipset=/.globalrescue.net/gfwlist +ipset=/.globalvoicesonline.org/gfwlist +ipset=/.gmail.com/gfwlist +ipset=/.gmbd.cn/gfwlist +ipset=/.gmhz.org/gfwlist +ipset=/.gmodules.com/gfwlist +ipset=/.gmozomg.izihost.org/gfwlist +ipset=/.gnci.org.hk/gfwlist +ipset=/.goagent.biz/gfwlist +ipset=/.goagent.googlecode.com/gfwlist +ipset=/.goagentplus.com/gfwlist +ipset=/.godfootsteps.org/gfwlist +ipset=/.golang.org/gfwlist +ipset=/.goldbetsports.com/gfwlist +ipset=/.goldwave.com/gfwlist +ipset=/.gongmeng.info/gfwlist +ipset=/.gongm.in/gfwlist +ipset=/.gongminliliang.com/gfwlist +ipset=/.gongwt.com/gfwlist +ipset=/.goodreaders.com/gfwlist +ipset=/.goodreads.com/gfwlist +ipset=/.goofind.com/gfwlist +ipset=/.goo.gl/gfwlist +ipset=/.googleadservices.com/gfwlist +ipset=/.google-analytics.com/gfwlist +ipset=/.googleapis.com/gfwlist +ipset=/.googlecode.com/gfwlist +ipset=/.google.co.jp/gfwlist +ipset=/.google.com/gfwlist +ipset=/.google.com.hk/gfwlist +ipset=/.google.com.sg/gfwlist +ipset=/.google.com.tw/gfwlist +ipset=/.google.com.uk/gfwlist +ipset=/.googledomains.com/gfwlist +ipset=/.googledrive.com/gfwlist +ipset=/.googleearth.com/gfwlist +ipset=/.googlehosted.com/gfwlist +ipset=/.googlelabs.com/gfwlist +ipset=/.googlemail.com/gfwlist +ipset=/.googleplus.com/gfwlist +ipset=/.googlesile.com/gfwlist +ipset=/.googlesource.com/gfwlist +ipset=/.googlesyndication.com/gfwlist +ipset=/.googletagmanager.com/gfwlist +ipset=/.googletagservices.com/gfwlist +ipset=/.googleusercontent.com/gfwlist +ipset=/.googlevideo.com/gfwlist +ipset=/.gopetition.com/gfwlist +ipset=/.gospelherald.com/gfwlist +ipset=/.gov.tw/gfwlist +ipset=/.gpass1.com/gfwlist +ipset=/.grandtrial.org/gfwlist +ipset=/.graphis.ne.jp/gfwlist +ipset=/.gravatar.com/gfwlist +ipset=/.graylog2.org/gfwlist +ipset=/.grb.gov.tw/gfwlist +ipset=/.greatfire.org/gfwlist +ipset=/.greatfirewall.biz/gfwlist +ipset=/.great-firewall.com/gfwlist +ipset=/.greatfirewallofchina.net/gfwlist +ipset=/.greatfirewallofchina.org/gfwlist +ipset=/.great-roc.org/gfwlist +ipset=/.greatroc.org/gfwlist +ipset=/.greatroc.tw/gfwlist +ipset=/.greatzhonghua.org/gfwlist +ipset=/.greenparty.org.tw/gfwlist +ipset=/.greenvpn.net/gfwlist +ipset=/.gs-discuss.com/gfwlist +ipset=/.gseeker.com/gfwlist +ipset=/.gsn-cert.nat.gov.tw/gfwlist +ipset=/.gstatic.com/gfwlist +ipset=/.gtap.googlecode.com/gfwlist +ipset=/.gtricks.com/gfwlist +ipset=/.guancha.org/gfwlist +ipset=/.gufeng521.spaces.live.com/gfwlist +ipset=/.guishan.org/gfwlist +ipset=/.gunsamerica.com/gfwlist +ipset=/.gun-world.net/gfwlist +ipset=/.guomin.us/gfwlist +ipset=/.gutteruncensored.com/gfwlist +ipset=/.gvm.com.tw/gfwlist +ipset=/.gyalwarinpoche.com/gfwlist +ipset=/.gysd.nyc.gov.tw/gfwlist +ipset=/.gzm.tv/gfwlist +ipset=/.gzone-anime.info/gfwlist +ipset=/.h1n1china.org/gfwlist +ipset=/.hacken.cc/gfwlist +ipset=/.hackthatphone.net/gfwlist +ipset=/.hahlo.com/gfwlist +ipset=/.hakkatv.org.tw/gfwlist +ipset=/.hanunyi.com/gfwlist +ipset=/.hardsextube.com/gfwlist +ipset=/.hasaowall.com/gfwlist +ipset=/.have8.com/gfwlist +ipset=/.haygo.com/gfwlist +ipset=/.hcc.gov.tw/gfwlist +ipset=/.hchcc.gov.tw/gfwlist +ipset=/.h-china.org/gfwlist +ipset=/.hdtvb.net/gfwlist +ipset=/.heartyit.com/gfwlist +ipset=/.hecaitou.net/gfwlist +ipset=/.hechaji.com/gfwlist +ipset=/.heix.pp.ru/gfwlist +ipset=/.heiyo.info/gfwlist +ipset=/.helloandroid.com/gfwlist +ipset=/.hellonewyork.us/gfwlist +ipset=/.helloqueer.com/gfwlist +ipset=/.hellotxt.com/gfwlist +ipset=/.hellouk.org/gfwlist +ipset=/.helpeachpeople.com/gfwlist +ipset=/.helplinfen.com/gfwlist +ipset=/.help.linksalpha.com/gfwlist +ipset=/.help.opera.com/gfwlist +ipset=/.helpzhuling.org/gfwlist +ipset=/.hen.bao.li/gfwlist +ipset=/.hengchuen.gov.tw/gfwlist +ipset=/.heqinglian.net/gfwlist +ipset=/.here4news.com/gfwlist +ipset=/.heungkongdiscuss.com/gfwlist +ipset=/.hgseav.com/gfwlist +ipset=/.hidden-advent.org/gfwlist +ipset=/.hidecloud.com/gfwlist +ipset=/.hideipvpn.com/gfwlist +ipset=/.hidemyass.com/gfwlist +ipset=/.higfw.com/gfwlist +ipset=/.highrockmedia.com/gfwlist +ipset=/.hihiforum.com/gfwlist +ipset=/.hihistory.net/gfwlist +ipset=/.hiitch.com/gfwlist +ipset=/.hikinggfw.org/gfwlist +ipset=/.himemix.com/gfwlist +ipset=/.himemix.net/gfwlist +ipset=/.hjclub.info/gfwlist +ipset=/.hk32168.com/gfwlist +ipset=/.hkbc.net/gfwlist +ipset=/.hkbf.org/gfwlist +ipset=/.hkchurch.org/gfwlist +ipset=/.hkdailynews.com.hk/gfwlist +ipset=/.hkday.net/gfwlist +ipset=/.hkej.com/gfwlist +ipset=/.hkepc.com/gfwlist +ipset=/.hkfront.org/gfwlist +ipset=/.hk.geocities.com/gfwlist +ipset=/.hkgolden.com/gfwlist +ipset=/.hkgreenradio.org/gfwlist +ipset=/.hkg.westkit.net/gfwlist +ipset=/.hkheadline.com/gfwlist +ipset=/.hkhkhk.com/gfwlist +ipset=/.hkjc.com/gfwlist +ipset=/.hk.jiepang.com/gfwlist +ipset=/.hkjp.easyweb.hk/gfwlist +ipset=/.hkjp.org/gfwlist +ipset=/.hk.knowledge.yahoo.com/gfwlist +ipset=/.hk.myblog.yahoo.com/gfwlist +ipset=/.hk.news.yahoo.com/gfwlist +ipset=/.hkptu.org/gfwlist +ipset=/.hk-pub.com/gfwlist +ipset=/.hk.rd.yahoo.com/gfwlist +ipset=/.hkreporter.com/gfwlist +ipset=/.hkreporter.loved.hk/gfwlist +ipset=/.hk.search.yahoo.com/gfwlist +ipset=/.hk.video.news.yahoo.com/gfwlist +ipset=/.hkwcc.org.hk/gfwlist +ipset=/.hk.yahoo.com/gfwlist +ipset=/.hkzone.org/gfwlist +ipset=/.hnjhj.com/gfwlist +ipset=/.hola.com/gfwlist +ipset=/.holyspiritspeaks.org/gfwlist +ipset=/.holz.byethost8.com/gfwlist +ipset=/.homeservershow.com/gfwlist +ipset=/.home.sina.com/gfwlist +ipset=/.home.so-net.net.tw/gfwlist +ipset=/.honeonet.spaces.live.com/gfwlist +ipset=/.hongmeimei.com/gfwlist +ipset=/.hongzhi.li/gfwlist +ipset=/.hootsuite.com/gfwlist +ipset=/.hotpot.hk/gfwlist +ipset=/.hotshame.com/gfwlist +ipset=/.hotspotshield.com/gfwlist +ipset=/.hougaige.com/gfwlist +ipset=/.howtoforge.com/gfwlist +ipset=/.hqcdp.org/gfwlist +ipset=/.hrcir.com/gfwlist +ipset=/.hrichina.org/gfwlist +ipset=/.hrw.org/gfwlist +ipset=/.hsinchu-cc.gov.tw/gfwlist +ipset=/.hsjp.net/gfwlist +ipset=/.hsselite.com/gfwlist +ipset=/.htkou.net/gfwlist +ipset=/.htl.li/gfwlist +ipset=/.ht.ly/gfwlist +ipset=/.htmldog.com/gfwlist +ipset=/.huaglad.com/gfwlist +ipset=/.huajiadi.spaces.live.com/gfwlist +ipset=/.huanghuagang.org/gfwlist +ipset=/.huaren.us/gfwlist +ipset=/.huaxia-news.com/gfwlist +ipset=/.huaxin.ph/gfwlist +ipset=/.hua-yue.net/gfwlist +ipset=/.hudatoriq.web.id/gfwlist +ipset=/.hugoroy.eu/gfwlist +ipset=/.huhamhire.com/gfwlist +ipset=/.hujiachina.spaces.live.com/gfwlist +ipset=/.hulu.com/gfwlist +ipset=/.huluim.com/gfwlist +ipset=/.humanities.uchicago.edu/gfwlist +ipset=/.hungerstrikeforaids.org/gfwlist +ipset=/.hung-ya.com/gfwlist +ipset=/.huping.net/gfwlist +ipset=/.hutianyi.net/gfwlist +ipset=/.hutong9.net/gfwlist +ipset=/.hwinfo.com/gfwlist +ipset=/.hyperrate.com/gfwlist +ipset=/.hypeshell.com/gfwlist +ipset=/.i1.hk/gfwlist +ipset=/.i2runner.com/gfwlist +ipset=/.ialmostlaugh.com/gfwlist +ipset=/.iask.bz/gfwlist +ipset=/.iask.ca/gfwlist +ipset=/.ibiblio.org/gfwlist +ipset=/.iblogserv-f.net/gfwlist +ipset=/.ibros.org/gfwlist +ipset=/.icij.org/gfwlist +ipset=/.icl-fi.org/gfwlist +ipset=/.iconpaper.org/gfwlist +ipset=/.icu-project.org/gfwlist +ipset=/.idemocracy.asia/gfwlist +ipset=/.identi.ca/gfwlist +ipset=/.idiomconnection.com/gfwlist +ipset=/.idouga.com/gfwlist +ipset=/.idv.tw/gfwlist +ipset=/.ieasynews.net/gfwlist +ipset=/.ied2k.net/gfwlist +ipset=/.ieemdai.spaces.live.com/gfwlist +ipset=/.ifan.cz.cc/gfwlist +ipset=/.ifanqiang.com/gfwlist +ipset=/.ifanr.com/gfwlist +ipset=/.ifcss.org/gfwlist +ipset=/.ifjc.org/gfwlist +ipset=/.igfw.net/gfwlist +ipset=/.ignitedetroit.net/gfwlist +ipset=/.igvita.com/gfwlist +ipset=/.ihakka.net/gfwlist +ipset=/.iicns.com/gfwlist +ipset=/.illusionfactory.com/gfwlist +ipset=/.ilove80.be/gfwlist +ipset=/.im88.tw/gfwlist +ipset=/.imageflea.com/gfwlist +ipset=/.imagesblog.gio.gov.tw/gfwlist +ipset=/.imageshack.us/gfwlist +ipset=/.imagevenue.com/gfwlist +ipset=/.imagezilla.net/gfwlist +ipset=/.ime.baidu.jp/gfwlist +ipset=/.img.ly/gfwlist +ipset=/.imkev.com/gfwlist +ipset=/.imlive.com/gfwlist +ipset=/.immigration.gov.tw/gfwlist +ipset=/.imrworldwide.com/gfwlist +ipset=/.im.tv/gfwlist +ipset=/.incredibox.fr/gfwlist +ipset=/.iner.gov.tw/gfwlist +ipset=/.initiativesforchina.org/gfwlist +ipset=/.inmediahk.net/gfwlist +ipset=/.innermongolia.org/gfwlist +ipset=/.instagram.com/gfwlist +ipset=/.interestinglaugh.com/gfwlist +ipset=/.interfaceaddiction.com/gfwlist +ipset=/.internationalrivers.org/gfwlist +ipset=/.internetdefenseleague.org/gfwlist +ipset=/.internetfreedom.org/gfwlist +ipset=/.internetpopculture.com/gfwlist +ipset=/.inxian.com/gfwlist +ipset=/.iphone4hongkong.com/gfwlist +ipset=/.iphonehacks.com/gfwlist +ipset=/.iphonix.fr/gfwlist +ipset=/.ipicture.ru/gfwlist +ipset=/.ipobar.com/gfwlist +ipset=/.ippotv.com/gfwlist +ipset=/.iptorrents.com/gfwlist +ipset=/.ipvanish.com/gfwlist +ipset=/.iredmail.org/gfwlist +ipset=/.ironbigfools.compython.net/gfwlist +ipset=/.ironicsoftware.com/gfwlist +ipset=/.ironpython.net/gfwlist +ipset=/.isaacmao.com/gfwlist +ipset=/.isgreat.org/gfwlist +ipset=/.islamicity.com/gfwlist +ipset=/.islam.org.hk/gfwlist +ipset=/.ismprofessional.net/gfwlist +ipset=/.isohunt.com/gfwlist +ipset=/.israbox.com/gfwlist +ipset=/.istockphoto.com/gfwlist +ipset=/.isunaffairs.com/gfwlist +ipset=/.isuntv.com/gfwlist +ipset=/.itaboo.info/gfwlist +ipset=/.ithelp.ithome.com.tw/gfwlist +ipset=/.itrc.gov.tw/gfwlist +ipset=/.itshidden.com/gfwlist +ipset=/.itweet.net/gfwlist +ipset=/.iu45.com/gfwlist +ipset=/.iverycd.com/gfwlist +ipset=/.ixquick.com/gfwlist +ipset=/.izaobao.us/gfwlist +ipset=/.izles.net/gfwlist +ipset=/.japan-whores.com/gfwlist +ipset=/.jayparkinsonmd.com/gfwlist +ipset=/.jbtalks.cc/gfwlist +ipset=/.jbtalks.com/gfwlist +ipset=/.jbtalks.my/gfwlist +ipset=/.jeanyim.com/gfwlist +ipset=/.jgoodies.com/gfwlist +ipset=/.jiaoyou8.com/gfwlist +ipset=/.jiehua.cz/gfwlist +ipset=/.jieshibaobao.com/gfwlist +ipset=/.jike.com/gfwlist +ipset=/.jimoparty.com/gfwlist +ipset=/.jinbushe.org/gfwlist +ipset=/.jingpin.org/gfwlist +ipset=/.jitouch.com/gfwlist +ipset=/.jkforum.net/gfwlist +ipset=/.j.mp/gfwlist +ipset=/.joachims.org/gfwlist +ipset=/.jobso.tv/gfwlist +ipset=/.joeedelman.com/gfwlist +ipset=/.journalofdemocracy.org/gfwlist +ipset=/.jpopforum.net/gfwlist +ipset=/.juliereyc.com/gfwlist +ipset=/.junauza.com/gfwlist +ipset=/.junefourth-20.net/gfwlist +ipset=/.justfreevpn.com/gfwlist +ipset=/.justtristan.com/gfwlist +ipset=/.juziyue.com/gfwlist +ipset=/.jwmusic.org/gfwlist +ipset=/.jyxf.net/gfwlist +ipset=/.jyzj.waqn.com/gfwlist +ipset=/.k2.xrea.com/gfwlist +ipset=/.kagyuoffice.org.tw/gfwlist +ipset=/.kaiyuan.de/gfwlist +ipset=/.kakao.com/gfwlist +ipset=/.kanzhongguo.com/gfwlist +ipset=/.kanzhongguo.eu/gfwlist +ipset=/.karayou.com/gfwlist +ipset=/.ka-wai.com/gfwlist +ipset=/.kcsoftwares.com/gfwlist +ipset=/.kechara.com/gfwlist +ipset=/.keepandshare.com/gfwlist +ipset=/.kendincos.net/gfwlist +ipset=/.kenengba.com/gfwlist +ipset=/.keontech.net/gfwlist +ipset=/.khcc.gov.tw/gfwlist +ipset=/.khms.gov.tw/gfwlist +ipset=/.khmusic.com.tw/gfwlist +ipset=/.killwall.com/gfwlist +ipset=/.kineox.free.fr/gfwlist +ipset=/.kingdomsalvation.org/gfwlist +ipset=/.kinghost.com/gfwlist +ipset=/.kingstone.com.tw/gfwlist +ipset=/.kissbbao.cn/gfwlist +ipset=/.kissyoutube.com/gfwlist +ipset=/.kk.gov.tw/gfwlist +ipset=/.klccab.gov.tw/gfwlist +ipset=/.klra.gov.tw/gfwlist +ipset=/.klsio.gov.tw/gfwlist +ipset=/.kmh.gov.tw/gfwlist +ipset=/.kmseh.gov.tw/gfwlist +ipset=/.knowledgerush.com/gfwlist +ipset=/.kodingen.com/gfwlist +ipset=/.kompozer.net/gfwlist +ipset=/.koolsolutions.com/gfwlist +ipset=/.koornk.com/gfwlist +ipset=/.kt.kcome.org/gfwlist +ipset=/.kui.name/gfwlist +ipset=/.kun.im/gfwlist +ipset=/.kurtmunger.com/gfwlist +ipset=/.kusocity.com/gfwlist +ipset=/.kwongwah.com.my/gfwlist +ipset=/.kyohk.net/gfwlist +ipset=/.kzeng.info/gfwlist +ipset=/.labiennale.org/gfwlist +ipset=/.ladbrokes.com/gfwlist +ipset=/.la-forum.org/gfwlist +ipset=/.lagranepoca.com/gfwlist +ipset=/.lalulalu.com/gfwlist +ipset=/.laogai.org/gfwlist +ipset=/.laomiu.com/gfwlist +ipset=/.laoyang.info/gfwlist +ipset=/.laptoplockdown.com/gfwlist +ipset=/.laqingdan.net/gfwlist +ipset=/.larsgeorge.com/gfwlist +ipset=/.lastfm.es/gfwlist +ipset=/.latelinenews.com/gfwlist +ipset=/.latimesblogs.latimes.com/gfwlist +ipset=/.lazarsearlymusic.com/gfwlist +ipset=/.leecheukyan.org/gfwlist +ipset=/.legaltech.law.com/gfwlist +ipset=/.lematin.ch/gfwlist +ipset=/.lemonde.fr/gfwlist +ipset=/.lenwhite.com/gfwlist +ipset=/.lerosua.org/gfwlist +ipset=/.lesoir.be/gfwlist +ipset=/.lesscss.org/gfwlist +ipset=/.letscorp.net/gfwlist +ipset=/.liansi.org/gfwlist +ipset=/.lianyue.net/gfwlist +ipset=/.liaowangxizang.net/gfwlist +ipset=/.liberal.org.hk/gfwlist +ipset=/.libertytimes.com.tw/gfwlist +ipset=/.lich355.megabyet.net/gfwlist +ipset=/.lidecheng.com/gfwlist +ipset=/.life.fly4ever.me/gfwlist +ipset=/.limiao.net/gfwlist +ipset=/.line.me/gfwlist +ipset=/.linglingfa.com/gfwlist +ipset=/.lingvodics.com/gfwlist +ipset=/.linkideo.com/gfwlist +ipset=/.linuxconfig.org/gfwlist +ipset=/.linux-engineer.net/gfwlist +ipset=/.linuxreviews.org/gfwlist +ipset=/.linuxtoy.org/gfwlist +ipset=/.lipuman.com/gfwlist +ipset=/.listentoyoutube.com/gfwlist +ipset=/.list.ly/gfwlist +ipset=/.listorious.com/gfwlist +ipset=/.lists.debian.org/gfwlist +ipset=/.lists.w3.org/gfwlist +ipset=/.littlebigdetails.com/gfwlist +ipset=/.liudejun.com/gfwlist +ipset=/.liuhanyu.com/gfwlist +ipset=/.liujianshu.com/gfwlist +ipset=/.liu.lu/gfwlist +ipset=/.liuxiaotong.com/gfwlist +ipset=/.liveleak.com/gfwlist +ipset=/.livestation.com/gfwlist +ipset=/.livestream.com/gfwlist +ipset=/.livevideo.com/gfwlist +ipset=/.livingonline.us/gfwlist +ipset=/.livingstream.com/gfwlist +ipset=/.lizhizhuangbi.com/gfwlist +ipset=/.lkcn.net/gfwlist +ipset=/.localpresshk.com/gfwlist +ipset=/.lockdown.com/gfwlist +ipset=/.lockestek.com/gfwlist +ipset=/.logbot.net/gfwlist +ipset=/.logiqx.com/gfwlist +ipset=/.logmike.com/gfwlist +ipset=/.log.riku.me/gfwlist +ipset=/.london.neighborhoodr.com/gfwlist +ipset=/.longhair.hk/gfwlist +ipset=/.longtermly.net/gfwlist +ipset=/.lookatgame.com/gfwlist +ipset=/.lookingglasstheatre.org/gfwlist +ipset=/.lookpic.com/gfwlist +ipset=/.lotuslight.org.tw/gfwlist +ipset=/.lovequicksilver.com/gfwlist +ipset=/.lovesphinx.tk/gfwlist +ipset=/.lrfz.com/gfwlist +ipset=/.lsd.org.hk/gfwlist +ipset=/.lsforum.net/gfwlist +ipset=/.lsmchinese.org/gfwlist +ipset=/.lsmkorean.org/gfwlist +ipset=/.lsm.org/gfwlist +ipset=/.lsxszzg.com/gfwlist +ipset=/.lua.org/gfwlist +ipset=/.lua-users.org/gfwlist +ipset=/.lungtanhr.gov.tw/gfwlist +ipset=/.luntan.zaobao.com/gfwlist +ipset=/.lupm.org/gfwlist +ipset=/.lushstories.com/gfwlist +ipset=/.lvhai.org/gfwlist +ipset=/.lyricsquote.com/gfwlist +ipset=/.mad-ar.ch/gfwlist +ipset=/.madmenunbuttoned.com/gfwlist +ipset=/.magazines.sina.com.tw/gfwlist +ipset=/.maiio.net/gfwlist +ipset=/.mail-archive.com/gfwlist +ipset=/.maiplus.com/gfwlist +ipset=/.makemymood.com/gfwlist +ipset=/.makzhou.warehouse333.com/gfwlist +ipset=/.malaysiakini.com/gfwlist +ipset=/.marc.info/gfwlist +ipset=/.marco.org/gfwlist +ipset=/.marguerite.su/gfwlist +ipset=/.marines.mil/gfwlist +ipset=/.markmilian.com/gfwlist +ipset=/.martau.com/gfwlist +ipset=/.martincartoons.com/gfwlist +ipset=/.maruta.be/gfwlist +ipset=/.marxist.com/gfwlist +ipset=/.marxist.net/gfwlist +ipset=/.marxists.org/gfwlist +ipset=/.mashable.com/gfwlist +ipset=/.mash.to/gfwlist +ipset=/.matainja.com/gfwlist +ipset=/.mathiew-badimon.com/gfwlist +ipset=/.matsu-news.gov.tw/gfwlist +ipset=/.matsushimakaede.com/gfwlist +ipset=/.maxgif.com/gfwlist +ipset=/.mayimayi.com/gfwlist +ipset=/.mcadforums.com/gfwlist +ipset=/.mcfog.com/gfwlist +ipset=/.md-t.org/gfwlist +ipset=/.mediafire.com/gfwlist +ipset=/.meetup.com/gfwlist +ipset=/.mefeedia.com/gfwlist +ipset=/.megaporn.com/gfwlist +ipset=/.megarotic.com/gfwlist +ipset=/.megavideo.com/gfwlist +ipset=/.megurineluka.com/gfwlist +ipset=/.meirixiaochao.com/gfwlist +ipset=/.melon-peach.com/gfwlist +ipset=/.memedia.cn/gfwlist +ipset=/.meme.yahoo.com/gfwlist +ipset=/.memrijttm.org/gfwlist +ipset=/.merit-times.com.tw/gfwlist +ipset=/.mesotw.com/gfwlist +ipset=/.metacafe.com/gfwlist +ipset=/.meteorshowersonline.com/gfwlist +ipset=/.metrolife.ca/gfwlist +ipset=/.mgoon.com/gfwlist +ipset=/.mgstage.com/gfwlist +ipset=/.mh4u.org/gfwlist +ipset=/.mhradio.org/gfwlist +ipset=/.michaelanti.com/gfwlist +ipset=/.michaelmarketl.com/gfwlist +ipset=/.middle-way.net/gfwlist +ipset=/.mihk.hk/gfwlist +ipset=/.mihua.org/gfwlist +ipset=/.mike.cz.cc/gfwlist +ipset=/.mimivip.com/gfwlist +ipset=/.minghui.org/gfwlist +ipset=/.minghui-school.org/gfwlist +ipset=/.mingjinglishi.com/gfwlist +ipset=/.mingjingnews.com/gfwlist +ipset=/.mingpaocanada.com/gfwlist +ipset=/.mingpao.com/gfwlist +ipset=/.mingpaomonthly.com/gfwlist +ipset=/.mingpaonews.com/gfwlist +ipset=/.mingpaony.com/gfwlist +ipset=/.mingpaosf.com/gfwlist +ipset=/.mingpaotor.com/gfwlist +ipset=/.mingpaovan.com/gfwlist +ipset=/.minimalmac.com/gfwlist +ipset=/.mininova.org/gfwlist +ipset=/.minzhuhua.net/gfwlist +ipset=/.minzhuzhongguo.org/gfwlist +ipset=/.miroguide.com/gfwlist +ipset=/.mirrorbooks.com/gfwlist +ipset=/.mitbbs.com/gfwlist +ipset=/.mixedmedialabs.com/gfwlist +ipset=/.mixero.com/gfwlist +ipset=/.mixpod.com/gfwlist +ipset=/.mixx.com/gfwlist +ipset=/.mizzmona.com/gfwlist +ipset=/.mk5000.com/gfwlist +ipset=/.mlcool.com/gfwlist +ipset=/.mmaaxx.com/gfwlist +ipset=/.mmmca.com/gfwlist +ipset=/.mobatek.net/gfwlist +ipset=/.mobile01.com/gfwlist +ipset=/.mobileways.de/gfwlist +ipset=/.mobypicture.com/gfwlist +ipset=/.moby.to/gfwlist +ipset=/.modfetish.com/gfwlist +ipset=/.moe.gov.tw/gfwlist +ipset=/.mog.com/gfwlist +ipset=/.molihua.org/gfwlist +ipset=/.mondex.org/gfwlist +ipset=/.monitorchina.org/gfwlist +ipset=/.moonriver7.files.wordpress.com/gfwlist +ipset=/.morningsun.org/gfwlist +ipset=/.m.oulove.org/gfwlist +ipset=/.movabletype.com/gfwlist +ipset=/.moviefap.com/gfwlist +ipset=/.mp3ye.eu/gfwlist +ipset=/.mpettis.com/gfwlist +ipset=/.mpfinance.com/gfwlist +ipset=/.mpinews.com/gfwlist +ipset=/.m.plixi.com/gfwlist +ipset=/.mrdoob.com/gfwlist +ipset=/.mrtweet.com/gfwlist +ipset=/.msguancha.com/gfwlist +ipset=/.m.slandr.net/gfwlist +ipset=/.mthruf.com/gfwlist +ipset=/.m.tweete.net/gfwlist +ipset=/.mtw.tl/gfwlist +ipset=/.multiply.com/gfwlist +ipset=/.multiproxy.org/gfwlist +ipset=/.multiupload.com/gfwlist +ipset=/.muouju.com/gfwlist +ipset=/.muselinks.co.jp/gfwlist +ipset=/.music.jwmusic.org/gfwlist +ipset=/.muzi.com/gfwlist +ipset=/.muzi.net/gfwlist +ipset=/.muzu.tv/gfwlist +ipset=/.mvdis.gov.tw/gfwlist +ipset=/.mx981.com/gfwlist +ipset=/.myactimes.com/gfwlist +ipset=/.my-addr.com/gfwlist +ipset=/.myaudiocast.com/gfwlist +ipset=/.myav.com.tw/gfwlist +ipset=/.my.backchina.com/gfwlist +ipset=/.myboooks.googlepages.com/gfwlist +ipset=/.mychinamyhome.com/gfwlist +ipset=/.myeclipseide.com/gfwlist +ipset=/.myforum.com.hk/gfwlist +ipset=/.myforum.com.uk/gfwlist +ipset=/.myfreshnet.com/gfwlist +ipset=/.my.keso.cn/gfwlist +ipset=/.myopenid.com/gfwlist +ipset=/.my.opera.com/gfwlist +ipset=/.mypaper.pchome.com.tw/gfwlist +ipset=/.myparagliding.com/gfwlist +ipset=/.mypopescu.com/gfwlist +ipset=/.my-proxy.com/gfwlist +ipset=/.myshare.url.com.tw/gfwlist +ipset=/.mysinablog.com/gfwlist +ipset=/.myspace.com/gfwlist +ipset=/.myvlog.im.tv/gfwlist +ipset=/.naacoalition.org/gfwlist +ipset=/.naitik.net/gfwlist +ipset=/.nakido.com/gfwlist +ipset=/.namsisi.com/gfwlist +ipset=/.nanyang.com/gfwlist +ipset=/.nanyangpost.com/gfwlist +ipset=/.nanzao.com/gfwlist +ipset=/.naol.ca/gfwlist +ipset=/.national-lottery.co.uk/gfwlist +ipset=/.navicat.com/gfwlist +ipset=/.navigeaters.com/gfwlist +ipset=/.navy.mil/gfwlist +ipset=/.nccwatch.org.tw/gfwlist +ipset=/.ncdr.nat.gov.tw/gfwlist +ipset=/.nch.com.tw/gfwlist +ipset=/.ncn.org/gfwlist +ipset=/.ncree.gov.tw/gfwlist +ipset=/.nde.de/gfwlist +ipset=/.ndr.de/gfwlist +ipset=/.nekoslovakia.net/gfwlist +ipset=/.nerch.gov.tw/gfwlist +ipset=/.ner.gov.tw/gfwlist +ipset=/.nerhl.gov.tw/gfwlist +ipset=/.nertt.gov.tw/gfwlist +ipset=/.netcolony.com/gfwlist +ipset=/.netflix.com/gfwlist +ipset=/.netme.cc/gfwlist +ipset=/.networkedblogs.com/gfwlist +ipset=/.neverforget8964.org/gfwlist +ipset=/.new-3lunch.net/gfwlist +ipset=/.new-akiba.com/gfwlist +ipset=/.newcenturymc.com/gfwlist +ipset=/.newcenturynews.com/gfwlist +ipset=/.newchen.com/gfwlist +ipset=/.newgrounds.com/gfwlist +ipset=/.newlandmagazine.com.au/gfwlist +ipset=/.news100.com.tw/gfwlist +ipset=/.newsancai.com/gfwlist +ipset=/.news.atebits.com/gfwlist +ipset=/.news.backchina.com/gfwlist +ipset=/.news.bbc.co.uk/gfwlist +ipset=/.newscn.org/gfwlist +ipset=/.news.cnyes.com/gfwlist +ipset=/.newsforums.bbc.co.uk/gfwlist +ipset=/.news.ghostery.com/gfwlist +ipset=/.news.google.com.hk/gfwlist +ipset=/.newsminer.com/gfwlist +ipset=/.news.msn.com.tw/gfwlist +ipset=/.news.omy.sg/gfwlist +ipset=/.news.pchome.com.tw/gfwlist +ipset=/.newspeak.cc/gfwlist +ipset=/.newspp.org/gfwlist +ipset=/.news.sina.com.hk/gfwlist +ipset=/.news.sina.com.tw/gfwlist +ipset=/.news.singtao.ca/gfwlist +ipset=/.newstapa.org/gfwlist +ipset=/.newtaiwan.com.tw/gfwlist +ipset=/.newtalk.tw/gfwlist +ipset=/.newyorktimes.com/gfwlist +ipset=/.nexton-net.jp/gfwlist +ipset=/.nexttv.com.tw/gfwlist +ipset=/.nf.id.au/gfwlist +ipset=/.nga.mil/gfwlist +ipset=/.ngensis.com/gfwlist +ipset=/.nhri.gov.tw/gfwlist +ipset=/.nic.cz.cc/gfwlist +ipset=/.nici.nat.gov.tw/gfwlist +ipset=/.nicovideo.tw/gfwlist +ipset=/.nict.gov.tw/gfwlist +ipset=/.nighost.org/gfwlist +ipset=/.nintendium.com/gfwlist +ipset=/.nintendowifi.net/gfwlist +ipset=/.njactb.org/gfwlist +ipset=/.njuice.com/gfwlist +ipset=/.nlfreevpn.com/gfwlist +ipset=/.nmh.gov.tw/gfwlist +ipset=/.nmmba.gov.tw/gfwlist +ipset=/.nmp.gov.tw/gfwlist +ipset=/.nmtl.gov.tw/gfwlist +ipset=/.nmvttc.gov.tw/gfwlist +ipset=/.nobelprize.org/gfwlist +ipset=/.nobel.se/gfwlist +ipset=/.nobodycanstop.us/gfwlist +ipset=/.nokogiri.org/gfwlist +ipset=/.nokola.com/gfwlist +ipset=/.noobbox.com/gfwlist +ipset=/.notes.alexdong.com/gfwlist +ipset=/.novelasia.com/gfwlist +ipset=/.nownews.com/gfwlist +ipset=/.nowtorrents.com/gfwlist +ipset=/.noypf.com/gfwlist +ipset=/.npa.go.jp/gfwlist +ipset=/.npm.gov.tw/gfwlist +ipset=/.nps.gov/gfwlist +ipset=/.nrk.no/gfwlist +ipset=/.nsc.gov.tw/gfwlist +ipset=/.nspo.gov.tw/gfwlist +ipset=/.nstm.gov.tw/gfwlist +ipset=/.ntdmh.gov.tw/gfwlist +ipset=/.ntdtv.ca/gfwlist +ipset=/.ntdtv.co/gfwlist +ipset=/.ntdtv.com/gfwlist +ipset=/.ntdtv.org/gfwlist +ipset=/.ntdtv.ru/gfwlist +ipset=/.ntl.gov.tw/gfwlist +ipset=/.ntsec.gov.tw/gfwlist +ipset=/.ntuh.gov.tw/gfwlist +ipset=/.nuexpo.com/gfwlist +ipset=/.nurgo-software.com/gfwlist +ipset=/.nuvid.com/gfwlist +ipset=/.nuzcom.com/gfwlist +ipset=/.nvquan.org/gfwlist +ipset=/.nvri.gov.tw/gfwlist +ipset=/.nydus.ca/gfwlist +ipset=/.nysingtao.com/gfwlist +ipset=/.nytco.com/gfwlist +ipset=/.nyt.com/gfwlist +ipset=/.nytimes.com/gfwlist +ipset=/.nytimg.com/gfwlist +ipset=/.nzchinese.net.nz/gfwlist +ipset=/.observechina.net/gfwlist +ipset=/.oclp.hk/gfwlist +ipset=/.october-review.org/gfwlist +ipset=/.offbeatchina.com/gfwlist +ipset=/.ogaoga.org/gfwlist +ipset=/.oikos.com.tw/gfwlist +ipset=/.oiktv.com/gfwlist +ipset=/.oizoblog.com/gfwlist +ipset=/.okayfreedom.com/gfwlist +ipset=/.old-cat.net/gfwlist +ipset=/.old.nabble.com/gfwlist +ipset=/.olumpo.com/gfwlist +ipset=/.olympicwatch.org/gfwlist +ipset=/.omgili.com/gfwlist +ipset=/.omnitalk.com/gfwlist +ipset=/.on.cc/gfwlist +ipset=/.one.xthost.info/gfwlist +ipset=/.onlylady.cn/gfwlist +ipset=/.onmoon.com/gfwlist +ipset=/.onmoon.net/gfwlist +ipset=/.oopsforum.com/gfwlist +ipset=/.ooyala.com/gfwlist +ipset=/.open.com.hk/gfwlist +ipset=/.opendemocracy.net/gfwlist +ipset=/.openid.net/gfwlist +ipset=/.openleaks.org/gfwlist +ipset=/.openvpn.net/gfwlist +ipset=/.openvpn.org/gfwlist +ipset=/.openwebster.com/gfwlist +ipset=/.opml.radiotime.com/gfwlist +ipset=/.opnir.com/gfwlist +ipset=/.orientaldaily.com.my/gfwlist +ipset=/.orient-doll.com/gfwlist +ipset=/.orn.jp/gfwlist +ipset=/.orzistic.org/gfwlist +ipset=/.osfoora.com/gfwlist +ipset=/.ourdearamy.com/gfwlist +ipset=/.oursogo.com/gfwlist +ipset=/.oursteps.com.au/gfwlist +ipset=/.overlapr.com/gfwlist +ipset=/.owl.li/gfwlist +ipset=/.ow.ly/gfwlist +ipset=/.oyax.com/gfwlist +ipset=/.ozchinese.com/gfwlist +ipset=/.ozyoyo.com/gfwlist +ipset=/.pabp.gov.tw/gfwlist +ipset=/.pacificpoker.com/gfwlist +ipset=/.packages.debian.org/gfwlist +ipset=/.packetix.net/gfwlist +ipset=/.page2rss.com/gfwlist +ipset=/.page.bid.yahoo.com/gfwlist +ipset=/.pagodabox.com/gfwlist +ipset=/.paint.net/gfwlist +ipset=/.palacemoon.com/gfwlist +ipset=/.pandora.com/gfwlist +ipset=/.pandora.tv/gfwlist +ipset=/.panluan.net/gfwlist +ipset=/.panoramio.com/gfwlist +ipset=/.pao-pao.net/gfwlist +ipset=/.paperb.us/gfwlist +ipset=/.paper.li/gfwlist +ipset=/.paper-replika.com/gfwlist +ipset=/.parade.com/gfwlist +ipset=/.parislemon.com/gfwlist +ipset=/.pastebin.com/gfwlist +ipset=/.pastie.org/gfwlist +ipset=/.patehr.gov.tw/gfwlist +ipset=/.pbs.org/gfwlist +ipset=/.pbwiki.com/gfwlist +ipset=/.pbworks.com/gfwlist +ipset=/.pbxes.com/gfwlist +ipset=/.pbxes.org/gfwlist +ipset=/.pcdiscuss.com/gfwlist +ipset=/.pcdvd.com.tw/gfwlist +ipset=/.pchome.com.tw/gfwlist +ipset=/.pct.org.tw/gfwlist +ipset=/.pcworld.com/gfwlist +ipset=/.pdetails.com/gfwlist +ipset=/.pdproxy.com/gfwlist +ipset=/.peacefire.org/gfwlist +ipset=/.peacehall.com/gfwlist +ipset=/.peeasian.com/gfwlist +ipset=/.peerpong.com/gfwlist +ipset=/.pekingduck.org/gfwlist +ipset=/.penchinese.com/gfwlist +ipset=/.penchinese.net/gfwlist +ipset=/.pengyulong.com/gfwlist +ipset=/.penthouse.com/gfwlist +ipset=/.peopo.org/gfwlist +ipset=/.percy.in/gfwlist +ipset=/.perfectgirls.net/gfwlist +ipset=/.perfectvpn.net/gfwlist +ipset=/.perfspot.com/gfwlist +ipset=/.perlhowto.com/gfwlist +ipset=/.pet.gov.tw/gfwlist +ipset=/.philly.com/gfwlist +ipset=/.photofocus.com/gfwlist +ipset=/.photos.dailyme.com/gfwlist +ipset=/.photo.utom.us/gfwlist +ipset=/.phuquocservices.com/gfwlist +ipset=/.picasaweb.google.com/gfwlist +ipset=/.picidae.net/gfwlist +ipset=/.picturesocial.com/gfwlist +ipset=/.pictures.playboy.com/gfwlist +ipset=/.pidown.com/gfwlist +ipset=/.pign.net/gfwlist +ipset=/.pimg.tw/gfwlist +ipset=/.pin6.com/gfwlist +ipset=/.ping.fm/gfwlist +ipset=/.pinoy-n.com/gfwlist +ipset=/.pioneer-worker.forums-free.com/gfwlist +ipset=/.piring.com/gfwlist +ipset=/.pixanalytics.com/gfwlist +ipset=/.pixelqi.com/gfwlist +ipset=/.pixfs.net/gfwlist +ipset=/.pixnet.cc/gfwlist +ipset=/.pixnet.net/gfwlist +ipset=/.pixplug.in/gfwlist +ipset=/.pk.com/gfwlist +ipset=/.placemix.com/gfwlist +ipset=/.planetsuzy.org/gfwlist +ipset=/.playboy.com/gfwlist +ipset=/.plays.com.tw/gfwlist +ipset=/.plm.org.hk/gfwlist +ipset=/.plunder.com/gfwlist +ipset=/.plurk.com/gfwlist +ipset=/.plurktop.mmdays.com/gfwlist +ipset=/.plus28.com/gfwlist +ipset=/.plusbb.com/gfwlist +ipset=/.pmates.com/gfwlist +ipset=/.po2b.com/gfwlist +ipset=/.podictionary.com/gfwlist +ipset=/.pokerstars.com/gfwlist +ipset=/.politicalchina.org/gfwlist +ipset=/.popvote.hk/gfwlist +ipset=/.popyard.com/gfwlist +ipset=/.popyard.org/gfwlist +ipset=/.porn2.com/gfwlist +ipset=/.pornbase.org/gfwlist +ipset=/.porn.com/gfwlist +ipset=/.pornhub.com/gfwlist +ipset=/.pornmm.net/gfwlist +ipset=/.pornoxo.com/gfwlist +ipset=/.pornrapidshare.com/gfwlist +ipset=/.pornstarclub.com/gfwlist +ipset=/.porntube.com/gfwlist +ipset=/.pornvisit.com/gfwlist +ipset=/.portis21.spaces.live.com/gfwlist +ipset=/.pose.com/gfwlist +ipset=/.postadult.com/gfwlist +ipset=/.post.anyu.org/gfwlist +ipset=/.posterous.com/gfwlist +ipset=/.post.ly/gfwlist +ipset=/.powerapple.com/gfwlist +ipset=/.power.com/gfwlist +ipset=/.powercx.com/gfwlist +ipset=/.prayforchina.net/gfwlist +ipset=/.premeforwindows7.com/gfwlist +ipset=/.presentationzen.com/gfwlist +ipset=/.president.gov.tw/gfwlist +ipset=/.prestige-av.com/gfwlist +ipset=/.previewshots.com/gfwlist +ipset=/.privacybox.de/gfwlist +ipset=/.privateinternetaccess.com/gfwlist +ipset=/.privatepaste.com/gfwlist +ipset=/.privatetunnel.com/gfwlist +ipset=/.procopytips.com/gfwlist +ipset=/.program-think.spaces.live.com/gfwlist +ipset=/.prosiben.de/gfwlist +ipset=/.provideocoalition.com/gfwlist +ipset=/.proxifier.com/gfwlist +ipset=/.proxomitron.info/gfwlist +ipset=/.proxy.org/gfwlist +ipset=/.proxypy.net/gfwlist +ipset=/.proxyroad.com/gfwlist +ipset=/.prozz.net/gfwlist +ipset=/.psblog.name/gfwlist +ipset=/.psiphon.ca/gfwlist +ipset=/.psiphon.civisec.org/gfwlist +ipset=/.pts.org.tw/gfwlist +ipset=/.ptt.cc/gfwlist +ipset=/.pubu.com.tw/gfwlist +ipset=/.puffinbrowser.com/gfwlist +ipset=/.puffstore.com/gfwlist +ipset=/.pullfolio.com/gfwlist +ipset=/.pulse.yahoo.com/gfwlist +ipset=/.pure18.com/gfwlist +ipset=/.pureconcepts.net/gfwlist +ipset=/.purepdf.com/gfwlist +ipset=/.purevpn.com/gfwlist +ipset=/.putlocker.com/gfwlist +ipset=/.puttycm.free.fr/gfwlist +ipset=/.pwned.com/gfwlist +ipset=/.python.com/gfwlist +ipset=/.python.com.tw/gfwlist +ipset=/.qanote.com/gfwlist +ipset=/.qidian.ca/gfwlist +ipset=/.qienkuen.org/gfwlist +ipset=/.qi-gong.me/gfwlist +ipset=/.qiwen.lu/gfwlist +ipset=/.qixianglu.cn/gfwlist +ipset=/.qkshare.com/gfwlist +ipset=/.qoos.com/gfwlist +ipset=/.qq.co.za/gfwlist +ipset=/.qstatus.com/gfwlist +ipset=/.qtrac.eu/gfwlist +ipset=/.qtweeter.com/gfwlist +ipset=/.quadedge.com/gfwlist +ipset=/.qusi8.net/gfwlist +ipset=/.qvodzy.org/gfwlist +ipset=/.qxbbs.org/gfwlist +ipset=/.radicalparty.org/gfwlist +ipset=/.radioaustralia.net.au/gfwlist +ipset=/.radiovaticana.org/gfwlist +ipset=/.radiovncr.com/gfwlist +ipset=/.raidcall.com.tw/gfwlist +ipset=/.rangzen.org/gfwlist +ipset=/.ranyunfei.com/gfwlist +ipset=/.rapbull.net/gfwlist +ipset=/.rapidshare8.com/gfwlist +ipset=/.rapidsharedata.com/gfwlist +ipset=/.rayfme.com/gfwlist +ipset=/.rcinet.ca/gfwlist +ipset=/.rconversation.blogs.com/gfwlist +ipset=/.rdio.com/gfwlist +ipset=/.read100.com/gfwlist +ipset=/.readingtimes.com.tw/gfwlist +ipset=/.readmoo.com/gfwlist +ipset=/.realraptalk.com/gfwlist +ipset=/.recordhistory.org/gfwlist +ipset=/.redchinacn.org/gfwlist +ipset=/.redtube.com/gfwlist +ipset=/.referer.us/gfwlist +ipset=/.reflectivecode.com/gfwlist +ipset=/.relaxbbs.com/gfwlist +ipset=/.renminbao.com/gfwlist +ipset=/.renyurenquan.org/gfwlist +ipset=/.retweeteffect.com/gfwlist +ipset=/.retweetist.com/gfwlist +ipset=/.retweetrank.com/gfwlist +ipset=/.revleft.com/gfwlist +ipset=/.revsci.net/gfwlist +ipset=/.revver.com/gfwlist +ipset=/.rfachina.com/gfwlist +ipset=/.rfamobile.org/gfwlist +ipset=/.rfa.org/gfwlist +ipset=/.rferl.org/gfwlist +ipset=/.rfi.fr/gfwlist +ipset=/.rhcloud.com/gfwlist +ipset=/.riku.me/gfwlist +ipset=/.rileyguide.com/gfwlist +ipset=/.rlwlw.com/gfwlist +ipset=/.rmjdw.com/gfwlist +ipset=/.rnw.nl/gfwlist +ipset=/.robtex.com/gfwlist +ipset=/.robustnessiskey.com/gfwlist +ipset=/.rocmp.org/gfwlist +ipset=/.rojo.com/gfwlist +ipset=/.ronjoneswriter.com/gfwlist +ipset=/.roodo.com/gfwlist +ipset=/.rotten.com/gfwlist +ipset=/.rsf-chinese.org/gfwlist +ipset=/.rsf.org/gfwlist +ipset=/.rssmeme.com/gfwlist +ipset=/.rthk.hk/gfwlist +ipset=/.rthk.org.hk/gfwlist +ipset=/.rti.org.tw/gfwlist +ipset=/.ruanyifeng.com/gfwlist +ipset=/.rushbee.com/gfwlist +ipset=/.rutube.ru/gfwlist +ipset=/.ruyiseek.com/gfwlist +ipset=/.rxhj.net/gfwlist +ipset=/.s1heng.com/gfwlist +ipset=/.s8forum.com/gfwlist +ipset=/.sacom.hk/gfwlist +ipset=/.sadpanda.us/gfwlist +ipset=/.saiq.me/gfwlist +ipset=/.salvation.org.hk/gfwlist +ipset=/.samair.ru/gfwlist +ipset=/.sammyjs.org/gfwlist +ipset=/.samsoff.es/gfwlist +ipset=/.sandnoble.com/gfwlist +ipset=/.sankaizok.com/gfwlist +ipset=/.sanmin.com.tw/gfwlist +ipset=/.sapikachu.net/gfwlist +ipset=/.savemedia.com/gfwlist +ipset=/.savetibet.de/gfwlist +ipset=/.savetibet.fr/gfwlist +ipset=/.savetibet.nl/gfwlist +ipset=/.savetibet.org/gfwlist +ipset=/.savetibet.ru/gfwlist +ipset=/.savevid.com/gfwlist +ipset=/.say2.info/gfwlist +ipset=/.scanscout.com/gfwlist +ipset=/.scmpchinese.com/gfwlist +ipset=/.scmp.com/gfwlist +ipset=/.scorecardresearch.com/gfwlist +ipset=/.scribd.com/gfwlist +ipset=/.scriptspot.com/gfwlist +ipset=/.seapuff.com/gfwlist +ipset=/.secretchina.com/gfwlist +ipset=/.secretgarden.no/gfwlist +ipset=/.secure.wikimedia.org/gfwlist +ipset=/.securitykiss.com/gfwlist +ipset=/.seesmic.com/gfwlist +ipset=/.seevpn.com/gfwlist +ipset=/.seezone.net/gfwlist +ipset=/.sejie.com/gfwlist +ipset=/.sendoid.com/gfwlist +ipset=/.sendspace.com/gfwlist +ipset=/.sesawe.net/gfwlist +ipset=/.sesawe.org/gfwlist +ipset=/.sethwklein.net/gfwlist +ipset=/.sevenload.com/gfwlist +ipset=/.sex-11.com/gfwlist +ipset=/.sex3.com/gfwlist +ipset=/.sex8.cc/gfwlist +ipset=/.sexandsubmission.com/gfwlist +ipset=/.sex.com/gfwlist +ipset=/.sexhuang.com/gfwlist +ipset=/.sexhu.com/gfwlist +ipset=/.sexinsex.net/gfwlist +ipset=/.sfileydy.com/gfwlist +ipset=/.shadow.ma/gfwlist +ipset=/.shadowsocks.org/gfwlist +ipset=/.shahamat-english.com/gfwlist +ipset=/.shangfang.org/gfwlist +ipset=/.shapeservices.com/gfwlist +ipset=/.sharebee.com/gfwlist +ipset=/.sharecool.org/gfwlist +ipset=/.share.ovi.com/gfwlist +ipset=/.share.skype.com/gfwlist +ipset=/.share.youthwant.com.tw/gfwlist +ipset=/.sharkdolphin.com/gfwlist +ipset=/.sharpdaily.com.hk/gfwlist +ipset=/.sharpdaily.hk/gfwlist +ipset=/.shaunthesheep.com/gfwlist +ipset=/.sheikyermami.com/gfwlist +ipset=/.shellmix.com/gfwlist +ipset=/.shenshou.org/gfwlist +ipset=/.shenyunperformingarts.org/gfwlist +ipset=/.shenzhoufilm.com/gfwlist +ipset=/.shifeike.blog125.fc2blog.net/gfwlist +ipset=/.shinychan.com/gfwlist +ipset=/.shitaotv.org/gfwlist +ipset=/.shixiao.org/gfwlist +ipset=/.shizhao.org/gfwlist +ipset=/.shkspr.mobi/gfwlist +ipset=/.shodanhq.com/gfwlist +ipset=/.shopping.com/gfwlist +ipset=/.showbiz.omy.sg/gfwlist +ipset=/.showtime.jp/gfwlist +ipset=/.shwchurch3.com/gfwlist +ipset=/.sidelinesnews.com/gfwlist +ipset=/.sidelinessportseatery.com/gfwlist +ipset=/.simplecd.me/gfwlist +ipset=/.simplecd.org/gfwlist +ipset=/.simpleproductivityblog.com/gfwlist +ipset=/.sina.com.tw/gfwlist +ipset=/.singtao.com/gfwlist +ipset=/.singularitys.spaces.live.com/gfwlist +ipset=/.sinoants.com/gfwlist +ipset=/.sinocast.com/gfwlist +ipset=/.sinocism.com/gfwlist +ipset=/.sino-monthly.com/gfwlist +ipset=/.sinomontreal.ca/gfwlist +ipset=/.sinonet.ca/gfwlist +ipset=/.sinopitt.info/gfwlist +ipset=/.sinoquebec.com/gfwlist +ipset=/.sis001.com/gfwlist +ipset=/.sis001.us/gfwlist +ipset=/.sis.xxx/gfwlist +ipset=/.site90.net/gfwlist +ipset=/.sitebro.tw/gfwlist +ipset=/.siteks.uk.to/gfwlist +ipset=/.site.locql.com/gfwlist +ipset=/.sitemaps.org/gfwlist +ipset=/.sites.google.com/gfwlist +ipset=/.sitetag.us/gfwlist +ipset=/.siyi123123123.spaces.live.com/gfwlist +ipset=/.skimtube.com/gfwlist +ipset=/.skybet.com/gfwlist +ipset=/.skyvegas.com/gfwlist +ipset=/.slacker.com/gfwlist +ipset=/.slavasoft.com/gfwlist +ipset=/.slheng.com/gfwlist +ipset=/.slickvpn.com/gfwlist +ipset=/.slideshare.net/gfwlist +ipset=/.slinkset.com/gfwlist +ipset=/.slutload.com/gfwlist +ipset=/.smhric.org/gfwlist +ipset=/.snapchat.com/gfwlist +ipset=/.snaptu.com/gfwlist +ipset=/.sndcdn.com/gfwlist +ipset=/.sneakme.net/gfwlist +ipset=/.snooper.co.uk/gfwlist +ipset=/.sobees.com/gfwlist +ipset=/.socialwhale.com/gfwlist +ipset=/.sockslist.net/gfwlist +ipset=/.sod.co.jp/gfwlist +ipset=/.softether.co.jp/gfwlist +ipset=/.softether-download.com/gfwlist +ipset=/.softether.org/gfwlist +ipset=/.softwarebychuck.com/gfwlist +ipset=/.so-ga.net/gfwlist +ipset=/.sogclub.com/gfwlist +ipset=/.sogrady.me/gfwlist +ipset=/.sohcradio.com/gfwlist +ipset=/.sohfrance.org/gfwlist +ipset=/.soh.tw/gfwlist +ipset=/.sokamonline.com/gfwlist +ipset=/.solozorro.tk/gfwlist +ipset=/.somee.com/gfwlist +ipset=/.so-news.com/gfwlist +ipset=/.songjianjun.com/gfwlist +ipset=/.sonidodelaesperanza.org/gfwlist +ipset=/.sopcast.com/gfwlist +ipset=/.sopcast.org/gfwlist +ipset=/.sorting-algorithms.com/gfwlist +ipset=/.soumo.info/gfwlist +ipset=/.soundcloud.com/gfwlist +ipset=/.soundofhope.kr/gfwlist +ipset=/.soundofhope.org/gfwlist +ipset=/.soupofmedia.com/gfwlist +ipset=/.sourceforge.net/gfwlist +ipset=/.southnews.com.tw/gfwlist +ipset=/.sowers.org.hk/gfwlist +ipset=/.space-scape.com/gfwlist +ipset=/.spankwire.com/gfwlist +ipset=/.spb.com/gfwlist +ipset=/.speckleapp.com/gfwlist +ipset=/.speedpluss.org/gfwlist +ipset=/.spencertipping.com/gfwlist +ipset=/.spinejs.com/gfwlist +ipset=/.sports.williamhill.com/gfwlist +ipset=/.spotify.com/gfwlist +ipset=/.sproutcore.com/gfwlist +ipset=/.squarespace.com/gfwlist +ipset=/.srcf.ucam.org/gfwlist +ipset=/.ssh91.com/gfwlist +ipset=/.sshtunnel.googlecode.com/gfwlist +ipset=/.sstatic.net/gfwlist +ipset=/.stag.gov.tw/gfwlist +ipset=/.standupfortibet.org/gfwlist +ipset=/.starp2p.com/gfwlist +ipset=/.startpage.com/gfwlist +ipset=/.statcounter.com/gfwlist +ipset=/.state168.com/gfwlist +ipset=/.static.apple.nextmedia.com/gfwlist +ipset=/.static.digg.com/gfwlist +ipset=/.staticflickr.com/gfwlist +ipset=/.static.nownews.com/gfwlist +ipset=/.static.soup.io/gfwlist +ipset=/.static.typepad.com/gfwlist +ipset=/.status.twhirl.org/gfwlist +ipset=/.stdtime.gov.tw/gfwlist +ipset=/.steel-storm.com/gfwlist +ipset=/.sthoo.com/gfwlist +ipset=/.stickam.com/gfwlist +ipset=/.stickeraction.com/gfwlist +ipset=/.stonegames.net/gfwlist +ipset=/.stoneip.info/gfwlist +ipset=/.stoptibetcrisis.net/gfwlist +ipset=/.storagenewsletter.com/gfwlist +ipset=/.stoweboyd.com/gfwlist +ipset=/.streamingthe.net/gfwlist +ipset=/.strongvpn.com/gfwlist +ipset=/.student.tw/gfwlist +ipset=/.stuffimreading.com/gfwlist +ipset=/.stuffimreading.net/gfwlist +ipset=/.stupidvideos.com/gfwlist +ipset=/.subacme.rerouted.org/gfwlist +ipset=/.sublexical.spaces.live.com/gfwlist +ipset=/.sufeng.org/gfwlist +ipset=/.sugarsync.com/gfwlist +ipset=/.summify.com/gfwlist +ipset=/.sun1911.com/gfwlist +ipset=/.suoluo.org/gfwlist +ipset=/.surfeasy.com.au/gfwlist +ipset=/.svwind.com/gfwlist +ipset=/.sweux.com/gfwlist +ipset=/.swift-tools.net/gfwlist +ipset=/.s.xiaod.in/gfwlist +ipset=/.sydneytoday.com/gfwlist +ipset=/.sylfoundation.org/gfwlist +ipset=/.syncback.com/gfwlist +ipset=/.sysadmin1138.net/gfwlist +ipset=/.sysresccd.org/gfwlist +ipset=/.sytes.net/gfwlist +ipset=/.szbbs.net/gfwlist +ipset=/.szetowah.org.hk/gfwlist +ipset=/.t35.com/gfwlist +ipset=/.t66y.com/gfwlist +ipset=/.taa-usa.org/gfwlist +ipset=/.tabtter.jp/gfwlist +ipset=/.tacem.org/gfwlist +ipset=/.tafaward.com/gfwlist +ipset=/.tagwalk.com/gfwlist +ipset=/.taipei.gov.tw/gfwlist +ipset=/.taipeisociety.org/gfwlist +ipset=/.taitung-house.gov.tw/gfwlist +ipset=/.taiwandaily.net/gfwlist +ipset=/.taiwankiss.com/gfwlist +ipset=/.taiwannation.50webs.com/gfwlist +ipset=/.taiwannation.com/gfwlist +ipset=/.taiwannation.com.tw/gfwlist +ipset=/.taiwannews.com.tw/gfwlist +ipset=/.taiwan-sex.com/gfwlist +ipset=/.taiwantt.org.tw/gfwlist +ipset=/.taiwanus.net/gfwlist +ipset=/.taiwanyes.com/gfwlist +ipset=/.taiwanyes.ning.com/gfwlist +ipset=/.tamiaode.tk/gfwlist +ipset=/.tanc.org/gfwlist +ipset=/.tangben.com/gfwlist +ipset=/.taolun.info/gfwlist +ipset=/.taoyuan.gov.tw/gfwlist +ipset=/.tap11.com/gfwlist +ipset=/.target.com/gfwlist +ipset=/.taweet.com/gfwlist +ipset=/.tax.nat.gov.tw/gfwlist +ipset=/.tbpic.info/gfwlist +ipset=/.tbsec.org/gfwlist +ipset=/.tbsn.org/gfwlist +ipset=/.tbsseattle.org/gfwlist +ipset=/.tchb.gov.tw/gfwlist +ipset=/.tchrd.org/gfwlist +ipset=/.t.co/gfwlist +ipset=/.tcsac.gov.tw/gfwlist +ipset=/.teamseesmic.com/gfwlist +ipset=/.teashark.com/gfwlist +ipset=/.techlifeweb.com/gfwlist +ipset=/.techparaiso.com/gfwlist +ipset=/.telecomspace.com/gfwlist +ipset=/.telegraph.co.uk/gfwlist +ipset=/.tenacy.com/gfwlist +ipset=/.thbstc.gov.tw/gfwlist +ipset=/.theampfactory.com/gfwlist +ipset=/.theappleblog.com/gfwlist +ipset=/.theatrum-belli.com/gfwlist +ipset=/.thebcomplex.com/gfwlist +ipset=/.theblemish.com/gfwlist +ipset=/.thebodyshop-usa.com/gfwlist +ipset=/.thechinabeat.org/gfwlist +ipset=/.thedailywh.at/gfwlist +ipset=/.thedieline.com/gfwlist +ipset=/.thedw.us/gfwlist +ipset=/.thegatesnotes.com/gfwlist +ipset=/.thehots.info/gfwlist +ipset=/.thehousenews.com/gfwlist +ipset=/.thehungrydudes.com/gfwlist +ipset=/.thehun.net/gfwlist +ipset=/.theinternetwishlist.com/gfwlist +ipset=/.thelifeyoucansave.com/gfwlist +ipset=/.thelius.org/gfwlist +ipset=/.thepiratebay.org/gfwlist +ipset=/.thepiratebay.se/gfwlist +ipset=/.theqii.info/gfwlist +ipset=/.thereallove.kr/gfwlist +ipset=/.thesartorialist.com/gfwlist +ipset=/.thespeeder.com/gfwlist +ipset=/.the-sun.on.cc/gfwlist +ipset=/.thetibetpost.com/gfwlist +ipset=/.thetrotskymovie.com/gfwlist +ipset=/.thevivekspot.com/gfwlist +ipset=/.thewgo.org/gfwlist +ipset=/.thisav.com/gfwlist +ipset=/.thisiswhyyouarefat.com/gfwlist +ipset=/.thkphoto.com/gfwlist +ipset=/.thomasbernhard.org/gfwlist +ipset=/.threatchaos.com/gfwlist +ipset=/.throughnightsfire.com/gfwlist +ipset=/.t.huhaitai.com/gfwlist +ipset=/.thumbzilla.com/gfwlist +ipset=/.thywords.com/gfwlist +ipset=/.tiananmenmother.org/gfwlist +ipset=/.tiananmenuniv.com/gfwlist +ipset=/.tiananmenuniv.net/gfwlist +ipset=/.tiandixing.org/gfwlist +ipset=/.tianhuayuan.com/gfwlist +ipset=/.tiantibooks.org/gfwlist +ipset=/.tianzhu.org/gfwlist +ipset=/.tibetalk.com/gfwlist +ipset=/.tibetanyouthcongress.org/gfwlist +ipset=/.tibet.at/gfwlist +ipset=/.tibet.com/gfwlist +ipset=/.tibetcorps.org/gfwlist +ipset=/.tibetfund.org/gfwlist +ipset=/.tibetjustice.org/gfwlist +ipset=/.tibet.net/gfwlist +ipset=/.tibetoffice.org/gfwlist +ipset=/.tibetonline.com/gfwlist +ipset=/.tibetonline.tv/gfwlist +ipset=/.tibet.org.tw/gfwlist +ipset=/.tibetsun.com/gfwlist +ipset=/.tibetwrites.org/gfwlist +ipset=/.tidyread.com/gfwlist +ipset=/.time.com/gfwlist +ipset=/.times.hinet.net/gfwlist +ipset=/.tinychat.com/gfwlist +ipset=/.tinypaste.com/gfwlist +ipset=/.tinypng.com/gfwlist +ipset=/.tistory.com/gfwlist +ipset=/.tjholowaychuk.com/gfwlist +ipset=/.tkcs-collins.com/gfwlist +ipset=/.tkforum.tk/gfwlist +ipset=/.t.kun.im/gfwlist +ipset=/.tmagazine.com/gfwlist +ipset=/.tmi.me/gfwlist +ipset=/.tnaflix.com/gfwlist +ipset=/.tncsec.gov.tw/gfwlist +ipset=/.t.neolee.cn/gfwlist +ipset=/.togetter.com/gfwlist +ipset=/.tokyo-247.com/gfwlist +ipset=/.tokyocn.com/gfwlist +ipset=/.tokyo-hot.com/gfwlist +ipset=/.tomayko.com/gfwlist +ipset=/.tomsc.com/gfwlist +ipset=/.tono-oka.jp/gfwlist +ipset=/.tonyyan.net/gfwlist +ipset=/.toodoc.com/gfwlist +ipset=/.toonel.net/gfwlist +ipset=/.topic.youthwant.com.tw/gfwlist +ipset=/.topnews.in/gfwlist +ipset=/.topshare.us/gfwlist +ipset=/.topshareware.com/gfwlist +ipset=/.topstyle4.com/gfwlist +ipset=/.topsy.com/gfwlist +ipset=/.tora.to/gfwlist +ipset=/.tor.blingblingsquad.net/gfwlist +ipset=/.torproject.org/gfwlist +ipset=/.torrentcrazy.com/gfwlist +ipset=/.torrentproject.se/gfwlist +ipset=/.tor.updatestar.com/gfwlist +ipset=/.torvpn.com/gfwlist +ipset=/.t.orzdream.com/gfwlist +ipset=/.tosh.comedycentral.com/gfwlist +ipset=/.touch99.com/gfwlist +ipset=/.toutfr.com/gfwlist +ipset=/.tpde.aide.gov.tw/gfwlist +ipset=/.tphcc.gov.tw/gfwlist +ipset=/.tpi.org.tw/gfwlist +ipset=/.transgressionism.org/gfwlist +ipset=/.transparency.org/gfwlist +ipset=/.travelinlocal.com/gfwlist +ipset=/.trendsmap.com/gfwlist +ipset=/.trialofccp.org/gfwlist +ipset=/.tripod.com/gfwlist +ipset=/.trouw.nl/gfwlist +ipset=/.trtc.com.tw/gfwlist +ipset=/.trt.net.tr/gfwlist +ipset=/.trulyergonomic.com/gfwlist +ipset=/.trustedbi.com/gfwlist +ipset=/.truth101.co.tv/gfwlist +ipset=/.truthcn.com/gfwlist +ipset=/.truveo.com/gfwlist +ipset=/.tsctv.net/gfwlist +ipset=/.tsemtulku.com/gfwlist +ipset=/.tsquare.tv/gfwlist +ipset=/.tsunagarumon.com/gfwlist +ipset=/.tt1069.com/gfwlist +ipset=/.tttan.com/gfwlist +ipset=/.tuanzt.com/gfwlist +ipset=/.tube8.com/gfwlist +ipset=/.tubecao.com/gfwlist +ipset=/.tube.com/gfwlist +ipset=/.tubewolf.com/gfwlist +ipset=/.tuidang.net/gfwlist +ipset=/.tuidang.org/gfwlist +ipset=/.tui.orzdream.com/gfwlist +ipset=/.tuite.googlecode.com/gfwlist +ipset=/.tumblr.awflasher.com/gfwlist +ipset=/.tumblweed.org/gfwlist +ipset=/.tumutanzi.com/gfwlist +ipset=/.tunein.com/gfwlist +ipset=/.tunnelbear.com/gfwlist +ipset=/.turbobit.net/gfwlist +ipset=/.turbotwitter.com/gfwlist +ipset=/.turningtorso.com/gfwlist +ipset=/.turntable.fm/gfwlist +ipset=/.tuxtraining.com/gfwlist +ipset=/.tvants.com/gfwlist +ipset=/.tvboxnow.com/gfwlist +ipset=/.tv.com/gfwlist +ipset=/.tvider.com/gfwlist +ipset=/.tv-intros.com/gfwlist +ipset=/.tv.on.cc/gfwlist +ipset=/.tvunetworks.com/gfwlist +ipset=/.twapperkeeper.com/gfwlist +ipset=/.twa.sh/gfwlist +ipset=/.twaud.io/gfwlist +ipset=/.twbbs.net.tw/gfwlist +ipset=/.twbbs.org/gfwlist +ipset=/.twbbs.tw/gfwlist +ipset=/.twblogger.com/gfwlist +ipset=/.tweepguide.com/gfwlist +ipset=/.tweeplike.me/gfwlist +ipset=/.tweepmag.com/gfwlist +ipset=/.tweepml.org/gfwlist +ipset=/.tweetbackup.com/gfwlist +ipset=/.tweetboard.com/gfwlist +ipset=/.tweetboner.biz/gfwlist +ipset=/.tweetdeck.com/gfwlist +ipset=/.tweetedtimes.com/gfwlist +ipset=/.tweetmeme.com/gfwlist +ipset=/.tweetmylast.fm/gfwlist +ipset=/.tweetphoto.com/gfwlist +ipset=/.tweetrans.com/gfwlist +ipset=/.tweetree.com/gfwlist +ipset=/.tweetwally.com/gfwlist +ipset=/.tweetymail.com/gfwlist +ipset=/.twftp.org/gfwlist +ipset=/.twibase.com/gfwlist +ipset=/.twibble.de/gfwlist +ipset=/.twibbon.com/gfwlist +ipset=/.twibs.com/gfwlist +ipset=/.twicsy.com/gfwlist +ipset=/.twifan.com/gfwlist +ipset=/.twiffo.com/gfwlist +ipset=/.twiggit.org/gfwlist +ipset=/.twilog.org/gfwlist +ipset=/.twimbow.com/gfwlist +ipset=/.twimg.com/gfwlist +ipset=/.twimg.edgesuite.net/gfwlist +ipset=/.tw.img.nextmedia.com/gfwlist +ipset=/.twindexx.com/gfwlist +ipset=/.twipple.jp/gfwlist +ipset=/.twistar.cc/gfwlist +ipset=/.twisternow.com/gfwlist +ipset=/.twistory.net/gfwlist +ipset=/.twit2d.com/gfwlist +ipset=/.twitbrowser.net/gfwlist +ipset=/.twitcause.com/gfwlist +ipset=/.twitese.spaces.live.com/gfwlist +ipset=/.twitgether.com/gfwlist +ipset=/.twitgoo.com/gfwlist +ipset=/.twitiq.com/gfwlist +ipset=/.twitlonger.com/gfwlist +ipset=/.twitoaster.com/gfwlist +ipset=/.twitonmsn.com/gfwlist +ipset=/.twitpic.com/gfwlist +ipset=/.twitreferral.com/gfwlist +ipset=/.twitstat.com/gfwlist +ipset=/.twittbot.net/gfwlist +ipset=/.twitter4j.org/gfwlist +ipset=/.twitter.com/gfwlist +ipset=/.twittercounter.com/gfwlist +ipset=/.twitterfeed.com/gfwlist +ipset=/.twittergadget.com/gfwlist +ipset=/.twitter.jp/gfwlist +ipset=/.twitterkr.com/gfwlist +ipset=/.twittermail.com/gfwlist +ipset=/.twittertim.es/gfwlist +ipset=/.twitthat.com/gfwlist +ipset=/.twitturk.com/gfwlist +ipset=/.twitturly.com/gfwlist +ipset=/.twitvid.com/gfwlist +ipset=/.twitzap.com/gfwlist +ipset=/.twiyia.com/gfwlist +ipset=/.tw.jiepang.com/gfwlist +ipset=/.tw.myblog.yahoo.com/gfwlist +ipset=/.tw.news.yahoo.com/gfwlist +ipset=/.tw-npo.org/gfwlist +ipset=/.tw.rd.yahoo.com/gfwlist +ipset=/.twreg.info/gfwlist +ipset=/.twstar.net/gfwlist +ipset=/.tw.streetvoice.com/gfwlist +ipset=/.twt.fm/gfwlist +ipset=/.twtkr.com/gfwlist +ipset=/.twtr2src.ogaoga.org/gfwlist +ipset=/.twtrland.com/gfwlist +ipset=/.twt.tl/gfwlist +ipset=/.twttr.com/gfwlist +ipset=/.twurl.nl/gfwlist +ipset=/.tw.voa.mobi/gfwlist +ipset=/.twyac.org/gfwlist +ipset=/.tw.yahoo.com/gfwlist +ipset=/.tycool.com/gfwlist +ipset=/.tynsoe.org/gfwlist +ipset=/.typepad.com/gfwlist +ipset=/.tzangms.com/gfwlist +ipset=/.ub0.cc/gfwlist +ipset=/.uberproxy.net/gfwlist +ipset=/.ucdc1998.org/gfwlist +ipset=/.uderzo.it/gfwlist +ipset=/.udn.com/gfwlist +ipset=/.ufreevpn.com/gfwlist +ipset=/.ugo.com/gfwlist +ipset=/.uhrp.org/gfwlist +ipset=/.uighurbiz.net/gfwlist +ipset=/.ukliferadio.co.uk/gfwlist +ipset=/.ulike.net/gfwlist +ipset=/.ultravpn.fr/gfwlist +ipset=/.ultraxs.com/gfwlist +ipset=/.unblock.cn.com/gfwlist +ipset=/.unblocksit.es/gfwlist +ipset=/.uncyclomedia.org/gfwlist +ipset=/.uncyclopedia.info/gfwlist +ipset=/.uncyclopedia.tw/gfwlist +ipset=/.unholyknight.com/gfwlist +ipset=/.uni.cc/gfwlist +ipset=/.unicode.org/gfwlist +ipset=/.uniteddaily.com.my/gfwlist +ipset=/.unix100.com/gfwlist +ipset=/.unknownspace.org/gfwlist +ipset=/.unpo.org/gfwlist +ipset=/.uocn.org/gfwlist +ipset=/.upcoming.yahoo.com/gfwlist +ipset=/.update.playstation.net/gfwlist +ipset=/.upload4u.info/gfwlist +ipset=/.upload.backchina.com/gfwlist +ipset=/.uploaded.to/gfwlist +ipset=/.uploadstation.com/gfwlist +ipset=/.upload.wikimedia.org/gfwlist +ipset=/.urlborg.com/gfwlist +ipset=/.urlparser.com/gfwlist +ipset=/.usacn.com/gfwlist +ipset=/.usfk.mil/gfwlist +ipset=/.usinfo.state.gov/gfwlist +ipset=/.usmc.mil/gfwlist +ipset=/.us.to/gfwlist +ipset=/.ustream.tv/gfwlist +ipset=/.usus.cc/gfwlist +ipset=/.uushare.com/gfwlist +ipset=/.uwants.com/gfwlist +ipset=/.uwants.net/gfwlist +ipset=/.uyghurcongress.org/gfwlist +ipset=/.uygur.org/gfwlist +ipset=/.v70.us/gfwlist +ipset=/.vaayoo.com/gfwlist +ipset=/.value-domain.com/gfwlist +ipset=/.van698.com/gfwlist +ipset=/.vanemu.cn/gfwlist +ipset=/.vanilla-jp.com/gfwlist +ipset=/.vansky.com/gfwlist +ipset=/.vapurl.com/gfwlist +ipset=/.vatn.org/gfwlist +ipset=/.vcfbuilder.org/gfwlist +ipset=/.vcf-online.org/gfwlist +ipset=/.veempiire.com/gfwlist +ipset=/.velkaepocha.sk/gfwlist +ipset=/.venbbs.com/gfwlist +ipset=/.venchina.com/gfwlist +ipset=/.ventureswell.com/gfwlist +ipset=/.veoh.com/gfwlist +ipset=/.verizon.net/gfwlist +ipset=/.verybs.com/gfwlist +ipset=/.vevo.com/gfwlist +ipset=/.vft.com.tw/gfwlist +ipset=/.vghks.gov.tw/gfwlist +ipset=/.vghtc.gov.tw/gfwlist +ipset=/.vghtpe.gov.tw/gfwlist +ipset=/.video.aol.ca/gfwlist +ipset=/.video.aol.com/gfwlist +ipset=/.video.aol.co.uk/gfwlist +ipset=/.video.ap.org/gfwlist +ipset=/.videobam.com/gfwlist +ipset=/.video.fdbox.com/gfwlist +ipset=/.video.foxbusiness.com/gfwlist +ipset=/.videomo.com/gfwlist +ipset=/.video.tiscali.it/gfwlist +ipset=/.video.yahoo.com/gfwlist +ipset=/.vidoemo.com/gfwlist +ipset=/.views.fm/gfwlist +ipset=/.viki.com/gfwlist +ipset=/.vimeocdn.com/gfwlist +ipset=/.vimeo.com/gfwlist +ipset=/.vimgolf.com/gfwlist +ipset=/.vimperator.org/gfwlist +ipset=/.vincnd.com/gfwlist +ipset=/.vinniev.com/gfwlist +ipset=/.vllcs.org/gfwlist +ipset=/.vlog.xuite.net/gfwlist +ipset=/.vmixcore.com/gfwlist +ipset=/.voacantonese.com/gfwlist +ipset=/.voachineseblog.com/gfwlist +ipset=/.voachinese.com/gfwlist +ipset=/.voagd.com/gfwlist +ipset=/.voanews.com/gfwlist +ipset=/.voatibetan.com/gfwlist +ipset=/.vocn.tv/gfwlist +ipset=/.vot.org/gfwlist +ipset=/.vpnbook.com/gfwlist +ipset=/.vpnfire.com/gfwlist +ipset=/.vpngate.jp/gfwlist +ipset=/.vpngate.net/gfwlist +ipset=/.vpnpop.com/gfwlist +ipset=/.vpnpronet.com/gfwlist +ipset=/.v-state.org/gfwlist +ipset=/.vtunnel.com/gfwlist +ipset=/.w3schools.com/gfwlist +ipset=/.waffle1999.com/gfwlist +ipset=/.wahas.com/gfwlist +ipset=/.waigaobu.com/gfwlist +ipset=/.waikeung.org/gfwlist +ipset=/.waiwaier.com/gfwlist +ipset=/.wallornot.org/gfwlist +ipset=/.wallpapercasa.com/gfwlist +ipset=/.wanderinghorse.net/gfwlist +ipset=/.wanfang.gov.tw/gfwlist +ipset=/.wangafu.net/gfwlist +ipset=/.wangjinbo.org/gfwlist +ipset=/.wanglixiong.com/gfwlist +ipset=/.wangruoshui.net/gfwlist +ipset=/.wangyi64.spaces.live.com/gfwlist +ipset=/.want-daily.com/gfwlist +ipset=/.wapedia.mobi/gfwlist +ipset=/.washeng.net/gfwlist +ipset=/.watchmygf.net/gfwlist +ipset=/.wattpad.com/gfwlist +ipset=/.wdf5.com/gfwlist +ipset=/.wearn.com/gfwlist +ipset=/.web2project.net/gfwlist +ipset=/.webbang.net/gfwlist +ipset=/.webfee.tk/gfwlist +ipset=/.weblagu.com/gfwlist +ipset=/.webmproject.org/gfwlist +ipset=/.webshots.com/gfwlist +ipset=/.websitepulse.com/gfwlist +ipset=/.webs-tv.net/gfwlist +ipset=/.webworkerdaily.com/gfwlist +ipset=/.weeewooo.net/gfwlist +ipset=/.weekmag.info/gfwlist +ipset=/.wefong.com/gfwlist +ipset=/.weiboleak.com/gfwlist +ipset=/.weigegebyc.dreamhosters.com/gfwlist +ipset=/.weijingsheng.org/gfwlist +ipset=/.weiming.info/gfwlist +ipset=/.weiquanwang.org/gfwlist +ipset=/.weisuo.ws/gfwlist +ipset=/.wellplacedpixels.com/gfwlist +ipset=/.wengewang.com/gfwlist +ipset=/.wengewang.org/gfwlist +ipset=/.wenhui.ch/gfwlist +ipset=/.wenku.com/gfwlist +ipset=/.wenxuecity.com/gfwlist +ipset=/.wenyunchao.com/gfwlist +ipset=/.wenyunchao.spaces.live.com/gfwlist +ipset=/.wepn.info/gfwlist +ipset=/.westca.com/gfwlist +ipset=/.westernwolves.com/gfwlist +ipset=/.wetplace.com/gfwlist +ipset=/.wetpussygames.com/gfwlist +ipset=/.wexiaobo.org/gfwlist +ipset=/.wezhiyong.org/gfwlist +ipset=/.wezone.net/gfwlist +ipset=/.wforum.com/gfwlist +ipset=/.whatblocked.com/gfwlist +ipset=/.whereiswerner.com/gfwlist +ipset=/.whippedass.com/gfwlist +ipset=/.whitebear.freebearblog.org/gfwlist +ipset=/.whydidyoubuymethat.com/gfwlist +ipset=/.whylover.com/gfwlist +ipset=/.whyx.org/gfwlist +ipset=/.w.idaiwan.com/gfwlist +ipset=/.wiki.cnitter.com/gfwlist +ipset=/.wiki.jqueryui.com/gfwlist +ipset=/.wiki.keso.cn/gfwlist +ipset=/.wikileaks.ch/gfwlist +ipset=/.wikileaks.de/gfwlist +ipset=/.wikileaks.eu/gfwlist +ipset=/.wikileaks.lu/gfwlist +ipset=/.wikileaks.org/gfwlist +ipset=/.wikileaks.pl/gfwlist +ipset=/.wikilivres.info/gfwlist +ipset=/.wikimapia.org/gfwlist +ipset=/.wikimedia.org.mo/gfwlist +ipset=/.wiki.moegirl.org/gfwlist +ipset=/.wikinet.org/gfwlist +ipset=/.wiki.oauth.net/gfwlist +ipset=/.wikipedia.org/gfwlist +ipset=/.wiki.phonegap.com/gfwlist +ipset=/.wikiwiki.jp/gfwlist +ipset=/.wikkii.com/gfwlist +ipset=/.williamlong.spaces.live.com/gfwlist +ipset=/.willw.net/gfwlist +ipset=/.windowsphoneme.com/gfwlist +ipset=/.winwhispers.info/gfwlist +ipset=/.wiredbytes.com/gfwlist +ipset=/.wiredpen.com/gfwlist +ipset=/.wireshark.org/gfwlist +ipset=/.wisevid.com/gfwlist +ipset=/.witnessleeteaching.com/gfwlist +ipset=/.witopia.net/gfwlist +ipset=/.wlx.sowiki.net/gfwlist +ipset=/.woeser.com/gfwlist +ipset=/.wolfax.com/gfwlist +ipset=/.womenbusiness.nyc.gov.tw/gfwlist +ipset=/.womensrightsofchina.org/gfwlist +ipset=/.woopie.jp/gfwlist +ipset=/.woopie.tv/gfwlist +ipset=/.wordboner.com/gfwlist +ipset=/.wordpress.com/gfwlist +ipset=/.wordsandturds.com/gfwlist +ipset=/.w.org/gfwlist +ipset=/.workatruna.com/gfwlist +ipset=/.worldcat.org/gfwlist +ipset=/.worldjournal.com/gfwlist +ipset=/.worstthingieverate.com/gfwlist +ipset=/.wo.tc/gfwlist +ipset=/.wowlegacy.ml/gfwlist +ipset=/.wow-life.net/gfwlist +ipset=/.woxinghuiguo.com/gfwlist +ipset=/.wozy.in/gfwlist +ipset=/.wp.com/gfwlist +ipset=/.wpoforum.com/gfwlist +ipset=/.wqlhw.com/gfwlist +ipset=/.wqyd.org/gfwlist +ipset=/.wrchina.org/gfwlist +ipset=/.wretch.cc/gfwlist +ipset=/.writer.zoho.com/gfwlist +ipset=/.wsj.com/gfwlist +ipset=/.wsj.net/gfwlist +ipset=/.wtfpeople.com/gfwlist +ipset=/.wuala.com/gfwlist +ipset=/.wuerkaixi.com/gfwlist +ipset=/.wufi.org.tw/gfwlist +ipset=/.wuguoguang.com/gfwlist +ipset=/.wujieliulan.com/gfwlist +ipset=/.wujie.net/gfwlist +ipset=/.wukangrui.net/gfwlist +ipset=/.wwitv.com/gfwlist +ipset=/.www.6v6dota.com/gfwlist +ipset=/.www.ajsands.com/gfwlist +ipset=/.www.antd.org/gfwlist +ipset=/.www.aolnews.com/gfwlist +ipset=/.www.bulbous.freeserve.co.uk/gfwlist +ipset=/.www.cmoinc.org/gfwlist +ipset=/.www.dfanning.com/gfwlist +ipset=/.www.dwheeler.com/gfwlist +ipset=/.www.eulam.com/gfwlist +ipset=/.www.exblog.jp/gfwlist +ipset=/.www.forum4hk.com/gfwlist +ipset=/.www.freetibet.org/gfwlist +ipset=/.www.getyouram.com/gfwlist +ipset=/.www.goldenmelody.com.tw/gfwlist +ipset=/.www.idlcoyote.com/gfwlist +ipset=/.www.immigration.gov.tw/gfwlist +ipset=/.www.klip.me/gfwlist +ipset=/.www.kodingen.com/gfwlist +ipset=/.www.linksalpha.com/gfwlist +ipset=/.www.loiclemeur.com/gfwlist +ipset=/.www.macrovpn.com/gfwlist +ipset=/.www.monlamit.org/gfwlist +ipset=/.www.moztw.org/gfwlist +ipset=/.www.mycould.com/gfwlist +ipset=/.www.ned.org/gfwlist +ipset=/.www.nownews.com/gfwlist +ipset=/.www.orchidbbs.com/gfwlist +ipset=/.www.owind.com/gfwlist +ipset=/.www.oxid.it/gfwlist +ipset=/.www.parkansky.com/gfwlist +ipset=/.www.powerpointninja.com/gfwlist +ipset=/.www.rnw.nl/gfwlist +ipset=/.www.somee.com/gfwlist +ipset=/.www.stackfile.com/gfwlist +ipset=/.www.supertweet.net/gfwlist +ipset=/.www.tiffanyarment.com/gfwlist +ipset=/.www.tripod.com/gfwlist +ipset=/.www.tv.com/gfwlist +ipset=/.www.twtrland.com/gfwlist +ipset=/.www.typepad.com/gfwlist +ipset=/.www.urbanoutfitters.com/gfwlist +ipset=/.www.vegorpedersen.com/gfwlist +ipset=/.www.voy.com/gfwlist +ipset=/.www.vpncup.com/gfwlist +ipset=/.www.wangruowang.org/gfwlist +ipset=/.www.wan-press.org/gfwlist +ipset=/.www.wet123.com/gfwlist +ipset=/.www.zaurus.org.uk/gfwlist +ipset=/.wzyboy.im/gfwlist +ipset=/.x1949x.com/gfwlist +ipset=/.x365x.com/gfwlist +ipset=/.xanga.com/gfwlist +ipset=/.x-art.com/gfwlist +ipset=/.xa.yimg.com/gfwlist +ipset=/.xbabe.com/gfwlist +ipset=/.xbookcn.com/gfwlist +ipset=/.xcafe.in/gfwlist +ipset=/.xcritic.com/gfwlist +ipset=/.xfm.pp.ru/gfwlist +ipset=/.xgmyd.com/gfwlist +ipset=/.xh4n.cn/gfwlist +ipset=/.xhamster.com/gfwlist +ipset=/.xiaochuncnjp.com/gfwlist +ipset=/.xiaohexie.com/gfwlist +ipset=/.xiaoma.org/gfwlist +ipset=/.xiezhua.com/gfwlist +ipset=/.xing.com/gfwlist +ipset=/.xinhuanet.org/gfwlist +ipset=/.xinmiao.com.hk/gfwlist +ipset=/.xinqimeng.over-blog.com/gfwlist +ipset=/.xinsheng.net/gfwlist +ipset=/.xinshijue.com/gfwlist +ipset=/.xinyubbs.net/gfwlist +ipset=/.xizang-zhiye.org/gfwlist +ipset=/.xjp.cc/gfwlist +ipset=/.xml-training-guide.com/gfwlist +ipset=/.xmovies.com/gfwlist +ipset=/.xmusic.fm/gfwlist +ipset=/.xnxx.com/gfwlist +ipset=/.xpdo.net/gfwlist +ipset=/.xpud.org/gfwlist +ipset=/.xskywalker.com/gfwlist +ipset=/.xtube.com/gfwlist +ipset=/.xuchao.net/gfwlist +ipset=/.xuchao.org/gfwlist +ipset=/.xuzhiyong.net/gfwlist +ipset=/.xuzhuoer.com/gfwlist +ipset=/.xvedios.com/gfwlist +ipset=/.xvideos.com/gfwlist +ipset=/.x-wall.org/gfwlist +ipset=/.xxbbx.com/gfwlist +ipset=/.x.xcity.jp/gfwlist +ipset=/.xxxx.com.au/gfwlist +ipset=/.xysblogs.org/gfwlist +ipset=/.xys.dxiong.com/gfwlist +ipset=/.xys.org/gfwlist +ipset=/.xyy69.com/gfwlist +ipset=/.xyy69.info/gfwlist +ipset=/.yahoo.cn/gfwlist +ipset=/.yahoo.com.hk/gfwlist +ipset=/.yam.com/gfwlist +ipset=/.yanghengjun.spaces.live.com/gfwlist +ipset=/.yasni.co.uk/gfwlist +ipset=/.yasukuni.or.jp/gfwlist +ipset=/.yatsen.gov.tw/gfwlist +ipset=/.ydy.com/gfwlist +ipset=/.yeelou.com/gfwlist +ipset=/.yeeyi.com/gfwlist +ipset=/.yegle.net/gfwlist +ipset=/.yezimary.spaces.live.com/gfwlist +ipset=/.yfrog.com/gfwlist +ipset=/.yhcw.net/gfwlist +ipset=/.yidio.com/gfwlist +ipset=/.yilubbs.com/gfwlist +ipset=/.yi.org/gfwlist +ipset=/.yipub.com/gfwlist +ipset=/.ym.backchina.com/gfwlist +ipset=/.yogichen.org/gfwlist +ipset=/.yong.hu/gfwlist +ipset=/.yorkbbs.ca/gfwlist +ipset=/.youdao.com/gfwlist +ipset=/.youjizz.com/gfwlist +ipset=/.youmaker.com/gfwlist +ipset=/.youpai.org/gfwlist +ipset=/.youporn.com/gfwlist +ipset=/.your-freedom.net/gfwlist +ipset=/.yousendit.com/gfwlist +ipset=/.youthbao.com/gfwlist +ipset=/.youthnetradio.org/gfwlist +ipset=/.youtu.be/gfwlist +ipset=/.youtubecn.com/gfwlist +ipset=/.youtube.com/gfwlist +ipset=/.youtube-nocookie.com/gfwlist +ipset=/.youversion.com/gfwlist +ipset=/.youxu.info/gfwlist +ipset=/.ytht.net/gfwlist +ipset=/.ytimg.com/gfwlist +ipset=/.yuanming.net/gfwlist +ipset=/.yuming.flnet.org/gfwlist +ipset=/.yunchao.net/gfwlist +ipset=/.yvesgeleyn.com/gfwlist +ipset=/.yvtc.gov.tw/gfwlist +ipset=/.yx51.net/gfwlist +ipset=/.yyii.org/gfwlist +ipset=/.yymaya.com/gfwlist +ipset=/.yzzk.com/gfwlist +ipset=/.zacebook.com/gfwlist +ipset=/.zannel.com/gfwlist +ipset=/.zaobao.com/gfwlist +ipset=/.zaobao.com.sg/gfwlist +ipset=/.zaozon.com/gfwlist +ipset=/.zarias.com/gfwlist +ipset=/.zattoo.com/gfwlist +ipset=/.zdnet.com.tw/gfwlist +ipset=/.zengjinyan.org/gfwlist +ipset=/.zengjinyan.spaces.live.com/gfwlist +ipset=/.zeutch.com/gfwlist +ipset=/.zgzcjj.net/gfwlist +ipset=/.zhanbin.net/gfwlist +ipset=/.zhao.jinhai.de/gfwlist +ipset=/.zhenghui.org/gfwlist +ipset=/.zhenlibu.info/gfwlist +ipset=/.zhinengluyou.com/gfwlist +ipset=/.zhllg.spaces.live.com/gfwlist +ipset=/.zh.m.wikipedia.org/gfwlist +ipset=/.zh.netlog.com/gfwlist +ipset=/.zhonggtuotese.net/gfwlist +ipset=/.zhongguotese.net/gfwlist +ipset=/.zhongmeng.org/gfwlist +ipset=/.zhongsou.com/gfwlist +ipset=/.zh.pokerstrategy.com/gfwlist +ipset=/.zhreader.com/gfwlist +ipset=/.zh-tw.justin.tv/gfwlist +ipset=/.zhuichaguoji.org/gfwlist +ipset=/.zh.uncyclopedia.wikia.com/gfwlist +ipset=/.zh.wikinews.org/gfwlist +ipset=/.zh.wikipedia.org/gfwlist +ipset=/.zh.wikisource.org/gfwlist +ipset=/.ziddu.com/gfwlist +ipset=/.zillionk.com/gfwlist +ipset=/.zinio.com/gfwlist +ipset=/.ziplib.com/gfwlist +ipset=/.zkaip.com/gfwlist +ipset=/.zmw.cn/gfwlist +ipset=/.zomobo.net/gfwlist +ipset=/.zonaeuropa.com/gfwlist +ipset=/.zootool.com/gfwlist +ipset=/.zoozle.net/gfwlist +ipset=/.zozotown.com/gfwlist +ipset=/.zshare.net/gfwlist +ipset=/.zsrhao.com/gfwlist +ipset=/.zuo.la/gfwlist +ipset=/.zuola.com/gfwlist +ipset=/.zvereff.com/gfwlist +ipset=/.zyzc9.com/gfwlist +ipset=/.zyzg.us/gfwlist +server=/.h12.io/127.0.0.1#5335 +server=/.starlark.net/127.0.0.1#5335 +server=/.golang.org/127.0.0.1#5335 +server=/.honnef.co/127.0.0.1#5335 +server=/.0rz.tw/127.0.0.1#5335 +server=/.0to255.com/127.0.0.1#5335 +server=/.10musume.com/127.0.0.1#5335 +server=/.123rf.com/127.0.0.1#5335 +server=/.12bet.com/127.0.0.1#5335 +server=/.12vpn.com/127.0.0.1#5335 +server=/.141hongkong.com/127.0.0.1#5335 +server=/.173ng.com/127.0.0.1#5335 +server=/.1984bbs.com/127.0.0.1#5335 +server=/.1984bbs.org/127.0.0.1#5335 +server=/.1-apple.com.tw/127.0.0.1#5335 +server=/.1bao.org/127.0.0.1#5335 +server=/.1eew.com/127.0.0.1#5335 +server=/.1pondo.tv/127.0.0.1#5335 +server=/.2000fun.com/127.0.0.1#5335 +server=/.2008xianzhang.info/127.0.0.1#5335 +server=/.21andy.com/127.0.0.1#5335 +server=/.247realmedia.com/127.0.0.1#5335 +server=/.24smile.org/127.0.0.1#5335 +server=/.2-hand.info/127.0.0.1#5335 +server=/.2mdn.net/127.0.0.1#5335 +server=/.2shared.com/127.0.0.1#5335 +server=/.301works.org/127.0.0.1#5335 +server=/.315lz.com/127.0.0.1#5335 +server=/.32red.com/127.0.0.1#5335 +server=/.365singles.com.ar/127.0.0.1#5335 +server=/.36rain.com/127.0.0.1#5335 +server=/.4bluestones.biz/127.0.0.1#5335 +server=/.4chan.org/127.0.0.1#5335 +server=/.4pppc.gov.tw/127.0.0.1#5335 +server=/.4shared.com/127.0.0.1#5335 +server=/.4sq.com/127.0.0.1#5335 +server=/.51.ca/127.0.0.1#5335 +server=/.5i01.com/127.0.0.1#5335 +server=/.5maodang.com/127.0.0.1#5335 +server=/.64tianwang.com/127.0.0.1#5335 +server=/.64wiki.com/127.0.0.1#5335 +server=/.666kb.com/127.0.0.1#5335 +server=/.6park.com/127.0.0.1#5335 +server=/.7capture.com/127.0.0.1#5335 +server=/.881903.com/127.0.0.1#5335 +server=/.888.com/127.0.0.1#5335 +server=/.89-64.org/127.0.0.1#5335 +server=/.9001700.com/127.0.0.1#5335 +server=/.91porn.com/127.0.0.1#5335 +server=/.921.gov.tw/127.0.0.1#5335 +server=/.92ccav.com/127.0.0.1#5335 +server=/.9bis.com/127.0.0.1#5335 +server=/.9bis.net/127.0.0.1#5335 +server=/.9city.me/127.0.0.1#5335 +server=/.a5.com.ru/127.0.0.1#5335 +server=/.abc.pp.ru/127.0.0.1#5335 +server=/.abitno.linpie.com/127.0.0.1#5335 +server=/.ablwang.com/127.0.0.1#5335 +server=/.aboluowang.com/127.0.0.1#5335 +server=/.aboutgfw.com/127.0.0.1#5335 +server=/.acgkj.com/127.0.0.1#5335 +server=/.ac.jiruan.net/127.0.0.1#5335 +server=/.ac.playstation.net/127.0.0.1#5335 +server=/.actimes.com.au/127.0.0.1#5335 +server=/.aculo.us/127.0.0.1#5335 +server=/.ad1.nownews.com/127.0.0.1#5335 +server=/.addictedtocoffee.de/127.0.0.1#5335 +server=/.ads.backchina.com/127.0.0.1#5335 +server=/.adultfriendfinder.com/127.0.0.1#5335 +server=/.adultkeep.net/127.0.0.1#5335 +server=/.advanscene.com/127.0.0.1#5335 +server=/.advertfan.com/127.0.0.1#5335 +server=/.aec.gov.tw/127.0.0.1#5335 +server=/.aenhancers.com/127.0.0.1#5335 +server=/.af.mil/127.0.0.1#5335 +server=/.aftygh.gov.tw/127.0.0.1#5335 +server=/.aide.gov.tw/127.0.0.1#5335 +server=/.aiph.net/127.0.0.1#5335 +server=/.aisex.com/127.0.0.1#5335 +server=/.ait.org.tw/127.0.0.1#5335 +server=/.aiweiweiblog.com/127.0.0.1#5335 +server=/.aiweiwei.com/127.0.0.1#5335 +server=/.ajaxplorer.info/127.0.0.1#5335 +server=/.akamaihd.net/127.0.0.1#5335 +server=/.akiba-online.com/127.0.0.1#5335 +server=/.alabout.com/127.0.0.1#5335 +server=/.alasbarricadas.org/127.0.0.1#5335 +server=/.alexlur.org/127.0.0.1#5335 +server=/.aliengu.com/127.0.0.1#5335 +server=/.alkasir.com/127.0.0.1#5335 +server=/.allaboutalpha.com/127.0.0.1#5335 +server=/.allgirlsallowed.org/127.0.0.1#5335 +server=/.alliance.org.hk/127.0.0.1#5335 +server=/.allinfa.com/127.0.0.1#5335 +server=/.allinfo.com/127.0.0.1#5335 +server=/.allmovie.com/127.0.0.1#5335 +server=/.allonlinux.free.fr/127.0.0.1#5335 +server=/.all-that-is-interesting.com/127.0.0.1#5335 +server=/.al-qimmah.net/127.0.0.1#5335 +server=/.alternate-tools.com/127.0.0.1#5335 +server=/.altrec.com/127.0.0.1#5335 +server=/.alvinalexander.com/127.0.0.1#5335 +server=/.alwaysdata.com/127.0.0.1#5335 +server=/.alwaysdata.net/127.0.0.1#5335 +server=/.am730.com.hk/127.0.0.1#5335 +server=/.amazonaws.com/127.0.0.1#5335 +server=/.ameblo.jp/127.0.0.1#5335 +server=/.americangreencard.com/127.0.0.1#5335 +server=/.amiblockedornot.com/127.0.0.1#5335 +server=/.amnesty.org/127.0.0.1#5335 +server=/.amnestyusa.org/127.0.0.1#5335 +server=/.amoiist.com/127.0.0.1#5335 +server=/.amzs.me/127.0.0.1#5335 +server=/.analyze-v.com/127.0.0.1#5335 +server=/.anchorfree.com/127.0.0.1#5335 +server=/.andfaraway.net/127.0.0.1#5335 +server=/.android.com/127.0.0.1#5335 +server=/.angularjs.org/127.0.0.1#5335 +server=/.animecrazy.net/127.0.0.1#5335 +server=/.anobii.com/127.0.0.1#5335 +server=/.anontext.com/127.0.0.1#5335 +server=/.anonymizer.com/127.0.0.1#5335 +server=/.a-normal-day.com/127.0.0.1#5335 +server=/.answering-islam.org/127.0.0.1#5335 +server=/.anthonycalzadilla.com/127.0.0.1#5335 +server=/.anti.anti.cnn.googlepages.com/127.0.0.1#5335 +server=/.antidrm.hpg.ig.com.br/127.0.0.1#5335 +server=/.antiwave.net/127.0.0.1#5335 +server=/.aobo.com.au/127.0.0.1#5335 +server=/.aolchannels.aol.com/127.0.0.1#5335 +server=/.aomiwang.com/127.0.0.1#5335 +server=/.apetube.com/127.0.0.1#5335 +server=/.apiary.io/127.0.0.1#5335 +server=/.apidocs.linksalpha.com/127.0.0.1#5335 +server=/.apigee.com/127.0.0.1#5335 +server=/.api.linksalpha.com/127.0.0.1#5335 +server=/.api.proxlet.com/127.0.0.1#5335 +server=/.api.supertweet.net/127.0.0.1#5335 +server=/.app.heywire.com/127.0.0.1#5335 +server=/.app.hkatvnews.com/127.0.0.1#5335 +server=/.appledaily.com/127.0.0.1#5335 +server=/.appledaily.com.tw/127.0.0.1#5335 +server=/.apps.hloli.net/127.0.0.1#5335 +server=/.appspot.com/127.0.0.1#5335 +server=/.archive.is/127.0.0.1#5335 +server=/.archive.org/127.0.0.1#5335 +server=/.arctosia.com/127.0.0.1#5335 +server=/.areca-backup.org/127.0.0.1#5335 +server=/.army.mil/127.0.0.1#5335 +server=/.arte.gov.tw/127.0.0.1#5335 +server=/.art-or-porn.com/127.0.0.1#5335 +server=/.artsy.net/127.0.0.1#5335 +server=/.asahichinese.com/127.0.0.1#5335 +server=/.asdfg.jp/127.0.0.1#5335 +server=/.asiafriendfinder.com/127.0.0.1#5335 +server=/.asiaharvest.org/127.0.0.1#5335 +server=/.asianews.it/127.0.0.1#5335 +server=/.asianwomensfilm.de/127.0.0.1#5335 +server=/.askstudent.com/127.0.0.1#5335 +server=/.askynz.net/127.0.0.1#5335 +server=/.assembla.com/127.0.0.1#5335 +server=/.astonmartinnews.com/127.0.0.1#5335 +server=/.atchinese.com/127.0.0.1#5335 +server=/.atc.org.au/127.0.0.1#5335 +server=/.atgfw.org/127.0.0.1#5335 +server=/.atj.org.tw/127.0.0.1#5335 +server=/.atlaspost.com/127.0.0.1#5335 +server=/.atnext.com/127.0.0.1#5335 +server=/.autoproxy.org/127.0.0.1#5335 +server=/.avaaz.org/127.0.0.1#5335 +server=/.avdb.in/127.0.0.1#5335 +server=/.avidemux.org/127.0.0.1#5335 +server=/.avoision.com/127.0.0.1#5335 +server=/.awardwinningfjords.com/127.0.0.1#5335 +server=/.axureformac.com/127.0.0.1#5335 +server=/.babynet.com.hk/127.0.0.1#5335 +server=/.backchina.com/127.0.0.1#5335 +server=/.backpackers.com.tw/127.0.0.1#5335 +server=/.badassjs.com/127.0.0.1#5335 +server=/.badoo.com/127.0.0.1#5335 +server=/.baidu.jp/127.0.0.1#5335 +server=/.baixing.me/127.0.0.1#5335 +server=/.bannedbook.org/127.0.0.1#5335 +server=/.barnabu.co.uk/127.0.0.1#5335 +server=/.basetimesheightdividedby2.com/127.0.0.1#5335 +server=/.bayvoice.net/127.0.0.1#5335 +server=/.bbcchinese.com/127.0.0.1#5335 +server=/.bbc.com/127.0.0.1#5335 +server=/.bbc.co.uk/127.0.0.1#5335 +server=/.bbci.co.uk/127.0.0.1#5335 +server=/.bbcimg.co.uk/127.0.0.1#5335 +server=/.bbc.in/127.0.0.1#5335 +server=/.bbg.gov/127.0.0.1#5335 +server=/.bbs2.newsgroup.la/127.0.0.1#5335 +server=/.bbs.ecstart.com/127.0.0.1#5335 +server=/.bbsfeed.com/127.0.0.1#5335 +server=/.bbs.kimy.com.tw/127.0.0.1#5335 +server=/.bbsland.com/127.0.0.1#5335 +server=/.bbs.morbell.com/127.0.0.1#5335 +server=/.bbs.mychat.to/127.0.0.1#5335 +server=/.bbs.newsgroup.la/127.0.0.1#5335 +server=/.bbs.ozchinese.com/127.0.0.1#5335 +server=/.bbs.qmzdd.com/127.0.0.1#5335 +server=/.bbs.sina.com/127.0.0.1#5335 +server=/.bbs.skykiwi.com/127.0.0.1#5335 +server=/.bbs.tuitui.info/127.0.0.1#5335 +server=/.bb.ttv.com.tw/127.0.0.1#5335 +server=/.bcc.com.tw/127.0.0.1#5335 +server=/.bcchinese.net/127.0.0.1#5335 +server=/.bdhr.gov.tw/127.0.0.1#5335 +server=/.bd.zhe.la/127.0.0.1#5335 +server=/.bebo.com/127.0.0.1#5335 +server=/.beeg.com/127.0.0.1#5335 +server=/.beijing1989.com/127.0.0.1#5335 +server=/.beijingspring.com/127.0.0.1#5335 +server=/.benjaminste.in/127.0.0.1#5335 +server=/.berlintwitterwall.com/127.0.0.1#5335 +server=/.bestforchina.org/127.0.0.1#5335 +server=/.bestvpnservice.com/127.0.0.1#5335 +server=/.bet365.com/127.0.0.1#5335 +server=/.beta.iset.com.tw/127.0.0.1#5335 +server=/.beta.usejump.com/127.0.0.1#5335 +server=/.betfair.com/127.0.0.1#5335 +server=/.bettween.com/127.0.0.1#5335 +server=/.betvictor.com/127.0.0.1#5335 +server=/.bewww.net/127.0.0.1#5335 +server=/.beyondfirewall.com/127.0.0.1#5335 +server=/.bfnn.org/127.0.0.1#5335 +server=/.biantailajiao.com/127.0.0.1#5335 +server=/.biantailajiao.in/127.0.0.1#5335 +server=/.bigfools.com/127.0.0.1#5335 +server=/.bignews.org/127.0.0.1#5335 +server=/.bigsound.org/127.0.0.1#5335 +server=/.bill2-software.com/127.0.0.1#5335 +server=/.billywr.com/127.0.0.1#5335 +server=/.bill.zhong.pp.ru/127.0.0.1#5335 +server=/.bipic.net/127.0.0.1#5335 +server=/.bitcointalk.org/127.0.0.1#5335 +server=/.bit.ly/127.0.0.1#5335 +server=/.bitly.com/127.0.0.1#5335 +server=/.bitshare.com/127.0.0.1#5335 +server=/.bjzc.org/127.0.0.1#5335 +server=/.blinkx.com/127.0.0.1#5335 +server=/.blinw.com/127.0.0.1#5335 +server=/.blip.tv/127.0.0.1#5335 +server=/.blockcn.com/127.0.0.1#5335 +server=/.blog.birdhouseapp.com/127.0.0.1#5335 +server=/.blog.bitly.com/127.0.0.1#5335 +server=/.blogblog.com/127.0.0.1#5335 +server=/.blog.boxcar.io/127.0.0.1#5335 +server=/.blogcatalog.com/127.0.0.1#5335 +server=/.blog.davidziegler.net/127.0.0.1#5335 +server=/.blog.dayoneapp.com/127.0.0.1#5335 +server=/.blog.de/127.0.0.1#5335 +server=/.blog.dribbble.com/127.0.0.1#5335 +server=/.blog.exblog.co.jp/127.0.0.1#5335 +server=/.blog.expofutures.com/127.0.0.1#5335 +server=/.blog.fizzik.com/127.0.0.1#5335 +server=/.blog.foolsmountain.com/127.0.0.1#5335 +server=/.blogger.com/127.0.0.1#5335 +server=/.blog.gowalla.com/127.0.0.1#5335 +server=/.blog.hotpotato.com/127.0.0.1#5335 +server=/.blog.ifttt.com/127.0.0.1#5335 +server=/.blogimg.jp/127.0.0.1#5335 +server=/.blog.instagram.com/127.0.0.1#5335 +server=/.blog.instapaper.com/127.0.0.1#5335 +server=/.blog.iphone-dev.org/127.0.0.1#5335 +server=/.blog.istef.info/127.0.0.1#5335 +server=/.blog.jackjia.com/127.0.0.1#5335 +server=/.blog.joeyrobert.org/127.0.0.1#5335 +server=/.blog.kangye.org/127.0.0.1#5335 +server=/.blog.kickstarter.com/127.0.0.1#5335 +server=/.blog.kl.am/127.0.0.1#5335 +server=/.blog.klip.me/127.0.0.1#5335 +server=/.blog.lester850.info/127.0.0.1#5335 +server=/.blog.lightbox.com/127.0.0.1#5335 +server=/.bloglines.com/127.0.0.1#5335 +server=/.bloglovin.com/127.0.0.1#5335 +server=/.blog.mongodb.org/127.0.0.1#5335 +server=/.blog.openinkpot.org/127.0.0.1#5335 +server=/.blog.palm.com/127.0.0.1#5335 +server=/.blog.path.com/127.0.0.1#5335 +server=/.blog.pathtosharepoint.com/127.0.0.1#5335 +server=/.blog.pchome.com.tw/127.0.0.1#5335 +server=/.blog.pentalogic.net/127.0.0.1#5335 +server=/.blog.pikchur.com/127.0.0.1#5335 +server=/.blog.pilotmoon.com/127.0.0.1#5335 +server=/.blog.redren.com/127.0.0.1#5335 +server=/.blog.rockmelt.com/127.0.0.1#5335 +server=/.blog.romanandreg.com/127.0.0.1#5335 +server=/.blog.s135.com/127.0.0.1#5335 +server=/.blogs.icerocket.com/127.0.0.1#5335 +server=/.blog.sina.com.tw/127.0.0.1#5335 +server=/.blog.sogoo.org/127.0.0.1#5335 +server=/.blog.sparrowmailapp.com/127.0.0.1#5335 +server=/.blogspot.com/127.0.0.1#5335 +server=/.blogspot.co.uk/127.0.0.1#5335 +server=/.blogspot.de/127.0.0.1#5335 +server=/.blogspot.fr/127.0.0.1#5335 +server=/.blogspot.in/127.0.0.1#5335 +server=/.blogspot.jp/127.0.0.1#5335 +server=/.blogs.tampabay.com/127.0.0.1#5335 +server=/.blog.summify.com/127.0.0.1#5335 +server=/.blogs.yahoo.co.jp/127.0.0.1#5335 +server=/.blog.syx86.cn/127.0.0.1#5335 +server=/.blog.syx86.com/127.0.0.1#5335 +server=/.blog.taragana.com/127.0.0.1#5335 +server=/.blogtd.net/127.0.0.1#5335 +server=/.blogtd.org/127.0.0.1#5335 +server=/.blog.tiney.com/127.0.0.1#5335 +server=/.blog.topify.com/127.0.0.1#5335 +server=/.blog.usa.gov/127.0.0.1#5335 +server=/.blog.xuite.net/127.0.0.1#5335 +server=/.blog.youthwant.com.tw/127.0.0.1#5335 +server=/.blog.youxu.info/127.0.0.1#5335 +server=/.bloodshed.net/127.0.0.1#5335 +server=/.bloomberg.cn/127.0.0.1#5335 +server=/.bloomberg.com/127.0.0.1#5335 +server=/.bloomberg.de/127.0.0.1#5335 +server=/.bloomfortune.com/127.0.0.1#5335 +server=/.bmediaasia.com/127.0.0.1#5335 +server=/.bnrmetal.com/127.0.0.1#5335 +server=/.boardreader.com/127.0.0.1#5335 +server=/.bobulate.com/127.0.0.1#5335 +server=/.bolin.netfirms.com/127.0.0.1#5335 +server=/.bonbonme.com/127.0.0.1#5335 +server=/.bonjourlesgeeks.com/127.0.0.1#5335 +server=/.boobstagram.com/127.0.0.1#5335 +server=/.books.com.tw/127.0.0.1#5335 +server=/.bookshelfporn.com/127.0.0.1#5335 +server=/.botanwang.com/127.0.0.1#5335 +server=/.bot.nu/127.0.0.1#5335 +server=/.bowenpress.com/127.0.0.1#5335 +server=/.boxunblog.com/127.0.0.1#5335 +server=/.boxunclub.com/127.0.0.1#5335 +server=/.boxun.com/127.0.0.1#5335 +server=/.boxun.tv/127.0.0.1#5335 +server=/.bralio.com/127.0.0.1#5335 +server=/.branch.com/127.0.0.1#5335 +server=/.brandonhutchinson.com/127.0.0.1#5335 +server=/.braumeister.org/127.0.0.1#5335 +server=/.break.com/127.0.0.1#5335 +server=/.breakingtweets.com/127.0.0.1#5335 +server=/.briefdream.com/127.0.0.1#5335 +server=/.brightcove.com/127.0.0.1#5335 +server=/.brightkite.com/127.0.0.1#5335 +server=/.brizzly.com/127.0.0.1#5335 +server=/.broadbook.com/127.0.0.1#5335 +server=/.br.st/127.0.0.1#5335 +server=/.brucewang.net/127.0.0.1#5335 +server=/.bt95.com/127.0.0.1#5335 +server=/.btdigg.org/127.0.0.1#5335 +server=/.btrd.net/127.0.0.1#5335 +server=/.budaedu.org/127.0.0.1#5335 +server=/.bugclub.org/127.0.0.1#5335 +server=/.builtwithbootstrap.com/127.0.0.1#5335 +server=/.bullogger.com/127.0.0.1#5335 +server=/.bullog.org/127.0.0.1#5335 +server=/.businesstimes.com.cn/127.0.0.1#5335 +server=/.businessweek.com/127.0.0.1#5335 +server=/.buugaa.com/127.0.0.1#5335 +server=/.buy.yahoo.com.tw/127.0.0.1#5335 +server=/.buzzurl.jp/127.0.0.1#5335 +server=/.bwbx.io/127.0.0.1#5335 +server=/.bwsj.hk/127.0.0.1#5335 +server=/.bx.tl/127.0.0.1#5335 +server=/.c1522.mooo.com/127.0.0.1#5335 +server=/.cacnw.com/127.0.0.1#5335 +server=/.cactusvpn.com/127.0.0.1#5335 +server=/.cafepress.com/127.0.0.1#5335 +server=/.cahr.org.tw/127.0.0.1#5335 +server=/.calameo.com/127.0.0.1#5335 +server=/.calebelston.com/127.0.0.1#5335 +server=/.cams.com/127.0.0.1#5335 +server=/.cams.org.sg/127.0.0.1#5335 +server=/.canadameet.com/127.0.0.1#5335 +server=/.canyu.org/127.0.0.1#5335 +server=/.caobian.info/127.0.0.1#5335 +server=/.caochangqing.com/127.0.0.1#5335 +server=/.cao.im/127.0.0.1#5335 +server=/.cari.com.my/127.0.0.1#5335 +server=/.catch22.net/127.0.0.1#5335 +server=/.catfightpayperview.xxx/127.0.0.1#5335 +server=/.catholic.org.hk/127.0.0.1#5335 +server=/.catholic.org.tw/127.0.0.1#5335 +server=/.cbs.ntu.edu.tw/127.0.0.1#5335 +server=/.cc9007.spaces.live.com/127.0.0.1#5335 +server=/.ccavtop10.com/127.0.0.1#5335 +server=/.ccdtr.org/127.0.0.1#5335 +server=/.ccim.org/127.0.0.1#5335 +server=/.cclife.org/127.0.0.1#5335 +server=/.ccthere.com/127.0.0.1#5335 +server=/.cctongbao.com/127.0.0.1#5335 +server=/.ccue.ca/127.0.0.1#5335 +server=/.ccue.com/127.0.0.1#5335 +server=/.cdig.info/127.0.0.1#5335 +server=/.cdjp.org/127.0.0.1#5335 +server=/.cdnews.com.tw/127.0.0.1#5335 +server=/.cdn.printfriendly.com/127.0.0.1#5335 +server=/.cdp1998.org/127.0.0.1#5335 +server=/.cdp2006.org/127.0.0.1#5335 +server=/.cdp.sinica.edu.tw/127.0.0.1#5335 +server=/.cdpusa.org/127.0.0.1#5335 +server=/.cdpweb.org/127.0.0.1#5335 +server=/.cdpwu.org/127.0.0.1#5335 +server=/.cdw.com/127.0.0.1#5335 +server=/.cecc.gov/127.0.0.1#5335 +server=/.cellulo.info/127.0.0.1#5335 +server=/.cenci.tk/127.0.0.1#5335 +server=/.cenews.eu/127.0.0.1#5335 +server=/.centralnation.com/127.0.0.1#5335 +server=/.centurys.net/127.0.0.1#5335 +server=/.c-est-simple.com/127.0.0.1#5335 +server=/.cfhks.org.hk/127.0.0.1#5335 +server=/.cftfc.com/127.0.0.1#5335 +server=/.cgdepot.org/127.0.0.1#5335 +server=/.chandoo.org/127.0.0.1#5335 +server=/.change.org/127.0.0.1#5335 +server=/.changp.com/127.0.0.1#5335 +server=/.chaos.e-spacy.com/127.0.0.1#5335 +server=/.chapm25.com/127.0.0.1#5335 +server=/.chartbeat.net/127.0.0.1#5335 +server=/.chaturbate.com/127.0.0.1#5335 +server=/.chccc.gov.tw/127.0.0.1#5335 +server=/.chengmingmag.com/127.0.0.1#5335 +server=/.chenguangcheng.com/127.0.0.1#5335 +server=/.chenpokong.com/127.0.0.1#5335 +server=/.chenyehao.spaces.live.com/127.0.0.1#5335 +server=/.cherrysave.com/127.0.0.1#5335 +server=/.chevronwp7.com/127.0.0.1#5335 +server=/.chicagoncmtv.com/127.0.0.1#5335 +server=/.china101.com/127.0.0.1#5335 +server=/.china21.com/127.0.0.1#5335 +server=/.china21.org/127.0.0.1#5335 +server=/.china5000.us/127.0.0.1#5335 +server=/.chinaaffairs.org/127.0.0.1#5335 +server=/.chinaaid.me/127.0.0.1#5335 +server=/.chinaaid.net/127.0.0.1#5335 +server=/.chinaaid.org/127.0.0.1#5335 +server=/.chinaaid.us/127.0.0.1#5335 +server=/.chinachange.org/127.0.0.1#5335 +server=/.chinachannel.hk/127.0.0.1#5335 +server=/.chinacomments.org/127.0.0.1#5335 +server=/.chinadigitaltimes.net/127.0.0.1#5335 +server=/.chinaeweekly.com/127.0.0.1#5335 +server=/.chinafreepress.org/127.0.0.1#5335 +server=/.chinagate.com/127.0.0.1#5335 +server=/.chinageeks.org/127.0.0.1#5335 +server=/.chinagfw.org/127.0.0.1#5335 +server=/.chinagreenparty.org/127.0.0.1#5335 +server=/.china-green-party.spaces.live.com/127.0.0.1#5335 +server=/.chinahush.com/127.0.0.1#5335 +server=/.chinainperspective.com/127.0.0.1#5335 +server=/.chinainperspective.net/127.0.0.1#5335 +server=/.chinainperspective.org/127.0.0.1#5335 +server=/.chinainterimgov.org/127.0.0.1#5335 +server=/.chinalawandpolicy.com/127.0.0.1#5335 +server=/.chinalawtranslate.com/127.0.0.1#5335 +server=/.chinamule.com/127.0.0.1#5335 +server=/.chinamz.org/127.0.0.1#5335 +server=/.chinarightsia.org/127.0.0.1#5335 +server=/.chinasocialdemocraticparty.com/127.0.0.1#5335 +server=/.chinasoul.org/127.0.0.1#5335 +server=/.chinatimes.com/127.0.0.1#5335 +server=/.chinatweeps.com/127.0.0.1#5335 +server=/.chinaway.org/127.0.0.1#5335 +server=/.china-week.com/127.0.0.1#5335 +server=/.chinaworker.info/127.0.0.1#5335 +server=/.chinaxchina.com/127.0.0.1#5335 +server=/.chinayouth.org.hk/127.0.0.1#5335 +server=/.chinayuanmin.org/127.0.0.1#5335 +server=/.chinesedailynews.com/127.0.0.1#5335 +server=/.chinese.engadget.com/127.0.0.1#5335 +server=/.chinese-hermit.net/127.0.0.1#5335 +server=/.chinese-memorial.org/127.0.0.1#5335 +server=/.chinesen.de/127.0.0.1#5335 +server=/.chinesenewsnet.com/127.0.0.1#5335 +server=/.chinesepen.org/127.0.0.1#5335 +server=/.chinese.rnw.nl/127.0.0.1#5335 +server=/.chinese.soifind.com/127.0.0.1#5335 +server=/.chinesetalks.net/127.0.0.1#5335 +server=/.chinese.wsj.com/127.0.0.1#5335 +server=/.chingcheong.com/127.0.0.1#5335 +server=/.chn.chosun.com/127.0.0.1#5335 +server=/.chrispederick.com/127.0.0.1#5335 +server=/.chrispederick.net/127.0.0.1#5335 +server=/.christianstudy.com/127.0.0.1#5335 +server=/.christiantimes.org.hk/127.0.0.1#5335 +server=/.christusrex.org/127.0.0.1#5335 +server=/.chrlawyers.hk/127.0.0.1#5335 +server=/.chrlcg-hk.org/127.0.0.1#5335 +server=/.chromeadblock.com/127.0.0.1#5335 +server=/.chrome.com/127.0.0.1#5335 +server=/.ch.shvoong.com/127.0.0.1#5335 +server=/.chubun.com/127.0.0.1#5335 +server=/.chuizi.net/127.0.0.1#5335 +server=/.chukuang.gov.tw/127.0.0.1#5335 +server=/.circlethebayfortibet.org/127.0.0.1#5335 +server=/.citizenlab.org/127.0.0.1#5335 +server=/.citizensradio.org/127.0.0.1#5335 +server=/.city9x.com/127.0.0.1#5335 +server=/.civicparty.hk/127.0.0.1#5335 +server=/.civilhrfront.org/127.0.0.1#5335 +server=/.civilmedia.tw/127.0.0.1#5335 +server=/.cjb.net/127.0.0.1#5335 +server=/.ck101.com/127.0.0.1#5335 +server=/.classicalguitarblog.net/127.0.0.1#5335 +server=/.clb.org.hk/127.0.0.1#5335 +server=/.cl.d0z.net/127.0.0.1#5335 +server=/.clientsfromhell.net/127.0.0.1#5335 +server=/.clipfish.de/127.0.0.1#5335 +server=/.cl.ly/127.0.0.1#5335 +server=/.cloudfront.net/127.0.0.1#5335 +server=/.club.backchina.com/127.0.0.1#5335 +server=/.cms.gov/127.0.0.1#5335 +server=/.cmule.com/127.0.0.1#5335 +server=/.cn2.streetvoice.com/127.0.0.1#5335 +server=/.cna.com.tw/127.0.0.1#5335 +server=/.cnavista.com.tw/127.0.0.1#5335 +server=/.cn.calameo.com/127.0.0.1#5335 +server=/.cn.dayabook.com/127.0.0.1#5335 +server=/.cnd.org/127.0.0.1#5335 +server=/.cn.fmnnow.com/127.0.0.1#5335 +server=/.cn.ibtimes.com/127.0.0.1#5335 +server=/.cnn.com/127.0.0.1#5335 +server=/.cn.news.cnyes.com/127.0.0.1#5335 +server=/.cn.streetvoice.com/127.0.0.1#5335 +server=/.cn.uncyclopedia.wikia.com/127.0.0.1#5335 +server=/.cn.voa.mobi/127.0.0.1#5335 +server=/.cochina.org/127.0.0.1#5335 +server=/.cocoapods.org/127.0.0.1#5335 +server=/.cocoa.zonble.net/127.0.0.1#5335 +server=/.code1984.com/127.0.0.1#5335 +server=/.codeboxapp.com/127.0.0.1#5335 +server=/.codeshare.io/127.0.0.1#5335 +server=/.collateralmurder.com/127.0.0.1#5335 +server=/.collateralmurder.org/127.0.0.1#5335 +server=/.comefromchina.com/127.0.0.1#5335 +server=/.comnews.gio.gov.tw/127.0.0.1#5335 +server=/.compileheart.com/127.0.0.1#5335 +server=/.connectedchina.reuters.com/127.0.0.1#5335 +server=/.connect.facebook.net/127.0.0.1#5335 +server=/.conoyo.com/127.0.0.1#5335 +server=/.contactmagazine.net/127.0.0.1#5335 +server=/.contests.twilio.com/127.0.0.1#5335 +server=/.conviva.com/127.0.0.1#5335 +server=/.cookingtothegoodlife.com/127.0.0.1#5335 +server=/.coolaler.com/127.0.0.1#5335 +server=/.coolder.com/127.0.0.1#5335 +server=/.coolloud.org.tw/127.0.0.1#5335 +server=/.corpus4u.org/127.0.0.1#5335 +server=/.corumcollege.com/127.0.0.1#5335 +server=/.cotweet.com/127.0.0.1#5335 +server=/.couchdbwiki.com/127.0.0.1#5335 +server=/.coveringweb.com/127.0.0.1#5335 +server=/.cp-house.gov.tw/127.0.0.1#5335 +server=/.cpj.org/127.0.0.1#5335 +server=/.crackle.com/127.0.0.1#5335 +server=/.crd-net.org/127.0.0.1#5335 +server=/.creaders.net/127.0.0.1#5335 +server=/.cromotc.nat.gov.tw/127.0.0.1#5335 +server=/.crossthewall.net/127.0.0.1#5335 +server=/.csdparty.com/127.0.0.1#5335 +server=/.c-spanvideo.org/127.0.0.1#5335 +server=/.css.pixnet.in/127.0.0.1#5335 +server=/.csuchen.de/127.0.0.1#5335 +server=/.cts.com.tw/127.0.0.1#5335 +server=/.cubicle17.com/127.0.0.1#5335 +server=/.cuhkacs.org/127.0.0.1#5335 +server=/.cuihua.org/127.0.0.1#5335 +server=/.cuiweiping.net/127.0.0.1#5335 +server=/.culture.tw/127.0.0.1#5335 +server=/.curvefish.com/127.0.0.1#5335 +server=/.cwb.gov.tw/127.0.0.1#5335 +server=/.cyanogenmod.org/127.0.0.1#5335 +server=/.cyberghost.natado.com/127.0.0.1#5335 +server=/.cyberghostvpn.com/127.0.0.1#5335 +server=/.cycab.gov.tw/127.0.0.1#5335 +server=/.cydia.ifuckgfw.com/127.0.0.1#5335 +server=/.cynscribe.com/127.0.0.1#5335 +server=/.cytode.us/127.0.0.1#5335 +server=/.dabr.co.uk/127.0.0.1#5335 +server=/.dabr.me/127.0.0.1#5335 +server=/.dabr.mobi/127.0.0.1#5335 +server=/.dadazim.com/127.0.0.1#5335 +server=/.dadi360.com/127.0.0.1#5335 +server=/.dafagood.com/127.0.0.1#5335 +server=/.dafahao.com/127.0.0.1#5335 +server=/.dailidaili.com/127.0.0.1#5335 +server=/.dailymotion.com/127.0.0.1#5335 +server=/.dailynews.sina.com/127.0.0.1#5335 +server=/.dajiyuan.com/127.0.0.1#5335 +server=/.dajiyuan.eu/127.0.0.1#5335 +server=/.dajusha.baywords.com/127.0.0.1#5335 +server=/.dalailama.com/127.0.0.1#5335 +server=/.dalailama.ru/127.0.0.1#5335 +server=/.dalailamaworld.com/127.0.0.1#5335 +server=/.dalianmeng.org/127.0.0.1#5335 +server=/.danke4china.net/127.0.0.1#5335 +server=/.danwei.org/127.0.0.1#5335 +server=/.daolan.net/127.0.0.1#5335 +server=/.dapu-house.gov.tw/127.0.0.1#5335 +server=/.darpa.mil/127.0.0.1#5335 +server=/.date.fm/127.0.0.1#5335 +server=/.davidslog.com/127.0.0.1#5335 +server=/.daxa.cn/127.0.0.1#5335 +server=/.dayaarmongol.ning.com/127.0.0.1#5335 +server=/.daylife.com/127.0.0.1#5335 +server=/.ddc.com.tw/127.0.0.1#5335 +server=/.deck.ly/127.0.0.1#5335 +server=/.default.secureserver.net/127.0.0.1#5335 +server=/.delcamp.net/127.0.0.1#5335 +server=/.delicious.com/127.0.0.1#5335 +server=/.democrats.org/127.0.0.1#5335 +server=/.demo.opera-mini.net/127.0.0.1#5335 +server=/.derekhsu.homeip.net/127.0.0.1#5335 +server=/.de-sci.org/127.0.0.1#5335 +server=/.designerol.com/127.0.0.1#5335 +server=/.destiny.xfiles.to/127.0.0.1#5335 +server=/.deutsche-welle.de/127.0.0.1#5335 +server=/.dev102.com/127.0.0.1#5335 +server=/.developers.box.net/127.0.0.1#5335 +server=/.deviantart.com/127.0.0.1#5335 +server=/.deviantart.net/127.0.0.1#5335 +server=/.devio.us/127.0.0.1#5335 +server=/.devpn.com/127.0.0.1#5335 +server=/.dfas.mil/127.0.0.1#5335 +server=/.df.gov.tw/127.0.0.1#5335 +server=/.diaoyuislands.org/127.0.0.1#5335 +server=/.digitalnomadsproject.org/127.0.0.1#5335 +server=/.diigo.com/127.0.0.1#5335 +server=/.dimitrik.free.fr/127.0.0.1#5335 +server=/.dipity.com/127.0.0.1#5335 +server=/.directcreative.com/127.0.0.1#5335 +server=/.discuss.com.hk/127.0.0.1#5335 +server=/.disp.cc/127.0.0.1#5335 +server=/.dit-inc.us/127.0.0.1#5335 +server=/.dizhidizhi.com/127.0.0.1#5335 +server=/.djangosnippets.org/127.0.0.1#5335 +server=/.dl.box.net/127.0.0.1#5335 +server=/.dl-laby.jp/127.0.0.1#5335 +server=/.dl.playstation.net/127.0.0.1#5335 +server=/.dlsite.com/127.0.0.1#5335 +server=/.dmcdn.net/127.0.0.1#5335 +server=/.dmtip.gov.tw/127.0.0.1#5335 +server=/.dns2go.com/127.0.0.1#5335 +server=/.dnscrypt.org/127.0.0.1#5335 +server=/.docstoc.com/127.0.0.1#5335 +server=/.dojin.com/127.0.0.1#5335 +server=/.dok-forum.net/127.0.0.1#5335 +server=/.dolc.de/127.0.0.1#5335 +server=/.dollf.com/127.0.0.1#5335 +server=/.domain.club.tw/127.0.0.1#5335 +server=/.domainhelp.search.com/127.0.0.1#5335 +server=/.dongde.com/127.0.0.1#5335 +server=/.dongtaiwang.com/127.0.0.1#5335 +server=/.dongtaiwang.net/127.0.0.1#5335 +server=/.dongyangjing.com/127.0.0.1#5335 +server=/.dontfilter.us/127.0.0.1#5335 +server=/.dontmovetochina.com/127.0.0.1#5335 +server=/.dotheyfolloweachother.com/127.0.0.1#5335 +server=/.dotplane.com/127.0.0.1#5335 +server=/.dotsub.com/127.0.0.1#5335 +server=/.doubleaf.com/127.0.0.1#5335 +server=/.doubleclick.net/127.0.0.1#5335 +server=/.dougscripts.com/127.0.0.1#5335 +server=/.dowei.org/127.0.0.1#5335 +server=/.download.syniumsoftware.com/127.0.0.1#5335 +server=/.doxygen.org/127.0.0.1#5335 +server=/.dphk.org/127.0.0.1#5335 +server=/.dpp.org.tw/127.0.0.1#5335 +server=/.drewolanoff.com/127.0.0.1#5335 +server=/.drgan.net/127.0.0.1#5335 +server=/.dropbox.com/127.0.0.1#5335 +server=/.dropboxusercontent.com/127.0.0.1#5335 +server=/.drsunacademy.com/127.0.0.1#5335 +server=/.drtuber.com/127.0.0.1#5335 +server=/.dscn.info/127.0.0.1#5335 +server=/.dtiblog.com/127.0.0.1#5335 +server=/.dtic.mil/127.0.0.1#5335 +server=/.dtiserv2.com/127.0.0.1#5335 +server=/.duckduckgo.com/127.0.0.1#5335 +server=/.duckload.com/127.0.0.1#5335 +server=/.duckmylife.com/127.0.0.1#5335 +server=/.duihuahrjournal.org/127.0.0.1#5335 +server=/.duihua.org/127.0.0.1#5335 +server=/.duoweitimes.com/127.0.0.1#5335 +server=/.duping.net/127.0.0.1#5335 +server=/.duplicati.com/127.0.0.1#5335 +server=/.dupola.com/127.0.0.1#5335 +server=/.dupola.net/127.0.0.1#5335 +server=/.dvorak.org/127.0.0.1#5335 +server=/.dw.de/127.0.0.1#5335 +server=/.dwnews.com/127.0.0.1#5335 +server=/.dwnews.net/127.0.0.1#5335 +server=/.dw-world.com/127.0.0.1#5335 +server=/.dw-world.de/127.0.0.1#5335 +server=/.dy24k.info/127.0.0.1#5335 +server=/.dynawebinc.com/127.0.0.1#5335 +server=/.dyndns.org/127.0.0.1#5335 +server=/.dzze.com/127.0.0.1#5335 +server=/.e123.hk/127.0.0.1#5335 +server=/.eamonnbrennan.com/127.0.0.1#5335 +server=/.earthquake.usgs.gov/127.0.0.1#5335 +server=/.easy-share.com/127.0.0.1#5335 +server=/.ebookbrowse.com/127.0.0.1#5335 +server=/.ebookee.com/127.0.0.1#5335 +server=/.echofon.com/127.0.0.1#5335 +server=/.ecministry.net/127.0.0.1#5335 +server=/.edicypages.com/127.0.0.1#5335 +server=/.edoors.com/127.0.0.1#5335 +server=/.edubridge.com/127.0.0.1#5335 +server=/.eevpn.com/127.0.0.1#5335 +server=/.efcc.org.hk/127.0.0.1#5335 +server=/.efksoft.com/127.0.0.1#5335 +server=/.efmoe.com/127.0.0.1#5335 +server=/.e-gold.com/127.0.0.1#5335 +server=/.eic-av.com/127.0.0.1#5335 +server=/.e-info.org.tw/127.0.0.1#5335 +server=/.electionsmeter.com/127.0.0.1#5335 +server=/.elpais.com/127.0.0.1#5335 +server=/.eltondisney.com/127.0.0.1#5335 +server=/.emacsblog.org/127.0.0.1#5335 +server=/.embr.in/127.0.0.1#5335 +server=/.emory.edu/127.0.0.1#5335 +server=/.emule-ed2k.com/127.0.0.1#5335 +server=/.emuparadise.me/127.0.0.1#5335 +server=/.enewstree.com/127.0.0.1#5335 +server=/.en.favotter.net/127.0.0.1#5335 +server=/.englishfromengland.co.uk/127.0.0.1#5335 +server=/.entermap.com/127.0.0.1#5335 +server=/.en.wikipedia.org/127.0.0.1#5335 +server=/.epochtimes-bg.com/127.0.0.1#5335 +server=/.epochtimes.co.il/127.0.0.1#5335 +server=/.epochtimes.co.kr/127.0.0.1#5335 +server=/.epochtimes.com/127.0.0.1#5335 +server=/.epochtimes.de/127.0.0.1#5335 +server=/.epochtimes.fr/127.0.0.1#5335 +server=/.epochtimes.ie/127.0.0.1#5335 +server=/.epochtimes.jp/127.0.0.1#5335 +server=/.epochtimes-romania.com/127.0.0.1#5335 +server=/.epochtimes.ru/127.0.0.1#5335 +server=/.epochtimes.se/127.0.0.1#5335 +server=/.epochtimestr.com/127.0.0.1#5335 +server=/.epochweekly.com/127.0.0.1#5335 +server=/.erabaru.net/127.0.0.1#5335 +server=/.erepublik.com/127.0.0.1#5335 +server=/.erepublik.net/127.0.0.1#5335 +server=/.erights.net/127.0.0.1#5335 +server=/.eriversoft.com/127.0.0.1#5335 +server=/.ernestmandel.org/127.0.0.1#5335 +server=/.etaiwannews.com/127.0.0.1#5335 +server=/.etizer.org/127.0.0.1#5335 +server=/.etools.ncol.com/127.0.0.1#5335 +server=/.e-traderland.net/127.0.0.1#5335 +server=/.etraining.gov.tw/127.0.0.1#5335 +server=/.ettoday.net/127.0.0.1#5335 +server=/.evchk.wikia.com/127.0.0.1#5335 +server=/.eventful.com/127.0.0.1#5335 +server=/.everyday-carry.com/127.0.0.1#5335 +server=/.exblog.jp/127.0.0.1#5335 +server=/.expatshield.com/127.0.0.1#5335 +server=/.exploader.net/127.0.0.1#5335 +server=/.extremetube.com/127.0.0.1#5335 +server=/.eyespirit.info/127.0.0.1#5335 +server=/.eyevio.jp/127.0.0.1#5335 +server=/.eyny.com/127.0.0.1#5335 +server=/.ezpc.tk/127.0.0.1#5335 +server=/.ezpeer.com/127.0.0.1#5335 +server=/.facebook.com/127.0.0.1#5335 +server=/.facebook.net/127.0.0.1#5335 +server=/.facesofnyfw.com/127.0.0.1#5335 +server=/.fail.hk/127.0.0.1#5335 +server=/.faiththedog.info/127.0.0.1#5335 +server=/.fakku.net/127.0.0.1#5335 +server=/.falsefire.com/127.0.0.1#5335 +server=/.falunart.org/127.0.0.1#5335 +server=/.falundafamuseum.org/127.0.0.1#5335 +server=/.falundafa.org/127.0.0.1#5335 +server=/.falunhr.org/127.0.0.1#5335 +server=/.famunion.com/127.0.0.1#5335 +server=/.fangbinxing.com/127.0.0.1#5335 +server=/.fangeming.com/127.0.0.1#5335 +server=/.fanglizhi.info/127.0.0.1#5335 +server=/.fangongheike.com/127.0.0.1#5335 +server=/.fangong.org/127.0.0.1#5335 +server=/.fan-qiang.com/127.0.0.1#5335 +server=/.fanqianghou.com/127.0.0.1#5335 +server=/.fanqiangyakexi.net/127.0.0.1#5335 +server=/.fanswong.com/127.0.0.1#5335 +server=/.fanyue.info/127.0.0.1#5335 +server=/.fapdu.com/127.0.0.1#5335 +server=/.farwestchina.com/127.0.0.1#5335 +server=/.farxian.com/127.0.0.1#5335 +server=/.fastpic.ru/127.0.0.1#5335 +server=/.faststone.org/127.0.0.1#5335 +server=/.favorious.com/127.0.0.1#5335 +server=/.favstar.fm/127.0.0.1#5335 +server=/.fawanghuihui.org/127.0.0.1#5335 +server=/.faydao.com/127.0.0.1#5335 +server=/.fbcdn.net/127.0.0.1#5335 +server=/.fb.com/127.0.0.1#5335 +server=/.fb.me/127.0.0.1#5335 +server=/.fbsbx.com/127.0.0.1#5335 +server=/.fc2china.com/127.0.0.1#5335 +server=/.fc2.com/127.0.0.1#5335 +server=/.f.cl.ly/127.0.0.1#5335 +server=/.fdc89.jp/127.0.0.1#5335 +server=/.feedbooks.mobi/127.0.0.1#5335 +server=/.feedburner.com/127.0.0.1#5335 +server=/.feeds2.feedburner.com/127.0.0.1#5335 +server=/.feeds.feedburner.com/127.0.0.1#5335 +server=/.feedzshare.com/127.0.0.1#5335 +server=/.feelssh.com/127.0.0.1#5335 +server=/.feer.com/127.0.0.1#5335 +server=/.felixcat.net/127.0.0.1#5335 +server=/.feministteacher.com/127.0.0.1#5335 +server=/.fengzhenghu.com/127.0.0.1#5335 +server=/.fetchvideo.com/127.0.0.1#5335 +server=/.ff.im/127.0.0.1#5335 +server=/.fflick.com/127.0.0.1#5335 +server=/.fgmtv.net/127.0.0.1#5335 +server=/.fgmtv.org/127.0.0.1#5335 +server=/.filefactory.com/127.0.0.1#5335 +server=/.files2me.com/127.0.0.1#5335 +server=/.fileserve.com/127.0.0.1#5335 +server=/.fillthesquare.org/127.0.0.1#5335 +server=/.finalion.jp/127.0.0.1#5335 +server=/.findbook.tw/127.0.0.1#5335 +server=/.finler.net/127.0.0.1#5335 +server=/.fireofliberty.org/127.0.0.1#5335 +server=/.firstfivefollowers.com/127.0.0.1#5335 +server=/.flecheinthepeche.fr/127.0.0.1#5335 +server=/.fleshbot.com/127.0.0.1#5335 +server=/.flickr.com/127.0.0.1#5335 +server=/.flickrhivemind.net/127.0.0.1#5335 +server=/.flightcaster.com/127.0.0.1#5335 +server=/.flowerofhappiness.spaces.live.com/127.0.0.1#5335 +server=/.focustaiwan.tw/127.0.0.1#5335 +server=/.focusvpn.com/127.0.0.1#5335 +server=/.fofg.org/127.0.0.1#5335 +server=/.fooooo.com/127.0.0.1#5335 +server=/.footwiball.com/127.0.0.1#5335 +server=/.forum.baby-kingdom.com/127.0.0.1#5335 +server=/.forum.cyberctm.com/127.0.0.1#5335 +server=/.forum.idsam.com/127.0.0.1#5335 +server=/.forum.iset.com.tw/127.0.0.1#5335 +server=/.forum.my903.com/127.0.0.1#5335 +server=/.forum.mymaji.com/127.0.0.1#5335 +server=/.forum.newsgroup.la/127.0.0.1#5335 +server=/.forum.nownews.com/127.0.0.1#5335 +server=/.forum.omy.sg/127.0.0.1#5335 +server=/.forum.palmislife.com/127.0.0.1#5335 +server=/.forum.pchome.com.tw/127.0.0.1#5335 +server=/.forum.setty.com.tw/127.0.0.1#5335 +server=/.forum.sina.com.hk/127.0.0.1#5335 +server=/.forum.slime.com.tw/127.0.0.1#5335 +server=/.forum.tvb.com/127.0.0.1#5335 +server=/.forum.yorkbbs.ca/127.0.0.1#5335 +server=/.fotop.net/127.0.0.1#5335 +server=/.fourface.nodesnoop.com/127.0.0.1#5335 +server=/.fourthinternational.org/127.0.0.1#5335 +server=/.foxdie.us/127.0.0.1#5335 +server=/.foxsub.com/127.0.0.1#5335 +server=/.foxtang.com/127.0.0.1#5335 +server=/.fqrouter.com/127.0.0.1#5335 +server=/.franklc.com/127.0.0.1#5335 +server=/.freakshare.com/127.0.0.1#5335 +server=/.fredwilson.vc/127.0.0.1#5335 +server=/.free4u.com.ar/127.0.0.1#5335 +server=/.freealim.com/127.0.0.1#5335 +server=/.freechal.com/127.0.0.1#5335 +server=/.freedomhouse.org/127.0.0.1#5335 +server=/.free.fr/127.0.0.1#5335 +server=/.freegao.com/127.0.0.1#5335 +server=/.freegateget.googlepages.com/127.0.0.1#5335 +server=/.free-gate.org/127.0.0.1#5335 +server=/.free-hada-now.org/127.0.0.1#5335 +server=/.freelotto.com/127.0.0.1#5335 +server=/.freeman2.com/127.0.0.1#5335 +server=/.freemoren.com/127.0.0.1#5335 +server=/.freemorenews.com/127.0.0.1#5335 +server=/.freenet-china.org/127.0.0.1#5335 +server=/.freenetproject.org/127.0.0.1#5335 +server=/.freenewscn.com/127.0.0.1#5335 +server=/.freeopenvpn.com/127.0.0.1#5335 +server=/.freeoz.org/127.0.0.1#5335 +server=/.free-ssh.com/127.0.0.1#5335 +server=/.freessh.us/127.0.0.1#5335 +server=/.freetibet.org/127.0.0.1#5335 +server=/.freevpn.nl/127.0.0.1#5335 +server=/.freewallpaper4.me/127.0.0.1#5335 +server=/.freewebs.com/127.0.0.1#5335 +server=/.freeweibo.com/127.0.0.1#5335 +server=/.freexinwen.com/127.0.0.1#5335 +server=/.freeyoutubeproxy.net/127.0.0.1#5335 +server=/.friendfeed.com/127.0.0.1#5335 +server=/.friendfeed-media.com/127.0.0.1#5335 +server=/.fring.com/127.0.0.1#5335 +server=/.fringenetwork.com/127.0.0.1#5335 +server=/.frommel.net/127.0.0.1#5335 +server=/.frontlinedefenders.org/127.0.0.1#5335 +server=/.fscked.org/127.0.0.1#5335 +server=/.fsurf.com/127.0.0.1#5335 +server=/.ftchinese.com/127.0.0.1#5335 +server=/.fuckcnnic.net/127.0.0.1#5335 +server=/.fuckgfw.com/127.0.0.1#5335 +server=/.fuckgfw.org/127.0.0.1#5335 +server=/.fulue.com/127.0.0.1#5335 +server=/.funf.tw/127.0.0.1#5335 +server=/.funp.com/127.0.0.1#5335 +server=/.furinkan.com/127.0.0.1#5335 +server=/.furl.net/127.0.0.1#5335 +server=/.futurechinaforum.org/127.0.0.1#5335 +server=/.futureme.org/127.0.0.1#5335 +server=/.futuremessage.org/127.0.0.1#5335 +server=/.fuyin.net/127.0.0.1#5335 +server=/.fw.cm/127.0.0.1#5335 +server=/.fxnetworks.com/127.0.0.1#5335 +server=/.fzh999.com/127.0.0.1#5335 +server=/.fzh999.net/127.0.0.1#5335 +server=/.gabocorp.com/127.0.0.1#5335 +server=/.gaeproxy.com/127.0.0.1#5335 +server=/.gaeproxy.googlecode.com/127.0.0.1#5335 +server=/.galenwu.com/127.0.0.1#5335 +server=/.game735.com/127.0.0.1#5335 +server=/.gamebase.com.tw/127.0.0.1#5335 +server=/.gamer.com.tw/127.0.0.1#5335 +server=/.gamez.com.tw/127.0.0.1#5335 +server=/.ganges.com/127.0.0.1#5335 +server=/.gaoming.net/127.0.0.1#5335 +server=/.gaopi.net/127.0.0.1#5335 +server=/.gaozhisheng.net/127.0.0.1#5335 +server=/.gaozhisheng.org/127.0.0.1#5335 +server=/.gardennetworks.com/127.0.0.1#5335 +server=/.gardennetworks.org/127.0.0.1#5335 +server=/.gartlive.com/127.0.0.1#5335 +server=/.gather.com/127.0.0.1#5335 +server=/.gaymap.cc/127.0.0.1#5335 +server=/.gazotube.com/127.0.0.1#5335 +server=/.gcc.org.hk/127.0.0.1#5335 +server=/.gclooney.com/127.0.0.1#5335 +server=/.g.co/127.0.0.1#5335 +server=/.gcpnews.com/127.0.0.1#5335 +server=/.gdbt.net/127.0.0.1#5335 +server=/.gdzf.org/127.0.0.1#5335 +server=/.geek-art.net/127.0.0.1#5335 +server=/.geekerhome.com/127.0.0.1#5335 +server=/.geekmade.co.uk/127.0.0.1#5335 +server=/.geekmanuals.com/127.0.0.1#5335 +server=/.generesis.com/127.0.0.1#5335 +server=/.genuitec.com/127.0.0.1#5335 +server=/.geocities.co.jp/127.0.0.1#5335 +server=/.geocities.com/127.0.0.1#5335 +server=/.geocities.jp/127.0.0.1#5335 +server=/.geohot.com/127.0.0.1#5335 +server=/.geometrictools.com/127.0.0.1#5335 +server=/.getchu.com/127.0.0.1#5335 +server=/.getcloudapp.com/127.0.0.1#5335 +server=/.get-digital-help.com/127.0.0.1#5335 +server=/.getfoxyproxy.org/127.0.0.1#5335 +server=/.getfreedur.com/127.0.0.1#5335 +server=/.getiton.com/127.0.0.1#5335 +server=/.getjetso.com/127.0.0.1#5335 +server=/.getlantern.org/127.0.0.1#5335 +server=/.getsmartlinks.com/127.0.0.1#5335 +server=/.getsocialscope.com/127.0.0.1#5335 +server=/.gfwinterceptor.googlecode.com/127.0.0.1#5335 +server=/.gfw.org.ua/127.0.0.1#5335 +server=/.ggpht.com/127.0.0.1#5335 +server=/.ggssl.com/127.0.0.1#5335 +server=/.ghost.org/127.0.0.1#5335 +server=/.ghut.org/127.0.0.1#5335 +server=/.giga-web.jp/127.0.0.1#5335 +server=/.gigporno.ru/127.0.0.1#5335 +server=/.gimpshop.com/127.0.0.1#5335 +server=/.girlbanker.com/127.0.0.1#5335 +server=/.github.com/127.0.0.1#5335 +server=/.git-scm.com/127.0.0.1#5335 +server=/.givemesomethingtoread.com/127.0.0.1#5335 +server=/.glennhilton.com/127.0.0.1#5335 +server=/.globaljihad.net/127.0.0.1#5335 +server=/.globalmuseumoncommunism.org/127.0.0.1#5335 +server=/.globalrescue.net/127.0.0.1#5335 +server=/.globalvoicesonline.org/127.0.0.1#5335 +server=/.gmail.com/127.0.0.1#5335 +server=/.gmbd.cn/127.0.0.1#5335 +server=/.gmhz.org/127.0.0.1#5335 +server=/.gmodules.com/127.0.0.1#5335 +server=/.gmozomg.izihost.org/127.0.0.1#5335 +server=/.gnci.org.hk/127.0.0.1#5335 +server=/.goagent.biz/127.0.0.1#5335 +server=/.goagent.googlecode.com/127.0.0.1#5335 +server=/.goagentplus.com/127.0.0.1#5335 +server=/.godfootsteps.org/127.0.0.1#5335 +server=/.golang.org/127.0.0.1#5335 +server=/.goldbetsports.com/127.0.0.1#5335 +server=/.goldwave.com/127.0.0.1#5335 +server=/.gongmeng.info/127.0.0.1#5335 +server=/.gongm.in/127.0.0.1#5335 +server=/.gongminliliang.com/127.0.0.1#5335 +server=/.gongwt.com/127.0.0.1#5335 +server=/.goodreaders.com/127.0.0.1#5335 +server=/.goodreads.com/127.0.0.1#5335 +server=/.goofind.com/127.0.0.1#5335 +server=/.goo.gl/127.0.0.1#5335 +server=/.googleadservices.com/127.0.0.1#5335 +server=/.google-analytics.com/127.0.0.1#5335 +server=/.googleapis.com/127.0.0.1#5335 +server=/.googlecode.com/127.0.0.1#5335 +server=/.google.co.jp/127.0.0.1#5335 +server=/.google.com/127.0.0.1#5335 +server=/.google.com.hk/127.0.0.1#5335 +server=/.google.com.sg/127.0.0.1#5335 +server=/.google.com.tw/127.0.0.1#5335 +server=/.google.com.uk/127.0.0.1#5335 +server=/.googledomains.com/127.0.0.1#5335 +server=/.googledrive.com/127.0.0.1#5335 +server=/.googleearth.com/127.0.0.1#5335 +server=/.googlehosted.com/127.0.0.1#5335 +server=/.googlelabs.com/127.0.0.1#5335 +server=/.googlemail.com/127.0.0.1#5335 +server=/.googleplus.com/127.0.0.1#5335 +server=/.googlesile.com/127.0.0.1#5335 +server=/.googlesource.com/127.0.0.1#5335 +server=/.googlesyndication.com/127.0.0.1#5335 +server=/.googletagmanager.com/127.0.0.1#5335 +server=/.googletagservices.com/127.0.0.1#5335 +server=/.googleusercontent.com/127.0.0.1#5335 +server=/.googlevideo.com/127.0.0.1#5335 +server=/.gopetition.com/127.0.0.1#5335 +server=/.gospelherald.com/127.0.0.1#5335 +server=/.gov.tw/127.0.0.1#5335 +server=/.gpass1.com/127.0.0.1#5335 +server=/.grandtrial.org/127.0.0.1#5335 +server=/.graphis.ne.jp/127.0.0.1#5335 +server=/.gravatar.com/127.0.0.1#5335 +server=/.graylog2.org/127.0.0.1#5335 +server=/.grb.gov.tw/127.0.0.1#5335 +server=/.greatfire.org/127.0.0.1#5335 +server=/.greatfirewall.biz/127.0.0.1#5335 +server=/.great-firewall.com/127.0.0.1#5335 +server=/.greatfirewallofchina.net/127.0.0.1#5335 +server=/.greatfirewallofchina.org/127.0.0.1#5335 +server=/.great-roc.org/127.0.0.1#5335 +server=/.greatroc.org/127.0.0.1#5335 +server=/.greatroc.tw/127.0.0.1#5335 +server=/.greatzhonghua.org/127.0.0.1#5335 +server=/.greenparty.org.tw/127.0.0.1#5335 +server=/.greenvpn.net/127.0.0.1#5335 +server=/.gs-discuss.com/127.0.0.1#5335 +server=/.gseeker.com/127.0.0.1#5335 +server=/.gsn-cert.nat.gov.tw/127.0.0.1#5335 +server=/.gstatic.com/127.0.0.1#5335 +server=/.gtap.googlecode.com/127.0.0.1#5335 +server=/.gtricks.com/127.0.0.1#5335 +server=/.guancha.org/127.0.0.1#5335 +server=/.gufeng521.spaces.live.com/127.0.0.1#5335 +server=/.guishan.org/127.0.0.1#5335 +server=/.gunsamerica.com/127.0.0.1#5335 +server=/.gun-world.net/127.0.0.1#5335 +server=/.guomin.us/127.0.0.1#5335 +server=/.gutteruncensored.com/127.0.0.1#5335 +server=/.gvm.com.tw/127.0.0.1#5335 +server=/.gyalwarinpoche.com/127.0.0.1#5335 +server=/.gysd.nyc.gov.tw/127.0.0.1#5335 +server=/.gzm.tv/127.0.0.1#5335 +server=/.gzone-anime.info/127.0.0.1#5335 +server=/.h1n1china.org/127.0.0.1#5335 +server=/.hacken.cc/127.0.0.1#5335 +server=/.hackthatphone.net/127.0.0.1#5335 +server=/.hahlo.com/127.0.0.1#5335 +server=/.hakkatv.org.tw/127.0.0.1#5335 +server=/.hanunyi.com/127.0.0.1#5335 +server=/.hardsextube.com/127.0.0.1#5335 +server=/.hasaowall.com/127.0.0.1#5335 +server=/.have8.com/127.0.0.1#5335 +server=/.haygo.com/127.0.0.1#5335 +server=/.hcc.gov.tw/127.0.0.1#5335 +server=/.hchcc.gov.tw/127.0.0.1#5335 +server=/.h-china.org/127.0.0.1#5335 +server=/.hdtvb.net/127.0.0.1#5335 +server=/.heartyit.com/127.0.0.1#5335 +server=/.hecaitou.net/127.0.0.1#5335 +server=/.hechaji.com/127.0.0.1#5335 +server=/.heix.pp.ru/127.0.0.1#5335 +server=/.heiyo.info/127.0.0.1#5335 +server=/.helloandroid.com/127.0.0.1#5335 +server=/.hellonewyork.us/127.0.0.1#5335 +server=/.helloqueer.com/127.0.0.1#5335 +server=/.hellotxt.com/127.0.0.1#5335 +server=/.hellouk.org/127.0.0.1#5335 +server=/.helpeachpeople.com/127.0.0.1#5335 +server=/.helplinfen.com/127.0.0.1#5335 +server=/.help.linksalpha.com/127.0.0.1#5335 +server=/.help.opera.com/127.0.0.1#5335 +server=/.helpzhuling.org/127.0.0.1#5335 +server=/.hen.bao.li/127.0.0.1#5335 +server=/.hengchuen.gov.tw/127.0.0.1#5335 +server=/.heqinglian.net/127.0.0.1#5335 +server=/.here4news.com/127.0.0.1#5335 +server=/.heungkongdiscuss.com/127.0.0.1#5335 +server=/.hgseav.com/127.0.0.1#5335 +server=/.hidden-advent.org/127.0.0.1#5335 +server=/.hidecloud.com/127.0.0.1#5335 +server=/.hideipvpn.com/127.0.0.1#5335 +server=/.hidemyass.com/127.0.0.1#5335 +server=/.higfw.com/127.0.0.1#5335 +server=/.highrockmedia.com/127.0.0.1#5335 +server=/.hihiforum.com/127.0.0.1#5335 +server=/.hihistory.net/127.0.0.1#5335 +server=/.hiitch.com/127.0.0.1#5335 +server=/.hikinggfw.org/127.0.0.1#5335 +server=/.himemix.com/127.0.0.1#5335 +server=/.himemix.net/127.0.0.1#5335 +server=/.hjclub.info/127.0.0.1#5335 +server=/.hk32168.com/127.0.0.1#5335 +server=/.hkbc.net/127.0.0.1#5335 +server=/.hkbf.org/127.0.0.1#5335 +server=/.hkchurch.org/127.0.0.1#5335 +server=/.hkdailynews.com.hk/127.0.0.1#5335 +server=/.hkday.net/127.0.0.1#5335 +server=/.hkej.com/127.0.0.1#5335 +server=/.hkepc.com/127.0.0.1#5335 +server=/.hkfront.org/127.0.0.1#5335 +server=/.hk.geocities.com/127.0.0.1#5335 +server=/.hkgolden.com/127.0.0.1#5335 +server=/.hkgreenradio.org/127.0.0.1#5335 +server=/.hkg.westkit.net/127.0.0.1#5335 +server=/.hkheadline.com/127.0.0.1#5335 +server=/.hkhkhk.com/127.0.0.1#5335 +server=/.hkjc.com/127.0.0.1#5335 +server=/.hk.jiepang.com/127.0.0.1#5335 +server=/.hkjp.easyweb.hk/127.0.0.1#5335 +server=/.hkjp.org/127.0.0.1#5335 +server=/.hk.knowledge.yahoo.com/127.0.0.1#5335 +server=/.hk.myblog.yahoo.com/127.0.0.1#5335 +server=/.hk.news.yahoo.com/127.0.0.1#5335 +server=/.hkptu.org/127.0.0.1#5335 +server=/.hk-pub.com/127.0.0.1#5335 +server=/.hk.rd.yahoo.com/127.0.0.1#5335 +server=/.hkreporter.com/127.0.0.1#5335 +server=/.hkreporter.loved.hk/127.0.0.1#5335 +server=/.hk.search.yahoo.com/127.0.0.1#5335 +server=/.hk.video.news.yahoo.com/127.0.0.1#5335 +server=/.hkwcc.org.hk/127.0.0.1#5335 +server=/.hk.yahoo.com/127.0.0.1#5335 +server=/.hkzone.org/127.0.0.1#5335 +server=/.hnjhj.com/127.0.0.1#5335 +server=/.hola.com/127.0.0.1#5335 +server=/.holyspiritspeaks.org/127.0.0.1#5335 +server=/.holz.byethost8.com/127.0.0.1#5335 +server=/.homeservershow.com/127.0.0.1#5335 +server=/.home.sina.com/127.0.0.1#5335 +server=/.home.so-net.net.tw/127.0.0.1#5335 +server=/.honeonet.spaces.live.com/127.0.0.1#5335 +server=/.hongmeimei.com/127.0.0.1#5335 +server=/.hongzhi.li/127.0.0.1#5335 +server=/.hootsuite.com/127.0.0.1#5335 +server=/.hotpot.hk/127.0.0.1#5335 +server=/.hotshame.com/127.0.0.1#5335 +server=/.hotspotshield.com/127.0.0.1#5335 +server=/.hougaige.com/127.0.0.1#5335 +server=/.howtoforge.com/127.0.0.1#5335 +server=/.hqcdp.org/127.0.0.1#5335 +server=/.hrcir.com/127.0.0.1#5335 +server=/.hrichina.org/127.0.0.1#5335 +server=/.hrw.org/127.0.0.1#5335 +server=/.hsinchu-cc.gov.tw/127.0.0.1#5335 +server=/.hsjp.net/127.0.0.1#5335 +server=/.hsselite.com/127.0.0.1#5335 +server=/.htkou.net/127.0.0.1#5335 +server=/.htl.li/127.0.0.1#5335 +server=/.ht.ly/127.0.0.1#5335 +server=/.htmldog.com/127.0.0.1#5335 +server=/.huaglad.com/127.0.0.1#5335 +server=/.huajiadi.spaces.live.com/127.0.0.1#5335 +server=/.huanghuagang.org/127.0.0.1#5335 +server=/.huaren.us/127.0.0.1#5335 +server=/.huaxia-news.com/127.0.0.1#5335 +server=/.huaxin.ph/127.0.0.1#5335 +server=/.hua-yue.net/127.0.0.1#5335 +server=/.hudatoriq.web.id/127.0.0.1#5335 +server=/.hugoroy.eu/127.0.0.1#5335 +server=/.huhamhire.com/127.0.0.1#5335 +server=/.hujiachina.spaces.live.com/127.0.0.1#5335 +server=/.hulu.com/127.0.0.1#5335 +server=/.huluim.com/127.0.0.1#5335 +server=/.humanities.uchicago.edu/127.0.0.1#5335 +server=/.hungerstrikeforaids.org/127.0.0.1#5335 +server=/.hung-ya.com/127.0.0.1#5335 +server=/.huping.net/127.0.0.1#5335 +server=/.hutianyi.net/127.0.0.1#5335 +server=/.hutong9.net/127.0.0.1#5335 +server=/.hwinfo.com/127.0.0.1#5335 +server=/.hyperrate.com/127.0.0.1#5335 +server=/.hypeshell.com/127.0.0.1#5335 +server=/.i1.hk/127.0.0.1#5335 +server=/.i2runner.com/127.0.0.1#5335 +server=/.ialmostlaugh.com/127.0.0.1#5335 +server=/.iask.bz/127.0.0.1#5335 +server=/.iask.ca/127.0.0.1#5335 +server=/.ibiblio.org/127.0.0.1#5335 +server=/.iblogserv-f.net/127.0.0.1#5335 +server=/.ibros.org/127.0.0.1#5335 +server=/.icij.org/127.0.0.1#5335 +server=/.icl-fi.org/127.0.0.1#5335 +server=/.iconpaper.org/127.0.0.1#5335 +server=/.icu-project.org/127.0.0.1#5335 +server=/.idemocracy.asia/127.0.0.1#5335 +server=/.identi.ca/127.0.0.1#5335 +server=/.idiomconnection.com/127.0.0.1#5335 +server=/.idouga.com/127.0.0.1#5335 +server=/.idv.tw/127.0.0.1#5335 +server=/.ieasynews.net/127.0.0.1#5335 +server=/.ied2k.net/127.0.0.1#5335 +server=/.ieemdai.spaces.live.com/127.0.0.1#5335 +server=/.ifan.cz.cc/127.0.0.1#5335 +server=/.ifanqiang.com/127.0.0.1#5335 +server=/.ifanr.com/127.0.0.1#5335 +server=/.ifcss.org/127.0.0.1#5335 +server=/.ifjc.org/127.0.0.1#5335 +server=/.igfw.net/127.0.0.1#5335 +server=/.ignitedetroit.net/127.0.0.1#5335 +server=/.igvita.com/127.0.0.1#5335 +server=/.ihakka.net/127.0.0.1#5335 +server=/.iicns.com/127.0.0.1#5335 +server=/.illusionfactory.com/127.0.0.1#5335 +server=/.ilove80.be/127.0.0.1#5335 +server=/.im88.tw/127.0.0.1#5335 +server=/.imageflea.com/127.0.0.1#5335 +server=/.imagesblog.gio.gov.tw/127.0.0.1#5335 +server=/.imageshack.us/127.0.0.1#5335 +server=/.imagevenue.com/127.0.0.1#5335 +server=/.imagezilla.net/127.0.0.1#5335 +server=/.ime.baidu.jp/127.0.0.1#5335 +server=/.img.ly/127.0.0.1#5335 +server=/.imkev.com/127.0.0.1#5335 +server=/.imlive.com/127.0.0.1#5335 +server=/.immigration.gov.tw/127.0.0.1#5335 +server=/.imrworldwide.com/127.0.0.1#5335 +server=/.im.tv/127.0.0.1#5335 +server=/.incredibox.fr/127.0.0.1#5335 +server=/.iner.gov.tw/127.0.0.1#5335 +server=/.initiativesforchina.org/127.0.0.1#5335 +server=/.inmediahk.net/127.0.0.1#5335 +server=/.innermongolia.org/127.0.0.1#5335 +server=/.instagram.com/127.0.0.1#5335 +server=/.interestinglaugh.com/127.0.0.1#5335 +server=/.interfaceaddiction.com/127.0.0.1#5335 +server=/.internationalrivers.org/127.0.0.1#5335 +server=/.internetdefenseleague.org/127.0.0.1#5335 +server=/.internetfreedom.org/127.0.0.1#5335 +server=/.internetpopculture.com/127.0.0.1#5335 +server=/.inxian.com/127.0.0.1#5335 +server=/.iphone4hongkong.com/127.0.0.1#5335 +server=/.iphonehacks.com/127.0.0.1#5335 +server=/.iphonix.fr/127.0.0.1#5335 +server=/.ipicture.ru/127.0.0.1#5335 +server=/.ipobar.com/127.0.0.1#5335 +server=/.ippotv.com/127.0.0.1#5335 +server=/.iptorrents.com/127.0.0.1#5335 +server=/.ipvanish.com/127.0.0.1#5335 +server=/.iredmail.org/127.0.0.1#5335 +server=/.ironbigfools.compython.net/127.0.0.1#5335 +server=/.ironicsoftware.com/127.0.0.1#5335 +server=/.ironpython.net/127.0.0.1#5335 +server=/.isaacmao.com/127.0.0.1#5335 +server=/.isgreat.org/127.0.0.1#5335 +server=/.islamicity.com/127.0.0.1#5335 +server=/.islam.org.hk/127.0.0.1#5335 +server=/.ismprofessional.net/127.0.0.1#5335 +server=/.isohunt.com/127.0.0.1#5335 +server=/.israbox.com/127.0.0.1#5335 +server=/.istockphoto.com/127.0.0.1#5335 +server=/.isunaffairs.com/127.0.0.1#5335 +server=/.isuntv.com/127.0.0.1#5335 +server=/.itaboo.info/127.0.0.1#5335 +server=/.ithelp.ithome.com.tw/127.0.0.1#5335 +server=/.itrc.gov.tw/127.0.0.1#5335 +server=/.itshidden.com/127.0.0.1#5335 +server=/.itweet.net/127.0.0.1#5335 +server=/.iu45.com/127.0.0.1#5335 +server=/.iverycd.com/127.0.0.1#5335 +server=/.ixquick.com/127.0.0.1#5335 +server=/.izaobao.us/127.0.0.1#5335 +server=/.izles.net/127.0.0.1#5335 +server=/.japan-whores.com/127.0.0.1#5335 +server=/.jayparkinsonmd.com/127.0.0.1#5335 +server=/.jbtalks.cc/127.0.0.1#5335 +server=/.jbtalks.com/127.0.0.1#5335 +server=/.jbtalks.my/127.0.0.1#5335 +server=/.jeanyim.com/127.0.0.1#5335 +server=/.jgoodies.com/127.0.0.1#5335 +server=/.jiaoyou8.com/127.0.0.1#5335 +server=/.jiehua.cz/127.0.0.1#5335 +server=/.jieshibaobao.com/127.0.0.1#5335 +server=/.jike.com/127.0.0.1#5335 +server=/.jimoparty.com/127.0.0.1#5335 +server=/.jinbushe.org/127.0.0.1#5335 +server=/.jingpin.org/127.0.0.1#5335 +server=/.jitouch.com/127.0.0.1#5335 +server=/.jkforum.net/127.0.0.1#5335 +server=/.j.mp/127.0.0.1#5335 +server=/.joachims.org/127.0.0.1#5335 +server=/.jobso.tv/127.0.0.1#5335 +server=/.joeedelman.com/127.0.0.1#5335 +server=/.journalofdemocracy.org/127.0.0.1#5335 +server=/.jpopforum.net/127.0.0.1#5335 +server=/.juliereyc.com/127.0.0.1#5335 +server=/.junauza.com/127.0.0.1#5335 +server=/.junefourth-20.net/127.0.0.1#5335 +server=/.justfreevpn.com/127.0.0.1#5335 +server=/.justtristan.com/127.0.0.1#5335 +server=/.juziyue.com/127.0.0.1#5335 +server=/.jwmusic.org/127.0.0.1#5335 +server=/.jyxf.net/127.0.0.1#5335 +server=/.jyzj.waqn.com/127.0.0.1#5335 +server=/.k2.xrea.com/127.0.0.1#5335 +server=/.kagyuoffice.org.tw/127.0.0.1#5335 +server=/.kaiyuan.de/127.0.0.1#5335 +server=/.kakao.com/127.0.0.1#5335 +server=/.kanzhongguo.com/127.0.0.1#5335 +server=/.kanzhongguo.eu/127.0.0.1#5335 +server=/.karayou.com/127.0.0.1#5335 +server=/.ka-wai.com/127.0.0.1#5335 +server=/.kcsoftwares.com/127.0.0.1#5335 +server=/.kechara.com/127.0.0.1#5335 +server=/.keepandshare.com/127.0.0.1#5335 +server=/.kendincos.net/127.0.0.1#5335 +server=/.kenengba.com/127.0.0.1#5335 +server=/.keontech.net/127.0.0.1#5335 +server=/.khcc.gov.tw/127.0.0.1#5335 +server=/.khms.gov.tw/127.0.0.1#5335 +server=/.khmusic.com.tw/127.0.0.1#5335 +server=/.killwall.com/127.0.0.1#5335 +server=/.kineox.free.fr/127.0.0.1#5335 +server=/.kingdomsalvation.org/127.0.0.1#5335 +server=/.kinghost.com/127.0.0.1#5335 +server=/.kingstone.com.tw/127.0.0.1#5335 +server=/.kissbbao.cn/127.0.0.1#5335 +server=/.kissyoutube.com/127.0.0.1#5335 +server=/.kk.gov.tw/127.0.0.1#5335 +server=/.klccab.gov.tw/127.0.0.1#5335 +server=/.klra.gov.tw/127.0.0.1#5335 +server=/.klsio.gov.tw/127.0.0.1#5335 +server=/.kmh.gov.tw/127.0.0.1#5335 +server=/.kmseh.gov.tw/127.0.0.1#5335 +server=/.knowledgerush.com/127.0.0.1#5335 +server=/.kodingen.com/127.0.0.1#5335 +server=/.kompozer.net/127.0.0.1#5335 +server=/.koolsolutions.com/127.0.0.1#5335 +server=/.koornk.com/127.0.0.1#5335 +server=/.kt.kcome.org/127.0.0.1#5335 +server=/.kui.name/127.0.0.1#5335 +server=/.kun.im/127.0.0.1#5335 +server=/.kurtmunger.com/127.0.0.1#5335 +server=/.kusocity.com/127.0.0.1#5335 +server=/.kwongwah.com.my/127.0.0.1#5335 +server=/.kyohk.net/127.0.0.1#5335 +server=/.kzeng.info/127.0.0.1#5335 +server=/.labiennale.org/127.0.0.1#5335 +server=/.ladbrokes.com/127.0.0.1#5335 +server=/.la-forum.org/127.0.0.1#5335 +server=/.lagranepoca.com/127.0.0.1#5335 +server=/.lalulalu.com/127.0.0.1#5335 +server=/.laogai.org/127.0.0.1#5335 +server=/.laomiu.com/127.0.0.1#5335 +server=/.laoyang.info/127.0.0.1#5335 +server=/.laptoplockdown.com/127.0.0.1#5335 +server=/.laqingdan.net/127.0.0.1#5335 +server=/.larsgeorge.com/127.0.0.1#5335 +server=/.lastfm.es/127.0.0.1#5335 +server=/.latelinenews.com/127.0.0.1#5335 +server=/.latimesblogs.latimes.com/127.0.0.1#5335 +server=/.lazarsearlymusic.com/127.0.0.1#5335 +server=/.leecheukyan.org/127.0.0.1#5335 +server=/.legaltech.law.com/127.0.0.1#5335 +server=/.lematin.ch/127.0.0.1#5335 +server=/.lemonde.fr/127.0.0.1#5335 +server=/.lenwhite.com/127.0.0.1#5335 +server=/.lerosua.org/127.0.0.1#5335 +server=/.lesoir.be/127.0.0.1#5335 +server=/.lesscss.org/127.0.0.1#5335 +server=/.letscorp.net/127.0.0.1#5335 +server=/.liansi.org/127.0.0.1#5335 +server=/.lianyue.net/127.0.0.1#5335 +server=/.liaowangxizang.net/127.0.0.1#5335 +server=/.liberal.org.hk/127.0.0.1#5335 +server=/.libertytimes.com.tw/127.0.0.1#5335 +server=/.lich355.megabyet.net/127.0.0.1#5335 +server=/.lidecheng.com/127.0.0.1#5335 +server=/.life.fly4ever.me/127.0.0.1#5335 +server=/.limiao.net/127.0.0.1#5335 +server=/.line.me/127.0.0.1#5335 +server=/.linglingfa.com/127.0.0.1#5335 +server=/.lingvodics.com/127.0.0.1#5335 +server=/.linkideo.com/127.0.0.1#5335 +server=/.linuxconfig.org/127.0.0.1#5335 +server=/.linux-engineer.net/127.0.0.1#5335 +server=/.linuxreviews.org/127.0.0.1#5335 +server=/.linuxtoy.org/127.0.0.1#5335 +server=/.lipuman.com/127.0.0.1#5335 +server=/.listentoyoutube.com/127.0.0.1#5335 +server=/.list.ly/127.0.0.1#5335 +server=/.listorious.com/127.0.0.1#5335 +server=/.lists.debian.org/127.0.0.1#5335 +server=/.lists.w3.org/127.0.0.1#5335 +server=/.littlebigdetails.com/127.0.0.1#5335 +server=/.liudejun.com/127.0.0.1#5335 +server=/.liuhanyu.com/127.0.0.1#5335 +server=/.liujianshu.com/127.0.0.1#5335 +server=/.liu.lu/127.0.0.1#5335 +server=/.liuxiaotong.com/127.0.0.1#5335 +server=/.liveleak.com/127.0.0.1#5335 +server=/.livestation.com/127.0.0.1#5335 +server=/.livestream.com/127.0.0.1#5335 +server=/.livevideo.com/127.0.0.1#5335 +server=/.livingonline.us/127.0.0.1#5335 +server=/.livingstream.com/127.0.0.1#5335 +server=/.lizhizhuangbi.com/127.0.0.1#5335 +server=/.lkcn.net/127.0.0.1#5335 +server=/.localpresshk.com/127.0.0.1#5335 +server=/.lockdown.com/127.0.0.1#5335 +server=/.lockestek.com/127.0.0.1#5335 +server=/.logbot.net/127.0.0.1#5335 +server=/.logiqx.com/127.0.0.1#5335 +server=/.logmike.com/127.0.0.1#5335 +server=/.log.riku.me/127.0.0.1#5335 +server=/.london.neighborhoodr.com/127.0.0.1#5335 +server=/.longhair.hk/127.0.0.1#5335 +server=/.longtermly.net/127.0.0.1#5335 +server=/.lookatgame.com/127.0.0.1#5335 +server=/.lookingglasstheatre.org/127.0.0.1#5335 +server=/.lookpic.com/127.0.0.1#5335 +server=/.lotuslight.org.tw/127.0.0.1#5335 +server=/.lovequicksilver.com/127.0.0.1#5335 +server=/.lovesphinx.tk/127.0.0.1#5335 +server=/.lrfz.com/127.0.0.1#5335 +server=/.lsd.org.hk/127.0.0.1#5335 +server=/.lsforum.net/127.0.0.1#5335 +server=/.lsmchinese.org/127.0.0.1#5335 +server=/.lsmkorean.org/127.0.0.1#5335 +server=/.lsm.org/127.0.0.1#5335 +server=/.lsxszzg.com/127.0.0.1#5335 +server=/.lua.org/127.0.0.1#5335 +server=/.lua-users.org/127.0.0.1#5335 +server=/.lungtanhr.gov.tw/127.0.0.1#5335 +server=/.luntan.zaobao.com/127.0.0.1#5335 +server=/.lupm.org/127.0.0.1#5335 +server=/.lushstories.com/127.0.0.1#5335 +server=/.lvhai.org/127.0.0.1#5335 +server=/.lyricsquote.com/127.0.0.1#5335 +server=/.mad-ar.ch/127.0.0.1#5335 +server=/.madmenunbuttoned.com/127.0.0.1#5335 +server=/.magazines.sina.com.tw/127.0.0.1#5335 +server=/.maiio.net/127.0.0.1#5335 +server=/.mail-archive.com/127.0.0.1#5335 +server=/.maiplus.com/127.0.0.1#5335 +server=/.makemymood.com/127.0.0.1#5335 +server=/.makzhou.warehouse333.com/127.0.0.1#5335 +server=/.malaysiakini.com/127.0.0.1#5335 +server=/.marc.info/127.0.0.1#5335 +server=/.marco.org/127.0.0.1#5335 +server=/.marguerite.su/127.0.0.1#5335 +server=/.marines.mil/127.0.0.1#5335 +server=/.markmilian.com/127.0.0.1#5335 +server=/.martau.com/127.0.0.1#5335 +server=/.martincartoons.com/127.0.0.1#5335 +server=/.maruta.be/127.0.0.1#5335 +server=/.marxist.com/127.0.0.1#5335 +server=/.marxist.net/127.0.0.1#5335 +server=/.marxists.org/127.0.0.1#5335 +server=/.mashable.com/127.0.0.1#5335 +server=/.mash.to/127.0.0.1#5335 +server=/.matainja.com/127.0.0.1#5335 +server=/.mathiew-badimon.com/127.0.0.1#5335 +server=/.matsu-news.gov.tw/127.0.0.1#5335 +server=/.matsushimakaede.com/127.0.0.1#5335 +server=/.maxgif.com/127.0.0.1#5335 +server=/.mayimayi.com/127.0.0.1#5335 +server=/.mcadforums.com/127.0.0.1#5335 +server=/.mcfog.com/127.0.0.1#5335 +server=/.md-t.org/127.0.0.1#5335 +server=/.mediafire.com/127.0.0.1#5335 +server=/.meetup.com/127.0.0.1#5335 +server=/.mefeedia.com/127.0.0.1#5335 +server=/.megaporn.com/127.0.0.1#5335 +server=/.megarotic.com/127.0.0.1#5335 +server=/.megavideo.com/127.0.0.1#5335 +server=/.megurineluka.com/127.0.0.1#5335 +server=/.meirixiaochao.com/127.0.0.1#5335 +server=/.melon-peach.com/127.0.0.1#5335 +server=/.memedia.cn/127.0.0.1#5335 +server=/.meme.yahoo.com/127.0.0.1#5335 +server=/.memrijttm.org/127.0.0.1#5335 +server=/.merit-times.com.tw/127.0.0.1#5335 +server=/.mesotw.com/127.0.0.1#5335 +server=/.metacafe.com/127.0.0.1#5335 +server=/.meteorshowersonline.com/127.0.0.1#5335 +server=/.metrolife.ca/127.0.0.1#5335 +server=/.mgoon.com/127.0.0.1#5335 +server=/.mgstage.com/127.0.0.1#5335 +server=/.mh4u.org/127.0.0.1#5335 +server=/.mhradio.org/127.0.0.1#5335 +server=/.michaelanti.com/127.0.0.1#5335 +server=/.michaelmarketl.com/127.0.0.1#5335 +server=/.middle-way.net/127.0.0.1#5335 +server=/.mihk.hk/127.0.0.1#5335 +server=/.mihua.org/127.0.0.1#5335 +server=/.mike.cz.cc/127.0.0.1#5335 +server=/.mimivip.com/127.0.0.1#5335 +server=/.minghui.org/127.0.0.1#5335 +server=/.minghui-school.org/127.0.0.1#5335 +server=/.mingjinglishi.com/127.0.0.1#5335 +server=/.mingjingnews.com/127.0.0.1#5335 +server=/.mingpaocanada.com/127.0.0.1#5335 +server=/.mingpao.com/127.0.0.1#5335 +server=/.mingpaomonthly.com/127.0.0.1#5335 +server=/.mingpaonews.com/127.0.0.1#5335 +server=/.mingpaony.com/127.0.0.1#5335 +server=/.mingpaosf.com/127.0.0.1#5335 +server=/.mingpaotor.com/127.0.0.1#5335 +server=/.mingpaovan.com/127.0.0.1#5335 +server=/.minimalmac.com/127.0.0.1#5335 +server=/.mininova.org/127.0.0.1#5335 +server=/.minzhuhua.net/127.0.0.1#5335 +server=/.minzhuzhongguo.org/127.0.0.1#5335 +server=/.miroguide.com/127.0.0.1#5335 +server=/.mirrorbooks.com/127.0.0.1#5335 +server=/.mitbbs.com/127.0.0.1#5335 +server=/.mixedmedialabs.com/127.0.0.1#5335 +server=/.mixero.com/127.0.0.1#5335 +server=/.mixpod.com/127.0.0.1#5335 +server=/.mixx.com/127.0.0.1#5335 +server=/.mizzmona.com/127.0.0.1#5335 +server=/.mk5000.com/127.0.0.1#5335 +server=/.mlcool.com/127.0.0.1#5335 +server=/.mmaaxx.com/127.0.0.1#5335 +server=/.mmmca.com/127.0.0.1#5335 +server=/.mobatek.net/127.0.0.1#5335 +server=/.mobile01.com/127.0.0.1#5335 +server=/.mobileways.de/127.0.0.1#5335 +server=/.mobypicture.com/127.0.0.1#5335 +server=/.moby.to/127.0.0.1#5335 +server=/.modfetish.com/127.0.0.1#5335 +server=/.moe.gov.tw/127.0.0.1#5335 +server=/.mog.com/127.0.0.1#5335 +server=/.molihua.org/127.0.0.1#5335 +server=/.mondex.org/127.0.0.1#5335 +server=/.monitorchina.org/127.0.0.1#5335 +server=/.moonriver7.files.wordpress.com/127.0.0.1#5335 +server=/.morningsun.org/127.0.0.1#5335 +server=/.m.oulove.org/127.0.0.1#5335 +server=/.movabletype.com/127.0.0.1#5335 +server=/.moviefap.com/127.0.0.1#5335 +server=/.mp3ye.eu/127.0.0.1#5335 +server=/.mpettis.com/127.0.0.1#5335 +server=/.mpfinance.com/127.0.0.1#5335 +server=/.mpinews.com/127.0.0.1#5335 +server=/.m.plixi.com/127.0.0.1#5335 +server=/.mrdoob.com/127.0.0.1#5335 +server=/.mrtweet.com/127.0.0.1#5335 +server=/.msguancha.com/127.0.0.1#5335 +server=/.m.slandr.net/127.0.0.1#5335 +server=/.mthruf.com/127.0.0.1#5335 +server=/.m.tweete.net/127.0.0.1#5335 +server=/.mtw.tl/127.0.0.1#5335 +server=/.multiply.com/127.0.0.1#5335 +server=/.multiproxy.org/127.0.0.1#5335 +server=/.multiupload.com/127.0.0.1#5335 +server=/.muouju.com/127.0.0.1#5335 +server=/.muselinks.co.jp/127.0.0.1#5335 +server=/.music.jwmusic.org/127.0.0.1#5335 +server=/.muzi.com/127.0.0.1#5335 +server=/.muzi.net/127.0.0.1#5335 +server=/.muzu.tv/127.0.0.1#5335 +server=/.mvdis.gov.tw/127.0.0.1#5335 +server=/.mx981.com/127.0.0.1#5335 +server=/.myactimes.com/127.0.0.1#5335 +server=/.my-addr.com/127.0.0.1#5335 +server=/.myaudiocast.com/127.0.0.1#5335 +server=/.myav.com.tw/127.0.0.1#5335 +server=/.my.backchina.com/127.0.0.1#5335 +server=/.myboooks.googlepages.com/127.0.0.1#5335 +server=/.mychinamyhome.com/127.0.0.1#5335 +server=/.myeclipseide.com/127.0.0.1#5335 +server=/.myforum.com.hk/127.0.0.1#5335 +server=/.myforum.com.uk/127.0.0.1#5335 +server=/.myfreshnet.com/127.0.0.1#5335 +server=/.my.keso.cn/127.0.0.1#5335 +server=/.myopenid.com/127.0.0.1#5335 +server=/.my.opera.com/127.0.0.1#5335 +server=/.mypaper.pchome.com.tw/127.0.0.1#5335 +server=/.myparagliding.com/127.0.0.1#5335 +server=/.mypopescu.com/127.0.0.1#5335 +server=/.my-proxy.com/127.0.0.1#5335 +server=/.myshare.url.com.tw/127.0.0.1#5335 +server=/.mysinablog.com/127.0.0.1#5335 +server=/.myspace.com/127.0.0.1#5335 +server=/.myvlog.im.tv/127.0.0.1#5335 +server=/.naacoalition.org/127.0.0.1#5335 +server=/.naitik.net/127.0.0.1#5335 +server=/.nakido.com/127.0.0.1#5335 +server=/.namsisi.com/127.0.0.1#5335 +server=/.nanyang.com/127.0.0.1#5335 +server=/.nanyangpost.com/127.0.0.1#5335 +server=/.nanzao.com/127.0.0.1#5335 +server=/.naol.ca/127.0.0.1#5335 +server=/.national-lottery.co.uk/127.0.0.1#5335 +server=/.navicat.com/127.0.0.1#5335 +server=/.navigeaters.com/127.0.0.1#5335 +server=/.navy.mil/127.0.0.1#5335 +server=/.nccwatch.org.tw/127.0.0.1#5335 +server=/.ncdr.nat.gov.tw/127.0.0.1#5335 +server=/.nch.com.tw/127.0.0.1#5335 +server=/.ncn.org/127.0.0.1#5335 +server=/.ncree.gov.tw/127.0.0.1#5335 +server=/.nde.de/127.0.0.1#5335 +server=/.ndr.de/127.0.0.1#5335 +server=/.nekoslovakia.net/127.0.0.1#5335 +server=/.nerch.gov.tw/127.0.0.1#5335 +server=/.ner.gov.tw/127.0.0.1#5335 +server=/.nerhl.gov.tw/127.0.0.1#5335 +server=/.nertt.gov.tw/127.0.0.1#5335 +server=/.netcolony.com/127.0.0.1#5335 +server=/.netflix.com/127.0.0.1#5335 +server=/.netme.cc/127.0.0.1#5335 +server=/.networkedblogs.com/127.0.0.1#5335 +server=/.neverforget8964.org/127.0.0.1#5335 +server=/.new-3lunch.net/127.0.0.1#5335 +server=/.new-akiba.com/127.0.0.1#5335 +server=/.newcenturymc.com/127.0.0.1#5335 +server=/.newcenturynews.com/127.0.0.1#5335 +server=/.newchen.com/127.0.0.1#5335 +server=/.newgrounds.com/127.0.0.1#5335 +server=/.newlandmagazine.com.au/127.0.0.1#5335 +server=/.news100.com.tw/127.0.0.1#5335 +server=/.newsancai.com/127.0.0.1#5335 +server=/.news.atebits.com/127.0.0.1#5335 +server=/.news.backchina.com/127.0.0.1#5335 +server=/.news.bbc.co.uk/127.0.0.1#5335 +server=/.newscn.org/127.0.0.1#5335 +server=/.news.cnyes.com/127.0.0.1#5335 +server=/.newsforums.bbc.co.uk/127.0.0.1#5335 +server=/.news.ghostery.com/127.0.0.1#5335 +server=/.news.google.com.hk/127.0.0.1#5335 +server=/.newsminer.com/127.0.0.1#5335 +server=/.news.msn.com.tw/127.0.0.1#5335 +server=/.news.omy.sg/127.0.0.1#5335 +server=/.news.pchome.com.tw/127.0.0.1#5335 +server=/.newspeak.cc/127.0.0.1#5335 +server=/.newspp.org/127.0.0.1#5335 +server=/.news.sina.com.hk/127.0.0.1#5335 +server=/.news.sina.com.tw/127.0.0.1#5335 +server=/.news.singtao.ca/127.0.0.1#5335 +server=/.newstapa.org/127.0.0.1#5335 +server=/.newtaiwan.com.tw/127.0.0.1#5335 +server=/.newtalk.tw/127.0.0.1#5335 +server=/.newyorktimes.com/127.0.0.1#5335 +server=/.nexton-net.jp/127.0.0.1#5335 +server=/.nexttv.com.tw/127.0.0.1#5335 +server=/.nf.id.au/127.0.0.1#5335 +server=/.nga.mil/127.0.0.1#5335 +server=/.ngensis.com/127.0.0.1#5335 +server=/.nhri.gov.tw/127.0.0.1#5335 +server=/.nic.cz.cc/127.0.0.1#5335 +server=/.nici.nat.gov.tw/127.0.0.1#5335 +server=/.nicovideo.tw/127.0.0.1#5335 +server=/.nict.gov.tw/127.0.0.1#5335 +server=/.nighost.org/127.0.0.1#5335 +server=/.nintendium.com/127.0.0.1#5335 +server=/.nintendowifi.net/127.0.0.1#5335 +server=/.njactb.org/127.0.0.1#5335 +server=/.njuice.com/127.0.0.1#5335 +server=/.nlfreevpn.com/127.0.0.1#5335 +server=/.nmh.gov.tw/127.0.0.1#5335 +server=/.nmmba.gov.tw/127.0.0.1#5335 +server=/.nmp.gov.tw/127.0.0.1#5335 +server=/.nmtl.gov.tw/127.0.0.1#5335 +server=/.nmvttc.gov.tw/127.0.0.1#5335 +server=/.nobelprize.org/127.0.0.1#5335 +server=/.nobel.se/127.0.0.1#5335 +server=/.nobodycanstop.us/127.0.0.1#5335 +server=/.nokogiri.org/127.0.0.1#5335 +server=/.nokola.com/127.0.0.1#5335 +server=/.noobbox.com/127.0.0.1#5335 +server=/.notes.alexdong.com/127.0.0.1#5335 +server=/.novelasia.com/127.0.0.1#5335 +server=/.nownews.com/127.0.0.1#5335 +server=/.nowtorrents.com/127.0.0.1#5335 +server=/.noypf.com/127.0.0.1#5335 +server=/.npa.go.jp/127.0.0.1#5335 +server=/.npm.gov.tw/127.0.0.1#5335 +server=/.nps.gov/127.0.0.1#5335 +server=/.nrk.no/127.0.0.1#5335 +server=/.nsc.gov.tw/127.0.0.1#5335 +server=/.nspo.gov.tw/127.0.0.1#5335 +server=/.nstm.gov.tw/127.0.0.1#5335 +server=/.ntdmh.gov.tw/127.0.0.1#5335 +server=/.ntdtv.ca/127.0.0.1#5335 +server=/.ntdtv.co/127.0.0.1#5335 +server=/.ntdtv.com/127.0.0.1#5335 +server=/.ntdtv.org/127.0.0.1#5335 +server=/.ntdtv.ru/127.0.0.1#5335 +server=/.ntl.gov.tw/127.0.0.1#5335 +server=/.ntsec.gov.tw/127.0.0.1#5335 +server=/.ntuh.gov.tw/127.0.0.1#5335 +server=/.nuexpo.com/127.0.0.1#5335 +server=/.nurgo-software.com/127.0.0.1#5335 +server=/.nuvid.com/127.0.0.1#5335 +server=/.nuzcom.com/127.0.0.1#5335 +server=/.nvquan.org/127.0.0.1#5335 +server=/.nvri.gov.tw/127.0.0.1#5335 +server=/.nydus.ca/127.0.0.1#5335 +server=/.nysingtao.com/127.0.0.1#5335 +server=/.nytco.com/127.0.0.1#5335 +server=/.nyt.com/127.0.0.1#5335 +server=/.nytimes.com/127.0.0.1#5335 +server=/.nytimg.com/127.0.0.1#5335 +server=/.nzchinese.net.nz/127.0.0.1#5335 +server=/.observechina.net/127.0.0.1#5335 +server=/.oclp.hk/127.0.0.1#5335 +server=/.october-review.org/127.0.0.1#5335 +server=/.offbeatchina.com/127.0.0.1#5335 +server=/.ogaoga.org/127.0.0.1#5335 +server=/.oikos.com.tw/127.0.0.1#5335 +server=/.oiktv.com/127.0.0.1#5335 +server=/.oizoblog.com/127.0.0.1#5335 +server=/.okayfreedom.com/127.0.0.1#5335 +server=/.old-cat.net/127.0.0.1#5335 +server=/.old.nabble.com/127.0.0.1#5335 +server=/.olumpo.com/127.0.0.1#5335 +server=/.olympicwatch.org/127.0.0.1#5335 +server=/.omgili.com/127.0.0.1#5335 +server=/.omnitalk.com/127.0.0.1#5335 +server=/.on.cc/127.0.0.1#5335 +server=/.one.xthost.info/127.0.0.1#5335 +server=/.onlylady.cn/127.0.0.1#5335 +server=/.onmoon.com/127.0.0.1#5335 +server=/.onmoon.net/127.0.0.1#5335 +server=/.oopsforum.com/127.0.0.1#5335 +server=/.ooyala.com/127.0.0.1#5335 +server=/.open.com.hk/127.0.0.1#5335 +server=/.opendemocracy.net/127.0.0.1#5335 +server=/.openid.net/127.0.0.1#5335 +server=/.openleaks.org/127.0.0.1#5335 +server=/.openvpn.net/127.0.0.1#5335 +server=/.openvpn.org/127.0.0.1#5335 +server=/.openwebster.com/127.0.0.1#5335 +server=/.opml.radiotime.com/127.0.0.1#5335 +server=/.opnir.com/127.0.0.1#5335 +server=/.orientaldaily.com.my/127.0.0.1#5335 +server=/.orient-doll.com/127.0.0.1#5335 +server=/.orn.jp/127.0.0.1#5335 +server=/.orzistic.org/127.0.0.1#5335 +server=/.osfoora.com/127.0.0.1#5335 +server=/.ourdearamy.com/127.0.0.1#5335 +server=/.oursogo.com/127.0.0.1#5335 +server=/.oursteps.com.au/127.0.0.1#5335 +server=/.overlapr.com/127.0.0.1#5335 +server=/.owl.li/127.0.0.1#5335 +server=/.ow.ly/127.0.0.1#5335 +server=/.oyax.com/127.0.0.1#5335 +server=/.ozchinese.com/127.0.0.1#5335 +server=/.ozyoyo.com/127.0.0.1#5335 +server=/.pabp.gov.tw/127.0.0.1#5335 +server=/.pacificpoker.com/127.0.0.1#5335 +server=/.packages.debian.org/127.0.0.1#5335 +server=/.packetix.net/127.0.0.1#5335 +server=/.page2rss.com/127.0.0.1#5335 +server=/.page.bid.yahoo.com/127.0.0.1#5335 +server=/.pagodabox.com/127.0.0.1#5335 +server=/.paint.net/127.0.0.1#5335 +server=/.palacemoon.com/127.0.0.1#5335 +server=/.pandora.com/127.0.0.1#5335 +server=/.pandora.tv/127.0.0.1#5335 +server=/.panluan.net/127.0.0.1#5335 +server=/.panoramio.com/127.0.0.1#5335 +server=/.pao-pao.net/127.0.0.1#5335 +server=/.paperb.us/127.0.0.1#5335 +server=/.paper.li/127.0.0.1#5335 +server=/.paper-replika.com/127.0.0.1#5335 +server=/.parade.com/127.0.0.1#5335 +server=/.parislemon.com/127.0.0.1#5335 +server=/.pastebin.com/127.0.0.1#5335 +server=/.pastie.org/127.0.0.1#5335 +server=/.patehr.gov.tw/127.0.0.1#5335 +server=/.pbs.org/127.0.0.1#5335 +server=/.pbwiki.com/127.0.0.1#5335 +server=/.pbworks.com/127.0.0.1#5335 +server=/.pbxes.com/127.0.0.1#5335 +server=/.pbxes.org/127.0.0.1#5335 +server=/.pcdiscuss.com/127.0.0.1#5335 +server=/.pcdvd.com.tw/127.0.0.1#5335 +server=/.pchome.com.tw/127.0.0.1#5335 +server=/.pct.org.tw/127.0.0.1#5335 +server=/.pcworld.com/127.0.0.1#5335 +server=/.pdetails.com/127.0.0.1#5335 +server=/.pdproxy.com/127.0.0.1#5335 +server=/.peacefire.org/127.0.0.1#5335 +server=/.peacehall.com/127.0.0.1#5335 +server=/.peeasian.com/127.0.0.1#5335 +server=/.peerpong.com/127.0.0.1#5335 +server=/.pekingduck.org/127.0.0.1#5335 +server=/.penchinese.com/127.0.0.1#5335 +server=/.penchinese.net/127.0.0.1#5335 +server=/.pengyulong.com/127.0.0.1#5335 +server=/.penthouse.com/127.0.0.1#5335 +server=/.peopo.org/127.0.0.1#5335 +server=/.percy.in/127.0.0.1#5335 +server=/.perfectgirls.net/127.0.0.1#5335 +server=/.perfectvpn.net/127.0.0.1#5335 +server=/.perfspot.com/127.0.0.1#5335 +server=/.perlhowto.com/127.0.0.1#5335 +server=/.pet.gov.tw/127.0.0.1#5335 +server=/.philly.com/127.0.0.1#5335 +server=/.photofocus.com/127.0.0.1#5335 +server=/.photos.dailyme.com/127.0.0.1#5335 +server=/.photo.utom.us/127.0.0.1#5335 +server=/.phuquocservices.com/127.0.0.1#5335 +server=/.picasaweb.google.com/127.0.0.1#5335 +server=/.picidae.net/127.0.0.1#5335 +server=/.picturesocial.com/127.0.0.1#5335 +server=/.pictures.playboy.com/127.0.0.1#5335 +server=/.pidown.com/127.0.0.1#5335 +server=/.pign.net/127.0.0.1#5335 +server=/.pimg.tw/127.0.0.1#5335 +server=/.pin6.com/127.0.0.1#5335 +server=/.ping.fm/127.0.0.1#5335 +server=/.pinoy-n.com/127.0.0.1#5335 +server=/.pioneer-worker.forums-free.com/127.0.0.1#5335 +server=/.piring.com/127.0.0.1#5335 +server=/.pixanalytics.com/127.0.0.1#5335 +server=/.pixelqi.com/127.0.0.1#5335 +server=/.pixfs.net/127.0.0.1#5335 +server=/.pixnet.cc/127.0.0.1#5335 +server=/.pixnet.net/127.0.0.1#5335 +server=/.pixplug.in/127.0.0.1#5335 +server=/.pk.com/127.0.0.1#5335 +server=/.placemix.com/127.0.0.1#5335 +server=/.planetsuzy.org/127.0.0.1#5335 +server=/.playboy.com/127.0.0.1#5335 +server=/.plays.com.tw/127.0.0.1#5335 +server=/.plm.org.hk/127.0.0.1#5335 +server=/.plunder.com/127.0.0.1#5335 +server=/.plurk.com/127.0.0.1#5335 +server=/.plurktop.mmdays.com/127.0.0.1#5335 +server=/.plus28.com/127.0.0.1#5335 +server=/.plusbb.com/127.0.0.1#5335 +server=/.pmates.com/127.0.0.1#5335 +server=/.po2b.com/127.0.0.1#5335 +server=/.podictionary.com/127.0.0.1#5335 +server=/.pokerstars.com/127.0.0.1#5335 +server=/.politicalchina.org/127.0.0.1#5335 +server=/.popvote.hk/127.0.0.1#5335 +server=/.popyard.com/127.0.0.1#5335 +server=/.popyard.org/127.0.0.1#5335 +server=/.porn2.com/127.0.0.1#5335 +server=/.pornbase.org/127.0.0.1#5335 +server=/.porn.com/127.0.0.1#5335 +server=/.pornhub.com/127.0.0.1#5335 +server=/.pornmm.net/127.0.0.1#5335 +server=/.pornoxo.com/127.0.0.1#5335 +server=/.pornrapidshare.com/127.0.0.1#5335 +server=/.pornstarclub.com/127.0.0.1#5335 +server=/.porntube.com/127.0.0.1#5335 +server=/.pornvisit.com/127.0.0.1#5335 +server=/.portis21.spaces.live.com/127.0.0.1#5335 +server=/.pose.com/127.0.0.1#5335 +server=/.postadult.com/127.0.0.1#5335 +server=/.post.anyu.org/127.0.0.1#5335 +server=/.posterous.com/127.0.0.1#5335 +server=/.post.ly/127.0.0.1#5335 +server=/.powerapple.com/127.0.0.1#5335 +server=/.power.com/127.0.0.1#5335 +server=/.powercx.com/127.0.0.1#5335 +server=/.prayforchina.net/127.0.0.1#5335 +server=/.premeforwindows7.com/127.0.0.1#5335 +server=/.presentationzen.com/127.0.0.1#5335 +server=/.president.gov.tw/127.0.0.1#5335 +server=/.prestige-av.com/127.0.0.1#5335 +server=/.previewshots.com/127.0.0.1#5335 +server=/.privacybox.de/127.0.0.1#5335 +server=/.privateinternetaccess.com/127.0.0.1#5335 +server=/.privatepaste.com/127.0.0.1#5335 +server=/.privatetunnel.com/127.0.0.1#5335 +server=/.procopytips.com/127.0.0.1#5335 +server=/.program-think.spaces.live.com/127.0.0.1#5335 +server=/.prosiben.de/127.0.0.1#5335 +server=/.provideocoalition.com/127.0.0.1#5335 +server=/.proxifier.com/127.0.0.1#5335 +server=/.proxomitron.info/127.0.0.1#5335 +server=/.proxy.org/127.0.0.1#5335 +server=/.proxypy.net/127.0.0.1#5335 +server=/.proxyroad.com/127.0.0.1#5335 +server=/.prozz.net/127.0.0.1#5335 +server=/.psblog.name/127.0.0.1#5335 +server=/.psiphon.ca/127.0.0.1#5335 +server=/.psiphon.civisec.org/127.0.0.1#5335 +server=/.pts.org.tw/127.0.0.1#5335 +server=/.ptt.cc/127.0.0.1#5335 +server=/.pubu.com.tw/127.0.0.1#5335 +server=/.puffinbrowser.com/127.0.0.1#5335 +server=/.puffstore.com/127.0.0.1#5335 +server=/.pullfolio.com/127.0.0.1#5335 +server=/.pulse.yahoo.com/127.0.0.1#5335 +server=/.pure18.com/127.0.0.1#5335 +server=/.pureconcepts.net/127.0.0.1#5335 +server=/.purepdf.com/127.0.0.1#5335 +server=/.purevpn.com/127.0.0.1#5335 +server=/.putlocker.com/127.0.0.1#5335 +server=/.puttycm.free.fr/127.0.0.1#5335 +server=/.pwned.com/127.0.0.1#5335 +server=/.python.com/127.0.0.1#5335 +server=/.python.com.tw/127.0.0.1#5335 +server=/.qanote.com/127.0.0.1#5335 +server=/.qidian.ca/127.0.0.1#5335 +server=/.qienkuen.org/127.0.0.1#5335 +server=/.qi-gong.me/127.0.0.1#5335 +server=/.qiwen.lu/127.0.0.1#5335 +server=/.qixianglu.cn/127.0.0.1#5335 +server=/.qkshare.com/127.0.0.1#5335 +server=/.qoos.com/127.0.0.1#5335 +server=/.qq.co.za/127.0.0.1#5335 +server=/.qstatus.com/127.0.0.1#5335 +server=/.qtrac.eu/127.0.0.1#5335 +server=/.qtweeter.com/127.0.0.1#5335 +server=/.quadedge.com/127.0.0.1#5335 +server=/.qusi8.net/127.0.0.1#5335 +server=/.qvodzy.org/127.0.0.1#5335 +server=/.qxbbs.org/127.0.0.1#5335 +server=/.radicalparty.org/127.0.0.1#5335 +server=/.radioaustralia.net.au/127.0.0.1#5335 +server=/.radiovaticana.org/127.0.0.1#5335 +server=/.radiovncr.com/127.0.0.1#5335 +server=/.raidcall.com.tw/127.0.0.1#5335 +server=/.rangzen.org/127.0.0.1#5335 +server=/.ranyunfei.com/127.0.0.1#5335 +server=/.rapbull.net/127.0.0.1#5335 +server=/.rapidshare8.com/127.0.0.1#5335 +server=/.rapidsharedata.com/127.0.0.1#5335 +server=/.rayfme.com/127.0.0.1#5335 +server=/.rcinet.ca/127.0.0.1#5335 +server=/.rconversation.blogs.com/127.0.0.1#5335 +server=/.rdio.com/127.0.0.1#5335 +server=/.read100.com/127.0.0.1#5335 +server=/.readingtimes.com.tw/127.0.0.1#5335 +server=/.readmoo.com/127.0.0.1#5335 +server=/.realraptalk.com/127.0.0.1#5335 +server=/.recordhistory.org/127.0.0.1#5335 +server=/.redchinacn.org/127.0.0.1#5335 +server=/.redtube.com/127.0.0.1#5335 +server=/.referer.us/127.0.0.1#5335 +server=/.reflectivecode.com/127.0.0.1#5335 +server=/.relaxbbs.com/127.0.0.1#5335 +server=/.renminbao.com/127.0.0.1#5335 +server=/.renyurenquan.org/127.0.0.1#5335 +server=/.retweeteffect.com/127.0.0.1#5335 +server=/.retweetist.com/127.0.0.1#5335 +server=/.retweetrank.com/127.0.0.1#5335 +server=/.revleft.com/127.0.0.1#5335 +server=/.revsci.net/127.0.0.1#5335 +server=/.revver.com/127.0.0.1#5335 +server=/.rfachina.com/127.0.0.1#5335 +server=/.rfamobile.org/127.0.0.1#5335 +server=/.rfa.org/127.0.0.1#5335 +server=/.rferl.org/127.0.0.1#5335 +server=/.rfi.fr/127.0.0.1#5335 +server=/.rhcloud.com/127.0.0.1#5335 +server=/.riku.me/127.0.0.1#5335 +server=/.rileyguide.com/127.0.0.1#5335 +server=/.rlwlw.com/127.0.0.1#5335 +server=/.rmjdw.com/127.0.0.1#5335 +server=/.rnw.nl/127.0.0.1#5335 +server=/.robtex.com/127.0.0.1#5335 +server=/.robustnessiskey.com/127.0.0.1#5335 +server=/.rocmp.org/127.0.0.1#5335 +server=/.rojo.com/127.0.0.1#5335 +server=/.ronjoneswriter.com/127.0.0.1#5335 +server=/.roodo.com/127.0.0.1#5335 +server=/.rotten.com/127.0.0.1#5335 +server=/.rsf-chinese.org/127.0.0.1#5335 +server=/.rsf.org/127.0.0.1#5335 +server=/.rssmeme.com/127.0.0.1#5335 +server=/.rthk.hk/127.0.0.1#5335 +server=/.rthk.org.hk/127.0.0.1#5335 +server=/.rti.org.tw/127.0.0.1#5335 +server=/.ruanyifeng.com/127.0.0.1#5335 +server=/.rushbee.com/127.0.0.1#5335 +server=/.rutube.ru/127.0.0.1#5335 +server=/.ruyiseek.com/127.0.0.1#5335 +server=/.rxhj.net/127.0.0.1#5335 +server=/.s1heng.com/127.0.0.1#5335 +server=/.s8forum.com/127.0.0.1#5335 +server=/.sacom.hk/127.0.0.1#5335 +server=/.sadpanda.us/127.0.0.1#5335 +server=/.saiq.me/127.0.0.1#5335 +server=/.salvation.org.hk/127.0.0.1#5335 +server=/.samair.ru/127.0.0.1#5335 +server=/.sammyjs.org/127.0.0.1#5335 +server=/.samsoff.es/127.0.0.1#5335 +server=/.sandnoble.com/127.0.0.1#5335 +server=/.sankaizok.com/127.0.0.1#5335 +server=/.sanmin.com.tw/127.0.0.1#5335 +server=/.sapikachu.net/127.0.0.1#5335 +server=/.savemedia.com/127.0.0.1#5335 +server=/.savetibet.de/127.0.0.1#5335 +server=/.savetibet.fr/127.0.0.1#5335 +server=/.savetibet.nl/127.0.0.1#5335 +server=/.savetibet.org/127.0.0.1#5335 +server=/.savetibet.ru/127.0.0.1#5335 +server=/.savevid.com/127.0.0.1#5335 +server=/.say2.info/127.0.0.1#5335 +server=/.scanscout.com/127.0.0.1#5335 +server=/.scmpchinese.com/127.0.0.1#5335 +server=/.scmp.com/127.0.0.1#5335 +server=/.scorecardresearch.com/127.0.0.1#5335 +server=/.scribd.com/127.0.0.1#5335 +server=/.scriptspot.com/127.0.0.1#5335 +server=/.seapuff.com/127.0.0.1#5335 +server=/.secretchina.com/127.0.0.1#5335 +server=/.secretgarden.no/127.0.0.1#5335 +server=/.secure.wikimedia.org/127.0.0.1#5335 +server=/.securitykiss.com/127.0.0.1#5335 +server=/.seesmic.com/127.0.0.1#5335 +server=/.seevpn.com/127.0.0.1#5335 +server=/.seezone.net/127.0.0.1#5335 +server=/.sejie.com/127.0.0.1#5335 +server=/.sendoid.com/127.0.0.1#5335 +server=/.sendspace.com/127.0.0.1#5335 +server=/.sesawe.net/127.0.0.1#5335 +server=/.sesawe.org/127.0.0.1#5335 +server=/.sethwklein.net/127.0.0.1#5335 +server=/.sevenload.com/127.0.0.1#5335 +server=/.sex-11.com/127.0.0.1#5335 +server=/.sex3.com/127.0.0.1#5335 +server=/.sex8.cc/127.0.0.1#5335 +server=/.sexandsubmission.com/127.0.0.1#5335 +server=/.sex.com/127.0.0.1#5335 +server=/.sexhuang.com/127.0.0.1#5335 +server=/.sexhu.com/127.0.0.1#5335 +server=/.sexinsex.net/127.0.0.1#5335 +server=/.sfileydy.com/127.0.0.1#5335 +server=/.shadow.ma/127.0.0.1#5335 +server=/.shadowsocks.org/127.0.0.1#5335 +server=/.shahamat-english.com/127.0.0.1#5335 +server=/.shangfang.org/127.0.0.1#5335 +server=/.shapeservices.com/127.0.0.1#5335 +server=/.sharebee.com/127.0.0.1#5335 +server=/.sharecool.org/127.0.0.1#5335 +server=/.share.ovi.com/127.0.0.1#5335 +server=/.share.skype.com/127.0.0.1#5335 +server=/.share.youthwant.com.tw/127.0.0.1#5335 +server=/.sharkdolphin.com/127.0.0.1#5335 +server=/.sharpdaily.com.hk/127.0.0.1#5335 +server=/.sharpdaily.hk/127.0.0.1#5335 +server=/.shaunthesheep.com/127.0.0.1#5335 +server=/.sheikyermami.com/127.0.0.1#5335 +server=/.shellmix.com/127.0.0.1#5335 +server=/.shenshou.org/127.0.0.1#5335 +server=/.shenyunperformingarts.org/127.0.0.1#5335 +server=/.shenzhoufilm.com/127.0.0.1#5335 +server=/.shifeike.blog125.fc2blog.net/127.0.0.1#5335 +server=/.shinychan.com/127.0.0.1#5335 +server=/.shitaotv.org/127.0.0.1#5335 +server=/.shixiao.org/127.0.0.1#5335 +server=/.shizhao.org/127.0.0.1#5335 +server=/.shkspr.mobi/127.0.0.1#5335 +server=/.shodanhq.com/127.0.0.1#5335 +server=/.shopping.com/127.0.0.1#5335 +server=/.showbiz.omy.sg/127.0.0.1#5335 +server=/.showtime.jp/127.0.0.1#5335 +server=/.shwchurch3.com/127.0.0.1#5335 +server=/.sidelinesnews.com/127.0.0.1#5335 +server=/.sidelinessportseatery.com/127.0.0.1#5335 +server=/.simplecd.me/127.0.0.1#5335 +server=/.simplecd.org/127.0.0.1#5335 +server=/.simpleproductivityblog.com/127.0.0.1#5335 +server=/.sina.com.tw/127.0.0.1#5335 +server=/.singtao.com/127.0.0.1#5335 +server=/.singularitys.spaces.live.com/127.0.0.1#5335 +server=/.sinoants.com/127.0.0.1#5335 +server=/.sinocast.com/127.0.0.1#5335 +server=/.sinocism.com/127.0.0.1#5335 +server=/.sino-monthly.com/127.0.0.1#5335 +server=/.sinomontreal.ca/127.0.0.1#5335 +server=/.sinonet.ca/127.0.0.1#5335 +server=/.sinopitt.info/127.0.0.1#5335 +server=/.sinoquebec.com/127.0.0.1#5335 +server=/.sis001.com/127.0.0.1#5335 +server=/.sis001.us/127.0.0.1#5335 +server=/.sis.xxx/127.0.0.1#5335 +server=/.site90.net/127.0.0.1#5335 +server=/.sitebro.tw/127.0.0.1#5335 +server=/.siteks.uk.to/127.0.0.1#5335 +server=/.site.locql.com/127.0.0.1#5335 +server=/.sitemaps.org/127.0.0.1#5335 +server=/.sites.google.com/127.0.0.1#5335 +server=/.sitetag.us/127.0.0.1#5335 +server=/.siyi123123123.spaces.live.com/127.0.0.1#5335 +server=/.skimtube.com/127.0.0.1#5335 +server=/.skybet.com/127.0.0.1#5335 +server=/.skyvegas.com/127.0.0.1#5335 +server=/.slacker.com/127.0.0.1#5335 +server=/.slavasoft.com/127.0.0.1#5335 +server=/.slheng.com/127.0.0.1#5335 +server=/.slickvpn.com/127.0.0.1#5335 +server=/.slideshare.net/127.0.0.1#5335 +server=/.slinkset.com/127.0.0.1#5335 +server=/.slutload.com/127.0.0.1#5335 +server=/.smhric.org/127.0.0.1#5335 +server=/.snapchat.com/127.0.0.1#5335 +server=/.snaptu.com/127.0.0.1#5335 +server=/.sndcdn.com/127.0.0.1#5335 +server=/.sneakme.net/127.0.0.1#5335 +server=/.snooper.co.uk/127.0.0.1#5335 +server=/.sobees.com/127.0.0.1#5335 +server=/.socialwhale.com/127.0.0.1#5335 +server=/.sockslist.net/127.0.0.1#5335 +server=/.sod.co.jp/127.0.0.1#5335 +server=/.softether.co.jp/127.0.0.1#5335 +server=/.softether-download.com/127.0.0.1#5335 +server=/.softether.org/127.0.0.1#5335 +server=/.softwarebychuck.com/127.0.0.1#5335 +server=/.so-ga.net/127.0.0.1#5335 +server=/.sogclub.com/127.0.0.1#5335 +server=/.sogrady.me/127.0.0.1#5335 +server=/.sohcradio.com/127.0.0.1#5335 +server=/.sohfrance.org/127.0.0.1#5335 +server=/.soh.tw/127.0.0.1#5335 +server=/.sokamonline.com/127.0.0.1#5335 +server=/.solozorro.tk/127.0.0.1#5335 +server=/.somee.com/127.0.0.1#5335 +server=/.so-news.com/127.0.0.1#5335 +server=/.songjianjun.com/127.0.0.1#5335 +server=/.sonidodelaesperanza.org/127.0.0.1#5335 +server=/.sopcast.com/127.0.0.1#5335 +server=/.sopcast.org/127.0.0.1#5335 +server=/.sorting-algorithms.com/127.0.0.1#5335 +server=/.soumo.info/127.0.0.1#5335 +server=/.soundcloud.com/127.0.0.1#5335 +server=/.soundofhope.kr/127.0.0.1#5335 +server=/.soundofhope.org/127.0.0.1#5335 +server=/.soupofmedia.com/127.0.0.1#5335 +server=/.sourceforge.net/127.0.0.1#5335 +server=/.southnews.com.tw/127.0.0.1#5335 +server=/.sowers.org.hk/127.0.0.1#5335 +server=/.space-scape.com/127.0.0.1#5335 +server=/.spankwire.com/127.0.0.1#5335 +server=/.spb.com/127.0.0.1#5335 +server=/.speckleapp.com/127.0.0.1#5335 +server=/.speedpluss.org/127.0.0.1#5335 +server=/.spencertipping.com/127.0.0.1#5335 +server=/.spinejs.com/127.0.0.1#5335 +server=/.sports.williamhill.com/127.0.0.1#5335 +server=/.spotify.com/127.0.0.1#5335 +server=/.sproutcore.com/127.0.0.1#5335 +server=/.squarespace.com/127.0.0.1#5335 +server=/.srcf.ucam.org/127.0.0.1#5335 +server=/.ssh91.com/127.0.0.1#5335 +server=/.sshtunnel.googlecode.com/127.0.0.1#5335 +server=/.sstatic.net/127.0.0.1#5335 +server=/.stag.gov.tw/127.0.0.1#5335 +server=/.standupfortibet.org/127.0.0.1#5335 +server=/.starp2p.com/127.0.0.1#5335 +server=/.startpage.com/127.0.0.1#5335 +server=/.statcounter.com/127.0.0.1#5335 +server=/.state168.com/127.0.0.1#5335 +server=/.static.apple.nextmedia.com/127.0.0.1#5335 +server=/.static.digg.com/127.0.0.1#5335 +server=/.staticflickr.com/127.0.0.1#5335 +server=/.static.nownews.com/127.0.0.1#5335 +server=/.static.soup.io/127.0.0.1#5335 +server=/.static.typepad.com/127.0.0.1#5335 +server=/.status.twhirl.org/127.0.0.1#5335 +server=/.stdtime.gov.tw/127.0.0.1#5335 +server=/.steel-storm.com/127.0.0.1#5335 +server=/.sthoo.com/127.0.0.1#5335 +server=/.stickam.com/127.0.0.1#5335 +server=/.stickeraction.com/127.0.0.1#5335 +server=/.stonegames.net/127.0.0.1#5335 +server=/.stoneip.info/127.0.0.1#5335 +server=/.stoptibetcrisis.net/127.0.0.1#5335 +server=/.storagenewsletter.com/127.0.0.1#5335 +server=/.stoweboyd.com/127.0.0.1#5335 +server=/.streamingthe.net/127.0.0.1#5335 +server=/.strongvpn.com/127.0.0.1#5335 +server=/.student.tw/127.0.0.1#5335 +server=/.stuffimreading.com/127.0.0.1#5335 +server=/.stuffimreading.net/127.0.0.1#5335 +server=/.stupidvideos.com/127.0.0.1#5335 +server=/.subacme.rerouted.org/127.0.0.1#5335 +server=/.sublexical.spaces.live.com/127.0.0.1#5335 +server=/.sufeng.org/127.0.0.1#5335 +server=/.sugarsync.com/127.0.0.1#5335 +server=/.summify.com/127.0.0.1#5335 +server=/.sun1911.com/127.0.0.1#5335 +server=/.suoluo.org/127.0.0.1#5335 +server=/.surfeasy.com.au/127.0.0.1#5335 +server=/.svwind.com/127.0.0.1#5335 +server=/.sweux.com/127.0.0.1#5335 +server=/.swift-tools.net/127.0.0.1#5335 +server=/.s.xiaod.in/127.0.0.1#5335 +server=/.sydneytoday.com/127.0.0.1#5335 +server=/.sylfoundation.org/127.0.0.1#5335 +server=/.syncback.com/127.0.0.1#5335 +server=/.sysadmin1138.net/127.0.0.1#5335 +server=/.sysresccd.org/127.0.0.1#5335 +server=/.sytes.net/127.0.0.1#5335 +server=/.szbbs.net/127.0.0.1#5335 +server=/.szetowah.org.hk/127.0.0.1#5335 +server=/.t35.com/127.0.0.1#5335 +server=/.t66y.com/127.0.0.1#5335 +server=/.taa-usa.org/127.0.0.1#5335 +server=/.tabtter.jp/127.0.0.1#5335 +server=/.tacem.org/127.0.0.1#5335 +server=/.tafaward.com/127.0.0.1#5335 +server=/.tagwalk.com/127.0.0.1#5335 +server=/.taipei.gov.tw/127.0.0.1#5335 +server=/.taipeisociety.org/127.0.0.1#5335 +server=/.taitung-house.gov.tw/127.0.0.1#5335 +server=/.taiwandaily.net/127.0.0.1#5335 +server=/.taiwankiss.com/127.0.0.1#5335 +server=/.taiwannation.50webs.com/127.0.0.1#5335 +server=/.taiwannation.com/127.0.0.1#5335 +server=/.taiwannation.com.tw/127.0.0.1#5335 +server=/.taiwannews.com.tw/127.0.0.1#5335 +server=/.taiwan-sex.com/127.0.0.1#5335 +server=/.taiwantt.org.tw/127.0.0.1#5335 +server=/.taiwanus.net/127.0.0.1#5335 +server=/.taiwanyes.com/127.0.0.1#5335 +server=/.taiwanyes.ning.com/127.0.0.1#5335 +server=/.tamiaode.tk/127.0.0.1#5335 +server=/.tanc.org/127.0.0.1#5335 +server=/.tangben.com/127.0.0.1#5335 +server=/.taolun.info/127.0.0.1#5335 +server=/.taoyuan.gov.tw/127.0.0.1#5335 +server=/.tap11.com/127.0.0.1#5335 +server=/.target.com/127.0.0.1#5335 +server=/.taweet.com/127.0.0.1#5335 +server=/.tax.nat.gov.tw/127.0.0.1#5335 +server=/.tbpic.info/127.0.0.1#5335 +server=/.tbsec.org/127.0.0.1#5335 +server=/.tbsn.org/127.0.0.1#5335 +server=/.tbsseattle.org/127.0.0.1#5335 +server=/.tchb.gov.tw/127.0.0.1#5335 +server=/.tchrd.org/127.0.0.1#5335 +server=/.t.co/127.0.0.1#5335 +server=/.tcsac.gov.tw/127.0.0.1#5335 +server=/.teamseesmic.com/127.0.0.1#5335 +server=/.teashark.com/127.0.0.1#5335 +server=/.techlifeweb.com/127.0.0.1#5335 +server=/.techparaiso.com/127.0.0.1#5335 +server=/.telecomspace.com/127.0.0.1#5335 +server=/.telegraph.co.uk/127.0.0.1#5335 +server=/.tenacy.com/127.0.0.1#5335 +server=/.thbstc.gov.tw/127.0.0.1#5335 +server=/.theampfactory.com/127.0.0.1#5335 +server=/.theappleblog.com/127.0.0.1#5335 +server=/.theatrum-belli.com/127.0.0.1#5335 +server=/.thebcomplex.com/127.0.0.1#5335 +server=/.theblemish.com/127.0.0.1#5335 +server=/.thebodyshop-usa.com/127.0.0.1#5335 +server=/.thechinabeat.org/127.0.0.1#5335 +server=/.thedailywh.at/127.0.0.1#5335 +server=/.thedieline.com/127.0.0.1#5335 +server=/.thedw.us/127.0.0.1#5335 +server=/.thegatesnotes.com/127.0.0.1#5335 +server=/.thehots.info/127.0.0.1#5335 +server=/.thehousenews.com/127.0.0.1#5335 +server=/.thehungrydudes.com/127.0.0.1#5335 +server=/.thehun.net/127.0.0.1#5335 +server=/.theinternetwishlist.com/127.0.0.1#5335 +server=/.thelifeyoucansave.com/127.0.0.1#5335 +server=/.thelius.org/127.0.0.1#5335 +server=/.thepiratebay.org/127.0.0.1#5335 +server=/.thepiratebay.se/127.0.0.1#5335 +server=/.theqii.info/127.0.0.1#5335 +server=/.thereallove.kr/127.0.0.1#5335 +server=/.thesartorialist.com/127.0.0.1#5335 +server=/.thespeeder.com/127.0.0.1#5335 +server=/.the-sun.on.cc/127.0.0.1#5335 +server=/.thetibetpost.com/127.0.0.1#5335 +server=/.thetrotskymovie.com/127.0.0.1#5335 +server=/.thevivekspot.com/127.0.0.1#5335 +server=/.thewgo.org/127.0.0.1#5335 +server=/.thisav.com/127.0.0.1#5335 +server=/.thisiswhyyouarefat.com/127.0.0.1#5335 +server=/.thkphoto.com/127.0.0.1#5335 +server=/.thomasbernhard.org/127.0.0.1#5335 +server=/.threatchaos.com/127.0.0.1#5335 +server=/.throughnightsfire.com/127.0.0.1#5335 +server=/.t.huhaitai.com/127.0.0.1#5335 +server=/.thumbzilla.com/127.0.0.1#5335 +server=/.thywords.com/127.0.0.1#5335 +server=/.tiananmenmother.org/127.0.0.1#5335 +server=/.tiananmenuniv.com/127.0.0.1#5335 +server=/.tiananmenuniv.net/127.0.0.1#5335 +server=/.tiandixing.org/127.0.0.1#5335 +server=/.tianhuayuan.com/127.0.0.1#5335 +server=/.tiantibooks.org/127.0.0.1#5335 +server=/.tianzhu.org/127.0.0.1#5335 +server=/.tibetalk.com/127.0.0.1#5335 +server=/.tibetanyouthcongress.org/127.0.0.1#5335 +server=/.tibet.at/127.0.0.1#5335 +server=/.tibet.com/127.0.0.1#5335 +server=/.tibetcorps.org/127.0.0.1#5335 +server=/.tibetfund.org/127.0.0.1#5335 +server=/.tibetjustice.org/127.0.0.1#5335 +server=/.tibet.net/127.0.0.1#5335 +server=/.tibetoffice.org/127.0.0.1#5335 +server=/.tibetonline.com/127.0.0.1#5335 +server=/.tibetonline.tv/127.0.0.1#5335 +server=/.tibet.org.tw/127.0.0.1#5335 +server=/.tibetsun.com/127.0.0.1#5335 +server=/.tibetwrites.org/127.0.0.1#5335 +server=/.tidyread.com/127.0.0.1#5335 +server=/.time.com/127.0.0.1#5335 +server=/.times.hinet.net/127.0.0.1#5335 +server=/.tinychat.com/127.0.0.1#5335 +server=/.tinypaste.com/127.0.0.1#5335 +server=/.tinypng.com/127.0.0.1#5335 +server=/.tistory.com/127.0.0.1#5335 +server=/.tjholowaychuk.com/127.0.0.1#5335 +server=/.tkcs-collins.com/127.0.0.1#5335 +server=/.tkforum.tk/127.0.0.1#5335 +server=/.t.kun.im/127.0.0.1#5335 +server=/.tmagazine.com/127.0.0.1#5335 +server=/.tmi.me/127.0.0.1#5335 +server=/.tnaflix.com/127.0.0.1#5335 +server=/.tncsec.gov.tw/127.0.0.1#5335 +server=/.t.neolee.cn/127.0.0.1#5335 +server=/.togetter.com/127.0.0.1#5335 +server=/.tokyo-247.com/127.0.0.1#5335 +server=/.tokyocn.com/127.0.0.1#5335 +server=/.tokyo-hot.com/127.0.0.1#5335 +server=/.tomayko.com/127.0.0.1#5335 +server=/.tomsc.com/127.0.0.1#5335 +server=/.tono-oka.jp/127.0.0.1#5335 +server=/.tonyyan.net/127.0.0.1#5335 +server=/.toodoc.com/127.0.0.1#5335 +server=/.toonel.net/127.0.0.1#5335 +server=/.topic.youthwant.com.tw/127.0.0.1#5335 +server=/.topnews.in/127.0.0.1#5335 +server=/.topshare.us/127.0.0.1#5335 +server=/.topshareware.com/127.0.0.1#5335 +server=/.topstyle4.com/127.0.0.1#5335 +server=/.topsy.com/127.0.0.1#5335 +server=/.tora.to/127.0.0.1#5335 +server=/.tor.blingblingsquad.net/127.0.0.1#5335 +server=/.torproject.org/127.0.0.1#5335 +server=/.torrentcrazy.com/127.0.0.1#5335 +server=/.torrentproject.se/127.0.0.1#5335 +server=/.tor.updatestar.com/127.0.0.1#5335 +server=/.torvpn.com/127.0.0.1#5335 +server=/.t.orzdream.com/127.0.0.1#5335 +server=/.tosh.comedycentral.com/127.0.0.1#5335 +server=/.touch99.com/127.0.0.1#5335 +server=/.toutfr.com/127.0.0.1#5335 +server=/.tpde.aide.gov.tw/127.0.0.1#5335 +server=/.tphcc.gov.tw/127.0.0.1#5335 +server=/.tpi.org.tw/127.0.0.1#5335 +server=/.transgressionism.org/127.0.0.1#5335 +server=/.transparency.org/127.0.0.1#5335 +server=/.travelinlocal.com/127.0.0.1#5335 +server=/.trendsmap.com/127.0.0.1#5335 +server=/.trialofccp.org/127.0.0.1#5335 +server=/.tripod.com/127.0.0.1#5335 +server=/.trouw.nl/127.0.0.1#5335 +server=/.trtc.com.tw/127.0.0.1#5335 +server=/.trt.net.tr/127.0.0.1#5335 +server=/.trulyergonomic.com/127.0.0.1#5335 +server=/.trustedbi.com/127.0.0.1#5335 +server=/.truth101.co.tv/127.0.0.1#5335 +server=/.truthcn.com/127.0.0.1#5335 +server=/.truveo.com/127.0.0.1#5335 +server=/.tsctv.net/127.0.0.1#5335 +server=/.tsemtulku.com/127.0.0.1#5335 +server=/.tsquare.tv/127.0.0.1#5335 +server=/.tsunagarumon.com/127.0.0.1#5335 +server=/.tt1069.com/127.0.0.1#5335 +server=/.tttan.com/127.0.0.1#5335 +server=/.tuanzt.com/127.0.0.1#5335 +server=/.tube8.com/127.0.0.1#5335 +server=/.tubecao.com/127.0.0.1#5335 +server=/.tube.com/127.0.0.1#5335 +server=/.tubewolf.com/127.0.0.1#5335 +server=/.tuidang.net/127.0.0.1#5335 +server=/.tuidang.org/127.0.0.1#5335 +server=/.tui.orzdream.com/127.0.0.1#5335 +server=/.tuite.googlecode.com/127.0.0.1#5335 +server=/.tumblr.awflasher.com/127.0.0.1#5335 +server=/.tumblweed.org/127.0.0.1#5335 +server=/.tumutanzi.com/127.0.0.1#5335 +server=/.tunein.com/127.0.0.1#5335 +server=/.tunnelbear.com/127.0.0.1#5335 +server=/.turbobit.net/127.0.0.1#5335 +server=/.turbotwitter.com/127.0.0.1#5335 +server=/.turningtorso.com/127.0.0.1#5335 +server=/.turntable.fm/127.0.0.1#5335 +server=/.tuxtraining.com/127.0.0.1#5335 +server=/.tvants.com/127.0.0.1#5335 +server=/.tvboxnow.com/127.0.0.1#5335 +server=/.tv.com/127.0.0.1#5335 +server=/.tvider.com/127.0.0.1#5335 +server=/.tv-intros.com/127.0.0.1#5335 +server=/.tv.on.cc/127.0.0.1#5335 +server=/.tvunetworks.com/127.0.0.1#5335 +server=/.twapperkeeper.com/127.0.0.1#5335 +server=/.twa.sh/127.0.0.1#5335 +server=/.twaud.io/127.0.0.1#5335 +server=/.twbbs.net.tw/127.0.0.1#5335 +server=/.twbbs.org/127.0.0.1#5335 +server=/.twbbs.tw/127.0.0.1#5335 +server=/.twblogger.com/127.0.0.1#5335 +server=/.tweepguide.com/127.0.0.1#5335 +server=/.tweeplike.me/127.0.0.1#5335 +server=/.tweepmag.com/127.0.0.1#5335 +server=/.tweepml.org/127.0.0.1#5335 +server=/.tweetbackup.com/127.0.0.1#5335 +server=/.tweetboard.com/127.0.0.1#5335 +server=/.tweetboner.biz/127.0.0.1#5335 +server=/.tweetdeck.com/127.0.0.1#5335 +server=/.tweetedtimes.com/127.0.0.1#5335 +server=/.tweetmeme.com/127.0.0.1#5335 +server=/.tweetmylast.fm/127.0.0.1#5335 +server=/.tweetphoto.com/127.0.0.1#5335 +server=/.tweetrans.com/127.0.0.1#5335 +server=/.tweetree.com/127.0.0.1#5335 +server=/.tweetwally.com/127.0.0.1#5335 +server=/.tweetymail.com/127.0.0.1#5335 +server=/.twftp.org/127.0.0.1#5335 +server=/.twibase.com/127.0.0.1#5335 +server=/.twibble.de/127.0.0.1#5335 +server=/.twibbon.com/127.0.0.1#5335 +server=/.twibs.com/127.0.0.1#5335 +server=/.twicsy.com/127.0.0.1#5335 +server=/.twifan.com/127.0.0.1#5335 +server=/.twiffo.com/127.0.0.1#5335 +server=/.twiggit.org/127.0.0.1#5335 +server=/.twilog.org/127.0.0.1#5335 +server=/.twimbow.com/127.0.0.1#5335 +server=/.twimg.com/127.0.0.1#5335 +server=/.twimg.edgesuite.net/127.0.0.1#5335 +server=/.tw.img.nextmedia.com/127.0.0.1#5335 +server=/.twindexx.com/127.0.0.1#5335 +server=/.twipple.jp/127.0.0.1#5335 +server=/.twistar.cc/127.0.0.1#5335 +server=/.twisternow.com/127.0.0.1#5335 +server=/.twistory.net/127.0.0.1#5335 +server=/.twit2d.com/127.0.0.1#5335 +server=/.twitbrowser.net/127.0.0.1#5335 +server=/.twitcause.com/127.0.0.1#5335 +server=/.twitese.spaces.live.com/127.0.0.1#5335 +server=/.twitgether.com/127.0.0.1#5335 +server=/.twitgoo.com/127.0.0.1#5335 +server=/.twitiq.com/127.0.0.1#5335 +server=/.twitlonger.com/127.0.0.1#5335 +server=/.twitoaster.com/127.0.0.1#5335 +server=/.twitonmsn.com/127.0.0.1#5335 +server=/.twitpic.com/127.0.0.1#5335 +server=/.twitreferral.com/127.0.0.1#5335 +server=/.twitstat.com/127.0.0.1#5335 +server=/.twittbot.net/127.0.0.1#5335 +server=/.twitter4j.org/127.0.0.1#5335 +server=/.twitter.com/127.0.0.1#5335 +server=/.twittercounter.com/127.0.0.1#5335 +server=/.twitterfeed.com/127.0.0.1#5335 +server=/.twittergadget.com/127.0.0.1#5335 +server=/.twitter.jp/127.0.0.1#5335 +server=/.twitterkr.com/127.0.0.1#5335 +server=/.twittermail.com/127.0.0.1#5335 +server=/.twittertim.es/127.0.0.1#5335 +server=/.twitthat.com/127.0.0.1#5335 +server=/.twitturk.com/127.0.0.1#5335 +server=/.twitturly.com/127.0.0.1#5335 +server=/.twitvid.com/127.0.0.1#5335 +server=/.twitzap.com/127.0.0.1#5335 +server=/.twiyia.com/127.0.0.1#5335 +server=/.tw.jiepang.com/127.0.0.1#5335 +server=/.tw.myblog.yahoo.com/127.0.0.1#5335 +server=/.tw.news.yahoo.com/127.0.0.1#5335 +server=/.tw-npo.org/127.0.0.1#5335 +server=/.tw.rd.yahoo.com/127.0.0.1#5335 +server=/.twreg.info/127.0.0.1#5335 +server=/.twstar.net/127.0.0.1#5335 +server=/.tw.streetvoice.com/127.0.0.1#5335 +server=/.twt.fm/127.0.0.1#5335 +server=/.twtkr.com/127.0.0.1#5335 +server=/.twtr2src.ogaoga.org/127.0.0.1#5335 +server=/.twtrland.com/127.0.0.1#5335 +server=/.twt.tl/127.0.0.1#5335 +server=/.twttr.com/127.0.0.1#5335 +server=/.twurl.nl/127.0.0.1#5335 +server=/.tw.voa.mobi/127.0.0.1#5335 +server=/.twyac.org/127.0.0.1#5335 +server=/.tw.yahoo.com/127.0.0.1#5335 +server=/.tycool.com/127.0.0.1#5335 +server=/.tynsoe.org/127.0.0.1#5335 +server=/.typepad.com/127.0.0.1#5335 +server=/.tzangms.com/127.0.0.1#5335 +server=/.ub0.cc/127.0.0.1#5335 +server=/.uberproxy.net/127.0.0.1#5335 +server=/.ucdc1998.org/127.0.0.1#5335 +server=/.uderzo.it/127.0.0.1#5335 +server=/.udn.com/127.0.0.1#5335 +server=/.ufreevpn.com/127.0.0.1#5335 +server=/.ugo.com/127.0.0.1#5335 +server=/.uhrp.org/127.0.0.1#5335 +server=/.uighurbiz.net/127.0.0.1#5335 +server=/.ukliferadio.co.uk/127.0.0.1#5335 +server=/.ulike.net/127.0.0.1#5335 +server=/.ultravpn.fr/127.0.0.1#5335 +server=/.ultraxs.com/127.0.0.1#5335 +server=/.unblock.cn.com/127.0.0.1#5335 +server=/.unblocksit.es/127.0.0.1#5335 +server=/.uncyclomedia.org/127.0.0.1#5335 +server=/.uncyclopedia.info/127.0.0.1#5335 +server=/.uncyclopedia.tw/127.0.0.1#5335 +server=/.unholyknight.com/127.0.0.1#5335 +server=/.uni.cc/127.0.0.1#5335 +server=/.unicode.org/127.0.0.1#5335 +server=/.uniteddaily.com.my/127.0.0.1#5335 +server=/.unix100.com/127.0.0.1#5335 +server=/.unknownspace.org/127.0.0.1#5335 +server=/.unpo.org/127.0.0.1#5335 +server=/.uocn.org/127.0.0.1#5335 +server=/.upcoming.yahoo.com/127.0.0.1#5335 +server=/.update.playstation.net/127.0.0.1#5335 +server=/.upload4u.info/127.0.0.1#5335 +server=/.upload.backchina.com/127.0.0.1#5335 +server=/.uploaded.to/127.0.0.1#5335 +server=/.uploadstation.com/127.0.0.1#5335 +server=/.upload.wikimedia.org/127.0.0.1#5335 +server=/.urlborg.com/127.0.0.1#5335 +server=/.urlparser.com/127.0.0.1#5335 +server=/.usacn.com/127.0.0.1#5335 +server=/.usfk.mil/127.0.0.1#5335 +server=/.usinfo.state.gov/127.0.0.1#5335 +server=/.usmc.mil/127.0.0.1#5335 +server=/.us.to/127.0.0.1#5335 +server=/.ustream.tv/127.0.0.1#5335 +server=/.usus.cc/127.0.0.1#5335 +server=/.uushare.com/127.0.0.1#5335 +server=/.uwants.com/127.0.0.1#5335 +server=/.uwants.net/127.0.0.1#5335 +server=/.uyghurcongress.org/127.0.0.1#5335 +server=/.uygur.org/127.0.0.1#5335 +server=/.v70.us/127.0.0.1#5335 +server=/.vaayoo.com/127.0.0.1#5335 +server=/.value-domain.com/127.0.0.1#5335 +server=/.van698.com/127.0.0.1#5335 +server=/.vanemu.cn/127.0.0.1#5335 +server=/.vanilla-jp.com/127.0.0.1#5335 +server=/.vansky.com/127.0.0.1#5335 +server=/.vapurl.com/127.0.0.1#5335 +server=/.vatn.org/127.0.0.1#5335 +server=/.vcfbuilder.org/127.0.0.1#5335 +server=/.vcf-online.org/127.0.0.1#5335 +server=/.veempiire.com/127.0.0.1#5335 +server=/.velkaepocha.sk/127.0.0.1#5335 +server=/.venbbs.com/127.0.0.1#5335 +server=/.venchina.com/127.0.0.1#5335 +server=/.ventureswell.com/127.0.0.1#5335 +server=/.veoh.com/127.0.0.1#5335 +server=/.verizon.net/127.0.0.1#5335 +server=/.verybs.com/127.0.0.1#5335 +server=/.vevo.com/127.0.0.1#5335 +server=/.vft.com.tw/127.0.0.1#5335 +server=/.vghks.gov.tw/127.0.0.1#5335 +server=/.vghtc.gov.tw/127.0.0.1#5335 +server=/.vghtpe.gov.tw/127.0.0.1#5335 +server=/.video.aol.ca/127.0.0.1#5335 +server=/.video.aol.com/127.0.0.1#5335 +server=/.video.aol.co.uk/127.0.0.1#5335 +server=/.video.ap.org/127.0.0.1#5335 +server=/.videobam.com/127.0.0.1#5335 +server=/.video.fdbox.com/127.0.0.1#5335 +server=/.video.foxbusiness.com/127.0.0.1#5335 +server=/.videomo.com/127.0.0.1#5335 +server=/.video.tiscali.it/127.0.0.1#5335 +server=/.video.yahoo.com/127.0.0.1#5335 +server=/.vidoemo.com/127.0.0.1#5335 +server=/.views.fm/127.0.0.1#5335 +server=/.viki.com/127.0.0.1#5335 +server=/.vimeocdn.com/127.0.0.1#5335 +server=/.vimeo.com/127.0.0.1#5335 +server=/.vimgolf.com/127.0.0.1#5335 +server=/.vimperator.org/127.0.0.1#5335 +server=/.vincnd.com/127.0.0.1#5335 +server=/.vinniev.com/127.0.0.1#5335 +server=/.vllcs.org/127.0.0.1#5335 +server=/.vlog.xuite.net/127.0.0.1#5335 +server=/.vmixcore.com/127.0.0.1#5335 +server=/.voacantonese.com/127.0.0.1#5335 +server=/.voachineseblog.com/127.0.0.1#5335 +server=/.voachinese.com/127.0.0.1#5335 +server=/.voagd.com/127.0.0.1#5335 +server=/.voanews.com/127.0.0.1#5335 +server=/.voatibetan.com/127.0.0.1#5335 +server=/.vocn.tv/127.0.0.1#5335 +server=/.vot.org/127.0.0.1#5335 +server=/.vpnbook.com/127.0.0.1#5335 +server=/.vpnfire.com/127.0.0.1#5335 +server=/.vpngate.jp/127.0.0.1#5335 +server=/.vpngate.net/127.0.0.1#5335 +server=/.vpnpop.com/127.0.0.1#5335 +server=/.vpnpronet.com/127.0.0.1#5335 +server=/.v-state.org/127.0.0.1#5335 +server=/.vtunnel.com/127.0.0.1#5335 +server=/.w3schools.com/127.0.0.1#5335 +server=/.waffle1999.com/127.0.0.1#5335 +server=/.wahas.com/127.0.0.1#5335 +server=/.waigaobu.com/127.0.0.1#5335 +server=/.waikeung.org/127.0.0.1#5335 +server=/.waiwaier.com/127.0.0.1#5335 +server=/.wallornot.org/127.0.0.1#5335 +server=/.wallpapercasa.com/127.0.0.1#5335 +server=/.wanderinghorse.net/127.0.0.1#5335 +server=/.wanfang.gov.tw/127.0.0.1#5335 +server=/.wangafu.net/127.0.0.1#5335 +server=/.wangjinbo.org/127.0.0.1#5335 +server=/.wanglixiong.com/127.0.0.1#5335 +server=/.wangruoshui.net/127.0.0.1#5335 +server=/.wangyi64.spaces.live.com/127.0.0.1#5335 +server=/.want-daily.com/127.0.0.1#5335 +server=/.wapedia.mobi/127.0.0.1#5335 +server=/.washeng.net/127.0.0.1#5335 +server=/.watchmygf.net/127.0.0.1#5335 +server=/.wattpad.com/127.0.0.1#5335 +server=/.wdf5.com/127.0.0.1#5335 +server=/.wearn.com/127.0.0.1#5335 +server=/.web2project.net/127.0.0.1#5335 +server=/.webbang.net/127.0.0.1#5335 +server=/.webfee.tk/127.0.0.1#5335 +server=/.weblagu.com/127.0.0.1#5335 +server=/.webmproject.org/127.0.0.1#5335 +server=/.webshots.com/127.0.0.1#5335 +server=/.websitepulse.com/127.0.0.1#5335 +server=/.webs-tv.net/127.0.0.1#5335 +server=/.webworkerdaily.com/127.0.0.1#5335 +server=/.weeewooo.net/127.0.0.1#5335 +server=/.weekmag.info/127.0.0.1#5335 +server=/.wefong.com/127.0.0.1#5335 +server=/.weiboleak.com/127.0.0.1#5335 +server=/.weigegebyc.dreamhosters.com/127.0.0.1#5335 +server=/.weijingsheng.org/127.0.0.1#5335 +server=/.weiming.info/127.0.0.1#5335 +server=/.weiquanwang.org/127.0.0.1#5335 +server=/.weisuo.ws/127.0.0.1#5335 +server=/.wellplacedpixels.com/127.0.0.1#5335 +server=/.wengewang.com/127.0.0.1#5335 +server=/.wengewang.org/127.0.0.1#5335 +server=/.wenhui.ch/127.0.0.1#5335 +server=/.wenku.com/127.0.0.1#5335 +server=/.wenxuecity.com/127.0.0.1#5335 +server=/.wenyunchao.com/127.0.0.1#5335 +server=/.wenyunchao.spaces.live.com/127.0.0.1#5335 +server=/.wepn.info/127.0.0.1#5335 +server=/.westca.com/127.0.0.1#5335 +server=/.westernwolves.com/127.0.0.1#5335 +server=/.wetplace.com/127.0.0.1#5335 +server=/.wetpussygames.com/127.0.0.1#5335 +server=/.wexiaobo.org/127.0.0.1#5335 +server=/.wezhiyong.org/127.0.0.1#5335 +server=/.wezone.net/127.0.0.1#5335 +server=/.wforum.com/127.0.0.1#5335 +server=/.whatblocked.com/127.0.0.1#5335 +server=/.whereiswerner.com/127.0.0.1#5335 +server=/.whippedass.com/127.0.0.1#5335 +server=/.whitebear.freebearblog.org/127.0.0.1#5335 +server=/.whydidyoubuymethat.com/127.0.0.1#5335 +server=/.whylover.com/127.0.0.1#5335 +server=/.whyx.org/127.0.0.1#5335 +server=/.w.idaiwan.com/127.0.0.1#5335 +server=/.wiki.cnitter.com/127.0.0.1#5335 +server=/.wiki.jqueryui.com/127.0.0.1#5335 +server=/.wiki.keso.cn/127.0.0.1#5335 +server=/.wikileaks.ch/127.0.0.1#5335 +server=/.wikileaks.de/127.0.0.1#5335 +server=/.wikileaks.eu/127.0.0.1#5335 +server=/.wikileaks.lu/127.0.0.1#5335 +server=/.wikileaks.org/127.0.0.1#5335 +server=/.wikileaks.pl/127.0.0.1#5335 +server=/.wikilivres.info/127.0.0.1#5335 +server=/.wikimapia.org/127.0.0.1#5335 +server=/.wikimedia.org.mo/127.0.0.1#5335 +server=/.wiki.moegirl.org/127.0.0.1#5335 +server=/.wikinet.org/127.0.0.1#5335 +server=/.wiki.oauth.net/127.0.0.1#5335 +server=/.wikipedia.org/127.0.0.1#5335 +server=/.wiki.phonegap.com/127.0.0.1#5335 +server=/.wikiwiki.jp/127.0.0.1#5335 +server=/.wikkii.com/127.0.0.1#5335 +server=/.williamlong.spaces.live.com/127.0.0.1#5335 +server=/.willw.net/127.0.0.1#5335 +server=/.windowsphoneme.com/127.0.0.1#5335 +server=/.winwhispers.info/127.0.0.1#5335 +server=/.wiredbytes.com/127.0.0.1#5335 +server=/.wiredpen.com/127.0.0.1#5335 +server=/.wireshark.org/127.0.0.1#5335 +server=/.wisevid.com/127.0.0.1#5335 +server=/.witnessleeteaching.com/127.0.0.1#5335 +server=/.witopia.net/127.0.0.1#5335 +server=/.wlx.sowiki.net/127.0.0.1#5335 +server=/.woeser.com/127.0.0.1#5335 +server=/.wolfax.com/127.0.0.1#5335 +server=/.womenbusiness.nyc.gov.tw/127.0.0.1#5335 +server=/.womensrightsofchina.org/127.0.0.1#5335 +server=/.woopie.jp/127.0.0.1#5335 +server=/.woopie.tv/127.0.0.1#5335 +server=/.wordboner.com/127.0.0.1#5335 +server=/.wordpress.com/127.0.0.1#5335 +server=/.wordsandturds.com/127.0.0.1#5335 +server=/.w.org/127.0.0.1#5335 +server=/.workatruna.com/127.0.0.1#5335 +server=/.worldcat.org/127.0.0.1#5335 +server=/.worldjournal.com/127.0.0.1#5335 +server=/.worstthingieverate.com/127.0.0.1#5335 +server=/.wo.tc/127.0.0.1#5335 +server=/.wowlegacy.ml/127.0.0.1#5335 +server=/.wow-life.net/127.0.0.1#5335 +server=/.woxinghuiguo.com/127.0.0.1#5335 +server=/.wozy.in/127.0.0.1#5335 +server=/.wp.com/127.0.0.1#5335 +server=/.wpoforum.com/127.0.0.1#5335 +server=/.wqlhw.com/127.0.0.1#5335 +server=/.wqyd.org/127.0.0.1#5335 +server=/.wrchina.org/127.0.0.1#5335 +server=/.wretch.cc/127.0.0.1#5335 +server=/.writer.zoho.com/127.0.0.1#5335 +server=/.wsj.com/127.0.0.1#5335 +server=/.wsj.net/127.0.0.1#5335 +server=/.wtfpeople.com/127.0.0.1#5335 +server=/.wuala.com/127.0.0.1#5335 +server=/.wuerkaixi.com/127.0.0.1#5335 +server=/.wufi.org.tw/127.0.0.1#5335 +server=/.wuguoguang.com/127.0.0.1#5335 +server=/.wujieliulan.com/127.0.0.1#5335 +server=/.wujie.net/127.0.0.1#5335 +server=/.wukangrui.net/127.0.0.1#5335 +server=/.wwitv.com/127.0.0.1#5335 +server=/.www.6v6dota.com/127.0.0.1#5335 +server=/.www.ajsands.com/127.0.0.1#5335 +server=/.www.antd.org/127.0.0.1#5335 +server=/.www.aolnews.com/127.0.0.1#5335 +server=/.www.bulbous.freeserve.co.uk/127.0.0.1#5335 +server=/.www.cmoinc.org/127.0.0.1#5335 +server=/.www.dfanning.com/127.0.0.1#5335 +server=/.www.dwheeler.com/127.0.0.1#5335 +server=/.www.eulam.com/127.0.0.1#5335 +server=/.www.exblog.jp/127.0.0.1#5335 +server=/.www.forum4hk.com/127.0.0.1#5335 +server=/.www.freetibet.org/127.0.0.1#5335 +server=/.www.getyouram.com/127.0.0.1#5335 +server=/.www.goldenmelody.com.tw/127.0.0.1#5335 +server=/.www.idlcoyote.com/127.0.0.1#5335 +server=/.www.immigration.gov.tw/127.0.0.1#5335 +server=/.www.klip.me/127.0.0.1#5335 +server=/.www.kodingen.com/127.0.0.1#5335 +server=/.www.linksalpha.com/127.0.0.1#5335 +server=/.www.loiclemeur.com/127.0.0.1#5335 +server=/.www.macrovpn.com/127.0.0.1#5335 +server=/.www.monlamit.org/127.0.0.1#5335 +server=/.www.moztw.org/127.0.0.1#5335 +server=/.www.mycould.com/127.0.0.1#5335 +server=/.www.ned.org/127.0.0.1#5335 +server=/.www.nownews.com/127.0.0.1#5335 +server=/.www.orchidbbs.com/127.0.0.1#5335 +server=/.www.owind.com/127.0.0.1#5335 +server=/.www.oxid.it/127.0.0.1#5335 +server=/.www.parkansky.com/127.0.0.1#5335 +server=/.www.powerpointninja.com/127.0.0.1#5335 +server=/.www.rnw.nl/127.0.0.1#5335 +server=/.www.somee.com/127.0.0.1#5335 +server=/.www.stackfile.com/127.0.0.1#5335 +server=/.www.supertweet.net/127.0.0.1#5335 +server=/.www.tiffanyarment.com/127.0.0.1#5335 +server=/.www.tripod.com/127.0.0.1#5335 +server=/.www.tv.com/127.0.0.1#5335 +server=/.www.twtrland.com/127.0.0.1#5335 +server=/.www.typepad.com/127.0.0.1#5335 +server=/.www.urbanoutfitters.com/127.0.0.1#5335 +server=/.www.vegorpedersen.com/127.0.0.1#5335 +server=/.www.voy.com/127.0.0.1#5335 +server=/.www.vpncup.com/127.0.0.1#5335 +server=/.www.wangruowang.org/127.0.0.1#5335 +server=/.www.wan-press.org/127.0.0.1#5335 +server=/.www.wet123.com/127.0.0.1#5335 +server=/.www.zaurus.org.uk/127.0.0.1#5335 +server=/.wzyboy.im/127.0.0.1#5335 +server=/.x1949x.com/127.0.0.1#5335 +server=/.x365x.com/127.0.0.1#5335 +server=/.xanga.com/127.0.0.1#5335 +server=/.x-art.com/127.0.0.1#5335 +server=/.xa.yimg.com/127.0.0.1#5335 +server=/.xbabe.com/127.0.0.1#5335 +server=/.xbookcn.com/127.0.0.1#5335 +server=/.xcafe.in/127.0.0.1#5335 +server=/.xcritic.com/127.0.0.1#5335 +server=/.xfm.pp.ru/127.0.0.1#5335 +server=/.xgmyd.com/127.0.0.1#5335 +server=/.xh4n.cn/127.0.0.1#5335 +server=/.xhamster.com/127.0.0.1#5335 +server=/.xiaochuncnjp.com/127.0.0.1#5335 +server=/.xiaohexie.com/127.0.0.1#5335 +server=/.xiaoma.org/127.0.0.1#5335 +server=/.xiezhua.com/127.0.0.1#5335 +server=/.xing.com/127.0.0.1#5335 +server=/.xinhuanet.org/127.0.0.1#5335 +server=/.xinmiao.com.hk/127.0.0.1#5335 +server=/.xinqimeng.over-blog.com/127.0.0.1#5335 +server=/.xinsheng.net/127.0.0.1#5335 +server=/.xinshijue.com/127.0.0.1#5335 +server=/.xinyubbs.net/127.0.0.1#5335 +server=/.xizang-zhiye.org/127.0.0.1#5335 +server=/.xjp.cc/127.0.0.1#5335 +server=/.xml-training-guide.com/127.0.0.1#5335 +server=/.xmovies.com/127.0.0.1#5335 +server=/.xmusic.fm/127.0.0.1#5335 +server=/.xnxx.com/127.0.0.1#5335 +server=/.xpdo.net/127.0.0.1#5335 +server=/.xpud.org/127.0.0.1#5335 +server=/.xskywalker.com/127.0.0.1#5335 +server=/.xtube.com/127.0.0.1#5335 +server=/.xuchao.net/127.0.0.1#5335 +server=/.xuchao.org/127.0.0.1#5335 +server=/.xuzhiyong.net/127.0.0.1#5335 +server=/.xuzhuoer.com/127.0.0.1#5335 +server=/.xvedios.com/127.0.0.1#5335 +server=/.xvideos.com/127.0.0.1#5335 +server=/.x-wall.org/127.0.0.1#5335 +server=/.xxbbx.com/127.0.0.1#5335 +server=/.x.xcity.jp/127.0.0.1#5335 +server=/.xxxx.com.au/127.0.0.1#5335 +server=/.xysblogs.org/127.0.0.1#5335 +server=/.xys.dxiong.com/127.0.0.1#5335 +server=/.xys.org/127.0.0.1#5335 +server=/.xyy69.com/127.0.0.1#5335 +server=/.xyy69.info/127.0.0.1#5335 +server=/.yahoo.cn/127.0.0.1#5335 +server=/.yahoo.com.hk/127.0.0.1#5335 +server=/.yam.com/127.0.0.1#5335 +server=/.yanghengjun.spaces.live.com/127.0.0.1#5335 +server=/.yasni.co.uk/127.0.0.1#5335 +server=/.yasukuni.or.jp/127.0.0.1#5335 +server=/.yatsen.gov.tw/127.0.0.1#5335 +server=/.ydy.com/127.0.0.1#5335 +server=/.yeelou.com/127.0.0.1#5335 +server=/.yeeyi.com/127.0.0.1#5335 +server=/.yegle.net/127.0.0.1#5335 +server=/.yezimary.spaces.live.com/127.0.0.1#5335 +server=/.yfrog.com/127.0.0.1#5335 +server=/.yhcw.net/127.0.0.1#5335 +server=/.yidio.com/127.0.0.1#5335 +server=/.yilubbs.com/127.0.0.1#5335 +server=/.yi.org/127.0.0.1#5335 +server=/.yipub.com/127.0.0.1#5335 +server=/.ym.backchina.com/127.0.0.1#5335 +server=/.yogichen.org/127.0.0.1#5335 +server=/.yong.hu/127.0.0.1#5335 +server=/.yorkbbs.ca/127.0.0.1#5335 +server=/.youdao.com/127.0.0.1#5335 +server=/.youjizz.com/127.0.0.1#5335 +server=/.youmaker.com/127.0.0.1#5335 +server=/.youpai.org/127.0.0.1#5335 +server=/.youporn.com/127.0.0.1#5335 +server=/.your-freedom.net/127.0.0.1#5335 +server=/.yousendit.com/127.0.0.1#5335 +server=/.youthbao.com/127.0.0.1#5335 +server=/.youthnetradio.org/127.0.0.1#5335 +server=/.youtu.be/127.0.0.1#5335 +server=/.youtubecn.com/127.0.0.1#5335 +server=/.youtube.com/127.0.0.1#5335 +server=/.youtube-nocookie.com/127.0.0.1#5335 +server=/.youversion.com/127.0.0.1#5335 +server=/.youxu.info/127.0.0.1#5335 +server=/.ytht.net/127.0.0.1#5335 +server=/.ytimg.com/127.0.0.1#5335 +server=/.yuanming.net/127.0.0.1#5335 +server=/.yuming.flnet.org/127.0.0.1#5335 +server=/.yunchao.net/127.0.0.1#5335 +server=/.yvesgeleyn.com/127.0.0.1#5335 +server=/.yvtc.gov.tw/127.0.0.1#5335 +server=/.yx51.net/127.0.0.1#5335 +server=/.yyii.org/127.0.0.1#5335 +server=/.yymaya.com/127.0.0.1#5335 +server=/.yzzk.com/127.0.0.1#5335 +server=/.zacebook.com/127.0.0.1#5335 +server=/.zannel.com/127.0.0.1#5335 +server=/.zaobao.com/127.0.0.1#5335 +server=/.zaobao.com.sg/127.0.0.1#5335 +server=/.zaozon.com/127.0.0.1#5335 +server=/.zarias.com/127.0.0.1#5335 +server=/.zattoo.com/127.0.0.1#5335 +server=/.zdnet.com.tw/127.0.0.1#5335 +server=/.zengjinyan.org/127.0.0.1#5335 +server=/.zengjinyan.spaces.live.com/127.0.0.1#5335 +server=/.zeutch.com/127.0.0.1#5335 +server=/.zgzcjj.net/127.0.0.1#5335 +server=/.zhanbin.net/127.0.0.1#5335 +server=/.zhao.jinhai.de/127.0.0.1#5335 +server=/.zhenghui.org/127.0.0.1#5335 +server=/.zhenlibu.info/127.0.0.1#5335 +server=/.zhinengluyou.com/127.0.0.1#5335 +server=/.zhllg.spaces.live.com/127.0.0.1#5335 +server=/.zh.m.wikipedia.org/127.0.0.1#5335 +server=/.zh.netlog.com/127.0.0.1#5335 +server=/.zhonggtuotese.net/127.0.0.1#5335 +server=/.zhongguotese.net/127.0.0.1#5335 +server=/.zhongmeng.org/127.0.0.1#5335 +server=/.zhongsou.com/127.0.0.1#5335 +server=/.zh.pokerstrategy.com/127.0.0.1#5335 +server=/.zhreader.com/127.0.0.1#5335 +server=/.zh-tw.justin.tv/127.0.0.1#5335 +server=/.zhuichaguoji.org/127.0.0.1#5335 +server=/.zh.uncyclopedia.wikia.com/127.0.0.1#5335 +server=/.zh.wikinews.org/127.0.0.1#5335 +server=/.zh.wikipedia.org/127.0.0.1#5335 +server=/.zh.wikisource.org/127.0.0.1#5335 +server=/.ziddu.com/127.0.0.1#5335 +server=/.zillionk.com/127.0.0.1#5335 +server=/.zinio.com/127.0.0.1#5335 +server=/.ziplib.com/127.0.0.1#5335 +server=/.zkaip.com/127.0.0.1#5335 +server=/.zmw.cn/127.0.0.1#5335 +server=/.zomobo.net/127.0.0.1#5335 +server=/.zonaeuropa.com/127.0.0.1#5335 +server=/.zootool.com/127.0.0.1#5335 +server=/.zoozle.net/127.0.0.1#5335 +server=/.zozotown.com/127.0.0.1#5335 +server=/.zshare.net/127.0.0.1#5335 +server=/.zsrhao.com/127.0.0.1#5335 +server=/.zuo.la/127.0.0.1#5335 +server=/.zuola.com/127.0.0.1#5335 +server=/.zvereff.com/127.0.0.1#5335 +server=/.zyzc9.com/127.0.0.1#5335 +server=/.zyzg.us/127.0.0.1#5335 diff --git a/package/lean/luci-app-ssr-plus/root/etc/dnsmasq.ssr/gfw_list.conf b/package/lean/luci-app-ssr-plus/root/etc/dnsmasq.ssr/gfw_list.conf new file mode 100644 index 0000000000..97fc505ab1 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/etc/dnsmasq.ssr/gfw_list.conf @@ -0,0 +1,2 @@ +server=/.t66y.com/127.0.0.1#5335 +ipset=/.t66y.com/gfwlist diff --git a/package/lean/luci-app-ssr-plus/root/etc/init.d/shadowsocksr b/package/lean/luci-app-ssr-plus/root/etc/init.d/shadowsocksr new file mode 100755 index 0000000000..42e4c2209c --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/etc/init.d/shadowsocksr @@ -0,0 +1,554 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (C) 2017 openwrt-ssr +# Copyright (C) 2017 yushi studio +# Copyright (C) 2018 lean +# +# This is free software, licensed under the GNU General Public License v3. +# See /LICENSE for more information. +# + +START=90 +STOP=15 + +SERVICE_DAEMONIZE=1 +NAME=shadowsocksr +EXTRA_COMMANDS=rules +CONFIG_FILE=/var/etc/${NAME}.json +CONFIG_UDP_FILE=/var/etc/${NAME}_u.json +CONFIG_SOCK5_FILE=/var/etc/${NAME}_s.json +server_count=0 +redir_tcp=0 +redir_udp=0 +tunnel_enable=0 +local_enable=0 +kcp_enable_flag=0 +kcp_flag=0 +pdnsd_enable_flag=0 +switch_enable=0 +switch_server=$1 +MAXFD=32768 +CRON_FILE=/etc/crontabs/root +threads=1 + +uci_get_by_name() { + local ret=$(uci get $NAME.$1.$2 2>/dev/null) + echo ${ret:=$3} +} + +uci_get_by_type() { + local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null) + echo ${ret:=$3} +} + +add_cron() +{ + sed -i '/ssrplus.log/d' $CRON_FILE + echo '0 1 * * * echo "" > /tmp/ssrplus.log' >> $CRON_FILE + [ -n "$(grep -w "/usr/share/shadowsocksr/subscribe.sh" $CRON_FILE)" ] && sed -i '/\/usr\/share\/shadowsocksr\/subscribe.sh/d' $CRON_FILE + [ $(uci_get_by_type server_subscribe auto_update 0) -eq 1 ] && echo "0 $(uci_get_by_type server_subscribe auto_update_time) * * * /usr/share/shadowsocksr/subscribe.sh" >> $CRON_FILE + [ -z "$(grep -w "/usr/share/shadowsocksr/update.sh" $CRON_FILE)" ] && echo "0 5 * * * /usr/share/shadowsocksr/update.sh" >> $CRON_FILE + crontab $CRON_FILE +} + +del_cron() +{ + sed -i '/shadowsocksr/d' $CRON_FILE + sed -i '/ssrplus.log/d' $CRON_FILE + /etc/init.d/cron restart +} + +run_mode=$(uci_get_by_type global run_mode) + +gen_config_file() { + local host=$(uci_get_by_name $1 server) + if echo $host|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then + hostip=${host} + elif [ "$host" != "${host#*:[0-9a-fA-F]}" ] ;then + hostip=${host} + else + hostip=`nslookup ${host} | grep 'Address 1' | sed 's/Address 1: //g'` + if echo $hostip|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then + hostip=${hostip} + else + hostip=`cat /etc/ssr_ip` + fi + fi + [ $2 = "0" -a $kcp_flag = "1" ] && hostip="127.0.0.1" + + if [ $2 = "0" ] ;then + config_file=$CONFIG_FILE + elif [ $2 = "1" ]; then + config_file=$CONFIG_UDP_FILE + else + config_file=$CONFIG_SOCK5_FILE + fi + if [ $(uci_get_by_name $1 fast_open 0) = "1" ] ;then + fastopen="true"; + else + fastopen="false"; + fi +local stype=$(uci_get_by_name $1 type) +if [ "$stype" == "ss" ] ;then + cat <<-EOF >$config_file + { + "server": "$hostip", + "server_port": $(uci_get_by_name $1 server_port), + "local_address": "0.0.0.0", + "local_port": $(uci_get_by_name $1 local_port), + "password": "$(uci_get_by_name $1 password)", + "timeout": $(uci_get_by_name $1 timeout 60), + "method": "$(uci_get_by_name $1 encrypt_method_ss)", + "reuse_port": true, + "fast_open": $fastopen + } +EOF + elif [ "$stype" == "ssr" ] ;then + cat <<-EOF >$config_file + { + + "server": "$hostip", + "server_port": $(uci_get_by_name $1 server_port), + "local_address": "0.0.0.0", + "local_port": $(uci_get_by_name $1 local_port), + "password": "$(uci_get_by_name $1 password)", + "timeout": $(uci_get_by_name $1 timeout 60), + "method": "$(uci_get_by_name $1 encrypt_method)", + "protocol": "$(uci_get_by_name $1 protocol)", + "protocol_param": "$(uci_get_by_name $1 protocol_param)", + "obfs": "$(uci_get_by_name $1 obfs)", + "obfs_param": "$(uci_get_by_name $1 obfs_param)", + "reuse_port": true, + "fast_open": $fastopen + } +EOF + elif [ "$stype" == "v2ray" ] ;then + lua /usr/share/shadowsocksr/genv2config.lua $GLOBAL_SERVER tcp $(uci_get_by_name $1 local_port) > /var/etc/v2-ssr-retcp.json + sed -i 's/\\//g' /var/etc/v2-ssr-retcp.json +fi +} + +get_arg_out() { + case "$(uci_get_by_type access_control router_proxy 1)" in + 1) echo "-o";; + 2) echo "-O";; + esac +} + +start_rules() { + local server=$(uci_get_by_name $GLOBAL_SERVER server) + #resolve name + if echo $server|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then + server=${server} + elif [ "$server" != "${server#*:[0-9a-fA-F]}" ] ;then + server=${server} + else + server=`nslookup ${server} | grep 'Address 1' | sed 's/Address 1: //g'` + if echo $server|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then + echo $server >/etc/ssr_ip + else + server=`cat /etc/ssr_ip` + fi + fi + + kcp_server=$server + + local kcp_enable=$(uci_get_by_name $GLOBAL_SERVER kcp_enable 0) + if [ $kcp_enable = "1" ] ;then + kcp_flag=1 + fi + + local local_port=$(uci_get_by_name $GLOBAL_SERVER local_port) + local lan_ac_ips=$(uci_get_by_type access_control lan_ac_ips) + local lan_ac_mode="b" + local router_proxy=$(uci_get_by_type access_control router_proxy) + if [ "$GLOBAL_SERVER" = "$UDP_RELAY_SERVER" -a $kcp_flag = 0 ]; then + ARG_UDP="-u" + elif [ -n "$UDP_RELAY_SERVER" ]; then + ARG_UDP="-U" + local udp_server=$(uci_get_by_name $UDP_RELAY_SERVER server) + local udp_local_port=$(uci_get_by_name $UDP_RELAY_SERVER local_port) + fi + + if [ -n "$lan_ac_ips" ]; then + case "$lan_ac_mode" in + w|W|b|B) local ac_ips="$lan_ac_mode$lan_ac_ips";; + esac + fi + +#deal gfw firewall rule + local gfwmode="" + if [ "$run_mode" = "gfw" ]; then + gfwmode="-g" + elif [ "$run_mode" = "router" ]; then + gfwmode="-r" + elif [ "$run_mode" = "oversea" ]; then + gfwmode="-c" + elif [ "$run_mode" = "all" ]; then + gfwmode="-z" + fi + + local dports=$(uci_get_by_type global dports 1) + if [ $dports = "1" ] ;then + proxyport=" " + else + proxyport="-m multiport --dports 22,53,587,465,995,993,143,80,443 " + fi + + /usr/bin/ssr-rules \ + -s "$server" \ + -l "$local_port" \ + -S "$udp_server" \ + -L "$udp_local_port" \ + -a "$ac_ips" \ + -i "$(uci_get_by_type access_control wan_bp_list)" \ + -b "$(uci_get_by_type access_control wan_bp_ips)" \ + -w "$(uci_get_by_type access_control wan_fw_ips)" \ + -p "$(uci_get_by_type access_control lan_fp_ips)" \ + -G "$(uci_get_by_type access_control lan_gm_ips)" \ + -D "$proxyport" \ + $(get_arg_out) $gfwmode $ARG_UDP + + return $? +} + +start_pdnsd() { + local usr_dns="$1" + local usr_port="$2" + + local tcp_dns_list="208.67.222.222, 208.67.220.220" + [ -z "$usr_dns" ] && usr_dns="8.8.8.8" + [ -z "$usr_port" ] && usr_port="53" + + [ -d /var/etc ] || mkdir -p /var/etc + + if [ ! -d /var/pdnsd ];then + mkdir -p /var/pdnsd + echo -ne "pd13\000\000\000\000" >/var/pdnsd/pdnsd.cache + chown -R nobody:nogroup /var/pdnsd + fi + + cat > /var/etc/pdnsd.conf </dev/null 2>&1 + done + echo "$(date "+%Y-%m-%d %H:%M:%S") Shadowsocks/ShadowsocksR $threads Threads Started!" >> /tmp/ssrplus.log + elif [ "$stype" == "v2ray" ] ;then + $sscmd -config /var/etc/v2-ssr-retcp.json >/dev/null 2>&1 & + echo "$(date "+%Y-%m-%d %H:%M:%S") $($sscmd -version | head -1) Started!" >> /tmp/ssrplus.log + fi + + if [ -n "$UDP_RELAY_SERVER" ] ;then + redir_udp=1 + if [ "$utype" == "ss" -o "$utype" == "ssr" ] ;then + case "$(uci_get_by_name $UDP_RELAY_SERVER auth_enable)" in + 1|on|true|yes|enabled) ARG_OTA="-A";; + *) ARG_OTA="";; + esac + gen_config_file $UDP_RELAY_SERVER 1 + last_config_file=$CONFIG_UDP_FILE + pid_file="/var/run/ssr-reudp.pid" + $ucmd -c $last_config_file $ARG_OTA -U -f /var/run/ssr-reudp.pid >/dev/null 2>&1 + elif [ "$utype" == "v2ray" ] ; then + lua /usr/share/shadowsocksr/genv2config.lua $UDP_RELAY_SERVER udp $(uci_get_by_name $UDP_RELAY_SERVER local_port) > /var/etc/v2-ssr-reudp.json + sed -i 's/\\//g' /var/etc/v2-ssr-reudp.json + $ucmd -config /var/etc/v2-ssr-reudp.json >/dev/null 2>&1 & + fi + fi + + + + #deal with dns + + if [ "$(uci_get_by_type global pdnsd_enable)" = "1" ] ;then + local dnsstr="$(uci_get_by_type global tunnel_forward 8.8.4.4:53)" + local dnsserver=`echo "$dnsstr"|awk -F ':' '{print $1}'` + local dnsport=`echo "$dnsstr"|awk -F ':' '{print $2}'` + if [ "$run_mode" = "gfw" ]; then + ipset add gfwlist $dnsserver 2>/dev/null + elif [ "$run_mode" = "oversea" ]; then + ipset add oversea $dnsserver 2>/dev/null + else + ipset add ss_spec_wan_ac $dnsserver nomatch 2>/dev/null + fi + start_pdnsd $dnsserver $dnsport + pdnsd_enable_flag=1 + fi + + if [ "$(uci_get_by_type global enable_switch)" = "1" ] ;then + if [ "$(uci_get_by_name $GLOBAL_SERVER switch_enable)" = "1" ] ;then + if [ -z "$switch_server" ] ;then + local switch_time=$(uci_get_by_type global switch_time) + local switch_timeout=$(uci_get_by_type global switch_timeout) + service_start /usr/bin/ssr-switch start $switch_time $switch_timeout + switch_enable=1 + fi + fi + fi + add_cron + + return $? +} + +gen_service_file() { + if [ $(uci_get_by_name $1 fast_open) = "1" ] ;then + fastopen="true"; + else + fastopen="false"; + fi + cat <<-EOF >$2 + { + "server": "0.0.0.0", + "server_port": $(uci_get_by_name $1 server_port), + "password": "$(uci_get_by_name $1 password)", + "timeout": $(uci_get_by_name $1 timeout 60), + "method": "$(uci_get_by_name $1 encrypt_method)", + "protocol": "$(uci_get_by_name $1 protocol)", + "protocol_param": "$(uci_get_by_name $1 protocol_param)", + "obfs": "$(uci_get_by_name $1 obfs)", + "obfs_param": "$(uci_get_by_name $1 obfs_param)", + "fast_open": $fastopen + } +EOF +} + +start_service() { +[ $(uci_get_by_name $1 enable) = "0" ] && return 1 +let server_count=server_count+1 +if [ $server_count = 1 ] ;then +iptables -N SSR-SERVER-RULE && \ +iptables -t filter -I INPUT -j SSR-SERVER-RULE +fi + +gen_service_file $1 /var/etc/${NAME}_${server_count}.json +/usr/bin/ssr-server -c /var/etc/${NAME}_${server_count}.json -u -f /var/run/ssr-server${server_count}.pid >/dev/null 2>&1 +iptables -t filter -A SSR-SERVER-RULE -p tcp --dport $(uci_get_by_name $1 server_port) -j ACCEPT +iptables -t filter -A SSR-SERVER-RULE -p udp --dport $(uci_get_by_name $1 server_port) -j ACCEPT +return 0 +} +gen_serv_include() { +FWI=$(uci get firewall.shadowsocksr.path 2>/dev/null) +[ -n "$FWI" ] || return 0 +if [ ! -f $FWI ] ;then +echo '#!/bin/sh' >$FWI +fi +extract_rules() { +echo "*filter" +iptables-save -t filter | grep SSR-SERVER-RULE|sed -e "s/^-A INPUT/-I INPUT/" +echo 'COMMIT' +} + cat <<-EOF >>$FWI + iptables-save -c | grep -v "SSR-SERVER" | iptables-restore -c + iptables-restore -n <<-EOT + $(extract_rules) + EOT +EOF + +} +start_server() { + SERVER_ENABLE=$(uci_get_by_type server_global enable_server) + [ "$SERVER_ENABLE" = 0 ] && return 0 + mkdir -p /var/run /var/etc + + config_load $NAME + config_foreach start_service server_config + gen_serv_include + return 0 +} + +start_local() { + local local_server=$(uci_get_by_type socks5_proxy server) + [ "$local_server" = "nil" ] && return 1 + mkdir -p /var/run /var/etc + gen_config_file $local_server 2 + /usr/bin/ssr-local -c $CONFIG_SOCK5_FILE -u \ + -l $(uci_get_by_type socks5_proxy local_port 1080) \ + -b $(uci_get_by_type socks5_proxy local_address 0.0.0.0) \ + -f /var/run/ssr-local.pid >/dev/null 2>&1 + local_enable=1 +} + +rules() { + [ "$GLOBAL_SERVER" = "nil" ] && return 1 + mkdir -p /var/run /var/etc + UDP_RELAY_SERVER=$(uci_get_by_type global udp_relay_server) + [ "$UDP_RELAY_SERVER" = "same" ] && UDP_RELAY_SERVER=$GLOBAL_SERVER + if start_rules ;then + return 0 + else + return 1 + fi +} + +start() { + if [ -z "$switch_server" ] ;then + GLOBAL_SERVER=$(uci_get_by_type global global_server) + else + GLOBAL_SERVER=$switch_server + switch_enable=1 + fi + + if rules ;then + start_redir + if ! [ "$(uci_get_by_type global pdnsd_enable)" = "2" ] ;then + mkdir -p /tmp/dnsmasq.d && cp -a /etc/dnsmasq.ssr /tmp/ && cp -a /etc/dnsmasq.oversea /tmp/ + if ! [ "$run_mode" = "oversea" ] ;then + cat > /tmp/dnsmasq.d/dnsmasq-ssr.conf < /tmp/dnsmasq.d/dnsmasq-ssr.conf </dev/null 2>&1 + /usr/share/shadowsocksr/gfw2ipset.sh + fi + fi + start_server + start_local + + if [ $(uci_get_by_type global monitor_enable) = 1 ] ;then + let total_count=server_count+redir_tcp+redir_udp+tunnel_enable+kcp_enable_flag+local_enable+pdnsd_enable_flag+switch_enable + if [ $total_count -gt 0 ] + then + #param:server(count) redir_tcp(0:no,1:yes) redir_udp tunnel kcp local gfw + service_start /usr/bin/ssr-monitor $server_count $redir_tcp $redir_udp $tunnel_enable $kcp_enable_flag $local_enable $pdnsd_enable_flag $switch_enable + fi + fi + + ENABLE_SERVER=$(uci_get_by_type global global_server) + [ "$ENABLE_SERVER" = "nil" ] && return 1 +} + +boot() { + (/usr/share/shadowsocksr/chinaipset.sh && sleep 5 && start >/dev/null 2>&1) & +} + +stop() { + /usr/bin/ssr-rules -f + srulecount=`iptables -L|grep SSR-SERVER-RULE|wc -l` + if [ $srulecount -gt 0 ] ;then + iptables -F SSR-SERVER-RULE + iptables -t filter -D INPUT -j SSR-SERVER-RULE + iptables -X SSR-SERVER-RULE 2>/dev/null + fi + if [ -z "$switch_server" ] ;then + kill -9 $(busybox ps -w | grep ssr-switch | grep -v grep | awk '{print $1}') >/dev/null 2>&1 + fi + if [ $(uci_get_by_type global monitor_enable) = 1 ] ;then + kill -9 $(busybox ps -w | grep ssr-monitor | grep -v grep | awk '{print $1}') >/dev/null 2>&1 + fi + killall -q -9 ssr-monitor + killall -q -9 ss-redir + killall -q -9 ssr-redir + killall -q -9 v2ray + killall -q -9 ssr-server + killall -q -9 kcptun-client + killall -q -9 ssr-local + if [ -f /var/run/pdnsd.pid ] ;then + kill $(cat /var/run/pdnsd.pid) >/dev/null 2>&1 + else + kill -9 $(busybox ps -w | grep pdnsd | grep -v grep | awk '{print $1}') >/dev/null 2>&1 + fi + + if [ -f "/tmp/dnsmasq.d/dnsmasq-ssr.conf" ]; then + rm -f /tmp/dnsmasq.d/dnsmasq-ssr.conf + /etc/init.d/dnsmasq restart >/dev/null 2>&1 + fi + del_cron +} diff --git a/package/lean/luci-app-ssr-plus/root/etc/uci-defaults/luci-ssr-plus b/package/lean/luci-app-ssr-plus/root/etc/uci-defaults/luci-ssr-plus new file mode 100755 index 0000000000..97aa54a468 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/etc/uci-defaults/luci-ssr-plus @@ -0,0 +1,18 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@shadowsocksr[-1] + add ucitrack shadowsocksr + set ucitrack.@shadowsocksr[-1].init=shadowsocksr + commit ucitrack + delete firewall.shadowsocksr + set firewall.shadowsocksr=include + set firewall.shadowsocksr.type=script + set firewall.shadowsocksr.path=/var/etc/shadowsocksr.include + set firewall.shadowsocksr.reload=1 + commit firewall +EOF + +/usr/share/shadowsocksr/gfw2ipset.sh +rm -f /tmp/luci-indexcache +exit 0 diff --git a/package/lean/luci-app-ssr-plus/root/usr/bin/ssr-ad b/package/lean/luci-app-ssr-plus/root/usr/bin/ssr-ad new file mode 100755 index 0000000000..668a262664 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/usr/bin/ssr-ad @@ -0,0 +1,6 @@ +#!/bin/sh -e + +if [ -f /tmp/adnew.conf ]; then + cat /tmp/adnew.conf | grep ^\|\|[^\*]*\^$ | sed -e 's:||:address\=\/:' -e 's:\^:/0\.0\.0\.0:' > /tmp/ad.conf +fi + diff --git a/package/lean/luci-app-ssr-plus/root/usr/bin/ssr-gfw b/package/lean/luci-app-ssr-plus/root/usr/bin/ssr-gfw new file mode 100755 index 0000000000..dffebbaca2 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/usr/bin/ssr-gfw @@ -0,0 +1,31 @@ +#!/bin/sh -e + +generate_china_banned() +{ + + cat $1 | base64 -d > /tmp/gfwlist.txt + rm -f $1 + sed -i '/^@@|/d' /tmp/gfwlist.txt + + 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 /tmp/gfw.b64 > /tmp/gfw.txt +rm -f /tmp/gfwlist.txt +sed '/.*/s/.*/server=\/\.&\/127.0.0.1#5335\nipset=\/\.&\/gfwlist/' /tmp/gfw.txt >/tmp/gfwnew.txt +rm -f /tmp/gfw.txt + diff --git a/package/lean/luci-app-ssr-plus/root/usr/bin/ssr-monitor b/package/lean/luci-app-ssr-plus/root/usr/bin/ssr-monitor new file mode 100755 index 0000000000..abf077f578 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/usr/bin/ssr-monitor @@ -0,0 +1,132 @@ +#!/bin/sh +# +# Copyright (C) 2017 openwrt-ssr +# Copyright (C) 2017 yushi studio +# +# This is free software, licensed under the GNU General Public License v3. +# See /LICENSE for more information. +# + + +NAME=shadowsocksr + +uci_get_by_name() { + local ret=$(uci get $NAME.$1.$2 2>/dev/null) + echo ${ret:=$3} +} + +uci_get_by_type() { + local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null) + echo ${ret:=$3} +} + +server_process_count=$1 +redir_tcp_process=$2 +redir_udp_process=$3 +tunnel_process=$4 +kcp_process=$5 +local_process=$6 +pdnsd_process=$7 +if [ -z "$pdnsd_process" ] ;then +pdnsd_process=0 +fi + +i=0 + +GLOBAL_SERVER=$(uci_get_by_type global global_server) +server=$(uci_get_by_name $GLOBAL_SERVER server) +lkcp_port=$(uci_get_by_name $GLOBAL_SERVER kcp_port) +server_port=$(uci_get_by_name $GLOBAL_SERVER server_port) +password=$(uci_get_by_name $GLOBAL_SERVER kcp_password) +kcp_param=$(uci_get_by_name $GLOBAL_SERVER kcp_param) +[ "$password" != "" ] && password="--key "${password} + +sock5_port=$(uci_get_by_type socks5_proxy local_port 1080) + +if echo $server|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then + server=${server} + else + server=`cat /etc/ssr_ip` +fi + +while [ "1" = "1" ] #ѭ +do + sleep 30 +#redir tcp + if [ $redir_tcp_process -gt 0 ] ;then + icount=`busybox ps -w | grep ssr-retcp |grep -v grep| wc -l` + if [ $icount = 0 ] ;then + logger -t "$NAME" "ssr redir tcp error.restart!" + /etc/init.d/shadowsocksr restart + exit 0 + fi + fi +#redir udp + if [ $redir_udp_process -gt 0 ] ;then + icount=`busybox ps -w | grep ssr-reudp|grep -v grep| wc -l` + if [ $icount = 0 ] ;then + logger -t "$NAME" "ssr redir udp error.restart!" + /etc/init.d/shadowsocksr restart + exit 0 + fi + fi +#tunnel + if [ $tunnel_process -gt 0 ] ;then + icount=`busybox ps -w | grep ssr-tunnel |grep -v grep| wc -l` + if [ $icount = 0 ] ;then + logger -t "$NAME" "ssr tunnel error.restart!" + /etc/init.d/shadowsocksr restart + exit 0 + fi + fi +#server + if [ $server_process_count -gt 0 ] ;then + icount=`busybox ps -w | grep ssr-server |grep -v grep| wc -l` + if [ $icount -lt $server_process_count ] #̹ҵ + then + logger -t "$NAME" "ssr server error.restart!" + killall -q -9 ssr-server + for i in `seq $server_process_count` + do + /usr/bin/ssr-server -c /var/etc/shadowsocksr_$i.json -u -f /var/run/ssr-server$i.pid + done + fi + fi +#kcptun + if [ $kcp_process -gt 0 ] ;then + icount=`busybox ps -w | grep kcptun-client |grep -v grep| wc -l` + if [ $icount -lt $kcp_process ] #̹ҵ + then + logger -t "$NAME" "ssr kcptun error.restart!" + killall -q -9 kcptun-client + + ( /usr/bin/kcptun-client -r $server:$kcp_port -l :$server_port $password $kcp_param &) + fi + fi +#local + if [ $local_process -gt 0 ] ;then + icount=`busybox ps -w | grep ssr-local |grep -v grep| wc -l` + if [ $icount -lt $local_process ] #̹ҵ + then + logger -t "$NAME" "ssr local error.restart!" + killall -q -9 ssr-local + + ( /usr/bin/ssr-local -c /var/etc/shadowsocksr_s.json -u -l $sock5_port -f /var/run/ssr-local.pid &) + fi + fi +#pdnsd + if [ $pdnsd_process -gt 0 ] ;then + icount=`busybox ps -w | grep pdnsd |grep -v grep| wc -l` + if [ $icount -lt $pdnsd_process ] #̹ҵ + then + logger -t "$NAME" "pdnsd tunnel error.restart!" + if [ -f /var/run/pdnsd.pid ] ;then + kill $(cat /var/run/pdnsd.pid) >/dev/null 2>&1 + else + kill -9 $(ps | grep pdnsd | grep -v grep | awk '{print $1}') >/dev/null 2>&1 + fi + + ( /usr/sbin/pdnsd -c /var/etc/pdnsd.conf -d &) + fi + fi +done diff --git a/package/lean/luci-app-ssr-plus/root/usr/bin/ssr-rules b/package/lean/luci-app-ssr-plus/root/usr/bin/ssr-rules new file mode 100755 index 0000000000..bad796dd18 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/usr/bin/ssr-rules @@ -0,0 +1,389 @@ +#!/bin/sh +# +# Copyright (C) 2017 openwrt-ssr +# Copyright (C) 2017 yushi studio +# +# This is free software, licensed under the GNU General Public License v3. +# See /LICENSE for more information. +# + +TAG="_SS_SPEC_RULE_" # comment tag +IPT="iptables -t nat" # alias of iptables +FWI=$(uci get firewall.shadowsocksr.path 2>/dev/null) # firewall include file + +usage() { + cat <<-EOF + Usage: ssr-rules [options] + + Valid options are: + + -s ip address of shadowsocksr remote server + -l port number of shadowsocksr local server + -S ip address of shadowsocksr remote UDP server + -L port number of shadowsocksr local UDP server + -i a file content is bypassed ip list + -a lan ip of access control, need a prefix to + define access control mode + -b wan ip of will be bypassed + -w wan ip of will be forwarded + -p lan ip of will be global proxy + -G lan ip of will be game mode proxy + -D proxy ports + -e extra options for iptables + -o apply the rules to the OUTPUT chain + -O apply the global rules to the OUTPUT chain + -u enable udprelay mode, TPROXY is required + -U enable udprelay mode, using different IP + and ports for TCP and UDP + -f flush the rules + -g gfw list mode + -r return china mode + -h show this help message and exit +EOF + exit $1 +} + +loger() { + # 1.alert 2.crit 3.err 4.warn 5.notice 6.info 7.debug + logger -st ssr-rules[$$] -p$1 $2 +} + +flush_r() { + flush_iptables() { + local ipt="iptables -t $1" + local DAT=$(iptables-save -t $1) + eval $(echo "$DAT" | grep "$TAG" | sed -e 's/^-A/$ipt -D/' -e 's/$/;/') + for chain in $(echo "$DAT" | awk '/^:SS_SPEC/{print $1}'); do + $ipt -F ${chain:1} 2>/dev/null && $ipt -X ${chain:1} + done + } + flush_iptables nat + flush_iptables mangle + ip rule del fwmark 0x01/0x01 table 100 2>/dev/null + ip route del local 0.0.0.0/0 dev lo table 100 2>/dev/null + ipset -X ss_spec_lan_ac 2>/dev/null + ipset -X ss_spec_wan_ac 2>/dev/null + ipset -X ssr_gen_router 2>/dev/null + ipset -X fplan 2>/dev/null + ipset -X gmlan 2>/dev/null + ipset -X oversea 2>/dev/null + ipset -X whitelist 2>/dev/null + ipset -X blacklist 2>/dev/null + [ -n "$FWI" ] && echo '#!/bin/sh' >$FWI + return 0 +} + +ipset_r() { + ipset -N gmlan hash:net 2>/dev/null + for ip in $LAN_GM_IP; do ipset -! add gmlan $ip ; done + + if [ "$RUNMODE" = "router" ] ;then + ipset -! -R <<-EOF || return 1 + create ss_spec_wan_ac hash:net + $(gen_iplist | sed -e "s/^/add ss_spec_wan_ac /") +EOF + ipset -N gfwlist hash:net 2>/dev/null + $IPT -N SS_SPEC_WAN_AC + $IPT -I SS_SPEC_WAN_AC -d $server -j RETURN + $IPT -A SS_SPEC_WAN_AC -m set --match-set ss_spec_wan_ac dst -j RETURN + $IPT -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW + + elif [ "$RUNMODE" = "gfw" ] ;then + ipset -N gfwlist hash:net 2>/dev/null + $IPT -N SS_SPEC_WAN_AC + $IPT -A SS_SPEC_WAN_AC -m set --match-set gfwlist dst -j SS_SPEC_WAN_FW + $IPT -A SS_SPEC_WAN_AC -m set --match-set gmlan src -m set ! --match-set china dst -j SS_SPEC_WAN_FW + $IPT -A SS_SPEC_WAN_AC -m set --match-set china dst -j RETURN + $IPT -I SS_SPEC_WAN_AC -d $server -j RETURN + + elif [ "$RUNMODE" = "oversea" ] ;then + ipset -N oversea hash:net 2>/dev/null + $IPT -N SS_SPEC_WAN_AC + ipset -N gmlan hash:net 2>/dev/null + for ip in $LAN_GM_IP; do ipset -! add gmlan $ip ; done + $IPT -A SS_SPEC_WAN_AC -m set --match-set china dst -j SS_SPEC_WAN_FW + $IPT -I SS_SPEC_WAN_AC -d $server -j RETURN + + elif [ "$RUNMODE" = "all" ] ;then + $IPT -N SS_SPEC_WAN_AC + $IPT -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW + $IPT -I SS_SPEC_WAN_AC -d $server -j RETURN + + fi + + ipset -N fplan hash:net 2>/dev/null + for ip in $LAN_FP_IP; do ipset -! add fplan $ip ; done + $IPT -I SS_SPEC_WAN_AC -m set --match-set fplan src -j SS_SPEC_WAN_FW + + ipset -N whitelist hash:net 2>/dev/null + ipset -N blacklist hash:net 2>/dev/null + $IPT -I SS_SPEC_WAN_AC -m set --match-set blacklist dst -j SS_SPEC_WAN_FW + $IPT -I SS_SPEC_WAN_AC -m set --match-set whitelist dst -j RETURN + + for ip in $WAN_BP_IP; do ipset -! add whitelist $ip; done + for ip in $WAN_FW_IP; do ipset -! add blacklist $ip; done + + return $? +} + +fw_rule() { + $IPT -N SS_SPEC_WAN_FW + $IPT -A SS_SPEC_WAN_FW -d 0.0.0.0/8 -j RETURN + $IPT -A SS_SPEC_WAN_FW -d 10.0.0.0/8 -j RETURN + $IPT -A SS_SPEC_WAN_FW -d 127.0.0.0/8 -j RETURN + $IPT -A SS_SPEC_WAN_FW -d 169.254.0.0/16 -j RETURN + $IPT -A SS_SPEC_WAN_FW -d 172.16.0.0/12 -j RETURN + $IPT -A SS_SPEC_WAN_FW -d 192.168.0.0/16 -j RETURN + $IPT -A SS_SPEC_WAN_FW -d 224.0.0.0/4 -j RETURN + $IPT -A SS_SPEC_WAN_FW -d 240.0.0.0/4 -j RETURN + $IPT -A SS_SPEC_WAN_FW -p tcp $PROXY_PORTS \ + -j REDIRECT --to-ports $local_port 2>/dev/null || { + loger 3 "Can't redirect, please check the iptables." + exit 1 + } + return $? +} + +ac_rule() { + if [ -n "$LAN_AC_IP" ]; then + case "${LAN_AC_IP:0:1}" in + w|W) + MATCH_SET="-m set --match-set ss_spec_lan_ac src" + ;; + b|B) + MATCH_SET="-m set ! --match-set ss_spec_lan_ac src" + ;; + *) + loger 3 "Bad argument \`-a $LAN_AC_IP\`." + return 2 + ;; + esac + fi + IFNAME=$(uci get -P/var/state network.lan.ifname 2>/dev/null) + ipset -! -R <<-EOF || return 1 + create ss_spec_lan_ac hash:net + $(for ip in ${LAN_AC_IP:1}; do echo "add ss_spec_lan_ac $ip"; done) +EOF + $IPT -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p tcp $EXT_ARGS $MATCH_SET \ + -m comment --comment "$TAG" -j SS_SPEC_WAN_AC + if [ "$OUTPUT" = 1 ]; then + $IPT -I OUTPUT 1 -p tcp $EXT_ARGS \ + -m comment --comment "$TAG" -j SS_SPEC_WAN_AC + elif [ "$OUTPUT" = 2 ]; then + ipset -! -R <<-EOF || return 1 + create ssr_gen_router hash:net + $(gen_spec_iplist | sed -e "s/^/add ssr_gen_router /") +EOF + $IPT -N SS_SPEC_ROUTER && \ + $IPT -A SS_SPEC_ROUTER -m set --match-set ssr_gen_router dst -j RETURN && \ + $IPT -A SS_SPEC_ROUTER -j SS_SPEC_WAN_FW + $IPT -I OUTPUT 1 -p tcp -m comment --comment "$TAG" -j SS_SPEC_ROUTER + fi + return $? +} + +tp_rule() { + [ -n "$TPROXY" ] || return 0 + ip rule add fwmark 0x01/0x01 table 100 + ip route add local 0.0.0.0/0 dev lo table 100 + local ipt="iptables -t mangle" + $ipt -N SS_SPEC_TPROXY + $ipt -A SS_SPEC_TPROXY -p udp --dport 53 -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -d 0.0.0.0/8 -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -d 10.0.0.0/8 -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -d 127.0.0.0/8 -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -d 169.254.0.0/16 -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -d 172.16.0.0/12 -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -d 192.168.0.0/16 -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -d 224.0.0.0/4 -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -d 240.0.0.0/4 -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -d $SERVER -j RETURN + + $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set fplan src \ + -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 + + if [ "$RUNMODE" = "router" ] ;then + $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set gmlan src -m set ! --match-set china dst \ + -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 + $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set ! --match-set ss_spec_wan_ac dst \ + -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 + + elif [ "$RUNMODE" = "gfw" ] ;then + $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set china dst -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set gmlan src -m set ! --match-set china dst \ + -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 + $ipt -A SS_SPEC_TPROXY -p udp -m set $PROXY_PORTS --match-set gfwlist dst \ + -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 + + elif [ "$RUNMODE" = "oversea" ] ;then + $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set china dst \ + -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 + + elif [ "$RUNMODE" = "all" ] ;then + $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 + fi + + $ipt -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS $MATCH_SET \ + -m comment --comment "$TAG" -j SS_SPEC_TPROXY + + return $? +} + +get_wan_ip() { + cat <<-EOF | grep -E "^([0-9]{1,3}\.){3}[0-9]{1,3}" + $server + $SERVER + $WAN_BP_IP +EOF +} + +gen_iplist() { + cat <<-EOF + 0.0.0.0/8 + 10.0.0.0/8 + 100.64.0.0/10 + 127.0.0.0/8 + 169.254.0.0/16 + 172.16.0.0/12 + 192.0.0.0/24 + 192.0.2.0/24 + 192.88.99.0/24 + 192.168.0.0/16 + 198.18.0.0/15 + 198.51.100.0/24 + 203.0.113.0/24 + 224.0.0.0/4 + 240.0.0.0/4 + 255.255.255.255 + $(get_wan_ip) + $(cat ${IGNORE_LIST:=/dev/null} 2>/dev/null) +EOF +} + +gen_spec_iplist() { + cat <<-EOF + 0.0.0.0/8 + 10.0.0.0/8 + 100.64.0.0/10 + 127.0.0.0/8 + 169.254.0.0/16 + 172.16.0.0/12 + 192.0.0.0/24 + 192.0.2.0/24 + 192.88.99.0/24 + 192.168.0.0/16 + 198.18.0.0/15 + 198.51.100.0/24 + 203.0.113.0/24 + 224.0.0.0/4 + 240.0.0.0/4 + 255.255.255.255 + $(get_wan_ip) +EOF +} + +gen_include() { + [ -n "$FWI" ] || return 0 + extract_rules() { + echo "*$1" + iptables-save -t $1 | grep SS_SPEC_ |\ + sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/" + echo 'COMMIT' + } + cat <<-EOF >>$FWI + iptables-save -c | grep -v "SS_SPEC" | iptables-restore -c + iptables-restore -n <<-EOT + $(extract_rules nat) + $(extract_rules mangle) + EOT +EOF + return 0 +} + +while getopts ":s:l:S:L:i:e:a:b:w:p:G:D:oOuUfgrczh" arg; do + case "$arg" in + s) + server=$OPTARG + ;; + l) + local_port=$OPTARG + ;; + S) + SERVER=$OPTARG + ;; + L) + LOCAL_PORT=$OPTARG + ;; + i) + IGNORE_LIST=$OPTARG + ;; + e) + EXT_ARGS=$OPTARG + ;; + a) + LAN_AC_IP=$OPTARG + ;; + b) + WAN_BP_IP=$(for ip in $OPTARG; do echo $ip; done) + ;; + w) + WAN_FW_IP=$OPTARG + ;; + p) + LAN_FP_IP=$OPTARG + ;; + G) + LAN_GM_IP=$OPTARG + ;; + D) + PROXY_PORTS=$OPTARG + ;; + o) + OUTPUT=1 + ;; + O) + OUTPUT=2 + ;; + u) + TPROXY=1 + ;; + U) + TPROXY=2 + ;; + g) + RUNMODE=gfw + ;; + r) + RUNMODE=router + ;; + c) + RUNMODE=oversea + ;; + z) + RUNMODE=all + ;; + f) + flush_r + exit 0 + ;; + h) + usage 0 + ;; + esac +done + +if [ -z "$server" -o -z "$local_port" ]; then + usage 2 +fi + +if [ "$TPROXY" = 1 ]; then + SERVER=$server + LOCAL_PORT=$local_port +elif [ "$TPROXY" = 2 ]; then + : ${SERVER:?"You must assign an ip for the udp relay server."} + : ${LOCAL_PORT:?"You must assign a port for the udp relay server."} +fi + +flush_r && fw_rule && ipset_r && ac_rule && tp_rule && gen_include +[ "$?" = 0 ] || loger 3 "Start failed!" +exit $? \ No newline at end of file diff --git a/package/lean/luci-app-ssr-plus/root/usr/bin/ssr-switch b/package/lean/luci-app-ssr-plus/root/usr/bin/ssr-switch new file mode 100755 index 0000000000..9be20f019f --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/usr/bin/ssr-switch @@ -0,0 +1,175 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (C) 2017 openwrt-ssr +# Copyright (C) 2017 yushi studio +# +# This is free software, licensed under the GNU General Public License v3. +# See /LICENSE for more information. +# + +cycle_time=60 +switch_time=3 +normal_flag=0 +server_locate=0 +server_count=0 +NAME=shadowsocksr +ENABLE_SERVER=nil +CONFIG_SWTICH_FILE=/var/etc/${NAME}_t.json + + +[ -n "$1" ] && cycle_time=$1 +[ -n "$2" ] && switch_time=$2 + +uci_get_by_name() { + local ret=$(uci get $NAME.$1.$2 2>/dev/null) + echo ${ret:=$3} +} + +uci_get_by_type() { + local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null) + echo ${ret:=$3} +} + +DEFAULT_SERVER=$(uci_get_by_type global global_server) +CURRENT_SERVER=$DEFAULT_SERVER + +#判断代理是否正常 +check_proxy() { +/usr/bin/ssr-check www.google.com 80 $switch_time 1 +if [ "$?" == "0" ]; then + return 0 +else + /usr/bin/ssr-check www.baidu.com 80 $switch_time 1 + if [ "$?" == "0" ]; then + #goole不通baidu通则不正常 + return 1 + else + return 2 + fi +fi +return 0 +} + + +test_proxy() { +local servername=$(uci_get_by_name $1 server) +local serverport=$(uci_get_by_name $1 server_port) +ret=$(ping -c 3 $servername | grep 'loss' | awk -F ',' '{ print $3 }' | awk -F "%" '{ print $1 }') +[ -z "$ret" ] && return 1 +[ "$ret" -gt "50" ] && return 1 +ipset add ss_spec_wan_ac $servername 2>/dev/null +ret=$? +/usr/bin/ssr-check $servername $serverport $switch_time +local ret2=$? +if [ "$ret" = "0" ] ;then +ipset del ss_spec_wan_ac $servername 2>/dev/null +fi +if [ "$ret2" = "0" ] ;then +return 0 +else +return 1 +fi +} + +search_proxy() { +let server_count=server_count+1 +[ "$normal_flag" = "1" -a "$server_count" -le "$server_locate" ] && return 0 +[ "$(uci_get_by_name $1 switch_enable)" != "1" ] && return 1 +[ $ENABLE_SERVER != nil ] && return 0 +[ "$1" = "$CURRENT_SERVER" ] && return 0 +local servername=$(uci_get_by_name $1 server) +local serverport=$(uci_get_by_name $1 server_port) +ipset add ss_spec_wan_ac $servername 2>/dev/null +ret=$? + /usr/bin/ssr-check $servername $serverport $switch_time + local ret2=$? +if [ "$ret" = "0" ] ;then +ipset del ss_spec_wan_ac $servername 2>/dev/null +fi +if [ "$ret2" = "0" ] ;then +server_locate=$server_count +ENABLE_SERVER=$1 +return 0 +else +return 1 +fi + +} +#选择可用的代理 +select_proxy() { + +config_load $NAME +ENABLE_SERVER=nil +mkdir -p /var/run /var/etc +server_count=0 +config_foreach search_proxy servers + +} + +#切换代理 +switch_proxy() { +/etc/init.d/shadowsocksr restart $1 +return 0 +} + +start() { +#不支持kcptun启用时的切换 +[ $(uci_get_by_name $DEFAULT_SERVER kcp_enable) = "1" ] && return 1 + +while [ "1" = "1" ] #死循环 +do + sleep $cycle_time + + LOGTIME=$(date "+%Y-%m-%d %H:%M:%S") + + + #判断当前代理是否为缺省服务器 + if [ "$CURRENT_SERVER" != "$DEFAULT_SERVER" ] ;then + #echo "not default proxy" + echo "$(date "+%Y-%m-%d %H:%M:%S") Current server is not default Main server, try to switch back." >> /tmp/ssrplus.log + + #检查缺省服务器是否正常 + if test_proxy $DEFAULT_SERVER ;then + #echo "switch to default proxy" + echo "$(date "+%Y-%m-%d %H:%M:%S") Main server is avilable." >> /tmp/ssrplus.log + #缺省服务器正常,切换回来 + CURRENT_SERVER=$DEFAULT_SERVER + switch_proxy $CURRENT_SERVER + echo "$(date "+%Y-%m-%d %H:%M:%S") switch to default ["$(uci_get_by_name $CURRENT_SERVER server)"] proxy!" >> /tmp/ssrplus.log + continue + else + echo "$(date "+%Y-%m-%d %H:%M:%S") Main server is NOT avilable.Continue using current server." >> /tmp/ssrplus.log + fi + fi + + #判断当前代理是否正常 + check_proxy + current_ret=$? + + if [ "$current_ret" = "1" ] ;then + #当前代理错误,判断有无可用的服务器 + #echo "current error" + echo "$(date "+%Y-%m-%d %H:%M:%S") Current server error, try to switch another server." >> /tmp/ssrplus.log + + select_proxy + if [ "$ENABLE_SERVER" != nil ] ;then + #有其他服务器可用,进行切换 + #echo $(uci_get_by_name $new_proxy server) + echo "$(date "+%Y-%m-%d %H:%M:%S") Another server is avilable, now switching server." >> /tmp/ssrplus.log + CURRENT_SERVER=$ENABLE_SERVER + switch_proxy $CURRENT_SERVER + normal_flag=1 + echo "$(date "+%Y-%m-%d %H:%M:%S") ShadowsocksR server switch OK" >> /tmp/ssrplus.log + else + switch_proxy $CURRENT_SERVER + normal_flag=1 + echo "$(date "+%Y-%m-%d %H:%M:%S") Try restart current server." >> /tmp/ssrplus.log + fi + else + normal_flag=0 + echo "$(date "+%Y-%m-%d %H:%M:%S") ShadowsocksR No Problem." >> /tmp/ssrplus.log + fi + + +done +} diff --git a/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/chinaipset.sh b/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/chinaipset.sh new file mode 100755 index 0000000000..044d524d94 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/chinaipset.sh @@ -0,0 +1,5 @@ +echo "create china hash:net family inet hashsize 1024 maxelem 65536" > /tmp/china.ipset +awk '!/^$/&&!/^#/{printf("add china %s'" "'\n",$0)}' /etc/china_ssr.txt >> /tmp/china.ipset +ipset -! flush china +ipset -! restore < /tmp/china.ipset 2>/dev/null +rm -f /tmp/china.ipset diff --git a/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/genv2config.lua b/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/genv2config.lua new file mode 100644 index 0000000000..85957e7143 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/genv2config.lua @@ -0,0 +1,95 @@ +local ucursor = require "luci.model.uci".cursor() +local json = require "luci.jsonc" +local server_section = arg[1] +local proto = arg[2] +local local_port = arg[3] + +local server = ucursor:get_all("shadowsocksr", server_section) + +local v2ray = { + log = { + -- error = "/var/ssrplus.log", + loglevel = "warning" + }, + -- 传入连接 + inbound = { + port = local_port, + protocol = "dokodemo-door", + settings = { + network = proto, + followRedirect = true + }, + sniffing = { + enabled = true, + destOverride = { "http", "tls" } + } + }, + -- 传出连接 + outbound = { + protocol = "vmess", + settings = { + vnext = { + { + address = server.server, + port = tonumber(server.server_port), + users = { + { + id = server.vmess_id, + alterId = tonumber(server.alter_id), + security = server.security + } + } + } + } + }, + -- 底层传输配置 + streamSettings = { + network = server.transport, + security = (server.tls == '1') and "tls" or "none", + tlsSettings = {allowInsecure = (server.insecure == "1") and true or false,serverName=server.ws_host,}, + kcpSettings = (server.transport == "kcp") and { + mtu = tonumber(server.mtu), + tti = tonumber(server.tti), + uplinkCapacity = tonumber(server.uplink_capacity), + downlinkCapacity = tonumber(server.downlink_capacity), + congestion = (server.congestion == "1") and true or false, + readBufferSize = tonumber(server.read_buffer_size), + writeBufferSize = tonumber(server.write_buffer_size), + header = { + type = server.kcp_guise + } + } or nil, + wsSettings = (server.transport == "ws") and (server.ws_path ~= nil or server.ws_host ~= nil) and { + path = server.ws_path, + headers = (server.ws_host ~= nil) and { + Host = server.ws_host + } or nil, + } or nil, + httpSettings = (server.transport == "h2") and { + path = server.h2_path, + host = server.h2_host, + } or nil, + quicSettings = (server.transport == "quic") and { + security = server.quic_security, + key = server.quic_key, + header = { + type = server.quic_guise + } + } or nil + }, + mux = { + enabled = (server.mux == "1") and true or false, + concurrency = tonumber(server.concurrency) + } + }, + + -- 额外传出连接 + outboundDetour = { + { + protocol = "freedom", + tag = "direct", + settings = { keep = "" } + } + } +} +print(json.stringify(v2ray, 1)) diff --git a/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/gfw2ipset.sh b/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/gfw2ipset.sh new file mode 100755 index 0000000000..a9249ceed1 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/gfw2ipset.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +mkdir -p /tmp/dnsmasq.ssr + +awk '!/^$/&&!/^#/{printf("ipset=/.%s/'"gfwlist"'\n",$0)}' /etc/config/gfw.list > /tmp/dnsmasq.ssr/custom_forward.conf +awk '!/^$/&&!/^#/{printf("server=/.%s/'"127.0.0.1#5335"'\n",$0)}' /etc/config/gfw.list >> /tmp/dnsmasq.ssr/custom_forward.conf + +awk '!/^$/&&!/^#/{printf("ipset=/.%s/'"blacklist"'\n",$0)}' /etc/config/black.list > /tmp/dnsmasq.ssr/blacklist_forward.conf +awk '!/^$/&&!/^#/{printf("server=/.%s/'"127.0.0.1#5335"'\n",$0)}' /etc/config/black.list >> /tmp/dnsmasq.ssr/blacklist_forward.conf + +awk '!/^$/&&!/^#/{printf("ipset=/.%s/'"whitelist"'\n",$0)}' /etc/config/white.list > /tmp/dnsmasq.ssr/whitelist_forward.conf + diff --git a/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/subscribe.sh b/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/subscribe.sh new file mode 100755 index 0000000000..4323a46893 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/subscribe.sh @@ -0,0 +1,259 @@ +#!/bin/bash +# Copyright (C) 2017 XiaoShan https://www.mivm.cn + +. /usr/share/libubox/jshn.sh + +urlsafe_b64decode() { + local d="====" data=$(echo $1 | sed 's/_/\//g; s/-/+/g') + local mod4=$((${#data}%4)) + [ $mod4 -gt 0 ] && data=${data}${d:mod4} + echo $data | base64 -d +} + +urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; } + +echo_date(){ + echo $(TZ=UTC-8 date -R +%Y-%m-%d\ %X):$1 +} + +Server_Update() { + local uci_set="uci -q set $name.$1." + ${uci_set}grouphashkey="$ssr_grouphashkey" + ${uci_set}hashkey="$ssr_hashkey" + ${uci_set}alias="[$ssr_group] $ssr_remarks" + ${uci_set}auth_enable="0" + ${uci_set}switch_enable="1" + ${uci_set}type="$ssr_type" + ${uci_set}server="$ssr_host" + ${uci_set}server_port="$ssr_port" + ${uci_set}local_port="1234" + uci -q get $name.@servers[$1].timeout >/dev/null || ${uci_set}timeout="60" + ${uci_set}password="$ssr_passwd" + ${uci_set}encrypt_method="$ssr_method" + ${uci_set}protocol="$ssr_protocol" + ${uci_set}protocol_param="$ssr_protoparam" + ${uci_set}obfs="$ssr_obfs" + ${uci_set}obfs_param="$ssr_obfsparam" + ${uci_set}fast_open="0" + ${uci_set}kcp_enable="0" + ${uci_set}kcp_port="0" + ${uci_set}kcp_param="--nocomp" + + if [ "$ssr_type" = "v2ray" ]; then + #v2ray + ${uci_set}alter_id="$ssr_alter_id" + ${uci_set}vmess_id="$ssr_vmess_id" + ${uci_set}transport="$ssr_transport" + ${uci_set}tcp_guise="$ssr_tcp_guise" + ${uci_set}ws_host="$ssr_ws_host" + ${uci_set}ws_path="$ssr_ws_path" + ${uci_set}h2_host="$ssr_h2_host" + ${uci_set}h2_path="$ssr_h2_path" + ${uci_set}tls="$ssr_tls" + ${uci_set}security=$ssr_security + ${uci_set}alias="$ssr_remarks" + fi + + if [ "$ssr_type" = "ss" ]; then + ${uci_set}encrypt_method_ss="$ss_method" + ${uci_set}alias="$ssr_remarks" + fi + +} + +name=shadowsocksr +subscribe_url=($(uci get $name.@server_subscribe[0].subscribe_url)) #订阅服务器地址 +[ ${#subscribe_url[@]} -eq 0 ] && exit 1 +[ $(uci -q get $name.@server_subscribe[0].proxy || echo 0) -eq 0 ] && /etc/init.d/$name stop >/dev/null 2>&1 +log_name=${name}_subscribe +for ((o=0;o<${#subscribe_url[@]};o++)) +do + echo_date "从 ${subscribe_url[o]} 获取订阅" + echo_date "开始更新在线订阅列表..." + echo_date "尝试下载订阅链接到本地临时文件,请稍等..." + subscribe_data=$(wget-ssl --no-check-certificate -t 3 -T 30 -O- ${subscribe_url[o]}) + curl_code=$? + # 计算group的hashkey + ssr_grouphashkey=$(echo "${subscribe_url[o]}" | md5sum | cut -d ' ' -f1) + if [ ! $curl_code -eq 0 ];then + echo_date "下载订阅失败,自动重试中..." + subscribe_data=$(wget-ssl --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" --no-check-certificate -t 3 -T 30 -O- ${subscribe_url[o]}) + curl_code=$? + fi + if [ $curl_code -eq 0 ];then + echo_date "下载订阅成功,开始解析节点信息..." + ssr_url=($(echo $subscribe_data | base64 -d | sed 's/\r//g')) # 解码数据并删除 \r 换行符 + subscribe_max=$(echo ${ssr_url[0]} | grep -i MAX= | awk -F = '{print $2}') + subscribe_max_x=() + if [ -n "$subscribe_max" ]; then + while [ ${#subscribe_max_x[@]} -ne $subscribe_max ] + do + if [ ${#ssr_url[@]} -ge 10 ]; then + if [ $((${RANDOM:0:2}%2)) -eq 0 ]; then + temp_x=${RANDOM:0:1} + else + temp_x=${RANDOM:0:2} + fi + else + temp_x=${RANDOM:0:1} + fi + [ $temp_x -lt ${#ssr_url[@]} -a -z "$(echo "${subscribe_max_x[*]}" | grep -w $temp_x)" ] && subscribe_max_x[${#subscribe_max_x[@]}]="$temp_x" + done + else + subscribe_max=${#ssr_url[@]} + fi + echo_date "共计$subscribe_max个节点" + + ssr_group=$(urlsafe_b64decode $(urlsafe_b64decode ${ssr_url[$((${#ssr_url[@]} - 1))]//ssr:\/\//} | sed 's/&/\n/g' | grep group= | awk -F = '{print $2}')) + if [ -z "$ssr_group" ]; then + ssr_group="default" + fi + if [ -n "$ssr_group" ]; then + subscribe_i=0 + subscribe_n=0 + subscribe_o=0 + subscribe_x="" + temp_host_o=() + curr_ssr=$(uci show $name | grep @servers | grep -c server=) + for ((x=0;x<$curr_ssr;x++)) # 循环已有服务器信息,匹配当前订阅群组 + do + temp_alias=$(uci -q get $name.@servers[$x].grouphashkey | grep "$ssr_grouphashkey") + [ -n "$temp_alias" ] && temp_host_o[${#temp_host_o[@]}]=$(uci get $name.@servers[$x].hashkey) + done + + for ((x=0;x<$subscribe_max;x++)) # 循环链接 + do + [ ${#subscribe_max_x[@]} -eq 0 ] && temp_x=$x || temp_x=${subscribe_max_x[x]} + result=$(echo ${ssr_url[temp_x]} | grep "ss") + subscribe_url_type=$(echo "$ssr_url" | awk -F ':' '{print $1}') + + if [ "$subscribe_url_type" = "ss" ]; then + temp_info=${ssr_url[temp_x]//ss:\/\//} # 解码 SS 链接 + # 计算hashkey + ssr_hashkey=$(echo "$temp_info" | md5sum | cut -d ' ' -f1) + + info=$(urlsafe_b64decode $(echo "$temp_info" | awk -F '@' '{print $1}')) + temp_info_array=(${info//:/ }) + ssr_type="ss" + ss_method=${temp_info_array[0]} + ssr_passwd=${temp_info_array[1]} + info=$(echo "$temp_info" | awk -F '@' '{print $2}' | awk -F '#' '{print $1}') + temp_info_array=(${info//:/ }) + ssr_host=${temp_info_array[0]} + ssr_port=${temp_info_array[1]} + ssr_remarks=$(urldecode $(echo "$temp_info" | awk -F '#' '{print $2}')) + fi + + if [ "$subscribe_url_type" = "ssr" ]; then + temp_info=$(urlsafe_b64decode ${ssr_url[temp_x]//ssr:\/\//}) # 解码 SSR 链接 + # 计算hashkey + ssr_hashkey=$(echo "$temp_info" | md5sum | cut -d ' ' -f1) + + info=${temp_info///?*/} + temp_info_array=(${info//:/ }) + ssr_type="ssr" + ssr_host=${temp_info_array[0]} + ssr_port=${temp_info_array[1]} + ssr_protocol=${temp_info_array[2]} + ssr_method=${temp_info_array[3]} + ssr_obfs=${temp_info_array[4]} + ssr_passwd=$(urlsafe_b64decode ${temp_info_array[5]}) + info=${temp_info:$((${#info} + 2))} + info=(${info//&/ }) + ssr_protoparam="" + ssr_obfsparam="" + ssr_remarks="$temp_x" + for ((i=0;i<${#info[@]};i++)) # 循环扩展信息 + do + temp_info=($(echo ${info[i]} | sed 's/=/ /g')) + case "${temp_info[0]}" in + protoparam) + ssr_protoparam=$(urlsafe_b64decode ${temp_info[1]});; + obfsparam) + ssr_obfsparam=$(urlsafe_b64decode ${temp_info[1]});; + remarks) + ssr_remarks=$(urlsafe_b64decode ${temp_info[1]});; + esac + done + fi + + if [ "$subscribe_url_type" = "vmess" ]; then + temp_info=$(urlsafe_b64decode ${ssr_url[temp_x]//vmess:\/\//}) # 解码 Vmess 链接 + # 计算hashkey + ssr_hashkey=$(echo "$temp_info" | md5sum | cut -d ' ' -f1) + + ssr_type="v2ray" + json_load "$temp_info" + json_get_var ssr_host add + json_get_var ssr_port port + json_get_var ssr_alter_id aid + json_get_var ssr_vmess_id id + json_get_var ssr_security security + if [ "$ssr_security" == "" ]; then + ssr_security="auto" + fi + json_get_var ssr_transport net + json_get_var ssr_remarks ps + ssr_tcp_guise="none" + json_get_var ssr_ws_host host + json_get_var ssr_ws_path path + json_get_var ssr_h2_host host + json_get_var ssr_h2_path path + json_get_var ssr_tls tls + if [ "$ssr_tls" == "tls" -o "$ssr_tls" == "1" ]; then + ssr_tls="1" + else + ssr_tls="0" + fi + fi + + if [ -z "ssr_remarks" ]; then # 没有备注的话则生成一个 + ssr_remarks="$ssr_host:$ssr_port"; + fi + + uci_name_tmp=$(uci show $name | grep -w "$ssr_hashkey" | awk -F . '{print $2}') + if [ -z "$uci_name_tmp" ]; then # 判断当前服务器信息是否存在 + uci_name_tmp=$(uci add $name servers) + subscribe_n=$(($subscribe_n + 1)) + fi + Server_Update $uci_name_tmp + subscribe_x=$subscribe_x$ssr_hashkey" " + ssrtype=$(echo $ssr_type | tr '[a-z]' '[A-Z]') + echo_date "$ssrtype节点:【$ssr_remarks】" + + # SSR + # echo "服务器地址: $ssr_host" + # echo "服务器端口 $ssr_port" + # echo "密码: $ssr_passwd" + # echo "SS加密: $ss_method" + # echo "加密: $ssr_method" + # echo "协议: $ssr_protocol" + # echo "协议参数: $ssr_protoparam" + # echo "混淆: $ssr_obfs" + # echo "混淆参数: $ssr_obfsparam" + # echo "备注: $ssr_remarks" + + done + for ((x=0;x<${#temp_host_o[@]};x++)) # 新旧服务器信息匹配,如果旧服务器信息不存在于新服务器信息则删除 + do + if [ -z "$(echo "$subscribe_x" | grep -w ${temp_host_o[x]})" ]; then + uci_name_tmp=$(uci show $name | grep ${temp_host_o[x]} | awk -F . '{print $2}') + uci delete $name.$uci_name_tmp + subscribe_o=$(($subscribe_o + 1)) + fi + done + echo_date "本次更新订阅来源 【$ssr_group】 服务器数量: ${#ssr_url[@]} 新增服务器: $subscribe_n 删除服务器: $subscribe_o" + echo_date "在线订阅列表更新完成!请等待网页自动刷新!" + subscribe_log="$ssr_group 服务器订阅更新成功 服务器数量: ${#ssr_url[@]} 新增服务器: $subscribe_n 删除服务器: $subscribe_o" + logger -st $log_name[$$] -p6 "$subscribe_log" + uci commit $name + else + echo_date "${subscribe_url[$o]} 订阅数据解析失败 无法获取 Group" + logger -st $log_name[$$] -p3 "${subscribe_url[$o]} 订阅数据解析失败 无法获取 Group" + fi + else + echo_date "${subscribe_url[$o]} 订阅数据获取失败 错误代码: $curl_code" + logger -st $log_name[$$] -p3 "${subscribe_url[$o]} 订阅数据获取失败 错误代码: $curl_code" + fi +done +/etc/init.d/$name restart >/dev/null 2>&1 diff --git a/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/update.sh b/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/update.sh new file mode 100755 index 0000000000..d7fb68567f --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/update.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +chnroute_data=$(wget -O- -t 3 -T 3 http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest) +[ $? -eq 0 ] && { + echo "$chnroute_data" | grep ipv4 | grep CN | awk -F\| '{ printf("%s/%d\n", $4, 32-log($5)/log(2)) }' > /tmp/china_ssr.txt +} + +if [ -s "/tmp/china_ssr.txt" ];then + if ( ! cmp -s /tmp/china_ssr.txt /etc/china_ssr.txt );then + mv /tmp/china_ssr.txt /etc/china_ssr.txt + fi +fi + +/usr/share/shadowsocksr/chinaipset.sh + +wget-ssl --no-check-certificate https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt -O /tmp/gfw.b64 +/usr/bin/ssr-gfw + +if [ -s "/tmp/gfwnew.txt" ];then + if ( ! cmp -s /tmp/gfwnew.txt /etc/dnsmasq.ssr/gfw_list.conf );then + mv /tmp/gfwnew.txt /etc/dnsmasq.ssr/gfw_list.conf + echo "copy" + fi +fi + +/etc/init.d/shadowsocksr restart diff --git a/package/lean/pdnsd-alt/Makefile b/package/lean/pdnsd-alt/Makefile new file mode 100644 index 0000000000..bbe3ebf51b --- /dev/null +++ b/package/lean/pdnsd-alt/Makefile @@ -0,0 +1,54 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=pdnsd +PKG_VERSION:=1.2.9b-par +PKG_RELEASE=$(PKG_SOURCE_VERSION) + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/shadowsocks/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 100755 index 0000000000..e678d8d6a9 --- /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 +} + diff --git a/package/lean/shadowsocksr-libev/Makefile b/package/lean/shadowsocksr-libev/Makefile new file mode 100644 index 0000000000..759b0f0d75 --- /dev/null +++ b/package/lean/shadowsocksr-libev/Makefile @@ -0,0 +1,67 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=shadowsocksr-libev +PKG_VERSION:=2.5.6 +PKG_RELEASE:=5 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz +PKG_SOURCE_URL:=https://github.com/shadowsocksrr/shadowsocksr-libev +PKG_SOURCE_VERSION:=d63ff863800a5645aca4309d5dd5962bd1e95543 +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION) + +PKG_LICENSE:=GPLv3 +PKG_LICENSE_FILES:=LICENSE + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)/$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION) + +PKG_INSTALL:=1 +PKG_FIXUP:=autoreconf +PKG_USE_MIPS16:=0 +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/shadowsocksr-libev + SECTION:=net + CATEGORY:=Network + TITLE:=Lightweight Secured Socks5 Proxy + URL:=https://github.com/shadowsocksrr/shadowsocksr-libev + DEPENDS:=+libopenssl +libpthread +libpcre +zlib +endef + +Package/shadowsocksr-libev-server = $(Package/shadowsocksr-libev) +Package/shadowsocksr-libev-alt = $(Package/shadowsocksr-libev) +Package/shadowsocksr-libev-ssr-local = $(Package/shadowsocksr-libev) + +CONFIGURE_ARGS += --disable-documentation --disable-ssp --disable-assert + +define Package/shadowsocksr-libev/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/ss-redir $(1)/usr/bin/ssr-redir + $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/ss-local $(1)/usr/bin/ssr-local + $(LN) ssr-local $(1)/usr/bin/ssr-tunnel + $(INSTALL_BIN) $(PKG_BUILD_DIR)/server/ss-check $(1)/usr/bin/ssr-check +endef + +define Package/shadowsocksr-libev-alt/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/ss-redir $(1)/usr/bin/ssr-redir + $(INSTALL_BIN) $(PKG_BUILD_DIR)/server/ss-check $(1)/usr/bin/ssr-check +endef + +define Package/shadowsocksr-libev-server/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/server/ss-server $(1)/usr/bin/ssr-server +endef + +define Package/shadowsocksr-libev-ssr-local/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/ss-local $(1)/usr/bin/ssr-local + $(LN) ssr-local $(1)/usr/bin/ssr-tunnel +endef + +$(eval $(call BuildPackage,shadowsocksr-libev)) +$(eval $(call BuildPackage,shadowsocksr-libev-alt)) +$(eval $(call BuildPackage,shadowsocksr-libev-server)) +$(eval $(call BuildPackage,shadowsocksr-libev-ssr-local)) diff --git a/package/lean/shadowsocksr-libev/patches/0001-Add-ss-server-and-ss-check.patch b/package/lean/shadowsocksr-libev/patches/0001-Add-ss-server-and-ss-check.patch new file mode 100644 index 0000000000..50a4e6a940 --- /dev/null +++ b/package/lean/shadowsocksr-libev/patches/0001-Add-ss-server-and-ss-check.patch @@ -0,0 +1,17186 @@ +diff --git a/.gitignore b/.gitignore +index 4eab18e..64b8d9f 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -2,6 +2,7 @@ build/ + .deps/ + /Makefile + src/Makefile ++server/Makefile + libev/Makefile + libudns/Makefile + libcork/Makefile +diff --git a/Makefile.am b/Makefile.am +index 690af43..75e158e 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -1,7 +1,7 @@ + if USE_SYSTEM_SHARED_LIB +-SUBDIRS = libcork libipset src ++SUBDIRS = libcork libipset src server + else +-SUBDIRS = libsodium libcork libipset libudns libev src ++SUBDIRS = libsodium libcork libipset libudns libev src server + endif + + if ENABLE_DOCUMENTATION +diff --git a/Makefile.in b/Makefile.in +index 4cb3deb..e210bc0 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -195,7 +195,7 @@ am__define_uniq_tagged_files = \ + ETAGS = etags + CTAGS = ctags + CSCOPE = cscope +-DIST_SUBDIRS = libsodium libcork libipset libudns libev src doc ++DIST_SUBDIRS = libsodium libcork libipset libudns libev src server doc + am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(srcdir)/shadowsocks-libev.pc.in $(top_srcdir)/auto/ar-lib \ + $(top_srcdir)/auto/compile $(top_srcdir)/auto/config.guess \ +@@ -377,8 +377,9 @@ top_build_prefix = @top_build_prefix@ + top_builddir = @top_builddir@ + top_srcdir = @top_srcdir@ + @USE_SYSTEM_SHARED_LIB_FALSE@SUBDIRS = libsodium libcork libipset \ +-@USE_SYSTEM_SHARED_LIB_FALSE@ libudns libev src $(am__append_1) +-@USE_SYSTEM_SHARED_LIB_TRUE@SUBDIRS = libcork libipset src \ ++@USE_SYSTEM_SHARED_LIB_FALSE@ libudns libev src server \ ++@USE_SYSTEM_SHARED_LIB_FALSE@ $(am__append_1) ++@USE_SYSTEM_SHARED_LIB_TRUE@SUBDIRS = libcork libipset src server \ + @USE_SYSTEM_SHARED_LIB_TRUE@ $(am__append_1) + ACLOCAL_AMFLAGS = -I m4 + pkgconfiglibdir = $(libdir)/pkgconfig +diff --git a/configure b/configure +index 7d854c4..01d66ab 100755 +--- a/configure ++++ b/configure +@@ -649,7 +649,6 @@ PTHREAD_CC + ax_pthread_config + INET_NTOP_LIB + MV +-RM + GZIP + XMLTO + ASCIIDOC +@@ -757,6 +756,7 @@ infodir + docdir + oldincludedir + includedir ++runstatedir + localstatedir + sharedstatedir + sysconfdir +@@ -857,6 +857,7 @@ datadir='${datarootdir}' + sysconfdir='${prefix}/etc' + sharedstatedir='${prefix}/com' + localstatedir='${prefix}/var' ++runstatedir='${localstatedir}/run' + includedir='${prefix}/include' + oldincludedir='/usr/include' + docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +@@ -1109,6 +1110,15 @@ do + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + ++ -runstatedir | --runstatedir | --runstatedi | --runstated \ ++ | --runstate | --runstat | --runsta | --runst | --runs \ ++ | --run | --ru | --r) ++ ac_prev=runstatedir ;; ++ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ ++ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ ++ | --run=* | --ru=* | --r=*) ++ runstatedir=$ac_optarg ;; ++ + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ +@@ -1246,7 +1256,7 @@ fi + for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ +- libdir localedir mandir ++ libdir localedir mandir runstatedir + do + eval ac_val=\$$ac_var + # Remove trailing slashes. +@@ -1399,6 +1409,7 @@ Fine tuning of the installation directories: + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] ++ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] +@@ -2472,8 +2483,8 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + + +-# expand $ac_aux_dir to an absolute path +-am_aux_dir=`cd $ac_aux_dir && pwd` ++# Expand $ac_aux_dir to an absolute path. ++am_aux_dir=`cd "$ac_aux_dir" && pwd` + + ac_ext=c + ac_cpp='$CPP $CPPFLAGS' +@@ -3783,7 +3794,7 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + + + +-am__api_version='1.14' ++am__api_version='1.15' + + # Find a good install program. We prefer a C program (faster), + # so one script is as good as another. But avoid the broken or +@@ -3972,7 +3983,7 @@ else + $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} + fi + +-if test x"${install_sh}" != xset; then ++if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; +@@ -4363,8 +4374,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + # + mkdir_p='$(MKDIR_P)' + +-# We need awk for the "check" target. The system "awk" is bad on +-# some platforms. ++# We need awk for the "check" target (and possibly the TAP driver). The ++# system "awk" is bad on some platforms. + # Always define AMTAR for backward compatibility. Yes, it's still used + # in the wild :-( We should find a proper way to deprecate it ... + AMTAR='$${TAR-tar}' +@@ -4549,6 +4560,7 @@ END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi + fi ++ + if test -n "$ac_tool_prefix"; then + for ac_prog in ar lib "link -lib" + do +@@ -12494,47 +12506,6 @@ $as_echo "no" >&6; } + fi + + +- # Extract the first word of "rm", so it can be a program name with args. +-set dummy rm; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_path_RM+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- case $RM in +- [\\/]* | ?:[\\/]*) +- ac_cv_path_RM="$RM" # Let the user override the test with a path. +- ;; +- *) +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_path_RM="$as_dir/$ac_word$ac_exec_ext" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +- test -z "$ac_cv_path_RM" && ac_cv_path_RM="rm" +- ;; +-esac +-fi +-RM=$ac_cv_path_RM +-if test -n "$RM"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RM" >&5 +-$as_echo "$RM" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- + # Extract the first word of "mv", so it can be a program name with args. + set dummy mv; ac_word=$2 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +@@ -16204,15 +16175,162 @@ $as_echo "#define HAVE_IPv6 1" >>confdefs.h + + + if test -z "$USE_SYSTEM_SHARED_LIB_TRUE"; then : +- else ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sodium_init in -lsodium" >&5 ++$as_echo_n "checking for sodium_init in -lsodium... " >&6; } ++if ${ac_cv_lib_sodium_sodium_init+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-lsodium $LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char sodium_init (); ++int ++main () ++{ ++return sodium_init (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_sodium_sodium_init=yes ++else ++ ac_cv_lib_sodium_sodium_init=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sodium_sodium_init" >&5 ++$as_echo "$ac_cv_lib_sodium_sodium_init" >&6; } ++if test "x$ac_cv_lib_sodium_sodium_init" = xyes; then : ++ cat >>confdefs.h <<_ACEOF ++#define HAVE_LIBSODIUM 1 ++_ACEOF ++ ++ LIBS="-lsodium $LIBS" ++ ++else ++ ++ as_fn_error $? "Couldn't find libsodium. Try installing libsodium-dev[el]." "$LINENO" 5 ++ ++fi ++ ++ ++else + subdirs="$subdirs libsodium" + + fi + +-ac_config_files="$ac_config_files shadowsocks-libev.pc Makefile libcork/Makefile libipset/Makefile src/Makefile" ++ac_config_files="$ac_config_files shadowsocks-libev.pc Makefile libcork/Makefile libipset/Makefile src/Makefile server/Makefile" + + if test -z "$USE_SYSTEM_SHARED_LIB_TRUE"; then : +- else ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dns_dnlen in -ludns" >&5 ++$as_echo_n "checking for dns_dnlen in -ludns... " >&6; } ++if ${ac_cv_lib_udns_dns_dnlen+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-ludns $LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char dns_dnlen (); ++int ++main () ++{ ++return dns_dnlen (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_udns_dns_dnlen=yes ++else ++ ac_cv_lib_udns_dns_dnlen=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_udns_dns_dnlen" >&5 ++$as_echo "$ac_cv_lib_udns_dns_dnlen" >&6; } ++if test "x$ac_cv_lib_udns_dns_dnlen" = xyes; then : ++ cat >>confdefs.h <<_ACEOF ++#define HAVE_LIBUDNS 1 ++_ACEOF ++ ++ LIBS="-ludns $LIBS" ++ ++else ++ as_fn_error $? "Couldn't find libudns. Try installing libudns-dev or udns-devel." "$LINENO" 5 ++fi ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ev_loop_destroy in -lev" >&5 ++$as_echo_n "checking for ev_loop_destroy in -lev... " >&6; } ++if ${ac_cv_lib_ev_ev_loop_destroy+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-lev $LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char ev_loop_destroy (); ++int ++main () ++{ ++return ev_loop_destroy (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_ev_ev_loop_destroy=yes ++else ++ ac_cv_lib_ev_ev_loop_destroy=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ev_ev_loop_destroy" >&5 ++$as_echo "$ac_cv_lib_ev_ev_loop_destroy" >&6; } ++if test "x$ac_cv_lib_ev_ev_loop_destroy" = xyes; then : ++ cat >>confdefs.h <<_ACEOF ++#define HAVE_LIBEV 1 ++_ACEOF ++ ++ LIBS="-lev $LIBS" ++ ++else ++ as_fn_error $? "Couldn't find libev. Try installing libev-dev[el]." "$LINENO" 5 ++fi ++ ++ ++else + ac_config_files="$ac_config_files libudns/Makefile libev/Makefile" + + fi +@@ -17258,6 +17376,7 @@ do + "libcork/Makefile") CONFIG_FILES="$CONFIG_FILES libcork/Makefile" ;; + "libipset/Makefile") CONFIG_FILES="$CONFIG_FILES libipset/Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; ++ "server/Makefile") CONFIG_FILES="$CONFIG_FILES server/Makefile" ;; + "libudns/Makefile") CONFIG_FILES="$CONFIG_FILES libudns/Makefile" ;; + "libev/Makefile") CONFIG_FILES="$CONFIG_FILES libev/Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; +@@ -17958,8 +18077,8 @@ $as_echo X"$file" | + fi + + cfgfile="${ofile}T" +- trap "$RM -f \"$cfgfile\"; exit 1" 1 2 15 +- $RM -f "$cfgfile" ++ trap "$RM \"$cfgfile\"; exit 1" 1 2 15 ++ $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" + #! $SHELL +diff --git a/configure.ac b/configure.ac +index 6586f2b..f9c51ab 100755 +--- a/configure.ac ++++ b/configure.ac +@@ -315,7 +315,8 @@ AC_CONFIG_FILES([ shadowsocks-libev.pc + Makefile + libcork/Makefile + libipset/Makefile +- src/Makefile]) ++ src/Makefile ++ server/Makefile]) + AM_COND_IF([USE_SYSTEM_SHARED_LIB],[ + AC_CHECK_LIB([udns], [dns_dnlen], ,[AC_MSG_ERROR([Couldn't find libudns. Try installing libudns-dev or udns-devel.])]) + AC_CHECK_LIB([ev], [ev_loop_destroy], ,[AC_MSG_ERROR([Couldn't find libev. Try installing libev-dev@<:@el@:>@.])]) +diff --git a/server/Makefile.am b/server/Makefile.am +new file mode 100644 +index 0000000..3ae8bc2 +--- /dev/null ++++ b/server/Makefile.am +@@ -0,0 +1,55 @@ ++VERSION_INFO = 2:0:0 ++ ++AM_CFLAGS = -g -O2 -Wall -Werror -Wno-deprecated-declarations -fno-strict-aliasing -std=gnu99 -D_GNU_SOURCE ++AM_CFLAGS += $(PTHREAD_CFLAGS) ++if !USE_SYSTEM_SHARED_LIB ++AM_CFLAGS += -I$(top_srcdir)/libev ++AM_CFLAGS += -I$(top_srcdir)/libudns ++AM_CFLAGS += -I$(top_srcdir)/libsodium/src/libsodium/include ++endif ++AM_CFLAGS += -I$(top_srcdir)/libipset/include ++AM_CFLAGS += -I$(top_srcdir)/libcork/include ++AM_CFLAGS += $(LIBPCRE_CFLAGS) ++ ++SS_COMMON_LIBS = $(top_builddir)/libipset/libipset.la \ ++ $(top_builddir)/libcork/libcork.la \ ++ $(INET_NTOP_LIB) $(LIBPCRE_LIBS) ++if USE_SYSTEM_SHARED_LIB ++SS_COMMON_LIBS += -lev -lsodium -lm ++else ++SS_COMMON_LIBS += $(top_builddir)/libev/libev.la \ ++ $(top_builddir)/libsodium/src/libsodium/libsodium.la ++endif ++ ++bin_PROGRAMS = ss-server ss-check ++ ++sni_src = http.c \ ++ tls.c \ ++ rule.c ++ ++ss_check_SOURCES = check.c ++ ++ss_server_SOURCES = utils.c \ ++ netutils.c \ ++ jconf.c \ ++ json.c \ ++ encrypt.c \ ++ udprelay.c \ ++ cache.c \ ++ acl.c \ ++ resolv.c \ ++ server.c \ ++ $(sni_src) ++ ++ ++ss_check_LDADD = $(SS_COMMON_LIBS) ++ss_server_LDADD = $(SS_COMMON_LIBS) ++ ++if USE_SYSTEM_SHARED_LIB ++ss_server_LDADD += -ludns ++else ++ss_server_LDADD += $(top_builddir)/libudns/libudns.la ++endif ++ ++ss_check_CFLAGS = $(AM_CFLAGS) ++ss_server_CFLAGS = $(AM_CFLAGS) -DMODULE_REMOTE +diff --git a/server/Makefile.in b/server/Makefile.in +new file mode 100644 +index 0000000..3bfa53e +--- /dev/null ++++ b/server/Makefile.in +@@ -0,0 +1,919 @@ ++# Makefile.in generated by automake 1.15 from Makefile.am. ++# @configure_input@ ++ ++# Copyright (C) 1994-2014 Free Software Foundation, Inc. ++ ++# This Makefile.in is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++@SET_MAKE@ ++ ++VPATH = @srcdir@ ++am__is_gnu_make = { \ ++ if test -z '$(MAKELEVEL)'; then \ ++ false; \ ++ elif test -n '$(MAKE_HOST)'; then \ ++ true; \ ++ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ ++ true; \ ++ else \ ++ false; \ ++ fi; \ ++} ++am__make_running_with_option = \ ++ case $${target_option-} in \ ++ ?) ;; \ ++ *) echo "am__make_running_with_option: internal error: invalid" \ ++ "target option '$${target_option-}' specified" >&2; \ ++ exit 1;; \ ++ esac; \ ++ has_opt=no; \ ++ sane_makeflags=$$MAKEFLAGS; \ ++ if $(am__is_gnu_make); then \ ++ sane_makeflags=$$MFLAGS; \ ++ else \ ++ case $$MAKEFLAGS in \ ++ *\\[\ \ ]*) \ ++ bs=\\; \ ++ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ ++ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ ++ esac; \ ++ fi; \ ++ skip_next=no; \ ++ strip_trailopt () \ ++ { \ ++ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ ++ }; \ ++ for flg in $$sane_makeflags; do \ ++ test $$skip_next = yes && { skip_next=no; continue; }; \ ++ case $$flg in \ ++ *=*|--*) continue;; \ ++ -*I) strip_trailopt 'I'; skip_next=yes;; \ ++ -*I?*) strip_trailopt 'I';; \ ++ -*O) strip_trailopt 'O'; skip_next=yes;; \ ++ -*O?*) strip_trailopt 'O';; \ ++ -*l) strip_trailopt 'l'; skip_next=yes;; \ ++ -*l?*) strip_trailopt 'l';; \ ++ -[dEDm]) skip_next=yes;; \ ++ -[JT]) skip_next=yes;; \ ++ esac; \ ++ case $$flg in \ ++ *$$target_option*) has_opt=yes; break;; \ ++ esac; \ ++ done; \ ++ test $$has_opt = yes ++am__make_dryrun = (target_option=n; $(am__make_running_with_option)) ++am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) ++pkgdatadir = $(datadir)/@PACKAGE@ ++pkgincludedir = $(includedir)/@PACKAGE@ ++pkglibdir = $(libdir)/@PACKAGE@ ++pkglibexecdir = $(libexecdir)/@PACKAGE@ ++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd ++install_sh_DATA = $(install_sh) -c -m 644 ++install_sh_PROGRAM = $(install_sh) -c ++install_sh_SCRIPT = $(install_sh) -c ++INSTALL_HEADER = $(INSTALL_DATA) ++transform = $(program_transform_name) ++NORMAL_INSTALL = : ++PRE_INSTALL = : ++POST_INSTALL = : ++NORMAL_UNINSTALL = : ++PRE_UNINSTALL = : ++POST_UNINSTALL = : ++build_triplet = @build@ ++host_triplet = @host@ ++@USE_SYSTEM_SHARED_LIB_FALSE@am__append_1 = -I$(top_srcdir)/libev \ ++@USE_SYSTEM_SHARED_LIB_FALSE@ -I$(top_srcdir)/libudns \ ++@USE_SYSTEM_SHARED_LIB_FALSE@ -I$(top_srcdir)/libsodium/src/libsodium/include ++@USE_SYSTEM_SHARED_LIB_TRUE@am__append_2 = -lev -lsodium -lm ++@USE_SYSTEM_SHARED_LIB_FALSE@am__append_3 = $(top_builddir)/libev/libev.la \ ++@USE_SYSTEM_SHARED_LIB_FALSE@ $(top_builddir)/libsodium/src/libsodium/libsodium.la ++ ++bin_PROGRAMS = ss-server$(EXEEXT) ss-check$(EXEEXT) ++@USE_SYSTEM_SHARED_LIB_TRUE@am__append_4 = -ludns ++@USE_SYSTEM_SHARED_LIB_FALSE@am__append_5 = $(top_builddir)/libudns/libudns.la ++subdir = server ++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ++am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ ++ $(top_srcdir)/m4/ax_tls.m4 $(top_srcdir)/m4/inet_ntop.m4 \ ++ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ ++ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ ++ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/mbedtls.m4 \ ++ $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/pcre.m4 \ ++ $(top_srcdir)/m4/polarssl.m4 \ ++ $(top_srcdir)/m4/stack-protector.m4 $(top_srcdir)/m4/zlib.m4 \ ++ $(top_srcdir)/libev/libev.m4 $(top_srcdir)/configure.ac ++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ ++ $(ACLOCAL_M4) ++DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) ++mkinstalldirs = $(install_sh) -d ++CONFIG_HEADER = $(top_builddir)/config.h ++CONFIG_CLEAN_FILES = ++CONFIG_CLEAN_VPATH_FILES = ++am__installdirs = "$(DESTDIR)$(bindir)" ++PROGRAMS = $(bin_PROGRAMS) ++am_ss_check_OBJECTS = ss_check-check.$(OBJEXT) ++ss_check_OBJECTS = $(am_ss_check_OBJECTS) ++am__DEPENDENCIES_1 = ++am__DEPENDENCIES_2 = $(top_builddir)/libipset/libipset.la \ ++ $(top_builddir)/libcork/libcork.la $(am__DEPENDENCIES_1) \ ++ $(am__DEPENDENCIES_1) $(am__append_3) ++ss_check_DEPENDENCIES = $(am__DEPENDENCIES_2) ++AM_V_lt = $(am__v_lt_@AM_V@) ++am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) ++am__v_lt_0 = --silent ++am__v_lt_1 = ++ss_check_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ ++ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ss_check_CFLAGS) \ ++ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ ++am__objects_1 = ss_server-http.$(OBJEXT) ss_server-tls.$(OBJEXT) \ ++ ss_server-rule.$(OBJEXT) ++am_ss_server_OBJECTS = ss_server-utils.$(OBJEXT) \ ++ ss_server-netutils.$(OBJEXT) ss_server-jconf.$(OBJEXT) \ ++ ss_server-json.$(OBJEXT) ss_server-encrypt.$(OBJEXT) \ ++ ss_server-udprelay.$(OBJEXT) ss_server-cache.$(OBJEXT) \ ++ ss_server-acl.$(OBJEXT) ss_server-resolv.$(OBJEXT) \ ++ ss_server-server.$(OBJEXT) $(am__objects_1) ++ss_server_OBJECTS = $(am_ss_server_OBJECTS) ++ss_server_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \ ++ $(am__append_5) ++ss_server_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ ++ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ss_server_CFLAGS) \ ++ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ ++AM_V_P = $(am__v_P_@AM_V@) ++am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) ++am__v_P_0 = false ++am__v_P_1 = : ++AM_V_GEN = $(am__v_GEN_@AM_V@) ++am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) ++am__v_GEN_0 = @echo " GEN " $@; ++am__v_GEN_1 = ++AM_V_at = $(am__v_at_@AM_V@) ++am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) ++am__v_at_0 = @ ++am__v_at_1 = ++DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) ++depcomp = $(SHELL) $(top_srcdir)/auto/depcomp ++am__depfiles_maybe = depfiles ++am__mv = mv -f ++COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ ++ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) ++LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ ++ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ ++ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ ++ $(AM_CFLAGS) $(CFLAGS) ++AM_V_CC = $(am__v_CC_@AM_V@) ++am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) ++am__v_CC_0 = @echo " CC " $@; ++am__v_CC_1 = ++CCLD = $(CC) ++LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ ++ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ ++ $(AM_LDFLAGS) $(LDFLAGS) -o $@ ++AM_V_CCLD = $(am__v_CCLD_@AM_V@) ++am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) ++am__v_CCLD_0 = @echo " CCLD " $@; ++am__v_CCLD_1 = ++SOURCES = $(ss_check_SOURCES) $(ss_server_SOURCES) ++DIST_SOURCES = $(ss_check_SOURCES) $(ss_server_SOURCES) ++am__can_run_installinfo = \ ++ case $$AM_UPDATE_INFO_DIR in \ ++ n|no|NO) false;; \ ++ *) (install-info --version) >/dev/null 2>&1;; \ ++ esac ++am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) ++# Read a list of newline-separated strings from the standard input, ++# and print each of them once, without duplicates. Input order is ++# *not* preserved. ++am__uniquify_input = $(AWK) '\ ++ BEGIN { nonempty = 0; } \ ++ { items[$$0] = 1; nonempty = 1; } \ ++ END { if (nonempty) { for (i in items) print i; }; } \ ++' ++# Make sure the list of sources is unique. This is necessary because, ++# e.g., the same source file might be shared among _SOURCES variables ++# for different programs/libraries. ++am__define_uniq_tagged_files = \ ++ list='$(am__tagged_files)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | $(am__uniquify_input)` ++ETAGS = etags ++CTAGS = ctags ++am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/auto/depcomp ++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ++ACLOCAL = @ACLOCAL@ ++AMTAR = @AMTAR@ ++AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ ++AR = @AR@ ++ASCIIDOC = @ASCIIDOC@ ++AUTOCONF = @AUTOCONF@ ++AUTOHEADER = @AUTOHEADER@ ++AUTOMAKE = @AUTOMAKE@ ++AWK = @AWK@ ++CC = @CC@ ++CCDEPMODE = @CCDEPMODE@ ++CFLAGS = @CFLAGS@ ++CPP = @CPP@ ++CPPFLAGS = @CPPFLAGS@ ++CYGPATH_W = @CYGPATH_W@ ++DEFS = @DEFS@ ++DEPDIR = @DEPDIR@ ++DLLTOOL = @DLLTOOL@ ++DSYMUTIL = @DSYMUTIL@ ++DUMPBIN = @DUMPBIN@ ++ECHO_C = @ECHO_C@ ++ECHO_N = @ECHO_N@ ++ECHO_T = @ECHO_T@ ++EGREP = @EGREP@ ++EXEEXT = @EXEEXT@ ++FGREP = @FGREP@ ++GREP = @GREP@ ++GZIP = @GZIP@ ++INET_NTOP_LIB = @INET_NTOP_LIB@ ++INSTALL = @INSTALL@ ++INSTALL_DATA = @INSTALL_DATA@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++LD = @LD@ ++LDFLAGS = @LDFLAGS@ ++LIBOBJS = @LIBOBJS@ ++LIBPCRE = @LIBPCRE@ ++LIBS = @LIBS@ ++LIBTOOL = @LIBTOOL@ ++LIPO = @LIPO@ ++LN_S = @LN_S@ ++LTLIBOBJS = @LTLIBOBJS@ ++MAINT = @MAINT@ ++MAKEINFO = @MAKEINFO@ ++MANIFEST_TOOL = @MANIFEST_TOOL@ ++MKDIR_P = @MKDIR_P@ ++MV = @MV@ ++NM = @NM@ ++NMEDIT = @NMEDIT@ ++OBJDUMP = @OBJDUMP@ ++OBJEXT = @OBJEXT@ ++OTOOL = @OTOOL@ ++OTOOL64 = @OTOOL64@ ++PACKAGE = @PACKAGE@ ++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ ++PACKAGE_NAME = @PACKAGE_NAME@ ++PACKAGE_STRING = @PACKAGE_STRING@ ++PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_URL = @PACKAGE_URL@ ++PACKAGE_VERSION = @PACKAGE_VERSION@ ++PATH_SEPARATOR = @PATH_SEPARATOR@ ++PCRE_CONFIG = @PCRE_CONFIG@ ++PTHREAD_CC = @PTHREAD_CC@ ++PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ ++PTHREAD_LIBS = @PTHREAD_LIBS@ ++RANLIB = @RANLIB@ ++SED = @SED@ ++SET_MAKE = @SET_MAKE@ ++SHELL = @SHELL@ ++STRIP = @STRIP@ ++VERSION = @VERSION@ ++XMLTO = @XMLTO@ ++abs_builddir = @abs_builddir@ ++abs_srcdir = @abs_srcdir@ ++abs_top_builddir = @abs_top_builddir@ ++abs_top_srcdir = @abs_top_srcdir@ ++ac_ct_AR = @ac_ct_AR@ ++ac_ct_CC = @ac_ct_CC@ ++ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ++am__include = @am__include@ ++am__leading_dot = @am__leading_dot@ ++am__quote = @am__quote@ ++am__tar = @am__tar@ ++am__untar = @am__untar@ ++ax_pthread_config = @ax_pthread_config@ ++bindir = @bindir@ ++build = @build@ ++build_alias = @build_alias@ ++build_cpu = @build_cpu@ ++build_os = @build_os@ ++build_vendor = @build_vendor@ ++builddir = @builddir@ ++datadir = @datadir@ ++datarootdir = @datarootdir@ ++docdir = @docdir@ ++dvidir = @dvidir@ ++exec_prefix = @exec_prefix@ ++host = @host@ ++host_alias = @host_alias@ ++host_cpu = @host_cpu@ ++host_os = @host_os@ ++host_vendor = @host_vendor@ ++htmldir = @htmldir@ ++includedir = @includedir@ ++infodir = @infodir@ ++install_sh = @install_sh@ ++libdir = @libdir@ ++libexecdir = @libexecdir@ ++localedir = @localedir@ ++localstatedir = @localstatedir@ ++mandir = @mandir@ ++mkdir_p = @mkdir_p@ ++oldincludedir = @oldincludedir@ ++pcre_pcreh = @pcre_pcreh@ ++pcreh = @pcreh@ ++pdfdir = @pdfdir@ ++prefix = @prefix@ ++program_transform_name = @program_transform_name@ ++psdir = @psdir@ ++runstatedir = @runstatedir@ ++sbindir = @sbindir@ ++sharedstatedir = @sharedstatedir@ ++srcdir = @srcdir@ ++subdirs = @subdirs@ ++sysconfdir = @sysconfdir@ ++target_alias = @target_alias@ ++top_build_prefix = @top_build_prefix@ ++top_builddir = @top_builddir@ ++top_srcdir = @top_srcdir@ ++VERSION_INFO = 2:0:0 ++AM_CFLAGS = -g -O2 -Wall -Werror -Wno-deprecated-declarations \ ++ -fno-strict-aliasing -std=gnu99 -D_GNU_SOURCE \ ++ $(PTHREAD_CFLAGS) $(am__append_1) \ ++ -I$(top_srcdir)/libipset/include \ ++ -I$(top_srcdir)/libcork/include $(LIBPCRE_CFLAGS) ++SS_COMMON_LIBS = $(top_builddir)/libipset/libipset.la \ ++ $(top_builddir)/libcork/libcork.la $(INET_NTOP_LIB) \ ++ $(LIBPCRE_LIBS) $(am__append_2) $(am__append_3) ++sni_src = http.c \ ++ tls.c \ ++ rule.c ++ ++ss_check_SOURCES = check.c ++ss_server_SOURCES = utils.c \ ++ netutils.c \ ++ jconf.c \ ++ json.c \ ++ encrypt.c \ ++ udprelay.c \ ++ cache.c \ ++ acl.c \ ++ resolv.c \ ++ server.c \ ++ $(sni_src) ++ ++ss_check_LDADD = $(SS_COMMON_LIBS) ++ss_server_LDADD = $(SS_COMMON_LIBS) $(am__append_4) $(am__append_5) ++ss_check_CFLAGS = $(AM_CFLAGS) ++ss_server_CFLAGS = $(AM_CFLAGS) -DMODULE_REMOTE ++all: all-am ++ ++.SUFFIXES: ++.SUFFIXES: .c .lo .o .obj ++$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) ++ @for dep in $?; do \ ++ case '$(am__configure_deps)' in \ ++ *$$dep*) \ ++ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ ++ && { if test -f $@; then exit 0; else break; fi; }; \ ++ exit 1;; \ ++ esac; \ ++ done; \ ++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign server/Makefile'; \ ++ $(am__cd) $(top_srcdir) && \ ++ $(AUTOMAKE) --foreign server/Makefile ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++ @case '$?' in \ ++ *config.status*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ ++ *) \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ ++ esac; ++ ++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(am__aclocal_m4_deps): ++install-binPROGRAMS: $(bin_PROGRAMS) ++ @$(NORMAL_INSTALL) ++ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ ++ if test -n "$$list"; then \ ++ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ ++ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ ++ fi; \ ++ for p in $$list; do echo "$$p $$p"; done | \ ++ sed 's/$(EXEEXT)$$//' | \ ++ while read p p1; do if test -f $$p \ ++ || test -f $$p1 \ ++ ; then echo "$$p"; echo "$$p"; else :; fi; \ ++ done | \ ++ sed -e 'p;s,.*/,,;n;h' \ ++ -e 's|.*|.|' \ ++ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ ++ sed 'N;N;N;s,\n, ,g' | \ ++ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ ++ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ ++ if ($$2 == $$4) files[d] = files[d] " " $$1; \ ++ else { print "f", $$3 "/" $$4, $$1; } } \ ++ END { for (d in files) print "f", d, files[d] }' | \ ++ while read type dir files; do \ ++ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ ++ test -z "$$files" || { \ ++ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ ++ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ ++ } \ ++ ; done ++ ++uninstall-binPROGRAMS: ++ @$(NORMAL_UNINSTALL) ++ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ ++ files=`for p in $$list; do echo "$$p"; done | \ ++ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ ++ -e 's/$$/$(EXEEXT)/' \ ++ `; \ ++ test -n "$$list" || exit 0; \ ++ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ ++ cd "$(DESTDIR)$(bindir)" && rm -f $$files ++ ++clean-binPROGRAMS: ++ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ ++ echo " rm -f" $$list; \ ++ rm -f $$list || exit $$?; \ ++ test -n "$(EXEEXT)" || exit 0; \ ++ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ ++ echo " rm -f" $$list; \ ++ rm -f $$list ++ ++ss-check$(EXEEXT): $(ss_check_OBJECTS) $(ss_check_DEPENDENCIES) $(EXTRA_ss_check_DEPENDENCIES) ++ @rm -f ss-check$(EXEEXT) ++ $(AM_V_CCLD)$(ss_check_LINK) $(ss_check_OBJECTS) $(ss_check_LDADD) $(LIBS) ++ ++ss-server$(EXEEXT): $(ss_server_OBJECTS) $(ss_server_DEPENDENCIES) $(EXTRA_ss_server_DEPENDENCIES) ++ @rm -f ss-server$(EXEEXT) ++ $(AM_V_CCLD)$(ss_server_LINK) $(ss_server_OBJECTS) $(ss_server_LDADD) $(LIBS) ++ ++mostlyclean-compile: ++ -rm -f *.$(OBJEXT) ++ ++distclean-compile: ++ -rm -f *.tab.c ++ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_check-check.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-acl.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-cache.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-encrypt.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-http.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-jconf.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-json.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-netutils.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-resolv.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-rule.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-server.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-tls.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-udprelay.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-utils.Po@am__quote@ ++ ++.c.o: ++@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ ++@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ ++@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< ++ ++.c.obj: ++@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ ++@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ ++@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` ++ ++.c.lo: ++@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ ++@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ ++@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< ++ ++ss_check-check.o: check.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_check_CFLAGS) $(CFLAGS) -MT ss_check-check.o -MD -MP -MF $(DEPDIR)/ss_check-check.Tpo -c -o ss_check-check.o `test -f 'check.c' || echo '$(srcdir)/'`check.c ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_check-check.Tpo $(DEPDIR)/ss_check-check.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='check.c' object='ss_check-check.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_check_CFLAGS) $(CFLAGS) -c -o ss_check-check.o `test -f 'check.c' || echo '$(srcdir)/'`check.c ++ ++ss_check-check.obj: check.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_check_CFLAGS) $(CFLAGS) -MT ss_check-check.obj -MD -MP -MF $(DEPDIR)/ss_check-check.Tpo -c -o ss_check-check.obj `if test -f 'check.c'; then $(CYGPATH_W) 'check.c'; else $(CYGPATH_W) '$(srcdir)/check.c'; fi` ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_check-check.Tpo $(DEPDIR)/ss_check-check.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='check.c' object='ss_check-check.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_check_CFLAGS) $(CFLAGS) -c -o ss_check-check.obj `if test -f 'check.c'; then $(CYGPATH_W) 'check.c'; else $(CYGPATH_W) '$(srcdir)/check.c'; fi` ++ ++ss_server-utils.o: utils.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-utils.o -MD -MP -MF $(DEPDIR)/ss_server-utils.Tpo -c -o ss_server-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-utils.Tpo $(DEPDIR)/ss_server-utils.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils.c' object='ss_server-utils.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c ++ ++ss_server-utils.obj: utils.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-utils.obj -MD -MP -MF $(DEPDIR)/ss_server-utils.Tpo -c -o ss_server-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi` ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-utils.Tpo $(DEPDIR)/ss_server-utils.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils.c' object='ss_server-utils.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi` ++ ++ss_server-netutils.o: netutils.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-netutils.o -MD -MP -MF $(DEPDIR)/ss_server-netutils.Tpo -c -o ss_server-netutils.o `test -f 'netutils.c' || echo '$(srcdir)/'`netutils.c ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-netutils.Tpo $(DEPDIR)/ss_server-netutils.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netutils.c' object='ss_server-netutils.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-netutils.o `test -f 'netutils.c' || echo '$(srcdir)/'`netutils.c ++ ++ss_server-netutils.obj: netutils.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-netutils.obj -MD -MP -MF $(DEPDIR)/ss_server-netutils.Tpo -c -o ss_server-netutils.obj `if test -f 'netutils.c'; then $(CYGPATH_W) 'netutils.c'; else $(CYGPATH_W) '$(srcdir)/netutils.c'; fi` ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-netutils.Tpo $(DEPDIR)/ss_server-netutils.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netutils.c' object='ss_server-netutils.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-netutils.obj `if test -f 'netutils.c'; then $(CYGPATH_W) 'netutils.c'; else $(CYGPATH_W) '$(srcdir)/netutils.c'; fi` ++ ++ss_server-jconf.o: jconf.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-jconf.o -MD -MP -MF $(DEPDIR)/ss_server-jconf.Tpo -c -o ss_server-jconf.o `test -f 'jconf.c' || echo '$(srcdir)/'`jconf.c ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-jconf.Tpo $(DEPDIR)/ss_server-jconf.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='jconf.c' object='ss_server-jconf.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-jconf.o `test -f 'jconf.c' || echo '$(srcdir)/'`jconf.c ++ ++ss_server-jconf.obj: jconf.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-jconf.obj -MD -MP -MF $(DEPDIR)/ss_server-jconf.Tpo -c -o ss_server-jconf.obj `if test -f 'jconf.c'; then $(CYGPATH_W) 'jconf.c'; else $(CYGPATH_W) '$(srcdir)/jconf.c'; fi` ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-jconf.Tpo $(DEPDIR)/ss_server-jconf.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='jconf.c' object='ss_server-jconf.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-jconf.obj `if test -f 'jconf.c'; then $(CYGPATH_W) 'jconf.c'; else $(CYGPATH_W) '$(srcdir)/jconf.c'; fi` ++ ++ss_server-json.o: json.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-json.o -MD -MP -MF $(DEPDIR)/ss_server-json.Tpo -c -o ss_server-json.o `test -f 'json.c' || echo '$(srcdir)/'`json.c ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-json.Tpo $(DEPDIR)/ss_server-json.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='json.c' object='ss_server-json.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-json.o `test -f 'json.c' || echo '$(srcdir)/'`json.c ++ ++ss_server-json.obj: json.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-json.obj -MD -MP -MF $(DEPDIR)/ss_server-json.Tpo -c -o ss_server-json.obj `if test -f 'json.c'; then $(CYGPATH_W) 'json.c'; else $(CYGPATH_W) '$(srcdir)/json.c'; fi` ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-json.Tpo $(DEPDIR)/ss_server-json.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='json.c' object='ss_server-json.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-json.obj `if test -f 'json.c'; then $(CYGPATH_W) 'json.c'; else $(CYGPATH_W) '$(srcdir)/json.c'; fi` ++ ++ss_server-encrypt.o: encrypt.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-encrypt.o -MD -MP -MF $(DEPDIR)/ss_server-encrypt.Tpo -c -o ss_server-encrypt.o `test -f 'encrypt.c' || echo '$(srcdir)/'`encrypt.c ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-encrypt.Tpo $(DEPDIR)/ss_server-encrypt.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='encrypt.c' object='ss_server-encrypt.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-encrypt.o `test -f 'encrypt.c' || echo '$(srcdir)/'`encrypt.c ++ ++ss_server-encrypt.obj: encrypt.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-encrypt.obj -MD -MP -MF $(DEPDIR)/ss_server-encrypt.Tpo -c -o ss_server-encrypt.obj `if test -f 'encrypt.c'; then $(CYGPATH_W) 'encrypt.c'; else $(CYGPATH_W) '$(srcdir)/encrypt.c'; fi` ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-encrypt.Tpo $(DEPDIR)/ss_server-encrypt.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='encrypt.c' object='ss_server-encrypt.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-encrypt.obj `if test -f 'encrypt.c'; then $(CYGPATH_W) 'encrypt.c'; else $(CYGPATH_W) '$(srcdir)/encrypt.c'; fi` ++ ++ss_server-udprelay.o: udprelay.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-udprelay.o -MD -MP -MF $(DEPDIR)/ss_server-udprelay.Tpo -c -o ss_server-udprelay.o `test -f 'udprelay.c' || echo '$(srcdir)/'`udprelay.c ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-udprelay.Tpo $(DEPDIR)/ss_server-udprelay.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='udprelay.c' object='ss_server-udprelay.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-udprelay.o `test -f 'udprelay.c' || echo '$(srcdir)/'`udprelay.c ++ ++ss_server-udprelay.obj: udprelay.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-udprelay.obj -MD -MP -MF $(DEPDIR)/ss_server-udprelay.Tpo -c -o ss_server-udprelay.obj `if test -f 'udprelay.c'; then $(CYGPATH_W) 'udprelay.c'; else $(CYGPATH_W) '$(srcdir)/udprelay.c'; fi` ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-udprelay.Tpo $(DEPDIR)/ss_server-udprelay.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='udprelay.c' object='ss_server-udprelay.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-udprelay.obj `if test -f 'udprelay.c'; then $(CYGPATH_W) 'udprelay.c'; else $(CYGPATH_W) '$(srcdir)/udprelay.c'; fi` ++ ++ss_server-cache.o: cache.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-cache.o -MD -MP -MF $(DEPDIR)/ss_server-cache.Tpo -c -o ss_server-cache.o `test -f 'cache.c' || echo '$(srcdir)/'`cache.c ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-cache.Tpo $(DEPDIR)/ss_server-cache.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cache.c' object='ss_server-cache.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-cache.o `test -f 'cache.c' || echo '$(srcdir)/'`cache.c ++ ++ss_server-cache.obj: cache.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-cache.obj -MD -MP -MF $(DEPDIR)/ss_server-cache.Tpo -c -o ss_server-cache.obj `if test -f 'cache.c'; then $(CYGPATH_W) 'cache.c'; else $(CYGPATH_W) '$(srcdir)/cache.c'; fi` ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-cache.Tpo $(DEPDIR)/ss_server-cache.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cache.c' object='ss_server-cache.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-cache.obj `if test -f 'cache.c'; then $(CYGPATH_W) 'cache.c'; else $(CYGPATH_W) '$(srcdir)/cache.c'; fi` ++ ++ss_server-acl.o: acl.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-acl.o -MD -MP -MF $(DEPDIR)/ss_server-acl.Tpo -c -o ss_server-acl.o `test -f 'acl.c' || echo '$(srcdir)/'`acl.c ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-acl.Tpo $(DEPDIR)/ss_server-acl.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='acl.c' object='ss_server-acl.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-acl.o `test -f 'acl.c' || echo '$(srcdir)/'`acl.c ++ ++ss_server-acl.obj: acl.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-acl.obj -MD -MP -MF $(DEPDIR)/ss_server-acl.Tpo -c -o ss_server-acl.obj `if test -f 'acl.c'; then $(CYGPATH_W) 'acl.c'; else $(CYGPATH_W) '$(srcdir)/acl.c'; fi` ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-acl.Tpo $(DEPDIR)/ss_server-acl.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='acl.c' object='ss_server-acl.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-acl.obj `if test -f 'acl.c'; then $(CYGPATH_W) 'acl.c'; else $(CYGPATH_W) '$(srcdir)/acl.c'; fi` ++ ++ss_server-resolv.o: resolv.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-resolv.o -MD -MP -MF $(DEPDIR)/ss_server-resolv.Tpo -c -o ss_server-resolv.o `test -f 'resolv.c' || echo '$(srcdir)/'`resolv.c ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-resolv.Tpo $(DEPDIR)/ss_server-resolv.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='resolv.c' object='ss_server-resolv.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-resolv.o `test -f 'resolv.c' || echo '$(srcdir)/'`resolv.c ++ ++ss_server-resolv.obj: resolv.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-resolv.obj -MD -MP -MF $(DEPDIR)/ss_server-resolv.Tpo -c -o ss_server-resolv.obj `if test -f 'resolv.c'; then $(CYGPATH_W) 'resolv.c'; else $(CYGPATH_W) '$(srcdir)/resolv.c'; fi` ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-resolv.Tpo $(DEPDIR)/ss_server-resolv.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='resolv.c' object='ss_server-resolv.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-resolv.obj `if test -f 'resolv.c'; then $(CYGPATH_W) 'resolv.c'; else $(CYGPATH_W) '$(srcdir)/resolv.c'; fi` ++ ++ss_server-server.o: server.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-server.o -MD -MP -MF $(DEPDIR)/ss_server-server.Tpo -c -o ss_server-server.o `test -f 'server.c' || echo '$(srcdir)/'`server.c ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-server.Tpo $(DEPDIR)/ss_server-server.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server.c' object='ss_server-server.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-server.o `test -f 'server.c' || echo '$(srcdir)/'`server.c ++ ++ss_server-server.obj: server.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-server.obj -MD -MP -MF $(DEPDIR)/ss_server-server.Tpo -c -o ss_server-server.obj `if test -f 'server.c'; then $(CYGPATH_W) 'server.c'; else $(CYGPATH_W) '$(srcdir)/server.c'; fi` ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-server.Tpo $(DEPDIR)/ss_server-server.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server.c' object='ss_server-server.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-server.obj `if test -f 'server.c'; then $(CYGPATH_W) 'server.c'; else $(CYGPATH_W) '$(srcdir)/server.c'; fi` ++ ++ss_server-http.o: http.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-http.o -MD -MP -MF $(DEPDIR)/ss_server-http.Tpo -c -o ss_server-http.o `test -f 'http.c' || echo '$(srcdir)/'`http.c ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-http.Tpo $(DEPDIR)/ss_server-http.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http.c' object='ss_server-http.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-http.o `test -f 'http.c' || echo '$(srcdir)/'`http.c ++ ++ss_server-http.obj: http.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-http.obj -MD -MP -MF $(DEPDIR)/ss_server-http.Tpo -c -o ss_server-http.obj `if test -f 'http.c'; then $(CYGPATH_W) 'http.c'; else $(CYGPATH_W) '$(srcdir)/http.c'; fi` ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-http.Tpo $(DEPDIR)/ss_server-http.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http.c' object='ss_server-http.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-http.obj `if test -f 'http.c'; then $(CYGPATH_W) 'http.c'; else $(CYGPATH_W) '$(srcdir)/http.c'; fi` ++ ++ss_server-tls.o: tls.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-tls.o -MD -MP -MF $(DEPDIR)/ss_server-tls.Tpo -c -o ss_server-tls.o `test -f 'tls.c' || echo '$(srcdir)/'`tls.c ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-tls.Tpo $(DEPDIR)/ss_server-tls.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls.c' object='ss_server-tls.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-tls.o `test -f 'tls.c' || echo '$(srcdir)/'`tls.c ++ ++ss_server-tls.obj: tls.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-tls.obj -MD -MP -MF $(DEPDIR)/ss_server-tls.Tpo -c -o ss_server-tls.obj `if test -f 'tls.c'; then $(CYGPATH_W) 'tls.c'; else $(CYGPATH_W) '$(srcdir)/tls.c'; fi` ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-tls.Tpo $(DEPDIR)/ss_server-tls.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls.c' object='ss_server-tls.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-tls.obj `if test -f 'tls.c'; then $(CYGPATH_W) 'tls.c'; else $(CYGPATH_W) '$(srcdir)/tls.c'; fi` ++ ++ss_server-rule.o: rule.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-rule.o -MD -MP -MF $(DEPDIR)/ss_server-rule.Tpo -c -o ss_server-rule.o `test -f 'rule.c' || echo '$(srcdir)/'`rule.c ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-rule.Tpo $(DEPDIR)/ss_server-rule.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rule.c' object='ss_server-rule.o' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-rule.o `test -f 'rule.c' || echo '$(srcdir)/'`rule.c ++ ++ss_server-rule.obj: rule.c ++@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-rule.obj -MD -MP -MF $(DEPDIR)/ss_server-rule.Tpo -c -o ss_server-rule.obj `if test -f 'rule.c'; then $(CYGPATH_W) 'rule.c'; else $(CYGPATH_W) '$(srcdir)/rule.c'; fi` ++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-rule.Tpo $(DEPDIR)/ss_server-rule.Po ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rule.c' object='ss_server-rule.obj' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-rule.obj `if test -f 'rule.c'; then $(CYGPATH_W) 'rule.c'; else $(CYGPATH_W) '$(srcdir)/rule.c'; fi` ++ ++mostlyclean-libtool: ++ -rm -f *.lo ++ ++clean-libtool: ++ -rm -rf .libs _libs ++ ++ID: $(am__tagged_files) ++ $(am__define_uniq_tagged_files); mkid -fID $$unique ++tags: tags-am ++TAGS: tags ++ ++tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) ++ set x; \ ++ here=`pwd`; \ ++ $(am__define_uniq_tagged_files); \ ++ shift; \ ++ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ ++ test -n "$$unique" || unique=$$empty_fix; \ ++ if test $$# -gt 0; then \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ "$$@" $$unique; \ ++ else \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ $$unique; \ ++ fi; \ ++ fi ++ctags: ctags-am ++ ++CTAGS: ctags ++ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) ++ $(am__define_uniq_tagged_files); \ ++ test -z "$(CTAGS_ARGS)$$unique" \ ++ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ ++ $$unique ++ ++GTAGS: ++ here=`$(am__cd) $(top_builddir) && pwd` \ ++ && $(am__cd) $(top_srcdir) \ ++ && gtags -i $(GTAGS_ARGS) "$$here" ++cscopelist: cscopelist-am ++ ++cscopelist-am: $(am__tagged_files) ++ list='$(am__tagged_files)'; \ ++ case "$(srcdir)" in \ ++ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ ++ *) sdir=$(subdir)/$(srcdir) ;; \ ++ esac; \ ++ for i in $$list; do \ ++ if test -f "$$i"; then \ ++ echo "$(subdir)/$$i"; \ ++ else \ ++ echo "$$sdir/$$i"; \ ++ fi; \ ++ done >> $(top_builddir)/cscope.files ++ ++distclean-tags: ++ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags ++ ++distdir: $(DISTFILES) ++ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ ++ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ ++ list='$(DISTFILES)'; \ ++ dist_files=`for file in $$list; do echo $$file; done | \ ++ sed -e "s|^$$srcdirstrip/||;t" \ ++ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ ++ case $$dist_files in \ ++ */*) $(MKDIR_P) `echo "$$dist_files" | \ ++ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ ++ sort -u` ;; \ ++ esac; \ ++ for file in $$dist_files; do \ ++ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ ++ if test -d $$d/$$file; then \ ++ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ ++ if test -d "$(distdir)/$$file"; then \ ++ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ ++ fi; \ ++ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ ++ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ ++ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ ++ fi; \ ++ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ ++ else \ ++ test -f "$(distdir)/$$file" \ ++ || cp -p $$d/$$file "$(distdir)/$$file" \ ++ || exit 1; \ ++ fi; \ ++ done ++check-am: all-am ++check: check-am ++all-am: Makefile $(PROGRAMS) ++installdirs: ++ for dir in "$(DESTDIR)$(bindir)"; do \ ++ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ ++ done ++install: install-am ++install-exec: install-exec-am ++install-data: install-data-am ++uninstall: uninstall-am ++ ++install-am: all-am ++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am ++ ++installcheck: installcheck-am ++install-strip: ++ if test -z '$(STRIP)'; then \ ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ install; \ ++ else \ ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ ++ fi ++mostlyclean-generic: ++ ++clean-generic: ++ ++distclean-generic: ++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) ++ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) ++ ++maintainer-clean-generic: ++ @echo "This command is intended for maintainers to use" ++ @echo "it deletes files that may require special tools to rebuild." ++clean: clean-am ++ ++clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am ++ ++distclean: distclean-am ++ -rm -rf ./$(DEPDIR) ++ -rm -f Makefile ++distclean-am: clean-am distclean-compile distclean-generic \ ++ distclean-tags ++ ++dvi: dvi-am ++ ++dvi-am: ++ ++html: html-am ++ ++html-am: ++ ++info: info-am ++ ++info-am: ++ ++install-data-am: ++ ++install-dvi: install-dvi-am ++ ++install-dvi-am: ++ ++install-exec-am: install-binPROGRAMS ++ ++install-html: install-html-am ++ ++install-html-am: ++ ++install-info: install-info-am ++ ++install-info-am: ++ ++install-man: ++ ++install-pdf: install-pdf-am ++ ++install-pdf-am: ++ ++install-ps: install-ps-am ++ ++install-ps-am: ++ ++installcheck-am: ++ ++maintainer-clean: maintainer-clean-am ++ -rm -rf ./$(DEPDIR) ++ -rm -f Makefile ++maintainer-clean-am: distclean-am maintainer-clean-generic ++ ++mostlyclean: mostlyclean-am ++ ++mostlyclean-am: mostlyclean-compile mostlyclean-generic \ ++ mostlyclean-libtool ++ ++pdf: pdf-am ++ ++pdf-am: ++ ++ps: ps-am ++ ++ps-am: ++ ++uninstall-am: uninstall-binPROGRAMS ++ ++.MAKE: install-am install-strip ++ ++.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ ++ clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ ++ ctags ctags-am distclean distclean-compile distclean-generic \ ++ distclean-libtool distclean-tags distdir dvi dvi-am html \ ++ html-am info info-am install install-am install-binPROGRAMS \ ++ install-data install-data-am install-dvi install-dvi-am \ ++ install-exec install-exec-am install-html install-html-am \ ++ install-info install-info-am install-man install-pdf \ ++ install-pdf-am install-ps install-ps-am install-strip \ ++ installcheck installcheck-am installdirs maintainer-clean \ ++ maintainer-clean-generic mostlyclean mostlyclean-compile \ ++ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ ++ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS ++ ++.PRECIOUS: Makefile ++ ++ ++# Tell versions [3.59,3.63) of GNU make to not export all variables. ++# Otherwise a system limit (for SysV at least) may be exceeded. ++.NOEXPORT: +diff --git a/server/README.md b/server/README.md +new file mode 100644 +index 0000000..ef6a20e +--- /dev/null ++++ b/server/README.md +@@ -0,0 +1,3 @@ ++# server ++ ++`ss-server` and `ss-check` from https://github.com/ywb94/shadowsocks-libev +diff --git a/server/acl.c b/server/acl.c +new file mode 100644 +index 0000000..60d4b72 +--- /dev/null ++++ b/server/acl.c +@@ -0,0 +1,597 @@ ++/* ++ * acl.c - Manage the ACL (Access Control List) ++ * ++ * Copyright (C) 2013 - 2016, Max Lv ++ * ++ * This file is part of the shadowsocks-libev. ++ * ++ * shadowsocks-libev 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 3 of the License, or ++ * (at your option) any later version. ++ * ++ * shadowsocks-libev 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 shadowsocks-libev; see the file COPYING. If not, see ++ * . ++ */ ++ ++#include ++#include ++ ++#include "rule.h" ++#include "utils.h" ++#include "cache.h" ++#include "acl.h" ++ ++static struct ip_set white_list_ipv4; ++static struct ip_set white_list_ipv6; ++ ++static struct ip_set black_list_ipv4; ++static struct ip_set black_list_ipv6; ++ ++static struct cork_dllist black_list_rules; ++static struct cork_dllist white_list_rules; ++ ++static int acl_mode = BLACK_LIST; ++ ++static struct cache *block_list; ++ ++static struct ip_set outbound_block_list_ipv4; ++static struct ip_set outbound_block_list_ipv6; ++static struct cork_dllist outbound_block_list_rules; ++ ++#ifdef __linux__ ++ ++#include ++#include ++ ++#define NO_FIREWALL_MODE 0 ++#define IPTABLES_MODE 1 ++#define FIREWALLD_MODE 2 ++ ++static FILE *shell_stdin; ++static int mode = NO_FIREWALL_MODE; ++ ++static char chain_name[64]; ++static char *iptables_init_chain = ++ "iptables -N %s; iptables -F %s; iptables -A OUTPUT -p tcp --tcp-flags RST RST -j %s"; ++static char *iptables_remove_chain = ++ "iptables -D OUTPUT -p tcp --tcp-flags RST RST -j %s; iptables -F %s; iptables -X %s"; ++static char *iptables_add_rule = "iptables -A %s -d %s -j DROP"; ++static char *iptables_remove_rule = "iptables -D %s -d %s -j DROP"; ++ ++static char *ip6tables_init_chain = ++ "ip6tables -N %s; ip6tables -F %s; ip6tables -A OUTPUT -p tcp --tcp-flags RST RST -j %s"; ++static char *ip6tables_remove_chain = ++ "ip6tables -D OUTPUT -p tcp --tcp-flags RST RST -j %s; ip6tables -F %s; ip6tables -X %s"; ++static char *ip6tables_add_rule = "ip6tables -A %s -d %s -j DROP"; ++static char *ip6tables_remove_rule = "ip6tables -D %s -d %s -j DROP"; ++ ++static char *firewalld_init_chain = ++ "firewall-cmd --direct --add-chain ipv4 filter %s; \ ++ firewall-cmd --direct --passthrough ipv4 -F %s; \ ++ firewall-cmd --direct --passthrough ipv4 -A OUTPUT -p tcp --tcp-flags RST RST -j %s"; ++static char *firewalld_remove_chain = ++ "firewall-cmd --direct --passthrough ipv4 -D OUTPUT -p tcp --tcp-flags RST RST -j %s; \ ++ firewall-cmd --direct --passthrough ipv4 -F %s; \ ++ firewall-cmd --direct --remove-chain ipv4 filter %s"; ++static char *firewalld_add_rule = "firewall-cmd --direct --passthrough ipv4 -A %s -d %s -j DROP"; ++static char *firewalld_remove_rule = "firewall-cmd --direct --passthrough ipv4 -D %s -d %s -j DROP"; ++ ++static char *firewalld6_init_chain = ++ "firewall-cmd --direct --add-chain ipv6 filter %s; \ ++ firewall-cmd --direct --passthrough ipv6 -F %s; \ ++ firewall-cmd --direct --passthrough ipv6 -A OUTPUT -p tcp --tcp-flags RST RST -j %s"; ++static char *firewalld6_remove_chain = ++ "firewall-cmd --direct --passthrough ipv6 -D OUTPUT -p tcp --tcp-flags RST RST -j %s; \ ++ firewall-cmd --direct --passthrough ipv6 -F %s; \ ++ firewall-cmd --direct --remove-chain ipv6 filter %s"; ++static char *firewalld6_add_rule = "firewall-cmd --direct --passthrough ipv6 -A %s -d %s -j DROP"; ++static char *firewalld6_remove_rule = "firewall-cmd --direct --passthrough ipv6 -D %s -d %s -j DROP"; ++ ++static int ++run_cmd(const char *cmd) ++{ ++ int ret = 0; ++ char cmdstring[256]; ++ ++ sprintf(cmdstring, "%s\n", cmd); ++ size_t len = strlen(cmdstring); ++ ++ if (shell_stdin != NULL) { ++ ret = fwrite(cmdstring, 1, len, shell_stdin); ++ fflush(shell_stdin); ++ } ++ ++ return ret == len; ++} ++ ++static int ++init_firewall() ++{ ++ int ret = 0; ++ char cli[256]; ++ FILE *fp; ++ ++ if (getuid() != 0) ++ return -1; ++ ++ sprintf(cli, "firewall-cmd --version 2>&1"); ++ fp = popen(cli, "r"); ++ ++ if (fp == NULL) ++ return -1; ++ ++ if (pclose(fp) == 0) { ++ mode = FIREWALLD_MODE; ++ } else { ++ /* Check whether we have permission to operate iptables. ++ * Note that checking `iptables --version` is insufficient: ++ * eg, running within a child user namespace. ++ */ ++ sprintf(cli, "iptables -L 2>&1"); ++ fp = popen(cli, "r"); ++ if (fp == NULL) ++ return -1; ++ if (pclose(fp) == 0) ++ mode = IPTABLES_MODE; ++ } ++ ++ sprintf(chain_name, "SHADOWSOCKS_LIBEV_%d", getpid()); ++ ++ if (mode == FIREWALLD_MODE) { ++ sprintf(cli, firewalld6_init_chain, chain_name, chain_name, chain_name); ++ ret |= system(cli); ++ sprintf(cli, firewalld_init_chain, chain_name, chain_name, chain_name); ++ ret |= system(cli); ++ } else if (mode == IPTABLES_MODE) { ++ sprintf(cli, ip6tables_init_chain, chain_name, chain_name, chain_name); ++ ret |= system(cli); ++ sprintf(cli, iptables_init_chain, chain_name, chain_name, chain_name); ++ ret |= system(cli); ++ } ++ ++ shell_stdin = popen("/bin/sh", "w"); ++ ++ return ret; ++} ++ ++static int ++reset_firewall() ++{ ++ int ret = 0; ++ char cli[256]; ++ ++ if (getuid() != 0) ++ return -1; ++ ++ if (mode == IPTABLES_MODE) { ++ sprintf(cli, ip6tables_remove_chain, chain_name, chain_name, chain_name); ++ ret |= system(cli); ++ sprintf(cli, iptables_remove_chain, chain_name, chain_name, chain_name); ++ ret |= system(cli); ++ } else if (mode == FIREWALLD_MODE) { ++ sprintf(cli, firewalld6_remove_chain, chain_name, chain_name, chain_name); ++ ret |= system(cli); ++ sprintf(cli, firewalld_remove_chain, chain_name, chain_name, chain_name); ++ ret |= system(cli); ++ } ++ ++ if (shell_stdin != NULL) { ++ run_cmd("exit 0"); ++ pclose(shell_stdin); ++ } ++ ++ return ret; ++} ++ ++static int ++set_firewall_rule(char *addr, int add) ++{ ++ char cli[256]; ++ struct cork_ip ip; ++ ++ if (getuid() != 0) ++ return -1; ++ ++ if (cork_ip_init(&ip, addr)) ++ return -1; ++ ++ if (add) { ++ if (mode == IPTABLES_MODE) ++ sprintf(cli, ip.version == 4 ? iptables_add_rule : ip6tables_add_rule, ++ chain_name, addr); ++ else if (mode == FIREWALLD_MODE) ++ sprintf(cli, ip.version == 4 ? firewalld_add_rule : firewalld6_add_rule, ++ chain_name, addr); ++ return run_cmd(cli); ++ } else { ++ if (mode == IPTABLES_MODE) ++ sprintf(cli, ip.version == 4 ? iptables_remove_rule : ip6tables_remove_rule, ++ chain_name, addr); ++ else if (mode == FIREWALLD_MODE) ++ sprintf(cli, ip.version == 4 ? firewalld_remove_rule : firewalld6_remove_rule, ++ chain_name, addr); ++ return run_cmd(cli); ++ } ++ ++ return 0; ++} ++ ++static void ++free_firewall_rule(void *key, void *element) ++{ ++ if (key == NULL) ++ return; ++ char *addr = (char *)key; ++ set_firewall_rule(addr, 0); ++ ss_free(element); ++} ++ ++#endif ++ ++void ++init_block_list(int firewall) ++{ ++ // Initialize cache ++#ifdef __linux__ ++ if (firewall) ++ init_firewall(); ++ else ++ mode = NO_FIREWALL_MODE; ++ cache_create(&block_list, 256, free_firewall_rule); ++#else ++ cache_create(&block_list, 256, NULL); ++#endif ++} ++ ++void ++free_block_list() ++{ ++#ifdef __linux__ ++ if (mode != NO_FIREWALL_MODE) ++ reset_firewall(); ++#endif ++ cache_clear(block_list, 0); // Remove all items ++} ++ ++int ++remove_from_block_list(char *addr) ++{ ++ size_t addr_len = strlen(addr); ++ return cache_remove(block_list, addr, addr_len); ++} ++ ++void ++clear_block_list() ++{ ++ cache_clear(block_list, 3600); // Clear items older than 1 hour ++} ++ ++int ++check_block_list(char *addr) ++{ ++ size_t addr_len = strlen(addr); ++ ++ if (cache_key_exist(block_list, addr, addr_len)) { ++ int *count = NULL; ++ cache_lookup(block_list, addr, addr_len, &count); ++ ++ if (count != NULL && *count > MAX_TRIES) ++ return 1; ++ } ++ ++ return 0; ++} ++ ++int ++update_block_list(char *addr, int err_level) ++{ ++ size_t addr_len = strlen(addr); ++ ++ if (cache_key_exist(block_list, addr, addr_len)) { ++ int *count = NULL; ++ cache_lookup(block_list, addr, addr_len, &count); ++ if (count != NULL) { ++ if (*count > MAX_TRIES) ++ return 1; ++ (*count) += err_level; ++ } ++ } else if (err_level > 0) { ++ int *count = (int *)ss_malloc(sizeof(int)); ++ *count = 1; ++ cache_insert(block_list, addr, addr_len, count); ++#ifdef __linux__ ++ if (mode != NO_FIREWALL_MODE) ++ set_firewall_rule(addr, 1); ++#endif ++ } ++ ++ return 0; ++} ++ ++static void ++parse_addr_cidr(const char *str, char *host, int *cidr) ++{ ++ int ret = -1, n = 0; ++ char *pch; ++ ++ pch = strchr(str, '/'); ++ while (pch != NULL) { ++ n++; ++ ret = pch - str; ++ pch = strchr(pch + 1, '/'); ++ } ++ if (ret == -1) { ++ strcpy(host, str); ++ *cidr = -1; ++ } else { ++ memcpy(host, str, ret); ++ host[ret] = '\0'; ++ *cidr = atoi(str + ret + 1); ++ } ++} ++ ++char * ++trimwhitespace(char *str) ++{ ++ char *end; ++ ++ // Trim leading space ++ while (isspace(*str)) ++ str++; ++ ++ if (*str == 0) // All spaces? ++ return str; ++ ++ // Trim trailing space ++ end = str + strlen(str) - 1; ++ while (end > str && isspace(*end)) ++ end--; ++ ++ // Write new null terminator ++ *(end + 1) = 0; ++ ++ return str; ++} ++ ++int ++init_acl(const char *path) ++{ ++ // initialize ipset ++ ipset_init_library(); ++ ++ ipset_init(&white_list_ipv4); ++ ipset_init(&white_list_ipv6); ++ ipset_init(&black_list_ipv4); ++ ipset_init(&black_list_ipv6); ++ ipset_init(&outbound_block_list_ipv4); ++ ipset_init(&outbound_block_list_ipv6); ++ ++ cork_dllist_init(&black_list_rules); ++ cork_dllist_init(&white_list_rules); ++ cork_dllist_init(&outbound_block_list_rules); ++ ++ struct ip_set *list_ipv4 = &black_list_ipv4; ++ struct ip_set *list_ipv6 = &black_list_ipv6; ++ struct cork_dllist *rules = &black_list_rules; ++ ++ FILE *f = fopen(path, "r"); ++ if (f == NULL) { ++ LOGE("Invalid acl path."); ++ return -1; ++ } ++ ++ char buf[257]; ++ while (!feof(f)) ++ if (fgets(buf, 256, f)) { ++ // Trim the newline ++ int len = strlen(buf); ++ if (len > 0 && buf[len - 1] == '\n') { ++ buf[len - 1] = '\0'; ++ } ++ ++ char *line = trimwhitespace(buf); ++ ++ // Skip comments ++ if (line[0] == '#') { ++ continue; ++ } ++ ++ if (strlen(line) == 0) { ++ continue; ++ } ++ ++ if (strcmp(line, "[outbound_block_list]") == 0) { ++ list_ipv4 = &outbound_block_list_ipv4; ++ list_ipv6 = &outbound_block_list_ipv6; ++ rules = &outbound_block_list_rules; ++ continue; ++ } else if (strcmp(line, "[black_list]") == 0 ++ || strcmp(line, "[bypass_list]") == 0) { ++ list_ipv4 = &black_list_ipv4; ++ list_ipv6 = &black_list_ipv6; ++ rules = &black_list_rules; ++ continue; ++ } else if (strcmp(line, "[white_list]") == 0 ++ || strcmp(line, "[proxy_list]") == 0) { ++ list_ipv4 = &white_list_ipv4; ++ list_ipv6 = &white_list_ipv6; ++ rules = &white_list_rules; ++ continue; ++ } else if (strcmp(line, "[reject_all]") == 0 ++ || strcmp(line, "[bypass_all]") == 0) { ++ acl_mode = WHITE_LIST; ++ continue; ++ } else if (strcmp(line, "[accept_all]") == 0 ++ || strcmp(line, "[proxy_all]") == 0) { ++ acl_mode = BLACK_LIST; ++ continue; ++ } ++ ++ char host[257]; ++ int cidr; ++ parse_addr_cidr(line, host, &cidr); ++ ++ struct cork_ip addr; ++ int err = cork_ip_init(&addr, host); ++ if (!err) { ++ if (addr.version == 4) { ++ if (cidr >= 0) { ++ ipset_ipv4_add_network(list_ipv4, &(addr.ip.v4), cidr); ++ } else { ++ ipset_ipv4_add(list_ipv4, &(addr.ip.v4)); ++ } ++ } else if (addr.version == 6) { ++ if (cidr >= 0) { ++ ipset_ipv6_add_network(list_ipv6, &(addr.ip.v6), cidr); ++ } else { ++ ipset_ipv6_add(list_ipv6, &(addr.ip.v6)); ++ } ++ } ++ } else { ++ rule_t *rule = new_rule(); ++ accept_rule_arg(rule, line); ++ init_rule(rule); ++ add_rule(rules, rule); ++ } ++ } ++ ++ fclose(f); ++ ++ return 0; ++} ++ ++void ++free_rules(struct cork_dllist *rules) ++{ ++ struct cork_dllist_item *iter; ++ while ((iter = cork_dllist_head(rules)) != NULL) { ++ rule_t *rule = cork_container_of(iter, rule_t, entries); ++ remove_rule(rule); ++ } ++} ++ ++void ++free_acl(void) ++{ ++ ipset_done(&black_list_ipv4); ++ ipset_done(&black_list_ipv6); ++ ipset_done(&white_list_ipv4); ++ ipset_done(&white_list_ipv6); ++ ++ free_rules(&black_list_rules); ++ free_rules(&white_list_rules); ++} ++ ++int ++get_acl_mode(void) ++{ ++ return acl_mode; ++} ++ ++/* ++ * Return 0, if not match. ++ * Return 1, if match black list. ++ * Return -1, if match white list. ++ */ ++int ++acl_match_host(const char *host) ++{ ++ struct cork_ip addr; ++ int ret = 0; ++ int err = cork_ip_init(&addr, host); ++ ++ if (err) { ++ int host_len = strlen(host); ++ if (lookup_rule(&black_list_rules, host, host_len) != NULL) ++ ret = 1; ++ else if (lookup_rule(&white_list_rules, host, host_len) != NULL) ++ ret = -1; ++ return ret; ++ } ++ ++ if (addr.version == 4) { ++ if (ipset_contains_ipv4(&black_list_ipv4, &(addr.ip.v4))) ++ ret = 1; ++ else if (ipset_contains_ipv4(&white_list_ipv4, &(addr.ip.v4))) ++ ret = -1; ++ } else if (addr.version == 6) { ++ if (ipset_contains_ipv6(&black_list_ipv6, &(addr.ip.v6))) ++ ret = 1; ++ else if (ipset_contains_ipv6(&white_list_ipv6, &(addr.ip.v6))) ++ ret = -1; ++ } ++ ++ return ret; ++} ++ ++int ++acl_add_ip(const char *ip) ++{ ++ struct cork_ip addr; ++ int err = cork_ip_init(&addr, ip); ++ if (err) { ++ return -1; ++ } ++ ++ if (addr.version == 4) { ++ ipset_ipv4_add(&black_list_ipv4, &(addr.ip.v4)); ++ } else if (addr.version == 6) { ++ ipset_ipv6_add(&black_list_ipv6, &(addr.ip.v6)); ++ } ++ ++ return 0; ++} ++ ++int ++acl_remove_ip(const char *ip) ++{ ++ struct cork_ip addr; ++ int err = cork_ip_init(&addr, ip); ++ if (err) { ++ return -1; ++ } ++ ++ if (addr.version == 4) { ++ ipset_ipv4_remove(&black_list_ipv4, &(addr.ip.v4)); ++ } else if (addr.version == 6) { ++ ipset_ipv6_remove(&black_list_ipv6, &(addr.ip.v6)); ++ } ++ ++ return 0; ++} ++ ++/* ++ * Return 0, if not match. ++ * Return 1, if match black list. ++ */ ++int ++outbound_block_match_host(const char *host) ++{ ++ struct cork_ip addr; ++ int ret = 0; ++ int err = cork_ip_init(&addr, host); ++ ++ if (err) { ++ int host_len = strlen(host); ++ if (lookup_rule(&outbound_block_list_rules, host, host_len) != NULL) ++ ret = 1; ++ return ret; ++ } ++ ++ if (addr.version == 4) { ++ if (ipset_contains_ipv4(&outbound_block_list_ipv4, &(addr.ip.v4))) ++ ret = 1; ++ } else if (addr.version == 6) { ++ if (ipset_contains_ipv6(&outbound_block_list_ipv6, &(addr.ip.v6))) ++ ret = 1; ++ } ++ ++ return ret; ++} +diff --git a/server/acl.h b/server/acl.h +new file mode 100644 +index 0000000..d6f18b8 +--- /dev/null ++++ b/server/acl.h +@@ -0,0 +1,53 @@ ++/* ++ * acl.h - Define the ACL interface ++ * ++ * Copyright (C) 2013 - 2016, Max Lv ++ * ++ * This file is part of the shadowsocks-libev. ++ * ++ * shadowsocks-libev 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 3 of the License, or ++ * (at your option) any later version. ++ * ++ * shadowsocks-libev 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 shadowsocks-libev; see the file COPYING. If not, see ++ * . ++ */ ++ ++#ifndef _ACL_H ++#define _ACL_H ++ ++#define BLACK_LIST 0 ++#define WHITE_LIST 1 ++ ++#define MAX_TRIES 64 ++#define MALICIOUS 8 ++#define SUSPICIOUS 4 ++#define BAD 2 ++#define MALFORMED 1 ++ ++int init_acl(const char *path); ++void free_acl(void); ++void clear_block_list(void); ++ ++int acl_match_host(const char *ip); ++int acl_add_ip(const char *ip); ++int acl_remove_ip(const char *ip); ++ ++int get_acl_mode(void); ++ ++void init_block_list(int firewall); ++void free_block_list(); ++int check_block_list(char *addr); ++int update_block_list(char *addr, int err_level); ++int remove_from_block_list(char *addr); ++ ++int outbound_block_match_host(const char *host); ++ ++#endif // _ACL_H +diff --git a/server/auth.c b/server/auth.c +new file mode 100644 +index 0000000..a36257a +--- /dev/null ++++ b/server/auth.c +@@ -0,0 +1,993 @@ ++ ++#include "auth.h" ++ ++static int auth_simple_pack_unit_size = 2000; ++typedef int (*hmac_with_key_func)(char *auth, char *msg, int msg_len, uint8_t *auth_key, int key_len); ++typedef int (*hash_func)(char *auth, char *msg, int msg_len); ++ ++typedef struct auth_simple_global_data { ++ uint8_t local_client_id[8]; ++ uint32_t connection_id; ++}auth_simple_global_data; ++ ++typedef struct auth_simple_local_data { ++ int has_sent_header; ++ char * recv_buffer; ++ int recv_buffer_size; ++ uint32_t recv_id; ++ uint32_t pack_id; ++ char * salt; ++ uint8_t * user_key; ++ char uid[4]; ++ int user_key_len; ++ hmac_with_key_func hmac; ++ hash_func hash; ++ int hash_len; ++}auth_simple_local_data; ++ ++void auth_simple_local_data_init(auth_simple_local_data* local) { ++ local->has_sent_header = 0; ++ local->recv_buffer = (char*)malloc(16384); ++ local->recv_buffer_size = 0; ++ local->recv_id = 1; ++ local->pack_id = 1; ++ local->salt = ""; ++ local->user_key = 0; ++ local->user_key_len = 0; ++ local->hmac = 0; ++ local->hash = 0; ++ local->hash_len = 0; ++ local->salt = ""; ++} ++ ++void * auth_simple_init_data() { ++ auth_simple_global_data *global = (auth_simple_global_data*)malloc(sizeof(auth_simple_global_data)); ++ rand_bytes(global->local_client_id, 8); ++ rand_bytes((uint8_t*)&global->connection_id, 4); ++ global->connection_id &= 0xFFFFFF; ++ return global; ++} ++ ++obfs * auth_simple_new_obfs() { ++ obfs * self = new_obfs(); ++ self->l_data = malloc(sizeof(auth_simple_local_data)); ++ auth_simple_local_data_init((auth_simple_local_data*)self->l_data); ++ return self; ++} ++ ++obfs * auth_aes128_md5_new_obfs() { ++ obfs * self = new_obfs(); ++ self->l_data = malloc(sizeof(auth_simple_local_data)); ++ auth_simple_local_data_init((auth_simple_local_data*)self->l_data); ++ ((auth_simple_local_data*)self->l_data)->hmac = ss_md5_hmac_with_key; ++ ((auth_simple_local_data*)self->l_data)->hash = ss_md5_hash_func; ++ ((auth_simple_local_data*)self->l_data)->hash_len = 16; ++ ((auth_simple_local_data*)self->l_data)->salt = "auth_aes128_md5"; ++ return self; ++} ++ ++obfs * auth_aes128_sha1_new_obfs() { ++ obfs * self = new_obfs(); ++ self->l_data = malloc(sizeof(auth_simple_local_data)); ++ auth_simple_local_data_init((auth_simple_local_data*)self->l_data); ++ ((auth_simple_local_data*)self->l_data)->hmac = ss_sha1_hmac_with_key; ++ ((auth_simple_local_data*)self->l_data)->hash = ss_sha1_hash_func; ++ ((auth_simple_local_data*)self->l_data)->hash_len = 20; ++ ((auth_simple_local_data*)self->l_data)->salt = "auth_aes128_sha1"; ++ return self; ++} ++ ++void auth_simple_dispose(obfs *self) { ++ auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; ++ if (local->recv_buffer != NULL) { ++ free(local->recv_buffer); ++ local->recv_buffer = NULL; ++ } ++ if (local->user_key != NULL) { ++ free(local->user_key); ++ local->user_key = NULL; ++ } ++ free(local); ++ self->l_data = NULL; ++ dispose_obfs(self); ++} ++ ++int auth_simple_pack_data(char *data, int datalength, char *outdata) { ++ unsigned char rand_len = (xorshift128plus() & 0xF) + 1; ++ int out_size = rand_len + datalength + 6; ++ outdata[0] = out_size >> 8; ++ outdata[1] = out_size; ++ outdata[2] = rand_len; ++ memmove(outdata + rand_len + 2, data, datalength); ++ fillcrc32((unsigned char *)outdata, out_size); ++ return out_size; ++} ++ ++void memintcopy_lt(void *mem, uint32_t val) { ++ ((uint8_t *)mem)[0] = val; ++ ((uint8_t *)mem)[1] = val >> 8; ++ ((uint8_t *)mem)[2] = val >> 16; ++ ((uint8_t *)mem)[3] = val >> 24; ++} ++ ++int auth_simple_pack_auth_data(auth_simple_global_data *global, char *data, int datalength, char *outdata) { ++ unsigned char rand_len = (xorshift128plus() & 0xF) + 1; ++ int out_size = rand_len + datalength + 6 + 12; ++ outdata[0] = out_size >> 8; ++ outdata[1] = out_size; ++ outdata[2] = rand_len; ++ ++global->connection_id; ++ if (global->connection_id > 0xFF000000) { ++ rand_bytes(global->local_client_id, 8); ++ rand_bytes((uint8_t*)&global->connection_id, 4); ++ global->connection_id &= 0xFFFFFF; ++ } ++ time_t t = time(NULL); ++ memintcopy_lt(outdata + rand_len + 2, t); ++ memmove(outdata + rand_len + 2 + 4, global->local_client_id, 4); ++ memintcopy_lt(outdata + rand_len + 2 + 8, global->connection_id); ++ memmove(outdata + rand_len + 2 + 12, data, datalength); ++ fillcrc32((unsigned char *)outdata, out_size); ++ return out_size; ++} ++ ++int auth_simple_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { ++ char *plaindata = *pplaindata; ++ auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; ++ char * out_buffer = (char*)malloc(datalength * 2 + 64); ++ char * buffer = out_buffer; ++ char * data = plaindata; ++ int len = datalength; ++ int pack_len; ++ if (len > 0 && local->has_sent_header == 0) { ++ int head_size = get_head_size(plaindata, datalength, 30); ++ if (head_size > datalength) ++ head_size = datalength; ++ pack_len = auth_simple_pack_auth_data((auth_simple_global_data *)self->server.g_data, data, head_size, buffer); ++ buffer += pack_len; ++ data += head_size; ++ len -= head_size; ++ local->has_sent_header = 1; ++ } ++ while ( len > auth_simple_pack_unit_size ) { ++ pack_len = auth_simple_pack_data(data, auth_simple_pack_unit_size, buffer); ++ buffer += pack_len; ++ data += auth_simple_pack_unit_size; ++ len -= auth_simple_pack_unit_size; ++ } ++ if (len > 0) { ++ pack_len = auth_simple_pack_data(data, len, buffer); ++ buffer += pack_len; ++ } ++ len = buffer - out_buffer; ++ if (*capacity < len) { ++ *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); ++ plaindata = *pplaindata; ++ } ++ memmove(plaindata, out_buffer, len); ++ free(out_buffer); ++ return len; ++} ++ ++int auth_simple_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { ++ char *plaindata = *pplaindata; ++ auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; ++ uint8_t * recv_buffer = (uint8_t *)local->recv_buffer; ++ if (local->recv_buffer_size + datalength > 16384) ++ return -1; ++ memmove(recv_buffer + local->recv_buffer_size, plaindata, datalength); ++ local->recv_buffer_size += datalength; ++ ++ char * out_buffer = (char*)malloc(local->recv_buffer_size); ++ char * buffer = out_buffer; ++ while (local->recv_buffer_size > 2) { ++ int length = ((int)recv_buffer[0] << 8) | recv_buffer[1]; ++ if (length >= 8192 || length < 7) { ++ free(out_buffer); ++ local->recv_buffer_size = 0; ++ return -1; ++ } ++ if (length > local->recv_buffer_size) ++ break; ++ ++ int crc = crc32((unsigned char*)recv_buffer, length); ++ if (crc != -1) { ++ free(out_buffer); ++ local->recv_buffer_size = 0; ++ return -1; ++ } ++ int data_size = length - recv_buffer[2] - 6; ++ memmove(buffer, recv_buffer + 2 + recv_buffer[2], data_size); ++ buffer += data_size; ++ memmove(recv_buffer, recv_buffer + length, local->recv_buffer_size -= length); ++ } ++ int len = buffer - out_buffer; ++ if (*capacity < len) { ++ *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); ++ plaindata = *pplaindata; ++ } ++ memmove(plaindata, out_buffer, len); ++ free(out_buffer); ++ return len; ++} ++ ++ ++int auth_sha1_pack_data(char *data, int datalength, char *outdata) { ++ unsigned char rand_len = (xorshift128plus() & 0xF) + 1; ++ int out_size = rand_len + datalength + 6; ++ outdata[0] = out_size >> 8; ++ outdata[1] = out_size; ++ outdata[2] = rand_len; ++ memmove(outdata + rand_len + 2, data, datalength); ++ filladler32((unsigned char *)outdata, out_size); ++ return out_size; ++} ++ ++int auth_sha1_pack_auth_data(auth_simple_global_data *global, server_info *server, char *data, int datalength, char *outdata) { ++ unsigned char rand_len = (xorshift128plus() & 0x7F) + 1; ++ int data_offset = rand_len + 4 + 2; ++ int out_size = data_offset + datalength + 12 + OBFS_HMAC_SHA1_LEN; ++ fillcrc32to((unsigned char *)server->key, server->key_len, (unsigned char *)outdata); ++ outdata[4] = out_size >> 8; ++ outdata[5] = out_size; ++ outdata[6] = rand_len; ++ ++global->connection_id; ++ if (global->connection_id > 0xFF000000) { ++ rand_bytes(global->local_client_id, 8); ++ rand_bytes((uint8_t*)&global->connection_id, 4); ++ global->connection_id &= 0xFFFFFF; ++ } ++ time_t t = time(NULL); ++ memintcopy_lt(outdata + data_offset, t); ++ memmove(outdata + data_offset + 4, global->local_client_id, 4); ++ memintcopy_lt(outdata + data_offset + 8, global->connection_id); ++ memmove(outdata + data_offset + 12, data, datalength); ++ char hash[ONETIMEAUTH_BYTES * 2]; ++ ss_sha1_hmac(hash, outdata, out_size - OBFS_HMAC_SHA1_LEN, server->iv); ++ memcpy(outdata + out_size - OBFS_HMAC_SHA1_LEN, hash, OBFS_HMAC_SHA1_LEN); ++ return out_size; ++} ++ ++int auth_sha1_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { ++ char *plaindata = *pplaindata; ++ auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; ++ char * out_buffer = (char*)malloc(datalength * 2 + 256); ++ char * buffer = out_buffer; ++ char * data = plaindata; ++ int len = datalength; ++ int pack_len; ++ if (len > 0 && local->has_sent_header == 0) { ++ int head_size = get_head_size(plaindata, datalength, 30); ++ if (head_size > datalength) ++ head_size = datalength; ++ pack_len = auth_sha1_pack_auth_data((auth_simple_global_data *)self->server.g_data, &self->server, data, head_size, buffer); ++ buffer += pack_len; ++ data += head_size; ++ len -= head_size; ++ local->has_sent_header = 1; ++ } ++ while ( len > auth_simple_pack_unit_size ) { ++ pack_len = auth_sha1_pack_data(data, auth_simple_pack_unit_size, buffer); ++ buffer += pack_len; ++ data += auth_simple_pack_unit_size; ++ len -= auth_simple_pack_unit_size; ++ } ++ if (len > 0) { ++ pack_len = auth_sha1_pack_data(data, len, buffer); ++ buffer += pack_len; ++ } ++ len = buffer - out_buffer; ++ if (*capacity < len) { ++ *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); ++ plaindata = *pplaindata; ++ } ++ memmove(plaindata, out_buffer, len); ++ free(out_buffer); ++ return len; ++} ++ ++int auth_sha1_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { ++ char *plaindata = *pplaindata; ++ auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; ++ uint8_t * recv_buffer = (uint8_t *)local->recv_buffer; ++ if (local->recv_buffer_size + datalength > 16384) ++ return -1; ++ memmove(recv_buffer + local->recv_buffer_size, plaindata, datalength); ++ local->recv_buffer_size += datalength; ++ ++ char * out_buffer = (char*)malloc(local->recv_buffer_size); ++ char * buffer = out_buffer; ++ while (local->recv_buffer_size > 2) { ++ int length = ((int)recv_buffer[0] << 8) | recv_buffer[1]; ++ if (length >= 8192 || length < 7) { ++ free(out_buffer); ++ local->recv_buffer_size = 0; ++ return -1; ++ } ++ if (length > local->recv_buffer_size) ++ break; ++ ++ if (checkadler32((unsigned char*)recv_buffer, length) == 0) { ++ free(out_buffer); ++ local->recv_buffer_size = 0; ++ return -1; ++ } ++ int pos = recv_buffer[2] + 2; ++ int data_size = length - pos - 4; ++ memmove(buffer, recv_buffer + pos, data_size); ++ buffer += data_size; ++ memmove(recv_buffer, recv_buffer + length, local->recv_buffer_size -= length); ++ } ++ int len = buffer - out_buffer; ++ if (*capacity < len) { ++ *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); ++ plaindata = *pplaindata; ++ } ++ memmove(plaindata, out_buffer, len); ++ free(out_buffer); ++ return len; ++} ++ ++int auth_sha1_v2_pack_data(char *data, int datalength, char *outdata) { ++ unsigned int rand_len = (datalength > 1300 ? 0 : datalength > 400 ? (xorshift128plus() & 0x7F) : (xorshift128plus() & 0x3FF)) + 1; ++ int out_size = rand_len + datalength + 6; ++ outdata[0] = out_size >> 8; ++ outdata[1] = out_size; ++ if (rand_len < 128) ++ { ++ outdata[2] = rand_len; ++ } ++ else ++ { ++ outdata[2] = 0xFF; ++ outdata[3] = rand_len >> 8; ++ outdata[4] = rand_len; ++ } ++ memmove(outdata + rand_len + 2, data, datalength); ++ filladler32((unsigned char *)outdata, out_size); ++ return out_size; ++} ++ ++int auth_sha1_v2_pack_auth_data(auth_simple_global_data *global, server_info *server, char *data, int datalength, char *outdata) { ++ unsigned int rand_len = (datalength > 1300 ? 0 : datalength > 400 ? (xorshift128plus() & 0x7F) : (xorshift128plus() & 0x3FF)) + 1; ++ int data_offset = rand_len + 4 + 2; ++ int out_size = data_offset + datalength + 12 + OBFS_HMAC_SHA1_LEN; ++ const char* salt = "auth_sha1_v2"; ++ int salt_len = strlen(salt); ++ unsigned char *crc_salt = (unsigned char*)malloc(salt_len + server->key_len); ++ memcpy(crc_salt, salt, salt_len); ++ memcpy(crc_salt + salt_len, server->key, server->key_len); ++ fillcrc32to(crc_salt, salt_len + server->key_len, (unsigned char *)outdata); ++ free(crc_salt); ++ outdata[4] = out_size >> 8; ++ outdata[5] = out_size; ++ if (rand_len < 128) ++ { ++ outdata[6] = rand_len; ++ } ++ else ++ { ++ outdata[6] = 0xFF; ++ outdata[7] = rand_len >> 8; ++ outdata[8] = rand_len; ++ } ++ ++global->connection_id; ++ if (global->connection_id > 0xFF000000) { ++ rand_bytes(global->local_client_id, 8); ++ rand_bytes((uint8_t*)&global->connection_id, 4); ++ global->connection_id &= 0xFFFFFF; ++ } ++ memmove(outdata + data_offset, global->local_client_id, 8); ++ memintcopy_lt(outdata + data_offset + 8, global->connection_id); ++ memmove(outdata + data_offset + 12, data, datalength); ++ char hash[ONETIMEAUTH_BYTES * 2]; ++ ss_sha1_hmac(hash, outdata, out_size - OBFS_HMAC_SHA1_LEN, server->iv); ++ memcpy(outdata + out_size - OBFS_HMAC_SHA1_LEN, hash, OBFS_HMAC_SHA1_LEN); ++ return out_size; ++} ++ ++int auth_sha1_v2_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { ++ char *plaindata = *pplaindata; ++ auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; ++ char * out_buffer = (char*)malloc(datalength * 2 + 4096); ++ char * buffer = out_buffer; ++ char * data = plaindata; ++ int len = datalength; ++ int pack_len; ++ if (len > 0 && local->has_sent_header == 0) { ++ int head_size = get_head_size(plaindata, datalength, 30); ++ if (head_size > datalength) ++ head_size = datalength; ++ pack_len = auth_sha1_v2_pack_auth_data((auth_simple_global_data *)self->server.g_data, &self->server, data, head_size, buffer); ++ buffer += pack_len; ++ data += head_size; ++ len -= head_size; ++ local->has_sent_header = 1; ++ } ++ while ( len > auth_simple_pack_unit_size ) { ++ pack_len = auth_sha1_v2_pack_data(data, auth_simple_pack_unit_size, buffer); ++ buffer += pack_len; ++ data += auth_simple_pack_unit_size; ++ len -= auth_simple_pack_unit_size; ++ } ++ if (len > 0) { ++ pack_len = auth_sha1_v2_pack_data(data, len, buffer); ++ buffer += pack_len; ++ } ++ len = buffer - out_buffer; ++ if (*capacity < len) { ++ *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); ++ plaindata = *pplaindata; ++ } ++ memmove(plaindata, out_buffer, len); ++ free(out_buffer); ++ return len; ++} ++ ++int auth_sha1_v2_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { ++ char *plaindata = *pplaindata; ++ auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; ++ uint8_t * recv_buffer = (uint8_t *)local->recv_buffer; ++ if (local->recv_buffer_size + datalength > 16384) ++ return -1; ++ memmove(recv_buffer + local->recv_buffer_size, plaindata, datalength); ++ local->recv_buffer_size += datalength; ++ ++ char * out_buffer = (char*)malloc(local->recv_buffer_size); ++ char * buffer = out_buffer; ++ char error = 0; ++ while (local->recv_buffer_size > 2) { ++ int length = ((int)recv_buffer[0] << 8) | recv_buffer[1]; ++ if (length >= 8192 || length < 7) { ++ local->recv_buffer_size = 0; ++ error = 1; ++ break; ++ } ++ if (length > local->recv_buffer_size) ++ break; ++ ++ if (checkadler32((unsigned char*)recv_buffer, length) == 0) { ++ local->recv_buffer_size = 0; ++ error = 1; ++ break; ++ } ++ int pos = recv_buffer[2]; ++ if (pos < 255) ++ { ++ pos += 2; ++ } ++ else ++ { ++ pos = ((recv_buffer[3] << 8) | recv_buffer[4]) + 2; ++ } ++ int data_size = length - pos - 4; ++ memmove(buffer, recv_buffer + pos, data_size); ++ buffer += data_size; ++ memmove(recv_buffer, recv_buffer + length, local->recv_buffer_size -= length); ++ } ++ int len; ++ if (error == 0) { ++ len = buffer - out_buffer; ++ if (*capacity < len) { ++ *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); ++ plaindata = *pplaindata; ++ } ++ memmove(plaindata, out_buffer, len); ++ } else { ++ len = -1; ++ } ++ free(out_buffer); ++ return len; ++} ++ ++int auth_sha1_v4_pack_data(char *data, int datalength, char *outdata) { ++ unsigned int rand_len = (datalength > 1300 ? 0 : datalength > 400 ? (xorshift128plus() & 0x7F) : (xorshift128plus() & 0x3FF)) + 1; ++ int out_size = rand_len + datalength + 8; ++ outdata[0] = out_size >> 8; ++ outdata[1] = out_size; ++ uint32_t crc_val = crc32((unsigned char*)outdata, 2); ++ outdata[2] = crc_val; ++ outdata[3] = crc_val >> 8; ++ if (rand_len < 128) ++ { ++ outdata[4] = rand_len; ++ } ++ else ++ { ++ outdata[4] = 0xFF; ++ outdata[5] = rand_len >> 8; ++ outdata[6] = rand_len; ++ } ++ memmove(outdata + rand_len + 4, data, datalength); ++ filladler32((unsigned char *)outdata, out_size); ++ return out_size; ++} ++ ++int auth_sha1_v4_pack_auth_data(auth_simple_global_data *global, server_info *server, char *data, int datalength, char *outdata) { ++ unsigned int rand_len = (datalength > 1300 ? 0 : datalength > 400 ? (xorshift128plus() & 0x7F) : (xorshift128plus() & 0x3FF)) + 1; ++ int data_offset = rand_len + 4 + 2; ++ int out_size = data_offset + datalength + 12 + OBFS_HMAC_SHA1_LEN; ++ const char* salt = "auth_sha1_v4"; ++ int salt_len = strlen(salt); ++ unsigned char *crc_salt = (unsigned char*)malloc(salt_len + server->key_len + 2); ++ crc_salt[0] = outdata[0] = out_size >> 8; ++ crc_salt[1] = outdata[1] = out_size; ++ ++ memcpy(crc_salt + 2, salt, salt_len); ++ memcpy(crc_salt + salt_len + 2, server->key, server->key_len); ++ fillcrc32to(crc_salt, salt_len + server->key_len + 2, (unsigned char *)outdata + 2); ++ free(crc_salt); ++ if (rand_len < 128) ++ { ++ outdata[6] = rand_len; ++ } ++ else ++ { ++ outdata[6] = 0xFF; ++ outdata[7] = rand_len >> 8; ++ outdata[8] = rand_len; ++ } ++ ++global->connection_id; ++ if (global->connection_id > 0xFF000000) { ++ rand_bytes(global->local_client_id, 8); ++ rand_bytes((uint8_t*)&global->connection_id, 4); ++ global->connection_id &= 0xFFFFFF; ++ } ++ time_t t = time(NULL); ++ memintcopy_lt(outdata + data_offset, t); ++ memmove(outdata + data_offset + 4, global->local_client_id, 4); ++ memintcopy_lt(outdata + data_offset + 8, global->connection_id); ++ memmove(outdata + data_offset + 12, data, datalength); ++ char hash[ONETIMEAUTH_BYTES * 2]; ++ ss_sha1_hmac(hash, outdata, out_size - OBFS_HMAC_SHA1_LEN, server->iv); ++ memcpy(outdata + out_size - OBFS_HMAC_SHA1_LEN, hash, OBFS_HMAC_SHA1_LEN); ++ return out_size; ++} ++ ++int auth_sha1_v4_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { ++ char *plaindata = *pplaindata; ++ auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; ++ char * out_buffer = (char*)malloc(datalength * 2 + 4096); ++ char * buffer = out_buffer; ++ char * data = plaindata; ++ int len = datalength; ++ int pack_len; ++ if (len > 0 && local->has_sent_header == 0) { ++ int head_size = get_head_size(plaindata, datalength, 30); ++ if (head_size > datalength) ++ head_size = datalength; ++ pack_len = auth_sha1_v4_pack_auth_data((auth_simple_global_data *)self->server.g_data, &self->server, data, head_size, buffer); ++ buffer += pack_len; ++ data += head_size; ++ len -= head_size; ++ local->has_sent_header = 1; ++ } ++ while ( len > auth_simple_pack_unit_size ) { ++ pack_len = auth_sha1_v4_pack_data(data, auth_simple_pack_unit_size, buffer); ++ buffer += pack_len; ++ data += auth_simple_pack_unit_size; ++ len -= auth_simple_pack_unit_size; ++ } ++ if (len > 0) { ++ pack_len = auth_sha1_v4_pack_data(data, len, buffer); ++ buffer += pack_len; ++ } ++ len = buffer - out_buffer; ++ if (*capacity < len) { ++ *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); ++ plaindata = *pplaindata; ++ } ++ memmove(plaindata, out_buffer, len); ++ free(out_buffer); ++ return len; ++} ++ ++int auth_sha1_v4_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { ++ char *plaindata = *pplaindata; ++ auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; ++ uint8_t * recv_buffer = (uint8_t *)local->recv_buffer; ++ if (local->recv_buffer_size + datalength > 16384) ++ return -1; ++ memmove(recv_buffer + local->recv_buffer_size, plaindata, datalength); ++ local->recv_buffer_size += datalength; ++ ++ char * out_buffer = (char*)malloc(local->recv_buffer_size); ++ char * buffer = out_buffer; ++ char error = 0; ++ while (local->recv_buffer_size > 4) { ++ uint32_t crc_val = crc32((unsigned char*)recv_buffer, 2); ++ if ((((uint32_t)recv_buffer[3] << 8) | recv_buffer[2]) != (crc_val & 0xffff)) { ++ local->recv_buffer_size = 0; ++ error = 1; ++ break; ++ } ++ int length = ((int)recv_buffer[0] << 8) | recv_buffer[1]; ++ if (length >= 8192 || length < 7) { ++ local->recv_buffer_size = 0; ++ error = 1; ++ break; ++ } ++ if (length > local->recv_buffer_size) ++ break; ++ ++ if (checkadler32((unsigned char*)recv_buffer, length) == 0) { ++ local->recv_buffer_size = 0; ++ error = 1; ++ break; ++ } ++ int pos = recv_buffer[4]; ++ if (pos < 255) ++ { ++ pos += 4; ++ } ++ else ++ { ++ pos = (((int)recv_buffer[5] << 8) | recv_buffer[6]) + 4; ++ } ++ int data_size = length - pos - 4; ++ memmove(buffer, recv_buffer + pos, data_size); ++ buffer += data_size; ++ memmove(recv_buffer, recv_buffer + length, local->recv_buffer_size -= length); ++ } ++ int len; ++ if (error == 0) { ++ len = buffer - out_buffer; ++ if (*capacity < len) { ++ *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); ++ plaindata = *pplaindata; ++ } ++ memmove(plaindata, out_buffer, len); ++ } else { ++ len = -1; ++ } ++ free(out_buffer); ++ return len; ++} ++ ++ ++int auth_aes128_sha1_pack_data(char *data, int datalength, char *outdata, auth_simple_local_data *local, server_info *server) { ++ unsigned int rand_len = (datalength > 1200 ? 0 : local->pack_id > 4 ? (xorshift128plus() & 0x20) : datalength > 900 ? (xorshift128plus() & 0x80) : (xorshift128plus() & 0x200)) + 1; ++ int out_size = rand_len + datalength + 8; ++ memcpy(outdata + rand_len + 4, data, datalength); ++ outdata[0] = out_size; ++ outdata[1] = out_size >> 8; ++ uint8_t key_len = local->user_key_len + 4; ++ uint8_t *key = (uint8_t*)malloc(key_len); ++ memcpy(key, local->user_key, local->user_key_len); ++ memintcopy_lt(key + key_len - 4, local->pack_id); ++ ++ { ++ uint8_t rnd_data[rand_len]; ++ rand_bytes(rnd_data, rand_len); ++ memcpy(outdata + 4, rnd_data, rand_len); ++ } ++ ++ { ++ char hash[20]; ++ local->hmac(hash, outdata, 2, key, key_len); ++ memcpy(outdata + 2, hash, 2); ++ } ++ ++ if (rand_len < 128) ++ { ++ outdata[4] = rand_len; ++ } ++ else ++ { ++ outdata[4] = 0xFF; ++ outdata[5] = rand_len; ++ outdata[6] = rand_len >> 8; ++ } ++ ++local->pack_id; ++ ++ { ++ char hash[20]; ++ local->hmac(hash, outdata, out_size - 4, key, key_len); ++ memcpy(outdata + out_size - 4, hash, 4); ++ } ++ free(key); ++ ++ return out_size; ++} ++ ++int auth_aes128_sha1_pack_auth_data(auth_simple_global_data *global, server_info *server, auth_simple_local_data *local, char *data, int datalength, char *outdata) { ++ unsigned int rand_len = (datalength > 400 ? (xorshift128plus() & 0x200) : (xorshift128plus() & 0x400)); ++ int data_offset = rand_len + 16 + 4 + 4 + 7; ++ int out_size = data_offset + datalength + 4; ++ ++ char encrypt[24]; ++ char encrypt_data[16]; ++ ++ uint8_t *key = (uint8_t*)malloc(server->iv_len + server->key_len); ++ uint8_t key_len = server->iv_len + server->key_len; ++ memcpy(key, server->iv, server->iv_len); ++ memcpy(key + server->iv_len, server->key, server->key_len); ++ ++ { ++ uint8_t rnd_data[rand_len]; ++ rand_bytes(rnd_data, rand_len); ++ memcpy(outdata + data_offset - rand_len, rnd_data, rand_len); ++ } ++ ++ ++global->connection_id; ++ if (global->connection_id > 0xFF000000) { ++ rand_bytes(global->local_client_id, 8); ++ rand_bytes((uint8_t*)&global->connection_id, 4); ++ global->connection_id &= 0xFFFFFF; ++ } ++ time_t t = time(NULL); ++ memintcopy_lt(encrypt, t); ++ memcpy(encrypt + 4, global->local_client_id, 4); ++ memintcopy_lt(encrypt + 8, global->connection_id); ++ encrypt[12] = out_size; ++ encrypt[13] = out_size >> 8; ++ encrypt[14] = rand_len; ++ encrypt[15] = rand_len >> 8; ++ ++ { ++ ++ if (local->user_key == NULL) { ++ if(server->param != NULL && server->param[0] != 0) { ++ char *param = server->param; ++ char *delim = strchr(param, ':'); ++ if(delim != NULL) { ++ char uid_str[16] = {}; ++ strncpy(uid_str, param, delim - param); ++ char key_str[128]; ++ strcpy(key_str, delim + 1); ++ long uid_long = strtol(uid_str, NULL, 10); ++ memintcopy_lt(local->uid, uid_long); ++ ++ char hash[21] = {0}; ++ local->hash(hash, key_str, strlen(key_str)); ++ ++ local->user_key_len = local->hash_len; ++ local->user_key = (uint8_t*)malloc(local->user_key_len); ++ memcpy(local->user_key, hash, local->hash_len); ++ } ++ } ++ if (local->user_key == NULL) { ++ rand_bytes((uint8_t *)local->uid, 4); ++ ++ local->user_key_len = server->key_len; ++ local->user_key = (uint8_t*)malloc(local->user_key_len); ++ memcpy(local->user_key, server->key, local->user_key_len); ++ } ++ } ++ ++ char encrypt_key_base64[256] = {0}; ++ unsigned char encrypt_key[local->user_key_len]; ++ memcpy(encrypt_key, local->user_key, local->user_key_len); ++ base64_encode(encrypt_key, local->user_key_len, encrypt_key_base64); ++ ++ int base64_len; ++ base64_len = (local->user_key_len + 2) / 3 * 4; ++ memcpy(encrypt_key_base64 + base64_len, local->salt, strlen(local->salt)); ++ ++ char enc_key[16]; ++ int enc_key_len = base64_len + strlen(local->salt); ++ bytes_to_key_with_size(encrypt_key_base64, enc_key_len, (uint8_t*)enc_key, 16); ++ ss_aes_128_cbc(encrypt, encrypt_data, enc_key); ++ memcpy(encrypt + 4, encrypt_data, 16); ++ memcpy(encrypt, local->uid, 4); ++ } ++ ++ { ++ char hash[20]; ++ local->hmac(hash, encrypt, 20, key, key_len); ++ memcpy(encrypt + 20, hash, 4); ++ } ++ ++ { ++ uint8_t rnd[1]; ++ rand_bytes(rnd, 1); ++ memcpy(outdata, rnd, 1); ++ char hash[20]; ++ local->hmac(hash, (char *)rnd, 1, key, key_len); ++ memcpy(outdata + 1, hash, 6); ++ } ++ ++ memcpy(outdata + 7, encrypt, 24); ++ memcpy(outdata + data_offset, data, datalength); ++ ++ { ++ char hash[20]; ++ local->hmac(hash, outdata, out_size - 4, local->user_key, local->user_key_len); ++ memmove(outdata + out_size - 4, hash, 4); ++ } ++ free(key); ++ ++ return out_size; ++} ++ ++int auth_aes128_sha1_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { ++ char *plaindata = *pplaindata; ++ auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; ++ char * out_buffer = (char*)malloc(datalength * 2 + 4096); ++ char * buffer = out_buffer; ++ char * data = plaindata; ++ int len = datalength; ++ int pack_len; ++ if (len > 0 && local->has_sent_header == 0) { ++ int head_size = 1200; ++ if (head_size > datalength) ++ head_size = datalength; ++ pack_len = auth_aes128_sha1_pack_auth_data((auth_simple_global_data *)self->server.g_data, &self->server, local, data, head_size, buffer); ++ buffer += pack_len; ++ data += head_size; ++ len -= head_size; ++ local->has_sent_header = 1; ++ } ++ while ( len > auth_simple_pack_unit_size ) { ++ pack_len = auth_aes128_sha1_pack_data(data, auth_simple_pack_unit_size, buffer, local, &self->server); ++ buffer += pack_len; ++ data += auth_simple_pack_unit_size; ++ len -= auth_simple_pack_unit_size; ++ } ++ if (len > 0) { ++ pack_len = auth_aes128_sha1_pack_data(data, len, buffer, local, &self->server); ++ buffer += pack_len; ++ } ++ len = buffer - out_buffer; ++ if (*capacity < len) { ++ *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); ++ plaindata = *pplaindata; ++ } ++ memmove(plaindata, out_buffer, len); ++ free(out_buffer); ++ return len; ++} ++ ++int auth_aes128_sha1_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { ++ char *plaindata = *pplaindata; ++ auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; ++ //server_info *server = (server_info*)&self->server; ++ uint8_t * recv_buffer = (uint8_t *)local->recv_buffer; ++ if (local->recv_buffer_size + datalength > 16384) ++ return -1; ++ memmove(recv_buffer + local->recv_buffer_size, plaindata, datalength); ++ local->recv_buffer_size += datalength; ++ ++ int key_len = local->user_key_len + 4; ++ uint8_t *key = (uint8_t*)malloc(key_len); ++ memcpy(key, local->user_key, local->user_key_len); ++ ++ char * out_buffer = (char*)malloc(local->recv_buffer_size); ++ char * buffer = out_buffer; ++ char error = 0; ++ while (local->recv_buffer_size > 4) { ++ memintcopy_lt(key + key_len - 4, local->recv_id); ++ ++ { ++ char hash[20]; ++ local->hmac(hash, (char*)recv_buffer, 2, key, key_len); ++ ++ if (memcmp(hash, recv_buffer + 2, 2)) { ++ local->recv_buffer_size = 0; ++ error = 1; ++ break; ++ } ++ } ++ ++ int length = ((int)recv_buffer[1] << 8) + recv_buffer[0]; ++ if (length >= 8192 || length < 8) { ++ local->recv_buffer_size = 0; ++ error = 1; ++ break; ++ } ++ if (length > local->recv_buffer_size) ++ break; ++ ++ { ++ char hash[20]; ++ local->hmac(hash, (char *)recv_buffer, length - 4, key, key_len); ++ if (memcmp(hash, recv_buffer + length - 4, 4)) ++ { ++ local->recv_buffer_size = 0; ++ error = 1; ++ break; ++ } ++ } ++ ++ ++local->recv_id; ++ int pos = recv_buffer[4]; ++ if (pos < 255) ++ { ++ pos += 4; ++ } ++ else ++ { ++ pos = (((int)recv_buffer[6] << 8) | recv_buffer[5]) + 4; ++ } ++ int data_size = length - pos - 4; ++ memmove(buffer, recv_buffer + pos, data_size); ++ buffer += data_size; ++ memmove(recv_buffer, recv_buffer + length, local->recv_buffer_size -= length); ++ } ++ int len; ++ if (error == 0) { ++ len = buffer - out_buffer; ++ if (*capacity < len) { ++ *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); ++ plaindata = *pplaindata; ++ } ++ memmove(plaindata, out_buffer, len); ++ } else { ++ len = -1; ++ } ++ free(out_buffer); ++ free(key); ++ return len; ++} ++ ++int auth_aes128_sha1_client_udp_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { ++ char *plaindata = *pplaindata; ++ auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; ++ char * out_buffer = (char*)malloc(datalength + 8); ++ ++ if (local->user_key == NULL) { ++ if(self->server.param != NULL && self->server.param[0] != 0) { ++ char *param = self->server.param; ++ char *delim = strchr(param, ':'); ++ if(delim != NULL) { ++ char uid_str[16] = {}; ++ strncpy(uid_str, param, delim - param); ++ char key_str[128]; ++ strcpy(key_str, delim + 1); ++ long uid_long = strtol(uid_str, NULL, 10); ++ memintcopy_lt(local->uid, uid_long); ++ ++ char hash[21] = {0}; ++ local->hash(hash, key_str, strlen(key_str)); ++ ++ local->user_key_len = local->hash_len; ++ local->user_key = (uint8_t*)malloc(local->user_key_len); ++ memcpy(local->user_key, hash, local->hash_len); ++ } ++ } ++ if (local->user_key == NULL) { ++ rand_bytes((uint8_t *)local->uid, 4); ++ ++ local->user_key_len = self->server.key_len; ++ local->user_key = (uint8_t*)malloc(local->user_key_len); ++ memcpy(local->user_key, self->server.key, local->user_key_len); ++ } ++ } ++ ++ int outlength = datalength + 8; ++ memmove(out_buffer, plaindata, datalength); ++ memmove(out_buffer + datalength, local->uid, 4); ++ ++ { ++ char hash[20]; ++ local->hmac(hash, out_buffer, outlength - 4, local->user_key, local->user_key_len); ++ memmove(out_buffer + outlength - 4, hash, 4); ++ } ++ ++ if (*capacity < outlength) { ++ *pplaindata = (char*)realloc(*pplaindata, *capacity = outlength * 2); ++ plaindata = *pplaindata; ++ } ++ memmove(plaindata, out_buffer, outlength); ++ ++ free(out_buffer); ++ return outlength; ++} ++ ++int auth_aes128_sha1_client_udp_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { ++ if (datalength <= 4) ++ return 0; ++ ++ char *plaindata = *pplaindata; ++ auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; ++ ++ char hash[20]; ++ local->hmac(hash, plaindata, datalength - 4, self->server.key, self->server.key_len); ++ ++ if (memcmp(hash, plaindata + datalength - 4, 4)) ++ { ++ return 0; ++ } ++ ++ return datalength - 4; ++} +diff --git a/server/auth.h b/server/auth.h +new file mode 100644 +index 0000000..f7730df +--- /dev/null ++++ b/server/auth.h +@@ -0,0 +1,30 @@ ++/* ++ * auth.h - Define shadowsocksR server's buffers and callbacks ++ * ++ * Copyright (C) 2015 - 2016, Break Wa11 ++ */ ++ ++#ifndef _AUTH_H ++#define _AUTH_H ++ ++void * auth_simple_init_data(); ++obfs * auth_simple_new_obfs(); ++void auth_simple_dispose(obfs *self); ++ ++int auth_simple_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); ++int auth_simple_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); ++ ++ ++int auth_sha1_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); ++int auth_sha1_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); ++ ++int auth_sha1_v2_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); ++int auth_sha1_v2_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); ++ ++int auth_sha1_v4_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); ++int auth_sha1_v4_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); ++ ++int auth_aes128_sha1_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); ++int auth_aes128_sha1_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); ++ ++#endif // _AUTH_H +diff --git a/server/base64.c b/server/base64.c +new file mode 100644 +index 0000000..7cf9552 +--- /dev/null ++++ b/server/base64.c +@@ -0,0 +1,119 @@ ++#include "base64.h" ++ ++/* BASE 64 encode table */ ++static const char base64en[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; ++ ++#define BASE64_PAD '=' ++ ++#define BASE64DE_FIRST '+' ++#define BASE64DE_LAST 'z' ++ ++/* ASCII order for BASE 64 decode, -1 in unused character */ ++static const signed char base64de[] = { ++ -1, -1, -1, -1, -1, -1, -1, -1, ++ -1, -1, -1, -1, -1, -1, -1, -1, ++ -1, -1, -1, -1, -1, -1, -1, -1, ++ -1, -1, -1, -1, -1, -1, -1, -1, ++ -1, -1, -1, -1, -1, -1, -1, -1, ++ /* '+', ',', '-', '.', '/', */ ++ -1, -1, -1, 62, -1, -1, -1, 63, ++ /* '0', '1', '2', '3', '4', '5', '6', '7', */ ++ 52, 53, 54, 55, 56, 57, 58, 59, ++ /* '8', '9', ':', ';', '<', '=', '>', '?', */ ++ 60, 61, -1, -1, -1, -1, -1, -1, ++ /* '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', */ ++ -1, 0, 1, 2, 3, 4, 5, 6, ++ /* 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', */ ++ 7, 8, 9, 10, 11, 12, 13, 14, ++ /* 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', */ ++ 15, 16, 17, 18, 19, 20, 21, 22, ++ /* 'X', 'Y', 'Z', '[', '\', ']', '^', '_', */ ++ 23, 24, 25, -1, -1, -1, -1, -1, ++ /* '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', */ ++ -1, 26, 27, 28, 29, 30, 31, 32, ++ /* 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', */ ++ 33, 34, 35, 36, 37, 38, 39, 40, ++ /* 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', */ ++ 41, 42, 43, 44, 45, 46, 47, 48, ++ /* 'x', 'y', 'z', */ ++ 49, 50, 51, ++}; ++ ++int ++base64_encode(const unsigned char *in, unsigned int inlen, char *out) ++{ ++ unsigned int i, j; ++ ++ for (i = j = 0; i < inlen; i++) { ++ int s = i % 3; /* from 6/gcd(6, 8) */ ++ ++ switch (s) { ++ case 0: ++ out[j++] = base64en[(in[i] >> 2) & 0x3F]; ++ continue; ++ case 1: ++ out[j++] = base64en[((in[i-1] & 0x3) << 4) + ((in[i] >> 4) & 0xF)]; ++ continue; ++ case 2: ++ out[j++] = base64en[((in[i-1] & 0xF) << 2) + ((in[i] >> 6) & 0x3)]; ++ out[j++] = base64en[in[i] & 0x3F]; ++ } ++ } ++ ++ /* move back */ ++ i -= 1; ++ ++ /* check the last and add padding */ ++ if ((i % 3) == 0) { ++ out[j++] = base64en[(in[i] & 0x3) << 4]; ++ out[j++] = BASE64_PAD; ++ out[j++] = BASE64_PAD; ++ } else if ((i % 3) == 1) { ++ out[j++] = base64en[(in[i] & 0xF) << 2]; ++ out[j++] = BASE64_PAD; ++ } ++ ++ return BASE64_OK; ++} ++ ++int ++base64_decode(const char *in, unsigned int inlen, unsigned char *out) ++{ ++ unsigned int i, j; ++ ++ for (i = j = 0; i < inlen; i++) { ++ int c; ++ int s = i % 4; /* from 8/gcd(6, 8) */ ++ ++ if (in[i] == '=') ++ return BASE64_OK; ++ ++ if (in[i] < BASE64DE_FIRST || in[i] > BASE64DE_LAST || ++ (c = base64de[(int)in[i]]) == -1) ++ return BASE64_INVALID; ++ ++ switch (s) { ++ case 0: ++ out[j] = ((unsigned int)c << 2) & 0xFF; ++ continue; ++ case 1: ++ out[j++] += ((unsigned int)c >> 4) & 0x3; ++ ++ /* if not last char with padding */ ++ if (i < (inlen - 3) || in[inlen - 2] != '=') ++ out[j] = ((unsigned int)c & 0xF) << 4; ++ continue; ++ case 2: ++ out[j++] += ((unsigned int)c >> 2) & 0xF; ++ ++ /* if not last char with padding */ ++ if (i < (inlen - 2) || in[inlen - 1] != '=') ++ out[j] = ((unsigned int)c & 0x3) << 6; ++ continue; ++ case 3: ++ out[j++] += (unsigned char)c; ++ } ++ } ++ ++ return BASE64_OK; ++} +diff --git a/server/base64.h b/server/base64.h +new file mode 100644 +index 0000000..6432ba3 +--- /dev/null ++++ b/server/base64.h +@@ -0,0 +1,16 @@ ++#ifndef __BASE64_H__ ++#define __BASE64_H__ ++ ++enum {BASE64_OK = 0, BASE64_INVALID}; ++ ++#define BASE64_ENCODE_OUT_SIZE(s) (((s) + 2) / 3 * 4) ++#define BASE64_DECODE_OUT_SIZE(s) (((s)) / 4 * 3) ++ ++int ++base64_encode(const unsigned char *in, unsigned int inlen, char *out); ++ ++int ++base64_decode(const char *in, unsigned int inlen, unsigned char *out); ++ ++ ++#endif /* __BASE64_H__ */ +diff --git a/server/cache.c b/server/cache.c +new file mode 100644 +index 0000000..c1a2995 +--- /dev/null ++++ b/server/cache.c +@@ -0,0 +1,308 @@ ++/* ++ * cache.c - Manage the connection cache for UDPRELAY ++ * ++ * Copyright (C) 2013 - 2016, Max Lv ++ * ++ * This file is part of the shadowsocks-libev. ++ * ++ * shadowsocks-libev 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 3 of the License, or ++ * (at your option) any later version. ++ * ++ * shadowsocks-libev 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 shadowsocks-libev; see the file COPYING. If not, see ++ * . ++ */ ++ ++/* ++ * Original Author: Oliver Lorenz (ol), olli@olorenz.org, https://olorenz.org ++ * License: This is licensed under the same terms as uthash itself ++ */ ++ ++#include ++#include ++ ++#include "cache.h" ++#include "utils.h" ++ ++#ifdef __MINGW32__ ++#include "win32.h" ++#endif ++ ++/** Creates a new cache object ++ * ++ * @param dst ++ * Where the newly allocated cache object will be stored in ++ * ++ * @param capacity ++ * The maximum number of elements this cache object can hold ++ * ++ * @return EINVAL if dst is NULL, ENOMEM if malloc fails, 0 otherwise ++ */ ++int ++cache_create(struct cache **dst, const size_t capacity, ++ void (*free_cb)(void *key, void *element)) ++{ ++ struct cache *new = NULL; ++ ++ if (!dst) { ++ return EINVAL; ++ } ++ ++ if ((new = malloc(sizeof(*new))) == NULL) { ++ return ENOMEM; ++ } ++ ++ new->max_entries = capacity; ++ new->entries = NULL; ++ new->free_cb = free_cb; ++ *dst = new; ++ return 0; ++} ++ ++/** Frees an allocated cache object ++ * ++ * @param cache ++ * The cache object to free ++ * ++ * @param keep_data ++ * Whether to free contained data or just delete references to it ++ * ++ * @return EINVAL if cache is NULL, 0 otherwise ++ */ ++int ++cache_delete(struct cache *cache, int keep_data) ++{ ++ struct cache_entry *entry, *tmp; ++ ++ if (!cache) { ++ return EINVAL; ++ } ++ ++ if (keep_data) { ++ HASH_CLEAR(hh, cache->entries); ++ } else { ++ HASH_ITER(hh, cache->entries, entry, tmp){ ++ HASH_DEL(cache->entries, entry); ++ if (entry->data != NULL) { ++ if (cache->free_cb) { ++ cache->free_cb(entry->key, entry->data); ++ } else { ++ ss_free(entry->data); ++ } ++ } ++ ss_free(entry->key); ++ ss_free(entry); ++ } ++ } ++ ++ ss_free(cache); ++ return 0; ++} ++ ++/** Clear old cache object ++ * ++ * @param cache ++ * The cache object to clear ++ * ++ * @param age ++ * Clear only objects older than the age (sec) ++ * ++ * @return EINVAL if cache is NULL, 0 otherwise ++ */ ++int ++cache_clear(struct cache *cache, ev_tstamp age) ++{ ++ struct cache_entry *entry, *tmp; ++ ++ if (!cache) { ++ return EINVAL; ++ } ++ ++ ev_tstamp now = ev_time(); ++ ++ HASH_ITER(hh, cache->entries, entry, tmp){ ++ if (now - entry->ts > age) { ++ HASH_DEL(cache->entries, entry); ++ if (entry->data != NULL) { ++ if (cache->free_cb) { ++ cache->free_cb(entry->key, entry->data); ++ } else { ++ ss_free(entry->data); ++ } ++ } ++ ss_free(entry->key); ++ ss_free(entry); ++ } ++ } ++ ++ return 0; ++} ++ ++/** Removes a cache entry ++ * ++ * @param cache ++ * The cache object ++ * ++ * @param key ++ * The key of the entry to remove ++ * ++ * @param key_len ++ * The length of key ++ * ++ * @return EINVAL if cache is NULL, 0 otherwise ++ */ ++int ++cache_remove(struct cache *cache, char *key, size_t key_len) ++{ ++ struct cache_entry *tmp; ++ ++ if (!cache || !key) { ++ return EINVAL; ++ } ++ ++ HASH_FIND(hh, cache->entries, key, key_len, tmp); ++ ++ if (tmp) { ++ HASH_DEL(cache->entries, tmp); ++ if (tmp->data != NULL) { ++ if (cache->free_cb) { ++ cache->free_cb(tmp->key, tmp->data); ++ } else { ++ ss_free(tmp->data); ++ } ++ } ++ ss_free(tmp->key); ++ ss_free(tmp); ++ } ++ ++ return 0; ++} ++ ++/** Checks if a given key is in the cache ++ * ++ * @param cache ++ * The cache object ++ * ++ * @param key ++ * The key to look-up ++ * ++ * @param key_len ++ * The length of key ++ * ++ * @param result ++ * Where to store the result if key is found. ++ * ++ * A warning: Even though result is just a pointer, ++ * you have to call this function with a **ptr, ++ * otherwise this will blow up in your face. ++ * ++ * @return EINVAL if cache is NULL, 0 otherwise ++ */ ++int ++cache_lookup(struct cache *cache, char *key, size_t key_len, void *result) ++{ ++ struct cache_entry *tmp = NULL; ++ char **dirty_hack = result; ++ ++ if (!cache || !key || !result) { ++ return EINVAL; ++ } ++ ++ HASH_FIND(hh, cache->entries, key, key_len, tmp); ++ if (tmp) { ++ HASH_DELETE(hh, cache->entries, tmp); ++ tmp->ts = ev_time(); ++ HASH_ADD_KEYPTR(hh, cache->entries, tmp->key, key_len, tmp); ++ *dirty_hack = tmp->data; ++ } else { ++ *dirty_hack = result = NULL; ++ } ++ ++ return 0; ++} ++ ++int ++cache_key_exist(struct cache *cache, char *key, size_t key_len) ++{ ++ struct cache_entry *tmp = NULL; ++ ++ if (!cache || !key) { ++ return 0; ++ } ++ ++ HASH_FIND(hh, cache->entries, key, key_len, tmp); ++ if (tmp) { ++ HASH_DELETE(hh, cache->entries, tmp); ++ tmp->ts = ev_time(); ++ HASH_ADD_KEYPTR(hh, cache->entries, tmp->key, key_len, tmp); ++ return 1; ++ } else { ++ return 0; ++ } ++ ++ return 0; ++} ++ ++/** Inserts a given pair into the cache ++ * ++ * @param cache ++ * The cache object ++ * ++ * @param key ++ * The key that identifies ++ * ++ * @param key_len ++ * The length of key ++ * ++ * @param data ++ * Data associated with ++ * ++ * @return EINVAL if cache is NULL, ENOMEM if malloc fails, 0 otherwise ++ */ ++int ++cache_insert(struct cache *cache, char *key, size_t key_len, void *data) ++{ ++ struct cache_entry *entry = NULL; ++ struct cache_entry *tmp_entry = NULL; ++ ++ if (!cache) { ++ return EINVAL; ++ } ++ ++ if ((entry = malloc(sizeof(*entry))) == NULL) { ++ return ENOMEM; ++ } ++ ++ entry->key = ss_malloc(key_len + 1); ++ memcpy(entry->key, key, key_len); ++ entry->key[key_len] = 0; ++ ++ entry->data = data; ++ entry->ts = ev_time(); ++ HASH_ADD_KEYPTR(hh, cache->entries, entry->key, key_len, entry); ++ ++ if (HASH_COUNT(cache->entries) >= cache->max_entries) { ++ HASH_ITER(hh, cache->entries, entry, tmp_entry){ ++ HASH_DELETE(hh, cache->entries, entry); ++ if (entry->data != NULL) { ++ if (cache->free_cb) { ++ cache->free_cb(entry->key, entry->data); ++ } else { ++ ss_free(entry->data); ++ } ++ } ++ ss_free(entry->key); ++ ss_free(entry); ++ break; ++ } ++ } ++ ++ return 0; ++} +diff --git a/server/cache.h b/server/cache.h +new file mode 100644 +index 0000000..0ec98f5 +--- /dev/null ++++ b/server/cache.h +@@ -0,0 +1,62 @@ ++/* ++ * cache.h - Define the cache manager interface ++ * ++ * Copyright (C) 2013 - 2016, Max Lv ++ * ++ * This file is part of the shadowsocks-libev. ++ * ++ * shadowsocks-libev 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 3 of the License, or ++ * (at your option) any later version. ++ * ++ * shadowsocks-libev 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 shadowsocks-libev; see the file COPYING. If not, see ++ * . ++ */ ++ ++/* ++ * Original Author: Oliver Lorenz (ol), olli@olorenz.org, https://olorenz.org ++ * License: This is licensed under the same terms as uthash itself ++ */ ++ ++#ifndef _CACHE_ ++#define _CACHE_ ++ ++#include "uthash.h" ++#include "ev.h" ++ ++/** ++ * A cache entry ++ */ ++struct cache_entry { ++ char *key; /** ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++//#define __DEBUG__ ++#ifdef __DEBUG__ ++#define DEBUG(format,...) printf("File: "__FILE__", Line: %05d: "format"/n", __LINE__, ##__VA_ARGS__) ++#else ++#define DEBUG(format,...) ++#endif ++ ++static sigjmp_buf jmpbuf; ++static void alarm_func() ++{ ++ siglongjmp(jmpbuf, 1); ++} ++ ++static struct hostent *timeGethostbyname(const char *domain, int timeout) ++{ ++ struct hostent *ipHostent = NULL; ++ signal(SIGALRM, alarm_func); ++ if(sigsetjmp(jmpbuf, 1) != 0) ++ { ++ alarm(0);//timout ++ signal(SIGALRM, SIG_IGN); ++ return NULL; ++ } ++ alarm(timeout);//setting alarm ++ ipHostent = gethostbyname(domain); ++ signal(SIGALRM, SIG_IGN); ++ return ipHostent; ++} ++ ++ ++#define MY_HTTP_DEFAULT_PORT 80 ++#define BUFFER_SIZE 1024 ++#define HTTP_POST "POST /%s HTTP/1.1\r\nHOST: %s:%d\r\nAccept: */*\r\n"\ ++ "Content-Type:application/x-www-form-urlencoded\r\nContent-Length: %d\r\n\r\n%s" ++#define HTTP_GET "GET /%s HTTP/1.1\r\nHOST: %s:%d\r\nAccept: */*\r\n\r\n" ++ ++static int http_parse_url(const char *url,char *host,char *file,int *port) ++{ ++ char *ptr1,*ptr2; ++ int len = 0; ++ if(!url || !host || !file || !port){ ++ return 1; ++ } ++ ++ ptr1 = (char *)url; ++ ++ if(!strncmp(ptr1,"http://",strlen("http://"))){ ++ ptr1 += strlen("http://"); ++ }else{ ++ return 1; ++ } ++ ++ ptr2 = strchr(ptr1,'/'); ++ if(ptr2){ ++ len = strlen(ptr1) - strlen(ptr2); ++ memcpy(host,ptr1,len); ++ host[len] = '\0'; ++ if(*(ptr2 + 1)){ ++ memcpy(file,ptr2 + 1,strlen(ptr2) - 1 ); ++ file[strlen(ptr2) - 1] = '\0'; ++ } ++ }else{ ++ memcpy(host,ptr1,strlen(ptr1)); ++ host[strlen(ptr1)] = '\0'; ++ } ++ //get host and ip ++ ptr1 = strchr(host,':'); ++ if(ptr1){ ++ *ptr1++ = '\0'; ++ *port = atoi(ptr1); ++ }else{ ++ *port = MY_HTTP_DEFAULT_PORT; ++ } ++ ++ return 0; ++} ++ ++ ++static int http_tcpclient_recv(int socket,char *lpbuff){ ++ int recvnum = 0; ++ ++ recvnum = recv(socket, lpbuff,BUFFER_SIZE*4,0); ++ ++ return recvnum; ++} ++ ++static int http_tcpclient_send(int socket,char *buff,int size){ ++ int sent=0,tmpres=0; ++ ++ while(sent < size){ ++ tmpres = send(socket,buff+sent,size-sent,0); ++ if(tmpres == -1){ ++ return 1; ++ } ++ sent += tmpres; ++ } ++ return sent; ++} ++ ++ ++ ++ ++ ++int http_get(const char *url,int socket_fd) ++{ ++ char lpbuf[BUFFER_SIZE*4] = {'\0'}; ++ ++ char host_addr[BUFFER_SIZE] = {'\0'}; ++ char file[BUFFER_SIZE] = {'\0'}; ++ int port = 0; ++ ++ ++ if(!url){ ++ DEBUG(" failed!\n"); ++ return 1; ++ } ++ ++ if(http_parse_url(url,host_addr,file,&port)){ ++ DEBUG("http_parse_url failed!\n"); ++ return 1; ++ } ++ DEBUG("url: %s\thost_addr : %s\tfile:%s\t,%d\n",url,host_addr,file,port); ++ ++ ++ if(socket_fd < 0){ ++ DEBUG("http_tcpclient_create failed\n"); ++ return 1; ++ } ++ ++ sprintf(lpbuf,HTTP_GET,file,host_addr,port); ++ ++ if(http_tcpclient_send(socket_fd,lpbuf,strlen(lpbuf)) < 0){ ++ DEBUG("http_tcpclient_send failed..\n"); ++ return 1; ++ } ++ DEBUG("request:\n%s\n",lpbuf); ++ ++ if(http_tcpclient_recv(socket_fd,lpbuf) <= 0){ ++ DEBUG("http_tcpclient_recv failed\n"); ++ close(socket_fd); ++ return 1; ++ } ++ DEBUG("rec:\n%s\n",lpbuf); ++ close(socket_fd); ++ ++ //return http_parse_result(lpbuf); ++return 0; ++} ++ ++ ++ ++int main(int argc, char *argv[]) ++{ ++ int fd,http_flag=0,http_ret=1; ++ struct sockaddr_in addr; ++ struct hostent *host; ++ struct timeval timeo = {3, 0}; ++ socklen_t len = sizeof(timeo); ++ ++ char http_url[100]="http://"; ++ ++ ++ ++ fd = socket(AF_INET, SOCK_STREAM, 0); ++ if (argc >= 4) ++ timeo.tv_sec = atoi(argv[3]); ++ if (argc>=5) ++ http_flag=1; ++ ++ if((host=timeGethostbyname(argv[1],timeo.tv_sec)) == NULL) { ++ DEBUG("gethostbyname err\n"); ++ return 1; ++ } ++ if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeo, len) == -1) ++ { ++ ++ DEBUG("setsockopt send err\n"); ++ return 1; ++ } ++ ++ if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo, len) == -1) ++ { ++ ++ DEBUG("setsockopt recv err\n"); ++ return 1; ++ } ++ ++ addr.sin_family = AF_INET; ++ addr.sin_addr = *((struct in_addr *)host->h_addr); ++ //addr.sin_addr.s_addr = inet_addr(argv[1]); ++ addr.sin_port = htons(atoi(argv[2])); ++if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) ++ { ++ if (errno == EINPROGRESS) ++ { ++ DEBUG("timeout err\n"); ++ return 1; ++ } ++ DEBUG("connect err\n"); ++ return 1; ++ } ++if(http_flag==0) ++{ ++ close(fd); ++ return 0; ++} ++strcat(http_url,argv[1]); ++http_ret=http_get(http_url,fd); ++if(http_ret==1) ++{ ++DEBUG("recv err"); ++ return 1; ++} ++else ++{ ++DEBUG("recv ok"); ++ ++ return 0; ++} ++ ++} +\ No newline at end of file +diff --git a/server/common.h b/server/common.h +new file mode 100644 +index 0000000..000f084 +--- /dev/null ++++ b/server/common.h +@@ -0,0 +1,58 @@ ++/* ++ * common.h - Provide global definitions ++ * ++ * Copyright (C) 2013 - 2016, Max Lv ++ * ++ * This file is part of the shadowsocks-libev. ++ * shadowsocks-libev 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 3 of the License, or ++ * (at your option) any later version. ++ * ++ * shadowsocks-libev 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 shadowsocks-libev; see the file COPYING. If not, see ++ * . ++ */ ++ ++#ifndef _COMMON_H ++#define _COMMON_H ++ ++#define DEFAULT_CONF_PATH "/etc/shadowsocks-libev/config.json" ++ ++#ifndef SOL_TCP ++#define SOL_TCP IPPROTO_TCP ++#endif ++ ++#if defined(MODULE_TUNNEL) || defined(MODULE_REDIR) ++#define MODULE_LOCAL ++#endif ++ ++int init_udprelay(const char *server_host, const char *server_port, ++#ifdef MODULE_LOCAL ++ const struct sockaddr *remote_addr, const int remote_addr_len, ++#ifdef MODULE_TUNNEL ++ const ss_addr_t tunnel_addr, ++#endif ++#endif ++ int mtu, int method, int auth, int timeout, const char *iface, const char *protocol, const char *protocol_param); ++ ++void free_udprelay(void); ++ ++#ifdef ANDROID ++int protect_socket(int fd); ++int send_traffic_stat(uint64_t tx, uint64_t rx); ++#endif ++ ++#define STAGE_ERROR -1 /* Error detected */ ++#define STAGE_INIT 0 /* Initial stage */ ++#define STAGE_HANDSHAKE 1 /* Handshake with client */ ++#define STAGE_PARSE 2 /* Parse the header */ ++#define STAGE_RESOLVE 4 /* Resolve the hostname */ ++#define STAGE_STREAM 5 /* Stream between client and server */ ++ ++#endif // _COMMON_H +diff --git a/server/crc32.c b/server/crc32.c +new file mode 100644 +index 0000000..6d328d2 +--- /dev/null ++++ b/server/crc32.c +@@ -0,0 +1,97 @@ ++static uint32_t crc32_table[256] = {0}; ++ ++void init_crc32_table(void) { ++ uint32_t c, i, j; ++ if (crc32_table[0] == 0) { ++ for (i = 0; i < 256; i++) { ++ c = i; ++ for (j = 0; j < 8; j++) { ++ if (c & 1) ++ c = 0xedb88320L ^ (c >> 1); ++ else ++ c = c >> 1; ++ } ++ crc32_table[i] = c; ++ } ++ } ++} ++ ++uint32_t crc32(unsigned char *buffer, unsigned int size) { ++ uint32_t crc = 0xFFFFFFFF; ++ unsigned int i; ++ for (i = 0; i < size; i++) { ++ crc = crc32_table[(crc ^ buffer[i]) & 0xFF] ^ (crc >> 8); ++ } ++ return crc ^ 0xFFFFFFFF; ++} ++ ++void fillcrc32to(unsigned char *buffer, unsigned int size, unsigned char *outbuffer) { ++ uint32_t crc = 0xFFFFFFFF; ++ unsigned int i; ++ for (i = 0; i < size; i++) { ++ crc = crc32_table[(crc ^ buffer[i]) & 0xff] ^ (crc >> 8); ++ } ++ crc ^= 0xFFFFFFFF; ++ outbuffer[0] = crc; ++ outbuffer[1] = crc >> 8; ++ outbuffer[2] = crc >> 16; ++ outbuffer[3] = crc >> 24; ++} ++ ++void fillcrc32(unsigned char *buffer, unsigned int size) { ++ uint32_t crc = 0xFFFFFFFF; ++ unsigned int i; ++ size -= 4; ++ for (i = 0; i < size; i++) { ++ crc = crc32_table[(crc ^ buffer[i]) & 0xff] ^ (crc >> 8); ++ } ++ buffer += size; ++ buffer[0] = crc; ++ buffer[1] = crc >> 8; ++ buffer[2] = crc >> 16; ++ buffer[3] = crc >> 24; ++} ++ ++void adler32_short(unsigned char *buffer, unsigned int size, uint32_t *a, uint32_t *b) { ++ for (int i = 0; i < size; i++) { ++ *a += buffer[i]; ++ *b += *a; ++ } ++ *a %= 65521; ++ *b %= 65521; ++} ++ ++#define NMAX 5552 ++uint32_t adler32(unsigned char *buffer, unsigned int size) { ++ uint32_t a = 1; ++ uint32_t b = 0; ++ while ( size >= NMAX ) { ++ adler32_short(buffer, NMAX, &a, &b); ++ buffer += NMAX; ++ size -= NMAX; ++ } ++ adler32_short(buffer, size, &a, &b); ++ return (b << 16) + a; ++} ++#undef NMAX ++ ++void filladler32(unsigned char *buffer, unsigned int size) { ++ size -= 4; ++ uint32_t checksum = adler32(buffer, size); ++ buffer += size; ++ buffer[0] = checksum; ++ buffer[1] = checksum >> 8; ++ buffer[2] = checksum >> 16; ++ buffer[3] = checksum >> 24; ++} ++ ++int checkadler32(unsigned char *buffer, unsigned int size) { ++ size -= 4; ++ uint32_t checksum = adler32(buffer, size); ++ buffer += size; ++ return checksum == (((uint32_t)buffer[3] << 24) ++ | ((uint32_t)buffer[2] << 16) ++ | ((uint32_t)buffer[1] << 8) ++ | (uint32_t)buffer[0]); ++} ++ +diff --git a/server/encrypt.c b/server/encrypt.c +new file mode 100644 +index 0000000..37dd5cd +--- /dev/null ++++ b/server/encrypt.c +@@ -0,0 +1,1645 @@ ++/* ++ * encrypt.c - Manage the global encryptor ++ * ++ * Copyright (C) 2013 - 2016, Max Lv ++ * ++ * This file is part of the shadowsocks-libev. ++ * ++ * shadowsocks-libev 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 3 of the License, or ++ * (at your option) any later version. ++ * ++ * shadowsocks-libev 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 shadowsocks-libev; see the file COPYING. If not, see ++ * . ++ */ ++ ++#include ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#if defined(USE_CRYPTO_OPENSSL) ++ ++#include ++#include ++#include ++#include ++ ++#elif defined(USE_CRYPTO_POLARSSL) ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#define CIPHER_UNSUPPORTED "unsupported" ++ ++#include ++#ifdef _WIN32 ++#include ++#include ++#else ++#include ++#endif ++ ++#elif defined(USE_CRYPTO_MBEDTLS) ++ ++#include ++#include ++#include ++#include ++#include ++#define CIPHER_UNSUPPORTED "unsupported" ++ ++#include ++#ifdef _WIN32 ++#include ++#include ++#else ++#include ++#endif ++ ++#endif ++ ++#include ++ ++#ifndef __MINGW32__ ++#include ++#endif ++ ++#include "cache.h" ++#include "encrypt.h" ++#include "utils.h" ++ ++#define OFFSET_ROL(p, o) ((uint64_t)(*(p + o)) << (8 * o)) ++ ++static uint8_t *enc_table; ++static uint8_t *dec_table; ++static uint8_t enc_key[MAX_KEY_LENGTH]; ++static int enc_key_len; ++static int enc_iv_len; ++static int enc_method; ++ ++static struct cache *iv_cache; ++ ++#ifdef DEBUG ++static void ++dump(char *tag, char *text, int len) ++{ ++ int i; ++ printf("%s: ", tag); ++ for (i = 0; i < len; i++) ++ printf("0x%02x ", (uint8_t)text[i]); ++ printf("\n"); ++} ++ ++#endif ++ ++static const char *supported_ciphers[CIPHER_NUM] = { ++ "table", ++ "rc4", ++ "rc4-md5-6", ++ "rc4-md5", ++ "aes-128-cfb", ++ "aes-192-cfb", ++ "aes-256-cfb", ++ "aes-128-ctr", ++ "aes-192-ctr", ++ "aes-256-ctr", ++ "bf-cfb", ++ "camellia-128-cfb", ++ "camellia-192-cfb", ++ "camellia-256-cfb", ++ "cast5-cfb", ++ "des-cfb", ++ "idea-cfb", ++ "rc2-cfb", ++ "seed-cfb", ++ "salsa20", ++ "chacha20", ++ "chacha20-ietf" ++}; ++ ++#ifdef USE_CRYPTO_POLARSSL ++static const char *supported_ciphers_polarssl[CIPHER_NUM] = { ++ "table", ++ "ARC4-128", ++ "ARC4-128", ++ "ARC4-128", ++ "AES-128-CFB128", ++ "AES-192-CFB128", ++ "AES-256-CFB128", ++ "AES-128-CTR", ++ "AES-192-CTR", ++ "AES-256-CTR", ++ "BLOWFISH-CFB64", ++ "CAMELLIA-128-CFB128", ++ "CAMELLIA-192-CFB128", ++ "CAMELLIA-256-CFB128", ++ CIPHER_UNSUPPORTED, ++ CIPHER_UNSUPPORTED, ++ CIPHER_UNSUPPORTED, ++ CIPHER_UNSUPPORTED, ++ CIPHER_UNSUPPORTED, ++ "salsa20", ++ "chacha20", ++ "chacha20-ietf" ++}; ++#endif ++ ++#ifdef USE_CRYPTO_MBEDTLS ++static const char *supported_ciphers_mbedtls[CIPHER_NUM] = { ++ "table", ++ "ARC4-128", ++ "ARC4-128", ++ "ARC4-128", ++ "AES-128-CFB128", ++ "AES-192-CFB128", ++ "AES-256-CFB128", ++ "AES-128-CTR", ++ "AES-192-CTR", ++ "AES-256-CTR", ++ "BLOWFISH-CFB64", ++ "CAMELLIA-128-CFB128", ++ "CAMELLIA-192-CFB128", ++ "CAMELLIA-256-CFB128", ++ CIPHER_UNSUPPORTED, ++ CIPHER_UNSUPPORTED, ++ CIPHER_UNSUPPORTED, ++ CIPHER_UNSUPPORTED, ++ CIPHER_UNSUPPORTED, ++ "salsa20", ++ "chacha20", ++ "chacha20-ietf" ++}; ++#endif ++ ++#ifdef USE_CRYPTO_APPLECC ++static const CCAlgorithm supported_ciphers_applecc[CIPHER_NUM] = { ++ kCCAlgorithmInvalid, ++ kCCAlgorithmRC4, ++ kCCAlgorithmRC4, ++ kCCAlgorithmRC4, ++ kCCAlgorithmAES, ++ kCCAlgorithmAES, ++ kCCAlgorithmAES, ++ kCCAlgorithmAES, ++ kCCAlgorithmAES, ++ kCCAlgorithmAES, ++ kCCAlgorithmBlowfish, ++ kCCAlgorithmInvalid, ++ kCCAlgorithmInvalid, ++ kCCAlgorithmInvalid, ++ kCCAlgorithmCAST, ++ kCCAlgorithmDES, ++ kCCAlgorithmInvalid, ++ kCCAlgorithmRC2, ++ kCCAlgorithmInvalid, ++ kCCAlgorithmInvalid, ++ kCCAlgorithmInvalid, ++ kCCAlgorithmInvalid ++}; ++ ++static const CCMode supported_modes_applecc[CIPHER_NUM] = { ++ kCCAlgorithmInvalid, ++ kCCAlgorithmInvalid, ++ kCCModeRC4, ++ kCCModeRC4, ++ kCCModeCFB, ++ kCCModeCFB, ++ kCCModeCFB, ++ kCCModeCTR, ++ kCCModeCTR, ++ kCCModeCTR, ++ kCCModeCFB, ++ kCCAlgorithmInvalid, ++ kCCAlgorithmInvalid, ++ kCCAlgorithmInvalid, ++ kCCModeCFB, ++ kCCModeCFB, ++ kCCModeCFB, ++ kCCModeCFB, ++ kCCAlgorithmInvalid, ++ kCCAlgorithmInvalid, ++ kCCAlgorithmInvalid, ++ kCCAlgorithmInvalid ++}; ++#endif ++ ++static const int supported_ciphers_iv_size[CIPHER_NUM] = { ++ 0, 0, 6, 16, 16, 16, 16, 16, 16, 16, 8, 16, 16, 16, 8, 8, 8, 8, 16, 8, 8, 12 ++}; ++ ++static const int supported_ciphers_key_size[CIPHER_NUM] = { ++ 0, 16, 16, 16, 16, 24, 32, 16, 24, 32, 16, 16, 24, 32, 16, 8, 16, 16, 16, 32, 32, 32 ++}; ++ ++static int ++safe_memcmp(const void *s1, const void *s2, size_t n) ++{ ++ const unsigned char *_s1 = (const unsigned char *)s1; ++ const unsigned char *_s2 = (const unsigned char *)s2; ++ int ret = 0; ++ size_t i; ++ for (i = 0; i < n; i++) ++ ret |= _s1[i] ^ _s2[i]; ++ return !!ret; ++} ++ ++int ++balloc(buffer_t *ptr, size_t capacity) ++{ ++ sodium_memzero(ptr, sizeof(buffer_t)); ++ ptr->array = ss_malloc(capacity); ++ ptr->capacity = capacity; ++ return capacity; ++} ++ ++int ++brealloc(buffer_t *ptr, size_t len, size_t capacity) ++{ ++ if (ptr == NULL) ++ return -1; ++ size_t real_capacity = max(len, capacity); ++ if (ptr->capacity < real_capacity) { ++ ptr->array = ss_realloc(ptr->array, real_capacity); ++ ptr->capacity = real_capacity; ++ } ++ return real_capacity; ++} ++ ++void ++bfree(buffer_t *ptr) ++{ ++ if (ptr == NULL) ++ return; ++ ptr->idx = 0; ++ ptr->len = 0; ++ ptr->capacity = 0; ++ if (ptr->array != NULL) { ++ ss_free(ptr->array); ++ } ++} ++ ++static int ++crypto_stream_xor_ic(uint8_t *c, const uint8_t *m, uint64_t mlen, ++ const uint8_t *n, uint64_t ic, const uint8_t *k, ++ int method) ++{ ++ switch (method) { ++ case SALSA20: ++ return crypto_stream_salsa20_xor_ic(c, m, mlen, n, ic, k); ++ case CHACHA20: ++ return crypto_stream_chacha20_xor_ic(c, m, mlen, n, ic, k); ++ case CHACHA20IETF: ++ return crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, n, (uint32_t)ic, k); ++ } ++ // always return 0 ++ return 0; ++} ++ ++static int ++random_compare(const void *_x, const void *_y, uint32_t i, ++ uint64_t a) ++{ ++ uint8_t x = *((uint8_t *)_x); ++ uint8_t y = *((uint8_t *)_y); ++ return a % (x + i) - a % (y + i); ++} ++ ++static void ++merge(uint8_t *left, int llength, uint8_t *right, ++ int rlength, uint32_t salt, uint64_t key) ++{ ++ uint8_t *ltmp = (uint8_t *)malloc(llength * sizeof(uint8_t)); ++ uint8_t *rtmp = (uint8_t *)malloc(rlength * sizeof(uint8_t)); ++ ++ uint8_t *ll = ltmp; ++ uint8_t *rr = rtmp; ++ ++ uint8_t *result = left; ++ ++ memcpy(ltmp, left, llength * sizeof(uint8_t)); ++ memcpy(rtmp, right, rlength * sizeof(uint8_t)); ++ ++ while (llength > 0 && rlength > 0) { ++ if (random_compare(ll, rr, salt, key) <= 0) { ++ *result = *ll; ++ ++ll; ++ --llength; ++ } else { ++ *result = *rr; ++ ++rr; ++ --rlength; ++ } ++ ++result; ++ } ++ ++ if (llength > 0) { ++ while (llength > 0) { ++ *result = *ll; ++ ++result; ++ ++ll; ++ --llength; ++ } ++ } else { ++ while (rlength > 0) { ++ *result = *rr; ++ ++result; ++ ++rr; ++ --rlength; ++ } ++ } ++ ++ ss_free(ltmp); ++ ss_free(rtmp); ++} ++ ++static void ++merge_sort(uint8_t array[], int length, ++ uint32_t salt, uint64_t key) ++{ ++ uint8_t middle; ++ uint8_t *left, *right; ++ int llength; ++ ++ if (length <= 1) { ++ return; ++ } ++ ++ middle = length / 2; ++ ++ llength = length - middle; ++ ++ left = array; ++ right = array + llength; ++ ++ merge_sort(left, llength, salt, key); ++ merge_sort(right, middle, salt, key); ++ merge(left, llength, right, middle, salt, key); ++} ++ ++int ++enc_get_iv_len() ++{ ++ return enc_iv_len; ++} ++ ++uint8_t* enc_get_key() ++{ ++ return enc_key; ++} ++ ++int enc_get_key_len() ++{ ++ return enc_key_len; ++} ++ ++unsigned char *enc_md5(const unsigned char *d, size_t n, unsigned char *md) ++{ ++#if defined(USE_CRYPTO_OPENSSL) ++ return MD5(d, n, md); ++#elif defined(USE_CRYPTO_POLARSSL) ++ static unsigned char m[16]; ++ if (md == NULL) { ++ md = m; ++ } ++ md5(d, n, md); ++ return md; ++#elif defined(USE_CRYPTO_MBEDTLS) ++ static unsigned char m[16]; ++ if (md == NULL) { ++ md = m; ++ } ++ mbedtls_md5(d, n, md); ++ return md; ++#endif ++} ++ ++void ++enc_table_init(const char *pass) ++{ ++ uint32_t i; ++ uint64_t key = 0; ++ uint8_t *digest; ++ ++ enc_table = ss_malloc(256); ++ dec_table = ss_malloc(256); ++ ++ digest = enc_md5((const uint8_t *)pass, strlen(pass), NULL); ++ ++ for (i = 0; i < 8; i++) ++ key += OFFSET_ROL(digest, i); ++ ++ for (i = 0; i < 256; ++i) ++ enc_table[i] = i; ++ for (i = 1; i < 1024; ++i) ++ merge_sort(enc_table, 256, i, key); ++ for (i = 0; i < 256; ++i) ++ // gen decrypt table from encrypt table ++ dec_table[enc_table[i]] = i; ++} ++ ++int ++cipher_iv_size(const cipher_t *cipher) ++{ ++#if defined(USE_CRYPTO_OPENSSL) ++ if (cipher->info == NULL) ++ return cipher->iv_len; ++ else ++ return EVP_CIPHER_iv_length(cipher->info); ++#elif defined(USE_CRYPTO_POLARSSL) || defined(USE_CRYPTO_MBEDTLS) ++ if (cipher == NULL) { ++ return 0; ++ } ++ return cipher->info->iv_size; ++#endif ++} ++ ++int ++cipher_key_size(const cipher_t *cipher) ++{ ++#if defined(USE_CRYPTO_OPENSSL) ++ if (cipher->info == NULL) ++ return cipher->key_len; ++ else ++ return EVP_CIPHER_key_length(cipher->info); ++#elif defined(USE_CRYPTO_POLARSSL) ++ if (cipher == NULL) { ++ return 0; ++ } ++ /* Override PolarSSL 32 bit default key size with sane 128 bit default */ ++ if (cipher->info->base != NULL && POLARSSL_CIPHER_ID_BLOWFISH == ++ cipher->info->base->cipher) { ++ return 128 / 8; ++ } ++ return cipher->info->key_length / 8; ++#elif defined(USE_CRYPTO_MBEDTLS) ++ /* ++ * Semi-API changes (technically public, morally private) ++ * Renamed a few headers to include _internal in the name. Those headers are ++ * not supposed to be included by users. ++ * Changed md_info_t into an opaque structure (use md_get_xxx() accessors). ++ * Changed pk_info_t into an opaque structure. ++ * Changed cipher_base_t into an opaque structure. ++ */ ++ if (cipher == NULL) { ++ return 0; ++ } ++ /* From Version 1.2.7 released 2013-04-13 Default Blowfish keysize is now 128-bits */ ++ return cipher->info->key_bitlen / 8; ++#endif ++} ++ ++void ++bytes_to_key_with_size(const char *pass, size_t len, uint8_t *md, size_t md_size) ++{ ++ uint8_t result[128]; ++ enc_md5((const unsigned char *)pass, len, result); ++ memcpy(md, result, 16); ++ int i = 16; ++ for (; i < md_size; i += 16) { ++ memcpy(result + 16, pass, len); ++ enc_md5(result, 16 + len, result); ++ memcpy(md + i, result, 16); ++ } ++} ++ ++int ++bytes_to_key(const cipher_t *cipher, const digest_type_t *md, ++ const uint8_t *pass, uint8_t *key) ++{ ++ size_t datal; ++ datal = strlen((const char *)pass); ++ ++#if defined(USE_CRYPTO_OPENSSL) ++ ++ MD5_CTX c; ++ unsigned char md_buf[MAX_MD_SIZE]; ++ int nkey; ++ int addmd; ++ unsigned int i, j, mds; ++ ++ mds = 16; ++ nkey = cipher_key_size(cipher); ++ if (pass == NULL) ++ return nkey; ++ memset(&c, 0, sizeof(MD5_CTX)); ++ ++ for (j = 0, addmd = 0; j < nkey; addmd++) { ++ MD5_Init(&c); ++ if (addmd) { ++ MD5_Update(&c, md_buf, mds); ++ } ++ MD5_Update(&c, pass, datal); ++ MD5_Final(md_buf, &c); ++ ++ for (i = 0; i < mds; i++, j++) { ++ if (j >= nkey) ++ break; ++ key[j] = md_buf[i]; ++ } ++ } ++ ++ return nkey; ++ ++#elif defined(USE_CRYPTO_POLARSSL) ++ md_context_t c; ++ unsigned char md_buf[MAX_MD_SIZE]; ++ int nkey; ++ int addmd; ++ unsigned int i, j, mds; ++ ++ nkey = cipher_key_size(cipher); ++ mds = md_get_size(md); ++ memset(&c, 0, sizeof(md_context_t)); ++ ++ if (pass == NULL) ++ return nkey; ++ if (md_init_ctx(&c, md)) ++ return 0; ++ ++ for (j = 0, addmd = 0; j < nkey; addmd++) { ++ md_starts(&c); ++ if (addmd) { ++ md_update(&c, md_buf, mds); ++ } ++ md_update(&c, pass, datal); ++ md_finish(&c, md_buf); ++ ++ for (i = 0; i < mds; i++, j++) { ++ if (j >= nkey) ++ break; ++ key[j] = md_buf[i]; ++ } ++ } ++ ++ md_free_ctx(&c); ++ return nkey; ++ ++#elif defined(USE_CRYPTO_MBEDTLS) ++ ++ mbedtls_md_context_t c; ++ unsigned char md_buf[MAX_MD_SIZE]; ++ int nkey; ++ int addmd; ++ unsigned int i, j, mds; ++ ++ nkey = cipher_key_size(cipher); ++ mds = mbedtls_md_get_size(md); ++ memset(&c, 0, sizeof(mbedtls_md_context_t)); ++ ++ if (pass == NULL) ++ return nkey; ++ if (mbedtls_md_setup(&c, md, 1)) ++ return 0; ++ ++ for (j = 0, addmd = 0; j < nkey; addmd++) { ++ mbedtls_md_starts(&c); ++ if (addmd) { ++ mbedtls_md_update(&c, md_buf, mds); ++ } ++ mbedtls_md_update(&c, pass, datal); ++ mbedtls_md_finish(&c, &(md_buf[0])); ++ ++ for (i = 0; i < mds; i++, j++) { ++ if (j >= nkey) ++ break; ++ key[j] = md_buf[i]; ++ } ++ } ++ ++ mbedtls_md_free(&c); ++ return nkey; ++#endif ++} ++ ++int ++rand_bytes(uint8_t *output, int len) ++{ ++ randombytes_buf(output, len); ++ // always return success ++ return 0; ++} ++ ++const cipher_kt_t * ++get_cipher_type(int method) ++{ ++ if (method <= TABLE || method >= CIPHER_NUM) { ++ LOGE("get_cipher_type(): Illegal method"); ++ return NULL; ++ } ++ ++ if (method == RC4_MD5 || method == RC4_MD5_6) { ++ method = RC4; ++ } ++ ++ if (method >= SALSA20) { ++ return NULL; ++ } ++ ++ const char *ciphername = supported_ciphers[method]; ++#if defined(USE_CRYPTO_OPENSSL) ++ return EVP_get_cipherbyname(ciphername); ++#elif defined(USE_CRYPTO_POLARSSL) ++ const char *polarname = supported_ciphers_polarssl[method]; ++ if (strcmp(polarname, CIPHER_UNSUPPORTED) == 0) { ++ LOGE("Cipher %s currently is not supported by PolarSSL library", ++ ciphername); ++ return NULL; ++ } ++ return cipher_info_from_string(polarname); ++#elif defined(USE_CRYPTO_MBEDTLS) ++ const char *mbedtlsname = supported_ciphers_mbedtls[method]; ++ if (strcmp(mbedtlsname, CIPHER_UNSUPPORTED) == 0) { ++ LOGE("Cipher %s currently is not supported by mbed TLS library", ++ ciphername); ++ return NULL; ++ } ++ return mbedtls_cipher_info_from_string(mbedtlsname); ++#endif ++} ++ ++const digest_type_t * ++get_digest_type(const char *digest) ++{ ++ if (digest == NULL) { ++ LOGE("get_digest_type(): Digest name is null"); ++ return NULL; ++ } ++ ++#if defined(USE_CRYPTO_OPENSSL) ++ return EVP_get_digestbyname(digest); ++#elif defined(USE_CRYPTO_POLARSSL) ++ return md_info_from_string(digest); ++#elif defined(USE_CRYPTO_MBEDTLS) ++ return mbedtls_md_info_from_string(digest); ++#endif ++} ++ ++void ++cipher_context_init(cipher_ctx_t *ctx, int method, int enc) ++{ ++ if (method <= TABLE || method >= CIPHER_NUM) { ++ LOGE("cipher_context_init(): Illegal method"); ++ return; ++ } ++ ++ if (method >= SALSA20) { ++ enc_iv_len = supported_ciphers_iv_size[method]; ++ return; ++ } ++ ++ const char *ciphername = supported_ciphers[method]; ++#if defined(USE_CRYPTO_APPLECC) ++ cipher_cc_t *cc = &ctx->cc; ++ cc->cryptor = NULL; ++ cc->cipher = supported_ciphers_applecc[method]; ++ if (cc->cipher == kCCAlgorithmInvalid) { ++ cc->valid = kCCContextInvalid; ++ } else { ++ cc->valid = kCCContextValid; ++ if (cc->cipher == kCCAlgorithmRC4) { ++ cc->mode = supported_modes_applecc[method]; ++ cc->padding = ccNoPadding; ++ } else { ++ cc->mode = supported_modes_applecc[method]; ++ if (cc->mode == kCCModeCTR) { ++ cc->padding = ccNoPadding; ++ } else { ++ cc->padding = ccPKCS7Padding; ++ } ++ } ++ return; ++ } ++#endif ++ ++ const cipher_kt_t *cipher = get_cipher_type(method); ++ ++#if defined(USE_CRYPTO_OPENSSL) ++ ctx->evp = EVP_CIPHER_CTX_new(); ++ cipher_evp_t *evp = ctx->evp; ++ ++ if (cipher == NULL) { ++ LOGE("Cipher %s not found in OpenSSL library", ciphername); ++ FATAL("Cannot initialize cipher"); ++ } ++ if (!EVP_CipherInit_ex(evp, cipher, NULL, NULL, NULL, enc)) { ++ LOGE("Cannot initialize cipher %s", ciphername); ++ exit(EXIT_FAILURE); ++ } ++ if (!EVP_CIPHER_CTX_set_key_length(evp, enc_key_len)) { ++ EVP_CIPHER_CTX_cleanup(evp); ++ LOGE("Invalid key length: %d", enc_key_len); ++ exit(EXIT_FAILURE); ++ } ++ if (method > RC4_MD5) { ++ EVP_CIPHER_CTX_set_padding(evp, 1); ++ } ++#elif defined(USE_CRYPTO_POLARSSL) ++ ctx->evp = (cipher_evp_t *)ss_malloc(sizeof(cipher_evp_t)); ++ cipher_evp_t *evp = ctx->evp; ++ ++ if (cipher == NULL) { ++ LOGE("Cipher %s not found in PolarSSL library", ciphername); ++ FATAL("Cannot initialize PolarSSL cipher"); ++ } ++ if (cipher_init_ctx(evp, cipher) != 0) { ++ FATAL("Cannot initialize PolarSSL cipher context"); ++ } ++#elif defined(USE_CRYPTO_MBEDTLS) ++ ctx->evp = (cipher_evp_t *)ss_malloc(sizeof(cipher_evp_t)); ++ cipher_evp_t *evp = ctx->evp; ++ ++ if (cipher == NULL) { ++ LOGE("Cipher %s not found in mbed TLS library", ciphername); ++ FATAL("Cannot initialize mbed TLS cipher"); ++ } ++ mbedtls_cipher_init(evp); ++ if (mbedtls_cipher_setup(evp, cipher) != 0) { ++ FATAL("Cannot initialize mbed TLS cipher context"); ++ } ++#endif ++} ++ ++void ++cipher_context_set_iv(cipher_ctx_t *ctx, uint8_t *iv, size_t iv_len, ++ int enc) ++{ ++ const unsigned char *true_key; ++ ++ if (iv == NULL) { ++ LOGE("cipher_context_set_iv(): IV is null"); ++ return; ++ } ++ ++ if (!enc) { ++ memcpy(ctx->iv, iv, iv_len); ++ } ++ ++ if (enc_method >= SALSA20) { ++ return; ++ } ++ ++ if (enc_method == RC4_MD5 || enc_method == RC4_MD5_6) { ++ unsigned char key_iv[32]; ++ memcpy(key_iv, enc_key, 16); ++ memcpy(key_iv + 16, iv, iv_len); ++ true_key = enc_md5(key_iv, 16 + iv_len, NULL); ++ iv_len = 0; ++ } else { ++ true_key = enc_key; ++ } ++ ++#ifdef USE_CRYPTO_APPLECC ++ cipher_cc_t *cc = &ctx->cc; ++ if (cc->valid == kCCContextValid) { ++ memcpy(cc->iv, iv, iv_len); ++ memcpy(cc->key, true_key, enc_key_len); ++ cc->iv_len = iv_len; ++ cc->key_len = enc_key_len; ++ cc->encrypt = enc ? kCCEncrypt : kCCDecrypt; ++ if (cc->cryptor != NULL) { ++ CCCryptorRelease(cc->cryptor); ++ cc->cryptor = NULL; ++ } ++ ++ CCCryptorStatus ret; ++ ret = CCCryptorCreateWithMode( ++ cc->encrypt, ++ cc->mode, ++ cc->cipher, ++ cc->padding, ++ cc->iv, cc->key, cc->key_len, ++ NULL, 0, 0, kCCModeOptionCTR_BE, ++ &cc->cryptor); ++ if (ret != kCCSuccess) { ++ if (cc->cryptor != NULL) { ++ CCCryptorRelease(cc->cryptor); ++ cc->cryptor = NULL; ++ } ++ FATAL("Cannot set CommonCrypto key and IV"); ++ } ++ return; ++ } ++#endif ++ ++ cipher_evp_t *evp = ctx->evp; ++ if (evp == NULL) { ++ LOGE("cipher_context_set_iv(): Cipher context is null"); ++ return; ++ } ++#if defined(USE_CRYPTO_OPENSSL) ++ if (!EVP_CipherInit_ex(evp, NULL, NULL, true_key, iv, enc)) { ++ EVP_CIPHER_CTX_cleanup(evp); ++ FATAL("Cannot set key and IV"); ++ } ++#elif defined(USE_CRYPTO_POLARSSL) ++ // XXX: PolarSSL 1.3.11: cipher_free_ctx deprecated, Use cipher_free() instead. ++ if (cipher_setkey(evp, true_key, enc_key_len * 8, enc) != 0) { ++ cipher_free_ctx(evp); ++ FATAL("Cannot set PolarSSL cipher key"); ++ } ++#if POLARSSL_VERSION_NUMBER >= 0x01030000 ++ if (cipher_set_iv(evp, iv, iv_len) != 0) { ++ cipher_free_ctx(evp); ++ FATAL("Cannot set PolarSSL cipher IV"); ++ } ++ if (cipher_reset(evp) != 0) { ++ cipher_free_ctx(evp); ++ FATAL("Cannot finalize PolarSSL cipher context"); ++ } ++#else ++ if (cipher_reset(evp, iv) != 0) { ++ cipher_free_ctx(evp); ++ FATAL("Cannot set PolarSSL cipher IV"); ++ } ++#endif ++#elif defined(USE_CRYPTO_MBEDTLS) ++ if (mbedtls_cipher_setkey(evp, true_key, enc_key_len * 8, enc) != 0) { ++ mbedtls_cipher_free(evp); ++ FATAL("Cannot set mbed TLS cipher key"); ++ } ++ ++ if (mbedtls_cipher_set_iv(evp, iv, iv_len) != 0) { ++ mbedtls_cipher_free(evp); ++ FATAL("Cannot set mbed TLS cipher IV"); ++ } ++ if (mbedtls_cipher_reset(evp) != 0) { ++ mbedtls_cipher_free(evp); ++ FATAL("Cannot finalize mbed TLS cipher context"); ++ } ++#endif ++ ++#ifdef DEBUG ++ dump("IV", (char *)iv, iv_len); ++#endif ++} ++ ++void ++cipher_context_release(cipher_ctx_t *ctx) ++{ ++ if (enc_method >= SALSA20) { ++ return; ++ } ++ ++#ifdef USE_CRYPTO_APPLECC ++ cipher_cc_t *cc = &ctx->cc; ++ if (cc->cryptor != NULL) { ++ CCCryptorRelease(cc->cryptor); ++ cc->cryptor = NULL; ++ } ++ if (cc->valid == kCCContextValid) { ++ return; ++ } ++#endif ++ ++#if defined(USE_CRYPTO_OPENSSL) ++ EVP_CIPHER_CTX_free(ctx->evp); ++#elif defined(USE_CRYPTO_POLARSSL) ++// NOTE: cipher_free_ctx deprecated in PolarSSL 1.3.11 ++ cipher_free_ctx(ctx->evp); ++ ss_free(ctx->evp); ++#elif defined(USE_CRYPTO_MBEDTLS) ++// NOTE: cipher_free_ctx deprecated ++ mbedtls_cipher_free(ctx->evp); ++ ss_free(ctx->evp); ++#endif ++} ++ ++static int ++cipher_context_update(cipher_ctx_t *ctx, uint8_t *output, size_t *olen, ++ const uint8_t *input, size_t ilen) ++{ ++#ifdef USE_CRYPTO_APPLECC ++ cipher_cc_t *cc = &ctx->cc; ++ if (cc->valid == kCCContextValid) { ++ CCCryptorStatus ret; ++ ret = CCCryptorUpdate(cc->cryptor, input, ilen, output, ++ ilen, olen); ++ return (ret == kCCSuccess) ? 1 : 0; ++ } ++#endif ++ cipher_evp_t *evp = ctx->evp; ++#if defined(USE_CRYPTO_OPENSSL) ++ int err = 0, tlen = *olen; ++ err = EVP_CipherUpdate(evp, (uint8_t *)output, &tlen, ++ (const uint8_t *)input, ilen); ++ *olen = tlen; ++ return err; ++#elif defined(USE_CRYPTO_POLARSSL) ++ return !cipher_update(evp, (const uint8_t *)input, ilen, ++ (uint8_t *)output, olen); ++#elif defined(USE_CRYPTO_MBEDTLS) ++ return !mbedtls_cipher_update(evp, (const uint8_t *)input, ilen, ++ (uint8_t *)output, olen); ++#endif ++} ++int ss_md5_hmac(char *auth, char *msg, int msg_len, uint8_t *iv) ++{ ++ uint8_t hash[MD5_BYTES]; ++ uint8_t auth_key[MAX_IV_LENGTH + MAX_KEY_LENGTH]; ++ memcpy(auth_key, iv, enc_iv_len); ++ memcpy(auth_key + enc_iv_len, enc_key, enc_key_len); ++ ++#if defined(USE_CRYPTO_OPENSSL) ++ HMAC(EVP_md5(), auth_key, enc_iv_len + enc_key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash, NULL); ++#elif defined(USE_CRYPTO_MBEDTLS) ++ mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_MD5), auth_key, enc_iv_len + enc_key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash); ++#else ++ md5_hmac(auth_key, enc_iv_len + enc_key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash); ++#endif ++ ++ memcpy(auth, hash, MD5_BYTES); ++ ++ return 0; ++} ++ ++int ss_md5_hmac_with_key(char *auth, char *msg, int msg_len, uint8_t *auth_key, int key_len) ++{ ++ uint8_t hash[MD5_BYTES]; ++ ++#if defined(USE_CRYPTO_OPENSSL) ++ HMAC(EVP_md5(), auth_key, key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash, NULL); ++#elif defined(USE_CRYPTO_MBEDTLS) ++ mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_MD5), auth_key, key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash); ++#else ++ md5_hmac(auth_key, key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash); ++#endif ++ ++ memcpy(auth, hash, MD5_BYTES); ++ ++ return 0; ++} ++ ++int ss_md5_hash_func(char *auth, char *msg, int msg_len) ++{ ++ uint8_t hash[MD5_BYTES]; ++ ++#if defined(USE_CRYPTO_OPENSSL) ++ MD5((uint8_t *)msg, msg_len, (uint8_t *)hash); ++#elif defined(USE_CRYPTO_MBEDTLS) ++ mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_MD5), (uint8_t *)msg, msg_len, (uint8_t *)hash); ++#else ++ md5((uint8_t *)msg, msg_len, (uint8_t *)hash); ++#endif ++ ++ memcpy(auth, hash, MD5_BYTES); ++ ++ return 0; ++} ++ ++int ss_sha1_hmac(char *auth, char *msg, int msg_len, uint8_t *iv) ++{ ++ uint8_t hash[SHA1_BYTES]; ++ uint8_t auth_key[MAX_IV_LENGTH + MAX_KEY_LENGTH]; ++ memcpy(auth_key, iv, enc_iv_len); ++ memcpy(auth_key + enc_iv_len, enc_key, enc_key_len); ++ ++#if defined(USE_CRYPTO_OPENSSL) ++ HMAC(EVP_sha1(), auth_key, enc_iv_len + enc_key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash, NULL); ++#elif defined(USE_CRYPTO_MBEDTLS) ++ mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), auth_key, enc_iv_len + enc_key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash); ++#else ++ sha1_hmac(auth_key, enc_iv_len + enc_key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash); ++#endif ++ ++ memcpy(auth, hash, SHA1_BYTES); ++ ++ return 0; ++} ++ ++int ss_sha1_hmac_with_key(char *auth, char *msg, int msg_len, uint8_t *auth_key, int key_len) ++{ ++ uint8_t hash[SHA1_BYTES]; ++ ++#if defined(USE_CRYPTO_OPENSSL) ++ HMAC(EVP_sha1(), auth_key, key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash, NULL); ++#elif defined(USE_CRYPTO_MBEDTLS) ++ mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), auth_key, key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash); ++#else ++ sha1_hmac(auth_key, key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash); ++#endif ++ ++ memcpy(auth, hash, SHA1_BYTES); ++ ++ return 0; ++} ++ ++int ss_sha1_hash_func(char *auth, char *msg, int msg_len) ++{ ++ uint8_t hash[SHA1_BYTES]; ++#if defined(USE_CRYPTO_OPENSSL) ++ SHA1((uint8_t *)msg, msg_len, (uint8_t *)hash); ++#elif defined(USE_CRYPTO_MBEDTLS) ++ mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), (uint8_t *)msg, msg_len, (uint8_t *)hash); ++#else ++ sha1((uint8_t *)msg, msg_len, (uint8_t *)hash); ++#endif ++ ++ memcpy(auth, hash, SHA1_BYTES); ++ ++ return 0; ++} ++ ++int ss_aes_128_cbc(char *encrypt, char *out_data, char *key) ++{ ++ unsigned char iv[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; ++ ++#if defined(USE_CRYPTO_OPENSSL) ++ AES_KEY aes; ++ AES_set_encrypt_key((unsigned char*)key, 128, &aes); ++ AES_cbc_encrypt((const unsigned char *)encrypt, (unsigned char *)out_data, 16, &aes, iv, AES_ENCRYPT); ++ ++#elif defined(USE_CRYPTO_MBEDTLS) ++ mbedtls_aes_context aes; ++ ++ unsigned char output[16]; ++ ++ mbedtls_aes_setkey_enc( &aes, (unsigned char *)key, 128 ); ++ mbedtls_aes_crypt_cbc( &aes, MBEDTLS_AES_ENCRYPT, 16, iv, (unsigned char *)encrypt, output ); ++ ++ memcpy(out_data, output, 16); ++#else ++ ++ aes_context aes; ++ ++ unsigned char output[16]; ++ ++ aes_setkey_enc( &aes, (unsigned char *)key, 128 ); ++ aes_crypt_cbc( &aes, AES_ENCRYPT, 16, iv, (unsigned char *)encrypt, output ); ++ ++ memcpy(out_data, output, 16); ++#endif ++ ++ return 0; ++} ++ ++int ss_onetimeauth(buffer_t *buf, uint8_t *iv, size_t capacity) ++{ ++ uint8_t hash[ONETIMEAUTH_BYTES * 2]; ++ uint8_t auth_key[MAX_IV_LENGTH + MAX_KEY_LENGTH]; ++ memcpy(auth_key, iv, enc_iv_len); ++ memcpy(auth_key + enc_iv_len, enc_key, enc_key_len); ++ ++ brealloc(buf, ONETIMEAUTH_BYTES + buf->len, capacity); ++ ++#if defined(USE_CRYPTO_OPENSSL) ++ HMAC(EVP_sha1(), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, buf->len, (uint8_t *)hash, NULL); ++#elif defined(USE_CRYPTO_MBEDTLS) ++ mbedtls_md_hmac(mbedtls_md_info_from_type( ++ MBEDTLS_MD_SHA1), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, buf->len, ++ (uint8_t *)hash); ++#else ++ sha1_hmac(auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, buf->len, (uint8_t *)hash); ++#endif ++ ++ memcpy(buf->array + buf->len, hash, ONETIMEAUTH_BYTES); ++ buf->len += ONETIMEAUTH_BYTES; ++ ++ return 0; ++} ++ ++int ++ss_onetimeauth_verify(buffer_t *buf, uint8_t *iv) ++{ ++ uint8_t hash[ONETIMEAUTH_BYTES * 2]; ++ uint8_t auth_key[MAX_IV_LENGTH + MAX_KEY_LENGTH]; ++ memcpy(auth_key, iv, enc_iv_len); ++ memcpy(auth_key + enc_iv_len, enc_key, enc_key_len); ++ size_t len = buf->len - ONETIMEAUTH_BYTES; ++ ++#if defined(USE_CRYPTO_OPENSSL) ++ HMAC(EVP_sha1(), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, len, hash, NULL); ++#elif defined(USE_CRYPTO_MBEDTLS) ++ mbedtls_md_hmac(mbedtls_md_info_from_type( ++ MBEDTLS_MD_SHA1), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, len, hash); ++#else ++ sha1_hmac(auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, len, hash); ++#endif ++ ++ return safe_memcmp(buf->array + len, hash, ONETIMEAUTH_BYTES); ++} ++ ++int ++ss_encrypt_all(buffer_t *plain, int method, int auth, size_t capacity) ++{ ++ if (method > TABLE) { ++ cipher_ctx_t evp; ++ cipher_context_init(&evp, method, 1); ++ ++ size_t iv_len = enc_iv_len; ++ int err = 1; ++ ++ static buffer_t tmp = { 0, 0, 0, NULL }; ++ brealloc(&tmp, iv_len + plain->len, capacity); ++ buffer_t *cipher = &tmp; ++ cipher->len = plain->len; ++ ++ uint8_t iv[MAX_IV_LENGTH]; ++ ++ rand_bytes(iv, iv_len); ++ cipher_context_set_iv(&evp, iv, iv_len, 1); ++ memcpy(cipher->array, iv, iv_len); ++ ++ if (auth) { ++ ss_onetimeauth(plain, iv, capacity); ++ cipher->len = plain->len; ++ } ++ ++ if (method >= SALSA20) { ++ crypto_stream_xor_ic((uint8_t *)(cipher->array + iv_len), ++ (const uint8_t *)plain->array, (uint64_t)(plain->len), ++ (const uint8_t *)iv, ++ 0, enc_key, method); ++ } else { ++ err = cipher_context_update(&evp, (uint8_t *)(cipher->array + iv_len), ++ &cipher->len, (const uint8_t *)plain->array, ++ plain->len); ++ } ++ ++ if (!err) { ++ bfree(plain); ++ cipher_context_release(&evp); ++ return -1; ++ } ++ ++#ifdef DEBUG ++ dump("PLAIN", plain->array, plain->len); ++ dump("CIPHER", cipher->array + iv_len, cipher->len); ++#endif ++ ++ cipher_context_release(&evp); ++ ++ brealloc(plain, iv_len + cipher->len, capacity); ++ memcpy(plain->array, cipher->array, iv_len + cipher->len); ++ plain->len = iv_len + cipher->len; ++ ++ return 0; ++ } else { ++ char *begin = plain->array; ++ char *ptr = plain->array; ++ while (ptr < begin + plain->len) { ++ *ptr = (char)enc_table[(uint8_t)*ptr]; ++ ptr++; ++ } ++ return 0; ++ } ++} ++ ++int ++ss_encrypt(buffer_t *plain, enc_ctx_t *ctx, size_t capacity) ++{ ++ if (ctx != NULL) { ++ static buffer_t tmp = { 0, 0, 0, NULL }; ++ ++ int err = 1; ++ size_t iv_len = 0; ++ if (!ctx->init) { ++ iv_len = enc_iv_len; ++ } ++ ++ brealloc(&tmp, iv_len + plain->len, capacity); ++ buffer_t *cipher = &tmp; ++ cipher->len = plain->len; ++ ++ if (!ctx->init) { ++ cipher_context_set_iv(&ctx->evp, ctx->evp.iv, iv_len, 1); ++ memcpy(cipher->array, ctx->evp.iv, iv_len); ++ ctx->counter = 0; ++ ctx->init = 1; ++ } ++ ++ if (enc_method >= SALSA20) { ++ int padding = ctx->counter % SODIUM_BLOCK_SIZE; ++ brealloc(cipher, iv_len + (padding + cipher->len) * 2, capacity); ++ if (padding) { ++ brealloc(plain, plain->len + padding, capacity); ++ memmove(plain->array + padding, plain->array, plain->len); ++ sodium_memzero(plain->array, padding); ++ } ++ crypto_stream_xor_ic((uint8_t *)(cipher->array + iv_len), ++ (const uint8_t *)plain->array, ++ (uint64_t)(plain->len + padding), ++ (const uint8_t *)ctx->evp.iv, ++ ctx->counter / SODIUM_BLOCK_SIZE, enc_key, ++ enc_method); ++ ctx->counter += plain->len; ++ if (padding) { ++ memmove(cipher->array + iv_len, ++ cipher->array + iv_len + padding, cipher->len); ++ } ++ } else { ++ err = ++ cipher_context_update(&ctx->evp, ++ (uint8_t *)(cipher->array + iv_len), ++ &cipher->len, (const uint8_t *)plain->array, ++ plain->len); ++ if (!err) { ++ return -1; ++ } ++ } ++ ++#ifdef DEBUG ++ dump("PLAIN", plain->array, plain->len); ++ dump("CIPHER", cipher->array + iv_len, cipher->len); ++#endif ++ ++ brealloc(plain, iv_len + cipher->len, capacity); ++ memcpy(plain->array, cipher->array, iv_len + cipher->len); ++ plain->len = iv_len + cipher->len; ++ ++ return 0; ++ } else { ++ char *begin = plain->array; ++ char *ptr = plain->array; ++ while (ptr < begin + plain->len) { ++ *ptr = (char)enc_table[(uint8_t)*ptr]; ++ ptr++; ++ } ++ return 0; ++ } ++} ++ ++int ++ss_decrypt_all(buffer_t *cipher, int method, int auth, size_t capacity) ++{ ++ if (method > TABLE) { ++ size_t iv_len = enc_iv_len; ++ int ret = 1; ++ ++ if (cipher->len <= iv_len) { ++ return -1; ++ } ++ ++ cipher_ctx_t evp; ++ cipher_context_init(&evp, method, 0); ++ ++ static buffer_t tmp = { 0, 0, 0, NULL }; ++ brealloc(&tmp, cipher->len, capacity); ++ buffer_t *plain = &tmp; ++ plain->len = cipher->len - iv_len; ++ ++ uint8_t iv[MAX_IV_LENGTH]; ++ memcpy(iv, cipher->array, iv_len); ++ cipher_context_set_iv(&evp, iv, iv_len, 0); ++ ++ if (method >= SALSA20) { ++ crypto_stream_xor_ic((uint8_t *)plain->array, ++ (const uint8_t *)(cipher->array + iv_len), ++ (uint64_t)(cipher->len - iv_len), ++ (const uint8_t *)iv, 0, enc_key, method); ++ } else { ++ ret = cipher_context_update(&evp, (uint8_t *)plain->array, &plain->len, ++ (const uint8_t *)(cipher->array + iv_len), ++ cipher->len - iv_len); ++ } ++ ++ if (auth || (plain->array[0] & ONETIMEAUTH_FLAG)) { ++ if (plain->len > ONETIMEAUTH_BYTES) { ++ ret = !ss_onetimeauth_verify(plain, iv); ++ if (ret) { ++ plain->len -= ONETIMEAUTH_BYTES; ++ } ++ } else { ++ ret = 0; ++ } ++ } ++ ++ if (!ret) { ++ bfree(cipher); ++ cipher_context_release(&evp); ++ return -1; ++ } ++ ++#ifdef DEBUG ++ dump("PLAIN", plain->array, plain->len); ++ dump("CIPHER", cipher->array + iv_len, cipher->len - iv_len); ++#endif ++ ++ cipher_context_release(&evp); ++ ++ brealloc(cipher, plain->len, capacity); ++ memcpy(cipher->array, plain->array, plain->len); ++ cipher->len = plain->len; ++ ++ return 0; ++ } else { ++ char *begin = cipher->array; ++ char *ptr = cipher->array; ++ while (ptr < begin + cipher->len) { ++ *ptr = (char)dec_table[(uint8_t)*ptr]; ++ ptr++; ++ } ++ return 0; ++ } ++} ++ ++int ++ss_decrypt(buffer_t *cipher, enc_ctx_t *ctx, size_t capacity) ++{ ++ if (ctx != NULL) { ++ static buffer_t tmp = { 0, 0, 0, NULL }; ++ ++ size_t iv_len = 0; ++ int err = 1; ++ ++ brealloc(&tmp, cipher->len, capacity); ++ buffer_t *plain = &tmp; ++ plain->len = cipher->len; ++ ++ if (!ctx->init) { ++ uint8_t iv[MAX_IV_LENGTH]; ++ iv_len = enc_iv_len; ++ plain->len -= iv_len; ++ ++ memcpy(iv, cipher->array, iv_len); ++ cipher_context_set_iv(&ctx->evp, iv, iv_len, 0); ++ ctx->counter = 0; ++ ctx->init = 1; ++ ++ if (enc_method > RC4) { ++ if (cache_key_exist(iv_cache, (char *)iv, iv_len)) { ++ bfree(cipher); ++ return -1; ++ } else { ++ cache_insert(iv_cache, (char *)iv, iv_len, NULL); ++ } ++ } ++ } ++ ++ if (enc_method >= SALSA20) { ++ int padding = ctx->counter % SODIUM_BLOCK_SIZE; ++ brealloc(plain, (plain->len + padding) * 2, capacity); ++ ++ if (padding) { ++ brealloc(cipher, cipher->len + padding, capacity); ++ memmove(cipher->array + iv_len + padding, cipher->array + iv_len, ++ cipher->len - iv_len); ++ sodium_memzero(cipher->array + iv_len, padding); ++ } ++ crypto_stream_xor_ic((uint8_t *)plain->array, ++ (const uint8_t *)(cipher->array + iv_len), ++ (uint64_t)(cipher->len - iv_len + padding), ++ (const uint8_t *)ctx->evp.iv, ++ ctx->counter / SODIUM_BLOCK_SIZE, enc_key, ++ enc_method); ++ ctx->counter += cipher->len - iv_len; ++ if (padding) { ++ memmove(plain->array, plain->array + padding, plain->len); ++ } ++ } else { ++ err = cipher_context_update(&ctx->evp, (uint8_t *)plain->array, &plain->len, ++ (const uint8_t *)(cipher->array + iv_len), ++ cipher->len - iv_len); ++ } ++ ++ if (!err) { ++ bfree(cipher); ++ return -1; ++ } ++ ++#ifdef DEBUG ++ dump("PLAIN", plain->array, plain->len); ++ dump("CIPHER", cipher->array + iv_len, cipher->len - iv_len); ++#endif ++ ++ brealloc(cipher, plain->len, capacity); ++ memcpy(cipher->array, plain->array, plain->len); ++ cipher->len = plain->len; ++ ++ return 0; ++ } else { ++ char *begin = cipher->array; ++ char *ptr = cipher->array; ++ while (ptr < begin + cipher->len) { ++ *ptr = (char)dec_table[(uint8_t)*ptr]; ++ ptr++; ++ } ++ return 0; ++ } ++} ++ ++void ++enc_ctx_init(int method, enc_ctx_t *ctx, int enc) ++{ ++ sodium_memzero(ctx, sizeof(enc_ctx_t)); ++ cipher_context_init(&ctx->evp, method, enc); ++ ++ if (enc) { ++ rand_bytes(ctx->evp.iv, enc_iv_len); ++ } ++} ++ ++void ++enc_key_init(int method, const char *pass) ++{ ++ if (method <= TABLE || method >= CIPHER_NUM) { ++ LOGE("enc_key_init(): Illegal method"); ++ return; ++ } ++ ++ // Initialize cache ++ cache_create(&iv_cache, 256, NULL); ++ ++#if defined(USE_CRYPTO_OPENSSL) ++ OpenSSL_add_all_algorithms(); ++#else ++ cipher_kt_t cipher_info; ++#endif ++ ++ cipher_t cipher; ++ memset(&cipher, 0, sizeof(cipher_t)); ++ ++ // Initialize sodium for random generator ++ if (sodium_init() == -1) { ++ FATAL("Failed to initialize sodium"); ++ } ++ ++ if (method == SALSA20 || method == CHACHA20 || method == CHACHA20IETF) { ++#if defined(USE_CRYPTO_OPENSSL) ++ cipher.info = NULL; ++ cipher.key_len = supported_ciphers_key_size[method]; ++ cipher.iv_len = supported_ciphers_iv_size[method]; ++#endif ++#if defined(USE_CRYPTO_POLARSSL) ++ cipher.info = &cipher_info; ++ cipher.info->base = NULL; ++ cipher.info->key_length = supported_ciphers_key_size[method] * 8; ++ cipher.info->iv_size = supported_ciphers_iv_size[method]; ++#endif ++#if defined(USE_CRYPTO_MBEDTLS) ++ // XXX: key_length changed to key_bitlen in mbed TLS 2.0.0 ++ cipher.info = &cipher_info; ++ cipher.info->base = NULL; ++ cipher.info->key_bitlen = supported_ciphers_key_size[method] * 8; ++ cipher.info->iv_size = supported_ciphers_iv_size[method]; ++#endif ++ } else { ++ cipher.info = (cipher_kt_t *)get_cipher_type(method); ++ } ++ ++ if (cipher.info == NULL && cipher.key_len == 0) { ++ do { ++#if defined(USE_CRYPTO_POLARSSL) && defined(USE_CRYPTO_APPLECC) ++ if (supported_ciphers_applecc[method] != kCCAlgorithmInvalid) { ++ cipher_info.base = NULL; ++ cipher_info.key_length = supported_ciphers_key_size[method] * 8; ++ cipher_info.iv_size = supported_ciphers_iv_size[method]; ++ cipher.info = (cipher_kt_t *)&cipher_info; ++ break; ++ } ++#endif ++#if defined(USE_CRYPTO_MBEDTLS) && defined(USE_CRYPTO_APPLECC) ++ // XXX: key_length changed to key_bitlen in mbed TLS 2.0.0 ++ if (supported_ciphers_applecc[method] != kCCAlgorithmInvalid) { ++ cipher_info.base = NULL; ++ cipher_info.key_bitlen = supported_ciphers_key_size[method] * 8; ++ cipher_info.iv_size = supported_ciphers_iv_size[method]; ++ cipher.info = (cipher_kt_t *)&cipher_info; ++ break; ++ } ++#endif ++ LOGE("Cipher %s not found in crypto library", supported_ciphers[method]); ++ FATAL("Cannot initialize cipher"); ++ } while (0); ++ } ++ ++ const digest_type_t *md = get_digest_type("MD5"); ++ if (md == NULL) { ++ FATAL("MD5 Digest not found in crypto library"); ++ } ++ ++ enc_key_len = bytes_to_key(&cipher, md, (const uint8_t *)pass, enc_key); ++ ++ if (enc_key_len == 0) { ++ FATAL("Cannot generate key and IV"); ++ } ++ if (method == RC4_MD5 || method == RC4_MD5_6) { ++ enc_iv_len = supported_ciphers_iv_size[method]; ++ } else { ++ enc_iv_len = cipher_iv_size(&cipher); ++ } ++ enc_method = method; ++} ++ ++int ++enc_init(const char *pass, const char *method) ++{ ++ int m = TABLE; ++ if (method != NULL) { ++ for (m = TABLE; m < CIPHER_NUM; m++) ++ if (strcmp(method, supported_ciphers[m]) == 0) { ++ break; ++ } ++ if (m >= CIPHER_NUM) { ++ LOGE("Invalid cipher name: %s, use rc4-md5 instead", method); ++ m = RC4_MD5; ++ } ++ } ++ if (m == TABLE) { ++ enc_table_init(pass); ++ } else { ++ enc_key_init(m, pass); ++ } ++ return m; ++} ++ ++int ++ss_check_hash(buffer_t *buf, chunk_t *chunk, enc_ctx_t *ctx, size_t capacity) ++{ ++ int i, j, k; ++ ssize_t blen = buf->len; ++ uint32_t cidx = chunk->idx; ++ ++ brealloc(chunk->buf, chunk->len + blen, capacity); ++ brealloc(buf, chunk->len + blen, capacity); ++ ++ for (i = 0, j = 0, k = 0; i < blen; i++) { ++ chunk->buf->array[cidx++] = buf->array[k++]; ++ ++ if (cidx == CLEN_BYTES) { ++ uint16_t clen = ntohs(*((uint16_t *)chunk->buf->array)); ++ brealloc(chunk->buf, clen + AUTH_BYTES, capacity); ++ chunk->len = clen; ++ } ++ ++ if (cidx == chunk->len + AUTH_BYTES) { ++ // Compare hash ++ uint8_t hash[ONETIMEAUTH_BYTES * 2]; ++ uint8_t key[MAX_IV_LENGTH + sizeof(uint32_t)]; ++ ++ uint32_t c = htonl(chunk->counter); ++ memcpy(key, ctx->evp.iv, enc_iv_len); ++ memcpy(key + enc_iv_len, &c, sizeof(uint32_t)); ++#if defined(USE_CRYPTO_OPENSSL) ++ HMAC(EVP_sha1(), key, enc_iv_len + sizeof(uint32_t), ++ (uint8_t *)chunk->buf->array + AUTH_BYTES, chunk->len, hash, NULL); ++#elif defined(USE_CRYPTO_MBEDTLS) ++ mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), key, enc_iv_len + sizeof(uint32_t), ++ (uint8_t *)chunk->buf->array + AUTH_BYTES, chunk->len, hash); ++#else ++ sha1_hmac(key, enc_iv_len + sizeof(uint32_t), ++ (uint8_t *)chunk->buf->array + AUTH_BYTES, chunk->len, hash); ++#endif ++ ++ if (safe_memcmp(hash, chunk->buf->array + CLEN_BYTES, ONETIMEAUTH_BYTES) != 0) { ++ return 0; ++ } ++ ++ // Copy chunk back to buffer ++ memmove(buf->array + j + chunk->len, buf->array + k, blen - i - 1); ++ memcpy(buf->array + j, chunk->buf->array + AUTH_BYTES, chunk->len); ++ ++ // Reset the base offset ++ j += chunk->len; ++ k = j; ++ cidx = 0; ++ chunk->counter++; ++ } ++ } ++ ++ buf->len = j; ++ chunk->idx = cidx; ++ return 1; ++} ++ ++int ++ss_gen_hash(buffer_t *buf, uint32_t *counter, enc_ctx_t *ctx, size_t capacity) ++{ ++ ssize_t blen = buf->len; ++ uint16_t chunk_len = htons((uint16_t)blen); ++ uint8_t hash[ONETIMEAUTH_BYTES * 2]; ++ uint8_t key[MAX_IV_LENGTH + sizeof(uint32_t)]; ++ uint32_t c = htonl(*counter); ++ ++ brealloc(buf, AUTH_BYTES + blen, capacity); ++ memcpy(key, ctx->evp.iv, enc_iv_len); ++ memcpy(key + enc_iv_len, &c, sizeof(uint32_t)); ++#if defined(USE_CRYPTO_OPENSSL) ++ HMAC(EVP_sha1(), key, enc_iv_len + sizeof(uint32_t), (uint8_t *)buf->array, blen, hash, NULL); ++#elif defined(USE_CRYPTO_MBEDTLS) ++ mbedtls_md_hmac(mbedtls_md_info_from_type( ++ MBEDTLS_MD_SHA1), key, enc_iv_len + sizeof(uint32_t), (uint8_t *)buf->array, blen, hash); ++#else ++ sha1_hmac(key, enc_iv_len + sizeof(uint32_t), (uint8_t *)buf->array, blen, hash); ++#endif ++ ++ memmove(buf->array + AUTH_BYTES, buf->array, blen); ++ memcpy(buf->array + CLEN_BYTES, hash, ONETIMEAUTH_BYTES); ++ memcpy(buf->array, &chunk_len, CLEN_BYTES); ++ ++ *counter = *counter + 1; ++ buf->len = blen + AUTH_BYTES; ++ ++ return 0; ++} +diff --git a/server/encrypt.h b/server/encrypt.h +new file mode 100644 +index 0000000..3bb7940 +--- /dev/null ++++ b/server/encrypt.h +@@ -0,0 +1,222 @@ ++/* ++ * encrypt.h - Define the enryptor's interface ++ * ++ * Copyright (C) 2013 - 2016, Max Lv ++ * ++ * This file is part of the shadowsocks-libev. ++ * ++ * shadowsocks-libev 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 3 of the License, or ++ * (at your option) any later version. ++ * ++ * shadowsocks-libev 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 shadowsocks-libev; see the file COPYING. If not, see ++ * . ++ */ ++ ++#ifndef _ENCRYPT_H ++#define _ENCRYPT_H ++ ++#ifndef __MINGW32__ ++#include ++#else ++ ++#ifdef max ++#undef max ++#endif ++ ++#ifdef min ++#undef min ++#endif ++ ++#endif ++ ++#include ++#include ++#include ++#include ++ ++#if defined(USE_CRYPTO_OPENSSL) ++ ++#include ++#include ++#include ++typedef EVP_CIPHER cipher_kt_t; ++typedef EVP_CIPHER_CTX cipher_evp_t; ++typedef EVP_MD digest_type_t; ++#define MAX_KEY_LENGTH EVP_MAX_KEY_LENGTH ++#define MAX_IV_LENGTH EVP_MAX_IV_LENGTH ++#define MAX_MD_SIZE EVP_MAX_MD_SIZE ++ ++#elif defined(USE_CRYPTO_POLARSSL) ++ ++#include ++#include ++typedef cipher_info_t cipher_kt_t; ++typedef cipher_context_t cipher_evp_t; ++typedef md_info_t digest_type_t; ++#define MAX_KEY_LENGTH 64 ++#define MAX_IV_LENGTH POLARSSL_MAX_IV_LENGTH ++#define MAX_MD_SIZE POLARSSL_MD_MAX_SIZE ++ ++#elif defined(USE_CRYPTO_MBEDTLS) ++ ++#include ++#include ++typedef mbedtls_cipher_info_t cipher_kt_t; ++typedef mbedtls_cipher_context_t cipher_evp_t; ++typedef mbedtls_md_info_t digest_type_t; ++#define MAX_KEY_LENGTH 64 ++#define MAX_IV_LENGTH MBEDTLS_MAX_IV_LENGTH ++#define MAX_MD_SIZE MBEDTLS_MD_MAX_SIZE ++ ++/* we must have MBEDTLS_CIPHER_MODE_CFB defined */ ++#if !defined(MBEDTLS_CIPHER_MODE_CFB) ++#error Cipher Feedback mode a.k.a CFB not supported by your mbed TLS. ++#endif ++ ++#endif ++ ++#ifdef USE_CRYPTO_APPLECC ++ ++#include ++ ++#define kCCAlgorithmInvalid UINT32_MAX ++#define kCCContextValid 0 ++#define kCCContextInvalid -1 ++ ++typedef struct { ++ CCCryptorRef cryptor; ++ int valid; ++ CCOperation encrypt; ++ CCAlgorithm cipher; ++ CCMode mode; ++ CCPadding padding; ++ uint8_t iv[MAX_IV_LENGTH]; ++ uint8_t key[MAX_KEY_LENGTH]; ++ size_t iv_len; ++ size_t key_len; ++} cipher_cc_t; ++ ++#endif ++ ++typedef struct { ++ cipher_evp_t *evp; ++#ifdef USE_CRYPTO_APPLECC ++ cipher_cc_t cc; ++#endif ++ uint8_t iv[MAX_IV_LENGTH]; ++} cipher_ctx_t; ++ ++typedef struct { ++ cipher_kt_t *info; ++ size_t iv_len; ++ size_t key_len; ++} cipher_t; ++ ++#ifdef HAVE_STDINT_H ++#include ++#elif HAVE_INTTYPES_H ++#include ++#endif ++ ++#define SODIUM_BLOCK_SIZE 64 ++ ++enum crpher_index { ++ NONE = -1, ++ TABLE = 0, ++ RC4, ++ RC4_MD5_6, ++ RC4_MD5, ++ AES_128_CFB, ++ AES_192_CFB, ++ AES_256_CFB, ++ AES_128_CTR, ++ AES_192_CTR, ++ AES_256_CTR, ++ BF_CFB, ++ CAMELLIA_128_CFB, ++ CAMELLIA_192_CFB, ++ CAMELLIA_256_CFB, ++ CAST5_CFB, ++ DES_CFB, ++ IDEA_CFB, ++ RC2_CFB, ++ SEED_CFB, ++ SALSA20, ++ CHACHA20, ++ CHACHA20IETF, ++ CIPHER_NUM, ++}; ++ ++#define ONETIMEAUTH_FLAG 0x10 ++#define ADDRTYPE_MASK 0xEF ++ ++#define ONETIMEAUTH_BYTES 10U ++#define MD5_BYTES 16U ++#define SHA1_BYTES 20U ++#define CLEN_BYTES 2U ++#define AUTH_BYTES (ONETIMEAUTH_BYTES + CLEN_BYTES) ++ ++#define min(a, b) (((a) < (b)) ? (a) : (b)) ++#define max(a, b) (((a) > (b)) ? (a) : (b)) ++ ++typedef struct buffer { ++ size_t idx; ++ size_t len; ++ size_t capacity; ++ char *array; ++} buffer_t; ++ ++typedef struct chunk { ++ uint32_t idx; ++ uint32_t len; ++ uint32_t counter; ++ buffer_t *buf; ++} chunk_t; ++ ++typedef struct enc_ctx { ++ uint8_t init; ++ uint64_t counter; ++ cipher_ctx_t evp; ++} enc_ctx_t; ++ ++void bytes_to_key_with_size(const char *pass, size_t len, uint8_t *md, size_t md_size); ++ ++int ss_encrypt_all(buffer_t *plaintext, int method, int auth, size_t capacity); ++int ss_decrypt_all(buffer_t *ciphertext, int method, int auth, size_t capacity); ++int ss_encrypt(buffer_t *plaintext, enc_ctx_t *ctx, size_t capacity); ++int ss_decrypt(buffer_t *ciphertext, enc_ctx_t *ctx, size_t capacity); ++ ++void enc_ctx_init(int method, enc_ctx_t *ctx, int enc); ++int enc_init(const char *pass, const char *method); ++int enc_get_iv_len(void); ++uint8_t* enc_get_key(void); ++int enc_get_key_len(void); ++void cipher_context_release(cipher_ctx_t *evp); ++unsigned char *enc_md5(const unsigned char *d, size_t n, unsigned char *md); ++ ++int ss_md5_hmac(char *auth, char *msg, int msg_len, uint8_t *iv); ++int ss_md5_hmac_with_key(char *auth, char *msg, int msg_len, uint8_t *auth_key, int key_len); ++int ss_md5_hash_func(char *auth, char *msg, int msg_len); ++int ss_sha1_hmac(char *auth, char *msg, int msg_len, uint8_t *iv); ++int ss_sha1_hmac_with_key(char *auth, char *msg, int msg_len, uint8_t *auth_key, int key_len); ++int ss_sha1_hash_func(char *auth, char *msg, int msg_len); ++int ss_aes_128_cbc(char *encrypt, char *out_data, char *key); ++int ss_onetimeauth(buffer_t *buf, uint8_t *iv, size_t capacity); ++int ss_onetimeauth_verify(buffer_t *buf, uint8_t *iv); ++ ++int ss_check_hash(buffer_t *buf, chunk_t *chunk, enc_ctx_t *ctx, size_t capacity); ++int ss_gen_hash(buffer_t *buf, uint32_t *counter, enc_ctx_t *ctx, size_t capacity); ++ ++int balloc(buffer_t *ptr, size_t capacity); ++int brealloc(buffer_t *ptr, size_t len, size_t capacity); ++void bfree(buffer_t *ptr); ++ ++#endif // _ENCRYPT_H +diff --git a/server/http.c b/server/http.c +new file mode 100644 +index 0000000..3bd4a32 +--- /dev/null ++++ b/server/http.c +@@ -0,0 +1,152 @@ ++/* ++ * Copyright (c) 2011 and 2012, Dustin Lundquist ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include /* malloc() */ ++#include /* strncpy() */ ++#include /* strncasecmp() */ ++#include /* isblank() */ ++ ++#include "http.h" ++#include "protocol.h" ++ ++#define SERVER_NAME_LEN 256 ++ ++static int parse_http_header(const char *, size_t, char **); ++static int get_header(const char *, const char *, int, char **); ++static int next_header(const char **, int *); ++ ++static const protocol_t http_protocol_st = { ++ .default_port = 80, ++ .parse_packet = &parse_http_header, ++}; ++const protocol_t *const http_protocol = &http_protocol_st; ++ ++/* ++ * Parses a HTTP request for the Host: header ++ * ++ * Returns: ++ * >=0 - length of the hostname and updates *hostname ++ * caller is responsible for freeing *hostname ++ * -1 - Incomplete request ++ * -2 - No Host header included in this request ++ * -3 - Invalid hostname pointer ++ * -4 - malloc failure ++ * < -4 - Invalid HTTP request ++ * ++ */ ++static int ++parse_http_header(const char *data, size_t data_len, char **hostname) ++{ ++ int result, i; ++ ++ if (hostname == NULL) ++ return -3; ++ ++ if (data_len == 0) ++ return -1; ++ ++ result = get_header("Host:", data, data_len, hostname); ++ if (result < 0) ++ return result; ++ ++ /* ++ * if the user specifies the port in the request, it is included here. ++ * Host: example.com:80 ++ * so we trim off port portion ++ */ ++ for (i = result - 1; i >= 0; i--) ++ if ((*hostname)[i] == ':') { ++ (*hostname)[i] = '\0'; ++ result = i; ++ break; ++ } ++ ++ return result; ++} ++ ++static int ++get_header(const char *header, const char *data, int data_len, char **value) ++{ ++ int len, header_len; ++ ++ header_len = strlen(header); ++ ++ /* loop through headers stopping at first blank line */ ++ while ((len = next_header(&data, &data_len)) != 0) ++ if (len > header_len && strncasecmp(header, data, header_len) == 0) { ++ /* Eat leading whitespace */ ++ while (header_len < len && isblank(data[header_len])) ++ header_len++; ++ ++ *value = malloc(len - header_len + 1); ++ if (*value == NULL) ++ return -4; ++ ++ strncpy(*value, data + header_len, len - header_len); ++ (*value)[len - header_len] = '\0'; ++ ++ return len - header_len; ++ } ++ ++ /* If there is no data left after reading all the headers then we do not ++ * have a complete HTTP request, there must be a blank line */ ++ if (data_len == 0) ++ return -1; ++ ++ return -2; ++} ++ ++static int ++next_header(const char **data, int *len) ++{ ++ int header_len; ++ ++ /* perhaps we can optimize this to reuse the value of header_len, rather ++ * than scanning twice. ++ * Walk our data stream until the end of the header */ ++ while (*len > 2 && (*data)[0] != '\r' && (*data)[1] != '\n') { ++ (*len)--; ++ (*data)++; ++ } ++ ++ /* advanced past the pair */ ++ *data += 2; ++ *len -= 2; ++ ++ /* Find the length of the next header */ ++ header_len = 0; ++ while (*len > header_len + 1 ++ && (*data)[header_len] != '\r' ++ && (*data)[header_len + 1] != '\n') ++ header_len++; ++ ++ return header_len; ++} +diff --git a/server/http.h b/server/http.h +new file mode 100644 +index 0000000..914815a +--- /dev/null ++++ b/server/http.h +@@ -0,0 +1,34 @@ ++/* ++ * Copyright (c) 2011 and 2012, Dustin Lundquist ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ */ ++#ifndef HTTP_H ++#define HTTP_H ++ ++#include ++#include "protocol.h" ++ ++const protocol_t *const http_protocol; ++ ++#endif +diff --git a/server/http_simple.c b/server/http_simple.c +new file mode 100644 +index 0000000..c1e34ee +--- /dev/null ++++ b/server/http_simple.c +@@ -0,0 +1,625 @@ ++ ++#include "http_simple.h" ++ ++static char* g_useragent[] = { ++ "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0", ++ "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:40.0) Gecko/20100101 Firefox/44.0", ++ "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36", ++ "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", ++ "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:35.0) Gecko/20100101 Firefox/35.0", ++ "Mozilla/5.0 (compatible; WOW64; MSIE 10.0; Windows NT 6.2)", ++ "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", ++ "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.3; Trident/7.0; .NET4.0E; .NET4.0C)", ++ "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko", ++ "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", ++ "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", ++ "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", ++}; ++ ++static int g_useragent_index = -1; ++ ++typedef struct http_simple_local_data { ++ int has_sent_header; ++ int has_recv_header; ++ char *encode_buffer; ++ int host_matched; ++ char *recv_buffer; ++ int recv_buffer_size; ++}http_simple_local_data; ++ ++void http_simple_local_data_init(http_simple_local_data* local) { ++ local->has_sent_header = 0; ++ local->has_recv_header = 0; ++ local->encode_buffer = NULL; ++ ++ local->recv_buffer = malloc(0); ++ local->recv_buffer_size = 0; ++ ++ local->host_matched = 0; ++ ++ if (g_useragent_index == -1) { ++ g_useragent_index = xorshift128plus() % (sizeof(g_useragent) / sizeof(*g_useragent)); ++ } ++} ++ ++obfs * http_simple_new_obfs() { ++ obfs * self = new_obfs(); ++ self->l_data = malloc(sizeof(http_simple_local_data)); ++ http_simple_local_data_init((http_simple_local_data*)self->l_data); ++ return self; ++} ++ ++void http_simple_dispose(obfs *self) { ++ http_simple_local_data *local = (http_simple_local_data*)self->l_data; ++ if (local->encode_buffer != NULL) { ++ free(local->encode_buffer); ++ local->encode_buffer = NULL; ++ } ++ free(local); ++ dispose_obfs(self); ++} ++ ++char http_simple_hex(char c) { ++ if (c < 10) return c + '0'; ++ return c - 10 + 'a'; ++} ++ ++int get_data_from_http_header(char *data, char **outdata) { ++ char *delim = "\r\n"; ++ char *delim_hex = "%"; ++ int outlength = 0; ++ ++ char *buf = *outdata; ++ char *p_line; ++ p_line = strtok(data, delim); ++ ++ //while(p_line) ++ { ++ char *p_hex; ++ ++ p_hex = strtok(p_line, delim_hex); ++ ++ while((p_hex = strtok(NULL, delim_hex))) ++ { ++ char hex = 0; ++ ++ if(strlen(p_hex) <= 0) ++ { ++ continue; ++ } ++ ++ if(strlen(p_hex) > 2) ++ { ++ char *c_hex = (char*)malloc(2); ++ memcpy(c_hex, p_hex, 2); ++ hex = (char)strtol(c_hex, NULL, 16); ++ free(c_hex); ++ } ++ else ++ { ++ hex = (char)strtol(p_hex, NULL, 16); ++ } ++ ++ outlength += 1; ++ buf = (char*)realloc(buf, outlength); ++ buf[outlength - 1] = hex; ++ } ++ ++ //p_line = strtok(p_line, delim); ++ } ++ return outlength; ++} ++ ++void get_host_from_http_header(char *data, char **host) { ++ char* data_begin = strstr(data, "Host: "); ++ ++ if(data_begin == NULL) ++ { ++ return; ++ } ++ ++ data_begin += 6; ++ char* data_end = strstr(data_begin, "\r\n"); ++ char* data_end_port = strstr(data_begin, ":"); ++ ++ int host_length = 0; ++ ++ if(data_end_port != NULL) ++ { ++ host_length = data_end_port - data_begin; ++ } ++ else ++ { ++ host_length = data_end - data_begin; ++ } ++ ++ if(host_length <= 0) ++ { ++ return; ++ } ++ ++ memset(*host, 0x00, 1024); ++ memcpy(*host, data_begin, host_length); ++} ++ ++void http_simple_encode_head(http_simple_local_data *local, char *data, int datalength) { ++ if (local->encode_buffer == NULL) { ++ local->encode_buffer = (char*)malloc(datalength * 3 + 1); ++ } ++ int pos = 0; ++ for (; pos < datalength; ++pos) { ++ local->encode_buffer[pos * 3] = '%'; ++ local->encode_buffer[pos * 3 + 1] = http_simple_hex(((unsigned char)data[pos] >> 4)); ++ local->encode_buffer[pos * 3 + 2] = http_simple_hex(data[pos] & 0xF); ++ } ++ local->encode_buffer[pos * 3] = 0; ++} ++ ++int http_simple_client_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity) { ++ char *encryptdata = *pencryptdata; ++ http_simple_local_data *local = (http_simple_local_data*)self->l_data; ++ if (local->has_sent_header) { ++ return datalength; ++ } ++ char hosts[1024]; ++ char * phost[128]; ++ int host_num = 0; ++ int pos; ++ char hostport[128]; ++ int head_size = self->server.head_len + (xorshift128plus() & 0x3F); ++ int outlength; ++ char * out_buffer = (char*)malloc(datalength + 2048); ++ char * body_buffer = NULL; ++ if (head_size > datalength) ++ head_size = datalength; ++ http_simple_encode_head(local, encryptdata, head_size); ++ if (self->server.param && strlen(self->server.param) == 0) ++ self->server.param = NULL; ++ strncpy(hosts, self->server.param ? self->server.param : self->server.host, sizeof hosts); ++ phost[host_num++] = hosts; ++ for (pos = 0; hosts[pos]; ++pos) { ++ if (hosts[pos] == ',') { ++ phost[host_num++] = &hosts[pos + 1]; ++ hosts[pos] = 0; ++ } else if (hosts[pos] == '#') { ++ char * body_pointer = &hosts[pos + 1]; ++ char * p; ++ int trans_char = 0; ++ p = body_buffer = (char*)malloc(2048); ++ for ( ; *body_pointer; ++body_pointer) { ++ if (*body_pointer == '\\') { ++ trans_char = 1; ++ continue; ++ } else if (*body_pointer == '\n') { ++ *p = '\r'; ++ *++p = '\n'; ++ continue; ++ } ++ if (trans_char) { ++ if (*body_pointer == '\\' ) { ++ *p = '\\'; ++ } else if (*body_pointer == 'n' ) { ++ *p = '\r'; ++ *++p = '\n'; ++ } else { ++ *p = '\\'; ++ *p = *body_pointer; ++ } ++ trans_char = 0; ++ } else { ++ *p = *body_pointer; ++ } ++ ++p; ++ } ++ *p = 0; ++ hosts[pos] = 0; ++ break; ++ } ++ } ++ host_num = xorshift128plus() % host_num; ++ if (self->server.port == 80) ++ sprintf(hostport, "%s", phost[host_num]); ++ else ++ sprintf(hostport, "%s:%d", phost[host_num], self->server.port); ++ if (body_buffer) { ++ sprintf(out_buffer, ++ "GET /%s HTTP/1.1\r\n" ++ "Host: %s\r\n" ++ "%s\r\n\r\n", ++ local->encode_buffer, ++ hostport, ++ body_buffer); ++ } else { ++ sprintf(out_buffer, ++ "GET /%s HTTP/1.1\r\n" ++ "Host: %s\r\n" ++ "User-Agent: %s\r\n" ++ "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" ++ "Accept-Language: en-US,en;q=0.8\r\n" ++ "Accept-Encoding: gzip, deflate\r\n" ++ "DNT: 1\r\n" ++ "Connection: keep-alive\r\n" ++ "\r\n", ++ local->encode_buffer, ++ hostport, ++ g_useragent[g_useragent_index] ++ ); ++ } ++ //LOGI("http header: %s", out_buffer); ++ outlength = strlen(out_buffer); ++ memmove(out_buffer + outlength, encryptdata + head_size, datalength - head_size); ++ outlength += datalength - head_size; ++ local->has_sent_header = 1; ++ if (*capacity < outlength) { ++ *pencryptdata = (char*)realloc(*pencryptdata, *capacity = outlength * 2); ++ encryptdata = *pencryptdata; ++ } ++ memmove(encryptdata, out_buffer, outlength); ++ free(out_buffer); ++ if (body_buffer != NULL) ++ free(body_buffer); ++ if (local->encode_buffer != NULL) { ++ free(local->encode_buffer); ++ local->encode_buffer = NULL; ++ } ++ return outlength; ++} ++ ++int http_simple_server_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity) { ++ char *encryptdata = *pencryptdata; ++ http_simple_local_data *local = (http_simple_local_data*)self->l_data; ++ if (local->has_sent_header) { ++ return datalength; ++ } ++ int outlength; ++ char * out_buffer = (char*)malloc(datalength + 2048); ++ ++ time_t now; ++ struct tm *tm_now; ++ char datetime[200]; ++ ++ time(&now); ++ tm_now = localtime(&now); ++ strftime(datetime, 200, "%a, %d %b %Y %H:%M:%S GMT", tm_now); ++ ++ sprintf(out_buffer, ++ "HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nContent-Encoding: gzip\r\nContent-Type: text/html\r\nDate: " ++ "%s" ++ "\r\nServer: nginx\r\nVary: Accept-Encoding\r\n\r\n", ++ datetime); ++ ++ outlength = strlen(out_buffer); ++ memmove(out_buffer + outlength, encryptdata, datalength); ++ outlength += datalength; ++ ++ local->has_sent_header = 1; ++ if (*capacity < outlength) { ++ *pencryptdata = (char*)realloc(*pencryptdata, *capacity = outlength * 2); ++ encryptdata = *pencryptdata; ++ } ++ memmove(encryptdata, out_buffer, outlength); ++ free(out_buffer); ++ return outlength; ++} ++ ++int http_simple_client_decode(obfs *self, char **pencryptdata, int datalength, size_t* capacity, int *needsendback) { ++ char *encryptdata = *pencryptdata; ++ http_simple_local_data *local = (http_simple_local_data*)self->l_data; ++ *needsendback = 0; ++ if (local->has_recv_header) { ++ return datalength; ++ } ++ char* data_begin = strstr(encryptdata, "\r\n\r\n"); ++ if (data_begin) { ++ int outlength; ++ data_begin += 4; ++ local->has_recv_header = 1; ++ outlength = datalength - (data_begin - encryptdata); ++ memmove(encryptdata, data_begin, outlength); ++ return outlength; ++ } else { ++ return 0; ++ } ++} ++ ++int http_simple_server_decode(obfs *self, char **pencryptdata, int datalength, size_t* capacity, int *needsendback) { ++ char *encryptdata = *pencryptdata; ++ http_simple_local_data *local = (http_simple_local_data*)self->l_data; ++ *needsendback = 0; ++ if (local->has_recv_header) { ++ return datalength; ++ } ++ ++ if(datalength != 0) ++ { ++ local->recv_buffer = (char*)realloc(local->recv_buffer, local->recv_buffer_size + datalength); ++ memmove(local->recv_buffer + local->recv_buffer_size, encryptdata, datalength); ++ local->recv_buffer_size += datalength; ++ ++ int outlength = local->recv_buffer_size; ++ if (*capacity < outlength) { ++ *pencryptdata = (char*)realloc(*pencryptdata, *capacity = outlength * 2); ++ encryptdata = *pencryptdata; ++ } ++ memcpy(encryptdata, local->recv_buffer, local->recv_buffer_size); ++ } ++ ++ if(local->recv_buffer_size > 10) ++ { ++ if(strstr(local->recv_buffer, "GET /") == local->recv_buffer || strstr(local->recv_buffer, "POST /") == local->recv_buffer) ++ { ++ if(local->recv_buffer_size > 65536) ++ { ++ free(local->recv_buffer); ++ local->recv_buffer = malloc(0); ++ local->recv_buffer_size = 0; ++ local->has_sent_header = 1; ++ local->has_recv_header = 1; ++ LOGE("http_simple: over size"); ++ return -1; ++ } ++ } ++ else ++ { ++ free(local->recv_buffer); ++ local->recv_buffer = malloc(0); ++ local->recv_buffer_size = 0; ++ local->has_sent_header = 1; ++ local->has_recv_header = 1; ++ LOGE("http_simple: not match begin"); ++ return -1; ++ } ++ } ++ else ++ { ++ LOGE("http_simple: too short"); ++ local->has_sent_header = 1; ++ local->has_recv_header = 1; ++ return -1; ++ } ++ ++ char* data_begin = strstr(encryptdata, "\r\n\r\n"); ++ if (data_begin) { ++ int outlength; ++ char *ret_buf = (char*)malloc(*capacity); ++ memset(ret_buf, 0x00, *capacity); ++ int ret_buf_len = 0; ++ ret_buf_len = get_data_from_http_header(encryptdata, &ret_buf); ++ ++ if (self->server.param && strlen(self->server.param) == 0) ++ { ++ self->server.param = NULL; ++ } ++ else ++ { ++ if(local->host_matched == 0) ++ { ++ char *host = (char*)malloc(1024); ++ get_host_from_http_header(local->recv_buffer, &host); ++ char hosts[1024]; ++ char * phost[128]; ++ int host_num = 0; ++ int pos = 0; ++ int is_match = 0; ++ char * body_buffer = NULL; ++ strncpy(hosts, self->server.param, sizeof hosts); ++ phost[host_num++] = hosts; ++ ++ for (pos = 0; hosts[pos]; ++pos) { ++ if (hosts[pos] == ',') { ++ phost[host_num++] = &hosts[pos + 1]; ++ hosts[pos] = 0; ++ } else if (hosts[pos] == '#') { ++ char * body_pointer = &hosts[pos + 1]; ++ char * p; ++ int trans_char = 0; ++ p = body_buffer = (char*)malloc(2048); ++ for ( ; *body_pointer; ++body_pointer) { ++ if (*body_pointer == '\\') { ++ trans_char = 1; ++ continue; ++ } else if (*body_pointer == '\n') { ++ *p = '\r'; ++ *++p = '\n'; ++ continue; ++ } ++ if (trans_char) { ++ if (*body_pointer == '\\' ) { ++ *p = '\\'; ++ } else if (*body_pointer == 'n' ) { ++ *p = '\r'; ++ *++p = '\n'; ++ } else { ++ *p = '\\'; ++ *p = *body_pointer; ++ } ++ trans_char = 0; ++ } else { ++ *p = *body_pointer; ++ } ++ ++p; ++ } ++ *p = 0; ++ hosts[pos] = 0; ++ break; ++ } ++ } ++ ++ ++ for(pos = 0; pos < host_num; pos++) ++ { ++ if(strcmp(phost[pos], host) == 0) ++ { ++ is_match = 1; ++ local->host_matched = 1; ++ } ++ } ++ ++ if(is_match == 0) ++ { ++ free(local->recv_buffer); ++ local->recv_buffer = malloc(0); ++ local->recv_buffer_size = 0; ++ local->has_sent_header = 1; ++ local->has_recv_header = 1; ++ LOGE("http_simple: not match host, host: %s", host); ++ return -1; ++ } ++ ++ free(host); ++ } ++ } ++ ++ if(ret_buf_len <= 0) ++ { ++ return -1; ++ } ++ ++ data_begin += 4; ++ local->has_recv_header = 1; ++ ++ ret_buf = (char*)realloc(ret_buf, ret_buf_len + datalength - (data_begin - encryptdata)); ++ outlength = ret_buf_len + datalength - (data_begin - encryptdata); ++ ++ memcpy(ret_buf + ret_buf_len, data_begin, datalength - (data_begin - encryptdata)); ++ ++ if (*capacity < outlength) { ++ *pencryptdata = (char*)realloc(*pencryptdata, *capacity = outlength * 2); ++ encryptdata = *pencryptdata; ++ } ++ ++ memcpy(encryptdata, ret_buf, outlength); ++ free(ret_buf); ++ return outlength; ++ } else { ++ return 0; ++ } ++} ++ ++void boundary(char result[]) ++{ ++ char *str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; ++ int i,lstr; ++ char ss[3] = {0}; ++ lstr = strlen(str); ++ srand((unsigned int)time((time_t *)NULL)); ++ for(i = 0; i < 32; ++i) ++ { ++ sprintf(ss, "%c", str[(rand()%lstr)]); ++ strcat(result, ss); ++ } ++} ++ ++int http_post_client_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity) { ++ char *encryptdata = *pencryptdata; ++ http_simple_local_data *local = (http_simple_local_data*)self->l_data; ++ if (local->has_sent_header) { ++ return datalength; ++ } ++ char hosts[1024]; ++ char * phost[128]; ++ int host_num = 0; ++ int pos; ++ char hostport[128]; ++ int head_size = self->server.head_len + (xorshift128plus() & 0x3F); ++ int outlength; ++ char * out_buffer = (char*)malloc(datalength + 2048); ++ char * body_buffer = NULL; ++ if (head_size > datalength) ++ head_size = datalength; ++ http_simple_encode_head(local, encryptdata, head_size); ++ if (self->server.param && strlen(self->server.param) == 0) ++ self->server.param = NULL; ++ strncpy(hosts, self->server.param ? self->server.param : self->server.host, sizeof hosts); ++ phost[host_num++] = hosts; ++ for (pos = 0; hosts[pos]; ++pos) { ++ if (hosts[pos] == ',') { ++ phost[host_num++] = &hosts[pos + 1]; ++ hosts[pos] = 0; ++ } else if (hosts[pos] == '#') { ++ char * body_pointer = &hosts[pos + 1]; ++ char * p; ++ int trans_char = 0; ++ p = body_buffer = (char*)malloc(2048); ++ for ( ; *body_pointer; ++body_pointer) { ++ if (*body_pointer == '\\') { ++ trans_char = 1; ++ continue; ++ } else if (*body_pointer == '\n') { ++ *p = '\r'; ++ *++p = '\n'; ++ continue; ++ } ++ if (trans_char) { ++ if (*body_pointer == '\\' ) { ++ *p = '\\'; ++ } else if (*body_pointer == 'n' ) { ++ *p = '\r'; ++ *++p = '\n'; ++ } else { ++ *p = '\\'; ++ *p = *body_pointer; ++ } ++ trans_char = 0; ++ } else { ++ *p = *body_pointer; ++ } ++ ++p; ++ } ++ *p = 0; ++ hosts[pos] = 0; ++ break; ++ } ++ } ++ host_num = xorshift128plus() % host_num; ++ if (self->server.port == 80) ++ sprintf(hostport, "%s", phost[host_num]); ++ else ++ sprintf(hostport, "%s:%d", phost[host_num], self->server.port); ++ if (body_buffer) { ++ sprintf(out_buffer, ++ "POST /%s HTTP/1.1\r\n" ++ "Host: %s\r\n" ++ "%s\r\n\r\n", ++ local->encode_buffer, ++ hostport, ++ body_buffer); ++ } else { ++ char result[33] = {0}; ++ boundary(result); ++ sprintf(out_buffer, ++ "POST /%s HTTP/1.1\r\n" ++ "Host: %s\r\n" ++ "User-Agent: %s\r\n" ++ "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" ++ "Accept-Language: en-US,en;q=0.8\r\n" ++ "Accept-Encoding: gzip, deflate\r\n" ++ "Content-Type: multipart/form-data; boundary=%s\r\n" ++ "DNT: 1\r\n" ++ "Connection: keep-alive\r\n" ++ "\r\n", ++ local->encode_buffer, ++ hostport, ++ g_useragent[g_useragent_index], ++ result ++ ); ++ } ++ //LOGI("http header: %s", out_buffer); ++ outlength = strlen(out_buffer); ++ memmove(out_buffer + outlength, encryptdata + head_size, datalength - head_size); ++ outlength += datalength - head_size; ++ local->has_sent_header = 1; ++ if (*capacity < outlength) { ++ *pencryptdata = (char*)realloc(*pencryptdata, *capacity = outlength * 2); ++ encryptdata = *pencryptdata; ++ } ++ memmove(encryptdata, out_buffer, outlength); ++ free(out_buffer); ++ if (body_buffer != NULL) ++ free(body_buffer); ++ if (local->encode_buffer != NULL) { ++ free(local->encode_buffer); ++ local->encode_buffer = NULL; ++ } ++ return outlength; ++} +diff --git a/server/http_simple.h b/server/http_simple.h +new file mode 100644 +index 0000000..cce24cc +--- /dev/null ++++ b/server/http_simple.h +@@ -0,0 +1,21 @@ ++/* ++ * http_simple.h - Define shadowsocksR server's buffers and callbacks ++ * ++ * Copyright (C) 2015 - 2016, Break Wa11 ++ */ ++ ++#ifndef _HTTP_SIMPLE_H ++#define _HTTP_SIMPLE_H ++ ++obfs * http_simple_new_obfs(); ++void http_simple_dispose(obfs *self); ++ ++int http_simple_client_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity); ++int http_simple_client_decode(obfs *self, char **pencryptdata, int datalength, size_t* capacity, int *needsendback); ++ ++int http_post_client_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity); ++ ++int http_simple_server_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity); ++int http_simple_server_decode(obfs *self, char **pencryptdata, int datalength, size_t* capacity, int *needsendback); ++ ++#endif // _HTTP_SIMPLE_H +diff --git a/server/jconf.c b/server/jconf.c +new file mode 100644 +index 0000000..494aa5f +--- /dev/null ++++ b/server/jconf.c +@@ -0,0 +1,260 @@ ++/* ++ * jconf.c - Parse the JSON format config file ++ * ++ * Copyright (C) 2013 - 2016, Max Lv ++ * ++ * This file is part of the shadowsocks-libev. ++ * shadowsocks-libev 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 3 of the License, or ++ * (at your option) any later version. ++ * ++ * shadowsocks-libev 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 shadowsocks-libev; see the file COPYING. If not, see ++ * . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "utils.h" ++#include "jconf.h" ++#include "json.h" ++#include "string.h" ++ ++#include ++ ++#define check_json_value_type(value, expected_type, message) \ ++ do { \ ++ if ((value)->type != (expected_type)) \ ++ FATAL((message)); \ ++ } while(0) ++ ++static char * ++to_string(const json_value *value) ++{ ++ if (value->type == json_string) { ++ return ss_strndup(value->u.string.ptr, value->u.string.length); ++ } else if (value->type == json_integer) { ++ return strdup(ss_itoa(value->u.integer)); ++ } else if (value->type == json_null) { ++ return "null"; ++ } else { ++ LOGE("%d", value->type); ++ FATAL("Invalid config format."); ++ } ++ return 0; ++} ++ ++void ++free_addr(ss_addr_t *addr) ++{ ++ ss_free(addr->host); ++ ss_free(addr->port); ++} ++ ++void ++parse_addr(const char *str, ss_addr_t *addr) ++{ ++ int ipv6 = 0, ret = -1, n = 0; ++ char *pch; ++ ++ struct cork_ip ip; ++ if (cork_ip_init(&ip, str) != -1) { ++ addr->host = strdup(str); ++ addr->port = NULL; ++ return; ++ } ++ ++ pch = strchr(str, ':'); ++ while (pch != NULL) { ++ n++; ++ ret = pch - str; ++ pch = strchr(pch + 1, ':'); ++ } ++ if (n > 1) { ++ ipv6 = 1; ++ if (str[ret - 1] != ']') { ++ ret = -1; ++ } ++ } ++ ++ if (ret == -1) { ++ if (ipv6) { ++ addr->host = ss_strndup(str + 1, strlen(str) - 2); ++ } else { ++ addr->host = strdup(str); ++ } ++ addr->port = NULL; ++ } else { ++ if (ipv6) { ++ addr->host = ss_strndup(str + 1, ret - 2); ++ } else { ++ addr->host = ss_strndup(str, ret); ++ } ++ addr->port = strdup(str + ret + 1); ++ } ++} ++ ++jconf_t * ++read_jconf(const char *file) ++{ ++ static jconf_t conf; ++ ++ memset(&conf, 0, sizeof(jconf_t)); ++ ++ char *buf; ++ json_value *obj; ++ ++ FILE *f = fopen(file, "rb"); ++ if (f == NULL) { ++ FATAL("Invalid config path."); ++ } ++ ++ fseek(f, 0, SEEK_END); ++ long pos = ftell(f); ++ fseek(f, 0, SEEK_SET); ++ ++ if (pos >= MAX_CONF_SIZE) { ++ FATAL("Too large config file."); ++ } ++ ++ buf = ss_malloc(pos + 1); ++ if (buf == NULL) { ++ FATAL("No enough memory."); ++ } ++ ++ int nread = fread(buf, pos, 1, f); ++ if (!nread) { ++ FATAL("Failed to read the config file."); ++ } ++ fclose(f); ++ ++ buf[pos] = '\0'; // end of string ++ ++ json_settings settings = { 0UL, 0, NULL, NULL, NULL }; ++ char error_buf[512]; ++ obj = json_parse_ex(&settings, buf, pos, error_buf); ++ ++ if (obj == NULL) { ++ FATAL(error_buf); ++ } ++ ++ if (obj->type == json_object) { ++ unsigned int i, j; ++ for (i = 0; i < obj->u.object.length; i++) { ++ char *name = obj->u.object.values[i].name; ++ json_value *value = obj->u.object.values[i].value; ++ if (strcmp(name, "server") == 0) { ++ if (value->type == json_array) { ++ for (j = 0; j < value->u.array.length; j++) { ++ if (j >= MAX_REMOTE_NUM) { ++ break; ++ } ++ json_value *v = value->u.array.values[j]; ++ char *addr_str = to_string(v); ++ parse_addr(addr_str, conf.remote_addr + j); ++ ss_free(addr_str); ++ conf.remote_num = j + 1; ++ } ++ } else if (value->type == json_string) { ++ conf.remote_addr[0].host = to_string(value); ++ conf.remote_addr[0].port = NULL; ++ conf.remote_num = 1; ++ } ++ } else if (strcmp(name, "port_password") == 0) { ++ if (value->type == json_object) { ++ for (j = 0; j < value->u.object.length; j++) { ++ if (j >= MAX_PORT_NUM) { ++ break; ++ } ++ json_value *v = value->u.object.values[j].value; ++ if (v->type == json_string) { ++ conf.port_password[j].port = ss_strndup(value->u.object.values[j].name, ++ value->u.object.values[j].name_length); ++ conf.port_password[j].password = to_string(v); ++ conf.port_password_num = j + 1; ++ } ++ } ++ } ++ } else if (strcmp(name, "server_port") == 0) { ++ conf.remote_port = to_string(value); ++ } else if (strcmp(name, "local_address") == 0) { ++ conf.local_addr = to_string(value); ++ } else if (strcmp(name, "local_port") == 0) { ++ conf.local_port = to_string(value); ++ } else if (strcmp(name, "password") == 0) { ++ conf.password = to_string(value); ++ } else if (strcmp(name, "protocol") == 0) { // SSR ++ conf.protocol = to_string(value); ++ } else if (strcmp(name, "protocol_param") == 0) { // SSR ++ conf.protocol_param = to_string(value); ++ } else if (strcmp(name, "method") == 0) { ++ conf.method = to_string(value); ++ } else if (strcmp(name, "obfs") == 0) { // SSR ++ conf.obfs = to_string(value); ++ } else if (strcmp(name, "obfs_param") == 0) { // SSR ++ conf.obfs_param = to_string(value); ++ } else if (strcmp(name, "timeout") == 0) { ++ conf.timeout = to_string(value); ++ } else if (strcmp(name, "user") == 0) { ++ conf.user = to_string(value); ++ } else if (strcmp(name, "fast_open") == 0) { ++ check_json_value_type(value, json_boolean, ++ "invalid config file: option 'fast_open' must be a boolean"); ++ conf.fast_open = value->u.boolean; ++ } else if (strcmp(name, "auth") == 0) { ++ check_json_value_type(value, json_boolean, ++ "invalid config file: option 'auth' must be a boolean"); ++ conf.auth = value->u.boolean; ++ } else if (strcmp(name, "nofile") == 0) { ++ check_json_value_type(value, json_integer, ++ "invalid config file: option 'nofile' must be an integer"); ++ conf.nofile = value->u.integer; ++ } else if (strcmp(name, "nameserver") == 0) { ++ conf.nameserver = to_string(value); ++ } else if (strcmp(name, "tunnel_address") == 0) { ++ conf.tunnel_address = to_string(value); ++ } else if (strcmp(name, "mode") == 0) { ++ char *mode_str = to_string(value); ++ ++ if (strcmp(mode_str, "tcp_only") == 0) ++ conf.mode = TCP_ONLY; ++ else if (strcmp(mode_str, "tcp_and_udp") == 0) ++ conf.mode = TCP_AND_UDP; ++ else if (strcmp(mode_str, "udp_only") == 0) ++ conf.mode = UDP_ONLY; ++ else ++ LOGI("ignore unknown mode: %s, use tcp_only as fallback", ++ mode_str); ++ ss_free(mode_str); ++ } else if (strcmp(name, "mtu") == 0) { ++ check_json_value_type(value, json_integer, ++ "invalid config file: option 'mtu' must be an integer"); ++ conf.mtu = value->u.integer; ++ } else if (strcmp(name, "mptcp") == 0) { ++ check_json_value_type(value, json_boolean, ++ "invalid config file: option 'mptcp' must be a boolean"); ++ conf.mptcp = value->u.boolean; ++ } else if (strcmp(name, "ipv6_first") == 0) { ++ check_json_value_type(value, json_boolean, ++ "invalid config file: option 'ipv6_first' must be a boolean"); ++ conf.ipv6_first = value->u.boolean; ++ } ++ } ++ } else { ++ FATAL("Invalid config file"); ++ } ++ ++ ss_free(buf); ++ json_value_free(obj); ++ return &conf; ++} +diff --git a/server/jconf.h b/server/jconf.h +new file mode 100644 +index 0000000..9a7e5e3 +--- /dev/null ++++ b/server/jconf.h +@@ -0,0 +1,78 @@ ++/* ++ * jconf.h - Define the config data structure ++ * ++ * Copyright (C) 2013 - 2016, Max Lv ++ * ++ * This file is part of the shadowsocks-libev. ++ * shadowsocks-libev 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 3 of the License, or ++ * (at your option) any later version. ++ * ++ * shadowsocks-libev 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 shadowsocks-libev; see the file COPYING. If not, see ++ * . ++ */ ++ ++#ifndef _JCONF_H ++#define _JCONF_H ++ ++#define MAX_PORT_NUM 1024 ++#define MAX_REMOTE_NUM 10 ++#define MAX_CONF_SIZE 128 * 1024 ++#define MAX_DNS_NUM 4 ++#define MAX_CONNECT_TIMEOUT 10 ++#define MAX_REQUEST_TIMEOUT 60 ++#define MIN_UDP_TIMEOUT 10 ++ ++#define TCP_ONLY 0 ++#define TCP_AND_UDP 1 ++#define UDP_ONLY 3 ++ ++typedef struct { ++ char *host; ++ char *port; ++} ss_addr_t; ++ ++typedef struct { ++ char *port; ++ char *password; ++} ss_port_password_t; ++ ++typedef struct { ++ int remote_num; ++ ss_addr_t remote_addr[MAX_REMOTE_NUM]; ++ int port_password_num; ++ ss_port_password_t port_password[MAX_PORT_NUM]; ++ char *remote_port; ++ char *local_addr; ++ char *local_port; ++ char *password; ++ char *protocol; // SSR ++ char *protocol_param; // SSR ++ char *method; ++ char *obfs; // SSR ++ char *obfs_param; // SSR ++ char *timeout; ++ char *user; ++ int auth; ++ int fast_open; ++ int nofile; ++ char *nameserver; ++ char *tunnel_address; ++ int mode; ++ int mtu; ++ int mptcp; ++ int ipv6_first; ++} jconf_t; ++ ++jconf_t *read_jconf(const char *file); ++void parse_addr(const char *str, ss_addr_t *addr); ++void free_addr(ss_addr_t *addr); ++ ++#endif // _JCONF_H +diff --git a/server/json.c b/server/json.c +new file mode 100644 +index 0000000..18e95ef +--- /dev/null ++++ b/server/json.c +@@ -0,0 +1,1002 @@ ++/* vim: set et ts=3 sw=3 sts=3 ft=c: ++ * ++ * Copyright (C) 2012, 2013, 2014 James McLaughlin et al. All rights reserved. ++ * https://github.com/udp/json-parser ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ */ ++ ++#include "json.h" ++#include "utils.h" ++ ++#ifdef _MSC_VER ++#ifndef _CRT_SECURE_NO_WARNINGS ++#define _CRT_SECURE_NO_WARNINGS ++#endif ++#endif ++ ++#ifdef __cplusplus ++const struct _json_value json_value_none; /* zero-d by ctor */ ++#else ++const struct _json_value json_value_none = { NULL, 0, { 0 }, { NULL } }; ++#endif ++ ++#include ++#include ++#include ++#include ++ ++typedef unsigned short json_uchar; ++ ++static unsigned char ++hex_value(json_char c) ++{ ++ if (isdigit((uint8_t)c)) { ++ return c - '0'; ++ } ++ ++ switch (c) { ++ case 'a': ++ case 'A': ++ return 0x0A; ++ case 'b': ++ case 'B': ++ return 0x0B; ++ case 'c': ++ case 'C': ++ return 0x0C; ++ case 'd': ++ case 'D': ++ return 0x0D; ++ case 'e': ++ case 'E': ++ return 0x0E; ++ case 'f': ++ case 'F': ++ return 0x0F; ++ default: ++ return 0xFF; ++ } ++} ++ ++typedef struct { ++ unsigned long used_memory; ++ ++ unsigned int uint_max; ++ unsigned long ulong_max; ++ ++ json_settings settings; ++ int first_pass; ++} json_state; ++ ++static void * ++default_alloc(size_t size, int zero, void *user_data) ++{ ++ return zero ? calloc(1, size) : ss_malloc(size); ++} ++ ++static void ++default_free(void *ptr, void *user_data) ++{ ++ ss_free(ptr); ++} ++ ++static void * ++json_alloc(json_state *state, unsigned long size, int zero) ++{ ++ if ((state->ulong_max - state->used_memory) < size) { ++ return 0; ++ } ++ ++ if (state->settings.max_memory ++ && (state->used_memory += size) > state->settings.max_memory) { ++ return 0; ++ } ++ ++ return state->settings.mem_alloc(size, zero, state->settings.user_data); ++} ++ ++static int ++new_value(json_state *state, json_value **top, json_value **root, ++ json_value **alloc, json_type type) ++{ ++ json_value *value; ++ int values_size; ++ ++ if (!state->first_pass) { ++ value = *top = *alloc; ++ *alloc = (*alloc)->_reserved.next_alloc; ++ ++ if (!*root) { ++ *root = value; ++ } ++ ++ switch (value->type) { ++ case json_array: ++ ++ if (!(value->u.array.values = (json_value **)json_alloc ++ (state, value->u.array.length * ++ sizeof(json_value *), 0))) { ++ return 0; ++ } ++ ++ value->u.array.length = 0; ++ break; ++ ++ case json_object: ++ ++ values_size = sizeof(*value->u.object.values) * ++ value->u.object.length; ++ ++ if (!((*(void **)&value->u.object.values) = json_alloc ++ (state, ++ values_size + ++ ((size_t)value->u. ++ object.values), ++ 0))) { ++ return 0; ++ } ++ ++ value->_reserved.object_mem = (*(char **)&value->u.object.values) + ++ values_size; ++ ++ value->u.object.length = 0; ++ break; ++ ++ case json_string: ++ ++ if (!(value->u.string.ptr = (json_char *)json_alloc ++ (state, ++ (value->u.string.length + ++ 1) * sizeof(json_char), 0))) { ++ return 0; ++ } ++ ++ value->u.string.length = 0; ++ break; ++ ++ default: ++ break; ++ } ++ ++ return 1; ++ } ++ ++ value = (json_value *)json_alloc(state, sizeof(json_value), 1); ++ ++ if (!value) { ++ return 0; ++ } ++ ++ if (!*root) { ++ *root = value; ++ } ++ ++ value->type = type; ++ value->parent = *top; ++ ++ if (*alloc) { ++ (*alloc)->_reserved.next_alloc = value; ++ } ++ ++ *alloc = *top = value; ++ ++ return 1; ++} ++ ++#define e_off \ ++ ((int)(i - cur_line_begin)) ++ ++#define whitespace \ ++case '\n': \ ++ ++cur_line; cur_line_begin = i; \ ++case ' ': \ ++case '\t': \ ++case '\r' ++ ++#define string_add(b) \ ++ do { if (!state.first_pass) { string[string_length] = b; \ ++ } ++string_length; } while (0) ++ ++static const long ++ flag_next = 1 << 0, ++ flag_reproc = 1 << 1, ++ flag_need_comma = 1 << 2, ++ flag_seek_value = 1 << 3, ++ flag_escaped = 1 << 4, ++ flag_string = 1 << 5, ++ flag_need_colon = 1 << 6, ++ flag_done = 1 << 7, ++ flag_num_negative = 1 << 8, ++ flag_num_zero = 1 << 9, ++ flag_num_e = 1 << 10, ++ flag_num_e_got_sign = 1 << 11, ++ flag_num_e_negative = 1 << 12, ++ flag_line_comment = 1 << 13, ++ flag_block_comment = 1 << 14; ++ ++json_value * ++json_parse_ex(json_settings *settings, ++ const json_char *json, ++ size_t length, ++ char *error_buf) ++{ ++ json_char error[json_error_max]; ++ int cur_line; ++ const json_char *cur_line_begin, *i, *end; ++ json_value *top, *root, *alloc = 0; ++ json_state state = { 0UL, 0U, 0UL, { 0UL, 0, NULL, NULL, NULL }, 0 }; ++ long flags; ++ long num_digits = 0, num_e = 0; ++ json_int_t num_fraction = 0; ++ ++ /* Skip UTF-8 BOM ++ */ ++ if (length >= 3 && ((unsigned char)json[0]) == 0xEF ++ && ((unsigned char)json[1]) == 0xBB ++ && ((unsigned char)json[2]) == 0xBF) { ++ json += 3; ++ length -= 3; ++ } ++ ++ error[0] = '\0'; ++ end = (json + length); ++ ++ memcpy(&state.settings, settings, sizeof(json_settings)); ++ ++ if (!state.settings.mem_alloc) { ++ state.settings.mem_alloc = default_alloc; ++ } ++ ++ if (!state.settings.mem_free) { ++ state.settings.mem_free = default_free; ++ } ++ ++ memset(&state.uint_max, 0xFF, sizeof(state.uint_max)); ++ memset(&state.ulong_max, 0xFF, sizeof(state.ulong_max)); ++ ++ state.uint_max -= 8; /* limit of how much can be added before next check */ ++ state.ulong_max -= 8; ++ ++ for (state.first_pass = 1; state.first_pass >= 0; --state.first_pass) { ++ json_uchar uchar; ++ unsigned char uc_b1, uc_b2, uc_b3, uc_b4; ++ json_char *string = 0; ++ unsigned int string_length = 0; ++ ++ top = root = 0; ++ flags = flag_seek_value; ++ ++ cur_line = 1; ++ cur_line_begin = json; ++ ++ for (i = json;; ++i) { ++ json_char b = (i == end ? 0 : *i); ++ ++ if (flags & flag_string) { ++ if (!b) { ++ sprintf(error, "Unexpected EOF in string (at %d:%d)", ++ cur_line, e_off); ++ goto e_failed; ++ } ++ ++ if (string_length > state.uint_max) { ++ goto e_overflow; ++ } ++ ++ if (flags & flag_escaped) { ++ flags &= ~flag_escaped; ++ ++ switch (b) { ++ case 'b': ++ string_add('\b'); ++ break; ++ case 'f': ++ string_add('\f'); ++ break; ++ case 'n': ++ string_add('\n'); ++ break; ++ case 'r': ++ string_add('\r'); ++ break; ++ case 't': ++ string_add('\t'); ++ break; ++ case 'u': ++ ++ if (end - i < 4 || ++ (uc_b1 = hex_value(*++i)) == 0xFF || ++ (uc_b2 = hex_value(*++i)) == 0xFF ++ || (uc_b3 = hex_value(*++i)) == 0xFF || ++ (uc_b4 = hex_value(*++i)) == 0xFF) { ++ sprintf(error, ++ "Invalid character value `%c` (at %d:%d)", ++ b, cur_line, e_off); ++ goto e_failed; ++ } ++ ++ uc_b1 = uc_b1 * 16 + uc_b2; ++ uc_b2 = uc_b3 * 16 + uc_b4; ++ ++ uchar = ((json_char)uc_b1) * 256 + uc_b2; ++ ++ if (sizeof(json_char) >= sizeof(json_uchar) || ++ (uc_b1 == 0 && uc_b2 <= 0x7F)) { ++ string_add((json_char)uchar); ++ break; ++ } ++ ++ if (uchar <= 0x7FF) { ++ if (state.first_pass) { ++ string_length += 2; ++ } else { ++ string[string_length++] = 0xC0 | ++ ((uc_b2 & ++ 0xC0) >> ++ 6) | ++ ((uc_b1 & 0x7) << 2); ++ string[string_length++] = 0x80 | ++ (uc_b2 & 0x3F); ++ } ++ ++ break; ++ } ++ ++ if (state.first_pass) { ++ string_length += 3; ++ } else { ++ string[string_length++] = 0xE0 | ++ ((uc_b1 & 0xF0) >> 4); ++ string[string_length++] = 0x80 | ++ ((uc_b1 & ++ 0xF) << ++ 2) | ++ ((uc_b2 & 0xC0) >> 6); ++ string[string_length++] = 0x80 | (uc_b2 & 0x3F); ++ } ++ ++ break; ++ ++ default: ++ string_add(b); ++ } ++ ++ continue; ++ } ++ ++ if (b == '\\') { ++ flags |= flag_escaped; ++ continue; ++ } ++ ++ if (b == '"') { ++ if (!state.first_pass) { ++ string[string_length] = 0; ++ } ++ ++ flags &= ~flag_string; ++ string = 0; ++ ++ switch (top->type) { ++ case json_string: ++ ++ top->u.string.length = string_length; ++ flags |= flag_next; ++ ++ break; ++ ++ case json_object: ++ ++ if (state.first_pass) { ++ (*(json_char **)&top->u.object.values) += ++ string_length + 1; ++ } else { ++ top->u.object.values[top->u.object.length].name ++ = (json_char *)top->_reserved.object_mem; ++ ++ top->u.object.values[top->u.object.length]. ++ name_length ++ = string_length; ++ ++ (*(json_char **)&top->_reserved.object_mem) += ++ string_length + 1; ++ } ++ ++ flags |= flag_seek_value | flag_need_colon; ++ continue; ++ ++ default: ++ break; ++ } ++ } else { ++ string_add(b); ++ continue; ++ } ++ } ++ ++ if (state.settings.settings & json_enable_comments) { ++ if (flags & (flag_line_comment | flag_block_comment)) { ++ if (flags & flag_line_comment) { ++ if (b == '\r' || b == '\n' || !b) { ++ flags &= ~flag_line_comment; ++ --i; /* so null can be reproc'd */ ++ } ++ ++ continue; ++ } ++ ++ if (flags & flag_block_comment) { ++ if (!b) { ++ sprintf(error, ++ "%d:%d: Unexpected EOF in block comment", ++ cur_line, e_off); ++ goto e_failed; ++ } ++ ++ if (b == '*' && i < (end - 1) && i[1] == '/') { ++ flags &= ~flag_block_comment; ++ ++i; /* skip closing sequence */ ++ } ++ ++ continue; ++ } ++ } else if (b == '/') { ++ if (!(flags & (flag_seek_value | flag_done)) && top->type != ++ json_object) { ++ sprintf(error, "%d:%d: Comment not allowed here", ++ cur_line, e_off); ++ goto e_failed; ++ } ++ ++ if (++i == end) { ++ sprintf(error, "%d:%d: EOF unexpected", cur_line, ++ e_off); ++ goto e_failed; ++ } ++ ++ switch (b = *i) { ++ case '/': ++ flags |= flag_line_comment; ++ continue; ++ ++ case '*': ++ flags |= flag_block_comment; ++ continue; ++ ++ default: ++ sprintf(error, ++ "%d:%d: Unexpected `%c` in comment opening sequence", cur_line, e_off, ++ b); ++ goto e_failed; ++ } ++ } ++ } ++ ++ if (flags & flag_done) { ++ if (!b) { ++ break; ++ } ++ ++ switch (b) { ++whitespace: ++ continue; ++ ++ default: ++ sprintf(error, "%d:%d: Trailing garbage: `%c`", cur_line, ++ e_off, b); ++ goto e_failed; ++ } ++ } ++ ++ if (flags & flag_seek_value) { ++ switch (b) { ++whitespace: ++ continue; ++ ++ case ']': ++ ++ if (top->type == json_array) { ++ flags = ++ (flags & ++ ~(flag_need_comma | flag_seek_value)) | flag_next; ++ } else { ++ sprintf(error, "%d:%d: Unexpected ]", cur_line, e_off); ++ goto e_failed; ++ } ++ ++ break; ++ ++ default: ++ ++ if (flags & flag_need_comma) { ++ if (b == ',') { ++ flags &= ~flag_need_comma; ++ continue; ++ } else { ++ sprintf(error, "%d:%d: Expected , before %c", ++ cur_line, e_off, b); ++ goto e_failed; ++ } ++ } ++ ++ if (flags & flag_need_colon) { ++ if (b == ':') { ++ flags &= ~flag_need_colon; ++ continue; ++ } else { ++ sprintf(error, "%d:%d: Expected : before %c", ++ cur_line, e_off, b); ++ goto e_failed; ++ } ++ } ++ ++ flags &= ~flag_seek_value; ++ ++ switch (b) { ++ case '{': ++ ++ if (!new_value(&state, &top, &root, &alloc, ++ json_object)) { ++ goto e_alloc_failure; ++ } ++ ++ continue; ++ ++ case '[': ++ ++ if (!new_value(&state, &top, &root, &alloc, ++ json_array)) { ++ goto e_alloc_failure; ++ } ++ ++ flags |= flag_seek_value; ++ continue; ++ ++ case '"': ++ ++ if (!new_value(&state, &top, &root, &alloc, ++ json_string)) { ++ goto e_alloc_failure; ++ } ++ ++ flags |= flag_string; ++ ++ string = top->u.string.ptr; ++ string_length = 0; ++ ++ continue; ++ ++ case 't': ++ ++ if ((end - i) < 3 || *(++i) != 'r' || *(++i) != 'u' || ++ *(++i) != 'e') { ++ goto e_unknown_value; ++ } ++ ++ if (!new_value(&state, &top, &root, &alloc, ++ json_boolean)) { ++ goto e_alloc_failure; ++ } ++ ++ top->u.boolean = 1; ++ ++ flags |= flag_next; ++ break; ++ ++ case 'f': ++ ++ if ((end - i) < 4 || *(++i) != 'a' || *(++i) != 'l' || ++ *(++i) != 's' || *(++i) != 'e') { ++ goto e_unknown_value; ++ } ++ ++ if (!new_value(&state, &top, &root, &alloc, ++ json_boolean)) { ++ goto e_alloc_failure; ++ } ++ ++ flags |= flag_next; ++ break; ++ ++ case 'n': ++ ++ if ((end - i) < 3 || *(++i) != 'u' || *(++i) != 'l' || ++ *(++i) != 'l') { ++ goto e_unknown_value; ++ } ++ ++ if (!new_value(&state, &top, &root, &alloc, ++ json_null)) { ++ goto e_alloc_failure; ++ } ++ ++ flags |= flag_next; ++ break; ++ ++ default: ++ ++ if (isdigit((uint8_t)b) || b == '-') { ++ if (!new_value(&state, &top, &root, &alloc, ++ json_integer)) { ++ goto e_alloc_failure; ++ } ++ ++ if (!state.first_pass) { ++ while (isdigit((uint8_t)b) || b == '+' || b == ++ '-' ++ || b == 'e' || b == 'E' || b == '.') { ++ if ((++i) == end) { ++ b = 0; ++ break; ++ } ++ ++ b = *i; ++ } ++ ++ flags |= flag_next | flag_reproc; ++ break; ++ } ++ ++ flags &= ~(flag_num_negative | flag_num_e | ++ flag_num_e_got_sign | ++ flag_num_e_negative | ++ flag_num_zero); ++ ++ num_digits = 0; ++ num_fraction = 0; ++ num_e = 0; ++ ++ if (b != '-') { ++ flags |= flag_reproc; ++ break; ++ } ++ ++ flags |= flag_num_negative; ++ continue; ++ } else { ++ sprintf(error, ++ "%d:%d: Unexpected %c when seeking value", ++ cur_line, e_off, b); ++ goto e_failed; ++ } ++ } ++ } ++ } else { ++ switch (top->type) { ++ case json_object: ++ ++ switch (b) { ++whitespace: ++ continue; ++ ++ case '"': ++ ++ if (flags & flag_need_comma) { ++ sprintf(error, "%d:%d: Expected , before \"", ++ cur_line, e_off); ++ goto e_failed; ++ } ++ ++ flags |= flag_string; ++ ++ string = (json_char *)top->_reserved.object_mem; ++ string_length = 0; ++ ++ break; ++ ++ case '}': ++ ++ flags = (flags & ~flag_need_comma) | flag_next; ++ break; ++ ++ case ',': ++ ++ if (flags & flag_need_comma) { ++ flags &= ~flag_need_comma; ++ break; ++ } ++ ++ default: ++ ++ sprintf(error, "%d:%d: Unexpected `%c` in object", ++ cur_line, e_off, b); ++ goto e_failed; ++ } ++ ++ break; ++ ++ case json_integer: ++ case json_double: ++ ++ if (isdigit((uint8_t)b)) { ++ ++num_digits; ++ ++ if (top->type == json_integer || flags & flag_num_e) { ++ if (!(flags & flag_num_e)) { ++ if (flags & flag_num_zero) { ++ sprintf(error, ++ "%d:%d: Unexpected `0` before `%c`", ++ cur_line, e_off, b); ++ goto e_failed; ++ } ++ ++ if (num_digits == 1 && b == '0') { ++ flags |= flag_num_zero; ++ } ++ } else { ++ flags |= flag_num_e_got_sign; ++ num_e = (num_e * 10) + (b - '0'); ++ continue; ++ } ++ ++ top->u.integer = (top->u.integer * 10) + (b - '0'); ++ continue; ++ } ++ ++ num_fraction = (num_fraction * 10) + (b - '0'); ++ continue; ++ } ++ ++ if (b == '+' || b == '-') { ++ if ((flags & flag_num_e) && ++ !(flags & flag_num_e_got_sign)) { ++ flags |= flag_num_e_got_sign; ++ ++ if (b == '-') { ++ flags |= flag_num_e_negative; ++ } ++ ++ continue; ++ } ++ } else if (b == '.' && top->type == json_integer) { ++ if (!num_digits) { ++ sprintf(error, "%d:%d: Expected digit before `.`", ++ cur_line, e_off); ++ goto e_failed; ++ } ++ ++ top->type = json_double; ++ top->u.dbl = (double)top->u.integer; ++ ++ num_digits = 0; ++ continue; ++ } ++ ++ if (!(flags & flag_num_e)) { ++ if (top->type == json_double) { ++ if (!num_digits) { ++ sprintf(error, ++ "%d:%d: Expected digit after `.`", ++ cur_line, e_off); ++ goto e_failed; ++ } ++ ++ top->u.dbl += ((double)num_fraction) / ++ (pow(10, (double)num_digits)); ++ } ++ ++ if (b == 'e' || b == 'E') { ++ flags |= flag_num_e; ++ ++ if (top->type == json_integer) { ++ top->type = json_double; ++ top->u.dbl = (double)top->u.integer; ++ } ++ ++ num_digits = 0; ++ flags &= ~flag_num_zero; ++ ++ continue; ++ } ++ } else { ++ if (!num_digits) { ++ sprintf(error, "%d:%d: Expected digit after `e`", ++ cur_line, e_off); ++ goto e_failed; ++ } ++ ++ top->u.dbl *= ++ pow(10, ++ (double)((flags & ++ flag_num_e_negative) ? -num_e : num_e)); ++ } ++ ++ if (flags & flag_num_negative) { ++ if (top->type == json_integer) { ++ top->u.integer = -top->u.integer; ++ } else { ++ top->u.dbl = -top->u.dbl; ++ } ++ } ++ ++ flags |= flag_next | flag_reproc; ++ break; ++ ++ default: ++ break; ++ } ++ } ++ ++ if (flags & flag_reproc) { ++ flags &= ~flag_reproc; ++ --i; ++ } ++ ++ if (flags & flag_next) { ++ flags = (flags & ~flag_next) | flag_need_comma; ++ ++ if (!top->parent) { ++ /* root value done */ ++ ++ flags |= flag_done; ++ continue; ++ } ++ ++ if (top->parent->type == json_array) { ++ flags |= flag_seek_value; ++ } ++ ++ if (!state.first_pass) { ++ json_value *parent = top->parent; ++ ++ switch (parent->type) { ++ case json_object: ++ ++ parent->u.object.values ++ [parent->u.object.length].value = top; ++ ++ break; ++ ++ case json_array: ++ ++ parent->u.array.values ++ [parent->u.array.length] = top; ++ ++ break; ++ ++ default: ++ break; ++ } ++ } ++ ++ if ((++top->parent->u.array.length) > state.uint_max) { ++ goto e_overflow; ++ } ++ ++ top = top->parent; ++ ++ continue; ++ } ++ } ++ ++ alloc = root; ++ } ++ ++ return root; ++ ++e_unknown_value: ++ ++ sprintf(error, "%d:%d: Unknown value", cur_line, e_off); ++ goto e_failed; ++ ++e_alloc_failure: ++ ++ strcpy(error, "Memory allocation failure"); ++ goto e_failed; ++ ++e_overflow: ++ ++ sprintf(error, "%d:%d: Too long (caught overflow)", cur_line, e_off); ++ goto e_failed; ++ ++e_failed: ++ ++ if (error_buf) { ++ if (*error) { ++ strcpy(error_buf, error); ++ } else { ++ strcpy(error_buf, "Unknown error"); ++ } ++ } ++ ++ if (state.first_pass) { ++ alloc = root; ++ } ++ ++ while (alloc) { ++ top = alloc->_reserved.next_alloc; ++ state.settings.mem_free(alloc, state.settings.user_data); ++ alloc = top; ++ } ++ ++ if (!state.first_pass) { ++ json_value_free_ex(&state.settings, root); ++ } ++ ++ return 0; ++} ++ ++json_value * ++json_parse(const json_char *json, size_t length) ++{ ++ json_settings settings = { 0UL, 0, NULL, NULL, NULL }; ++ return json_parse_ex(&settings, json, length, 0); ++} ++ ++void ++json_value_free_ex(json_settings *settings, json_value *value) ++{ ++ json_value *cur_value; ++ ++ if (!value) { ++ return; ++ } ++ ++ value->parent = 0; ++ ++ while (value) { ++ switch (value->type) { ++ case json_array: ++ ++ if (!value->u.array.length) { ++ settings->mem_free(value->u.array.values, settings->user_data); ++ break; ++ } ++ ++ value = value->u.array.values[--value->u.array.length]; ++ continue; ++ ++ case json_object: ++ ++ if (!value->u.object.length) { ++ settings->mem_free(value->u.object.values, settings->user_data); ++ break; ++ } ++ ++ value = value->u.object.values[--value->u.object.length].value; ++ continue; ++ ++ case json_string: ++ ++ settings->mem_free(value->u.string.ptr, settings->user_data); ++ break; ++ ++ default: ++ break; ++ } ++ ++ cur_value = value; ++ value = value->parent; ++ settings->mem_free(cur_value, settings->user_data); ++ } ++} ++ ++void ++json_value_free(json_value *value) ++{ ++ json_settings settings = { 0UL, 0, NULL, NULL, NULL }; ++ settings.mem_free = default_free; ++ json_value_free_ex(&settings, value); ++} +diff --git a/server/json.h b/server/json.h +new file mode 100644 +index 0000000..016fc5a +--- /dev/null ++++ b/server/json.h +@@ -0,0 +1,249 @@ ++/* vim: set et ts=3 sw=3 sts=3 ft=c: ++ * ++ * Copyright (C) 2012, 2013, 2014 James McLaughlin et al. All rights reserved. ++ * https://github.com/udp/json-parser ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ */ ++ ++#ifndef _JSON_H ++#define _JSON_H ++ ++#ifndef json_char ++#define json_char char ++#endif ++ ++#ifndef json_int_t ++#ifndef _MSC_VER ++#include ++#define json_int_t int64_t ++#else ++#define json_int_t __int64 ++#endif ++#endif ++ ++#include ++ ++#ifdef __cplusplus ++ ++#include ++ ++extern "C" ++{ ++#endif ++ ++typedef struct { ++ unsigned long max_memory; ++ int settings; ++ ++ /* Custom allocator support (leave null to use malloc/free) ++ */ ++ ++ void * (*mem_alloc)(size_t, int zero, void *user_data); ++ void (*mem_free)(void *, void *user_data); ++ ++ void *user_data; /* will be passed to mem_alloc and mem_free */ ++} json_settings; ++ ++#define json_enable_comments 0x01 ++ ++typedef enum { ++ json_none, ++ json_object, ++ json_array, ++ json_integer, ++ json_double, ++ json_string, ++ json_boolean, ++ json_null ++} json_type; ++ ++extern const struct _json_value json_value_none; ++ ++typedef struct _json_value { ++ struct _json_value *parent; ++ ++ json_type type; ++ ++ union { ++ int boolean; ++ json_int_t integer; ++ double dbl; ++ ++ struct { ++ unsigned int length; ++ json_char *ptr; /* null terminated */ ++ } string; ++ ++ struct { ++ unsigned int length; ++ ++ struct { ++ json_char *name; ++ unsigned int name_length; ++ ++ struct _json_value *value; ++ } *values; ++ ++#if defined(__cplusplus) && __cplusplus >= 201103L ++ decltype(values) begin() const ++ { ++ return values; ++ } ++ decltype(values) end() const ++ { ++ return values + length; ++ } ++#endif ++ } object; ++ ++ struct { ++ unsigned int length; ++ struct _json_value **values; ++ ++#if defined(__cplusplus) && __cplusplus >= 201103L ++ decltype(values) begin() const ++ { ++ return values; ++ } ++ decltype(values) end() const ++ { ++ return values + length; ++ } ++#endif ++ } array; ++ } u; ++ ++ union { ++ struct _json_value *next_alloc; ++ void *object_mem; ++ } _reserved; ++ ++ /* Some C++ operator sugar */ ++ ++#ifdef __cplusplus ++ ++public: ++ ++ inline _json_value(){ ++ memset(this, 0, sizeof(_json_value)); ++ } ++ ++ inline const struct _json_value &operator [] (int index) const { ++ if (type != json_array || index < 0 ++ || ((unsigned int)index) >= u.array.length) { ++ return json_value_none; ++ } ++ ++ return *u.array.values[index]; ++ } ++ ++ inline const struct _json_value &operator [] (const char *index) const { ++ if (type != json_object) { ++ return json_value_none; ++ } ++ ++ for (unsigned int i = 0; i < u.object.length; ++i) ++ if (!strcmp(u.object.values[i].name, index)) { ++ return *u.object.values[i].value; ++ } ++ ++ return json_value_none; ++ } ++ ++ inline operator const char * () const ++ { ++ switch (type) { ++ case json_string: ++ return u.string.ptr; ++ ++ default: ++ return ""; ++ } ++ } ++ ++ inline operator ++ json_int_t() const ++ { ++ switch (type) { ++ case json_integer: ++ return u.integer; ++ ++ case json_double: ++ return (json_int_t)u.dbl; ++ ++ default: ++ return 0; ++ } ++ } ++ ++ inline operator ++ bool() const ++ { ++ if (type != json_boolean) { ++ return false; ++ } ++ ++ return u.boolean != 0; ++ } ++ ++ inline operator double () const ++ { ++ switch (type) { ++ case json_integer: ++ return (double)u.integer; ++ ++ case json_double: ++ return u.dbl; ++ ++ default: ++ return 0; ++ } ++ } ++ ++#endif ++} json_value; ++ ++json_value *json_parse(const json_char *json, ++ size_t length); ++ ++#define json_error_max 128 ++json_value *json_parse_ex(json_settings *settings, ++ const json_char *json, ++ size_t length, ++ char *error); ++ ++void json_value_free(json_value *); ++ ++/* Not usually necessary, unless you used a custom mem_alloc and now want to ++ * use a custom mem_free. ++ */ ++void json_value_free_ex(json_settings *settings, ++ json_value *); ++ ++#ifdef __cplusplus ++} /* extern "C" */ ++#endif ++ ++#endif +diff --git a/server/list.c b/server/list.c +new file mode 100644 +index 0000000..dde085d +--- /dev/null ++++ b/server/list.c +@@ -0,0 +1,370 @@ ++#include "list.h" ++ ++/// 文件:list_impl.c ++/// 功能:实现链表的基本操作 ++/// 作者:bluewind ++/// 完成时间:2011.5.29 ++/// 修改时间:2011.5.31, 2011.7.2 ++/// 修改备注:在头节点处添加一个空节点,可以优化添加、删除节点代码 ++/// 再次修改,链表增加节点数据data_size,限制数据大小,修改了 ++/// 添加复制数据代码,修正重复添加节点后释放节点的Bug,添加了前 ++/// 插、排序和遍历功能,7.3 添加tail尾指针,改进后插法性能,并改名 ++/// -------------------------------------------------------------- ++ ++void swap_data(Node n1, Node n2); ++ ++/// -------------------------------------------------------------- ++// 函数名:list_init ++// 功能: 链表初始化 ++// 参数: 无 ++// 返回值:已初始化链表指针 ++// 备注: 链表本身动态分配,由list_destroy函数管理释放 ++/// -------------------------------------------------------------- ++List list_init(unsigned int data_size) ++{ ++ List list = (List) malloc(sizeof(struct clist)); ++ if(list != NULL) //内存分配成功 ++ { ++ list->head = (Node) malloc(sizeof(node)); //为头节点分配内存 ++ if(list->head) //内存分配成功 ++ { ++ list->head->data = NULL; //初始化头节点 ++ list->head->next = NULL; ++ list->data_size = data_size; ++ list->tail = list->head; ++ list->size = 0; ++ ++ list->add_back = list_add_back; //初始化成员函数 ++ list->add_front = list_add_front; ++ list->delete_node = list_delete_node; ++ list->delete_at = list_delete_at; ++ list->modify_at = list_modify_at; ++ list->have_same = list_have_same; ++ list->have_same_cmp = list_have_same_cmp; ++ list->foreach = list_foreach; ++ list->clear = list_clear; ++ list->sort = list_sort; ++ list->destroy = list_destroy; ++ } ++ } ++ return list; ++} ++ ++/// -------------------------------------------------------------- ++// 函数名:list_add_back ++// 功能: 添加链表结点 (后插法) ++// 参数: l--链表指针,data--链表数据指针,可为任意类型 ++// 返回值:int型,为1表示添加成功,为0表示添加失败 ++// 备注: 如果链表本身为空或是分配节点内存失败,将返回0 ++/// -------------------------------------------------------------- ++int list_add_back(List l, void *data) ++{ ++ Node new_node = (Node) malloc(sizeof(node)); ++ ++ if(l != NULL && new_node != NULL) //链表本身不为空,且内存申请成功 ++ { ++ new_node->data = malloc(l->data_size); ++ memcpy(new_node->data, data, l->data_size); ++ new_node->next = NULL; ++ ++ l->tail->next = new_node; //添加节点 ++ l->tail = new_node; //记录尾节点位置 ++ l->size ++; //链表元素总数加1 ++ ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/// -------------------------------------------------------------- ++// 函数名:list_add_front ++// 功能: 添加链表结点 (前插法) ++// 参数: l--链表指针,data--链表数据指针,可为任意类型 ++// 返回值:int型,为1表示添加成功,为0表示添加失败 ++// 备注: 如果链表本身为空或是分配节点内存失败,将返回0 ++/// -------------------------------------------------------------- ++int list_add_front(List l, void *data) ++{ ++ Node new_node = (Node) malloc(sizeof(node)); ++ ++ if(l != NULL && new_node != NULL) ++ { ++ new_node->data = malloc(l->data_size); ++ memcpy(new_node->data, data, l->data_size); ++ new_node->next = l->head->next; ++ ++ l->head->next = new_node; ++ if(!l->size) //记录尾指针位置 ++ l->tail = new_node; ++ l->size ++; ++ ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/// -------------------------------------------------------------- ++// 函数名:list_delete_node ++// 功能:删除链表结点 ++// 参数:l--链表指针,data--链表数据指针,可为任意类型 ++// *pfunc为指向一个数据类型比较的函数指针 ++// 返回值:int型,为1表示删除成功,为0表示没有找到匹配数据 ++// 备注:*pfunc函数接口参数ndata为节点数据,data为比较数据,返回为真表示匹配数据 ++/// -------------------------------------------------------------- ++int list_delete_node(List l, void *data, int (*pfunc)(void *ndata, void *data)) ++{ ++ if(l != NULL) ++ { ++ Node prev = l->head; //前一个节点 ++ Node curr = l->head->next; //当前节点 ++ ++ while(curr != NULL) ++ { ++ if(pfunc(curr->data, data)) //如果找到匹配数据 ++ { ++ if(curr == l->tail) //如果是删除尾节点 ++ l->tail = prev; ++ ++ prev->next = prev->next->next; //修改前节点next指针指向下下个节点 ++ ++ free(curr->data); //释放节点数据 ++ free(curr); //释放节点 ++ ++ l->size--; //链表元素总数减1 ++ return 1; //返回真值 ++ } ++ prev = prev->next; //没有找到匹配时移动前节点和当前节点 ++ curr = curr->next; ++ } ++ } ++ ++ return 0; //没有找到匹配数据 ++} ++ ++/// -------------------------------------------------------------- ++// 函数名:list_delete_at ++// 功能: 修改链表节点元素值 ++// 参数: l--链表指针,index--索引值, 范围(0 -- size-1) ++// 返回值:int型,为1表示删除成功,为0表示删除失败 ++// 备注: 如果链表本身为空或是index为非法值,将返回0 ++/// -------------------------------------------------------------- ++int list_delete_at(List l, unsigned int index) ++{ ++ unsigned int cindex = 0; ++ ++ if(l != NULL && index >= 0 && index < l->size) ++ { ++ Node prev = l->head; //前一个节点 ++ Node curr = l->head->next; //当前节点 ++ ++ while(cindex != index) ++ { ++ prev = prev->next; ++ curr = curr->next; ++ cindex ++; ++ } ++ ++ if(index == (l->size) - 1) ++ l->tail = prev; ++ ++ prev->next = prev->next->next; ++ free(curr->data); ++ free(curr); ++ l->size --; ++ ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/// -------------------------------------------------------------- ++// 函数名:list_modify_at ++// 功能: 修改链表节点元素值 ++// 参数: l--链表指针,index--索引值, 范围(0 -- size-1) ++// data--链表数据指针 ++// 返回值:int型,为1表示修改成功,为0表示修改失败 ++// 备注: 如果链表本身为空或是index为非法值,将返回0 ++/// -------------------------------------------------------------- ++int list_modify_at(List l, unsigned int index, void *new_data) ++{ ++ unsigned int cindex = 0; ++ ++ if(l != NULL && index >= 0 && index < l->size ) //非空链表,并且index值合法 ++ { ++ Node curr = l->head->next; ++ while(cindex != index) ++ { ++ curr = curr->next; ++ cindex ++; ++ } ++ memcpy(curr->data, new_data, l->data_size); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/// -------------------------------------------------------------- ++// 函数名:list_sort ++// 功能: 链表排序 ++// 参数: l--链表指针,*pfunc为指向一个数据类型比较的函数指针 ++// 返回值:无 ++// 备注: 使用简单选择排序法,相比冒泡法每次交换,效率高一点 ++/// -------------------------------------------------------------- ++void list_sort(List l, compare pfunc) ++{ ++ if(l != NULL) ++ { ++ Node min, icurr, jcurr; ++ ++ icurr = l->head->next; ++ while(icurr) ++ { ++ min = icurr; //记录最小值 ++ jcurr = icurr->next; //内循环指向下一个节点 ++ while(jcurr) ++ { ++ if(pfunc(min->data, jcurr->data)) //如果找到n+1到最后一个元素最小值 ++ min = jcurr; //记录下最小值的位置 ++ ++ jcurr = jcurr->next; ++ } ++ ++ if(min != icurr) //当最小值位置和n+1元素位置不相同时 ++ { ++ swap_data(min, icurr); //才进行交换,减少交换次数 ++ } ++ ++ icurr = icurr->next; ++ } ++ } ++} ++ ++void swap_data(Node n1, Node n2) ++{ ++ void *temp; ++ ++ temp = n2->data; ++ n2->data = n1->data; ++ n1->data = temp; ++} ++ ++ ++int list_have_same(List l, void *data, int (*pfunc)(void *ndata, void *data)) ++{ ++ if(l != NULL) ++ { ++ Node curr; ++ ++ for(curr = l->head->next; curr != NULL; curr = curr->next) ++ { ++ if(pfunc(curr->data, data)) ++ { ++ return 1; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++int list_have_same_cmp(List l, void *data) ++{ ++ if(l != NULL) ++ { ++ Node curr; ++ ++ for(curr = l->head->next; curr != NULL; curr = curr->next) ++ { ++ if(memcmp(curr->data, data, l->data_size)) ++ { ++ return 1; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++/// -------------------------------------------------------------- ++// 函数名:list_foreach ++// 功能: 遍历链表元素 ++// 参数: l--链表指针,doit为指向一个处理数据的函数指针 ++// 返回值:无 ++// 备注: doit申明为void (*dofunc)(void *ndata)原型 ++/// -------------------------------------------------------------- ++void list_foreach(List l, dofunc doit) ++{ ++ if(l != NULL) ++ { ++ Node curr; ++ ++ for(curr = l->head->next; curr != NULL; curr = curr->next) ++ { ++ doit(curr->data); ++ } ++ } ++} ++ ++/// -------------------------------------------------------------- ++// 函数名:list_clear ++// 功能: 清空链表元素 ++// 参数: l--链表指针 ++// 返回值:无 ++// 备注: 没有使用先Destroy再Init链表的办法,直接实现 ++/// -------------------------------------------------------------- ++void list_clear(List l) ++{ ++ if(l != NULL) ++ { ++ Node temp; ++ Node curr = l->head->next; ++ ++ while(curr != NULL) ++ { ++ temp = curr->next; ++ ++ free(curr->data); //释放节点和数据 ++ free(curr); ++ ++ curr = temp; ++ } ++ ++ l->size = 0; //重置链表数据 ++ l->head->next = NULL; ++ l->tail = l->head; ++ } ++} ++ ++/// -------------------------------------------------------------- ++// 函数名:list_destroy ++// 功能: 释放链表 ++// 参数: l--链表指针 ++// 返回值:空链表指针 ++/// -------------------------------------------------------------- ++List list_destroy(List l) ++{ ++ if(l != NULL) ++ { ++ Node temp; ++ ++ while(l->head) ++ { ++ temp = l->head->next; ++ ++ if(l->head->data != NULL) //如果是头节点就不释放数据空间 ++ free(l->head->data); //先释放节点数据(但是节点数据里也有指针?) ++ free(l->head); //再释放节点 ++ ++ l->head = temp; ++ } ++ ++ free(l); //释放链表本身占用空间 ++ l = NULL; ++ } ++ ++ return l; ++} +diff --git a/server/list.h b/server/list.h +new file mode 100644 +index 0000000..ab49720 +--- /dev/null ++++ b/server/list.h +@@ -0,0 +1,61 @@ ++#ifndef LIST_H_H ++#define LIST_H_H ++ ++#include ++#include ++#include ++ ++typedef struct clist *List; ++ ++typedef int (*compare)(void *ndata, void *data); ++typedef void (*dofunc)(void *ndata); ++ ++typedef int (*lpf0)(List l, void *data); ++typedef int (*lpf1)(List l, void *data, compare pfunc); ++typedef List (*lpf2)(List l); ++typedef void (*lpf3)(List l); ++typedef void (*lpf4)(List l, dofunc pfunc); ++typedef int (*lpf5)(List l, unsigned int index, void *new_data); ++typedef void (*lpf6)(List l, compare pfunc); ++typedef int (*lpf7)(List l, unsigned int index); ++ ++typedef struct cnode ++{ ++ void *data; ++ struct cnode *next; ++}node, *Node; ++ ++typedef struct clist ++{ ++ Node head; ++ Node tail; ++ unsigned int size; ++ unsigned int data_size; ++ lpf0 add_back; ++ lpf0 add_front; ++ lpf1 delete_node; ++ lpf1 have_same; ++ lpf0 have_same_cmp; ++ lpf4 foreach; ++ lpf3 clear; ++ lpf2 destroy; ++ lpf5 modify_at; ++ lpf6 sort; ++ lpf7 delete_at; ++}list; ++ ++//初始化链表 ++List list_init(unsigned int data_size); ++int list_add_back(List l, void *data); ++int list_add_front(List l, void *data); ++int list_delete_node(List l, void *data, compare pfunc); ++int list_delete_at(List l, unsigned int index); ++int list_modify_at(List l, unsigned int index, void *new_data); ++int list_have_same(List l, void *data, compare pfunc); ++int list_have_same_cmp(List l, void *data); ++void list_foreach(List l, dofunc doit); ++void list_sort(List l, compare pfunc); ++void list_clear(List l); ++//释放链表 ++List list_destroy(List l); ++#endif +diff --git a/server/netutils.c b/server/netutils.c +new file mode 100644 +index 0000000..3a32b4d +--- /dev/null ++++ b/server/netutils.c +@@ -0,0 +1,297 @@ ++/* ++ * netutils.c - Network utilities ++ * ++ * Copyright (C) 2013 - 2016, Max Lv ++ * ++ * This file is part of the shadowsocks-libev. ++ * ++ * shadowsocks-libev 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 3 of the License, or ++ * (at your option) any later version. ++ * ++ * shadowsocks-libev 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 shadowsocks-libev; see the file COPYING. If not, see ++ * . ++ */ ++ ++#include ++ ++#include ++#include ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#ifdef __MINGW32__ ++#include "win32.h" ++#define sleep(n) Sleep(1000 * (n)) ++#else ++#include ++#include ++#include ++#include ++#endif ++ ++#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_NET_IF_H) && defined(__linux__) ++#include ++#include ++#define SET_INTERFACE ++#endif ++ ++#include "netutils.h" ++#include "utils.h" ++ ++#ifndef SO_REUSEPORT ++#define SO_REUSEPORT 15 ++#endif ++ ++extern int verbose; ++ ++static const char valid_label_bytes[] = ++ "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"; ++ ++#if defined(MODULE_LOCAL) ++extern int keep_resolving; ++#endif ++ ++int ++set_reuseport(int socket) ++{ ++ int opt = 1; ++ return setsockopt(socket, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)); ++} ++ ++size_t ++get_sockaddr_len(struct sockaddr *addr) ++{ ++ if (addr->sa_family == AF_INET) { ++ return sizeof(struct sockaddr_in); ++ } else if (addr->sa_family == AF_INET6) { ++ return sizeof(struct sockaddr_in6); ++ } ++ return 0; ++} ++ ++#ifdef SET_INTERFACE ++int ++setinterface(int socket_fd, const char *interface_name) ++{ ++ struct ifreq interface; ++ memset(&interface, 0, sizeof(struct ifreq)); ++ strncpy(interface.ifr_name, interface_name, IFNAMSIZ); ++ int res = setsockopt(socket_fd, SOL_SOCKET, SO_BINDTODEVICE, &interface, ++ sizeof(struct ifreq)); ++ return res; ++} ++ ++#endif ++ ++int ++bind_to_address(int socket_fd, const char *host) ++{ ++ if (host != NULL) { ++ struct cork_ip ip; ++ struct sockaddr_storage storage; ++ memset(&storage, 0, sizeof(struct sockaddr_storage)); ++ if (cork_ip_init(&ip, host) != -1) { ++ if (ip.version == 4) { ++ struct sockaddr_in *addr = (struct sockaddr_in *)&storage; ++ dns_pton(AF_INET, host, &addr->sin_addr); ++ addr->sin_family = AF_INET; ++ return bind(socket_fd, (struct sockaddr *)addr, sizeof(struct sockaddr_in)); ++ } else if (ip.version == 6) { ++ struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&storage; ++ dns_pton(AF_INET6, host, &addr->sin6_addr); ++ addr->sin6_family = AF_INET6; ++ return bind(socket_fd, (struct sockaddr *)addr, sizeof(struct sockaddr_in6)); ++ } ++ } ++ } ++ return -1; ++} ++ ++ssize_t ++get_sockaddr(char *host, char *port, ++ struct sockaddr_storage *storage, int block, ++ int ipv6first) ++{ ++ struct cork_ip ip; ++ if (cork_ip_init(&ip, host) != -1) { ++ if (ip.version == 4) { ++ struct sockaddr_in *addr = (struct sockaddr_in *)storage; ++ addr->sin_family = AF_INET; ++ dns_pton(AF_INET, host, &(addr->sin_addr)); ++ if (port != NULL) { ++ addr->sin_port = htons(atoi(port)); ++ } ++ } else if (ip.version == 6) { ++ struct sockaddr_in6 *addr = (struct sockaddr_in6 *)storage; ++ addr->sin6_family = AF_INET6; ++ dns_pton(AF_INET6, host, &(addr->sin6_addr)); ++ if (port != NULL) { ++ addr->sin6_port = htons(atoi(port)); ++ } ++ } ++ return 0; ++ } else { ++ struct addrinfo hints; ++ struct addrinfo *result, *rp; ++ ++ memset(&hints, 0, sizeof(struct addrinfo)); ++ hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */ ++ hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */ ++ ++ int err, i; ++ ++ for (i = 1; i < 8; i++) { ++ err = getaddrinfo(host, port, &hints, &result); ++#if defined(MODULE_LOCAL) ++ if (!keep_resolving) ++ break; ++#endif ++ if ((!block || !err)) { ++ break; ++ } else { ++ sleep(pow(2, i)); ++ LOGE("failed to resolve server name, wait %.0f seconds", pow(2, i)); ++ } ++ } ++ ++ if (err != 0) { ++ LOGE("getaddrinfo: %s", gai_strerror(err)); ++ return -1; ++ } ++ ++ int prefer_af = ipv6first ? AF_INET6 : AF_INET; ++ for (rp = result; rp != NULL; rp = rp->ai_next) ++ if (rp->ai_family == prefer_af) { ++ if (rp->ai_family == AF_INET) ++ memcpy(storage, rp->ai_addr, sizeof(struct sockaddr_in)); ++ else if (rp->ai_family == AF_INET6) ++ memcpy(storage, rp->ai_addr, sizeof(struct sockaddr_in6)); ++ break; ++ } ++ ++ if (rp == NULL) { ++ for (rp = result; rp != NULL; rp = rp->ai_next) { ++ if (rp->ai_family == AF_INET) ++ memcpy(storage, rp->ai_addr, sizeof(struct sockaddr_in)); ++ else if (rp->ai_family == AF_INET6) ++ memcpy(storage, rp->ai_addr, sizeof(struct sockaddr_in6)); ++ break; ++ } ++ } ++ ++ if (rp == NULL) { ++ LOGE("failed to resolve remote addr"); ++ return -1; ++ } ++ ++ freeaddrinfo(result); ++ return 0; ++ } ++ ++ return -1; ++} ++ ++int ++sockaddr_cmp(struct sockaddr_storage *addr1, ++ struct sockaddr_storage *addr2, socklen_t len) ++{ ++ struct sockaddr_in *p1_in = (struct sockaddr_in *)addr1; ++ struct sockaddr_in *p2_in = (struct sockaddr_in *)addr2; ++ struct sockaddr_in6 *p1_in6 = (struct sockaddr_in6 *)addr1; ++ struct sockaddr_in6 *p2_in6 = (struct sockaddr_in6 *)addr2; ++ if (p1_in->sin_family < p2_in->sin_family) ++ return -1; ++ if (p1_in->sin_family > p2_in->sin_family) ++ return 1; ++ /* compare ip4 */ ++ if (p1_in->sin_family == AF_INET) { ++ /* just order it, ntohs not required */ ++ if (p1_in->sin_port < p2_in->sin_port) ++ return -1; ++ if (p1_in->sin_port > p2_in->sin_port) ++ return 1; ++ return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE); ++ } else if (p1_in6->sin6_family == AF_INET6) { ++ /* just order it, ntohs not required */ ++ if (p1_in6->sin6_port < p2_in6->sin6_port) ++ return -1; ++ if (p1_in6->sin6_port > p2_in6->sin6_port) ++ return 1; ++ return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr, ++ INET6_SIZE); ++ } else { ++ /* eek unknown type, perform this comparison for sanity. */ ++ return memcmp(addr1, addr2, len); ++ } ++} ++ ++int ++sockaddr_cmp_addr(struct sockaddr_storage *addr1, ++ struct sockaddr_storage *addr2, socklen_t len) ++{ ++ struct sockaddr_in *p1_in = (struct sockaddr_in *)addr1; ++ struct sockaddr_in *p2_in = (struct sockaddr_in *)addr2; ++ struct sockaddr_in6 *p1_in6 = (struct sockaddr_in6 *)addr1; ++ struct sockaddr_in6 *p2_in6 = (struct sockaddr_in6 *)addr2; ++ if (p1_in->sin_family < p2_in->sin_family) ++ return -1; ++ if (p1_in->sin_family > p2_in->sin_family) ++ return 1; ++ /* compare ip4 */ ++ if (p1_in->sin_family == AF_INET) { ++ return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE); ++ } else if (p1_in6->sin6_family == AF_INET6) { ++ return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr, ++ INET6_SIZE); ++ } else { ++ /* eek unknown type, perform this comparison for sanity. */ ++ return memcmp(addr1, addr2, len); ++ } ++} ++ ++int ++validate_hostname(const char *hostname, const int hostname_len) ++{ ++ if (hostname == NULL) ++ return 0; ++ ++ if (hostname_len < 1 || hostname_len > 255) ++ return 0; ++ ++ if (hostname[0] == '.') ++ return 0; ++ ++ const char *label = hostname; ++ while (label < hostname + hostname_len) { ++ size_t label_len = hostname_len - (label - hostname); ++ char *next_dot = strchr(label, '.'); ++ if (next_dot != NULL) ++ label_len = next_dot - label; ++ ++ if (label + label_len > hostname + hostname_len) ++ return 0; ++ ++ if (label_len > 63 || label_len < 1) ++ return 0; ++ ++ if (label[0] == '-' || label[label_len - 1] == '-') ++ return 0; ++ ++ if (strspn(label, valid_label_bytes) < label_len) ++ return 0; ++ ++ label += label_len + 1; ++ } ++ ++ return 1; ++} +diff --git a/server/netutils.h b/server/netutils.h +new file mode 100644 +index 0000000..0725592 +--- /dev/null ++++ b/server/netutils.h +@@ -0,0 +1,98 @@ ++/* ++ * netutils.h - Network utilities ++ * ++ * Copyright (C) 2013 - 2016, Max Lv ++ * ++ * This file is part of the shadowsocks-libev. ++ * ++ * shadowsocks-libev 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 3 of the License, or ++ * (at your option) any later version. ++ * ++ * shadowsocks-libev 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 shadowsocks-libev; see the file COPYING. If not, see ++ * . ++ */ ++ ++#ifndef _NETUTILS_H ++#define _NETUTILS_H ++ ++#if defined(__linux__) ++#include ++#elif !defined(__MINGW32__) ++#include ++#endif ++ ++// only enable TCP_FASTOPEN on linux ++#if defined(__linux__) ++#include ++/* conditional define for TCP_FASTOPEN */ ++#ifndef TCP_FASTOPEN ++#define TCP_FASTOPEN 23 ++#endif ++/* conditional define for MSG_FASTOPEN */ ++#ifndef MSG_FASTOPEN ++#define MSG_FASTOPEN 0x20000000 ++#endif ++#elif !defined(__APPLE__) ++#ifdef TCP_FASTOPEN ++#undef TCP_FASTOPEN ++#endif ++#endif ++ ++/* Backward compatibility for MPTCP_ENABLED between kernel 3 & 4 */ ++#ifndef MPTCP_ENABLED ++#ifdef TCP_CC_INFO ++#define MPTCP_ENABLED 42 ++#else ++#define MPTCP_ENABLED 26 ++#endif ++#endif ++ ++/** byte size of ip4 address */ ++#define INET_SIZE 4 ++/** byte size of ip6 address */ ++#define INET6_SIZE 16 ++ ++size_t get_sockaddr_len(struct sockaddr *addr); ++ssize_t get_sockaddr(char *host, char *port, ++ struct sockaddr_storage *storage, int block, ++ int ipv6first); ++int set_reuseport(int socket); ++ ++#ifdef SET_INTERFACE ++int setinterface(int socket_fd, const char *interface_name); ++#endif ++ ++int bind_to_address(int socket_fd, const char *address); ++ ++/** ++ * Compare two sockaddrs. Imposes an ordering on the addresses. ++ * Compares address and port. ++ * @param addr1: address 1. ++ * @param addr2: address 2. ++ * @param len: lengths of addr. ++ * @return: 0 if addr1 == addr2. -1 if addr1 is smaller, +1 if larger. ++ */ ++int sockaddr_cmp(struct sockaddr_storage *addr1, ++ struct sockaddr_storage *addr2, socklen_t len); ++ ++/** ++ * Compare two sockaddrs. Compares address, not the port. ++ * @param addr1: address 1. ++ * @param addr2: address 2. ++ * @param len: lengths of addr. ++ * @return: 0 if addr1 == addr2. -1 if addr1 is smaller, +1 if larger. ++ */ ++int sockaddr_cmp_addr(struct sockaddr_storage *addr1, ++ struct sockaddr_storage *addr2, socklen_t len); ++ ++int validate_hostname(const char *hostname, const int hostname_len); ++ ++#endif +diff --git a/server/obfs.c b/server/obfs.c +new file mode 100644 +index 0000000..5c885bf +--- /dev/null ++++ b/server/obfs.c +@@ -0,0 +1,205 @@ ++#include ++#include ++ ++#include "utils.h" ++#include "obfs.h" ++ ++int rand_bytes(uint8_t *output, int len); ++#define OBFS_HMAC_SHA1_LEN 10 ++ ++#include "obfsutil.c" ++#include "crc32.c" ++#include "base64.c" ++#include "http_simple.c" ++#include "tls1.2_ticket.c" ++#include "verify.c" ++#include "auth.c" ++ ++void * init_data() { ++ return malloc(1); ++} ++ ++obfs * new_obfs() { ++ obfs * self = (obfs*)malloc(sizeof(obfs)); ++ self->l_data = NULL; ++ return self; ++} ++ ++void set_server_info(obfs *self, server_info *server) { ++ memmove(&self->server, server, sizeof(server_info)); ++} ++ ++void get_server_info(obfs *self, server_info *server) { ++ memmove(server, &self->server, sizeof(server_info)); ++} ++ ++void dispose_obfs(obfs *self) { ++ free(self); ++} ++ ++obfs_class * new_obfs_class(char *plugin_name) ++{ ++ if (plugin_name == NULL) ++ return NULL; ++ if (strcmp(plugin_name, "origin") == 0) ++ return NULL; ++ if (strcmp(plugin_name, "plain") == 0) ++ return NULL; ++ init_crc32_table(); ++ init_shift128plus(); ++ if (strcmp(plugin_name, "http_simple") == 0) { ++ obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); ++ plugin->init_data = init_data; ++ plugin->new_obfs = http_simple_new_obfs; ++ plugin->get_server_info = get_server_info; ++ plugin->set_server_info = set_server_info; ++ plugin->dispose = http_simple_dispose; ++ ++ plugin->client_encode = http_simple_client_encode; ++ plugin->client_decode = http_simple_client_decode; ++ ++ plugin->server_encode = http_simple_server_encode; ++ plugin->server_decode = http_simple_server_decode; ++ ++ return plugin; ++ } else if (strcmp(plugin_name, "http_post") == 0) { ++ obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); ++ plugin->init_data = init_data; ++ plugin->new_obfs = http_simple_new_obfs; ++ plugin->get_server_info = get_server_info; ++ plugin->set_server_info = set_server_info; ++ plugin->dispose = http_simple_dispose; ++ ++ plugin->client_encode = http_post_client_encode; ++ plugin->client_decode = http_simple_client_decode; ++ ++ plugin->server_encode = http_simple_server_encode; ++ plugin->server_decode = http_simple_server_decode; ++ ++ return plugin; ++ } else if (strcmp(plugin_name, "tls1.2_ticket_auth") == 0) { ++ obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); ++ plugin->init_data = tls12_ticket_auth_init_data; ++ plugin->new_obfs = tls12_ticket_auth_new_obfs; ++ plugin->get_server_info = get_server_info; ++ plugin->set_server_info = set_server_info; ++ plugin->dispose = tls12_ticket_auth_dispose; ++ ++ plugin->client_encode = tls12_ticket_auth_client_encode; ++ plugin->client_decode = tls12_ticket_auth_client_decode; ++ ++ plugin->server_encode = tls12_ticket_auth_server_encode; ++ plugin->server_decode = tls12_ticket_auth_server_decode; ++ ++ return plugin; ++ } else if (strcmp(plugin_name, "verify_simple") == 0) { ++ obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); ++ plugin->init_data = init_data; ++ plugin->new_obfs = verify_simple_new_obfs; ++ plugin->get_server_info = get_server_info; ++ plugin->set_server_info = set_server_info; ++ plugin->dispose = verify_simple_dispose; ++ ++ plugin->client_pre_encrypt = verify_simple_client_pre_encrypt; ++ plugin->client_post_decrypt = verify_simple_client_post_decrypt; ++ plugin->client_udp_pre_encrypt = NULL; ++ plugin->client_udp_post_decrypt = NULL; ++ ++ plugin->server_pre_encrypt = verify_simple_server_pre_encrypt; ++ plugin->server_post_decrypt = verify_simple_server_post_decrypt; ++ plugin->server_udp_pre_encrypt = NULL; ++ plugin->server_udp_post_decrypt = NULL; ++ ++ return plugin; ++ } else if (strcmp(plugin_name, "auth_simple") == 0) { ++ obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); ++ plugin->init_data = auth_simple_init_data; ++ plugin->new_obfs = auth_simple_new_obfs; ++ plugin->get_server_info = get_server_info; ++ plugin->set_server_info = set_server_info; ++ plugin->dispose = auth_simple_dispose; ++ ++ plugin->client_pre_encrypt = auth_simple_client_pre_encrypt; ++ plugin->client_post_decrypt = auth_simple_client_post_decrypt; ++ plugin->client_udp_pre_encrypt = NULL; ++ plugin->client_udp_post_decrypt = NULL; ++ ++ return plugin; ++ } else if (strcmp(plugin_name, "auth_sha1") == 0) { ++ obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); ++ plugin->init_data = auth_simple_init_data; ++ plugin->new_obfs = auth_simple_new_obfs; ++ plugin->get_server_info = get_server_info; ++ plugin->set_server_info = set_server_info; ++ plugin->dispose = auth_simple_dispose; ++ ++ plugin->client_pre_encrypt = auth_sha1_client_pre_encrypt; ++ plugin->client_post_decrypt = auth_sha1_client_post_decrypt; ++ plugin->client_udp_pre_encrypt = NULL; ++ plugin->client_udp_post_decrypt = NULL; ++ ++ return plugin; ++ } else if (strcmp(plugin_name, "auth_sha1_v2") == 0) { ++ obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); ++ plugin->init_data = auth_simple_init_data; ++ plugin->new_obfs = auth_simple_new_obfs; ++ plugin->get_server_info = get_server_info; ++ plugin->set_server_info = set_server_info; ++ plugin->dispose = auth_simple_dispose; ++ ++ plugin->client_pre_encrypt = auth_sha1_v2_client_pre_encrypt; ++ plugin->client_post_decrypt = auth_sha1_v2_client_post_decrypt; ++ plugin->client_udp_pre_encrypt = NULL; ++ plugin->client_udp_post_decrypt = NULL; ++ ++ return plugin; ++ } else if (strcmp(plugin_name, "auth_sha1_v4") == 0) { ++ obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); ++ plugin->init_data = auth_simple_init_data; ++ plugin->new_obfs = auth_simple_new_obfs; ++ plugin->get_server_info = get_server_info; ++ plugin->set_server_info = set_server_info; ++ plugin->dispose = auth_simple_dispose; ++ ++ plugin->client_pre_encrypt = auth_sha1_v4_client_pre_encrypt; ++ plugin->client_post_decrypt = auth_sha1_v4_client_post_decrypt; ++ plugin->client_udp_pre_encrypt = NULL; ++ plugin->client_udp_post_decrypt = NULL; ++ ++ return plugin; ++ } else if (strcmp(plugin_name, "auth_aes128_md5") == 0) { ++ obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); ++ plugin->init_data = auth_simple_init_data; ++ plugin->new_obfs = auth_aes128_md5_new_obfs; ++ plugin->get_server_info = get_server_info; ++ plugin->set_server_info = set_server_info; ++ plugin->dispose = auth_simple_dispose; ++ ++ plugin->client_pre_encrypt = auth_aes128_sha1_client_pre_encrypt; ++ plugin->client_post_decrypt = auth_aes128_sha1_client_post_decrypt; ++ plugin->client_udp_pre_encrypt = auth_aes128_sha1_client_udp_pre_encrypt; ++ plugin->client_udp_post_decrypt = auth_aes128_sha1_client_udp_post_decrypt; ++ ++ return plugin; ++ } else if (strcmp(plugin_name, "auth_aes128_sha1") == 0) { ++ obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); ++ plugin->init_data = auth_simple_init_data; ++ plugin->new_obfs = auth_aes128_sha1_new_obfs; ++ plugin->get_server_info = get_server_info; ++ plugin->set_server_info = set_server_info; ++ plugin->dispose = auth_simple_dispose; ++ ++ plugin->client_pre_encrypt = auth_aes128_sha1_client_pre_encrypt; ++ plugin->client_post_decrypt = auth_aes128_sha1_client_post_decrypt; ++ plugin->client_udp_pre_encrypt = auth_aes128_sha1_client_udp_pre_encrypt; ++ plugin->client_udp_post_decrypt = auth_aes128_sha1_client_udp_post_decrypt; ++ ++ return plugin; ++ } ++ LOGE("Load obfs '%s' failed", plugin_name); ++ return NULL; ++} ++ ++void free_obfs_class(obfs_class *plugin) { ++ free(plugin); ++} +diff --git a/server/obfs.h b/server/obfs.h +new file mode 100644 +index 0000000..74c60c9 +--- /dev/null ++++ b/server/obfs.h +@@ -0,0 +1,100 @@ ++/* ++ * obfs.h - Define shadowsocksR server's buffers and callbacks ++ * ++ * Copyright (C) 2015 - 2016, Break Wa11 ++ */ ++ ++#ifndef _OBFS_H ++#define _OBFS_H ++ ++#include ++#include ++ ++typedef struct server_info { ++ char host[64]; ++ uint16_t port; ++ char *param; ++ void *g_data; ++ uint8_t *iv; ++ size_t iv_len; ++ uint8_t *recv_iv; ++ size_t recv_iv_len; ++ uint8_t *key; ++ size_t key_len; ++ int head_len; ++ size_t tcp_mss; ++}server_info; ++ ++typedef struct obfs { ++ server_info server; ++ void *l_data; ++}obfs; ++ ++typedef struct obfs_class { ++ void * (*init_data)(); ++ obfs * (*new_obfs)(); ++ void (*get_server_info)(obfs *self, server_info *server); ++ void (*set_server_info)(obfs *self, server_info *server); ++ void (*dispose)(obfs *self); ++ ++ int (*client_pre_encrypt)(obfs *self, ++ char **pplaindata, ++ int datalength, ++ size_t* capacity); ++ int (*client_encode)(obfs *self, ++ char **pencryptdata, ++ int datalength, ++ size_t* capacity); ++ int (*client_decode)(obfs *self, ++ char **pencryptdata, ++ int datalength, ++ size_t* capacity, ++ int *needsendback); ++ int (*client_post_decrypt)(obfs *self, ++ char **pplaindata, ++ int datalength, ++ size_t* capacity); ++ int (*client_udp_pre_encrypt)(obfs *self, ++ char **pplaindata, ++ int datalength, ++ size_t* capacity); ++ int (*client_udp_post_decrypt)(obfs *self, ++ char **pplaindata, ++ int datalength, ++ size_t* capacity); ++ int (*server_pre_encrypt)(obfs *self, ++ char **pplaindata, ++ int datalength, ++ size_t* capacity); ++ int (*server_post_decrypt)(obfs *self, ++ char **pplaindata, ++ int datalength, ++ size_t* capacity); ++ int (*server_udp_pre_encrypt)(obfs *self, ++ char **pplaindata, ++ int datalength, ++ size_t* capacity); ++ int (*server_udp_post_decrypt)(obfs *self, ++ char **pplaindata, ++ int datalength, ++ size_t* capacity); ++ int (*server_encode)(obfs *self, ++ char **pencryptdata, ++ int datalength, ++ size_t* capacity); ++ int (*server_decode)(obfs *self, ++ char **pencryptdata, ++ int datalength, ++ size_t* capacity, ++ int *needsendback); ++}obfs_class; ++ ++obfs_class * new_obfs_class(char *plugin_name); ++void free_obfs_class(obfs_class *plugin); ++ ++void set_server_info(obfs *self, server_info *server); ++void get_server_info(obfs *self, server_info *server); ++obfs * new_obfs(); ++void dispose_obfs(obfs *self); ++ ++#endif // _OBFS_H +diff --git a/server/obfsutil.c b/server/obfsutil.c +new file mode 100644 +index 0000000..d00959b +--- /dev/null ++++ b/server/obfsutil.c +@@ -0,0 +1,36 @@ ++int get_head_size(char *plaindata, int size, int def_size) { ++ if (plaindata == NULL || size < 2) ++ return def_size; ++ int head_type = plaindata[0] & 0x7; ++ if (head_type == 1) ++ return 7; ++ if (head_type == 4) ++ return 19; ++ if (head_type == 3) ++ return 4 + plaindata[1]; ++ return def_size; ++} ++ ++static int shift128plus_init_flag = 0; ++static uint64_t shift128plus_s[2] = {0x10000000, 0xFFFFFFFF}; ++ ++void init_shift128plus(void) { ++ if (shift128plus_init_flag == 0) { ++ shift128plus_init_flag = 1; ++ uint32_t seed = time(NULL); ++ shift128plus_s[0] = seed | 0x100000000L; ++ shift128plus_s[1] = ((uint64_t)seed << 32) | 0x1; ++ } ++} ++ ++uint64_t xorshift128plus(void) { ++ uint64_t x = shift128plus_s[0]; ++ uint64_t const y = shift128plus_s[1]; ++ shift128plus_s[0] = y; ++ x ^= x << 23; // a ++ x ^= x >> 17; // b ++ x ^= y ^ (y >> 26); // c ++ shift128plus_s[1] = x; ++ return x + y; ++} ++ +diff --git a/server/protocol.h b/server/protocol.h +new file mode 100644 +index 0000000..eaa866e +--- /dev/null ++++ b/server/protocol.h +@@ -0,0 +1,34 @@ ++/* ++ * Copyright (c) 2014, Dustin Lundquist ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ */ ++#ifndef PROTOCOL_H ++#define PROTOCOL_H ++ ++typedef struct protocol { ++ const int default_port; ++ int(*const parse_packet)(const char *, size_t, char **); ++} protocol_t; ++ ++#endif +diff --git a/server/resolv.c b/server/resolv.c +new file mode 100644 +index 0000000..f580d06 +--- /dev/null ++++ b/server/resolv.c +@@ -0,0 +1,444 @@ ++/* ++ * Copyright (c) 2014, Dustin Lundquist ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef __MINGW32__ ++#include "win32.h" ++#else ++#include ++#include ++#include ++#include ++#endif ++ ++#include "resolv.h" ++#include "utils.h" ++#include "netutils.h" ++ ++/* ++ * Implement DNS resolution interface using libudns ++ */ ++ ++struct ResolvQuery { ++ void (*client_cb)(struct sockaddr *, void *); ++ void (*client_free_cb)(void *); ++ void *client_cb_data; ++ struct dns_query *queries[2]; ++ size_t response_count; ++ struct sockaddr **responses; ++ uint16_t port; ++}; ++ ++extern int verbose; ++ ++static struct ev_io resolv_io_watcher; ++static struct ev_timer resolv_timeout_watcher; ++static const int MODE_IPV4_ONLY = 0; ++static const int MODE_IPV6_ONLY = 1; ++static const int MODE_IPV4_FIRST = 2; ++static const int MODE_IPV6_FIRST = 3; ++static int resolv_mode = 0; ++ ++static void resolv_sock_cb(struct ev_loop *, struct ev_io *, int); ++static void resolv_timeout_cb(struct ev_loop *, struct ev_timer *, int); ++static void dns_query_v4_cb(struct dns_ctx *, struct dns_rr_a4 *, void *); ++static void dns_query_v6_cb(struct dns_ctx *, struct dns_rr_a6 *, void *); ++static void dns_timer_setup_cb(struct dns_ctx *, int, void *); ++static void process_client_callback(struct ResolvQuery *); ++static inline int all_queries_are_null(struct ResolvQuery *); ++static struct sockaddr *choose_ipv4_first(struct ResolvQuery *); ++static struct sockaddr *choose_ipv6_first(struct ResolvQuery *); ++static struct sockaddr *choose_any(struct ResolvQuery *); ++ ++int ++resolv_init(struct ev_loop *loop, char **nameservers, int nameserver_num, int ipv6first) ++{ ++ if (ipv6first) ++ resolv_mode = MODE_IPV6_FIRST; ++ else ++ resolv_mode = MODE_IPV4_FIRST; ++ ++ struct dns_ctx *ctx = &dns_defctx; ++ if (nameservers == NULL) { ++ /* Nameservers not specified, use system resolver config */ ++ dns_init(ctx, 0); ++ } else { ++ dns_reset(ctx); ++ ++ for (int i = 0; i < nameserver_num; i++) { ++ char *server = nameservers[i]; ++ dns_add_serv(ctx, server); ++ } ++ } ++ ++ int sockfd = dns_open(ctx); ++ if (sockfd < 0) { ++ FATAL("Failed to open DNS resolver socket"); ++ } ++ ++ if (nameserver_num == 1 && nameservers != NULL) { ++ if (strncmp("127.0.0.1", nameservers[0], 9) == 0 ++ || strncmp("::1", nameservers[0], 3) == 0) { ++ if (verbose) { ++ LOGI("bind UDP resolver to %s", nameservers[0]); ++ } ++ if (bind_to_address(sockfd, nameservers[0]) == -1) ++ ERROR("bind_to_address"); ++ } ++ } ++ ++#ifdef __MINGW32__ ++ setnonblocking(sockfd); ++#else ++ int flags = fcntl(sockfd, F_GETFL, 0); ++ fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); ++#endif ++ ++ ev_io_init(&resolv_io_watcher, resolv_sock_cb, sockfd, EV_READ); ++ resolv_io_watcher.data = ctx; ++ ++ ev_io_start(loop, &resolv_io_watcher); ++ ++ ev_timer_init(&resolv_timeout_watcher, resolv_timeout_cb, 0.0, 0.0); ++ resolv_timeout_watcher.data = ctx; ++ ++ dns_set_tmcbck(ctx, dns_timer_setup_cb, loop); ++ ++ return sockfd; ++} ++ ++void ++resolv_shutdown(struct ev_loop *loop) ++{ ++ struct dns_ctx *ctx = (struct dns_ctx *)resolv_io_watcher.data; ++ ++ ev_io_stop(loop, &resolv_io_watcher); ++ ++ if (ev_is_active(&resolv_timeout_watcher)) { ++ ev_timer_stop(loop, &resolv_timeout_watcher); ++ } ++ ++ dns_close(ctx); ++} ++ ++struct ResolvQuery * ++resolv_query(const char *hostname, void (*client_cb)(struct sockaddr *, void *), ++ void (*client_free_cb)(void *), void *client_cb_data, ++ uint16_t port) ++{ ++ struct dns_ctx *ctx = (struct dns_ctx *)resolv_io_watcher.data; ++ ++ /* ++ * Wrap udns's call back in our own ++ */ ++ struct ResolvQuery *cb_data = ss_malloc(sizeof(struct ResolvQuery)); ++ if (cb_data == NULL) { ++ LOGE("Failed to allocate memory for DNS query callback data."); ++ return NULL; ++ } ++ memset(cb_data, 0, sizeof(struct ResolvQuery)); ++ ++ cb_data->client_cb = client_cb; ++ cb_data->client_free_cb = client_free_cb; ++ cb_data->client_cb_data = client_cb_data; ++ memset(cb_data->queries, 0, sizeof(cb_data->queries)); ++ cb_data->response_count = 0; ++ cb_data->responses = NULL; ++ cb_data->port = port; ++ ++ /* Submit A and AAAA queries */ ++ if (resolv_mode != MODE_IPV6_ONLY) { ++ cb_data->queries[0] = dns_submit_a4(ctx, ++ hostname, 0, ++ dns_query_v4_cb, cb_data); ++ if (cb_data->queries[0] == NULL) { ++ LOGE("Failed to submit DNS query: %s", ++ dns_strerror(dns_status(ctx))); ++ } ++ } ++ ++ if (resolv_mode != MODE_IPV4_ONLY) { ++ cb_data->queries[1] = dns_submit_a6(ctx, ++ hostname, 0, ++ dns_query_v6_cb, cb_data); ++ if (cb_data->queries[1] == NULL) { ++ LOGE("Failed to submit DNS query: %s", ++ dns_strerror(dns_status(ctx))); ++ } ++ } ++ ++ if (all_queries_are_null(cb_data)) { ++ if (cb_data->client_free_cb != NULL) { ++ cb_data->client_free_cb(cb_data->client_cb_data); ++ } ++ ss_free(cb_data); ++ } ++ ++ return cb_data; ++} ++ ++void ++resolv_cancel(struct ResolvQuery *query_handle) ++{ ++ struct ResolvQuery *cb_data = (struct ResolvQuery *)query_handle; ++ struct dns_ctx *ctx = (struct dns_ctx *)resolv_io_watcher.data; ++ ++ for (int i = 0; i < sizeof(cb_data->queries) / sizeof(cb_data->queries[0]); ++ i++) ++ if (cb_data->queries[i] != NULL) { ++ dns_cancel(ctx, cb_data->queries[i]); ++ ss_free(cb_data->queries[i]); ++ } ++ ++ if (cb_data->client_free_cb != NULL) { ++ cb_data->client_free_cb(cb_data->client_cb_data); ++ } ++ ++ ss_free(cb_data); ++} ++ ++/* ++ * DNS UDP socket activity callback ++ */ ++static void ++resolv_sock_cb(struct ev_loop *loop, struct ev_io *w, int revents) ++{ ++ struct dns_ctx *ctx = (struct dns_ctx *)w->data; ++ ++ if (revents & EV_READ) { ++ dns_ioevent(ctx, ev_now(loop)); ++ } ++} ++ ++/* ++ * Wrapper for client callback we provide to udns ++ */ ++static void ++dns_query_v4_cb(struct dns_ctx *ctx, struct dns_rr_a4 *result, void *data) ++{ ++ struct ResolvQuery *cb_data = (struct ResolvQuery *)data; ++ ++ if (result == NULL) { ++ if (verbose) { ++ LOGI("IPv4 resolv: %s", dns_strerror(dns_status(ctx))); ++ } ++ } else if (result->dnsa4_nrr > 0) { ++ struct sockaddr **new_responses = ss_realloc(cb_data->responses, ++ (cb_data->response_count + ++ result->dnsa4_nrr) * ++ sizeof(struct sockaddr *)); ++ if (new_responses == NULL) { ++ LOGE("Failed to allocate memory for additional DNS responses"); ++ } else { ++ cb_data->responses = new_responses; ++ ++ for (int i = 0; i < result->dnsa4_nrr; i++) { ++ struct sockaddr_in *sa = ++ (struct sockaddr_in *)ss_malloc(sizeof(struct sockaddr_in)); ++ sa->sin_family = AF_INET; ++ sa->sin_port = cb_data->port; ++ sa->sin_addr = result->dnsa4_addr[i]; ++ ++ cb_data->responses[cb_data->response_count] = ++ (struct sockaddr *)sa; ++ if (cb_data->responses[cb_data->response_count] == NULL) { ++ LOGE( ++ "Failed to allocate memory for DNS query result address"); ++ } else { ++ cb_data->response_count++; ++ } ++ } ++ } ++ } ++ ++ ss_free(result); ++ cb_data->queries[0] = NULL; /* mark A query as being completed */ ++ ++ /* Once all queries have completed, call client callback */ ++ if (all_queries_are_null(cb_data)) { ++ return process_client_callback(cb_data); ++ } ++} ++ ++static void ++dns_query_v6_cb(struct dns_ctx *ctx, struct dns_rr_a6 *result, void *data) ++{ ++ struct ResolvQuery *cb_data = (struct ResolvQuery *)data; ++ ++ if (result == NULL) { ++ if (verbose) { ++ LOGI("IPv6 resolv: %s", dns_strerror(dns_status(ctx))); ++ } ++ } else if (result->dnsa6_nrr > 0) { ++ struct sockaddr **new_responses = ss_realloc(cb_data->responses, ++ (cb_data->response_count + ++ result->dnsa6_nrr) * ++ sizeof(struct sockaddr *)); ++ if (new_responses == NULL) { ++ LOGE("Failed to allocate memory for additional DNS responses"); ++ } else { ++ cb_data->responses = new_responses; ++ ++ for (int i = 0; i < result->dnsa6_nrr; i++) { ++ struct sockaddr_in6 *sa = ++ (struct sockaddr_in6 *)ss_malloc(sizeof(struct sockaddr_in6)); ++ sa->sin6_family = AF_INET6; ++ sa->sin6_port = cb_data->port; ++ sa->sin6_addr = result->dnsa6_addr[i]; ++ ++ cb_data->responses[cb_data->response_count] = ++ (struct sockaddr *)sa; ++ if (cb_data->responses[cb_data->response_count] == NULL) { ++ LOGE( ++ "Failed to allocate memory for DNS query result address"); ++ } else { ++ cb_data->response_count++; ++ } ++ } ++ } ++ } ++ ++ ss_free(result); ++ cb_data->queries[1] = NULL; /* mark AAAA query as being completed */ ++ ++ /* Once all queries have completed, call client callback */ ++ if (all_queries_are_null(cb_data)) { ++ return process_client_callback(cb_data); ++ } ++} ++ ++/* ++ * Called once all queries have been completed ++ */ ++static void ++process_client_callback(struct ResolvQuery *cb_data) ++{ ++ struct sockaddr *best_address = NULL; ++ ++ if (resolv_mode == MODE_IPV4_FIRST) { ++ best_address = choose_ipv4_first(cb_data); ++ } else if (resolv_mode == MODE_IPV6_FIRST) { ++ best_address = choose_ipv6_first(cb_data); ++ } else { ++ best_address = choose_any(cb_data); ++ } ++ ++ cb_data->client_cb(best_address, cb_data->client_cb_data); ++ ++ for (int i = 0; i < cb_data->response_count; i++) ++ ss_free(cb_data->responses[i]); ++ ++ ss_free(cb_data->responses); ++ if (cb_data->client_free_cb != NULL) { ++ cb_data->client_free_cb(cb_data->client_cb_data); ++ } ++ ss_free(cb_data); ++} ++ ++static struct sockaddr * ++choose_ipv4_first(struct ResolvQuery *cb_data) ++{ ++ for (int i = 0; i < cb_data->response_count; i++) ++ if (cb_data->responses[i]->sa_family == AF_INET) { ++ return cb_data->responses[i]; ++ } ++ ++ return choose_any(cb_data); ++} ++ ++static struct sockaddr * ++choose_ipv6_first(struct ResolvQuery *cb_data) ++{ ++ for (int i = 0; i < cb_data->response_count; i++) ++ if (cb_data->responses[i]->sa_family == AF_INET6) { ++ return cb_data->responses[i]; ++ } ++ ++ return choose_any(cb_data); ++} ++ ++static struct sockaddr * ++choose_any(struct ResolvQuery *cb_data) ++{ ++ if (cb_data->response_count >= 1) { ++ return cb_data->responses[0]; ++ } ++ ++ return NULL; ++} ++ ++/* ++ * DNS timeout callback ++ */ ++static void ++resolv_timeout_cb(struct ev_loop *loop, struct ev_timer *w, int revents) ++{ ++ struct dns_ctx *ctx = (struct dns_ctx *)w->data; ++ ++ if (revents & EV_TIMER) { ++ dns_timeouts(ctx, 30, ev_now(loop)); ++ } ++} ++ ++/* ++ * Callback to setup DNS timeout callback ++ */ ++static void ++dns_timer_setup_cb(struct dns_ctx *ctx, int timeout, void *data) ++{ ++ struct ev_loop *loop = (struct ev_loop *)data; ++ ++ if (ev_is_active(&resolv_timeout_watcher)) { ++ ev_timer_stop(loop, &resolv_timeout_watcher); ++ } ++ ++ if (ctx != NULL && timeout >= 0) { ++ ev_timer_set(&resolv_timeout_watcher, timeout, 0.0); ++ ev_timer_start(loop, &resolv_timeout_watcher); ++ } ++} ++ ++static inline int ++all_queries_are_null(struct ResolvQuery *cb_data) ++{ ++ int result = 1; ++ ++ for (int i = 0; i < sizeof(cb_data->queries) / sizeof(cb_data->queries[0]); ++ i++) ++ result = result && cb_data->queries[i] == NULL; ++ ++ return result; ++} +diff --git a/server/resolv.h b/server/resolv.h +new file mode 100644 +index 0000000..0552922 +--- /dev/null ++++ b/server/resolv.h +@@ -0,0 +1,50 @@ ++/* ++ * Copyright (c) 2014, Dustin Lundquist ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ */ ++#ifndef RESOLV_H ++#define RESOLV_H ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++ ++#ifdef __MINGW32__ ++#include "win32.h" ++#else ++#include ++#endif ++ ++struct ResolvQuery; ++ ++int resolv_init(struct ev_loop *, char **, int, int); ++struct ResolvQuery *resolv_query(const char *, void (*)(struct sockaddr *, ++ void *), void (*)( ++ void *), void *, uint16_t); ++void resolv_cancel(struct ResolvQuery *); ++void resolv_shutdown(struct ev_loop *); ++ ++#endif +diff --git a/server/rule.c b/server/rule.c +new file mode 100644 +index 0000000..8aae04e +--- /dev/null ++++ b/server/rule.c +@@ -0,0 +1,137 @@ ++/* ++ * Copyright (c) 2011 and 2012, Dustin Lundquist ++ * Copyright (c) 2011 Manuel Kasper ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include ++ ++#ifdef __MINGW32__ ++extern void ss_error(const char *s); ++#endif ++ ++#include "rule.h" ++#include "utils.h" ++ ++static void free_rule(rule_t *); ++ ++rule_t * ++new_rule() ++{ ++ rule_t *rule; ++ ++ rule = calloc(1, sizeof(rule_t)); ++ if (rule == NULL) { ++ ERROR("malloc"); ++ return NULL; ++ } ++ ++ return rule; ++} ++ ++int ++accept_rule_arg(rule_t *rule, const char *arg) ++{ ++ if (rule->pattern == NULL) { ++ rule->pattern = strdup(arg); ++ if (rule->pattern == NULL) { ++ ERROR("strdup failed"); ++ return -1; ++ } ++ } else { ++ LOGE("Unexpected table rule argument: %s", arg); ++ return -1; ++ } ++ ++ return 1; ++} ++ ++void ++add_rule(struct cork_dllist *rules, rule_t *rule) ++{ ++ cork_dllist_add(rules, &rule->entries); ++} ++ ++int ++init_rule(rule_t *rule) ++{ ++ if (rule->pattern_re == NULL) { ++ const char *reerr; ++ int reerroffset; ++ ++ rule->pattern_re = ++ pcre_compile(rule->pattern, 0, &reerr, &reerroffset, NULL); ++ if (rule->pattern_re == NULL) { ++ LOGE("Regex compilation of \"%s\" failed: %s, offset %d", ++ rule->pattern, reerr, reerroffset); ++ return 0; ++ } ++ } ++ ++ return 1; ++} ++ ++rule_t * ++lookup_rule(const struct cork_dllist *rules, const char *name, size_t name_len) ++{ ++ struct cork_dllist_item *curr, *next; ++ ++ if (name == NULL) { ++ name = ""; ++ name_len = 0; ++ } ++ ++ cork_dllist_foreach_void(rules, curr, next) { ++ rule_t *rule = cork_container_of(curr, rule_t, entries); ++ if (pcre_exec(rule->pattern_re, NULL, ++ name, name_len, 0, 0, NULL, 0) >= 0) ++ return rule; ++ } ++ ++ return NULL; ++} ++ ++void ++remove_rule(rule_t *rule) ++{ ++ cork_dllist_remove(&rule->entries); ++ free_rule(rule); ++} ++ ++static void ++free_rule(rule_t *rule) ++{ ++ if (rule == NULL) ++ return; ++ ++ ss_free(rule->pattern); ++ if (rule->pattern_re != NULL) ++ pcre_free(rule->pattern_re); ++ ss_free(rule); ++} +diff --git a/server/rule.h b/server/rule.h +new file mode 100644 +index 0000000..015bc42 +--- /dev/null ++++ b/server/rule.h +@@ -0,0 +1,58 @@ ++/* ++ * Copyright (c) 2011 and 2012, Dustin Lundquist ++ * Copyright (c) 2011 Manuel Kasper ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ */ ++#ifndef RULE_H ++#define RULE_H ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++ ++#ifdef HAVE_PCRE_H ++#include ++#elif HAVE_PCRE_PCRE_H ++#include ++#endif ++ ++typedef struct rule { ++ char *pattern; ++ ++ /* Runtime fields */ ++ pcre *pattern_re; ++ ++ struct cork_dllist_item entries; ++} rule_t; ++ ++void add_rule(struct cork_dllist *, rule_t *); ++int init_rule(rule_t *); ++rule_t *lookup_rule(const struct cork_dllist *, const char *, size_t); ++void remove_rule(rule_t *); ++rule_t *new_rule(); ++int accept_rule_arg(rule_t *, const char *); ++ ++#endif +diff --git a/server/server.c b/server/server.c +new file mode 100644 +index 0000000..65b0e42 +--- /dev/null ++++ b/server/server.c +@@ -0,0 +1,2209 @@ ++/* ++ * server.c - Provide shadowsocks service ++ * ++ * Copyright (C) 2013 - 2016, Max Lv ++ * ++ * This file is part of the shadowsocks-libev. ++ * ++ * shadowsocks-libev 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 3 of the License, or ++ * (at your option) any later version. ++ * ++ * shadowsocks-libev 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 shadowsocks-libev; see the file COPYING. If not, see ++ * . ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifndef __MINGW32__ ++#include ++#include ++#include ++#include ++#include ++#include ++#endif ++ ++#include ++#include ++ ++#ifdef __MINGW32__ ++#include "win32.h" ++#endif ++ ++#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_NET_IF_H) && defined(__linux__) ++#include ++#include ++#define SET_INTERFACE ++#endif ++ ++#include "netutils.h" ++#include "utils.h" ++#include "acl.h" ++#include "server.h" ++ ++#include "obfs.c" // I don't want to modify makefile ++ ++#ifndef EAGAIN ++#define EAGAIN EWOULDBLOCK ++#endif ++ ++#ifndef EWOULDBLOCK ++#define EWOULDBLOCK EAGAIN ++#endif ++ ++#ifndef BUF_SIZE ++#define BUF_SIZE 2048 ++#endif ++ ++#ifndef SSMAXCONN ++#define SSMAXCONN 1024 ++#endif ++ ++#ifndef UPDATE_INTERVAL ++#define UPDATE_INTERVAL 30 ++#endif ++ ++static void signal_cb(EV_P_ ev_signal *w, int revents); ++static void accept_cb(EV_P_ ev_io *w, int revents); ++static void server_send_cb(EV_P_ ev_io *w, int revents); ++static void server_recv_cb(EV_P_ ev_io *w, int revents); ++static void remote_recv_cb(EV_P_ ev_io *w, int revents); ++static void remote_send_cb(EV_P_ ev_io *w, int revents); ++static void server_timeout_cb(EV_P_ ev_timer *watcher, int revents); ++static void block_list_clear_cb(EV_P_ ev_timer *watcher, int revents); ++ ++static remote_t *new_remote(int fd); ++static server_t *new_server(int fd, listen_ctx_t *listener); ++static remote_t *connect_to_remote(EV_P_ struct addrinfo *res, ++ server_t *server); ++ ++static void free_remote(remote_t *remote); ++static void close_and_free_remote(EV_P_ remote_t *remote); ++static void free_server(server_t *server); ++static void close_and_free_server(EV_P_ server_t *server); ++static void server_resolve_cb(struct sockaddr *addr, void *data); ++static void query_free_cb(void *data); ++ ++static size_t parse_header_len(const char atyp, const char *data, size_t offset); ++static int is_header_complete(const buffer_t *buf); ++ ++int verbose = 0; ++ ++static int acl = 0; ++static int mode = TCP_ONLY; ++static int auth = 0; ++static int ipv6first = 0; ++ ++static int protocol_compatible = 0;//SSR ++static int obfs_compatible = 0;//SSR ++ ++static int fast_open = 0; ++#ifdef HAVE_SETRLIMIT ++static int nofile = 0; ++#endif ++static int remote_conn = 0; ++static int server_conn = 0; ++ ++static char *bind_address = NULL; ++static char *server_port = NULL; ++static char *manager_address = NULL; ++uint64_t tx = 0; ++uint64_t rx = 0; ++ev_timer stat_update_watcher; ++ev_timer block_list_watcher; ++ ++static struct cork_dllist connections; ++ ++static void ++stat_update_cb(EV_P_ ev_timer *watcher, int revents) ++{ ++ struct sockaddr_un svaddr, claddr; ++ int sfd = -1; ++ size_t msgLen; ++ char resp[BUF_SIZE]; ++ ++ if (verbose) { ++ LOGI("update traffic stat: tx: %" PRIu64 " rx: %" PRIu64 "", tx, rx); ++ } ++ ++ snprintf(resp, BUF_SIZE, "stat: {\"%s\":%" PRIu64 "}", server_port, tx + rx); ++ msgLen = strlen(resp) + 1; ++ ++ ss_addr_t ip_addr = { .host = NULL, .port = NULL }; ++ parse_addr(manager_address, &ip_addr); ++ ++ if (ip_addr.host == NULL || ip_addr.port == NULL) { ++ sfd = socket(AF_UNIX, SOCK_DGRAM, 0); ++ if (sfd == -1) { ++ ERROR("stat_socket"); ++ return; ++ } ++ ++ memset(&claddr, 0, sizeof(struct sockaddr_un)); ++ claddr.sun_family = AF_UNIX; ++ snprintf(claddr.sun_path, sizeof(claddr.sun_path), "/tmp/shadowsocks.%s", server_port); ++ ++ unlink(claddr.sun_path); ++ ++ if (bind(sfd, (struct sockaddr *)&claddr, sizeof(struct sockaddr_un)) == -1) { ++ ERROR("stat_bind"); ++ close(sfd); ++ return; ++ } ++ ++ memset(&svaddr, 0, sizeof(struct sockaddr_un)); ++ svaddr.sun_family = AF_UNIX; ++ strncpy(svaddr.sun_path, manager_address, sizeof(svaddr.sun_path) - 1); ++ ++ if (sendto(sfd, resp, strlen(resp) + 1, 0, (struct sockaddr *)&svaddr, ++ sizeof(struct sockaddr_un)) != msgLen) { ++ ERROR("stat_sendto"); ++ close(sfd); ++ return; ++ } ++ ++ unlink(claddr.sun_path); ++ } else { ++ struct sockaddr_storage storage; ++ memset(&storage, 0, sizeof(struct sockaddr_storage)); ++ if (get_sockaddr(ip_addr.host, ip_addr.port, &storage, 0, ipv6first) == -1) { ++ ERROR("failed to parse the manager addr"); ++ return; ++ } ++ ++ sfd = socket(storage.ss_family, SOCK_DGRAM, 0); ++ ++ if (sfd == -1) { ++ ERROR("stat_socket"); ++ return; ++ } ++ ++ size_t addr_len = get_sockaddr_len((struct sockaddr *)&storage); ++ if (sendto(sfd, resp, strlen(resp) + 1, 0, (struct sockaddr *)&storage, ++ addr_len) != msgLen) { ++ ERROR("stat_sendto"); ++ close(sfd); ++ return; ++ } ++ } ++ ++ close(sfd); ++} ++ ++static void ++free_connections(struct ev_loop *loop) ++{ ++ struct cork_dllist_item *curr, *next; ++ cork_dllist_foreach_void(&connections, curr, next) { ++ server_t *server = cork_container_of(curr, server_t, entries); ++ remote_t *remote = server->remote; ++ close_and_free_server(loop, server); ++ close_and_free_remote(loop, remote); ++ } ++} ++ ++static size_t ++parse_header_len(const char atyp, const char *data, size_t offset) ++{ ++ size_t len = 0; ++ if ((atyp & ADDRTYPE_MASK) == 1) { ++ // IP V4 ++ len += sizeof(struct in_addr); ++ } else if ((atyp & ADDRTYPE_MASK) == 3) { ++ // Domain name ++ uint8_t name_len = *(uint8_t *)(data + offset); ++ len += name_len + 1; ++ } else if ((atyp & ADDRTYPE_MASK) == 4) { ++ // IP V6 ++ len += sizeof(struct in6_addr); ++ } else { ++ return 0; ++ } ++ len += 2; ++ return len; ++} ++ ++static int ++is_header_complete(const buffer_t *buf) ++{ ++ size_t header_len = 0; ++ size_t buf_len = buf->len; ++ ++ char atyp = buf->array[header_len]; ++ ++ // 1 byte for atyp ++ header_len++; ++ ++ if ((atyp & ADDRTYPE_MASK) == 1) { ++ // IP V4 ++ header_len += sizeof(struct in_addr); ++ } else if ((atyp & ADDRTYPE_MASK) == 3) { ++ // Domain name ++ // domain len + len of domain ++ if (buf_len < header_len + 1) ++ return 0; ++ uint8_t name_len = *(uint8_t *)(buf->array + header_len); ++ header_len += name_len + 1; ++ } else if ((atyp & ADDRTYPE_MASK) == 4) { ++ // IP V6 ++ header_len += sizeof(struct in6_addr); ++ } else { ++ return -1; ++ } ++ ++ // len of port ++ header_len += 2; ++ ++ // size of ONETIMEAUTH_BYTES ++ if (auth || (atyp & ONETIMEAUTH_FLAG)) { ++ header_len += ONETIMEAUTH_BYTES; ++ } ++ ++ return buf_len >= header_len ? 1 : 0; ++} ++ ++static char * ++get_peer_name(int fd) ++{ ++ static char peer_name[INET6_ADDRSTRLEN] = { 0 }; ++ struct sockaddr_storage addr; ++ socklen_t len = sizeof(struct sockaddr_storage); ++ memset(&addr, 0, len); ++ memset(peer_name, 0, INET6_ADDRSTRLEN); ++ int err = getpeername(fd, (struct sockaddr *)&addr, &len); ++ if (err == 0) { ++ if (addr.ss_family == AF_INET) { ++ struct sockaddr_in *s = (struct sockaddr_in *)&addr; ++ dns_ntop(AF_INET, &s->sin_addr, peer_name, INET_ADDRSTRLEN); ++ } else if (addr.ss_family == AF_INET6) { ++ struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr; ++ dns_ntop(AF_INET6, &s->sin6_addr, peer_name, INET6_ADDRSTRLEN); ++ } ++ } else { ++ return NULL; ++ } ++ return peer_name; ++} ++ ++#ifdef __linux__ ++static void ++set_linger(int fd) ++{ ++ struct linger so_linger; ++ memset(&so_linger, 0, sizeof(struct linger)); ++ so_linger.l_onoff = 1; ++ so_linger.l_linger = 0; ++ setsockopt(fd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger); ++} ++#endif ++ ++static void ++reset_addr(int fd) ++{ ++ char *peer_name; ++ peer_name = get_peer_name(fd); ++ if (peer_name != NULL) { ++ remove_from_block_list(peer_name); ++ } ++} ++ ++static void ++report_addr(int fd, int err_level) ++{ ++#ifdef __linux__ ++ set_linger(fd); ++#endif ++ ++ char *peer_name; ++ peer_name = get_peer_name(fd); ++ if (peer_name != NULL) { ++ LOGE("failed to handshake with %s", peer_name); ++ update_block_list(peer_name, err_level); ++ } ++} ++ ++int ++setfastopen(int fd) ++{ ++ int s = 0; ++#ifdef TCP_FASTOPEN ++ if (fast_open) { ++#ifdef __APPLE__ ++ int opt = 1; ++#else ++ int opt = 5; ++#endif ++ s = setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, &opt, sizeof(opt)); ++ ++ if (s == -1) { ++ if (errno == EPROTONOSUPPORT || errno == ENOPROTOOPT) { ++ LOGE("fast open is not supported on this platform"); ++ fast_open = 0; ++ } else { ++ ERROR("setsockopt"); ++ } ++ } ++ } ++#endif ++ return s; ++} ++ ++#ifndef __MINGW32__ ++int ++setnonblocking(int fd) ++{ ++ int flags; ++ if (-1 == (flags = fcntl(fd, F_GETFL, 0))) { ++ flags = 0; ++ } ++ return fcntl(fd, F_SETFL, flags | O_NONBLOCK); ++} ++ ++#endif ++ ++int ++create_and_bind(const char *host, const char *port, int mptcp) ++{ ++ struct addrinfo hints; ++ struct addrinfo *result, *rp, *ipv4v6bindall; ++ int s, listen_sock; ++ ++ memset(&hints, 0, sizeof(struct addrinfo)); ++ hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */ ++ hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */ ++ hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; /* For wildcard IP address */ ++ hints.ai_protocol = IPPROTO_TCP; ++ ++ for (int i = 1; i < 8; i++) { ++ s = getaddrinfo(host, port, &hints, &result); ++ if (s == 0) { ++ break; ++ } else { ++ sleep(pow(2, i)); ++ LOGE("failed to resolve server name, wait %.0f seconds", pow(2, i)); ++ } ++ } ++ ++ if (s != 0) { ++ LOGE("getaddrinfo: %s", gai_strerror(s)); ++ return -1; ++ } ++ ++ rp = result; ++ ++ /* ++ * On Linux, with net.ipv6.bindv6only = 0 (the default), getaddrinfo(NULL) with ++ * AI_PASSIVE returns 0.0.0.0 and :: (in this order). AI_PASSIVE was meant to ++ * return a list of addresses to listen on, but it is impossible to listen on ++ * 0.0.0.0 and :: at the same time, if :: implies dualstack mode. ++ */ ++ if (!host) { ++ ipv4v6bindall = result; ++ ++ /* Loop over all address infos found until a IPV6 address is found. */ ++ while (ipv4v6bindall) { ++ if (ipv4v6bindall->ai_family == AF_INET6) { ++ rp = ipv4v6bindall; /* Take first IPV6 address available */ ++ break; ++ } ++ ipv4v6bindall = ipv4v6bindall->ai_next; /* Get next address info, if any */ ++ } ++ } ++ ++ for (/*rp = result*/; rp != NULL; rp = rp->ai_next) { ++ listen_sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); ++ if (listen_sock == -1) { ++ continue; ++ } ++ ++ if (rp->ai_family == AF_INET6) { ++ int ipv6only = host ? 1 : 0; ++ setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, sizeof(ipv6only)); ++ } ++ ++ int opt = 1; ++ setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); ++#ifdef SO_NOSIGPIPE ++ setsockopt(listen_sock, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt)); ++#endif ++ int err = set_reuseport(listen_sock); ++ if (err == 0) { ++ LOGI("tcp port reuse enabled"); ++ } ++ ++ if (mptcp == 1) { ++ int err = setsockopt(listen_sock, SOL_TCP, MPTCP_ENABLED, &opt, sizeof(opt)); ++ if (err == -1) { ++ ERROR("failed to enable multipath TCP"); ++ } ++ } ++ ++ s = bind(listen_sock, rp->ai_addr, rp->ai_addrlen); ++ if (s == 0) { ++ /* We managed to bind successfully! */ ++ break; ++ } else { ++ ERROR("bind"); ++ } ++ ++ close(listen_sock); ++ } ++ ++ if (rp == NULL) { ++ LOGE("Could not bind"); ++ return -1; ++ } ++ ++ freeaddrinfo(result); ++ ++ return listen_sock; ++} ++ ++static remote_t * ++connect_to_remote(EV_P_ struct addrinfo *res, ++ server_t *server) ++{ ++ int sockfd; ++#ifdef SET_INTERFACE ++ const char *iface = server->listen_ctx->iface; ++#endif ++ ++ if (acl) { ++ char ipstr[INET6_ADDRSTRLEN]; ++ memset(ipstr, 0, INET6_ADDRSTRLEN); ++ ++ if (res->ai_addr->sa_family == AF_INET) { ++ struct sockaddr_in *s = (struct sockaddr_in *)res->ai_addr; ++ dns_ntop(AF_INET, &s->sin_addr, ipstr, INET_ADDRSTRLEN); ++ } else if (res->ai_addr->sa_family == AF_INET6) { ++ struct sockaddr_in6 *s = (struct sockaddr_in6 *)res->ai_addr; ++ dns_ntop(AF_INET6, &s->sin6_addr, ipstr, INET6_ADDRSTRLEN); ++ } ++ ++ if (outbound_block_match_host(ipstr) == 1) { ++ if (verbose) ++ LOGI("outbound blocked %s", ipstr); ++ return NULL; ++ } ++ } ++ ++ // initialize remote socks ++ sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); ++ if (sockfd == -1) { ++ ERROR("socket"); ++ close(sockfd); ++ return NULL; ++ } ++ ++ int opt = 1; ++ setsockopt(sockfd, SOL_TCP, TCP_NODELAY, &opt, sizeof(opt)); ++#ifdef SO_NOSIGPIPE ++ setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt)); ++#endif ++ setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); ++ ++ // setup remote socks ++ ++ if (setnonblocking(sockfd) == -1) ++ ERROR("setnonblocking"); ++ ++ if (bind_address != NULL) ++ if (bind_to_address(sockfd, bind_address) == -1) { ++ ERROR("bind_to_address"); ++ close(sockfd); ++ return NULL; ++ } ++ ++#ifdef SET_INTERFACE ++ if (iface) { ++ if (setinterface(sockfd, iface) == -1) { ++ ERROR("setinterface"); ++ close(sockfd); ++ return NULL; ++ } ++ } ++#endif ++ ++ remote_t *remote = new_remote(sockfd); ++ ++#ifdef TCP_FASTOPEN ++ if (fast_open) { ++#ifdef __APPLE__ ++ ((struct sockaddr_in *)(res->ai_addr))->sin_len = sizeof(struct sockaddr_in); ++ sa_endpoints_t endpoints; ++ memset((char *)&endpoints, 0, sizeof(endpoints)); ++ endpoints.sae_dstaddr = res->ai_addr; ++ endpoints.sae_dstaddrlen = res->ai_addrlen; ++ ++ struct iovec iov; ++ iov.iov_base = server->buf->array + server->buf->idx; ++ iov.iov_len = server->buf->len; ++ size_t len; ++ int s = connectx(sockfd, &endpoints, SAE_ASSOCID_ANY, CONNECT_DATA_IDEMPOTENT, ++ &iov, 1, &len, NULL); ++ if (s == 0) { ++ s = len; ++ } ++#else ++ ssize_t s = sendto(sockfd, server->buf->array + server->buf->idx, ++ server->buf->len, MSG_FASTOPEN, res->ai_addr, ++ res->ai_addrlen); ++#endif ++ if (s == -1) { ++ if (errno == CONNECT_IN_PROGRESS || errno == EAGAIN ++ || errno == EWOULDBLOCK) { ++ // The remote server doesn't support tfo or it's the first connection to the server. ++ // It will automatically fall back to conventional TCP. ++ } else if (errno == EOPNOTSUPP || errno == EPROTONOSUPPORT || ++ errno == ENOPROTOOPT) { ++ // Disable fast open as it's not supported ++ fast_open = 0; ++ LOGE("fast open is not supported on this platform"); ++ } else { ++ ERROR("sendto"); ++ } ++ } else if (s <= server->buf->len) { ++ server->buf->idx += s; ++ server->buf->len -= s; ++ } else { ++ server->buf->idx = 0; ++ server->buf->len = 0; ++ } ++ } ++#endif ++ ++ if (!fast_open) { ++ int r = connect(sockfd, res->ai_addr, res->ai_addrlen); ++ ++ if (r == -1 && errno != CONNECT_IN_PROGRESS) { ++ ERROR("connect"); ++ close_and_free_remote(EV_A_ remote); ++ return NULL; ++ } ++ } ++ ++ return remote; ++} ++ ++static void ++server_recv_cb(EV_P_ ev_io *w, int revents) ++{ ++ server_ctx_t *server_recv_ctx = (server_ctx_t *)w; ++ server_t *server = server_recv_ctx->server; ++ remote_t *remote = NULL; ++ ++ int len = server->buf->len; ++ buffer_t *buf = server->buf; ++ ++ if (server->stage > STAGE_PARSE) { ++ remote = server->remote; ++ buf = remote->buf; ++ len = 0; ++ ++ ev_timer_again(EV_A_ & server->recv_ctx->watcher); ++ } ++ ++ if (len > BUF_SIZE) { ++ ERROR("out of recv buffer"); ++ close_and_free_remote(EV_A_ remote); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ ++ ssize_t r = recv(server->fd, buf->array + len, BUF_SIZE - len, 0); ++ ++ if (r == 0) { ++ // connection closed ++ if (verbose) { ++ LOGI("server_recv close the connection"); ++ } ++ close_and_free_remote(EV_A_ remote); ++ close_and_free_server(EV_A_ server); ++ return; ++ } else if (r == -1) { ++ if (errno == EAGAIN || errno == EWOULDBLOCK) { ++ // no data ++ // continue to wait for recv ++ return; ++ } else { ++ ERROR("server recv"); ++ close_and_free_remote(EV_A_ remote); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ } ++ ++ tx += r; ++ ++ if (server->stage == STAGE_ERROR) { ++ server->buf->len = 0; ++ server->buf->idx = 0; ++ return; ++ } ++ ++ // handle incomplete header part 1 ++ if (server->stage == STAGE_INIT) { ++ buf->len += r; ++ if (buf->len <= enc_get_iv_len() + 1) { ++ // wait for more ++ return; ++ } ++ } else { ++ buf->len = r; ++ } ++ ++ // SSR beg ++ ++ if (server->obfs_plugin) { ++ obfs_class *obfs_plugin = server->obfs_plugin; ++ if (obfs_plugin->server_decode) { ++ int needsendback = 0; ++ ++ if(obfs_compatible == 1) ++ { ++ char *back_buf = (char*)malloc(sizeof(buffer_t)); ++ memcpy(back_buf, buf, sizeof(buffer_t)); ++ buf->len = obfs_plugin->server_decode(server->obfs, &buf->array, buf->len, &buf->capacity, &needsendback); ++ ++ if ((int)buf->len < 0) ++ { ++ LOGE("obfs_compatible"); ++ memcpy(buf, back_buf, sizeof(buffer_t)); ++ free(back_buf); ++ server->obfs_compatible_state = 1; ++ } ++ } ++ else ++ { ++ buf->len = obfs_plugin->server_decode(server->obfs, &buf->array, buf->len, &buf->capacity, &needsendback); ++ if ((int)buf->len < 0) { ++ LOGE("server_decode"); ++ close_and_free_remote(EV_A_ remote); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ } ++ ++ if (needsendback) { ++ size_t capacity = BUF_SIZE; ++ char *sendback_buf = (char*)malloc(capacity); ++ obfs_class *obfs_plugin = server->obfs_plugin; ++ if (obfs_plugin->server_encode) { ++ int len = obfs_plugin->server_encode(server->obfs, &sendback_buf, 0, &capacity); ++ send(server->fd, sendback_buf, len, 0); ++ } ++ free(sendback_buf); ++ return; ++ } ++ } ++ } ++ ++ int err = ss_decrypt(buf, server->d_ctx, BUF_SIZE); ++ ++ if (err) { ++ report_addr(server->fd, MALICIOUS); ++ close_and_free_remote(EV_A_ remote); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ ++ if (server->protocol_plugin) { ++ obfs_class *protocol_plugin = server->protocol_plugin; ++ if (protocol_plugin->server_post_decrypt) { ++ ++ if(protocol_compatible == 1) ++ { ++ char *back_buf = (char*)malloc(sizeof(buffer_t)); ++ memcpy(back_buf, buf, sizeof(buffer_t)); ++ buf->len = protocol_plugin->server_post_decrypt(server->protocol, &buf->array, buf->len, &buf->capacity); ++ ++ if ((int)buf->len < 0) { ++ LOGE("protocol_compatible"); ++ memcpy(buf, back_buf, sizeof(buffer_t)); ++ free(back_buf); ++ server->protocol_compatible_state = 1; ++ } ++ if ( buf->len == 0 ) ++ { ++ LOGE("protocol_compatible"); ++ memcpy(buf, back_buf, sizeof(buffer_t)); ++ free(back_buf); ++ server->protocol_compatible_state = 1; ++ } ++ } ++ else ++ { ++ buf->len = protocol_plugin->server_post_decrypt(server->protocol, &buf->array, buf->len, &buf->capacity); ++ if ((int)buf->len < 0) { ++ LOGE("server_post_decrypt"); ++ close_and_free_remote(EV_A_ remote); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ if ( buf->len == 0 ) ++ { ++ LOGE("server_post_decrypt"); ++ return; ++ } ++ } ++ } ++ } ++ // SSR end ++ ++ // handle incomplete header part 2 ++ if (server->stage == STAGE_INIT) { ++ int ret = is_header_complete(server->buf); ++ if (ret == 1) { ++ bfree(server->header_buf); ++ ss_free(server->header_buf); ++ server->stage = STAGE_PARSE; ++ } else if (ret == -1) { ++ server->stage = STAGE_ERROR; ++ report_addr(server->fd, MALFORMED); ++ server->buf->len = 0; ++ server->buf->idx = 0; ++ return; ++ } else { ++ server->stage = STAGE_HANDSHAKE; ++ } ++ } ++ ++ if (server->stage == STAGE_HANDSHAKE) { ++ size_t header_len = server->header_buf->len; ++ brealloc(server->header_buf, server->buf->len + header_len, BUF_SIZE); ++ memcpy(server->header_buf->array + header_len, ++ server->buf->array, server->buf->len); ++ server->header_buf->len = server->buf->len + header_len; ++ ++ int ret = is_header_complete(server->buf); ++ ++ if (ret == 1) { ++ brealloc(server->buf, server->header_buf->len, BUF_SIZE); ++ memcpy(server->buf->array, server->header_buf->array, server->header_buf->len); ++ server->buf->len = server->header_buf->len; ++ bfree(server->header_buf); ++ ss_free(server->header_buf); ++ server->stage = STAGE_PARSE; ++ } else { ++ if (ret == -1) ++ server->stage = STAGE_ERROR; ++ server->buf->len = 0; ++ server->buf->idx = 0; ++ return; ++ } ++ } ++ ++ // handshake and transmit data ++ if (server->stage == STAGE_STREAM) { ++ if (server->auth && !ss_check_hash(remote->buf, server->chunk, server->d_ctx, BUF_SIZE)) { ++ LOGE("hash error"); ++ report_addr(server->fd, BAD); ++ close_and_free_server(EV_A_ server); ++ close_and_free_remote(EV_A_ remote); ++ return; ++ } ++ ++ int s = send(remote->fd, remote->buf->array, remote->buf->len, 0); ++ if (s == -1) { ++ if (errno == EAGAIN || errno == EWOULDBLOCK) { ++ // no data, wait for send ++ remote->buf->idx = 0; ++ ev_io_stop(EV_A_ & server_recv_ctx->io); ++ ev_io_start(EV_A_ & remote->send_ctx->io); ++ } else { ++ ERROR("server_recv_send"); ++ close_and_free_remote(EV_A_ remote); ++ close_and_free_server(EV_A_ server); ++ } ++ } else if (s < remote->buf->len) { ++ remote->buf->len -= s; ++ remote->buf->idx = s; ++ ev_io_stop(EV_A_ & server_recv_ctx->io); ++ ev_io_start(EV_A_ & remote->send_ctx->io); ++ } ++ return; ++ } else if (server->stage == STAGE_PARSE) { ++ /* ++ * Shadowsocks TCP Relay Header: ++ * ++ * +------+----------+----------+----------------+ ++ * | ATYP | DST.ADDR | DST.PORT | HMAC-SHA1 | ++ * +------+----------+----------+----------------+ ++ * | 1 | Variable | 2 | 10 | ++ * +------+----------+----------+----------------+ ++ * ++ * If ATYP & ONETIMEAUTH_FLAG(0x10) != 0, Authentication (HMAC-SHA1) is enabled. ++ * ++ * The key of HMAC-SHA1 is (IV + KEY) and the input is the whole header. ++ * The output of HMAC-SHA is truncated to 10 bytes (leftmost bits). ++ */ ++ ++ /* ++ * Shadowsocks Request's Chunk Authentication for TCP Relay's payload ++ * (No chunk authentication for response's payload): ++ * ++ * +------+-----------+-------------+------+ ++ * | LEN | HMAC-SHA1 | DATA | ... ++ * +------+-----------+-------------+------+ ++ * | 2 | 10 | Variable | ... ++ * +------+-----------+-------------+------+ ++ * ++ * The key of HMAC-SHA1 is (IV + CHUNK ID) ++ * The output of HMAC-SHA is truncated to 10 bytes (leftmost bits). ++ */ ++ ++ int offset = 0; ++ int need_query = 0; ++ char atyp = server->buf->array[offset++]; ++ char host[257] = { 0 }; ++ uint16_t port = 0; ++ struct addrinfo info; ++ struct sockaddr_storage storage; ++ memset(&info, 0, sizeof(struct addrinfo)); ++ memset(&storage, 0, sizeof(struct sockaddr_storage)); ++ ++ if (auth || (atyp & ONETIMEAUTH_FLAG)) { ++ size_t header_len = parse_header_len(atyp, server->buf->array, offset); ++ size_t len = server->buf->len; ++ ++ if (header_len == 0 || len < offset + header_len + ONETIMEAUTH_BYTES) { ++ report_addr(server->fd, MALFORMED); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ ++ server->buf->len = offset + header_len + ONETIMEAUTH_BYTES; ++ if (ss_onetimeauth_verify(server->buf, server->d_ctx->evp.iv)) { ++ report_addr(server->fd, BAD); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ ++ server->buf->len = len; ++ server->auth = 1; ++ } ++ ++ // get remote addr and port ++ if ((atyp & ADDRTYPE_MASK) == 1) { ++ // IP V4 ++ struct sockaddr_in *addr = (struct sockaddr_in *)&storage; ++ size_t in_addr_len = sizeof(struct in_addr); ++ addr->sin_family = AF_INET; ++ if (server->buf->len >= in_addr_len + 3) { ++ addr->sin_addr = *(struct in_addr *)(server->buf->array + offset); ++ dns_ntop(AF_INET, (const void *)(server->buf->array + offset), ++ host, INET_ADDRSTRLEN); ++ offset += in_addr_len; ++ } else { ++ LOGE("invalid header with addr type %d", atyp); ++ report_addr(server->fd, MALFORMED); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ addr->sin_port = *(uint16_t *)(server->buf->array + offset); ++ info.ai_family = AF_INET; ++ info.ai_socktype = SOCK_STREAM; ++ info.ai_protocol = IPPROTO_TCP; ++ info.ai_addrlen = sizeof(struct sockaddr_in); ++ info.ai_addr = (struct sockaddr *)addr; ++ } else if ((atyp & ADDRTYPE_MASK) == 3) { ++ // Domain name ++ uint8_t name_len = *(uint8_t *)(server->buf->array + offset); ++ if (name_len + 4 <= server->buf->len) { ++ memcpy(host, server->buf->array + offset + 1, name_len); ++ offset += name_len + 1; ++ } else { ++ LOGE("invalid name length: %d", name_len); ++ report_addr(server->fd, MALFORMED); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ if (acl && outbound_block_match_host(host) == 1) { ++ if (verbose) ++ LOGI("outbound blocked %s", host); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ struct cork_ip ip; ++ if (cork_ip_init(&ip, host) != -1) { ++ info.ai_socktype = SOCK_STREAM; ++ info.ai_protocol = IPPROTO_TCP; ++ if (ip.version == 4) { ++ struct sockaddr_in *addr = (struct sockaddr_in *)&storage; ++ dns_pton(AF_INET, host, &(addr->sin_addr)); ++ addr->sin_port = *(uint16_t *)(server->buf->array + offset); ++ addr->sin_family = AF_INET; ++ info.ai_family = AF_INET; ++ info.ai_addrlen = sizeof(struct sockaddr_in); ++ info.ai_addr = (struct sockaddr *)addr; ++ } else if (ip.version == 6) { ++ struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&storage; ++ dns_pton(AF_INET6, host, &(addr->sin6_addr)); ++ addr->sin6_port = *(uint16_t *)(server->buf->array + offset); ++ addr->sin6_family = AF_INET6; ++ info.ai_family = AF_INET6; ++ info.ai_addrlen = sizeof(struct sockaddr_in6); ++ info.ai_addr = (struct sockaddr *)addr; ++ } ++ } else { ++ if (!validate_hostname(host, name_len)) { ++ LOGE("invalid host name"); ++ report_addr(server->fd, MALFORMED); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ need_query = 1; ++ } ++ } else if ((atyp & ADDRTYPE_MASK) == 4) { ++ // IP V6 ++ struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&storage; ++ size_t in6_addr_len = sizeof(struct in6_addr); ++ addr->sin6_family = AF_INET6; ++ if (server->buf->len >= in6_addr_len + 3) { ++ addr->sin6_addr = *(struct in6_addr *)(server->buf->array + offset); ++ dns_ntop(AF_INET6, (const void *)(server->buf->array + offset), ++ host, INET6_ADDRSTRLEN); ++ offset += in6_addr_len; ++ } else { ++ LOGE("invalid header with addr type %d", atyp); ++ report_addr(server->fd, MALFORMED); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ addr->sin6_port = *(uint16_t *)(server->buf->array + offset); ++ info.ai_family = AF_INET6; ++ info.ai_socktype = SOCK_STREAM; ++ info.ai_protocol = IPPROTO_TCP; ++ info.ai_addrlen = sizeof(struct sockaddr_in6); ++ info.ai_addr = (struct sockaddr *)addr; ++ } ++ ++ if (offset == 1) { ++ LOGE("invalid header with addr type %d", atyp); ++ report_addr(server->fd, MALFORMED); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ ++ port = (*(uint16_t *)(server->buf->array + offset)); ++ ++ offset += 2; ++ ++ if (server->auth) { ++ offset += ONETIMEAUTH_BYTES; ++ } ++ ++ if (server->buf->len < offset) { ++ report_addr(server->fd, MALFORMED); ++ close_and_free_server(EV_A_ server); ++ return; ++ } else { ++ server->buf->len -= offset; ++ memmove(server->buf->array, server->buf->array + offset, server->buf->len); ++ } ++ ++ if (verbose) { ++ if ((atyp & ADDRTYPE_MASK) == 4) ++ LOGI("connect to [%s]:%d", host, ntohs(port)); ++ else ++ LOGI("connect to %s:%d", host, ntohs(port)); ++ } ++ ++ if (server->auth && !ss_check_hash(server->buf, server->chunk, server->d_ctx, BUF_SIZE)) { ++ LOGE("hash error"); ++ report_addr(server->fd, BAD); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ ++ ++ if (!need_query) { ++ remote_t *remote = connect_to_remote(EV_A_ &info, server); ++ ++ if (remote == NULL) { ++ LOGE("connect error"); ++ close_and_free_server(EV_A_ server); ++ return; ++ } else { ++ server->remote = remote; ++ remote->server = server; ++ ++ // XXX: should handle buffer carefully ++ if (server->buf->len > 0) { ++ memcpy(remote->buf->array, server->buf->array, server->buf->len); ++ remote->buf->len = server->buf->len; ++ remote->buf->idx = 0; ++ server->buf->len = 0; ++ server->buf->idx = 0; ++ } ++ ++ // waiting on remote connected event ++ ev_io_stop(EV_A_ & server_recv_ctx->io); ++ ev_io_start(EV_A_ & remote->send_ctx->io); ++ } ++ } else { ++ query_t *query = (query_t *)ss_malloc(sizeof(query_t)); ++ query->server = server; ++ snprintf(query->hostname, 256, "%s", host); ++ ++ server->stage = STAGE_RESOLVE; ++ server->query = resolv_query(host, server_resolve_cb, ++ query_free_cb, query, port); ++ ++ ev_io_stop(EV_A_ & server_recv_ctx->io); ++ } ++ ++ return; ++ } ++ // should not reach here ++ FATAL("server context error"); ++} ++ ++static void ++server_send_cb(EV_P_ ev_io *w, int revents) ++{ ++ server_ctx_t *server_send_ctx = (server_ctx_t *)w; ++ server_t *server = server_send_ctx->server; ++ remote_t *remote = server->remote; ++ ++ if (remote == NULL) { ++ LOGE("invalid server"); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ ++ if (server->buf->len == 0) { ++ // close and free ++ if (verbose) { ++ LOGI("server_send close the connection"); ++ } ++ close_and_free_remote(EV_A_ remote); ++ close_and_free_server(EV_A_ server); ++ return; ++ } else { ++ // has data to send ++ ssize_t s = send(server->fd, server->buf->array + server->buf->idx, ++ server->buf->len, 0); ++ if (s == -1) { ++ if (errno != EAGAIN && errno != EWOULDBLOCK) { ++ ERROR("server_send_send"); ++ close_and_free_remote(EV_A_ remote); ++ close_and_free_server(EV_A_ server); ++ } ++ return; ++ } else if (s < server->buf->len) { ++ // partly sent, move memory, wait for the next time to send ++ server->buf->len -= s; ++ server->buf->idx += s; ++ return; ++ } else { ++ // all sent out, wait for reading ++ server->buf->len = 0; ++ server->buf->idx = 0; ++ ev_io_stop(EV_A_ & server_send_ctx->io); ++ if (remote != NULL) { ++ ev_io_start(EV_A_ & remote->recv_ctx->io); ++ return; ++ } else { ++ LOGE("invalid remote"); ++ close_and_free_remote(EV_A_ remote); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ } ++ } ++} ++ ++static void ++block_list_clear_cb(EV_P_ ev_timer *watcher, int revents) ++{ ++ clear_block_list(); ++} ++ ++static void ++server_timeout_cb(EV_P_ ev_timer *watcher, int revents) ++{ ++ server_ctx_t *server_ctx ++ = cork_container_of(watcher, server_ctx_t, watcher); ++ server_t *server = server_ctx->server; ++ remote_t *remote = server->remote; ++ ++ if (verbose) { ++ LOGI("TCP connection timeout"); ++ } ++ ++ if (server->stage < STAGE_PARSE) { ++ if (verbose) { ++ size_t len = server->stage ? ++ server->header_buf->len : server->buf->len; ++#ifdef __MINGW32__ ++ LOGI("incomplete header: %u", len); ++#else ++ LOGI("incomplete header: %zu", len); ++#endif ++ } ++ report_addr(server->fd, SUSPICIOUS); ++ } ++ ++ close_and_free_remote(EV_A_ remote); ++ close_and_free_server(EV_A_ server); ++} ++ ++static void ++query_free_cb(void *data) ++{ ++ if (data != NULL) { ++ ss_free(data); ++ } ++} ++ ++static void ++server_resolve_cb(struct sockaddr *addr, void *data) ++{ ++ query_t *query = (query_t *)data; ++ server_t *server = query->server; ++ struct ev_loop *loop = server->listen_ctx->loop; ++ ++ server->query = NULL; ++ ++ if (addr == NULL) { ++ LOGE("unable to resolve %s", query->hostname); ++ close_and_free_server(EV_A_ server); ++ } else { ++ if (verbose) { ++ LOGI("successfully resolved %s", query->hostname); ++ } ++ ++ struct addrinfo info; ++ memset(&info, 0, sizeof(struct addrinfo)); ++ info.ai_socktype = SOCK_STREAM; ++ info.ai_protocol = IPPROTO_TCP; ++ info.ai_addr = addr; ++ ++ if (addr->sa_family == AF_INET) { ++ info.ai_family = AF_INET; ++ info.ai_addrlen = sizeof(struct sockaddr_in); ++ } else if (addr->sa_family == AF_INET6) { ++ info.ai_family = AF_INET6; ++ info.ai_addrlen = sizeof(struct sockaddr_in6); ++ } ++ ++ remote_t *remote = connect_to_remote(EV_A_ &info, server); ++ ++ if (remote == NULL) { ++ close_and_free_server(EV_A_ server); ++ } else { ++ server->remote = remote; ++ remote->server = server; ++ ++ // XXX: should handle buffer carefully ++ if (server->buf->len > 0) { ++ memcpy(remote->buf->array, server->buf->array + server->buf->idx, ++ server->buf->len); ++ remote->buf->len = server->buf->len; ++ remote->buf->idx = 0; ++ server->buf->len = 0; ++ server->buf->idx = 0; ++ } ++ ++ // listen to remote connected event ++ ev_io_start(EV_A_ & remote->send_ctx->io); ++ } ++ } ++} ++ ++static void ++remote_recv_cb(EV_P_ ev_io *w, int revents) ++{ ++ remote_ctx_t *remote_recv_ctx = (remote_ctx_t *)w; ++ remote_t *remote = remote_recv_ctx->remote; ++ server_t *server = remote->server; ++ ++ if (server == NULL) { ++ LOGE("invalid server"); ++ close_and_free_remote(EV_A_ remote); ++ return; ++ } ++ ++ ev_timer_again(EV_A_ & server->recv_ctx->watcher); ++ ++ ssize_t r = recv(remote->fd, server->buf->array, BUF_SIZE, 0); ++ ++ if (r == 0) { ++ // connection closed ++ if (verbose) { ++ LOGI("remote_recv close the connection"); ++ } ++ close_and_free_remote(EV_A_ remote); ++ close_and_free_server(EV_A_ server); ++ return; ++ } else if (r == -1) { ++ if (errno == EAGAIN || errno == EWOULDBLOCK) { ++ // no data ++ // continue to wait for recv ++ return; ++ } else { ++ ERROR("remote recv"); ++ close_and_free_remote(EV_A_ remote); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ } ++ ++ rx += r; ++ ++ server->buf->len = r; ++ ++ // SSR beg ++ server_info _server_info; ++ if (server->obfs_plugin) { ++ server->obfs_plugin->get_server_info(server->obfs, &_server_info); ++ _server_info.head_len = get_head_size(server->buf->array, server->buf->len, 30); ++ server->obfs_plugin->set_server_info(server->obfs, &_server_info); ++ } ++ ++ if (server->protocol_plugin && server->obfs_compatible_state == 0) { ++ obfs_class *protocol_plugin = server->protocol_plugin; ++ if (protocol_plugin->server_pre_encrypt) { ++ server->buf->len = protocol_plugin->server_pre_encrypt(server->protocol, &server->buf->array, server->buf->len, &server->buf->capacity); ++ } ++ } ++ ++ int err = ss_encrypt(server->buf, server->e_ctx, BUF_SIZE); ++ ++ if (err) { ++ LOGE("invalid password or cipher"); ++ close_and_free_remote(EV_A_ remote); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ ++ if (server->obfs_plugin && server->obfs_compatible_state == 0) { ++ obfs_class *obfs_plugin = server->obfs_plugin; ++ if (obfs_plugin->server_encode) { ++ server->buf->len = obfs_plugin->server_encode(server->obfs, &server->buf->array, server->buf->len, &server->buf->capacity); ++ } ++ } ++ // SSR end ++ ++ int s = send(server->fd, server->buf->array, server->buf->len, 0); ++ ++ if (s == -1) { ++ if (errno == EAGAIN || errno == EWOULDBLOCK) { ++ // no data, wait for send ++ server->buf->idx = 0; ++ ev_io_stop(EV_A_ & remote_recv_ctx->io); ++ ev_io_start(EV_A_ & server->send_ctx->io); ++ } else { ++ ERROR("remote_recv_send"); ++ close_and_free_remote(EV_A_ remote); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ } else if (s < server->buf->len) { ++ server->buf->len -= s; ++ server->buf->idx = s; ++ ev_io_stop(EV_A_ & remote_recv_ctx->io); ++ ev_io_start(EV_A_ & server->send_ctx->io); ++ } ++ ++ // Disable TCP_NODELAY after the first response are sent ++ if (!remote->recv_ctx->connected) { ++ int opt = 0; ++ setsockopt(server->fd, SOL_TCP, TCP_NODELAY, &opt, sizeof(opt)); ++ setsockopt(remote->fd, SOL_TCP, TCP_NODELAY, &opt, sizeof(opt)); ++ remote->recv_ctx->connected = 1; ++ } ++} ++ ++static void ++remote_send_cb(EV_P_ ev_io *w, int revents) ++{ ++ remote_ctx_t *remote_send_ctx = (remote_ctx_t *)w; ++ remote_t *remote = remote_send_ctx->remote; ++ server_t *server = remote->server; ++ ++ if (server == NULL) { ++ LOGE("invalid server"); ++ close_and_free_remote(EV_A_ remote); ++ return; ++ } ++ ++ if (!remote_send_ctx->connected) { ++ struct sockaddr_storage addr; ++ socklen_t len = sizeof(struct sockaddr_storage); ++ memset(&addr, 0, len); ++ int r = getpeername(remote->fd, (struct sockaddr *)&addr, &len); ++ if (r == 0) { ++ if (verbose) { ++ LOGI("remote connected"); ++ } ++ remote_send_ctx->connected = 1; ++ ++ // Clear the state of this address in the block list ++ reset_addr(server->fd); ++ ++ if (remote->buf->len == 0) { ++ server->stage = STAGE_STREAM; ++ ev_io_stop(EV_A_ & remote_send_ctx->io); ++ ev_io_start(EV_A_ & server->recv_ctx->io); ++ ev_io_start(EV_A_ & remote->recv_ctx->io); ++ return; ++ } ++ } else { ++ ERROR("getpeername"); ++ // not connected ++ close_and_free_remote(EV_A_ remote); ++ close_and_free_server(EV_A_ server); ++ return; ++ } ++ } ++ ++ if (remote->buf->len == 0) { ++ // close and free ++ if (verbose) { ++ LOGI("remote_send close the connection"); ++ } ++ close_and_free_remote(EV_A_ remote); ++ close_and_free_server(EV_A_ server); ++ return; ++ } else { ++ // has data to send ++ ssize_t s = send(remote->fd, remote->buf->array + remote->buf->idx, ++ remote->buf->len, 0); ++ if (s == -1) { ++ if (errno != EAGAIN && errno != EWOULDBLOCK) { ++ ERROR("remote_send_send"); ++ // close and free ++ close_and_free_remote(EV_A_ remote); ++ close_and_free_server(EV_A_ server); ++ } ++ return; ++ } else if (s < remote->buf->len) { ++ // partly sent, move memory, wait for the next time to send ++ remote->buf->len -= s; ++ remote->buf->idx += s; ++ return; ++ } else { ++ // all sent out, wait for reading ++ remote->buf->len = 0; ++ remote->buf->idx = 0; ++ ev_io_stop(EV_A_ & remote_send_ctx->io); ++ if (server != NULL) { ++ ev_io_start(EV_A_ & server->recv_ctx->io); ++ if (server->stage != STAGE_STREAM) { ++ server->stage = STAGE_STREAM; ++ ev_io_start(EV_A_ & remote->recv_ctx->io); ++ } ++ } else { ++ LOGE("invalid server"); ++ close_and_free_remote(EV_A_ remote); ++ close_and_free_server(EV_A_ server); ++ } ++ return; ++ } ++ } ++} ++ ++static remote_t * ++new_remote(int fd) ++{ ++ if (verbose) { ++ remote_conn++; ++ } ++ ++ remote_t *remote; ++ ++ remote = ss_malloc(sizeof(remote_t)); ++ remote->recv_ctx = ss_malloc(sizeof(remote_ctx_t)); ++ remote->send_ctx = ss_malloc(sizeof(remote_ctx_t)); ++ remote->buf = ss_malloc(sizeof(buffer_t)); ++ remote->fd = fd; ++ remote->recv_ctx->remote = remote; ++ remote->recv_ctx->connected = 0; ++ remote->send_ctx->remote = remote; ++ remote->send_ctx->connected = 0; ++ remote->server = NULL; ++ ++ ev_io_init(&remote->recv_ctx->io, remote_recv_cb, fd, EV_READ); ++ ev_io_init(&remote->send_ctx->io, remote_send_cb, fd, EV_WRITE); ++ ++ balloc(remote->buf, BUF_SIZE); ++ ++ return remote; ++} ++ ++static void ++free_remote(remote_t *remote) ++{ ++ if (remote->server != NULL) { ++ remote->server->remote = NULL; ++ } ++ if (remote->buf != NULL) { ++ bfree(remote->buf); ++ ss_free(remote->buf); ++ } ++ ss_free(remote->recv_ctx); ++ ss_free(remote->send_ctx); ++ ss_free(remote); ++} ++ ++static void ++close_and_free_remote(EV_P_ remote_t *remote) ++{ ++ if (remote != NULL) { ++ ev_io_stop(EV_A_ & remote->send_ctx->io); ++ ev_io_stop(EV_A_ & remote->recv_ctx->io); ++ close(remote->fd); ++ free_remote(remote); ++ if (verbose) { ++ remote_conn--; ++ LOGI("current remote connection: %d", remote_conn); ++ } ++ } ++} ++ ++static server_t * ++new_server(int fd, listen_ctx_t *listener) ++{ ++ if (verbose) { ++ server_conn++; ++ } ++ ++ server_t *server; ++ server = ss_malloc(sizeof(server_t)); ++ ++ memset(server, 0, sizeof(server_t)); ++ ++ server->recv_ctx = ss_malloc(sizeof(server_ctx_t)); ++ server->send_ctx = ss_malloc(sizeof(server_ctx_t)); ++ server->buf = ss_malloc(sizeof(buffer_t)); ++ server->header_buf = ss_malloc(sizeof(buffer_t)); ++ server->fd = fd; ++ server->recv_ctx->server = server; ++ server->recv_ctx->connected = 0; ++ server->send_ctx->server = server; ++ server->send_ctx->connected = 0; ++ server->stage = STAGE_INIT; ++ server->query = NULL; ++ server->listen_ctx = listener; ++ server->remote = NULL; ++ ++ if (listener->method) { ++ server->e_ctx = ss_malloc(sizeof(enc_ctx_t)); ++ server->d_ctx = ss_malloc(sizeof(enc_ctx_t)); ++ enc_ctx_init(listener->method, server->e_ctx, 1); ++ enc_ctx_init(listener->method, server->d_ctx, 0); ++ } else { ++ server->e_ctx = NULL; ++ server->d_ctx = NULL; ++ } ++ ++ int request_timeout = min(MAX_REQUEST_TIMEOUT, listener->timeout) ++ + rand() % MAX_REQUEST_TIMEOUT; ++ ++ ev_io_init(&server->recv_ctx->io, server_recv_cb, fd, EV_READ); ++ ev_io_init(&server->send_ctx->io, server_send_cb, fd, EV_WRITE); ++ ev_timer_init(&server->recv_ctx->watcher, server_timeout_cb, ++ request_timeout, listener->timeout); ++ ++ balloc(server->buf, BUF_SIZE); ++ balloc(server->header_buf, BUF_SIZE); ++ ++ server->chunk = (chunk_t *)malloc(sizeof(chunk_t)); ++ memset(server->chunk, 0, sizeof(chunk_t)); ++ server->chunk->buf = ss_malloc(sizeof(buffer_t)); ++ memset(server->chunk->buf, 0, sizeof(buffer_t)); ++ ++ cork_dllist_add(&connections, &server->entries); ++ ++ return server; ++} ++ ++static void ++free_server(server_t *server) ++{ ++ cork_dllist_remove(&server->entries); ++ ++ if (server->chunk != NULL) { ++ if (server->chunk->buf != NULL) { ++ bfree(server->chunk->buf); ++ ss_free(server->chunk->buf); ++ } ++ ss_free(server->chunk); ++ } ++ if (server->remote != NULL) { ++ server->remote->server = NULL; ++ } ++ if (server->e_ctx != NULL) { ++ cipher_context_release(&server->e_ctx->evp); ++ ss_free(server->e_ctx); ++ } ++ if (server->d_ctx != NULL) { ++ cipher_context_release(&server->d_ctx->evp); ++ ss_free(server->d_ctx); ++ } ++ if (server->buf != NULL) { ++ bfree(server->buf); ++ ss_free(server->buf); ++ } ++ if (server->header_buf != NULL) { ++ bfree(server->header_buf); ++ ss_free(server->header_buf); ++ } ++ ++ ss_free(server->recv_ctx); ++ ss_free(server->send_ctx); ++ ss_free(server); ++} ++ ++static void ++close_and_free_server(EV_P_ server_t *server) ++{ ++ if (server != NULL) { ++ if (server->query != NULL) { ++ resolv_cancel(server->query); ++ server->query = NULL; ++ } ++ ev_io_stop(EV_A_ & server->send_ctx->io); ++ ev_io_stop(EV_A_ & server->recv_ctx->io); ++ ev_timer_stop(EV_A_ & server->recv_ctx->watcher); ++ close(server->fd); ++ free_server(server); ++ if (verbose) { ++ server_conn--; ++ LOGI("current server connection: %d", server_conn); ++ } ++ } ++} ++ ++static void ++signal_cb(EV_P_ ev_signal *w, int revents) ++{ ++ if (revents & EV_SIGNAL) { ++ switch (w->signum) { ++ case SIGINT: ++ case SIGTERM: ++ ev_unloop(EV_A_ EVUNLOOP_ALL); ++ } ++ } ++} ++ ++static void ++accept_cb(EV_P_ ev_io *w, int revents) ++{ ++ listen_ctx_t *listener = (listen_ctx_t *)w; ++ int serverfd = accept(listener->fd, NULL, NULL); ++ if (serverfd == -1) { ++ ERROR("accept"); ++ return; ++ } ++ ++ char *peer_name = get_peer_name(serverfd); ++ if (peer_name != NULL) { ++ int in_white_list = 0; ++ if (acl) { ++ if ((get_acl_mode() == BLACK_LIST && acl_match_host(peer_name) == 1) ++ || (get_acl_mode() == WHITE_LIST && acl_match_host(peer_name) >= 0)) { ++ LOGE("Access denied from %s", peer_name); ++ close(serverfd); ++ return; ++ } else if (acl_match_host(peer_name) == -1) { ++ in_white_list = 1; ++ } ++ } ++ if (!in_white_list && check_block_list(peer_name)) { ++ LOGE("block all requests from %s", peer_name); ++#ifdef __linux__ ++ set_linger(serverfd); ++#endif ++ close(serverfd); ++ return; ++ } ++ } ++ ++ int opt = 1; ++ setsockopt(serverfd, SOL_TCP, TCP_NODELAY, &opt, sizeof(opt)); ++#ifdef SO_NOSIGPIPE ++ setsockopt(serverfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt)); ++#endif ++ setnonblocking(serverfd); ++ ++ if (verbose) { ++ LOGI("accept a connection"); ++ } ++ ++ server_t *server = new_server(serverfd, listener); ++ ++ // SSR beg ++ server->obfs_plugin = new_obfs_class(server->listen_ctx->obfs_name); ++ if (server->obfs_plugin) { ++ server->obfs = server->obfs_plugin->new_obfs(); ++ server->obfs_compatible_state = 0; ++ } ++ server->protocol_plugin = new_obfs_class(server->listen_ctx->protocol_name); ++ if (server->protocol_plugin) { ++ server->protocol = server->protocol_plugin->new_obfs(); ++ server->protocol_compatible_state = 0; ++ } ++ server_info _server_info; ++ memset(&_server_info, 0, sizeof(server_info)); ++ _server_info.param = server->listen_ctx->obfs_param; ++ if(server->obfs_plugin) ++ _server_info.g_data = server->obfs_plugin->init_data(); ++ _server_info.head_len = 7; ++ _server_info.iv = server->e_ctx->evp.iv; ++ _server_info.iv_len = enc_get_iv_len(); ++ _server_info.key = enc_get_key(); ++ _server_info.key_len = enc_get_key_len(); ++ _server_info.tcp_mss = 1460; ++ ++ if (server->obfs_plugin) ++ server->obfs_plugin->set_server_info(server->obfs, &_server_info); ++ ++ _server_info.param = server->listen_ctx->protocol_param; ++ if (server->protocol_plugin) ++ _server_info.g_data = server->protocol_plugin->init_data(); ++ ++ if (server->protocol_plugin) ++ server->protocol_plugin->set_server_info(server->protocol, &_server_info); ++ // SSR end ++ ++ ev_io_start(EV_A_ & server->recv_ctx->io); ++ ev_timer_start(EV_A_ & server->recv_ctx->watcher); ++} ++ ++int ++main(int argc, char **argv) ++{ ++ int i, c; ++ int pid_flags = 0; ++ int mptcp = 0; ++ int firewall = 0; ++ int mtu = 0; ++ char *user = NULL; ++ char *password = NULL; ++ char *timeout = NULL; ++ char *protocol = NULL; // SSR ++ char *protocol_param = NULL; // SSR ++ char *method = NULL; ++ char *obfs = NULL; // SSR ++ char *obfs_param = NULL; // SSR ++ char *pid_path = NULL; ++ char *conf_path = NULL; ++ char *iface = NULL; ++ ++ int server_num = 0; ++ const char *server_host[MAX_REMOTE_NUM]; ++ ++ char *nameservers[MAX_DNS_NUM + 1]; ++ int nameserver_num = 0; ++ ++ int option_index = 0; ++ static struct option long_options[] = { ++ { "fast-open", no_argument, 0, 0 }, ++ { "acl", required_argument, 0, 0 }, ++ { "manager-address", required_argument, 0, 0 }, ++ { "mtu", required_argument, 0, 0 }, ++ { "help", no_argument, 0, 0 }, ++#ifdef __linux__ ++ { "mptcp", no_argument, 0, 0 }, ++ { "firewall", no_argument, 0, 0 }, ++#endif ++ { 0, 0, 0, 0 } ++ }; ++ ++ opterr = 0; ++ ++ USE_TTY(); ++ ++ while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:b:c:i:d:a:n:O:o:G:g:huUvA6", ++ long_options, &option_index)) != -1) { ++ switch (c) { ++ case 0: ++ if (option_index == 0) { ++ fast_open = 1; ++ } else if (option_index == 1) { ++ LOGI("initializing acl..."); ++ acl = !init_acl(optarg); ++ } else if (option_index == 2) { ++ manager_address = optarg; ++ } else if (option_index == 3) { ++ mtu = atoi(optarg); ++ LOGI("set MTU to %d", mtu); ++ } else if (option_index == 4) { ++ usage(); ++ exit(EXIT_SUCCESS); ++ } else if (option_index == 5) { ++ mptcp = 1; ++ LOGI("enable multipath TCP"); ++ } else if (option_index == 6) { ++ firewall = 1; ++ LOGI("enable firewall rules"); ++ } ++ break; ++ case 's': ++ if (server_num < MAX_REMOTE_NUM) { ++ server_host[server_num++] = optarg; ++ } ++ break; ++ case 'b': ++ bind_address = optarg; ++ break; ++ case 'p': ++ server_port = optarg; ++ break; ++ case 'k': ++ password = optarg; ++ break; ++ case 'f': ++ pid_flags = 1; ++ pid_path = optarg; ++ break; ++ case 't': ++ timeout = optarg; ++ break; ++ // SSR beg ++ case 'O': ++ protocol = optarg; ++ break; ++ case 'm': ++ method = optarg; ++ break; ++ case 'o': ++ obfs = optarg; ++ break; ++ case 'G': ++ protocol_param = optarg; ++ break; ++ case 'g': ++ obfs_param = optarg; ++ break; ++ // SSR end ++ case 'c': ++ conf_path = optarg; ++ break; ++ case 'i': ++ iface = optarg; ++ break; ++ case 'd': ++ if (nameserver_num < MAX_DNS_NUM) { ++ nameservers[nameserver_num++] = optarg; ++ } ++ break; ++ case 'a': ++ user = optarg; ++ break; ++#ifdef HAVE_SETRLIMIT ++ case 'n': ++ nofile = atoi(optarg); ++ break; ++#endif ++ case 'u': ++ mode = TCP_AND_UDP; ++ break; ++ case 'U': ++ mode = UDP_ONLY; ++ break; ++ case 'v': ++ verbose = 1; ++ break; ++ case 'h': ++ usage(); ++ exit(EXIT_SUCCESS); ++ case 'A': ++ auth = 1; ++ break; ++ case '6': ++ ipv6first = 1; ++ break; ++ case '?': ++ // The option character is not recognized. ++ LOGE("Unrecognized option: %s", optarg); ++ opterr = 1; ++ break; ++ } ++ } ++ ++ if (opterr) { ++ usage(); ++ exit(EXIT_FAILURE); ++ } ++ ++ if (argc == 1) { ++ if (conf_path == NULL) { ++ conf_path = DEFAULT_CONF_PATH; ++ } ++ } ++ ++ if (conf_path != NULL) { ++ jconf_t *conf = read_jconf(conf_path); ++ if (server_num == 0) { ++ server_num = conf->remote_num; ++ for (i = 0; i < server_num; i++) ++ server_host[i] = conf->remote_addr[i].host; ++ } ++ if (server_port == NULL) { ++ server_port = conf->remote_port; ++ } ++ if (password == NULL) { ++ password = conf->password; ++ } ++ // SSR beg ++ if (protocol == NULL) { ++ protocol = conf->protocol; ++ LOGI("protocol %s", protocol); ++ } ++ if (protocol_param == NULL) { ++ protocol_param = conf->protocol_param; ++ LOGI("protocol_param %s", obfs_param); ++ } ++ if (method == NULL) { ++ method = conf->method; ++ LOGI("method %s", method); ++ } ++ if (obfs == NULL) { ++ obfs = conf->obfs; ++ LOGI("obfs %s", obfs); ++ } ++ if (obfs_param == NULL) { ++ obfs_param = conf->obfs_param; ++ LOGI("obfs_param %s", obfs_param); ++ } ++ // SSR end ++ if (timeout == NULL) { ++ timeout = conf->timeout; ++ } ++ if (user == NULL) { ++ user = conf->user; ++ } ++ if (auth == 0) { ++ auth = conf->auth; ++ } ++ if (mode == TCP_ONLY) { ++ mode = conf->mode; ++ } ++ if (mtu == 0) { ++ mtu = conf->mtu; ++ } ++ if (mptcp == 0) { ++ mptcp = conf->mptcp; ++ } ++#ifdef TCP_FASTOPEN ++ if (fast_open == 0) { ++ fast_open = conf->fast_open; ++ } ++#endif ++#ifdef HAVE_SETRLIMIT ++ if (nofile == 0) { ++ nofile = conf->nofile; ++ } ++#endif ++ if (conf->nameserver != NULL) { ++ nameservers[nameserver_num++] = conf->nameserver; ++ } ++ if (ipv6first == 0) { ++ ipv6first = conf->ipv6_first; ++ } ++ } ++ ++ //_compatible ++ if(strlen(protocol)>11) ++ { ++ char *text; ++ text = (char*)malloc(12); ++ memcpy(text, protocol + strlen(protocol) - 11, 12); ++ ++ if(strcmp(text, "_compatible") == 0) ++ { ++ free(text); ++ text = (char*)malloc(strlen(protocol) - 11); ++ memcpy(text, protocol, strlen(protocol) - 11); ++ int length = strlen(protocol) - 11; ++ free(protocol); ++ obfs = (char*)malloc(length); ++ memset(protocol, 0x00, length); ++ memcpy(protocol, text, length); ++ LOGI("protocol compatible enable, %s", protocol); ++ free(text); ++ protocol_compatible = 1; ++ } ++ } ++ ++ if(strlen(obfs)>11) ++ { ++ char *text; ++ text = (char*)malloc(12); ++ memcpy(text, obfs + strlen(obfs) - 11, 12); ++ ++ if(strcmp(text, "_compatible") == 0) ++ { ++ free(text); ++ text = (char*)malloc(strlen(obfs) - 11); ++ memcpy(text, obfs, strlen(obfs) - 11); ++ int length = strlen(obfs) - 11; ++ free(obfs); ++ obfs = (char*)malloc(length); ++ memset(obfs, 0x00, length); ++ memcpy(obfs, text, length); ++ LOGI("obfs compatible enable, %s", obfs); ++ free(text); ++ obfs_compatible = 1; ++ } ++ } ++ ++ ++ if (server_num == 0) { ++ server_host[server_num++] = NULL; ++ } ++ ++ if (server_num == 0 || server_port == NULL || password == NULL) { ++ usage(); ++ exit(EXIT_FAILURE); ++ } ++ ++ if (protocol && strcmp(protocol, "verify_sha1") == 0) { ++ auth = 1; ++ protocol = NULL; ++ } ++ ++ if (method == NULL) { ++ method = "rc4-md5"; ++ } ++ ++ if (timeout == NULL) { ++ timeout = "60"; ++ } ++ ++#ifdef HAVE_SETRLIMIT ++ /* ++ * no need to check the return value here since we will show ++ * the user an error message if setrlimit(2) fails ++ */ ++ if (nofile > 1024) { ++ if (verbose) { ++ LOGI("setting NOFILE to %d", nofile); ++ } ++ set_nofile(nofile); ++ } ++#endif ++ ++ if (pid_flags) { ++ USE_SYSLOG(argv[0]); ++ daemonize(pid_path); ++ } ++ ++ if (ipv6first) { ++ LOGI("resolving hostname to IPv6 address first"); ++ } ++ ++ if (fast_open == 1) { ++#ifdef TCP_FASTOPEN ++ LOGI("using tcp fast open"); ++#else ++ LOGE("tcp fast open is not supported by this environment"); ++ fast_open = 0; ++#endif ++ } ++ ++ if (auth) { ++ LOGI("onetime authentication enabled"); ++ } ++ ++ if (mode != TCP_ONLY) { ++ LOGI("UDP relay enabled"); ++ } ++ ++ if (mode == UDP_ONLY) { ++ LOGI("TCP relay disabled"); ++ } ++ ++#ifdef __MINGW32__ ++ winsock_init(); ++#else ++ // ignore SIGPIPE ++ signal(SIGPIPE, SIG_IGN); ++ signal(SIGCHLD, SIG_IGN); ++ signal(SIGABRT, SIG_IGN); ++#endif ++ ++ struct ev_signal sigint_watcher; ++ struct ev_signal sigterm_watcher; ++ ev_signal_init(&sigint_watcher, signal_cb, SIGINT); ++ ev_signal_init(&sigterm_watcher, signal_cb, SIGTERM); ++ ev_signal_start(EV_DEFAULT, &sigint_watcher); ++ ev_signal_start(EV_DEFAULT, &sigterm_watcher); ++ ++ // setup keys ++ LOGI("initializing ciphers... %s", method); ++ int m = enc_init(password, method); ++ ++ // initialize ev loop ++ struct ev_loop *loop = EV_DEFAULT; ++ ++ // setup udns ++ if (nameserver_num == 0) { ++#ifdef __MINGW32__ ++ nameservers[nameserver_num++] = "8.8.8.8"; ++ resolv_init(loop, nameservers, nameserver_num, ipv6first); ++#else ++ resolv_init(loop, NULL, 0, ipv6first); ++#endif ++ } else { ++ resolv_init(loop, nameservers, nameserver_num, ipv6first); ++ } ++ ++ for (int i = 0; i < nameserver_num; i++) ++ LOGI("using nameserver: %s", nameservers[i]); ++ ++ // initialize listen context ++ listen_ctx_t listen_ctx_list[server_num]; ++ ++ // bind to each interface ++ while (server_num > 0) { ++ int index = --server_num; ++ const char *host = server_host[index]; ++ ++ if (mode != UDP_ONLY) { ++ // Bind to port ++ int listenfd; ++ listenfd = create_and_bind(host, server_port, mptcp); ++ if (listenfd == -1) { ++ FATAL("bind() error"); ++ } ++ if (listen(listenfd, SSMAXCONN) == -1) { ++ FATAL("listen() error"); ++ } ++ setfastopen(listenfd); ++ setnonblocking(listenfd); ++ listen_ctx_t *listen_ctx = &listen_ctx_list[index]; ++ ++ // Setup proxy context ++ listen_ctx->timeout = atoi(timeout); ++ listen_ctx->fd = listenfd; ++ listen_ctx->method = m; ++ listen_ctx->iface = iface; ++ ++ // SSR beg ++ listen_ctx->protocol_name = protocol; ++ listen_ctx->protocol_param = protocol_param; ++ listen_ctx->method = m; ++ listen_ctx->obfs_name = obfs; ++ listen_ctx->obfs_param = obfs_param; ++ listen_ctx->list_protocol_global = malloc(sizeof(void *)); ++ listen_ctx->list_obfs_global = malloc(sizeof(void *)); ++ memset(listen_ctx->list_protocol_global, 0, sizeof(void *)); ++ memset(listen_ctx->list_obfs_global, 0, sizeof(void *)); ++ // SSR end ++ ++ listen_ctx->loop = loop; ++ ++ ev_io_init(&listen_ctx->io, accept_cb, listenfd, EV_READ); ++ ev_io_start(loop, &listen_ctx->io); ++ } ++ ++ // Setup UDP ++ if (mode != TCP_ONLY) { ++ init_udprelay(server_host[index], server_port, mtu, m, ++ auth, atoi(timeout), iface, protocol, protocol_param); ++ } ++ ++ if (host && strcmp(host, ":") > 0) ++ LOGI("listening at [%s]:%s", host, server_port); ++ else ++ LOGI("listening at %s:%s", host ? host : "*", server_port); ++ } ++ ++ if (manager_address != NULL) { ++ ev_timer_init(&stat_update_watcher, stat_update_cb, UPDATE_INTERVAL, UPDATE_INTERVAL); ++ ev_timer_start(EV_DEFAULT, &stat_update_watcher); ++ } ++ ++ ev_timer_init(&block_list_watcher, block_list_clear_cb, UPDATE_INTERVAL, UPDATE_INTERVAL); ++ ev_timer_start(EV_DEFAULT, &block_list_watcher); ++ ++ // setuid ++ if (user != NULL && ! run_as(user)) { ++ FATAL("failed to switch user"); ++ } ++ ++#ifndef __MINGW32__ ++ if (geteuid() == 0){ ++ LOGI("running from root user"); ++ } else if (firewall) { ++ LOGE("firewall setup requires running from root user"); ++ exit(-1); ++ } ++#endif ++ ++ // init block list ++ init_block_list(firewall); ++ ++ // Init connections ++ cork_dllist_init(&connections); ++ ++ // start ev loop ++ ev_run(loop, 0); ++ ++ if (verbose) { ++ LOGI("closed gracefully"); ++ } ++ ++ // Free block list ++ free_block_list(); ++ ++ if (manager_address != NULL) { ++ ev_timer_stop(EV_DEFAULT, &stat_update_watcher); ++ } ++ ev_timer_stop(EV_DEFAULT, &block_list_watcher); ++ ++ // Clean up ++ for (int i = 0; i <= server_num; i++) { ++ listen_ctx_t *listen_ctx = &listen_ctx_list[i]; ++ if (mode != UDP_ONLY) { ++ ev_io_stop(loop, &listen_ctx->io); ++ close(listen_ctx->fd); ++ } ++ } ++ ++ if (mode != UDP_ONLY) { ++ free_connections(loop); ++ } ++ ++ if (mode != TCP_ONLY) { ++ free_udprelay(); ++ } ++ ++ resolv_shutdown(loop); ++ ++#ifdef __MINGW32__ ++ winsock_cleanup(); ++#endif ++ ++ ev_signal_stop(EV_DEFAULT, &sigint_watcher); ++ ev_signal_stop(EV_DEFAULT, &sigterm_watcher); ++ ++ return 0; ++} +diff --git a/server/server.h b/server/server.h +new file mode 100644 +index 0000000..4cd3cf6 +--- /dev/null ++++ b/server/server.h +@@ -0,0 +1,115 @@ ++/* ++ * server.h - Define shadowsocks server's buffers and callbacks ++ * ++ * Copyright (C) 2013 - 2016, Max Lv ++ * ++ * This file is part of the shadowsocks-libev. ++ * ++ * shadowsocks-libev 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 3 of the License, or ++ * (at your option) any later version. ++ * ++ * shadowsocks-libev 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 shadowsocks-libev; see the file COPYING. If not, see ++ * . ++ */ ++ ++#ifndef _SERVER_H ++#define _SERVER_H ++ ++#include ++#include ++#include ++ ++#include "encrypt.h" ++#include "jconf.h" ++#include "resolv.h" ++#include "obfs.h" ++#include "protocol.h" ++ ++#include "common.h" ++ ++typedef struct listen_ctx { ++ ev_io io; ++ int fd; ++ int timeout; ++ int method; ++ char *iface; ++ struct ev_loop *loop; ++ ++ // SSR ++ char *protocol_name; ++ char *protocol_param; ++ char *obfs_name; ++ char *obfs_param; ++ void **list_protocol_global; ++ void **list_obfs_global; ++} listen_ctx_t; ++ ++typedef struct server_ctx { ++ ev_io io; ++ ev_timer watcher; ++ int connected; ++ struct server *server; ++} server_ctx_t; ++ ++typedef struct server { ++ int fd; ++ int stage; ++ buffer_t *buf; ++ ssize_t buf_capacity; ++ buffer_t *header_buf; ++ ++ int auth; ++ struct chunk *chunk; ++ ++ struct enc_ctx *e_ctx; ++ struct enc_ctx *d_ctx; ++ struct server_ctx *recv_ctx; ++ struct server_ctx *send_ctx; ++ struct listen_ctx *listen_ctx; ++ struct remote *remote; ++ ++ struct ResolvQuery *query; ++ ++ struct cork_dllist_item entries; ++ ++ // SSR ++ obfs *protocol; ++ obfs *obfs; ++ obfs_class *protocol_plugin; ++ obfs_class *obfs_plugin; ++ int obfs_compatible_state; ++ int protocol_compatible_state; ++} server_t; ++ ++typedef struct query { ++ server_t *server; ++ char hostname[257]; ++} query_t; ++ ++typedef struct remote_ctx { ++ ev_io io; ++ int connected; ++ struct remote *remote; ++} remote_ctx_t; ++ ++typedef struct remote { ++ int fd; ++ buffer_t *buf; ++ ssize_t buf_capacity; ++ struct remote_ctx *recv_ctx; ++ struct remote_ctx *send_ctx; ++ struct server *server; ++ ++ // SSR ++ int remote_index; ++} remote_t; ++ ++#endif // _SERVER_H +diff --git a/server/tls.c b/server/tls.c +new file mode 100644 +index 0000000..5c42216 +--- /dev/null ++++ b/server/tls.c +@@ -0,0 +1,263 @@ ++/* ++ * Copyright (c) 2011 and 2012, Dustin Lundquist ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ */ ++/* ++ * This is a minimal TLS implementation intended only to parse the server name ++ * extension. This was created based primarily on Wireshark dissection of a ++ * TLS handshake and RFC4366. ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include /* malloc() */ ++#include /* strncpy() */ ++ ++#ifndef __MINGW32__ ++#include ++#else ++#include ++#endif ++ ++#include "tls.h" ++#include "protocol.h" ++#include "utils.h" ++ ++#define SERVER_NAME_LEN 256 ++#define TLS_HEADER_LEN 5 ++#define TLS_HANDSHAKE_CONTENT_TYPE 0x16 ++#define TLS_HANDSHAKE_TYPE_CLIENT_HELLO 0x01 ++ ++#ifndef MIN ++#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) ++#endif ++ ++extern int verbose; ++ ++static int parse_tls_header(const char *, size_t, char **); ++static int parse_extensions(const char *, size_t, char **); ++static int parse_server_name_extension(const char *, size_t, char **); ++ ++static const protocol_t tls_protocol_st = { ++ .default_port = 443, ++ .parse_packet = &parse_tls_header, ++}; ++const protocol_t *const tls_protocol = &tls_protocol_st; ++ ++/* Parse a TLS packet for the Server Name Indication extension in the client ++ * hello handshake, returning the first servername found (pointer to static ++ * array) ++ * ++ * Returns: ++ * >=0 - length of the hostname and updates *hostname ++ * caller is responsible for freeing *hostname ++ * -1 - Incomplete request ++ * -2 - No Host header included in this request ++ * -3 - Invalid hostname pointer ++ * -4 - malloc failure ++ * < -4 - Invalid TLS client hello ++ */ ++static int ++parse_tls_header(const char *data, size_t data_len, char **hostname) ++{ ++ char tls_content_type; ++ char tls_version_major; ++ char tls_version_minor; ++ size_t pos = TLS_HEADER_LEN; ++ size_t len; ++ ++ if (hostname == NULL) ++ return -3; ++ ++ /* Check that our TCP payload is at least large enough for a TLS header */ ++ if (data_len < TLS_HEADER_LEN) ++ return -1; ++ ++ /* SSL 2.0 compatible Client Hello ++ * ++ * High bit of first byte (length) and content type is Client Hello ++ * ++ * See RFC5246 Appendix E.2 ++ */ ++ if (data[0] & 0x80 && data[2] == 1) { ++ if (verbose) ++ LOGI("Received SSL 2.0 Client Hello which can not support SNI."); ++ return -2; ++ } ++ ++ tls_content_type = data[0]; ++ if (tls_content_type != TLS_HANDSHAKE_CONTENT_TYPE) { ++ if (verbose) ++ LOGI("Request did not begin with TLS handshake."); ++ return -5; ++ } ++ ++ tls_version_major = data[1]; ++ tls_version_minor = data[2]; ++ if (tls_version_major < 3) { ++ if (verbose) ++ LOGI("Received SSL %d.%d handshake which can not support SNI.", ++ tls_version_major, tls_version_minor); ++ ++ return -2; ++ } ++ ++ /* TLS record length */ ++ len = ((unsigned char)data[3] << 8) + ++ (unsigned char)data[4] + TLS_HEADER_LEN; ++ data_len = MIN(data_len, len); ++ ++ /* Check we received entire TLS record length */ ++ if (data_len < len) ++ return -1; ++ ++ /* ++ * Handshake ++ */ ++ if (pos + 1 > data_len) { ++ return -5; ++ } ++ if (data[pos] != TLS_HANDSHAKE_TYPE_CLIENT_HELLO) { ++ if (verbose) ++ LOGI("Not a client hello"); ++ ++ return -5; ++ } ++ ++ /* Skip past fixed length records: ++ * 1 Handshake Type ++ * 3 Length ++ * 2 Version (again) ++ * 32 Random ++ * to Session ID Length ++ */ ++ pos += 38; ++ ++ /* Session ID */ ++ if (pos + 1 > data_len) ++ return -5; ++ len = (unsigned char)data[pos]; ++ pos += 1 + len; ++ ++ /* Cipher Suites */ ++ if (pos + 2 > data_len) ++ return -5; ++ len = ((unsigned char)data[pos] << 8) + (unsigned char)data[pos + 1]; ++ pos += 2 + len; ++ ++ /* Compression Methods */ ++ if (pos + 1 > data_len) ++ return -5; ++ len = (unsigned char)data[pos]; ++ pos += 1 + len; ++ ++ if (pos == data_len && tls_version_major == 3 && tls_version_minor == 0) { ++ if (verbose) ++ LOGI("Received SSL 3.0 handshake without extensions"); ++ return -2; ++ } ++ ++ /* Extensions */ ++ if (pos + 2 > data_len) ++ return -5; ++ len = ((unsigned char)data[pos] << 8) + (unsigned char)data[pos + 1]; ++ pos += 2; ++ ++ if (pos + len > data_len) ++ return -5; ++ return parse_extensions(data + pos, len, hostname); ++} ++ ++static int ++parse_extensions(const char *data, size_t data_len, char **hostname) ++{ ++ size_t pos = 0; ++ size_t len; ++ ++ /* Parse each 4 bytes for the extension header */ ++ while (pos + 4 <= data_len) { ++ /* Extension Length */ ++ len = ((unsigned char)data[pos + 2] << 8) + ++ (unsigned char)data[pos + 3]; ++ ++ /* Check if it's a server name extension */ ++ if (data[pos] == 0x00 && data[pos + 1] == 0x00) { ++ /* There can be only one extension of each type, so we break ++ * our state and move p to beinnging of the extension here */ ++ if (pos + 4 + len > data_len) ++ return -5; ++ return parse_server_name_extension(data + pos + 4, len, hostname); ++ } ++ pos += 4 + len; /* Advance to the next extension header */ ++ } ++ /* Check we ended where we expected to */ ++ if (pos != data_len) ++ return -5; ++ ++ return -2; ++} ++ ++static int ++parse_server_name_extension(const char *data, size_t data_len, ++ char **hostname) ++{ ++ size_t pos = 2; /* skip server name list length */ ++ size_t len; ++ ++ while (pos + 3 < data_len) { ++ len = ((unsigned char)data[pos + 1] << 8) + ++ (unsigned char)data[pos + 2]; ++ ++ if (pos + 3 + len > data_len) ++ return -5; ++ ++ switch (data[pos]) { /* name type */ ++ case 0x00: /* host_name */ ++ *hostname = malloc(len + 1); ++ if (*hostname == NULL) { ++ ERROR("malloc() failure"); ++ return -4; ++ } ++ ++ strncpy(*hostname, data + pos + 3, len); ++ ++ (*hostname)[len] = '\0'; ++ ++ return len; ++ default: ++ if (verbose) ++ LOGI("Unknown server name extension name type: %d", ++ data[pos]); ++ } ++ pos += 3 + len; ++ } ++ /* Check we ended where we expected to */ ++ if (pos != data_len) ++ return -5; ++ ++ return -2; ++} +diff --git a/server/tls.h b/server/tls.h +new file mode 100644 +index 0000000..3998913 +--- /dev/null ++++ b/server/tls.h +@@ -0,0 +1,33 @@ ++/* ++ * Copyright (c) 2011 and 2012, Dustin Lundquist ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ */ ++#ifndef TLS_H ++#define TLS_H ++ ++#include "protocol.h" ++ ++const protocol_t *const tls_protocol; ++ ++#endif +diff --git a/server/tls1.2_ticket.c b/server/tls1.2_ticket.c +new file mode 100644 +index 0000000..88970c0 +--- /dev/null ++++ b/server/tls1.2_ticket.c +@@ -0,0 +1,609 @@ ++ ++#include "tls1.2_ticket.h" ++#include "list.c" ++ ++typedef struct tls12_ticket_auth_global_data { ++ uint8_t local_client_id[32]; ++ List client_data; ++ time_t startup_time; ++}tls12_ticket_auth_global_data; ++ ++typedef struct tls12_ticket_auth_local_data { ++ int handshake_status; ++ char *send_buffer; ++ int send_buffer_size; ++ char *recv_buffer; ++ int recv_buffer_size; ++}tls12_ticket_auth_local_data; ++ ++void tls12_ticket_auth_local_data_init(tls12_ticket_auth_local_data* local) { ++ local->handshake_status = 0; ++ local->send_buffer = malloc(0); ++ local->send_buffer_size = 0; ++ local->recv_buffer = malloc(0); ++ local->recv_buffer_size = 0; ++} ++ ++void * tls12_ticket_auth_init_data() { ++ tls12_ticket_auth_global_data *global = (tls12_ticket_auth_global_data*)malloc(sizeof(tls12_ticket_auth_global_data)); ++ rand_bytes(global->local_client_id, 32); ++ global->client_data = list_init(22); ++ global->startup_time = time(NULL); ++ return global; ++} ++ ++obfs * tls12_ticket_auth_new_obfs() { ++ obfs * self = new_obfs(); ++ self->l_data = malloc(sizeof(tls12_ticket_auth_local_data)); ++ tls12_ticket_auth_local_data_init((tls12_ticket_auth_local_data*)self->l_data); ++ return self; ++} ++ ++void tls12_ticket_auth_dispose(obfs *self) { ++ tls12_ticket_auth_local_data *local = (tls12_ticket_auth_local_data*)self->l_data; ++ if (local->send_buffer != NULL) { ++ free(local->send_buffer); ++ local->send_buffer = NULL; ++ } ++ if (local->recv_buffer != NULL) { ++ free(local->recv_buffer); ++ local->recv_buffer = NULL; ++ } ++ free(local); ++ dispose_obfs(self); ++} ++ ++int tls12_ticket_pack_auth_data(tls12_ticket_auth_global_data *global, server_info *server, char *outdata) { ++ int out_size = 32; ++ time_t t = time(NULL); ++ outdata[0] = t >> 24; ++ outdata[1] = t >> 16; ++ outdata[2] = t >> 8; ++ outdata[3] = t; ++ rand_bytes((uint8_t*)outdata + 4, 18); ++ ++ uint8_t *key = (uint8_t*)malloc(server->key_len + 32); ++ char hash[ONETIMEAUTH_BYTES * 2]; ++ memcpy(key, server->key, server->key_len); ++ memcpy(key + server->key_len, global->local_client_id, 32); ++ ss_sha1_hmac_with_key(hash, outdata, out_size - OBFS_HMAC_SHA1_LEN, key, server->key_len + 32); ++ free(key); ++ memcpy(outdata + out_size - OBFS_HMAC_SHA1_LEN, hash, OBFS_HMAC_SHA1_LEN); ++ return out_size; ++} ++ ++void tls12_ticket_auth_pack_data(char *encryptdata, int datalength, int start, int len, char *out_buffer, int outlength) { ++ out_buffer[outlength] = 0x17; ++ out_buffer[outlength + 1] = 0x3; ++ out_buffer[outlength + 2] = 0x3; ++ out_buffer[outlength + 3] = len >> 8; ++ out_buffer[outlength + 4] = len; ++ memcpy(out_buffer + outlength + 5, encryptdata + start, len); ++} ++ ++int tls12_ticket_auth_client_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity) { ++ char *encryptdata = *pencryptdata; ++ tls12_ticket_auth_local_data *local = (tls12_ticket_auth_local_data*)self->l_data; ++ tls12_ticket_auth_global_data *global = (tls12_ticket_auth_global_data*)self->server.g_data; ++ char * out_buffer = NULL; ++ ++ if (local->handshake_status == 8) { ++ if (datalength < 1024) { ++ if (*capacity < datalength + 5) { ++ *pencryptdata = (char*)realloc(*pencryptdata, *capacity = (datalength + 5) * 2); ++ encryptdata = *pencryptdata; ++ } ++ memmove(encryptdata + 5, encryptdata, datalength); ++ encryptdata[0] = 0x17; ++ encryptdata[1] = 0x3; ++ encryptdata[2] = 0x3; ++ encryptdata[3] = datalength >> 8; ++ encryptdata[4] = datalength; ++ return datalength + 5; ++ } else { ++ out_buffer = (char*)malloc(datalength + 2048); ++ int start = 0; ++ int outlength = 0; ++ int len; ++ while (datalength - start > 2048) { ++ len = xorshift128plus() % 4096 + 100; ++ if (len > datalength - start) ++ len = datalength - start; ++ tls12_ticket_auth_pack_data(encryptdata, datalength, start, len, out_buffer, outlength); ++ outlength += len + 5; ++ start += len; ++ } ++ if (datalength - start > 0) { ++ len = datalength - start; ++ tls12_ticket_auth_pack_data(encryptdata, datalength, start, len, out_buffer, outlength); ++ outlength += len + 5; ++ } ++ if (*capacity < outlength) { ++ *pencryptdata = (char*)realloc(*pencryptdata, *capacity = outlength * 2); ++ encryptdata = *pencryptdata; ++ } ++ memcpy(encryptdata, out_buffer, outlength); ++ free(out_buffer); ++ return outlength; ++ } ++ } ++ local->send_buffer = (char*)realloc(local->send_buffer, local->send_buffer_size + datalength + 5); ++ memcpy(local->send_buffer + local->send_buffer_size + 5, encryptdata, datalength); ++ local->send_buffer[local->send_buffer_size] = 0x17; ++ local->send_buffer[local->send_buffer_size + 1] = 0x3; ++ local->send_buffer[local->send_buffer_size + 2] = 0x3; ++ local->send_buffer[local->send_buffer_size + 3] = datalength >> 8; ++ local->send_buffer[local->send_buffer_size + 4] = datalength; ++ local->send_buffer_size += datalength + 5; ++ ++ if (local->handshake_status == 0) { ++#define CSTR_DECL(name, len, str) const char* name = str; const int len = sizeof(str) - 1; ++ CSTR_DECL(tls_data0, tls_data0_len, "\x00\x1c\xc0\x2b\xc0\x2f\xcc\xa9\xcc\xa8\xcc\x14\xcc\x13\xc0\x0a\xc0\x14\xc0\x09\xc0\x13\x00\x9c\x00\x35\x00\x2f\x00\x0a\x01\x00" ++ ); ++ CSTR_DECL(tls_data1, tls_data1_len, "\xff\x01\x00\x01\x00" ++ ); ++ CSTR_DECL(tls_data2, tls_data2_len, "\x00\x17\x00\x00\x00\x23\x00\xd0"); ++ CSTR_DECL(tls_data3, tls_data3_len, "\x00\x0d\x00\x16\x00\x14\x06\x01\x06\x03\x05\x01\x05\x03\x04\x01\x04\x03\x03\x01\x03\x03\x02\x01\x02\x03\x00\x05\x00\x05\x01\x00\x00\x00\x00\x00\x12\x00\x00\x75\x50\x00\x00\x00\x0b\x00\x02\x01\x00\x00\x0a\x00\x06\x00\x04\x00\x17\x00\x18" ++ //"00150066000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" // padding ++ ); ++ uint8_t tls_data[2048]; ++ int tls_data_len = 0; ++ memcpy(tls_data, tls_data1, tls_data1_len); ++ tls_data_len += tls_data1_len; ++ ++ char hosts[1024]; ++ char * phost[128]; ++ int host_num = 0; ++ int pos; ++ ++ char sni[256] = {0}; ++ if (self->server.param && strlen(self->server.param) == 0) ++ self->server.param = NULL; ++ strncpy(hosts, self->server.param ? self->server.param : self->server.host, sizeof hosts); ++ phost[host_num++] = hosts; ++ for (pos = 0; hosts[pos]; ++pos) { ++ if (hosts[pos] == ',') { ++ phost[host_num++] = &hosts[pos + 1]; ++ } ++ } ++ host_num = xorshift128plus() % host_num; ++ ++ sprintf(sni, "%s", phost[host_num]); ++ int sni_len = strlen(sni); ++ if (sni_len > 0 && sni[sni_len - 1] >= '0' && sni[sni_len - 1] <= '9') ++ sni_len = 0; ++ tls_data[tls_data_len] = '\0'; ++ tls_data[tls_data_len + 1] = '\0'; ++ tls_data[tls_data_len + 2] = (sni_len + 5) >> 8; ++ tls_data[tls_data_len + 3] = (sni_len + 5); ++ tls_data[tls_data_len + 4] = (sni_len + 3) >> 8; ++ tls_data[tls_data_len + 5] = (sni_len + 3); ++ tls_data[tls_data_len + 6] = '\0'; ++ tls_data[tls_data_len + 7] = sni_len >> 8; ++ tls_data[tls_data_len + 8] = sni_len; ++ memcpy(tls_data + tls_data_len + 9, sni, sni_len); ++ tls_data_len += 9 + sni_len; ++ memcpy(tls_data + tls_data_len, tls_data2, tls_data2_len); ++ tls_data_len += tls_data2_len; ++ rand_bytes(tls_data + tls_data_len, 208); ++ tls_data_len += 208; ++ memcpy(tls_data + tls_data_len, tls_data3, tls_data3_len); ++ tls_data_len += tls_data3_len; ++ ++ datalength = 11 + 32 + 1 + 32 + tls_data0_len + 2 + tls_data_len; ++ out_buffer = (char*)malloc(datalength); ++ char *pdata = out_buffer + datalength - tls_data_len; ++ int len = tls_data_len; ++ memcpy(pdata, tls_data, tls_data_len); ++ pdata[-1] = tls_data_len; ++ pdata[-2] = tls_data_len >> 8; ++ pdata -= 2; len += 2; ++ memcpy(pdata - tls_data0_len, tls_data0, tls_data0_len); ++ pdata -= tls_data0_len; len += tls_data0_len; ++ memcpy(pdata - 32, global->local_client_id, 32); ++ pdata -= 32; len += 32; ++ pdata[-1] = 0x20; ++ pdata -= 1; len += 1; ++ tls12_ticket_pack_auth_data(global, &self->server, pdata - 32); ++ pdata -= 32; len += 32; ++ pdata[-1] = 0x3; ++ pdata[-2] = 0x3; // tls version ++ pdata -= 2; len += 2; ++ pdata[-1] = len; ++ pdata[-2] = len >> 8; ++ pdata[-3] = 0; ++ pdata[-4] = 1; ++ pdata -= 4; len += 4; ++ ++ pdata[-1] = len; ++ pdata[-2] = len >> 8; ++ pdata -= 2; len += 2; ++ pdata[-1] = 0x1; ++ pdata[-2] = 0x3; // tls version ++ pdata -= 2; len += 2; ++ pdata[-1] = 0x16; // tls handshake ++ pdata -= 1; len += 1; ++ ++ local->handshake_status = 1; ++ } else if (datalength == 0) { ++ datalength = local->send_buffer_size + 43; ++ out_buffer = (char*)malloc(datalength); ++ char *pdata = out_buffer; ++ memcpy(pdata, "\x14\x03\x03\x00\x01\x01", 6); ++ pdata += 6; ++ memcpy(pdata, "\x16\x03\x03\x00\x20", 5); ++ pdata += 5; ++ rand_bytes((uint8_t*)pdata, 22); ++ pdata += 22; ++ ++ uint8_t *key = (uint8_t*)malloc(self->server.key_len + 32); ++ char hash[ONETIMEAUTH_BYTES * 2]; ++ memcpy(key, self->server.key, self->server.key_len); ++ memcpy(key + self->server.key_len, global->local_client_id, 32); ++ ss_sha1_hmac_with_key(hash, out_buffer, pdata - out_buffer, key, self->server.key_len + 32); ++ free(key); ++ memcpy(pdata, hash, OBFS_HMAC_SHA1_LEN); ++ ++ pdata += OBFS_HMAC_SHA1_LEN; ++ memcpy(pdata, local->send_buffer, local->send_buffer_size); ++ free(local->send_buffer); ++ local->send_buffer = NULL; ++ ++ local->handshake_status = 8; ++ } else { ++ return 0; ++ } ++ if (*capacity < datalength) { ++ *pencryptdata = (char*)realloc(*pencryptdata, *capacity = datalength * 2); ++ encryptdata = *pencryptdata; ++ } ++ memmove(encryptdata, out_buffer, datalength); ++ free(out_buffer); ++ return datalength; ++} ++ ++int tls12_ticket_auth_server_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity) { ++ char *encryptdata = *pencryptdata; ++ tls12_ticket_auth_local_data *local = (tls12_ticket_auth_local_data*)self->l_data; ++ tls12_ticket_auth_global_data *global = (tls12_ticket_auth_global_data*)self->server.g_data; ++ char * out_buffer = NULL; ++ ++ if (local->handshake_status == 8) { ++ if (datalength < 1024) { ++ if (*capacity < datalength + 5) { ++ *pencryptdata = (char*)realloc(*pencryptdata, *capacity = (datalength + 5) * 2); ++ encryptdata = *pencryptdata; ++ } ++ memmove(encryptdata + 5, encryptdata, datalength); ++ encryptdata[0] = 0x17; ++ encryptdata[1] = 0x3; ++ encryptdata[2] = 0x3; ++ encryptdata[3] = datalength >> 8; ++ encryptdata[4] = datalength; ++ return datalength + 5; ++ } else { ++ out_buffer = (char*)malloc(datalength + 2048); ++ int start = 0; ++ int outlength = 0; ++ int len; ++ while (datalength - start > 2048) { ++ len = xorshift128plus() % 4096 + 100; ++ if (len > datalength - start) ++ len = datalength - start; ++ tls12_ticket_auth_pack_data(encryptdata, datalength, start, len, out_buffer, outlength); ++ outlength += len + 5; ++ start += len; ++ } ++ if (datalength - start > 0) { ++ len = datalength - start; ++ tls12_ticket_auth_pack_data(encryptdata, datalength, start, len, out_buffer, outlength); ++ outlength += len + 5; ++ } ++ if (*capacity < outlength) { ++ *pencryptdata = (char*)realloc(*pencryptdata, *capacity = outlength * 2); ++ encryptdata = *pencryptdata; ++ } ++ memcpy(encryptdata, out_buffer, outlength); ++ free(out_buffer); ++ return outlength; ++ } ++ } ++ ++ local->handshake_status = 3; ++ ++ out_buffer = (char*)malloc(43 + 86); ++ int data_len = 0; ++ char *p_data = out_buffer + 86; ++ ++ memcpy(p_data - 10, "\xc0\x2f\x00\x00\x05\xff\x01\x00\x01\x00", 10); ++ p_data -= 10;data_len += 10; ++ ++ memcpy(p_data - 32, global->local_client_id, 32); ++ p_data -= 32;data_len += 32; ++ ++ p_data[-1] = 0x20; ++ p_data -= 1;data_len += 1; ++ ++ tls12_ticket_pack_auth_data(global, &self->server, p_data - 32); ++ p_data -= 32;data_len += 32; ++ ++ p_data[-1] = 0x3; ++ p_data[-2] = 0x3; // tls version ++ p_data -= 2;data_len += 2; ++ ++ p_data[-1] = data_len; ++ p_data[-2] = data_len >> 8; ++ p_data[-3] = 0x00; ++ p_data[-4] = 0x02; ++ p_data -= 4; data_len += 4; ++ ++ p_data[-1] = data_len; ++ p_data[-2] = data_len >> 8; ++ p_data[-3] = 0x03; ++ p_data[-4] = 0x03; ++ p_data[-5] = 0x16; ++ p_data -= 5; data_len += 5; ++ ++ memcpy(out_buffer, p_data, data_len); ++ char *pdata = out_buffer + 86; ++ ++ memcpy(pdata, "\x14\x03\x03\x00\x01\x01", 6); ++ pdata += 6; ++ memcpy(pdata, "\x16\x03\x03\x00\x20", 5); ++ pdata += 5; ++ rand_bytes((uint8_t*)pdata, 22); ++ pdata += 22; ++ ++ uint8_t *key = (uint8_t*)malloc(self->server.key_len + 32); ++ char hash[ONETIMEAUTH_BYTES * 2]; ++ memcpy(key, self->server.key, self->server.key_len); ++ memcpy(key + self->server.key_len, global->local_client_id, 32); ++ ss_sha1_hmac_with_key(hash, out_buffer, 43 + 86, key, self->server.key_len + 32); ++ free(key); ++ memcpy(pdata, hash, OBFS_HMAC_SHA1_LEN); ++ ++ memmove(encryptdata, out_buffer, 43 + 86); ++ free(out_buffer); ++ return 43 + 86; ++} ++ ++int tls12_ticket_auth_client_decode(obfs *self, char **pencryptdata, int datalength, size_t* capacity, int *needsendback) { ++ char *encryptdata = *pencryptdata; ++ tls12_ticket_auth_local_data *local = (tls12_ticket_auth_local_data*)self->l_data; ++ tls12_ticket_auth_global_data *global = (tls12_ticket_auth_global_data*)self->server.g_data; ++ ++ *needsendback = 0; ++ ++ if (local->handshake_status == 8) { ++ local->recv_buffer_size += datalength; ++ local->recv_buffer = (char*)realloc(local->recv_buffer, local->recv_buffer_size); ++ memcpy(local->recv_buffer + local->recv_buffer_size - datalength, encryptdata, datalength); ++ datalength = 0; ++ while (local->recv_buffer_size > 5) { ++ if (local->recv_buffer[0] != 0x17) ++ return -1; ++ int size = ((int)(unsigned char)local->recv_buffer[3] << 8) + (unsigned char)local->recv_buffer[4]; ++ if (size + 5 > local->recv_buffer_size) ++ break; ++ if (*capacity < datalength + size) { ++ *pencryptdata = (char*)realloc(*pencryptdata, *capacity = (datalength + size) * 2); ++ encryptdata = *pencryptdata; ++ } ++ memcpy(encryptdata + datalength, local->recv_buffer + 5, size); ++ datalength += size; ++ local->recv_buffer_size -= 5 + size; ++ memmove(local->recv_buffer, local->recv_buffer + 5 + size, local->recv_buffer_size); ++ } ++ return datalength; ++ } ++ if (datalength < 11 + 32 + 1 + 32) { ++ return -1; ++ } ++ ++ uint8_t *key = (uint8_t*)malloc(self->server.key_len + 32); ++ char hash[ONETIMEAUTH_BYTES * 2]; ++ memcpy(key, self->server.key, self->server.key_len); ++ memcpy(key + self->server.key_len, global->local_client_id, 32); ++ ss_sha1_hmac_with_key(hash, encryptdata + 11, 22, key, self->server.key_len + 32); ++ free(key); ++ ++ if (memcmp(encryptdata + 33, hash, OBFS_HMAC_SHA1_LEN)) { ++ return -1; ++ } ++ ++ *needsendback = 1; ++ return 0; ++} ++ ++int tls12_ticket_auth_server_decode(obfs *self, char **pencryptdata, int datalength, size_t* capacity, int *needsendback) { ++ char *encryptdata = *pencryptdata; ++ tls12_ticket_auth_local_data *local = (tls12_ticket_auth_local_data*)self->l_data; ++ tls12_ticket_auth_global_data *global = (tls12_ticket_auth_global_data*)self->server.g_data; ++ ++ *needsendback = 0; ++ ++ if (local->handshake_status == 8) { ++ if(datalength != 0) ++ { ++ local->recv_buffer = (char*)realloc(local->recv_buffer, local->recv_buffer_size + datalength); ++ memmove(local->recv_buffer + local->recv_buffer_size, encryptdata, datalength); ++ local->recv_buffer_size += datalength; ++ } ++ datalength = 0; ++ ++ while (local->recv_buffer_size > 5) { ++ if (local->recv_buffer[0] != 0x17 || local->recv_buffer[1] != 0x03 || local->recv_buffer[2] != 0x03) ++ { ++ LOGE("server_decode data error, wrong tls version 3"); ++ return -1; ++ } ++ int size = ((int)(unsigned char)local->recv_buffer[3] << 8) + (unsigned char)local->recv_buffer[4]; ++ if (size + 5 > local->recv_buffer_size) ++ break; ++ if (*capacity < local->recv_buffer_size + size) { ++ *pencryptdata = (char*)realloc(*pencryptdata, *capacity = (local->recv_buffer_size + size) * 2); ++ encryptdata = *pencryptdata; ++ } ++ memcpy(encryptdata + datalength, local->recv_buffer + 5, size); ++ datalength += size; ++ local->recv_buffer_size -= 5 + size; ++ memmove(local->recv_buffer, local->recv_buffer + 5 + size, local->recv_buffer_size); ++ } ++ return datalength; ++ } ++ ++ if (local->handshake_status == 3) { ++ ++ char *verify = encryptdata; ++ ++ if(datalength < 43) ++ { ++ LOGE("server_decode data error, too short:%d", (int)datalength); ++ return -1; ++ } ++ ++ if(encryptdata[0] != 0x14 || encryptdata[1] != 0x03 || encryptdata[2] != 0x03 || encryptdata[3] != 0x00 || encryptdata[4] != 0x01 || encryptdata[5] != 0x01) ++ { ++ LOGE("server_decode data error, wrong tls version"); ++ return -1; ++ } ++ ++ encryptdata += 6; ++ ++ if(encryptdata[0] != 0x16 || encryptdata[1] != 0x03 || encryptdata[2] != 0x03 || encryptdata[3] != 0x00 || encryptdata[4] != 0x20) ++ { ++ LOGE("server_decode data error, wrong tls version 2"); ++ return -1; ++ } ++ ++ uint8_t *key = (uint8_t*)malloc(self->server.key_len + 32); ++ char hash[ONETIMEAUTH_BYTES * 2]; ++ memcpy(key, self->server.key, self->server.key_len); ++ memcpy(key + self->server.key_len, global->local_client_id, 32); ++ ss_sha1_hmac_with_key(hash, verify, 33, key, self->server.key_len + 32); ++ free(key); ++ ++ if (memcmp(verify + 33, hash, OBFS_HMAC_SHA1_LEN) != 0) { ++ LOGE("server_decode data error, hash Mismatch %d",(int)memcmp(verify + 33, hash, OBFS_HMAC_SHA1_LEN)); ++ return -1; ++ } ++ ++ local->recv_buffer_size = datalength - 43; ++ local->recv_buffer = (char*)realloc(local->recv_buffer, local->recv_buffer_size); ++ memmove(local->recv_buffer, encryptdata + 37, datalength - 43); ++ ++ local->handshake_status = 8; ++ return tls12_ticket_auth_server_decode(self, pencryptdata, 0, capacity, needsendback); ++ } ++ ++ local->handshake_status = 2; ++ if(encryptdata[0] != 0x16 || encryptdata[1] != 0x03 || encryptdata[2] != 0x01) ++ { ++ return -1; ++ } ++ ++ encryptdata += 3; ++ ++ { ++ int size = ((int)(unsigned char)encryptdata[0] << 8) + (unsigned char)encryptdata[1]; ++ if(size != datalength - 5) ++ { ++ LOGE("tls_auth wrong tls head size"); ++ return -1; ++ } ++ } ++ ++ encryptdata += 2; ++ ++ if(encryptdata[0] != 0x01 || encryptdata[1] != 0x00) ++ { ++ LOGE("tls_auth not client hello message"); ++ return -1; ++ } ++ ++ encryptdata += 2; ++ ++ { ++ int size = ((int)(unsigned char)encryptdata[0] << 8) + (unsigned char)encryptdata[1]; ++ if(size != datalength - 9) ++ { ++ LOGE("tls_auth wrong message size"); ++ return -1; ++ } ++ } ++ ++ encryptdata += 2; ++ ++ if(encryptdata[0] != 0x03 || encryptdata[1] != 0x03) ++ { ++ LOGE("tls_auth wrong tls version"); ++ return -1; ++ } ++ ++ encryptdata += 2; ++ ++ char *verifyid = encryptdata; ++ ++ encryptdata += 32; ++ ++ int sessionid_len = encryptdata[0]; ++ if(sessionid_len < 32) ++ { ++ LOGE("tls_auth wrong sessionid_len"); ++ return -1; ++ } ++ ++ char *sessionid = encryptdata + 1; ++ memcpy(global->local_client_id , sessionid, sessionid_len); ++ ++ uint8_t *key = (uint8_t*)malloc(self->server.key_len + sessionid_len); ++ char hash[ONETIMEAUTH_BYTES * 2]; ++ memcpy(key, self->server.key, self->server.key_len); ++ memcpy(key + self->server.key_len, global->local_client_id, sessionid_len); ++ ss_sha1_hmac_with_key(hash, verifyid, 22, key, self->server.key_len + sessionid_len); ++ free(key); ++ ++ encryptdata += (sessionid_len + 1); ++ ++ long utc_time = ((int)(unsigned char)verifyid[0] << 24) + ((int)(unsigned char)verifyid[1] << 16) + ((int)(unsigned char)verifyid[2] << 8) + (unsigned char)verifyid[3]; ++ time_t t = time(NULL); ++ ++ ++ if (self->server.param && strlen(self->server.param) == 0) ++ { ++ self->server.param = NULL; ++ } ++ ++ int max_time_dif = 0; ++ int time_dif = utc_time - t; ++ if(self->server.param) ++ { ++ max_time_dif = atoi(self->server.param); ++ } ++ ++ if(max_time_dif > 0 && (time_dif < -max_time_dif || time_dif > max_time_dif || utc_time - global->startup_time < -max_time_dif / 2)) ++ { ++ LOGE("tls_auth wrong time"); ++ return -1; ++ } ++ ++ if (memcmp(verifyid + 22, hash, OBFS_HMAC_SHA1_LEN)) { ++ LOGE("tls_auth wrong sha1"); ++ return -1; ++ } ++ ++ int search_result = global->client_data->have_same_cmp(global->client_data, verifyid); ++ if(search_result != 0) ++ { ++ LOGE("replay attack detect!"); ++ return -1; ++ } ++ ++ global->client_data->add_back(global->client_data, verifyid); ++ ++ encryptdata += 48; ++ ++ *needsendback = 1; ++ ++ return 0; ++} +diff --git a/server/tls1.2_ticket.h b/server/tls1.2_ticket.h +new file mode 100644 +index 0000000..10a57c9 +--- /dev/null ++++ b/server/tls1.2_ticket.h +@@ -0,0 +1,20 @@ ++/* ++ * http_simple.h - Define shadowsocksR server's buffers and callbacks ++ * ++ * Copyright (C) 2015 - 2016, Break Wa11 ++ */ ++ ++#ifndef _TLS1_2_TICKET_H ++#define _TLS1_2_TICKET_H ++ ++void * tls12_ticket_auth_init_data(); ++obfs * tls12_ticket_auth_new_obfs(); ++void tls12_ticket_auth_dispose(obfs *self); ++ ++int tls12_ticket_auth_client_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity); ++int tls12_ticket_auth_client_decode(obfs *self, char **pencryptdata, int datalength, size_t* capacity, int *needsendback); ++ ++int tls12_ticket_auth_server_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity); ++int tls12_ticket_auth_server_decode(obfs *self, char **pencryptdata, int datalength, size_t* capacity, int *needsendback); ++ ++#endif // _TLS1_2_TICKET_H +diff --git a/server/udprelay.c b/server/udprelay.c +new file mode 100644 +index 0000000..d9251ee +--- /dev/null ++++ b/server/udprelay.c +@@ -0,0 +1,1452 @@ ++/* ++ * udprelay.c - Setup UDP relay for both client and server ++ * ++ * Copyright (C) 2013 - 2016, Max Lv ++ * ++ * This file is part of the shadowsocks-libev. ++ * ++ * shadowsocks-libev 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 3 of the License, or ++ * (at your option) any later version. ++ * ++ * shadowsocks-libev 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 shadowsocks-libev; see the file COPYING. If not, see ++ * . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifndef __MINGW32__ ++#include ++#include ++#include ++#include ++#include ++#endif ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_NET_IF_H) && defined(__linux__) ++#include ++#include ++#define SET_INTERFACE ++#endif ++ ++#ifdef __MINGW32__ ++#include "win32.h" ++#endif ++ ++#include ++#include ++ ++#include "utils.h" ++#include "netutils.h" ++#include "cache.h" ++#include "udprelay.h" ++ ++#ifdef MODULE_REMOTE ++#define MAX_UDP_CONN_NUM 512 ++#else ++#define MAX_UDP_CONN_NUM 256 ++#endif ++ ++#ifdef MODULE_REMOTE ++#ifdef MODULE_ ++#error "MODULE_REMOTE and MODULE_LOCAL should not be both defined" ++#endif ++#endif ++ ++#ifndef EAGAIN ++#define EAGAIN EWOULDBLOCK ++#endif ++ ++#ifndef EWOULDBLOCK ++#define EWOULDBLOCK EAGAIN ++#endif ++ ++static void server_recv_cb(EV_P_ ev_io *w, int revents); ++static void remote_recv_cb(EV_P_ ev_io *w, int revents); ++static void remote_timeout_cb(EV_P_ ev_timer *watcher, int revents); ++ ++static char *hash_key(const int af, const struct sockaddr_storage *addr); ++#ifdef MODULE_REMOTE ++static void query_resolve_cb(struct sockaddr *addr, void *data); ++#endif ++static void close_and_free_remote(EV_P_ remote_ctx_t *ctx); ++static remote_ctx_t *new_remote(int fd, server_ctx_t *server_ctx); ++ ++#ifdef ANDROID ++extern uint64_t tx; ++extern uint64_t rx; ++extern int vpn; ++#endif ++ ++extern int verbose; ++#ifdef MODULE_REMOTE ++extern uint64_t tx; ++extern uint64_t rx; ++#endif ++ ++static int packet_size = DEFAULT_PACKET_SIZE; ++static int buf_size = DEFAULT_PACKET_SIZE * 2; ++static int server_num = 0; ++static server_ctx_t *server_ctx_list[MAX_REMOTE_NUM] = { NULL }; ++ ++#ifndef __MINGW32__ ++static int ++setnonblocking(int fd) ++{ ++ int flags; ++ if (-1 == (flags = fcntl(fd, F_GETFL, 0))) { ++ flags = 0; ++ } ++ return fcntl(fd, F_SETFL, flags | O_NONBLOCK); ++} ++ ++#endif ++ ++#if defined(MODULE_REMOTE) && defined(SO_BROADCAST) ++static int ++set_broadcast(int socket_fd) ++{ ++ int opt = 1; ++ return setsockopt(socket_fd, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt)); ++} ++ ++#endif ++ ++#ifdef SO_NOSIGPIPE ++static int ++set_nosigpipe(int socket_fd) ++{ ++ int opt = 1; ++ return setsockopt(socket_fd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt)); ++} ++ ++#endif ++ ++#ifdef MODULE_REDIR ++ ++#ifndef IP_TRANSPARENT ++#define IP_TRANSPARENT 19 ++#endif ++ ++#ifndef IP_RECVORIGDSTADDR ++#define IP_RECVORIGDSTADDR 20 ++#endif ++ ++static int ++get_dstaddr(struct msghdr *msg, struct sockaddr_storage *dstaddr) ++{ ++ struct cmsghdr *cmsg; ++ ++ for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { ++ if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVORIGDSTADDR) { ++ memcpy(dstaddr, CMSG_DATA(cmsg), sizeof(struct sockaddr_in)); ++ dstaddr->ss_family = AF_INET; ++ return 0; ++ } else if (cmsg->cmsg_level == SOL_IPV6 && cmsg->cmsg_type == IP_RECVORIGDSTADDR) { ++ memcpy(dstaddr, CMSG_DATA(cmsg), sizeof(struct sockaddr_in6)); ++ dstaddr->ss_family = AF_INET6; ++ return 0; ++ } ++ } ++ ++ return 1; ++} ++ ++#endif ++ ++#define HASH_KEY_LEN sizeof(struct sockaddr_storage) + sizeof(int) ++static char * ++hash_key(const int af, const struct sockaddr_storage *addr) ++{ ++ size_t addr_len = sizeof(struct sockaddr_storage); ++ static char key[HASH_KEY_LEN]; ++ ++ memset(key, 0, HASH_KEY_LEN); ++ memcpy(key, &af, sizeof(int)); ++ memcpy(key + sizeof(int), (const uint8_t *)addr, addr_len); ++ ++ return key; ++} ++ ++#if defined(MODULE_REDIR) || defined(MODULE_REMOTE) ++static int ++construct_udprealy_header(const struct sockaddr_storage *in_addr, ++ char *addr_header) ++{ ++ int addr_header_len = 0; ++ if (in_addr->ss_family == AF_INET) { ++ struct sockaddr_in *addr = (struct sockaddr_in *)in_addr; ++ size_t addr_len = sizeof(struct in_addr); ++ addr_header[addr_header_len++] = 1; ++ memcpy(addr_header + addr_header_len, &addr->sin_addr, addr_len); ++ addr_header_len += addr_len; ++ memcpy(addr_header + addr_header_len, &addr->sin_port, 2); ++ addr_header_len += 2; ++ } else if (in_addr->ss_family == AF_INET6) { ++ struct sockaddr_in6 *addr = (struct sockaddr_in6 *)in_addr; ++ size_t addr_len = sizeof(struct in6_addr); ++ addr_header[addr_header_len++] = 4; ++ memcpy(addr_header + addr_header_len, &addr->sin6_addr, addr_len); ++ addr_header_len += addr_len; ++ memcpy(addr_header + addr_header_len, &addr->sin6_port, 2); ++ addr_header_len += 2; ++ } else { ++ return 0; ++ } ++ return addr_header_len; ++} ++ ++#endif ++ ++static int ++parse_udprealy_header(const char *buf, const size_t buf_len, ++ char *host, char *port, struct sockaddr_storage *storage) ++{ ++ const uint8_t atyp = *(uint8_t *)buf; ++ int offset = 1; ++ ++ // get remote addr and port ++ if ((atyp & ADDRTYPE_MASK) == 1) { ++ // IP V4 ++ size_t in_addr_len = sizeof(struct in_addr); ++ if (buf_len >= in_addr_len + 3) { ++ if (storage != NULL) { ++ struct sockaddr_in *addr = (struct sockaddr_in *)storage; ++ addr->sin_family = AF_INET; ++ addr->sin_addr = *(struct in_addr *)(buf + offset); ++ addr->sin_port = *(uint16_t *)(buf + offset + in_addr_len); ++ } ++ if (host != NULL) { ++ dns_ntop(AF_INET, (const void *)(buf + offset), ++ host, INET_ADDRSTRLEN); ++ } ++ offset += in_addr_len; ++ } ++ } else if ((atyp & ADDRTYPE_MASK) == 3) { ++ // Domain name ++ uint8_t name_len = *(uint8_t *)(buf + offset); ++ if (name_len + 4 <= buf_len) { ++ if (storage != NULL) { ++ char tmp[257] = { 0 }; ++ struct cork_ip ip; ++ memcpy(tmp, buf + offset + 1, name_len); ++ if (cork_ip_init(&ip, tmp) != -1) { ++ if (ip.version == 4) { ++ struct sockaddr_in *addr = (struct sockaddr_in *)storage; ++ dns_pton(AF_INET, tmp, &(addr->sin_addr)); ++ addr->sin_port = *(uint16_t *)(buf + offset + 1 + name_len); ++ addr->sin_family = AF_INET; ++ } else if (ip.version == 6) { ++ struct sockaddr_in6 *addr = (struct sockaddr_in6 *)storage; ++ dns_pton(AF_INET, tmp, &(addr->sin6_addr)); ++ addr->sin6_port = *(uint16_t *)(buf + offset + 1 + name_len); ++ addr->sin6_family = AF_INET6; ++ } ++ } ++ } ++ if (host != NULL) { ++ memcpy(host, buf + offset + 1, name_len); ++ } ++ offset += 1 + name_len; ++ } ++ } else if ((atyp & ADDRTYPE_MASK) == 4) { ++ // IP V6 ++ size_t in6_addr_len = sizeof(struct in6_addr); ++ if (buf_len >= in6_addr_len + 3) { ++ if (storage != NULL) { ++ struct sockaddr_in6 *addr = (struct sockaddr_in6 *)storage; ++ addr->sin6_family = AF_INET6; ++ addr->sin6_addr = *(struct in6_addr *)(buf + offset); ++ addr->sin6_port = *(uint16_t *)(buf + offset + in6_addr_len); ++ } ++ if (host != NULL) { ++ dns_ntop(AF_INET6, (const void *)(buf + offset), ++ host, INET6_ADDRSTRLEN); ++ } ++ offset += in6_addr_len; ++ } ++ } ++ ++ if (offset == 1) { ++ LOGE("[udp] invalid header with addr type %d", atyp); ++ return 0; ++ } ++ ++ if (port != NULL) { ++ sprintf(port, "%d", ntohs(*(uint16_t *)(buf + offset))); ++ } ++ offset += 2; ++ ++ return offset; ++} ++ ++static char * ++get_addr_str(const struct sockaddr *sa) ++{ ++ static char s[SS_ADDRSTRLEN]; ++ memset(s, 0, SS_ADDRSTRLEN); ++ char addr[INET6_ADDRSTRLEN] = { 0 }; ++ char port[PORTSTRLEN] = { 0 }; ++ uint16_t p; ++ ++ switch (sa->sa_family) { ++ case AF_INET: ++ dns_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr), ++ addr, INET_ADDRSTRLEN); ++ p = ntohs(((struct sockaddr_in *)sa)->sin_port); ++ sprintf(port, "%d", p); ++ break; ++ ++ case AF_INET6: ++ dns_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr), ++ addr, INET6_ADDRSTRLEN); ++ p = ntohs(((struct sockaddr_in *)sa)->sin_port); ++ sprintf(port, "%d", p); ++ break; ++ ++ default: ++ strncpy(s, "Unknown AF", SS_ADDRSTRLEN); ++ } ++ ++ int addr_len = strlen(addr); ++ int port_len = strlen(port); ++ memcpy(s, addr, addr_len); ++ memcpy(s + addr_len + 1, port, port_len); ++ s[addr_len] = ':'; ++ ++ return s; ++} ++ ++int ++create_remote_socket(int ipv6) ++{ ++ int remote_sock; ++ ++ if (ipv6) { ++ // Try to bind IPv6 first ++ struct sockaddr_in6 addr; ++ memset(&addr, 0, sizeof(struct sockaddr_in6)); ++ addr.sin6_family = AF_INET6; ++ addr.sin6_addr = in6addr_any; ++ addr.sin6_port = 0; ++ remote_sock = socket(AF_INET6, SOCK_DGRAM, 0); ++ if (remote_sock == -1) { ++ ERROR("[udp] cannot create socket"); ++ return -1; ++ } ++ if (bind(remote_sock, (struct sockaddr *)&addr, sizeof(addr)) != 0) { ++ FATAL("[udp] cannot bind remote"); ++ return -1; ++ } ++ } else { ++ // Or else bind to IPv4 ++ struct sockaddr_in addr; ++ memset(&addr, 0, sizeof(struct sockaddr_in)); ++ addr.sin_family = AF_INET; ++ addr.sin_addr.s_addr = INADDR_ANY; ++ addr.sin_port = 0; ++ remote_sock = socket(AF_INET, SOCK_DGRAM, 0); ++ if (remote_sock == -1) { ++ ERROR("[udp] cannot create socket"); ++ return -1; ++ } ++ ++ if (bind(remote_sock, (struct sockaddr *)&addr, sizeof(addr)) != 0) { ++ FATAL("[udp] cannot bind remote"); ++ return -1; ++ } ++ } ++ return remote_sock; ++} ++ ++int ++create_server_socket(const char *host, const char *port) ++{ ++ struct addrinfo hints; ++ struct addrinfo *result, *rp, *ipv4v6bindall; ++ int s, server_sock; ++ ++ memset(&hints, 0, sizeof(struct addrinfo)); ++ hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */ ++ hints.ai_socktype = SOCK_DGRAM; /* We want a UDP socket */ ++ hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; /* For wildcard IP address */ ++ hints.ai_protocol = IPPROTO_UDP; ++ ++ s = getaddrinfo(host, port, &hints, &result); ++ if (s != 0) { ++ LOGE("[udp] getaddrinfo: %s", gai_strerror(s)); ++ return -1; ++ } ++ ++ rp = result; ++ ++ /* ++ * On Linux, with net.ipv6.bindv6only = 0 (the default), getaddrinfo(NULL) with ++ * AI_PASSIVE returns 0.0.0.0 and :: (in this order). AI_PASSIVE was meant to ++ * return a list of addresses to listen on, but it is impossible to listen on ++ * 0.0.0.0 and :: at the same time, if :: implies dualstack mode. ++ */ ++ if (!host) { ++ ipv4v6bindall = result; ++ ++ /* Loop over all address infos found until a IPV6 address is found. */ ++ while (ipv4v6bindall) { ++ if (ipv4v6bindall->ai_family == AF_INET6) { ++ rp = ipv4v6bindall; /* Take first IPV6 address available */ ++ break; ++ } ++ ipv4v6bindall = ipv4v6bindall->ai_next; /* Get next address info, if any */ ++ } ++ } ++ ++ for (/*rp = result*/; rp != NULL; rp = rp->ai_next) { ++ server_sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); ++ if (server_sock == -1) { ++ continue; ++ } ++ ++ if (rp->ai_family == AF_INET6) { ++ int ipv6only = host ? 1 : 0; ++ setsockopt(server_sock, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, sizeof(ipv6only)); ++ } ++ ++ int opt = 1; ++ setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); ++#ifdef SO_NOSIGPIPE ++ set_nosigpipe(server_sock); ++#endif ++ int err = set_reuseport(server_sock); ++ if (err == 0) { ++ LOGI("udp port reuse enabled"); ++ } ++#ifdef IP_TOS ++ // Set QoS flag ++ int tos = 46; ++ setsockopt(server_sock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); ++#endif ++ ++#ifdef MODULE_REDIR ++ if (setsockopt(server_sock, SOL_IP, IP_TRANSPARENT, &opt, sizeof(opt))) { ++ ERROR("[udp] setsockopt IP_TRANSPARENT"); ++ exit(EXIT_FAILURE); ++ } ++ if (setsockopt(server_sock, IPPROTO_IP, IP_RECVORIGDSTADDR, &opt, sizeof(opt))) { ++ FATAL("[udp] setsockopt IP_RECVORIGDSTADDR"); ++ } ++#endif ++ ++ s = bind(server_sock, rp->ai_addr, rp->ai_addrlen); ++ if (s == 0) { ++ /* We managed to bind successfully! */ ++ break; ++ } else { ++ ERROR("[udp] bind"); ++ } ++ ++ close(server_sock); ++ } ++ ++ if (rp == NULL) { ++ LOGE("[udp] cannot bind"); ++ return -1; ++ } ++ ++ freeaddrinfo(result); ++ ++ return server_sock; ++} ++ ++remote_ctx_t * ++new_remote(int fd, server_ctx_t *server_ctx) ++{ ++ remote_ctx_t *ctx = ss_malloc(sizeof(remote_ctx_t)); ++ memset(ctx, 0, sizeof(remote_ctx_t)); ++ ++ ctx->fd = fd; ++ ctx->server_ctx = server_ctx; ++ ++ ev_io_init(&ctx->io, remote_recv_cb, fd, EV_READ); ++ ev_timer_init(&ctx->watcher, remote_timeout_cb, server_ctx->timeout, ++ server_ctx->timeout); ++ ++ return ctx; ++} ++ ++server_ctx_t * ++new_server_ctx(int fd) ++{ ++ server_ctx_t *ctx = ss_malloc(sizeof(server_ctx_t)); ++ memset(ctx, 0, sizeof(server_ctx_t)); ++ ++ ctx->fd = fd; ++ ++ ev_io_init(&ctx->io, server_recv_cb, fd, EV_READ); ++ ++ return ctx; ++} ++ ++#ifdef MODULE_REMOTE ++struct query_ctx * ++new_query_ctx(char *buf, size_t len) ++{ ++ struct query_ctx *ctx = ss_malloc(sizeof(struct query_ctx)); ++ memset(ctx, 0, sizeof(struct query_ctx)); ++ ctx->buf = ss_malloc(sizeof(buffer_t)); ++ balloc(ctx->buf, len); ++ memcpy(ctx->buf->array, buf, len); ++ ctx->buf->len = len; ++ return ctx; ++} ++ ++void ++close_and_free_query(EV_P_ struct query_ctx *ctx) ++{ ++ if (ctx != NULL) { ++ if (ctx->query != NULL) { ++ resolv_cancel(ctx->query); ++ ctx->query = NULL; ++ } ++ if (ctx->buf != NULL) { ++ bfree(ctx->buf); ++ ss_free(ctx->buf); ++ } ++ ss_free(ctx); ++ } ++} ++ ++#endif ++ ++void ++close_and_free_remote(EV_P_ remote_ctx_t *ctx) ++{ ++ if (ctx != NULL) { ++ ev_timer_stop(EV_A_ & ctx->watcher); ++ ev_io_stop(EV_A_ & ctx->io); ++ close(ctx->fd); ++ ss_free(ctx); ++ } ++} ++ ++static void ++remote_timeout_cb(EV_P_ ev_timer *watcher, int revents) ++{ ++ remote_ctx_t *remote_ctx ++ = cork_container_of(watcher, remote_ctx_t, watcher); ++ ++ if (verbose) { ++ LOGI("[udp] connection timeout"); ++ } ++ ++ char *key = hash_key(remote_ctx->af, &remote_ctx->src_addr); ++ cache_remove(remote_ctx->server_ctx->conn_cache, key, HASH_KEY_LEN); ++} ++ ++#ifdef MODULE_REMOTE ++static void ++query_resolve_cb(struct sockaddr *addr, void *data) ++{ ++ struct query_ctx *query_ctx = (struct query_ctx *)data; ++ struct ev_loop *loop = query_ctx->server_ctx->loop; ++ ++ if (verbose) { ++ LOGI("[udp] udns resolved"); ++ } ++ ++ query_ctx->query = NULL; ++ ++ if (addr == NULL) { ++ LOGE("[udp] udns returned an error"); ++ } else { ++ remote_ctx_t *remote_ctx = query_ctx->remote_ctx; ++ int cache_hit = 0; ++ ++ // Lookup in the conn cache ++ if (remote_ctx == NULL) { ++ char *key = hash_key(AF_UNSPEC, &query_ctx->src_addr); ++ cache_lookup(query_ctx->server_ctx->conn_cache, key, HASH_KEY_LEN, (void *)&remote_ctx); ++ } ++ ++ if (remote_ctx == NULL) { ++ int remotefd = create_remote_socket(addr->sa_family == AF_INET6); ++ if (remotefd != -1) { ++ setnonblocking(remotefd); ++#ifdef SO_BROADCAST ++ set_broadcast(remotefd); ++#endif ++#ifdef SO_NOSIGPIPE ++ set_nosigpipe(remotefd); ++#endif ++#ifdef IP_TOS ++ // Set QoS flag ++ int tos = 46; ++ setsockopt(remotefd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); ++#endif ++#ifdef SET_INTERFACE ++ if (query_ctx->server_ctx->iface) { ++ if (setinterface(remotefd, query_ctx->server_ctx->iface) == -1) ++ ERROR("setinterface"); ++ } ++#endif ++ remote_ctx = new_remote(remotefd, query_ctx->server_ctx); ++ remote_ctx->src_addr = query_ctx->src_addr; ++ remote_ctx->server_ctx = query_ctx->server_ctx; ++ remote_ctx->addr_header_len = query_ctx->addr_header_len; ++ memcpy(remote_ctx->addr_header, query_ctx->addr_header, ++ query_ctx->addr_header_len); ++ } else { ++ ERROR("[udp] bind() error"); ++ } ++ } else { ++ cache_hit = 1; ++ } ++ ++ if (remote_ctx != NULL) { ++ memcpy(&remote_ctx->dst_addr, addr, sizeof(struct sockaddr_storage)); ++ ++ size_t addr_len = get_sockaddr_len(addr); ++ int s = sendto(remote_ctx->fd, query_ctx->buf->array, query_ctx->buf->len, ++ 0, addr, addr_len); ++ ++ if (s == -1) { ++ ERROR("[udp] sendto_remote"); ++ if (!cache_hit) { ++ close_and_free_remote(EV_A_ remote_ctx); ++ } ++ } else { ++ if (!cache_hit) { ++ // Add to conn cache ++ char *key = hash_key(AF_UNSPEC, &remote_ctx->src_addr); ++ cache_insert(query_ctx->server_ctx->conn_cache, key, HASH_KEY_LEN, (void *)remote_ctx); ++ ev_io_start(EV_A_ & remote_ctx->io); ++ ev_timer_start(EV_A_ & remote_ctx->watcher); ++ } ++ } ++ } ++ } ++ ++ // clean up ++ close_and_free_query(EV_A_ query_ctx); ++} ++ ++#endif ++ ++static void ++remote_recv_cb(EV_P_ ev_io *w, int revents) ++{ ++ ssize_t r; ++ remote_ctx_t *remote_ctx = (remote_ctx_t *)w; ++ server_ctx_t *server_ctx = remote_ctx->server_ctx; ++ ++ // server has been closed ++ if (server_ctx == NULL) { ++ LOGE("[udp] invalid server"); ++ close_and_free_remote(EV_A_ remote_ctx); ++ return; ++ } ++ ++ struct sockaddr_storage src_addr; ++ socklen_t src_addr_len = sizeof(struct sockaddr_storage); ++ memset(&src_addr, 0, src_addr_len); ++ ++ buffer_t *buf = ss_malloc(sizeof(buffer_t)); ++ balloc(buf, buf_size); ++ ++ // recv ++ r = recvfrom(remote_ctx->fd, buf->array, buf_size, 0, (struct sockaddr *)&src_addr, &src_addr_len); ++ ++ if (r == -1) { ++ // error on recv ++ // simply drop that packet ++ ERROR("[udp] remote_recv_recvfrom"); ++ goto CLEAN_UP; ++ } else if (r > packet_size) { ++ LOGE("[udp] remote_recv_recvfrom fragmentation"); ++ goto CLEAN_UP; ++ } ++ ++ buf->len = r; ++ ++#ifdef MODULE_LOCAL ++ int err = ss_decrypt_all(buf, server_ctx->method, 0, buf_size); ++ if (err) { ++ // drop the packet silently ++ goto CLEAN_UP; ++ } ++ ++ //SSR beg ++ if (server_ctx->protocol_plugin) { ++ obfs_class *protocol_plugin = server_ctx->protocol_plugin; ++ if (protocol_plugin->client_udp_post_decrypt) { ++ buf->len = protocol_plugin->client_udp_post_decrypt(server_ctx->protocol, &buf->array, buf->len, &buf->capacity); ++ if ((int)buf->len < 0) { ++ LOGE("client_udp_post_decrypt"); ++ close_and_free_remote(EV_A_ remote_ctx); ++ return; ++ } ++ if ( buf->len == 0 ) ++ return; ++ } ++ } ++ // SSR end ++ ++#ifdef MODULE_REDIR ++ struct sockaddr_storage dst_addr; ++ memset(&dst_addr, 0, sizeof(struct sockaddr_storage)); ++ int len = parse_udprealy_header(buf->array, buf->len, NULL, NULL, &dst_addr); ++ ++ if (dst_addr.ss_family != AF_INET && dst_addr.ss_family != AF_INET6) { ++ LOGI("[udp] ss-redir does not support domain name"); ++ goto CLEAN_UP; ++ } ++ ++ if (verbose) { ++ char src[SS_ADDRSTRLEN]; ++ char dst[SS_ADDRSTRLEN]; ++ strcpy(src, get_addr_str((struct sockaddr *)&src_addr)); ++ strcpy(dst, get_addr_str((struct sockaddr *)&dst_addr)); ++ LOGI("[udp] recv %s via %s", dst, src); ++ } ++#else ++ int len = parse_udprealy_header(buf->array, buf->len, NULL, NULL, NULL); ++#endif ++ ++ if (len == 0) { ++ LOGI("[udp] error in parse header"); ++ // error in parse header ++ goto CLEAN_UP; ++ } ++ ++ // server may return using a different address type other than the type we ++ // have used during sending ++#if defined(MODULE_TUNNEL) || defined(MODULE_REDIR) ++ // Construct packet ++ buf->len -= len; ++ memmove(buf->array, buf->array + len, buf->len); ++#else ++#ifdef ANDROID ++ rx += buf->len; ++#endif ++ // Construct packet ++ brealloc(buf, buf->len + 3, buf_size); ++ memmove(buf->array + 3, buf->array, buf->len); ++ memset(buf->array, 0, 3); ++ buf->len += 3; ++#endif ++ ++#endif ++ ++#ifdef MODULE_REMOTE ++ ++ rx += buf->len; ++ ++ char addr_header_buf[512]; ++ char *addr_header = remote_ctx->addr_header; ++ int addr_header_len = remote_ctx->addr_header_len; ++ ++ if (remote_ctx->af == AF_INET || remote_ctx->af == AF_INET6) { ++ addr_header_len = construct_udprealy_header(&src_addr, addr_header_buf); ++ addr_header = addr_header_buf; ++ } ++ ++ // Construct packet ++ brealloc(buf, buf->len + addr_header_len, buf_size); ++ memmove(buf->array + addr_header_len, buf->array, buf->len); ++ memcpy(buf->array, addr_header, addr_header_len); ++ buf->len += addr_header_len; ++ ++ int err = ss_encrypt_all(buf, server_ctx->method, 0, buf_size); ++ if (err) { ++ // drop the packet silently ++ goto CLEAN_UP; ++ } ++ ++#endif ++ ++ if (buf->len > packet_size) { ++ LOGE("[udp] remote_recv_sendto fragmentation"); ++ goto CLEAN_UP; ++ } ++ ++ size_t remote_src_addr_len = get_sockaddr_len((struct sockaddr *)&remote_ctx->src_addr); ++ ++#ifdef MODULE_REDIR ++ ++ size_t remote_dst_addr_len = get_sockaddr_len((struct sockaddr *)&dst_addr); ++ ++ int src_fd = socket(remote_ctx->src_addr.ss_family, SOCK_DGRAM, 0); ++ if (src_fd < 0) { ++ ERROR("[udp] remote_recv_socket"); ++ goto CLEAN_UP; ++ } ++ int opt = 1; ++ if (setsockopt(src_fd, SOL_IP, IP_TRANSPARENT, &opt, sizeof(opt))) { ++ ERROR("[udp] remote_recv_setsockopt"); ++ close(src_fd); ++ goto CLEAN_UP; ++ } ++ if (setsockopt(src_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) { ++ ERROR("[udp] remote_recv_setsockopt"); ++ close(src_fd); ++ goto CLEAN_UP; ++ } ++#ifdef IP_TOS ++ // Set QoS flag ++ int tos = 46; ++ setsockopt(src_fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); ++#endif ++ if (bind(src_fd, (struct sockaddr *)&dst_addr, remote_dst_addr_len) != 0) { ++ ERROR("[udp] remote_recv_bind"); ++ close(src_fd); ++ goto CLEAN_UP; ++ } ++ ++ int s = sendto(src_fd, buf->array, buf->len, 0, ++ (struct sockaddr *)&remote_ctx->src_addr, remote_src_addr_len); ++ if (s == -1) { ++ ERROR("[udp] remote_recv_sendto"); ++ close(src_fd); ++ goto CLEAN_UP; ++ } ++ close(src_fd); ++ ++#else ++ ++ int s = sendto(server_ctx->fd, buf->array, buf->len, 0, ++ (struct sockaddr *)&remote_ctx->src_addr, remote_src_addr_len); ++ if (s == -1) { ++ ERROR("[udp] remote_recv_sendto"); ++ goto CLEAN_UP; ++ } ++ ++#endif ++ ++ // handle the UDP packet successfully, ++ // triger the timer ++ ev_timer_again(EV_A_ & remote_ctx->watcher); ++ ++CLEAN_UP: ++ ++ bfree(buf); ++ ss_free(buf); ++} ++ ++static void ++server_recv_cb(EV_P_ ev_io *w, int revents) ++{ ++ server_ctx_t *server_ctx = (server_ctx_t *)w; ++ struct sockaddr_storage src_addr; ++ memset(&src_addr, 0, sizeof(struct sockaddr_storage)); ++ ++ buffer_t *buf = ss_malloc(sizeof(buffer_t)); ++ balloc(buf, buf_size); ++ ++ socklen_t src_addr_len = sizeof(struct sockaddr_storage); ++ unsigned int offset = 0; ++ ++#ifdef MODULE_REDIR ++ char control_buffer[64] = { 0 }; ++ struct msghdr msg; ++ memset(&msg, 0, sizeof(struct msghdr)); ++ struct iovec iov[1]; ++ struct sockaddr_storage dst_addr; ++ memset(&dst_addr, 0, sizeof(struct sockaddr_storage)); ++ ++ msg.msg_name = &src_addr; ++ msg.msg_namelen = src_addr_len; ++ msg.msg_control = control_buffer; ++ msg.msg_controllen = sizeof(control_buffer); ++ ++ iov[0].iov_base = buf->array; ++ iov[0].iov_len = buf_size; ++ msg.msg_iov = iov; ++ msg.msg_iovlen = 1; ++ ++ buf->len = recvmsg(server_ctx->fd, &msg, 0); ++ if (buf->len == -1) { ++ ERROR("[udp] server_recvmsg"); ++ goto CLEAN_UP; ++ } else if (buf->len > packet_size) { ++ ERROR("[udp] UDP server_recv_recvmsg fragmentation"); ++ goto CLEAN_UP; ++ } ++ ++ if (get_dstaddr(&msg, &dst_addr)) { ++ LOGE("[udp] unable to get dest addr"); ++ goto CLEAN_UP; ++ } ++ ++ src_addr_len = msg.msg_namelen; ++#else ++ ssize_t r; ++ r = recvfrom(server_ctx->fd, buf->array, buf_size, ++ 0, (struct sockaddr *)&src_addr, &src_addr_len); ++ ++ if (r == -1) { ++ // error on recv ++ // simply drop that packet ++ ERROR("[udp] server_recv_recvfrom"); ++ goto CLEAN_UP; ++ } else if (r > packet_size) { ++ ERROR("[udp] server_recv_recvfrom fragmentation"); ++ goto CLEAN_UP; ++ } ++ ++ buf->len = r; ++#endif ++ ++#ifdef MODULE_REMOTE ++ tx += buf->len; ++ ++ int err = ss_decrypt_all(buf, server_ctx->method, server_ctx->auth, buf_size); ++ if (err) { ++ // drop the packet silently ++ goto CLEAN_UP; ++ } ++#endif ++ ++#ifdef MODULE_LOCAL ++#if !defined(MODULE_TUNNEL) && !defined(MODULE_REDIR) ++#ifdef ANDROID ++ tx += buf->len; ++#endif ++ uint8_t frag = *(uint8_t *)(buf->array + 2); ++ offset += 3; ++#endif ++#endif ++ ++ /* ++ * ++ * 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 | HMAC-SHA1 | ++ * +------+----------+----------+----------+-------------+ ++ * | 1 | Variable | 2 | Variable | 10 | ++ * +------+----------+----------+----------+-------------+ ++ * ++ * If ATYP & ONETIMEAUTH_FLAG(0x10) != 0, Authentication (HMAC-SHA1) is enabled. ++ * ++ * The key of HMAC-SHA1 is (IV + KEY) and the input is the whole packet. ++ * The output of HMAC-SHA is truncated to 10 bytes (leftmost bits). ++ * ++ * 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 | ++ * +-------+--------------+ ++ * ++ */ ++ ++#ifdef MODULE_REDIR ++ if (verbose) { ++ char src[SS_ADDRSTRLEN]; ++ char dst[SS_ADDRSTRLEN]; ++ strcpy(src, get_addr_str((struct sockaddr *)&src_addr)); ++ strcpy(dst, get_addr_str((struct sockaddr *)&dst_addr)); ++ LOGI("[udp] redir to %s from %s", dst, src); ++ } ++ ++ char addr_header[512] = { 0 }; ++ int addr_header_len = construct_udprealy_header(&dst_addr, addr_header); ++ ++ if (addr_header_len == 0) { ++ LOGE("[udp] failed to parse tproxy addr"); ++ goto CLEAN_UP; ++ } ++ ++ // reconstruct the buffer ++ brealloc(buf, buf->len + addr_header_len, buf_size); ++ memmove(buf->array + addr_header_len, buf->array, buf->len); ++ memcpy(buf->array, addr_header, addr_header_len); ++ buf->len += addr_header_len; ++ ++#elif MODULE_TUNNEL ++ ++ char addr_header[512] = { 0 }; ++ char *host = server_ctx->tunnel_addr.host; ++ char *port = server_ctx->tunnel_addr.port; ++ uint16_t port_num = (uint16_t)atoi(port); ++ uint16_t port_net_num = htons(port_num); ++ int addr_header_len = 0; ++ ++ struct cork_ip ip; ++ if (cork_ip_init(&ip, host) != -1) { ++ if (ip.version == 4) { ++ // send as IPv4 ++ struct in_addr host_addr; ++ memset(&host_addr, 0, sizeof(struct in_addr)); ++ int host_len = sizeof(struct in_addr); ++ ++ if (dns_pton(AF_INET, host, &host_addr) == -1) { ++ FATAL("IP parser error"); ++ } ++ addr_header[addr_header_len++] = 1; ++ memcpy(addr_header + addr_header_len, &host_addr, host_len); ++ addr_header_len += host_len; ++ } else if (ip.version == 6) { ++ // send as IPv6 ++ struct in6_addr host_addr; ++ memset(&host_addr, 0, sizeof(struct in6_addr)); ++ int host_len = sizeof(struct in6_addr); ++ ++ if (dns_pton(AF_INET6, host, &host_addr) == -1) { ++ FATAL("IP parser error"); ++ } ++ addr_header[addr_header_len++] = 4; ++ memcpy(addr_header + addr_header_len, &host_addr, host_len); ++ addr_header_len += host_len; ++ } else { ++ FATAL("IP parser error"); ++ } ++ } else { ++ // send as domain ++ int host_len = strlen(host); ++ ++ addr_header[addr_header_len++] = 3; ++ addr_header[addr_header_len++] = host_len; ++ memcpy(addr_header + addr_header_len, host, host_len); ++ addr_header_len += host_len; ++ } ++ memcpy(addr_header + addr_header_len, &port_net_num, 2); ++ addr_header_len += 2; ++ ++ // reconstruct the buffer ++ brealloc(buf, buf->len + addr_header_len, buf_size); ++ memmove(buf->array + addr_header_len, buf->array, buf->len); ++ memcpy(buf->array, addr_header, addr_header_len); ++ buf->len += addr_header_len; ++ ++#else ++ ++ char host[257] = { 0 }; ++ char port[64] = { 0 }; ++ struct sockaddr_storage dst_addr; ++ memset(&dst_addr, 0, sizeof(struct sockaddr_storage)); ++ ++ int addr_header_len = parse_udprealy_header(buf->array + offset, buf->len - offset, ++ host, port, &dst_addr); ++ if (addr_header_len == 0) { ++ // error in parse header ++ goto CLEAN_UP; ++ } ++ ++ char *addr_header = buf->array + offset; ++#endif ++ ++#ifdef MODULE_LOCAL ++ char *key = hash_key(server_ctx->remote_addr->sa_family, &src_addr); ++#else ++ char *key = hash_key(dst_addr.ss_family, &src_addr); ++#endif ++ ++ struct cache *conn_cache = server_ctx->conn_cache; ++ ++ remote_ctx_t *remote_ctx = NULL; ++ cache_lookup(conn_cache, key, HASH_KEY_LEN, (void *)&remote_ctx); ++ ++ if (remote_ctx != NULL) { ++ if (sockaddr_cmp(&src_addr, &remote_ctx->src_addr, sizeof(src_addr))) { ++ remote_ctx = NULL; ++ } ++ } ++ ++ // reset the timer ++ if (remote_ctx != NULL) { ++ ev_timer_again(EV_A_ & remote_ctx->watcher); ++ } ++ ++ if (remote_ctx == NULL) { ++ if (verbose) { ++#ifdef MODULE_REDIR ++ char src[SS_ADDRSTRLEN]; ++ char dst[SS_ADDRSTRLEN]; ++ strcpy(src, get_addr_str((struct sockaddr *)&src_addr)); ++ strcpy(dst, get_addr_str((struct sockaddr *)&dst_addr)); ++ LOGI("[udp] cache miss: %s <-> %s", dst, src); ++#else ++ LOGI("[udp] cache miss: %s:%s <-> %s", host, port, ++ get_addr_str((struct sockaddr *)&src_addr)); ++#endif ++ } ++ } else { ++ if (verbose) { ++#ifdef MODULE_REDIR ++ char src[SS_ADDRSTRLEN]; ++ char dst[SS_ADDRSTRLEN]; ++ strcpy(src, get_addr_str((struct sockaddr *)&src_addr)); ++ strcpy(dst, get_addr_str((struct sockaddr *)&dst_addr)); ++ LOGI("[udp] cache hit: %s <-> %s", dst, src); ++#else ++ LOGI("[udp] cache hit: %s:%s <-> %s", host, port, ++ get_addr_str((struct sockaddr *)&src_addr)); ++#endif ++ } ++ } ++ ++#ifdef MODULE_LOCAL ++ ++#if !defined(MODULE_TUNNEL) && !defined(MODULE_REDIR) ++ if (frag) { ++ LOGE("[udp] drop a message since frag is not 0, but %d", frag); ++ goto CLEAN_UP; ++ } ++#endif ++ ++ const struct sockaddr *remote_addr = server_ctx->remote_addr; ++ const int remote_addr_len = server_ctx->remote_addr_len; ++ ++ if (remote_ctx == NULL) { ++ // Bind to any port ++ int remotefd = create_remote_socket(remote_addr->sa_family == AF_INET6); ++ if (remotefd < 0) { ++ ERROR("[udp] udprelay bind() error"); ++ goto CLEAN_UP; ++ } ++ setnonblocking(remotefd); ++ ++#ifdef SO_NOSIGPIPE ++ set_nosigpipe(remotefd); ++#endif ++#ifdef IP_TOS ++ // Set QoS flag ++ int tos = 46; ++ setsockopt(remotefd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); ++#endif ++#ifdef SET_INTERFACE ++ if (server_ctx->iface) { ++ if (setinterface(remotefd, server_ctx->iface) == -1) ++ ERROR("setinterface"); ++ } ++#endif ++ ++#ifdef ANDROID ++ if (vpn) { ++ if (protect_socket(remotefd) == -1) { ++ ERROR("protect_socket"); ++ close(remotefd); ++ goto CLEAN_UP; ++ } ++ } ++#endif ++ ++ // Init remote_ctx ++ remote_ctx = new_remote(remotefd, server_ctx); ++ remote_ctx->src_addr = src_addr; ++ remote_ctx->af = remote_addr->sa_family; ++ remote_ctx->addr_header_len = addr_header_len; ++ memcpy(remote_ctx->addr_header, addr_header, addr_header_len); ++ ++ // Add to conn cache ++ cache_insert(conn_cache, key, HASH_KEY_LEN, (void *)remote_ctx); ++ ++ // Start remote io ++ ev_io_start(EV_A_ & remote_ctx->io); ++ ev_timer_start(EV_A_ & remote_ctx->watcher); ++ } ++ ++ if (offset > 0) { ++ buf->len -= offset; ++ memmove(buf->array, buf->array + offset, buf->len); ++ } ++ ++ if (server_ctx->auth) { ++ buf->array[0] |= ONETIMEAUTH_FLAG; ++ } ++ ++ // SSR beg ++ if (server_ctx->protocol_plugin) { ++ obfs_class *protocol_plugin = server_ctx->protocol_plugin; ++ if (protocol_plugin->client_udp_pre_encrypt) { ++ buf->len = protocol_plugin->client_udp_pre_encrypt(server_ctx->protocol, &buf->array, buf->len, &buf->capacity); ++ } ++ } ++ //SSR end ++ ++ int err = ss_encrypt_all(buf, server_ctx->method, server_ctx->auth, buf->len); ++ ++ if (err) { ++ // drop the packet silently ++ goto CLEAN_UP; ++ } ++ ++ if (buf->len > packet_size) { ++ LOGE("[udp] server_recv_sendto fragmentation"); ++ goto CLEAN_UP; ++ } ++ ++ int s = sendto(remote_ctx->fd, buf->array, buf->len, 0, remote_addr, remote_addr_len); ++ ++ if (s == -1) { ++ ERROR("[udp] server_recv_sendto"); ++ } ++ ++#else ++ ++ int cache_hit = 0; ++ int need_query = 0; ++ ++ if (buf->len - addr_header_len > packet_size) { ++ LOGE("[udp] server_recv_sendto fragmentation"); ++ goto CLEAN_UP; ++ } ++ ++ if (remote_ctx != NULL) { ++ cache_hit = 1; ++ // detect destination mismatch ++ if (remote_ctx->addr_header_len != addr_header_len ++ || memcmp(addr_header, remote_ctx->addr_header, addr_header_len) != 0) { ++ if (dst_addr.ss_family != AF_INET && dst_addr.ss_family != AF_INET6) { ++ need_query = 1; ++ } ++ } else { ++ memcpy(&dst_addr, &remote_ctx->dst_addr, sizeof(struct sockaddr_storage)); ++ } ++ } else { ++ if (dst_addr.ss_family == AF_INET || dst_addr.ss_family == AF_INET6) { ++ int remotefd = create_remote_socket(dst_addr.ss_family == AF_INET6); ++ if (remotefd != -1) { ++ setnonblocking(remotefd); ++#ifdef SO_BROADCAST ++ set_broadcast(remotefd); ++#endif ++#ifdef SO_NOSIGPIPE ++ set_nosigpipe(remotefd); ++#endif ++#ifdef IP_TOS ++ // Set QoS flag ++ int tos = 46; ++ setsockopt(remotefd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); ++#endif ++#ifdef SET_INTERFACE ++ if (server_ctx->iface) { ++ if (setinterface(remotefd, server_ctx->iface) == -1) ++ ERROR("setinterface"); ++ } ++#endif ++ remote_ctx = new_remote(remotefd, server_ctx); ++ remote_ctx->src_addr = src_addr; ++ remote_ctx->server_ctx = server_ctx; ++ remote_ctx->addr_header_len = addr_header_len; ++ memcpy(remote_ctx->addr_header, addr_header, addr_header_len); ++ memcpy(&remote_ctx->dst_addr, &dst_addr, sizeof(struct sockaddr_storage)); ++ } else { ++ ERROR("[udp] bind() error"); ++ goto CLEAN_UP; ++ } ++ } ++ } ++ ++ if (remote_ctx != NULL && !need_query) { ++ size_t addr_len = get_sockaddr_len((struct sockaddr *)&dst_addr); ++ int s = sendto(remote_ctx->fd, buf->array + addr_header_len, ++ buf->len - addr_header_len, 0, ++ (struct sockaddr *)&dst_addr, addr_len); ++ ++ if (s == -1) { ++ ERROR("[udp] sendto_remote"); ++ if (!cache_hit) { ++ close_and_free_remote(EV_A_ remote_ctx); ++ } ++ } else { ++ if (!cache_hit) { ++ // Add to conn cache ++ remote_ctx->af = dst_addr.ss_family; ++ char *key = hash_key(remote_ctx->af, &remote_ctx->src_addr); ++ cache_insert(server_ctx->conn_cache, key, HASH_KEY_LEN, (void *)remote_ctx); ++ ++ ev_io_start(EV_A_ & remote_ctx->io); ++ ev_timer_start(EV_A_ & remote_ctx->watcher); ++ } ++ } ++ } else { ++ struct addrinfo hints; ++ memset(&hints, 0, sizeof(struct addrinfo)); ++ hints.ai_family = AF_UNSPEC; ++ hints.ai_socktype = SOCK_DGRAM; ++ hints.ai_protocol = IPPROTO_UDP; ++ ++ struct query_ctx *query_ctx = new_query_ctx(buf->array + addr_header_len, ++ buf->len - addr_header_len); ++ query_ctx->server_ctx = server_ctx; ++ query_ctx->addr_header_len = addr_header_len; ++ query_ctx->src_addr = src_addr; ++ memcpy(query_ctx->addr_header, addr_header, addr_header_len); ++ ++ if (need_query) { ++ query_ctx->remote_ctx = remote_ctx; ++ } ++ ++ struct ResolvQuery *query = resolv_query(host, query_resolve_cb, ++ NULL, query_ctx, htons(atoi(port))); ++ if (query == NULL) { ++ ERROR("[udp] unable to create DNS query"); ++ close_and_free_query(EV_A_ query_ctx); ++ goto CLEAN_UP; ++ } ++ query_ctx->query = query; ++ } ++#endif ++ ++CLEAN_UP: ++ bfree(buf); ++ ss_free(buf); ++} ++ ++void ++free_cb(void *key, void *element) ++{ ++ remote_ctx_t *remote_ctx = (remote_ctx_t *)element; ++ ++ if (verbose) { ++ LOGI("[udp] one connection freed"); ++ } ++ ++ close_and_free_remote(EV_DEFAULT, remote_ctx); ++} ++ ++int ++init_udprelay(const char *server_host, const char *server_port, ++#ifdef MODULE_LOCAL ++ const struct sockaddr *remote_addr, const int remote_addr_len, ++#ifdef MODULE_TUNNEL ++ const ss_addr_t tunnel_addr, ++#endif ++#endif ++ int mtu, int method, int auth, int timeout, const char *iface, const char *protocol, const char *protocol_param) ++{ ++ // Initialize ev loop ++ struct ev_loop *loop = EV_DEFAULT; ++ ++ // Initialize MTU ++ if (mtu > 0) { ++ packet_size = mtu - 1 - 28 - 2 - 64; ++ buf_size = packet_size * 2; ++ } ++ ++ // Initialize cache ++ struct cache *conn_cache; ++ cache_create(&conn_cache, MAX_UDP_CONN_NUM, free_cb); ++ ++ // //////////////////////////////////////////////// ++ // Setup server context ++ ++ // Bind to port ++ int serverfd = create_server_socket(server_host, server_port); ++ if (serverfd < 0) { ++ FATAL("[udp] bind() error"); ++ } ++ setnonblocking(serverfd); ++ if (protocol != NULL && strcmp(protocol, "verify_sha1") == 0) { ++ auth = 1; ++ protocol = NULL; ++ } ++ ++ server_ctx_t *server_ctx = new_server_ctx(serverfd); ++#ifdef MODULE_REMOTE ++ server_ctx->loop = loop; ++#endif ++ server_ctx->auth = auth; ++ server_ctx->timeout = max(timeout, MIN_UDP_TIMEOUT); ++ server_ctx->method = method; ++ server_ctx->iface = iface; ++ server_ctx->conn_cache = conn_cache; ++#ifdef MODULE_LOCAL ++ server_ctx->remote_addr = remote_addr; ++ server_ctx->remote_addr_len = remote_addr_len; ++ //SSR beg ++ server_ctx->protocol_plugin = new_obfs_class((char *)protocol); ++ if (server_ctx->protocol_plugin) { ++ server_ctx->protocol = server_ctx->protocol_plugin->new_obfs(); ++ server_ctx->protocol_global = server_ctx->protocol_plugin->init_data(); ++ } ++ ++ server_info _server_info; ++ memset(&_server_info, 0, sizeof(server_info)); ++ strcpy(_server_info.host, inet_ntoa(((struct sockaddr_in*)remote_addr)->sin_addr)); ++ _server_info.port = ((struct sockaddr_in*)remote_addr)->sin_port; ++ _server_info.port = _server_info.port >> 8 | _server_info.port << 8; ++ _server_info.g_data = server_ctx->protocol_global; ++ _server_info.param = (char *)protocol_param; ++ _server_info.key = enc_get_key(); ++ _server_info.key_len = enc_get_key_len(); ++ ++ if (server_ctx->protocol_plugin) ++ server_ctx->protocol_plugin->set_server_info(server_ctx->protocol, &_server_info); ++ //SSR end ++#ifdef MODULE_TUNNEL ++ server_ctx->tunnel_addr = tunnel_addr; ++#endif ++#endif ++ ++ ev_io_start(loop, &server_ctx->io); ++ ++ server_ctx_list[server_num++] = server_ctx; ++ ++ return 0; ++} ++ ++void ++free_udprelay() ++{ ++ struct ev_loop *loop = EV_DEFAULT; ++ while (server_num-- > 0) { ++ server_ctx_t *server_ctx = server_ctx_list[server_num]; ++ ++#ifdef MODULE_LOCAL ++ //SSR beg ++ if (server_ctx->protocol_plugin) { ++ server_ctx->protocol_plugin->dispose(server_ctx->protocol); ++ server_ctx->protocol = NULL; ++ free_obfs_class(server_ctx->protocol_plugin); ++ server_ctx->protocol_plugin = NULL; ++ } ++ //SSR end ++#endif ++ ++ ev_io_stop(loop, &server_ctx->io); ++ close(server_ctx->fd); ++ cache_delete(server_ctx->conn_cache, 0); ++ ss_free(server_ctx); ++ server_ctx_list[server_num] = NULL; ++ } ++} +diff --git a/server/udprelay.h b/server/udprelay.h +new file mode 100644 +index 0000000..89876d4 +--- /dev/null ++++ b/server/udprelay.h +@@ -0,0 +1,95 @@ ++/* ++ * udprelay.h - Define UDP relay's buffers and callbacks ++ * ++ * Copyright (C) 2013 - 2016, Max Lv ++ * ++ * This file is part of the shadowsocks-libev. ++ * ++ * shadowsocks-libev 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 3 of the License, or ++ * (at your option) any later version. ++ * ++ * shadowsocks-libev 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 shadowsocks-libev; see the file COPYING. If not, see ++ * . ++ */ ++ ++#ifndef _UDPRELAY_H ++#define _UDPRELAY_H ++ ++#include ++#include ++ ++#include "encrypt.h" ++#include "jconf.h" ++#include "obfs.h" ++ ++#ifdef MODULE_REMOTE ++#include "resolv.h" ++#endif ++ ++#include "cache.h" ++ ++#include "common.h" ++ ++#define MAX_UDP_PACKET_SIZE (65507) ++ ++#define DEFAULT_PACKET_SIZE 1397 // 1492 - 1 - 28 - 2 - 64 = 1397, the default MTU for UDP relay ++ ++typedef struct server_ctx { ++ ev_io io; ++ int fd; ++ int method; ++ int auth; ++ int timeout; ++ const char *iface; ++ struct cache *conn_cache; ++#ifdef MODULE_LOCAL ++ const struct sockaddr *remote_addr; ++ int remote_addr_len; ++#ifdef MODULE_TUNNEL ++ ss_addr_t tunnel_addr; ++#endif ++#endif ++#ifdef MODULE_REMOTE ++ struct ev_loop *loop; ++#endif ++ // SSR ++ obfs *protocol; ++ obfs_class *protocol_plugin; ++ void *protocol_global; ++} server_ctx_t; ++ ++#ifdef MODULE_REMOTE ++typedef struct query_ctx { ++ struct ResolvQuery *query; ++ struct sockaddr_storage src_addr; ++ buffer_t *buf; ++ int addr_header_len; ++ char addr_header[384]; ++ struct server_ctx *server_ctx; ++ struct remote_ctx *remote_ctx; ++} query_ctx_t; ++#endif ++ ++typedef struct remote_ctx { ++ ev_io io; ++ ev_timer watcher; ++ int af; ++ int fd; ++ int addr_header_len; ++ char addr_header[384]; ++ struct sockaddr_storage src_addr; ++#ifdef MODULE_REMOTE ++ struct sockaddr_storage dst_addr; ++#endif ++ struct server_ctx *server_ctx; ++} remote_ctx_t; ++ ++#endif // _UDPRELAY_H +diff --git a/server/uthash.h b/server/uthash.h +new file mode 100644 +index 0000000..45d1f9f +--- /dev/null ++++ b/server/uthash.h +@@ -0,0 +1,1074 @@ ++/* ++Copyright (c) 2003-2016, Troy D. Hanson http://troydhanson.github.com/uthash/ ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions are met: ++ ++ * Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ ++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ++IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ++TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A ++PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER ++OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ++EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ++PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ++PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++*/ ++ ++#ifndef UTHASH_H ++#define UTHASH_H ++ ++#define UTHASH_VERSION 2.0.1 ++ ++#include /* memcmp,strlen */ ++#include /* ptrdiff_t */ ++#include /* exit() */ ++ ++/* These macros use decltype or the earlier __typeof GNU extension. ++ As decltype is only available in newer compilers (VS2010 or gcc 4.3+ ++ when compiling c++ source) this code uses whatever method is needed ++ or, for VS2008 where neither is available, uses casting workarounds. */ ++#if defined(_MSC_VER) /* MS compiler */ ++#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ ++#define DECLTYPE(x) (decltype(x)) ++#else /* VS2008 or older (or VS2010 in C mode) */ ++#define NO_DECLTYPE ++#define DECLTYPE(x) ++#endif ++#elif defined(__BORLANDC__) || defined(__LCC__) || defined(__WATCOMC__) ++#define NO_DECLTYPE ++#define DECLTYPE(x) ++#else /* GNU, Sun and other compilers */ ++#define DECLTYPE(x) (__typeof(x)) ++#endif ++ ++#ifdef NO_DECLTYPE ++#define DECLTYPE_ASSIGN(dst,src) \ ++do { \ ++ char **_da_dst = (char**)(&(dst)); \ ++ *_da_dst = (char*)(src); \ ++} while (0) ++#else ++#define DECLTYPE_ASSIGN(dst,src) \ ++do { \ ++ (dst) = DECLTYPE(dst)(src); \ ++} while (0) ++#endif ++ ++/* a number of the hash function use uint32_t which isn't defined on Pre VS2010 */ ++#if defined(_WIN32) ++#if defined(_MSC_VER) && _MSC_VER >= 1600 ++#include ++#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) ++#include ++#else ++typedef unsigned int uint32_t; ++typedef unsigned char uint8_t; ++#endif ++#elif defined(__GNUC__) && !defined(__VXWORKS__) ++#include ++#else ++typedef unsigned int uint32_t; ++typedef unsigned char uint8_t; ++#endif ++ ++#ifndef uthash_fatal ++#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ ++#endif ++#ifndef uthash_malloc ++#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ ++#endif ++#ifndef uthash_free ++#define uthash_free(ptr,sz) free(ptr) /* free fcn */ ++#endif ++#ifndef uthash_strlen ++#define uthash_strlen(s) strlen(s) ++#endif ++#ifndef uthash_memcmp ++#define uthash_memcmp(a,b,n) memcmp(a,b,n) ++#endif ++ ++#ifndef uthash_noexpand_fyi ++#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ ++#endif ++#ifndef uthash_expand_fyi ++#define uthash_expand_fyi(tbl) /* can be defined to log expands */ ++#endif ++ ++/* initial number of buckets */ ++#define HASH_INITIAL_NUM_BUCKETS 32U /* initial number of buckets */ ++#define HASH_INITIAL_NUM_BUCKETS_LOG2 5U /* lg2 of initial number of buckets */ ++#define HASH_BKT_CAPACITY_THRESH 10U /* expand when bucket count reaches */ ++ ++/* calculate the element whose hash handle address is hhp */ ++#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) ++/* calculate the hash handle from element address elp */ ++#define HH_FROM_ELMT(tbl,elp) ((UT_hash_handle *)(((char*)(elp)) + ((tbl)->hho))) ++ ++#define HASH_VALUE(keyptr,keylen,hashv) \ ++do { \ ++ HASH_FCN(keyptr, keylen, hashv); \ ++} while (0) ++ ++#define HASH_FIND_BYHASHVALUE(hh,head,keyptr,keylen,hashval,out) \ ++do { \ ++ (out) = NULL; \ ++ if (head) { \ ++ unsigned _hf_bkt; \ ++ HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _hf_bkt); \ ++ if (HASH_BLOOM_TEST((head)->hh.tbl, hashval) != 0) { \ ++ HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], keyptr, keylen, hashval, out); \ ++ } \ ++ } \ ++} while (0) ++ ++#define HASH_FIND(hh,head,keyptr,keylen,out) \ ++do { \ ++ unsigned _hf_hashv; \ ++ HASH_VALUE(keyptr, keylen, _hf_hashv); \ ++ HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out); \ ++} while (0) ++ ++#ifdef HASH_BLOOM ++#define HASH_BLOOM_BITLEN (1UL << HASH_BLOOM) ++#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8UL) + (((HASH_BLOOM_BITLEN%8UL)!=0UL) ? 1UL : 0UL) ++#define HASH_BLOOM_MAKE(tbl) \ ++do { \ ++ (tbl)->bloom_nbits = HASH_BLOOM; \ ++ (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ ++ if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \ ++ memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \ ++ (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ ++} while (0) ++ ++#define HASH_BLOOM_FREE(tbl) \ ++do { \ ++ uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ ++} while (0) ++ ++#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8U] |= (1U << ((idx)%8U))) ++#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8U] & (1U << ((idx)%8U))) ++ ++#define HASH_BLOOM_ADD(tbl,hashv) \ ++ HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1U))) ++ ++#define HASH_BLOOM_TEST(tbl,hashv) \ ++ HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1U))) ++ ++#else ++#define HASH_BLOOM_MAKE(tbl) ++#define HASH_BLOOM_FREE(tbl) ++#define HASH_BLOOM_ADD(tbl,hashv) ++#define HASH_BLOOM_TEST(tbl,hashv) (1) ++#define HASH_BLOOM_BYTELEN 0U ++#endif ++ ++#define HASH_MAKE_TABLE(hh,head) \ ++do { \ ++ (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \ ++ sizeof(UT_hash_table)); \ ++ if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \ ++ memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \ ++ (head)->hh.tbl->tail = &((head)->hh); \ ++ (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ ++ (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ ++ (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ ++ (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ ++ HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ ++ if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \ ++ memset((head)->hh.tbl->buckets, 0, \ ++ HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ ++ HASH_BLOOM_MAKE((head)->hh.tbl); \ ++ (head)->hh.tbl->signature = HASH_SIGNATURE; \ ++} while (0) ++ ++#define HASH_REPLACE_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,replaced,cmpfcn) \ ++do { \ ++ (replaced) = NULL; \ ++ HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ ++ if (replaced) { \ ++ HASH_DELETE(hh, head, replaced); \ ++ } \ ++ HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn); \ ++} while (0) ++ ++#define HASH_REPLACE_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add,replaced) \ ++do { \ ++ (replaced) = NULL; \ ++ HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ ++ if (replaced) { \ ++ HASH_DELETE(hh, head, replaced); \ ++ } \ ++ HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add); \ ++} while (0) ++ ++#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \ ++do { \ ++ unsigned _hr_hashv; \ ++ HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ ++ HASH_REPLACE_BYHASHVALUE(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced); \ ++} while (0) ++ ++#define HASH_REPLACE_INORDER(hh,head,fieldname,keylen_in,add,replaced,cmpfcn) \ ++do { \ ++ unsigned _hr_hashv; \ ++ HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ ++ HASH_REPLACE_BYHASHVALUE_INORDER(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced, cmpfcn); \ ++} while (0) ++ ++#define HASH_APPEND_LIST(hh, head, add) \ ++do { \ ++ (add)->hh.next = NULL; \ ++ (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ ++ (head)->hh.tbl->tail->next = (add); \ ++ (head)->hh.tbl->tail = &((add)->hh); \ ++} while (0) ++ ++#define HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh,head,keyptr,keylen_in,hashval,add,cmpfcn) \ ++do { \ ++ unsigned _ha_bkt; \ ++ (add)->hh.hashv = (hashval); \ ++ (add)->hh.key = (char*) (keyptr); \ ++ (add)->hh.keylen = (unsigned) (keylen_in); \ ++ if (!(head)) { \ ++ (add)->hh.next = NULL; \ ++ (add)->hh.prev = NULL; \ ++ (head) = (add); \ ++ HASH_MAKE_TABLE(hh, head); \ ++ } else { \ ++ struct UT_hash_handle *_hs_iter = &(head)->hh; \ ++ (add)->hh.tbl = (head)->hh.tbl; \ ++ do { \ ++ if (cmpfcn(DECLTYPE(head) ELMT_FROM_HH((head)->hh.tbl, _hs_iter), add) > 0) \ ++ break; \ ++ } while ((_hs_iter = _hs_iter->next)); \ ++ if (_hs_iter) { \ ++ (add)->hh.next = _hs_iter; \ ++ if (((add)->hh.prev = _hs_iter->prev)) { \ ++ HH_FROM_ELMT((head)->hh.tbl, _hs_iter->prev)->next = (add); \ ++ } else { \ ++ (head) = (add); \ ++ } \ ++ _hs_iter->prev = (add); \ ++ } else { \ ++ HASH_APPEND_LIST(hh, head, add); \ ++ } \ ++ } \ ++ (head)->hh.tbl->num_items++; \ ++ HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ ++ HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], &(add)->hh); \ ++ HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ ++ HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ ++ HASH_FSCK(hh, head); \ ++} while (0) ++ ++#define HASH_ADD_KEYPTR_INORDER(hh,head,keyptr,keylen_in,add,cmpfcn) \ ++do { \ ++ unsigned _hs_hashv; \ ++ HASH_VALUE(keyptr, keylen_in, _hs_hashv); \ ++ HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, keyptr, keylen_in, _hs_hashv, add, cmpfcn); \ ++} while (0) ++ ++#define HASH_ADD_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,cmpfcn) \ ++ HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn) ++ ++#define HASH_ADD_INORDER(hh,head,fieldname,keylen_in,add,cmpfcn) \ ++ HASH_ADD_KEYPTR_INORDER(hh, head, &((add)->fieldname), keylen_in, add, cmpfcn) ++ ++#define HASH_ADD_KEYPTR_BYHASHVALUE(hh,head,keyptr,keylen_in,hashval,add) \ ++do { \ ++ unsigned _ha_bkt; \ ++ (add)->hh.hashv = (hashval); \ ++ (add)->hh.key = (char*) (keyptr); \ ++ (add)->hh.keylen = (unsigned) (keylen_in); \ ++ if (!(head)) { \ ++ (add)->hh.next = NULL; \ ++ (add)->hh.prev = NULL; \ ++ (head) = (add); \ ++ HASH_MAKE_TABLE(hh, head); \ ++ } else { \ ++ (add)->hh.tbl = (head)->hh.tbl; \ ++ HASH_APPEND_LIST(hh, head, add); \ ++ } \ ++ (head)->hh.tbl->num_items++; \ ++ HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ ++ HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], &(add)->hh); \ ++ HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ ++ HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ ++ HASH_FSCK(hh, head); \ ++} while (0) ++ ++#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ ++do { \ ++ unsigned _ha_hashv; \ ++ HASH_VALUE(keyptr, keylen_in, _ha_hashv); \ ++ HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, keyptr, keylen_in, _ha_hashv, add); \ ++} while (0) ++ ++#define HASH_ADD_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add) \ ++ HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add) ++ ++#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ ++ HASH_ADD_KEYPTR(hh, head, &((add)->fieldname), keylen_in, add) ++ ++#define HASH_TO_BKT(hashv,num_bkts,bkt) \ ++do { \ ++ bkt = ((hashv) & ((num_bkts) - 1U)); \ ++} while (0) ++ ++/* delete "delptr" from the hash table. ++ * "the usual" patch-up process for the app-order doubly-linked-list. ++ * The use of _hd_hh_del below deserves special explanation. ++ * These used to be expressed using (delptr) but that led to a bug ++ * if someone used the same symbol for the head and deletee, like ++ * HASH_DELETE(hh,users,users); ++ * We want that to work, but by changing the head (users) below ++ * we were forfeiting our ability to further refer to the deletee (users) ++ * in the patch-up process. Solution: use scratch space to ++ * copy the deletee pointer, then the latter references are via that ++ * scratch pointer rather than through the repointed (users) symbol. ++ */ ++#define HASH_DELETE(hh,head,delptr) \ ++do { \ ++ struct UT_hash_handle *_hd_hh_del; \ ++ if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \ ++ uthash_free((head)->hh.tbl->buckets, \ ++ (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ ++ HASH_BLOOM_FREE((head)->hh.tbl); \ ++ uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ ++ head = NULL; \ ++ } else { \ ++ unsigned _hd_bkt; \ ++ _hd_hh_del = &((delptr)->hh); \ ++ if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \ ++ (head)->hh.tbl->tail = \ ++ (UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ ++ (head)->hh.tbl->hho); \ ++ } \ ++ if ((delptr)->hh.prev != NULL) { \ ++ ((UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ ++ (head)->hh.tbl->hho))->next = (delptr)->hh.next; \ ++ } else { \ ++ DECLTYPE_ASSIGN(head,(delptr)->hh.next); \ ++ } \ ++ if (_hd_hh_del->next != NULL) { \ ++ ((UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next + \ ++ (head)->hh.tbl->hho))->prev = \ ++ _hd_hh_del->prev; \ ++ } \ ++ HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ ++ HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ ++ (head)->hh.tbl->num_items--; \ ++ } \ ++ HASH_FSCK(hh,head); \ ++} while (0) ++ ++ ++/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ ++#define HASH_FIND_STR(head,findstr,out) \ ++ HASH_FIND(hh,head,findstr,(unsigned)uthash_strlen(findstr),out) ++#define HASH_ADD_STR(head,strfield,add) \ ++ HASH_ADD(hh,head,strfield[0],(unsigned)uthash_strlen(add->strfield),add) ++#define HASH_REPLACE_STR(head,strfield,add,replaced) \ ++ HASH_REPLACE(hh,head,strfield[0],(unsigned)uthash_strlen(add->strfield),add,replaced) ++#define HASH_FIND_INT(head,findint,out) \ ++ HASH_FIND(hh,head,findint,sizeof(int),out) ++#define HASH_ADD_INT(head,intfield,add) \ ++ HASH_ADD(hh,head,intfield,sizeof(int),add) ++#define HASH_REPLACE_INT(head,intfield,add,replaced) \ ++ HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced) ++#define HASH_FIND_PTR(head,findptr,out) \ ++ HASH_FIND(hh,head,findptr,sizeof(void *),out) ++#define HASH_ADD_PTR(head,ptrfield,add) \ ++ HASH_ADD(hh,head,ptrfield,sizeof(void *),add) ++#define HASH_REPLACE_PTR(head,ptrfield,add,replaced) \ ++ HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) ++#define HASH_DEL(head,delptr) \ ++ HASH_DELETE(hh,head,delptr) ++ ++/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. ++ * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. ++ */ ++#ifdef HASH_DEBUG ++#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) ++#define HASH_FSCK(hh,head) \ ++do { \ ++ struct UT_hash_handle *_thh; \ ++ if (head) { \ ++ unsigned _bkt_i; \ ++ unsigned _count; \ ++ char *_prev; \ ++ _count = 0; \ ++ for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \ ++ unsigned _bkt_count = 0; \ ++ _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ ++ _prev = NULL; \ ++ while (_thh) { \ ++ if (_prev != (char*)(_thh->hh_prev)) { \ ++ HASH_OOPS("invalid hh_prev %p, actual %p\n", \ ++ _thh->hh_prev, _prev ); \ ++ } \ ++ _bkt_count++; \ ++ _prev = (char*)(_thh); \ ++ _thh = _thh->hh_next; \ ++ } \ ++ _count += _bkt_count; \ ++ if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ ++ HASH_OOPS("invalid bucket count %u, actual %u\n", \ ++ (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ ++ } \ ++ } \ ++ if (_count != (head)->hh.tbl->num_items) { \ ++ HASH_OOPS("invalid hh item count %u, actual %u\n", \ ++ (head)->hh.tbl->num_items, _count ); \ ++ } \ ++ /* traverse hh in app order; check next/prev integrity, count */ \ ++ _count = 0; \ ++ _prev = NULL; \ ++ _thh = &(head)->hh; \ ++ while (_thh) { \ ++ _count++; \ ++ if (_prev !=(char*)(_thh->prev)) { \ ++ HASH_OOPS("invalid prev %p, actual %p\n", \ ++ _thh->prev, _prev ); \ ++ } \ ++ _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ ++ _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \ ++ (head)->hh.tbl->hho) : NULL ); \ ++ } \ ++ if (_count != (head)->hh.tbl->num_items) { \ ++ HASH_OOPS("invalid app item count %u, actual %u\n", \ ++ (head)->hh.tbl->num_items, _count ); \ ++ } \ ++ } \ ++} while (0) ++#else ++#define HASH_FSCK(hh,head) ++#endif ++ ++/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to ++ * the descriptor to which this macro is defined for tuning the hash function. ++ * The app can #include to get the prototype for write(2). */ ++#ifdef HASH_EMIT_KEYS ++#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ ++do { \ ++ unsigned _klen = fieldlen; \ ++ write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ ++ write(HASH_EMIT_KEYS, keyptr, (unsigned long)fieldlen); \ ++} while (0) ++#else ++#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) ++#endif ++ ++/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ ++#ifdef HASH_FUNCTION ++#define HASH_FCN HASH_FUNCTION ++#else ++#define HASH_FCN HASH_JEN ++#endif ++ ++/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */ ++#define HASH_BER(key,keylen,hashv) \ ++do { \ ++ unsigned _hb_keylen=(unsigned)keylen; \ ++ const unsigned char *_hb_key=(const unsigned char*)(key); \ ++ (hashv) = 0; \ ++ while (_hb_keylen-- != 0U) { \ ++ (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; \ ++ } \ ++} while (0) ++ ++ ++/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at ++ * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ ++#define HASH_SAX(key,keylen,hashv) \ ++do { \ ++ unsigned _sx_i; \ ++ const unsigned char *_hs_key=(const unsigned char*)(key); \ ++ hashv = 0; \ ++ for(_sx_i=0; _sx_i < keylen; _sx_i++) { \ ++ hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ ++ } \ ++} while (0) ++/* FNV-1a variation */ ++#define HASH_FNV(key,keylen,hashv) \ ++do { \ ++ unsigned _fn_i; \ ++ const unsigned char *_hf_key=(const unsigned char*)(key); \ ++ hashv = 2166136261U; \ ++ for(_fn_i=0; _fn_i < keylen; _fn_i++) { \ ++ hashv = hashv ^ _hf_key[_fn_i]; \ ++ hashv = hashv * 16777619U; \ ++ } \ ++} while (0) ++ ++#define HASH_OAT(key,keylen,hashv) \ ++do { \ ++ unsigned _ho_i; \ ++ const unsigned char *_ho_key=(const unsigned char*)(key); \ ++ hashv = 0; \ ++ for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ ++ hashv += _ho_key[_ho_i]; \ ++ hashv += (hashv << 10); \ ++ hashv ^= (hashv >> 6); \ ++ } \ ++ hashv += (hashv << 3); \ ++ hashv ^= (hashv >> 11); \ ++ hashv += (hashv << 15); \ ++} while (0) ++ ++#define HASH_JEN_MIX(a,b,c) \ ++do { \ ++ a -= b; a -= c; a ^= ( c >> 13 ); \ ++ b -= c; b -= a; b ^= ( a << 8 ); \ ++ c -= a; c -= b; c ^= ( b >> 13 ); \ ++ a -= b; a -= c; a ^= ( c >> 12 ); \ ++ b -= c; b -= a; b ^= ( a << 16 ); \ ++ c -= a; c -= b; c ^= ( b >> 5 ); \ ++ a -= b; a -= c; a ^= ( c >> 3 ); \ ++ b -= c; b -= a; b ^= ( a << 10 ); \ ++ c -= a; c -= b; c ^= ( b >> 15 ); \ ++} while (0) ++ ++#define HASH_JEN(key,keylen,hashv) \ ++do { \ ++ unsigned _hj_i,_hj_j,_hj_k; \ ++ unsigned const char *_hj_key=(unsigned const char*)(key); \ ++ hashv = 0xfeedbeefu; \ ++ _hj_i = _hj_j = 0x9e3779b9u; \ ++ _hj_k = (unsigned)(keylen); \ ++ while (_hj_k >= 12U) { \ ++ _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ ++ + ( (unsigned)_hj_key[2] << 16 ) \ ++ + ( (unsigned)_hj_key[3] << 24 ) ); \ ++ _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ ++ + ( (unsigned)_hj_key[6] << 16 ) \ ++ + ( (unsigned)_hj_key[7] << 24 ) ); \ ++ hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ ++ + ( (unsigned)_hj_key[10] << 16 ) \ ++ + ( (unsigned)_hj_key[11] << 24 ) ); \ ++ \ ++ HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ ++ \ ++ _hj_key += 12; \ ++ _hj_k -= 12U; \ ++ } \ ++ hashv += (unsigned)(keylen); \ ++ switch ( _hj_k ) { \ ++ case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); /* FALLTHROUGH */ \ ++ case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); /* FALLTHROUGH */ \ ++ case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); /* FALLTHROUGH */ \ ++ case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); /* FALLTHROUGH */ \ ++ case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); /* FALLTHROUGH */ \ ++ case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); /* FALLTHROUGH */ \ ++ case 5: _hj_j += _hj_key[4]; /* FALLTHROUGH */ \ ++ case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); /* FALLTHROUGH */ \ ++ case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); /* FALLTHROUGH */ \ ++ case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); /* FALLTHROUGH */ \ ++ case 1: _hj_i += _hj_key[0]; \ ++ } \ ++ HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ ++} while (0) ++ ++/* The Paul Hsieh hash function */ ++#undef get16bits ++#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ ++ || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) ++#define get16bits(d) (*((const uint16_t *) (d))) ++#endif ++ ++#if !defined (get16bits) ++#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ ++ +(uint32_t)(((const uint8_t *)(d))[0]) ) ++#endif ++#define HASH_SFH(key,keylen,hashv) \ ++do { \ ++ unsigned const char *_sfh_key=(unsigned const char*)(key); \ ++ uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen; \ ++ \ ++ unsigned _sfh_rem = _sfh_len & 3U; \ ++ _sfh_len >>= 2; \ ++ hashv = 0xcafebabeu; \ ++ \ ++ /* Main loop */ \ ++ for (;_sfh_len > 0U; _sfh_len--) { \ ++ hashv += get16bits (_sfh_key); \ ++ _sfh_tmp = ((uint32_t)(get16bits (_sfh_key+2)) << 11) ^ hashv; \ ++ hashv = (hashv << 16) ^ _sfh_tmp; \ ++ _sfh_key += 2U*sizeof (uint16_t); \ ++ hashv += hashv >> 11; \ ++ } \ ++ \ ++ /* Handle end cases */ \ ++ switch (_sfh_rem) { \ ++ case 3: hashv += get16bits (_sfh_key); \ ++ hashv ^= hashv << 16; \ ++ hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)]) << 18; \ ++ hashv += hashv >> 11; \ ++ break; \ ++ case 2: hashv += get16bits (_sfh_key); \ ++ hashv ^= hashv << 11; \ ++ hashv += hashv >> 17; \ ++ break; \ ++ case 1: hashv += *_sfh_key; \ ++ hashv ^= hashv << 10; \ ++ hashv += hashv >> 1; \ ++ } \ ++ \ ++ /* Force "avalanching" of final 127 bits */ \ ++ hashv ^= hashv << 3; \ ++ hashv += hashv >> 5; \ ++ hashv ^= hashv << 4; \ ++ hashv += hashv >> 17; \ ++ hashv ^= hashv << 25; \ ++ hashv += hashv >> 6; \ ++} while (0) ++ ++#ifdef HASH_USING_NO_STRICT_ALIASING ++/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. ++ * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. ++ * MurmurHash uses the faster approach only on CPU's where we know it's safe. ++ * ++ * Note the preprocessor built-in defines can be emitted using: ++ * ++ * gcc -m64 -dM -E - < /dev/null (on gcc) ++ * cc -## a.c (where a.c is a simple test file) (Sun Studio) ++ */ ++#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86)) ++#define MUR_GETBLOCK(p,i) p[i] ++#else /* non intel */ ++#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 3UL) == 0UL) ++#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 3UL) == 1UL) ++#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 3UL) == 2UL) ++#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 3UL) == 3UL) ++#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) ++#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) ++#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) ++#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) ++#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8)) ++#else /* assume little endian non-intel */ ++#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) ++#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) ++#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8)) ++#endif ++#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \ ++ (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ ++ (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \ ++ MUR_ONE_THREE(p)))) ++#endif ++#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) ++#define MUR_FMIX(_h) \ ++do { \ ++ _h ^= _h >> 16; \ ++ _h *= 0x85ebca6bu; \ ++ _h ^= _h >> 13; \ ++ _h *= 0xc2b2ae35u; \ ++ _h ^= _h >> 16; \ ++} while (0) ++ ++#define HASH_MUR(key,keylen,hashv) \ ++do { \ ++ const uint8_t *_mur_data = (const uint8_t*)(key); \ ++ const int _mur_nblocks = (int)(keylen) / 4; \ ++ uint32_t _mur_h1 = 0xf88D5353u; \ ++ uint32_t _mur_c1 = 0xcc9e2d51u; \ ++ uint32_t _mur_c2 = 0x1b873593u; \ ++ uint32_t _mur_k1 = 0; \ ++ const uint8_t *_mur_tail; \ ++ const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+(_mur_nblocks*4)); \ ++ int _mur_i; \ ++ for(_mur_i = -_mur_nblocks; _mur_i!=0; _mur_i++) { \ ++ _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \ ++ _mur_k1 *= _mur_c1; \ ++ _mur_k1 = MUR_ROTL32(_mur_k1,15); \ ++ _mur_k1 *= _mur_c2; \ ++ \ ++ _mur_h1 ^= _mur_k1; \ ++ _mur_h1 = MUR_ROTL32(_mur_h1,13); \ ++ _mur_h1 = (_mur_h1*5U) + 0xe6546b64u; \ ++ } \ ++ _mur_tail = (const uint8_t*)(_mur_data + (_mur_nblocks*4)); \ ++ _mur_k1=0; \ ++ switch((keylen) & 3U) { \ ++ case 3: _mur_k1 ^= (uint32_t)_mur_tail[2] << 16; /* FALLTHROUGH */ \ ++ case 2: _mur_k1 ^= (uint32_t)_mur_tail[1] << 8; /* FALLTHROUGH */ \ ++ case 1: _mur_k1 ^= (uint32_t)_mur_tail[0]; \ ++ _mur_k1 *= _mur_c1; \ ++ _mur_k1 = MUR_ROTL32(_mur_k1,15); \ ++ _mur_k1 *= _mur_c2; \ ++ _mur_h1 ^= _mur_k1; \ ++ } \ ++ _mur_h1 ^= (uint32_t)(keylen); \ ++ MUR_FMIX(_mur_h1); \ ++ hashv = _mur_h1; \ ++} while (0) ++#endif /* HASH_USING_NO_STRICT_ALIASING */ ++ ++/* iterate over items in a known bucket to find desired item */ ++#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,hashval,out) \ ++do { \ ++ if ((head).hh_head != NULL) { \ ++ DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (head).hh_head)); \ ++ } else { \ ++ (out) = NULL; \ ++ } \ ++ while ((out) != NULL) { \ ++ if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) { \ ++ if (uthash_memcmp((out)->hh.key, keyptr, keylen_in) == 0) { \ ++ break; \ ++ } \ ++ } \ ++ if ((out)->hh.hh_next != NULL) { \ ++ DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (out)->hh.hh_next)); \ ++ } else { \ ++ (out) = NULL; \ ++ } \ ++ } \ ++} while (0) ++ ++/* add an item to a bucket */ ++#define HASH_ADD_TO_BKT(head,addhh) \ ++do { \ ++ head.count++; \ ++ (addhh)->hh_next = head.hh_head; \ ++ (addhh)->hh_prev = NULL; \ ++ if (head.hh_head != NULL) { (head).hh_head->hh_prev = (addhh); } \ ++ (head).hh_head=addhh; \ ++ if ((head.count >= ((head.expand_mult+1U) * HASH_BKT_CAPACITY_THRESH)) \ ++ && ((addhh)->tbl->noexpand != 1U)) { \ ++ HASH_EXPAND_BUCKETS((addhh)->tbl); \ ++ } \ ++} while (0) ++ ++/* remove an item from a given bucket */ ++#define HASH_DEL_IN_BKT(hh,head,hh_del) \ ++ (head).count--; \ ++ if ((head).hh_head == hh_del) { \ ++ (head).hh_head = hh_del->hh_next; \ ++ } \ ++ if (hh_del->hh_prev) { \ ++ hh_del->hh_prev->hh_next = hh_del->hh_next; \ ++ } \ ++ if (hh_del->hh_next) { \ ++ hh_del->hh_next->hh_prev = hh_del->hh_prev; \ ++ } ++ ++/* Bucket expansion has the effect of doubling the number of buckets ++ * and redistributing the items into the new buckets. Ideally the ++ * items will distribute more or less evenly into the new buckets ++ * (the extent to which this is true is a measure of the quality of ++ * the hash function as it applies to the key domain). ++ * ++ * With the items distributed into more buckets, the chain length ++ * (item count) in each bucket is reduced. Thus by expanding buckets ++ * the hash keeps a bound on the chain length. This bounded chain ++ * length is the essence of how a hash provides constant time lookup. ++ * ++ * The calculation of tbl->ideal_chain_maxlen below deserves some ++ * explanation. First, keep in mind that we're calculating the ideal ++ * maximum chain length based on the *new* (doubled) bucket count. ++ * In fractions this is just n/b (n=number of items,b=new num buckets). ++ * Since the ideal chain length is an integer, we want to calculate ++ * ceil(n/b). We don't depend on floating point arithmetic in this ++ * hash, so to calculate ceil(n/b) with integers we could write ++ * ++ * ceil(n/b) = (n/b) + ((n%b)?1:0) ++ * ++ * and in fact a previous version of this hash did just that. ++ * But now we have improved things a bit by recognizing that b is ++ * always a power of two. We keep its base 2 log handy (call it lb), ++ * so now we can write this with a bit shift and logical AND: ++ * ++ * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) ++ * ++ */ ++#define HASH_EXPAND_BUCKETS(tbl) \ ++do { \ ++ unsigned _he_bkt; \ ++ unsigned _he_bkt_i; \ ++ struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ ++ UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ ++ _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ ++ 2UL * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ ++ if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \ ++ memset(_he_new_buckets, 0, \ ++ 2UL * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ ++ tbl->ideal_chain_maxlen = \ ++ (tbl->num_items >> (tbl->log2_num_buckets+1U)) + \ ++ (((tbl->num_items & ((tbl->num_buckets*2U)-1U)) != 0U) ? 1U : 0U); \ ++ tbl->nonideal_items = 0; \ ++ for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \ ++ { \ ++ _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \ ++ while (_he_thh != NULL) { \ ++ _he_hh_nxt = _he_thh->hh_next; \ ++ HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2U, _he_bkt); \ ++ _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \ ++ if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \ ++ tbl->nonideal_items++; \ ++ _he_newbkt->expand_mult = _he_newbkt->count / \ ++ tbl->ideal_chain_maxlen; \ ++ } \ ++ _he_thh->hh_prev = NULL; \ ++ _he_thh->hh_next = _he_newbkt->hh_head; \ ++ if (_he_newbkt->hh_head != NULL) { _he_newbkt->hh_head->hh_prev = \ ++ _he_thh; } \ ++ _he_newbkt->hh_head = _he_thh; \ ++ _he_thh = _he_hh_nxt; \ ++ } \ ++ } \ ++ uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ ++ tbl->num_buckets *= 2U; \ ++ tbl->log2_num_buckets++; \ ++ tbl->buckets = _he_new_buckets; \ ++ tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \ ++ (tbl->ineff_expands+1U) : 0U; \ ++ if (tbl->ineff_expands > 1U) { \ ++ tbl->noexpand=1; \ ++ uthash_noexpand_fyi(tbl); \ ++ } \ ++ uthash_expand_fyi(tbl); \ ++} while (0) ++ ++ ++/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ ++/* Note that HASH_SORT assumes the hash handle name to be hh. ++ * HASH_SRT was added to allow the hash handle name to be passed in. */ ++#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) ++#define HASH_SRT(hh,head,cmpfcn) \ ++do { \ ++ unsigned _hs_i; \ ++ unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ ++ struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ ++ if (head != NULL) { \ ++ _hs_insize = 1; \ ++ _hs_looping = 1; \ ++ _hs_list = &((head)->hh); \ ++ while (_hs_looping != 0U) { \ ++ _hs_p = _hs_list; \ ++ _hs_list = NULL; \ ++ _hs_tail = NULL; \ ++ _hs_nmerges = 0; \ ++ while (_hs_p != NULL) { \ ++ _hs_nmerges++; \ ++ _hs_q = _hs_p; \ ++ _hs_psize = 0; \ ++ for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \ ++ _hs_psize++; \ ++ _hs_q = (UT_hash_handle*)((_hs_q->next != NULL) ? \ ++ ((void*)((char*)(_hs_q->next) + \ ++ (head)->hh.tbl->hho)) : NULL); \ ++ if (! (_hs_q) ) { break; } \ ++ } \ ++ _hs_qsize = _hs_insize; \ ++ while ((_hs_psize > 0U) || ((_hs_qsize > 0U) && (_hs_q != NULL))) {\ ++ if (_hs_psize == 0U) { \ ++ _hs_e = _hs_q; \ ++ _hs_q = (UT_hash_handle*)((_hs_q->next != NULL) ? \ ++ ((void*)((char*)(_hs_q->next) + \ ++ (head)->hh.tbl->hho)) : NULL); \ ++ _hs_qsize--; \ ++ } else if ( (_hs_qsize == 0U) || (_hs_q == NULL) ) { \ ++ _hs_e = _hs_p; \ ++ if (_hs_p != NULL){ \ ++ _hs_p = (UT_hash_handle*)((_hs_p->next != NULL) ? \ ++ ((void*)((char*)(_hs_p->next) + \ ++ (head)->hh.tbl->hho)) : NULL); \ ++ } \ ++ _hs_psize--; \ ++ } else if (( \ ++ cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \ ++ DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \ ++ ) <= 0) { \ ++ _hs_e = _hs_p; \ ++ if (_hs_p != NULL){ \ ++ _hs_p = (UT_hash_handle*)((_hs_p->next != NULL) ? \ ++ ((void*)((char*)(_hs_p->next) + \ ++ (head)->hh.tbl->hho)) : NULL); \ ++ } \ ++ _hs_psize--; \ ++ } else { \ ++ _hs_e = _hs_q; \ ++ _hs_q = (UT_hash_handle*)((_hs_q->next != NULL) ? \ ++ ((void*)((char*)(_hs_q->next) + \ ++ (head)->hh.tbl->hho)) : NULL); \ ++ _hs_qsize--; \ ++ } \ ++ if ( _hs_tail != NULL ) { \ ++ _hs_tail->next = ((_hs_e != NULL) ? \ ++ ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \ ++ } else { \ ++ _hs_list = _hs_e; \ ++ } \ ++ if (_hs_e != NULL) { \ ++ _hs_e->prev = ((_hs_tail != NULL) ? \ ++ ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \ ++ } \ ++ _hs_tail = _hs_e; \ ++ } \ ++ _hs_p = _hs_q; \ ++ } \ ++ if (_hs_tail != NULL){ \ ++ _hs_tail->next = NULL; \ ++ } \ ++ if ( _hs_nmerges <= 1U ) { \ ++ _hs_looping=0; \ ++ (head)->hh.tbl->tail = _hs_tail; \ ++ DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ ++ } \ ++ _hs_insize *= 2U; \ ++ } \ ++ HASH_FSCK(hh,head); \ ++ } \ ++} while (0) ++ ++/* This function selects items from one hash into another hash. ++ * The end result is that the selected items have dual presence ++ * in both hashes. There is no copy of the items made; rather ++ * they are added into the new hash through a secondary hash ++ * hash handle that must be present in the structure. */ ++#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ ++do { \ ++ unsigned _src_bkt, _dst_bkt; \ ++ void *_last_elt=NULL, *_elt; \ ++ UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ ++ ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ ++ if (src != NULL) { \ ++ for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ ++ for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ ++ _src_hh != NULL; \ ++ _src_hh = _src_hh->hh_next) { \ ++ _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ ++ if (cond(_elt)) { \ ++ _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ ++ _dst_hh->key = _src_hh->key; \ ++ _dst_hh->keylen = _src_hh->keylen; \ ++ _dst_hh->hashv = _src_hh->hashv; \ ++ _dst_hh->prev = _last_elt; \ ++ _dst_hh->next = NULL; \ ++ if (_last_elt_hh != NULL) { _last_elt_hh->next = _elt; } \ ++ if (dst == NULL) { \ ++ DECLTYPE_ASSIGN(dst,_elt); \ ++ HASH_MAKE_TABLE(hh_dst,dst); \ ++ } else { \ ++ _dst_hh->tbl = (dst)->hh_dst.tbl; \ ++ } \ ++ HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ ++ HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \ ++ (dst)->hh_dst.tbl->num_items++; \ ++ _last_elt = _elt; \ ++ _last_elt_hh = _dst_hh; \ ++ } \ ++ } \ ++ } \ ++ } \ ++ HASH_FSCK(hh_dst,dst); \ ++} while (0) ++ ++#define HASH_CLEAR(hh,head) \ ++do { \ ++ if (head != NULL) { \ ++ uthash_free((head)->hh.tbl->buckets, \ ++ (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ ++ HASH_BLOOM_FREE((head)->hh.tbl); \ ++ uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ ++ (head)=NULL; \ ++ } \ ++} while (0) ++ ++#define HASH_OVERHEAD(hh,head) \ ++ ((head != NULL) ? ( \ ++ (size_t)(((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ ++ ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ ++ sizeof(UT_hash_table) + \ ++ (HASH_BLOOM_BYTELEN))) : 0U) ++ ++#ifdef NO_DECLTYPE ++#define HASH_ITER(hh,head,el,tmp) \ ++for(((el)=(head)), ((*(char**)(&(tmp)))=(char*)((head!=NULL)?(head)->hh.next:NULL)); \ ++ (el) != NULL; ((el)=(tmp)), ((*(char**)(&(tmp)))=(char*)((tmp!=NULL)?(tmp)->hh.next:NULL))) ++#else ++#define HASH_ITER(hh,head,el,tmp) \ ++for(((el)=(head)), ((tmp)=DECLTYPE(el)((head!=NULL)?(head)->hh.next:NULL)); \ ++ (el) != NULL; ((el)=(tmp)), ((tmp)=DECLTYPE(el)((tmp!=NULL)?(tmp)->hh.next:NULL))) ++#endif ++ ++/* obtain a count of items in the hash */ ++#define HASH_COUNT(head) HASH_CNT(hh,head) ++#define HASH_CNT(hh,head) ((head != NULL)?((head)->hh.tbl->num_items):0U) ++ ++typedef struct UT_hash_bucket { ++ struct UT_hash_handle *hh_head; ++ unsigned count; ++ ++ /* expand_mult is normally set to 0. In this situation, the max chain length ++ * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If ++ * the bucket's chain exceeds this length, bucket expansion is triggered). ++ * However, setting expand_mult to a non-zero value delays bucket expansion ++ * (that would be triggered by additions to this particular bucket) ++ * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. ++ * (The multiplier is simply expand_mult+1). The whole idea of this ++ * multiplier is to reduce bucket expansions, since they are expensive, in ++ * situations where we know that a particular bucket tends to be overused. ++ * It is better to let its chain length grow to a longer yet-still-bounded ++ * value, than to do an O(n) bucket expansion too often. ++ */ ++ unsigned expand_mult; ++ ++} UT_hash_bucket; ++ ++/* random signature used only to find hash tables in external analysis */ ++#define HASH_SIGNATURE 0xa0111fe1u ++#define HASH_BLOOM_SIGNATURE 0xb12220f2u ++ ++typedef struct UT_hash_table { ++ UT_hash_bucket *buckets; ++ unsigned num_buckets, log2_num_buckets; ++ unsigned num_items; ++ struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ ++ ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ ++ ++ /* in an ideal situation (all buckets used equally), no bucket would have ++ * more than ceil(#items/#buckets) items. that's the ideal chain length. */ ++ unsigned ideal_chain_maxlen; ++ ++ /* nonideal_items is the number of items in the hash whose chain position ++ * exceeds the ideal chain maxlen. these items pay the penalty for an uneven ++ * hash distribution; reaching them in a chain traversal takes >ideal steps */ ++ unsigned nonideal_items; ++ ++ /* ineffective expands occur when a bucket doubling was performed, but ++ * afterward, more than half the items in the hash had nonideal chain ++ * positions. If this happens on two consecutive expansions we inhibit any ++ * further expansion, as it's not helping; this happens when the hash ++ * function isn't a good fit for the key domain. When expansion is inhibited ++ * the hash will still work, albeit no longer in constant time. */ ++ unsigned ineff_expands, noexpand; ++ ++ uint32_t signature; /* used only to find hash tables in external analysis */ ++#ifdef HASH_BLOOM ++ uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ ++ uint8_t *bloom_bv; ++ uint8_t bloom_nbits; ++#endif ++ ++} UT_hash_table; ++ ++typedef struct UT_hash_handle { ++ struct UT_hash_table *tbl; ++ void *prev; /* prev element in app order */ ++ void *next; /* next element in app order */ ++ struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ ++ struct UT_hash_handle *hh_next; /* next hh in bucket order */ ++ void *key; /* ptr to enclosing struct's key */ ++ unsigned keylen; /* enclosing struct's key len */ ++ unsigned hashv; /* result of hash-fcn(key) */ ++} UT_hash_handle; ++ ++#endif /* UTHASH_H */ +diff --git a/server/utils.c b/server/utils.c +new file mode 100644 +index 0000000..14a60c7 +--- /dev/null ++++ b/server/utils.c +@@ -0,0 +1,448 @@ ++/* ++ * utils.c - Misc utilities ++ * ++ * Copyright (C) 2013 - 2016, Max Lv ++ * ++ * This file is part of the shadowsocks-libev. ++ * ++ * shadowsocks-libev 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 3 of the License, or ++ * (at your option) any later version. ++ * ++ * shadowsocks-libev 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 shadowsocks-libev; see the file COPYING. If not, see ++ * . ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#ifndef __MINGW32__ ++#include ++#include ++#endif ++ ++#include ++#include ++ ++#include "utils.h" ++ ++#ifdef HAVE_SETRLIMIT ++#include ++#include ++#endif ++ ++#define INT_DIGITS 19 /* enough for 64 bit integer */ ++ ++#ifdef LIB_ONLY ++FILE *logfile; ++#endif ++ ++#ifdef HAS_SYSLOG ++int use_syslog = 0; ++#endif ++ ++#ifndef __MINGW32__ ++void ++ERROR(const char *s) ++{ ++ char *msg = strerror(errno); ++ LOGE("%s: %s", s, msg); ++} ++ ++#endif ++ ++int use_tty = 1; ++ ++char * ++ss_itoa(int i) ++{ ++ /* Room for INT_DIGITS digits, - and '\0' */ ++ static char buf[INT_DIGITS + 2]; ++ char *p = buf + INT_DIGITS + 1; /* points to terminating '\0' */ ++ if (i >= 0) { ++ do { ++ *--p = '0' + (i % 10); ++ i /= 10; ++ } while (i != 0); ++ return p; ++ } else { /* i < 0 */ ++ do { ++ *--p = '0' - (i % 10); ++ i /= 10; ++ } while (i != 0); ++ *--p = '-'; ++ } ++ return p; ++} ++ ++int ++ss_isnumeric(const char *s) { ++ if (!s || !*s) ++ return 0; ++ while (isdigit(*s)) ++ ++s; ++ return *s == '\0'; ++} ++ ++/* ++ * setuid() and setgid() for a specified user. ++ */ ++int ++run_as(const char *user) ++{ ++#ifndef __MINGW32__ ++ if (user[0]) { ++ /* Convert user to a long integer if it is a non-negative number. ++ * -1 means it is a user name. */ ++ long uid = -1; ++ if (ss_isnumeric(user)) { ++ errno = 0; ++ char *endptr; ++ uid = strtol(user, &endptr, 10); ++ if (errno || endptr == user) ++ uid = -1; ++ } ++ ++#ifdef HAVE_GETPWNAM_R ++ struct passwd pwdbuf, *pwd; ++ memset(&pwdbuf, 0, sizeof(struct passwd)); ++ size_t buflen; ++ int err; ++ ++ for (buflen = 128;; buflen *= 2) { ++ char buf[buflen]; /* variable length array */ ++ ++ /* Note that we use getpwnam_r() instead of getpwnam(), ++ * which returns its result in a statically allocated buffer and ++ * cannot be considered thread safe. */ ++ err = uid >= 0 ? getpwuid_r((uid_t)uid, &pwdbuf, buf, buflen, &pwd) ++ : getpwnam_r(user, &pwdbuf, buf, buflen, &pwd); ++ ++ if (err == 0 && pwd) { ++ /* setgid first, because we may not be allowed to do it anymore after setuid */ ++ if (setgid(pwd->pw_gid) != 0) { ++ LOGE( ++ "Could not change group id to that of run_as user '%s': %s", ++ pwd->pw_name, strerror(errno)); ++ return 0; ++ } ++ ++ if (initgroups(pwd->pw_name, pwd->pw_gid) == -1) { ++ LOGE("Could not change supplementary groups for user '%s'.", pwd->pw_name); ++ return 0; ++ } ++ ++ if (setuid(pwd->pw_uid) != 0) { ++ LOGE( ++ "Could not change user id to that of run_as user '%s': %s", ++ pwd->pw_name, strerror(errno)); ++ return 0; ++ } ++ break; ++ } else if (err != ERANGE) { ++ if (err) { ++ LOGE("run_as user '%s' could not be found: %s", user, ++ strerror(err)); ++ } else { ++ LOGE("run_as user '%s' could not be found.", user); ++ } ++ return 0; ++ } else if (buflen >= 16 * 1024) { ++ /* If getpwnam_r() seems defective, call it quits rather than ++ * keep on allocating ever larger buffers until we crash. */ ++ LOGE( ++ "getpwnam_r() requires more than %u bytes of buffer space.", ++ (unsigned)buflen); ++ return 0; ++ } ++ /* Else try again with larger buffer. */ ++ } ++#else ++ /* No getpwnam_r() :-( We'll use getpwnam() and hope for the best. */ ++ struct passwd *pwd; ++ ++ if (!(pwd = uid >=0 ? getpwuid((uid_t)uid) : getpwnam(user))) { ++ LOGE("run_as user %s could not be found.", user); ++ return 0; ++ } ++ /* setgid first, because we may not allowed to do it anymore after setuid */ ++ if (setgid(pwd->pw_gid) != 0) { ++ LOGE("Could not change group id to that of run_as user '%s': %s", ++ pwd->pw_name, strerror(errno)); ++ return 0; ++ } ++ if (initgroups(pwd->pw_name, pwd->pw_gid) == -1) { ++ LOGE("Could not change supplementary groups for user '%s'.", pwd->pw_name); ++ return 0; ++ } ++ if (setuid(pwd->pw_uid) != 0) { ++ LOGE("Could not change user id to that of run_as user '%s': %s", ++ pwd->pw_name, strerror(errno)); ++ return 0; ++ } ++#endif ++ } ++ ++#endif // __MINGW32__ ++ return 1; ++} ++ ++char * ++ss_strndup(const char *s, size_t n) ++{ ++ size_t len = strlen(s); ++ char *ret; ++ ++ if (len <= n) { ++ return strdup(s); ++ } ++ ++ ret = ss_malloc(n + 1); ++ strncpy(ret, s, n); ++ ret[n] = '\0'; ++ return ret; ++} ++ ++void ++FATAL(const char *msg) ++{ ++ LOGE("%s", msg); ++ exit(-1); ++} ++ ++void * ++ss_malloc(size_t size) ++{ ++ void *tmp = malloc(size); ++ if (tmp == NULL) ++ exit(EXIT_FAILURE); ++ return tmp; ++} ++ ++void * ++ss_realloc(void *ptr, size_t new_size) ++{ ++ void *new = realloc(ptr, new_size); ++ if (new == NULL) { ++ free(ptr); ++ ptr = NULL; ++ exit(EXIT_FAILURE); ++ } ++ return new; ++} ++ ++void ++usage() ++{ ++ printf("\n"); ++ printf("shadowsocks-libev %s with %s\n\n", VERSION, USING_CRYPTO); ++ printf( ++ " maintained by Max Lv and Linus Yang \n\n"); ++ printf(" usage:\n\n"); ++#ifdef MODULE_LOCAL ++ printf(" ss-local\n"); ++#elif MODULE_REMOTE ++ printf(" ss-server\n"); ++#elif MODULE_TUNNEL ++ printf(" ss-tunnel\n"); ++#elif MODULE_REDIR ++ printf(" ss-redir\n"); ++#elif MODULE_MANAGER ++ printf(" ss-manager\n"); ++#endif ++ printf("\n"); ++ printf( ++ " -s Host name or IP address of your remote server.\n"); ++ printf( ++ " -p Port number of your remote server.\n"); ++ printf( ++ " -l Port number of your local server.\n"); ++ printf( ++ " -k Password of your remote server.\n"); ++ printf( ++ " -m Encrypt method: table, rc4, rc4-md5,\n"); ++ printf( ++ " aes-128-cfb, aes-192-cfb, aes-256-cfb,\n"); ++ printf( ++ " aes-128-ctr, aes-192-ctr, aes-256-ctr,\n"); ++ printf( ++ " bf-cfb, camellia-128-cfb, camellia-192-cfb,\n"); ++ printf( ++ " camellia-256-cfb, cast5-cfb, des-cfb,\n"); ++ printf( ++ " idea-cfb, rc2-cfb, seed-cfb, salsa20,\n"); ++ printf( ++ " chacha20 and chacha20-ietf.\n"); ++ printf( ++ " The default cipher is rc4-md5.\n"); ++ printf("\n"); ++ printf( ++ " [-a ] Run as another user.\n"); ++ printf( ++ " [-f ] The file path to store pid.\n"); ++ printf( ++ " [-t ] Socket timeout in seconds.\n"); ++ printf( ++ " [-c ] The path to config file.\n"); ++#ifdef HAVE_SETRLIMIT ++ printf( ++ " [-n ] Max number of open files.\n"); ++#endif ++#ifndef MODULE_REDIR ++ printf( ++ " [-i ] Network interface to bind.\n"); ++#endif ++ printf( ++ " [-b ] Local address to bind.\n"); ++ printf("\n"); ++ printf( ++ " [-u] Enable UDP relay.\n"); ++#ifdef MODULE_REDIR ++ printf( ++ " TPROXY is required in redir mode.\n"); ++#endif ++ printf( ++ " [-U] Enable UDP relay and disable TCP relay.\n"); ++ printf( ++ " [-A] Enable onetime authentication.\n"); ++#ifdef MODULE_REMOTE ++ printf( ++ " [-6] Resovle hostname to IPv6 address first.\n"); ++#endif ++ printf("\n"); ++#ifdef MODULE_TUNNEL ++ printf( ++ " [-L :] Destination server address and port\n"); ++ printf( ++ " for local port forwarding.\n"); ++#endif ++#ifdef MODULE_REMOTE ++ printf( ++ " [-d ] Name servers for internal DNS resolver.\n"); ++#endif ++#if defined(MODULE_REMOTE) || defined(MODULE_LOCAL) ++ printf( ++ " [--fast-open] Enable TCP fast open.\n"); ++ printf( ++ " with Linux kernel > 3.7.0.\n"); ++ printf( ++ " [--acl ] Path to ACL (Access Control List).\n"); ++#endif ++#if defined(MODULE_REMOTE) || defined(MODULE_MANAGER) ++ printf( ++ " [--manager-address ] UNIX domain socket address.\n"); ++#endif ++#ifdef MODULE_MANAGER ++ printf( ++ " [--executable ] Path to the executable of ss-server.\n"); ++#endif ++ printf( ++ " [--mtu ] MTU of your network interface.\n"); ++#ifdef __linux__ ++ printf( ++ " [--mptcp] Enable Multipath TCP on MPTCP Kernel.\n"); ++#ifdef MODULE_REMOTE ++ printf( ++ " [--firewall] Setup firewall rules for auto blocking.\n"); ++#endif ++#endif ++ printf("\n"); ++ printf( ++ " [-v] Verbose mode.\n"); ++ printf( ++ " [-h, --help] Print this message.\n"); ++ printf("\n"); ++} ++ ++void ++daemonize(const char *path) ++{ ++#ifndef __MINGW32__ ++ /* Our process ID and Session ID */ ++ pid_t pid, sid; ++ ++ /* Fork off the parent process */ ++ pid = fork(); ++ if (pid < 0) { ++ exit(EXIT_FAILURE); ++ } ++ ++ /* If we got a good PID, then ++ * we can exit the parent process. */ ++ if (pid > 0) { ++ FILE *file = fopen(path, "w"); ++ if (file == NULL) { ++ FATAL("Invalid pid file\n"); ++ } ++ ++ fprintf(file, "%d", (int)pid); ++ fclose(file); ++ exit(EXIT_SUCCESS); ++ } ++ ++ /* Change the file mode mask */ ++ umask(0); ++ ++ /* Open any logs here */ ++ ++ /* Create a new SID for the child process */ ++ sid = setsid(); ++ if (sid < 0) { ++ /* Log the failure */ ++ exit(EXIT_FAILURE); ++ } ++ ++ /* Change the current working directory */ ++ if ((chdir("/")) < 0) { ++ /* Log the failure */ ++ exit(EXIT_FAILURE); ++ } ++ ++ /* Close out the standard file descriptors */ ++ close(STDIN_FILENO); ++ close(STDOUT_FILENO); ++ close(STDERR_FILENO); ++#endif ++} ++ ++#ifdef HAVE_SETRLIMIT ++int ++set_nofile(int nofile) ++{ ++ struct rlimit limit = { nofile, nofile }; /* set both soft and hard limit */ ++ ++ if (nofile <= 0) { ++ FATAL("nofile must be greater than 0\n"); ++ } ++ ++ if (setrlimit(RLIMIT_NOFILE, &limit) < 0) { ++ if (errno == EPERM) { ++ LOGE( ++ "insufficient permission to change NOFILE, not starting as root?"); ++ return -1; ++ } else if (errno == EINVAL) { ++ LOGE("invalid nofile, decrease nofile and try again"); ++ return -1; ++ } else { ++ LOGE("setrlimit failed: %s", strerror(errno)); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++#endif +diff --git a/server/utils.h b/server/utils.h +new file mode 100644 +index 0000000..0fb7f5a +--- /dev/null ++++ b/server/utils.h +@@ -0,0 +1,232 @@ ++/* ++ * utils.h - Misc utilities ++ * ++ * Copyright (C) 2013 - 2016, Max Lv ++ * ++ * This file is part of the shadowsocks-libev. ++ * ++ * shadowsocks-libev 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 3 of the License, or ++ * (at your option) any later version. ++ * ++ * shadowsocks-libev 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 shadowsocks-libev; see the file COPYING. If not, see ++ * . ++ */ ++ ++#if defined(USE_CRYPTO_OPENSSL) ++ ++#include ++#define USING_CRYPTO OPENSSL_VERSION_TEXT ++ ++#elif defined(USE_CRYPTO_POLARSSL) ++#include ++#define USING_CRYPTO POLARSSL_VERSION_STRING_FULL ++ ++#elif defined(USE_CRYPTO_MBEDTLS) ++#include ++#define USING_CRYPTO MBEDTLS_VERSION_STRING_FULL ++ ++#endif ++ ++#ifndef _UTILS_H ++#define _UTILS_H ++ ++#include ++#include ++#include ++#include ++ ++#define PORTSTRLEN 16 ++#define SS_ADDRSTRLEN (INET6_ADDRSTRLEN + PORTSTRLEN + 1) ++ ++#ifdef ANDROID ++ ++#include ++ ++#define USE_TTY() ++#define USE_SYSLOG(ident) ++#define LOGI(...) \ ++ ((void)__android_log_print(ANDROID_LOG_DEBUG, "shadowsocks", \ ++ __VA_ARGS__)) ++#define LOGE(...) \ ++ ((void)__android_log_print(ANDROID_LOG_ERROR, "shadowsocks", \ ++ __VA_ARGS__)) ++ ++#else ++ ++#define STR(x) # x ++#define TOSTR(x) STR(x) ++ ++#ifdef LIB_ONLY ++ ++extern FILE *logfile; ++ ++#define TIME_FORMAT "%Y-%m-%d %H:%M:%S" ++ ++#define USE_TTY() ++ ++#define USE_SYSLOG(ident) ++ ++#define USE_LOGFILE(ident) \ ++ do { \ ++ if (ident != NULL) { logfile = fopen(ident, "w+"); } } \ ++ while (0) ++ ++#define CLOSE_LOGFILE \ ++ do { \ ++ if (logfile != NULL) { fclose(logfile); } } \ ++ while (0) ++ ++#define LOGI(format, ...) \ ++ do { \ ++ if (logfile != NULL) { \ ++ time_t now = time(NULL); \ ++ char timestr[20]; \ ++ strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \ ++ fprintf(logfile, " %s INFO: " format "\n", timestr, ## __VA_ARGS__); \ ++ fflush(logfile); } \ ++ } \ ++ while (0) ++ ++#define LOGE(format, ...) \ ++ do { \ ++ if (logfile != NULL) { \ ++ time_t now = time(NULL); \ ++ char timestr[20]; \ ++ strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \ ++ fprintf(logfile, " %s ERROR: " format "\n", timestr, \ ++ ## __VA_ARGS__); \ ++ fflush(logfile); } \ ++ } \ ++ while (0) ++ ++#elif defined(_WIN32) ++ ++#define TIME_FORMAT "%Y-%m-%d %H:%M:%S" ++ ++#define USE_TTY() ++ ++#define USE_SYSLOG(ident) ++ ++#define LOGI(format, ...) \ ++ do { \ ++ time_t now = time(NULL); \ ++ char timestr[20]; \ ++ strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \ ++ fprintf(stderr, " %s INFO: " format "\n", timestr, ## __VA_ARGS__); \ ++ fflush(stderr); } \ ++ while (0) ++ ++#define LOGE(format, ...) \ ++ do { \ ++ time_t now = time(NULL); \ ++ char timestr[20]; \ ++ strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \ ++ fprintf(stderr, " %s ERROR: " format "\n", timestr, ## __VA_ARGS__); \ ++ fflush(stderr); } \ ++ while (0) ++ ++#else ++ ++#include ++ ++extern int use_tty; ++#define USE_TTY() \ ++ do { \ ++ use_tty = isatty(STDERR_FILENO); \ ++ } while (0) \ ++ ++#define HAS_SYSLOG ++extern int use_syslog; ++ ++#define TIME_FORMAT "%F %T" ++ ++#define USE_SYSLOG(ident) \ ++ do { \ ++ use_syslog = 1; \ ++ openlog((ident), LOG_CONS | LOG_PID, 0); } \ ++ while (0) ++ ++#define LOGI(format, ...) \ ++ do { \ ++ if (use_syslog) { \ ++ syslog(LOG_INFO, format, ## __VA_ARGS__); \ ++ } else { \ ++ time_t now = time(NULL); \ ++ char timestr[20]; \ ++ strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \ ++ if (use_tty) { \ ++ fprintf(stderr, "\e[01;32m %s INFO: \e[0m" format "\n", timestr, \ ++ ## __VA_ARGS__); \ ++ } else { \ ++ fprintf(stderr, " %s INFO: " format "\n", timestr, \ ++ ## __VA_ARGS__); \ ++ } \ ++ } \ ++ } \ ++ while (0) ++ ++#define LOGE(format, ...) \ ++ do { \ ++ if (use_syslog) { \ ++ syslog(LOG_ERR, format, ## __VA_ARGS__); \ ++ } else { \ ++ time_t now = time(NULL); \ ++ char timestr[20]; \ ++ strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \ ++ if (use_tty) { \ ++ fprintf(stderr, "\e[01;35m %s ERROR: \e[0m" format "\n", timestr, \ ++ ## __VA_ARGS__); \ ++ } else { \ ++ fprintf(stderr, " %s ERROR: " format "\n", timestr, \ ++ ## __VA_ARGS__); \ ++ } \ ++ } } \ ++ while (0) ++ ++#endif ++/* _WIN32 */ ++ ++#endif ++ ++#ifdef __MINGW32__ ++ ++#ifdef ERROR ++#undef ERROR ++#endif ++#define ERROR(s) ss_error(s) ++ ++#else ++ ++void ERROR(const char *s); ++ ++#endif ++ ++char *ss_itoa(int i); ++int ss_isnumeric(const char *s); ++int run_as(const char *user); ++void FATAL(const char *msg); ++void usage(void); ++void daemonize(const char *path); ++char *ss_strndup(const char *s, size_t n); ++#ifdef HAVE_SETRLIMIT ++int set_nofile(int nofile); ++#endif ++ ++void *ss_malloc(size_t size); ++void *ss_realloc(void *ptr, size_t new_size); ++ ++#define ss_free(ptr) \ ++ do { \ ++ free(ptr); \ ++ ptr = NULL; \ ++ } while (0) ++ ++#endif // _UTILS_H +diff --git a/server/verify.c b/server/verify.c +new file mode 100644 +index 0000000..9e7393d +--- /dev/null ++++ b/server/verify.c +@@ -0,0 +1,188 @@ ++ ++#include "verify.h" ++ ++static int verify_simple_pack_unit_size = 2000; ++ ++typedef struct verify_simple_local_data { ++ char * recv_buffer; ++ int recv_buffer_size; ++}verify_simple_local_data; ++ ++void verify_simple_local_data_init(verify_simple_local_data* local) { ++ local->recv_buffer = (char*)malloc(16384); ++ local->recv_buffer_size = 0; ++} ++ ++obfs * verify_simple_new_obfs() { ++ obfs * self = new_obfs(); ++ self->l_data = malloc(sizeof(verify_simple_local_data)); ++ verify_simple_local_data_init((verify_simple_local_data*)self->l_data); ++ return self; ++} ++ ++void verify_simple_dispose(obfs *self) { ++ verify_simple_local_data *local = (verify_simple_local_data*)self->l_data; ++ if (local->recv_buffer != NULL) { ++ free(local->recv_buffer); ++ local->recv_buffer = NULL; ++ } ++ free(local); ++ self->l_data = NULL; ++ dispose_obfs(self); ++} ++ ++int verify_simple_pack_data(char *data, int datalength, char *outdata) { ++ unsigned char rand_len = (xorshift128plus() & 0xF) + 1; ++ int out_size = rand_len + datalength + 6; ++ outdata[0] = out_size >> 8; ++ outdata[1] = out_size; ++ outdata[2] = rand_len; ++ memmove(outdata + rand_len + 2, data, datalength); ++ fillcrc32((unsigned char *)outdata, out_size); ++ return out_size; ++} ++ ++int verify_simple_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t *capacity) { ++ char *plaindata = *pplaindata; ++ //verify_simple_local_data *local = (verify_simple_local_data*)self->l_data; ++ char * out_buffer = (char*)malloc(datalength * 2 + 32); ++ char * buffer = out_buffer; ++ char * data = plaindata; ++ int len = datalength; ++ int pack_len; ++ while ( len > verify_simple_pack_unit_size ) { ++ pack_len = verify_simple_pack_data(data, verify_simple_pack_unit_size, buffer); ++ buffer += pack_len; ++ data += verify_simple_pack_unit_size; ++ len -= verify_simple_pack_unit_size; ++ } ++ if (len > 0) { ++ pack_len = verify_simple_pack_data(data, len, buffer); ++ buffer += pack_len; ++ } ++ len = buffer - out_buffer; ++ if (*capacity < len) { ++ *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); ++ plaindata = *pplaindata; ++ } ++ memmove(plaindata, out_buffer, len); ++ free(out_buffer); ++ return len; ++} ++ ++int verify_simple_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t *capacity) { ++ char *plaindata = *pplaindata; ++ verify_simple_local_data *local = (verify_simple_local_data*)self->l_data; ++ uint8_t * recv_buffer = (uint8_t *)local->recv_buffer; ++ if (local->recv_buffer_size + datalength > 16384) ++ return -1; ++ memmove(recv_buffer + local->recv_buffer_size, plaindata, datalength); ++ local->recv_buffer_size += datalength; ++ ++ char * out_buffer = (char*)malloc(local->recv_buffer_size); ++ char * buffer = out_buffer; ++ while (local->recv_buffer_size > 2) { ++ int length = ((int)recv_buffer[0] << 8) | recv_buffer[1]; ++ if (length >= 8192 || length < 7) { ++ free(out_buffer); ++ local->recv_buffer_size = 0; ++ return -1; ++ } ++ if (length > local->recv_buffer_size) ++ break; ++ ++ int crc = crc32((unsigned char*)recv_buffer, length); ++ if (crc != -1) { ++ free(out_buffer); ++ local->recv_buffer_size = 0; ++ return -1; ++ } ++ int data_size = length - recv_buffer[2] - 6; ++ memmove(buffer, recv_buffer + 2 + recv_buffer[2], data_size); ++ buffer += data_size; ++ memmove(recv_buffer, recv_buffer + length, local->recv_buffer_size -= length); ++ } ++ int len = buffer - out_buffer; ++ if (*capacity < len) { ++ *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); ++ plaindata = *pplaindata; ++ } ++ memmove(plaindata, out_buffer, len); ++ free(out_buffer); ++ return len; ++} ++ ++int verify_simple_server_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t *capacity) { ++ char *plaindata = *pplaindata; ++ //verify_simple_local_data *local = (verify_simple_local_data*)self->l_data; ++ char * out_buffer = (char*)malloc(datalength * 2 + 32); ++ char * buffer = out_buffer; ++ char * data = plaindata; ++ int len = datalength; ++ int pack_len; ++ while ( len > verify_simple_pack_unit_size ) { ++ pack_len = verify_simple_pack_data(data, verify_simple_pack_unit_size, buffer); ++ buffer += pack_len; ++ data += verify_simple_pack_unit_size; ++ len -= verify_simple_pack_unit_size; ++ } ++ if (len > 0) { ++ pack_len = verify_simple_pack_data(data, len, buffer); ++ buffer += pack_len; ++ } ++ len = buffer - out_buffer; ++ if (*capacity < len) { ++ *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); ++ plaindata = *pplaindata; ++ } ++ memmove(plaindata, out_buffer, len); ++ free(out_buffer); ++ return len; ++} ++ ++int verify_simple_server_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t *capacity) { ++ char *plaindata = *pplaindata; ++ verify_simple_local_data *local = (verify_simple_local_data*)self->l_data; ++ uint8_t * recv_buffer = (uint8_t *)local->recv_buffer; ++ if (local->recv_buffer_size + datalength > 16384) ++ { ++ LOGE("verify_simple: wrong buf length %d", local->recv_buffer_size + datalength); ++ return -1; ++ } ++ memmove(recv_buffer + local->recv_buffer_size, plaindata, datalength); ++ local->recv_buffer_size += datalength; ++ ++ char * out_buffer = (char*)malloc(local->recv_buffer_size); ++ char * buffer = out_buffer; ++ while (local->recv_buffer_size > 2) { ++ int length = ((int)recv_buffer[0] << 8) | recv_buffer[1]; ++ if (length >= 8192 || length < 7) { ++ free(out_buffer); ++ local->recv_buffer_size = 0; ++ LOGE("verify_simple: wrong length %d", length); ++ return -1; ++ } ++ if (length > local->recv_buffer_size) ++ break; ++ ++ int crc = crc32((unsigned char*)recv_buffer, length); ++ if (crc != -1) { ++ free(out_buffer); ++ local->recv_buffer_size = 0; ++ LOGE("verify_simple: wrong crc"); ++ return -1; ++ } ++ int data_size = length - recv_buffer[2] - 6; ++ memmove(buffer, recv_buffer + 2 + recv_buffer[2], data_size); ++ buffer += data_size; ++ memmove(recv_buffer, recv_buffer + length, local->recv_buffer_size -= length); ++ } ++ int len = buffer - out_buffer; ++ if (*capacity < len) { ++ *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); ++ plaindata = *pplaindata; ++ } ++ memmove(plaindata, out_buffer, len); ++ free(out_buffer); ++ return len; ++} +diff --git a/server/verify.h b/server/verify.h +new file mode 100644 +index 0000000..57c6ff9 +--- /dev/null ++++ b/server/verify.h +@@ -0,0 +1,19 @@ ++/* ++ * verify.h - Define shadowsocksR server's buffers and callbacks ++ * ++ * Copyright (C) 2015 - 2016, Break Wa11 ++ */ ++ ++#ifndef _VERIFY_H ++#define _VERIFY_H ++ ++obfs * verify_simple_new_obfs(); ++void verify_simple_dispose(obfs *self); ++ ++int verify_simple_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); ++int verify_simple_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); ++ ++int verify_simple_server_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); ++int verify_simple_server_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); ++ ++#endif // _VERIFY_H +-- +2.19.1 + diff --git a/package/lean/shadowsocksr-libev/patches/0002-Revert-verify_simple-and-auth_simple.patch b/package/lean/shadowsocksr-libev/patches/0002-Revert-verify_simple-and-auth_simple.patch new file mode 100644 index 0000000000..72ee3337d2 --- /dev/null +++ b/package/lean/shadowsocksr-libev/patches/0002-Revert-verify_simple-and-auth_simple.patch @@ -0,0 +1,22 @@ +diff --git a/src/obfs/obfs.c b/src/obfs/obfs.c +index 463359f..4cd750a 100644 +--- a/src/obfs/obfs.c ++++ b/src/obfs/obfs.c +@@ -88,7 +88,7 @@ + plugin->client_decode = tls12_ticket_auth_client_decode; + + return plugin; +- /*} else if (strcmp(plugin_name, "verify_simple") == 0) { ++ } else if (strcmp(plugin_name, "verify_simple") == 0) { + obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs_class)); + plugin->init_data = init_data; + plugin->new_obfs = verify_simple_new_obfs; +@@ -115,7 +115,7 @@ + plugin->client_udp_pre_encrypt = NULL; + plugin->client_udp_post_decrypt = NULL; + +- return plugin;*/ ++ return plugin; + } else if (strcmp(plugin_name, "auth_sha1") == 0) { + obfs_class *plugin = (obfs_class *) malloc(sizeof(obfs_class)); + plugin->init_data = auth_simple_init_data; \ No newline at end of file diff --git a/package/lean/shadowsocksr-libev/patches/0003-Refine-Usage.patch b/package/lean/shadowsocksr-libev/patches/0003-Refine-Usage.patch new file mode 100644 index 0000000000..85aa0f1344 --- /dev/null +++ b/package/lean/shadowsocksr-libev/patches/0003-Refine-Usage.patch @@ -0,0 +1,42 @@ +diff --git a/src/utils.c b/src/utils.c +index 94f8a83..01bcbac 100644 +--- a/src/utils.c ++++ b/src/utils.c +@@ -258,8 +258,6 @@ usage() + { + printf("\n"); + printf("shadowsocks-libev %s with %s\n\n", VERSION, USING_CRYPTO); +- printf( +- " maintained by Max Lv and Linus Yang \n\n"); + printf(" usage:\n\n"); + #ifdef MODULE_LOCAL + printf(" ss-local\n"); +@@ -298,6 +296,25 @@ usage() + printf( + " The default cipher is rc4-md5.\n"); + printf("\n"); ++ printf( ++ " -o Obfs of your remote server: plain,\n"); ++ printf( ++ " http_simple, http_post and tls1.2_ticket_auth.\n"); ++ printf( ++ " -g Obfs-Param of your remote server.\n"); ++ printf( ++ " -O Protocol of your remote server: orgin,\n"); ++ printf( ++ " auth_sha1, auth_sha1_v2, auth_sha1_v4,\n"); ++ printf( ++ " auth_aes128_md5, auth_aes128_sha1,\n"); ++ printf( ++ " auth_chain_a, auth_chain_b, auth_chain_c,\n"); ++ printf( ++ " auth_chain_d, auth_chain_e and auth_chain_f.\n"); ++ printf( ++ " -G Protocol-Param of your remote server.\n"); ++ printf("\n"); + printf( + " [-a ] Run as another user.\n"); + printf( +-- +2.19.1 + diff --git a/package/lean/shadowsocksr-libev/patches/999-Fix-Werror-sizeof-pointer-memaccess.patch b/package/lean/shadowsocksr-libev/patches/999-Fix-Werror-sizeof-pointer-memaccess.patch new file mode 100644 index 0000000000..9da0c52b99 --- /dev/null +++ b/package/lean/shadowsocksr-libev/patches/999-Fix-Werror-sizeof-pointer-memaccess.patch @@ -0,0 +1,11 @@ +--- a/src/local.c ++++ b/src/local.c +@@ -718,7 +718,7 @@ + + ss_free(hostname); + } else { +- strncpy(host, ip, sizeof(ip)); ++ strncpy(host, ip, INET6_ADDRSTRLEN); + } + } + diff --git a/package/lean/v2ray/Makefile b/package/lean/v2ray/Makefile new file mode 100644 index 0000000000..138ff75c9e --- /dev/null +++ b/package/lean/v2ray/Makefile @@ -0,0 +1,69 @@ +# +# Copyright (C) 2015-2016 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v3. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=v2ray +PKG_VERSION:=4.20 +PKG_RELEASE:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME) + SECTION:=net + CATEGORY:=Network + TITLE:=V2Ray is a cross-platform proxy software + DEPENDS:=+ca-certificates + URL:=https://github.com/v2ray/v2ray-core +endef + + +define Package/$(PKG_NAME)/description +V2Ray is a cross-platform proxy software +endef + +V2RAY_BIN:=v2ray + +ifeq ($(ARCH),x86_64) + PKG_ARCH_V2RAY:=amd64 +endif +ifeq ($(ARCH),mipsel) + PKG_ARCH_V2RAY:=mipsle +endif +ifeq ($(ARCH),mips) + PKG_ARCH_V2RAY:=mips +endif +ifeq ($(ARCH),i386) + PKG_ARCH_V2RAY:=x86 +endif +ifeq ($(ARCH),arm) + PKG_ARCH_V2RAY:=arm + ifneq ($(BOARD),bcm53xx) + V2RAY_BIN:=v2ray_armv7 + endif + ifeq ($(BOARD),kirkwood) + V2RAY_BIN:=v2ray + endif +endif +ifeq ($(ARCH),aarch64) + PKG_ARCH_V2RAY:=arm64 +endif + +define Build/Prepare +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/usr/bin/v2ray + $(INSTALL_BIN) ./files/$(PKG_ARCH_V2RAY)/$(V2RAY_BIN) $(1)/usr/bin/v2ray/v2ray +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/package/lean/v2ray/files/amd64/v2ray b/package/lean/v2ray/files/amd64/v2ray new file mode 100755 index 0000000000..5ae09fced5 Binary files /dev/null and b/package/lean/v2ray/files/amd64/v2ray differ diff --git a/package/lean/v2ray/files/arm/v2ray b/package/lean/v2ray/files/arm/v2ray new file mode 100755 index 0000000000..36b213b2ee Binary files /dev/null and b/package/lean/v2ray/files/arm/v2ray differ diff --git a/package/lean/v2ray/files/arm/v2ray_armv7 b/package/lean/v2ray/files/arm/v2ray_armv7 new file mode 100755 index 0000000000..23190110cd Binary files /dev/null and b/package/lean/v2ray/files/arm/v2ray_armv7 differ diff --git a/package/lean/v2ray/files/arm64/v2ray b/package/lean/v2ray/files/arm64/v2ray new file mode 100755 index 0000000000..9b4728d3ed Binary files /dev/null and b/package/lean/v2ray/files/arm64/v2ray differ diff --git a/package/lean/v2ray/files/mips/v2ray b/package/lean/v2ray/files/mips/v2ray new file mode 100755 index 0000000000..625f8d6ecd Binary files /dev/null and b/package/lean/v2ray/files/mips/v2ray differ diff --git a/package/lean/v2ray/files/mipsle/v2ray b/package/lean/v2ray/files/mipsle/v2ray new file mode 100755 index 0000000000..917b161c43 Binary files /dev/null and b/package/lean/v2ray/files/mipsle/v2ray differ diff --git a/package/lean/v2ray/files/x86/v2ray b/package/lean/v2ray/files/x86/v2ray new file mode 100755 index 0000000000..75b7cab72f Binary files /dev/null and b/package/lean/v2ray/files/x86/v2ray differ