From 6d8320550b1066bc55b967053654be48baa3d796 Mon Sep 17 00:00:00 2001 From: coolsnowwolf Date: Sun, 12 Nov 2023 13:51:42 +0800 Subject: [PATCH] Revert "luci-app-ssr-plus: `mosdns` switch config file to json format (#1326)" This reverts commit 4dbd29ee826613294d434d06ea49a8ee93349413. --- luci-app-ssr-plus/Makefile | 4 +- .../root/etc/init.d/shadowsocksr | 57 +++-- .../etc/ssrplus/mosdns-config-chinadns.json | 202 ------------------ .../etc/ssrplus/mosdns-config-chinadns.yaml | 154 +++++++++++++ .../root/etc/ssrplus/mosdns-config.json | 71 ------ .../root/etc/ssrplus/mosdns-config.yaml | 41 ++++ 6 files changed, 225 insertions(+), 304 deletions(-) delete mode 100644 luci-app-ssr-plus/root/etc/ssrplus/mosdns-config-chinadns.json create mode 100644 luci-app-ssr-plus/root/etc/ssrplus/mosdns-config-chinadns.yaml delete mode 100644 luci-app-ssr-plus/root/etc/ssrplus/mosdns-config.json create mode 100644 luci-app-ssr-plus/root/etc/ssrplus/mosdns-config.yaml diff --git a/luci-app-ssr-plus/Makefile b/luci-app-ssr-plus/Makefile index d2ae4c74c63..33173f39157 100644 --- a/luci-app-ssr-plus/Makefile +++ b/luci-app-ssr-plus/Makefile @@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-ssr-plus PKG_VERSION:=190 -PKG_RELEASE:=2 +PKG_RELEASE:=1 PKG_CONFIG_DEPENDS:= \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY \ @@ -42,7 +42,7 @@ LUCI_DEPENDS:= \ +PACKAGE_$(PKG_NAME)_INCLUDE_Xray:xray-core \ +PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG:chinadns-ng \ +PACKAGE_$(PKG_NAME)_INCLUDE_MosDNS:mosdns \ - +PACKAGE_$(PKG_NAME)_INCLUDE_MosDNS:jq \ + +PACKAGE_$(PKG_NAME)_INCLUDE_MosDNS:yq \ +PACKAGE_$(PKG_NAME)_INCLUDE_MosDNS:v2dat \ +PACKAGE_$(PKG_NAME)_INCLUDE_MosDNS:diffutils \ +PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria:hysteria \ diff --git a/luci-app-ssr-plus/root/etc/init.d/shadowsocksr b/luci-app-ssr-plus/root/etc/init.d/shadowsocksr index 9a8a843707b..e28483d512f 100755 --- a/luci-app-ssr-plus/root/etc/init.d/shadowsocksr +++ b/luci-app-ssr-plus/root/etc/init.d/shadowsocksr @@ -99,9 +99,9 @@ get_host_ip() { echo $ip } -jq_ssr() { +yq_ssr() { temp_file="$(echo "$2" | awk -F '.' '{print $1"-temp."$2}')" - cat $2 | jq "$1" > "$temp_file" + cat $2 | yq e "$1" -M > "$temp_file" mv "$temp_file" "$2" } @@ -219,45 +219,45 @@ start_dns() { local mosdns_dnsleak="$(uci_get_by_type global mosdns_dnsleak)" local netflix_enable="$(uci_get_by_type global netflix_enable)" if [ "$run_mode" = "router" ] && [ -n "$chinadns_mosdns" ]; then - mosdns_config_file="$TMP_PATH/mosdns-config-chinadns.json" - cp /etc/ssrplus/mosdns-config-chinadns.json $mosdns_config_file + mosdns_config_file="$TMP_PATH/mosdns-config-chinadns.yaml" + cp /etc/ssrplus/mosdns-config-chinadns.yaml $mosdns_config_file tmp=$(for i in $(echo $mosdns_dnsserver | sed "s/,/ /g"); do dnsserver=${i%:*} dnsserver=${i##*/} add_dns_into_ipset $run_mode $dnsserver - jq_ssr '.plugins[4].args.upstreams += [{"addr":"'"${i}"'","enable_pipeline":"true"}]' $mosdns_config_file + yq_ssr '.plugins[4].args.upstreams += [{"addr":"'"${i}"'","enable_pipeline":"true"}]' $mosdns_config_file done) if [ "$chinadns_mosdns" = "wan" ]; then wandns=$(ifstatus wan | jsonfilter -e '@["dns-server"]' | sed 's/\[//g; s/\]//g' | sed 's/"//g' | sed 's/ //g' | sed 's/,/ /g') tmp=$(for i in $(echo $wandns); do i="udp://$i:53" - jq_ssr '.plugins[5].args.upstreams += [{"addr":"'"${i}"'"}]' $mosdns_config_file + yq_ssr '.plugins[5].args.upstreams += [{"addr":"'"${i}"'"}]' $mosdns_config_file done) else tmp=$(for i in $(echo $chinadns_mosdns | sed "s/,/ /g"); do - jq_ssr '.plugins[5].args.upstreams += [{"addr":"'"${i}"'"}]' $mosdns_config_file + yq_ssr '.plugins[5].args.upstreams += [{"addr":"'"${i}"'"}]' $mosdns_config_file done) fi if [ "$mosdns_disable_ipv6" == "0" ]; then - jq_ssr '.plugins[10].args[0].exec="$remote_sequence_with_IPv6" | .plugins[12].args[0].exec="$remote_sequence_with_IPv6"' $mosdns_config_file + yq_ssr '.plugins[10].args[0].exec="$remote_sequence_with_IPv6" | .plugins[12].args[0].exec="$remote_sequence_with_IPv6"' $mosdns_config_file else - jq_ssr '.plugins[10].args[0].exec="$remote_sequence_disable_IPv6" | .plugins[12].args[0].exec="$remote_sequence_disable_IPv6"' $mosdns_config_file + yq_ssr '.plugins[10].args[0].exec="$remote_sequence_disable_IPv6" | .plugins[12].args[0].exec="$remote_sequence_disable_IPv6"' $mosdns_config_file fi if [ "$mosdns_dnsleak" != "0" ]; then - jq_ssr '.plugins[13].args.primary="query_is_remote_ip"' $mosdns_config_file + yq_ssr '.plugins[13].args.primary="query_is_remote_ip"' $mosdns_config_file fi - jq_ssr '.plugins[16].args.listen="0.0.0.0:'${dns_port}'" | .plugins[17].args.listen="0.0.0.0:'${dns_port}'"' $mosdns_config_file + yq_ssr '.plugins[16].args.listen="0.0.0.0:'${dns_port}'" | .plugins[17].args.listen="0.0.0.0:'${dns_port}'"' $mosdns_config_file if [ "$netflix_enable" == 1 ]; then - jq_ssr '.plugins |= (.[:4] + [{"tag": "netflix_domain", "type": "domain_set", "args": {"files": ["/etc/ssrplus/netflix.list"]}}] + .[4:])' $mosdns_config_file - jq_ssr '.plugins |= (.[:7] + [{"tag": "forward_netflix", "type": "forward", "args": {"upstreams": [{"addr":"udp://127.0.0.1:'"${tmp_shunt_dns_port}"'"}]}}] + .[7:])' $mosdns_config_file - jq_ssr '.plugins |= (.[:11] + [{"tag": "netflix_sequence", "type": "sequence", "args": [{"exec": "$forward_netflix"}]}] + .[11:])' $mosdns_config_file - jq_ssr '.plugins |= (.[:14] + [{"tag": "query_is_netflix_domain", "type": "sequence", "args": [{"matches": "qname $netflix_domain", "exec": "$netflix_sequence"}, {"exec": "ipset netflix,inet,24"}]}] + .[14:])' $mosdns_config_file - jq_ssr '.plugins[19].args |= (.[:3] + [{"exec": "$query_is_netflix_domain"}, {"exec": "jump has_resp_sequence"}] + .[3:])' $mosdns_config_file + yq_ssr '.plugins |= (.[:4] + [{"tag": "netflix_domain", "type": "domain_set", "args": {"files": ["/etc/ssrplus/netflix.list"]}}] + .[4:])' $mosdns_config_file + yq_ssr '.plugins |= (.[:7] + [{"tag": "forward_netflix", "type": "forward", "args": {"upstreams": [{"addr":"udp://127.0.0.1:'"${tmp_shunt_dns_port}"'"}]}}] + .[7:])' $mosdns_config_file + yq_ssr '.plugins |= (.[:11] + [{"tag": "netflix_sequence", "type": "sequence", "args": [{"exec": "$forward_netflix"}]}] + .[11:])' $mosdns_config_file + yq_ssr '.plugins |= (.[:14] + [{"tag": "query_is_netflix_domain", "type": "sequence", "args": [{"matches": "qname $netflix_domain", "exec": "$netflix_sequence"}, {"exec": "ipset netflix,inet,24"}]}] + .[14:])' $mosdns_config_file + yq_ssr '.plugins[19].args |= (.[:3] + [{"exec": "$query_is_netflix_domain"}, {"exec": "jump has_resp_sequence"}] + .[3:])' $mosdns_config_file fi pdnsd_enable_flag=3 @@ -268,21 +268,21 @@ start_dns() { server=127.0.0.1#$dns_port EOF else - mosdns_config_file="$TMP_PATH/mosdns-config.json" - cp /etc/ssrplus/mosdns-config.json $mosdns_config_file + mosdns_config_file="$TMP_PATH/mosdns-config.yaml" + cp /etc/ssrplus/mosdns-config.yaml $mosdns_config_file tmp=$(for i in $(echo $mosdns_dnsserver | sed "s/,/ /g"); do dnsserver=${i%:*} dnsserver=${i##*/} add_dns_into_ipset $run_mode $dnsserver - jq_ssr '.plugins[1].args.upstreams += [{"addr":"'"${i}"'","enable_pipeline":"true"}]' $mosdns_config_file + yq_ssr '.plugins[1].args.upstreams += [{"addr":"'"${i}"'","enable_pipeline":"true"}]' $mosdns_config_file done) if [ "$mosdns_disable_ipv6" == "0" ]; then - jq_ssr '.plugins[4].args.entry="main_sequence_with_IPv6" | .plugins[5].args.entry="main_sequence_with_IPv6"' $mosdns_config_file + yq_ssr '.plugins[4].args.entry="main_sequence_with_IPv6" | .plugins[5].args.entry="main_sequence_with_IPv6"' $mosdns_config_file else - jq_ssr '.plugins[4].args.entry="main_sequence_disable_IPv6" | .plugins[5].args.entry="main_sequence_disable_IPv6"' $mosdns_config_file + yq_ssr '.plugins[4].args.entry="main_sequence_disable_IPv6" | .plugins[5].args.entry="main_sequence_disable_IPv6"' $mosdns_config_file fi - jq_ssr '.plugins[4].args.listen="0.0.0.0:'${dns_port}'" | .plugins[5].args.listen="0.0.0.0:'${dns_port}'"' $mosdns_config_file + yq_ssr '.plugins[4].args.listen="0.0.0.0:'${dns_port}'" | .plugins[5].args.listen="0.0.0.0:'${dns_port}'"' $mosdns_config_file pdnsd_enable_flag=3 ln_start_bin $(first_type mosdns) mosdns start -c $mosdns_config_file fi @@ -551,19 +551,18 @@ shunt_dns_command() { 2) local shunt_mosdns_disable_ipv6="$(uci_get_by_type global shunt_mosdns_disable_ipv6)" local shunt_mosdns_dnsserver="$(uci_get_by_type global shunt_mosdns_dnsserver)" - mosdns_shunt_config_file="$TMP_PATH/mosdns-config-shunt.json" - cp /etc/ssrplus/mosdns-config.json $mosdns_shunt_config_file + cp /etc/ssrplus/mosdns-config.yaml $TMP_PATH/mosdns-config-shunt.yaml tmp=$(for i in $(echo $shunt_mosdns_dnsserver | sed "s/,/ /g"); do - jq_ssr '.plugins[1].args.upstreams += [{"addr":"'"${i}"'","socks5":"127.0.0.1:'"${tmp_port}"'","enable_pipeline":"true"}]' $mosdns_shunt_config_file + yq_ssr '.plugins[1].args.upstreams += [{"addr":"'"${i}"'","socks5":"127.0.0.1:'"${tmp_port}"'","enable_pipeline":"true"}]' $TMP_PATH/mosdns-config-shunt.yaml done) if [ "$shunt_mosdns_disable_ipv6" == "0" ]; then - jq_ssr '.plugins[4].args.entry="main_sequence_with_IPv6" | .plugins[5].args.entry="main_sequence_with_IPv6"' $mosdns_shunt_config_file + yq_ssr '.plugins[4].args.entry="main_sequence_with_IPv6" | .plugins[5].args.entry="main_sequence_with_IPv6"' $TMP_PATH/mosdns-config-shunt.yaml else - jq_ssr '.plugins[4].args.entry="main_sequence_disable_IPv6" | .plugins[5].args.entry="main_sequence_disable_IPv6"' $mosdns_shunt_config_file + yq_ssr '.plugins[4].args.entry="main_sequence_disable_IPv6" | .plugins[5].args.entry="main_sequence_disable_IPv6"' $TMP_PATH/mosdns-config-shunt.yaml fi - jq_ssr '.plugins[4].args.listen="0.0.0.0:'${tmp_shunt_dns_port}'" | .plugins[5].args.listen="0.0.0.0:'${tmp_shunt_dns_port}'"' $mosdns_shunt_config_file - ln_start_bin $(first_type mosdns) mosdns start -c $mosdns_shunt_config_file + yq_ssr '.plugins[4].args.listen="0.0.0.0:'${tmp_shunt_dns_port}'" | .plugins[5].args.listen="0.0.0.0:'${tmp_shunt_dns_port}'"' $TMP_PATH/mosdns-config-shunt.yaml + ln_start_bin $(first_type mosdns) mosdns start -c $TMP_PATH/mosdns-config-shunt.yaml ;; esac } diff --git a/luci-app-ssr-plus/root/etc/ssrplus/mosdns-config-chinadns.json b/luci-app-ssr-plus/root/etc/ssrplus/mosdns-config-chinadns.json deleted file mode 100644 index 4524ed0fdfa..00000000000 --- a/luci-app-ssr-plus/root/etc/ssrplus/mosdns-config-chinadns.json +++ /dev/null @@ -1,202 +0,0 @@ -{ - "log": { - "level": "info" - }, - "plugins": [ - { - "tag": "lazy_cache", - "type": "cache", - "args": { - "size": 20000, - "lazy_cache_ttl": 86400 - } - }, - { - "tag": "geosite_cn", - "type": "domain_set", - "args": { - "files": [ - "/etc/ssrplus/mosdns-chinadns/geosite_cn.txt", - "/etc/ssrplus/white.list" - ] - } - }, - { - "tag": "geoip_cn", - "type": "ip_set", - "args": { - "files": [ - "/etc/ssrplus/china_ssr.txt" - ] - } - }, - { - "tag": "geosite_not_cn", - "type": "domain_set", - "args": { - "files": [ - "/etc/ssrplus/mosdns-chinadns/geosite_geolocation_not_cn.txt", - "/etc/ssrplus/black.list" - ] - } - }, - { - "tag": "forward_remote", - "type": "forward", - "args": { - "concurrent": 2, - "upstreams": null - } - }, - { - "tag": "forward_local", - "type": "forward", - "args": { - "concurrent": 2, - "upstreams": null - } - }, - { - "tag": "local_sequence", - "type": "sequence", - "args": [ - { - "exec": "$forward_local" - } - ] - }, - { - "tag": "remote_sequence_with_IPv6", - "type": "sequence", - "args": [ - { - "exec": "$forward_remote" - } - ] - }, - { - "tag": "remote_sequence_disable_IPv6", - "type": "sequence", - "args": [ - { - "exec": "prefer_ipv4" - }, - { - "exec": "$forward_remote" - }, - { - "matches": [ - "qtype 28 65" - ], - "exec": "reject 0" - } - ] - }, - { - "tag": "query_is_local_domain", - "type": "sequence", - "args": [ - { - "matches": "qname $geosite_cn", - "exec": "$local_sequence" - } - ] - }, - { - "tag": "query_is_proxy_domain", - "type": "sequence", - "args": [ - { - "matches": "qname $geosite_not_cn" - }, - { - "exec": "ipset blacklist,inet,24" - } - ] - }, - { - "tag": "query_is_local_ip", - "type": "sequence", - "args": [ - { - "exec": "$local_sequence" - }, - { - "matches": "!resp_ip $geoip_cn", - "exec": "drop_resp" - } - ] - }, - { - "tag": "query_is_remote_ip", - "type": "sequence", - "args": [ - { - "exec": "$remote_sequence_disable_IPv6" - }, - { - "exec": "ipset blacklist,inet,24" - } - ] - }, - { - "tag": "fallback", - "type": "fallback", - "args": { - "primary": "query_is_local_ip", - "secondary": "query_is_remote_ip", - "threshold": 600, - "always_standby": true - } - }, - { - "tag": "has_resp_sequence", - "type": "sequence", - "args": [ - { - "matches": "has_resp", - "exec": "accept" - } - ] - }, - { - "tag": "main_sequence", - "type": "sequence", - "args": [ - { - "exec": "$lazy_cache" - }, - { - "exec": "$query_is_local_domain" - }, - { - "exec": "jump has_resp_sequence" - }, - { - "exec": "$query_is_proxy_domain" - }, - { - "exec": "jump has_resp_sequence" - }, - { - "exec": "$fallback" - } - ] - }, - { - "tag": "udp_server", - "type": "udp_server", - "args": { - "entry": "main_sequence" - } - }, - { - "tag": "tcp_server", - "type": "tcp_server", - "args": { - "entry": "main_sequence" - } - } - ] -} - diff --git a/luci-app-ssr-plus/root/etc/ssrplus/mosdns-config-chinadns.yaml b/luci-app-ssr-plus/root/etc/ssrplus/mosdns-config-chinadns.yaml new file mode 100644 index 00000000000..5d0c8a0444a --- /dev/null +++ b/luci-app-ssr-plus/root/etc/ssrplus/mosdns-config-chinadns.yaml @@ -0,0 +1,154 @@ +# Author: sbwml +# Origin from repository: https://github.com/sbwml/luci-app-mosdns +# Reference: https://github.com/sbwml/luci-app-mosdns/blob/v5/luci-app-mosdns/root/usr/share/mosdns/default.yaml +# Modify by: XiaoliChan +log: + level: info +plugins: + # Num0: Cache + - tag: lazy_cache + type: cache + args: + size: 20000 + lazy_cache_ttl: 86400 + + # Num1: CN domain + # https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/release/direct-list.txt + # cat direct-list.txt | grep -v "regexp:\|full:" | sort -u | uniq -u > china-domain-2.lst + - tag: geosite_cn + type: domain_set + args: + files: + - "/etc/ssrplus/mosdns-chinadns/geosite_cn.txt" + - "/etc/ssrplus/white.list" + + # Num2: CN IP + # https://raw.githubusercontent.com/Hackl0us/GeoIP2-CN/release/CN-ip-cidr.txt + - tag: geoip_cn + type: ip_set + args: + files: + - "/etc/ssrplus/china_ssr.txt" + + # Num3: Domain need proxy (gfwlist) + # https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/release/proxy-list.txt + # https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/release/gfw.txt + - tag: geosite_not_cn + type: domain_set + args: + files: + - "/etc/ssrplus/mosdns-chinadns/geosite_geolocation_not_cn.txt" + - "/etc/ssrplus/black.list" + + # Num4: Forward to google + - tag: forward_remote + type: forward + args: + concurrent: 2 + upstreams: + + # Num5: Forward to local + # ifstatus wan | jsonfilter -e '@["dns-server"]' + - tag: forward_local + type: forward + args: + concurrent: 2 + upstreams: + + # Num6 + - tag: local_sequence + type: sequence + args: + - exec: $forward_local + + # Num7 + - tag: remote_sequence_with_IPv6 + type: sequence + args: + - exec: prefer_ipv4 + - exec: $forward_remote + + # Num8 + - tag: remote_sequence_disable_IPv6 + type: sequence + args: + - exec: prefer_ipv4 + - exec: $forward_remote + - matches: + - qtype 28 65 + exec: reject 0 + + # Num9 + - tag: query_is_local_domain + type: sequence + args: + - matches: qname $geosite_cn + exec: $local_sequence + + # Num10 + - tag: query_is_proxy_domain + type: sequence + args: + - matches: qname $geosite_not_cn + - exec: ipset blacklist,inet,24 + + # fallback 用本地服务器 sequence + # 返回非国内 ip 则 drop_resp + # Num11 + - tag: query_is_local_ip + type: sequence + args: + - exec: $local_sequence + - matches: "!resp_ip $geoip_cn" + exec: drop_resp + + # Num12 + # fallback 用远程服务器 sequence + - tag: query_is_remote_ip + type: sequence + args: + - exec: $remote_sequence_disable_IPv6 + - exec: ipset blacklist,inet,24 + + # fallback 用远程服务器 sequence + # query_is_local_ip to query_is_remote_ip + # Num13 + - tag: fallback + type: fallback + args: + # DNS Leak solution + primary: query_is_local_ip + secondary: query_is_remote_ip + threshold: 600 + always_standby: true + + # 有响应终止返回 + # Num14 + - tag: has_resp_sequence + type: sequence + args: + - matches: has_resp + exec: accept + + # Num15 + - tag: main_sequence + type: sequence + args: + - exec: $lazy_cache + - exec: $query_is_local_domain + - exec: jump has_resp_sequence + - exec: $query_is_proxy_domain + - exec: jump has_resp_sequence + - exec: $fallback + + # Num16 + - tag: udp_server + type: udp_server + args: + entry: main_sequence + + # Num17 + - tag: tcp_server + type: tcp_server + args: + entry: main_sequence diff --git a/luci-app-ssr-plus/root/etc/ssrplus/mosdns-config.json b/luci-app-ssr-plus/root/etc/ssrplus/mosdns-config.json deleted file mode 100644 index 353c75fe77e..00000000000 --- a/luci-app-ssr-plus/root/etc/ssrplus/mosdns-config.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "log": { - "level": "info" - }, - "plugins": [ - { - "tag": "lazy_cache", - "type": "cache", - "args": { - "size": 8000, - "lazy_cache_ttl": 86400 - } - }, - { - "tag": "forward_google", - "type": "forward", - "args": { - "concurrent": 2, - "upstreams": null - } - }, - { - "tag": "main_sequence_disable_IPv6", - "type": "sequence", - "args": [ - { - "exec": "$lazy_cache" - }, - { - "exec": "prefer_ipv4" - }, - { - "exec": "$forward_google" - }, - { - "matches": [ - "qtype 28 65" - ], - "exec": "reject 0" - } - ] - }, - { - "tag": "main_sequence_with_IPv6", - "type": "sequence", - "args": [ - { - "exec": "$lazy_cache" - }, - { - "exec": "$forward_google" - } - ] - }, - { - "tag": "udp_server", - "type": "udp_server", - "args": { - "entry": "DNS_MODE" - } - }, - { - "tag": "tcp_server", - "type": "tcp_server", - "args": { - "entry": "DNS_MODE" - } - } - ] -} - diff --git a/luci-app-ssr-plus/root/etc/ssrplus/mosdns-config.yaml b/luci-app-ssr-plus/root/etc/ssrplus/mosdns-config.yaml new file mode 100644 index 00000000000..00facaa76c4 --- /dev/null +++ b/luci-app-ssr-plus/root/etc/ssrplus/mosdns-config.yaml @@ -0,0 +1,41 @@ +log: + level: info +plugins: + - tag: lazy_cache + type: cache + args: + size: 8000 + lazy_cache_ttl: 86400 + + - tag: forward_google + type: forward + args: + concurrent: 2 + upstreams: + + - tag: main_sequence_disable_IPv6 + type: sequence + args: + - exec: $lazy_cache + - exec: prefer_ipv4 + - exec: $forward_google + - matches: + - qtype 28 65 + exec: reject 0 + + - tag: main_sequence_with_IPv6 + type: sequence + args: + - exec: $lazy_cache + - exec: $forward_google + + - tag: udp_server + type: udp_server + args: + entry: DNS_MODE + + - tag: tcp_server + type: tcp_server + args: + entry: DNS_MODE +