mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-01 03:25:13 +08:00
🍕 Sync 2026-09-14 23:30:37
This commit is contained in:
1 parent
0603b094cf
commit
81fe4cd866
214 files changed
+10806
-2630
No files matched your search
@@ -0,0 +1,19 @@
|
||||
The overview combines DHCPv4, DHCPv6 and resolved `br-lan` ARP entries by MAC.
|
||||
IPv6 leases without a MAC can join a client only when their addresses have an
|
||||
unambiguous MAC mapping in host hints or another lease. Hostnames alone never
|
||||
merge devices. DUID/IAID identify otherwise unknown lease records and preserve
|
||||
IPv6 reservation actions.
|
||||
|
||||
`luci-client-history` samples leases and ARP every ten seconds without requiring
|
||||
an open browser. It atomically checkpoints discovered records in
|
||||
`/tmp/luci-client-history.json`. Records are retained after lease/ARP expiry and
|
||||
collector/rpcd restarts; a new boot clears them. Collection starts when the
|
||||
service is installed/enabled, so earlier expired records cannot be reconstructed.
|
||||
Historical addresses are dimmed and excluded from live rates and reservation
|
||||
buttons. Totals remain the existing per-MAC conntrack accounting totals.
|
||||
|
||||
Run `ucode client-history.uc` on a target with the installed
|
||||
`luci.client_history` module. The tests cover LAN filtering, expiry, collector
|
||||
restart, IP reassignment, changing IPv6 addresses and boot-ID reset without
|
||||
rebooting the device. Run the existing frontend tests with
|
||||
`node libs/rpcd-mod-luci/tests/traffic-ui.js` from the LuCI repository.
|
||||
@@ -0,0 +1,29 @@
|
||||
// Run with ucode after installing luci.client_history on the test target.
|
||||
import { arp_leases, update_history } from 'luci.client_history';
|
||||
function check(value, message) {
|
||||
if (!value) die(message + '\n');
|
||||
};
|
||||
const arp = '192.168.0.2 0x1 0x2 aa:bb:cc:dd:ee:ff * br-lan\n' +
|
||||
'192.168.0.3 0x1 0x0 00:11:22:33:44:66 * br-lan\n' +
|
||||
'192.168.9.1 0x1 0x2 00:11:22:33:44:77 * eth1\n';
|
||||
let first = update_history({}, {
|
||||
dhcp_leases: arp_leases(arp),
|
||||
dhcp6_leases: [{ macaddr: 'aa:bb:cc:dd:ee:ff', duid: 'uuid', iaid: '1', ip6addrs: ['2001:db8::2/128'] }]
|
||||
}, 'boot-a');
|
||||
check(length(first.dhcp_leases) == 1, 'filter non-LAN and unresolved ARP');
|
||||
let absent = update_history(first, {}, 'boot-a');
|
||||
check(length(absent.dhcp_leases) == 1 && length(absent.dhcp6_leases) == 1, 'retain expired DHCP and ARP');
|
||||
let restored = update_history(json(sprintf('%J', absent)), {}, 'boot-a');
|
||||
check(sprintf('%J', restored) == sprintf('%J', absent), 'restore after collector restart');
|
||||
let updated = update_history(restored, {
|
||||
dhcp_leases: [{ macaddr: '00:11:22:33:44:66', ipaddr: '192.168.0.2', interface: 'br-lan' }],
|
||||
dhcp6_leases: [{ macaddr: 'AA:BB:CC:DD:EE:FF', duid: 'uuid', iaid: '1', ip6addrs: ['2001:db8::3/128'] }]
|
||||
}, 'boot-a');
|
||||
check(length(updated.dhcp_leases) == 2, 'preserve former owner after address reuse');
|
||||
check(length(updated.dhcp6_leases) == 1 && length(updated.dhcp6_leases[0].ip6addrs) == 2, 'retain IPv6 address changes');
|
||||
let repeat = update_history(updated, { dhcp_leases: arp_leases(arp) }, 'boot-a');
|
||||
check(length(repeat.dhcp_leases) == 2, 'deduplicate repeated discoveries');
|
||||
let rebooted = update_history(updated, {}, 'boot-b');
|
||||
check(!length(rebooted.dhcp_leases) && !length(rebooted.dhcp6_leases), 'new boot resets history');
|
||||
check(!length(update_history('invalid', {}, 'boot-a').dhcp_leases), 'recover invalid state');
|
||||
print('client history: LAN filtering, expiry, restart, reassignment, IPv6 changes and boot reset passed\n');
|
||||
Reference in new issue
Block a user