🍓 Sync 2026-05-07 20:40:44

This commit is contained in:
github-actions[bot] 2026-05-07 20:40:44 +08:00
parent 8c8d04257c
commit 3d2871dd73
14 changed files with 132 additions and 52 deletions

View File

@ -5,8 +5,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=dufs
PKG_VERSION:=0.45.0
PKG_RELEASE:=1
PKG_VERSION:=0.46.0
PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/sigoden/dufs/tar.gz/v$(PKG_VERSION)?

View File

@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=hickory-dns
PKG_VERSION:=0.26.1
PKG_RELEASE:=20
PKG_RELEASE:=21
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/hickory-dns/hickory-dns/tar.gz/v$(PKG_VERSION)?

View File

@ -31,8 +31,3 @@ start_service() {
# dynamic DNS entries from the current neighbour table.
/etc/init.d/ipv6-neigh restart
}
service_triggers() {
procd_add_reload_trigger "dhcp" "network" "system"
procd_add_reload_interface_trigger "wan_6"
}

View File

@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=ipv6-neigh
PKG_VERSION:=0.1.0
PKG_RELEASE:=5
PKG_RELEASE:=6
PKG_BUILD_DEPENDS:=rust/host
PKG_BUILD_PARALLEL:=1

View File

@ -8,7 +8,8 @@ PROG=/usr/bin/ipv6-neigh
start_service() {
procd_open_instance ipv6-neigh
procd_set_param command $PROG -p -d "[::1]:53" -z lan
# 默认: IPv4 仅私网IPv6 允许公网(GUA)
procd_set_param command $PROG --private-subnet-v4 -d "[::1]:53" -z lan
procd_set_param stdout 1
procd_set_param stderr 1
procd_set_param respawn "${respawn_threshold:-3600}" "${respawn_timeout:-5}" "${respawn_retry:-5}"

View File

@ -1,12 +1,13 @@
use std::collections::HashMap;
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr as StdSocketAddr};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr as StdSocketAddr};
use std::time::Instant;
use futures::stream::StreamExt;
use futures::stream::TryStreamExt;
use log::{debug, error, info};
use log::{debug, error, info, warn};
use netlink_packet_core::NetlinkPayload;
use netlink_packet_route::RouteNetlinkMessage;
use netlink_packet_route::address::AddressAttribute;
use netlink_packet_route::neighbour::NeighbourMessage;
use netlink_packet_route::neighbour::{NeighbourAddress, NeighbourAttribute, NeighbourState};
use netlink_packet_route::route::RouteType;
@ -35,8 +36,12 @@ const fn nl_mgrp(group: u32) -> u32 {
#[derive(Debug, Parser)]
#[clap()]
struct Cli {
#[clap(short, long)]
private_subnet: bool,
/// Restrict IPv4 neighbours to private subnets only (10/8, 172.16/12, 192.168/16, 127/8)
#[clap(long)]
private_subnet_v4: bool,
/// Restrict IPv6 neighbours to ULA (fc00::/7) only; without this flag GUA is also included
#[clap(long)]
private_subnet_v6: bool,
/// hickory-dns server address for DNS updates (e.g. "[::1]:5335")
#[clap(short, long, default_value = "[::1]:5335")]
dns_server: StdSocketAddr,
@ -53,8 +58,11 @@ struct Cli {
#[clap(short = 'l', long, default_value = "info")]
log_level: String,
/// Probe interval in seconds for active reachability checks (0 to disable)
#[clap(long, default_value = "120")]
#[clap(long, default_value = "75")]
probe_interval: u64,
/// Network interface to read the router's own addresses from
#[clap(long, default_value = "br-lan")]
router_iface: String,
}
#[derive(Debug)]
@ -68,12 +76,8 @@ struct Neigh {
fn if_ipv6_in_private_subnet(ip: &Ipv6Addr) -> bool {
// Check if address is ULA (fc00::/7)
let is_ula = (ip.segments()[0] & 0xfe00) == 0xfc00;
// Check if address is link-local (fe80::/10)
let is_link_local = (ip.segments()[0] & 0xffc0) == 0xfe80;
is_ula || is_link_local
// Note: link-local is always filtered earlier by is_link_local_ipv6()
(ip.segments()[0] & 0xfe00) == 0xfc00
}
fn if_ipv4_in_private_subnet(ip: &Ipv4Addr) -> bool {
@ -177,7 +181,8 @@ async fn main() -> Result<(), ()> {
.format_timestamp_secs()
.init();
let private_subnet = args.private_subnet;
let private_subnet_v4 = args.private_subnet_v4;
let private_subnet_v6 = args.private_subnet_v6;
let zone = Name::from_ascii(&args.zone).expect("invalid zone name");
let key_data = std::fs::read(&args.key_file)
@ -191,6 +196,24 @@ async fn main() -> Result<(), ()> {
let (connection, handle, _) = new_connection().unwrap();
tokio::spawn(connection);
// Register router's own addresses in DNS
let router_hostname = std::fs::read_to_string("/proc/sys/kernel/hostname")
.unwrap_or_default()
.trim()
.to_owned();
if router_hostname.is_empty() {
warn!("could not read router hostname from /proc/sys/kernel/hostname");
} else {
register_router_addresses(
handle.clone(),
&args.router_iface,
&router_hostname,
&updater,
private_subnet_v6,
)
.await;
}
// Load DHCP leases (mac -> hostname) from ubus
let mut leases = op::get_lease().unwrap_or_default();
info!("loaded {} DHCP leases", leases.len());
@ -200,7 +223,7 @@ async fn main() -> Result<(), ()> {
// Dump existing neighbours and register only reachable/stale ones
debug!("dumping neighbours");
if let Ok(neighbours) = dump_neighbours(handle.clone(), private_subnet).await {
if let Ok(neighbours) = dump_neighbours(handle.clone(), private_subnet_v4, private_subnet_v6).await {
for neigh in &neighbours {
debug!("{:?}", neigh);
if should_skip_neigh(neigh) || !is_reachable_state(neigh.state) {
@ -260,7 +283,7 @@ async fn main() -> Result<(), ()> {
if let NetlinkPayload::InnerMessage(msg) = payload {
match msg {
RouteNetlinkMessage::NewNeighbour(new_neigh) => {
let Some(neigh) = parse_neighbour_message(new_neigh, private_subnet) else {
let Some(neigh) = parse_neighbour_message(new_neigh, private_subnet_v4, private_subnet_v6) else {
continue;
};
if should_skip_neigh(&neigh) {
@ -291,7 +314,7 @@ async fn main() -> Result<(), ()> {
}
}
RouteNetlinkMessage::DelNeighbour(del_neigh) => {
let Some(neigh) = parse_neighbour_message(del_neigh, private_subnet) else {
let Some(neigh) = parse_neighbour_message(del_neigh, private_subnet_v4, private_subnet_v6) else {
continue;
};
if should_skip_neigh(&neigh) {
@ -387,7 +410,7 @@ fn is_link_local_ipv6(addr: &NeighbourAddress) -> bool {
matches!(addr, NeighbourAddress::Inet6(ip) if (ip.segments()[0] & 0xffc0) == 0xfe80)
}
fn parse_neighbour_message(neigh: NeighbourMessage, private_subnet: bool) -> Option<Neigh> {
fn parse_neighbour_message(neigh: NeighbourMessage, private_subnet_v4: bool, private_subnet_v6: bool) -> Option<Neigh> {
let state = neigh.header.state;
// Filter out static and incomplete entries
if matches!(state, NeighbourState::Permanent | NeighbourState::Noarp) {
@ -401,20 +424,18 @@ fn parse_neighbour_message(neigh: NeighbourMessage, private_subnet: bool) -> Opt
if is_link_local_ipv6(&addr) {
return None;
}
if private_subnet {
match addr {
NeighbourAddress::Inet(addr) => {
if !if_ipv4_in_private_subnet(&addr) {
return None;
}
match addr {
NeighbourAddress::Inet(addr) => {
if private_subnet_v4 && !if_ipv4_in_private_subnet(&addr) {
return None;
}
NeighbourAddress::Inet6(addr) => {
if !if_ipv6_in_private_subnet(&addr) {
return None;
}
}
_ => {}
}
NeighbourAddress::Inet6(addr) => {
if private_subnet_v6 && !if_ipv6_in_private_subnet(&addr) {
return None;
}
}
_ => {}
};
let kind = neigh.header.kind;
let ifindex = neigh.header.ifindex;
@ -436,11 +457,11 @@ fn parse_neighbour_message(neigh: NeighbourMessage, private_subnet: bool) -> Opt
})
}
async fn dump_neighbours(handle: Handle, private_subnet: bool) -> Result<Vec<Neigh>, Error> {
async fn dump_neighbours(handle: Handle, private_subnet_v4: bool, private_subnet_v6: bool) -> Result<Vec<Neigh>, Error> {
let mut neighbours = handle.neighbours().get().execute();
let mut vec: Vec<Neigh> = Vec::new();
while let Some(route) = neighbours.try_next().await? {
if let Some(neigh) = parse_neighbour_message(route, private_subnet) {
if let Some(neigh) = parse_neighbour_message(route, private_subnet_v4, private_subnet_v6) {
if !should_skip_neigh(&neigh) {
vec.push(neigh);
}
@ -448,3 +469,58 @@ async fn dump_neighbours(handle: Handle, private_subnet: bool) -> Result<Vec<Nei
}
Ok(vec)
}
/// Enumerate addresses on `iface`, register A/AAAA records for the router itself.
async fn register_router_addresses(
handle: Handle,
iface: &str,
hostname: &str,
updater: &db::DnsUpdater,
private_subnet_v6: bool,
) {
let mut links = handle.link().get().match_name(iface.to_owned()).execute();
let link = match links.try_next().await {
Ok(Some(l)) => l,
Ok(None) => {
warn!("interface {} not found, skipping router address registration", iface);
return;
}
Err(e) => {
warn!("failed to find interface {}: {}", iface, e);
return;
}
};
let ifindex = link.header.index;
let mut addresses = handle.address().get().set_link_index_filter(ifindex).execute();
while let Ok(Some(msg)) = addresses.try_next().await {
for attr in &msg.attributes {
let ip = match attr {
AddressAttribute::Address(ip) => ip,
_ => continue,
};
match ip {
IpAddr::V6(addr) => {
// Always skip link-local
if (addr.segments()[0] & 0xffc0) == 0xfe80 {
continue;
}
// Restrict to ULA only when private_subnet_v6 is set
let is_ula = (addr.segments()[0] & 0xfe00) == 0xfc00;
if private_subnet_v6 && !is_ula {
continue;
}
match updater.upsert_aaaa(hostname, *addr, DEFAULT_TTL).await {
Ok(()) => info!("registered router {} AAAA {}", hostname, addr),
Err(e) => warn!("failed to register router AAAA {} for {}: {}", addr, hostname, e),
}
}
IpAddr::V4(addr) => {
match updater.upsert_a(hostname, *addr, DEFAULT_TTL).await {
Ok(()) => info!("registered router {} A {}", hostname, addr),
Err(e) => warn!("failed to register router A {} for {}: {}", addr, hostname, e),
}
}
}
}
}
}

View File

@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
PKG_VERSION:=26.5.3
PKG_RELEASE:=114
PKG_RELEASE:=115
PKG_PO_VERSION:=$(PKG_VERSION)
PKG_CONFIG_DEPENDS:= \

View File

@ -613,13 +613,17 @@ function delete_select_nodes()
uci:delete(appname, t[".name"])
socks = "Socks_" .. t[".name"]
end
local changed = false
local auto_switch_node_list = uci:get(appname, t[".name"], "autoswitch_backup_node") or {}
for i = #auto_switch_node_list, 1, -1 do
if w == auto_switch_node_list[i] then
table.remove(auto_switch_node_list, i)
changed = true
end
end
uci:set_list(appname, t[".name"], "autoswitch_backup_node", auto_switch_node_list)
if changed then
uci:set_list(appname, t[".name"], "autoswitch_backup_node", auto_switch_node_list)
end
end)
local tcp_node = uci:get(appname, "@global[0]", "tcp_node") or ""
if tcp_node == w or tcp_node == socks then

View File

@ -186,7 +186,7 @@ if load_balancing_options then -- [[ Load balancing Start ]]
o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
end
for k1, v1 in pairs(node_list) do
if k1 == "socks_list" or k1 == "normal_list" then
if k1 == "socks_list" or k1 == "normal_list" or k1 == "urltest_list" then
for i, v in ipairs(v1) do
o:value(v.id, v.remark)
o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")

View File

@ -1267,7 +1267,6 @@ function gen_config(var)
else
ut_nodes = _node.urltest_node
end
if #ut_nodes == 0 then return nil end
local valid_nodes = {}
for i = 1, #(ut_nodes or {}) do
local ut_node_id = ut_nodes[i]

View File

@ -1543,8 +1543,13 @@ start_adblock() {
start_haproxy() {
[ "$(config_t_get global_haproxy balancing_enable 0)" != "1" ] && return
haproxy_path=$TMP_PATH/haproxy
haproxy_conf="config.cfg"
local haproxy_ver=$($(first_type haproxy) -v 2>/dev/null | awk 'NR==1 {print $3}' | cut -d'-' -f1)
if [ "$(check_ver "$haproxy_ver" "3.0.0")" = "1" ]; then
echolog "* 注意haproxy($haproxy_ver) 程序版本低HAPROXY 负载均衡启动失败,请更新到 3.0 以上版本。"
return
fi
local haproxy_path=$TMP_PATH/haproxy
local haproxy_conf="config.cfg"
lua $APP_PATH/haproxy.lua -path ${haproxy_path} -conf ${haproxy_conf} -dns ${LOCAL_DNS}
ln_run "$(first_type haproxy)" haproxy "/dev/null" -f "${haproxy_path}/${haproxy_conf}"
}

View File

@ -10,12 +10,12 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=natflow
PKG_VERSION:=20260313
PKG_RELEASE:=7
PKG_RELEASE:=8
PKG_SOURCE:=$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://github.com/ptpt52/natflow.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=9a7789da898a627f3f55f821260f5695bb98f868
PKG_SOURCE_VERSION:=22c630b387a5ca027bc77d3364818ed87e0a6254
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_MAINTAINER:=Chen Minqiang <ptpt52@gmail.com>
PKG_LICENSE:=GPL-2.0

View File

@ -5,8 +5,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=tuic-client
PKG_VERSION:=1.7.2
PKG_RELEASE:=3
PKG_VERSION:=1.8.1
PKG_RELEASE:=4
PKG_LICENSE_FILES:=LICENSE
PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>

View File

@ -2,11 +2,11 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=tun2socks
PKG_VERSION:=2.6.0
PKG_RELEASE:=2
PKG_RELEASE:=3
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/xjasonlyu/tun2socks.git
PKG_SOURCE_VERSION:=1d8af8ed96bc281b81b319193c94305f074e34be
PKG_SOURCE_VERSION:=a9747fa54b2b2bfa6e3411220fd660dcc00acfc1
PKG_MAINTAINER:=Konstantine Shevlakov <shevlako@132lan.ru>
PKG_LICENSE:=GPL-3.0