meow_netmgrd 期4:SDK 自愿通道 + wifi forget + RSSI signal_poll + AAAA 过滤 + iptables 评估
NETMGR_DESIGN.md §7/§13 期4 落地(只动 patch_v2/meow_netmgrd/ + patch_v2/sdk/ 追加式): 1. SDK 自愿通道(§6.3/§4):meow_ui.h 新增 meow_net_policy_check(host)(0=放行 1=block; netmgrd 不在/超时→0 乐观放行)+ meow_net_report(rx,tx)(自愿上报,§4 字节级记账自报通道)。 meow_ipc.h 追加 0xEE MSG_NET_SDK(op=CHECK/REPORT)/ 0xEF RESULT。netmgrd 侧:CHECK 以 app_id→实体 app:<pkg> 评估 policy_net_blocked||dns_query_domain_denied;REPORT 记入 per-实体 g_ent_bytes(status JSON 新增 entity_bytes)。SDK 实现 meow_net_ipc.c(一次 connect+send+read, 降级不崩);meow_ui.a 重编。 2. wifi forget <id>:wpa_cli remove_network+save_config(MeowOS;HibyOS 只读门控),CLI+IPC 接通 (286 launcher 录入 UI 缺口)。 3. RSSI:wifi_status 在 status 无 signal= 时回退 wpa_cli signal_poll(真机 rssi=-38,修面板 rssi=null 缺口)。 4. DNS AAAA 过滤:global dns.filter_aaaa=0|1(默认 0 透传;纯 IPv4 设备可置 1 让 AAAA 查询回空答案回落 A)。 5. 静态 iptables 评估(devdocs/plan/NETMGR_IPTABLES_EVAL.md,本机不入库):iptables-legacy 1.8.9 交叉 编译成功(~578KB,含 owner/cgroup/REDIRECT 等全部 extension),但内核实测 matches 仅 quota/icmp/udp/tcp、targets 仅 NFQUEUE/NFLOG/ERROR、无 nat 表、全部进程 UID 0 → **per-app 管控 与 REDIRECT 透明代理判不可行**(与 NETWORK_HW_FACTS 一致);正路为 per-app UID 框架改造(单独立项)。 验证:宿主 test_netmgrd.sh 70/70 + qemu 70/70;test_netmgrd_p2/p3/p5 宿主全过 + 交叉 0 warning; netmgrd_authtest 全过;sdk meow_net_ipc 交叉 0 warning。真机(固件 netmgrd 共存,独立 socket+DNS off): wifi status rssi=-38(signal_poll)、wifi forget 0(DISABLED 安全移除,id1 CURRENT 保留、wifi 未断)、 SDK policy check(CHECK_GOOD=0/CHECK_BLOCK=1/REPORT ok)、policy show 正常;resolv.conf 未触碰、 固件 meow_netmgrd(pid) running 未动;测试产物全清。 新 md5:meow_netmgrd 20243ea1a800b29badefebb395603aaf;meow_ui.a be24214e24faadba63577f3a98c2c9d1 (主会话更 fw_content.conf / 热更设备 / 记录新 meow_ui.a)。
This commit is contained in:
1 parent
4e0e7441fd
commit
8a43f17653
17 files changed
+563
-16
No files matched your search
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* meow_net_ipc.c — MeowOS SDK 网络自愿通道 → netmgrd IPC 桥(期4;追加式协议 0x00EE/0x00EF)。
|
||||
*
|
||||
* 与 meow_notify_ipc.c 同型:只做「一次性 connect + send + read」,不维护连接/订阅循环。
|
||||
* - meow_net_policy_check(host):MSG_NET_SDK op=NET_SDK_CHECK(app_id=MEOW_LOG_APP + host);
|
||||
* 读到 allow=1 → 返回 0(allow),allow=0 → 返回 1(block);任何失败(无 socket/超时/非法应答)
|
||||
* → 返回 0(乐观放行,绝不因监控不可用误封业务——NETMGR_DESIGN §6.3 自愿性质)。
|
||||
* - meow_net_report(rx,tx):MSG_NET_SDK op=NET_SDK_REPORT;send 后读一次应答头即关(不读文本),
|
||||
* best-effort,失败静默(返回值 void)。
|
||||
* 映射层(SDK 入参 ↔ IPC m_net_sdk_t 字段)集中在本文件;app_id 取 env MEOW_LOG_APP(与 meow_ui_log.c
|
||||
* 口径一致),socket 路径取 env MEOW_NET_SOCK(宿主/qemu 覆盖)缺省 /usr/data/meow_net.sock。
|
||||
*
|
||||
* 线程安全:app_id pthread_once 缓存;本文件纯传输层不调 meow_log(与 meow_notify_ipc.c 同约定)。
|
||||
*/
|
||||
#include "meow_net_ipc.h"
|
||||
#include "meow_ipc.h" /* 共享协议:帧头/m_net_sdk_t/m_net_sdk_result_t/MSG_NET_SDK* —— 防漂移 */
|
||||
|
||||
#include <stdio.h> /* snprintf */
|
||||
#include <stdlib.h> /* getenv */
|
||||
#include <string.h>
|
||||
#include <errno.h> /* EINTR */
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define MEOW_NET_IPC_TIMEOUT_MS 500 /* 应答读超时:netmgrd 单线程 poll,>500ms 视为降级 */
|
||||
|
||||
static pthread_once_t g_once = PTHREAD_ONCE_INIT;
|
||||
static char g_app_id[MEOW_APP_ID_MAX] = "app";
|
||||
|
||||
static void ipc_init(void)
|
||||
{
|
||||
const char *s = getenv("MEOW_LOG_APP");
|
||||
if (s && s[0]) snprintf(g_app_id, sizeof g_app_id, "%s", s);
|
||||
}
|
||||
|
||||
const char *meow_net_ipc_app_id(void)
|
||||
{
|
||||
pthread_once(&g_once, ipc_init);
|
||||
return g_app_id;
|
||||
}
|
||||
|
||||
/* socket 路径:优先 env MEOW_NET_SOCK,缺省 /usr/data/meow_net.sock。 */
|
||||
static const char *ipc_sock_path(void)
|
||||
{
|
||||
const char *s = getenv("MEOW_NET_SOCK");
|
||||
return (s && s[0]) ? s : "/usr/data/meow_net.sock";
|
||||
}
|
||||
|
||||
/* 连接 socket;失败 -1(调用方降级)。 */
|
||||
static int conn_path(const char *path)
|
||||
{
|
||||
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd < 0) return -1;
|
||||
struct sockaddr_un a;
|
||||
memset(&a, 0, sizeof a);
|
||||
a.sun_family = AF_UNIX;
|
||||
strncpy(a.sun_path, path, sizeof a.sun_path - 1);
|
||||
if (connect(fd, (struct sockaddr *)&a, sizeof a) < 0) { close(fd); return -1; }
|
||||
return fd;
|
||||
}
|
||||
static int write_all(int fd, const uint8_t *p, size_t n)
|
||||
{
|
||||
size_t off = 0;
|
||||
while (off < n) {
|
||||
ssize_t w = write(fd, p + off, n - off);
|
||||
if (w < 0) { if (errno == EINTR) continue; return 0; }
|
||||
if (w == 0) return 0;
|
||||
off += (size_t)w;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
static int read_all(int fd, uint8_t *p, size_t n)
|
||||
{
|
||||
size_t off = 0;
|
||||
while (off < n) {
|
||||
ssize_t r = read(fd, p + off, n - off);
|
||||
if (r < 0) { if (errno == EINTR) continue; return 0; }
|
||||
if (r == 0) return 0;
|
||||
off += (size_t)r;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
static int send_frame(int fd, uint16_t type, uint32_t req_id, const void *payload, uint32_t len)
|
||||
{
|
||||
uint8_t hdr[MEOW_IPC_HDR_LEN];
|
||||
uint32_t magic = MEOW_IPC_MAGIC, rl = len;
|
||||
uint16_t ver = MEOW_IPC_VERSION, t = type;
|
||||
memcpy(hdr + 0, &magic, 4); memcpy(hdr + 4, &ver, 2); memcpy(hdr + 6, &t, 2);
|
||||
memcpy(hdr + 8, &req_id, 4); memcpy(hdr + 12, &rl, 4);
|
||||
if (!write_all(fd, hdr, sizeof hdr)) return 0;
|
||||
if (len && payload && !write_all(fd, payload, len)) return 0;
|
||||
return 1;
|
||||
}
|
||||
static void set_timeout(int fd)
|
||||
{
|
||||
struct timeval tv;
|
||||
tv.tv_sec = MEOW_NET_IPC_TIMEOUT_MS / 1000;
|
||||
tv.tv_usec = (MEOW_NET_IPC_TIMEOUT_MS % 1000) * 1000;
|
||||
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv);
|
||||
}
|
||||
|
||||
int meow_net_policy_check(const char *host)
|
||||
{
|
||||
if (!host || !host[0]) return 0;
|
||||
m_net_sdk_t q;
|
||||
memset(&q, 0, sizeof q);
|
||||
q.op = NET_SDK_CHECK;
|
||||
snprintf(q.app_id, sizeof q.app_id, "%s", meow_net_ipc_app_id());
|
||||
snprintf(q.host, sizeof q.host, "%s", host);
|
||||
|
||||
int fd = conn_path(ipc_sock_path());
|
||||
if (fd < 0) return 0; /* java socket:乐观放行 */
|
||||
set_timeout(fd);
|
||||
int allow = 0; /* 默认放行 */
|
||||
if (send_frame(fd, MSG_NET_SDK, 0x4E455443u /* "NETC" */, &q, (uint32_t)sizeof q)) {
|
||||
uint8_t rhdr[MEOW_IPC_HDR_LEN];
|
||||
if (read_all(fd, rhdr, sizeof rhdr)) {
|
||||
uint16_t rtype; uint32_t rlen;
|
||||
memcpy(&rtype, rhdr + 6, 2); memcpy(&rlen, rhdr + 12, 4);
|
||||
if (rtype == MSG_NET_SDK_RESULT && rlen >= 10) {
|
||||
uint8_t pay[12];
|
||||
if (read_all(fd, pay, 12)) { /* code(4)+allow(4)+text_len(2)+pad(2) */
|
||||
m_net_sdk_result_t res;
|
||||
memset(&res, 0, sizeof res);
|
||||
memcpy(&res.code, pay, 4);
|
||||
memcpy(&res.allow, pay + 4, 4);
|
||||
memcpy(&res.text_len, pay + 8, 2);
|
||||
if (res.text_len < sizeof res.text)
|
||||
read_all(fd, (uint8_t *)res.text, res.text_len);
|
||||
if (res.code == MEOW_OK) allow = (res.allow != 0) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
return allow ? 0 : 1; /* allow=1 → 返回 0(放行);allow=0 → 返回 1(block) */
|
||||
}
|
||||
|
||||
void meow_net_report(uint32_t rx, uint32_t tx)
|
||||
{
|
||||
m_net_sdk_t q;
|
||||
memset(&q, 0, sizeof q);
|
||||
q.op = NET_SDK_REPORT;
|
||||
snprintf(q.app_id, sizeof q.app_id, "%s", meow_net_ipc_app_id());
|
||||
q.rx = rx; q.tx = tx;
|
||||
int fd = conn_path(ipc_sock_path());
|
||||
if (fd < 0) return; /* 无 socket:静默 */
|
||||
set_timeout(fd);
|
||||
if (send_frame(fd, MSG_NET_SDK, 0x4E455452u /* "NETR" */, &q, (uint32_t)sizeof q)) {
|
||||
uint8_t rhdr[MEOW_IPC_HDR_LEN];
|
||||
read_all(fd, rhdr, sizeof rhdr); /* best-effort:读一次应答头即关,不解析 */
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
Reference in new issue
Block a user