5.3 KiB
5.3 KiB
meow_mdns — 自研极简 IPv4-only mDNS 应答器(mipsel-linux-muslsf 静态)
目的:让 R3 Pro II / MeowOS 设备在纯 IPv4(内核无 IPv6)下应答
*.local, 使主机avahi-resolve <host>.local/avahi-browse能识别设备。 产出为自研 C 代码,零 IPv6 依赖,覆盖路径 A(mDNSResponder HAVE_IPV6=0)无法满足的功能缺口。
为什么不用 mDNSResponder / SAResponder
| 原因 | 说明 |
|---|---|
| 需 IPv6 | 两者都在 socket(AF_INET6) 处失败:Address family not supported by protocol。mDNSResponder 无 NOT_HAVE_IPV6 宏(0 处),IPv6 是运行时硬编码;即便 make HAVE_IPV6=0 编译通过(见下“路径 A 试验”),仍不解决下一条 |
| 不公布主机名 A 记录 | 完整版 mdnsd 是 IPC 服务型守护进程:它等客户端经 UDS(/var/run/mdnsd) 注册名字,自身不自动登记主机名。-debug 日志证实它只注册接口 wlan0 + _dns-sd 浏览记录,从无 ingenic.local A。应答记录需客户端调用 DNSServiceRegister,没有现成客户端 |
| SAResponder 单服务 | 只用 mDNS_RegisterService 注册单一服务,不注册主机 A 记录,ingenic.local 无法按名解析 |
路径 A 试验结论(编译层面 MVP,但功能不达标)
- 源码无
NOT_HAVE_IPV6;开关是 Makefile Linux 分支的-DHAVE_IPV6(第 113 行)+ 第 196-200 行HAVE_IPV6=0/1可覆盖。 make os=linux tls=no HAVE_IPV6=0 CC=zig-mipsel-cc CFLAGS="-Os -static -Wno-date-time" LD=... LINKOPTS="-s" Daemon能编译出 1015792B 的 mdnsd(md57ee68d626d718d0572d4087c5a584d7f),SetupSocket/接口枚举/unicast v6 socket 均被#if HAVE_IPV6移除;仅硬件地址那段socket(AF_INET6)被if(sockfd>=0)守护(无 IPv6 内核返回 -1,无害)。- 该 mdnsd 在设备上可运行(绑 0.0.0.0:5353 + 加入 224.0.0.251),但不发布主机名(见上),故不满足
ingenic.local解析。→ 转路径 B。
功能
- join IPv4 组播
224.0.0.251:5353(IP_ADD_MEMBERSHIP/SO_REUSEADDR/SO_REUSEPORT)。 - 应答(QNAME 大小写不敏感):
<host>.localA → 设备 wlan0 IPv4。_ssh._tcp.localPTR →<host>._ssh._tcp.local。<host>._ssh._tcp.localSRV(port 22,target<host>.local)+ TXT(空)。_services._dns-sd._udp.localPTR →_ssh._tcp.local(便于 avahi-browse)。- 支持 QTYPE=ANY(255)。
- RFC 1035 名压缩(owner 名若已在响应中出现则回写
0xC0指针)。 - IP_PKTINFO 判断查询到组播还是单播:组播查询→组播应答 + 单播冗余回源;单播查询→单播回源。
- 线程/信号安全;SIGINT/SIGTERM 优雅退出(留组并关 socket)。
环境覆写
| 变量 | 默认 | 说明 |
|---|---|---|
MEOW_MDNS_HOST |
gethostname() 首标签 |
公布的主机名(设备上=内核 hostname meowos,/etc/hostname 残留 ingenic) |
MEOW_MDNS_ADDR |
首块非回环 UP 接口 IPv4 | 应答的 A 记录 IP(设备=wlan0 <device_ip>) |
MEOW_MDNS_PORT |
5353 | 监听端口(通常仅宿主单测用) |
MEOW_MDNS_TTL |
255 | IP_MULTICAST_TTL |
MEOW_MDNS_CF |
0 | 唯一记录(A/SRV/TXT)是否置 cache-flush 位 |
MEOW_MDNS_QD |
1 | 应答是否回显问题段(QDCOUNT) |
MEOW_MDNS_MCAST |
1 | 组播查询是否同时回组播应答(0=只单播回源) |
MEOW_MDNS_MIF |
0 | 是否显式设 IP_MULTICAST_IF 为设备接口 IP |
MEOW_MDNS_DBG |
- | (调试用) |
ARCH / 运行库
- ARCH: mipsel (MIPS32r2 little-endian)
- 目标: mipsel-linux-musleabi (soft-float)
- 静态链接 musl,无 glibc 依赖。
file 结果(bin/meow_mdns)
ELF 32-bit LSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), statically linked, stripped
体积
- 部署版:79,468 B ≈ 77.6 KB(strip 后)
- MD5 :b23de7ce54873e926e7601a3b21b66a9
构建命令
见同目录 build.sh(宿主 gcc -O2 可编译并在本机组播/单播自测;交叉 zig-mipsel-cc -Os -static)。
部署
- 设备:
/usr/data/mnt/sd_0/MeowOS/opt/mdnsd/mdnsd(已部署, 755)。启动./mdnsd -v(或经 meow_svcd 托管)。 - 验证:设备
netstat -uln | grep 5353(0.0.0.0:5353)、cat /proc/net/igmp(wlan0 含FB0000E0=224.0.0.251)、主机单播dig @<设备IP> -p 5353 <host>.local A或 python 探测。
已知限制(重要)
- 手机热点丢弃客户端间组播:设备能收到主机发来的组播查询并组播+单播应答,但设备→主机组播被热点丢弃(主机加入 224.0.0.251 组后 5s 收不到设备组播应答)。avahi 又只接受组播应答(对组播查询的单播应答, avahi 拒绝, 已实测)。故此刻
avahi-resolve <host>.local超时——这是网络层热点隔离,非应答器缺陷。主机需 DNS 兜底(如getent hosts meowos.local走库, 或主机/etc/hosts静态条目, 或设备侧起一个 UDP:53 应答器)。 - 本机(多接口 phone-Linux host)自测时, 应答器组播发送在同机环回也偶发不达(与接口/多默认路由相关),但单播回源始终正确;单接口设备上的组播发送不受此影响。
bin/ 内容
bin/meow_mdns= 部署版(mipsel 静态, 79,468 B, md5 b23de7ce…)