Skip to content

Commit 9dc1b1f

Browse files
authored
Support new fragment (#5437)
* Support new fragment * Fix
1 parent b61cad5 commit 9dc1b1f

File tree

2 files changed

+69
-53
lines changed

2 files changed

+69
-53
lines changed

V2rayNG/app/src/main/java/com/v2ray/ang/dto/V2rayConfig.kt

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@ data class V2rayConfig(
6868
) {
6969
data class OutSettingsBean(
7070
var vnext: List<VnextBean>? = null,
71-
var fragment: FragmentBean? = null,
72-
var noises: List<NoiseBean>? = null,
7371
var servers: List<ServersBean>? = null,
7472
/*Blackhole*/
7573
var response: Response? = null,
@@ -108,18 +106,6 @@ data class V2rayConfig(
108106
)
109107
}
110108

111-
data class FragmentBean(
112-
var packets: String? = null,
113-
var length: String? = null,
114-
var interval: String? = null
115-
)
116-
117-
data class NoiseBean(
118-
var type: String? = null,
119-
var packet: String? = null,
120-
var delay: String? = null
121-
)
122-
123109
data class ServersBean(
124110
var address: String = "",
125111
var method: String? = null,
@@ -306,9 +292,25 @@ data class V2rayConfig(
306292
var settings: MaskSettingsBean? = null
307293
) {
308294
data class MaskSettingsBean(
309-
var password: String? = null,
310-
var domain: String? = null
311-
)
295+
val password: String? = null,
296+
val domain: String? = null,
297+
// fragment
298+
val packets: String? = null,
299+
val length: String? = null,
300+
val delay: String? = null,
301+
// val maxSplit: String? = null,
302+
// noise
303+
val reset: Int? = null,
304+
val noise: List<NoiseMaskBean>? = null
305+
) {
306+
data class NoiseMaskBean(
307+
val rand: String? = null,
308+
// val randRange: String? = null,
309+
// val type: String? = null,
310+
// val packet: String? = null,
311+
val delay: String? = null,
312+
)
313+
}
312314
}
313315
data class QuicParamsBean(
314316
var congestion: String? = null,

V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -710,8 +710,6 @@ object V2rayConfigManager {
710710
} else {
711711
v2rayConfig.outbounds.add(outbound)
712712
}
713-
714-
updateOutboundFragment(v2rayConfig)
715713
return true
716714
}
717715

@@ -955,68 +953,80 @@ object V2rayConfigManager {
955953
*
956954
* Configures packet fragmentation for TLS and REALITY protocols if enabled.
957955
*
958-
* @param v2rayConfig The V2ray configuration object to be modified
956+
* @param streamSettings The streamSettings object to be modified
959957
* @return true if fragment configuration was successful, false otherwise
960958
*/
961-
private fun updateOutboundFragment(v2rayConfig: V2rayConfig): Boolean {
959+
private fun updateOutboundFragment(streamSettings: StreamSettingsBean): Boolean {
962960
try {
963961
if (MmkvManager.decodeSettingsBool(AppConfig.PREF_FRAGMENT_ENABLED, false) == false) {
964962
return true
965963
}
966-
if (v2rayConfig.outbounds[0].streamSettings?.security != AppConfig.TLS
967-
&& v2rayConfig.outbounds[0].streamSettings?.security != AppConfig.REALITY
964+
if (streamSettings.security != AppConfig.TLS
965+
&& streamSettings.security != AppConfig.REALITY
968966
) {
969967
return true
970968
}
971-
972-
val fragmentOutbound =
973-
OutboundBean(
974-
protocol = AppConfig.PROTOCOL_FREEDOM,
975-
tag = AppConfig.TAG_FRAGMENT,
976-
mux = null
977-
)
969+
if (streamSettings.sockopt?.dialerProxy.isNotNullEmpty()) {
970+
return true
971+
}
978972

979973
var packets =
980974
MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_PACKETS) ?: "tlshello"
981-
if (v2rayConfig.outbounds[0].streamSettings?.security == AppConfig.REALITY
975+
if (streamSettings.security == AppConfig.REALITY
982976
&& packets == "tlshello"
983977
) {
984978
packets = "1-3"
985-
} else if (v2rayConfig.outbounds[0].streamSettings?.security == AppConfig.TLS
979+
} else if (streamSettings.security == AppConfig.TLS
986980
&& packets != "tlshello"
987981
) {
988982
packets = "tlshello"
989983
}
990984

991-
fragmentOutbound.settings = OutSettingsBean(
992-
fragment = OutSettingsBean.FragmentBean(
985+
val fragmentMask = StreamSettingsBean.FinalMaskBean.MaskBean(
986+
type = "fragment",
987+
settings = StreamSettingsBean.FinalMaskBean.MaskBean.MaskSettingsBean(
993988
packets = packets,
994989
length = MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_LENGTH)
995990
?: "50-100",
996-
interval = MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_INTERVAL)
991+
delay = MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_INTERVAL)
997992
?: "10-20"
998-
),
999-
noises = listOf(
1000-
OutSettingsBean.NoiseBean(
1001-
type = "rand",
1002-
packet = "10-20",
1003-
delay = "10-16",
1004-
)
1005-
),
993+
)
1006994
)
1007-
fragmentOutbound.streamSettings = StreamSettingsBean(
1008-
sockopt = StreamSettingsBean.SockoptBean(
1009-
TcpNoDelay = true,
1010-
mark = 255
995+
val noiseMask = StreamSettingsBean.FinalMaskBean.MaskBean(
996+
type = "noise",
997+
settings = StreamSettingsBean.FinalMaskBean.MaskBean.MaskSettingsBean(
998+
noise = listOf(
999+
StreamSettingsBean.FinalMaskBean.MaskBean.MaskSettingsBean.NoiseMaskBean(
1000+
rand = "10-20",
1001+
delay = "10-16",
1002+
)
1003+
)
10111004
)
10121005
)
1013-
v2rayConfig.outbounds.add(fragmentOutbound)
10141006

1015-
//proxy chain
1016-
v2rayConfig.outbounds[0].streamSettings?.sockopt =
1017-
StreamSettingsBean.SockoptBean(
1018-
dialerProxy = AppConfig.TAG_FRAGMENT
1019-
)
1007+
val finalMaskObj = streamSettings.finalmask?.let { existingFinalMask ->
1008+
JsonUtil.parseString(JsonUtil.toJson(existingFinalMask))
1009+
} ?: com.google.gson.JsonObject()
1010+
1011+
// finalmask.tcp / finalmask.udp are arrays; prepend mask at index 0.
1012+
fun prependMask(scope: String, mask: StreamSettingsBean.FinalMaskBean.MaskBean) {
1013+
val current = finalMaskObj.get(scope)
1014+
if (current != null && current.isJsonArray && current.asJsonArray.size() > 0) {
1015+
return
1016+
}
1017+
1018+
val newArray = JsonArray()
1019+
newArray.add(JsonUtil.parseString(JsonUtil.toJson(mask)))
1020+
1021+
if (current != null && current.isJsonArray) {
1022+
current.asJsonArray.forEach { newArray.add(it) }
1023+
}
1024+
finalMaskObj.add(scope, newArray)
1025+
}
1026+
1027+
prependMask("tcp", fragmentMask)
1028+
prependMask("udp", noiseMask)
1029+
streamSettings.finalmask = finalMaskObj
10201030
} catch (e: Exception) {
10211031
Log.e(AppConfig.TAG, "Failed to update outbound fragment", e)
10221032
return false
@@ -1402,6 +1412,10 @@ object V2rayConfigManager {
14021412
streamSettings.tlsSettings = null
14031413
streamSettings.realitySettings = tlsSetting
14041414
}
1415+
1416+
if (profileItem.finalMask.isNullOrEmpty()) {
1417+
updateOutboundFragment(streamSettings)
1418+
}
14051419
}
14061420

14071421
//endregion

0 commit comments

Comments
 (0)