update 2023-08-23 16:21:03

This commit is contained in:
github-actions[bot] 2023-08-23 16:21:03 +08:00
parent f702f28149
commit d90cc3c59b
9 changed files with 1626 additions and 1238 deletions

View File

@ -261,8 +261,10 @@ return view.extend({
ss = o.subsection;
so = ss.option(form.ListValue, 'tcpip_stack', _('TCP/IP stack'),
_('TCP/IP stack.'));
if (features.with_gvisor)
if (features.with_gvisor) {
so.value('mixed', _('Mixed'));
so.value('gvisor', _('gVisor'));
}
if (features.with_lwip)
so.value('lwip', _('LWIP'));
so.value('system', _('System'));
@ -272,8 +274,10 @@ return view.extend({
so.rmempty = false;
so.onchange = function(ev, section_id, value) {
var desc = ev.target.nextElementSibling;
if (value === 'gvisor')
desc.innerHTML = _('Based on google/gvisor (recommended).');
if (value === 'mixed')
desc.innerHTML = _('Mixed <code>system</code> TCP stack and <code>gVisor</code> UDP stack.')
else if (value === 'gvisor')
desc.innerHTML = _('Based on google/gvisor.');
else if (value === 'lwip')
desc.innerHTML = _('Upstream archived. Not recommended.');
else if (value === 'system')

View File

@ -210,6 +210,30 @@ function parseShareLink(uri, features) {
break;
}
break;
case 'tuic':
/* https://github.com/daeuniverse/dae/discussions/182 */
var url = new URL('http://' + uri[1]);
var params = url.searchParams;
/* Check if uuid exists */
if (!url.username)
return null;
config = {
label: url.hash ? decodeURIComponent(url.hash.slice(1)) : null,
type: 'tuic',
address: url.hostname,
port: url.port || '80',
uuid: url.username,
password: url.password ? decodeURIComponent(url.password) : null,
tuic_congestion_control: params.get('congestion_control'),
tuic_udp_relay_mode: params.get('udp_relay_mode'),
tls: '1',
tls_sni: params.get('sni'),
tls_alpn: params.get('alpn') ? decodeURIComponent(params.get('alpn')).split(',') : null
};
break;
case 'vless':
/* https://github.com/XTLS/Xray-core/discussions/716 */
@ -496,6 +520,8 @@ return view.extend({
so.value('shadowtls', _('ShadowTLS'));
so.value('socks', _('Socks'));
so.value('trojan', _('Trojan'));
if (features.with_quic)
so.value('tuic', _('Tuic'));
if (features.with_wireguard)
so.value('wireguard', _('WireGuard'));
so.value('vless', _('VLESS'));
@ -504,10 +530,12 @@ return view.extend({
so = ss.option(form.Value, 'address', _('Address'));
so.datatype = 'host';
so.depends({'type': 'direct', '!reverse': true});
so.rmempty = false;
so = ss.option(form.Value, 'port', _('Port'));
so.datatype = 'port';
so.depends({'type': 'direct', '!reverse': true});
so.rmempty = false;
so = ss.option(form.Value, 'username', _('Username'));
@ -521,6 +549,7 @@ return view.extend({
so.depends('type', 'shadowsocks');
so.depends('type', 'shadowsocksr');
so.depends('type', 'trojan');
so.depends('type', 'tuic');
so.depends({'type': 'shadowtls', 'shadowtls_version': '2'});
so.depends({'type': 'shadowtls', 'shadowtls_version': '3'});
so.depends({'type': 'socks', 'socks_version': '5'});
@ -549,6 +578,16 @@ return view.extend({
so.modalonly = true;
/* Direct config */
so = ss.option(form.Value, 'override_address', _('Override address'),
_('Override the connection destination address.'));
so.datatype = 'host';
so.depends('type', 'direct');
so = ss.option(form.Value, 'override_port', _('Override port'),
_('Override the connection destination port.'));
so.datatype = 'port';
so.depends('type', 'direct');
so = ss.option(form.ListValue, 'proxy_protocol', _('Proxy protocol'),
_('Write Proxy Protocol in the connection header.'));
so.value('', _('Disable'));
@ -735,13 +774,54 @@ return view.extend({
so.rmempty = false;
so.modalonly = true;
/* VMess / VLESS config start */
/* TUIC config start */
so = ss.option(form.Value, 'uuid', _('UUID'));
so.depends('type', 'tuic');
so.depends('type', 'vless');
so.depends('type', 'vmess');
so.validate = hp.validateUUID;
so.modalonly = true;
so = ss.option(form.ListValue, 'tuic_congestion_control', _('Congestion control algorithm'),
_('QUIC congestion control algorithm.'));
so.value('cubic', _('CUBIC'));
so.value('new_reno', _('New Reno'));
so.value('bbr', _('BBR'));
so.default = 'cubic';
so.depends('type', 'tuic');
so.rmempty = false;
so.modalonly = true;
so = ss.option(form.ListValue, 'tuic_udp_relay_mode', _('UDP relay mode'),
_('UDP packet relay mode.'));
so.value('native', _('Native'));
so.value('quic', _('QUIC'));
so.default = 'native';
so.depends('type', 'tuic');
so.modalonly = true;
so = ss.option(form.Flag, 'tuic_udp_over_stream', _('UDP over stream'),
_('This is the TUIC port of the UDP over TCP protocol, designed to provide a QUIC stream based UDP relay mode that TUIC does not provide.'));
so.default = so.disabled;
so.depends({'type': 'tuic','tuic_udp_relay_mode': 'native'});
so.modalonly = true;
so = ss.option(form.Flag, 'tuic_enable_zero_rtt', _('Enable 0-RTT handshake'),
_('Enable 0-RTT QUIC connection handshake on the client side. This is not impacting much on the performance, as the protocol is fully multiplexed.<br/>' +
'Disabling this is highly recommended, as it is vulnerable to replay attacks.'));
so.default = so.disabled;
so.depends('type', 'tuic');
so.modalonly = true;
so = ss.option(form.Value, 'tuic_heartbeat', _('Heartbeat interval'),
_('Interval for sending heartbeat packets for keeping the connection alive (in seconds).'));
so.datatype = 'uinteger';
so.default = '10';
so.depends('type', 'tuic');
so.modalonly = true;
/* Tuic config end */
/* VMess / VLESS config start */
so = ss.option(form.ListValue, 'vless_flow', _('Flow'));
so.value('', _('None'));
so.value('xtls-rprx-vision');
@ -802,18 +882,18 @@ return view.extend({
var tls = this.map.findElement('id', 'cbid.homeproxy.%s.tls'.format(section_id)).firstElementChild;
if ((value === 'http' && tls.checked) || (value === 'grpc' && !features.with_grpc)) {
this.map.findElement('id', 'cbid.homeproxy.%s.http_idle_timeout'.format(section_id)).nextElementSibling.innerHTML =
_('Specifies the period of time after which a health check will be performed using a ping frame if no frames have been received on the connection.<br/>' +
_('Specifies the period of time (in seconds) after which a health check will be performed using a ping frame if no frames have been received on the connection.<br/>' +
'Please note that a ping response is considered a received frame, so if there is no other traffic on the connection, the health check will be executed every interval.');
this.map.findElement('id', 'cbid.homeproxy.%s.http_ping_timeout'.format(section_id)).nextElementSibling.innerHTML =
_('Specifies the timeout duration after sending a PING frame, within which a response must be received.<br/>' +
_('Specifies the timeout duration (in seconds) after sending a PING frame, within which a response must be received.<br/>' +
'If a response to the PING frame is not received within the specified timeout duration, the connection will be closed.');
} else if (value === 'grpc' && features.with_grpc) {
this.map.findElement('id', 'cbid.homeproxy.%s.http_idle_timeout'.format(section_id)).nextElementSibling.innerHTML =
_('If the transport doesn\'t see any activity after a duration of this time, it pings the client to check if the connection is still active.');
_('If the transport doesn\'t see any activity after a duration of this time (in seconds), it pings the client to check if the connection is still active.');
this.map.findElement('id', 'cbid.homeproxy.%s.http_ping_timeout'.format(section_id)).nextElementSibling.innerHTML =
_('The timeout that after performing a keepalive check, the client will wait for activity. If no activity is detected, the connection will be closed.');
_('The timeout (in seconds) that after performing a keepalive check, the client will wait for activity. If no activity is detected, the connection will be closed.');
}
}
so.modalonly = true;
@ -849,7 +929,7 @@ return view.extend({
so.modalonly = true;
so = ss.option(form.Value, 'http_idle_timeout', _('Idle timeout'),
_('Specifies the period of time after which a health check will be performed using a ping frame if no frames have been received on the connection.<br/>' +
_('Specifies the period of time (in seconds) after which a health check will be performed using a ping frame if no frames have been received on the connection.<br/>' +
'Please note that a ping response is considered a received frame, so if there is no other traffic on the connection, the health check will be executed every interval.'));
so.datatype = 'uinteger';
so.depends('transport', 'grpc');
@ -857,7 +937,7 @@ return view.extend({
so.modalonly = true;
so = ss.option(form.Value, 'http_ping_timeout', _('Ping timeout'),
_('Specifies the timeout duration after sending a PING frame, within which a response must be received.<br/>' +
_('Specifies the timeout duration (in seconds) after sending a PING frame, within which a response must be received.<br/>' +
'If a response to the PING frame is not received within the specified timeout duration, the connection will be closed.'));
so.datatype = 'uinteger';
so.depends('transport', 'grpc');
@ -987,6 +1067,7 @@ return view.extend({
so.depends('type', 'hysteria');
so.depends('type', 'shadowtls');
so.depends('type', 'trojan');
so.depends('type', 'tuic');
so.depends('type', 'vless');
so.depends('type', 'vmess');
so.validate = function(section_id, value) {
@ -994,7 +1075,7 @@ return view.extend({
var type = this.map.lookupOption('type', section_id)[0].formvalue(section_id);
var tls = this.map.findElement('id', 'cbid.homeproxy.%s.tls'.format(section_id)).firstElementChild;
if (['hysteria', 'shadowtls'].includes(type)) {
if (['hysteria', 'shadowtls', 'tuic'].includes(type)) {
tls.checked = true;
tls.disabled = true;
} else {

View File

@ -109,6 +109,8 @@ return view.extend({
o.value('shadowsocks', _('Shadowsocks'));
o.value('socks', _('Socks'));
o.value('trojan', _('Trojan'));
if (features.with_quic)
o.value('tuic', _('Tuic'));
o.value('vless', _('VLESS'));
o.value('vmess', _('VMess'));
o.rmempty = false;
@ -129,6 +131,7 @@ return view.extend({
o.depends({'type': /^(http|naive|socks)$/, 'username': /[\s\S]/});
o.depends('type', 'shadowsocks');
o.depends('type', 'trojan');
o.depends('type', 'tuic');
o.validate = function(section_id, value) {
if (section_id) {
var type = this.map.lookupOption('type', section_id)[0].formvalue(section_id);
@ -229,13 +232,46 @@ return view.extend({
o.depends('type', 'shadowsocks');
o.modalonly = true;
/* VLESS / VMess config start */
/* Tuic config start */
o = s.option(form.Value, 'uuid', _('UUID'));
o.depends('type', 'tuic');
o.depends('type', 'vless');
o.depends('type', 'vmess');
o.validate = hp.validateUUID;
o.modalonly = true;
o = s.option(form.ListValue, 'tuic_congestion_control', _('Congestion control algorithm'),
_('QUIC congestion control algorithm.'));
o.value('cubic');
o.value('new_reno');
o.value('bbr');
o.default = 'cubic';
o.depends('type', 'tuic');
o.modalonly = true;
o = s.option(form.ListValue, 'tuic_auth_timeout', _('Auth timeout'),
_('How long the server should wait for the client to send the authentication command (in seconds).'));
o.datatype = 'uinteger';
o.default = '3';
o.depends('type', 'tuic');
o.modalonly = true;
o = s.option(form.Flag, 'tuic_enable_zero_rtt', _('Enable 0-RTT handshake'),
_('Enable 0-RTT QUIC connection handshake on the client side. This is not impacting much on the performance, as the protocol is fully multiplexed.<br/>' +
'Disabling this is highly recommended, as it is vulnerable to replay attacks.'));
o.default = o.disabled;
o.depends('type', 'tuic');
o.modalonly = true;
o = s.option(form.Value, 'tuic_heartbeat', _('Heartbeat interval'),
_('Interval for sending heartbeat packets for keeping the connection alive (in seconds).'));
o.datatype = 'uinteger';
o.default = '10';
o.depends('type', 'tuic');
o.modalonly = true;
/* Tuic config end */
/* VLESS / VMess config start */
o = s.option(form.ListValue, 'vless_flow', _('Flow'));
o.value('', _('None'));
o.value('xtls-rprx-vision');
@ -269,10 +305,10 @@ return view.extend({
var tls_element = this.map.findElement('id', 'cbid.homeproxy.%s.tls'.format(section_id)).firstElementChild;
if ((value === 'http' && tls_element.checked) || (value === 'grpc' && !features.with_grpc))
this.map.findElement('id', 'cbid.homeproxy.%s.http_idle_timeout'.format(section_id)).nextElementSibling.innerHTML =
_('Specifies the time until idle clients should be closed with a GOAWAY frame. PING frames are not considered as activity.');
_('Specifies the time (in seconds) until idle clients should be closed with a GOAWAY frame. PING frames are not considered as activity.');
else if (value === 'grpc' && features.with_grpc)
this.map.findElement('id', 'cbid.homeproxy.%s.http_idle_timeout'.format(section_id)).nextElementSibling.innerHTML =
_('If the transport doesn\'t see any activity after a duration of this time, it pings the client to check if the connection is still active.');
_('If the transport doesn\'t see any activity after a duration of this time (in seconds), it pings the client to check if the connection is still active.');
}
o.depends('type', 'trojan');
o.depends('type', 'vless');
@ -301,7 +337,7 @@ return view.extend({
o.modalonly = true;
o = s.option(form.Value, 'http_idle_timeout', _('Idle timeout'),
_('Specifies the time until idle clients should be closed with a GOAWAY frame. PING frames are not considered as activity.'));
_('Specifies the time (in seconds) until idle clients should be closed with a GOAWAY frame. PING frames are not considered as activity.'));
o.datatype = 'uinteger';
o.depends('transport', 'grpc');
o.depends({'transport': 'http', 'tls': '1'});
@ -309,7 +345,7 @@ return view.extend({
if (features.with_grpc) {
o = s.option(form.Value, 'http_ping_timeout', _('Ping timeout'),
_('The timeout that after performing a keepalive check, the client will wait for activity. If no activity is detected, the connection will be closed.'));
_('The timeout (in seconds) that after performing a keepalive check, the client will wait for activity. If no activity is detected, the connection will be closed.'));
o.datatype = 'uinteger';
o.depends('transport', 'grpc');
o.modalonly = true;
@ -358,7 +394,7 @@ return view.extend({
var type = this.map.lookupOption('type', section_id)[0].formvalue(section_id);
var tls = this.map.findElement('id', 'cbid.homeproxy.%s.tls'.format(section_id)).firstElementChild;
if (['hysteria'].includes(type)) {
if (['hysteria', 'tuic'].includes(type)) {
tls.checked = true;
tls.disabled = true;
} else {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -123,15 +123,15 @@ function generate_outbound(node) {
tag: 'cfg-' + node['.name'] + '-out',
routing_mark: strToInt(self_mark),
server: (node.type !== 'direct') ? node.address : null,
server_port: (node.type !== 'direct') ? int(node.port) : null,
server: node.address,
server_port: int(node.port),
username: node.username,
password: node.password,
/* Direct */
override_address: (node.type === 'direct') ? node.address : null,
override_port: (node.type === 'direct') ? node.port : null,
override_address: node.override_address,
override_port: strToInt(node.override_port),
proxy_protocol: strToInt(node.proxy_protocol),
/* Hysteria */
up_mbps: strToInt(node.hysteria_down_mbps),
@ -153,8 +153,14 @@ function generate_outbound(node) {
obfs_param: node.shadowsocksr_obfs_param,
/* ShadowTLS / Socks */
version: (node.type === 'shadowtls') ? strToInt(node.shadowtls_version) : ((node.type === 'socks') ? node.socks_version : null),
/* VLESS / VMess */
/* Tuic */
uuid: node.uuid,
congestion_control: node.tuic_congestion_control,
udp_relay_mode: node.tuic_udp_relay_mode,
udp_over_stream: (node.tuic_udp_over_stream === '1') || null,
zero_rtt_handshake: (node.tuic_enable_zero_rtt === '1') || null,
heartbeat: node.tuic_heartbeat ? (node.tuic_heartbeat + 's') : null,
/* VLESS / VMess */
flow: node.vless_flow,
alter_id: strToInt(node.vmess_alterid),
security: node.vmess_encrypt,

View File

@ -68,7 +68,13 @@ uci.foreach(uciconfig, uciserver, (cfg) => {
method: (cfg.type === 'shadowsocks') ? cfg.shadowsocks_encrypt_method : null,
password: (cfg.type in ['shadowsocks', 'shadowtls']) ? cfg.password : null,
/* HTTP / Hysteria / Socks / Trojan / VLESS / VMess */
/* Tuic */
congestion_control: cfg.tuic_congestion_control,
auth_timeout: cfg.tuic_auth_timeout ? (cfg.tuic_auth_timeout + 's') : null,
zero_rtt_handshake: (cfg.tuic_enable_zero_rtt === '1') || null,
heartbeat: cfg.tuic_heartbeat ? (cfg.tuic_heartbeat + 's') : null,
/* HTTP / Hysteria / Socks / Trojan / Tuic / VLESS / VMess */
users: (cfg.type !== 'shadowsocks') ? [
{
name: !(cfg.type in ['http', 'socks']) ? 'cfg-' + cfg['.name'] + '-server' : null,
@ -79,8 +85,10 @@ uci.foreach(uciconfig, uciserver, (cfg) => {
auth: (cfg.hysteria_auth_type === 'base64') ? cfg.hysteria_auth_payload : null,
auth_str: (cfg.hysteria_auth_type === 'string') ? cfg.hysteria_auth_payload : null,
/* VLESS / VMess */
/* Tuic */
uuid: cfg.uuid,
/* VLESS / VMess */
flow: cfg.vless_flow,
alterId: strToInt(cfg.vmess_alterid)
}

View File

@ -273,6 +273,33 @@ function parse_uri(uri) {
break;
}
break;
case 'tuic':
/* https://github.com/daeuniverse/dae/discussions/182 */
const tuic_url = parseURL('http://' + uri[1]),
tuic_params = tuic_url.searchParams || {};
if (!sing_features.with_quic) {
log(sprintf('Skipping unsupported %s node: %s.', 'tuic', urldecode(tuic_url.hash) || tuic_url.hostname));
log(sprintf('Please rebuild sing-box with %s support!', 'QUIC'));
return null;
}
config = {
label: tuic_url.hash ? urldecode(tuic_url.hash) : null,
type: 'tuic',
address: tuic_url.hostname,
port: tuic_url.port,
uuid: tuic_url.username,
password: tuic_url.password ? urldecode(tuic_url.password) : null,
tuic_congestion_control: tuic_params.congestion_control,
tuic_udp_relay_mode: tuic_params.udp_relay_mode,
tls: '1',
tls_sni: tuic_params.sni,
tls_alpn: tuic_params.alpn ? split(urldecode(tuic_params.alpn), ',') : null,
};
break;
case 'vless':
/* https://github.com/XTLS/Xray-core/discussions/716 */

View File

@ -5,12 +5,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=v2rayA
PKG_VERSION:=2.2.0
PKG_VERSION:=2.2.1
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/v2rayA/v2rayA/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=3a87521caf830102158620313a13217534e22cd5198706ab5c0e333cf1066e6b
PKG_HASH:=97ae3d41ddd649dd07cfecf2bbe06a513d71186ef2620ca44af12e7956be5650
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/service
PKG_LICENSE:=AGPL-3.0-only