Skip to content

Commit

Permalink
feat(client): add urltest support for simple mode
Browse files Browse the repository at this point in the history
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
  • Loading branch information
1715173329 committed Jan 11, 2025
1 parent 5c226ff commit d53de2f
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 6 deletions.
45 changes: 45 additions & 0 deletions htdocs/luci-static/resources/view/homeproxy/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,21 +140,61 @@ return view.extend({

o = s.taboption('routing', form.ListValue, 'main_node', _('Main node'));
o.value('nil', _('Disable'));
o.value('urltest', _('URLTest'));
for (let i in proxy_nodes)
o.value(i, proxy_nodes[i]);
o.default = 'nil';
o.depends({'routing_mode': 'custom', '!reverse': true});
o.rmempty = false;

o = s.taboption('routing', hp.CBIStaticList, 'main_urltest_nodes', _('URLTest nodes'),
_('List of nodes to test.'));
for (let i in proxy_nodes)
o.value(i, proxy_nodes[i]);
o.depends('main_node', 'urltest');
o.rmempty = false;

o = s.taboption('routing', form.Value, 'main_urltest_interval', _('Test interval'),
_('The test interval in seconds. <code>180</code> will be used if empty.'));
o.datatype = 'uinteger';
o.placeholder = '180';
o.depends('main_node', 'urltest');

o = s.taboption('routing', form.Value, 'main_urltest_tolerance', _('Test tolerance'),
_('The test tolerance in milliseconds. <code>50</code> will be used if empty.'));
o.datatype = 'uinteger';
o.placeholder = '50';
o.depends('main_node', 'urltest');

o = s.taboption('routing', form.ListValue, 'main_udp_node', _('Main UDP node'));
o.value('nil', _('Disable'));
o.value('same', _('Same as main node'));
o.value('urltest', _('URLTest'));
for (let i in proxy_nodes)
o.value(i, proxy_nodes[i]);
o.default = 'nil';
o.depends({'routing_mode': /^((?!custom).)+$/, 'proxy_mode': /^((?!redirect$).)+$/});
o.rmempty = false;

o = s.taboption('routing', hp.CBIStaticList, 'main_udp_urltest_nodes', _('URLTest nodes'),
_('List of nodes to test.'));
for (let i in proxy_nodes)
o.value(i, proxy_nodes[i]);
o.depends('main_udp_node', 'urltest');
o.rmempty = false;

o = s.taboption('routing', form.Value, 'main_udp_urltest_interval', _('Test interval'),
_('The test interval in seconds. <code>180</code> will be used if empty.'));
o.datatype = 'uinteger';
o.placeholder = '180';
o.depends('main_udp_node', 'urltest');

o = s.taboption('routing', form.Value, 'main_udp_urltest_tolerance', _('Test tolerance'),
_('The test tolerance in milliseconds. <code>50</code> will be used if empty.'));
o.datatype = 'uinteger';
o.placeholder = '50';
o.depends('main_udp_node', 'urltest');

o = s.taboption('routing', form.Value, 'dns_server', _('DNS server'),
_('Support UDP, TCP, DoH, DoQ, DoT. TCP protocol will be used if not specified.'));
o.value('wan', _('WAN DNS (read from interface)'));
Expand Down Expand Up @@ -447,10 +487,12 @@ return view.extend({
for (let i in proxy_nodes)
so.value(i, proxy_nodes[i]);
so.depends('node', 'urltest');
so.rmempty = false;
so.modalonly = true;

so = ss.option(form.Value, 'urltest_url', _('Test URL'),
_('The URL to test. <code>https://www.gstatic.com/generate_204</code> will be used if empty.'));
so.placeholder = 'https://www.gstatic.com/generate_204';
so.validate = function(section_id, value) {
if (section_id && value) {
try {
Expand All @@ -471,6 +513,7 @@ return view.extend({
so = ss.option(form.Value, 'urltest_interval', _('Test interval'),
_('The test interval in seconds. <code>180</code> will be used if empty.'));
so.datatype = 'uinteger';
so.placeholder = '180';
so.validate = function(section_id, value) {
if (section_id && value) {
let idle_timeout = this.map.lookupOption('urltest_idle_timeout', section_id)[0].formvalue(section_id) || '1800';
Expand All @@ -486,12 +529,14 @@ return view.extend({
so = ss.option(form.Value, 'urltest_tolerance', _('Test tolerance'),
_('The test tolerance in milliseconds. <code>50</code> will be used if empty.'));
so.datatype = 'uinteger';
so.placeholder = '50';
so.depends('node', 'urltest');
so.modalonly = true;

so = ss.option(form.Value, 'urltest_idle_timeout', _('Idle timeout'),
_('The idle timeout in seconds. <code>1800</code> will be used if empty.'));
so.datatype = 'uinteger';
so.placeholder = '1800';
so.depends('node', 'urltest');
so.modalonly = true;

Expand Down
48 changes: 42 additions & 6 deletions root/etc/homeproxy/scripts/generate_client.uc
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,6 @@ if (!isEmpty(main_node)) {
server: 'china-dns'
});
}

} else if (!isEmpty(default_outbound)) {
/* DNS servers */
uci.foreach(uciconfig, ucidnsserver, (cfg) => {
Expand Down Expand Up @@ -584,17 +583,54 @@ config.outbounds = [

/* Main outbounds */
if (!isEmpty(main_node)) {
const main_node_cfg = uci.get_all(uciconfig, main_node) || {};
push(config.outbounds, generate_outbound(main_node_cfg));
config.outbounds[length(config.outbounds)-1].domain_strategy = (ipv6_support !== '1') ? 'prefer_ipv4' : null;
config.outbounds[length(config.outbounds)-1].tag = 'main-out';
let urltest_nodes = [];

if (main_node === 'urltest') {
const main_urltest_nodes = uci.get(uciconfig, ucimain, 'main_urltest_nodes') || [];
const main_urltest_interval = uci.get(uciconfig, ucimain, 'main_urltest_interval');
const main_urltest_tolerance = uci.get(uciconfig, ucimain, 'main_urltest_tolerance');

push(config.outbounds, {
type: 'urltest',
tag: 'main-out',
outbounds: map(main_urltest_nodes, (k) => `cfg-${k}-out`),
interval: main_urltest_interval ? (main_urltest_interval + 's') : null,
tolerance: strToInt(main_urltest_tolerance),
idle_timeout: (strToInt(main_urltest_interval) > 1800) ? `${main_urltest_interval * 2}s` : null,
});
urltest_nodes = main_urltest_nodes;
} else {
const main_node_cfg = uci.get_all(uciconfig, main_node) || {};
push(config.outbounds, generate_outbound(main_node_cfg));
config.outbounds[length(config.outbounds)-1].domain_strategy = (ipv6_support !== '1') ? 'prefer_ipv4' : null;
config.outbounds[length(config.outbounds)-1].tag = 'main-out';
}

if (dedicated_udp_node) {
if (main_udp_node === 'urltest') {
const main_udp_urltest_nodes = uci.get(uciconfig, ucimain, 'main_udp_urltest_nodes') || [];
const main_udp_urltest_interval = uci.get(uciconfig, ucimain, 'main_udp_urltest_interval');
const main_udp_urltest_tolerance = uci.get(uciconfig, ucimain, 'main_udp_urltest_tolerance');

push(config.outbounds, {
type: 'urltest',
tag: 'main-udp-out',
outbounds: map(main_udp_urltest_nodes, (k) => `cfg-${k}-out`),
interval: main_udp_urltest_interval ? (main_udp_urltest_interval + 's') : null,
tolerance: strToInt(main_udp_urltest_tolerance),
idle_timeout: (strToInt(main_udp_urltest_interval) > 1800) ? `${main_udp_urltest_interval * 2}s` : null,
});
urltest_nodes = [...urltest_nodes, ...filter(main_udp_urltest_nodes, ((l) => !~index(urltest_nodes, l)))];
} else if (dedicated_udp_node) {
const main_udp_node_cfg = uci.get_all(uciconfig, main_udp_node) || {};
push(config.outbounds, generate_outbound(main_udp_node_cfg));
config.outbounds[length(config.outbounds)-1].domain_strategy = (ipv6_support !== '1') ? 'prefer_ipv4' : null;
config.outbounds[length(config.outbounds)-1].tag = 'main-udp-out';
}

for (let i in urltest_nodes) {
push(config.outbounds, generate_outbound(uci.get_all(uciconfig, i)));
config.outbounds[length(config.outbounds)-1].domain_strategy = (ipv6_support !== '1') ? 'prefer_ipv4' : null;
}
} else if (!isEmpty(default_outbound)) {
let urltest_nodes = [],
routing_nodes = [];
Expand Down

0 comments on commit d53de2f

Please sign in to comment.