support hysteria2

This commit is contained in:
arm64v8a 2023-09-04 20:53:49 +09:00
parent eab03deb2c
commit 3f7d39a9d9
16 changed files with 702 additions and 127 deletions

View File

@ -78,6 +78,8 @@ object Key {
const val SERVER_METHOD = "serverMethod"
const val SERVER_PASSWORD1 = "serverPassword1"
const val PROTOCOL_VERSION = "protocolVersion"
const val SERVER_PROTOCOL = "serverProtocol"
const val SERVER_OBFS = "serverObfs"

View File

@ -206,7 +206,9 @@ object DataStore : OnPreferenceDataStoreChangeListener {
var serverDisableMtuDiscovery by profileCacheStore.boolean(Key.SERVER_DISABLE_MTU_DISCOVERY)
var serverHopInterval by profileCacheStore.stringToInt(Key.SERVER_HOP_INTERVAL) { 10 }
var serverProtocolVersion by profileCacheStore.stringToInt(Key.SERVER_PROTOCOL)
var protocolVersion by profileCacheStore.stringToInt(Key.PROTOCOL_VERSION)
var serverProtocolInt by profileCacheStore.stringToInt(Key.SERVER_PROTOCOL)
var serverPrivateKey by profileCacheStore.string(Key.SERVER_PRIVATE_KEY)
var serverInsecureConcurrency by profileCacheStore.stringToInt(Key.SERVER_INSECURE_CONCURRENCY)

View File

@ -385,7 +385,7 @@ fun buildConfig(
buildSingBoxOutboundStandardV2RayBean(bean).asMap()
is HysteriaBean ->
buildSingBoxOutboundHysteriaBean(bean).asMap()
buildSingBoxOutboundHysteriaBean(bean)
is TuicBean ->
buildSingBoxOutboundTuicBean(bean).asMap()

View File

@ -13,25 +13,17 @@ import io.nekohasekai.sagernet.ktx.NetsKt;
import kotlin.text.StringsKt;
public class HysteriaBean extends AbstractBean {
public Integer protocolVersion;
public static final int TYPE_NONE = 0;
public static final int TYPE_STRING = 1;
public static final int TYPE_BASE64 = 2;
// Use serverPorts instead of serverPort
public String serverPorts;
// HY1 & 2
public Integer authPayloadType;
public String authPayload;
public static final int PROTOCOL_UDP = 0;
public static final int PROTOCOL_FAKETCP = 1;
public static final int PROTOCOL_WECHAT_VIDEO = 2;
public Integer protocol;
public String obfuscation;
public String sni;
public String alpn;
public String caText;
public Integer uploadMbps;
public Integer downloadMbps;
public Boolean allowInsecure;
@ -40,7 +32,19 @@ public class HysteriaBean extends AbstractBean {
public Boolean disableMtuDiscovery;
public Integer hopInterval;
public String serverPorts;
// HY1
public String alpn;
public static final int TYPE_NONE = 0;
public static final int TYPE_STRING = 1;
public static final int TYPE_BASE64 = 2;
public Integer authPayloadType;
public static final int PROTOCOL_UDP = 0;
public static final int PROTOCOL_FAKETCP = 1;
public static final int PROTOCOL_WECHAT_VIDEO = 2;
public Integer protocol;
@Override
public boolean canMapping() {
@ -50,6 +54,8 @@ public class HysteriaBean extends AbstractBean {
@Override
public void initializeDefaultValues() {
super.initializeDefaultValues();
if (protocolVersion == null) protocolVersion = 2;
if (authPayloadType == null) authPayloadType = TYPE_NONE;
if (authPayload == null) authPayload = "";
if (protocol == null) protocol = PROTOCOL_UDP;
@ -57,11 +63,16 @@ public class HysteriaBean extends AbstractBean {
if (sni == null) sni = "";
if (alpn == null) alpn = "";
if (caText == null) caText = "";
if (uploadMbps == null) uploadMbps = 10;
if (downloadMbps == null) downloadMbps = 50;
if (allowInsecure == null) allowInsecure = false;
if (protocolVersion == 1) {
if (uploadMbps == null) uploadMbps = 10;
if (downloadMbps == null) downloadMbps = 50;
} else {
if (uploadMbps == null) uploadMbps = 0;
if (downloadMbps == null) downloadMbps = 0;
}
if (streamReceiveWindow == null) streamReceiveWindow = 0;
if (connectionReceiveWindow == null) connectionReceiveWindow = 0;
if (disableMtuDiscovery == null) disableMtuDiscovery = false;
@ -71,8 +82,11 @@ public class HysteriaBean extends AbstractBean {
@Override
public void serialize(ByteBufferOutput output) {
output.writeInt(6);
output.writeInt(7);
super.serialize(output);
output.writeInt(protocolVersion);
output.writeInt(authPayloadType);
output.writeString(authPayload);
output.writeInt(protocol);
@ -90,13 +104,17 @@ public class HysteriaBean extends AbstractBean {
output.writeBoolean(disableMtuDiscovery);
output.writeInt(hopInterval);
output.writeString(serverPorts);
}
@Override
public void deserialize(ByteBufferInput input) {
int version = input.readInt();
super.deserialize(input);
if (version >= 7) {
protocolVersion = input.readInt();
} else {
protocolVersion = 1;
}
authPayloadType = input.readInt();
authPayload = input.readString();
if (version >= 3) {

View File

@ -11,12 +11,15 @@ import java.io.File
// hysteria://host:port?auth=123456&peer=sni.domain&insecure=1|0&upmbps=100&downmbps=100&alpn=hysteria&obfs=xplus&obfsParam=123456#remarks
fun parseHysteria(url: String): HysteriaBean {
if (url.startsWith("hysteria2:") || url.startsWith("hy2:")) {
return parseHysteria2(url)
}
val link = url.replace("hysteria://", "https://").toHttpUrlOrNull() ?: error(
"invalid hysteria link $url"
)
return HysteriaBean().apply {
protocolVersion = 1
serverAddress = link.host
serverPorts = link.port.toString()
name = link.fragment
@ -60,51 +63,114 @@ fun parseHysteria(url: String): HysteriaBean {
}
}
// hysteria2://[auth@]hostname[:port]/?[key=value]&[key=value]...
fun parseHysteria2(url: String): HysteriaBean {
val link = url
.replace("hysteria2://", "https://")
.replace("hy2://", "https://")
.toHttpUrlOrNull() ?: error("invalid hysteria link $url")
return HysteriaBean().apply {
protocolVersion = 2
serverAddress = link.host
serverPorts = link.port.toString()
authPayload = if (link.password.isNotBlank()) {
link.username + ":" + link.password
} else {
link.username
}
name = link.fragment
link.queryParameter("mport")?.also {
serverPorts = it
}
link.queryParameter("sni")?.also {
sni = it
}
link.queryParameter("insecure")?.also {
allowInsecure = it == "1"
}
// link.queryParameter("upmbps")?.also {
// uploadMbps = it.toIntOrNull() ?: uploadMbps
// }
// link.queryParameter("downmbps")?.also {
// downloadMbps = it.toIntOrNull() ?: downloadMbps
// }
link.queryParameter("obfs-password")?.also {
obfuscation = it
}
link.queryParameter("pinSHA256")?.also {
// TODO your box do not support it
}
}
}
fun HysteriaBean.toUri(): String {
var un = ""
var pw = ""
if (protocolVersion == 2) {
if (authPayload.contains(":")) {
un = authPayload.substringBefore(":")
pw = authPayload.substringAfter(":")
} else {
un = authPayload
}
}
//
val builder = linkBuilder()
.host(serverAddress)
.port(getFirstPort(serverPorts))
.username(un)
.password(pw)
if (isMultiPort(displayAddress())) {
builder.addQueryParameter("mport", serverPorts)
}
if (allowInsecure) {
builder.addQueryParameter("insecure", "1")
}
if (sni.isNotBlank()) {
builder.addQueryParameter("peer", sni)
}
if (authPayload.isNotBlank()) {
builder.addQueryParameter("auth", authPayload)
}
builder.addQueryParameter("upmbps", "$uploadMbps")
builder.addQueryParameter("downmbps", "$downloadMbps")
if (alpn.isNotBlank()) {
builder.addQueryParameter("alpn", alpn)
}
if (obfuscation.isNotBlank()) {
builder.addQueryParameter("obfs", "xplus")
builder.addQueryParameter("obfsParam", obfuscation)
}
when (protocol) {
HysteriaBean.PROTOCOL_FAKETCP -> {
builder.addQueryParameter("protocol", "faketcp")
}
HysteriaBean.PROTOCOL_WECHAT_VIDEO -> {
builder.addQueryParameter("protocol", "wechat-video")
}
}
if (protocol == HysteriaBean.PROTOCOL_FAKETCP) {
builder.addQueryParameter("protocol", "faketcp")
}
if (name.isNotBlank()) {
builder.encodedFragment(name.urlSafe())
}
return builder.toLink("hysteria")
if (allowInsecure) {
builder.addQueryParameter("insecure", "1")
}
if (protocolVersion == 1) {
if (sni.isNotBlank()) {
builder.addQueryParameter("peer", sni)
}
if (authPayload.isNotBlank()) {
builder.addQueryParameter("auth", authPayload)
}
builder.addQueryParameter("upmbps", "$uploadMbps")
builder.addQueryParameter("downmbps", "$downloadMbps")
if (alpn.isNotBlank()) {
builder.addQueryParameter("alpn", alpn)
}
if (obfuscation.isNotBlank()) {
builder.addQueryParameter("obfs", "xplus")
builder.addQueryParameter("obfsParam", obfuscation)
}
when (protocol) {
HysteriaBean.PROTOCOL_FAKETCP -> {
builder.addQueryParameter("protocol", "faketcp")
}
HysteriaBean.PROTOCOL_WECHAT_VIDEO -> {
builder.addQueryParameter("protocol", "wechat-video")
}
}
} else {
if (sni.isNotBlank()) {
builder.addQueryParameter("sni", sni)
}
if (obfuscation.isNotBlank()) {
builder.addQueryParameter("obfs", "salamander")
builder.addQueryParameter("obfs-password", obfuscation)
}
}
return builder.toLink(if (protocolVersion == 2) "hy2" else "hysteria")
}
fun JSONObject.parseHysteria(): HysteriaBean {
// TODO parse HY2 JSON+YAML
return HysteriaBean().apply {
protocolVersion = 1
serverAddress = optString("server").substringBeforeLast(":")
serverPorts = optString("server").substringAfterLast(":")
uploadMbps = getIntNya("up_mbps")
@ -140,6 +206,9 @@ fun JSONObject.parseHysteria(): HysteriaBean {
}
fun HysteriaBean.buildHysteriaConfig(port: Int, cacheFile: (() -> File)?): String {
if (protocolVersion != 1) {
throw Exception("error version: $protocolVersion")
}
return JSONObject().apply {
put("server", displayAddress())
when (protocol) {
@ -209,43 +278,86 @@ fun HysteriaBean.canUseSingBox(): Boolean {
return true
}
fun buildSingBoxOutboundHysteriaBean(bean: HysteriaBean): SingBoxOptions.Outbound_HysteriaOptions {
return SingBoxOptions.Outbound_HysteriaOptions().apply {
type = "hysteria"
server = bean.serverAddress
val port = bean.serverPorts.toIntOrNull()
if (port != null) {
server_port = port
} else {
hop_ports = bean.serverPorts
}
hop_interval = bean.hopInterval
up_mbps = bean.uploadMbps
down_mbps = bean.downloadMbps
obfs = bean.obfuscation
disable_mtu_discovery = bean.disableMtuDiscovery
when (bean.authPayloadType) {
HysteriaBean.TYPE_BASE64 -> auth = bean.authPayload
HysteriaBean.TYPE_STRING -> auth_str = bean.authPayload
}
if (bean.streamReceiveWindow > 0) {
recv_window_conn = bean.streamReceiveWindow.toLong()
}
if (bean.connectionReceiveWindow > 0) {
recv_window_conn = bean.connectionReceiveWindow.toLong()
}
tls = SingBoxOptions.OutboundTLSOptions().apply {
if (bean.sni.isNotBlank()) {
server_name = bean.sni
fun buildSingBoxOutboundHysteriaBean(bean: HysteriaBean): MutableMap<String, Any> {
return when (bean.protocolVersion) {
1 -> SingBoxOptions.Outbound_HysteriaOptions().apply {
type = "hysteria"
server = bean.serverAddress
val port = bean.serverPorts.toIntOrNull()
if (port != null) {
server_port = port
} else {
hop_ports = bean.serverPorts
}
if (bean.alpn.isNotBlank()) {
alpn = bean.alpn.listByLineOrComma()
hop_interval = bean.hopInterval
up_mbps = bean.uploadMbps
down_mbps = bean.downloadMbps
obfs = bean.obfuscation
disable_mtu_discovery = bean.disableMtuDiscovery
when (bean.authPayloadType) {
HysteriaBean.TYPE_BASE64 -> auth = bean.authPayload
HysteriaBean.TYPE_STRING -> auth_str = bean.authPayload
}
if (bean.caText.isNotBlank()) {
certificate = bean.caText
if (bean.streamReceiveWindow > 0) {
recv_window_conn = bean.streamReceiveWindow.toLong()
}
insecure = bean.allowInsecure
enabled = true
}
if (bean.connectionReceiveWindow > 0) {
recv_window_conn = bean.connectionReceiveWindow.toLong()
}
tls = SingBoxOptions.OutboundTLSOptions().apply {
if (bean.sni.isNotBlank()) {
server_name = bean.sni
}
if (bean.alpn.isNotBlank()) {
alpn = bean.alpn.listByLineOrComma()
}
if (bean.caText.isNotBlank()) {
certificate = bean.caText
}
insecure = bean.allowInsecure
enabled = true
}
}.asMap()
2 -> SingBoxOptions.Outbound_Hysteria2Options().apply {
type = "hysteria2"
server = bean.serverAddress
val port = bean.serverPorts.toIntOrNull()
if (port != null) {
server_port = port
} else {
// hop_ports = bean.serverPorts
}
// hop_interval = bean.hopInterval
up_mbps = bean.uploadMbps
down_mbps = bean.downloadMbps
if (bean.obfuscation.isNotBlank()) {
obfs = SingBoxOptions.Hysteria2Obfs().apply {
type = "salamander"
password = bean.obfuscation
}
}
// disable_mtu_discovery = bean.disableMtuDiscovery
password = bean.authPayload
// if (bean.streamReceiveWindow > 0) {
// recv_window_conn = bean.streamReceiveWindow.toLong()
// }
// if (bean.connectionReceiveWindow > 0) {
// recv_window_conn = bean.connectionReceiveWindow.toLong()
// }
tls = SingBoxOptions.OutboundTLSOptions().apply {
if (bean.sni.isNotBlank()) {
server_name = bean.sni
}
alpn = listOf("h3")
if (bean.caText.isNotBlank()) {
certificate = bean.caText
}
insecure = bean.allowInsecure
enabled = true
}
}.asMap()
else -> mutableMapOf("error_version" to bean.protocolVersion)
}
}

View File

@ -181,7 +181,7 @@ suspend fun parseProxies(text: String): List<AbstractBean> {
}.onFailure {
Logs.w(it)
}
} else if (startsWith("hysteria://")) {
} else if (startsWith("hysteria://") || startsWith("hysteria2://") || startsWith("hy2://")) {
Logs.d("Try parse hysteria link: $this")
runCatching {
entities.add(parseHysteria(this))

View File

@ -3,6 +3,7 @@ package io.nekohasekai.sagernet.ui.profile
import android.os.Bundle
import androidx.preference.EditTextPreference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference
import io.nekohasekai.sagernet.Key
import io.nekohasekai.sagernet.R
import io.nekohasekai.sagernet.database.DataStore
@ -17,11 +18,12 @@ class HysteriaSettingsActivity : ProfileSettingsActivity<HysteriaBean>() {
override fun HysteriaBean.init() {
DataStore.profileName = name
DataStore.protocolVersion = protocolVersion
DataStore.serverAddress = serverAddress
DataStore.serverPorts = serverPorts
DataStore.serverObfs = obfuscation
DataStore.serverAuthType = authPayloadType
DataStore.serverProtocolVersion = protocol
DataStore.serverProtocolInt = protocol
DataStore.serverPassword = authPayload
DataStore.serverSNI = sni
DataStore.serverALPN = alpn
@ -37,12 +39,13 @@ class HysteriaSettingsActivity : ProfileSettingsActivity<HysteriaBean>() {
override fun HysteriaBean.serialize() {
name = DataStore.profileName
protocolVersion = DataStore.protocolVersion
serverAddress = DataStore.serverAddress
serverPorts = DataStore.serverPorts
obfuscation = DataStore.serverObfs
authPayloadType = DataStore.serverAuthType
authPayload = DataStore.serverPassword
protocol = DataStore.serverProtocolVersion
protocol = DataStore.serverProtocolInt
sni = DataStore.serverSNI
alpn = DataStore.serverALPN
caText = DataStore.serverCertificates
@ -69,6 +72,44 @@ class HysteriaSettingsActivity : ProfileSettingsActivity<HysteriaBean>() {
true
}
val protocol = findPreference<SimpleMenuPreference>(Key.SERVER_PROTOCOL)!!
val alpn = findPreference<EditTextPreference>(Key.SERVER_ALPN)!!
fun updateVersion(v: Int) {
if (v == 2) {
authPayload.isVisible = true
//
authType.isVisible = false
protocol.isVisible = false
alpn.isVisible = false
//
findPreference<EditTextPreference>(Key.SERVER_HOP_INTERVAL)!!.isVisible = false
findPreference<EditTextPreference>(Key.SERVER_STREAM_RECEIVE_WINDOW)!!.isVisible =
false
findPreference<EditTextPreference>(Key.SERVER_CONNECTION_RECEIVE_WINDOW)!!.isVisible =
false
findPreference<SwitchPreference>(Key.SERVER_DISABLE_MTU_DISCOVERY)!!.isVisible =
false
} else {
authType.isVisible = true
protocol.isVisible = true
alpn.isVisible = true
//
findPreference<EditTextPreference>(Key.SERVER_HOP_INTERVAL)!!.isVisible = true
findPreference<EditTextPreference>(Key.SERVER_STREAM_RECEIVE_WINDOW)!!.isVisible =
true
findPreference<EditTextPreference>(Key.SERVER_CONNECTION_RECEIVE_WINDOW)!!.isVisible =
true
findPreference<SwitchPreference>(Key.SERVER_DISABLE_MTU_DISCOVERY)!!.isVisible =
true
}
}
findPreference<SimpleMenuPreference>(Key.PROTOCOL_VERSION)!!.setOnPreferenceChangeListener { _, newValue ->
updateVersion(newValue.toString().toIntOrNull() ?: 1)
true
}
updateVersion(DataStore.protocolVersion)
findPreference<EditTextPreference>(Key.SERVER_UPLOAD_SPEED)!!.apply {
setOnBindEditTextListener(EditTextPreferenceModifiers.Number)
}
@ -85,6 +126,9 @@ class HysteriaSettingsActivity : ProfileSettingsActivity<HysteriaBean>() {
findPreference<EditTextPreference>(Key.SERVER_PASSWORD)!!.apply {
summaryProvider = PasswordSummaryProvider
}
findPreference<EditTextPreference>(Key.SERVER_OBFS)!!.apply {
summaryProvider = PasswordSummaryProvider
}
findPreference<EditTextPreference>(Key.SERVER_HOP_INTERVAL)!!.apply {
setOnBindEditTextListener(EditTextPreferenceModifiers.Number)

View File

@ -18,7 +18,7 @@ class SocksSettingsActivity : ProfileSettingsActivity<SOCKSBean>() {
DataStore.serverAddress = serverAddress
DataStore.serverPort = serverPort
DataStore.serverProtocolVersion = protocol
DataStore.serverProtocolInt = protocol
DataStore.serverUsername = username
DataStore.serverPassword = password
@ -30,7 +30,7 @@ class SocksSettingsActivity : ProfileSettingsActivity<SOCKSBean>() {
serverAddress = DataStore.serverAddress
serverPort = DataStore.serverPort
protocol = DataStore.serverProtocolVersion
protocol = DataStore.serverProtocolInt
username = DataStore.serverUsername
password = DataStore.serverPassword
@ -54,7 +54,7 @@ class SocksSettingsActivity : ProfileSettingsActivity<SOCKSBean>() {
password.isVisible = version == SOCKSBean.PROTOCOL_SOCKS5
}
updateProtocol(DataStore.serverProtocolVersion)
updateProtocol(DataStore.protocolVersion)
protocol.setOnPreferenceChangeListener { _, newValue ->
updateProtocol((newValue as String).toInt())
true

View File

@ -9,7 +9,6 @@ import io.nekohasekai.sagernet.R
import io.nekohasekai.sagernet.database.DataStore
import io.nekohasekai.sagernet.fmt.tuic.TuicBean
import io.nekohasekai.sagernet.ktx.applyDefaultValues
import moe.matsuri.nb4a.ui.EditConfigPreference
import moe.matsuri.nb4a.ui.SimpleMenuPreference
class TuicSettingsActivity : ProfileSettingsActivity<TuicBean>() {
@ -34,7 +33,7 @@ class TuicSettingsActivity : ProfileSettingsActivity<TuicBean>() {
DataStore.serverAllowInsecure = allowInsecure
//
DataStore.serverConfig = customJSON
DataStore.serverProtocolVersion = protocolVersion
DataStore.protocolVersion = protocolVersion
DataStore.serverUsername = uuid
}
@ -56,7 +55,7 @@ class TuicSettingsActivity : ProfileSettingsActivity<TuicBean>() {
allowInsecure = DataStore.serverAllowInsecure
//
customJSON = DataStore.serverConfig
protocolVersion = DataStore.serverProtocolVersion
protocolVersion = DataStore.protocolVersion
uuid = DataStore.serverUsername
}
@ -80,11 +79,11 @@ class TuicSettingsActivity : ProfileSettingsActivity<TuicBean>() {
fastConnect.isVisible = true
}
}
findPreference<SimpleMenuPreference>(Key.SERVER_PROTOCOL)!!.setOnPreferenceChangeListener { _, newValue ->
findPreference<SimpleMenuPreference>(Key.PROTOCOL_VERSION)!!.setOnPreferenceChangeListener { _, newValue ->
updateVersion(newValue.toString().toIntOrNull() ?: 4)
true
}
updateVersion(DataStore.serverProtocolVersion)
updateVersion(DataStore.protocolVersion)
val disableSNI = findPreference<SwitchPreference>(Key.SERVER_DISABLE_SNI)!!
val sni = findPreference<EditTextPreference>(Key.SERVER_SNI)!!

View File

@ -56,6 +56,8 @@ public class SingBoxOptions {
public String default_mode;
public Boolean store_mode;
public Boolean store_selected;
public Boolean store_fakeip;
@ -64,6 +66,8 @@ public class SingBoxOptions {
public String cache_id;
// Generate note: option type: public List<String> ModeList;
}
public static class SelectorOutboundOptions extends SingBoxOption {
@ -152,6 +156,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -206,6 +212,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -309,6 +317,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -390,6 +400,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -438,6 +450,128 @@ public class SingBoxOptions {
}
public static class Hysteria2InboundOptions extends SingBoxOption {
// Generate note: nested type ListenOptions
public String listen;
public Integer listen_port;
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
public Long udp_timeout;
public Boolean proxy_protocol;
public Boolean proxy_protocol_accept_no_header;
public String detour;
// Generate note: nested type InboundOptions
public Boolean sniff;
public Boolean sniff_override_destination;
public Long sniff_timeout;
public String domain_strategy;
// End of public InboundOptions ;
// End of public ListenOptions ;
public Integer up_mbps;
public Integer down_mbps;
public Hysteria2Obfs obfs;
public List<Hysteria2User> users;
public Boolean ignore_client_bandwidth;
public InboundTLSOptions tls;
public String masquerade;
}
public static class Hysteria2Obfs extends SingBoxOption {
public String type;
public String password;
}
public static class Hysteria2User extends SingBoxOption {
public String name;
public String password;
}
public static class Hysteria2OutboundOptions extends SingBoxOption {
// Generate note: nested type DialerOptions
public String detour;
public String bind_interface;
public String inet4_bind_address;
public String inet6_bind_address;
public String protect_path;
public Integer routing_mark;
public Boolean reuse_addr;
public Long connect_timeout;
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
public String domain_strategy;
public Long fallback_delay;
// End of public DialerOptions ;
// Generate note: nested type ServerOptions
public String server;
public Integer server_port;
// End of public ServerOptions ;
public Integer up_mbps;
public Integer down_mbps;
public Hysteria2Obfs obfs;
public String password;
public String network;
public OutboundTLSOptions tls;
}
public static class Inbound extends SingBoxOption {
@ -475,6 +609,8 @@ public class SingBoxOptions {
// Generate note: option type: public TUICInboundOptions TUICOptions;
// Generate note: option type: public Hysteria2InboundOptions Hysteria2Options;
}
public static class InboundOptions extends SingBoxOption {
@ -497,6 +633,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -531,6 +669,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -598,6 +738,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -645,6 +787,8 @@ public class SingBoxOptions {
// Generate note: option type: public TUICOutboundOptions TUICOptions;
// Generate note: option type: public Hysteria2OutboundOptions Hysteria2Options;
// Generate note: option type: public SelectorOutboundOptions SelectorOptions;
// Generate note: option type: public URLTestOutboundOptions URLTestOptions;
@ -671,6 +815,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -742,6 +888,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -778,6 +926,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -1069,6 +1219,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -1150,6 +1302,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -1204,6 +1358,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -1246,6 +1402,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -1321,6 +1479,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -1354,6 +1514,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -1388,6 +1550,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -1426,6 +1590,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -1480,6 +1646,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -1530,6 +1698,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -1580,6 +1750,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -1635,16 +1807,20 @@ public class SingBoxOptions {
// Generate note: Listable
public List<String> cipher_suites;
public String certificate;
// Generate note: Listable
public List<String> certificate;
public String certificate_path;
public String key;
// Generate note: Listable
public List<String> key;
public String key_path;
public InboundACMEOptions acme;
public InboundECHOptions ech;
public InboundRealityOptions reality;
}
@ -1724,6 +1900,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -1736,6 +1914,21 @@ public class SingBoxOptions {
}
public static class InboundECHOptions extends SingBoxOption {
public Boolean enabled;
public Boolean pq_signature_schemes_enabled;
public Boolean dynamic_record_sizing_disabled;
// Generate note: Listable
public List<String> key;
public String key_path;
}
public static class OutboundECHOptions extends SingBoxOption {
public Boolean enabled;
@ -1744,7 +1937,10 @@ public class SingBoxOptions {
public Boolean dynamic_record_sizing_disabled;
public String config;
// Generate note: Listable
public List<String> config;
public String config_path;
}
@ -1820,6 +2016,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -1849,6 +2047,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -1915,6 +2115,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -1953,6 +2155,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -2023,6 +2227,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -2048,6 +2254,8 @@ public class SingBoxOptions {
public String udp_relay_mode;
public Boolean udp_over_stream;
public Boolean zero_rtt_handshake;
public Long heartbeat;
@ -2080,6 +2288,12 @@ public class SingBoxOptions {
// Generate note: Listable
public List<String> inet6_route_address;
// Generate note: Listable
public List<String> include_interface;
// Generate note: Listable
public List<String> exclude_interface;
// Generate note: Listable
public List<Integer> include_uid;
@ -2238,6 +2452,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -2302,6 +2518,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -2344,6 +2562,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -2408,6 +2628,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -2468,6 +2690,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
// Generate note: option type: public Boolean UDPFragmentDefault;
@ -2554,6 +2778,12 @@ public class SingBoxOptions {
// Generate note: Listable
public List<String> inet6_route_address;
// Generate note: Listable
public List<String> include_interface;
// Generate note: Listable
public List<String> exclude_interface;
// Generate note: Listable
public List<Integer> include_uid;
@ -2605,6 +2835,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -2640,6 +2872,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -2677,6 +2911,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -2718,6 +2954,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -2755,6 +2993,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -2796,6 +3036,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -2837,6 +3079,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -2882,6 +3126,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -2923,6 +3169,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -2968,6 +3216,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -3009,6 +3259,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -3066,6 +3318,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -3113,6 +3367,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -3154,6 +3410,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -3192,6 +3450,57 @@ public class SingBoxOptions {
}
public static class Inbound_Hysteria2Options extends Inbound {
// Generate note: nested type ListenOptions
public String listen;
public Integer listen_port;
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
public Long udp_timeout;
public Boolean proxy_protocol;
public Boolean proxy_protocol_accept_no_header;
public String detour;
// Generate note: nested type InboundOptions
public Boolean sniff;
public Boolean sniff_override_destination;
public Long sniff_timeout;
public String domain_strategy;
// End of public InboundOptions ;
// End of public ListenOptions ;
public Integer up_mbps;
public Integer down_mbps;
public Hysteria2Obfs obfs;
public List<Hysteria2User> users;
public Boolean ignore_client_bandwidth;
public InboundTLSOptions tls;
public String masquerade;
}
public static class Outbound_DirectOptions extends Outbound {
// Generate note: nested type DialerOptions
@ -3213,6 +3522,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -3251,6 +3562,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -3300,6 +3613,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -3349,6 +3664,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -3402,6 +3719,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -3461,6 +3780,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -3510,6 +3831,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -3573,6 +3896,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -3641,6 +3966,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -3681,6 +4008,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -3738,6 +4067,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -3783,6 +4114,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -3836,6 +4169,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -3889,6 +4224,8 @@ public class SingBoxOptions {
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
@ -3913,6 +4250,8 @@ public class SingBoxOptions {
public String udp_relay_mode;
public Boolean udp_over_stream;
public Boolean zero_rtt_handshake;
public Long heartbeat;
@ -3923,6 +4262,59 @@ public class SingBoxOptions {
}
public static class Outbound_Hysteria2Options extends Outbound {
// Generate note: nested type DialerOptions
public String detour;
public String bind_interface;
public String inet4_bind_address;
public String inet6_bind_address;
public String protect_path;
public Integer routing_mark;
public Boolean reuse_addr;
public Long connect_timeout;
public Boolean tcp_fast_open;
public Boolean tcp_multi_path;
public Boolean udp_fragment;
public String domain_strategy;
public Long fallback_delay;
// End of public DialerOptions ;
// Generate note: nested type ServerOptions
public String server;
public Integer server_port;
// End of public ServerOptions ;
public Integer up_mbps;
public Integer down_mbps;
public Hysteria2Obfs obfs;
public String password;
public String network;
public OutboundTLSOptions tls;
}
public static class Outbound_SelectorOptions extends Outbound {
public List<String> outbounds;

View File

@ -386,6 +386,11 @@
<item>BASE64</item>
</string-array>
<string-array name="hysteria_version">
<item>1</item>
<item>2</item>
</string-array>
<string-array name="tuic_version">
<item>5</item>
<item>4</item>

View File

@ -6,6 +6,15 @@
app:title="@string/profile_name"
app:useSimpleSummaryProvider="true" />
<moe.matsuri.nb4a.ui.SimpleMenuPreference
app:defaultValue="2"
app:entries="@array/hysteria_version"
app:entryValues="@array/hysteria_version"
app:icon="@drawable/ic_baseline_update_24"
app:key="protocolVersion"
app:title="@string/protocol_version"
app:useSimpleSummaryProvider="true" />
<PreferenceCategory app:title="@string/proxy_cat">
<EditTextPreference

View File

@ -11,7 +11,7 @@
app:entries="@array/tuic_version"
app:entryValues="@array/tuic_version"
app:icon="@drawable/ic_baseline_update_24"
app:key="serverProtocol"
app:key="protocolVersion"
app:title="@string/protocol_version"
app:useSimpleSummaryProvider="true" />

View File

@ -1,5 +1,5 @@
if [ ! -z $ENV_NB4A ]; then
export COMMIT_SING_BOX_EXTRA="70387142a28f10663b847988306ff6899fce0176"
export COMMIT_SING_BOX_EXTRA="2d7e05f22f2c3285ca929aaa0cad79ba4fd3e1fb"
fi
if [ ! -z $ENV_SING_BOX_EXTRA ]; then

View File

@ -7,7 +7,7 @@ require (
github.com/matsuridayo/libneko v1.0.0 // replaced
github.com/matsuridayo/sing-box-extra v1.0.0 // replaced
github.com/miekg/dns v1.1.55
github.com/sagernet/sing v0.2.10-0.20230824115837-8d731e68853a
github.com/sagernet/sing v0.2.10-0.20230830132630-30bf19f2833c
github.com/sagernet/sing-box v1.0.0 // replaced
github.com/sagernet/sing-dns v0.1.9-0.20230824120133-4d5cbceb40c1
github.com/sagernet/sing-tun v0.1.12-0.20230821065522-7545dc2d5641
@ -22,7 +22,7 @@ require (
github.com/ajg/form v1.5.1 // indirect
github.com/andybalholm/brotli v1.0.5 // indirect
github.com/caddyserver/certmagic v0.19.2 // indirect
github.com/cloudflare/circl v1.2.1-0.20221019164342-6ab4dfed8f3c // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/cretz/bine v0.2.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
@ -32,7 +32,6 @@ require (
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/gofrs/uuid/v5 v5.0.0 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
@ -54,13 +53,13 @@ require (
github.com/pires/go-proxyproto v0.7.0 // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/qtls-go1-20 v0.3.3 // indirect
github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0 // indirect
github.com/sagernet/cloudflare-tls v0.0.0-20230829051644-4a68352d0c4a // indirect
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 // indirect
github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2 // indirect
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect
github.com/sagernet/quic-go v0.0.0-20230825040534-0cd917b2ddda // indirect
github.com/sagernet/quic-go v0.0.0-20230831052420-45809eee2e86 // indirect
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 // indirect
github.com/sagernet/sing-mux v0.1.3-0.20230811111955-dc1639b5204c // indirect
github.com/sagernet/sing-mux v0.1.3-0.20230830095209-2a10ebd53ba8 // indirect
github.com/sagernet/sing-shadowsocks v0.2.4 // indirect
github.com/sagernet/sing-shadowsocks2 v0.1.3 // indirect
github.com/sagernet/sing-shadowtls v0.1.4 // indirect

View File

@ -15,8 +15,8 @@ github.com/caddyserver/certmagic v0.19.2/go.mod h1:fsL01NomQ6N+kE2j37ZCnig2MFosG
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/cloudflare/circl v1.2.1-0.20221019164342-6ab4dfed8f3c h1:K1VdSnBZiGapczwcUKnE1qcsMBclA84DUOD2NG/78VY=
github.com/cloudflare/circl v1.2.1-0.20221019164342-6ab4dfed8f3c/go.mod h1:+CauBF6R70Jqcyl8N2hC8pAXYbWkGIezuSbuGLtRhnw=
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/codeclysm/extract v2.2.0+incompatible h1:q3wyckoA30bhUSiwdQezMqVhwd8+WGE64/GL//LtUhI=
github.com/codeclysm/extract v2.2.0+incompatible/go.mod h1:2nhFMPHiU9At61hz+12bfrlpXSUrOnK+wR+KlGO4Uks=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
@ -43,8 +43,6 @@ github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEe
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
@ -101,26 +99,26 @@ github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1
github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM=
github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0 h1:KyhtFFt1Jtp5vW2ohNvstvQffTOQ/s5vENuGXzdA+TM=
github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0/go.mod h1:D4SFEOkJK+4W1v86ZhX0jPM0rAL498fyQAChqMtes/I=
github.com/sagernet/cloudflare-tls v0.0.0-20230829051644-4a68352d0c4a h1:wZHruBxZCsQLXHAozWpnJBL3wJ/XufDpz0qKtgpSnA4=
github.com/sagernet/cloudflare-tls v0.0.0-20230829051644-4a68352d0c4a/go.mod h1:dNV1ZP9y3qx5ltULeKaQZTZWTLHflgW5DES+Ses7cMI=
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 h1:5+m7c6AkmAylhauulqN/c5dnh8/KssrE9c93TQrXldA=
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h1:QUQ4RRHD6hGGHdFMEtR8T2P6GS6R3D/CXKdaYHKKXms=
github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2 h1:dnkKrzapqtAwjTSWt6hdPrARORfoYvuUczynvRLrueo=
github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2/go.mod h1:1JUiV7nGuf++YFm9eWZ8q2lrwHmhcUGzptMl/vL1+LA=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
github.com/sagernet/quic-go v0.0.0-20230825040534-0cd917b2ddda h1:7J/hnOFqCThiCrVpvr0wKO+Dic/XPSulPr5yI8FVJMs=
github.com/sagernet/quic-go v0.0.0-20230825040534-0cd917b2ddda/go.mod h1:Iw8Tt3dMqC/61cMHa0nN5i/958oYuuMnQCMOSPx+xcg=
github.com/sagernet/quic-go v0.0.0-20230831052420-45809eee2e86 h1:g4TEg9inAtA1FDTXpNrvmx72nN5mTOLQrJce6fVxF9g=
github.com/sagernet/quic-go v0.0.0-20230831052420-45809eee2e86/go.mod h1:O4Cj7TmMOvqD6S0XMqJRZfcYzA3m0H0ARbbaJFB0p7A=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
github.com/sagernet/sing v0.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
github.com/sagernet/sing v0.2.10-0.20230824115837-8d731e68853a h1:eV4HEz9NP7eAlQ/IHD6OF2VVM6ke4Vw6htuSAsvgtDk=
github.com/sagernet/sing v0.2.10-0.20230824115837-8d731e68853a/go.mod h1:9uOZwWkhT2Z2WldolLxX34s+1svAX4i4vvz5hy8u1MA=
github.com/sagernet/sing v0.2.10-0.20230830132630-30bf19f2833c h1:J2ptRncTNy+ZHfcFYSBfTmpvmgNlSEUZz6sDjh1np/Y=
github.com/sagernet/sing v0.2.10-0.20230830132630-30bf19f2833c/go.mod h1:9uOZwWkhT2Z2WldolLxX34s+1svAX4i4vvz5hy8u1MA=
github.com/sagernet/sing-dns v0.1.9-0.20230824120133-4d5cbceb40c1 h1:5w+jXz8y/8UQAxO74TjftN5okYkpg5mGvVxXunlKdqI=
github.com/sagernet/sing-dns v0.1.9-0.20230824120133-4d5cbceb40c1/go.mod h1:Kg98PBJEg/08jsNFtmZWmPomhskn9Ausn50ecNm4M+8=
github.com/sagernet/sing-mux v0.1.3-0.20230811111955-dc1639b5204c h1:35/FowAvt3Z62mck0TXzVc4jS5R5CWq62qcV2P1cp0I=
github.com/sagernet/sing-mux v0.1.3-0.20230811111955-dc1639b5204c/go.mod h1:TKxqIvfQQgd36jp2tzsPavGjYTVZilV+atip1cssjIY=
github.com/sagernet/sing-mux v0.1.3-0.20230830095209-2a10ebd53ba8 h1:UyUkEUEGqfIGqzOJ7OuJry4slgcT/qb0etDJ+89LTAs=
github.com/sagernet/sing-mux v0.1.3-0.20230830095209-2a10ebd53ba8/go.mod h1:TKxqIvfQQgd36jp2tzsPavGjYTVZilV+atip1cssjIY=
github.com/sagernet/sing-shadowsocks v0.2.4 h1:s/CqXlvFAZhlIoHWUwPw5CoNnQ9Ibki9pckjuugtVfY=
github.com/sagernet/sing-shadowsocks v0.2.4/go.mod h1:80fNKP0wnqlu85GZXV1H1vDPC/2t+dQbFggOw4XuFUM=
github.com/sagernet/sing-shadowsocks2 v0.1.3 h1:WXoLvCFi5JTFBRYorf1YePGYIQyJ/zbsBM6Fwbl5kGA=
@ -158,7 +156,6 @@ github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8=
github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
@ -198,7 +195,6 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
@ -212,9 +208,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -235,7 +229,6 @@ golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E=
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=