Closed Mosney closed 4 years ago
Forgot to mention it: Don't use 0.0.0.0/:: to bind is a quick way to fix this issue, but the drawbacks are obvious, you will no longer be able to listen all IP.
This SO_REUSEADDR
is an old golang issue, but it seems I've finally found a way to fix it.
@szolin check this out: https://gist.github.com/joliver/4ccd58605e07e8edf71904b172d95513
I am not sure if this approach will work properly on Windows, but other than that, it seems okay.
I don't understand how it's possible.
Some programs bind to 0.0.0.0:53 or :::53 and no set SO_REUSEADDR, which makes it impossible to bind the WriteBack By 8.8.8.8:53
SO_REUSEADDR won't help in case AGH is listening on 0.0.0.0
check this out: https://gist.github.com/joliver/4ccd58605e07e8edf71904b172d95513
SO_REUSEPORT is a feature for distributing network load between several processes of the same application. If we start using it, we will receive half of the incoming requests. The other half will be received by another application.
I don't understand how it's possible.
Some programs bind to 0.0.0.0:53 or :::53 and no set SO_REUSEADDR, which makes it impossible to bind the WriteBack By 8.8.8.8:53
It's possible.
If you dive into the Linux TPROXY stack,when processing a UDP connection, for example ,if the Dest Addr is 8.8.8.8:53
, the TPROXY program must bind to 8.8.8.8:53
on TPROXY host os and send the UDP packet back to the Client to make sure the Src Addr and Port is 8.8.8.8:53
, IF,when ADG has binded :53 on this host os without SO_REUSEADDR
, the behavior of the TPROXY program will fail with EADDRINUSE (Address already in use)
Here are some example of TPROXY program that has this behavior
SO_REUSEADDR won't help in case AGH is listening on 0.0.0.0
check this out: https://gist.github.com/joliver/4ccd58605e07e8edf71904b172d95513
SO_REUSEPORT is a feature for distributing network load between several processes of the same application. If we start using it, we will receive half of the incoming requests. The other half will be received by another application.
it's true when working with distributing network load between several processes
,
but in the scene above I've mentioned ,it's really safe for ADG to use SO_REUSEADDR
,because we wont get inbound connection to 8.8.8.8:53
for our HOST
And,DNSMASQ
also allow SO_REUSEADDR
by default
IMO, we should make this behavior configurable...
@ameshkov @szolin
after 5 days since this comment,the Team seems to take some actions to support SO_REUSEADDR
I just can't understand why SO_REUSEPORT
is also used and the TCP listen is also applied to these socket options.
these aren't necessary, IMO.
let's wait and see @ainar-g
Prerequisites
Please answer the following questions for yourself before submitting an issue. YOU MAY DELETE THE PREREQUISITES SECTION.
Issue Details
Additional Information
I deploy a proxy software clash as gateway transparent proxy at OpenWrt which also run AdGuardHome, and AGH's config is
bind_host: 0.0.0.0
. Because of AGH deficiencies(see original issue below).In conclusion, AGH not allow reuse bind-address, so other processes cannot writeback via :53 port, cause proxy software behavioural peculiarities, it will lead proxied standard DNS query respond failed. And it will not affect local network DNS query which not through proxy at all. Of course, is a small probability bug, few users run AGH and proxy software on the same system. Nevertheless, I still hope you can check and fix it, AGH is a gateway level service, it should robustness and compatibility enough.
Original issue: https://github.com/Dreamacro/clash/issues/616#issuecomment-611961492 Comment translation: Some programs bind to
0.0.0.0:53
or:::53
and no set SO_REUSEADDR, which makes it impossible to bind the WriteBack By 8.8.8.8:53