parent
6229c68387
commit
40fd2535d5
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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');
|
||||||
|
@ -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
@ -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'
|
||||||
|
@ -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'),
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user