-
Notifications
You must be signed in to change notification settings - Fork 128
Large improvement pack #192
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
Conversation
Preparations for TCP serving
- added TCP client limit option, also can be used to disable TCP DNS server in case of issues - readme and help pages updated - combined API with UDP DNS server - using minimally necessary public header - added TCP only statistic counters - added TCP functional tests - basic querries with valgrind - fragmented TCP request processing - testing 4k large response support - started to use stricter compiler warnings
To ensure code quality and make life harder. Notes: - choosed to use enum or int (e.g. ares_status_t) - CURLINFO_SSL_VERIFYRESULT was wrong - https_fetch_ctx_cleanup's curl_result_code parameter - int options range checked in options.c
If there are not any successful request.
Goal is to indicate service readyness after bootstrap has finished.
Because of larger feature pack
|
Ps.: I was testing my changes for 2 months and I have even asked issue reporters to test with proxy built from my repo if it works well. You can check the conversation on bug reports. I suppose it will be good enough. |
|
bugbot run |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bugbot free trial expires on September 2, 2025
Learn more in the Cursor dashboard.
src/main.c
Outdated
| https_client_init(&https_client, &opt, (opt.stats_interval ? &stat : NULL), loop); | ||
|
|
||
| struct addrinfo *listen_addrinfo = get_listen_address(opt.listen_addr); | ||
| ((struct sockaddr_in*) listen_addrinfo->ai_addr)->sin_port = htons((uint16_t)opt.listen_port); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: DNS Server Fails IPv6 Port Handling
The DNS server incorrectly casts network address structures to sockaddr_in when accessing port numbers. This assumption breaks for IPv6 addresses, leading to memory corruption when setting ports and incorrect port values when extracting them, impacting both UDP and TCP operations.
Additional Locations (2)
src/dns_server_tcp.c
Outdated
| if (len <= 0) { | ||
| if (len == 0 || errno == ECONNRESET) { | ||
| DLOG_CLIENT("Connection closed"); | ||
| } else if (errno == EAGAIN && errno == EWOULDBLOCK) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
I have fixed the bugbot findings. Before merge lets squash the fixups. |
src/dns_server.c
Outdated
| /* recvfrom can write to addrlen */ | ||
| socklen_t tmp_addrlen = d->addrlen; | ||
| ssize_t len = recvfrom(w->fd, buf, REQUEST_MAX, 0, (struct sockaddr*)&raddr, | ||
| char tmp_buf[UINT16_MAX]; // stack buffer for largest UDP packet to support EDNS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I worry a little about this. It's probably OK but might blow up on some small systems with limited stack space.
We copy it into a heap allocated buffer anyway, so what about
char *dns_req = (char *)malloc(UINT16_MAX);
recvfrom(...);
...
dns_req = (char *)realloc(dns_req, len);
if (dns_req == NULL) { ... }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even on openwrt the stack limit is 8MB per thread. Stack size grows only by usage. For my taste 64k is not a huge deal and I would not mess with heap for temporary buffers. Also I would not reserve more on heap (and shrik later) to avoid heap fragmentation. So I'm not expecting any issues with this.
Anyway: I will think about this.
| return udp_size; | ||
| } | ||
|
|
||
| static void truncate_dns_response(char *buf, size_t *buflen, const uint16_t size_limit) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh wow!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wow what? :D What a long overkill function? well yes :(
I have tested this a lot manually with valgrind+dig not to make any mistakes, but still I'm not sure if it is 100% OK, but I hope that calling into this will happen extremely rarely, since EDNS0 UDP buffer limit is enough for most oversized response.
aarond10
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are some solid changes. Thanks! The UINT16_MAX stack allocation is the only thing that stands out as possibly problematic. Hope I didn't miss anything. :D
|
You are welcome! Lets not hurry, check again a few days later. I know, that it is a large change to take in... |
|
I have been thinking about the stack buffer and I would like to keep it. My compromise is to lower the size from 64k to 4k. Before the limit was 1500 byte, so this should be more than enough. Now it will be logged if it was not enough. In case of TCP this does not cause issue, just the read callback will be called multiple times. I hope that this is acceptable by you, if not, then please let me know your proposal. |
|
That sounds fine to me. I haven't used realloc much in the past and I like
the idea that we are in control of the semantics of buffer management
rather than using some niche libc call.
…On Fri, 29 Aug 2025 at 06:09, baranyaib90 ***@***.***> wrote:
*baranyaib90* left a comment (aarond10/https_dns_proxy#192)
<#192 (comment)>
I have been thinking about the stack buffer and I would like to keep it.
My compromise is to lower the size from 64k to 4k. Before the limit was
1500 byte, so this should be more than enough. Now it will be logged if it
was not enough. In case of TCP this does not cause issue, just the read
callback will be called multiple times. I hope that this is acceptable by
you, if not, then please let me know your proposal.
—
Reply to this email directly, view it on GitHub
<#192 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABTOXWWF3CGIFF2ESXGFN33P5OYVAVCNFSM6AAAAACEV7UCE2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTEMZUG44TOMBWGE>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
|
@stangri do you plan to make the new command line arguments configurable trough the luci page? |
I've noticed the following changes, please let me know if I missed any: I'll add support for uci configuration for these in the init script first. Like with some other packages I think the less used (or more expert-like) settings should be separated into the advanced tab. Once the init script/uci support these options it would be a trivial update (beyond adding tabs) to support these in the luci app too. PS. So with the binary you can set these options per-instance. The WebUI for the instance settings already looks overloaded, so If you're willing to provide your feedback/confirm which settings have more to do with environment/OS and can be globalized (like the user/group should most likely be the same for all instances) and which settings might be more resolver-specific I'd be all ears. |
|
Advanced tab sounds great! Resolver specific:
Other options are more like global. |
The more I thought about integrating more of the CLI options into the init script, the more I think following makes sense:
So for example: Can become more compact: And the PROCD command no longer includes That gives flexibility in configuring and in adding options support to the WebUI. That also means that I would have to update the init script in multiple places if some default values change upstream/here. I've documented it at https://docs.openwrt.melmac.ca/https-dns-proxy/#global-settings-for-instances and CI is rebuilding 2025.09.01-r1 with the init file fixes. |
|
Nice page. The only thing I'm missing is the settings value range. e.g. |
We're on the same page. I wanted to add another column with the value options, but the table is pretty narrow to fit the theme as it is. I might have to play with the theme/settings at some point to allow another column. All the docs are in this repo: https://github.com/stangri/docs.openwrt.melmac.ca |
|
@baranyaib90 on 24.10.2 (x86-64) I got the following in dmesg: |
|
It looks like a divide by 0 error, but the location is unclear to me. If you can reproduce the issue, could you run the proxy with debug logs? I would need the last ~1000 logs of the stopped proxy. |
|
Sorry, clarification: I was looking for something else at dmesg and saw these, I don't know how/when it happened, I'll try to reproduce but not sure if i can. |
|
Actually you may not need to help me out with the reproduction. I have reviewed the new code I introduced, and I may have found the issue: answers could be 0 at 866a916#diff-593ced5c0d2c1e50378c33c17cd07cac9c6ba0856e3919474081ef40c68155abR142 |
|
I would like to ask you to build and test from my repo (https://github.com/baranyaib90/https_dns_proxy) to see if the division by 0 issue got fixed or not. Thanks! |
|
Thanks @baranyaib90 I've built a binary from your repo. Any insight on how to try to trigger an event which previously resulted in a division by zero? |
|
Well hard to tell actually. I suspect div by 0 could have happened in 2 ways: DNS response had:
I would recommend instead to:
|
|
Hi @stangri, are there any new crashes mentioned in dmesg since? |
|
Hey @baranyaib90, nothing in dmesg. Your change either worked or at least did no harm, so I'd vote in favour of PR/merging this code. I'll create PR for the OpenWrt package once your code is merged in this repo. |
Hi Aaron,
I hope you are doing well! I suppose you won't like me now. I have a lot of things for review.
Content list:
@stangri it I may ask, please remove file https://github.com/openwrt/packages/blob/master/net/https-dns-proxy/patches/010-cmakelists-remove-cflags.patch if you would uplift the OpenWRT package after this pull request would be merged. I have compiled the OpenWRT package myself and I have not met any warnings. If there would be, please let me know. Thanks!
Take your time.
Best regards,
Balázs