ssr-switch 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #!/bin/sh /etc/rc.common
  2. #
  3. # Copyright (C) 2017 openwrt-ssr
  4. # Copyright (C) 2017 yushi studio <[email protected]>
  5. #
  6. # This is free software, licensed under the GNU General Public License v3.
  7. # See /LICENSE for more information.
  8. #
  9. LOCK_FILE="/var/lock/ssr-switch.lock"
  10. [ -f "$LOCK_FILE" ] && exit 2
  11. touch "$LOCK_FILE"
  12. cycle_time=60
  13. switch_time=3
  14. normal_flag=0
  15. server_locate=0
  16. server_count=0
  17. NAME=shadowsocksr
  18. ENABLE_SERVER=nil
  19. CONFIG_SWTICH_FILE=/var/etc/${NAME}_t.json
  20. [ -n "$1" ] && cycle_time=$1
  21. [ -n "$2" ] && switch_time=$2
  22. uci_get_by_name() {
  23. local ret=$(uci get $NAME.$1.$2 2>/dev/null)
  24. echo ${ret:=$3}
  25. }
  26. uci_get_by_type() {
  27. local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null)
  28. echo ${ret:=$3}
  29. }
  30. DEFAULT_SERVER=$(uci_get_by_type global global_server)
  31. CURRENT_SERVER=$DEFAULT_SERVER
  32. #解析ip
  33. get_host_ip() {
  34. local host=$1
  35. local isip=""
  36. local ip=$host
  37. isip=$(echo $host | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}")
  38. if [ -z "$isip" ]; then
  39. if [ "$host" != "${host#*:[0-9a-fA-F]}" ]; then
  40. ip=$host
  41. else
  42. local ip=$(resolveip -4 -t 3 $host | awk 'NR==1{print}')
  43. [ -z "$ip" ] && ip=$(wget -q -O- http://119.29.29.29/d?dn=$1 | awk -F ';' '{print $1}')
  44. fi
  45. fi
  46. echo ${ip:="ERROR"}
  47. }
  48. #判断代理是否正常
  49. check_proxy() {
  50. local result=0
  51. local try_count=$(uci_get_by_type global switch_try_count 3)
  52. for i in $(seq 1 $try_count); do
  53. /usr/bin/ssr-check www.google.com 80 $switch_time 1
  54. if [ "$?" == "0" ]; then
  55. # echo "$(date "+%Y-%m-%d %H:%M:%S") Check Google Proxy Success, count=$i" >> /tmp/ssrplus.log
  56. result=0
  57. break
  58. else
  59. # echo "$(date "+%Y-%m-%d %H:%M:%S") Check Google Proxy Fail, count=$i" >> /tmp/ssrplus.log
  60. /usr/bin/ssr-check www.baidu.com 80 $switch_time 1
  61. if [ "$?" == "0" ]; then
  62. result=1
  63. else
  64. result=2
  65. fi
  66. fi
  67. sleep 1
  68. done
  69. return $result
  70. }
  71. test_proxy() {
  72. local servername=$(get_host_ip $(uci_get_by_name $1 server))
  73. local serverport=$(uci_get_by_name $1 server_port)
  74. ipset add ss_spec_wan_ac $servername 2>/dev/null
  75. ret1=$?
  76. ret=$(tcpping -c 3 -p $serverport $servername | grep 'loss' | awk -F ',' '{ print $3 }' | awk -F "%" '{ print $1 }' | awk -F "." '{ print $1 }')
  77. #echo "$(date "+%Y-%m-%d %H:%M:%S") test_proxy> name: $servername, ret1: $ret1, ret: $ret" >> /tmp/ssrplus.log
  78. if [ -z "$ret" ] || [ "$ret" -gt "50" ]; then
  79. [ "$ret1" == "0" ] && ipset del ss_spec_wan_ac $servername 2>/dev/null
  80. return 1
  81. fi
  82. /usr/bin/ssr-check $servername $serverport $switch_time
  83. local ret2=$?
  84. [ "$ret1" == "0" ] && ipset del ss_spec_wan_ac $servername 2>/dev/null
  85. if [ "$ret2" == "0" ]; then
  86. return 0
  87. else
  88. return 1
  89. fi
  90. }
  91. search_proxy() {
  92. let server_count=server_count+1
  93. [ "$normal_flag" == "1" -a "$server_count" -le "$server_locate" ] && return 0
  94. [ "$(uci_get_by_name $1 switch_enable 0)" != "1" ] && return 1
  95. [ $ENABLE_SERVER != nil ] && return 0
  96. [ "$1" == "$CURRENT_SERVER" ] && return 0
  97. local servername=$(get_host_ip $(uci_get_by_name $1 server))
  98. local serverport=$(uci_get_by_name $1 server_port)
  99. ipset add ss_spec_wan_ac $servername 2>/dev/null
  100. ret=$?
  101. /usr/bin/ssr-check $servername $serverport $switch_time
  102. local ret2=$?
  103. [ "$ret" == "0" ] && ipset del ss_spec_wan_ac $servername 2>/dev/null
  104. if [ "$ret2" == "0" ]; then
  105. server_locate=$server_count
  106. ENABLE_SERVER=$1
  107. return 0
  108. else
  109. return 1
  110. fi
  111. }
  112. #选择可用的代理
  113. select_proxy() {
  114. config_load $NAME
  115. ENABLE_SERVER=nil
  116. mkdir -p /var/run /var/etc
  117. server_count=0
  118. config_foreach search_proxy servers
  119. }
  120. #切换代理
  121. switch_proxy() {
  122. /etc/init.d/shadowsocksr restart $1
  123. return 0
  124. }
  125. start() {
  126. #不支持kcptun启用时的切换
  127. [ $(uci_get_by_name $DEFAULT_SERVER kcp_enable) = "1" ] && return 1
  128. while [ "1" == "1" ]; do #死循环
  129. sleep $cycle_time
  130. LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")
  131. #判断当前代理是否为缺省服务器
  132. if [ "$CURRENT_SERVER" != "$DEFAULT_SERVER" ]; then
  133. #echo "not default proxy"
  134. echo "$(date "+%Y-%m-%d %H:%M:%S") Current server is not default Main server, try to switch back." >>/tmp/ssrplus.log
  135. #检查缺省服务器是否正常
  136. if test_proxy $DEFAULT_SERVER; then
  137. #echo "switch to default proxy"
  138. echo "$(date "+%Y-%m-%d %H:%M:%S") Main server is avilable." >>/tmp/ssrplus.log
  139. #缺省服务器正常,切换回来
  140. CURRENT_SERVER=$DEFAULT_SERVER
  141. switch_proxy $CURRENT_SERVER
  142. echo "$(date "+%Y-%m-%d %H:%M:%S") switch to default "$(uci_get_by_name $CURRENT_SERVER alias)" proxy!" >>/tmp/ssrplus.log
  143. else
  144. echo "$(date "+%Y-%m-%d %H:%M:%S") Main server is NOT avilable.Continue using current server." >>/tmp/ssrplus.log
  145. fi
  146. fi
  147. #判断当前代理是否正常
  148. #echo "$(date "+%Y-%m-%d %H:%M:%S") Start checking if the current server is available." >>/tmp/ssrplus.log
  149. check_proxy
  150. current_ret=$?
  151. if [ "$current_ret" == "1" ]; then
  152. #当前代理错误,判断有无可用的服务器
  153. #echo "current error"
  154. echo "$(date "+%Y-%m-%d %H:%M:%S") Current server error, try to switch another server." >>/tmp/ssrplus.log
  155. select_proxy
  156. if [ "$ENABLE_SERVER" != nil ]; then
  157. #有其他服务器可用,进行切换
  158. #echo $(uci_get_by_name $new_proxy server)
  159. echo "$(date "+%Y-%m-%d %H:%M:%S") Another server is avilable, now switching server." >>/tmp/ssrplus.log
  160. CURRENT_SERVER=$ENABLE_SERVER
  161. switch_proxy $CURRENT_SERVER
  162. normal_flag=1
  163. echo "$(date "+%Y-%m-%d %H:%M:%S") Switch to "$(uci_get_by_name $CURRENT_SERVER alias)" proxy!" >>/tmp/ssrplus.log
  164. else
  165. switch_proxy $CURRENT_SERVER
  166. normal_flag=1
  167. echo "$(date "+%Y-%m-%d %H:%M:%S") Try restart current server." >>/tmp/ssrplus.log
  168. fi
  169. else
  170. normal_flag=0
  171. # echo "$(date "+%Y-%m-%d %H:%M:%S") ShadowsocksR No Problem." >>/tmp/ssrplus.log
  172. fi
  173. done
  174. }