-
Notifications
You must be signed in to change notification settings - Fork 190
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[增强] 支持 udp://
上游
#160
Comments
目前临时解决的方法就只能是先指定udp了 |
不过有一点你确实提醒了我,就是启动时的打印消息:
现在是无脑的打印 tcpin 和 udpin 两个上游地址(没有管TCP、UDP是否监听) |
你的问题与 #153 完全一样,我在那里也做了详细解释和说明: |
不可行,具体原因见 #153 简单来说:
|
我昨天也翻看到#153 的内容, 目前配置文件如下
想了一下能不能这样优化 在国内dns里加上了tcp协议的dns tcp://223.5.5.5,tcp://223.6.6.6 当客户端发起tcp查询时。chinadns-ng能否直接把查询转发到指定tcp协议的dns服务器上。而不转发到211.136.192.6,120.196.165.24这类不支持tcp的运营商dns服务器。 昨天到现在统计限一下udp的查询占有95%,tcp查询占有5%,所以udp查询在运营商的dns上是最快的。 |
当然还有个思路:对于从tcp收到的查询,chinadns-ng允许转发给任意协议的上游(包括udp),如果收到的reply被TC了,则在chinadns-ng这边丢弃这个reply(先不交给tcp客户端),然后再次向上游发起一次相同的查询(这回就需要排除udp上游了),然后这次拿到的reply肯定不会被TC,最后将这个reply返回给tcp客户端。 但是这样真的有必要吗?而且即使真的这样做,也有个前提条件:上游组中必须有至少一个支持TCP查询的上游,否则因TC而发起的第二次query必定会失败。 |
根据你给出的配置,目前chinadns-ng对于一个上游组的查询策略是 并发查询所有,因此你说的是可以做到的,只不过实际的情况是这样: 从tcp收到查询,转发给china组时:
最终结果采纳最先返回的哪个,也就是要么是223.5.5.5、要么是223.6.6.6返回的结果,运营商dns失败不会有任何影响(这就是允许配置多个dns上游的核心目的)。 |
这个目前就是这样工作的,无需更改。 |
其实我现在纠结的是当客户端使用tcp查询发送到上游运营商DNS:211.136.192.6,120.196.165.24的时候他使用tcpin导致Operation timed out,然后dnsmasq无故挂起后启动多个进程的问题。。 然而。如果bind-port 5354@udp,或者去掉运营商dns(211.136.192.6,120.196.165.24,),只使用223.5.5.5,223.6.6.6可以udp+tcp的dns时 dnsmasq则正常没问题
|
其实,你可以关闭 dnsmasq 的 dns 功能,让 chinadns-ng 负责所有 dns,这样就不会有你说的 dnsmasq 因为 tcp 查询而启动多个进程的问题了。
将 dnsmasq 里面的 port 设置为 0,这样就关闭了 DNS,只留下 DHCP 等功能。 |
因为目前 dnsmasq 对于 TCP 上的 DNS 实现很糟糕,效率也很低,每个 TCP 连接/查询 都会 fork 一个新的 dnsmasq 进程去处理,如果并发量稍微高一些,再加上路由器上本来内存就不多,进程数多起来之后很容易把系统弄得宕机。 不如让dnsmasq专门负责DHCP,dns交给其他软件去做。 |
现在先这样处理了,关了dnsmasq的53端口。chinadns-ng监听tcp+udp的53端口,添加了cache与verdict-cache,先观察使用情况。感谢大神回复!!! |
另外,我建议你修改下配置,没必要在 223.5.5.5/223.6.6.6 前面加上 tcp:// 限定,直接和运营商 DNS 一样就行了(没有协议限定),这样 chinadns-ng 这边会自动根据查询方的传入协议来决定与上游的通信协议,因为大部分情况下DNS仍然走UDP,所以能减少很多不必要的TCP查询。 |
这个问题也不太可能吧,在tcp的处理上,chinadns-ng和dns2tcp一样的。访问失败建议查询下是不是iptables规则问题(没有走代理?) |
其实这是我一个很奇怪的需求,目前我这的运营商是中国移动的,ping 8.8.8.8以及2001:4860:4860::8888的延时平时只有20ms左右,夜深人静的时候。延时更可达到10ms。
然而,使用8.8.8.8以及2001:4860:4860::8888查udp的53端口,一些国外的域名就会被污染。使用tcp查询。则干净。 平时主要在油站游荡。使用ipv6能直连rr1---sn-i3b7knsd.googlevideo.com等googlevideo.com的域名。 然后看到chinadns-ng也能直接支持tcp://,就把dns2tcp关了。然后路由器就经常报。 他能用。但就是会报这个错。
但是chinadns-ng(udp)->udp2tcp->8.8.8.8就没有这个问题。。。 |
好吧,那确实摸不着头脑。那就不管了哈哈。 |
所以。。才想着。上游那里能指定udp就更好了,因为按照我现在的配置
127.0.0.1#5353,127.0.0.1#5352 tcp://2001:4860:4860::8888,tcp://2001:4860:4860::8844,tcp://8.8.8.8,tcp://8.8.4.4 |
回头有空我看看,用这个思路,这样就能支持 udp:// 上游了(仅udp查询),在TC截断重试的查询中,此类上游被禁用。 因为tc的情况还是比较少见,所以还是没啥问题的。逻辑上和效率上都OK |
好咧。感谢大佬的关注和回复。。 就目前来说,我觉得dns所返回的MSG SIZE,应该是由网站/app/dns的服务提供商控制的。
其实正常情况MSG SIZE 都不大。。。 |
想了下,其实根本不用在chinadns-ng这边重试,直接过滤TC的reply就行了(tcp查询时)
UPDATE: dev分支已修改,测试正常。 |
坐等更新,今天使用还发现一个问题, dns上游为 查询域名cn-beijing-data.aliyundrive.net时上游返回EDNS的数据MSG SIZE达到530
此时chinadns-ng把这个reply给缓存了。 只有等缓存时间过了,再请求cn-beijing-data.aliyundrive.net时。返回新的reply没有带EDNS字样MSG SIZE 为491时。才能正常访问cn-beijing-data.aliyundrive.net
当使用dnsmasq时。第一次请求没缓存的SIZE也是491,如下
再次查询时。他缓存的SIZE就只有249了。
仔细看过。dnsmasq缓存的只有ANSWER SECTION但是多了一个EDNS的标识 |
这其实是一个musl的dns问题,最新的musl才支持tcp fallback(udp上的msg被TC时),之前的版本不支持。 因为530字节,刚好超过了512的默认大小(musl没有带EDNS0选项,所以只能接受512字节的udp msg)。 https://news.ycombinator.com/item?id=36933028 https://git.musl-libc.org/cgit/musl/commit/?id=51d4669fb97782f6a66606da852b5afd49a08001 不过为了兼容性(兼容这种不支持tcp fallback的resolver),等会我也修改下cache逻辑吧,只保留answer section,其他去除。
|
我差点忽略了一个细节。就是那个wget。在第一次请求(reply还没缓存)的时候是可以的,然后我手贱把wget关了再开。。才发现这个问题。就是wget查chinadns-ng缓存命中之后才会这样。 |
其实是因为你第一次dig的请求,dig支持edns,所以第一次的reply是有edns rr的,看log,这个rr应该有十几二十字节。 然后chinadns-ng把这个reply缓存下来 第二次wget来请求,因为刚好size超过了512,于是产生了truncate,刚好你的musl版本没有tcp fallback。所以提示解析失败。 此时你可以其他主机用wget测试(glibc版本的,不能是musl),或者用dig重新请求,其实都是正常的,没有问题。 另外,如果第一次解析请求是musl/glibc发起的,比如用刚刚的wget去解析这个域名(然后被chinadns缓存起来),因为size为491,不会发生truncate,其实就没问题。 总之,原因已经了解,待会我改一下就ok了。 |
顺序应该是这样的: 第一次wget是正常的。当时还没dig。第一个reply应该返回给wget了,并且chinadns-ng进行缓存, 第二次wget的时候dns部分应该只有resolver和chinadns-ng通迅了。中间是否少了什么东西。。 。。但这个问题很难复现, |
应该不用复现了,因为这个问题本质就是旧版 musl 不支持 size > 512 的 msg(具体地说,> 512 的 reply 被 TC 了,而 musl 又不支持 tcp fallback),所以 musl 报告 dns 解析失败,于是 wget 抛出这个错误。 此时,如果使用glibc版本的wget,或者用浏览器去访问,都是ok的。问题其实与chinadns-ng无关。 我已经在修改缓存代码了,缓存时只保留answer节(也就是最小化的response),防止msg过大,而resolver又不支持tcp fallback的问题。(也就是dnsmasq这样的行为,缓存的reply只有answer) |
dev已修改,测试ok。 |
dnsmasq上是添加了
flags由 移除了 但是缓存后的 完整的是这样的
|
就是 OPT RR,也就是 EDNS version 0 那行。 |
期待新版本,,,求编译个开发版测试测试。。。 |
什么平台?发release的chinadns-ng文件名给我 |
两个平台。 |
明天会发布一个版本。 |
目前两个平台测试未发现问题。。 |
见最新版本。 |
拓扑如下:
国内:局域网设备->dnsmasq->chinadns-ng->211.136.192.6/120.196.165.24(运营商DNS)
国外:局域网设备->dnsmasq->chinadns-ng->dns2tcp->8.8.8.8
dnsmasq有ipv6需求,不能扔
dns2tcp只能监听udp,使用chinadns-ng自带的tcp://8.8.8.8会出现大量的connection reset by peer.所以只能用dns2tcp
今天使用时出现一个情况,手机在刷抖音的时候。app会调起大量的tcp的dns查询,dnsmasq监听53端口,接收到请求后转发到chinadns-ng,但chinadns-ng上游全都只支持udp导致dnsmasq在等待结果时启动了多个进程。
运行时配置如下
当客户端使用以下命令查询时
dig @127.0.0.1 -p5354 +tcp www.youtube.com
chinadns-ng报以下错误
客户端的dig报以下错误
同样地。国内网站使用tcp查询时因为运营商dns不支持tcp而导至查询失败连接超时
虽然运行时看似upstream有udpin和tcpin,但是客户端只要指定了tcp查询,chinadns-ng就只forward tcp,并不会使用udp,
The text was updated successfully, but these errors were encountered: