luci-app-homeproxy: sync upstream

last commit: c05700366a
This commit is contained in:
sbwml 2024-08-31 11:30:08 +08:00
parent 6229c68387
commit 40fd2535d5
9 changed files with 1568 additions and 1404 deletions

View File

@ -169,11 +169,26 @@ return baseclass.extend({
return L.resolveDefault(callGetSingBoxFeatures(), {}); return L.resolveDefault(callGetSingBoxFeatures(), {});
}, },
generateUUIDv4: function() { generateRand: function(type, length) {
/* Thanks to https://stackoverflow.com/a/2117523 */ var byteArr;
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, (c) => if (['base64', 'hex'].includes(type))
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) byteArr = crypto.getRandomValues(new Uint8Array(length));
); switch (type) {
case 'base64':
/* Thanks to https://stackoverflow.com/questions/9267899 */
return btoa(String.fromCharCode.apply(null, byteArr));
case 'hex':
return Array.from(byteArr, (byte) =>
(byte & 255).toString(16).padStart(2, '0')
).join('');
case 'uuid':
/* Thanks to https://stackoverflow.com/a/2117523 */
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, (c) =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
);
default:
return null;
};
}, },
loadDefaultLabel: function(uciconfig, ucisection) { loadDefaultLabel: function(uciconfig, ucisection) {

View File

@ -313,6 +313,15 @@ return view.extend({
so.depends('tcpip_stack', 'gvisor'); so.depends('tcpip_stack', 'gvisor');
so.rmempty = false; so.rmempty = false;
so = ss.option(form.Value, 'udp_timeout', _('UDP NAT expiration time'),
_('In seconds. <code>300</code> is used by default.'));
so.datatype = 'uinteger';
so.default = '300';
so.depends('homeproxy.config.proxy_mode', 'redirect_tproxy');
so.depends('homeproxy.config.proxy_mode', 'redirect_tun');
so.depends('homeproxy.config.proxy_mode', 'tun');
so.rmempty = false;
so = ss.option(form.Flag, 'bypass_cn_traffic', _('Bypass CN traffic'), so = ss.option(form.Flag, 'bypass_cn_traffic', _('Bypass CN traffic'),
_('Bypass mainland China traffic via firewall rules by default.')); _('Bypass mainland China traffic via firewall rules by default.'));
so.default = so.disabled; so.default = so.disabled;

View File

@ -468,6 +468,14 @@ function renderNodeSettings(section, data, features, main_node, routing_mode) {
o.datatype = 'port'; o.datatype = 'port';
o.depends('type', 'direct'); o.depends('type', 'direct');
o = s.option(form.ListValue, 'proxy_protocol', _('Proxy protocol'),
_('Write proxy protocol in the connection header.'));
o.value('', _('Disable'));
o.value('1', _('v1'));
o.value('2', _('v2'));
o.depends('type', 'direct');
o.modalonly = true;
/* Hysteria (2) config start */ /* Hysteria (2) config start */
o = s.option(form.ListValue, 'hysteria_protocol', _('Protocol')); o = s.option(form.ListValue, 'hysteria_protocol', _('Protocol'));
o.value('udp'); o.value('udp');

View File

@ -9,6 +9,7 @@
'require poll'; 'require poll';
'require rpc'; 'require rpc';
'require uci'; 'require uci';
'require ui';
'require view'; 'require view';
'require homeproxy as hp'; 'require homeproxy as hp';
@ -41,6 +42,46 @@ function renderStatus(isRunning) {
return renderHTML; return renderHTML;
} }
function handleGenKey(option) {
var section_id = this.section.section;
var type = this.section.getOption('type').formvalue(section_id);
var widget = this.map.findElement('id', 'widget.cbid.homeproxy.%s.%s'.format(section_id, option));
var password, required_method;
if (option === 'uuid')
required_method = 'uuid';
else if (type === 'shadowsocks')
required_method = this.section.getOption('shadowsocks_encrypt_method')?.formvalue(section_id);
switch (required_method) {
case 'aes-128-gcm':
case '2022-blake3-aes-128-gcm':
password = hp.generateRand('base64', 16);
break;
case 'aes-192-gcm':
password = hp.generateRand('base64', 24);
break;
case 'aes-256-gcm':
case 'chacha20-ietf-poly1305':
case 'xchacha20-ietf-poly1305':
case '2022-blake3-aes-256-gcm':
case '2022-blake3-chacha20-poly1305':
password = hp.generateRand('base64', 32);
break;
case 'none':
password = '';
break;
case 'uuid':
password = hp.generateRand('uuid');
break;
default:
password = hp.generateRand('hex', 16);
break;
}
return widget.value = password;
}
return view.extend({ return view.extend({
load: function() { load: function() {
return Promise.all([ return Promise.all([
@ -139,6 +180,17 @@ return view.extend({
o.depends('type', 'shadowsocks'); o.depends('type', 'shadowsocks');
o.depends('type', 'trojan'); o.depends('type', 'trojan');
o.depends('type', 'tuic'); o.depends('type', 'tuic');
o.renderWidget = function() {
var node = form.Value.prototype.renderWidget.apply(this, arguments);
(node.querySelector('.control-group') || node).appendChild(E('button', {
'class': 'cbi-button cbi-button-apply',
'title': _('Generate'),
'click': ui.createHandlerFn(this, handleGenKey, this.option)
}, [ _('Generate') ]));
return node;
}
o.validate = function(section_id, value) { o.validate = function(section_id, value) {
if (section_id) { if (section_id) {
var type = this.map.lookupOption('type', section_id)[0].formvalue(section_id); var type = this.map.lookupOption('type', section_id)[0].formvalue(section_id);
@ -265,6 +317,17 @@ return view.extend({
o.depends('type', 'tuic'); o.depends('type', 'tuic');
o.depends('type', 'vless'); o.depends('type', 'vless');
o.depends('type', 'vmess'); o.depends('type', 'vmess');
o.renderWidget = function() {
var node = form.Value.prototype.renderWidget.apply(this, arguments);
(node.querySelector('.control-group') || node).appendChild(E('button', {
'class': 'cbi-button cbi-button-apply',
'title': _('Generate'),
'click': ui.createHandlerFn(this, handleGenKey, this.option)
}, [ _('Generate') ]));
return node;
}
o.validate = hp.validateUUID; o.validate = hp.validateUUID;
o.modalonly = true; o.modalonly = true;
@ -277,7 +340,7 @@ return view.extend({
o.depends('type', 'tuic'); o.depends('type', 'tuic');
o.modalonly = true; o.modalonly = true;
o = s.option(form.ListValue, 'tuic_auth_timeout', _('Auth timeout'), o = s.option(form.Value, 'tuic_auth_timeout', _('Auth timeout'),
_('How long the server should wait for the client to send the authentication command (in seconds).')); _('How long the server should wait for the client to send the authentication command (in seconds).'));
o.datatype = 'uinteger'; o.datatype = 'uinteger';
o.default = '3'; o.default = '3';
@ -716,6 +779,13 @@ return view.extend({
o.depends({'network': 'tcp', '!reverse': true}); o.depends({'network': 'tcp', '!reverse': true});
o.modalonly = true; o.modalonly = true;
o = s.option(form.Value, 'udp_timeout', _('UDP NAT expiration time'),
_('In seconds. <code>300</code> is used by default.'));
o.datatype = 'uinteger';
o.default = '300';
o.depends({'network': 'tcp', '!reverse': true});
o.modalonly = true;
o = s.option(form.Flag, 'sniff_override', _('Override destination'), o = s.option(form.Flag, 'sniff_override', _('Override destination'),
_('Override the connection destination address with the sniffed domain.')); _('Override the connection destination address with the sniffed domain.'));
o.rmempty = false; o.rmempty = false;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@ config homeproxy 'infra'
option tproxy_port '5332' option tproxy_port '5332'
option dns_port '5333' option dns_port '5333'
option china_dns_port '5334' option china_dns_port '5334'
option udp_timeout ''
option tun_name 'singtun0' option tun_name 'singtun0'
option tun_addr4 '172.19.0.1/30' option tun_addr4 '172.19.0.1/30'
option tun_addr6 'fdfe:dcba:9876::1/126' option tun_addr6 'fdfe:dcba:9876::1/126'

View File

@ -93,7 +93,10 @@ const cache_file_store_rdrc = uci.get(uciconfig, uciexp, 'cache_file_store_rdrc'
const mixed_port = uci.get(uciconfig, uciinfra, 'mixed_port') || '5330'; const mixed_port = uci.get(uciconfig, uciinfra, 'mixed_port') || '5330';
let self_mark, redirect_port, tproxy_port, let self_mark, redirect_port, tproxy_port,
tun_name, tun_addr4, tun_addr6, tun_mtu, tun_gso, tun_name, tun_addr4, tun_addr6, tun_mtu, tun_gso,
tcpip_stack, endpoint_independent_nat; tcpip_stack, endpoint_independent_nat, udp_timeout;
udp_timeout = uci.get(uciconfig, 'infra', 'udp_timeout');
if (routing_mode === 'custom')
udp_timeout = uci.get(uciconfig, uciroutingsetting, 'udp_timeout');
if (match(proxy_mode, /redirect/)) { if (match(proxy_mode, /redirect/)) {
self_mark = uci.get(uciconfig, 'infra', 'self_mark') || '100'; self_mark = uci.get(uciconfig, 'infra', 'self_mark') || '100';
redirect_port = uci.get(uciconfig, 'infra', 'redirect_port') || '5331'; redirect_port = uci.get(uciconfig, 'infra', 'redirect_port') || '5331';
@ -160,6 +163,7 @@ function generate_outbound(node) {
/* Direct */ /* Direct */
override_address: node.override_address, override_address: node.override_address,
override_port: strToInt(node.override_port), override_port: strToInt(node.override_port),
proxy_protocol: strToInt(node.proxy_protocol),
/* Hysteria (2) */ /* Hysteria (2) */
up_mbps: strToInt(node.hysteria_up_mbps), up_mbps: strToInt(node.hysteria_up_mbps),
down_mbps: strToInt(node.hysteria_down_mbps), down_mbps: strToInt(node.hysteria_down_mbps),
@ -482,6 +486,7 @@ push(config.inbounds, {
tag: 'mixed-in', tag: 'mixed-in',
listen: '::', listen: '::',
listen_port: int(mixed_port), listen_port: int(mixed_port),
udp_timeout: udp_timeout ? (udp_timeout + 's') : null,
sniff: true, sniff: true,
sniff_override_destination: (sniff_override === '1'), sniff_override_destination: (sniff_override === '1'),
set_system_proxy: false set_system_proxy: false
@ -505,6 +510,7 @@ if (match(proxy_mode, /tproxy/))
listen: '::', listen: '::',
listen_port: int(tproxy_port), listen_port: int(tproxy_port),
network: 'udp', network: 'udp',
udp_timeout: udp_timeout ? (udp_timeout + 's') : null,
sniff: true, sniff: true,
sniff_override_destination: (sniff_override === '1') sniff_override_destination: (sniff_override === '1')
}); });
@ -520,6 +526,7 @@ if (match(proxy_mode, /tun/))
gso: (tun_gso === '1'), gso: (tun_gso === '1'),
auto_route: false, auto_route: false,
endpoint_independent_nat: strToBool(endpoint_independent_nat), endpoint_independent_nat: strToBool(endpoint_independent_nat),
udp_timeout: udp_timeout ? (udp_timeout + 's') : null,
stack: tcpip_stack, stack: tcpip_stack,
sniff: true, sniff: true,
sniff_override_destination: (sniff_override === '1'), sniff_override_destination: (sniff_override === '1'),

View File

@ -49,6 +49,7 @@ uci.foreach(uciconfig, uciserver, (cfg) => {
tcp_fast_open: strToBool(cfg.tcp_fast_open), tcp_fast_open: strToBool(cfg.tcp_fast_open),
tcp_multi_path: strToBool(cfg.tcp_multi_path), tcp_multi_path: strToBool(cfg.tcp_multi_path),
udp_fragment: strToBool(cfg.udp_fragment), udp_fragment: strToBool(cfg.udp_fragment),
udp_timeout: cfg.udp_timeout ? (cfg.udp_timeout + 's') : null,
sniff: true, sniff: true,
sniff_override_destination: (cfg.sniff_override === '1'), sniff_override_destination: (cfg.sniff_override === '1'),
domain_strategy: cfg.domain_strategy, domain_strategy: cfg.domain_strategy,